Fix HIDL VHAL descriptor name in VTS. am: 928062ccac

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2928798

Change-Id: I6f7dd76ee3c813194085f131fe495e8f60492f7c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/OWNERS b/OWNERS
index 3a1a038..a53d83e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -9,6 +9,3 @@
 
 # historical/backup
 maco@google.com
-
-# vts tests
-guangzhu@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
index acae4f3..25246d8 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -12,6 +12,11 @@
     {
       "name": "VtsHalTvInputV1_0TargetTest"
     }
+  ],
+  "auto-presubmit": [
+    {
+      "name": "hal_implementation_test"
+    }
   ]
 }
 
diff --git a/audio/OWNERS b/audio/OWNERS
new file mode 100644
index 0000000..3671685
--- /dev/null
+++ b/audio/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 48436
+
+elaurent@google.com
+mnaganov@google.com
diff --git a/audio/README.md b/audio/README.md
index 1938ad4..3f40d72 100644
--- a/audio/README.md
+++ b/audio/README.md
@@ -2,10 +2,29 @@
 
 Directory structure of the audio HAL related code.
 
-Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL
-based on an existing one.
+## Directory Structure for AIDL audio HAL
 
-## Directory Structure
+The AIDL version is located inside `aidl` directory. The tree below explains
+the role of each subdirectory:
+
+* `aidl_api` — snapshots of the API created each Android release. Every
+  release, the current version of the API becomes "frozen" and gets assigned
+  the next version number. If the API needs further modifications, they are
+  made on the "current" version. After making modifications, run
+  `m <package name>-update-api` to update the snapshot of the "current"
+  version.
+* `android/hardware/audio/common` — data structures and interfaces shared
+  between various HALs: BT HAL, core and effects audio HALs.
+* `android/hardware/audio/core` — data structures and interfaces of the
+  core audio HAL.
+* `default` — the default, reference implementation of the audio HAL service.
+* `vts` — VTS tests for the AIDL HAL.
+
+## Directory Structure for HIDL audio HAL
+
+Run `common/all-versions/copyHAL.sh` to create a new version of the HIDL audio
+HAL based on an existing one. Note that this isn't possible since Android T
+release. Android U and above uses AIDL audio HAL.
 
 * `2.0` — version 2.0 of the core HIDL API. Note that `.hal` files
   can not be moved into the `core` directory because that would change
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 0b5b993..5a009fe 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -23,19 +23,29 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+aidl_interface_defaults {
+    name: "android.hardware.audio_defaults",
+    host_supported: true,
+    vendor_available: true,
+    stability: "vintf",
+}
+
 aidl_interface {
     name: "android.hardware.audio.common",
-    vendor_available: true,
+    defaults: [
+        "android.hardware.audio_defaults",
+    ],
     srcs: [
+        "android/hardware/audio/common/AudioOffloadMetadata.aidl",
         "android/hardware/audio/common/PlaybackTrackMetadata.aidl",
         "android/hardware/audio/common/RecordTrackMetadata.aidl",
         "android/hardware/audio/common/SinkMetadata.aidl",
         "android/hardware/audio/common/SourceMetadata.aidl",
     ],
+    frozen: true,
     imports: [
-        "android.media.audio.common.types-V1",
+        "android.media.audio.common.types-V2",
     ],
-    stability: "vintf",
     backend: {
         cpp: {
             enabled: true,
@@ -49,12 +59,9 @@
             ],
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apex_available: [
                 "//apex_available:platform",
-                "com.android.bluetooth",
+                "com.android.btservices",
             ],
             min_sdk_version: "31",
         },
@@ -62,8 +69,256 @@
     versions_with_info: [
         {
             version: "1",
-            imports: ["android.media.audio.common.types-V1"],
+            imports: ["android.media.audio.common.types-V2"],
         },
+        {
+            version: "2",
+            imports: ["android.media.audio.common.types-V2"],
+        },
+
+        // IMPORTANT: Update latest_android_hardware_audio_common every time you
+        // add the latest frozen version to versions_with_info
     ],
 
 }
+
+// Note: This should always be one version ahead of the last frozen version
+latest_android_hardware_audio_common = "android.hardware.audio.common-V2"
+
+// Modules that depend on android.hardware.audio.common directly can include
+// the following cc_defaults to avoid explicitly managing dependency versions
+// across many scattered files.
+cc_defaults {
+    name: "latest_android_hardware_audio_common_cpp_static",
+    static_libs: [
+        latest_android_hardware_audio_common + "-cpp",
+    ],
+}
+
+cc_defaults {
+    name: "latest_android_hardware_audio_common_ndk_static",
+    static_libs: [
+        latest_android_hardware_audio_common + "-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "latest_android_hardware_audio_common_ndk_shared",
+    shared_libs: [
+        latest_android_hardware_audio_common + "-ndk",
+    ],
+}
+
+aidl_interface {
+    name: "android.hardware.audio.core",
+    defaults: [
+        "android.hardware.audio_defaults",
+    ],
+    srcs: [
+        "android/hardware/audio/core/AudioPatch.aidl",
+        "android/hardware/audio/core/AudioRoute.aidl",
+        "android/hardware/audio/core/IBluetooth.aidl",
+        "android/hardware/audio/core/IBluetoothA2dp.aidl",
+        "android/hardware/audio/core/IBluetoothLe.aidl",
+        "android/hardware/audio/core/IConfig.aidl",
+        "android/hardware/audio/core/IModule.aidl",
+        "android/hardware/audio/core/IStreamCallback.aidl",
+        "android/hardware/audio/core/IStreamCommon.aidl",
+        "android/hardware/audio/core/IStreamIn.aidl",
+        "android/hardware/audio/core/IStreamOut.aidl",
+        "android/hardware/audio/core/IStreamOutEventCallback.aidl",
+        "android/hardware/audio/core/ITelephony.aidl",
+        "android/hardware/audio/core/MmapBufferDescriptor.aidl",
+        "android/hardware/audio/core/ModuleDebug.aidl",
+        "android/hardware/audio/core/StreamDescriptor.aidl",
+        "android/hardware/audio/core/SurroundSoundConfig.aidl",
+        "android/hardware/audio/core/VendorParameter.aidl",
+    ],
+    imports: [
+        "android.hardware.common-V2",
+        "android.hardware.common.fmq-V1",
+        "android.hardware.audio.common-V2",
+        "android.hardware.audio.core.sounddose-V1",
+        "android.hardware.audio.effect-V1",
+        "android.media.audio.common.types-V2",
+    ],
+    backend: {
+        // The C++ backend is disabled transitively due to use of FMQ.
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.common.fmq-V1",
+                "android.hardware.audio.common-V2",
+                "android.hardware.audio.core.sounddose-V1",
+                "android.hardware.audio.effect-V1",
+                "android.media.audio.common.types-V2",
+            ],
+        },
+
+        // IMPORTANT: Update latest_android_hardware_audio_core every time you
+        // add the latest frozen version to versions_with_info
+    ],
+    frozen: true,
+}
+
+// Note: This should always be one version ahead of the last frozen version
+latest_android_hardware_audio_core = "android.hardware.audio.core-V1"
+
+// Modules that depend on android.hardware.audio.core directly can include
+// the following cc_defaults to avoid explicitly managing dependency versions
+// across many scattered files.
+cc_defaults {
+    name: "latest_android_hardware_audio_core_ndk_shared",
+    shared_libs: [
+        latest_android_hardware_audio_core + "-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "latest_android_hardware_audio_core_ndk_static",
+    static_libs: [
+        latest_android_hardware_audio_core + "-ndk",
+    ],
+}
+
+// Used for the standalone sounddose HAL
+aidl_interface {
+    name: "android.hardware.audio.core.sounddose",
+    defaults: [
+        "android.hardware.audio_defaults",
+    ],
+    srcs: [
+        "android/hardware/audio/core/sounddose/ISoundDose.aidl",
+    ],
+    imports: [
+        "android.media.audio.common.types-V2",
+    ],
+    backend: {
+        // The C++ backend is disabled transitively due to use of FMQ by the core HAL.
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.media.audio.common.types-V2"],
+        },
+
+        // IMPORTANT: Update latest_android_hardware_audio_core_sounddose every time you
+        // add the latest frozen version to versions_with_info
+    ],
+    frozen: true,
+}
+
+// Note: This should always be one version ahead of the last frozen version
+latest_android_hardware_audio_core_sounddose = "android.hardware.audio.core.sounddose-V1"
+
+// Modules that depend on android.hardware.audio.core.sounddose directly can include
+// the following cc_defaults to avoid explicitly managing dependency versions
+// across many scattered files.
+cc_defaults {
+    name: "latest_android_hardware_audio_core_sounddose_ndk_shared",
+    shared_libs: [
+        latest_android_hardware_audio_core_sounddose + "-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "latest_android_hardware_audio_core_sounddose_ndk_static",
+    static_libs: [
+        latest_android_hardware_audio_core_sounddose + "-ndk",
+    ],
+}
+
+aidl_interface {
+    name: "android.hardware.audio.effect",
+    defaults: [
+        "android.hardware.audio_defaults",
+    ],
+    srcs: [
+        "android/hardware/audio/effect/AcousticEchoCanceler.aidl",
+        "android/hardware/audio/effect/AutomaticGainControlV1.aidl",
+        "android/hardware/audio/effect/AutomaticGainControlV2.aidl",
+        "android/hardware/audio/effect/BassBoost.aidl",
+        "android/hardware/audio/effect/Capability.aidl",
+        "android/hardware/audio/effect/CommandId.aidl",
+        "android/hardware/audio/effect/DefaultExtension.aidl",
+        "android/hardware/audio/effect/Descriptor.aidl",
+        "android/hardware/audio/effect/Downmix.aidl",
+        "android/hardware/audio/effect/DynamicsProcessing.aidl",
+        "android/hardware/audio/effect/EnvironmentalReverb.aidl",
+        "android/hardware/audio/effect/Equalizer.aidl",
+        "android/hardware/audio/effect/Flags.aidl",
+        "android/hardware/audio/effect/HapticGenerator.aidl",
+        "android/hardware/audio/effect/IEffect.aidl",
+        "android/hardware/audio/effect/IFactory.aidl",
+        "android/hardware/audio/effect/LoudnessEnhancer.aidl",
+        "android/hardware/audio/effect/NoiseSuppression.aidl",
+        "android/hardware/audio/effect/Parameter.aidl",
+        "android/hardware/audio/effect/PresetReverb.aidl",
+        "android/hardware/audio/effect/Processing.aidl",
+        "android/hardware/audio/effect/Range.aidl",
+        "android/hardware/audio/effect/State.aidl",
+        "android/hardware/audio/effect/VendorExtension.aidl",
+        "android/hardware/audio/effect/Virtualizer.aidl",
+        "android/hardware/audio/effect/Visualizer.aidl",
+        "android/hardware/audio/effect/Volume.aidl",
+    ],
+    imports: [
+        "android.hardware.common-V2",
+        "android.hardware.common.fmq-V1",
+        "android.hardware.audio.common-V2",
+        "android.media.audio.common.types-V2",
+    ],
+    backend: {
+        // The C++ backend is disabled transitively due to use of FMQ.
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.common.fmq-V1",
+                "android.hardware.audio.common-V2",
+                "android.media.audio.common.types-V2",
+            ],
+        },
+    ],
+    frozen: true,
+
+}
+
+latest_android_hardware_audio_effect = "android.hardware.audio.effect-V1"
+
+cc_defaults {
+    name: "latest_android_hardware_audio_effect_ndk_shared",
+    shared_libs: [
+        latest_android_hardware_audio_effect + "-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "latest_android_hardware_audio_effect_ndk_static",
+    static_libs: [
+        latest_android_hardware_audio_effect + "-ndk",
+    ],
+}
diff --git a/audio/aidl/OWNERS b/audio/aidl/OWNERS
deleted file mode 100644
index f9a2d6b..0000000
--- a/audio/aidl/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 48436
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
new file mode 100644
index 0000000..3e06595
--- /dev/null
+++ b/audio/aidl/TEST_MAPPING
@@ -0,0 +1,52 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalAudioCoreTargetTest"
+    },
+    {
+      "name": "VtsHalAudioEffectFactoryTargetTest"
+    },
+    {
+      "name": "VtsHalAudioEffectTargetTest"
+    },
+    {
+      "name": "VtsHalDownmixTargetTest"
+    },
+    {
+      "name": "VtsHalEnvironmentalReverbTargetTest"
+    },
+    {
+      "name": "VtsHalEqualizerTargetTest"
+    },
+    {
+      "name": "VtsHalHapticGeneratorTargetTest"
+    },
+    {
+      "name": "VtsHalLoudnessEnhancerTargetTest"
+    },
+    {
+      "name": "VtsHalPresetReverbTargetTest"
+    },
+    {
+      "name": "VtsHalVirtualizerTargetTest"
+    },
+    {
+      "name": "VtsHalVisualizerTargetTest"
+    },
+    {
+      "name": "VtsHalVolumeTargetTest"
+    },
+    {
+      "name": "VtsHalAECTargetTest"
+    },
+    {
+      "name": "VtsHalAGC1TargetTest"
+    },
+    {
+      "name": "VtsHalAGC2TargetTest"
+    },
+    {
+      "name": "VtsHalNSTargetTest"
+    }
+  ]
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/2/.hash b/audio/aidl/aidl_api/android.hardware.audio.common/2/.hash
new file mode 100644
index 0000000..6f56a4c
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/.hash
@@ -0,0 +1 @@
+6780ccb29120b4c7d3ed60f55a23c13b0431f3a4
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/AudioOffloadMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/AudioOffloadMetadata.aidl
new file mode 100644
index 0000000..000504b
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/AudioOffloadMetadata.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioOffloadMetadata {
+  int sampleRate;
+  android.media.audio.common.AudioChannelLayout channelMask;
+  int averageBitRatePerSecond;
+  int delayFrames;
+  int paddingFrames;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/PlaybackTrackMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/PlaybackTrackMetadata.aidl
new file mode 100644
index 0000000..be4941c
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/PlaybackTrackMetadata.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable PlaybackTrackMetadata {
+  android.media.audio.common.AudioUsage usage = android.media.audio.common.AudioUsage.INVALID;
+  android.media.audio.common.AudioContentType contentType = android.media.audio.common.AudioContentType.UNKNOWN;
+  float gain;
+  android.media.audio.common.AudioChannelLayout channelMask;
+  @nullable android.media.audio.common.AudioDevice sourceDevice;
+  @utf8InCpp String[] tags;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/RecordTrackMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/RecordTrackMetadata.aidl
new file mode 100644
index 0000000..8f667d1
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/RecordTrackMetadata.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable RecordTrackMetadata {
+  android.media.audio.common.AudioSource source = android.media.audio.common.AudioSource.SYS_RESERVED_INVALID;
+  float gain;
+  @nullable android.media.audio.common.AudioDevice destinationDevice;
+  android.media.audio.common.AudioChannelLayout channelMask;
+  @utf8InCpp String[] tags;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SinkMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SinkMetadata.aidl
new file mode 100644
index 0000000..270147d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SinkMetadata.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SinkMetadata {
+  android.hardware.audio.common.RecordTrackMetadata[] tracks;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SourceMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SourceMetadata.aidl
new file mode 100644
index 0000000..2d4a982
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/2/android/hardware/audio/common/SourceMetadata.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SourceMetadata {
+  android.hardware.audio.common.PlaybackTrackMetadata[] tracks;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/AudioOffloadMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/AudioOffloadMetadata.aidl
new file mode 100644
index 0000000..000504b
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/AudioOffloadMetadata.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioOffloadMetadata {
+  int sampleRate;
+  android.media.audio.common.AudioChannelLayout channelMask;
+  int averageBitRatePerSecond;
+  int delayFrames;
+  int paddingFrames;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/.hash b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/.hash
new file mode 100644
index 0000000..270b1c9
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/.hash
@@ -0,0 +1 @@
+7913a7ff584002e6889416e5dddbe46878d0a51e
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/android/hardware/audio/core/sounddose/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/android/hardware/audio/core/sounddose/ISoundDose.aidl
new file mode 100644
index 0000000..5800091
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/1/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core.sounddose;
+@VintfStability
+interface ISoundDose {
+  void setOutputRs2UpperBound(float rs2ValueDbA);
+  float getOutputRs2UpperBound();
+  void registerSoundDoseCallback(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback callback);
+  const int DEFAULT_MAX_RS2 = 100;
+  const int MIN_RS2 = 80;
+  @VintfStability
+  interface IHalSoundDoseCallback {
+    oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
+    oneway void onNewMelValues(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
+    @VintfStability
+    parcelable MelRecord {
+      float[] melValues;
+      long timestamp;
+    }
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
new file mode 100644
index 0000000..5800091
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core.sounddose;
+@VintfStability
+interface ISoundDose {
+  void setOutputRs2UpperBound(float rs2ValueDbA);
+  float getOutputRs2UpperBound();
+  void registerSoundDoseCallback(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback callback);
+  const int DEFAULT_MAX_RS2 = 100;
+  const int MIN_RS2 = 80;
+  @VintfStability
+  interface IHalSoundDoseCallback {
+    oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
+    oneway void onNewMelValues(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
+    @VintfStability
+    parcelable MelRecord {
+      float[] melValues;
+      long timestamp;
+    }
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/.hash b/audio/aidl/aidl_api/android.hardware.audio.core/1/.hash
new file mode 100644
index 0000000..8eb6be5
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/.hash
@@ -0,0 +1 @@
+1cec1e67515bdd2b896d80d20a64bf899b2470bf
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioPatch.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioPatch.aidl
new file mode 100644
index 0000000..078b5ea
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioPatch.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioPatch {
+  int id;
+  int[] sourcePortConfigIds;
+  int[] sinkPortConfigIds;
+  int minimumStreamBufferSizeFrames;
+  int[] latenciesMs;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioRoute.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioRoute.aidl
new file mode 100644
index 0000000..deeef87
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/AudioRoute.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioRoute {
+  int[] sourcePortIds;
+  int sinkPortId;
+  boolean isExclusive;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetooth.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetooth.aidl
new file mode 100644
index 0000000..9357a15
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetooth.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IBluetooth {
+  android.hardware.audio.core.IBluetooth.ScoConfig setScoConfig(in android.hardware.audio.core.IBluetooth.ScoConfig config);
+  android.hardware.audio.core.IBluetooth.HfpConfig setHfpConfig(in android.hardware.audio.core.IBluetooth.HfpConfig config);
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable ScoConfig {
+    @nullable android.media.audio.common.Boolean isEnabled;
+    @nullable android.media.audio.common.Boolean isNrecEnabled;
+    android.hardware.audio.core.IBluetooth.ScoConfig.Mode mode = android.hardware.audio.core.IBluetooth.ScoConfig.Mode.UNSPECIFIED;
+    @nullable @utf8InCpp String debugName;
+    @VintfStability
+    enum Mode {
+      UNSPECIFIED,
+      SCO,
+      SCO_WB,
+      SCO_SWB,
+    }
+  }
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable HfpConfig {
+    @nullable android.media.audio.common.Boolean isEnabled;
+    @nullable android.media.audio.common.Int sampleRate;
+    @nullable android.media.audio.common.Float volume;
+    const int VOLUME_MIN = 0;
+    const int VOLUME_MAX = 1;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothA2dp.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothA2dp.aidl
new file mode 100644
index 0000000..0f4c46d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothA2dp.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IBluetoothA2dp {
+  boolean isEnabled();
+  void setEnabled(boolean enabled);
+  boolean supportsOffloadReconfiguration();
+  void reconfigureOffload(in android.hardware.audio.core.VendorParameter[] parameters);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothLe.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothLe.aidl
new file mode 100644
index 0000000..2068daf
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IBluetoothLe.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IBluetoothLe {
+  boolean isEnabled();
+  void setEnabled(boolean enabled);
+  boolean supportsOffloadReconfiguration();
+  void reconfigureOffload(in android.hardware.audio.core.VendorParameter[] parameters);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IConfig.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IConfig.aidl
new file mode 100644
index 0000000..9ce45bb
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IConfig {
+  android.hardware.audio.core.SurroundSoundConfig getSurroundSoundConfig();
+  android.media.audio.common.AudioHalEngineConfig getEngineConfig();
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IModule.aidl
new file mode 100644
index 0000000..e14e9c0
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IModule.aidl
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IModule {
+  void setModuleDebug(in android.hardware.audio.core.ModuleDebug debug);
+  @nullable android.hardware.audio.core.ITelephony getTelephony();
+  @nullable android.hardware.audio.core.IBluetooth getBluetooth();
+  @nullable android.hardware.audio.core.IBluetoothA2dp getBluetoothA2dp();
+  @nullable android.hardware.audio.core.IBluetoothLe getBluetoothLe();
+  android.media.audio.common.AudioPort connectExternalDevice(in android.media.audio.common.AudioPort templateIdAndAdditionalData);
+  void disconnectExternalDevice(int portId);
+  android.hardware.audio.core.AudioPatch[] getAudioPatches();
+  android.media.audio.common.AudioPort getAudioPort(int portId);
+  android.media.audio.common.AudioPortConfig[] getAudioPortConfigs();
+  android.media.audio.common.AudioPort[] getAudioPorts();
+  android.hardware.audio.core.AudioRoute[] getAudioRoutes();
+  android.hardware.audio.core.AudioRoute[] getAudioRoutesForAudioPort(int portId);
+  android.hardware.audio.core.IModule.OpenInputStreamReturn openInputStream(in android.hardware.audio.core.IModule.OpenInputStreamArguments args);
+  android.hardware.audio.core.IModule.OpenOutputStreamReturn openOutputStream(in android.hardware.audio.core.IModule.OpenOutputStreamArguments args);
+  android.hardware.audio.core.IModule.SupportedPlaybackRateFactors getSupportedPlaybackRateFactors();
+  android.hardware.audio.core.AudioPatch setAudioPatch(in android.hardware.audio.core.AudioPatch requested);
+  boolean setAudioPortConfig(in android.media.audio.common.AudioPortConfig requested, out android.media.audio.common.AudioPortConfig suggested);
+  void resetAudioPatch(int patchId);
+  void resetAudioPortConfig(int portConfigId);
+  boolean getMasterMute();
+  void setMasterMute(boolean mute);
+  float getMasterVolume();
+  void setMasterVolume(float volume);
+  boolean getMicMute();
+  void setMicMute(boolean mute);
+  android.media.audio.common.MicrophoneInfo[] getMicrophones();
+  void updateAudioMode(android.media.audio.common.AudioMode mode);
+  void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation);
+  void updateScreenState(boolean isTurnedOn);
+  @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose();
+  int generateHwAvSyncId();
+  android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
+  void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async);
+  void addDeviceEffect(int portConfigId, in android.hardware.audio.effect.IEffect effect);
+  void removeDeviceEffect(int portConfigId, in android.hardware.audio.effect.IEffect effect);
+  android.media.audio.common.AudioMMapPolicyInfo[] getMmapPolicyInfos(android.media.audio.common.AudioMMapPolicyType mmapPolicyType);
+  boolean supportsVariableLatency();
+  int getAAudioMixerBurstCount();
+  int getAAudioHardwareBurstMinUsec();
+  const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2;
+  const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000;
+  @VintfStability
+  parcelable OpenInputStreamArguments {
+    int portConfigId;
+    android.hardware.audio.common.SinkMetadata sinkMetadata;
+    long bufferSizeFrames;
+  }
+  @VintfStability
+  parcelable OpenInputStreamReturn {
+    android.hardware.audio.core.IStreamIn stream;
+    android.hardware.audio.core.StreamDescriptor desc;
+  }
+  @VintfStability
+  parcelable OpenOutputStreamArguments {
+    int portConfigId;
+    android.hardware.audio.common.SourceMetadata sourceMetadata;
+    @nullable android.media.audio.common.AudioOffloadInfo offloadInfo;
+    long bufferSizeFrames;
+    @nullable android.hardware.audio.core.IStreamCallback callback;
+    @nullable android.hardware.audio.core.IStreamOutEventCallback eventCallback;
+  }
+  @VintfStability
+  parcelable OpenOutputStreamReturn {
+    android.hardware.audio.core.IStreamOut stream;
+    android.hardware.audio.core.StreamDescriptor desc;
+  }
+  @VintfStability
+  parcelable SupportedPlaybackRateFactors {
+    float minSpeed;
+    float maxSpeed;
+    float minPitch;
+    float maxPitch;
+  }
+  @Backing(type="int") @VintfStability
+  enum ScreenRotation {
+    DEG_0 = 0,
+    DEG_90 = 1,
+    DEG_180 = 2,
+    DEG_270 = 3,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCallback.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCallback.aidl
new file mode 100644
index 0000000..5a2ab78
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamCallback {
+  oneway void onTransferReady();
+  oneway void onError();
+  oneway void onDrainReady();
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCommon.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCommon.aidl
new file mode 100644
index 0000000..65a2ee4
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamCommon.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamCommon {
+  void close();
+  void prepareToClose();
+  void updateHwAvSyncId(int hwAvSyncId);
+  android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
+  void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async);
+  void addEffect(in android.hardware.audio.effect.IEffect effect);
+  void removeEffect(in android.hardware.audio.effect.IEffect effect);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamIn.aidl
new file mode 100644
index 0000000..a01f877
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamIn.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamIn {
+  android.hardware.audio.core.IStreamCommon getStreamCommon();
+  android.media.audio.common.MicrophoneDynamicInfo[] getActiveMicrophones();
+  android.hardware.audio.core.IStreamIn.MicrophoneDirection getMicrophoneDirection();
+  void setMicrophoneDirection(android.hardware.audio.core.IStreamIn.MicrophoneDirection direction);
+  float getMicrophoneFieldDimension();
+  void setMicrophoneFieldDimension(float zoom);
+  void updateMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
+  float[] getHwGain();
+  void setHwGain(in float[] channelGains);
+  const int MIC_FIELD_DIMENSION_WIDE_ANGLE = (-1) /* -1 */;
+  const int MIC_FIELD_DIMENSION_NO_ZOOM = 0;
+  const int MIC_FIELD_DIMENSION_MAX_ZOOM = 1;
+  const int HW_GAIN_MIN = 0;
+  const int HW_GAIN_MAX = 1;
+  @Backing(type="int") @VintfStability
+  enum MicrophoneDirection {
+    UNSPECIFIED = 0,
+    FRONT = 1,
+    BACK = 2,
+    EXTERNAL = 3,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOut.aidl
new file mode 100644
index 0000000..ec3078e
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOut.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamOut {
+  android.hardware.audio.core.IStreamCommon getStreamCommon();
+  void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+  void updateOffloadMetadata(in android.hardware.audio.common.AudioOffloadMetadata offloadMetadata);
+  float[] getHwVolume();
+  void setHwVolume(in float[] channelVolumes);
+  float getAudioDescriptionMixLevel();
+  void setAudioDescriptionMixLevel(float leveldB);
+  android.media.audio.common.AudioDualMonoMode getDualMonoMode();
+  void setDualMonoMode(android.media.audio.common.AudioDualMonoMode mode);
+  android.media.audio.common.AudioLatencyMode[] getRecommendedLatencyModes();
+  void setLatencyMode(android.media.audio.common.AudioLatencyMode mode);
+  android.media.audio.common.AudioPlaybackRate getPlaybackRateParameters();
+  void setPlaybackRateParameters(in android.media.audio.common.AudioPlaybackRate playbackRate);
+  void selectPresentation(int presentationId, int programId);
+  const int HW_VOLUME_MIN = 0;
+  const int HW_VOLUME_MAX = 1;
+  const int AUDIO_DESCRIPTION_MIX_LEVEL_MAX = 48;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOutEventCallback.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOutEventCallback.aidl
new file mode 100644
index 0000000..31cf0b7
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/IStreamOutEventCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamOutEventCallback {
+  oneway void onCodecFormatChanged(in byte[] audioMetadata);
+  oneway void onRecommendedLatencyModeChanged(in android.media.audio.common.AudioLatencyMode[] modes);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ITelephony.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ITelephony.aidl
new file mode 100644
index 0000000..84d7aa1
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ITelephony.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface ITelephony {
+  android.media.audio.common.AudioMode[] getSupportedAudioModes();
+  void switchAudioMode(android.media.audio.common.AudioMode mode);
+  android.hardware.audio.core.ITelephony.TelecomConfig setTelecomConfig(in android.hardware.audio.core.ITelephony.TelecomConfig config);
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable TelecomConfig {
+    @nullable android.media.audio.common.Float voiceVolume;
+    android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode ttyMode = android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode.UNSPECIFIED;
+    @nullable android.media.audio.common.Boolean isHacEnabled;
+    const int VOICE_VOLUME_MIN = 0;
+    const int VOICE_VOLUME_MAX = 1;
+    @Backing(type="int") @VintfStability
+    enum TtyMode {
+      UNSPECIFIED = (-1) /* -1 */,
+      OFF = 0,
+      FULL = 1,
+      HCO = 2,
+      VCO = 3,
+    }
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/MmapBufferDescriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/MmapBufferDescriptor.aidl
new file mode 100644
index 0000000..6ea1c69
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/MmapBufferDescriptor.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable MmapBufferDescriptor {
+  android.hardware.common.Ashmem sharedMemory;
+  long burstSizeFrames;
+  int flags;
+  const int FLAG_INDEX_APPLICATION_SHAREABLE = 0;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ModuleDebug.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ModuleDebug.aidl
new file mode 100644
index 0000000..467d37b
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/ModuleDebug.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ModuleDebug {
+  boolean simulateDeviceConnections;
+  int streamTransientStateDelayMs;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/StreamDescriptor.aidl
new file mode 100644
index 0000000..3e3dc38
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/StreamDescriptor.aidl
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable StreamDescriptor {
+  android.hardware.common.fmq.MQDescriptor<android.hardware.audio.core.StreamDescriptor.Command,android.hardware.common.fmq.SynchronizedReadWrite> command;
+  android.hardware.common.fmq.MQDescriptor<android.hardware.audio.core.StreamDescriptor.Reply,android.hardware.common.fmq.SynchronizedReadWrite> reply;
+  int frameSizeBytes;
+  long bufferSizeFrames;
+  android.hardware.audio.core.StreamDescriptor.AudioBuffer audio;
+  const int LATENCY_UNKNOWN = (-1) /* -1 */;
+  @FixedSize @VintfStability
+  parcelable Position {
+    long frames = UNKNOWN /* -1 */;
+    long timeNs = UNKNOWN /* -1 */;
+    const long UNKNOWN = (-1) /* -1 */;
+  }
+  @Backing(type="int") @VintfStability
+  enum State {
+    STANDBY = 1,
+    IDLE = 2,
+    ACTIVE = 3,
+    PAUSED = 4,
+    DRAINING = 5,
+    DRAIN_PAUSED = 6,
+    TRANSFERRING = 7,
+    TRANSFER_PAUSED = 8,
+    ERROR = 100,
+  }
+  @Backing(type="byte") @VintfStability
+  enum DrainMode {
+    DRAIN_UNSPECIFIED = 0,
+    DRAIN_ALL = 1,
+    DRAIN_EARLY_NOTIFY = 2,
+  }
+  @FixedSize @VintfStability
+  union Command {
+    int halReservedExit;
+    android.media.audio.common.Void getStatus;
+    android.media.audio.common.Void start;
+    int burst;
+    android.hardware.audio.core.StreamDescriptor.DrainMode drain;
+    android.media.audio.common.Void standby;
+    android.media.audio.common.Void pause;
+    android.media.audio.common.Void flush;
+  }
+  @FixedSize @VintfStability
+  parcelable Reply {
+    int status;
+    int fmqByteCount;
+    android.hardware.audio.core.StreamDescriptor.Position observable;
+    android.hardware.audio.core.StreamDescriptor.Position hardware;
+    int latencyMs;
+    int xrunFrames;
+    android.hardware.audio.core.StreamDescriptor.State state = android.hardware.audio.core.StreamDescriptor.State.STANDBY;
+  }
+  @VintfStability
+  union AudioBuffer {
+    android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> fmq;
+    android.hardware.audio.core.MmapBufferDescriptor mmap;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/SurroundSoundConfig.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/SurroundSoundConfig.aidl
new file mode 100644
index 0000000..08a1537
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/SurroundSoundConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SurroundSoundConfig {
+  android.hardware.audio.core.SurroundSoundConfig.SurroundFormatFamily[] formatFamilies;
+  @VintfStability
+  parcelable SurroundFormatFamily {
+    android.media.audio.common.AudioFormatDescription primaryFormat;
+    android.media.audio.common.AudioFormatDescription[] subFormats;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/VendorParameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/VendorParameter.aidl
new file mode 100644
index 0000000..bfe33ee
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/1/android/hardware/audio/core/VendorParameter.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VendorParameter {
+  @utf8InCpp String id;
+  ParcelableHolder ext;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioPatch.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioPatch.aidl
new file mode 100644
index 0000000..078b5ea
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioPatch.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioPatch {
+  int id;
+  int[] sourcePortConfigIds;
+  int[] sinkPortConfigIds;
+  int minimumStreamBufferSizeFrames;
+  int[] latenciesMs;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioRoute.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioRoute.aidl
new file mode 100644
index 0000000..deeef87
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/AudioRoute.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioRoute {
+  int[] sourcePortIds;
+  int sinkPortId;
+  boolean isExclusive;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetooth.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetooth.aidl
new file mode 100644
index 0000000..9357a15
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetooth.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IBluetooth {
+  android.hardware.audio.core.IBluetooth.ScoConfig setScoConfig(in android.hardware.audio.core.IBluetooth.ScoConfig config);
+  android.hardware.audio.core.IBluetooth.HfpConfig setHfpConfig(in android.hardware.audio.core.IBluetooth.HfpConfig config);
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable ScoConfig {
+    @nullable android.media.audio.common.Boolean isEnabled;
+    @nullable android.media.audio.common.Boolean isNrecEnabled;
+    android.hardware.audio.core.IBluetooth.ScoConfig.Mode mode = android.hardware.audio.core.IBluetooth.ScoConfig.Mode.UNSPECIFIED;
+    @nullable @utf8InCpp String debugName;
+    @VintfStability
+    enum Mode {
+      UNSPECIFIED,
+      SCO,
+      SCO_WB,
+      SCO_SWB,
+    }
+  }
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable HfpConfig {
+    @nullable android.media.audio.common.Boolean isEnabled;
+    @nullable android.media.audio.common.Int sampleRate;
+    @nullable android.media.audio.common.Float volume;
+    const int VOLUME_MIN = 0;
+    const int VOLUME_MAX = 1;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothA2dp.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothA2dp.aidl
new file mode 100644
index 0000000..0f4c46d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothA2dp.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IBluetoothA2dp {
+  boolean isEnabled();
+  void setEnabled(boolean enabled);
+  boolean supportsOffloadReconfiguration();
+  void reconfigureOffload(in android.hardware.audio.core.VendorParameter[] parameters);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothLe.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothLe.aidl
new file mode 100644
index 0000000..2068daf
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetoothLe.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IBluetoothLe {
+  boolean isEnabled();
+  void setEnabled(boolean enabled);
+  boolean supportsOffloadReconfiguration();
+  void reconfigureOffload(in android.hardware.audio.core.VendorParameter[] parameters);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
new file mode 100644
index 0000000..9ce45bb
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IConfig {
+  android.hardware.audio.core.SurroundSoundConfig getSurroundSoundConfig();
+  android.media.audio.common.AudioHalEngineConfig getEngineConfig();
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
new file mode 100644
index 0000000..e14e9c0
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IModule {
+  void setModuleDebug(in android.hardware.audio.core.ModuleDebug debug);
+  @nullable android.hardware.audio.core.ITelephony getTelephony();
+  @nullable android.hardware.audio.core.IBluetooth getBluetooth();
+  @nullable android.hardware.audio.core.IBluetoothA2dp getBluetoothA2dp();
+  @nullable android.hardware.audio.core.IBluetoothLe getBluetoothLe();
+  android.media.audio.common.AudioPort connectExternalDevice(in android.media.audio.common.AudioPort templateIdAndAdditionalData);
+  void disconnectExternalDevice(int portId);
+  android.hardware.audio.core.AudioPatch[] getAudioPatches();
+  android.media.audio.common.AudioPort getAudioPort(int portId);
+  android.media.audio.common.AudioPortConfig[] getAudioPortConfigs();
+  android.media.audio.common.AudioPort[] getAudioPorts();
+  android.hardware.audio.core.AudioRoute[] getAudioRoutes();
+  android.hardware.audio.core.AudioRoute[] getAudioRoutesForAudioPort(int portId);
+  android.hardware.audio.core.IModule.OpenInputStreamReturn openInputStream(in android.hardware.audio.core.IModule.OpenInputStreamArguments args);
+  android.hardware.audio.core.IModule.OpenOutputStreamReturn openOutputStream(in android.hardware.audio.core.IModule.OpenOutputStreamArguments args);
+  android.hardware.audio.core.IModule.SupportedPlaybackRateFactors getSupportedPlaybackRateFactors();
+  android.hardware.audio.core.AudioPatch setAudioPatch(in android.hardware.audio.core.AudioPatch requested);
+  boolean setAudioPortConfig(in android.media.audio.common.AudioPortConfig requested, out android.media.audio.common.AudioPortConfig suggested);
+  void resetAudioPatch(int patchId);
+  void resetAudioPortConfig(int portConfigId);
+  boolean getMasterMute();
+  void setMasterMute(boolean mute);
+  float getMasterVolume();
+  void setMasterVolume(float volume);
+  boolean getMicMute();
+  void setMicMute(boolean mute);
+  android.media.audio.common.MicrophoneInfo[] getMicrophones();
+  void updateAudioMode(android.media.audio.common.AudioMode mode);
+  void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation);
+  void updateScreenState(boolean isTurnedOn);
+  @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose();
+  int generateHwAvSyncId();
+  android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
+  void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async);
+  void addDeviceEffect(int portConfigId, in android.hardware.audio.effect.IEffect effect);
+  void removeDeviceEffect(int portConfigId, in android.hardware.audio.effect.IEffect effect);
+  android.media.audio.common.AudioMMapPolicyInfo[] getMmapPolicyInfos(android.media.audio.common.AudioMMapPolicyType mmapPolicyType);
+  boolean supportsVariableLatency();
+  int getAAudioMixerBurstCount();
+  int getAAudioHardwareBurstMinUsec();
+  const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2;
+  const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000;
+  @VintfStability
+  parcelable OpenInputStreamArguments {
+    int portConfigId;
+    android.hardware.audio.common.SinkMetadata sinkMetadata;
+    long bufferSizeFrames;
+  }
+  @VintfStability
+  parcelable OpenInputStreamReturn {
+    android.hardware.audio.core.IStreamIn stream;
+    android.hardware.audio.core.StreamDescriptor desc;
+  }
+  @VintfStability
+  parcelable OpenOutputStreamArguments {
+    int portConfigId;
+    android.hardware.audio.common.SourceMetadata sourceMetadata;
+    @nullable android.media.audio.common.AudioOffloadInfo offloadInfo;
+    long bufferSizeFrames;
+    @nullable android.hardware.audio.core.IStreamCallback callback;
+    @nullable android.hardware.audio.core.IStreamOutEventCallback eventCallback;
+  }
+  @VintfStability
+  parcelable OpenOutputStreamReturn {
+    android.hardware.audio.core.IStreamOut stream;
+    android.hardware.audio.core.StreamDescriptor desc;
+  }
+  @VintfStability
+  parcelable SupportedPlaybackRateFactors {
+    float minSpeed;
+    float maxSpeed;
+    float minPitch;
+    float maxPitch;
+  }
+  @Backing(type="int") @VintfStability
+  enum ScreenRotation {
+    DEG_0 = 0,
+    DEG_90 = 1,
+    DEG_180 = 2,
+    DEG_270 = 3,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCallback.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCallback.aidl
new file mode 100644
index 0000000..5a2ab78
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamCallback {
+  oneway void onTransferReady();
+  oneway void onError();
+  oneway void onDrainReady();
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl
new file mode 100644
index 0000000..65a2ee4
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamCommon {
+  void close();
+  void prepareToClose();
+  void updateHwAvSyncId(int hwAvSyncId);
+  android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
+  void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async);
+  void addEffect(in android.hardware.audio.effect.IEffect effect);
+  void removeEffect(in android.hardware.audio.effect.IEffect effect);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl
new file mode 100644
index 0000000..a01f877
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamIn {
+  android.hardware.audio.core.IStreamCommon getStreamCommon();
+  android.media.audio.common.MicrophoneDynamicInfo[] getActiveMicrophones();
+  android.hardware.audio.core.IStreamIn.MicrophoneDirection getMicrophoneDirection();
+  void setMicrophoneDirection(android.hardware.audio.core.IStreamIn.MicrophoneDirection direction);
+  float getMicrophoneFieldDimension();
+  void setMicrophoneFieldDimension(float zoom);
+  void updateMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
+  float[] getHwGain();
+  void setHwGain(in float[] channelGains);
+  const int MIC_FIELD_DIMENSION_WIDE_ANGLE = (-1) /* -1 */;
+  const int MIC_FIELD_DIMENSION_NO_ZOOM = 0;
+  const int MIC_FIELD_DIMENSION_MAX_ZOOM = 1;
+  const int HW_GAIN_MIN = 0;
+  const int HW_GAIN_MAX = 1;
+  @Backing(type="int") @VintfStability
+  enum MicrophoneDirection {
+    UNSPECIFIED = 0,
+    FRONT = 1,
+    BACK = 2,
+    EXTERNAL = 3,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl
new file mode 100644
index 0000000..ec3078e
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamOut {
+  android.hardware.audio.core.IStreamCommon getStreamCommon();
+  void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+  void updateOffloadMetadata(in android.hardware.audio.common.AudioOffloadMetadata offloadMetadata);
+  float[] getHwVolume();
+  void setHwVolume(in float[] channelVolumes);
+  float getAudioDescriptionMixLevel();
+  void setAudioDescriptionMixLevel(float leveldB);
+  android.media.audio.common.AudioDualMonoMode getDualMonoMode();
+  void setDualMonoMode(android.media.audio.common.AudioDualMonoMode mode);
+  android.media.audio.common.AudioLatencyMode[] getRecommendedLatencyModes();
+  void setLatencyMode(android.media.audio.common.AudioLatencyMode mode);
+  android.media.audio.common.AudioPlaybackRate getPlaybackRateParameters();
+  void setPlaybackRateParameters(in android.media.audio.common.AudioPlaybackRate playbackRate);
+  void selectPresentation(int presentationId, int programId);
+  const int HW_VOLUME_MIN = 0;
+  const int HW_VOLUME_MAX = 1;
+  const int AUDIO_DESCRIPTION_MIX_LEVEL_MAX = 48;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOutEventCallback.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOutEventCallback.aidl
new file mode 100644
index 0000000..31cf0b7
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOutEventCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface IStreamOutEventCallback {
+  oneway void onCodecFormatChanged(in byte[] audioMetadata);
+  oneway void onRecommendedLatencyModeChanged(in android.media.audio.common.AudioLatencyMode[] modes);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
new file mode 100644
index 0000000..84d7aa1
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface ITelephony {
+  android.media.audio.common.AudioMode[] getSupportedAudioModes();
+  void switchAudioMode(android.media.audio.common.AudioMode mode);
+  android.hardware.audio.core.ITelephony.TelecomConfig setTelecomConfig(in android.hardware.audio.core.ITelephony.TelecomConfig config);
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  parcelable TelecomConfig {
+    @nullable android.media.audio.common.Float voiceVolume;
+    android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode ttyMode = android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode.UNSPECIFIED;
+    @nullable android.media.audio.common.Boolean isHacEnabled;
+    const int VOICE_VOLUME_MIN = 0;
+    const int VOICE_VOLUME_MAX = 1;
+    @Backing(type="int") @VintfStability
+    enum TtyMode {
+      UNSPECIFIED = (-1) /* -1 */,
+      OFF = 0,
+      FULL = 1,
+      HCO = 2,
+      VCO = 3,
+    }
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MmapBufferDescriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MmapBufferDescriptor.aidl
new file mode 100644
index 0000000..6ea1c69
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MmapBufferDescriptor.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable MmapBufferDescriptor {
+  android.hardware.common.Ashmem sharedMemory;
+  long burstSizeFrames;
+  int flags;
+  const int FLAG_INDEX_APPLICATION_SHAREABLE = 0;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ModuleDebug.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ModuleDebug.aidl
new file mode 100644
index 0000000..467d37b
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ModuleDebug.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ModuleDebug {
+  boolean simulateDeviceConnections;
+  int streamTransientStateDelayMs;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl
new file mode 100644
index 0000000..3e3dc38
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable StreamDescriptor {
+  android.hardware.common.fmq.MQDescriptor<android.hardware.audio.core.StreamDescriptor.Command,android.hardware.common.fmq.SynchronizedReadWrite> command;
+  android.hardware.common.fmq.MQDescriptor<android.hardware.audio.core.StreamDescriptor.Reply,android.hardware.common.fmq.SynchronizedReadWrite> reply;
+  int frameSizeBytes;
+  long bufferSizeFrames;
+  android.hardware.audio.core.StreamDescriptor.AudioBuffer audio;
+  const int LATENCY_UNKNOWN = (-1) /* -1 */;
+  @FixedSize @VintfStability
+  parcelable Position {
+    long frames = UNKNOWN /* -1 */;
+    long timeNs = UNKNOWN /* -1 */;
+    const long UNKNOWN = (-1) /* -1 */;
+  }
+  @Backing(type="int") @VintfStability
+  enum State {
+    STANDBY = 1,
+    IDLE = 2,
+    ACTIVE = 3,
+    PAUSED = 4,
+    DRAINING = 5,
+    DRAIN_PAUSED = 6,
+    TRANSFERRING = 7,
+    TRANSFER_PAUSED = 8,
+    ERROR = 100,
+  }
+  @Backing(type="byte") @VintfStability
+  enum DrainMode {
+    DRAIN_UNSPECIFIED = 0,
+    DRAIN_ALL = 1,
+    DRAIN_EARLY_NOTIFY = 2,
+  }
+  @FixedSize @VintfStability
+  union Command {
+    int halReservedExit;
+    android.media.audio.common.Void getStatus;
+    android.media.audio.common.Void start;
+    int burst;
+    android.hardware.audio.core.StreamDescriptor.DrainMode drain;
+    android.media.audio.common.Void standby;
+    android.media.audio.common.Void pause;
+    android.media.audio.common.Void flush;
+  }
+  @FixedSize @VintfStability
+  parcelable Reply {
+    int status;
+    int fmqByteCount;
+    android.hardware.audio.core.StreamDescriptor.Position observable;
+    android.hardware.audio.core.StreamDescriptor.Position hardware;
+    int latencyMs;
+    int xrunFrames;
+    android.hardware.audio.core.StreamDescriptor.State state = android.hardware.audio.core.StreamDescriptor.State.STANDBY;
+  }
+  @VintfStability
+  union AudioBuffer {
+    android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> fmq;
+    android.hardware.audio.core.MmapBufferDescriptor mmap;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/SurroundSoundConfig.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/SurroundSoundConfig.aidl
new file mode 100644
index 0000000..08a1537
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/SurroundSoundConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SurroundSoundConfig {
+  android.hardware.audio.core.SurroundSoundConfig.SurroundFormatFamily[] formatFamilies;
+  @VintfStability
+  parcelable SurroundFormatFamily {
+    android.media.audio.common.AudioFormatDescription primaryFormat;
+    android.media.audio.common.AudioFormatDescription[] subFormats;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/VendorParameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/VendorParameter.aidl
new file mode 100644
index 0000000..bfe33ee
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/VendorParameter.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VendorParameter {
+  @utf8InCpp String id;
+  ParcelableHolder ext;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash b/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash
new file mode 100644
index 0000000..b71ab29
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/.hash
@@ -0,0 +1 @@
+34b618a587cb9977ee0cd13b173e699d2dcdb320
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AcousticEchoCanceler.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AcousticEchoCanceler.aidl
new file mode 100644
index 0000000..16367c0
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AcousticEchoCanceler.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union AcousticEchoCanceler {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int echoDelayUs;
+  boolean mobileMode;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AcousticEchoCanceler.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV1.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV1.aidl
new file mode 100644
index 0000000..e69e2bd
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV1.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union AutomaticGainControlV1 {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int targetPeakLevelDbFs;
+  int maxCompressionGainDb;
+  boolean enableLimiter;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AutomaticGainControlV1.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV2.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV2.aidl
new file mode 100644
index 0000000..46ffcaf
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/AutomaticGainControlV2.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union AutomaticGainControlV2 {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int fixedDigitalGainMb;
+  android.hardware.audio.effect.AutomaticGainControlV2.LevelEstimator levelEstimator;
+  int saturationMarginMb;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AutomaticGainControlV2.Tag commonTag;
+  }
+  @Backing(type="int") @VintfStability
+  enum LevelEstimator {
+    RMS = 0,
+    PEAK = 1,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/BassBoost.aidl
new file mode 100644
index 0000000..c248ce8
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/BassBoost.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union BassBoost {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int strengthPm;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.BassBoost.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Capability.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Capability.aidl
new file mode 100644
index 0000000..c9df073
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Capability.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Capability {
+  android.hardware.audio.effect.VendorExtension vendorExtension;
+  android.hardware.audio.effect.Range range;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/CommandId.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/CommandId.aidl
new file mode 100644
index 0000000..86b69fa
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/CommandId.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@Backing(type="int") @VintfStability
+enum CommandId {
+  START = 0,
+  STOP = 1,
+  RESET = 2,
+  VENDOR_COMMAND_0 = 0x100,
+  VENDOR_COMMAND_1,
+  VENDOR_COMMAND_2,
+  VENDOR_COMMAND_3,
+  VENDOR_COMMAND_4,
+  VENDOR_COMMAND_5,
+  VENDOR_COMMAND_6,
+  VENDOR_COMMAND_7,
+  VENDOR_COMMAND_8,
+  VENDOR_COMMAND_9,
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DefaultExtension.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DefaultExtension.aidl
new file mode 100644
index 0000000..f1cf389
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DefaultExtension.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable DefaultExtension {
+  byte[] bytes;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl
new file mode 100644
index 0000000..115da1d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Descriptor.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Descriptor {
+  android.hardware.audio.effect.Descriptor.Common common;
+  android.hardware.audio.effect.Capability capability;
+  const String EFFECT_TYPE_UUID_AEC = "7b491460-8d4d-11e0-bd61-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_AGC1 = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_AGC2 = "ae3c653b-be18-4ab8-8938-418f0a7f06ac";
+  const String EFFECT_TYPE_UUID_BASS_BOOST = "0634f220-ddd4-11db-a0fc-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_DOWNMIX = "381e49cc-a858-4aa2-87f6-e8388e7601b2";
+  const String EFFECT_TYPE_UUID_DYNAMICS_PROCESSING = "7261676f-6d75-7369-6364-28e2fd3ac39e";
+  const String EFFECT_TYPE_UUID_ENV_REVERB = "c2e5d5f0-94bd-4763-9cac-4e234d06839e";
+  const String EFFECT_TYPE_UUID_EQUALIZER = "0bed4300-ddd6-11db-8f34-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_HAPTIC_GENERATOR = "1411e6d6-aecd-4021-a1cf-a6aceb0d71e5";
+  const String EFFECT_TYPE_UUID_LOUDNESS_ENHANCER = "fe3199be-aed0-413f-87bb-11260eb63cf1";
+  const String EFFECT_TYPE_UUID_NS = "58b4b260-8e06-11e0-aa8e-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f";
+  const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
+  @VintfStability
+  parcelable Identity {
+    android.media.audio.common.AudioUuid type;
+    android.media.audio.common.AudioUuid uuid;
+    @nullable android.media.audio.common.AudioUuid proxy;
+  }
+  @VintfStability
+  parcelable Common {
+    android.hardware.audio.effect.Descriptor.Identity id;
+    android.hardware.audio.effect.Flags flags;
+    int cpuLoad;
+    int memoryUsage;
+    @utf8InCpp String name;
+    @utf8InCpp String implementor;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Downmix.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Downmix.aidl
new file mode 100644
index 0000000..ce0a7df
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Downmix.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Downmix {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.Downmix.Type type;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Downmix.Tag commonTag;
+  }
+  @VintfStability
+  enum Type {
+    STRIP,
+    FOLD,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DynamicsProcessing.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DynamicsProcessing.aidl
new file mode 100644
index 0000000..04f627d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/DynamicsProcessing.aidl
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union DynamicsProcessing {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.DynamicsProcessing.EngineArchitecture engineArchitecture;
+  android.hardware.audio.effect.DynamicsProcessing.ChannelConfig[] preEq;
+  android.hardware.audio.effect.DynamicsProcessing.ChannelConfig[] postEq;
+  android.hardware.audio.effect.DynamicsProcessing.EqBandConfig[] preEqBand;
+  android.hardware.audio.effect.DynamicsProcessing.EqBandConfig[] postEqBand;
+  android.hardware.audio.effect.DynamicsProcessing.ChannelConfig[] mbc;
+  android.hardware.audio.effect.DynamicsProcessing.MbcBandConfig[] mbcBand;
+  android.hardware.audio.effect.DynamicsProcessing.LimiterConfig[] limiter;
+  android.hardware.audio.effect.DynamicsProcessing.InputGain[] inputGain;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.DynamicsProcessing.Tag commonTag;
+  }
+  enum ResolutionPreference {
+    FAVOR_FREQUENCY_RESOLUTION,
+    FAVOR_TIME_RESOLUTION,
+  }
+  @VintfStability
+  parcelable StageEnablement {
+    boolean inUse;
+    int bandCount;
+  }
+  @VintfStability
+  parcelable EngineArchitecture {
+    android.hardware.audio.effect.DynamicsProcessing.ResolutionPreference resolutionPreference = android.hardware.audio.effect.DynamicsProcessing.ResolutionPreference.FAVOR_FREQUENCY_RESOLUTION;
+    float preferredProcessingDurationMs;
+    android.hardware.audio.effect.DynamicsProcessing.StageEnablement preEqStage;
+    android.hardware.audio.effect.DynamicsProcessing.StageEnablement postEqStage;
+    android.hardware.audio.effect.DynamicsProcessing.StageEnablement mbcStage;
+    boolean limiterInUse;
+  }
+  @VintfStability
+  parcelable ChannelConfig {
+    int channel;
+    boolean enable;
+  }
+  @VintfStability
+  parcelable EqBandConfig {
+    int channel;
+    int band;
+    boolean enable;
+    float cutoffFrequencyHz;
+    float gainDb;
+  }
+  @VintfStability
+  parcelable MbcBandConfig {
+    int channel;
+    int band;
+    boolean enable;
+    float cutoffFrequencyHz;
+    float attackTimeMs;
+    float releaseTimeMs;
+    float ratio;
+    float thresholdDb;
+    float kneeWidthDb;
+    float noiseGateThresholdDb;
+    float expanderRatio;
+    float preGainDb;
+    float postGainDb;
+  }
+  @VintfStability
+  parcelable LimiterConfig {
+    int channel;
+    boolean enable;
+    int linkGroup;
+    float attackTimeMs;
+    float releaseTimeMs;
+    float ratio;
+    float thresholdDb;
+    float postGainDb;
+  }
+  @VintfStability
+  parcelable InputGain {
+    int channel;
+    float gainDb;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/EnvironmentalReverb.aidl
new file mode 100644
index 0000000..00b7d1a
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union EnvironmentalReverb {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int roomLevelMb;
+  int roomHfLevelMb;
+  int decayTimeMs;
+  int decayHfRatioPm;
+  int reflectionsLevelMb;
+  int reflectionsDelayMs;
+  int levelMb;
+  int delayMs;
+  int diffusionPm;
+  int densityPm;
+  boolean bypass;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.EnvironmentalReverb.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Equalizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Equalizer.aidl
new file mode 100644
index 0000000..80f7c7e
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Equalizer.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Equalizer {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.Equalizer.BandLevel[] bandLevels;
+  int preset;
+  int[] centerFreqMh;
+  android.hardware.audio.effect.Equalizer.BandFrequency[] bandFrequencies;
+  android.hardware.audio.effect.Equalizer.Preset[] presets;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Equalizer.Tag commonTag;
+  }
+  @VintfStability
+  parcelable BandLevel {
+    int index;
+    int levelMb;
+  }
+  @VintfStability
+  parcelable BandFrequency {
+    int index;
+    int minMh;
+    int maxMh;
+  }
+  @VintfStability
+  parcelable Preset {
+    int index;
+    @utf8InCpp String name;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Flags.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Flags.aidl
new file mode 100644
index 0000000..bcbf870
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Flags.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Flags {
+  android.hardware.audio.effect.Flags.Type type = android.hardware.audio.effect.Flags.Type.INSERT;
+  android.hardware.audio.effect.Flags.Insert insert = android.hardware.audio.effect.Flags.Insert.ANY;
+  android.hardware.audio.effect.Flags.Volume volume = android.hardware.audio.effect.Flags.Volume.NONE;
+  android.hardware.audio.effect.Flags.HardwareAccelerator hwAcceleratorMode = android.hardware.audio.effect.Flags.HardwareAccelerator.NONE;
+  boolean offloadIndication;
+  boolean deviceIndication;
+  boolean audioModeIndication;
+  boolean audioSourceIndication;
+  boolean bypass;
+  @Backing(type="byte") @VintfStability
+  enum Type {
+    INSERT = 0,
+    AUXILIARY = 1,
+    REPLACE = 2,
+    PRE_PROC = 3,
+    POST_PROC = 4,
+  }
+  @Backing(type="byte") @VintfStability
+  enum Insert {
+    ANY = 0,
+    FIRST = 1,
+    LAST = 2,
+    EXCLUSIVE = 3,
+  }
+  @Backing(type="byte") @VintfStability
+  enum Volume {
+    NONE = 0,
+    CTRL = 1,
+    IND = 2,
+    MONITOR = 3,
+  }
+  @Backing(type="byte") @VintfStability
+  enum HardwareAccelerator {
+    NONE = 0,
+    SIMPLE = 1,
+    TUNNEL = 2,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/HapticGenerator.aidl
new file mode 100644
index 0000000..8addab7
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/HapticGenerator.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union HapticGenerator {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.HapticGenerator.HapticScale[] hapticScales;
+  android.hardware.audio.effect.HapticGenerator.VibratorInformation vibratorInfo;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.HapticGenerator.Tag commonTag;
+  }
+  @Backing(type="int") @VintfStability
+  enum VibratorScale {
+    MUTE = (-100) /* -100 */,
+    VERY_LOW = (-2) /* -2 */,
+    LOW = (-1) /* -1 */,
+    NONE = 0,
+    HIGH = 1,
+    VERY_HIGH = 2,
+  }
+  @VintfStability
+  parcelable HapticScale {
+    int id;
+    android.hardware.audio.effect.HapticGenerator.VibratorScale scale = android.hardware.audio.effect.HapticGenerator.VibratorScale.MUTE;
+  }
+  @VintfStability
+  parcelable VibratorInformation {
+    float resonantFrequencyHz;
+    float qFactor;
+    float maxAmplitude;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IEffect.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IEffect.aidl
new file mode 100644
index 0000000..8c196e7
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IEffect.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+interface IEffect {
+  android.hardware.audio.effect.IEffect.OpenEffectReturn open(in android.hardware.audio.effect.Parameter.Common common, in @nullable android.hardware.audio.effect.Parameter.Specific specific);
+  void close();
+  android.hardware.audio.effect.Descriptor getDescriptor();
+  void command(in android.hardware.audio.effect.CommandId commandId);
+  android.hardware.audio.effect.State getState();
+  void setParameter(in android.hardware.audio.effect.Parameter param);
+  android.hardware.audio.effect.Parameter getParameter(in android.hardware.audio.effect.Parameter.Id paramId);
+  @FixedSize @VintfStability
+  parcelable Status {
+    int status;
+    int fmqConsumed;
+    int fmqProduced;
+  }
+  @VintfStability
+  parcelable OpenEffectReturn {
+    android.hardware.common.fmq.MQDescriptor<android.hardware.audio.effect.IEffect.Status,android.hardware.common.fmq.SynchronizedReadWrite> statusMQ;
+    android.hardware.common.fmq.MQDescriptor<float,android.hardware.common.fmq.SynchronizedReadWrite> inputDataMQ;
+    android.hardware.common.fmq.MQDescriptor<float,android.hardware.common.fmq.SynchronizedReadWrite> outputDataMQ;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IFactory.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IFactory.aidl
new file mode 100644
index 0000000..a6c138c
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/IFactory.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+interface IFactory {
+  android.hardware.audio.effect.Descriptor[] queryEffects(in @nullable android.media.audio.common.AudioUuid type, in @nullable android.media.audio.common.AudioUuid implementation, in @nullable android.media.audio.common.AudioUuid proxy);
+  android.hardware.audio.effect.Processing[] queryProcessing(in @nullable android.hardware.audio.effect.Processing.Type type);
+  android.hardware.audio.effect.IEffect createEffect(in android.media.audio.common.AudioUuid implUuid);
+  void destroyEffect(in android.hardware.audio.effect.IEffect handle);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/LoudnessEnhancer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/LoudnessEnhancer.aidl
new file mode 100644
index 0000000..fc276d6
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/LoudnessEnhancer.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union LoudnessEnhancer {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int gainMb;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.LoudnessEnhancer.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/NoiseSuppression.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/NoiseSuppression.aidl
new file mode 100644
index 0000000..7f30fe2
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/NoiseSuppression.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union NoiseSuppression {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.NoiseSuppression.Level level;
+  android.hardware.audio.effect.NoiseSuppression.Type type;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.NoiseSuppression.Tag commonTag;
+  }
+  @Backing(type="int") @VintfStability
+  enum Level {
+    LOW,
+    MEDIUM,
+    HIGH,
+    VERY_HIGH,
+  }
+  @Backing(type="int") @VintfStability
+  enum Type {
+    SINGLE_CHANNEL,
+    MULTI_CHANNEL,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Parameter.aidl
new file mode 100644
index 0000000..0422bd9
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Parameter.aidl
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Parameter {
+  android.hardware.audio.effect.Parameter.Common common;
+  android.media.audio.common.AudioDeviceDescription[] deviceDescription;
+  android.media.audio.common.AudioMode mode;
+  android.media.audio.common.AudioSource source;
+  boolean offload;
+  android.hardware.audio.effect.Parameter.VolumeStereo volumeStereo;
+  android.hardware.audio.effect.Parameter.Specific specific;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorEffectTag;
+    android.hardware.audio.effect.AcousticEchoCanceler.Id acousticEchoCancelerTag;
+    android.hardware.audio.effect.AutomaticGainControlV1.Id automaticGainControlV1Tag;
+    android.hardware.audio.effect.AutomaticGainControlV2.Id automaticGainControlV2Tag;
+    android.hardware.audio.effect.BassBoost.Id bassBoostTag;
+    android.hardware.audio.effect.Downmix.Id downmixTag;
+    android.hardware.audio.effect.DynamicsProcessing.Id dynamicsProcessingTag;
+    android.hardware.audio.effect.EnvironmentalReverb.Id environmentalReverbTag;
+    android.hardware.audio.effect.Equalizer.Id equalizerTag;
+    android.hardware.audio.effect.HapticGenerator.Id hapticGeneratorTag;
+    android.hardware.audio.effect.LoudnessEnhancer.Id loudnessEnhancerTag;
+    android.hardware.audio.effect.NoiseSuppression.Id noiseSuppressionTag;
+    android.hardware.audio.effect.PresetReverb.Id presetReverbTag;
+    android.hardware.audio.effect.Virtualizer.Id virtualizerTag;
+    android.hardware.audio.effect.Visualizer.Id visualizerTag;
+    android.hardware.audio.effect.Volume.Id volumeTag;
+    android.hardware.audio.effect.Parameter.Tag commonTag;
+  }
+  @VintfStability
+  parcelable Common {
+    int session;
+    int ioHandle;
+    android.media.audio.common.AudioConfig input;
+    android.media.audio.common.AudioConfig output;
+  }
+  @VintfStability
+  parcelable VolumeStereo {
+    float left;
+    float right;
+  }
+  @VintfStability
+  union Specific {
+    android.hardware.audio.effect.VendorExtension vendorEffect;
+    android.hardware.audio.effect.AcousticEchoCanceler acousticEchoCanceler;
+    android.hardware.audio.effect.AutomaticGainControlV1 automaticGainControlV1;
+    android.hardware.audio.effect.AutomaticGainControlV2 automaticGainControlV2;
+    android.hardware.audio.effect.BassBoost bassBoost;
+    android.hardware.audio.effect.Downmix downmix;
+    android.hardware.audio.effect.DynamicsProcessing dynamicsProcessing;
+    android.hardware.audio.effect.EnvironmentalReverb environmentalReverb;
+    android.hardware.audio.effect.Equalizer equalizer;
+    android.hardware.audio.effect.HapticGenerator hapticGenerator;
+    android.hardware.audio.effect.LoudnessEnhancer loudnessEnhancer;
+    android.hardware.audio.effect.NoiseSuppression noiseSuppression;
+    android.hardware.audio.effect.PresetReverb presetReverb;
+    android.hardware.audio.effect.Virtualizer virtualizer;
+    android.hardware.audio.effect.Visualizer visualizer;
+    android.hardware.audio.effect.Volume volume;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/PresetReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/PresetReverb.aidl
new file mode 100644
index 0000000..26d96b5
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/PresetReverb.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union PresetReverb {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.PresetReverb.Presets[] supportedPresets;
+  android.hardware.audio.effect.PresetReverb.Presets preset;
+  @Backing(type="int") @VintfStability
+  enum Presets {
+    NONE,
+    SMALLROOM,
+    MEDIUMROOM,
+    LARGEROOM,
+    MEDIUMHALL,
+    LARGEHALL,
+    PLATE,
+  }
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.PresetReverb.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Processing.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Processing.aidl
new file mode 100644
index 0000000..f6d6ee2
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Processing.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Processing {
+  android.hardware.audio.effect.Processing.Type type;
+  android.hardware.audio.effect.Descriptor[] ids;
+  @VintfStability
+  union Type {
+    android.media.audio.common.AudioStreamType streamType = android.media.audio.common.AudioStreamType.INVALID;
+    android.media.audio.common.AudioSource source;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Range.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Range.aidl
new file mode 100644
index 0000000..93edc5e
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Range.aidl
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Range {
+  android.hardware.audio.effect.Range.VendorExtensionRange[] vendorExtension = {};
+  android.hardware.audio.effect.Range.AcousticEchoCancelerRange[] acousticEchoCanceler;
+  android.hardware.audio.effect.Range.AutomaticGainControlV1Range[] automaticGainControlV1;
+  android.hardware.audio.effect.Range.AutomaticGainControlV2Range[] automaticGainControlV2;
+  android.hardware.audio.effect.Range.BassBoostRange[] bassBoost;
+  android.hardware.audio.effect.Range.DownmixRange[] downmix;
+  android.hardware.audio.effect.Range.DynamicsProcessingRange[] dynamicsProcessing;
+  android.hardware.audio.effect.Range.EnvironmentalReverbRange[] environmentalReverb;
+  android.hardware.audio.effect.Range.EqualizerRange[] equalizer;
+  android.hardware.audio.effect.Range.HapticGeneratorRange[] hapticGenerator;
+  android.hardware.audio.effect.Range.LoudnessEnhancerRange[] loudnessEnhancer;
+  android.hardware.audio.effect.Range.NoiseSuppressionRange[] noiseSuppression;
+  android.hardware.audio.effect.Range.PresetReverbRange[] presetReverb;
+  android.hardware.audio.effect.Range.VirtualizerRange[] virtualizer;
+  android.hardware.audio.effect.Range.VisualizerRange[] visualizer;
+  android.hardware.audio.effect.Range.VolumeRange[] volume;
+  @VintfStability
+  parcelable AcousticEchoCancelerRange {
+    android.hardware.audio.effect.AcousticEchoCanceler min;
+    android.hardware.audio.effect.AcousticEchoCanceler max;
+  }
+  @VintfStability
+  parcelable AutomaticGainControlV1Range {
+    android.hardware.audio.effect.AutomaticGainControlV1 min;
+    android.hardware.audio.effect.AutomaticGainControlV1 max;
+  }
+  @VintfStability
+  parcelable AutomaticGainControlV2Range {
+    android.hardware.audio.effect.AutomaticGainControlV2 min;
+    android.hardware.audio.effect.AutomaticGainControlV2 max;
+  }
+  @VintfStability
+  parcelable BassBoostRange {
+    android.hardware.audio.effect.BassBoost min;
+    android.hardware.audio.effect.BassBoost max;
+  }
+  @VintfStability
+  parcelable DownmixRange {
+    android.hardware.audio.effect.Downmix min;
+    android.hardware.audio.effect.Downmix max;
+  }
+  @VintfStability
+  parcelable DynamicsProcessingRange {
+    android.hardware.audio.effect.DynamicsProcessing min;
+    android.hardware.audio.effect.DynamicsProcessing max;
+  }
+  @VintfStability
+  parcelable EnvironmentalReverbRange {
+    android.hardware.audio.effect.EnvironmentalReverb min;
+    android.hardware.audio.effect.EnvironmentalReverb max;
+  }
+  @VintfStability
+  parcelable EqualizerRange {
+    android.hardware.audio.effect.Equalizer min;
+    android.hardware.audio.effect.Equalizer max;
+  }
+  @VintfStability
+  parcelable HapticGeneratorRange {
+    android.hardware.audio.effect.HapticGenerator min;
+    android.hardware.audio.effect.HapticGenerator max;
+  }
+  @VintfStability
+  parcelable LoudnessEnhancerRange {
+    android.hardware.audio.effect.LoudnessEnhancer min;
+    android.hardware.audio.effect.LoudnessEnhancer max;
+  }
+  @VintfStability
+  parcelable NoiseSuppressionRange {
+    android.hardware.audio.effect.NoiseSuppression min;
+    android.hardware.audio.effect.NoiseSuppression max;
+  }
+  @VintfStability
+  parcelable PresetReverbRange {
+    android.hardware.audio.effect.PresetReverb min;
+    android.hardware.audio.effect.PresetReverb max;
+  }
+  @VintfStability
+  parcelable VendorExtensionRange {
+    android.hardware.audio.effect.VendorExtension min;
+    android.hardware.audio.effect.VendorExtension max;
+  }
+  @VintfStability
+  parcelable VirtualizerRange {
+    android.hardware.audio.effect.Virtualizer min;
+    android.hardware.audio.effect.Virtualizer max;
+  }
+  @VintfStability
+  parcelable VisualizerRange {
+    android.hardware.audio.effect.Visualizer min;
+    android.hardware.audio.effect.Visualizer max;
+  }
+  @VintfStability
+  parcelable VolumeRange {
+    android.hardware.audio.effect.Volume min;
+    android.hardware.audio.effect.Volume max;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/State.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/State.aidl
new file mode 100644
index 0000000..17f9814
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/State.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@Backing(type="byte") @VintfStability
+enum State {
+  INIT,
+  IDLE,
+  PROCESSING,
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/VendorExtension.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/VendorExtension.aidl
new file mode 100644
index 0000000..b806334
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/VendorExtension.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable VendorExtension {
+  ParcelableHolder extension;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Virtualizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Virtualizer.aidl
new file mode 100644
index 0000000..6092b14
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Virtualizer.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Virtualizer {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int strengthPm;
+  android.hardware.audio.effect.Virtualizer.ChannelAngle[] speakerAngles;
+  android.media.audio.common.AudioDeviceDescription device;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Virtualizer.Tag commonTag;
+    android.hardware.audio.effect.Virtualizer.SpeakerAnglesPayload speakerAnglesPayload;
+  }
+  @VintfStability
+  parcelable SpeakerAnglesPayload {
+    android.media.audio.common.AudioChannelLayout layout;
+    android.media.audio.common.AudioDeviceDescription device;
+  }
+  @VintfStability
+  parcelable ChannelAngle {
+    int channel;
+    int azimuthDegree;
+    int elevationDegree;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Visualizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Visualizer.aidl
new file mode 100644
index 0000000..7d319da
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Visualizer.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Visualizer {
+  android.hardware.audio.effect.Visualizer.Id id;
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.Visualizer.Measurement measurement;
+  byte[] captureSampleBuffer;
+  int latencyMs;
+  int captureSamples;
+  android.hardware.audio.effect.Visualizer.ScalingMode scalingMode;
+  android.hardware.audio.effect.Visualizer.MeasurementMode measurementMode;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Visualizer.Tag commonTag;
+  }
+  @VintfStability
+  enum ScalingMode {
+    NORMALIZED = 0,
+    AS_PLAYED,
+  }
+  @VintfStability
+  enum MeasurementMode {
+    NONE = 0,
+    PEAK_RMS,
+  }
+  @VintfStability
+  parcelable Measurement {
+    int rms;
+    int peak;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Volume.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Volume.aidl
new file mode 100644
index 0000000..8227118
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/1/android/hardware/audio/effect/Volume.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Volume {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int levelDb;
+  boolean mute;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Volume.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl
new file mode 100644
index 0000000..16367c0
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union AcousticEchoCanceler {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int echoDelayUs;
+  boolean mobileMode;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AcousticEchoCanceler.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl
new file mode 100644
index 0000000..e69e2bd
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union AutomaticGainControlV1 {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int targetPeakLevelDbFs;
+  int maxCompressionGainDb;
+  boolean enableLimiter;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AutomaticGainControlV1.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV2.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV2.aidl
new file mode 100644
index 0000000..46ffcaf
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV2.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union AutomaticGainControlV2 {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int fixedDigitalGainMb;
+  android.hardware.audio.effect.AutomaticGainControlV2.LevelEstimator levelEstimator;
+  int saturationMarginMb;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.AutomaticGainControlV2.Tag commonTag;
+  }
+  @Backing(type="int") @VintfStability
+  enum LevelEstimator {
+    RMS = 0,
+    PEAK = 1,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl
new file mode 100644
index 0000000..c248ce8
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union BassBoost {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int strengthPm;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.BassBoost.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl
new file mode 100644
index 0000000..c9df073
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Capability {
+  android.hardware.audio.effect.VendorExtension vendorExtension;
+  android.hardware.audio.effect.Range range;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/CommandId.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/CommandId.aidl
new file mode 100644
index 0000000..86b69fa
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/CommandId.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@Backing(type="int") @VintfStability
+enum CommandId {
+  START = 0,
+  STOP = 1,
+  RESET = 2,
+  VENDOR_COMMAND_0 = 0x100,
+  VENDOR_COMMAND_1,
+  VENDOR_COMMAND_2,
+  VENDOR_COMMAND_3,
+  VENDOR_COMMAND_4,
+  VENDOR_COMMAND_5,
+  VENDOR_COMMAND_6,
+  VENDOR_COMMAND_7,
+  VENDOR_COMMAND_8,
+  VENDOR_COMMAND_9,
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DefaultExtension.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DefaultExtension.aidl
new file mode 100644
index 0000000..f1cf389
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DefaultExtension.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable DefaultExtension {
+  byte[] bytes;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
new file mode 100644
index 0000000..115da1d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Descriptor {
+  android.hardware.audio.effect.Descriptor.Common common;
+  android.hardware.audio.effect.Capability capability;
+  const String EFFECT_TYPE_UUID_AEC = "7b491460-8d4d-11e0-bd61-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_AGC1 = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_AGC2 = "ae3c653b-be18-4ab8-8938-418f0a7f06ac";
+  const String EFFECT_TYPE_UUID_BASS_BOOST = "0634f220-ddd4-11db-a0fc-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_DOWNMIX = "381e49cc-a858-4aa2-87f6-e8388e7601b2";
+  const String EFFECT_TYPE_UUID_DYNAMICS_PROCESSING = "7261676f-6d75-7369-6364-28e2fd3ac39e";
+  const String EFFECT_TYPE_UUID_ENV_REVERB = "c2e5d5f0-94bd-4763-9cac-4e234d06839e";
+  const String EFFECT_TYPE_UUID_EQUALIZER = "0bed4300-ddd6-11db-8f34-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_HAPTIC_GENERATOR = "1411e6d6-aecd-4021-a1cf-a6aceb0d71e5";
+  const String EFFECT_TYPE_UUID_LOUDNESS_ENHANCER = "fe3199be-aed0-413f-87bb-11260eb63cf1";
+  const String EFFECT_TYPE_UUID_NS = "58b4b260-8e06-11e0-aa8e-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f";
+  const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
+  const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
+  @VintfStability
+  parcelable Identity {
+    android.media.audio.common.AudioUuid type;
+    android.media.audio.common.AudioUuid uuid;
+    @nullable android.media.audio.common.AudioUuid proxy;
+  }
+  @VintfStability
+  parcelable Common {
+    android.hardware.audio.effect.Descriptor.Identity id;
+    android.hardware.audio.effect.Flags flags;
+    int cpuLoad;
+    int memoryUsage;
+    @utf8InCpp String name;
+    @utf8InCpp String implementor;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl
new file mode 100644
index 0000000..ce0a7df
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Downmix {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.Downmix.Type type;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Downmix.Tag commonTag;
+  }
+  @VintfStability
+  enum Type {
+    STRIP,
+    FOLD,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl
new file mode 100644
index 0000000..04f627d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union DynamicsProcessing {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.DynamicsProcessing.EngineArchitecture engineArchitecture;
+  android.hardware.audio.effect.DynamicsProcessing.ChannelConfig[] preEq;
+  android.hardware.audio.effect.DynamicsProcessing.ChannelConfig[] postEq;
+  android.hardware.audio.effect.DynamicsProcessing.EqBandConfig[] preEqBand;
+  android.hardware.audio.effect.DynamicsProcessing.EqBandConfig[] postEqBand;
+  android.hardware.audio.effect.DynamicsProcessing.ChannelConfig[] mbc;
+  android.hardware.audio.effect.DynamicsProcessing.MbcBandConfig[] mbcBand;
+  android.hardware.audio.effect.DynamicsProcessing.LimiterConfig[] limiter;
+  android.hardware.audio.effect.DynamicsProcessing.InputGain[] inputGain;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.DynamicsProcessing.Tag commonTag;
+  }
+  enum ResolutionPreference {
+    FAVOR_FREQUENCY_RESOLUTION,
+    FAVOR_TIME_RESOLUTION,
+  }
+  @VintfStability
+  parcelable StageEnablement {
+    boolean inUse;
+    int bandCount;
+  }
+  @VintfStability
+  parcelable EngineArchitecture {
+    android.hardware.audio.effect.DynamicsProcessing.ResolutionPreference resolutionPreference = android.hardware.audio.effect.DynamicsProcessing.ResolutionPreference.FAVOR_FREQUENCY_RESOLUTION;
+    float preferredProcessingDurationMs;
+    android.hardware.audio.effect.DynamicsProcessing.StageEnablement preEqStage;
+    android.hardware.audio.effect.DynamicsProcessing.StageEnablement postEqStage;
+    android.hardware.audio.effect.DynamicsProcessing.StageEnablement mbcStage;
+    boolean limiterInUse;
+  }
+  @VintfStability
+  parcelable ChannelConfig {
+    int channel;
+    boolean enable;
+  }
+  @VintfStability
+  parcelable EqBandConfig {
+    int channel;
+    int band;
+    boolean enable;
+    float cutoffFrequencyHz;
+    float gainDb;
+  }
+  @VintfStability
+  parcelable MbcBandConfig {
+    int channel;
+    int band;
+    boolean enable;
+    float cutoffFrequencyHz;
+    float attackTimeMs;
+    float releaseTimeMs;
+    float ratio;
+    float thresholdDb;
+    float kneeWidthDb;
+    float noiseGateThresholdDb;
+    float expanderRatio;
+    float preGainDb;
+    float postGainDb;
+  }
+  @VintfStability
+  parcelable LimiterConfig {
+    int channel;
+    boolean enable;
+    int linkGroup;
+    float attackTimeMs;
+    float releaseTimeMs;
+    float ratio;
+    float thresholdDb;
+    float postGainDb;
+  }
+  @VintfStability
+  parcelable InputGain {
+    int channel;
+    float gainDb;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
new file mode 100644
index 0000000..00b7d1a
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union EnvironmentalReverb {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int roomLevelMb;
+  int roomHfLevelMb;
+  int decayTimeMs;
+  int decayHfRatioPm;
+  int reflectionsLevelMb;
+  int reflectionsDelayMs;
+  int levelMb;
+  int delayMs;
+  int diffusionPm;
+  int densityPm;
+  boolean bypass;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.EnvironmentalReverb.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl
new file mode 100644
index 0000000..80f7c7e
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Equalizer {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.Equalizer.BandLevel[] bandLevels;
+  int preset;
+  int[] centerFreqMh;
+  android.hardware.audio.effect.Equalizer.BandFrequency[] bandFrequencies;
+  android.hardware.audio.effect.Equalizer.Preset[] presets;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Equalizer.Tag commonTag;
+  }
+  @VintfStability
+  parcelable BandLevel {
+    int index;
+    int levelMb;
+  }
+  @VintfStability
+  parcelable BandFrequency {
+    int index;
+    int minMh;
+    int maxMh;
+  }
+  @VintfStability
+  parcelable Preset {
+    int index;
+    @utf8InCpp String name;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
new file mode 100644
index 0000000..bcbf870
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Flags {
+  android.hardware.audio.effect.Flags.Type type = android.hardware.audio.effect.Flags.Type.INSERT;
+  android.hardware.audio.effect.Flags.Insert insert = android.hardware.audio.effect.Flags.Insert.ANY;
+  android.hardware.audio.effect.Flags.Volume volume = android.hardware.audio.effect.Flags.Volume.NONE;
+  android.hardware.audio.effect.Flags.HardwareAccelerator hwAcceleratorMode = android.hardware.audio.effect.Flags.HardwareAccelerator.NONE;
+  boolean offloadIndication;
+  boolean deviceIndication;
+  boolean audioModeIndication;
+  boolean audioSourceIndication;
+  boolean bypass;
+  @Backing(type="byte") @VintfStability
+  enum Type {
+    INSERT = 0,
+    AUXILIARY = 1,
+    REPLACE = 2,
+    PRE_PROC = 3,
+    POST_PROC = 4,
+  }
+  @Backing(type="byte") @VintfStability
+  enum Insert {
+    ANY = 0,
+    FIRST = 1,
+    LAST = 2,
+    EXCLUSIVE = 3,
+  }
+  @Backing(type="byte") @VintfStability
+  enum Volume {
+    NONE = 0,
+    CTRL = 1,
+    IND = 2,
+    MONITOR = 3,
+  }
+  @Backing(type="byte") @VintfStability
+  enum HardwareAccelerator {
+    NONE = 0,
+    SIMPLE = 1,
+    TUNNEL = 2,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
new file mode 100644
index 0000000..8addab7
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union HapticGenerator {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.HapticGenerator.HapticScale[] hapticScales;
+  android.hardware.audio.effect.HapticGenerator.VibratorInformation vibratorInfo;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.HapticGenerator.Tag commonTag;
+  }
+  @Backing(type="int") @VintfStability
+  enum VibratorScale {
+    MUTE = (-100) /* -100 */,
+    VERY_LOW = (-2) /* -2 */,
+    LOW = (-1) /* -1 */,
+    NONE = 0,
+    HIGH = 1,
+    VERY_HIGH = 2,
+  }
+  @VintfStability
+  parcelable HapticScale {
+    int id;
+    android.hardware.audio.effect.HapticGenerator.VibratorScale scale = android.hardware.audio.effect.HapticGenerator.VibratorScale.MUTE;
+  }
+  @VintfStability
+  parcelable VibratorInformation {
+    float resonantFrequencyHz;
+    float qFactor;
+    float maxAmplitude;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl
new file mode 100644
index 0000000..8c196e7
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IEffect.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+interface IEffect {
+  android.hardware.audio.effect.IEffect.OpenEffectReturn open(in android.hardware.audio.effect.Parameter.Common common, in @nullable android.hardware.audio.effect.Parameter.Specific specific);
+  void close();
+  android.hardware.audio.effect.Descriptor getDescriptor();
+  void command(in android.hardware.audio.effect.CommandId commandId);
+  android.hardware.audio.effect.State getState();
+  void setParameter(in android.hardware.audio.effect.Parameter param);
+  android.hardware.audio.effect.Parameter getParameter(in android.hardware.audio.effect.Parameter.Id paramId);
+  @FixedSize @VintfStability
+  parcelable Status {
+    int status;
+    int fmqConsumed;
+    int fmqProduced;
+  }
+  @VintfStability
+  parcelable OpenEffectReturn {
+    android.hardware.common.fmq.MQDescriptor<android.hardware.audio.effect.IEffect.Status,android.hardware.common.fmq.SynchronizedReadWrite> statusMQ;
+    android.hardware.common.fmq.MQDescriptor<float,android.hardware.common.fmq.SynchronizedReadWrite> inputDataMQ;
+    android.hardware.common.fmq.MQDescriptor<float,android.hardware.common.fmq.SynchronizedReadWrite> outputDataMQ;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IFactory.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IFactory.aidl
new file mode 100644
index 0000000..a6c138c
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/IFactory.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+interface IFactory {
+  android.hardware.audio.effect.Descriptor[] queryEffects(in @nullable android.media.audio.common.AudioUuid type, in @nullable android.media.audio.common.AudioUuid implementation, in @nullable android.media.audio.common.AudioUuid proxy);
+  android.hardware.audio.effect.Processing[] queryProcessing(in @nullable android.hardware.audio.effect.Processing.Type type);
+  android.hardware.audio.effect.IEffect createEffect(in android.media.audio.common.AudioUuid implUuid);
+  void destroyEffect(in android.hardware.audio.effect.IEffect handle);
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl
new file mode 100644
index 0000000..fc276d6
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union LoudnessEnhancer {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int gainMb;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.LoudnessEnhancer.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl
new file mode 100644
index 0000000..7f30fe2
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union NoiseSuppression {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.NoiseSuppression.Level level;
+  android.hardware.audio.effect.NoiseSuppression.Type type;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.NoiseSuppression.Tag commonTag;
+  }
+  @Backing(type="int") @VintfStability
+  enum Level {
+    LOW,
+    MEDIUM,
+    HIGH,
+    VERY_HIGH,
+  }
+  @Backing(type="int") @VintfStability
+  enum Type {
+    SINGLE_CHANNEL,
+    MULTI_CHANNEL,
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
new file mode 100644
index 0000000..0422bd9
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Parameter {
+  android.hardware.audio.effect.Parameter.Common common;
+  android.media.audio.common.AudioDeviceDescription[] deviceDescription;
+  android.media.audio.common.AudioMode mode;
+  android.media.audio.common.AudioSource source;
+  boolean offload;
+  android.hardware.audio.effect.Parameter.VolumeStereo volumeStereo;
+  android.hardware.audio.effect.Parameter.Specific specific;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorEffectTag;
+    android.hardware.audio.effect.AcousticEchoCanceler.Id acousticEchoCancelerTag;
+    android.hardware.audio.effect.AutomaticGainControlV1.Id automaticGainControlV1Tag;
+    android.hardware.audio.effect.AutomaticGainControlV2.Id automaticGainControlV2Tag;
+    android.hardware.audio.effect.BassBoost.Id bassBoostTag;
+    android.hardware.audio.effect.Downmix.Id downmixTag;
+    android.hardware.audio.effect.DynamicsProcessing.Id dynamicsProcessingTag;
+    android.hardware.audio.effect.EnvironmentalReverb.Id environmentalReverbTag;
+    android.hardware.audio.effect.Equalizer.Id equalizerTag;
+    android.hardware.audio.effect.HapticGenerator.Id hapticGeneratorTag;
+    android.hardware.audio.effect.LoudnessEnhancer.Id loudnessEnhancerTag;
+    android.hardware.audio.effect.NoiseSuppression.Id noiseSuppressionTag;
+    android.hardware.audio.effect.PresetReverb.Id presetReverbTag;
+    android.hardware.audio.effect.Virtualizer.Id virtualizerTag;
+    android.hardware.audio.effect.Visualizer.Id visualizerTag;
+    android.hardware.audio.effect.Volume.Id volumeTag;
+    android.hardware.audio.effect.Parameter.Tag commonTag;
+  }
+  @VintfStability
+  parcelable Common {
+    int session;
+    int ioHandle;
+    android.media.audio.common.AudioConfig input;
+    android.media.audio.common.AudioConfig output;
+  }
+  @VintfStability
+  parcelable VolumeStereo {
+    float left;
+    float right;
+  }
+  @VintfStability
+  union Specific {
+    android.hardware.audio.effect.VendorExtension vendorEffect;
+    android.hardware.audio.effect.AcousticEchoCanceler acousticEchoCanceler;
+    android.hardware.audio.effect.AutomaticGainControlV1 automaticGainControlV1;
+    android.hardware.audio.effect.AutomaticGainControlV2 automaticGainControlV2;
+    android.hardware.audio.effect.BassBoost bassBoost;
+    android.hardware.audio.effect.Downmix downmix;
+    android.hardware.audio.effect.DynamicsProcessing dynamicsProcessing;
+    android.hardware.audio.effect.EnvironmentalReverb environmentalReverb;
+    android.hardware.audio.effect.Equalizer equalizer;
+    android.hardware.audio.effect.HapticGenerator hapticGenerator;
+    android.hardware.audio.effect.LoudnessEnhancer loudnessEnhancer;
+    android.hardware.audio.effect.NoiseSuppression noiseSuppression;
+    android.hardware.audio.effect.PresetReverb presetReverb;
+    android.hardware.audio.effect.Virtualizer virtualizer;
+    android.hardware.audio.effect.Visualizer visualizer;
+    android.hardware.audio.effect.Volume volume;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl
new file mode 100644
index 0000000..26d96b5
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union PresetReverb {
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.PresetReverb.Presets[] supportedPresets;
+  android.hardware.audio.effect.PresetReverb.Presets preset;
+  @Backing(type="int") @VintfStability
+  enum Presets {
+    NONE,
+    SMALLROOM,
+    MEDIUMROOM,
+    LARGEROOM,
+    MEDIUMHALL,
+    LARGEHALL,
+    PLATE,
+  }
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.PresetReverb.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl
new file mode 100644
index 0000000..f6d6ee2
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Processing.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable Processing {
+  android.hardware.audio.effect.Processing.Type type;
+  android.hardware.audio.effect.Descriptor[] ids;
+  @VintfStability
+  union Type {
+    android.media.audio.common.AudioStreamType streamType = android.media.audio.common.AudioStreamType.INVALID;
+    android.media.audio.common.AudioSource source;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
new file mode 100644
index 0000000..93edc5e
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Range {
+  android.hardware.audio.effect.Range.VendorExtensionRange[] vendorExtension = {};
+  android.hardware.audio.effect.Range.AcousticEchoCancelerRange[] acousticEchoCanceler;
+  android.hardware.audio.effect.Range.AutomaticGainControlV1Range[] automaticGainControlV1;
+  android.hardware.audio.effect.Range.AutomaticGainControlV2Range[] automaticGainControlV2;
+  android.hardware.audio.effect.Range.BassBoostRange[] bassBoost;
+  android.hardware.audio.effect.Range.DownmixRange[] downmix;
+  android.hardware.audio.effect.Range.DynamicsProcessingRange[] dynamicsProcessing;
+  android.hardware.audio.effect.Range.EnvironmentalReverbRange[] environmentalReverb;
+  android.hardware.audio.effect.Range.EqualizerRange[] equalizer;
+  android.hardware.audio.effect.Range.HapticGeneratorRange[] hapticGenerator;
+  android.hardware.audio.effect.Range.LoudnessEnhancerRange[] loudnessEnhancer;
+  android.hardware.audio.effect.Range.NoiseSuppressionRange[] noiseSuppression;
+  android.hardware.audio.effect.Range.PresetReverbRange[] presetReverb;
+  android.hardware.audio.effect.Range.VirtualizerRange[] virtualizer;
+  android.hardware.audio.effect.Range.VisualizerRange[] visualizer;
+  android.hardware.audio.effect.Range.VolumeRange[] volume;
+  @VintfStability
+  parcelable AcousticEchoCancelerRange {
+    android.hardware.audio.effect.AcousticEchoCanceler min;
+    android.hardware.audio.effect.AcousticEchoCanceler max;
+  }
+  @VintfStability
+  parcelable AutomaticGainControlV1Range {
+    android.hardware.audio.effect.AutomaticGainControlV1 min;
+    android.hardware.audio.effect.AutomaticGainControlV1 max;
+  }
+  @VintfStability
+  parcelable AutomaticGainControlV2Range {
+    android.hardware.audio.effect.AutomaticGainControlV2 min;
+    android.hardware.audio.effect.AutomaticGainControlV2 max;
+  }
+  @VintfStability
+  parcelable BassBoostRange {
+    android.hardware.audio.effect.BassBoost min;
+    android.hardware.audio.effect.BassBoost max;
+  }
+  @VintfStability
+  parcelable DownmixRange {
+    android.hardware.audio.effect.Downmix min;
+    android.hardware.audio.effect.Downmix max;
+  }
+  @VintfStability
+  parcelable DynamicsProcessingRange {
+    android.hardware.audio.effect.DynamicsProcessing min;
+    android.hardware.audio.effect.DynamicsProcessing max;
+  }
+  @VintfStability
+  parcelable EnvironmentalReverbRange {
+    android.hardware.audio.effect.EnvironmentalReverb min;
+    android.hardware.audio.effect.EnvironmentalReverb max;
+  }
+  @VintfStability
+  parcelable EqualizerRange {
+    android.hardware.audio.effect.Equalizer min;
+    android.hardware.audio.effect.Equalizer max;
+  }
+  @VintfStability
+  parcelable HapticGeneratorRange {
+    android.hardware.audio.effect.HapticGenerator min;
+    android.hardware.audio.effect.HapticGenerator max;
+  }
+  @VintfStability
+  parcelable LoudnessEnhancerRange {
+    android.hardware.audio.effect.LoudnessEnhancer min;
+    android.hardware.audio.effect.LoudnessEnhancer max;
+  }
+  @VintfStability
+  parcelable NoiseSuppressionRange {
+    android.hardware.audio.effect.NoiseSuppression min;
+    android.hardware.audio.effect.NoiseSuppression max;
+  }
+  @VintfStability
+  parcelable PresetReverbRange {
+    android.hardware.audio.effect.PresetReverb min;
+    android.hardware.audio.effect.PresetReverb max;
+  }
+  @VintfStability
+  parcelable VendorExtensionRange {
+    android.hardware.audio.effect.VendorExtension min;
+    android.hardware.audio.effect.VendorExtension max;
+  }
+  @VintfStability
+  parcelable VirtualizerRange {
+    android.hardware.audio.effect.Virtualizer min;
+    android.hardware.audio.effect.Virtualizer max;
+  }
+  @VintfStability
+  parcelable VisualizerRange {
+    android.hardware.audio.effect.Visualizer min;
+    android.hardware.audio.effect.Visualizer max;
+  }
+  @VintfStability
+  parcelable VolumeRange {
+    android.hardware.audio.effect.Volume min;
+    android.hardware.audio.effect.Volume max;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/State.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/State.aidl
new file mode 100644
index 0000000..17f9814
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/State.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@Backing(type="byte") @VintfStability
+enum State {
+  INIT,
+  IDLE,
+  PROCESSING,
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/VendorExtension.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/VendorExtension.aidl
new file mode 100644
index 0000000..b806334
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/VendorExtension.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+parcelable VendorExtension {
+  ParcelableHolder extension;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl
new file mode 100644
index 0000000..6092b14
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Virtualizer {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int strengthPm;
+  android.hardware.audio.effect.Virtualizer.ChannelAngle[] speakerAngles;
+  android.media.audio.common.AudioDeviceDescription device;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Virtualizer.Tag commonTag;
+    android.hardware.audio.effect.Virtualizer.SpeakerAnglesPayload speakerAnglesPayload;
+  }
+  @VintfStability
+  parcelable SpeakerAnglesPayload {
+    android.media.audio.common.AudioChannelLayout layout;
+    android.media.audio.common.AudioDeviceDescription device;
+  }
+  @VintfStability
+  parcelable ChannelAngle {
+    int channel;
+    int azimuthDegree;
+    int elevationDegree;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
new file mode 100644
index 0000000..7d319da
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Visualizer {
+  android.hardware.audio.effect.Visualizer.Id id;
+  android.hardware.audio.effect.VendorExtension vendor;
+  android.hardware.audio.effect.Visualizer.Measurement measurement;
+  byte[] captureSampleBuffer;
+  int latencyMs;
+  int captureSamples;
+  android.hardware.audio.effect.Visualizer.ScalingMode scalingMode;
+  android.hardware.audio.effect.Visualizer.MeasurementMode measurementMode;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Visualizer.Tag commonTag;
+  }
+  @VintfStability
+  enum ScalingMode {
+    NORMALIZED = 0,
+    AS_PLAYED,
+  }
+  @VintfStability
+  enum MeasurementMode {
+    NONE = 0,
+    PEAK_RMS,
+  }
+  @VintfStability
+  parcelable Measurement {
+    int rms;
+    int peak;
+  }
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
new file mode 100644
index 0000000..8227118
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.effect;
+@VintfStability
+union Volume {
+  android.hardware.audio.effect.VendorExtension vendor;
+  int levelDb;
+  boolean mute;
+  @VintfStability
+  union Id {
+    android.hardware.audio.effect.VendorExtension vendorExtensionTag;
+    android.hardware.audio.effect.Volume.Tag commonTag;
+  }
+}
diff --git a/audio/aidl/android/hardware/audio/common/AudioOffloadMetadata.aidl b/audio/aidl/android/hardware/audio/common/AudioOffloadMetadata.aidl
new file mode 100644
index 0000000..5881658
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/common/AudioOffloadMetadata.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.common;
+
+import android.media.audio.common.AudioChannelLayout;
+
+/**
+ * Dynamic metadata for offloaded compressed audio.
+ * For static metadata, see android.media.audio.common.AudioOffloadInfo.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioOffloadMetadata {
+    int sampleRate;
+    AudioChannelLayout channelMask;
+    /** Average bit rate in bits per second. */
+    int averageBitRatePerSecond;
+    /**
+     * Number of frames to be ignored at the beginning of the stream.
+     * The value must be non-negative. A value of 0 indicates no delay
+     * has to be applied.
+     */
+    int delayFrames;
+    /**
+     * Number of frames to be ignored at the end of the stream.
+     * The value must be non-negative. A value of 0 indicates no padding
+     * has to be applied.
+     */
+    int paddingFrames;
+}
diff --git a/audio/aidl/android/hardware/audio/core/AudioPatch.aidl b/audio/aidl/android/hardware/audio/core/AudioPatch.aidl
new file mode 100644
index 0000000..005d4c0
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/AudioPatch.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+/**
+ * Audio patch specifies a connection between multiple audio port
+ * configurations.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioPatch {
+    /** The ID of the patch, unique within the HAL module. */
+    int id;
+    /**
+     * The list of IDs of source audio port configs ('AudioPortConfig.id').
+     * There must be at least one source in a valid patch and all IDs must be
+     * unique.
+     */
+    int[] sourcePortConfigIds;
+    /**
+     * The list of IDs of sink audio port configs ('AudioPortConfig.id').
+     * There must be at least one sink in a valid patch and all IDs must be
+     * unique.
+     */
+    int[] sinkPortConfigIds;
+    /**
+     * The minimum buffer size, in frames, which streams must use for
+     * this connection configuration. This field is filled out by the
+     * HAL module on creation of the patch and must be a positive number.
+     */
+    int minimumStreamBufferSizeFrames;
+    /**
+     * Latencies, in milliseconds, associated with each sink port config from
+     * the 'sinkPortConfigIds' field. This field is filled out by the HAL module
+     * on creation or updating of the patch and must be a positive number. This
+     * is a nominal value. The current value of latency is provided via
+     * 'StreamDescriptor' command exchange on each audio I/O operation.
+     */
+    int[] latenciesMs;
+}
diff --git a/audio/aidl/android/hardware/audio/core/AudioRoute.aidl b/audio/aidl/android/hardware/audio/core/AudioRoute.aidl
new file mode 100644
index 0000000..1e7b441
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/AudioRoute.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+/**
+ * Audio route specifies a path from multiple audio source ports to one audio
+ * sink port. As an example, when emitting audio output, source ports typically
+ * are mix ports (audio data from the framework), the sink is a device
+ * port. When acquiring audio, source ports are device ports, the sink is a mix
+ * port.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioRoute {
+    /**
+     * The list of IDs of source audio ports ('AudioPort.id').
+     * There must be at least one source in a valid route and all IDs must be
+     * unique.
+     */
+    int[] sourcePortIds;
+    /** The ID of the sink audio port ('AudioPort.id'). */
+    int sinkPortId;
+    /** If set, only one source can be active, mixing is not supported. */
+    boolean isExclusive;
+}
diff --git a/audio/aidl/android/hardware/audio/core/IBluetooth.aidl b/audio/aidl/android/hardware/audio/core/IBluetooth.aidl
new file mode 100644
index 0000000..7fa2e24
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IBluetooth.aidl
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.media.audio.common.Boolean;
+import android.media.audio.common.Float;
+import android.media.audio.common.Int;
+
+/**
+ * An instance of IBluetooth manages settings for the Hands-Free Profile (HFP)
+ * and the SCO Link. This interface is optional to implement and provide by the
+ * vendor. It needs to be provided only if the device actually supports BT SCO
+ * or HFP.
+ *
+ * Each of IBluetooth* interfaces is independent of each other. The HAL module
+ * can provide any combination of them.
+ */
+@VintfStability
+interface IBluetooth {
+    @JavaDerive(equals=true, toString=true)
+    @VintfStability
+    parcelable ScoConfig {
+        /**
+         * Whether BT SCO is enabled. The client might need to disable it
+         * when another profile (for example, A2DP) is activated.
+         */
+        @nullable Boolean isEnabled;
+        /**
+         * Whether BT SCO Noise Reduction and Echo Cancellation are enabled.
+         */
+        @nullable Boolean isNrecEnabled;
+        @VintfStability enum Mode { UNSPECIFIED, SCO, SCO_WB, SCO_SWB }
+        /**
+         * If set, specifies the SCO mode to use:
+         *   regular, wide band (WB), or super wide band (SWB).
+         */
+        Mode mode = Mode.UNSPECIFIED;
+        /**
+         * The name of the BT SCO headset used for debugging purposes. Can be empty.
+         */
+        @nullable @utf8InCpp String debugName;
+    }
+
+    /**
+     * Set the configuration of Bluetooth SCO.
+     *
+     * In the provided parcelable, the client sets zero, one or more parameters
+     * which have to be updated on the HAL side. The parameters that are left
+     * unset must retain their current values. It is allowed to change
+     * parameters while the SCO profile is disabled (isEnabled.value == false).
+     *
+     * In the returned parcelable, all parameter fields known to the HAL module
+     * must be populated to their current values. If the SCO profile is
+     * currently disabled (isEnabled.value == false), the parameters must
+     * reflect the last values that were in use.
+     *
+     * The client can pass an uninitialized parcelable in order to retrieve the
+     * current configuration.
+     *
+     * @return The current configuration (after update). All fields known to
+     *         the HAL must be populated.
+     * @param config The configuration to set. Any number of fields may be left
+     *               uninitialized.
+     * @throws EX_UNSUPPORTED_OPERATION If BT SCO is not supported.
+     * @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
+     *                             values is invalid.
+     */
+    ScoConfig setScoConfig(in ScoConfig config);
+
+    @JavaDerive(equals=true, toString=true)
+    @VintfStability
+    parcelable HfpConfig {
+        /**
+         * Whether BT HFP is enabled.
+         */
+        @nullable Boolean isEnabled;
+        /**
+         * The sample rate of BT HFP, in Hertz. Must be a positive number.
+         */
+        @nullable Int sampleRate;
+
+        const int VOLUME_MIN = 0;
+        const int VOLUME_MAX = 1;
+        /**
+         * The output volume of BT HFP. 1.0f means unity gain, 0.0f is muted,
+         * see VOLUME_* constants;
+         */
+        @nullable Float volume;
+    }
+
+    /**
+     * Set the configuration of Bluetooth HFP.
+     *
+     * In the provided parcelable, the client sets zero, one or more parameters
+     * which have to be updated on the HAL side. The parameters that are left
+     * unset must retain their current values. It is allowed to change
+     * parameters while the HFP profile is disabled (isEnabled.value == false).
+     *
+     * In the returned parcelable, all parameter fields known to the HAL module
+     * must be populated to their current values. If the HFP profile is
+     * currently disabled (isEnabled.value == false), the parameters must
+     * reflect the last values that were in use.
+     *
+     * The client can pass an uninitialized parcelable in order to retrieve the
+     * current configuration.
+     *
+     * @return The current configuration (after update). All fields known to
+     *         the HAL must be populated.
+     * @param config The configuration to set. Any number of fields may be left
+     *               uninitialized.
+     * @throws EX_UNSUPPORTED_OPERATION If BT HFP is not supported.
+     * @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
+     *                             values is invalid.
+     */
+    HfpConfig setHfpConfig(in HfpConfig config);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IBluetoothA2dp.aidl b/audio/aidl/android/hardware/audio/core/IBluetoothA2dp.aidl
new file mode 100644
index 0000000..a690ca4
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IBluetoothA2dp.aidl
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.hardware.audio.core.VendorParameter;
+
+/**
+ * An instance of IBluetoothA2dp manages settings for the A2DP (Advanced Audio
+ * Distribution Profile) profiles. This interface is optional to implement by
+ * the vendor. It needs to be provided only if the device actually supports BT
+ * A2DP.
+ *
+ * Each of IBluetooth* interfaces is independent of each other. The HAL module
+ * can provide any combination of them.
+ */
+@VintfStability
+interface IBluetoothA2dp {
+    /**
+     * Whether BT A2DP is enabled.
+     *
+     * Returns the current state of A2DP support. The client might need to
+     * disable (suspend) A2DP when another profile (for example, SCO) is
+     * activated.
+     *
+     * @return Whether BT A2DP is enabled.
+     */
+    boolean isEnabled();
+
+    /**
+     * Enable or disable A2DP.
+     *
+     * Sets the current state of A2DP support. The client might need to
+     * disable (suspend) A2DP when another profile (for example, SCO) is
+     * activated.
+     *
+     * @param enabled Whether BT A2DP must be enabled or suspended.
+     * @throws EX_ILLEGAL_STATE If there was an error performing the operation.
+     */
+    void setEnabled(boolean enabled);
+
+    /**
+     * Indicates whether the module supports reconfiguration of offloaded codecs.
+     *
+     * Offloaded codec implementations may need to be reconfigured when the
+     * active A2DP device changes. This method indicates whether the HAL module
+     * supports the reconfiguration event. The result returned from this method
+     * must not change over time.
+     *
+     * @return Whether reconfiguration offload of offloaded codecs is supported.
+     */
+    boolean supportsOffloadReconfiguration();
+
+    /**
+     * Instructs the HAL module to reconfigure offloaded codec.
+     *
+     * Offloaded codec implementations may need to be reconfigured when the
+     * active A2DP device changes. This method is a notification for the HAL
+     * module to commence reconfiguration.
+     *
+     * Note that 'EX_UNSUPPORTED_OPERATION' must be thrown if and only if
+     * 'supportsOffloadReconfiguration' returns 'false'.
+     *
+     * @param parameter Optional vendor-specific parameters, can be left empty.
+     * @throws EX_ILLEGAL_STATE If there was an error performing the operation,
+     *                          or the operation can not be commenced in the current state.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support codec reconfiguration.
+     */
+    void reconfigureOffload(in VendorParameter[] parameters);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IBluetoothLe.aidl b/audio/aidl/android/hardware/audio/core/IBluetoothLe.aidl
new file mode 100644
index 0000000..444ff68
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IBluetoothLe.aidl
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.hardware.audio.core.VendorParameter;
+
+/**
+ * An instance of IBluetoothLe manages settings for the LE (Low Energy)
+ * profiles. This interface is optional to implement by the vendor. It needs to
+ * be provided only if the device actually supports BT LE.
+ *
+ * Each of IBluetooth* interfaces is independent of each other. The HAL module
+ * can provide any combination of them.
+ */
+@VintfStability
+interface IBluetoothLe {
+    /**
+     * Whether BT LE is enabled.
+     *
+     * Returns the current state of LE support. The client might need to
+     * disable (suspend) LE when another profile (for example, SCO) is
+     * activated.
+     *
+     * @return Whether BT LE is enabled.
+     */
+    boolean isEnabled();
+
+    /**
+     * Enable or disable LE.
+     *
+     * Sets the current state of LE support. The client might need to
+     * disable (suspend) LE when another Bluetooth profile (for example, SCO) is
+     * activated.
+     *
+     * @param enabled Whether BT LE must be enabled or suspended.
+     * @throws EX_ILLEGAL_STATE If there was an error performing the operation.
+     */
+    void setEnabled(boolean enabled);
+
+    /**
+     * Indicates whether the module supports reconfiguration of offloaded codecs.
+     *
+     * Offloaded codec implementations may need to be reconfigured when the
+     * active LE device changes. This method indicates whether the HAL module
+     * supports the reconfiguration event. The result returned from this method
+     * must not change over time.
+     *
+     * @return Whether reconfiguration offload of offloaded codecs is supported.
+     */
+    boolean supportsOffloadReconfiguration();
+
+    /**
+     * Instructs the HAL module to reconfigure offloaded codec.
+     *
+     * Offloaded codec implementations may need to be reconfigured when the
+     * active LE device changes. This method is a notification for the HAL
+     * module to commence reconfiguration.
+     *
+     * Note that 'EX_UNSUPPORTED_OPERATION' must be thrown if and only if
+     * 'supportsOffloadReconfiguration' returns 'false'.
+     *
+     * @param parameter Optional vendor-specific parameters, can be left empty.
+     * @throws EX_ILLEGAL_STATE If there was an error performing the operation,
+     *                          or the operation can not be commenced in the current state.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support codec reconfiguration.
+     */
+    void reconfigureOffload(in VendorParameter[] parameters);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IConfig.aidl b/audio/aidl/android/hardware/audio/core/IConfig.aidl
new file mode 100644
index 0000000..094d233
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IConfig.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.hardware.audio.core.SurroundSoundConfig;
+import android.media.audio.common.AudioHalEngineConfig;
+
+/**
+ * This interface provides system-wide configuration parameters for audio I/O
+ * (by "system" here we mean the device running Android).
+ */
+@VintfStability
+interface IConfig {
+    /**
+     * Returns the surround sound configuration used for the Audio Policy
+     * Manager initial configuration.
+     *
+     * This method will only be called during the initialization of the Audio
+     * Policy Manager, and must always return the same result.
+     *
+     * @return The surround sound configuration
+     */
+    SurroundSoundConfig getSurroundSoundConfig();
+    /**
+     * Returns the configuration items used to determine the audio policy engine
+     * flavor and initial configuration.
+     *
+     * Engine flavor is determined by presence of capSpecificConfig, which must
+     * only be present if the device uses the Configurable Audio Policy (CAP)
+     * engine. Clients normally use the default audio policy engine. The client
+     * will use the CAP engine only when capSpecificConfig has a non-null value.
+     *
+     * This method is expected to only be called during the initialization of
+     * the audio policy engine, and must always return the same result.
+     *
+     * @return The engine configuration
+     */
+    AudioHalEngineConfig getEngineConfig();
+}
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
new file mode 100644
index 0000000..e736c32
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -0,0 +1,915 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.hardware.audio.common.SinkMetadata;
+import android.hardware.audio.common.SourceMetadata;
+import android.hardware.audio.core.AudioPatch;
+import android.hardware.audio.core.AudioRoute;
+import android.hardware.audio.core.IBluetooth;
+import android.hardware.audio.core.IBluetoothA2dp;
+import android.hardware.audio.core.IBluetoothLe;
+import android.hardware.audio.core.IStreamCallback;
+import android.hardware.audio.core.IStreamIn;
+import android.hardware.audio.core.IStreamOut;
+import android.hardware.audio.core.IStreamOutEventCallback;
+import android.hardware.audio.core.ITelephony;
+import android.hardware.audio.core.ModuleDebug;
+import android.hardware.audio.core.StreamDescriptor;
+import android.hardware.audio.core.VendorParameter;
+import android.hardware.audio.core.sounddose.ISoundDose;
+import android.hardware.audio.effect.IEffect;
+import android.media.audio.common.AudioMMapPolicyInfo;
+import android.media.audio.common.AudioMMapPolicyType;
+import android.media.audio.common.AudioMode;
+import android.media.audio.common.AudioOffloadInfo;
+import android.media.audio.common.AudioPort;
+import android.media.audio.common.AudioPortConfig;
+import android.media.audio.common.Float;
+import android.media.audio.common.MicrophoneInfo;
+
+/**
+ * Each instance of IModule corresponds to a separate audio module. The system
+ * (the term "system" as used here applies to the entire device running Android)
+ * may have multiple modules due to the physical architecture, for example, it
+ * can have multiple DSPs or other audio I/O units which are not interconnected
+ * in hardware directly. Usually there is at least one audio module which is
+ * responsible for the "main" (or "built-in") audio functionality of the
+ * system. Even if the system lacks any physical audio I/O capabilities, there
+ * will be a "null" audio module.
+ *
+ * On a typical mobile phone there is usually a main DSP module which handles
+ * most of the phone's audio I/O via the built-in speakers and microphones. USB
+ * audio can exist as a separate module. Some audio modules can be implemented
+ * purely in software, for example, the remote submix module.
+ */
+@VintfStability
+interface IModule {
+    /**
+     * Sets debugging configuration for the HAL module. This method is only
+     * called during xTS testing and is intended for validating the aspects of
+     * the HAL module behavior that would otherwise require human intervention.
+     *
+     * The HAL module must throw an error if there is an attempt to change
+     * the debug behavior for the aspect which is currently in use, or when
+     * the value of any of the debug flags is invalid. See 'ModuleDebug' for
+     * the full list of constraints.
+     *
+     * @param debug The debug options.
+     * @throws EX_ILLEGAL_ARGUMENT If some of the configuration parameters are
+     *                             invalid.
+     * @throws EX_ILLEGAL_STATE If the flag(s) being changed affect functionality
+     *                          which is currently in use.
+     */
+    void setModuleDebug(in ModuleDebug debug);
+
+    /**
+     * Retrieve the interface to control telephony audio.
+     *
+     * If the HAL module supports telephony functions, it must return an
+     * instance of the ITelephony interface. The same instance must be returned
+     * during the lifetime of the HAL module. If the HAL module does not support
+     * telephony, a null must be returned, without throwing any errors.
+     *
+     * @return An instance of the ITelephony interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable ITelephony getTelephony();
+
+    /**
+     * Retrieve the interface to control Bluetooth SCO and HFP.
+     *
+     * If the HAL module supports either the SCO Link or Hands-Free Profile
+     * functionality (or both) for Bluetooth, it must return an instance of the
+     * IBluetooth interface. The same instance must be returned during the
+     * lifetime of the HAL module. If the HAL module does not support BT SCO and
+     * HFP, a null must be returned, without throwing any errors.
+     *
+     * @return An instance of the IBluetooth interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable IBluetooth getBluetooth();
+
+    /**
+     * Retrieve the interface to control Bluetooth A2DP.
+     *
+     * If the HAL module supports A2DP Profile functionality for Bluetooth, it
+     * must return an instance of the IBluetoothA2dp interface. The same
+     * instance must be returned during the lifetime of the HAL module. If the
+     * HAL module does not support BT A2DP, a null must be returned, without
+     * throwing any errors.
+     *
+     * @return An instance of the IBluetoothA2dp interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable IBluetoothA2dp getBluetoothA2dp();
+
+    /**
+     * Retrieve the interface to control Bluetooth LE.
+     *
+     * If the HAL module supports LE Profile functionality for Bluetooth, it
+     * must return an instance of the IBluetoothLe interface. The same
+     * instance must be returned during the lifetime of the HAL module. If the
+     * HAL module does not support BT LE, a null must be returned, without
+     * throwing any errors.
+     *
+     * @return An instance of the IBluetoothLe interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable IBluetoothLe getBluetoothLe();
+
+    /**
+     * Set a device port of an external device into connected state.
+     *
+     * This method is used to inform the HAL module that an external device has
+     * been connected to a device port selected using the 'id' field of the
+     * input AudioPort parameter. This device port must have dynamic profiles
+     * (an empty list of profiles). This port is further referenced to as "port
+     * template" because it acts as a template for creating a new instance of a
+     * "connected" device port which gets returned from this method.
+     *
+     * The input AudioPort parameter may contain any additional data obtained by
+     * the system side from other subsystems. The nature of data depends on the
+     * type of the connection. For example, for point-to-multipoint external
+     * device connections, the input parameter may contain the address of the
+     * connected external device. Another example is EDID information for HDMI
+     * connections (ExtraAudioDescriptor), which can be provided by the HDMI-CEC
+     * HAL module.
+     *
+     * It is the responsibility of the HAL module to query audio profiles
+     * supported by the connected device and return them as part of the returned
+     * AudioPort instance. In the case when the HAL is unable to query the
+     * external device, an error must be thrown.
+     *
+     * Thus, the returned audio port instance is the result of combining the
+     * following information:
+     *  - a unique port ID generated by the HAL module;
+     *  - static information from the port template;
+     *  - list of audio profiles supported by the connected device;
+     *  - additional data from the input AudioPort parameter.
+     *
+     * The HAL module must also update the list of audio routes to include the
+     * ID of the instantiated connected device port. Normally, the connected
+     * port allows the same routing as the port template.
+     *
+     * Also see notes on 'ModuleDebug.simulateDeviceConnections'.
+     *
+     * The following protocol is used by HAL module client for handling
+     * connection of an external device:
+     *  1. Obtain the list of device ports and their IDs via 'getAudioPorts'
+     *     method. Select the appropriate port template using
+     *     AudioDeviceDescription ('ext.device' field of AudioPort).
+     *  2. Combine the ID of the port template with any additional data and call
+     *     'connectExternalDevice'. The HAL module returns a new instance of
+     *     AudioPort created using the rules explained above. Both
+     *     'getAudioPort' and 'getAudioPorts' methods will be returning the same
+     *     information for this port until disconnection.
+     *  3. Configure the connected port with one of supported profiles using
+     *     'setAudioPortConfig'.
+     *  4. Query the list of AudioRoutes for the new AudioPort using
+     *     'getAudioRoutesForAudioPort' or 'getAudioRoutes' methods.
+     *
+     * External devices are distinguished by the connection type and device
+     * address. Calling this method multiple times to inform about connection of
+     * the same external device without disconnecting it first is an error.
+     *
+     * The HAL module must perform validation of the input parameter and throw
+     * an error if it is lacking required information, for example, when no
+     * device address is specified for a point-to-multipoint external device
+     * connection.
+     *
+     * Since not all modules have a DSP that could perform sample rate and
+     * format conversions, behavior related to mix port configurations may vary.
+     * For modules with a DSP, mix ports can be pre-configured and have a fixed
+     * set of audio profiles supported by the DSP. For modules without a DSP,
+     * audio profiles of mix ports may change after connecting an external
+     * device. The typical case is that the mix port has an empty set of
+     * profiles when no external devices are connected, and after external
+     * device connection it receives the same set of profiles as the device
+     * ports that they can be routed to. The client will re-query current port
+     * configurations using 'getAudioPorts'. All mix ports that can be routed to
+     * the connected device port must have a non-empty set of audio profiles
+     * after successful connection of an external device.
+     *
+     * Handling of a disconnect is done in a reverse order:
+     *  1. Reset port configuration using the 'resetAudioPortConfig' method.
+     *  2. Release the connected device port by calling the 'disconnectExternalDevice'
+     *     method. This also removes the audio routes associated with this
+     *     device port.
+     *
+     * @return New instance of an audio port for the connected external device.
+     * @param templateIdAndAdditionalData Specifies port template ID and any
+     *                                    additional data.
+     * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+     *                             - If the template port can not be found by the ID.
+     *                             - If the template is not a device port, or
+     *                               it does not have dynamic profiles.
+     *                             - If the input parameter is lacking required
+     *                               information.
+     * @throws EX_ILLEGAL_STATE In the following cases:
+     *                          - If the HAL module is unable to query audio profiles.
+     *                          - If the external device has already been connected.
+     */
+    AudioPort connectExternalDevice(in AudioPort templateIdAndAdditionalData);
+
+    /**
+     * Set a device port of a an external device into disconnected state.
+     *
+     * This method is used to inform the HAL module that an external device has
+     * been disconnected. The 'portId' must be of a connected device port
+     * instance previously instantiated using the 'connectExternalDevice'
+     * method.
+     *
+     * The framework will call this method before closing streams and resetting
+     * patches. This call can be used by the HAL module to prepare itself to
+     * device disconnection. If the HAL module indicates an error after the first
+     * call, the framework will call this method once again after closing associated
+     * streams and patches.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+     *                             - If the port can not be found by the ID.
+     *                             - If this is not a connected device port.
+     * @throws EX_ILLEGAL_STATE If the port has active configurations.
+     */
+    void disconnectExternalDevice(int portId);
+
+    /**
+     * Return all audio patches of this module.
+     *
+     * Returns a list of audio patches, that is, established connections between
+     * audio port configurations.
+     *
+     * @return The list of audio patches.
+     */
+    AudioPatch[] getAudioPatches();
+
+    /**
+     * Return the current state of the audio port.
+     *
+     * Using the port ID provided on input, returns the current state of the
+     * audio port. The values of the AudioPort structure must be the same as
+     * currently returned by the 'getAudioPorts' method. The 'getAudioPort'
+     * method is provided to reduce overhead in the case when the client needs
+     * to check the state of one port only.
+     *
+     * @return The current state of an audio port.
+     * @param portId The ID of the audio port.
+     * @throws EX_ILLEGAL_ARGUMENT If the port can not be found by the ID.
+     */
+    AudioPort getAudioPort(int portId);
+
+    /**
+     * Return all active audio port configurations of this module.
+     *
+     * Returns a list of active configurations that are currently set for mix
+     * ports and device ports. Each returned configuration must have an unique
+     * ID within this module ('AudioPortConfig.id' field), which can coincide
+     * with an ID of an audio port, if the port only supports a single active
+     * configuration. Each returned configuration must also have a reference to
+     * an existing port ('AudioPortConfig.portId' field). All optional
+     * (nullable) fields of the configurations must be initialized by the HAL
+     * module.
+     *
+     * @return The list of active audio port configurations.
+     */
+    AudioPortConfig[] getAudioPortConfigs();
+
+    /**
+     * Return the current state of all audio ports provided by this module.
+     *
+     * Returns a list of all mix ports and device ports provided by this HAL
+     * module, reflecting their current states. Each returned port must have a
+     * unique ID within this module ('AudioPort.id' field). The list also
+     * includes "connected" ports created using 'connectExternalDevice' method.
+     *
+     * @return The list of audio ports.
+     */
+    AudioPort[] getAudioPorts();
+
+    /**
+     * Return all current audio routes of this module.
+     *
+     * Returns the current list of audio routes, that is, allowed connections
+     * between audio ports. The list can change when new device audio ports
+     * get created as a result of connecting or disconnecting of external
+     * devices.
+     *
+     * @return The list of audio routes.
+     */
+    AudioRoute[] getAudioRoutes();
+
+    /**
+     * Return audio routes related to the specified audio port.
+     *
+     * Returns the list of audio routes that include the specified port ID
+     * as a source or as a sink. The returned list is a subset of the result
+     * returned by the 'getAudioRoutes' method, filtered by the port ID.
+     * An empty list can be returned, indicating that the audio port can not
+     * be used for creating audio patches.
+     *
+     * @return The list of audio routes.
+     * @param portId The ID of the audio port.
+     * @throws EX_ILLEGAL_ARGUMENT If the port can not be found by the ID.
+     */
+    AudioRoute[] getAudioRoutesForAudioPort(int portId);
+
+    /**
+     * Open an input stream using an existing audio mix port configuration.
+     *
+     * The audio port configuration ID must be obtained by calling
+     * 'setAudioPortConfig' method. Existence of an audio patch involving this
+     * port configuration is not required for successful opening of a stream.
+     *
+     * The requested buffer size is expressed in frames, thus the actual size
+     * in bytes depends on the audio port configuration. Also, the HAL module
+     * may end up providing a larger buffer, thus the requested size is treated
+     * as the minimum size that the client needs. The minimum buffer size
+     * suggested by the HAL is in the 'AudioPatch.minimumStreamBufferSizeFrames'
+     * field, returned as a result of calling the 'setAudioPatch' method.
+     *
+     * Only one stream is allowed per audio port configuration. HAL module can
+     * also set a limit on how many output streams can be opened for a particular
+     * mix port by using its 'AudioPortMixExt.maxOpenStreamCount' field.
+     *
+     * Note that although it's not prohibited to open a stream on a mix port
+     * configuration which is not connected (using a patch) to any device port,
+     * and set up a patch afterwards, this sequence of calls is not recommended,
+     * because setting up of a patch might fail due to an insufficient stream
+     * buffer size. Another consequence of having a stream on an unconnected mix
+     * port is that capture positions can not be determined because there is no
+     * "external observer," thus read operations done via StreamDescriptor will
+     * be completing with an error, although data (zero filled) will still be
+     * provided.
+     *
+     * After the stream has been opened, it remains in the STANDBY state, see
+     * StreamDescriptor for more details.
+     *
+     * @return An opened input stream and the associated descriptor.
+     * @param args The pack of arguments, see 'OpenInputStreamArguments' parcelable.
+     * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+     *                             - If the port config can not be found by the ID.
+     *                             - If the port config is not of an input mix port.
+     *                             - If a buffer of the requested size can not be provided.
+     * @throws EX_ILLEGAL_STATE In the following cases:
+     *                          - If the port config already has a stream opened on it.
+     *                          - If the limit on the open stream count for the port has
+     *                            been reached.
+     *                          - If the HAL module failed to initialize the stream.
+     */
+    @VintfStability
+    parcelable OpenInputStreamArguments {
+        /** The ID of the audio mix port config. */
+        int portConfigId;
+        /** Description of the audio that will be recorded. */
+        SinkMetadata sinkMetadata;
+        /** Requested audio I/O buffer minimum size, in frames. */
+        long bufferSizeFrames;
+    }
+    @VintfStability
+    parcelable OpenInputStreamReturn {
+        IStreamIn stream;
+        StreamDescriptor desc;
+    }
+    OpenInputStreamReturn openInputStream(in OpenInputStreamArguments args);
+
+    /**
+     * Open an output stream using an existing audio mix port configuration.
+     *
+     * The audio port configuration ID must be obtained by calling
+     * 'setAudioPortConfig' method. Existence of an audio patch involving this
+     * port configuration is not required for successful opening of a stream.
+     *
+     * If the port configuration has the 'COMPRESS_OFFLOAD' output flag set,
+     * the client must provide additional information about the encoded
+     * audio stream in the 'offloadInfo' argument.
+     *
+     * If the port configuration has the 'NON_BLOCKING' output flag set,
+     * the client must provide a callback for asynchronous notifications
+     * in the 'callback' argument.
+     *
+     * The requested buffer size is expressed in frames, thus the actual size
+     * in bytes depends on the audio port configuration. Also, the HAL module
+     * may end up providing a larger buffer, thus the requested size is treated
+     * as the minimum size that the client needs. The minimum buffer size
+     * suggested by the HAL is in the 'AudioPatch.minimumStreamBufferSizeFrames'
+     * field, returned as a result of calling the 'setAudioPatch' method.
+     *
+     * Only one stream is allowed per audio port configuration. HAL module can
+     * also set a limit on how many output streams can be opened for a particular
+     * mix port by using its 'AudioPortMixExt.maxOpenStreamCount' field.
+     * Only one stream can be opened on the audio port with 'PRIMARY' output
+     * flag. This rule can not be overridden with 'maxOpenStreamCount' field.
+     *
+     * Note that although it's not prohibited to open a stream on a mix port
+     * configuration which is not connected (using a patch) to any device port,
+     * and set up a patch afterwards, this sequence of calls is not recommended,
+     * because setting up of a patch might fail due to an insufficient stream
+     * buffer size. Another consequence of having a stream on an unconnected mix
+     * port is that presentation positions can not be determined because there
+     * is no "external observer," thus write operations done via
+     * StreamDescriptor will be completing with an error, although the data
+     * will still be accepted and immediately discarded.
+     *
+     * After the stream has been opened, it remains in the STANDBY state, see
+     * StreamDescriptor for more details.
+     *
+     * @return An opened output stream and the associated descriptor.
+     * @param args The pack of arguments, see 'OpenOutputStreamArguments' parcelable.
+     * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+     *                             - If the port config can not be found by the ID.
+     *                             - If the port config is not of an output mix port.
+     *                             - If the offload info is not provided for an offload
+     *                               port configuration.
+     *                             - If a buffer of the requested size can not be provided.
+     *                             - If the callback is not provided for a non-blocking
+     *                               port configuration.
+     * @throws EX_ILLEGAL_STATE In the following cases:
+     *                          - If the port config already has a stream opened on it.
+     *                          - If the limit on the open stream count for the port has
+     *                            been reached.
+     *                          - If another opened stream already exists for the 'PRIMARY'
+     *                            output port.
+     *                          - If the HAL module failed to initialize the stream.
+     */
+    @VintfStability
+    parcelable OpenOutputStreamArguments {
+        /** The ID of the audio mix port config. */
+        int portConfigId;
+        /** Description of the audio that will be played. */
+        SourceMetadata sourceMetadata;
+        /** Additional information used for offloaded playback only. */
+        @nullable AudioOffloadInfo offloadInfo;
+        /** Requested audio I/O buffer minimum size, in frames. */
+        long bufferSizeFrames;
+        /** Client callback interface for the non-blocking output mode. */
+        @nullable IStreamCallback callback;
+        /** Optional callback to notify client about stream events. */
+        @nullable IStreamOutEventCallback eventCallback;
+    }
+    @VintfStability
+    parcelable OpenOutputStreamReturn {
+        IStreamOut stream;
+        StreamDescriptor desc;
+    }
+    OpenOutputStreamReturn openOutputStream(in OpenOutputStreamArguments args);
+
+    /**
+     * Get supported ranges of playback rate factors.
+     *
+     * See 'PlaybackRate' for the information on the playback rate parameters.
+     * This method provides supported ranges (inclusive) for the speed factor
+     * and the pitch factor.
+     *
+     * If the HAL module supports setting the playback rate, it is recommended
+     * to support speed and pitch factor values at least in the range from 0.5f
+     * to 2.0f.
+     *
+     * @throws EX_UNSUPPORTED_OPERATION If setting of playback rate parameters
+     *                                  is not supported by the module.
+     */
+    @VintfStability
+    parcelable SupportedPlaybackRateFactors {
+        /** The minimum allowed speed factor. */
+        float minSpeed;
+        /** The maximum allowed speed factor. */
+        float maxSpeed;
+        /** The minimum allowed pitch factor. */
+        float minPitch;
+        /** The maximum allowed pitch factor. */
+        float maxPitch;
+    }
+    SupportedPlaybackRateFactors getSupportedPlaybackRateFactors();
+
+    /**
+     * Set an audio patch.
+     *
+     * This method creates new or updates an existing audio patch. If the
+     * requested audio patch does not have a specified id, then a new patch is
+     * created and an ID is allocated for it by the HAL module. Otherwise an
+     * attempt to update an existing patch is made.
+     *
+     * The operation of updating an existing audio patch must not change
+     * playback state of audio streams opened on the audio port configurations
+     * of the patch. That is, the HAL module must still be able to consume or
+     * to provide data from / to streams continuously during the patch
+     * switching. Natural intermittent audible loss of some audio frames due to
+     * switching between device ports which does not affect stream playback is
+     * allowed. If the HAL module is unable to avoid playback or recording
+     * state change when updating a certain patch, it must return an error. In
+     * that case, the client must take care of changing port configurations,
+     * patches, and recreating streams in a way which provides an acceptable
+     * user experience.
+     *
+     * Audio port configurations specified in the patch must be obtained by
+     * calling 'setAudioPortConfig' method. There must be an audio route which
+     * allows connection between the audio ports whose configurations are used.
+     *
+     * When updating an existing audio patch, nominal latency values may change
+     * and must be provided by the HAL module in the returned 'AudioPatch'
+     * structure.
+     *
+     * @return Resulting audio patch.
+     * @param requested Requested audio patch.
+     * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+     *                             - If the patch is invalid (see AudioPatch).
+     *                             - If a port config can not be found from the specified IDs.
+     *                             - If there are no routes satisfying the patch.
+     *                             - If an existing patch can not be found by the ID.
+     * @throws EX_ILLEGAL_STATE In the following cases:
+     *                          - If application of the patch can only use a route with an
+     *                            exclusive use the sink port, and it is already patched.
+     *                          - If updating an existing patch will cause interruption
+     *                            of audio, or requires re-opening of streams due to
+     *                            change of minimum audio I/O buffer size.
+     * @throws EX_UNSUPPORTED_OPERATION If the patch can not be established because
+     *                                  the HAL module does not support this otherwise valid
+     *                                  patch configuration. For example, if it's a patch
+     *                                  between multiple sources and sinks, and the HAL module
+     *                                  does not support this.
+     */
+    AudioPatch setAudioPatch(in AudioPatch requested);
+
+    /**
+     * Set the active configuration of an audio port.
+     *
+     * This method is used to create or update an active configuration for a mix
+     * port or a device port. The port is specified using the
+     * 'AudioPortConfig.portId' field. If the requested audio port
+     * configuration does not have a specified id in the 'AudioPortConfig.id'
+     * field, then a new configuration is created and an ID is allocated for it
+     * by the HAL module. Otherwise an attempt to update an existing port
+     * configuration is made. The HAL module returns the resulting audio port
+     * configuration. Depending on the port and on the capabilities of the HAL
+     * module, it can either update an existing port configuration (same port
+     * configuration ID remains), or create a new one. The resulting port
+     * configuration ID is returned in the 'id' field of the 'suggested'
+     * argument.
+     *
+     * If the specified port configuration can not be set, this method must
+     * return 'false' and provide its own suggestion in the output
+     * parameter. The framework can then set the suggested configuration on a
+     * subsequent retry call to this method.
+     *
+     * Device ports with dynamic audio profiles (an empty list of profiles)
+     * can not be used with this method. The list of profiles must be filled in
+     * as a result of calling 'connectExternalDevice' method.
+     *
+     * @return Whether the requested configuration has been applied.
+     * @param requested Requested audio port configuration.
+     * @param suggested Same as requested configuration, if it was applied.
+     *                  Suggested audio port configuration if the requested
+     *                  configuration can't be applied.
+     * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+     *                             - If neither port config ID, nor port ID are specified.
+     *                             - If an existing port config can not be found by the ID.
+     *                             - If the port can not be found by the port ID.
+     *                             - If it is not possible to generate a suggested port
+     *                               configuration, for example, if the port only has dynamic
+     *                               profiles.
+     */
+    boolean setAudioPortConfig(in AudioPortConfig requested, out AudioPortConfig suggested);
+
+    /**
+     * Reset the audio patch.
+     *
+     * Resets previously created audio patch using its ID ('AudioPatch.id').  It
+     * is allowed to reset a patch which uses audio port configurations having
+     * associated streams. In this case the mix port becomes disconnected from
+     * the hardware, but the stream does not close.
+     *
+     * @param patchId The ID of the audio patch.
+     * @throws EX_ILLEGAL_ARGUMENT If an existing patch can not be found by the ID.
+     */
+    void resetAudioPatch(int patchId);
+
+    /**
+     * Reset the audio port configuration.
+     *
+     * Resets the specified audio port configuration, discarding all changes
+     * previously done by the framework. That means, if a call to this method is
+     * a success, the effect of all previous calls to 'setAudioPortConfig' which
+     * used or initially have generated the provided 'portConfigId', since the
+     * module start, or since the last call to this method, has been canceled.
+     *
+     * Audio port configurations of mix ports with streams opened on them can
+     * not be reset. Also can not be reset port configurations currently used by
+     * any patches.
+     *
+     * @param portConfigId The ID of the audio port config.
+     * @throws EX_ILLEGAL_ARGUMENT If the port config can not be found by the ID.
+     * @throws EX_ILLEGAL_STATE In the following cases:
+     *                          - If the port config has a stream opened on it;
+     *                          - If the port config is used by a patch;
+     *                          - If the port config has an audio effect on it.
+     */
+    void resetAudioPortConfig(int portConfigId);
+
+    /**
+     * Get the current state of audio output muting.
+     *
+     * If the HAL module supports muting its combined output completely,
+     * this method returns whether muting is currently enabled.
+     *
+     * Note that muting operates independently from the master volume.
+     *
+     * @return Whether the output from the module is muted.
+     * @throws EX_UNSUPPORTED_OPERATION If muting of combined output
+     *                                  is not supported by the module.
+     */
+    boolean getMasterMute();
+
+    /**
+     * Set the current value of the audio output muting.
+     *
+     * If the HAL module supports muting its combined output completely, this
+     * method controls the mute. Note that for modules supporting telephony,
+     * muting does not affect the voice call.
+     *
+     * For HAL modules not supporting this operation, it's functionality is
+     * typically emulated by the client, in the digital domain.
+     *
+     * @param mute Whether the output from the module is muted.
+     * @throws EX_UNSUPPORTED_OPERATION If muting of combined output
+     *                                  is not supported by the module.
+     * @throws EX_ILLEGAL_STATE If any error happens while muting of combined output.
+     */
+    void setMasterMute(boolean mute);
+
+    /**
+     * Get the current value of the audio output attenuation.
+     *
+     * If the HAL module supports attenuating the level its combined output,
+     * this method returns the current attenuation value.
+     *
+     * @return Volume 1.0f means no attenuation (unity), 0.0f is mute.
+     * @throws EX_UNSUPPORTED_OPERATION If attenuation of combined output
+     *                                  is not supported by the module.
+     */
+    float getMasterVolume();
+
+    /**
+     * Set the current value of the audio output attenuation.
+     *
+     * If the HAL module supports attenuating the level its combined output,
+     * this method sets the attenuation value. Note that for modules supporting
+     * telephony, the attenuation of the voice call volume is set separately
+     * via ITelephony interface.
+     *
+     * For HAL modules not supporting this operation, it's functionality is
+     * typically emulated by the client, in the digital domain.
+     *
+     * @param volume The new value, 1.0f means no attenuation (unity), 0.0f is mute.
+     * @throws EX_ILLEGAL_ARGUMENT If the value of the volume is outside of
+     *                             accepted range.
+     * @throws EX_UNSUPPORTED_OPERATION If attenuation of combined output
+     *                                  is not supported by the module.
+     * @throws EX_ILLEGAL_STATE If any error happens while updating attenuation of
+                                combined output.
+     */
+    void setMasterVolume(float volume);
+
+    /**
+     * Get the current state of audio input muting.
+     *
+     * If the HAL module supports muting its external input, this method returns
+     * whether muting is currently enabled.
+     *
+     * @return Whether the input is muted.
+     * @throws EX_UNSUPPORTED_OPERATION If muting of input is not supported by
+     *                                  the module.
+     */
+    boolean getMicMute();
+
+    /**
+     * Set the current value of the audio input muting.
+     *
+     * If the HAL module supports muting its external input, this method
+     * controls the mute.
+     *
+     * For HAL modules not supporting this operation, it's functionality is
+     * emulated by the client.
+     *
+     * @param mute Whether input is muted.
+     * @throws EX_UNSUPPORTED_OPERATION If muting of input is not supported by
+     *                                  the module.
+     */
+    void setMicMute(boolean mute);
+
+    /**
+     * Provide information describing built-in microphones of the HAL module.
+     *
+     * If there are no built-in microphones in the HAL module, it must return an
+     * empty vector. If there are microphones, but the HAL module does not
+     * possess the required information about them, EX_UNSUPPORTED_OPERATION
+     * must be thrown.
+     *
+     * If this method is supported by the HAL module, it must also support
+     * 'IStreamIn.getActiveMicrophones' method.
+     *
+     * @return The vector with information about each microphone.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    MicrophoneInfo[] getMicrophones();
+
+    /**
+     * Notify the HAL module on the change of the current audio mode.
+     *
+     * The current audio mode is always controlled by the client. This is an
+     * informative notification sent to all modules, no reply is needed. The HAL
+     * module should silently ignore this notification if it does not need to
+     * be aware of the current audio mode.
+     *
+     * The client sends this notification to all HAL modules after successfully
+     * switching the telephony module by calling the 'ITelephony.switchAudioMode'
+     * method.
+     *
+     * @param mode The current mode.
+     * @throws EX_ILLEGAL_ARGUMENT If the mode is out of range of valid values.
+     */
+    void updateAudioMode(AudioMode mode);
+
+    @VintfStability
+    @Backing(type="int")
+    enum ScreenRotation {
+        /** Natural orientation. */
+        DEG_0 = 0,
+        DEG_90 = 1,
+        /** Upside down. */
+        DEG_180 = 2,
+        DEG_270 = 3,
+    }
+    /**
+     * Notify the HAL module on the change of the screen rotation.
+     *
+     * Informs the HAL of the current orientation of the device screen. This
+     * information can be used to optimize the output of built-in speakers.
+     * This is an informative notification sent to all modules, no reply is
+     * needed.
+     *
+     * @param rotation The current rotation.
+     */
+    void updateScreenRotation(ScreenRotation rotation);
+
+    /**
+     * Notify the HAL module on the change of the screen state.
+     *
+     * Informs the HAL whether the screen of the device is turned on. This is an
+     * informative notification sent to all modules, no reply is needed.
+     *
+     * @param isTurnedOn True if the screen is turned on.
+     */
+    void updateScreenState(boolean isTurnedOn);
+
+    /**
+     * Retrieve the sound dose interface.
+     *
+     * If a device must comply to IEC62368-1 3rd edition audio safety requirements and is
+     * implementing audio offload decoding or other direct playback paths where volume control
+     * happens below the audio HAL, it must return an instance of the ISoundDose interface.
+     * The same instance must be returned during the lifetime of the HAL module.
+     * If the HAL module does not support sound dose, null must be returned, without throwing
+     * any errors.
+     *
+     * @return An instance of the ISoundDose interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable ISoundDose getSoundDose();
+
+    /**
+     * Generate a HW AV Sync identifier for a new audio session.
+     *
+     * Creates a new unique identifier which can be further used by the client
+     * for tagging input / output streams that belong to the same audio
+     * session and thus must use the same HW AV Sync timestamps sequence.
+     *
+     * HW AV Sync timestamps are used for "tunneled" I/O modes and thus
+     * are not mandatory.
+     *
+     * @throws EX_ILLEGAL_STATE If the identifier can not be provided at the moment.
+     * @throws EX_UNSUPPORTED_OPERATION If synchronization with HW AV Sync markers
+     *                                  is not supported.
+     */
+    int generateHwAvSyncId();
+
+    /**
+     * Get current values of vendor parameters.
+     *
+     * Return current values for the parameters corresponding to the provided ids.
+     *
+     * @param ids Ids of the parameters to retrieve values of.
+     * @return Current values of parameters, one per each id.
+     * @throws EX_ILLEGAL_ARGUMENT If the module does not recognize provided ids.
+     * @throws EX_ILLEGAL_STATE If parameter values can not be retrieved at the moment.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support vendor parameters.
+     */
+    VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
+    /**
+     * Set vendor parameters.
+     *
+     * Update values for provided vendor parameters. If the 'async' parameter
+     * is set to 'true', the implementation must return the control back without
+     * waiting for the application of parameters to complete.
+     *
+     * @param parameters Ids and values of parameters to set.
+     * @param async Whether to return from the method as early as possible.
+     * @throws EX_ILLEGAL_ARGUMENT If the module does not recognize provided parameters.
+     * @throws EX_ILLEGAL_STATE If parameters can not be set at the moment.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support vendor parameters.
+     */
+    void setVendorParameters(in VendorParameter[] parameters, boolean async);
+
+    /**
+     * Apply an audio effect to a device port.
+     *
+     * The audio effect applies to all audio input or output on the specific
+     * configuration of the device audio port. The effect is inserted according
+     * to its insertion preference specified by the 'flags.insert' field of the
+     * EffectDescriptor.
+     *
+     * @param portConfigId The ID of the audio port config.
+     * @param effect The effect instance.
+     * @throws EX_ILLEGAL_ARGUMENT If the device port config can not be found by the ID,
+     *                             or the effect reference is invalid.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support device port effects.
+     */
+    void addDeviceEffect(int portConfigId, in IEffect effect);
+
+    /**
+     * Stop applying an audio effect to a device port.
+     *
+     * Undo the action of the 'addDeviceEffect' method.
+     *
+     * @param portConfigId The ID of the audio port config.
+     * @param effect The effect instance.
+     * @throws EX_ILLEGAL_ARGUMENT If the device port config can not be found by the ID,
+     *                             or the effect reference is invalid, or the effect is
+     *                             not currently applied to the port config.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support device port effects.
+     */
+    void removeDeviceEffect(int portConfigId, in IEffect effect);
+
+    /**
+     * Provide information describing how aaudio MMAP is supported per queried aaudio
+     * MMAP policy type.
+     *
+     * If there are no devices that support aaudio MMAP for the queried aaudio MMAP policy
+     * type in the HAL module, it must return an empty vector. Otherwise, return a vector
+     * describing how the devices support aaudio MMAP.
+     *
+     * @param mmapPolicyType the aaudio mmap policy type to query.
+     * @return The vector with mmap policy information.
+     */
+    AudioMMapPolicyInfo[] getMmapPolicyInfos(AudioMMapPolicyType mmapPolicyType);
+
+    /**
+     * Indicates if this module supports variable latency control, for instance,
+     * over Bluetooth A2DP or LE Audio links.
+     *
+     * If supported, all instances of IStreamOut interface returned by this module must
+     * implement getRecommendedLatencyModes() and setLatencyMode() APIs.
+     *
+     * @return Whether the module supports variable latency control.
+     */
+    boolean supportsVariableLatency();
+
+    /**
+     * Default value for number of bursts per aaudio mixer cycle. This is a suggested value
+     * to return for the HAL module, unless it is known that a better option exists.
+     */
+    const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2;
+    /**
+     * Get the number of bursts per aaudio mixer cycle.
+     *
+     * @return The number of burst per aaudio mixer cycle.
+     * @throw EX_UNSUPPORTED_OPERATION If the module does not support aaudio MMAP.
+     */
+    int getAAudioMixerBurstCount();
+
+    /**
+     * Default value for minimum duration in microseconds for a MMAP hardware burst. This
+     * is a suggested value to return for the HAL module, unless it is known that a better
+     * option exists.
+     */
+    const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000;
+    /**
+     * Get the minimum duration in microseconds for a MMAP hardware burst.
+     *
+     * @return The minimum number of microseconds for a MMAP hardware burst.
+     * @throw EX_UNSUPPORTED_OPERATION If the module does not support aaudio MMAP.
+     */
+    int getAAudioHardwareBurstMinUsec();
+}
diff --git a/audio/aidl/android/hardware/audio/core/IStreamCallback.aidl b/audio/aidl/android/hardware/audio/core/IStreamCallback.aidl
new file mode 100644
index 0000000..440ab25
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IStreamCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+/**
+ * This interface is used to indicate completion of asynchronous operations.
+ * See the state machines referenced by StreamDescriptor for details.
+ */
+@VintfStability
+oneway interface IStreamCallback {
+    /**
+     * Indicate that the stream is ready for next data exchange.
+     */
+    void onTransferReady();
+    /**
+     * Indicate that an irrecoverable error has occurred during the last I/O
+     * operation. After sending this callback, the stream enters the 'ERROR'
+     * state.
+     */
+    void onError();
+    /**
+     * Indicate that the stream has finished draining. This is only used
+     * for output streams because for input streams draining is performed
+     * by the client.
+     */
+    void onDrainReady();
+}
diff --git a/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl b/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl
new file mode 100644
index 0000000..543d9e2
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.hardware.audio.core.VendorParameter;
+import android.hardware.audio.effect.IEffect;
+
+/**
+ * This interface contains operations that are common to input and output
+ * streams (IStreamIn and IStreamOut). The lifetime of the server-side
+ * implementation object is the same as of the "parent" IStreamIn/Out object.
+ * The client must release all references to this object together with
+ * references to the "parent" object.
+ */
+@VintfStability
+interface IStreamCommon {
+    /**
+     * Close the stream.
+     *
+     * Releases any resources allocated for this stream on the HAL module side.
+     * This includes the fast message queues and shared memories returned via
+     * the StreamDescriptor. Thus, the stream can not be operated anymore after
+     * it has been closed. The client needs to release the audio data I/O
+     * objects after the call to this method returns.
+     *
+     * Methods of IStream* interfaces throw EX_ILLEGAL_STATE for a closed stream.
+     *
+     * @throws EX_ILLEGAL_STATE If the stream has already been closed.
+     */
+    void close();
+
+    /**
+     * Notify the stream that it is about to be closed.
+     *
+     * This is a notification sent by the client to indicate that it intends to
+     * close the stream "soon" (the actual time period is unspecified). The
+     * purpose of this notification is to allow the stream implementation to
+     * unblock the I/O thread. This is useful for HAL modules that act as
+     * proxies to other subsystems, examples are "bluetooth" and "r_submix"
+     * modules. In such modules the I/O thread might get blocked on a read or
+     * write operation to the external subsystem. Thus, calling 'close' directly
+     * will stall, as it will try to send the 'Command.halReservedExit' on the
+     * I/O thread which is blocked and is not reading commands from the FMQ. The
+     * HAL implementation must initiate unblocking as a result of receiving the
+     * 'prepareToClose' notification.
+     *
+     * This operation must be handled by the HAL module in an "asynchronous"
+     * manner, returning control back as quick as possible.
+     *
+     * Since this operation does not have any effects observable from the client
+     * side, the HAL module must be able to handle multiple calls of this method
+     * without throwing any errors. The only case when this method is allowed
+     * to throw is when the stream has been closed.
+     *
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     */
+    void prepareToClose();
+
+    /**
+     * Update the HW AV Sync identifier for the stream.
+     *
+     * The argument to this method must be one of the identifiers previously
+     * returned by the 'IModule.generateHwAvSyncId' method. By tagging streams
+     * with the same identifier, the client indicates to the HAL that they all
+     * use the same HW AV Sync timestamps sequence.
+     *
+     * HW AV Sync timestamps are used for "tunneled" I/O modes and thus
+     * are not mandatory.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT If the provided ID is unknown to the HAL module.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If synchronization with HW AV Sync markers
+     *                                  is not supported.
+     */
+    void updateHwAvSyncId(int hwAvSyncId);
+
+    /**
+     * Get current values of vendor parameters.
+     *
+     * Return current values for the parameters corresponding to the provided ids.
+     *
+     * @param ids Ids of the parameters to retrieve values of.
+     * @return Current values of parameters.
+     * @throws EX_ILLEGAL_ARGUMENT If the stream does not recognize provided ids.
+     * @throws EX_ILLEGAL_STATE If parameter values can not be retrieved at the moment.
+     * @throws EX_UNSUPPORTED_OPERATION If the stream does not support vendor parameters.
+     */
+    VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
+    /**
+     * Set vendor parameters.
+     *
+     * Update values for provided vendor parameters. If the 'async' parameter
+     * is set to 'true', the implementation must return the control back without
+     * waiting for the application of parameters to complete.
+     *
+     * @param parameters Ids and values of parameters to set.
+     * @param async Whether to return from the method as early as possible.
+     * @throws EX_ILLEGAL_ARGUMENT If the stream does not recognize provided parameters.
+     * @throws EX_ILLEGAL_STATE If parameters can not be set at the moment.
+     * @throws EX_UNSUPPORTED_OPERATION If the stream does not support vendor parameters.
+     */
+    void setVendorParameters(in VendorParameter[] parameters, boolean async);
+
+    /**
+     * Apply an audio effect to the stream.
+     *
+     * This method is intended for the cases when the effect has an offload
+     * implementation, since software effects can be applied at the client side.
+     *
+     * @param effect The effect instance.
+     * @throws EX_ILLEGAL_ARGUMENT If the effect reference is invalid.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support audio effects.
+     */
+    void addEffect(in IEffect effect);
+
+    /**
+     * Stop applying an audio effect to the stream.
+     *
+     * Undo the action of the 'addEffect' method.
+     *
+     * @param effect The effect instance.
+     * @throws EX_ILLEGAL_ARGUMENT If the effect reference is invalid, or the effect is
+     *                             not currently applied to the stream.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the module does not support audio effects.
+     */
+    void removeEffect(in IEffect effect);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
new file mode 100644
index 0000000..93cad11
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.hardware.audio.common.SinkMetadata;
+import android.hardware.audio.core.IStreamCommon;
+import android.media.audio.common.MicrophoneDynamicInfo;
+
+/**
+ * This interface provides means for receiving audio data from input devices.
+ */
+@VintfStability
+interface IStreamIn {
+    /**
+     * Return the interface for common stream operations.
+     *
+     * This method must always succeed. The implementation must
+     * return the same instance object for all subsequent calls to
+     * this method.
+     *
+     * @return The interface for common operations.
+     */
+    IStreamCommon getStreamCommon();
+
+    /**
+     * Provides information on the microphones that are active for this stream.
+     *
+     * The returned array contains dynamic information on the microphones which
+     * are active for this stream. Each entry in the returned array must have a
+     * corresponding entry (matched by the 'MicrophoneInfo.id' field value) in
+     * the list of all available microphones which is provided by the
+     * 'IModule.getMicrophones' method.
+     *
+     * This method must be supported by the HAL module if
+     * 'IModule.getMicrophones' is supported.
+     *
+     * @return The vector with dynamic information on the microphones.
+     * @throws EX_ILLEGAL_STATE If the stream has already been closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    MicrophoneDynamicInfo[] getActiveMicrophones();
+
+    @VintfStability
+    @Backing(type="int")
+    enum MicrophoneDirection {
+        /**
+         * Don't do any directionality processing of the activated microphone(s).
+         */
+        UNSPECIFIED = 0,
+        /**
+         * Optimize capture for audio coming from the screen-side of the device.
+         */
+        FRONT = 1,
+        /**
+         * Optimize capture for audio coming from the side of the device opposite the screen.
+         */
+        BACK = 2,
+        /**
+         * Optimize capture for audio coming from an off-device microphone.
+         */
+        EXTERNAL = 3,
+    }
+    /**
+     * Get the current logical microphone direction.
+     *
+     * @return The current logical microphone direction.
+     * @throws EX_ILLEGAL_STATE If the stream has already been closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    MicrophoneDirection getMicrophoneDirection();
+    /**
+     * Set the current logical microphone direction.
+     *
+     * The client sets this parameter in order to specify its preference for
+     * optimizing the direction of capture when multiple microphones are in use.
+     *
+     * @param direction The preferred capture direction.
+     * @throws EX_ILLEGAL_STATE If the stream has already been closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the operation is not supported.
+     */
+    void setMicrophoneDirection(MicrophoneDirection direction);
+
+    const int MIC_FIELD_DIMENSION_WIDE_ANGLE = -1;
+    const int MIC_FIELD_DIMENSION_NO_ZOOM = 0;
+    const int MIC_FIELD_DIMENSION_MAX_ZOOM = 1;
+    /**
+     * Get the "zoom factor" for the logical microphone.
+     *
+     * The returned value must be within the range of [-1.0, 1.0] (see
+     * MIC_FIELD_DIMENSION_* constants).
+     *
+     * @throws EX_ILLEGAL_STATE If the stream has already been closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    float getMicrophoneFieldDimension();
+    /**
+     * Set the "zoom factor" for the logical microphone.
+     *
+     * If multiple microphones are in use, the provided zoom factor must be
+     * treated as a preference for their combined field dimension. The zoom
+     * factor must be within the range of [-1.0, 1.0] (see MIC_FIELD_DIMENSION_*
+     * constants).
+     *
+     * @param zoom The preferred field dimension of the microphone capture.
+     * @throws EX_ILLEGAL_ARGUMENT If the dimension value is outside of the range.
+     * @throws EX_ILLEGAL_STATE If the stream has already been closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the operation is not supported.
+     */
+    void setMicrophoneFieldDimension(float zoom);
+
+    /**
+     * Update stream metadata.
+     *
+     * Updates the metadata initially provided at the stream creation.
+     *
+     * @param sinkMetadata Updated metadata.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     */
+    void updateMetadata(in SinkMetadata sinkMetadata);
+
+    const int HW_GAIN_MIN = 0;
+    const int HW_GAIN_MAX = 1;
+    /**
+     * Retrieve current gain applied in hardware.
+     *
+     * In case when the HAL module has a gain controller, this method returns
+     * the current value of its gain for each input channel.
+     *
+     * The valid range for gain is [0.0f, 1.0f], where 1.0f corresponds to unity
+     * gain, 0.0f corresponds to full mute (see HW_GAIN_* constants).
+     *
+     * @return Current gain values for each input channel.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If hardware gain control is not supported.
+     */
+    float[] getHwGain();
+    /**
+     * Set gain applied in hardware.
+     *
+     * In case when the HAL module has a gain controller, this method sets the
+     * current value of its gain for each input channel.
+     *
+     * The valid range for gain is [0.0f, 1.0f], where 1.0f corresponds to unity
+     * gain, 0.0f corresponds to full mute (see HW_GAIN_* constants).
+     *
+     * @param gain Gain values for each input channel.
+     * @throws EX_ILLEGAL_ARGUMENT If the number of elements in the provided
+     *                             array does not match the channel count, or
+     *                             gain values are out of range.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If hardware gain control is not supported.
+     */
+    void setHwGain(in float[] channelGains);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
new file mode 100644
index 0000000..f26dc1c
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.hardware.audio.common.AudioOffloadMetadata;
+import android.hardware.audio.common.SourceMetadata;
+import android.hardware.audio.core.IStreamCommon;
+import android.media.audio.common.AudioDualMonoMode;
+import android.media.audio.common.AudioLatencyMode;
+import android.media.audio.common.AudioPlaybackRate;
+
+/**
+ * This interface provides means for sending audio data to output devices.
+ */
+@VintfStability
+interface IStreamOut {
+    /**
+     * Return the interface for common stream operations.
+     *
+     * This method must always succeed. The implementation must
+     * return the same instance object for all subsequent calls to
+     * this method.
+     *
+     * @return The interface for common operations.
+     */
+    IStreamCommon getStreamCommon();
+
+    /**
+     * Update stream metadata.
+     *
+     * Updates the metadata initially provided at the stream creation.
+     *
+     * @param sourceMetadata Updated metadata.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     */
+    void updateMetadata(in SourceMetadata sourceMetadata);
+
+    /**
+     * Update offload metadata for a compressed stream.
+     *
+     * Updates the offload metadata initially provided at the stream creation.
+     *
+     * @param offloadMetadata Updated offload metadata.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_ILLEGAL_ARGUMENT If the metadata contains invalid values.
+     * @throws EX_UNSUPPORTED_OPERATION If the stream is not for compressed offload.
+     */
+    void updateOffloadMetadata(in AudioOffloadMetadata offloadMetadata);
+
+    const int HW_VOLUME_MIN = 0;
+    const int HW_VOLUME_MAX = 1;
+    /**
+     * Retrieve current attenuation applied in hardware.
+     *
+     * Hardware attenuation can be used in cases when the client can not, or is
+     * not allowed to modify the audio stream, for example because the stream is
+     * encoded.
+     *
+     * The valid range for attenuation is [0.0f, 1.0f], where 1.0f corresponds
+     * to unity gain, 0.0f corresponds to full mute (see HW_VOLUME_*
+     * constants). The returned array specifies attenuation for each output
+     * channel of the stream.
+     *
+     * Support of hardware volume control is optional.
+     *
+     * @return Current attenuation values for each output channel.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If hardware volume control is not supported.
+     */
+    float[] getHwVolume();
+    /**
+     * Set attenuation applied in hardware.
+     *
+     * Hardware attenuation can be used in cases when the client can not, or is
+     * not allowed to modify the audio stream, for example because the stream is
+     * encoded.
+     *
+     * The valid range for attenuation is [0.0f, 1.0f], where 1.0f corresponds
+     * to unity gain, 0.0f corresponds to full mute (see HW_VOLUME_* constants).
+     *
+     * Support of hardware volume control is optional.
+     *
+     * @param channelVolumes Attenuation values for each output channel.
+     * @throws EX_ILLEGAL_ARGUMENT If the number of elements in the provided
+     *                             array does not match the channel count, or
+     *                             attenuation values are out of range.
+     * @throws EX_ILLEGAL_STATE If the stream is closed or there is any error happens
+                                when applying hardware volume.
+     * @throws EX_UNSUPPORTED_OPERATION If hardware volume control is not supported.
+     */
+    void setHwVolume(in float[] channelVolumes);
+
+    // aidl: Constant of type float is not supported (b/251286924).
+    // const float AUDIO_DESCRIPTION_MIX_LEVEL_MIN = -Inf;
+    const int AUDIO_DESCRIPTION_MIX_LEVEL_MAX = 48;
+    /**
+     * Returns the Audio Description Mix level in dB.
+     *
+     * The level is applied to streams incorporating a secondary Audio
+     * Description stream. It specifies the relative level of mixing for
+     * the Audio Description with a reference to the Main Audio.
+     *
+     * The value of the relative level is in the range from negative infinity
+     * to +48, see AUDIO_DESCRIPTION_MIX_LEVEL_* constants.
+     *
+     * @return The current Audio Description Mix Level in dB.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    float getAudioDescriptionMixLevel();
+    /**
+     * Sets the Audio Description Mix level in dB.
+     *
+     * For streams incorporating a secondary Audio Description stream the
+     * relative level of mixing of the Audio Description to the Main Audio is
+     * controlled by this method.
+     *
+     * The value of the relative level must be in the range from negative
+     * infinity to +48, see AUDIO_DESCRIPTION_MIX_LEVEL_* constants.
+     *
+     * @param leveldB Audio Description Mix Level in dB.
+     * @throws EX_ILLEGAL_ARGUMENT If the provided value is out of range.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If setting of this parameter is not supported.
+     */
+    void setAudioDescriptionMixLevel(float leveldB);
+
+    /**
+     * Returns the Dual Mono mode presentation setting.
+     *
+     * @return The current setting of Dual Mono mode.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    AudioDualMonoMode getDualMonoMode();
+    /**
+     * Sets the Dual Mono mode presentation on the output device.
+     *
+     * The Dual Mono mode is generally applied to stereo audio streams
+     * where the left and right channels come from separate sources.
+     *
+     * @param mode Selected Dual Mono mode.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If setting of this parameter is not supported.
+     */
+    void setDualMonoMode(AudioDualMonoMode mode);
+
+    /**
+     * Retrieve supported latency modes.
+     *
+     * Indicates which latency modes are currently supported on this output
+     * stream. If the transport protocol (for example, Bluetooth A2DP) used by
+     * this output stream to reach the output device supports variable latency
+     * modes, the HAL indicates which modes are currently supported. The client
+     * can then call setLatencyMode() with one of the supported modes to select
+     * the desired operation mode.
+     *
+     * Implementation for this method is mandatory only on specific spatial
+     * audio streams indicated by AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can
+     * be routed to a BT sinks or if the implementation indicates support
+     * on all streams via IModule.supportsVariableLatency().
+     *
+     * @return Currently supported latency modes.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    AudioLatencyMode[] getRecommendedLatencyModes();
+    /**
+     * Sets the latency mode.
+     *
+     * The requested mode must be one of the modes returned by the
+     * 'getRecommendedLatencyModes()' method.
+     *
+     * Implementation for this method is mandatory only on specific spatial
+     * audio streams indicated by AUDIO_OUTPUT_FLAG_SPATIALIZER flag if they can
+     * be routed to a BT sinks or if the implementation indicates support
+     * on all streams via IModule.supportsVariableLatency().
+     *
+     * @throws EX_ILLEGAL_ARGUMENT If the specified mode is not supported.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If setting of this parameter is not supported.
+     */
+    void setLatencyMode(AudioLatencyMode mode);
+
+    /**
+     * Retrieve current playback rate parameters.
+     *
+     * @return Current playback parameters.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If the information is unavailable.
+     */
+    AudioPlaybackRate getPlaybackRateParameters();
+    /**
+     * Set playback rate parameters.
+     *
+     * Sets the playback rate parameters that control playback behavior. This
+     * is normally used when playing encoded content and decoding is performed
+     * in hardware. Otherwise, the client can apply necessary transformations
+     * itself.
+     *
+     * The range of supported values for speed and pitch factors is provided by
+     * the 'IModule.getSupportedPlaybackRateFactors' method. Out of range speed
+     * and pitch values must not be rejected if the fallback mode is 'MUTE'.
+     *
+     * @param playbackRate Playback parameters to set.
+     * @throws EX_ILLEGAL_ARGUMENT If provided parameters are out of acceptable range.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If setting playback rate parameters
+     *                                  is not supported.
+     */
+    void setPlaybackRateParameters(in AudioPlaybackRate playbackRate);
+
+    /**
+     * Select presentation and program from for decoding.
+     *
+     * Selects a presentation for decoding from a next generation media stream
+     * (as defined per ETSI TS 103 190-2) and a program within the presentation.
+     * The client must obtain valid presentation and program IDs from the media
+     * stream on its own.
+     *
+     * @param presentationId Selected audio presentation.
+     * @param programId Refinement for the presentation.
+     * @throws EX_ILLEGAL_ARGUMENT If the HAL module is unable to locate
+     *                             the specified presentation or program in
+     *                             the media stream.
+     * @throws EX_ILLEGAL_STATE If the stream is closed.
+     * @throws EX_UNSUPPORTED_OPERATION If presentation selection is not supported.
+     */
+    void selectPresentation(int presentationId, int programId);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IStreamOutEventCallback.aidl b/audio/aidl/android/hardware/audio/core/IStreamOutEventCallback.aidl
new file mode 100644
index 0000000..75d7385
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IStreamOutEventCallback.aidl
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.media.audio.common.AudioLatencyMode;
+
+/**
+ * This interface provides means for asynchronous notification of the client
+ * by an output stream.
+ */
+@VintfStability
+oneway interface IStreamOutEventCallback {
+    /**
+     * Codec format changed notification.
+     *
+     * onCodecFormatChanged returns an AudioMetadata object in read-only
+     * ByteString format.  It represents the most recent codec format decoded by
+     * a HW audio decoder.
+     *
+     * Codec format is an optional message from HW audio decoders. It serves to
+     * notify the application about the codec format and audio objects contained
+     * within the compressed audio stream for control, informational,
+     * and display purposes.
+     *
+     * audioMetadata ByteString is convertible to an AudioMetadata object
+     * through both a C++ and a C API present in Metadata.h [1], or through a
+     * Java API present in AudioMetadata.java [2].
+     *
+     * The ByteString format is a stable format used for parcelling
+     * (marshalling) across JNI, AIDL, and HIDL interfaces.  The test for R
+     * compatibility for native marshalling is TEST(metadata_tests,
+     * compatibility_R) [3]. The test for R compatibility for JNI marshalling
+     * is android.media.cts.AudioMetadataTest#testCompatibilityR [4].
+     *
+     * Android R defined keys are as follows [2]:
+     * "bitrate", int32
+     * "channel-mask", int32
+     * "mime", string
+     * "sample-rate", int32
+     * "bit-width", int32
+     * "has-atmos", int32
+     * "audio-encoding", int32
+     *
+     * Android S in addition adds the following keys:
+     * "presentation-id", int32
+     * "program-id", int32
+     * "presentation-content-classifier", int32
+     *    presentation-content-classifier key values can be referenced from
+     *    frameworks/base/media/java/android/media/AudioPresentation.java
+     *    i.e. AudioPresentation.ContentClassifier
+     *    It can contain any of the below values
+     *    CONTENT_UNKNOWN   = -1,
+     *    CONTENT_MAIN      =  0,
+     *    CONTENT_MUSIC_AND_EFFECTS = 1,
+     *    CONTENT_VISUALLY_IMPAIRED = 2,
+     *    CONTENT_HEARING_IMPAIRED  = 3,
+     *    CONTENT_DIALOG = 4,
+     *    CONTENT_COMMENTARY = 5,
+     *    CONTENT_EMERGENCY = 6,
+     *    CONTENT_VOICEOVER = 7
+     * "presentation-language", string  // represents ISO 639-2 (three letter code)
+     *
+     * Parceling Format:
+     * All values are native endian order. [1]
+     *
+     * using type_size_t = uint32_t;
+     * using index_size_t = uint32_t;
+     * using datum_size_t = uint32_t;
+     *
+     * Permitted type indexes are
+     * TYPE_NONE = 0, // Reserved
+     * TYPE_INT32 = 1,
+     * TYPE_INT64 = 2,
+     * TYPE_FLOAT = 3,
+     * TYPE_DOUBLE = 4,
+     * TYPE_STRING = 5,
+     * TYPE_DATA = 6,  // A data table of <String, Datum>
+     *
+     * Datum = {
+     *           (type_size_t)  Type (the type index from type_as_value<T>.)
+     *           (datum_size_t) Size (size of the Payload)
+     *           (byte string)  Payload<Type>
+     *         }
+     *
+     * The data is specified in native endian order. Since the size of the
+     * Payload is always present, unknown types may be skipped.
+     *
+     * Payload<Fixed-size Primitive_Value>
+     * [ sizeof(Primitive_Value) in raw bytes ]
+     *
+     * Example of Payload<Int32> of 123:
+     * Payload<Int32>
+     * [ value of 123                   ] =  0x7b 0x00 0x00 0x00       123
+     *
+     * Payload<String>
+     * [ (index_size_t) length, not including zero terminator.]
+     * [ (length) raw bytes ]
+     *
+     * Example of Payload<String> of std::string("hi"):
+     * [ (index_size_t) length          ] = 0x02 0x00 0x00 0x00        2 strlen("hi")
+     * [ raw bytes "hi"                 ] = 0x68 0x69                  "hi"
+     *
+     * Payload<Data>
+     * [ (index_size_t) entries ]
+     * [ raw bytes   (entry 1) Key   (Payload<String>)
+     *                         Value (Datum)
+     *                ...  (until #entries) ]
+     *
+     * Example of Payload<Data> of {{"hello", "world"},
+     *                              {"value", (int32_t)1000}};
+     * [ (index_size_t) #entries        ] = 0x02 0x00 0x00 0x00        2 entries
+     *    Key (Payload<String>)
+     *    [ index_size_t length         ] = 0x05 0x00 0x00 0x00        5 strlen("hello")
+     *    [ raw bytes "hello"           ] = 0x68 0x65 0x6c 0x6c 0x6f   "hello"
+     *    Value (Datum)
+     *    [ (type_size_t) type          ] = 0x05 0x00 0x00 0x00        5 (TYPE_STRING)
+     *    [ (datum_size_t) size         ] = 0x09 0x00 0x00 0x00        sizeof(index_size_t) +
+     *                                                                 strlen("world")
+     *       Payload<String>
+     *       [ (index_size_t) length    ] = 0x05 0x00 0x00 0x00        5 strlen("world")
+     *       [ raw bytes "world"        ] = 0x77 0x6f 0x72 0x6c 0x64   "world"
+     *    Key (Payload<String>)
+     *    [ index_size_t length         ] = 0x05 0x00 0x00 0x00        5 strlen("value")
+     *    [ raw bytes "value"           ] = 0x76 0x61 0x6c 0x75 0x65   "value"
+     *    Value (Datum)
+     *    [ (type_size_t) type          ] = 0x01 0x00 0x00 0x00        1 (TYPE_INT32)
+     *    [ (datum_size_t) size         ] = 0x04 0x00 0x00 0x00        4 sizeof(int32_t)
+     *        Payload<Int32>
+     *        [ raw bytes 1000          ] = 0xe8 0x03 0x00 0x00        1000
+     *
+     * The contents of audioMetadata is a Payload<Data>.
+     * An implementation dependent detail is that the Keys are always
+     * stored sorted, so the byte string representation generated is unique.
+     *
+     * Vendor keys are allowed for informational and debugging purposes.
+     * Vendor keys should consist of the vendor company name followed
+     * by a dot; for example, "vendorCompany.someVolume" [2].
+     *
+     * [1] system/media/audio_utils/include/audio_utils/Metadata.h
+     * [2] frameworks/base/media/java/android/media/AudioMetadata.java
+     * [3] system/media/audio_utils/tests/metadata_tests.cpp
+     * [4] cts/tests/tests/media/src/android/media/cts/AudioMetadataTest.java
+     *
+     * @param audioMetadata A buffer containing decoded format changes
+     *     reported by codec. The buffer contains data that can be transformed
+     *     to audio metadata, which is a C++ object based map.
+     */
+    void onCodecFormatChanged(in byte[] audioMetadata);
+
+    /**
+     * Called with the new list of supported latency modes when a change occurs.
+     */
+    void onRecommendedLatencyModeChanged(in AudioLatencyMode[] modes);
+}
diff --git a/audio/aidl/android/hardware/audio/core/ITelephony.aidl b/audio/aidl/android/hardware/audio/core/ITelephony.aidl
new file mode 100644
index 0000000..7fc1ace
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/ITelephony.aidl
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.media.audio.common.AudioMode;
+import android.media.audio.common.Boolean;
+import android.media.audio.common.Float;
+
+/**
+ * An instance of ITelephony manages settings which are specific to voice calls
+ * and SMS messaging functionality. This interface is optional to implement and
+ * provide by the vendor. It needs to be provided only if the device actually
+ * supports telephony.
+ */
+@VintfStability
+interface ITelephony {
+    /**
+     * Return the list of supported audio modes.
+     *
+     * The first 4 AudioModes: NORMAL, RINGTONE, IN_CALL, IN_COMMUNICATION must
+     * be supported by all implementations.
+     *
+     * This method is only called once, during the audio system initialization,
+     * and must return the same result all the time.
+     *
+     * @return The list of supported audio modes.
+     */
+    AudioMode[] getSupportedAudioModes();
+
+    /**
+     * Switch the HAL into a new audio mode.
+     *
+     * The current audio mode is always controlled by the client. The HAL must
+     * accept all modes returned by 'getSupportedAudioModes' and reject the
+     * rest. The HAL must return from this method only after switching itself
+     * to the specified mode, or throw an error if there was a problem during
+     * switching.
+     *
+     * @param mode The mode to switch to.
+     * @throws EX_UNSUPPORTED_OPERATION If the HAL does not support the specified mode.
+     * @throws EX_ILLEGAL_ARGUMENT If the mode is out of range of valid values.
+     * @throws EX_ILLEGAL_STATE If there was an error during switching.
+     */
+    void switchAudioMode(AudioMode mode);
+
+    @JavaDerive(equals=true, toString=true)
+    @VintfStability
+    parcelable TelecomConfig {
+        const int VOICE_VOLUME_MIN = 0;
+        const int VOICE_VOLUME_MAX = 1;
+        /**
+         * Volume of a voice call. 1.0f means unity gain, 0.0f is muted,
+         * see VOLUME_* constants.
+         */
+        @nullable Float voiceVolume;
+        /**
+         * The current mode of teletypewritter (TTY).
+         */
+        @VintfStability
+        @Backing(type="int")
+        enum TtyMode {
+            /**
+             * The default uninitialized value.
+             */
+            UNSPECIFIED = -1,
+            /**
+             * TTY mode is off.
+             */
+            OFF = 0,
+            /**
+             * TTY mode is on. The speaker is off and the microphone is muted. The
+             * user will communicate with the remote party by sending and receiving
+             * text messages.
+             */
+            FULL = 1,
+            /**
+             * TTY mode is in hearing carryover mode (HCO). The microphone is muted
+             * but the speaker is on. The user will communicate with the remote
+             * party by sending text messages and hearing an audible reply.
+             */
+            HCO = 2,
+            /**
+             * TTY mode is in voice carryover mode (VCO). The speaker is off but the
+             * microphone is still on. User will communicate with the remote party
+             * by speaking and receiving text message replies.
+             */
+            VCO = 3,
+        }
+        TtyMode ttyMode = TtyMode.UNSPECIFIED;
+        /**
+         * Whether Hearing Aid Compatibility - Telecoil (HAC-T) mode is enabled.
+         */
+        @nullable Boolean isHacEnabled;
+    }
+
+    /**
+     * Set the configuration of the telephony audio.
+     *
+     * In the provided parcelable, the client sets zero, one or more parameters
+     * which have to be updated on the HAL side. The parameters that are left
+     * unset must retain their current values.
+     *
+     * In the returned parcelable, all parameter fields known to the HAL module
+     * must be populated to their current values.The client can pass an
+     * uninitialized parcelable in order to retrieve the current configuration.
+     *
+     * @return The current configuration (after update). All fields known to
+     *         the HAL must be populated.
+     * @param config The configuration to set. Any number of fields may be left
+     *               uninitialized.
+     * @throws EX_UNSUPPORTED_OPERATION If telephony is not supported.
+     * @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
+     *                             values is invalid.
+     */
+    TelecomConfig setTelecomConfig(in TelecomConfig config);
+}
diff --git a/audio/aidl/android/hardware/audio/core/MmapBufferDescriptor.aidl b/audio/aidl/android/hardware/audio/core/MmapBufferDescriptor.aidl
new file mode 100644
index 0000000..108bcbe
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/MmapBufferDescriptor.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.hardware.common.Ashmem;
+
+/**
+ * MMap buffer descriptor is used by streams opened in MMap No IRQ mode.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable MmapBufferDescriptor {
+    /**
+     * MMap memory buffer.
+     */
+    Ashmem sharedMemory;
+    /**
+     * Transfer size granularity in frames.
+     */
+    long burstSizeFrames;
+    /**
+     * Attributes describing the buffer. Bitmask indexed by FLAG_INDEX_*
+     * constants.
+     */
+    int flags;
+
+    /**
+     * Whether the buffer can be securely shared to untrusted applications
+     * through the AAudio exclusive mode.
+     *
+     * Only set this flag if applications are restricted from accessing the
+     * memory surrounding the audio data buffer by a kernel mechanism.
+     * See Linux kernel's dma-buf
+     * (https://www.kernel.org/doc/html/v4.16/driver-api/dma-buf.html).
+     */
+    const int FLAG_INDEX_APPLICATION_SHAREABLE = 0;
+}
diff --git a/audio/aidl/android/hardware/audio/core/ModuleDebug.aidl b/audio/aidl/android/hardware/audio/core/ModuleDebug.aidl
new file mode 100644
index 0000000..871a5c9
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/ModuleDebug.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+/**
+ * This structure contains flags used for enabling various debugging aspects
+ * in a HAL module. By default, all debugging aspects are turned off. They
+ * can be enabled during xTS tests for functionality that, for example, would
+ * otherwise require human intervention (e.g. connection of external devices).
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable ModuleDebug {
+    /**
+     * When set to 'true', HAL module must simulate connection of external
+     * devices. An external device becomes 'connected' after a call to
+     * IModule.connectExternalDevice, simulation of connection requires:
+     *  - provision of at least one non-dynamic device port profile on
+     *    connection (as if it was retrieved from a connected device);
+     *  - simulating successful application of port configurations for reported
+     *    profiles.
+     */
+    boolean simulateDeviceConnections;
+    /**
+     * Must be non-negative. When set to non-zero, HAL module must delay
+     * transition from "transient" stream states (see StreamDescriptor.aidl)
+     * by the specified amount of milliseconds. The purpose of this delay
+     * is to allow VTS to test sending of stream commands while the stream is
+     * in a transient state. The delay must apply to newly created streams,
+     * it is not required to apply the delay to already opened streams.
+     *
+     * Note: the drawback of enabling this delay for asynchronous (non-blocking)
+     *       modes is that sending of callbacks will also be delayed, because
+     *       callbacks are sent once the stream state machine exits a transient
+     *       state. Thus, it's not recommended to use it with tests that require
+     *       waiting for an async callback.
+     */
+    int streamTransientStateDelayMs;
+}
diff --git a/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
new file mode 100644
index 0000000..65ea9ef
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.hardware.audio.core.MmapBufferDescriptor;
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.media.audio.common.Void;
+
+/**
+ * Stream descriptor contains fast message queues and buffers used for sending
+ * and receiving audio data. The descriptor complements IStream* interfaces by
+ * providing communication channels that serve as an alternative to Binder
+ * transactions.
+ *
+ * Handling of audio data and commands must be done by the HAL module on a
+ * dedicated thread with high priority, for all modes, including MMap No
+ * IRQ. The HAL module is responsible for creating this thread and setting its
+ * priority. The HAL module is also responsible for serializing access to the
+ * internal components of the stream while serving commands invoked via the
+ * stream's AIDL interface and commands invoked via the command queue of the
+ * descriptor.
+ *
+ * There is a state machine defined for the stream, which executes on the
+ * thread handling the commands from the queue. The states are defined based
+ * on the model of idealized producer and consumer connected via a ring buffer.
+ * For input streams, the "producer" is hardware, the "consumer" is software,
+ * for outputs streams it's the opposite. When the producer is active, but
+ * the buffer is full, the following actions are possible:
+ *  - if the consumer is active, the producer blocks until there is space,
+ *    this behavior is only possible for software producers;
+ *  - if the consumer is passive:
+ *    - the producer can preserve the buffer contents—a s/w producer can
+ *      keep the data on their side, while a h/w producer can only drop captured
+ *      data in this case;
+ *    - or the producer overwrites old data in the buffer.
+ * Similarly, when an active consumer faces an empty buffer, it can:
+ *  - block until there is data (producer must be active), only possible
+ *    for software consumers;
+ *  - walk away with no data; when the consumer is hardware, it must emit
+ *    silence in this case.
+ *
+ * The model is defined below, note the asymmetry regarding the 'IDLE' state
+ * between input and output streams:
+ *
+ *  Producer | Buffer state | Consumer | Applies | State
+ *  active?  |              | active?  | to      |
+ * ==========|==============|==========|=========|==============================
+ *  No       | Empty        | No       | Both    | STANDBY
+ * ----------|--------------|----------|---------|-----------------------------
+ *  Yes      | Filling up   | No       | Input   | IDLE, overwrite behavior
+ * ----------|--------------|----------|---------|-----------------------------
+ *  No       | Empty        | Yes†     | Output  | IDLE, h/w emits silence
+ * ----------|--------------|----------|---------|-----------------------------
+ *  Yes      | Not empty    | Yes      | Both    | ACTIVE, s/w x-runs counted
+ * ----------|--------------|----------|---------|-----------------------------
+ *  Yes      | Filling up   | No       | Input   | PAUSED, drop behavior
+ * ----------|--------------|----------|---------|-----------------------------
+ *  Yes      | Filling up   | No†      | Output  | PAUSED, s/w stops writing once
+ *           |              |          |         | the buffer is filled up;
+ *           |              |          |         | h/w emits silence.
+ * ----------|--------------|----------|---------|-----------------------------
+ *  No       | Not empty    | Yes      | Both    | DRAINING
+ * ----------|--------------|----------|---------|-----------------------------
+ *  No       | Not empty    | No†      | Output  | DRAIN_PAUSED,
+ *           |              |          |         | h/w emits silence.
+ *
+ * † - note that for output, "buffer empty, h/w consuming" has the same outcome
+ *     as "buffer not empty, h/w not consuming", but logically these conditions
+ *     are different.
+ *
+ * State machines of both input and output streams start from the 'STANDBY'
+ * state. Transitions between states happen naturally with changes in the
+ * states of the model elements. For simplicity, we restrict the change to one
+ * element only, for example, in the 'STANDBY' state, either the producer or the
+ * consumer can become active, but not both at the same time. States 'STANDBY',
+ * 'IDLE', 'READY', and '*PAUSED' are "stable"—they require an external event,
+ * whereas a change from the 'DRAINING' state can happen with time as the buffer
+ * gets empty, thus it's a "transient" state.
+ *
+ * The state machine for input streams is defined in the `stream-in-sm.gv` file,
+ * for output streams—in the `stream-out-sm.gv` file. State machines define how
+ * commands (from the enum 'CommandCode') trigger state changes. The full list
+ * of states and commands is defined by constants of the 'State' enum. Note that
+ * the 'CLOSED' state does not have a constant in the interface because the
+ * client can never observe a stream with a functioning command queue in this
+ * state. The 'ERROR' state is a special state which the state machine enters
+ * when an unrecoverable hardware error is detected by the HAL module.
+ *
+ * Non-blocking (asynchronous) modes introduce a new 'TRANSFERRING' state, which
+ * the state machine can enter after replying to the 'burst' command, instead of
+ * staying in the 'ACTIVE' state. In this case the client gets unblocked
+ * earlier, while the actual audio delivery to / from the observer is not
+ * complete yet. Once the HAL module is ready for the next transfer, it notifies
+ * the client via a oneway callback, and the machine switches to 'ACTIVE'
+ * state. The 'TRANSFERRING' state is thus "transient", similar to the
+ * 'DRAINING' state. For output streams, asynchronous transfer can be paused,
+ * and it's another new state: 'TRANSFER_PAUSED'. It differs from 'PAUSED' by
+ * the fact that no new writes are allowed. Please see 'stream-in-async-sm.gv'
+ * and 'stream-out-async-sm.gv' files for details. Below is the table summary
+ * for asynchronous only-states:
+ *
+ *  Producer | Buffer state | Consumer | Applies | State
+ *  active?  |              | active?  | to      |
+ * ==========|==============|==========|=========|==============================
+ *  Yes      | Not empty    | Yes      | Both    | TRANSFERRING, s/w x-runs counted
+ * ----------|--------------|----------|---------|-----------------------------
+ *  Yes      | Not empty    | No       | Output  | TRANSFER_PAUSED,
+ *           |              |          |         | h/w emits silence.
+ *
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable StreamDescriptor {
+    /**
+     * Position binds together a position within the stream and time.
+     *
+     * The timestamp must use "monotonic" clock.
+     *
+     * The frame count must advance between consecutive I/O operations, and stop
+     * advancing when the stream was put into the 'standby' mode. On exiting the
+     * 'standby' mode, the frame count must not reset, but continue counting.
+     */
+    @VintfStability
+    @FixedSize
+    parcelable Position {
+        /**
+         * The value used when the position can not be reported by the HAL
+         * module.
+         */
+        const long UNKNOWN = -1;
+        /** Frame count. */
+        long frames = UNKNOWN;
+        /** Timestamp in nanoseconds. */
+        long timeNs = UNKNOWN;
+    }
+
+    @VintfStability
+    @Backing(type="int")
+    enum State {
+        /**
+         * 'STANDBY' is the initial state of the stream, entered after
+         * opening. Since both the producer and the consumer are inactive in
+         * this state, it allows the HAL module to put associated hardware into
+         * "standby" mode to save power.
+         */
+        STANDBY = 1,
+        /**
+         * In the 'IDLE' state the audio hardware is active. For input streams,
+         * the hardware is filling buffer with captured data, overwriting old
+         * contents on buffer wraparounds. For output streams, the buffer is
+         * still empty, and the hardware is outputting zeroes. The HAL module
+         * must not account for any under- or overruns as the client is not
+         * expected to perform audio I/O.
+         */
+        IDLE = 2,
+        /**
+         * The active state of the stream in which it handles audio I/O. The HAL
+         * module can assume that the audio I/O will be periodic, thus inability
+         * of the client to provide or consume audio data on time must be
+         * considered as an under- or overrun and indicated via the 'xrunFrames'
+         * field of the reply.
+         */
+        ACTIVE = 3,
+        /**
+         * In the 'PAUSED' state the consumer is inactive. For input streams,
+         * the hardware stops updating the buffer as soon as it fills up (this
+         * is the difference from the 'IDLE' state). For output streams,
+         * "inactivity" of hardware means that it does not consume audio data,
+         * but rather emits silence.
+         */
+        PAUSED = 4,
+        /**
+         * In the 'DRAINING' state the producer is inactive, the consumer is
+         * finishing up on the buffer contents, emptying it up. As soon as it
+         * gets empty, the stream transfers itself into the next state.
+         */
+        DRAINING = 5,
+        /**
+         * Used for output streams only, pauses draining. This state is similar
+         * to the 'PAUSED' state, except that the client is not adding any
+         * new data. If it emits a 'burst' command, this brings the stream
+         * into the regular 'PAUSED' state.
+         */
+        DRAIN_PAUSED = 6,
+        /**
+         * Used only for streams in asynchronous mode. The stream enters this
+         * state after receiving a 'burst' command and returning control back
+         * to the client, thus unblocking it.
+         */
+        TRANSFERRING = 7,
+        /**
+         * Used only for output streams in asynchronous mode only. The stream
+         * enters this state after receiving a 'pause' command while being in
+         * the 'TRANSFERRING' state. Unlike 'PAUSED' state, this state does not
+         * accept new writes.
+         */
+        TRANSFER_PAUSED = 8,
+        /**
+         * The ERROR state is entered when the stream has encountered an
+         * irrecoverable error from the lower layer. After entering it, the
+         * stream can only be closed.
+         */
+        ERROR = 100,
+    }
+
+    @VintfStability
+    @Backing(type="byte")
+    enum DrainMode {
+        /**
+         * Unspecified—used with input streams only, because the client controls
+         * draining.
+         */
+        DRAIN_UNSPECIFIED = 0,
+        /**
+         * Used with output streams only, the HAL module indicates drain
+         * completion when all remaining audio data has been consumed.
+         */
+        DRAIN_ALL = 1,
+        /**
+         * Used with output streams only, the HAL module indicates drain
+         * completion shortly before all audio data has been consumed in order
+         * to give the client an opportunity to provide data for the next track
+         * for gapless playback. The exact amount of provided time is specific
+         * to the HAL implementation.
+         */
+        DRAIN_EARLY_NOTIFY = 2,
+    }
+
+    /**
+     * Used for sending commands to the HAL module. The client writes into
+     * the queue, the HAL module reads. The queue can only contain a single
+     * command.
+     *
+     * Variants of type 'Void' correspond to commands without
+     * arguments. Variants of other types correspond to commands with an
+     * argument. Would in future a need for a command with multiple argument
+     * arise, a Parcelable type should be used for the corresponding variant.
+     */
+    @VintfStability
+    @FixedSize
+    union Command {
+        /**
+         * Reserved for the HAL implementation to allow unblocking the wait on a
+         * command and exiting the I/O thread. A command of this variant must
+         * never be sent from the client side. To prevent that, the
+         * implementation must pass a random cookie as the command argument,
+         * which is only known to the implementation.
+         */
+        int halReservedExit;
+        /**
+         * Retrieve the current state of the stream. This command must be
+         * processed by the stream in any state. The stream must provide current
+         * positions, counters, and its state in the reply. This command must be
+         * handled by the HAL module without any observable side effects.
+         */
+        Void getStatus;
+        /**
+         * See the state machines on the applicability of this command to
+         * different states.
+         */
+        Void start;
+        /**
+         * The 'burst' command used for audio I/O, see 'AudioBuffer'. The value
+         * specifies:
+         *
+         *  - for output streams: the amount of bytes that the client requests the
+         *    HAL module to use out of the data contained in the 'audio.fmq' queue.
+         *
+         *  - for input streams: the amount of bytes requested by the client to
+         *    read from the hardware into the 'audio.fmq' queue.
+         *
+         * In both cases it is allowed for this field to contain any
+         * non-negative number. Any sufficiently big value which exceeds the
+         * size of the queue's area which is currently available for reading or
+         * writing by the HAL module must be trimmed by the HAL module to the
+         * available size. Note that the HAL module is allowed to consume or
+         * provide less data than requested, and it must return the amount of
+         * actually read or written data via the 'Reply.fmqByteCount'
+         * field. Thus, only attempts to pass a negative number must be
+         * constituted as a client's error.
+         *
+         * Differences for the MMap No IRQ mode:
+         *
+         *  - this command only provides updated positions and latency because
+         *    actual audio I/O is done via the 'AudioBuffer.mmap' shared buffer.
+         *    The client does not synchronize reads and writes into the buffer
+         *    with sending of this command.
+         *
+         *  - the value must always be set to 0.
+         *
+         * See the state machines on the applicability of this command to
+         * different states.
+         */
+        int burst;
+        /**
+         * See the state machines on the applicability of this command to
+         * different states.
+         */
+        DrainMode drain;
+        /**
+         * See the state machines on the applicability of this command to
+         * different states.
+         *
+         * Note that it's left on the discretion of the HAL implementation to
+         * assess all the necessary conditions that could prevent hardware from
+         * being suspended. Even if it can not be suspended, the state machine
+         * must still enter the 'STANDBY' state for consistency. Since the
+         * buffer must remain empty in this state, even if capturing hardware is
+         * still active, captured data must be discarded.
+         */
+        Void standby;
+        /**
+         * See the state machines on the applicability of this command to
+         * different states.
+         */
+        Void pause;
+        /**
+         * See the state machines on the applicability of this command to
+         * different states.
+         */
+        Void flush;
+    }
+    MQDescriptor<Command, SynchronizedReadWrite> command;
+
+    /**
+     * The value used for the 'Reply.latencyMs' field when the effective
+     * latency can not be reported by the HAL module.
+     */
+    const int LATENCY_UNKNOWN = -1;
+
+    /**
+     * Used for providing replies to commands. The HAL module writes into
+     * the queue, the client reads. The queue can only contain a single reply,
+     * corresponding to the last command sent by the client.
+     */
+    @VintfStability
+    @FixedSize
+    parcelable Reply {
+        /**
+         * One of Binder STATUS_* statuses:
+         *  - STATUS_OK: the command has completed successfully;
+         *  - STATUS_BAD_VALUE: invalid value in the 'Command' structure;
+         *  - STATUS_INVALID_OPERATION: the command is not applicable in the
+         *                              current state of the stream, or to this
+         *                              type of the stream;
+         *  - STATUS_NOT_ENOUGH_DATA: a read or write error has
+         *                            occurred for the 'audio.fmq' queue;
+         */
+        int status;
+        /**
+         * Used with the 'burst' command only.
+         *
+         * For output streams: the amount of bytes of data actually consumed
+         *   by the HAL module.
+         * For input streams: the amount of bytes actually provided by the HAL
+         *   in the 'audio.fmq' queue.
+         *
+         * The returned value must not exceed the value passed as the
+         * argument of the corresponding command, or be negative.
+         */
+        int fmqByteCount;
+        /**
+         * It is recommended to report the current position for any command. If
+         * the position can not be reported, for example because the mix port is
+         * not connected to any producer or consumer, or because the HAL module
+         * does not support positions reporting for this AudioSource (on input
+         * streams), the 'Position::UNKNOWN' value must be used.
+         *
+         * For output streams: the moment when the specified stream position
+         *   was presented to an external observer (i.e. presentation position).
+         * For input streams: the moment when data at the specified stream position
+         *   was acquired (i.e. capture position).
+         *
+         * The observable position must never be reset by the HAL module.
+         * The data type of the frame counter is large enough to support
+         * continuous counting for years of operation.
+         */
+        Position observable;
+        /**
+         * Used only for MMap streams to provide the hardware read / write
+         * position for audio data in the shared memory buffer 'audio.mmap'.
+         */
+        Position hardware;
+        /**
+         * Current latency reported by the hardware. It is recommended to
+         * report the current latency for any command. If the value of latency
+         * can not be determined, this field must be set to 'LATENCY_UNKNOWN'.
+         */
+        int latencyMs;
+        /**
+         * Number of frames lost due to an underrun (for input streams),
+         * or not provided on time (for output streams) for the **previous**
+         * transfer operation.
+         */
+        int xrunFrames;
+        /**
+         * The state that the stream was in while the HAL module was sending the
+         * reply.
+         */
+        State state = State.STANDBY;
+    }
+    MQDescriptor<Reply, SynchronizedReadWrite> reply;
+
+    /**
+     * The size of one frame of audio data in bytes. For PCM formats this is
+     * usually equal to the size of a sample multiplied by the number of
+     * channels used. For encoded bitstreams encapsulated into PCM the sample
+     * size of the underlying PCM stream is used. For encoded bitstreams that
+     * are passed without encapsulation, the frame size is usually 1 byte.
+     */
+    int frameSizeBytes;
+    /**
+     * Total buffer size in frames. This applies both to the size of the 'audio.fmq'
+     * queue and to the size of the shared memory buffer for MMap No IRQ streams.
+     * Note that this size may end up being slightly larger than the size requested
+     * in a call to 'IModule.openInputStream' or 'openOutputStream' due to memory
+     * alignment requirements.
+     */
+    long bufferSizeFrames;
+
+    /**
+     * Used for sending or receiving audio data to/from the stream. In the case
+     * of MMap No IRQ streams this structure only contains the information about
+     * the shared memory buffer. Audio data is sent via the shared buffer
+     * directly.
+     */
+    @VintfStability
+    union AudioBuffer {
+        /**
+         * The fast message queue used for BURST commands in all modes except
+         * MMap No IRQ. Both reads and writes into this queue are non-blocking
+         * because access to this queue is synchronized via the 'command' and
+         * 'reply' queues as described below. The queue nevertheless uses
+         * 'SynchronizedReadWrite' because there is only one reader, and the
+         * reading position must be shared.
+         *
+         * Note that the fast message queue is a transient buffer, only used for
+         * data transfer. Neither of the sides can use it to store any data
+         * outside of the 'BURST' operation. The consumer must always retrieve
+         * all data available in the fast message queue, even if it can not use
+         * it. The producer must re-send any unconsumed data on the next
+         * transfer operation. This restriction is posed in order to make the
+         * fast message queue fully transparent from the latency perspective.
+         *
+         * For output streams the following sequence of operations is used:
+         *  1. The client writes audio data into the 'audio.fmq' queue.
+         *  2. The client writes the BURST command into the 'command' queue,
+         *     and hangs on waiting on a read from the 'reply' queue.
+         *  3. The high priority thread in the HAL module wakes up due to 2.
+         *  4. The HAL module reads the command and audio data. According
+         *     to the statement above, the HAL module must always read
+         *     from the FMQ all the data it contains. The amount of data that
+         *     the HAL module has actually consumed is indicated to the client
+         *     via the 'reply.fmqByteCount' field.
+         *  5. The HAL module writes the command status and current positions
+         *     into 'reply' queue, and hangs on waiting on a read from
+         *     the 'command' queue.
+         *  6. The client wakes up due to 5. and reads the reply.
+         *     Note: in non-blocking mode, when the HAL module goes to
+         *           the 'TRANSFERRING' state (as indicated by the 'reply.state'
+         *           field), the client must wait for the 'IStreamCallback.onTransferReady'
+         *           notification to arrive before starting the next burst.
+         *
+         * For input streams the following sequence of operations is used:
+         *  1. The client writes the BURST command into the 'command' queue,
+         *     and hangs on waiting on a read from the 'reply' queue.
+         *  2. The high priority thread in the HAL module wakes up due to 1.
+         *  3. The HAL module writes audio data into the 'audio.fmq' queue.
+         *     The value of 'reply.fmqByteCount' must be the equal to the amount
+         *     of data in the queue.
+         *  4. The HAL module writes the command status and current positions
+         *     into 'reply' queue, and hangs on waiting on a read from
+         *     the 'command' queue.
+         *  5. The client wakes up due to 4.
+         *  6. The client reads the reply and audio data. The client must
+         *     always read from the FMQ all the data it contains.
+         *     Note: in non-blocking mode, when the HAL module goes to
+         *           the 'TRANSFERRING' state (as indicated by the 'reply.state'
+         *           field) the client must wait for the 'IStreamCallback.onTransferReady'
+         *           notification to arrive before starting the next burst.
+         *
+         */
+        MQDescriptor<byte, SynchronizedReadWrite> fmq;
+        /**
+         * MMap buffers are shared directly with the DSP, which operates
+         * independently from the CPU. Writes and reads into these buffers are
+         * not synchronized with 'command' and 'reply' queues. However, the
+         * client still uses the same commands for controlling the audio data
+         * exchange and for obtaining current positions and latency from the HAL
+         * module.
+         */
+        MmapBufferDescriptor mmap;
+    }
+    AudioBuffer audio;
+}
diff --git a/audio/aidl/android/hardware/audio/core/SurroundSoundConfig.aidl b/audio/aidl/android/hardware/audio/core/SurroundSoundConfig.aidl
new file mode 100644
index 0000000..eeda12a
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/SurroundSoundConfig.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+import android.media.audio.common.AudioFormatDescription;
+
+/**
+ * SurroundSoundConfig defines the multi-channel formats that can be enabled on
+ * (primarily TV) devices.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable SurroundSoundConfig {
+    @VintfStability
+    parcelable SurroundFormatFamily {
+        /**
+         * A primaryFormat shall get an entry in the 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.
+         */
+        AudioFormatDescription primaryFormat;
+        /**
+         * List of formats that shall be equivalent to the primaryFormat from the
+         * users' point of view and don't need a dedicated Surround Settings
+         * dialog entry.
+         */
+        AudioFormatDescription[] subFormats;
+    }
+    SurroundFormatFamily[] formatFamilies;
+}
diff --git a/audio/aidl/android/hardware/audio/core/VendorParameter.aidl b/audio/aidl/android/hardware/audio/core/VendorParameter.aidl
new file mode 100644
index 0000000..206bd9d
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/VendorParameter.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core;
+
+/**
+ * Vendor parameters are used as a lightweight way to pass vendor-specific
+ * configuration data back and forth between the HAL and vendor's extension
+ * to the Android framework, without the need to extend audio interfaces
+ * from AOSP.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable VendorParameter {
+    /**
+     * Vendor-generated unique ID of the parameter. In order to avoid
+     * collisions, vendors must use a vendor-specific prefix for parameter
+     * ids. The Android framework always passes ids as-is, without any attempt
+     * to parse their content.
+     */
+    @utf8InCpp String id;
+    /**
+     * The payload of the parameter.
+     */
+    ParcelableHolder ext;
+}
diff --git a/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl b/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
new file mode 100644
index 0000000..b442ac5
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.core.sounddose;
+
+import android.media.audio.common.AudioDevice;
+
+/**
+ * This interface provides functions related to sound exposure control required for compliance to
+ * EN/IEC 62368-1 3rd edition. Implementing this interface is mandatory for devices for which
+ * compliance to this standard is mandated and implementing audio offload decoding or other direct
+ * playback paths where volume control happens below the audio HAL.
+ */
+@VintfStability
+interface ISoundDose {
+    /**
+     * Max value in dBA used for momentary exposure warnings as defined by IEC62368-1
+     * 3rd edition. This value represents the default RS2 value.
+     */
+    const int DEFAULT_MAX_RS2 = 100;
+    /** Min value of the RS2 threshold in dBA as defined by IEC62368-1 3rd edition. */
+    const int MIN_RS2 = 80;
+
+    /**
+     * Sets the RS2 upper bound used for momentary exposure warnings. Default value is
+     * DEFAULT_MAX_RS2 as specified in IEC62368-1 3rd edition.
+     *
+     * @param rs2ValueDbA custom RS2 upper bound to use
+     * @throws EX_ILLEGAL_ARGUMENT if rs2ValueDbA is greater than DEFAULT_MAX_RS2 or lower
+     *                             than MIN_RS2
+     */
+    void setOutputRs2UpperBound(float rs2ValueDbA);
+
+    /**
+     * Gets the RS2 upper bound used for momentary exposure warnings.
+     *
+     * @return the RS2 upper bound in dBA
+     */
+    float getOutputRs2UpperBound();
+
+    /**
+     * Registers the HAL callback for sound dose computation. If sound dose is supported
+     * the MEL values and exposure notifications will be received through this callback
+     * only. The internal framework MEL computation will be disabled.
+     * It is not possible to unregister the callback. The HAL is responsible to provide
+     * the MEL values throughout its lifecycle.
+     * This method should only be called once (no updates allowed) with a valid callback.
+     *
+     * @param callback to use when new updates are available for sound dose
+     * @throws EX_ILLEGAL_STATE if the method is called more than once
+     * @throws EX_ILLEGAL_ARGUMENT if the passed callback is null
+     */
+    void registerSoundDoseCallback(in IHalSoundDoseCallback callback);
+
+    @VintfStability
+    oneway interface IHalSoundDoseCallback {
+        /**
+         * Called whenever the current MEL value exceeds the set RS2 upper bound.
+         *
+         * @param currentDbA the current MEL value which exceeds the RS2 upper bound
+         * @param audioDevice the audio device where the MEL exposure warning was recorded
+         */
+        void onMomentaryExposureWarning(float currentDbA, in AudioDevice audioDevice);
+
+        @VintfStability
+        parcelable MelRecord {
+            /**
+             * Array of continuously recorded MEL values >= MIN_RS2 (1 per second).
+             * First value in the array was recorded at 'timestamp'.
+             */
+            float[] melValues;
+            /**
+             * Corresponds to the time in seconds, as reported by CLOCK_MONOTONIC, when
+             * the first MEL entry in melValues was recorded. The timestamp values have
+             * to be consistent throughout all audio ports, equal timestamp values will
+             * be aggregated.
+             */
+            long timestamp;
+        }
+
+        /**
+         * Provides a MelRecord containing continuous MEL values sorted by timestamp.
+         * Note that all the MEL values originate from the audio device specified by audioDevice.
+         * In case values from multiple devices need to be reported, the caller should execute
+         * this callback once for every device.
+         *
+         * @param melRecord contains the MEL values used for CSD
+         * @param audioDevice the audio device where the MEL values were recorded
+         */
+        void onNewMelValues(in MelRecord melRecord, in AudioDevice audioDevice);
+    }
+}
diff --git a/audio/aidl/android/hardware/audio/core/stream-in-async-sm.gv b/audio/aidl/android/hardware/audio/core/stream-in-async-sm.gv
new file mode 100644
index 0000000..818b18e
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/stream-in-async-sm.gv
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// To render: dot -Tpng stream-in-async-sm.gv -o stream-in-async-sm.png
+digraph stream_in_async_state_machine {
+    node [shape=doublecircle style=filled fillcolor=black width=0.5] I;
+    node [shape=point width=0.5] F;
+    node [shape=oval width=1];
+    node [fillcolor=lightgreen] STANDBY;  // buffer is empty
+    node [fillcolor=tomato] CLOSED;
+    node [fillcolor=tomato] ERROR;
+    node [style=dashed] ANY_STATE;
+    node [fillcolor=lightblue style=filled];
+    // Note that when the producer (h/w) is passive, "burst" operations
+    // complete synchronously, bypassing the TRANSFERRING state.
+    I -> STANDBY;
+    STANDBY -> IDLE [label="start"];           // producer -> active
+    IDLE -> STANDBY [label="standby"];         // producer -> passive, buffer is cleared
+    IDLE -> TRANSFERRING [label="burst"];      // consumer -> active
+    ACTIVE -> PAUSED [label="pause"];          // consumer -> passive
+    ACTIVE -> DRAINING [label="drain"];        // producer -> passive
+    ACTIVE -> TRANSFERRING [label="burst"];
+    TRANSFERRING -> ACTIVE [label="←IStreamCallback.onTransferReady"];
+    TRANSFERRING -> PAUSED [label="pause"];    // consumer -> passive
+    TRANSFERRING -> DRAINING [label="drain"];  // producer -> passive
+    PAUSED -> TRANSFERRING [label="burst"];    // consumer -> active
+    PAUSED -> STANDBY [label="flush"];         // producer -> passive, buffer is cleared
+    DRAINING -> DRAINING [label="burst"];
+    DRAINING -> ACTIVE [label="start"];      // producer -> active
+    DRAINING -> STANDBY [label="<empty buffer>"];  // consumer deactivates
+    IDLE -> ERROR [label="←IStreamCallback.onError"];
+    PAUSED -> ERROR [label="←IStreamCallback.onError"];
+    TRANSFERRING -> ERROR [label="←IStreamCallback.onError"];
+    ANY_STATE -> CLOSED [label="→IStream*.close"];
+    CLOSED -> F;
+}
diff --git a/audio/aidl/android/hardware/audio/core/stream-in-sm.gv b/audio/aidl/android/hardware/audio/core/stream-in-sm.gv
new file mode 100644
index 0000000..805dc32
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/stream-in-sm.gv
@@ -0,0 +1,42 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// To render: dot -Tpng stream-in-sm.gv -o stream-in-sm.png
+digraph stream_in_state_machine {
+    node [shape=doublecircle style=filled fillcolor=black width=0.5] I;
+    node [shape=point width=0.5] F;
+    node [shape=oval width=1];
+    node [fillcolor=lightgreen] STANDBY;  // buffer is empty
+    node [fillcolor=tomato] CLOSED;
+    node [fillcolor=tomato] ERROR;
+    node [style=dashed] ANY_STATE;
+    node [fillcolor=lightblue style=filled];
+    I -> STANDBY;
+    STANDBY -> IDLE [label="start"];    // producer -> active
+    IDLE -> STANDBY [label="standby"];  // producer -> passive, buffer is cleared
+    IDLE -> ACTIVE [label="burst"];     // consumer -> active
+    ACTIVE -> ACTIVE [label="burst"];
+    ACTIVE -> PAUSED [label="pause"];   // consumer -> passive
+    ACTIVE -> DRAINING [label="drain"]; // producer -> passive
+    PAUSED -> ACTIVE [label="burst"];   // consumer -> active
+    PAUSED -> STANDBY [label="flush"];  // producer -> passive, buffer is cleared
+    DRAINING -> DRAINING [label="burst"];
+    DRAINING -> ACTIVE [label="start"];  // producer -> active
+    DRAINING -> STANDBY [label="<empty buffer>"];  // consumer deactivates
+    IDLE -> ERROR [label="<hardware failure>"];
+    ACTIVE -> ERROR [label="<hardware failure>"];
+    PAUSED -> ERROR [label="<hardware failure>"];
+    ANY_STATE -> CLOSED [label="→IStream*.close"];
+    CLOSED -> F;
+}
diff --git a/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv b/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
new file mode 100644
index 0000000..501dc01
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
@@ -0,0 +1,59 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// To render: dot -Tpng stream-out-async-sm.gv -o stream-out-async-sm.png
+digraph stream_out_async_state_machine {
+    node [shape=doublecircle style=filled fillcolor=black width=0.5] I;
+    node [shape=point width=0.5] F;
+    node [shape=oval width=1];
+    node [fillcolor=lightgreen] STANDBY;  // buffer is empty
+    node [fillcolor=lightgreen] IDLE;     // buffer is empty
+    node [fillcolor=tomato] CLOSED;
+    node [fillcolor=tomato] ERROR;
+    node [style=dashed] ANY_STATE;
+    node [fillcolor=lightblue style=filled];
+    // Note that when the consumer (h/w) is passive, "burst" operations
+    // complete synchronously, bypassing the TRANSFERRING state.
+    I -> STANDBY;
+    STANDBY -> IDLE [label="start"];                  // consumer -> active
+    STANDBY -> PAUSED [label="burst"];                // producer -> active
+    IDLE -> STANDBY [label="standby"];                // consumer -> passive
+    IDLE -> TRANSFERRING [label="burst"];             // producer -> active
+    IDLE -> ACTIVE [label="burst"];                   // full write
+    ACTIVE -> PAUSED [label="pause"];                 // consumer -> passive (not consuming)
+    ACTIVE -> DRAINING [label="drain"];               // producer -> passive
+    ACTIVE -> TRANSFERRING [label="burst"];           // early unblocking
+    ACTIVE -> ACTIVE [label="burst"];                 // full write
+    TRANSFERRING -> ACTIVE [label="←IStreamCallback.onTransferReady"];
+    TRANSFERRING -> TRANSFER_PAUSED [label="pause"];  // consumer -> passive (not consuming)
+    TRANSFERRING -> DRAINING [label="drain"];         // producer -> passive
+    TRANSFER_PAUSED -> TRANSFERRING [label="start"];  // consumer -> active
+    TRANSFER_PAUSED -> DRAIN_PAUSED [label="drain"];  // producer -> passive
+    TRANSFER_PAUSED -> IDLE [label="flush"];          // buffer is cleared
+    PAUSED -> PAUSED [label="burst"];
+    PAUSED -> ACTIVE [label="start"];                 // consumer -> active
+    PAUSED -> IDLE [label="flush"];                   // producer -> passive, buffer is cleared
+    DRAINING -> IDLE [label="←IStreamCallback.onDrainReady"];
+    DRAINING -> TRANSFERRING [label="burst"];         // producer -> active
+    DRAINING -> ACTIVE [label="burst"];               // full write
+    DRAINING -> DRAIN_PAUSED [label="pause"];         // consumer -> passive (not consuming)
+    DRAIN_PAUSED -> DRAINING [label="start"];         // consumer -> active
+    DRAIN_PAUSED -> TRANSFER_PAUSED [label="burst"];  // producer -> active
+    DRAIN_PAUSED -> IDLE [label="flush"];             // buffer is cleared
+    IDLE -> ERROR [label="←IStreamCallback.onError"];
+    DRAINING -> ERROR [label="←IStreamCallback.onError"];
+    TRANSFERRING -> ERROR [label="←IStreamCallback.onError"];
+    ANY_STATE -> CLOSED [label="→IStream*.close"];
+    CLOSED -> F;
+}
diff --git a/audio/aidl/android/hardware/audio/core/stream-out-sm.gv b/audio/aidl/android/hardware/audio/core/stream-out-sm.gv
new file mode 100644
index 0000000..47e7fda
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/stream-out-sm.gv
@@ -0,0 +1,49 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// To render: dot -Tpng stream-out-sm.gv -o stream-out-sm.png
+digraph stream_out_state_machine {
+    node [shape=doublecircle style=filled fillcolor=black width=0.5] I;
+    node [shape=point width=0.5] F;
+    node [shape=oval width=1];
+    node [fillcolor=lightgreen] STANDBY;  // buffer is empty
+    node [fillcolor=lightgreen] IDLE;     // buffer is empty
+    node [fillcolor=tomato] CLOSED;
+    node [fillcolor=tomato] ERROR;
+    node [style=dashed] ANY_STATE;
+    node [fillcolor=lightblue style=filled];
+    I -> STANDBY;
+    STANDBY -> IDLE [label="start"];           // consumer -> active
+    STANDBY -> PAUSED [label="burst"];         // producer -> active
+    IDLE -> STANDBY [label="standby"];         // consumer -> passive
+    IDLE -> ACTIVE [label="burst"];            // producer -> active
+    ACTIVE -> ACTIVE [label="burst"];
+    ACTIVE -> PAUSED [label="pause"];          // consumer -> passive (not consuming)
+    ACTIVE -> DRAINING [label="drain"];        // producer -> passive
+    ACTIVE -> IDLE [label="drain"];            // synchronous drain
+    PAUSED -> PAUSED [label="burst"];
+    PAUSED -> ACTIVE [label="start"];          // consumer -> active
+    PAUSED -> IDLE [label="flush"];            // producer -> passive, buffer is cleared
+    DRAINING -> IDLE [label="<empty buffer>"];
+    DRAINING -> ACTIVE [label="burst"];        // producer -> active
+    DRAINING -> DRAIN_PAUSED [label="pause"];  // consumer -> passive (not consuming)
+    DRAIN_PAUSED -> DRAINING [label="start"];  // consumer -> active
+    DRAIN_PAUSED -> PAUSED [label="burst"];    // producer -> active
+    DRAIN_PAUSED -> IDLE [label="flush"];      // buffer is cleared
+    IDLE -> ERROR [label="<hardware failure>"];
+    ACTIVE -> ERROR [label="<hardware failure>"];
+    DRAINING -> ERROR [label="<hardware failure>"];
+    ANY_STATE -> CLOSED [label="→IStream*.close"];
+    CLOSED -> F;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl b/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl
new file mode 100644
index 0000000..bf1f8a2
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Acoustic Echo Canceler (AEC) is an audio pre-processor which removes the contribution of the
+ * signal received from the remote party from the captured audio signal.
+ *
+ * All parameter settings must be inside the range of Capability.Range.acousticEchoCanceler
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
+ */
+@VintfStability
+union AcousticEchoCanceler {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        AcousticEchoCanceler.Tag commonTag;
+    }
+
+    /**
+     * Vendor AEC implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * The AEC echo delay in microseconds.
+     */
+    int echoDelayUs;
+    /**
+     * Indicate if the AEC mobile mode is enabled or not.
+     * If an effect implementation supports enabling and disabling mobileMode at runtime, it does
+     * not need to set the min and max range for mobileMode, or report the mobileMode min/max range
+     * as [false, true] in Range.AcousticEchoCancelerRange. If the effect implementation doesn't
+     * support mobileMode, it must report the mobileMode range as [false, false]. If the effect
+     * implementation supports mobileMode and cannot be disabled, it must report the mobileMode
+     * range as [true, true].
+     * If the effect implementation sets the range as invalid: [true, false], it indicates that
+     * mobileMode setParameter is not supported, and clients can only use getParameter to check if
+     * it's enabled or not.
+     */
+    boolean mobileMode;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl
new file mode 100644
index 0000000..e7bf99d
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Automatic Gain Control (AGC) is an audio pre-processor which automatically normalizes the output
+ * of the captured signal by boosting or lowering input from the microphone to match a preset level
+ * so that the output signal level is virtually constant. AGC can be used by applications where the
+ * input signal dynamic range is not important but where a constant strong capture level is desired.
+ *
+ * All parameter settings must be inside the range of Capability.Range.automaticGainControlV1
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
+ */
+@VintfStability
+union AutomaticGainControlV1 {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        AutomaticGainControlV1.Tag commonTag;
+    }
+
+    /**
+     * Vendor AutomaticGainControlV1 implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * Target peak level (or envelope) of the AGC implementation in dBFs (dB relative to full
+     * scale).
+     */
+    int targetPeakLevelDbFs;
+    /*
+     * Sets the maximum gain the digital compression stage may apply, in dB. A higher number
+     * corresponds to greater compression, while a value of 0 will leave the signal uncompressed.
+     */
+    int maxCompressionGainDb;
+    /**
+     * Enable or disable limiter.
+     * When enabled, the compression stage will hard limit the signal to the target level.
+     * Otherwise, the signal will be compressed but not limited above the target level.
+     */
+    boolean enableLimiter;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV2.aidl b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV2.aidl
new file mode 100644
index 0000000..8f2afdc
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV2.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Automatic Gain Control V2 (AGC2) is an audio pre-processor which automatically normalizes the
+ * output of the captured signal by boosting or lowering input from the microphone to match a preset
+ * level so that the output signal level is virtually constant. AGC can be used by applications
+ * where the input signal dynamic range is not important but where a constant strong capture level
+ * is desired.
+ *
+ * All parameter settings must be inside the range of Capability.Range.automaticGainControlV2
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
+ */
+@VintfStability
+union AutomaticGainControlV2 {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        AutomaticGainControlV2.Tag commonTag;
+    }
+
+    /**
+     * Vendor AutomaticGainControlV2 implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    @VintfStability
+    @Backing(type="int")
+    enum LevelEstimator {
+        /* Use Root Mean Square level estimator*/
+        RMS = 0,
+        /* Use Peak level estimator*/
+        PEAK = 1,
+    }
+
+    /**
+     * The AGC fixed digital gain in millibel.
+     */
+    int fixedDigitalGainMb;
+    /*
+     * Adaptive digital level estimator.
+     */
+    LevelEstimator levelEstimator;
+    /**
+     * The AGC saturation margin in millibel.
+     */
+    int saturationMarginMb;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
new file mode 100644
index 0000000..479db96
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Bass boost is an audio effect to boost or amplify low frequencies of the sound. It is comparable
+ * to a simple equalizer but limited to one band amplification in the low frequency range.
+ *
+ * All parameter settings must be inside the range of Capability.Range.bassBoost definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
+ */
+@VintfStability
+union BassBoost {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        BassBoost.Tag commonTag;
+    }
+
+    /**
+     * Vendor BassBoost implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * The per mille strength of the bass boost effect.
+     *
+     * If the implementation does not support per mille accuracy for setting the strength, it is
+     * allowed to round the given strength to the nearest supported value. In this case {@link
+     * #IEffect.getParameter()} method should return the rounded value that was actually set.
+     */
+    int strengthPm;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Capability.aidl b/audio/aidl/android/hardware/audio/effect/Capability.aidl
new file mode 100644
index 0000000..06c2024
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Capability.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.Range;
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Effect capability definitions.
+ * This data structure is used as part of effect Descriptor to identify effect capabilities which
+ * not meant to change at runtime.
+ */
+@VintfStability
+parcelable Capability {
+    /**
+     * Vendor defined effect capability.
+     * This extension can be used when vendor has a new effect implementation and needs
+     * capability definition for this new type of effect.
+     * If vendor want to extend existing effect capabilities, it is recommended to expose through
+     * the ParcelableHolder in each effect definition. For example: Equalizer.vendorExtension. And
+     * define an appropriate Range for the extension.
+     */
+    VendorExtension vendorExtension;
+
+    /**
+     * Supported range for parameters. See Range.aidl.
+     */
+    Range range;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/CommandId.aidl b/audio/aidl/android/hardware/audio/effect/CommandId.aidl
new file mode 100644
index 0000000..d940b42
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/CommandId.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+/**
+ * Defines all commands supported by the effect instance.
+ *
+ * There are three groups of commands:
+ * 1. Common part which MUST be supported by all effects.
+ * 2. Commands MUST be supported by a specific type of effect.
+ * 3. Extension commands for vendor.
+ */
+@VintfStability
+@Backing(type="int")
+enum CommandId {
+    /**
+     * Commands MUST be supported by all effects.
+     */
+    /**
+     * Start effect engine processing.
+     * An effect instance must start processing data and transfer to PROCESSING state if it is in
+     * IDLE state and have all necessary information. Otherwise it must:
+     * 1. Throw a EX_ILLEGAL_STATE exception if effect is not in IDLE state, or
+     * 2. Throw a EX_TRANSACTION_FAILED for all other errors.
+     *
+     * Depending on parameters set to the effect instance, effect may do process or reverse
+     * process after START command.
+     */
+    START = 0,
+    /**
+     * Stop effect engine processing with all resource kept.
+     * The currently processed audio data will be discarded if the effect engine is in PROCESSING
+     * state.
+     * Effect instance must do nothing and return ok when it receive STOP command in IDLE state.
+     */
+    STOP = 1,
+    /**
+     * Keep all parameter settings but reset the buffer content, stop engine processing, and transit
+     * instance state to IDLE if its in PROCESSING state.
+     * Effect instance must be able to handle RESET command at IDLE and PROCESSING states.
+     */
+    RESET = 2,
+
+    /**
+     * Commands MUST be supported by a specific type of effect.
+     */
+
+    /**
+     * Extension commands for vendor.
+     */
+    VENDOR_COMMAND_0 = 0x100,
+    VENDOR_COMMAND_1,
+    VENDOR_COMMAND_2,
+    VENDOR_COMMAND_3,
+    VENDOR_COMMAND_4,
+    VENDOR_COMMAND_5,
+    VENDOR_COMMAND_6,
+    VENDOR_COMMAND_7,
+    VENDOR_COMMAND_8,
+    VENDOR_COMMAND_9,
+}
diff --git a/audio/aidl/android/hardware/audio/effect/DefaultExtension.aidl b/audio/aidl/android/hardware/audio/effect/DefaultExtension.aidl
new file mode 100644
index 0000000..33e827f
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/DefaultExtension.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+/**
+ * The default extension used for Parameter.Specific.vendorEffect ParcelableHolder.
+ *
+ * The audio framework attach this default extension to the ParcelableHolder in VendorExtension,
+ * and pass though all parameters it received from the client to audio HAL.
+ *
+ * For now it's not possible for vendor to define their own vendor extensions without changing the
+ * audio framework. More specificly, in order to add a customized effect parameter AIDL parcelable,
+ * vendors need to add the logic for conversion between AIDL and effect_param_t for the effect AIDL
+ * in: frameworks/av/media/libaudiohal/impl/effectAidlConversion.
+ *
+ * There is no VTS test cases for the vendor extension effect implementation, however all effect
+ * implementations must support the common parameters defined in Parameter.aidl, so vendor
+ * extension effect implementation still need to support setting and getting of these common
+ * parameters, which is enforced by VTS.
+ */
+@VintfStability
+parcelable DefaultExtension {
+    byte[] bytes;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
new file mode 100644
index 0000000..b152f76
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.Capability;
+import android.hardware.audio.effect.Flags;
+import android.media.audio.common.AudioUuid;
+
+/**
+ * Descriptor contains all information (capabilities, attributes, etc) for an effect implementation.
+ * The client uses this information to decide when and how to apply an effect implementation.
+ *
+ * Each type of effect can have more than one implementation (differentiated by implementation
+ * UUID), the effect proxy act as a combination of two implementations (usually one software and
+ * one offload implementation), so effect processing can be seamlessly switched between
+ * implementations in same proxy depending on the configuration and/or use case. If the optional
+ * proxy UUID is specified in Descriptor.Identity, then client must consider the effect instance as
+ * part of the effect proxy.
+ */
+@VintfStability
+parcelable Descriptor {
+    /**
+     * UUID for effect types, these definitions are in sync with SDK, see @c AudioEffect.java.
+     */
+    /**
+     * UUID for Acoustic Echo Canceler (AEC) type.
+     */
+    const String EFFECT_TYPE_UUID_AEC = "7b491460-8d4d-11e0-bd61-0002a5d5c51b";
+
+    /**
+     * UUID for Automatic Gain Control V1 (AGC1) type.
+     */
+    const String EFFECT_TYPE_UUID_AGC1 = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
+    /**
+     * UUID for Automatic Gain Control V2 (AGC2) type.
+     */
+    const String EFFECT_TYPE_UUID_AGC2 = "ae3c653b-be18-4ab8-8938-418f0a7f06ac";
+    /**
+     * UUID for bass boost effect type.
+     */
+    const String EFFECT_TYPE_UUID_BASS_BOOST = "0634f220-ddd4-11db-a0fc-0002a5d5c51b";
+    /**
+     * UUID for downmix effect type.
+     */
+    const String EFFECT_TYPE_UUID_DOWNMIX = "381e49cc-a858-4aa2-87f6-e8388e7601b2";
+    /**
+     * UUID for Dynamics Processing type.
+     */
+    const String EFFECT_TYPE_UUID_DYNAMICS_PROCESSING = "7261676f-6d75-7369-6364-28e2fd3ac39e";
+    /**
+     * UUID for environmental reverberation effect type.
+     */
+    const String EFFECT_TYPE_UUID_ENV_REVERB = "c2e5d5f0-94bd-4763-9cac-4e234d06839e";
+    /**
+     * UUID for equalizer effect type.
+     */
+    const String EFFECT_TYPE_UUID_EQUALIZER = "0bed4300-ddd6-11db-8f34-0002a5d5c51b";
+    /**
+     * UUID for Haptic Generator type.
+     */
+    const String EFFECT_TYPE_UUID_HAPTIC_GENERATOR = "1411e6d6-aecd-4021-a1cf-a6aceb0d71e5";
+    /**
+     * UUID for Loudness Enhancer type.
+     */
+    const String EFFECT_TYPE_UUID_LOUDNESS_ENHANCER = "fe3199be-aed0-413f-87bb-11260eb63cf1";
+    /**
+     * UUID for Noise Suppressor (NS) type.
+     */
+    const String EFFECT_TYPE_UUID_NS = "58b4b260-8e06-11e0-aa8e-0002a5d5c51b";
+    /**
+     * UUID for preset reverberation effect type.
+     */
+    const String EFFECT_TYPE_UUID_PRESET_REVERB = "47382d60-ddd8-11db-bf3a-0002a5d5c51b";
+    /**
+     * UUID for Spatializer type.
+     */
+    const String EFFECT_TYPE_UUID_SPATIALIZER = "ccd4cf09-a79d-46c2-9aae-06a1698d6c8f";
+    /**
+     * UUID for virtualizer effect type.
+     */
+    const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
+    /**
+     * UUID for visualizer effect type.
+     */
+    const String EFFECT_TYPE_UUID_VISUALIZER = "e46b26a0-dddd-11db-8afd-0002a5d5c51b";
+    /**
+     * UUID for Volume effect type.
+     */
+    const String EFFECT_TYPE_UUID_VOLUME = "09e8ede0-ddde-11db-b4f6-0002a5d5c51b";
+
+    /**
+     * This structure completely identifies an effect implementation.
+     */
+    @VintfStability
+    parcelable Identity {
+        /**
+         * UUID for the type of effect.
+         */
+        AudioUuid type;
+        /**
+         * UUID for this particular implementation.
+         */
+        AudioUuid uuid;
+        /**
+         * Optional proxy UUID. This field must be set to the proxy effect type UUID if the effect
+         * implementation is part of a proxy effect.
+         */
+        @nullable AudioUuid proxy;
+    }
+
+    /**
+     * Common attributes of all effect implementation.
+     */
+    @VintfStability
+    parcelable Common {
+        /**
+         * Identity of effect implementation.
+         */
+        Identity id;
+        /**
+         * Capability flags defined for the effect implementation.
+         */
+        Flags flags;
+        /**
+         * CPU load indication expressed in 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE)
+         * with 0 WS.
+         */
+        int cpuLoad;
+        /**
+         * Data memory usage expressed in KB and includes only dynamically allocated memory.
+         */
+        int memoryUsage;
+        /**
+         * Human readable effect name, no intended to display on UI directly.
+         */
+        @utf8InCpp String name;
+        /**
+         * Human readable effect implementor name, no intended to display on UI directly.
+         */
+        @utf8InCpp String implementor;
+    }
+    Common common;
+
+    /**
+     * Effect implementation capability.
+     */
+    Capability capability;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Downmix.aidl b/audio/aidl/android/hardware/audio/effect/Downmix.aidl
new file mode 100644
index 0000000..90fd4c7
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Downmix.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Downmix specific definitions.
+ *
+ * All parameter settings must be inside the range of Capability.Range.downmix definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
+ */
+@VintfStability
+union Downmix {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        Downmix.Tag commonTag;
+    }
+
+    /**
+     * Vendor Downmix implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    @VintfStability
+    enum Type {
+        /**
+         * Throw away the extra channels.
+         */
+        STRIP,
+        /**
+         * Mix the extra channels with FL/FR.
+         */
+        FOLD,
+    }
+
+    /**
+     * Type of downmix.
+     */
+    Type type;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl b/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl
new file mode 100644
index 0000000..5aea211
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * DynamicsProcessing specific definitions.
+ *
+ * All parameter settings must be inside the range of Capability.Range.dynamicsProcessing definition
+ * if the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
+ */
+@VintfStability
+union DynamicsProcessing {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        DynamicsProcessing.Tag commonTag;
+    }
+
+    /**
+     * Vendor DynamicsProcessing implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * Resolution preference definition.
+     */
+    enum ResolutionPreference {
+        /**
+         * Favors frequency domain based implementation.
+         */
+        FAVOR_FREQUENCY_RESOLUTION,
+        /**
+         * Favors tme domain based implementation.
+         */
+        FAVOR_TIME_RESOLUTION,
+    }
+
+    /**
+     * Stage enablement configuration.
+     */
+    @VintfStability
+    parcelable StageEnablement {
+        /**
+         * True if stage is in use.
+         */
+        boolean inUse;
+        /**
+         * Number of bands configured for this stage. Must be positive when inUse is true.
+         */
+        int bandCount;
+    }
+
+    /**
+     * Effect engine configuration. Set the enablement of all stages.
+     */
+    @VintfStability
+    parcelable EngineArchitecture {
+        /**
+         * Resolution preference.
+         */
+        ResolutionPreference resolutionPreference = ResolutionPreference.FAVOR_FREQUENCY_RESOLUTION;
+        /**
+         * Preferred processing duration in milliseconds (ms). Must not be negative, 0 means no
+         * preference.
+         */
+        float preferredProcessingDurationMs;
+        /**
+         * PreEq stage (Multi-band Equalizer) configuration.
+         */
+        StageEnablement preEqStage;
+        /**
+         * PostEq stage (Multi-band Equalizer) configuration.
+         */
+        StageEnablement postEqStage;
+        /**
+         * MBC stage (Multi-band Compressor) configuration.
+         */
+        StageEnablement mbcStage;
+        /**
+         * True if Limiter stage is in use.
+         */
+        boolean limiterInUse;
+    }
+
+    /**
+     * Enablement configuration for a specific channel.
+     */
+    @VintfStability
+    parcelable ChannelConfig {
+        /**
+         * Channel index. Must not be negative, and not exceed the channel count calculated from
+         * Parameter.common.input.base.channelMask.
+         */
+        int channel;
+        /**
+         * Channel enablement configuration. Can not be true if corresponding stage is not in use.
+         */
+        boolean enable;
+    }
+
+    /**
+     * Equalizer band configuration for a specific channel and band.
+     */
+    @VintfStability
+    parcelable EqBandConfig {
+        /**
+         * Channel index. Must not be negative, and not exceed the channel count calculated from
+         * Parameter.common.input.base.channelMask.
+         */
+        int channel;
+        /**
+         * Band index, must in the range of [0, bandCount-1].
+         */
+        int band;
+        /**
+         * True if EQ band is enabled.
+         * If EngineArchitecture EQ stage inUse was set to false, then enable can not be set to
+         * true.
+         */
+        boolean enable;
+        /**
+         * Topmost frequency number (in Hz) this band will process.
+         */
+        float cutoffFrequencyHz;
+        /**
+         * Gain factor in decibels (dB).
+         */
+        float gainDb;
+    }
+
+    /**
+     * MBC configuration for a specific channel and band.
+     */
+    @VintfStability
+    parcelable MbcBandConfig {
+        /**
+         * Channel index. Must not be negative, and not exceed the channel count calculated from
+         * Parameter.common.input.base.channelMask.
+         */
+        int channel;
+        /**
+         * Band index. Must be in the range of [0, bandCount-1].
+         */
+        int band;
+        /**
+         * True if MBC band is enabled.
+         * If EngineArchitecture MBC inUse was set to false, then enable here can not be set to
+         * true.
+         */
+        boolean enable;
+        /**
+         * Topmost frequency number (in Hz) this band will process.
+         */
+        float cutoffFrequencyHz;
+        /**
+         * Attack Time for compressor in milliseconds (ms). Must not be negative.
+         */
+        float attackTimeMs;
+        /**
+         * Release Time for compressor in milliseconds (ms). Must not be negative.
+         */
+        float releaseTimeMs;
+        /**
+         * Compressor ratio (N:1) (input:output). Must not be negative.
+         */
+        float ratio;
+        /**
+         * Compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS).  Must not be
+         * positive.
+         */
+        float thresholdDb;
+        /**
+         * Width in decibels (dB) around compressor threshold point. Must not be negative.
+         */
+        float kneeWidthDb;
+        /**
+         * Noise gate threshold in decibels (dB) from 0 dB Full Scale (dBFS). Must not be positive.
+         */
+        float noiseGateThresholdDb;
+        /**
+         * Expander ratio (1:N) (input:output) for signals below the Noise Gate Threshold. Must not
+         * be negative.
+         */
+        float expanderRatio;
+        /**
+         * Gain applied to the signal BEFORE the compression in dB.
+         */
+        float preGainDb;
+        /**
+         * Gain applied to the signal AFTER compression in dB.
+         */
+        float postGainDb;
+    }
+
+    /**
+     * Limiter configuration for a specific channel.
+     */
+    @VintfStability
+    parcelable LimiterConfig {
+        /**
+         * Channel index. Must not be negative, and not exceed the channel count calculated from
+         * Parameter.common.input.base.channelMask.
+         */
+        int channel;
+        /**
+         * True if Limiter band is enabled.
+         * If EngineArchitecture limiterInUse was set to false, then enable can not be set to true.
+         */
+        boolean enable;
+        /**
+         * Index of group assigned to this Limiter. Only limiters that share the same linkGroup
+         * index will react together.
+         */
+        int linkGroup;
+        /**
+         * Attack Time for compressor in milliseconds (ms). Must not be negative.
+         */
+        float attackTimeMs;
+        /**
+         * Release Time for compressor in milliseconds (ms). Must not be negative.
+         */
+        float releaseTimeMs;
+        /**
+         * Compressor ratio (N:1) (input:output). Must not be negative.
+         */
+        float ratio;
+        /**
+         * Compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS). Must not be
+         * positive.
+         */
+        float thresholdDb;
+        /**
+         * Gain applied to the signal AFTER compression in dB.
+         */
+        float postGainDb;
+    }
+
+    /**
+     * Input gain for a channel (specified by the channel index).
+     */
+    @VintfStability
+    parcelable InputGain {
+        /**
+         * Channel index. Must not be negative, and not exceed the channel count calculated from
+         * Parameter.common.input.base.channelMask.
+         */
+        int channel;
+        /**
+         * Gain applied to the input signal in decibels (dB). 0 dB means no change in level.
+         */
+        float gainDb;
+    }
+
+    /**
+     * Effect engine architecture.
+     */
+    EngineArchitecture engineArchitecture;
+    /**
+     * PreEq stage per channel configuration. Only valid when pre EQ stage inUse is true.
+     */
+    ChannelConfig[] preEq;
+    /**
+     * PostEq stage per channel configuration. Only valid when post EQ stage inUse is true.
+     */
+    ChannelConfig[] postEq;
+    /**
+     * PreEq stage per band configuration. Only valid when pre EQ stage inUse is true.
+     */
+    EqBandConfig[] preEqBand;
+    /**
+     * PostEq stage per band configuration. Only valid when post EQ stage inUse is true.
+     */
+    EqBandConfig[] postEqBand;
+    /**
+     * MBC stage per channel configuration. Only valid when MBC stage inUse is true.
+     */
+    ChannelConfig[] mbc;
+    /**
+     * PostEq stage per band configuration. Only valid when MBC stage inUse is true.
+     */
+    MbcBandConfig[] mbcBand;
+    /**
+     * Limiter stage configuration. Only valid when limiter stage inUse is true.
+     */
+    LimiterConfig[] limiter;
+    /**
+     * Input gain factor.
+     */
+    InputGain[] inputGain;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
new file mode 100644
index 0000000..1d58e50
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Environmental Reverb specific definitions.
+ *
+ * All parameter settings must be inside the range of Capability.Range.environmentalReverb
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
+ */
+
+@VintfStability
+union EnvironmentalReverb {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        EnvironmentalReverb.Tag commonTag;
+    }
+
+    /**
+     * Vendor EnvironmentalReverb implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * Room level apply to the reverb effect in millibels.
+     */
+    int roomLevelMb;
+    /**
+     * Room HF level apply to the reverb effect in millibels.
+     */
+    int roomHfLevelMb;
+    /**
+     * Delay time apply to the reverb effect in milliseconds.
+     */
+    int decayTimeMs;
+    /**
+     * HF decay ratio in permilles.
+     */
+    int decayHfRatioPm;
+    /**
+     * Reverb reflections level in millibels.
+     */
+    int reflectionsLevelMb;
+    /**
+     * Reverb reflections delay in milliseconds.
+     */
+    int reflectionsDelayMs;
+    /**
+     * Reverb level in millibels.
+     */
+    int levelMb;
+    /**
+     * Reverb delay in milliseconds.
+     */
+    int delayMs;
+    /**
+     * Diffusion in permilles.
+     */
+    int diffusionPm;
+    /**
+     * Density in permilles.
+     */
+    int densityPm;
+
+    /**
+     * Bypass reverb and copy input to output if set to true.
+     */
+    boolean bypass;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Equalizer.aidl b/audio/aidl/android/hardware/audio/effect/Equalizer.aidl
new file mode 100644
index 0000000..e727f70
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Equalizer.aidl
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Equalizer specific definitions.
+ *
+ * All parameter settings must be inside the range of Capability.Range.equalizer definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
+ */
+@VintfStability
+union Equalizer {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        Equalizer.Tag commonTag;
+    }
+
+    /**
+     * Vendor Equalizer implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * Level setting for each band in millibels.
+     */
+    @VintfStability
+    parcelable BandLevel {
+        int index;
+        int levelMb;
+    }
+
+    /**
+     * Supported minimal and maximal frequency for each band in milliHertz.
+     */
+    @VintfStability
+    parcelable BandFrequency {
+        int index;
+        int minMh;
+        int maxMh;
+    }
+
+    /**
+     * Factory presets supported.
+     */
+    @VintfStability
+    parcelable Preset {
+        int index;
+        /**
+         * Preset name, used to identify presets but no intended to display on UI directly.
+         */
+        @utf8InCpp String name;
+    }
+
+    /**
+     * Level for each band.
+     */
+    BandLevel[] bandLevels;
+
+    /**
+     * Index of current preset.
+     */
+    int preset;
+
+    /**
+     * Get only parameter, get the center frequency for all bands in milliHertz.
+     */
+    int[] centerFreqMh;
+
+    /**
+     * Get only parameter, indicating bands frequency ranges supported by implementation.
+     */
+    BandFrequency[] bandFrequencies;
+
+    /**
+     * Get only parameter, indicating presets name and index supported by implementation.
+     */
+    Preset[] presets;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Flags.aidl b/audio/aidl/android/hardware/audio/effect/Flags.aidl
new file mode 100644
index 0000000..28685c3
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Flags.aidl
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+/**
+ * Some common capability for an effect instance.
+ */
+@VintfStability
+parcelable Flags {
+    /**
+     * Type of connection.
+     */
+    @VintfStability
+    @Backing(type="byte")
+    enum Type {
+        /**
+         * After track process.
+         */
+        INSERT = 0,
+        /**
+         * Connect to track auxiliary output and use send level.
+         */
+        AUXILIARY = 1,
+        /**
+         * Rreplaces track process function; must implement SRC, volume and mono to stereo.
+         */
+        REPLACE = 2,
+        /**
+         * Applied below audio HAL on in.
+         */
+        PRE_PROC = 3,
+        /**
+         * Applied below audio HAL on out.
+         */
+        POST_PROC = 4,
+    }
+    Type type = Type.INSERT;
+
+    /**
+     * Insertion preference.
+     */
+    @VintfStability
+    @Backing(type="byte")
+    enum Insert {
+        ANY = 0,
+        /**
+         * First of the chain.
+         */
+        FIRST = 1,
+        /**
+         * Last of the chain.
+         */
+        LAST = 2,
+        /**
+         * Exclusive (only effect in the insert chain.
+         */
+        EXCLUSIVE = 3,
+    }
+    Insert insert = Insert.ANY;
+
+    @VintfStability
+    @Backing(type="byte")
+    enum Volume {
+        NONE = 0,
+        /**
+         * Implements volume control.
+         */
+        CTRL = 1,
+        /**
+         * Requires volume indication.
+         */
+        IND = 2,
+        /**
+         * Monitors requested volume.
+         */
+        MONITOR = 3,
+    }
+    Volume volume = Volume.NONE;
+
+    @VintfStability
+    @Backing(type="byte")
+    enum HardwareAccelerator {
+        /**
+         * No hardware acceleration
+         */
+        NONE = 0,
+        /**
+         * Non tunneled hw acceleration: effect reads the samples, send them to HW accelerated
+         * effect processor, reads back the processed samples and returns them to the output buffer.
+         */
+        SIMPLE = 1,
+        /**
+         * The effect interface is only used to control the effect engine. This mode is relevant for
+         * global effects actually applied by the audio hardware on the output stream.
+         */
+        TUNNEL = 2,
+    }
+    HardwareAccelerator hwAcceleratorMode = HardwareAccelerator.NONE;
+
+    /**
+     * Effect instance sets this flag to true if it requires updates on whether the playback thread
+     * the effect is attached to is offloaded or not.  In this case the framework must call
+     * IEffect.setParameter(Parameter.offload) to notify effect instance when playback thread
+     * offload changes.
+     */
+    boolean offloadIndication;
+
+    /**
+     * Effect instance sets this flag to true if it requires device change update. In this case the
+     * framework must call IEffect.setParameter(Parameter.device) to notify effect instance when the
+     * device changes.
+     */
+    boolean deviceIndication;
+
+    /**
+     * Effect instance sets this flag to true if it requires audio mode change update. In this case
+     * the framework must call IEffect.setParameter(Parameter.mode) to notify effect instance when
+     * the audio mode changes.
+     */
+    boolean audioModeIndication;
+
+    /**
+     * Effect instance sets this flag to true if it requires audio source change update. In this
+     * case the framework must call IEffect.setParameter(Parameter.source) to notify effect instance
+     * when the audio source changes.
+     */
+    boolean audioSourceIndication;
+
+    /**
+     * Set to true if the effect instance bypass audio data (no processing).
+     */
+    boolean bypass;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
new file mode 100644
index 0000000..3cc5acb
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * HapticGenerator specific definitions. HapticGenerator effect provide HapticGenerator control and
+ * mute/unmute functionality.
+ *
+ * All parameter settings must be inside the range of Capability.Range.hapticGenerator definition if
+ * the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
+ */
+@VintfStability
+union HapticGenerator {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        HapticGenerator.Tag commonTag;
+    }
+
+    /**
+     * Vendor HapticGenerator implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    @VintfStability
+    @Backing(type="int")
+    enum VibratorScale {
+        MUTE = -100,
+        VERY_LOW = -2,
+        LOW = -1,
+        NONE = 0,
+        HIGH = 1,
+        VERY_HIGH = 2,
+    }
+
+    @VintfStability
+    parcelable HapticScale {
+        /**
+         * Audio track ID.
+         */
+        int id;
+        /**
+         * Haptic intensity.
+         */
+        VibratorScale scale = VibratorScale.MUTE;
+    }
+
+    /**
+     * Vibrator information including resonant frequency, Q factor.
+     */
+    @VintfStability
+    parcelable VibratorInformation {
+        /**
+         * Resonant frequency in Hz.
+         */
+        float resonantFrequencyHz;
+        float qFactor;
+        float maxAmplitude;
+    }
+
+    HapticScale[] hapticScales;
+    VibratorInformation vibratorInfo;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/IEffect.aidl b/audio/aidl/android/hardware/audio/effect/IEffect.aidl
new file mode 100644
index 0000000..6097f34
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/IEffect.aidl
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.CommandId;
+import android.hardware.audio.effect.Descriptor;
+import android.hardware.audio.effect.Parameter;
+import android.hardware.audio.effect.State;
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+
+/**
+ * Effect interfaces definitions to configure and control the effect instance.
+ */
+@VintfStability
+interface IEffect {
+    @VintfStability
+    @FixedSize
+    parcelable Status {
+        /**
+         * One of Binder STATUS_* statuses:
+         *  - STATUS_OK: the command has completed successfully;
+         *  - STATUS_BAD_VALUE: invalid parameters or state detected in effects;
+         *  - STATUS_INVALID_OPERATION: an internal error happens in effect audio buffer processing;
+         *  - STATUS_NOT_ENOUGH_DATA: a read or write error has occurred for the 'inputDataMQ' or
+         * 'outputDataMQ';
+         *
+         */
+        int status;
+        /**
+         * The amount of audio data samples in the floating point format consumed by the effect
+         * instance.
+         */
+        int fmqConsumed;
+        /**
+         * The amount of audio data samples in the floating point format produced by the effect
+         * instance.
+         */
+        int fmqProduced;
+    }
+
+    /**
+     * Return data structure of IEffect.open() interface.
+     */
+    @VintfStability
+    parcelable OpenEffectReturn {
+        /**
+         * Message queue for effect processing status.
+         */
+        MQDescriptor<Status, SynchronizedReadWrite> statusMQ;
+        /**
+         * Message queue for input data buffer.
+         */
+        MQDescriptor<float, SynchronizedReadWrite> inputDataMQ;
+        /**
+         * Message queue for output data buffer.
+         */
+        MQDescriptor<float, SynchronizedReadWrite> outputDataMQ;
+    }
+
+    /**
+     * Open an effect instance, effect must not start processing data before receive
+     * CommandId::START command. All necessary information should be allocated and instance must
+     * transfer to State::IDLE state after open() call has been handled successfully. After open,
+     * the effect instance must be able to handle all IEffect interface calls.
+     *
+     * @param common Parameters which MUST pass from client at open time.
+     * @param specific Effect specific parameters which can optional pass from client at open time.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT if the effect instance receive unsupported command.
+     * @throws a EX_UNSUPPORTED_OPERATION if device capability/resource is not enough or system
+     *         failure happens.
+     * @note Open an already-opened effect instance should do nothing and should not throw an error.
+     */
+    OpenEffectReturn open(
+            in Parameter.Common common, in @nullable Parameter.Specific specific);
+
+    /**
+     * Called by the client to close the effect instance, processing thread should be destroyed and
+     * consume no CPU after close.
+     *
+     * It is recommended to close the effect on the client side as soon as it becomes unused, it's
+     * client responsibility to make sure all parameter/buffer is correct if client wants to reopen
+     * a closed instance.
+     *
+     * Effect instance close interface should always succeed unless:
+     * 1. The effect instance is not in a proper state to be closed, for example it's still in
+     * State::PROCESSING state.
+     * 2. There is system/hardware related failure when close.
+     *
+     * @throws EX_ILLEGAL_STATE if the effect instance is not in a proper state to be closed.
+     * @throws EX_UNSUPPORTED_OPERATION if the effect instance failed to close for any other reason.
+     * @note Close an already-closed effect should do nothing and should not throw an error.
+     */
+    void close();
+
+    /**
+     * Return the @c Descriptor of this effect instance.
+     *
+     * Must be available for the effect instance at anytime and should always succeed.
+     *
+     * @return Descriptor The @c Descriptor of this effect instance.
+     */
+    Descriptor getDescriptor();
+
+    /**
+     * Send a command (defined in enum CommandId) to the effect instance, instance state can be
+     * changed as result of command handling.
+     *
+     * Must be available for the effect instance after it has been open().
+     *
+     * @param commandId ID of the command send to the effect instance.
+     *
+     * @throws EX_ILLEGAL_STATE if the effect instance is not in a proper state to handle the
+     * command.
+     * @throws EX_ILLEGAL_ARGUMENT if the effect instance receive unsupported command.
+     */
+    void command(in CommandId commandId);
+
+    /**
+     * Get current state of the effect instance.
+     *
+     * Must be available for the effect instance at anytime and should always succeed.
+     *
+     * @return Current effect instance state.
+     */
+    State getState();
+
+    /**
+     * Set a parameter to the effect instance.
+     *
+     * Must be available for the effect instance after open().
+     *
+     * @param param Parameter data to set to the effect instance.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT if the effect instance receive unsupported parameter.
+     */
+    void setParameter(in Parameter param);
+
+    /**
+     * Get a parameter from the effect instance with parameter ID.
+     *
+     * This interface must return the current parameter of the effect instance, if no parameter
+     * has been set by client yet, the default value must be returned.
+     *
+     * Must be available for the effect instance after open().
+     *
+     * @param paramId The tag enum of parameter to get.
+     * @return Parameter The parameter to get from the effect instance.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT if the effect instance receive unsupported parameter tag.
+     */
+    Parameter getParameter(in Parameter.Id paramId);
+}
diff --git a/audio/aidl/android/hardware/audio/effect/IFactory.aidl b/audio/aidl/android/hardware/audio/effect/IFactory.aidl
new file mode 100644
index 0000000..b80e6ac
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/IFactory.aidl
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.Descriptor;
+import android.hardware.audio.effect.IEffect;
+import android.hardware.audio.effect.Processing;
+import android.media.audio.common.AudioUuid;
+
+/**
+ * Provides system-wide effect factory interfaces.
+ *
+ * An android.hardware.audio.effect.IFactory platform service is registered with ServiceManager, and
+ * is always available on the device.
+ *
+ */
+@VintfStability
+interface IFactory {
+    /**
+     * Return a list of effect descriptors supported by this device, with the optional filter by
+     * type and/or by instance UUID.
+     *
+     * @param type UUID identifying the effect type.
+     *        This is an optional parameter, pass in null if this parameter is not necessary; if non
+     *        null, used as a filter for effect type UUIDs.
+     * @param implementation Indicates the particular implementation of the effect in that type.
+     *        This is an optional parameter, pass in null if this parameter is not necessary; if
+     *        non null, used as a filter for effect implementation UUIDs.
+     * @param proxy Indicates the proxy UUID filter to query.
+     *        This is an optional parameter, pass in null if this parameter is not necessary; if
+     *        non null, used as a filter for effect proxy UUIDs.
+     * @return List of effect Descriptors supported and filtered by type/implementation/proxy UUID.
+     */
+    Descriptor[] queryEffects(in @nullable AudioUuid type,
+            in @nullable AudioUuid implementation, in @nullable AudioUuid proxy);
+
+    /**
+     * Return a list of defined processings, with the optional filter by Processing type.
+     * An effect can exist more than once in the returned list, which means this effect must be used
+     * in more than one processing type.
+     *
+     * @param type Type of processing to query, can be AudioStreamType, AudioSource, or null.
+     * @return list of processing defined with the optional filter by Processing.Type.
+     */
+    Processing[] queryProcessing(in @nullable Processing.Type type);
+
+    /**
+     * Called by the audio framework to create the effect (identified by the implementation UUID
+     * parameter).
+     *
+     * The effect instance should be able to maintain its own context and parameters after creation.
+     *
+     * @param implUuid UUID for the effect implementation which instance will be created based on.
+     * @return The effect instance handle created.
+     * @throws EX_ILLEGAL_ARGUMENT if the implUuid is not valid.
+     * @throws EX_TRANSACTION_FAILED if device capability/resource is not enough to create the
+     *         effect instance.
+     */
+    IEffect createEffect(in AudioUuid implUuid);
+
+    /**
+     * Called by the framework to destroy the effect and free up all currently allocated resources.
+     * It is recommended to destroy the effect from the client side as soon as it is becomes unused.
+     *
+     * The client must ensure effect instance is closed before destroy.
+     *
+     * @param handle The handle of effect instance to be destroyed.
+     * @throws EX_ILLEGAL_ARGUMENT if the effect handle is not valid.
+     * @throws EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
+     */
+    void destroyEffect(in IEffect handle);
+}
diff --git a/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl b/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl
new file mode 100644
index 0000000..23e1e5a
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * LoudnessEnhancer specific definitions.
+ *
+ * All parameter settings must be inside the range of Capability.Range.loudnessEnhancer definition
+ * if the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
+ */
+@VintfStability
+union LoudnessEnhancer {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        LoudnessEnhancer.Tag commonTag;
+    }
+
+    /**
+     * Vendor LoudnessEnhancer implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * The maximum gain in millibels (mB) applied to the signal to process, default value is 0 which
+     * corresponds to no amplification.
+     */
+    int gainMb;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl b/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl
new file mode 100644
index 0000000..c6bcc43
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Noise suppression (NS) is an audio pre-processor which removes background noise from the captured
+ * signal. The component of the signal considered as noise can be either stationary (car/airplane
+ * engine, AC system) or non-stationary (other peoples conversations, car horn) for more advanced
+ * implementations.
+ *
+ * All parameter settings must be inside the range of Capability.Range.noiseSuppression definition
+ * if the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
+ */
+@VintfStability
+union NoiseSuppression {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        NoiseSuppression.Tag commonTag;
+    }
+
+    /**
+     * Vendor NoiseSuppression implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * Different level of Noise Suppression to set.
+     * As an example, webrtc have NsConfig::SuppressionLevel::k6dB applied for LOW level noise
+     * suppression, NsConfig::SuppressionLevel::k12dB for MEDIUM, and
+     * NsConfig::SuppressionLevel::k18dB for HIGH.
+     */
+    @VintfStability @Backing(type="int") enum Level { LOW, MEDIUM, HIGH, VERY_HIGH }
+
+    /**
+     * The NS level.
+     */
+    Level level;
+
+    /**
+     * Noise suppression type.
+     */
+    @VintfStability @Backing(type="int") enum Type { SINGLE_CHANNEL, MULTI_CHANNEL }
+
+    Type type;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
new file mode 100644
index 0000000..0954055
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.AcousticEchoCanceler;
+import android.hardware.audio.effect.AutomaticGainControlV1;
+import android.hardware.audio.effect.AutomaticGainControlV2;
+import android.hardware.audio.effect.BassBoost;
+import android.hardware.audio.effect.Downmix;
+import android.hardware.audio.effect.DynamicsProcessing;
+import android.hardware.audio.effect.EnvironmentalReverb;
+import android.hardware.audio.effect.Equalizer;
+import android.hardware.audio.effect.HapticGenerator;
+import android.hardware.audio.effect.LoudnessEnhancer;
+import android.hardware.audio.effect.NoiseSuppression;
+import android.hardware.audio.effect.PresetReverb;
+import android.hardware.audio.effect.VendorExtension;
+import android.hardware.audio.effect.Virtualizer;
+import android.hardware.audio.effect.Visualizer;
+import android.hardware.audio.effect.Volume;
+import android.media.audio.common.AudioConfig;
+import android.media.audio.common.AudioDeviceDescription;
+import android.media.audio.common.AudioMode;
+import android.media.audio.common.AudioSource;
+
+/**
+ * Defines all parameters supported by the effect instance.
+ *
+ * There are three groups of parameters:
+ * 1. Common parameters are essential parameters, MUST pass to effects at open() interface.
+ * 2. Parameters defined for a specific effect type.
+ * 3. Extension parameters ParcelableHolder can be used for vendor effect definition.
+ *
+ * All parameter settings must be inside the range of Capability.Range.$EffectType$ definition. If
+ * an effect implementation doesn't have limitation for a parameter, then don't define any effect
+ * range.
+ *
+ * All parameters are get-able, if any parameter doesn't support set, effect implementation should
+ * report the supported range for this parameter as range.min > range.max. If no support range is
+ * defined for a parameter, it means this parameter doesn't have any limitation.
+ *
+ */
+@VintfStability
+union Parameter {
+    /**
+     * Client can pass in Parameter.Id with the corresponding tag value in IEffect.getParameter()
+     * call to get android.hardware.audio.effect.Parameter.
+     *
+     * As an example, if a client want to get audio.hardware.audio.effect.Specific.Equalizer, the
+     * value of Id should be audio.hardware.audio.effect.Parameter.Specific.equalizer.
+     */
+    @VintfStability
+    union Id {
+        /**
+         * Parameter tag defined for vendor effects. Use VendorExtension here so it's possible to
+         * pass customized information.
+         */
+        VendorExtension vendorEffectTag;
+        /**
+         * Parameter tag defined for nested parameters. Can be used to get any parameter defined in
+         * nested Union structure.
+         *
+         * Example:
+         * To get BassBoost strength in param from effectInstance:
+         *  IEffect effectInstance;
+         *  Parameter param;
+         *  BassBoost::Id bassId = BassBoost::Id::make<BassBoost::Id::tag>(BassBoost::strengthPm);
+         *  Parameter::Id id = Parameter::Id::make<Parameter::Id::bassBoostTag>(bassId);
+         *  effectInstance.getParameter(id, &param);
+         *
+         */
+        AcousticEchoCanceler.Id acousticEchoCancelerTag;
+        AutomaticGainControlV1.Id automaticGainControlV1Tag;
+        AutomaticGainControlV2.Id automaticGainControlV2Tag;
+        BassBoost.Id bassBoostTag;
+        Downmix.Id downmixTag;
+        DynamicsProcessing.Id dynamicsProcessingTag;
+        EnvironmentalReverb.Id environmentalReverbTag;
+        Equalizer.Id equalizerTag;
+        HapticGenerator.Id hapticGeneratorTag;
+        LoudnessEnhancer.Id loudnessEnhancerTag;
+        NoiseSuppression.Id noiseSuppressionTag;
+        PresetReverb.Id presetReverbTag;
+        Virtualizer.Id virtualizerTag;
+        Visualizer.Id visualizerTag;
+        Volume.Id volumeTag;
+        /**
+         * Non-nested parameter tag. Can be used to get any parameter defined in Union Parameter
+         * directly.
+         */
+        Parameter.Tag commonTag;
+    }
+
+    /**
+     * Common parameters MUST be supported by all effect implementations.
+     */
+    @VintfStability
+    parcelable Common {
+        /**
+         * Type of Audio device.
+         */
+        int session;
+        /**
+         * I/O Handle.
+         */
+        int ioHandle;
+        /**
+         * Input config.
+         */
+        AudioConfig input;
+        /**
+         * Output config.
+         */
+        AudioConfig output;
+    }
+    Common common;
+
+    /**
+     * Used by audio framework to set the device type(s) to effect engine.
+     * Effect engine must apply all AudioDeviceDescription in the list.
+     * Effect must implement setParameter(deviceDescription) if Flags.deviceIndication set to true.
+     */
+    AudioDeviceDescription[] deviceDescription;
+
+    /**
+     * Used by audio framework to set the audio mode to effect engine.
+     * Effect must implement setParameter(mode) if Flags.audioModeIndication set to true.
+     */
+    AudioMode mode;
+
+    /**
+     * Used by audio framework to set the audio source to effect engine.
+     * Effect must implement setParameter(source) if Flags.audioSourceIndication set to true.
+     */
+    AudioSource source;
+
+    /**
+     * Used by audio framework to indicate whether the playback thread the effect is attached to is
+     * offloaded or not.
+     */
+    boolean offload;
+
+    /**
+     * The volume gain for left and right channel, left and right equals to same value if it's mono.
+     */
+    @VintfStability
+    parcelable VolumeStereo {
+        float left;
+        float right;
+    }
+    /**
+     * Used by audio framework to delegate volume control to effect engine.
+     * Effect must implement setParameter(volume) if Flags.volume set to Volume.IND.
+     */
+    VolumeStereo volumeStereo;
+
+    /**
+     * Parameters MUST be supported by a Specific type of effect.
+     */
+    @VintfStability
+    union Specific {
+        VendorExtension vendorEffect;
+        AcousticEchoCanceler acousticEchoCanceler;
+        AutomaticGainControlV1 automaticGainControlV1;
+        AutomaticGainControlV2 automaticGainControlV2;
+        BassBoost bassBoost;
+        Downmix downmix;
+        DynamicsProcessing dynamicsProcessing;
+        EnvironmentalReverb environmentalReverb;
+        Equalizer equalizer;
+        HapticGenerator hapticGenerator;
+        LoudnessEnhancer loudnessEnhancer;
+        NoiseSuppression noiseSuppression;
+        PresetReverb presetReverb;
+        Virtualizer virtualizer;
+        Visualizer visualizer;
+        Volume volume;
+    }
+    Specific specific;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl b/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl
new file mode 100644
index 0000000..a36da2c
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * PresetReverb specific definitions.
+ *
+ * All parameter settings must be inside the range of Capability.Range.presetReverb definition if
+ * the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
+ */
+@VintfStability
+union PresetReverb {
+    /**
+     * Presets enum definition.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum Presets {
+        /**
+         * No reverb or reflections
+         */
+        NONE,
+        /**
+         * A small room less than five meters in length
+         */
+        SMALLROOM,
+        /**
+         * A medium room with a length of ten meters or less.
+         */
+        MEDIUMROOM,
+        /**
+         * A large-sized room suitable for live performances.
+         */
+        LARGEROOM,
+        /**
+         * A medium-sized hall.
+         */
+        MEDIUMHALL,
+        /**
+         * a large-sized hall suitable for a full orchestra.
+         */
+        LARGEHALL,
+        /**
+         * Synthesis of the traditional plate reverb.
+         */
+        PLATE,
+    }
+
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        PresetReverb.Tag commonTag;
+    }
+
+    /**
+     * Vendor PresetReverb implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * The list of presets supported by implementation, effect implementation must declare the
+     * support of Presets with Capability.Range.presetReverb definition. For example, if an effect
+     * implementation supports all Presets in PresetReverb.Presets, then the capability will be:
+     *  const std::vector<PresetReverb::Presets> kSupportedPresets{
+     *          ndk::enum_range<PresetReverb::Presets>().begin(),
+     *          ndk::enum_range<PresetReverb::Presets>().end()};
+     *  const std::vector<Range::PresetReverbRange> kRanges = {
+     *          MAKE_RANGE(PresetReverb, supportedPresets, kSupportedPresets, kSupportedPresets)};
+     */
+    Presets[] supportedPresets;
+
+    /**
+     * Get current reverb preset when used in getParameter.
+     * Enable a preset reverb when used in setParameter.
+     * With the current Range definition, there is no good way to define enum capability, so the
+     * Presets vector supportedPresets is used to defined the capability. Client must check the
+     * capability in PresetReverb.supportedPresets, and make sure to get the list of supported
+     * presets before setting.
+     */
+    Presets preset;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Processing.aidl b/audio/aidl/android/hardware/audio/effect/Processing.aidl
new file mode 100644
index 0000000..cb77350
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Processing.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.Descriptor;
+import android.media.audio.common.AudioSource;
+import android.media.audio.common.AudioStreamType;
+import android.media.audio.common.AudioUuid;
+
+/**
+ * List of effects which must be used for certain pre-processing or post-processing.
+ */
+@VintfStability
+parcelable Processing {
+    @VintfStability
+    union Type {
+        AudioStreamType streamType = AudioStreamType.INVALID;
+        AudioSource source;
+    }
+
+    /**
+     * Specifies the type of processing by referring to the output stream type (AudioStreamType) or
+     * the input stream source (AudioSource).
+     */
+    Type type;
+    /**
+     * List of effect descriptors for this processing.
+     */
+    Descriptor[] ids;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Range.aidl b/audio/aidl/android/hardware/audio/effect/Range.aidl
new file mode 100644
index 0000000..567320a
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Range.aidl
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.AcousticEchoCanceler;
+import android.hardware.audio.effect.AutomaticGainControlV1;
+import android.hardware.audio.effect.AutomaticGainControlV2;
+import android.hardware.audio.effect.BassBoost;
+import android.hardware.audio.effect.Downmix;
+import android.hardware.audio.effect.DynamicsProcessing;
+import android.hardware.audio.effect.EnvironmentalReverb;
+import android.hardware.audio.effect.Equalizer;
+import android.hardware.audio.effect.HapticGenerator;
+import android.hardware.audio.effect.LoudnessEnhancer;
+import android.hardware.audio.effect.NoiseSuppression;
+import android.hardware.audio.effect.PresetReverb;
+import android.hardware.audio.effect.VendorExtension;
+import android.hardware.audio.effect.Virtualizer;
+import android.hardware.audio.effect.Visualizer;
+import android.hardware.audio.effect.Volume;
+
+/**
+ * Define the supported range of effect parameters.
+ * Effect implementation must report the supported range of parameter/capability if there is any
+ * limitation.
+ * Range of each effect type is defined with a vector, because each $EffectType$Range can only
+ * describe the range of one parameter. For example, Range::AcousticEchoCancelerRange can only
+ * describe one of vendor, echoDelayUs, and mobileMode.
+ *
+ * If an effect implementation needs to define the valid range for a certain parameter, it can
+ * write the minimum/maximum supported value to the corresponding effect range, and add the range
+ * to vector of this effect type.
+ * Say if an AcousticEchoCanceler implementation wants to define the supported range of echoDelayUs
+ * to [0, 500], then the Capability range should include an item in acousticEchoCanceler list:
+ * std::vector<Range::AcousticEchoCancelerRange> kRanges = {
+ *       MAKE_RANGE(AcousticEchoCanceler, echoDelayUs, 0, 500)};
+ *
+ * For a more complex example, if a DynamicsProcessing implementation wants to define the
+ * supported range of preEqBand channel to [0, 1], band index to [0, 5], and cutoffFrequencyHz to
+ * [220, 20000]:
+ * Range::DynamicsProcessingRange kRange = {
+ *   .min = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ *           {EqBandConfig({.channel = 0,
+ *                          .band = 0,
+ *                          .enable = false,
+ *                          .cutoffFrequencyHz = 220,
+ *                          .gainDb = std::numeric_limits<float>::min()})}),
+ *   .max = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ *           {EqBandConfig({.channel = 1,
+ *                          .band = 5,
+ *                          .enable = true,
+ *                          .cutoffFrequencyHz = 20000,
+ *                          .gainDb = std::numeric_limits<float>::max()})})};
+ *
+ * For get only parameters, the effect implementation must define an invalid range (min > max), to
+ * indicate no parameter from the effect client can be accepted for setting. The effect
+ * implementation must return EX_ILLEGAL_ARGUMENT if it receives any setParameter call for a get
+ * only parameter.
+ * As an example, the get-only parameter Virtualizer.speakerAngles can be defined with:
+ *   Range::VirtualizerRange kRanges = {
+ *       MAKE_RANGE(Virtualizer, speakerAngles,
+ *                  {Virtualizer::ChannelAngle({.channel = 1},
+ *                  {Virtualizer::ChannelAngle({.channel = 0})};
+ *
+ * For a capability definition (which is also get only), the effect implementation must define a
+ * range with min == max, to indicate this is a fixed capability which shouldn't set by client.
+ * As an example, the Equalizer presets capability can be defined with:
+ * std::vector<Equalizer::Preset> kPresets = {
+ *       {0, "Normal"},      {1, "Classical"}, {2, "Dance"}, {3, "Flat"}, {4, "Folk"},
+ *       {5, "Heavy Metal"}, {6, "Hip Hop"},   {7, "Jazz"},  {8, "Pop"},  {9, "Rock"}};
+ * Range::EqualizerRange kRanges =
+ *      MAKE_RANGE(Equalizer, presets, EqualizerSw::kPresets, EqualizerSw::kPresets);
+ *
+ * For enum capability, it's necessary to either list a range, or explicitly list out all enums in
+ * the Range definition, see PresetReverb.supportedPresets as example.
+ *
+ * The effect implementation must return EX_ILLEGAL_ARGUMENT if:
+ * 1. receive any setParameter call for get only parameter (min > max).
+ * 2. receive any setParameter call for capability parameter definition (min == max).
+ * 3. receive any setParameter call for parameters not in the range of [min, max].
+ *
+ */
+@VintfStability
+union Range {
+    @VintfStability
+    parcelable AcousticEchoCancelerRange {
+        AcousticEchoCanceler min;
+        AcousticEchoCanceler max;
+    }
+
+    @VintfStability
+    parcelable AutomaticGainControlV1Range {
+        AutomaticGainControlV1 min;
+        AutomaticGainControlV1 max;
+    }
+
+    @VintfStability
+    parcelable AutomaticGainControlV2Range {
+        AutomaticGainControlV2 min;
+        AutomaticGainControlV2 max;
+    }
+
+    @VintfStability
+    parcelable BassBoostRange {
+        BassBoost min;
+        BassBoost max;
+    }
+
+    @VintfStability
+    parcelable DownmixRange {
+        Downmix min;
+        Downmix max;
+    }
+
+    @VintfStability
+    parcelable DynamicsProcessingRange {
+        DynamicsProcessing min;
+        DynamicsProcessing max;
+    }
+
+    @VintfStability
+    parcelable EnvironmentalReverbRange {
+        EnvironmentalReverb min;
+        EnvironmentalReverb max;
+    }
+
+    @VintfStability
+    parcelable EqualizerRange {
+        Equalizer min;
+        Equalizer max;
+    }
+
+    @VintfStability
+    parcelable HapticGeneratorRange {
+        HapticGenerator min;
+        HapticGenerator max;
+    }
+
+    @VintfStability
+    parcelable LoudnessEnhancerRange {
+        LoudnessEnhancer min;
+        LoudnessEnhancer max;
+    }
+
+    @VintfStability
+    parcelable NoiseSuppressionRange {
+        NoiseSuppression min;
+        NoiseSuppression max;
+    }
+
+    @VintfStability
+    parcelable PresetReverbRange {
+        PresetReverb min;
+        PresetReverb max;
+    }
+
+    @VintfStability
+    parcelable VendorExtensionRange {
+        VendorExtension min;
+        VendorExtension max;
+    }
+
+    @VintfStability
+    parcelable VirtualizerRange {
+        Virtualizer min;
+        Virtualizer max;
+    }
+
+    @VintfStability
+    parcelable VisualizerRange {
+        Visualizer min;
+        Visualizer max;
+    }
+
+    @VintfStability
+    parcelable VolumeRange {
+        Volume min;
+        Volume max;
+    }
+
+    /**
+     * The vector of range defined for parameters of each effect implementation.
+     * Each element of the vector represents the min and max range of a parameter, so the size of
+     * vector is the number of parameter ranges defined for this effect implementation.
+     *
+     * The effect implementation must not have duplicated parameter range definition in the vector.
+     * Client side must go though the vector and make sure the parameter setting to effect
+     * implementation is in valid range.
+     */
+    VendorExtensionRange[] vendorExtension = {};
+    AcousticEchoCancelerRange[] acousticEchoCanceler;
+    AutomaticGainControlV1Range[] automaticGainControlV1;
+    AutomaticGainControlV2Range[] automaticGainControlV2;
+    BassBoostRange[] bassBoost;
+    DownmixRange[] downmix;
+    DynamicsProcessingRange[] dynamicsProcessing;
+    EnvironmentalReverbRange[] environmentalReverb;
+    EqualizerRange[] equalizer;
+    HapticGeneratorRange[] hapticGenerator;
+    LoudnessEnhancerRange[] loudnessEnhancer;
+    NoiseSuppressionRange[] noiseSuppression;
+    PresetReverbRange[] presetReverb;
+    VirtualizerRange[] virtualizer;
+    VisualizerRange[] visualizer;
+    VolumeRange[] volume;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/State.aidl b/audio/aidl/android/hardware/audio/effect/State.aidl
new file mode 100644
index 0000000..85a4afc
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/State.aidl
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+/**
+ * Possible states of an effect instance.
+ * A typical effect instance will be in INIT state when it is created with IFactory.createEffect()
+ * interface, transfer to IDLE after open(), and to PROCESSING after
+ * IEffect.command(Command.Id.START) command. When an effect instance receive STOP or RESET command,
+ * it should transfer to IDLE state after handle the command successfully. Effect instance should
+ * consume minimal resource and transfer to INIT state after it was close().
+ *
+ * Refer to State.gv for detailed state diagram.
+ */
+@VintfStability
+@Backing(type="byte")
+enum State {
+
+    /**
+     * An effect instance is in INIT state by default after it was created with
+     * IFactory.createEffect(). When an effect instance is in INIT state, it should have instance
+     * context initialized, and ready to handle IEffect.setParameter(), IEffect.open() as well as
+     * all getter interfaces.
+     *
+     * In INIT state, effect instance must:
+     * 1. Not handle any IEffect.command() and return EX_ILLEGAL_STATE with any Command.Id.
+     * 2. Be able to handle all parameter setting with IEffect.setParameter().
+     * 3. Be able to handle all getter interface calls like IEffect.getParameter() and
+     * IEffect.getState().
+     * 4. Be able to handle IEffect.open() successfully after configuration.
+     *
+     * Client is expected to do necessary configuration with IEffect.setParameter(), get all
+     * resource ready with IEffect.open(), and make sure effect instance transfer to IDLE state
+     * before sending commands with IEffect.command() interface. Effect instance must transfer
+     * from INIT to IDLE state after handle IEffect.open() call successfully.
+     */
+    INIT,
+    /**
+     * An effect instance transfer to IDLE state after it was open successfully with IEffect.open()
+     * in INIT state, or after it was stop/reset with Command.Id.STOP/RESET in PROCESSING state.
+     *
+     * In IDLE state, effect instance must:
+     * 1. Be able to start effect processing engine with IEffect.command(Command.Id.START) call.
+     * 2. Be able to handle all parameter setting with IEffect.setParameter().
+     * 3. Be able to handle all getter interface calls like IEffect.getParameter() and
+     * IEffect.getState().
+     *
+     * The following state transfer can happen in IDLE state:
+     * 1. Transfer to PROCESSING if instance receive an START command and start processing data
+     * successfully.
+     * 2. Transfer to INIT if instance receive a close() call.
+     */
+    IDLE,
+    /**
+     * An effect instance is in PROCESSING state after it receive an START command and start
+     * processing data successfully. Effect instance will transfer from PROCESSING to IDLE state if
+     * it receive an STOP or RESET command and handle the command successfully.
+     *
+     * When an instance is in PROCESSING state, client should try not to close() it directly,
+     * instead client should try to stop processing data first with STOP command before close(). In
+     * the case of a close() call received when instance in PROCESSING state, it should try to stop
+     * processing and transfer to IDLE first before close().
+     *
+     * In PROCESSING state, effect instance must:
+     * 1. Return EX_ILLEGAL_STATE if it's not able to handle any parameter settings at runtime.
+     * 2. Be able to handle STOP and RESET for IEffect.command() interface, and return
+     * EX_ILLEGAL_STATE for all other commands.
+     * 3. Must be able to handle all get* interface calls like IEffect.getParameter() and
+     * IEffect.getState().
+     */
+    PROCESSING,
+}
diff --git a/audio/aidl/android/hardware/audio/effect/VendorExtension.aidl b/audio/aidl/android/hardware/audio/effect/VendorExtension.aidl
new file mode 100644
index 0000000..c60f01a
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/VendorExtension.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+/**
+ * Vendor exntension implementation definition, can be used for additional parameters.
+ */
+@VintfStability
+parcelable VendorExtension {
+    ParcelableHolder extension;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
new file mode 100644
index 0000000..1dbb509
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+import android.media.audio.common.AudioChannelLayout;
+import android.media.audio.common.AudioDeviceDescription;
+
+/**
+ * Virtualizer specific definitions. An audio virtualizer is a general name for an effect to
+ * spatialize audio channels.
+ *
+ * All parameter settings must be inside the range of Capability.Range.virtualizer definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
+ */
+@VintfStability
+union Virtualizer {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        Virtualizer.Tag commonTag;
+        SpeakerAnglesPayload speakerAnglesPayload;
+    }
+
+    /**
+     * Vendor Virtualizer implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * Payload to query speaker angles for the given channel position mask and device.
+     * The Virtualizer implementation must return EX_ILLEGAL_ARGUMENT if the given payload not
+     * supported.
+     */
+    @VintfStability
+    parcelable SpeakerAnglesPayload {
+        /**
+         * Audio channel position definition. See
+         * android.media.audio.common.AudioChannelLayout.aidl. Only the channel position "CHANNEL_*"
+         * in AudioChannelLayout be used.
+         */
+        AudioChannelLayout layout;
+        /**
+         * Audio device type. See android.media.audio.common.AudioDeviceDescription.aidl.
+         */
+        AudioDeviceDescription device;
+    }
+
+    /**
+     * The per mille strength of the virtualizer effect.
+     *
+     * If the implementation does not support per mille accuracy for setting the strength, it is
+     * allowed to round the given strength to the nearest supported value. In this case {@link
+     * #IEffect.getParameter()} method should return the rounded value that was actually set.
+     *
+     */
+    int strengthPm;
+
+    /**
+     * All angles are expressed in degrees and are relative to the listener.
+     */
+    @VintfStability
+    parcelable ChannelAngle {
+        /**
+         * Audio channel layout, CHANNEL_* constants defined in
+         * android.media.audio.common.AudioChannelLayout.
+         */
+        int channel;
+
+        /**
+         * 0 is the direction the listener faces, 180 is behind the listener, and -90 is left of
+         * the listener.
+         */
+        int azimuthDegree;
+
+        /**
+         * 0 is the horizontal plane, +90 is above the listener, -90 is below.
+         */
+        int elevationDegree;
+    }
+
+    /**
+     * Get only parameter.
+     * A vector of angles per channel represented by azimuth and elevation (in degrees), client must
+     * set Parameter.Id to SpeakerAnglesPayload to get speakerAngles.
+     */
+    ChannelAngle[] speakerAngles;
+
+    /**
+     * Get only parameter.
+     * The audio device on which virtualzation mode is forced.
+     */
+    AudioDeviceDescription device;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Visualizer.aidl b/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
new file mode 100644
index 0000000..0b37546
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Visualizer specific definitions. Visualizer enables application to retrieve part of the currently
+ * playing audio for visualization purpose
+ *
+ * All parameter settings must be inside the range of Capability.Range.visualizer definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
+ *
+ */
+@VintfStability
+union Visualizer {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        Visualizer.Tag commonTag;
+    }
+    Id id;
+
+    /**
+     * Vendor Visualizer implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * Type of scaling applied on the captured visualization data.
+     */
+    @VintfStability
+    enum ScalingMode {
+        /**
+         * Defines a capture mode where amplification is applied based on the content of the
+         * captured data. This is the default Visualizer mode, and is suitable for music
+         * visualization.
+         */
+        NORMALIZED = 0,
+        /**
+         * Defines a capture mode where the playback volume will affect (scale) the range of the
+         * captured data. A low playback volume will lead to low sample and fft values, and
+         * vice-versa.
+         */
+        AS_PLAYED,
+    }
+
+    /**
+     * Measurement modes to be performed.
+     */
+    @VintfStability
+    enum MeasurementMode {
+        /**
+         * No measurements are performed.
+         */
+        NONE = 0,
+        /**
+         * Defines a measurement mode which computes the peak and RMS value in mB below the "full
+         * scale", where 0mB is normally the maximum sample value (but see the note below). Minimum
+         * value depends on the resolution of audio samples used by the audio framework. The value
+         * of -9600mB is the minimum value for 16-bit audio systems and -14400mB or below for "high
+         * resolution" systems. Values for peak and RMS can be retrieved with {@link
+         * #getMeasurementPeakRms(MeasurementPeakRms)}.
+         */
+        PEAK_RMS,
+    }
+
+    /**
+     * Get only parameter to get the current measurements.
+     */
+    @VintfStability
+    parcelable Measurement {
+        int rms;
+        int peak;
+    }
+    Measurement measurement;
+
+    /**
+     * Get only parameter to get the latest captured samples of PCM samples (8 bits per sample).
+     */
+    byte[] captureSampleBuffer;
+
+    /**
+     * Used by framework to inform the visualizer about the downstream latency (audio hardware
+     * driver estimated latency in milliseconds).
+     *
+     * Visualizer implementation must use Range.VisualizerRange to define the range of supported
+     * latency.
+     */
+    int latencyMs;
+
+    /**
+     * Current capture size in number of samples.
+     *
+     * Visualizer implementation must use Range.VisualizerRange to define the range of supported
+     * capture size.
+     */
+    int captureSamples;
+
+    /**
+     * Visualizer capture mode
+     */
+    ScalingMode scalingMode;
+
+    /**
+     * Visualizer measurement mode.
+     */
+    MeasurementMode measurementMode;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Volume.aidl b/audio/aidl/android/hardware/audio/effect/Volume.aidl
new file mode 100644
index 0000000..15cfdd2
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/Volume.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Volume specific definitions. Volume effect provide volume control and mute/unmute functionality.
+ *
+ * All parameter settings must be inside the range of Capability.Range.volume definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
+ */
+@VintfStability
+union Volume {
+    /**
+     * Effect parameter tag to identify the parameters for getParameter().
+     */
+    @VintfStability
+    union Id {
+        VendorExtension vendorExtensionTag;
+        Volume.Tag commonTag;
+    }
+
+    /**
+     * Vendor Volume implementation definition for additional parameters.
+     */
+    VendorExtension vendor;
+
+    /**
+     * Current level in dB.
+     */
+    int levelDb;
+    /**
+     * Mute volume if true, when volume set to mute, the current level still saved and take effect
+     * when unmute.
+     */
+    boolean mute;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/state.gv b/audio/aidl/android/hardware/audio/effect/state.gv
new file mode 100644
index 0000000..c88521e
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/state.gv
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// To render: "dot -Tpng state.gv -o state.png"
+digraph effect_state_machine {
+    node[shape = point style = filled fillcolor = black width = 0.5] I;
+    node[shape = doublecircle] F;
+    node[shape = oval width = 1];
+    node[fillcolor = lightgreen] INIT;
+    node[fillcolor = lightblue] IDLE;
+    node[fillcolor = lightyellow] PROCESSING;
+
+    I -> INIT[label = "IFactory.createEffect" labelfontcolor = "navy"];
+    INIT -> F[label = "IFactory.destroyEffect"];
+    INIT -> IDLE[label = "open()" labelfontcolor = "lime"];
+    IDLE -> PROCESSING[label = "command(START"];
+    PROCESSING -> IDLE[label = "command(STOP)\ncommand(RESET)"];
+    IDLE -> INIT[label = "close()"];
+
+    INIT -> INIT[label = "getState\ngetDescriptor"];
+    IDLE -> IDLE[label = "getXXX\nsetParameter\ncommand(RESET)"];
+    PROCESSING -> PROCESSING[label = "getXXX\nsetParameter"];
+}
diff --git a/audio/aidl/common/Android.bp b/audio/aidl/common/Android.bp
new file mode 100644
index 0000000..4c6a74e
--- /dev/null
+++ b/audio/aidl/common/Android.bp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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 {
+    name: "libaudioaidlcommon",
+    host_supported: true,
+    vendor_available: true,
+    export_include_dirs: ["include"],
+    header_libs: [
+        "libbase_headers",
+        "libsystem_headers",
+    ],
+    export_header_lib_headers: [
+        "libbase_headers",
+        "libsystem_headers",
+    ],
+    srcs: [
+        "StreamWorker.cpp",
+    ],
+}
+
+cc_library {
+    name: "libaudioaidlranges",
+    host_supported: true,
+    vendor_available: true,
+    static_libs: [
+        "android.hardware.audio.effect-V1-ndk",
+    ],
+    export_include_dirs: ["include"],
+    header_libs: ["libaudioaidl_headers"],
+    srcs: [
+        "EffectRangeSpecific.cpp",
+    ],
+}
+
+cc_test {
+    name: "libaudioaidlcommon_test",
+    host_supported: true,
+    vendor_available: true,
+    static_libs: [
+        "android.media.audio.common.types-V1-ndk",
+        "libaudioaidlcommon",
+    ],
+    shared_libs: [
+        "liblog",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+    ],
+    srcs: [
+        "tests/streamworker_tests.cpp",
+        "tests/utils_tests.cpp",
+    ],
+    test_suites: [
+        "general-tests",
+    ],
+}
diff --git a/audio/aidl/common/EffectRangeSpecific.cpp b/audio/aidl/common/EffectRangeSpecific.cpp
new file mode 100644
index 0000000..bd78ea0
--- /dev/null
+++ b/audio/aidl/common/EffectRangeSpecific.cpp
@@ -0,0 +1,161 @@
+/*

+ * Copyright (C) 2023 The Android Open Source Project

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+#include <aidl/android/hardware/audio/effect/DynamicsProcessing.h>

+#include <aidl/android/hardware/audio/effect/Range.h>

+

+#include "EffectRangeSpecific.h"

+#include "effect-impl/EffectRange.h"

+

+namespace aidl::android::hardware::audio::effect {

+

+namespace DynamicsProcessingRanges {

+

+static bool isInputGainConfigInRange(const std::vector<DynamicsProcessing::InputGain>& cfgs,

+                                     const DynamicsProcessing::InputGain& min,

+                                     const DynamicsProcessing::InputGain& max) {

+    auto func = [](const DynamicsProcessing::InputGain& arg) {

+        return std::make_tuple(arg.channel, arg.gainDb);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isLimiterConfigInRange(const std::vector<DynamicsProcessing::LimiterConfig>& cfgs,

+                                   const DynamicsProcessing::LimiterConfig& min,

+                                   const DynamicsProcessing::LimiterConfig& max) {

+    auto func = [](const DynamicsProcessing::LimiterConfig& arg) {

+        return std::make_tuple(arg.channel, arg.enable, arg.linkGroup, arg.attackTimeMs,

+                               arg.releaseTimeMs, arg.ratio, arg.thresholdDb, arg.postGainDb);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isMbcBandConfigInRange(const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,

+                                   const DynamicsProcessing::MbcBandConfig& min,

+                                   const DynamicsProcessing::MbcBandConfig& max) {

+    auto func = [](const DynamicsProcessing::MbcBandConfig& arg) {

+        return std::make_tuple(arg.channel, arg.band, arg.enable, arg.cutoffFrequencyHz,

+                               arg.attackTimeMs, arg.releaseTimeMs, arg.ratio, arg.thresholdDb,

+                               arg.kneeWidthDb, arg.noiseGateThresholdDb, arg.expanderRatio,

+                               arg.preGainDb, arg.postGainDb);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isEqBandConfigInRange(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,

+                                  const DynamicsProcessing::EqBandConfig& min,

+                                  const DynamicsProcessing::EqBandConfig& max) {

+    auto func = [](const DynamicsProcessing::EqBandConfig& arg) {

+        return std::make_tuple(arg.channel, arg.band, arg.enable, arg.cutoffFrequencyHz,

+                               arg.gainDb);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isChannelConfigInRange(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs,

+                                   const DynamicsProcessing::ChannelConfig& min,

+                                   const DynamicsProcessing::ChannelConfig& max) {

+    auto func = [](const DynamicsProcessing::ChannelConfig& arg) {

+        return std::make_tuple(arg.channel, arg.enable);

+    };

+    return isTupleInRange(cfgs, min, max, func);

+}

+

+static bool isEngineConfigInRange(const DynamicsProcessing::EngineArchitecture& cfg,

+                                  const DynamicsProcessing::EngineArchitecture& min,

+                                  const DynamicsProcessing::EngineArchitecture& max) {

+    auto func = [](const DynamicsProcessing::EngineArchitecture& arg) {

+        return std::make_tuple(arg.resolutionPreference, arg.preferredProcessingDurationMs,

+                               arg.preEqStage.inUse, arg.preEqStage.bandCount,

+                               arg.postEqStage.inUse, arg.postEqStage.bandCount, arg.mbcStage.inUse,

+                               arg.mbcStage.bandCount, arg.limiterInUse);

+    };

+    return isTupleInRange(func(cfg), func(min), func(max));

+}

+

+static int locateMinMaxForTag(DynamicsProcessing::Tag tag,

+                              const std::vector<Range::DynamicsProcessingRange>& ranges) {

+    for (int i = 0; i < (int)ranges.size(); i++) {

+        if (tag == ranges[i].min.getTag() && tag == ranges[i].max.getTag()) {

+            return i;

+        }

+    }

+    return -1;

+}

+

+bool isParamInRange(const DynamicsProcessing& dp,

+                    const std::vector<Range::DynamicsProcessingRange>& ranges) {

+    auto tag = dp.getTag();

+    int i = locateMinMaxForTag(tag, ranges);

+    if (i == -1) return true;

+

+    switch (tag) {

+        case DynamicsProcessing::engineArchitecture: {

+            return isEngineConfigInRange(

+                    dp.get<DynamicsProcessing::engineArchitecture>(),

+                    ranges[i].min.get<DynamicsProcessing::engineArchitecture>(),

+                    ranges[i].max.get<DynamicsProcessing::engineArchitecture>());

+        }

+        case DynamicsProcessing::preEq: {

+            return isChannelConfigInRange(dp.get<DynamicsProcessing::preEq>(),

+                                          ranges[i].min.get<DynamicsProcessing::preEq>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::preEq>()[0]);

+        }

+        case DynamicsProcessing::postEq: {

+            return isChannelConfigInRange(dp.get<DynamicsProcessing::postEq>(),

+                                          ranges[i].min.get<DynamicsProcessing::postEq>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::postEq>()[0]);

+        }

+        case DynamicsProcessing::mbc: {

+            return isChannelConfigInRange(dp.get<DynamicsProcessing::mbc>(),

+                                          ranges[i].min.get<DynamicsProcessing::mbc>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::mbc>()[0]);

+        }

+        case DynamicsProcessing::preEqBand: {

+            return isEqBandConfigInRange(dp.get<DynamicsProcessing::preEqBand>(),

+                                         ranges[i].min.get<DynamicsProcessing::preEqBand>()[0],

+                                         ranges[i].max.get<DynamicsProcessing::preEqBand>()[0]);

+        }

+        case DynamicsProcessing::postEqBand: {

+            return isEqBandConfigInRange(dp.get<DynamicsProcessing::postEqBand>(),

+                                         ranges[i].min.get<DynamicsProcessing::postEqBand>()[0],

+                                         ranges[i].max.get<DynamicsProcessing::postEqBand>()[0]);

+        }

+        case DynamicsProcessing::mbcBand: {

+            return isMbcBandConfigInRange(dp.get<DynamicsProcessing::mbcBand>(),

+                                          ranges[i].min.get<DynamicsProcessing::mbcBand>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::mbcBand>()[0]);

+        }

+        case DynamicsProcessing::limiter: {

+            return isLimiterConfigInRange(dp.get<DynamicsProcessing::limiter>(),

+                                          ranges[i].min.get<DynamicsProcessing::limiter>()[0],

+                                          ranges[i].max.get<DynamicsProcessing::limiter>()[0]);

+        }

+        case DynamicsProcessing::inputGain: {

+            return isInputGainConfigInRange(dp.get<DynamicsProcessing::inputGain>(),

+                                            ranges[i].min.get<DynamicsProcessing::inputGain>()[0],

+                                            ranges[i].max.get<DynamicsProcessing::inputGain>()[0]);

+        }

+        default: {

+            return true;

+        }

+    }

+    return true;

+}

+

+}  // namespace DynamicsProcessingRanges

+

+}  // namespace aidl::android::hardware::audio::effect
\ No newline at end of file
diff --git a/audio/aidl/common/StreamWorker.cpp b/audio/aidl/common/StreamWorker.cpp
new file mode 100644
index 0000000..0d2121c
--- /dev/null
+++ b/audio/aidl/common/StreamWorker.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <pthread.h>
+#include <sched.h>
+#include <sys/resource.h>
+
+#include "include/StreamWorker.h"
+
+namespace android::hardware::audio::common::internal {
+
+bool ThreadController::start(const std::string& name, int priority) {
+    mThreadName = name;
+    mThreadPriority = priority;
+    if (kTestSingleThread != name) {
+        mWorker = std::thread(&ThreadController::workerThread, this);
+    } else {
+        // Simulate the case when the workerThread completes prior
+        // to the moment when we being waiting for its start.
+        workerThread();
+    }
+    std::unique_lock<std::mutex> lock(mWorkerLock);
+    android::base::ScopedLockAssertion lock_assertion(mWorkerLock);
+    mWorkerCv.wait(lock, [&]() {
+        android::base::ScopedLockAssertion lock_assertion(mWorkerLock);
+        return mWorkerState != WorkerState::INITIAL || !mError.empty();
+    });
+    return mError.empty();
+}
+
+void ThreadController::stop() {
+    {
+        std::lock_guard<std::mutex> lock(mWorkerLock);
+        if (mWorkerState != WorkerState::STOPPED) {
+            mWorkerState = WorkerState::STOPPED;
+            mWorkerStateChangeRequest = true;
+        }
+    }
+    join();
+}
+
+void ThreadController::join() {
+    if (mWorker.joinable()) {
+        mWorker.join();
+    }
+}
+
+bool ThreadController::waitForAtLeastOneCycle() {
+    WorkerState newState;
+    switchWorkerStateSync(WorkerState::RUNNING, WorkerState::PAUSE_REQUESTED, &newState);
+    if (newState != WorkerState::PAUSED) return false;
+    switchWorkerStateSync(newState, WorkerState::RESUME_REQUESTED, &newState);
+    return newState == WorkerState::RUNNING;
+}
+
+void ThreadController::switchWorkerStateSync(WorkerState oldState, WorkerState newState,
+                                             WorkerState* finalState) {
+    std::unique_lock<std::mutex> lock(mWorkerLock);
+    android::base::ScopedLockAssertion lock_assertion(mWorkerLock);
+    if (mWorkerState != oldState) {
+        if (finalState) *finalState = mWorkerState;
+        return;
+    }
+    mWorkerState = newState;
+    mWorkerStateChangeRequest = true;
+    mWorkerCv.wait(lock, [&]() {
+        android::base::ScopedLockAssertion lock_assertion(mWorkerLock);
+        return mWorkerState != newState;
+    });
+    if (finalState) *finalState = mWorkerState;
+}
+
+void ThreadController::workerThread() {
+    using Status = StreamLogic::Status;
+
+    std::string error;
+    if (!mThreadName.empty()) {
+        std::string compliantName(mThreadName.substr(0, 15));
+        if (int errCode = pthread_setname_np(pthread_self(), compliantName.c_str()); errCode != 0) {
+            error.append("Failed to set thread name: ").append(strerror(errCode));
+        }
+    }
+    if (error.empty() && mThreadPriority != ANDROID_PRIORITY_DEFAULT) {
+        if (int result = setpriority(PRIO_PROCESS, 0, mThreadPriority); result != 0) {
+            int errCode = errno;
+            error.append("Failed to set thread priority: ").append(strerror(errCode));
+        }
+    }
+    if (error.empty()) {
+        error.append(mLogic->init());
+    }
+    {
+        std::lock_guard<std::mutex> lock(mWorkerLock);
+        mWorkerState = error.empty() ? WorkerState::RUNNING : WorkerState::STOPPED;
+        mError = error;
+    }
+    mWorkerCv.notify_one();
+    if (!error.empty()) return;
+
+    for (WorkerState state = WorkerState::RUNNING; state != WorkerState::STOPPED;) {
+        bool needToNotify = false;
+        if (Status status = state != WorkerState::PAUSED ? mLogic->cycle()
+                                                         : (sched_yield(), Status::CONTINUE);
+            status == Status::CONTINUE) {
+            {
+                // See https://developer.android.com/training/articles/smp#nonracing
+                android::base::ScopedLockAssertion lock_assertion(mWorkerLock);
+                if (!mWorkerStateChangeRequest.load(std::memory_order_relaxed)) continue;
+            }
+            //
+            // Pause and resume are synchronous. One worker cycle must complete
+            // before the worker indicates a state change. This is how 'mWorkerState' and
+            // 'state' interact:
+            //
+            // mWorkerState == RUNNING
+            // client sets mWorkerState := PAUSE_REQUESTED
+            // last workerCycle gets executed, state := mWorkerState := PAUSED by us
+            //   (or the workers enters the 'error' state if workerCycle fails)
+            // client gets notified about state change in any case
+            // thread is doing a busy wait while 'state == PAUSED'
+            // client sets mWorkerState := RESUME_REQUESTED
+            // state := mWorkerState (RESUME_REQUESTED)
+            // mWorkerState := RUNNING, but we don't notify the client yet
+            // first workerCycle gets executed, the code below triggers a client notification
+            //   (or if workerCycle fails, worker enters 'error' state and also notifies)
+            // state := mWorkerState (RUNNING)
+            std::lock_guard<std::mutex> lock(mWorkerLock);
+            if (state == WorkerState::RESUME_REQUESTED) {
+                needToNotify = true;
+            }
+            state = mWorkerState;
+            if (mWorkerState == WorkerState::PAUSE_REQUESTED) {
+                state = mWorkerState = WorkerState::PAUSED;
+                needToNotify = true;
+            } else if (mWorkerState == WorkerState::RESUME_REQUESTED) {
+                mWorkerState = WorkerState::RUNNING;
+            }
+        } else {
+            std::lock_guard<std::mutex> lock(mWorkerLock);
+            if (state == WorkerState::RESUME_REQUESTED ||
+                mWorkerState == WorkerState::PAUSE_REQUESTED) {
+                needToNotify = true;
+            }
+            state = mWorkerState = WorkerState::STOPPED;
+            if (status == Status::ABORT) {
+                mError = "Received ABORT from the logic cycle";
+            }
+        }
+        if (needToNotify) {
+            {
+                std::lock_guard<std::mutex> lock(mWorkerLock);
+                mWorkerStateChangeRequest = false;
+            }
+            mWorkerCv.notify_one();
+        }
+    }
+}
+
+}  // namespace android::hardware::audio::common::internal
diff --git a/audio/aidl/common/TEST_MAPPING b/audio/aidl/common/TEST_MAPPING
new file mode 100644
index 0000000..9dcf44e
--- /dev/null
+++ b/audio/aidl/common/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "libaudioaidlcommon_test"
+    }
+  ]
+}
diff --git a/audio/aidl/common/include/EffectRangeSpecific.h b/audio/aidl/common/include/EffectRangeSpecific.h
new file mode 100644
index 0000000..c7262bb
--- /dev/null
+++ b/audio/aidl/common/include/EffectRangeSpecific.h
@@ -0,0 +1,28 @@
+/*

+ * Copyright (C) 2023 The Android Open Source Project

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+#pragma once

+

+namespace aidl::android::hardware::audio::effect {

+

+namespace DynamicsProcessingRanges {

+

+bool isParamInRange(const DynamicsProcessing& dp,

+                    const std::vector<Range::DynamicsProcessingRange>& ranges);

+

+}  // namespace DynamicsProcessingRanges

+

+}  // namespace aidl::android::hardware::audio::effect
\ No newline at end of file
diff --git a/audio/aidl/common/include/StreamWorker.h b/audio/aidl/common/include/StreamWorker.h
new file mode 100644
index 0000000..e9c1070
--- /dev/null
+++ b/audio/aidl/common/include/StreamWorker.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+
+#include <android-base/thread_annotations.h>
+#include <system/thread_defs.h>
+
+namespace android::hardware::audio::common {
+
+class StreamLogic;
+
+namespace internal {
+
+class ThreadController {
+    enum class WorkerState { INITIAL, STOPPED, RUNNING, PAUSE_REQUESTED, PAUSED, RESUME_REQUESTED };
+
+  public:
+    explicit ThreadController(StreamLogic* logic) : mLogic(logic) {}
+    ~ThreadController() { stop(); }
+
+    bool start(const std::string& name, int priority);
+    // Note: 'pause' and 'resume' methods should only be used on the "driving" side.
+    // In the case of audio HAL I/O, the driving side is the client, because the HAL
+    // implementation always blocks on getting a command.
+    void pause() { switchWorkerStateSync(WorkerState::RUNNING, WorkerState::PAUSE_REQUESTED); }
+    void resume() { switchWorkerStateSync(WorkerState::PAUSED, WorkerState::RESUME_REQUESTED); }
+    bool hasError() {
+        std::lock_guard<std::mutex> lock(mWorkerLock);
+        return !mError.empty();
+    }
+    std::string getError() {
+        std::lock_guard<std::mutex> lock(mWorkerLock);
+        return mError;
+    }
+    void stop();
+    // Direct use of 'join' assumes that the StreamLogic is not intended
+    // to run forever, and is guaranteed to exit by itself. This normally
+    // only happen in tests.
+    void join();
+    bool waitForAtLeastOneCycle();
+
+    // Only used by unit tests.
+    void lockUnlockMutex(bool lock) NO_THREAD_SAFETY_ANALYSIS {
+        lock ? mWorkerLock.lock() : mWorkerLock.unlock();
+    }
+    std::thread::native_handle_type getThreadNativeHandle() { return mWorker.native_handle(); }
+
+  private:
+    void switchWorkerStateSync(WorkerState oldState, WorkerState newState,
+                               WorkerState* finalState = nullptr);
+    void workerThread();
+
+    StreamLogic* const mLogic;
+    std::string mThreadName;
+    int mThreadPriority = ANDROID_PRIORITY_DEFAULT;
+    std::thread mWorker;
+    std::mutex mWorkerLock;
+    std::condition_variable mWorkerCv;
+    WorkerState mWorkerState GUARDED_BY(mWorkerLock) = WorkerState::INITIAL;
+    std::string mError GUARDED_BY(mWorkerLock);
+    // The atomic lock-free variable is used to prevent priority inversions
+    // that can occur when a high priority worker tries to acquire the lock
+    // which has been taken by a lower priority control thread which in its turn
+    // got preempted. To prevent a PI under normal operating conditions, that is,
+    // when there are no errors or state changes, the worker does not attempt
+    // taking `mWorkerLock` unless `mWorkerStateChangeRequest` is set.
+    // To make sure that updates to `mWorkerState` and `mWorkerStateChangeRequest`
+    // are serialized, they are always made under a lock.
+    static_assert(std::atomic<bool>::is_always_lock_free);
+    std::atomic<bool> mWorkerStateChangeRequest GUARDED_BY(mWorkerLock) = false;
+};
+
+// A special thread name used in tests only.
+static const std::string kTestSingleThread = "__testST__";
+
+}  // namespace internal
+
+class StreamLogic {
+  public:
+    friend class internal::ThreadController;
+
+    virtual ~StreamLogic() = default;
+
+  protected:
+    enum class Status { ABORT, CONTINUE, EXIT };
+
+    /* Called once at the beginning of the thread loop. Must return
+     * an empty string to enter the thread loop, otherwise the thread loop
+     * exits and the worker switches into the 'error' state, setting
+     * the error to the returned value.
+     */
+    virtual std::string init() = 0;
+
+    /* Called for each thread loop unless the thread is in 'paused' state.
+     * Must return 'CONTINUE' to continue running, otherwise the thread loop
+     * exits. If the result from worker cycle is 'ABORT' then the worker switches
+     * into the 'error' state with a generic error message. It is recommended that
+     * the subclass reports any problems via logging facilities. Returning the 'EXIT'
+     * status is equivalent to calling 'stop()' method. This is just a way of
+     * of stopping the worker by its own initiative.
+     */
+    virtual Status cycle() = 0;
+};
+
+template <class LogicImpl>
+class StreamWorker : public LogicImpl {
+  public:
+    template <class... Args>
+    explicit StreamWorker(Args&&... args) : LogicImpl(std::forward<Args>(args)...), mThread(this) {}
+
+    // Methods of LogicImpl are available via inheritance.
+    // Forwarded methods of ThreadController follow.
+
+    // Note that 'priority' here is what is known as the 'nice number' in *nix systems.
+    // The nice number is used with the default scheduler. For threads that
+    // need to use a specialized scheduler (e.g. SCHED_FIFO) and set the priority within it,
+    // it is recommended to implement an appropriate configuration sequence within
+    // 'LogicImpl' or 'StreamLogic::init'.
+    bool start(const std::string& name = "", int priority = ANDROID_PRIORITY_DEFAULT) {
+        return mThread.start(name, priority);
+    }
+    void pause() { mThread.pause(); }
+    void resume() { mThread.resume(); }
+    bool hasError() { return mThread.hasError(); }
+    std::string getError() { return mThread.getError(); }
+    void stop() { mThread.stop(); }
+    void join() { mThread.join(); }
+    bool waitForAtLeastOneCycle() { return mThread.waitForAtLeastOneCycle(); }
+
+    // Only used by unit tests.
+    void testLockUnlockMutex(bool lock) { mThread.lockUnlockMutex(lock); }
+    std::thread::native_handle_type testGetThreadNativeHandle() {
+        return mThread.getThreadNativeHandle();
+    }
+
+  private:
+    // The ThreadController gets destroyed before LogicImpl.
+    // After the controller has been destroyed, it is guaranteed that
+    // the thread was joined, thus the 'cycle' method of LogicImpl
+    // will not be called anymore, and it is safe to destroy LogicImpl.
+    internal::ThreadController mThread;
+};
+
+}  // namespace android::hardware::audio::common
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
new file mode 100644
index 0000000..305c924
--- /dev/null
+++ b/audio/aidl/common/include/Utils.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <array>
+#include <initializer_list>
+#include <regex>
+#include <type_traits>
+
+#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <aidl/android/media/audio/common/AudioDeviceType.h>
+#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+#include <aidl/android/media/audio/common/AudioInputFlags.h>
+#include <aidl/android/media/audio/common/AudioMode.h>
+#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+#include <aidl/android/media/audio/common/PcmType.h>
+
+namespace aidl::android::hardware::audio::common {
+
+// Some values are reserved for use by the system code only.
+// HALs must not accept or emit values outside from the provided list.
+constexpr std::array<::aidl::android::media::audio::common::AudioMode, 5> kValidAudioModes = {
+        ::aidl::android::media::audio::common::AudioMode::NORMAL,
+        ::aidl::android::media::audio::common::AudioMode::RINGTONE,
+        ::aidl::android::media::audio::common::AudioMode::IN_CALL,
+        ::aidl::android::media::audio::common::AudioMode::IN_COMMUNICATION,
+        ::aidl::android::media::audio::common::AudioMode::CALL_SCREEN,
+};
+
+constexpr size_t getPcmSampleSizeInBytes(::aidl::android::media::audio::common::PcmType pcm) {
+    using ::aidl::android::media::audio::common::PcmType;
+    switch (pcm) {
+        case PcmType::UINT_8_BIT:
+            return 1;
+        case PcmType::INT_16_BIT:
+            return 2;
+        case PcmType::INT_32_BIT:
+            return 4;
+        case PcmType::FIXED_Q_8_24:
+            return 4;
+        case PcmType::FLOAT_32_BIT:
+            return 4;
+        case PcmType::INT_24_BIT:
+            return 3;
+    }
+    return 0;
+}
+
+constexpr size_t getChannelCount(
+        const ::aidl::android::media::audio::common::AudioChannelLayout& layout,
+        int32_t mask = std::numeric_limits<int32_t>::max()) {
+    using Tag = ::aidl::android::media::audio::common::AudioChannelLayout::Tag;
+    switch (layout.getTag()) {
+        case Tag::none:
+            return 0;
+        case Tag::invalid:
+            return 0;
+        case Tag::indexMask:
+            return __builtin_popcount(layout.get<Tag::indexMask>() & mask);
+        case Tag::layoutMask:
+            return __builtin_popcount(layout.get<Tag::layoutMask>() & mask);
+        case Tag::voiceMask:
+            return __builtin_popcount(layout.get<Tag::voiceMask>() & mask);
+    }
+    return 0;
+}
+
+constexpr size_t getFrameSizeInBytes(
+        const ::aidl::android::media::audio::common::AudioFormatDescription& format,
+        const ::aidl::android::media::audio::common::AudioChannelLayout& layout) {
+    if (format == ::aidl::android::media::audio::common::AudioFormatDescription{}) {
+        // Unspecified format.
+        return 0;
+    }
+    using ::aidl::android::media::audio::common::AudioFormatType;
+    if (format.type == AudioFormatType::PCM) {
+        return getPcmSampleSizeInBytes(format.pcm) * getChannelCount(layout);
+    } else if (format.type == AudioFormatType::NON_PCM) {
+        // For non-PCM formats always use the underlying PCM size. The default value for
+        // PCM is "UINT_8_BIT", thus non-encapsulated streams have the frame size of 1.
+        return getPcmSampleSizeInBytes(format.pcm);
+    }
+    // Something unexpected.
+    return 0;
+}
+
+constexpr bool isDefaultAudioFormat(
+        const ::aidl::android::media::audio::common::AudioFormatDescription& desc) {
+    return desc.type == ::aidl::android::media::audio::common::AudioFormatType::DEFAULT &&
+           desc.pcm == ::aidl::android::media::audio::common::PcmType::DEFAULT;
+}
+
+constexpr bool isTelephonyDeviceType(
+        ::aidl::android::media::audio::common::AudioDeviceType device) {
+    return device == ::aidl::android::media::audio::common::AudioDeviceType::IN_TELEPHONY_RX ||
+           device == ::aidl::android::media::audio::common::AudioDeviceType::OUT_TELEPHONY_TX;
+}
+
+constexpr bool isUsbInputDeviceType(::aidl::android::media::audio::common::AudioDeviceType type) {
+    switch (type) {
+        case ::aidl::android::media::audio::common::AudioDeviceType::IN_DOCK:
+        case ::aidl::android::media::audio::common::AudioDeviceType::IN_ACCESSORY:
+        case ::aidl::android::media::audio::common::AudioDeviceType::IN_DEVICE:
+        case ::aidl::android::media::audio::common::AudioDeviceType::IN_HEADSET:
+            return true;
+        default:
+            return false;
+    }
+}
+
+constexpr bool isUsbOutputtDeviceType(::aidl::android::media::audio::common::AudioDeviceType type) {
+    switch (type) {
+        case ::aidl::android::media::audio::common::AudioDeviceType::OUT_DOCK:
+        case ::aidl::android::media::audio::common::AudioDeviceType::OUT_ACCESSORY:
+        case ::aidl::android::media::audio::common::AudioDeviceType::OUT_DEVICE:
+        case ::aidl::android::media::audio::common::AudioDeviceType::OUT_HEADSET:
+            return true;
+        default:
+            return false;
+    }
+}
+
+constexpr bool isValidAudioMode(::aidl::android::media::audio::common::AudioMode mode) {
+    return std::find(kValidAudioModes.begin(), kValidAudioModes.end(), mode) !=
+           kValidAudioModes.end();
+}
+
+static inline bool maybeVendorExtension(const std::string& s) {
+    // Only checks whether the string starts with the "vendor prefix".
+    static const std::string vendorPrefix = "VX_";
+    return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix;
+}
+
+static inline bool isVendorExtension(const std::string& s) {
+    // Must be the same as defined in {Playback|Record}TrackMetadata.aidl
+    static const std::regex vendorExtension("VX_[A-Z0-9]{3,}_[_A-Z0-9]+");
+    return std::regex_match(s.begin(), s.end(), vendorExtension);
+}
+
+// The helper functions defined below are only applicable to the case when an enum type
+// specifies zero-based bit positions, not bit masks themselves. This is why instantiation
+// is restricted to certain enum types.
+template <typename E>
+using is_bit_position_enum = std::integral_constant<
+        bool, std::is_same_v<E, ::aidl::android::media::audio::common::AudioInputFlags> ||
+                      std::is_same_v<E, ::aidl::android::media::audio::common::AudioOutputFlags>>;
+
+template <typename E, typename U = std::underlying_type_t<E>,
+          typename = std::enable_if_t<is_bit_position_enum<E>::value>>
+constexpr U makeBitPositionFlagMask(E flag) {
+    return 1 << static_cast<U>(flag);
+}
+
+template <typename E, typename U = std::underlying_type_t<E>,
+          typename = std::enable_if_t<is_bit_position_enum<E>::value>>
+constexpr bool isBitPositionFlagSet(U mask, E flag) {
+    return (mask & makeBitPositionFlagMask(flag)) != 0;
+}
+
+template <typename E, typename U = std::underlying_type_t<E>,
+          typename = std::enable_if_t<is_bit_position_enum<E>::value>>
+constexpr U makeBitPositionFlagMask(std::initializer_list<E> flags) {
+    U result = 0;
+    for (const auto flag : flags) {
+        result |= makeBitPositionFlagMask(flag);
+    }
+    return result;
+}
+
+}  // namespace aidl::android::hardware::audio::common
diff --git a/audio/aidl/common/tests/streamworker_tests.cpp b/audio/aidl/common/tests/streamworker_tests.cpp
new file mode 100644
index 0000000..f7a30b9
--- /dev/null
+++ b/audio/aidl/common/tests/streamworker_tests.cpp
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <pthread.h>
+#include <sched.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+#include <atomic>
+
+#include <StreamWorker.h>
+
+#include <gtest/gtest.h>
+#define LOG_TAG "StreamWorker_Test"
+#include <log/log.h>
+
+using android::hardware::audio::common::StreamLogic;
+using android::hardware::audio::common::StreamWorker;
+
+class TestWorkerLogic : public StreamLogic {
+  public:
+    struct Stream {
+        void setErrorStatus() { status = Status::ABORT; }
+        void setStopStatus() { status = Status::EXIT; }
+        std::atomic<Status> status = Status::CONTINUE;
+    };
+
+    // Use nullptr to test error reporting from the worker thread.
+    explicit TestWorkerLogic(Stream* stream) : mStream(stream) {}
+
+    size_t getWorkerCycles() const { return mWorkerCycles; }
+    int getPriority() const { return mPriority; }
+    bool hasWorkerCycleCalled() const { return mWorkerCycles != 0; }
+    bool hasNoWorkerCycleCalled(useconds_t usec) {
+        const size_t cyclesBefore = mWorkerCycles;
+        usleep(usec);
+        return mWorkerCycles == cyclesBefore;
+    }
+
+  protected:
+    // StreamLogic implementation
+    std::string init() override { return mStream != nullptr ? "" : "Expected error"; }
+    Status cycle() override {
+        mPriority = getpriority(PRIO_PROCESS, 0);
+        do {
+            mWorkerCycles++;
+        } while (mWorkerCycles == 0);
+        return mStream->status;
+    }
+
+  private:
+    Stream* const mStream;
+    std::atomic<size_t> mWorkerCycles = 0;
+    std::atomic<int> mPriority = ANDROID_PRIORITY_DEFAULT;
+};
+using TestWorker = StreamWorker<TestWorkerLogic>;
+
+// The parameter specifies whether an extra call to 'stop' is made at the end.
+class StreamWorkerInvalidTest : public testing::TestWithParam<bool> {
+  public:
+    StreamWorkerInvalidTest() : StreamWorkerInvalidTest(nullptr) {}
+    void TearDown() override {
+        if (GetParam()) {
+            worker.stop();
+        }
+    }
+
+  protected:
+    StreamWorkerInvalidTest(TestWorker::Stream* stream)
+        : testing::TestWithParam<bool>(), worker(stream) {}
+    TestWorker worker;
+};
+
+TEST_P(StreamWorkerInvalidTest, Uninitialized) {
+    EXPECT_FALSE(worker.hasWorkerCycleCalled());
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerInvalidTest, UninitializedPauseIgnored) {
+    EXPECT_FALSE(worker.hasError());
+    worker.pause();
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerInvalidTest, UninitializedResumeIgnored) {
+    EXPECT_FALSE(worker.hasError());
+    worker.resume();
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerInvalidTest, Start) {
+    EXPECT_FALSE(worker.start());
+    EXPECT_FALSE(worker.hasWorkerCycleCalled());
+    EXPECT_TRUE(worker.hasError());
+}
+
+TEST_P(StreamWorkerInvalidTest, PauseIgnored) {
+    EXPECT_FALSE(worker.start());
+    EXPECT_TRUE(worker.hasError());
+    worker.pause();
+    EXPECT_TRUE(worker.hasError());
+}
+
+TEST_P(StreamWorkerInvalidTest, ResumeIgnored) {
+    EXPECT_FALSE(worker.start());
+    EXPECT_TRUE(worker.hasError());
+    worker.resume();
+    EXPECT_TRUE(worker.hasError());
+}
+
+INSTANTIATE_TEST_SUITE_P(StreamWorkerInvalid, StreamWorkerInvalidTest, testing::Bool());
+
+class StreamWorkerTest : public StreamWorkerInvalidTest {
+  public:
+    StreamWorkerTest() : StreamWorkerInvalidTest(&stream) {}
+
+  protected:
+    TestWorker::Stream stream;
+};
+
+static constexpr unsigned kWorkerIdleCheckTime = 50 * 1000;
+
+TEST_P(StreamWorkerTest, Uninitialized) {
+    EXPECT_FALSE(worker.hasWorkerCycleCalled());
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, Start) {
+    ASSERT_TRUE(worker.start());
+    EXPECT_TRUE(worker.waitForAtLeastOneCycle());
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, StartStop) {
+    ASSERT_TRUE(worker.start());
+    EXPECT_TRUE(worker.waitForAtLeastOneCycle());
+    EXPECT_FALSE(worker.hasError());
+    worker.stop();
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, WorkerExit) {
+    ASSERT_TRUE(worker.start());
+    stream.setStopStatus();
+    worker.waitForAtLeastOneCycle();
+    EXPECT_FALSE(worker.hasError());
+    EXPECT_TRUE(worker.hasNoWorkerCycleCalled(kWorkerIdleCheckTime));
+}
+
+TEST_P(StreamWorkerTest, WorkerJoin) {
+    ASSERT_TRUE(worker.start());
+    stream.setStopStatus();
+    worker.join();
+    EXPECT_FALSE(worker.hasError());
+    EXPECT_TRUE(worker.hasNoWorkerCycleCalled(kWorkerIdleCheckTime));
+}
+
+TEST_P(StreamWorkerTest, WorkerError) {
+    ASSERT_TRUE(worker.start());
+    stream.setErrorStatus();
+    worker.waitForAtLeastOneCycle();
+    EXPECT_TRUE(worker.hasError());
+    EXPECT_TRUE(worker.hasNoWorkerCycleCalled(kWorkerIdleCheckTime));
+}
+
+TEST_P(StreamWorkerTest, StopAfterError) {
+    ASSERT_TRUE(worker.start());
+    stream.setErrorStatus();
+    worker.waitForAtLeastOneCycle();
+    EXPECT_TRUE(worker.hasError());
+    EXPECT_TRUE(worker.hasNoWorkerCycleCalled(kWorkerIdleCheckTime));
+    worker.stop();
+    EXPECT_TRUE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, PauseResume) {
+    ASSERT_TRUE(worker.start());
+    EXPECT_TRUE(worker.waitForAtLeastOneCycle());
+    EXPECT_FALSE(worker.hasError());
+    worker.pause();
+    EXPECT_TRUE(worker.hasNoWorkerCycleCalled(kWorkerIdleCheckTime));
+    EXPECT_FALSE(worker.hasError());
+    const size_t workerCyclesBefore = worker.getWorkerCycles();
+    worker.resume();
+    // 'resume' is synchronous and returns after the worker has looped at least once.
+    EXPECT_GT(worker.getWorkerCycles(), workerCyclesBefore);
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, StopPaused) {
+    ASSERT_TRUE(worker.start());
+    EXPECT_TRUE(worker.waitForAtLeastOneCycle());
+    EXPECT_FALSE(worker.hasError());
+    worker.pause();
+    worker.stop();
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, PauseAfterErrorIgnored) {
+    ASSERT_TRUE(worker.start());
+    stream.setErrorStatus();
+    worker.waitForAtLeastOneCycle();
+    EXPECT_TRUE(worker.hasError());
+    worker.pause();
+    EXPECT_TRUE(worker.hasNoWorkerCycleCalled(kWorkerIdleCheckTime));
+    EXPECT_TRUE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, ResumeAfterErrorIgnored) {
+    ASSERT_TRUE(worker.start());
+    stream.setErrorStatus();
+    worker.waitForAtLeastOneCycle();
+    EXPECT_TRUE(worker.hasError());
+    worker.resume();
+    EXPECT_TRUE(worker.hasNoWorkerCycleCalled(kWorkerIdleCheckTime));
+    EXPECT_TRUE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, WorkerErrorOnResume) {
+    ASSERT_TRUE(worker.start());
+    EXPECT_TRUE(worker.waitForAtLeastOneCycle());
+    EXPECT_FALSE(worker.hasError());
+    worker.pause();
+    EXPECT_FALSE(worker.hasError());
+    stream.setErrorStatus();
+    EXPECT_FALSE(worker.hasError());
+    worker.resume();
+    worker.waitForAtLeastOneCycle();
+    EXPECT_TRUE(worker.hasError());
+    EXPECT_TRUE(worker.hasNoWorkerCycleCalled(kWorkerIdleCheckTime));
+}
+
+TEST_P(StreamWorkerTest, WaitForAtLeastOneCycle) {
+    ASSERT_TRUE(worker.start());
+    const size_t workerCyclesBefore = worker.getWorkerCycles();
+    EXPECT_TRUE(worker.waitForAtLeastOneCycle());
+    EXPECT_GT(worker.getWorkerCycles(), workerCyclesBefore);
+}
+
+TEST_P(StreamWorkerTest, WaitForAtLeastOneCycleError) {
+    ASSERT_TRUE(worker.start());
+    stream.setErrorStatus();
+    EXPECT_FALSE(worker.waitForAtLeastOneCycle());
+}
+
+TEST_P(StreamWorkerTest, MutexDoesNotBlockWorker) {
+    ASSERT_TRUE(worker.start());
+    const size_t workerCyclesBefore = worker.getWorkerCycles();
+    worker.testLockUnlockMutex(true);
+    while (worker.getWorkerCycles() == workerCyclesBefore) {
+        usleep(kWorkerIdleCheckTime);
+    }
+    worker.testLockUnlockMutex(false);
+    EXPECT_TRUE(worker.waitForAtLeastOneCycle());
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, ThreadName) {
+    const std::string workerName = "TestWorker";
+    ASSERT_TRUE(worker.start(workerName)) << worker.getError();
+    char nameBuf[128];
+    ASSERT_EQ(0, pthread_getname_np(worker.testGetThreadNativeHandle(), nameBuf, sizeof(nameBuf)));
+    EXPECT_EQ(workerName, nameBuf);
+}
+
+TEST_P(StreamWorkerTest, ThreadPriority) {
+    const int priority = ANDROID_PRIORITY_LOWEST;
+    ASSERT_TRUE(worker.start("", priority)) << worker.getError();
+    EXPECT_TRUE(worker.waitForAtLeastOneCycle());
+    EXPECT_EQ(priority, worker.getPriority());
+}
+
+TEST_P(StreamWorkerTest, DeferredStartCheckNoError) {
+    stream.setStopStatus();
+    EXPECT_TRUE(worker.start(android::hardware::audio::common::internal::kTestSingleThread));
+    EXPECT_FALSE(worker.hasError());
+}
+
+TEST_P(StreamWorkerTest, DeferredStartCheckWithError) {
+    stream.setErrorStatus();
+    EXPECT_FALSE(worker.start(android::hardware::audio::common::internal::kTestSingleThread));
+    EXPECT_TRUE(worker.hasError());
+}
+
+INSTANTIATE_TEST_SUITE_P(StreamWorker, StreamWorkerTest, testing::Bool());
diff --git a/audio/aidl/common/tests/utils_tests.cpp b/audio/aidl/common/tests/utils_tests.cpp
new file mode 100644
index 0000000..1b8b8df
--- /dev/null
+++ b/audio/aidl/common/tests/utils_tests.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdint>
+#include <limits>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include <Utils.h>
+
+#include <gtest/gtest.h>
+#define LOG_TAG "Utils_Test"
+#include <log/log.h>
+
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
+using aidl::android::hardware::audio::common::getPcmSampleSizeInBytes;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::PcmType;
+
+TEST(UtilsTest, ChannelCountOddCases) {
+    using Tag = AudioChannelLayout::Tag;
+    EXPECT_EQ(0UL, getChannelCount(AudioChannelLayout{}));
+    EXPECT_EQ(0UL, getChannelCount(AudioChannelLayout::make<Tag::invalid>(0)));
+    EXPECT_EQ(0UL, getChannelCount(AudioChannelLayout::make<Tag::invalid>(-1)));
+}
+
+TEST(UtilsTest, ChannelCountForIndexMask) {
+    using Tag = AudioChannelLayout::Tag;
+    EXPECT_EQ(0UL, getChannelCount(AudioChannelLayout::make<Tag::indexMask>(0)));
+#define VERIFY_INDEX_MASK(N)                                                                  \
+    {                                                                                         \
+        const auto l =                                                                        \
+                AudioChannelLayout::make<Tag::indexMask>(AudioChannelLayout::INDEX_MASK_##N); \
+        EXPECT_EQ(N##UL, getChannelCount(l)) << l.toString();                                 \
+    }
+    VERIFY_INDEX_MASK(1);
+    VERIFY_INDEX_MASK(2);
+    VERIFY_INDEX_MASK(3);
+    VERIFY_INDEX_MASK(4);
+    VERIFY_INDEX_MASK(5);
+    VERIFY_INDEX_MASK(6);
+    VERIFY_INDEX_MASK(7);
+    VERIFY_INDEX_MASK(8);
+    VERIFY_INDEX_MASK(9);
+    VERIFY_INDEX_MASK(10);
+    VERIFY_INDEX_MASK(11);
+    VERIFY_INDEX_MASK(12);
+    VERIFY_INDEX_MASK(13);
+    VERIFY_INDEX_MASK(14);
+    VERIFY_INDEX_MASK(15);
+    VERIFY_INDEX_MASK(16);
+    VERIFY_INDEX_MASK(17);
+    VERIFY_INDEX_MASK(18);
+    VERIFY_INDEX_MASK(19);
+    VERIFY_INDEX_MASK(20);
+    VERIFY_INDEX_MASK(21);
+    VERIFY_INDEX_MASK(22);
+    VERIFY_INDEX_MASK(23);
+    VERIFY_INDEX_MASK(24);
+#undef VERIFY_INDEX_MASK
+}
+
+TEST(UtilsTest, ChannelCountForLayoutMask) {
+    using Tag = AudioChannelLayout::Tag;
+    const std::vector<std::pair<size_t, int32_t>> kTestLayouts = {
+            std::make_pair(0UL, 0),
+            std::make_pair(1UL, AudioChannelLayout::LAYOUT_MONO),
+            std::make_pair(2UL, AudioChannelLayout::LAYOUT_STEREO),
+            std::make_pair(6UL, AudioChannelLayout::LAYOUT_5POINT1),
+            std::make_pair(8UL, AudioChannelLayout::LAYOUT_7POINT1),
+            std::make_pair(16UL, AudioChannelLayout::LAYOUT_9POINT1POINT6),
+            std::make_pair(13UL, AudioChannelLayout::LAYOUT_13POINT_360RA),
+            std::make_pair(24UL, AudioChannelLayout::LAYOUT_22POINT2),
+            std::make_pair(3UL, AudioChannelLayout::LAYOUT_STEREO_HAPTIC_A),
+            std::make_pair(4UL, AudioChannelLayout::LAYOUT_STEREO_HAPTIC_AB)};
+    for (const auto& [expected_count, layout] : kTestLayouts) {
+        const auto l = AudioChannelLayout::make<Tag::layoutMask>(layout);
+        EXPECT_EQ(expected_count, getChannelCount(l)) << l.toString();
+    }
+}
+
+TEST(UtilsTest, ChannelCountForVoiceMask) {
+    using Tag = AudioChannelLayout::Tag;
+    // clang-format off
+    const std::vector<std::pair<size_t, int32_t>> kTestLayouts = {
+            std::make_pair(0UL, 0),
+            std::make_pair(1UL, AudioChannelLayout::VOICE_UPLINK_MONO),
+            std::make_pair(1UL, AudioChannelLayout::VOICE_DNLINK_MONO),
+            std::make_pair(2UL, AudioChannelLayout::VOICE_CALL_MONO)};
+    // clang-format on
+    for (const auto& [expected_count, layout] : kTestLayouts) {
+        const auto l = AudioChannelLayout::make<Tag::voiceMask>(layout);
+        EXPECT_EQ(expected_count, getChannelCount(l)) << l.toString();
+    }
+}
+
+namespace {
+
+AudioChannelLayout make_AudioChannelLayout_Mono() {
+    return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+            AudioChannelLayout::LAYOUT_MONO);
+}
+
+AudioChannelLayout make_AudioChannelLayout_Stereo() {
+    return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
+            AudioChannelLayout::LAYOUT_STEREO);
+}
+
+AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
+    AudioFormatDescription result;
+    result.type = type;
+    return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(PcmType pcm) {
+    auto result = make_AudioFormatDescription(AudioFormatType::PCM);
+    result.pcm = pcm;
+    return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(const std::string& encoding) {
+    AudioFormatDescription result;
+    result.encoding = encoding;
+    return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(PcmType transport, const std::string& encoding) {
+    auto result = make_AudioFormatDescription(encoding);
+    result.pcm = transport;
+    return result;
+}
+
+}  // namespace
+
+TEST(UtilsTest, FrameSize) {
+    EXPECT_EQ(0UL, getFrameSizeInBytes(AudioFormatDescription{}, AudioChannelLayout{}));
+    EXPECT_EQ(sizeof(int16_t), getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_16_BIT),
+                                                   make_AudioChannelLayout_Mono()));
+    EXPECT_EQ(2 * sizeof(int16_t),
+              getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_16_BIT),
+                                  make_AudioChannelLayout_Stereo()));
+    EXPECT_EQ(sizeof(int32_t), getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_32_BIT),
+                                                   make_AudioChannelLayout_Mono()));
+    EXPECT_EQ(2 * sizeof(int32_t),
+              getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_32_BIT),
+                                  make_AudioChannelLayout_Stereo()));
+    EXPECT_EQ(sizeof(float), getFrameSizeInBytes(make_AudioFormatDescription(PcmType::FLOAT_32_BIT),
+                                                 make_AudioChannelLayout_Mono()));
+    EXPECT_EQ(2 * sizeof(float),
+              getFrameSizeInBytes(make_AudioFormatDescription(PcmType::FLOAT_32_BIT),
+                                  make_AudioChannelLayout_Stereo()));
+    EXPECT_EQ(sizeof(uint8_t),
+              getFrameSizeInBytes(make_AudioFormatDescription("bitstream"), AudioChannelLayout{}));
+    EXPECT_EQ(sizeof(int16_t),
+              getFrameSizeInBytes(make_AudioFormatDescription(PcmType::INT_16_BIT, "encapsulated"),
+                                  AudioChannelLayout{}));
+}
+
+TEST(UtilsTest, PcmSampleSize) {
+    EXPECT_EQ(1UL, getPcmSampleSizeInBytes(PcmType{}));
+    EXPECT_EQ(sizeof(uint8_t), getPcmSampleSizeInBytes(PcmType::UINT_8_BIT));
+    EXPECT_EQ(sizeof(int16_t), getPcmSampleSizeInBytes(PcmType::INT_16_BIT));
+    EXPECT_EQ(sizeof(int32_t), getPcmSampleSizeInBytes(PcmType::INT_32_BIT));
+    EXPECT_EQ(sizeof(int32_t), getPcmSampleSizeInBytes(PcmType::FIXED_Q_8_24));
+    EXPECT_EQ(sizeof(float), getPcmSampleSizeInBytes(PcmType::FLOAT_32_BIT));
+    EXPECT_EQ(3UL, getPcmSampleSizeInBytes(PcmType::INT_24_BIT));
+    EXPECT_EQ(0UL, getPcmSampleSizeInBytes(PcmType(-1)));
+    using PcmTypeUnderlyingType = std::underlying_type_t<PcmType>;
+    EXPECT_EQ(0UL,
+              getPcmSampleSizeInBytes(PcmType(std::numeric_limits<PcmTypeUnderlyingType>::min())));
+    EXPECT_EQ(0UL,
+              getPcmSampleSizeInBytes(PcmType(std::numeric_limits<PcmTypeUnderlyingType>::max())));
+}
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
new file mode 100644
index 0000000..c9edae0
--- /dev/null
+++ b/audio/aidl/default/Android.bp
@@ -0,0 +1,174 @@
+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_defaults {
+    name: "aidlaudioservice_defaults",
+    vendor: true,
+    shared_libs: [
+        "libalsautilsv2",
+        "libaudioaidlcommon",
+        "libaudioutils",
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "libstagefright_foundation",
+        "libtinyalsav2",
+        "libutils",
+        "libxml2",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+    ],
+    header_libs: [
+        "libaudio_system_headers",
+        "libaudioaidl_headers",
+        "libxsdc-utils",
+    ],
+}
+
+cc_library {
+    name: "libaudioservicesounddoseimpl",
+    vendor: true,
+    defaults: [
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_core_sounddose_ndk_shared",
+        "latest_android_hardware_audio_sounddose_ndk_shared",
+    ],
+    export_include_dirs: ["include"],
+    srcs: [
+        "SoundDose.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libutils",
+    ],
+    visibility: [
+        "//hardware/interfaces/audio/aidl/sounddose/default",
+    ],
+}
+
+cc_library {
+    name: "libaudioserviceexampleimpl",
+    defaults: [
+        "aidlaudioservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_core_ndk_shared",
+        "latest_android_hardware_audio_core_sounddose_ndk_shared",
+    ],
+    export_include_dirs: ["include"],
+    srcs: [
+        "AudioPolicyConfigXmlConverter.cpp",
+        "Bluetooth.cpp",
+        "Config.cpp",
+        "Configuration.cpp",
+        "EngineConfigXmlConverter.cpp",
+        "Module.cpp",
+        "SoundDose.cpp",
+        "Stream.cpp",
+        "StreamStub.cpp",
+        "Telephony.cpp",
+        "usb/ModuleUsb.cpp",
+        "usb/StreamUsb.cpp",
+        "usb/UsbAlsaMixerControl.cpp",
+        "usb/UsbAlsaUtils.cpp",
+    ],
+    generated_sources: [
+        "audio_policy_configuration_aidl_default",
+        "audio_policy_engine_configuration_aidl_default",
+    ],
+    generated_headers: [
+        "audio_policy_configuration_aidl_default",
+        "audio_policy_engine_configuration_aidl_default",
+    ],
+    export_generated_headers: [
+        "audio_policy_configuration_aidl_default",
+        "audio_policy_engine_configuration_aidl_default",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.audio.service-aidl.example",
+    relative_install_path: "hw",
+    init_rc: ["android.hardware.audio.service-aidl.example.rc"],
+    vintf_fragments: ["android.hardware.audio.service-aidl.xml"],
+    defaults: [
+        "aidlaudioservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_core_sounddose_ndk_shared",
+        "latest_android_hardware_audio_core_ndk_shared",
+    ],
+    static_libs: [
+        "libaudioserviceexampleimpl",
+    ],
+    srcs: ["main.cpp"],
+}
+
+cc_defaults {
+    name: "aidlaudioeffectservice_defaults",
+    defaults: [
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    vendor: true,
+    shared_libs: [
+        "libaudioaidlcommon",
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libutils",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+    ],
+    header_libs: [
+        "libaudioaidl_headers",
+        "libaudio_system_headers",
+        "libsystem_headers",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+    ],
+}
+
+filegroup {
+    name: "effectCommonFile",
+    srcs: [
+        "EffectThread.cpp",
+        "EffectImpl.cpp",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.audio.effect.service-aidl.example",
+    relative_install_path: "hw",
+    init_rc: ["android.hardware.audio.effect.service-aidl.example.rc"],
+    vintf_fragments: ["android.hardware.audio.effect.service-aidl.xml"],
+    defaults: ["aidlaudioeffectservice_defaults"],
+    shared_libs: [
+        "libtinyxml2",
+    ],
+    srcs: [
+        "EffectConfig.cpp",
+        "EffectFactory.cpp",
+        "EffectMain.cpp",
+    ],
+}
+
+cc_library_headers {
+    name: "libaudioaidl_headers",
+    export_include_dirs: ["include"],
+    vendor_available: true,
+    host_supported: true,
+}
diff --git a/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp
new file mode 100644
index 0000000..6290912
--- /dev/null
+++ b/audio/aidl/default/AudioPolicyConfigXmlConverter.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#include <functional>
+#include <unordered_map>
+
+#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <system/audio-base-utils.h>
+
+#include "core-impl/AudioPolicyConfigXmlConverter.h"
+
+using aidl::android::media::audio::common::AudioHalEngineConfig;
+using aidl::android::media::audio::common::AudioHalVolumeCurve;
+using aidl::android::media::audio::common::AudioHalVolumeGroup;
+using aidl::android::media::audio::common::AudioStreamType;
+
+namespace xsd = android::audio::policy::configuration;
+
+namespace aidl::android::hardware::audio::core::internal {
+
+static const int kDefaultVolumeIndexMin = 0;
+static const int kDefaultVolumeIndexMax = 100;
+static const int KVolumeIndexDeferredToAudioService = -1;
+/**
+ * Valid curve points take the form "<index>,<attenuationMb>", where the index
+ * must be in the range [0,100]. kInvalidCurvePointIndex is used to indicate
+ * that a point was formatted incorrectly (e.g. if a vendor accidentally typed a
+ * '.' instead of a ',' in their XML) -- using such a curve point will result in
+ * failed VTS tests.
+ */
+static const int8_t kInvalidCurvePointIndex = -1;
+
+AudioHalVolumeCurve::CurvePoint AudioPolicyConfigXmlConverter::convertCurvePointToAidl(
+        const std::string& xsdcCurvePoint) {
+    AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
+    if (sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index,
+               &aidlCurvePoint.attenuationMb) != 2) {
+        aidlCurvePoint.index = kInvalidCurvePointIndex;
+    }
+    return aidlCurvePoint;
+}
+
+AudioHalVolumeCurve AudioPolicyConfigXmlConverter::convertVolumeCurveToAidl(
+        const xsd::Volume& xsdcVolumeCurve) {
+    AudioHalVolumeCurve aidlVolumeCurve;
+    aidlVolumeCurve.deviceCategory =
+            static_cast<AudioHalVolumeCurve::DeviceCategory>(xsdcVolumeCurve.getDeviceCategory());
+    if (xsdcVolumeCurve.hasRef()) {
+        if (mVolumesReferenceMap.empty()) {
+            mVolumesReferenceMap = generateReferenceMap<xsd::Volumes, xsd::Reference>(
+                    getXsdcConfig()->getVolumes());
+        }
+        aidlVolumeCurve.curvePoints =
+                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                        mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(),
+                        std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this,
+                                  std::placeholders::_1));
+    } else {
+        aidlVolumeCurve.curvePoints =
+                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                        xsdcVolumeCurve.getPoint(),
+                        std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this,
+                                  std::placeholders::_1));
+    }
+    return aidlVolumeCurve;
+}
+
+void AudioPolicyConfigXmlConverter::mapStreamToVolumeCurve(const xsd::Volume& xsdcVolumeCurve) {
+    mStreamToVolumeCurvesMap[xsdcVolumeCurve.getStream()].push_back(
+            convertVolumeCurveToAidl(xsdcVolumeCurve));
+}
+
+const AudioHalEngineConfig& AudioPolicyConfigXmlConverter::getAidlEngineConfig() {
+    if (mAidlEngineConfig.volumeGroups.empty() && getXsdcConfig() &&
+        getXsdcConfig()->hasVolumes()) {
+        parseVolumes();
+    }
+    return mAidlEngineConfig;
+}
+
+void AudioPolicyConfigXmlConverter::mapStreamsToVolumeCurves() {
+    if (getXsdcConfig()->hasVolumes()) {
+        for (const xsd::Volumes& xsdcWrapperType : getXsdcConfig()->getVolumes()) {
+            for (const xsd::Volume& xsdcVolume : xsdcWrapperType.getVolume()) {
+                mapStreamToVolumeCurve(xsdcVolume);
+            }
+        }
+    }
+}
+
+void AudioPolicyConfigXmlConverter::addVolumeGroupstoEngineConfig() {
+    for (const auto& [xsdcStream, volumeCurves] : mStreamToVolumeCurvesMap) {
+        AudioHalVolumeGroup volumeGroup;
+        volumeGroup.name = xsd::toString(xsdcStream);
+        if (static_cast<int>(xsdcStream) >= AUDIO_STREAM_PUBLIC_CNT) {
+            volumeGroup.minIndex = kDefaultVolumeIndexMin;
+            volumeGroup.maxIndex = kDefaultVolumeIndexMax;
+        } else {
+            volumeGroup.minIndex = KVolumeIndexDeferredToAudioService;
+            volumeGroup.maxIndex = KVolumeIndexDeferredToAudioService;
+        }
+        volumeGroup.volumeCurves = volumeCurves;
+        mAidlEngineConfig.volumeGroups.push_back(std::move(volumeGroup));
+    }
+}
+
+void AudioPolicyConfigXmlConverter::parseVolumes() {
+    if (mStreamToVolumeCurvesMap.empty() && getXsdcConfig()->hasVolumes()) {
+        mapStreamsToVolumeCurves();
+        addVolumeGroupstoEngineConfig();
+    }
+}
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/Bluetooth.cpp b/audio/aidl/default/Bluetooth.cpp
new file mode 100644
index 0000000..c32b538
--- /dev/null
+++ b/audio/aidl/default/Bluetooth.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_Bluetooth"
+#include <android-base/logging.h>
+
+#include "core-impl/Bluetooth.h"
+
+using aidl::android::hardware::audio::core::VendorParameter;
+using aidl::android::media::audio::common::Boolean;
+using aidl::android::media::audio::common::Float;
+using aidl::android::media::audio::common::Int;
+
+namespace aidl::android::hardware::audio::core {
+
+Bluetooth::Bluetooth() {
+    mScoConfig.isEnabled = Boolean{false};
+    mScoConfig.isNrecEnabled = Boolean{false};
+    mScoConfig.mode = ScoConfig::Mode::SCO;
+    mHfpConfig.isEnabled = Boolean{false};
+    mHfpConfig.sampleRate = Int{8000};
+    mHfpConfig.volume = Float{HfpConfig::VOLUME_MAX};
+}
+
+ndk::ScopedAStatus Bluetooth::setScoConfig(const ScoConfig& in_config, ScoConfig* _aidl_return) {
+    if (in_config.isEnabled.has_value()) {
+        mScoConfig.isEnabled = in_config.isEnabled;
+    }
+    if (in_config.isNrecEnabled.has_value()) {
+        mScoConfig.isNrecEnabled = in_config.isNrecEnabled;
+    }
+    if (in_config.mode != ScoConfig::Mode::UNSPECIFIED) {
+        mScoConfig.mode = in_config.mode;
+    }
+    if (in_config.debugName.has_value()) {
+        mScoConfig.debugName = in_config.debugName;
+    }
+    *_aidl_return = mScoConfig;
+    LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
+               << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Bluetooth::setHfpConfig(const HfpConfig& in_config, HfpConfig* _aidl_return) {
+    if (in_config.sampleRate.has_value() && in_config.sampleRate.value().value <= 0) {
+        LOG(ERROR) << __func__ << ": invalid sample rate: " << in_config.sampleRate.value().value;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_config.volume.has_value() && (in_config.volume.value().value < HfpConfig::VOLUME_MIN ||
+                                         in_config.volume.value().value > HfpConfig::VOLUME_MAX)) {
+        LOG(ERROR) << __func__ << ": invalid volume: " << in_config.volume.value().value;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    if (in_config.isEnabled.has_value()) {
+        mHfpConfig.isEnabled = in_config.isEnabled;
+    }
+    if (in_config.sampleRate.has_value()) {
+        mHfpConfig.sampleRate = in_config.sampleRate;
+    }
+    if (in_config.volume.has_value()) {
+        mHfpConfig.volume = in_config.volume;
+    }
+    *_aidl_return = mHfpConfig;
+    LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
+               << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothA2dp::isEnabled(bool* _aidl_return) {
+    *_aidl_return = mEnabled;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothA2dp::setEnabled(bool in_enabled) {
+    mEnabled = in_enabled;
+    LOG(DEBUG) << __func__ << ": " << mEnabled;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothA2dp::supportsOffloadReconfiguration(bool* _aidl_return) {
+    *_aidl_return = true;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothA2dp::reconfigureOffload(
+        const std::vector<::aidl::android::hardware::audio::core::VendorParameter>& in_parameters
+                __unused) {
+    LOG(DEBUG) << __func__ << ": " << ::android::internal::ToString(in_parameters);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothLe::isEnabled(bool* _aidl_return) {
+    *_aidl_return = mEnabled;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothLe::setEnabled(bool in_enabled) {
+    mEnabled = in_enabled;
+    LOG(DEBUG) << __func__ << ": " << mEnabled;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothLe::supportsOffloadReconfiguration(bool* _aidl_return) {
+    *_aidl_return = true;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothLe::reconfigureOffload(
+        const std::vector<::aidl::android::hardware::audio::core::VendorParameter>& in_parameters
+                __unused) {
+    LOG(DEBUG) << __func__ << ": " << ::android::internal::ToString(in_parameters);
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/Config.cpp b/audio/aidl/default/Config.cpp
new file mode 100644
index 0000000..87c0ace
--- /dev/null
+++ b/audio/aidl/default/Config.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_Config"
+#include <android-base/logging.h>
+
+#include <system/audio_config.h>
+
+#include "core-impl/AudioPolicyConfigXmlConverter.h"
+#include "core-impl/Config.h"
+#include "core-impl/EngineConfigXmlConverter.h"
+
+using aidl::android::media::audio::common::AudioHalEngineConfig;
+
+namespace aidl::android::hardware::audio::core {
+ndk::ScopedAStatus Config::getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) {
+    SurroundSoundConfig surroundSoundConfig;
+    // TODO: parse from XML; for now, use empty config as default
+    *_aidl_return = std::move(surroundSoundConfig);
+    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Config::getEngineConfig(AudioHalEngineConfig* _aidl_return) {
+    static const AudioHalEngineConfig returnEngCfg = [this]() {
+        AudioHalEngineConfig engConfig;
+        if (mEngConfigConverter.getStatus() == ::android::OK) {
+            engConfig = mEngConfigConverter.getAidlEngineConfig();
+        } else {
+            LOG(INFO) << __func__ << mEngConfigConverter.getError();
+            if (mAudioPolicyConverter.getStatus() == ::android::OK) {
+                engConfig = mAudioPolicyConverter.getAidlEngineConfig();
+            } else {
+                LOG(WARNING) << __func__ << mAudioPolicyConverter.getError();
+            }
+        }
+        return engConfig;
+    }();
+    *_aidl_return = returnEngCfg;
+    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
new file mode 100644
index 0000000..e1e1f79
--- /dev/null
+++ b/audio/aidl/default/Configuration.cpp
@@ -0,0 +1,471 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Utils.h>
+#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <aidl/android/media/audio/common/AudioDeviceType.h>
+#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+#include <aidl/android/media/audio/common/AudioFormatType.h>
+#include <aidl/android/media/audio/common/AudioIoFlags.h>
+#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include "core-impl/Configuration.h"
+
+using aidl::android::hardware::audio::common::makeBitPositionFlagMask;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioGainConfig;
+using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioOutputFlags;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortDeviceExt;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioPortMixExt;
+using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::MicrophoneInfo;
+using aidl::android::media::audio::common::PcmType;
+
+namespace aidl::android::hardware::audio::core::internal {
+
+static void fillProfile(AudioProfile* profile, const std::vector<int32_t>& channelLayouts,
+                        const std::vector<int32_t>& sampleRates) {
+    for (auto layout : channelLayouts) {
+        profile->channelMasks.push_back(
+                AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout));
+    }
+    profile->sampleRates.insert(profile->sampleRates.end(), sampleRates.begin(), sampleRates.end());
+}
+
+static AudioProfile createProfile(PcmType pcmType, const std::vector<int32_t>& channelLayouts,
+                                  const std::vector<int32_t>& sampleRates) {
+    AudioProfile profile;
+    profile.format.type = AudioFormatType::PCM;
+    profile.format.pcm = pcmType;
+    fillProfile(&profile, channelLayouts, sampleRates);
+    return profile;
+}
+
+static AudioProfile createProfile(const std::string& encodingType,
+                                  const std::vector<int32_t>& channelLayouts,
+                                  const std::vector<int32_t>& sampleRates) {
+    AudioProfile profile;
+    profile.format.encoding = encodingType;
+    fillProfile(&profile, channelLayouts, sampleRates);
+    return profile;
+}
+
+static AudioPortExt createDeviceExt(AudioDeviceType devType, int32_t flags,
+                                    std::string connection = "") {
+    AudioPortDeviceExt deviceExt;
+    deviceExt.device.type.type = devType;
+    if (devType == AudioDeviceType::IN_MICROPHONE && connection.empty()) {
+        deviceExt.device.address = "bottom";
+    } else if (devType == AudioDeviceType::IN_MICROPHONE_BACK && connection.empty()) {
+        deviceExt.device.address = "back";
+    }
+    deviceExt.device.type.connection = std::move(connection);
+    deviceExt.flags = flags;
+    return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
+}
+
+static AudioPortExt createPortMixExt(int32_t maxOpenStreamCount, int32_t maxActiveStreamCount) {
+    AudioPortMixExt mixExt;
+    mixExt.maxOpenStreamCount = maxOpenStreamCount;
+    mixExt.maxActiveStreamCount = maxActiveStreamCount;
+    return AudioPortExt::make<AudioPortExt::Tag::mix>(mixExt);
+}
+
+static AudioPort createPort(int32_t id, const std::string& name, int32_t flags, bool isInput,
+                            const AudioPortExt& ext) {
+    AudioPort port;
+    port.id = id;
+    port.name = name;
+    port.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
+                         : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
+    port.ext = ext;
+    return port;
+}
+
+static AudioPortConfig createPortConfig(int32_t id, int32_t portId, PcmType pcmType, int32_t layout,
+                                        int32_t sampleRate, int32_t flags, bool isInput,
+                                        const AudioPortExt& ext) {
+    AudioPortConfig config;
+    config.id = id;
+    config.portId = portId;
+    config.sampleRate = Int{.value = sampleRate};
+    config.channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout);
+    config.format = AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = pcmType};
+    config.gain = AudioGainConfig();
+    config.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
+                           : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
+    config.ext = ext;
+    return config;
+}
+
+static AudioRoute createRoute(const std::vector<AudioPort>& sources, const AudioPort& sink) {
+    AudioRoute route;
+    route.sinkPortId = sink.id;
+    std::transform(sources.begin(), sources.end(), std::back_inserter(route.sourcePortIds),
+                   [](const auto& port) { return port.id; });
+    return route;
+}
+
+// Primary (default) configuration:
+//
+// Device ports:
+//  * "Speaker", OUT_SPEAKER, default
+//    - no profiles specified
+//  * "Built-in Mic", IN_MICROPHONE, default
+//    - no profiles specified
+//  * "Telephony Tx", OUT_TELEPHONY_TX
+//    - no profiles specified
+//  * "Telephony Rx", IN_TELEPHONY_RX
+//    - no profiles specified
+//  * "FM Tuner", IN_FM_TUNER
+//    - no profiles specified
+//  * "USB Out", OUT_DEVICE, CONNECTION_USB
+//    - no profiles specified
+//  * "USB In", IN_DEVICE, CONNECTION_USB
+//    - no profiles specified
+//
+// Mix ports:
+//  * "primary output", PRIMARY, 1 max open, 1 max active stream
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//  * "compressed offload", DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING, 1 max open, 1 max active stream
+//    - profile MP3; MONO, STEREO; 44100, 48000
+//  * "primary input", 2 max open, 2 max active streams
+//    - profile PCM 16-bit; MONO, STEREO, FRONT_BACK;
+//        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO, FRONT_BACK;
+//        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+//  * "telephony_tx", 1 max open, 1 max active stream
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//  * "telephony_rx", 1 max open, 1 max active stream
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//  * "fm_tuner", 1 max open, 1 max active stream
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//
+// Routes:
+//  "primary out", "compressed offload" -> "Speaker"
+//  "primary out", "compressed offload" -> "USB Out"
+//  "Built-in Mic", "USB In" -> "primary input"
+//  "telephony_tx" -> "Telephony Tx"
+//  "Telephony Rx" -> "telephony_rx"
+//  "FM Tuner" -> "fm_tuner"
+//
+// Initial port configs:
+//  * "Speaker" device port: PCM 24-bit; STEREO; 48000
+//  * "Built-in Mic" device port: PCM 24-bit; MONO; 48000
+//  * "Telephony Tx" device port: PCM 24-bit; MONO; 48000
+//  * "Telephony Rx" device port: PCM 24-bit; MONO; 48000
+//  * "FM Tuner" device port: PCM 24-bit; STEREO; 48000
+//
+// Profiles for device port connected state:
+//  * USB Out":
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//  * USB In":
+//    - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+//
+std::unique_ptr<Configuration> getPrimaryConfiguration() {
+    static const Configuration configuration = []() {
+        const std::vector<AudioProfile> standardPcmAudioProfiles = {
+                createProfile(PcmType::INT_16_BIT,
+                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
+                              {8000, 11025, 16000, 32000, 44100, 48000}),
+                createProfile(PcmType::INT_24_BIT,
+                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
+                              {8000, 11025, 16000, 32000, 44100, 48000})};
+        Configuration c;
+
+        // Device ports
+
+        AudioPort speakerOutDevice =
+                createPort(c.nextPortId++, "Speaker", 0, false,
+                           createDeviceExt(AudioDeviceType::OUT_SPEAKER,
+                                           1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
+        c.ports.push_back(speakerOutDevice);
+        c.initialConfigs.push_back(
+                createPortConfig(speakerOutDevice.id, speakerOutDevice.id, PcmType::INT_24_BIT,
+                                 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false,
+                                 createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)));
+
+        AudioPort micInDevice =
+                createPort(c.nextPortId++, "Built-in Mic", 0, true,
+                           createDeviceExt(AudioDeviceType::IN_MICROPHONE,
+                                           1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
+        c.ports.push_back(micInDevice);
+        c.initialConfigs.push_back(
+                createPortConfig(micInDevice.id, micInDevice.id, PcmType::INT_24_BIT,
+                                 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
+                                 createDeviceExt(AudioDeviceType::IN_MICROPHONE, 0)));
+
+        AudioPort telephonyTxOutDevice =
+                createPort(c.nextPortId++, "Telephony Tx", 0, false,
+                           createDeviceExt(AudioDeviceType::OUT_TELEPHONY_TX, 0));
+        c.ports.push_back(telephonyTxOutDevice);
+        c.initialConfigs.push_back(
+                createPortConfig(telephonyTxOutDevice.id, telephonyTxOutDevice.id,
+                                 PcmType::INT_24_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
+                                 false, createDeviceExt(AudioDeviceType::OUT_TELEPHONY_TX, 0)));
+
+        AudioPort telephonyRxInDevice =
+                createPort(c.nextPortId++, "Telephony Rx", 0, true,
+                           createDeviceExt(AudioDeviceType::IN_TELEPHONY_RX, 0));
+        c.ports.push_back(telephonyRxInDevice);
+        c.initialConfigs.push_back(
+                createPortConfig(telephonyRxInDevice.id, telephonyRxInDevice.id,
+                                 PcmType::INT_24_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
+                                 true, createDeviceExt(AudioDeviceType::IN_TELEPHONY_RX, 0)));
+
+        AudioPort fmTunerInDevice = createPort(c.nextPortId++, "FM Tuner", 0, true,
+                                               createDeviceExt(AudioDeviceType::IN_FM_TUNER, 0));
+        c.ports.push_back(fmTunerInDevice);
+        c.initialConfigs.push_back(
+                createPortConfig(fmTunerInDevice.id, fmTunerInDevice.id, PcmType::INT_24_BIT,
+                                 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, true,
+                                 createDeviceExt(AudioDeviceType::IN_FM_TUNER, 0)));
+
+        AudioPort usbOutDevice =
+                createPort(c.nextPortId++, "USB Out", 0, false,
+                           createDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
+                                           AudioDeviceDescription::CONNECTION_USB));
+        c.ports.push_back(usbOutDevice);
+        c.connectedProfiles[usbOutDevice.id] = standardPcmAudioProfiles;
+
+        AudioPort usbInDevice = createPort(c.nextPortId++, "USB In", 0, true,
+                                           createDeviceExt(AudioDeviceType::IN_DEVICE, 0,
+                                                           AudioDeviceDescription::CONNECTION_USB));
+        c.ports.push_back(usbInDevice);
+        c.connectedProfiles[usbInDevice.id] = standardPcmAudioProfiles;
+
+        // Mix ports
+
+        AudioPort primaryOutMix = createPort(c.nextPortId++, "primary output",
+                                             makeBitPositionFlagMask(AudioOutputFlags::PRIMARY),
+                                             false, createPortMixExt(1, 1));
+        primaryOutMix.profiles.insert(primaryOutMix.profiles.begin(),
+                                      standardPcmAudioProfiles.begin(),
+                                      standardPcmAudioProfiles.end());
+        c.ports.push_back(primaryOutMix);
+
+        AudioPort compressedOffloadOutMix =
+                createPort(c.nextPortId++, "compressed offload",
+                           makeBitPositionFlagMask({AudioOutputFlags::DIRECT,
+                                                    AudioOutputFlags::COMPRESS_OFFLOAD,
+                                                    AudioOutputFlags::NON_BLOCKING}),
+                           false, createPortMixExt(1, 1));
+        compressedOffloadOutMix.profiles.push_back(
+                createProfile(::android::MEDIA_MIMETYPE_AUDIO_MPEG,
+                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
+                              {44100, 48000}));
+        c.ports.push_back(compressedOffloadOutMix);
+
+        AudioPort primaryInMix =
+                createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(2, 2));
+        primaryInMix.profiles.push_back(
+                createProfile(PcmType::INT_16_BIT,
+                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
+                               AudioChannelLayout::LAYOUT_FRONT_BACK},
+                              {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
+        primaryInMix.profiles.push_back(
+                createProfile(PcmType::INT_24_BIT,
+                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
+                               AudioChannelLayout::LAYOUT_FRONT_BACK},
+                              {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
+        c.ports.push_back(primaryInMix);
+
+        AudioPort telephonyTxOutMix =
+                createPort(c.nextPortId++, "telephony_tx", 0, false, createPortMixExt(1, 1));
+        telephonyTxOutMix.profiles.insert(telephonyTxOutMix.profiles.begin(),
+                                          standardPcmAudioProfiles.begin(),
+                                          standardPcmAudioProfiles.end());
+        c.ports.push_back(telephonyTxOutMix);
+
+        AudioPort telephonyRxInMix =
+                createPort(c.nextPortId++, "telephony_rx", 0, true, createPortMixExt(1, 1));
+        telephonyRxInMix.profiles.insert(telephonyRxInMix.profiles.begin(),
+                                         standardPcmAudioProfiles.begin(),
+                                         standardPcmAudioProfiles.end());
+        c.ports.push_back(telephonyRxInMix);
+
+        AudioPort fmTunerInMix =
+                createPort(c.nextPortId++, "fm_tuner", 0, true, createPortMixExt(1, 1));
+        fmTunerInMix.profiles.insert(fmTunerInMix.profiles.begin(),
+                                     standardPcmAudioProfiles.begin(),
+                                     standardPcmAudioProfiles.end());
+        c.ports.push_back(fmTunerInMix);
+
+        c.routes.push_back(createRoute({primaryOutMix, compressedOffloadOutMix}, speakerOutDevice));
+        c.routes.push_back(createRoute({primaryOutMix, compressedOffloadOutMix}, usbOutDevice));
+        c.routes.push_back(createRoute({micInDevice, usbInDevice}, primaryInMix));
+        c.routes.push_back(createRoute({telephonyTxOutMix}, telephonyTxOutDevice));
+        c.routes.push_back(createRoute({telephonyRxInDevice}, telephonyRxInMix));
+        c.routes.push_back(createRoute({fmTunerInDevice}, fmTunerInMix));
+
+        c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());
+
+        MicrophoneInfo mic;
+        mic.id = "mic";
+        mic.device = micInDevice.ext.get<AudioPortExt::Tag::device>().device;
+        mic.group = 0;
+        mic.indexInTheGroup = 0;
+        c.microphones = std::vector<MicrophoneInfo>{mic};
+
+        return c;
+    }();
+    return std::make_unique<Configuration>(configuration);
+}
+
+// Remote Submix configuration:
+//
+// Device ports:
+//  * "Remote Submix Out", OUT_SUBMIX
+//    - profile PCM 24-bit; STEREO; 48000
+//  * "Remote Submix In", IN_SUBMIX
+//    - profile PCM 24-bit; STEREO; 48000
+//
+// Mix ports:
+//  * "r_submix output", stream count unlimited
+//    - profile PCM 24-bit; STEREO; 48000
+//  * "r_submix input", stream count unlimited
+//    - profile PCM 24-bit; STEREO; 48000
+//
+// Routes:
+//  "r_submix output" -> "Remote Submix Out"
+//  "Remote Submix In" -> "r_submix input"
+//
+std::unique_ptr<Configuration> getRSubmixConfiguration() {
+    static const Configuration configuration = []() {
+        Configuration c;
+
+        // Device ports
+
+        AudioPort rsubmixOutDevice = createPort(c.nextPortId++, "Remote Submix Out", 0, false,
+                                                createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0));
+        rsubmixOutDevice.profiles.push_back(
+                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
+        c.ports.push_back(rsubmixOutDevice);
+
+        AudioPort rsubmixInDevice = createPort(c.nextPortId++, "Remote Submix In", 0, true,
+                                               createDeviceExt(AudioDeviceType::IN_SUBMIX, 0));
+        rsubmixInDevice.profiles.push_back(
+                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
+        c.ports.push_back(rsubmixInDevice);
+
+        // Mix ports
+
+        AudioPort rsubmixOutMix =
+                createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(0, 0));
+        rsubmixOutMix.profiles.push_back(
+                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
+        c.ports.push_back(rsubmixOutMix);
+
+        AudioPort rsubmixInMix =
+                createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(0, 0));
+        rsubmixInMix.profiles.push_back(
+                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
+        c.ports.push_back(rsubmixInMix);
+
+        c.routes.push_back(createRoute({rsubmixOutMix}, rsubmixOutDevice));
+        c.routes.push_back(createRoute({rsubmixInDevice}, rsubmixInMix));
+
+        return c;
+    }();
+    return std::make_unique<Configuration>(configuration);
+}
+
+// Usb configuration:
+//
+// Device ports:
+//  * "USB Headset Out", OUT_HEADSET, CONNECTION_USB
+//    - no profiles specified
+//  * "USB Headset In", IN_HEADSET, CONNECTION_USB
+//    - no profiles specified
+//
+// Mix ports:
+//  * "usb_headset output", 1 max open, 1 max active stream
+//    - no profiles specified
+//  * "usb_headset input", 1 max open, 1 max active stream
+//    - no profiles specified
+//
+// Profiles for device port connected state:
+//  * USB Headset Out":
+//    - profile PCM 16-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000
+//  * USB Headset In":
+//    - profile PCM 16-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000
+//    - profile PCM 24-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000
+//
+std::unique_ptr<Configuration> getUsbConfiguration() {
+    static const Configuration configuration = []() {
+        const std::vector<AudioProfile> standardPcmAudioProfiles = {
+                createProfile(PcmType::INT_16_BIT,
+                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
+                               AudioChannelLayout::INDEX_MASK_1, AudioChannelLayout::INDEX_MASK_2},
+                              {44100, 48000}),
+                createProfile(PcmType::INT_24_BIT,
+                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
+                               AudioChannelLayout::INDEX_MASK_1, AudioChannelLayout::INDEX_MASK_2},
+                              {44100, 48000})};
+        Configuration c;
+
+        // Device ports
+
+        AudioPort usbOutHeadset =
+                createPort(c.nextPortId++, "USB Headset Out", 0, false,
+                           createDeviceExt(AudioDeviceType::OUT_HEADSET, 0,
+                                           AudioDeviceDescription::CONNECTION_USB));
+        c.ports.push_back(usbOutHeadset);
+        c.connectedProfiles[usbOutHeadset.id] = standardPcmAudioProfiles;
+
+        AudioPort usbInHeadset =
+                createPort(c.nextPortId++, "USB Headset In", 0, true,
+                           createDeviceExt(AudioDeviceType::IN_HEADSET, 0,
+                                           AudioDeviceDescription::CONNECTION_USB));
+        c.ports.push_back(usbInHeadset);
+        c.connectedProfiles[usbInHeadset.id] = standardPcmAudioProfiles;
+
+        // Mix ports
+
+        AudioPort usbHeadsetOutMix =
+                createPort(c.nextPortId++, "usb_headset output", 0, false, createPortMixExt(1, 1));
+        c.ports.push_back(usbHeadsetOutMix);
+
+        AudioPort usbHeadsetInMix =
+                createPort(c.nextPortId++, "usb_headset input", 0, true, createPortMixExt(1, 1));
+        c.ports.push_back(usbHeadsetInMix);
+
+        c.routes.push_back(createRoute({usbHeadsetOutMix}, usbOutHeadset));
+        c.routes.push_back(createRoute({usbInHeadset}, usbHeadsetInMix));
+
+        return c;
+    }();
+    return std::make_unique<Configuration>(configuration);
+}
+
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp
new file mode 100644
index 0000000..71d111b
--- /dev/null
+++ b/audio/aidl/default/EffectConfig.cpp
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <optional>
+#include <string>
+#define LOG_TAG "AHAL_EffectConfig"
+#include <android-base/logging.h>
+#include <system/audio_effects/audio_effects_conf.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "effectFactory-impl/EffectConfig.h"
+
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
+using aidl::android::media::audio::common::AudioUuid;
+
+namespace aidl::android::hardware::audio::effect {
+
+EffectConfig::EffectConfig(const std::string& file) {
+    tinyxml2::XMLDocument doc;
+    doc.LoadFile(file.c_str());
+    LOG(DEBUG) << __func__ << " loading " << file;
+    // parse the xml file into maps
+    if (doc.Error()) {
+        LOG(ERROR) << __func__ << " tinyxml2 failed to load " << file
+                   << " error: " << doc.ErrorStr();
+        return;
+    }
+
+    auto registerFailure = [&](bool result) { mSkippedElements += result ? 0 : 1; };
+
+    for (auto& xmlConfig : getChildren(doc, "audio_effects_conf")) {
+        // Parse library
+        for (auto& xmlLibraries : getChildren(xmlConfig, "libraries")) {
+            for (auto& xmlLibrary : getChildren(xmlLibraries, "library")) {
+                registerFailure(parseLibrary(xmlLibrary));
+            }
+        }
+
+        // Parse effects
+        for (auto& xmlEffects : getChildren(xmlConfig, "effects")) {
+            for (auto& xmlEffect : getChildren(xmlEffects)) {
+                registerFailure(parseEffect(xmlEffect));
+            }
+        }
+
+        // Parse pre processing chains
+        for (auto& xmlPreprocess : getChildren(xmlConfig, "preprocess")) {
+            for (auto& xmlStream : getChildren(xmlPreprocess, "stream")) {
+                // AudioSource
+                registerFailure(parseProcessing(Processing::Type::source, xmlStream));
+            }
+        }
+
+        // Parse post processing chains
+        for (auto& xmlPostprocess : getChildren(xmlConfig, "postprocess")) {
+            for (auto& xmlStream : getChildren(xmlPostprocess, "stream")) {
+                // AudioStreamType
+                registerFailure(parseProcessing(Processing::Type::streamType, xmlStream));
+            }
+        }
+    }
+    LOG(DEBUG) << __func__ << " successfully parsed " << file << ", skipping " << mSkippedElements
+               << " element(s)";
+}
+
+std::vector<std::reference_wrapper<const tinyxml2::XMLElement>> EffectConfig::getChildren(
+        const tinyxml2::XMLNode& node, const char* childTag) {
+    std::vector<std::reference_wrapper<const tinyxml2::XMLElement>> children;
+    for (auto* child = node.FirstChildElement(childTag); child != nullptr;
+         child = child->NextSiblingElement(childTag)) {
+        children.emplace_back(*child);
+    }
+    return children;
+}
+
+bool EffectConfig::resolveLibrary(const std::string& path, std::string* resolvedPath) {
+    for (auto* libraryDirectory : kEffectLibPath) {
+        std::string candidatePath = std::string(libraryDirectory) + '/' + path;
+        if (access(candidatePath.c_str(), R_OK) == 0) {
+            *resolvedPath = std::move(candidatePath);
+            return true;
+        }
+    }
+    return false;
+}
+
+bool EffectConfig::parseLibrary(const tinyxml2::XMLElement& xml) {
+    const char* name = xml.Attribute("name");
+    RETURN_VALUE_IF(!name, false, "noNameAttribute");
+    const char* path = xml.Attribute("path");
+    RETURN_VALUE_IF(!path, false, "noPathAttribute");
+
+    std::string resolvedPath;
+    if (!resolveLibrary(path, &resolvedPath)) {
+        LOG(ERROR) << __func__ << " can't find " << path;
+        return false;
+    }
+    mLibraryMap[name] = resolvedPath;
+    LOG(DEBUG) << __func__ << " " << name << " : " << resolvedPath;
+    return true;
+}
+
+bool EffectConfig::parseEffect(const tinyxml2::XMLElement& xml) {
+    struct EffectLibraries effectLibraries;
+    std::vector<LibraryUuid> libraryUuids;
+    std::string name = xml.Attribute("name");
+    RETURN_VALUE_IF(name == "", false, "effectsNoName");
+
+    LOG(DEBUG) << __func__ << dump(xml);
+    struct LibraryUuid libraryUuid;
+    if (std::strcmp(xml.Name(), "effectProxy") == 0) {
+        // proxy lib and uuid
+        RETURN_VALUE_IF(!parseLibraryUuid(xml, libraryUuid, true), false, "parseProxyLibFailed");
+        effectLibraries.proxyLibrary = libraryUuid;
+        // proxy effect libs and UUID
+        auto xmlProxyLib = xml.FirstChildElement();
+        RETURN_VALUE_IF(!xmlProxyLib, false, "noLibForProxy");
+        while (xmlProxyLib) {
+            struct LibraryUuid tempLibraryUuid;
+            RETURN_VALUE_IF(!parseLibraryUuid(*xmlProxyLib, tempLibraryUuid), false,
+                            "parseEffectLibFailed");
+            libraryUuids.push_back(std::move(tempLibraryUuid));
+            xmlProxyLib = xmlProxyLib->NextSiblingElement();
+        }
+    } else {
+        // expect only one library if not proxy
+        RETURN_VALUE_IF(!parseLibraryUuid(xml, libraryUuid), false, "parseEffectLibFailed");
+        libraryUuids.push_back(std::move(libraryUuid));
+    }
+
+    effectLibraries.libraries = std::move(libraryUuids);
+    mEffectsMap[name] = std::move(effectLibraries);
+    return true;
+}
+
+bool EffectConfig::parseLibraryUuid(const tinyxml2::XMLElement& xml,
+                                    struct LibraryUuid& libraryUuid, bool isProxy) {
+    // Retrieve library name only if not effectProxy element
+    if (!isProxy) {
+        const char* name = xml.Attribute("library");
+        RETURN_VALUE_IF(!name, false, "noLibraryAttribute");
+        libraryUuid.name = name;
+    }
+
+    const char* uuidStr = xml.Attribute("uuid");
+    RETURN_VALUE_IF(!uuidStr, false, "noUuidAttribute");
+    libraryUuid.uuid = stringToUuid(uuidStr);
+    RETURN_VALUE_IF((libraryUuid.uuid == getEffectUuidZero()), false, "invalidUuidAttribute");
+
+    LOG(DEBUG) << __func__ << (isProxy ? " proxy " : libraryUuid.name) << " : "
+               << libraryUuid.uuid.toString();
+    return true;
+}
+
+std::optional<Processing::Type> EffectConfig::stringToProcessingType(Processing::Type::Tag typeTag,
+                                                                     const std::string& type) {
+    // see list of audio stream types in audio_stream_type_t:
+    // system/media/audio/include/system/audio_effects/audio_effects_conf.h
+    // AUDIO_STREAM_DEFAULT_TAG is not listed here because according to SYS_RESERVED_DEFAULT in
+    // AudioStreamType.aidl: "Value reserved for system use only. HALs must never return this value
+    // to the system or accept it from the system".
+    static const std::map<const std::string, AudioStreamType> sAudioStreamTypeTable = {
+            {AUDIO_STREAM_VOICE_CALL_TAG, AudioStreamType::VOICE_CALL},
+            {AUDIO_STREAM_SYSTEM_TAG, AudioStreamType::SYSTEM},
+            {AUDIO_STREAM_RING_TAG, AudioStreamType::RING},
+            {AUDIO_STREAM_MUSIC_TAG, AudioStreamType::MUSIC},
+            {AUDIO_STREAM_ALARM_TAG, AudioStreamType::ALARM},
+            {AUDIO_STREAM_NOTIFICATION_TAG, AudioStreamType::NOTIFICATION},
+            {AUDIO_STREAM_BLUETOOTH_SCO_TAG, AudioStreamType::BLUETOOTH_SCO},
+            {AUDIO_STREAM_ENFORCED_AUDIBLE_TAG, AudioStreamType::ENFORCED_AUDIBLE},
+            {AUDIO_STREAM_DTMF_TAG, AudioStreamType::DTMF},
+            {AUDIO_STREAM_TTS_TAG, AudioStreamType::TTS},
+            {AUDIO_STREAM_ASSISTANT_TAG, AudioStreamType::ASSISTANT}};
+
+    // see list of audio sources in audio_source_t:
+    // system/media/audio/include/system/audio_effects/audio_effects_conf.h
+    static const std::map<const std::string, AudioSource> sAudioSourceTable = {
+            {MIC_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_UL_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_DL_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_CALL_SRC_TAG, AudioSource::VOICE_CALL},
+            {CAMCORDER_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_REC_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_COMM_SRC_TAG, AudioSource::VOICE_CALL},
+            {REMOTE_SUBMIX_SRC_TAG, AudioSource::VOICE_CALL},
+            {UNPROCESSED_SRC_TAG, AudioSource::VOICE_CALL},
+            {VOICE_PERFORMANCE_SRC_TAG, AudioSource::VOICE_CALL}};
+
+    if (typeTag == Processing::Type::streamType) {
+        auto typeIter = sAudioStreamTypeTable.find(type);
+        if (typeIter != sAudioStreamTypeTable.end()) {
+            return typeIter->second;
+        }
+    } else if (typeTag == Processing::Type::source) {
+        auto typeIter = sAudioSourceTable.find(type);
+        if (typeIter != sAudioSourceTable.end()) {
+            return typeIter->second;
+        }
+    }
+
+    return std::nullopt;
+}
+
+bool EffectConfig::parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml) {
+    LOG(DEBUG) << __func__ << dump(xml);
+    const char* typeStr = xml.Attribute("type");
+    auto aidlType = stringToProcessingType(typeTag, typeStr);
+    RETURN_VALUE_IF(!aidlType.has_value(), false, "illegalStreamType");
+    RETURN_VALUE_IF(0 != mProcessingMap.count(aidlType.value()), false, "duplicateStreamType");
+
+    for (auto& apply : getChildren(xml, "apply")) {
+        const char* name = apply.get().Attribute("effect");
+        if (mEffectsMap.find(name) == mEffectsMap.end()) {
+            LOG(ERROR) << __func__ << " effect " << name << " doesn't exist, skipping";
+            continue;
+        }
+        RETURN_VALUE_IF(!name, false, "noEffectAttribute");
+        mProcessingMap[aidlType.value()].emplace_back(mEffectsMap[name]);
+        LOG(WARNING) << __func__ << " " << typeStr << " : " << name;
+    }
+    return true;
+}
+
+const std::map<Processing::Type, std::vector<EffectConfig::EffectLibraries>>&
+EffectConfig::getProcessingMap() const {
+    return mProcessingMap;
+}
+
+bool EffectConfig::findUuid(const std::string& xmlEffectName, AudioUuid* uuid) {
+// Difference from EFFECT_TYPE_LIST_DEF, there could be multiple name mapping to same Effect Type
+#define EFFECT_XML_TYPE_LIST_DEF(V)                        \
+    V("acoustic_echo_canceler", AcousticEchoCanceler)      \
+    V("automatic_gain_control_v1", AutomaticGainControlV1) \
+    V("automatic_gain_control_v2", AutomaticGainControlV2) \
+    V("bassboost", BassBoost)                              \
+    V("downmix", Downmix)                                  \
+    V("dynamics_processing", DynamicsProcessing)           \
+    V("equalizer", Equalizer)                              \
+    V("haptic_generator", HapticGenerator)                 \
+    V("loudness_enhancer", LoudnessEnhancer)               \
+    V("env_reverb", EnvReverb)                             \
+    V("reverb_env_aux", EnvReverb)                         \
+    V("reverb_env_ins", EnvReverb)                         \
+    V("preset_reverb", PresetReverb)                       \
+    V("reverb_pre_aux", PresetReverb)                      \
+    V("reverb_pre_ins", PresetReverb)                      \
+    V("noise_suppression", NoiseSuppression)               \
+    V("spatializer", Spatializer)                          \
+    V("virtualizer", Virtualizer)                          \
+    V("visualizer", Visualizer)                            \
+    V("volume", Volume)
+
+#define GENERATE_MAP_ENTRY_V(s, symbol) {s, &getEffectTypeUuid##symbol},
+
+    typedef const AudioUuid& (*UuidGetter)(void);
+    static const std::map<std::string, UuidGetter> uuidMap{
+            // std::make_pair("s", &getEffectTypeUuidExtension)};
+            {EFFECT_XML_TYPE_LIST_DEF(GENERATE_MAP_ENTRY_V)}};
+    if (auto it = uuidMap.find(xmlEffectName); it != uuidMap.end()) {
+        *uuid = (*it->second)();
+        return true;
+    }
+    return false;
+}
+
+const char* EffectConfig::dump(const tinyxml2::XMLElement& element,
+                               tinyxml2::XMLPrinter&& printer) const {
+    element.Accept(&printer);
+    return printer.CStr();
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp
new file mode 100644
index 0000000..7073a10
--- /dev/null
+++ b/audio/aidl/default/EffectFactory.cpp
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlfcn.h>
+#include <algorithm>
+#include <iterator>
+#include <memory>
+#include <optional>
+#include <tuple>
+#include <unordered_set>
+#define LOG_TAG "AHAL_EffectFactory"
+
+#include <android-base/logging.h>
+#include <android/binder_ibinder_platform.h>
+#include <system/audio_effects/effect_uuid.h>
+#include <system/thread_defs.h>
+
+#include "effect-impl/EffectTypes.h"
+#include "effectFactory-impl/EffectFactory.h"
+
+using aidl::android::media::audio::common::AudioUuid;
+
+namespace aidl::android::hardware::audio::effect {
+
+Factory::Factory(const std::string& file) : mConfig(EffectConfig(file)) {
+    LOG(DEBUG) << __func__ << " with config file: " << file;
+    loadEffectLibs();
+}
+
+Factory::~Factory() {
+    if (auto count = mEffectMap.size()) {
+        LOG(ERROR) << __func__ << " remaining " << count
+                   << " effect instances not destroyed indicating resource leak!";
+        for (const auto& it : mEffectMap) {
+            if (auto spEffect = it.first.lock()) {
+                LOG(ERROR) << __func__ << " erase remaining instance UUID "
+                           << it.second.first.toString();
+                destroyEffectImpl(spEffect);
+            }
+        }
+    }
+}
+
+ndk::ScopedAStatus Factory::getDescriptorWithUuid(const AudioUuid& uuid, Descriptor* desc) {
+    RETURN_IF(!desc, EX_NULL_POINTER, "nullDescriptor");
+
+    if (mEffectLibMap.count(uuid)) {
+        auto& entry = mEffectLibMap[uuid];
+        getDlSyms(entry);
+        auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry);
+        RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER,
+                  "dlNullQueryEffectFunc");
+        RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&uuid, desc));
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus Factory::queryEffects(const std::optional<AudioUuid>& in_type_uuid,
+                                         const std::optional<AudioUuid>& in_impl_uuid,
+                                         const std::optional<AudioUuid>& in_proxy_uuid,
+                                         std::vector<Descriptor>* _aidl_return) {
+    // get the matching list
+    std::vector<Descriptor::Identity> idList;
+    std::copy_if(mIdentitySet.begin(), mIdentitySet.end(), std::back_inserter(idList),
+                 [&](auto& id) {
+                     return (!in_type_uuid.has_value() || in_type_uuid.value() == id.type) &&
+                            (!in_impl_uuid.has_value() || in_impl_uuid.value() == id.uuid) &&
+                            (!in_proxy_uuid.has_value() ||
+                             (id.proxy.has_value() && in_proxy_uuid.value() == id.proxy.value()));
+                 });
+    // query through the matching list
+    for (const auto& id : idList) {
+        if (mEffectLibMap.count(id.uuid)) {
+            Descriptor desc;
+            RETURN_IF_ASTATUS_NOT_OK(getDescriptorWithUuid(id.uuid, &desc), "getDescriptorFailed");
+            // update proxy UUID with information from config xml
+            desc.common.id.proxy = id.proxy;
+            _aidl_return->emplace_back(std::move(desc));
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Factory::queryProcessing(const std::optional<Processing::Type>& in_type,
+                                            std::vector<Processing>* _aidl_return) {
+    const auto& processings = mConfig.getProcessingMap();
+    // Processing stream type
+    for (const auto& procIter : processings) {
+        if (!in_type.has_value() || in_type.value() == procIter.first) {
+            Processing process = {.type = procIter.first /* Processing::Type */};
+            for (const auto& libs : procIter.second /* std::vector<struct EffectLibraries> */) {
+                for (const auto& lib : libs.libraries /* std::vector<struct LibraryUuid> */) {
+                    Descriptor desc;
+                    if (libs.proxyLibrary.has_value()) {
+                        desc.common.id.proxy = libs.proxyLibrary.value().uuid;
+                    }
+                    RETURN_IF_ASTATUS_NOT_OK(getDescriptorWithUuid(lib.uuid, &desc),
+                                             "getDescriptorFailed");
+                    process.ids.emplace_back(desc);
+                }
+            }
+            _aidl_return->emplace_back(process);
+        }
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Factory::createEffect(const AudioUuid& in_impl_uuid,
+                                         std::shared_ptr<IEffect>* _aidl_return) {
+    LOG(DEBUG) << __func__ << ": UUID " << in_impl_uuid.toString();
+    if (mEffectLibMap.count(in_impl_uuid)) {
+        auto& entry = mEffectLibMap[in_impl_uuid];
+        getDlSyms(entry);
+
+        auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry);
+        RETURN_IF(!libInterface || !libInterface->createEffectFunc, EX_NULL_POINTER,
+                  "dlNullcreateEffectFunc");
+        std::shared_ptr<IEffect> effectSp;
+        RETURN_IF_BINDER_EXCEPTION(libInterface->createEffectFunc(&in_impl_uuid, &effectSp));
+        if (!effectSp) {
+            LOG(ERROR) << __func__ << ": library created null instance without return error!";
+            return ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
+        }
+        *_aidl_return = effectSp;
+        ndk::SpAIBinder effectBinder = effectSp->asBinder();
+        AIBinder_setMinSchedulerPolicy(effectBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
+        mEffectMap[std::weak_ptr<IEffect>(effectSp)] =
+                std::make_pair(in_impl_uuid, std::move(effectBinder));
+        LOG(DEBUG) << __func__ << ": instance " << effectSp.get() << " created successfully";
+        return ndk::ScopedAStatus::ok();
+    } else {
+        LOG(ERROR) << __func__ << ": library doesn't exist";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Factory::destroyEffectImpl(const std::shared_ptr<IEffect>& in_handle) {
+    std::weak_ptr<IEffect> wpHandle(in_handle);
+    // find the effect entry with key (std::weak_ptr<IEffect>)
+    if (auto effectIt = mEffectMap.find(wpHandle); effectIt != mEffectMap.end()) {
+        auto& uuid = effectIt->second.first;
+        // find implementation library with UUID
+        if (auto libIt = mEffectLibMap.find(uuid); libIt != mEffectLibMap.end()) {
+            auto& interface = std::get<kMapEntryInterfaceIndex>(libIt->second);
+            RETURN_IF(!interface || !interface->destroyEffectFunc, EX_NULL_POINTER,
+                      "dlNulldestroyEffectFunc");
+            RETURN_IF_BINDER_EXCEPTION(interface->destroyEffectFunc(in_handle));
+        } else {
+            LOG(ERROR) << __func__ << ": UUID " << uuid.toString() << " does not exist in libMap!";
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+        mEffectMap.erase(effectIt);
+        return ndk::ScopedAStatus::ok();
+    } else {
+        LOG(ERROR) << __func__ << ": instance " << in_handle << " does not exist!";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+}
+
+// go over the map and cleanup all expired weak_ptrs.
+void Factory::cleanupEffectMap() {
+    for (auto it = mEffectMap.begin(); it != mEffectMap.end();) {
+        if (nullptr == it->first.lock()) {
+            it = mEffectMap.erase(it);
+        } else {
+            ++it;
+        }
+    }
+}
+
+ndk::ScopedAStatus Factory::destroyEffect(const std::shared_ptr<IEffect>& in_handle) {
+    LOG(DEBUG) << __func__ << ": instance " << in_handle.get();
+    ndk::ScopedAStatus status = destroyEffectImpl(in_handle);
+    // always do the cleanup
+    cleanupEffectMap();
+    return status;
+}
+
+bool Factory::openEffectLibrary(const AudioUuid& impl, const std::string& path) {
+    std::function<void(void*)> dlClose = [](void* handle) -> void {
+        if (handle && dlclose(handle)) {
+            LOG(ERROR) << "dlclose failed " << dlerror();
+        }
+    };
+
+    auto libHandle =
+            std::unique_ptr<void, decltype(dlClose)>{dlopen(path.c_str(), RTLD_LAZY), dlClose};
+    if (!libHandle) {
+        LOG(ERROR) << __func__ << ": dlopen failed, err: " << dlerror();
+        return false;
+    }
+
+    LOG(INFO) << __func__ << " dlopen lib:" << path << "\nimpl:" << impl.toString()
+              << "\nhandle:" << libHandle;
+    auto interface = new effect_dl_interface_s{nullptr, nullptr, nullptr};
+    mEffectLibMap.insert(
+            {impl,
+             std::make_tuple(std::move(libHandle),
+                             std::unique_ptr<struct effect_dl_interface_s>(interface), path)});
+    return true;
+}
+
+void Factory::createIdentityWithConfig(const EffectConfig::LibraryUuid& configLib,
+                                       const AudioUuid& typeUuid,
+                                       const std::optional<AudioUuid> proxyUuid) {
+    static const auto& libMap = mConfig.getLibraryMap();
+    const std::string& libName = configLib.name;
+    if (auto path = libMap.find(libName); path != libMap.end()) {
+        Descriptor::Identity id;
+        id.type = typeUuid;
+        id.uuid = configLib.uuid;
+        id.proxy = proxyUuid;
+        LOG(DEBUG) << __func__ << " loading lib " << path->second << ": typeUuid "
+                   << id.type.toString() << "\nimplUuid " << id.uuid.toString() << " proxyUuid "
+                   << (proxyUuid.has_value() ? proxyUuid->toString() : "null");
+        if (openEffectLibrary(id.uuid, path->second)) {
+            mIdentitySet.insert(std::move(id));
+        }
+    } else {
+        LOG(ERROR) << __func__ << ": library " << libName << " not exist!";
+        return;
+    }
+}
+
+void Factory::loadEffectLibs() {
+    const auto& configEffectsMap = mConfig.getEffectsMap();
+    for (const auto& configEffects : configEffectsMap) {
+        if (AudioUuid uuid;
+            EffectConfig::findUuid(configEffects.first /* xml effect name */, &uuid)) {
+            const auto& configLibs = configEffects.second;
+            std::optional<AudioUuid> proxyUuid;
+            if (configLibs.proxyLibrary.has_value()) {
+                const auto& proxyLib = configLibs.proxyLibrary.value();
+                proxyUuid = proxyLib.uuid;
+            }
+            for (const auto& configLib : configLibs.libraries) {
+                createIdentityWithConfig(configLib, uuid, proxyUuid);
+            }
+        } else {
+            LOG(ERROR) << __func__ << ": can not find type UUID for effect " << configEffects.first
+                       << " skipping!";
+        }
+    }
+}
+
+void Factory::getDlSyms(DlEntry& entry) {
+    auto& dlHandle = std::get<kMapEntryHandleIndex>(entry);
+    RETURN_VALUE_IF(!dlHandle, void(), "dlNullHandle");
+    // Get the reference of the DL interfaces in library map tuple.
+    auto& dlInterface = std::get<kMapEntryInterfaceIndex>(entry);
+    // return if interface already exist
+    if (!dlInterface->createEffectFunc) {
+        dlInterface->createEffectFunc = (EffectCreateFunctor)dlsym(dlHandle.get(), "createEffect");
+    }
+    if (!dlInterface->queryEffectFunc) {
+        dlInterface->queryEffectFunc = (EffectQueryFunctor)dlsym(dlHandle.get(), "queryEffect");
+    }
+    if (!dlInterface->destroyEffectFunc) {
+        dlInterface->destroyEffectFunc =
+                (EffectDestroyFunctor)dlsym(dlHandle.get(), "destroyEffect");
+    }
+
+    if (!dlInterface->createEffectFunc || !dlInterface->destroyEffectFunc ||
+        !dlInterface->queryEffectFunc) {
+        LOG(ERROR) << __func__ << ": create (" << dlInterface->createEffectFunc << "), query ("
+                   << dlInterface->queryEffectFunc << "), or destroy ("
+                   << dlInterface->destroyEffectFunc
+                   << ") not exist in library: " << std::get<kMapEntryLibNameIndex>(entry)
+                   << " handle: " << dlHandle << " with dlerror: " << dlerror();
+        return;
+    }
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
new file mode 100644
index 0000000..da1ad11
--- /dev/null
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_EffectImpl"
+#include "effect-impl/EffectImpl.h"
+#include "effect-impl/EffectTypes.h"
+#include "include/effect-impl/EffectTypes.h"
+
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::PcmType;
+
+extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect>& instanceSp) {
+    State state;
+    ndk::ScopedAStatus status = instanceSp->getState(&state);
+    if (!status.isOk() || State::INIT != state) {
+        LOG(ERROR) << __func__ << " instance " << instanceSp.get()
+                   << " in state: " << toString(state) << ", status: " << status.getDescription();
+        return EX_ILLEGAL_STATE;
+    }
+    LOG(DEBUG) << __func__ << " instance " << instanceSp.get() << " destroyed";
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common,
+                                    const std::optional<Parameter::Specific>& specific,
+                                    OpenEffectReturn* ret) {
+    LOG(DEBUG) << getEffectName() << __func__;
+    // effect only support 32bits float
+    RETURN_IF(common.input.base.format.pcm != common.output.base.format.pcm ||
+                      common.input.base.format.pcm != PcmType::FLOAT_32_BIT,
+              EX_ILLEGAL_ARGUMENT, "dataMustBe32BitsFloat");
+    RETURN_OK_IF(mState != State::INIT);
+    auto context = createContext(common);
+    RETURN_IF(!context, EX_NULL_POINTER, "createContextFailed");
+
+    if (specific.has_value()) {
+        RETURN_IF_ASTATUS_NOT_OK(setParameterSpecific(specific.value()), "setSpecParamErr");
+    }
+
+    mState = State::IDLE;
+    context->dupeFmq(ret);
+    RETURN_IF(createThread(context, getEffectName()) != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
+              "FailedToCreateWorker");
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectImpl::close() {
+    RETURN_OK_IF(mState == State::INIT);
+    RETURN_IF(mState == State::PROCESSING, EX_ILLEGAL_STATE, "closeAtProcessing");
+
+    // stop the worker thread, ignore the return code
+    RETURN_IF(destroyThread() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
+              "FailedToDestroyWorker");
+    mState = State::INIT;
+    RETURN_IF(releaseContext() != RetCode::SUCCESS, EX_UNSUPPORTED_OPERATION,
+              "FailedToCreateWorker");
+
+    LOG(DEBUG) << getEffectName() << __func__;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) {
+    LOG(DEBUG) << getEffectName() << __func__ << " with: " << param.toString();
+
+    const auto tag = param.getTag();
+    switch (tag) {
+        case Parameter::common:
+        case Parameter::deviceDescription:
+        case Parameter::mode:
+        case Parameter::source:
+            FALLTHROUGH_INTENDED;
+        case Parameter::volumeStereo:
+            return setParameterCommon(param);
+        case Parameter::specific: {
+            return setParameterSpecific(param.get<Parameter::specific>());
+        }
+        default: {
+            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+                       << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "ParameterNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus EffectImpl::getParameter(const Parameter::Id& id, Parameter* param) {
+    LOG(DEBUG) << getEffectName() << __func__ << id.toString();
+    auto tag = id.getTag();
+    switch (tag) {
+        case Parameter::Id::commonTag: {
+            RETURN_IF_ASTATUS_NOT_OK(getParameterCommon(id.get<Parameter::Id::commonTag>(), param),
+                                     "CommonParamNotSupported");
+            break;
+        }
+        case Parameter::Id::vendorEffectTag:
+            FALLTHROUGH_INTENDED;
+        default: {
+            Parameter::Specific specific;
+            RETURN_IF_ASTATUS_NOT_OK(getParameterSpecific(id, &specific), "SpecParamNotSupported");
+            param->set<Parameter::specific>(specific);
+            break;
+        }
+    }
+    LOG(DEBUG) << getEffectName() << __func__ << param->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectImpl::setParameterCommon(const Parameter& param) {
+    auto context = getContext();
+    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+
+    auto tag = param.getTag();
+    switch (tag) {
+        case Parameter::common:
+            RETURN_IF(context->setCommon(param.get<Parameter::common>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setCommFailed");
+            break;
+        case Parameter::deviceDescription:
+            RETURN_IF(context->setOutputDevice(param.get<Parameter::deviceDescription>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
+            break;
+        case Parameter::mode:
+            RETURN_IF(context->setAudioMode(param.get<Parameter::mode>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setModeFailed");
+            break;
+        case Parameter::source:
+            RETURN_IF(context->setAudioSource(param.get<Parameter::source>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setSourceFailed");
+            break;
+        case Parameter::volumeStereo:
+            RETURN_IF(context->setVolumeStereo(param.get<Parameter::volumeStereo>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setVolumeStereoFailed");
+            break;
+        default: {
+            LOG(ERROR) << getEffectName() << __func__ << " unsupportedParameterTag "
+                       << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "commonParamNotSupported");
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectImpl::getParameterCommon(const Parameter::Tag& tag, Parameter* param) {
+    auto context = getContext();
+    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+
+    switch (tag) {
+        case Parameter::common: {
+            param->set<Parameter::common>(context->getCommon());
+            break;
+        }
+        case Parameter::deviceDescription: {
+            param->set<Parameter::deviceDescription>(context->getOutputDevice());
+            break;
+        }
+        case Parameter::mode: {
+            param->set<Parameter::mode>(context->getAudioMode());
+            break;
+        }
+        case Parameter::source: {
+            param->set<Parameter::source>(context->getAudioSource());
+            break;
+        }
+        case Parameter::volumeStereo: {
+            param->set<Parameter::volumeStereo>(context->getVolumeStereo());
+            break;
+        }
+        default: {
+            LOG(DEBUG) << getEffectName() << __func__ << " unsupported tag " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "tagNotSupported");
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectImpl::getState(State* state) {
+    *state = mState;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectImpl::command(CommandId command) {
+    RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "CommandStateError");
+    LOG(DEBUG) << getEffectName() << __func__ << ": receive command: " << toString(command)
+               << " at state " << toString(mState);
+
+    switch (command) {
+        case CommandId::START:
+            RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "instanceNotOpen");
+            RETURN_OK_IF(mState == State::PROCESSING);
+            RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
+            startThread();
+            mState = State::PROCESSING;
+            break;
+        case CommandId::STOP:
+        case CommandId::RESET:
+            RETURN_OK_IF(mState == State::IDLE);
+            stopThread();
+            RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
+            mState = State::IDLE;
+            break;
+        default:
+            LOG(ERROR) << getEffectName() << __func__ << " instance still processing";
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "CommandIdNotSupported");
+    }
+    LOG(DEBUG) << getEffectName() << __func__ << " transfer to state: " << toString(mState);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EffectImpl::commandImpl(CommandId command) {
+    auto context = getContext();
+    RETURN_IF(!context, EX_NULL_POINTER, "nullContext");
+    if (command == CommandId::RESET) {
+        context->resetBuffer();
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+void EffectImpl::cleanUp() {
+    command(CommandId::STOP);
+    close();
+}
+
+IEffect::Status EffectImpl::status(binder_status_t status, size_t consumed, size_t produced) {
+    IEffect::Status ret;
+    ret.status = status;
+    ret.fmqConsumed = consumed;
+    ret.fmqProduced = produced;
+    return ret;
+}
+
+// A placeholder processing implementation to copy samples from input to output
+IEffect::Status EffectImpl::effectProcessImpl(float* in, float* out, int samples) {
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    LOG(DEBUG) << getEffectName() << __func__ << " done processing " << samples << " samples";
+    return {STATUS_OK, samples, samples};
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectMain.cpp b/audio/aidl/default/EffectMain.cpp
new file mode 100644
index 0000000..ca81204
--- /dev/null
+++ b/audio/aidl/default/EffectMain.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "effectFactory-impl/EffectFactory.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <system/audio_config.h>
+
+/** Default name of effect configuration file. */
+static const char* kDefaultConfigName = "audio_effects_config.xml";
+
+int main() {
+    // This is a debug implementation, always enable debug logging.
+    android::base::SetMinimumLogSeverity(::android::base::DEBUG);
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+    auto configFile = android::audio_find_readable_configuration_file(kDefaultConfigName);
+    if (configFile == "") {
+        LOG(ERROR) << __func__ << ": config file " << kDefaultConfigName << " not found!";
+        return EXIT_FAILURE;
+    }
+    LOG(DEBUG) << __func__ << ": start factory with configFile:" << configFile;
+    auto effectFactory =
+            ndk::SharedRefBase::make<aidl::android::hardware::audio::effect::Factory>(configFile);
+
+    std::string serviceName = std::string() + effectFactory->descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(effectFactory->asBinder().get(), serviceName.c_str());
+    CHECK_EQ(STATUS_OK, status);
+
+    LOG(DEBUG) << __func__ << ": effectFactory: " << serviceName << " start";
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/audio/aidl/default/EffectThread.cpp b/audio/aidl/default/EffectThread.cpp
new file mode 100644
index 0000000..574dc69
--- /dev/null
+++ b/audio/aidl/default/EffectThread.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstddef>
+#include <memory>
+
+#define LOG_TAG "AHAL_EffectThread"
+#include <android-base/logging.h>
+#include <pthread.h>
+#include <sys/resource.h>
+
+#include "effect-impl/EffectThread.h"
+#include "effect-impl/EffectTypes.h"
+
+using ::android::hardware::EventFlag;
+
+namespace aidl::android::hardware::audio::effect {
+
+EffectThread::EffectThread() {
+    LOG(DEBUG) << __func__;
+}
+
+EffectThread::~EffectThread() {
+    destroyThread();
+    LOG(DEBUG) << __func__ << " done";
+}
+
+RetCode EffectThread::createThread(std::shared_ptr<EffectContext> context, const std::string& name,
+                                   int priority) {
+    if (mThread.joinable()) {
+        LOG(WARNING) << mName << __func__ << " thread already created, no-op";
+        return RetCode::SUCCESS;
+    }
+    mName = name;
+    mPriority = priority;
+    {
+        std::lock_guard lg(mThreadMutex);
+        mThreadContext = std::move(context);
+        auto statusMQ = mThreadContext->getStatusFmq();
+        EventFlag* efGroup = nullptr;
+        ::android::status_t status =
+                EventFlag::createEventFlag(statusMQ->getEventFlagWord(), &efGroup);
+        if (status != ::android::OK || !efGroup) {
+            LOG(ERROR) << mName << __func__ << " create EventFlagGroup failed " << status
+                       << " efGroup " << efGroup;
+            return RetCode::ERROR_THREAD;
+        }
+        mEfGroup.reset(efGroup);
+        // kickoff and wait for commands (CommandId::START/STOP) or IEffect.close from client
+        mEfGroup->wake(kEventFlagNotEmpty);
+    }
+
+    mThread = std::thread(&EffectThread::threadLoop, this);
+    LOG(DEBUG) << mName << __func__ << " priority " << mPriority << " done";
+    return RetCode::SUCCESS;
+}
+
+RetCode EffectThread::destroyThread() {
+    {
+        std::lock_guard lg(mThreadMutex);
+        mStop = mExit = true;
+    }
+    mCv.notify_one();
+
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+
+    {
+        std::lock_guard lg(mThreadMutex);
+        mThreadContext.reset();
+    }
+    LOG(DEBUG) << mName << __func__;
+    return RetCode::SUCCESS;
+}
+
+RetCode EffectThread::startThread() {
+    {
+        std::lock_guard lg(mThreadMutex);
+        mStop = false;
+        mCv.notify_one();
+    }
+
+    mEfGroup->wake(kEventFlagNotEmpty);
+    LOG(DEBUG) << mName << __func__;
+    return RetCode::SUCCESS;
+}
+
+RetCode EffectThread::stopThread() {
+    {
+        std::lock_guard lg(mThreadMutex);
+        mStop = true;
+        mCv.notify_one();
+    }
+
+    mEfGroup->wake(kEventFlagNotEmpty);
+    LOG(DEBUG) << mName << __func__;
+    return RetCode::SUCCESS;
+}
+
+void EffectThread::threadLoop() {
+    pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
+    setpriority(PRIO_PROCESS, 0, mPriority);
+    while (true) {
+        /**
+         * wait for the EventFlag without lock, it's ok because the mEfGroup pointer will not change
+         * in the life cycle of workerThread (threadLoop).
+         */
+        uint32_t efState = 0;
+        mEfGroup->wait(kEventFlagNotEmpty, &efState);
+
+        {
+            std::unique_lock l(mThreadMutex);
+            ::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
+            mCv.wait(l, [&]() REQUIRES(mThreadMutex) { return mExit || !mStop; });
+            if (mExit) {
+                LOG(INFO) << __func__ << " EXIT!";
+                return;
+            }
+            process_l();
+        }
+    }
+}
+
+void EffectThread::process_l() {
+    RETURN_VALUE_IF(!mThreadContext, void(), "nullContext");
+
+    auto statusMQ = mThreadContext->getStatusFmq();
+    auto inputMQ = mThreadContext->getInputDataFmq();
+    auto outputMQ = mThreadContext->getOutputDataFmq();
+    auto buffer = mThreadContext->getWorkBuffer();
+
+    auto processSamples = inputMQ->availableToRead();
+    if (processSamples) {
+        inputMQ->read(buffer, processSamples);
+        IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
+        outputMQ->write(buffer, status.fmqProduced);
+        statusMQ->writeBlocking(&status, 1);
+        LOG(DEBUG) << mName << __func__ << ": done processing, effect consumed "
+                   << status.fmqConsumed << " produced " << status.fmqProduced;
+    }
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EngineConfigXmlConverter.cpp b/audio/aidl/default/EngineConfigXmlConverter.cpp
new file mode 100644
index 0000000..5f17d71
--- /dev/null
+++ b/audio/aidl/default/EngineConfigXmlConverter.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <functional>
+#include <unordered_map>
+
+#include <aidl/android/media/audio/common/AudioFlag.h>
+#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <aidl/android/media/audio/common/AudioProductStrategyType.h>
+
+#include "core-impl/EngineConfigXmlConverter.h"
+
+using aidl::android::media::audio::common::AudioAttributes;
+using aidl::android::media::audio::common::AudioContentType;
+using aidl::android::media::audio::common::AudioFlag;
+using aidl::android::media::audio::common::AudioHalAttributesGroup;
+using aidl::android::media::audio::common::AudioHalCapCriterion;
+using aidl::android::media::audio::common::AudioHalCapCriterionType;
+using aidl::android::media::audio::common::AudioHalEngineConfig;
+using aidl::android::media::audio::common::AudioHalProductStrategy;
+using aidl::android::media::audio::common::AudioHalVolumeCurve;
+using aidl::android::media::audio::common::AudioHalVolumeGroup;
+using aidl::android::media::audio::common::AudioProductStrategyType;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
+using aidl::android::media::audio::common::AudioUsage;
+
+namespace xsd = android::audio::policy::engine::configuration;
+
+namespace aidl::android::hardware::audio::core::internal {
+
+/**
+ * Valid curve points take the form "<index>,<attenuationMb>", where the index
+ * must be in the range [0,100]. kInvalidCurvePointIndex is used to indicate
+ * that a point was formatted incorrectly (e.g. if a vendor accidentally typed a
+ * '.' instead of a ',' in their XML)-- using such a curve point will result in
+ * failed VTS tests.
+ */
+static const int8_t kInvalidCurvePointIndex = -1;
+
+void EngineConfigXmlConverter::initProductStrategyMap() {
+#define STRATEGY_ENTRY(name) {"STRATEGY_" #name, static_cast<int>(AudioProductStrategyType::name)}
+
+    mProductStrategyMap = {STRATEGY_ENTRY(MEDIA),
+                           STRATEGY_ENTRY(PHONE),
+                           STRATEGY_ENTRY(SONIFICATION),
+                           STRATEGY_ENTRY(SONIFICATION_RESPECTFUL),
+                           STRATEGY_ENTRY(DTMF),
+                           STRATEGY_ENTRY(ENFORCED_AUDIBLE),
+                           STRATEGY_ENTRY(TRANSMITTED_THROUGH_SPEAKER),
+                           STRATEGY_ENTRY(ACCESSIBILITY)};
+#undef STRATEGY_ENTRY
+}
+
+int EngineConfigXmlConverter::convertProductStrategyNameToAidl(
+        const std::string& xsdcProductStrategyName) {
+    const auto [it, success] = mProductStrategyMap.insert(
+            std::make_pair(xsdcProductStrategyName, mNextVendorStrategy));
+    if (success) {
+        mNextVendorStrategy++;
+    }
+    return it->second;
+}
+
+bool isDefaultAudioAttributes(const AudioAttributes& attributes) {
+    return ((attributes.contentType == AudioContentType::UNKNOWN) &&
+            (attributes.usage == AudioUsage::UNKNOWN) &&
+            (attributes.source == AudioSource::DEFAULT) && (attributes.flags == 0) &&
+            (attributes.tags.empty()));
+}
+
+AudioAttributes EngineConfigXmlConverter::convertAudioAttributesToAidl(
+        const xsd::AttributesType& xsdcAudioAttributes) {
+    if (xsdcAudioAttributes.hasAttributesRef()) {
+        if (mAttributesReferenceMap.empty()) {
+            mAttributesReferenceMap =
+                    generateReferenceMap<xsd::AttributesRef, xsd::AttributesRefType>(
+                            getXsdcConfig()->getAttributesRef());
+        }
+        return convertAudioAttributesToAidl(
+                *(mAttributesReferenceMap.at(xsdcAudioAttributes.getAttributesRef())
+                          .getFirstAttributes()));
+    }
+    AudioAttributes aidlAudioAttributes;
+    if (xsdcAudioAttributes.hasContentType()) {
+        aidlAudioAttributes.contentType = static_cast<AudioContentType>(
+                xsdcAudioAttributes.getFirstContentType()->getValue());
+    }
+    if (xsdcAudioAttributes.hasUsage()) {
+        aidlAudioAttributes.usage =
+                static_cast<AudioUsage>(xsdcAudioAttributes.getFirstUsage()->getValue());
+    }
+    if (xsdcAudioAttributes.hasSource()) {
+        aidlAudioAttributes.source =
+                static_cast<AudioSource>(xsdcAudioAttributes.getFirstSource()->getValue());
+    }
+    if (xsdcAudioAttributes.hasFlags()) {
+        std::vector<xsd::FlagType> xsdcFlagTypeVec =
+                xsdcAudioAttributes.getFirstFlags()->getValue();
+        for (const xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) {
+            if (xsdcFlagType != xsd::FlagType::AUDIO_FLAG_NONE) {
+                aidlAudioAttributes.flags |= 1 << (static_cast<int>(xsdcFlagType) - 1);
+            }
+        }
+    }
+    if (xsdcAudioAttributes.hasBundle()) {
+        const xsd::BundleType* xsdcBundle = xsdcAudioAttributes.getFirstBundle();
+        aidlAudioAttributes.tags[0] = xsdcBundle->getKey() + "=" + xsdcBundle->getValue();
+    }
+    if (isDefaultAudioAttributes(aidlAudioAttributes)) {
+        mDefaultProductStrategyId = std::optional<int>{-1};
+    }
+    return aidlAudioAttributes;
+}
+
+AudioHalAttributesGroup EngineConfigXmlConverter::convertAttributesGroupToAidl(
+        const xsd::AttributesGroup& xsdcAttributesGroup) {
+    AudioHalAttributesGroup aidlAttributesGroup;
+    static const int kStreamTypeEnumOffset =
+            static_cast<int>(xsd::Stream::AUDIO_STREAM_VOICE_CALL) -
+            static_cast<int>(AudioStreamType::VOICE_CALL);
+    aidlAttributesGroup.streamType = static_cast<AudioStreamType>(
+            static_cast<int>(xsdcAttributesGroup.getStreamType()) - kStreamTypeEnumOffset);
+    aidlAttributesGroup.volumeGroupName = xsdcAttributesGroup.getVolumeGroup();
+    if (xsdcAttributesGroup.hasAttributes_optional()) {
+        aidlAttributesGroup.attributes =
+                convertCollectionToAidl<xsd::AttributesType, AudioAttributes>(
+                        xsdcAttributesGroup.getAttributes_optional(),
+                        std::bind(&EngineConfigXmlConverter::convertAudioAttributesToAidl, this,
+                                  std::placeholders::_1));
+    } else if (xsdcAttributesGroup.hasContentType_optional() ||
+               xsdcAttributesGroup.hasUsage_optional() ||
+               xsdcAttributesGroup.hasSource_optional() ||
+               xsdcAttributesGroup.hasFlags_optional() ||
+               xsdcAttributesGroup.hasBundle_optional()) {
+        aidlAttributesGroup.attributes.push_back(convertAudioAttributesToAidl(xsd::AttributesType(
+                xsdcAttributesGroup.getContentType_optional(),
+                xsdcAttributesGroup.getUsage_optional(), xsdcAttributesGroup.getSource_optional(),
+                xsdcAttributesGroup.getFlags_optional(), xsdcAttributesGroup.getBundle_optional(),
+                std::nullopt)));
+
+    } else {
+        // do nothing;
+        // TODO: check if this is valid or if we should treat as an error.
+        // Currently, attributes are not mandatory in schema, but an AttributesGroup
+        // without attributes does not make much sense.
+    }
+    return aidlAttributesGroup;
+}
+
+AudioHalProductStrategy EngineConfigXmlConverter::convertProductStrategyToAidl(
+        const xsd::ProductStrategies::ProductStrategy& xsdcProductStrategy) {
+    AudioHalProductStrategy aidlProductStrategy;
+
+    aidlProductStrategy.id = convertProductStrategyNameToAidl(xsdcProductStrategy.getName());
+
+    if (xsdcProductStrategy.hasAttributesGroup()) {
+        aidlProductStrategy.attributesGroups =
+                convertCollectionToAidl<xsd::AttributesGroup, AudioHalAttributesGroup>(
+                        xsdcProductStrategy.getAttributesGroup(),
+                        std::bind(&EngineConfigXmlConverter::convertAttributesGroupToAidl, this,
+                                  std::placeholders::_1));
+    }
+    if ((mDefaultProductStrategyId != std::nullopt) && (mDefaultProductStrategyId.value() == -1)) {
+        mDefaultProductStrategyId = aidlProductStrategy.id;
+    }
+    return aidlProductStrategy;
+}
+
+AudioHalVolumeCurve::CurvePoint EngineConfigXmlConverter::convertCurvePointToAidl(
+        const std::string& xsdcCurvePoint) {
+    AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
+    if (sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index,
+               &aidlCurvePoint.attenuationMb) != 2) {
+        aidlCurvePoint.index = kInvalidCurvePointIndex;
+    }
+    return aidlCurvePoint;
+}
+
+AudioHalVolumeCurve EngineConfigXmlConverter::convertVolumeCurveToAidl(
+        const xsd::Volume& xsdcVolumeCurve) {
+    AudioHalVolumeCurve aidlVolumeCurve;
+    aidlVolumeCurve.deviceCategory =
+            static_cast<AudioHalVolumeCurve::DeviceCategory>(xsdcVolumeCurve.getDeviceCategory());
+    if (xsdcVolumeCurve.hasRef()) {
+        if (mVolumesReferenceMap.empty()) {
+            mVolumesReferenceMap = generateReferenceMap<xsd::VolumesType, xsd::VolumeRef>(
+                    getXsdcConfig()->getVolumes());
+        }
+        aidlVolumeCurve.curvePoints =
+                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                        mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(),
+                        std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this,
+                                  std::placeholders::_1));
+    } else {
+        aidlVolumeCurve.curvePoints =
+                convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
+                        xsdcVolumeCurve.getPoint(),
+                        std::bind(&EngineConfigXmlConverter::convertCurvePointToAidl, this,
+                                  std::placeholders::_1));
+    }
+    return aidlVolumeCurve;
+}
+
+AudioHalVolumeGroup EngineConfigXmlConverter::convertVolumeGroupToAidl(
+        const xsd::VolumeGroupsType::VolumeGroup& xsdcVolumeGroup) {
+    AudioHalVolumeGroup aidlVolumeGroup;
+    aidlVolumeGroup.name = xsdcVolumeGroup.getName();
+    aidlVolumeGroup.minIndex = xsdcVolumeGroup.getIndexMin();
+    aidlVolumeGroup.maxIndex = xsdcVolumeGroup.getIndexMax();
+    aidlVolumeGroup.volumeCurves = convertCollectionToAidl<xsd::Volume, AudioHalVolumeCurve>(
+            xsdcVolumeGroup.getVolume(),
+            std::bind(&EngineConfigXmlConverter::convertVolumeCurveToAidl, this,
+                      std::placeholders::_1));
+    return aidlVolumeGroup;
+}
+
+AudioHalCapCriterion EngineConfigXmlConverter::convertCapCriterionToAidl(
+        const xsd::CriterionType& xsdcCriterion) {
+    AudioHalCapCriterion aidlCapCriterion;
+    aidlCapCriterion.name = xsdcCriterion.getName();
+    aidlCapCriterion.criterionTypeName = xsdcCriterion.getType();
+    aidlCapCriterion.defaultLiteralValue = xsdcCriterion.get_default();
+    return aidlCapCriterion;
+}
+
+std::string EngineConfigXmlConverter::convertCriterionTypeValueToAidl(
+        const xsd::ValueType& xsdcCriterionTypeValue) {
+    return xsdcCriterionTypeValue.getLiteral();
+}
+
+AudioHalCapCriterionType EngineConfigXmlConverter::convertCapCriterionTypeToAidl(
+        const xsd::CriterionTypeType& xsdcCriterionType) {
+    AudioHalCapCriterionType aidlCapCriterionType;
+    aidlCapCriterionType.name = xsdcCriterionType.getName();
+    aidlCapCriterionType.isInclusive = !(static_cast<bool>(xsdcCriterionType.getType()));
+    aidlCapCriterionType.values =
+            convertWrappedCollectionToAidl<xsd::ValuesType, xsd::ValueType, std::string>(
+                    xsdcCriterionType.getValues(), &xsd::ValuesType::getValue,
+                    std::bind(&EngineConfigXmlConverter::convertCriterionTypeValueToAidl, this,
+                              std::placeholders::_1));
+    return aidlCapCriterionType;
+}
+
+AudioHalEngineConfig& EngineConfigXmlConverter::getAidlEngineConfig() {
+    return mAidlEngineConfig;
+}
+
+void EngineConfigXmlConverter::init() {
+    initProductStrategyMap();
+    if (getXsdcConfig()->hasProductStrategies()) {
+        mAidlEngineConfig.productStrategies =
+                convertWrappedCollectionToAidl<xsd::ProductStrategies,
+                                               xsd::ProductStrategies::ProductStrategy,
+                                               AudioHalProductStrategy>(
+                        getXsdcConfig()->getProductStrategies(),
+                        &xsd::ProductStrategies::getProductStrategy,
+                        std::bind(&EngineConfigXmlConverter::convertProductStrategyToAidl, this,
+                                  std::placeholders::_1));
+        if (mDefaultProductStrategyId) {
+            mAidlEngineConfig.defaultProductStrategyId = mDefaultProductStrategyId.value();
+        }
+    }
+    if (getXsdcConfig()->hasVolumeGroups()) {
+        mAidlEngineConfig.volumeGroups = convertWrappedCollectionToAidl<
+                xsd::VolumeGroupsType, xsd::VolumeGroupsType::VolumeGroup, AudioHalVolumeGroup>(
+                getXsdcConfig()->getVolumeGroups(), &xsd::VolumeGroupsType::getVolumeGroup,
+                std::bind(&EngineConfigXmlConverter::convertVolumeGroupToAidl, this,
+                          std::placeholders::_1));
+    }
+    if (getXsdcConfig()->hasCriteria() && getXsdcConfig()->hasCriterion_types()) {
+        AudioHalEngineConfig::CapSpecificConfig capSpecificConfig;
+        capSpecificConfig.criteria =
+                convertWrappedCollectionToAidl<xsd::CriteriaType, xsd::CriterionType,
+                                               AudioHalCapCriterion>(
+                        getXsdcConfig()->getCriteria(), &xsd::CriteriaType::getCriterion,
+                        std::bind(&EngineConfigXmlConverter::convertCapCriterionToAidl, this,
+                                  std::placeholders::_1));
+        capSpecificConfig.criterionTypes =
+                convertWrappedCollectionToAidl<xsd::CriterionTypesType, xsd::CriterionTypeType,
+                                               AudioHalCapCriterionType>(
+                        getXsdcConfig()->getCriterion_types(),
+                        &xsd::CriterionTypesType::getCriterion_type,
+                        std::bind(&EngineConfigXmlConverter::convertCapCriterionTypeToAidl, this,
+                                  std::placeholders::_1));
+        mAidlEngineConfig.capSpecificConfig = capSpecificConfig;
+    }
+}
+}  // namespace aidl::android::hardware::audio::core::internal
\ No newline at end of file
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
new file mode 100644
index 0000000..6b417a4
--- /dev/null
+++ b/audio/aidl/default/Module.cpp
@@ -0,0 +1,1356 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <set>
+
+#define LOG_TAG "AHAL_Module"
+#include <android-base/logging.h>
+#include <android/binder_ibinder_platform.h>
+
+#include <Utils.h>
+#include <aidl/android/media/audio/common/AudioInputFlags.h>
+#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+
+#include "core-impl/Bluetooth.h"
+#include "core-impl/Module.h"
+#include "core-impl/ModuleUsb.h"
+#include "core-impl/SoundDose.h"
+#include "core-impl/StreamStub.h"
+#include "core-impl/StreamUsb.h"
+#include "core-impl/Telephony.h"
+#include "core-impl/utils.h"
+
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
+using aidl::android::hardware::audio::common::isBitPositionFlagSet;
+using aidl::android::hardware::audio::common::isValidAudioMode;
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioInputFlags;
+using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioMMapPolicy;
+using aidl::android::media::audio::common::AudioMMapPolicyInfo;
+using aidl::android::media::audio::common::AudioMMapPolicyType;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::AudioOutputFlags;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::Boolean;
+using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::MicrophoneInfo;
+using aidl::android::media::audio::common::PcmType;
+
+namespace aidl::android::hardware::audio::core {
+
+namespace {
+
+bool generateDefaultPortConfig(const AudioPort& port, AudioPortConfig* config) {
+    *config = {};
+    config->portId = port.id;
+    if (port.profiles.empty()) {
+        LOG(ERROR) << __func__ << ": port " << port.id << " has no profiles";
+        return false;
+    }
+    const auto& profile = port.profiles.begin();
+    config->format = profile->format;
+    if (profile->channelMasks.empty()) {
+        LOG(ERROR) << __func__ << ": the first profile in port " << port.id
+                   << " has no channel masks";
+        return false;
+    }
+    config->channelMask = *profile->channelMasks.begin();
+    if (profile->sampleRates.empty()) {
+        LOG(ERROR) << __func__ << ": the first profile in port " << port.id
+                   << " has no sample rates";
+        return false;
+    }
+    Int sampleRate;
+    sampleRate.value = *profile->sampleRates.begin();
+    config->sampleRate = sampleRate;
+    config->flags = port.flags;
+    config->ext = port.ext;
+    return true;
+}
+
+bool findAudioProfile(const AudioPort& port, const AudioFormatDescription& format,
+                      AudioProfile* profile) {
+    if (auto profilesIt =
+                find_if(port.profiles.begin(), port.profiles.end(),
+                        [&format](const auto& profile) { return profile.format == format; });
+        profilesIt != port.profiles.end()) {
+        *profile = *profilesIt;
+        return true;
+    }
+    return false;
+}
+
+}  // namespace
+
+// static
+std::shared_ptr<Module> Module::createInstance(Type type) {
+    switch (type) {
+        case Module::Type::USB:
+            return ndk::SharedRefBase::make<ModuleUsb>(type);
+        case Type::DEFAULT:
+        case Type::R_SUBMIX:
+        default:
+            return ndk::SharedRefBase::make<Module>(type);
+    }
+}
+
+// static
+StreamIn::CreateInstance Module::getStreamInCreator(Type type) {
+    switch (type) {
+        case Type::USB:
+            return StreamInUsb::createInstance;
+        case Type::DEFAULT:
+        case Type::R_SUBMIX:
+        default:
+            return StreamInStub::createInstance;
+    }
+}
+
+// static
+StreamOut::CreateInstance Module::getStreamOutCreator(Type type) {
+    switch (type) {
+        case Type::USB:
+            return StreamOutUsb::createInstance;
+        case Type::DEFAULT:
+        case Type::R_SUBMIX:
+        default:
+            return StreamOutStub::createInstance;
+    }
+}
+
+std::ostream& operator<<(std::ostream& os, Module::Type t) {
+    switch (t) {
+        case Module::Type::DEFAULT:
+            os << "default";
+            break;
+        case Module::Type::R_SUBMIX:
+            os << "r_submix";
+            break;
+        case Module::Type::USB:
+            os << "usb";
+            break;
+    }
+    return os;
+}
+
+void Module::cleanUpPatch(int32_t patchId) {
+    erase_all_values(mPatches, std::set<int32_t>{patchId});
+}
+
+ndk::ScopedAStatus Module::createStreamContext(
+        int32_t in_portConfigId, int64_t in_bufferSizeFrames,
+        std::shared_ptr<IStreamCallback> asyncCallback,
+        std::shared_ptr<IStreamOutEventCallback> outEventCallback, StreamContext* out_context) {
+    if (in_bufferSizeFrames <= 0) {
+        LOG(ERROR) << __func__ << ": non-positive buffer size " << in_bufferSizeFrames;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_bufferSizeFrames < kMinimumStreamBufferSizeFrames) {
+        LOG(ERROR) << __func__ << ": insufficient buffer size " << in_bufferSizeFrames
+                   << ", must be at least " << kMinimumStreamBufferSizeFrames;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    auto& configs = getConfig().portConfigs;
+    auto portConfigIt = findById<AudioPortConfig>(configs, in_portConfigId);
+    // Since this is a private method, it is assumed that
+    // validity of the portConfigId has already been checked.
+    const size_t frameSize =
+            getFrameSizeInBytes(portConfigIt->format.value(), portConfigIt->channelMask.value());
+    if (frameSize == 0) {
+        LOG(ERROR) << __func__ << ": could not calculate frame size for port config "
+                   << portConfigIt->toString();
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    LOG(DEBUG) << __func__ << ": frame size " << frameSize << " bytes";
+    if (frameSize > kMaximumStreamBufferSizeBytes / in_bufferSizeFrames) {
+        LOG(ERROR) << __func__ << ": buffer size " << in_bufferSizeFrames
+                   << " frames is too large, maximum size is "
+                   << kMaximumStreamBufferSizeBytes / frameSize;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    const auto& flags = portConfigIt->flags.value();
+    if ((flags.getTag() == AudioIoFlags::Tag::input &&
+         !isBitPositionFlagSet(flags.get<AudioIoFlags::Tag::input>(),
+                               AudioInputFlags::MMAP_NOIRQ)) ||
+        (flags.getTag() == AudioIoFlags::Tag::output &&
+         !isBitPositionFlagSet(flags.get<AudioIoFlags::Tag::output>(),
+                               AudioOutputFlags::MMAP_NOIRQ))) {
+        StreamContext::DebugParameters params{mDebug.streamTransientStateDelayMs,
+                                              mVendorDebug.forceTransientBurst,
+                                              mVendorDebug.forceSynchronousDrain};
+        StreamContext temp(
+                std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
+                std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
+                portConfigIt->format.value(), portConfigIt->channelMask.value(),
+                portConfigIt->sampleRate.value().value,
+                std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames),
+                asyncCallback, outEventCallback, params);
+        if (temp.isValid()) {
+            *out_context = std::move(temp);
+        } else {
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+    } else {
+        // TODO: Implement simulation of MMAP buffer allocation
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::vector<AudioDevice> Module::findConnectedDevices(int32_t portConfigId) {
+    std::vector<AudioDevice> result;
+    auto& ports = getConfig().ports;
+    auto portIds = portIdsFromPortConfigIds(findConnectedPortConfigIds(portConfigId));
+    for (auto it = portIds.begin(); it != portIds.end(); ++it) {
+        auto portIt = findById<AudioPort>(ports, *it);
+        if (portIt != ports.end() && portIt->ext.getTag() == AudioPortExt::Tag::device) {
+            result.push_back(portIt->ext.template get<AudioPortExt::Tag::device>().device);
+        }
+    }
+    return result;
+}
+
+std::set<int32_t> Module::findConnectedPortConfigIds(int32_t portConfigId) {
+    std::set<int32_t> result;
+    auto patchIdsRange = mPatches.equal_range(portConfigId);
+    auto& patches = getConfig().patches;
+    for (auto it = patchIdsRange.first; it != patchIdsRange.second; ++it) {
+        auto patchIt = findById<AudioPatch>(patches, it->second);
+        if (patchIt == patches.end()) {
+            LOG(FATAL) << __func__ << ": patch with id " << it->second << " taken from mPatches "
+                       << "not found in the configuration";
+        }
+        if (std::find(patchIt->sourcePortConfigIds.begin(), patchIt->sourcePortConfigIds.end(),
+                      portConfigId) != patchIt->sourcePortConfigIds.end()) {
+            result.insert(patchIt->sinkPortConfigIds.begin(), patchIt->sinkPortConfigIds.end());
+        } else {
+            result.insert(patchIt->sourcePortConfigIds.begin(), patchIt->sourcePortConfigIds.end());
+        }
+    }
+    return result;
+}
+
+ndk::ScopedAStatus Module::findPortIdForNewStream(int32_t in_portConfigId, AudioPort** port) {
+    auto& configs = getConfig().portConfigs;
+    auto portConfigIt = findById<AudioPortConfig>(configs, in_portConfigId);
+    if (portConfigIt == configs.end()) {
+        LOG(ERROR) << __func__ << ": existing port config id " << in_portConfigId << " not found";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    const int32_t portId = portConfigIt->portId;
+    // In our implementation, configs of mix ports always have unique IDs.
+    CHECK(portId != in_portConfigId);
+    auto& ports = getConfig().ports;
+    auto portIt = findById<AudioPort>(ports, portId);
+    if (portIt == ports.end()) {
+        LOG(ERROR) << __func__ << ": port id " << portId << " used by port config id "
+                   << in_portConfigId << " not found";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (mStreams.count(in_portConfigId) != 0) {
+        LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+                   << " already has a stream opened on it";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    if (portIt->ext.getTag() != AudioPortExt::Tag::mix) {
+        LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+                   << " does not correspond to a mix port";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    const int32_t maxOpenStreamCount = portIt->ext.get<AudioPortExt::Tag::mix>().maxOpenStreamCount;
+    if (maxOpenStreamCount != 0 && mStreams.count(portId) >= maxOpenStreamCount) {
+        LOG(ERROR) << __func__ << ": port id " << portId
+                   << " has already reached maximum allowed opened stream count: "
+                   << maxOpenStreamCount;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    *port = &(*portIt);
+    return ndk::ScopedAStatus::ok();
+}
+
+template <typename C>
+std::set<int32_t> Module::portIdsFromPortConfigIds(C portConfigIds) {
+    std::set<int32_t> result;
+    auto& portConfigs = getConfig().portConfigs;
+    for (auto it = portConfigIds.begin(); it != portConfigIds.end(); ++it) {
+        auto portConfigIt = findById<AudioPortConfig>(portConfigs, *it);
+        if (portConfigIt != portConfigs.end()) {
+            result.insert(portConfigIt->portId);
+        }
+    }
+    return result;
+}
+
+internal::Configuration& Module::getConfig() {
+    if (!mConfig) {
+        switch (mType) {
+            case Type::DEFAULT:
+                mConfig = std::move(internal::getPrimaryConfiguration());
+                break;
+            case Type::R_SUBMIX:
+                mConfig = std::move(internal::getRSubmixConfiguration());
+                break;
+            case Type::USB:
+                mConfig = std::move(internal::getUsbConfiguration());
+                break;
+        }
+    }
+    return *mConfig;
+}
+
+void Module::registerPatch(const AudioPatch& patch) {
+    auto& configs = getConfig().portConfigs;
+    auto do_insert = [&](const std::vector<int32_t>& portConfigIds) {
+        for (auto portConfigId : portConfigIds) {
+            auto configIt = findById<AudioPortConfig>(configs, portConfigId);
+            if (configIt != configs.end()) {
+                mPatches.insert(std::pair{portConfigId, patch.id});
+                if (configIt->portId != portConfigId) {
+                    mPatches.insert(std::pair{configIt->portId, patch.id});
+                }
+            }
+        };
+    };
+    do_insert(patch.sourcePortConfigIds);
+    do_insert(patch.sinkPortConfigIds);
+}
+
+void Module::updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch) {
+    // Streams from the old patch need to be disconnected, streams from the new
+    // patch need to be connected. If the stream belongs to both patches, no need
+    // to update it.
+    std::set<int32_t> idsToDisconnect, idsToConnect;
+    idsToDisconnect.insert(oldPatch.sourcePortConfigIds.begin(),
+                           oldPatch.sourcePortConfigIds.end());
+    idsToDisconnect.insert(oldPatch.sinkPortConfigIds.begin(), oldPatch.sinkPortConfigIds.end());
+    idsToConnect.insert(newPatch.sourcePortConfigIds.begin(), newPatch.sourcePortConfigIds.end());
+    idsToConnect.insert(newPatch.sinkPortConfigIds.begin(), newPatch.sinkPortConfigIds.end());
+    std::for_each(idsToDisconnect.begin(), idsToDisconnect.end(), [&](const auto& portConfigId) {
+        if (idsToConnect.count(portConfigId) == 0) {
+            LOG(DEBUG) << "The stream on port config id " << portConfigId << " is not connected";
+            mStreams.setStreamIsConnected(portConfigId, {});
+        }
+    });
+    std::for_each(idsToConnect.begin(), idsToConnect.end(), [&](const auto& portConfigId) {
+        if (idsToDisconnect.count(portConfigId) == 0) {
+            const auto connectedDevices = findConnectedDevices(portConfigId);
+            LOG(DEBUG) << "The stream on port config id " << portConfigId
+                       << " is connected to: " << ::android::internal::ToString(connectedDevices);
+            mStreams.setStreamIsConnected(portConfigId, connectedDevices);
+        }
+    });
+}
+
+ndk::ScopedAStatus Module::setModuleDebug(
+        const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) {
+    LOG(DEBUG) << __func__ << ": " << mType << ": old flags:" << mDebug.toString()
+               << ", new flags: " << in_debug.toString();
+    if (mDebug.simulateDeviceConnections != in_debug.simulateDeviceConnections &&
+        !mConnectedDevicePorts.empty()) {
+        LOG(ERROR) << __func__ << ": " << mType
+                   << ": attempting to change device connections simulation while having external "
+                   << "devices connected";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    if (in_debug.streamTransientStateDelayMs < 0) {
+        LOG(ERROR) << __func__ << ": " << mType << ": streamTransientStateDelayMs is negative: "
+                   << in_debug.streamTransientStateDelayMs;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    mDebug = in_debug;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getTelephony(std::shared_ptr<ITelephony>* _aidl_return) {
+    if (!mTelephony) {
+        mTelephony = ndk::SharedRefBase::make<Telephony>();
+    }
+    *_aidl_return = mTelephony.getPtr();
+    LOG(DEBUG) << __func__ << ": returning instance of ITelephony: " << _aidl_return->get();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) {
+    if (!mBluetooth) {
+        mBluetooth = ndk::SharedRefBase::make<Bluetooth>();
+    }
+    *_aidl_return = mBluetooth.getPtr();
+    LOG(DEBUG) << __func__ << ": returning instance of IBluetooth: " << _aidl_return->get();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _aidl_return) {
+    if (!mBluetoothA2dp) {
+        mBluetoothA2dp = ndk::SharedRefBase::make<BluetoothA2dp>();
+    }
+    *_aidl_return = mBluetoothA2dp.getPtr();
+    LOG(DEBUG) << __func__ << ": returning instance of IBluetoothA2dp: " << _aidl_return->get();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) {
+    if (!mBluetoothLe) {
+        mBluetoothLe = ndk::SharedRefBase::make<BluetoothLe>();
+    }
+    *_aidl_return = mBluetoothLe.getPtr();
+    LOG(DEBUG) << __func__ << ": returning instance of IBluetoothLe: " << _aidl_return->get();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdAndAdditionalData,
+                                                 AudioPort* _aidl_return) {
+    const int32_t templateId = in_templateIdAndAdditionalData.id;
+    auto& ports = getConfig().ports;
+    AudioPort connectedPort;
+    {  // Scope the template port so that we don't accidentally modify it.
+        auto templateIt = findById<AudioPort>(ports, templateId);
+        if (templateIt == ports.end()) {
+            LOG(ERROR) << __func__ << ": port id " << templateId << " not found";
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+        if (templateIt->ext.getTag() != AudioPortExt::Tag::device) {
+            LOG(ERROR) << __func__ << ": port id " << templateId << " is not a device port";
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+        if (!templateIt->profiles.empty()) {
+            LOG(ERROR) << __func__ << ": port id " << templateId
+                       << " does not have dynamic profiles";
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+        auto& templateDevicePort = templateIt->ext.get<AudioPortExt::Tag::device>();
+        if (templateDevicePort.device.type.connection.empty()) {
+            LOG(ERROR) << __func__ << ": port id " << templateId << " is permanently attached";
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+        // Postpone id allocation until we ensure that there are no client errors.
+        connectedPort = *templateIt;
+        connectedPort.extraAudioDescriptors = in_templateIdAndAdditionalData.extraAudioDescriptors;
+        const auto& inputDevicePort =
+                in_templateIdAndAdditionalData.ext.get<AudioPortExt::Tag::device>();
+        auto& connectedDevicePort = connectedPort.ext.get<AudioPortExt::Tag::device>();
+        connectedDevicePort.device.address = inputDevicePort.device.address;
+        LOG(DEBUG) << __func__ << ": device port " << connectedPort.id << " device set to "
+                   << connectedDevicePort.device.toString();
+        // Check if there is already a connected port with for the same external device.
+        for (auto connectedPortPair : mConnectedDevicePorts) {
+            auto connectedPortIt = findById<AudioPort>(ports, connectedPortPair.first);
+            if (connectedPortIt->ext.get<AudioPortExt::Tag::device>().device ==
+                connectedDevicePort.device) {
+                LOG(ERROR) << __func__ << ": device " << connectedDevicePort.device.toString()
+                           << " is already connected at the device port id "
+                           << connectedPortPair.first;
+                return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+            }
+        }
+    }
+
+    if (!mDebug.simulateDeviceConnections) {
+        if (ndk::ScopedAStatus status = populateConnectedDevicePort(&connectedPort);
+            !status.isOk()) {
+            return status;
+        }
+    } else {
+        auto& connectedProfiles = getConfig().connectedProfiles;
+        if (auto connectedProfilesIt = connectedProfiles.find(templateId);
+            connectedProfilesIt != connectedProfiles.end()) {
+            connectedPort.profiles = connectedProfilesIt->second;
+        }
+    }
+    if (connectedPort.profiles.empty()) {
+        LOG(ERROR) << "Profiles of a connected port still empty after connecting external device "
+                   << connectedPort.toString();
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    connectedPort.id = ++getConfig().nextPortId;
+    auto [connectedPortsIt, _] =
+            mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::vector<int32_t>()));
+    LOG(DEBUG) << __func__ << ": template port " << templateId << " external device connected, "
+               << "connected port ID " << connectedPort.id;
+    ports.push_back(connectedPort);
+    onExternalDeviceConnectionChanged(connectedPort, true /*connected*/);
+
+    std::vector<int32_t> routablePortIds;
+    std::vector<AudioRoute> newRoutes;
+    auto& routes = getConfig().routes;
+    for (auto& r : routes) {
+        if (r.sinkPortId == templateId) {
+            AudioRoute newRoute;
+            newRoute.sourcePortIds = r.sourcePortIds;
+            newRoute.sinkPortId = connectedPort.id;
+            newRoute.isExclusive = r.isExclusive;
+            newRoutes.push_back(std::move(newRoute));
+            routablePortIds.insert(routablePortIds.end(), r.sourcePortIds.begin(),
+                                   r.sourcePortIds.end());
+        } else {
+            auto& srcs = r.sourcePortIds;
+            if (std::find(srcs.begin(), srcs.end(), templateId) != srcs.end()) {
+                srcs.push_back(connectedPort.id);
+                routablePortIds.push_back(r.sinkPortId);
+            }
+        }
+    }
+    routes.insert(routes.end(), newRoutes.begin(), newRoutes.end());
+
+    // Note: this is a simplistic approach assuming that a mix port can only be populated
+    // from a single device port. Implementing support for stuffing dynamic profiles with a superset
+    // of all profiles from all routable dynamic device ports would be more involved.
+    for (const auto mixPortId : routablePortIds) {
+        auto portsIt = findById<AudioPort>(ports, mixPortId);
+        if (portsIt != ports.end() && portsIt->profiles.empty()) {
+            portsIt->profiles = connectedPort.profiles;
+            connectedPortsIt->second.push_back(portsIt->id);
+        }
+    }
+    *_aidl_return = std::move(connectedPort);
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::disconnectExternalDevice(int32_t in_portId) {
+    auto& ports = getConfig().ports;
+    auto portIt = findById<AudioPort>(ports, in_portId);
+    if (portIt == ports.end()) {
+        LOG(ERROR) << __func__ << ": port id " << in_portId << " not found";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (portIt->ext.getTag() != AudioPortExt::Tag::device) {
+        LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a device port";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    auto connectedPortsIt = mConnectedDevicePorts.find(in_portId);
+    if (connectedPortsIt == mConnectedDevicePorts.end()) {
+        LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a connected device port";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    auto& configs = getConfig().portConfigs;
+    auto& initials = getConfig().initialConfigs;
+    auto configIt = std::find_if(configs.begin(), configs.end(), [&](const auto& config) {
+        if (config.portId == in_portId) {
+            // Check if the configuration was provided by the client.
+            const auto& initialIt = findById<AudioPortConfig>(initials, config.id);
+            return initialIt == initials.end() || config != *initialIt;
+        }
+        return false;
+    });
+    if (configIt != configs.end()) {
+        LOG(ERROR) << __func__ << ": port id " << in_portId << " has a non-default config with id "
+                   << configIt->id;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    onExternalDeviceConnectionChanged(*portIt, false /*connected*/);
+    ports.erase(portIt);
+    LOG(DEBUG) << __func__ << ": connected device port " << in_portId << " released";
+
+    auto& routes = getConfig().routes;
+    for (auto routesIt = routes.begin(); routesIt != routes.end();) {
+        if (routesIt->sinkPortId == in_portId) {
+            routesIt = routes.erase(routesIt);
+        } else {
+            // Note: the list of sourcePortIds can't become empty because there must
+            // be the id of the template port in the route.
+            erase_if(routesIt->sourcePortIds, [in_portId](auto src) { return src == in_portId; });
+            ++routesIt;
+        }
+    }
+
+    for (const auto mixPortId : connectedPortsIt->second) {
+        auto mixPortIt = findById<AudioPort>(ports, mixPortId);
+        if (mixPortIt != ports.end()) {
+            mixPortIt->profiles = {};
+        }
+    }
+    mConnectedDevicePorts.erase(connectedPortsIt);
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getAudioPatches(std::vector<AudioPatch>* _aidl_return) {
+    *_aidl_return = getConfig().patches;
+    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " patches";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getAudioPort(int32_t in_portId, AudioPort* _aidl_return) {
+    auto& ports = getConfig().ports;
+    auto portIt = findById<AudioPort>(ports, in_portId);
+    if (portIt != ports.end()) {
+        *_aidl_return = *portIt;
+        LOG(DEBUG) << __func__ << ": returning port by id " << in_portId;
+        return ndk::ScopedAStatus::ok();
+    }
+    LOG(ERROR) << __func__ << ": port id " << in_portId << " not found";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus Module::getAudioPortConfigs(std::vector<AudioPortConfig>* _aidl_return) {
+    *_aidl_return = getConfig().portConfigs;
+    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " port configs";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getAudioPorts(std::vector<AudioPort>* _aidl_return) {
+    *_aidl_return = getConfig().ports;
+    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " ports";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getAudioRoutes(std::vector<AudioRoute>* _aidl_return) {
+    *_aidl_return = getConfig().routes;
+    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " routes";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getAudioRoutesForAudioPort(int32_t in_portId,
+                                                      std::vector<AudioRoute>* _aidl_return) {
+    auto& ports = getConfig().ports;
+    if (auto portIt = findById<AudioPort>(ports, in_portId); portIt == ports.end()) {
+        LOG(ERROR) << __func__ << ": port id " << in_portId << " not found";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    auto& routes = getConfig().routes;
+    std::copy_if(routes.begin(), routes.end(), std::back_inserter(*_aidl_return),
+                 [&](const auto& r) {
+                     const auto& srcs = r.sourcePortIds;
+                     return r.sinkPortId == in_portId ||
+                            std::find(srcs.begin(), srcs.end(), in_portId) != srcs.end();
+                 });
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_args,
+                                           OpenInputStreamReturn* _aidl_return) {
+    LOG(DEBUG) << __func__ << ": port config id " << in_args.portConfigId << ", buffer size "
+               << in_args.bufferSizeFrames << " frames";
+    AudioPort* port = nullptr;
+    if (auto status = findPortIdForNewStream(in_args.portConfigId, &port); !status.isOk()) {
+        return status;
+    }
+    if (port->flags.getTag() != AudioIoFlags::Tag::input) {
+        LOG(ERROR) << __func__ << ": port config id " << in_args.portConfigId
+                   << " does not correspond to an input mix port";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    StreamContext context;
+    if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, nullptr,
+                                          nullptr, &context);
+        !status.isOk()) {
+        return status;
+    }
+    context.fillDescriptor(&_aidl_return->desc);
+    std::shared_ptr<StreamIn> stream;
+    ndk::ScopedAStatus status = getStreamInCreator(mType)(in_args.sinkMetadata, std::move(context),
+                                                          mConfig->microphones, &stream);
+    if (!status.isOk()) {
+        return status;
+    }
+    StreamWrapper streamWrapper(stream);
+    AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL,
+                                   ANDROID_PRIORITY_AUDIO);
+    auto patchIt = mPatches.find(in_args.portConfigId);
+    if (patchIt != mPatches.end()) {
+        streamWrapper.setStreamIsConnected(findConnectedDevices(in_args.portConfigId));
+    }
+    mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper));
+    _aidl_return->stream = std::move(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_args,
+                                            OpenOutputStreamReturn* _aidl_return) {
+    LOG(DEBUG) << __func__ << ": port config id " << in_args.portConfigId << ", has offload info? "
+               << (in_args.offloadInfo.has_value()) << ", buffer size " << in_args.bufferSizeFrames
+               << " frames";
+    AudioPort* port = nullptr;
+    if (auto status = findPortIdForNewStream(in_args.portConfigId, &port); !status.isOk()) {
+        return status;
+    }
+    if (port->flags.getTag() != AudioIoFlags::Tag::output) {
+        LOG(ERROR) << __func__ << ": port config id " << in_args.portConfigId
+                   << " does not correspond to an output mix port";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    const bool isOffload = isBitPositionFlagSet(port->flags.get<AudioIoFlags::Tag::output>(),
+                                                AudioOutputFlags::COMPRESS_OFFLOAD);
+    if (isOffload && !in_args.offloadInfo.has_value()) {
+        LOG(ERROR) << __func__ << ": port id " << port->id
+                   << " has COMPRESS_OFFLOAD flag set, requires offload info";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    const bool isNonBlocking = isBitPositionFlagSet(port->flags.get<AudioIoFlags::Tag::output>(),
+                                                    AudioOutputFlags::NON_BLOCKING);
+    if (isNonBlocking && in_args.callback == nullptr) {
+        LOG(ERROR) << __func__ << ": port id " << port->id
+                   << " has NON_BLOCKING flag set, requires async callback";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    StreamContext context;
+    if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames,
+                                          isNonBlocking ? in_args.callback : nullptr,
+                                          in_args.eventCallback, &context);
+        !status.isOk()) {
+        return status;
+    }
+    context.fillDescriptor(&_aidl_return->desc);
+    std::shared_ptr<StreamOut> stream;
+    ndk::ScopedAStatus status = getStreamOutCreator(mType)(
+            in_args.sourceMetadata, std::move(context), in_args.offloadInfo, &stream);
+    if (!status.isOk()) {
+        return status;
+    }
+    StreamWrapper streamWrapper(stream);
+    AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL,
+                                   ANDROID_PRIORITY_AUDIO);
+    auto patchIt = mPatches.find(in_args.portConfigId);
+    if (patchIt != mPatches.end()) {
+        streamWrapper.setStreamIsConnected(findConnectedDevices(in_args.portConfigId));
+    }
+    mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper));
+    _aidl_return->stream = std::move(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getSupportedPlaybackRateFactors(
+        SupportedPlaybackRateFactors* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Module::setAudioPatch(const AudioPatch& in_requested, AudioPatch* _aidl_return) {
+    LOG(DEBUG) << __func__ << ": requested patch " << in_requested.toString();
+    if (in_requested.sourcePortConfigIds.empty()) {
+        LOG(ERROR) << __func__ << ": requested patch has empty sources list";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (!all_unique<int32_t>(in_requested.sourcePortConfigIds)) {
+        LOG(ERROR) << __func__ << ": requested patch has duplicate ids in the sources list";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_requested.sinkPortConfigIds.empty()) {
+        LOG(ERROR) << __func__ << ": requested patch has empty sinks list";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (!all_unique<int32_t>(in_requested.sinkPortConfigIds)) {
+        LOG(ERROR) << __func__ << ": requested patch has duplicate ids in the sinks list";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    auto& configs = getConfig().portConfigs;
+    std::vector<int32_t> missingIds;
+    auto sources =
+            selectByIds<AudioPortConfig>(configs, in_requested.sourcePortConfigIds, &missingIds);
+    if (!missingIds.empty()) {
+        LOG(ERROR) << __func__ << ": following source port config ids not found: "
+                   << ::android::internal::ToString(missingIds);
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    auto sinks = selectByIds<AudioPortConfig>(configs, in_requested.sinkPortConfigIds, &missingIds);
+    if (!missingIds.empty()) {
+        LOG(ERROR) << __func__ << ": following sink port config ids not found: "
+                   << ::android::internal::ToString(missingIds);
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    // bool indicates whether a non-exclusive route is available.
+    // If only an exclusive route is available, that means the patch can not be
+    // established if there is any other patch which currently uses the sink port.
+    std::map<int32_t, bool> allowedSinkPorts;
+    auto& routes = getConfig().routes;
+    for (auto src : sources) {
+        for (const auto& r : routes) {
+            const auto& srcs = r.sourcePortIds;
+            if (std::find(srcs.begin(), srcs.end(), src->portId) != srcs.end()) {
+                if (!allowedSinkPorts[r.sinkPortId]) {  // prefer non-exclusive
+                    allowedSinkPorts[r.sinkPortId] = !r.isExclusive;
+                }
+            }
+        }
+    }
+    for (auto sink : sinks) {
+        if (allowedSinkPorts.count(sink->portId) == 0) {
+            LOG(ERROR) << __func__ << ": there is no route to the sink port id " << sink->portId;
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+    }
+
+    if (auto status = checkAudioPatchEndpointsMatch(sources, sinks); !status.isOk()) {
+        return status;
+    }
+
+    auto& patches = getConfig().patches;
+    auto existing = patches.end();
+    std::optional<decltype(mPatches)> patchesBackup;
+    if (in_requested.id != 0) {
+        existing = findById<AudioPatch>(patches, in_requested.id);
+        if (existing != patches.end()) {
+            patchesBackup = mPatches;
+            cleanUpPatch(existing->id);
+        } else {
+            LOG(ERROR) << __func__ << ": not found existing patch id " << in_requested.id;
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+    }
+    // Validate the requested patch.
+    for (const auto& [sinkPortId, nonExclusive] : allowedSinkPorts) {
+        if (!nonExclusive && mPatches.count(sinkPortId) != 0) {
+            LOG(ERROR) << __func__ << ": sink port id " << sinkPortId
+                       << "is exclusive and is already used by some other patch";
+            if (patchesBackup.has_value()) {
+                mPatches = std::move(*patchesBackup);
+            }
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+    }
+    *_aidl_return = in_requested;
+    _aidl_return->minimumStreamBufferSizeFrames = kMinimumStreamBufferSizeFrames;
+    _aidl_return->latenciesMs.clear();
+    _aidl_return->latenciesMs.insert(_aidl_return->latenciesMs.end(),
+                                     _aidl_return->sinkPortConfigIds.size(), kLatencyMs);
+    AudioPatch oldPatch{};
+    if (existing == patches.end()) {
+        _aidl_return->id = getConfig().nextPatchId++;
+        patches.push_back(*_aidl_return);
+        existing = patches.begin() + (patches.size() - 1);
+    } else {
+        oldPatch = *existing;
+        *existing = *_aidl_return;
+    }
+    registerPatch(*existing);
+    updateStreamsConnectedState(oldPatch, *_aidl_return);
+
+    LOG(DEBUG) << __func__ << ": " << (oldPatch.id == 0 ? "created" : "updated") << " patch "
+               << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::setAudioPortConfig(const AudioPortConfig& in_requested,
+                                              AudioPortConfig* out_suggested, bool* _aidl_return) {
+    LOG(DEBUG) << __func__ << ": requested " << in_requested.toString();
+    auto& configs = getConfig().portConfigs;
+    auto existing = configs.end();
+    if (in_requested.id != 0) {
+        if (existing = findById<AudioPortConfig>(configs, in_requested.id);
+            existing == configs.end()) {
+            LOG(ERROR) << __func__ << ": existing port config id " << in_requested.id
+                       << " not found";
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+    }
+
+    const int portId = existing != configs.end() ? existing->portId : in_requested.portId;
+    if (portId == 0) {
+        LOG(ERROR) << __func__ << ": input port config does not specify portId";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    auto& ports = getConfig().ports;
+    auto portIt = findById<AudioPort>(ports, portId);
+    if (portIt == ports.end()) {
+        LOG(ERROR) << __func__ << ": input port config points to non-existent portId " << portId;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (existing != configs.end()) {
+        *out_suggested = *existing;
+    } else {
+        AudioPortConfig newConfig;
+        if (generateDefaultPortConfig(*portIt, &newConfig)) {
+            *out_suggested = newConfig;
+        } else {
+            LOG(ERROR) << __func__ << ": unable generate a default config for port " << portId;
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+    }
+    // From this moment, 'out_suggested' is either an existing port config,
+    // or a new generated config. Now attempt to update it according to the specified
+    // fields of 'in_requested'.
+
+    bool requestedIsValid = true, requestedIsFullySpecified = true;
+
+    AudioIoFlags portFlags = portIt->flags;
+    if (in_requested.flags.has_value()) {
+        if (in_requested.flags.value() != portFlags) {
+            LOG(WARNING) << __func__ << ": requested flags "
+                         << in_requested.flags.value().toString() << " do not match port's "
+                         << portId << " flags " << portFlags.toString();
+            requestedIsValid = false;
+        }
+    } else {
+        requestedIsFullySpecified = false;
+    }
+
+    AudioProfile portProfile;
+    if (in_requested.format.has_value()) {
+        const auto& format = in_requested.format.value();
+        if (findAudioProfile(*portIt, format, &portProfile)) {
+            out_suggested->format = format;
+        } else {
+            LOG(WARNING) << __func__ << ": requested format " << format.toString()
+                         << " is not found in port's " << portId << " profiles";
+            requestedIsValid = false;
+        }
+    } else {
+        requestedIsFullySpecified = false;
+    }
+    if (!findAudioProfile(*portIt, out_suggested->format.value(), &portProfile)) {
+        LOG(ERROR) << __func__ << ": port " << portId << " does not support format "
+                   << out_suggested->format.value().toString() << " anymore";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    if (in_requested.channelMask.has_value()) {
+        const auto& channelMask = in_requested.channelMask.value();
+        if (find(portProfile.channelMasks.begin(), portProfile.channelMasks.end(), channelMask) !=
+            portProfile.channelMasks.end()) {
+            out_suggested->channelMask = channelMask;
+        } else {
+            LOG(WARNING) << __func__ << ": requested channel mask " << channelMask.toString()
+                         << " is not supported for the format " << portProfile.format.toString()
+                         << " by the port " << portId;
+            requestedIsValid = false;
+        }
+    } else {
+        requestedIsFullySpecified = false;
+    }
+
+    if (in_requested.sampleRate.has_value()) {
+        const auto& sampleRate = in_requested.sampleRate.value();
+        if (find(portProfile.sampleRates.begin(), portProfile.sampleRates.end(),
+                 sampleRate.value) != portProfile.sampleRates.end()) {
+            out_suggested->sampleRate = sampleRate;
+        } else {
+            LOG(WARNING) << __func__ << ": requested sample rate " << sampleRate.value
+                         << " is not supported for the format " << portProfile.format.toString()
+                         << " by the port " << portId;
+            requestedIsValid = false;
+        }
+    } else {
+        requestedIsFullySpecified = false;
+    }
+
+    if (in_requested.gain.has_value()) {
+        // Let's pretend that gain can always be applied.
+        out_suggested->gain = in_requested.gain.value();
+    }
+
+    if (in_requested.ext.getTag() != AudioPortExt::Tag::unspecified) {
+        if (in_requested.ext.getTag() == out_suggested->ext.getTag()) {
+            if (out_suggested->ext.getTag() == AudioPortExt::Tag::mix) {
+                // 'AudioMixPortExt.handle' is set by the client, copy from in_requested
+                out_suggested->ext.get<AudioPortExt::Tag::mix>().handle =
+                        in_requested.ext.get<AudioPortExt::Tag::mix>().handle;
+            }
+        } else {
+            LOG(WARNING) << __func__ << ": requested ext tag "
+                         << toString(in_requested.ext.getTag()) << " do not match port's tag "
+                         << toString(out_suggested->ext.getTag());
+            requestedIsValid = false;
+        }
+    }
+
+    if (existing == configs.end() && requestedIsValid && requestedIsFullySpecified) {
+        out_suggested->id = getConfig().nextPortId++;
+        configs.push_back(*out_suggested);
+        *_aidl_return = true;
+        LOG(DEBUG) << __func__ << ": created new port config " << out_suggested->toString();
+    } else if (existing != configs.end() && requestedIsValid) {
+        *existing = *out_suggested;
+        *_aidl_return = true;
+        LOG(DEBUG) << __func__ << ": updated port config " << out_suggested->toString();
+    } else {
+        LOG(DEBUG) << __func__ << ": not applied; existing config ? " << (existing != configs.end())
+                   << "; requested is valid? " << requestedIsValid << ", fully specified? "
+                   << requestedIsFullySpecified;
+        *_aidl_return = false;
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::resetAudioPatch(int32_t in_patchId) {
+    auto& patches = getConfig().patches;
+    auto patchIt = findById<AudioPatch>(patches, in_patchId);
+    if (patchIt != patches.end()) {
+        cleanUpPatch(patchIt->id);
+        updateStreamsConnectedState(*patchIt, AudioPatch{});
+        patches.erase(patchIt);
+        LOG(DEBUG) << __func__ << ": erased patch " << in_patchId;
+        return ndk::ScopedAStatus::ok();
+    }
+    LOG(ERROR) << __func__ << ": patch id " << in_patchId << " not found";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus Module::resetAudioPortConfig(int32_t in_portConfigId) {
+    auto& configs = getConfig().portConfigs;
+    auto configIt = findById<AudioPortConfig>(configs, in_portConfigId);
+    if (configIt != configs.end()) {
+        if (mStreams.count(in_portConfigId) != 0) {
+            LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+                       << " has a stream opened on it";
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+        auto patchIt = mPatches.find(in_portConfigId);
+        if (patchIt != mPatches.end()) {
+            LOG(ERROR) << __func__ << ": port config id " << in_portConfigId
+                       << " is used by the patch with id " << patchIt->second;
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+        auto& initials = getConfig().initialConfigs;
+        auto initialIt = findById<AudioPortConfig>(initials, in_portConfigId);
+        if (initialIt == initials.end()) {
+            configs.erase(configIt);
+            LOG(DEBUG) << __func__ << ": erased port config " << in_portConfigId;
+        } else if (*configIt != *initialIt) {
+            *configIt = *initialIt;
+            LOG(DEBUG) << __func__ << ": reset port config " << in_portConfigId;
+        }
+        return ndk::ScopedAStatus::ok();
+    }
+    LOG(ERROR) << __func__ << ": port config id " << in_portConfigId << " not found";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus Module::getMasterMute(bool* _aidl_return) {
+    *_aidl_return = mMasterMute;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::setMasterMute(bool in_mute) {
+    LOG(DEBUG) << __func__ << ": " << in_mute;
+    auto result = mDebug.simulateDeviceConnections ? ndk::ScopedAStatus::ok()
+                                                   : onMasterMuteChanged(in_mute);
+    if (result.isOk()) {
+        mMasterMute = in_mute;
+    } else {
+        LOG(ERROR) << __func__ << ": failed calling onMasterMuteChanged(" << in_mute
+                   << "), error=" << result;
+        // Reset master mute if it failed.
+        onMasterMuteChanged(mMasterMute);
+    }
+    return std::move(result);
+}
+
+ndk::ScopedAStatus Module::getMasterVolume(float* _aidl_return) {
+    *_aidl_return = mMasterVolume;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::setMasterVolume(float in_volume) {
+    LOG(DEBUG) << __func__ << ": " << in_volume;
+    if (in_volume >= 0.0f && in_volume <= 1.0f) {
+        auto result = mDebug.simulateDeviceConnections ? ndk::ScopedAStatus::ok()
+                                                       : onMasterVolumeChanged(in_volume);
+        if (result.isOk()) {
+            mMasterVolume = in_volume;
+        } else {
+            // Reset master volume if it failed.
+            LOG(ERROR) << __func__ << ": failed calling onMasterVolumeChanged(" << in_volume
+                       << "), error=" << result;
+            onMasterVolumeChanged(mMasterVolume);
+        }
+        return std::move(result);
+    }
+    LOG(ERROR) << __func__ << ": invalid master volume value: " << in_volume;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus Module::getMicMute(bool* _aidl_return) {
+    *_aidl_return = mMicMute;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::setMicMute(bool in_mute) {
+    LOG(DEBUG) << __func__ << ": " << in_mute;
+    mMicMute = in_mute;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getMicrophones(std::vector<MicrophoneInfo>* _aidl_return) {
+    *_aidl_return = getConfig().microphones;
+    LOG(DEBUG) << __func__ << ": returning " << ::android::internal::ToString(*_aidl_return);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::updateAudioMode(AudioMode in_mode) {
+    if (!isValidAudioMode(in_mode)) {
+        LOG(ERROR) << __func__ << ": invalid mode " << toString(in_mode);
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    // No checks for supported audio modes here, it's an informative notification.
+    LOG(DEBUG) << __func__ << ": " << toString(in_mode);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::updateScreenRotation(ScreenRotation in_rotation) {
+    LOG(DEBUG) << __func__ << ": " << toString(in_rotation);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::updateScreenState(bool in_isTurnedOn) {
+    LOG(DEBUG) << __func__ << ": " << in_isTurnedOn;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getSoundDose(std::shared_ptr<ISoundDose>* _aidl_return) {
+    if (!mSoundDose) {
+        mSoundDose = ndk::SharedRefBase::make<sounddose::SoundDose>();
+    }
+    *_aidl_return = mSoundDose.getPtr();
+    LOG(DEBUG) << __func__ << ": returning instance of ISoundDose: " << _aidl_return->get();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::generateHwAvSyncId(int32_t* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+const std::string Module::VendorDebug::kForceTransientBurstName = "aosp.forceTransientBurst";
+const std::string Module::VendorDebug::kForceSynchronousDrainName = "aosp.forceSynchronousDrain";
+
+ndk::ScopedAStatus Module::getVendorParameters(const std::vector<std::string>& in_ids,
+                                               std::vector<VendorParameter>* _aidl_return) {
+    LOG(DEBUG) << __func__ << ": id count: " << in_ids.size();
+    bool allParametersKnown = true;
+    for (const auto& id : in_ids) {
+        if (id == VendorDebug::kForceTransientBurstName) {
+            VendorParameter forceTransientBurst{.id = id};
+            forceTransientBurst.ext.setParcelable(Boolean{mVendorDebug.forceTransientBurst});
+            _aidl_return->push_back(std::move(forceTransientBurst));
+        } else if (id == VendorDebug::kForceSynchronousDrainName) {
+            VendorParameter forceSynchronousDrain{.id = id};
+            forceSynchronousDrain.ext.setParcelable(Boolean{mVendorDebug.forceSynchronousDrain});
+            _aidl_return->push_back(std::move(forceSynchronousDrain));
+        } else {
+            allParametersKnown = false;
+            LOG(ERROR) << __func__ << ": unrecognized parameter \"" << id << "\"";
+        }
+    }
+    if (allParametersKnown) return ndk::ScopedAStatus::ok();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+namespace {
+
+template <typename W>
+bool extractParameter(const VendorParameter& p, decltype(W::value)* v) {
+    std::optional<W> value;
+    binder_status_t result = p.ext.getParcelable(&value);
+    if (result == STATUS_OK && value.has_value()) {
+        *v = value.value().value;
+        return true;
+    }
+    LOG(ERROR) << __func__ << ": failed to read the value of the parameter \"" << p.id
+               << "\": " << result;
+    return false;
+}
+
+}  // namespace
+
+ndk::ScopedAStatus Module::setVendorParameters(const std::vector<VendorParameter>& in_parameters,
+                                               bool in_async) {
+    LOG(DEBUG) << __func__ << ": parameter count " << in_parameters.size()
+               << ", async: " << in_async;
+    bool allParametersKnown = true;
+    for (const auto& p : in_parameters) {
+        if (p.id == VendorDebug::kForceTransientBurstName) {
+            if (!extractParameter<Boolean>(p, &mVendorDebug.forceTransientBurst)) {
+                return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+            }
+        } else if (p.id == VendorDebug::kForceSynchronousDrainName) {
+            if (!extractParameter<Boolean>(p, &mVendorDebug.forceSynchronousDrain)) {
+                return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+            }
+        } else {
+            allParametersKnown = false;
+            LOG(ERROR) << __func__ << ": unrecognized parameter \"" << p.id << "\"";
+        }
+    }
+    if (allParametersKnown) return ndk::ScopedAStatus::ok();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus Module::addDeviceEffect(
+        int32_t in_portConfigId,
+        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
+    if (in_effect == nullptr) {
+        LOG(DEBUG) << __func__ << ": port id " << in_portConfigId << ", null effect";
+    } else {
+        LOG(DEBUG) << __func__ << ": port id " << in_portConfigId << ", effect Binder "
+                   << in_effect->asBinder().get();
+    }
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Module::removeDeviceEffect(
+        int32_t in_portConfigId,
+        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
+    if (in_effect == nullptr) {
+        LOG(DEBUG) << __func__ << ": port id " << in_portConfigId << ", null effect";
+    } else {
+        LOG(DEBUG) << __func__ << ": port id " << in_portConfigId << ", effect Binder "
+                   << in_effect->asBinder().get();
+    }
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Module::getMmapPolicyInfos(AudioMMapPolicyType mmapPolicyType,
+                                              std::vector<AudioMMapPolicyInfo>* _aidl_return) {
+    LOG(DEBUG) << __func__ << ": mmap policy type " << toString(mmapPolicyType);
+    std::set<int32_t> mmapSinks;
+    std::set<int32_t> mmapSources;
+    auto& ports = getConfig().ports;
+    for (const auto& port : ports) {
+        if (port.flags.getTag() == AudioIoFlags::Tag::input &&
+            isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::input>(),
+                                 AudioInputFlags::MMAP_NOIRQ)) {
+            mmapSinks.insert(port.id);
+        } else if (port.flags.getTag() == AudioIoFlags::Tag::output &&
+                   isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
+                                        AudioOutputFlags::MMAP_NOIRQ)) {
+            mmapSources.insert(port.id);
+        }
+    }
+    for (const auto& route : getConfig().routes) {
+        if (mmapSinks.count(route.sinkPortId) != 0) {
+            // The sink is a mix port, add the sources if they are device ports.
+            for (int sourcePortId : route.sourcePortIds) {
+                auto sourcePortIt = findById<AudioPort>(ports, sourcePortId);
+                if (sourcePortIt == ports.end()) {
+                    // This must not happen
+                    LOG(ERROR) << __func__ << ": port id " << sourcePortId << " cannot be found";
+                    continue;
+                }
+                if (sourcePortIt->ext.getTag() != AudioPortExt::Tag::device) {
+                    // The source is not a device port, skip
+                    continue;
+                }
+                AudioMMapPolicyInfo policyInfo;
+                policyInfo.device = sourcePortIt->ext.get<AudioPortExt::Tag::device>().device;
+                // Always return AudioMMapPolicy.AUTO if the device supports mmap for
+                // default implementation.
+                policyInfo.mmapPolicy = AudioMMapPolicy::AUTO;
+                _aidl_return->push_back(policyInfo);
+            }
+        } else {
+            auto sinkPortIt = findById<AudioPort>(ports, route.sinkPortId);
+            if (sinkPortIt == ports.end()) {
+                // This must not happen
+                LOG(ERROR) << __func__ << ": port id " << route.sinkPortId << " cannot be found";
+                continue;
+            }
+            if (sinkPortIt->ext.getTag() != AudioPortExt::Tag::device) {
+                // The sink is not a device port, skip
+                continue;
+            }
+            if (count_any(mmapSources, route.sourcePortIds)) {
+                AudioMMapPolicyInfo policyInfo;
+                policyInfo.device = sinkPortIt->ext.get<AudioPortExt::Tag::device>().device;
+                // Always return AudioMMapPolicy.AUTO if the device supports mmap for
+                // default implementation.
+                policyInfo.mmapPolicy = AudioMMapPolicy::AUTO;
+                _aidl_return->push_back(policyInfo);
+            }
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::supportsVariableLatency(bool* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    *_aidl_return = false;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getAAudioMixerBurstCount(int32_t* _aidl_return) {
+    if (!isMmapSupported()) {
+        LOG(DEBUG) << __func__ << ": mmap is not supported ";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    *_aidl_return = DEFAULT_AAUDIO_MIXER_BURST_COUNT;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) {
+    if (!isMmapSupported()) {
+        LOG(DEBUG) << __func__ << ": mmap is not supported ";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    *_aidl_return = DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+bool Module::isMmapSupported() {
+    if (mIsMmapSupported.has_value()) {
+        return mIsMmapSupported.value();
+    }
+    std::vector<AudioMMapPolicyInfo> mmapPolicyInfos;
+    if (!getMmapPolicyInfos(AudioMMapPolicyType::DEFAULT, &mmapPolicyInfos).isOk()) {
+        mIsMmapSupported = false;
+    } else {
+        mIsMmapSupported =
+                std::find_if(mmapPolicyInfos.begin(), mmapPolicyInfos.end(), [](const auto& info) {
+                    return info.mmapPolicy == AudioMMapPolicy::AUTO ||
+                           info.mmapPolicy == AudioMMapPolicy::ALWAYS;
+                }) != mmapPolicyInfos.end();
+    }
+    return mIsMmapSupported.value();
+}
+
+ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort __unused) {
+    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::checkAudioPatchEndpointsMatch(
+        const std::vector<AudioPortConfig*>& sources __unused,
+        const std::vector<AudioPortConfig*>& sinks __unused) {
+    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    return ndk::ScopedAStatus::ok();
+}
+
+void Module::onExternalDeviceConnectionChanged(
+        const ::aidl::android::media::audio::common::AudioPort& audioPort __unused,
+        bool connected __unused) {
+    LOG(DEBUG) << __func__ << ": do nothing and return";
+}
+
+ndk::ScopedAStatus Module::onMasterMuteChanged(bool mute __unused) {
+    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::onMasterVolumeChanged(float volume __unused) {
+    LOG(VERBOSE) << __func__ << ": do nothing and return ok";
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/SoundDose.cpp b/audio/aidl/default/SoundDose.cpp
new file mode 100644
index 0000000..f12ce5d
--- /dev/null
+++ b/audio/aidl/default/SoundDose.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_SoundDose"
+
+#include "core-impl/SoundDose.h"
+
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::audio::core::sounddose {
+
+ndk::ScopedAStatus SoundDose::setOutputRs2UpperBound(float in_rs2ValueDbA) {
+    if (in_rs2ValueDbA < MIN_RS2 || in_rs2ValueDbA > DEFAULT_MAX_RS2) {
+        LOG(ERROR) << __func__ << ": RS2 value is invalid: " << in_rs2ValueDbA;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    mRs2Value = in_rs2ValueDbA;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SoundDose::getOutputRs2UpperBound(float* _aidl_return) {
+    *_aidl_return = mRs2Value;
+    LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SoundDose::registerSoundDoseCallback(
+        const std::shared_ptr<ISoundDose::IHalSoundDoseCallback>& in_callback) {
+    if (in_callback.get() == nullptr) {
+        LOG(ERROR) << __func__ << ": Callback is nullptr";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (mCallback != nullptr) {
+        LOG(ERROR) << __func__ << ": Sound dose callback was already registered";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    mCallback = in_callback;
+    LOG(DEBUG) << __func__ << ": Registered sound dose callback ";
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::audio::core::sounddose
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
new file mode 100644
index 0000000..77b0601
--- /dev/null
+++ b/audio/aidl/default/Stream.cpp
@@ -0,0 +1,895 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_Stream"
+#include <android-base/logging.h>
+#include <android/binder_ibinder_platform.h>
+#include <utils/SystemClock.h>
+
+#include <Utils.h>
+
+#include "core-impl/Module.h"
+#include "core-impl/Stream.h"
+
+using aidl::android::hardware::audio::common::AudioOffloadMetadata;
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDualMonoMode;
+using aidl::android::media::audio::common::AudioLatencyMode;
+using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::AudioPlaybackRate;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
+
+namespace aidl::android::hardware::audio::core {
+
+void StreamContext::fillDescriptor(StreamDescriptor* desc) {
+    if (mCommandMQ) {
+        desc->command = mCommandMQ->dupeDesc();
+    }
+    if (mReplyMQ) {
+        desc->reply = mReplyMQ->dupeDesc();
+    }
+    if (mDataMQ) {
+        const size_t frameSize = getFrameSize();
+        desc->frameSizeBytes = frameSize;
+        desc->bufferSizeFrames = mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize() / frameSize;
+        desc->audio.set<StreamDescriptor::AudioBuffer::Tag::fmq>(mDataMQ->dupeDesc());
+    }
+}
+
+size_t StreamContext::getFrameSize() const {
+    return getFrameSizeInBytes(mFormat, mChannelLayout);
+}
+
+bool StreamContext::isValid() const {
+    if (mCommandMQ && !mCommandMQ->isValid()) {
+        LOG(ERROR) << "command FMQ is invalid";
+        return false;
+    }
+    if (mReplyMQ && !mReplyMQ->isValid()) {
+        LOG(ERROR) << "reply FMQ is invalid";
+        return false;
+    }
+    if (getFrameSize() == 0) {
+        LOG(ERROR) << "frame size is invalid";
+        return false;
+    }
+    if (mDataMQ && !mDataMQ->isValid()) {
+        LOG(ERROR) << "data FMQ is invalid";
+        return false;
+    }
+    return true;
+}
+
+void StreamContext::reset() {
+    mCommandMQ.reset();
+    mReplyMQ.reset();
+    mDataMQ.reset();
+}
+
+std::string StreamWorkerCommonLogic::init() {
+    if (mCommandMQ == nullptr) return "Command MQ is null";
+    if (mReplyMQ == nullptr) return "Reply MQ is null";
+    if (mDataMQ == nullptr) return "Data MQ is null";
+    if (sizeof(DataBufferElement) != mDataMQ->getQuantumSize()) {
+        return "Unexpected Data MQ quantum size: " + std::to_string(mDataMQ->getQuantumSize());
+    }
+    mDataBufferSize = mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize();
+    mDataBuffer.reset(new (std::nothrow) DataBufferElement[mDataBufferSize]);
+    if (mDataBuffer == nullptr) {
+        return "Failed to allocate data buffer for element count " +
+               std::to_string(mDataMQ->getQuantumCount()) +
+               ", size in bytes: " + std::to_string(mDataBufferSize);
+    }
+    if (::android::status_t status = mDriver->init(); status != STATUS_OK) {
+        return "Failed to initialize the driver: " + std::to_string(status);
+    }
+    return "";
+}
+
+void StreamWorkerCommonLogic::populateReply(StreamDescriptor::Reply* reply,
+                                            bool isConnected) const {
+    reply->status = STATUS_OK;
+    if (isConnected) {
+        reply->observable.frames = mFrameCount;
+        reply->observable.timeNs = ::android::elapsedRealtimeNano();
+    } else {
+        reply->observable.frames = StreamDescriptor::Position::UNKNOWN;
+        reply->observable.timeNs = StreamDescriptor::Position::UNKNOWN;
+    }
+}
+
+void StreamWorkerCommonLogic::populateReplyWrongState(
+        StreamDescriptor::Reply* reply, const StreamDescriptor::Command& command) const {
+    LOG(WARNING) << "command '" << toString(command.getTag())
+                 << "' can not be handled in the state " << toString(mState);
+    reply->status = STATUS_INVALID_OPERATION;
+}
+
+const std::string StreamInWorkerLogic::kThreadName = "reader";
+
+StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() {
+    // Note: for input streams, draining is driven by the client, thus
+    // "empty buffer" condition can only happen while handling the 'burst'
+    // command. Thus, unlike for output streams, it does not make sense to
+    // delay the 'DRAINING' state here by 'mTransientStateDelayMs'.
+    // TODO: Add a delay for transitions of async operations when/if they added.
+
+    StreamDescriptor::Command command{};
+    if (!mCommandMQ->readBlocking(&command, 1)) {
+        LOG(ERROR) << __func__ << ": reading of command from MQ failed";
+        mState = StreamDescriptor::State::ERROR;
+        return Status::ABORT;
+    }
+    using Tag = StreamDescriptor::Command::Tag;
+    using LogSeverity = ::android::base::LogSeverity;
+    const LogSeverity severity =
+            command.getTag() == Tag::burst || command.getTag() == Tag::getStatus
+                    ? LogSeverity::VERBOSE
+                    : LogSeverity::DEBUG;
+    LOG(severity) << __func__ << ": received command " << command.toString() << " in "
+                  << kThreadName;
+    StreamDescriptor::Reply reply{};
+    reply.status = STATUS_BAD_VALUE;
+    switch (command.getTag()) {
+        case Tag::halReservedExit:
+            if (const int32_t cookie = command.get<Tag::halReservedExit>();
+                cookie == mInternalCommandCookie) {
+                setClosed();
+                // This is an internal command, no need to reply.
+                return Status::EXIT;
+            } else {
+                LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
+            }
+            break;
+        case Tag::getStatus:
+            populateReply(&reply, mIsConnected);
+            break;
+        case Tag::start:
+            if (mState == StreamDescriptor::State::STANDBY ||
+                mState == StreamDescriptor::State::DRAINING) {
+                populateReply(&reply, mIsConnected);
+                mState = mState == StreamDescriptor::State::STANDBY
+                                 ? StreamDescriptor::State::IDLE
+                                 : StreamDescriptor::State::ACTIVE;
+            } else {
+                populateReplyWrongState(&reply, command);
+            }
+            break;
+        case Tag::burst:
+            if (const int32_t fmqByteCount = command.get<Tag::burst>(); fmqByteCount >= 0) {
+                LOG(VERBOSE) << __func__ << ": '" << toString(command.getTag()) << "' command for "
+                             << fmqByteCount << " bytes";
+                if (mState == StreamDescriptor::State::IDLE ||
+                    mState == StreamDescriptor::State::ACTIVE ||
+                    mState == StreamDescriptor::State::PAUSED ||
+                    mState == StreamDescriptor::State::DRAINING) {
+                    if (!read(fmqByteCount, &reply)) {
+                        mState = StreamDescriptor::State::ERROR;
+                    }
+                    if (mState == StreamDescriptor::State::IDLE ||
+                        mState == StreamDescriptor::State::PAUSED) {
+                        mState = StreamDescriptor::State::ACTIVE;
+                    } else if (mState == StreamDescriptor::State::DRAINING) {
+                        // To simplify the reference code, we assume that the read operation
+                        // has consumed all the data remaining in the hardware buffer.
+                        // In a real implementation, here we would either remain in
+                        // the 'DRAINING' state, or transfer to 'STANDBY' depending on the
+                        // buffer state.
+                        mState = StreamDescriptor::State::STANDBY;
+                    }
+                } else {
+                    populateReplyWrongState(&reply, command);
+                }
+            } else {
+                LOG(WARNING) << __func__ << ": invalid burst byte count: " << fmqByteCount;
+            }
+            break;
+        case Tag::drain:
+            if (const auto mode = command.get<Tag::drain>();
+                mode == StreamDescriptor::DrainMode::DRAIN_UNSPECIFIED) {
+                if (mState == StreamDescriptor::State::ACTIVE) {
+                    if (::android::status_t status = mDriver->drain(mode);
+                        status == ::android::OK) {
+                        populateReply(&reply, mIsConnected);
+                        mState = StreamDescriptor::State::DRAINING;
+                    } else {
+                        LOG(ERROR) << __func__ << ": drain failed: " << status;
+                        mState = StreamDescriptor::State::ERROR;
+                    }
+                } else {
+                    populateReplyWrongState(&reply, command);
+                }
+            } else {
+                LOG(WARNING) << __func__ << ": invalid drain mode: " << toString(mode);
+            }
+            break;
+        case Tag::standby:
+            if (mState == StreamDescriptor::State::IDLE) {
+                if (::android::status_t status = mDriver->standby(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::STANDBY;
+                } else {
+                    LOG(ERROR) << __func__ << ": standby failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
+            } else {
+                populateReplyWrongState(&reply, command);
+            }
+            break;
+        case Tag::pause:
+            if (mState == StreamDescriptor::State::ACTIVE) {
+                if (::android::status_t status = mDriver->pause(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::PAUSED;
+                } else {
+                    LOG(ERROR) << __func__ << ": pause failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
+            } else {
+                populateReplyWrongState(&reply, command);
+            }
+            break;
+        case Tag::flush:
+            if (mState == StreamDescriptor::State::PAUSED) {
+                if (::android::status_t status = mDriver->flush(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::STANDBY;
+                } else {
+                    LOG(ERROR) << __func__ << ": flush failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
+            } else {
+                populateReplyWrongState(&reply, command);
+            }
+            break;
+    }
+    reply.state = mState;
+    LOG(severity) << __func__ << ": writing reply " << reply.toString();
+    if (!mReplyMQ->writeBlocking(&reply, 1)) {
+        LOG(ERROR) << __func__ << ": writing of reply " << reply.toString() << " to MQ failed";
+        mState = StreamDescriptor::State::ERROR;
+        return Status::ABORT;
+    }
+    return Status::CONTINUE;
+}
+
+bool StreamInWorkerLogic::read(size_t clientSize, StreamDescriptor::Reply* reply) {
+    const size_t byteCount = std::min({clientSize, mDataMQ->availableToWrite(), mDataBufferSize});
+    const bool isConnected = mIsConnected;
+    size_t actualFrameCount = 0;
+    bool fatal = false;
+    int32_t latency = Module::kLatencyMs;
+    if (isConnected) {
+        if (::android::status_t status = mDriver->transfer(
+                    mDataBuffer.get(), byteCount / mFrameSize, &actualFrameCount, &latency);
+            status != ::android::OK) {
+            fatal = true;
+            LOG(ERROR) << __func__ << ": read failed: " << status;
+        }
+    } else {
+        usleep(3000);  // Simulate blocking transfer delay.
+        for (size_t i = 0; i < byteCount; ++i) mDataBuffer[i] = 0;
+        actualFrameCount = byteCount / mFrameSize;
+    }
+    const size_t actualByteCount = actualFrameCount * mFrameSize;
+    if (bool success =
+                actualByteCount > 0 ? mDataMQ->write(&mDataBuffer[0], actualByteCount) : true;
+        success) {
+        LOG(VERBOSE) << __func__ << ": writing of " << actualByteCount << " bytes into data MQ"
+                     << " succeeded; connected? " << isConnected;
+        // Frames are provided and counted regardless of connection status.
+        reply->fmqByteCount += actualByteCount;
+        mFrameCount += actualFrameCount;
+        populateReply(reply, isConnected);
+    } else {
+        LOG(WARNING) << __func__ << ": writing of " << actualByteCount
+                     << " bytes of data to MQ failed";
+        reply->status = STATUS_NOT_ENOUGH_DATA;
+    }
+    reply->latencyMs = latency;
+    return !fatal;
+}
+
+const std::string StreamOutWorkerLogic::kThreadName = "writer";
+
+StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() {
+    if (mState == StreamDescriptor::State::DRAINING ||
+        mState == StreamDescriptor::State::TRANSFERRING) {
+        if (auto stateDurationMs = std::chrono::duration_cast<std::chrono::milliseconds>(
+                    std::chrono::steady_clock::now() - mTransientStateStart);
+            stateDurationMs >= mTransientStateDelayMs) {
+            if (mAsyncCallback == nullptr) {
+                // In blocking mode, mState can only be DRAINING.
+                mState = StreamDescriptor::State::IDLE;
+            } else {
+                // In a real implementation, the driver should notify the HAL about
+                // drain or transfer completion. In the stub, we switch unconditionally.
+                if (mState == StreamDescriptor::State::DRAINING) {
+                    mState = StreamDescriptor::State::IDLE;
+                    ndk::ScopedAStatus status = mAsyncCallback->onDrainReady();
+                    if (!status.isOk()) {
+                        LOG(ERROR) << __func__ << ": error from onDrainReady: " << status;
+                    }
+                } else {
+                    mState = StreamDescriptor::State::ACTIVE;
+                    ndk::ScopedAStatus status = mAsyncCallback->onTransferReady();
+                    if (!status.isOk()) {
+                        LOG(ERROR) << __func__ << ": error from onTransferReady: " << status;
+                    }
+                }
+            }
+            if (mTransientStateDelayMs.count() != 0) {
+                LOG(DEBUG) << __func__ << ": switched to state " << toString(mState)
+                           << " after a timeout";
+            }
+        }
+    }
+
+    StreamDescriptor::Command command{};
+    if (!mCommandMQ->readBlocking(&command, 1)) {
+        LOG(ERROR) << __func__ << ": reading of command from MQ failed";
+        mState = StreamDescriptor::State::ERROR;
+        return Status::ABORT;
+    }
+    using Tag = StreamDescriptor::Command::Tag;
+    using LogSeverity = ::android::base::LogSeverity;
+    const LogSeverity severity =
+            command.getTag() == Tag::burst || command.getTag() == Tag::getStatus
+                    ? LogSeverity::VERBOSE
+                    : LogSeverity::DEBUG;
+    LOG(severity) << __func__ << ": received command " << command.toString() << " in "
+                  << kThreadName;
+    StreamDescriptor::Reply reply{};
+    reply.status = STATUS_BAD_VALUE;
+    using Tag = StreamDescriptor::Command::Tag;
+    switch (command.getTag()) {
+        case Tag::halReservedExit:
+            if (const int32_t cookie = command.get<Tag::halReservedExit>();
+                cookie == mInternalCommandCookie) {
+                setClosed();
+                // This is an internal command, no need to reply.
+                return Status::EXIT;
+            } else {
+                LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
+            }
+            break;
+        case Tag::getStatus:
+            populateReply(&reply, mIsConnected);
+            break;
+        case Tag::start: {
+            bool commandAccepted = true;
+            switch (mState) {
+                case StreamDescriptor::State::STANDBY:
+                    mState = StreamDescriptor::State::IDLE;
+                    break;
+                case StreamDescriptor::State::PAUSED:
+                    mState = StreamDescriptor::State::ACTIVE;
+                    break;
+                case StreamDescriptor::State::DRAIN_PAUSED:
+                    switchToTransientState(StreamDescriptor::State::DRAINING);
+                    break;
+                case StreamDescriptor::State::TRANSFER_PAUSED:
+                    switchToTransientState(StreamDescriptor::State::TRANSFERRING);
+                    break;
+                default:
+                    populateReplyWrongState(&reply, command);
+                    commandAccepted = false;
+            }
+            if (commandAccepted) {
+                populateReply(&reply, mIsConnected);
+            }
+        } break;
+        case Tag::burst:
+            if (const int32_t fmqByteCount = command.get<Tag::burst>(); fmqByteCount >= 0) {
+                LOG(VERBOSE) << __func__ << ": '" << toString(command.getTag()) << "' command for "
+                             << fmqByteCount << " bytes";
+                if (mState != StreamDescriptor::State::ERROR &&
+                    mState != StreamDescriptor::State::TRANSFERRING &&
+                    mState != StreamDescriptor::State::TRANSFER_PAUSED) {
+                    if (!write(fmqByteCount, &reply)) {
+                        mState = StreamDescriptor::State::ERROR;
+                    }
+                    if (mState == StreamDescriptor::State::STANDBY ||
+                        mState == StreamDescriptor::State::DRAIN_PAUSED ||
+                        mState == StreamDescriptor::State::PAUSED) {
+                        if (mAsyncCallback == nullptr ||
+                            mState != StreamDescriptor::State::DRAIN_PAUSED) {
+                            mState = StreamDescriptor::State::PAUSED;
+                        } else {
+                            mState = StreamDescriptor::State::TRANSFER_PAUSED;
+                        }
+                    } else if (mState == StreamDescriptor::State::IDLE ||
+                               mState == StreamDescriptor::State::DRAINING ||
+                               mState == StreamDescriptor::State::ACTIVE) {
+                        if (mAsyncCallback == nullptr || reply.fmqByteCount == fmqByteCount) {
+                            mState = StreamDescriptor::State::ACTIVE;
+                        } else {
+                            switchToTransientState(StreamDescriptor::State::TRANSFERRING);
+                        }
+                    }
+                } else {
+                    populateReplyWrongState(&reply, command);
+                }
+            } else {
+                LOG(WARNING) << __func__ << ": invalid burst byte count: " << fmqByteCount;
+            }
+            break;
+        case Tag::drain:
+            if (const auto mode = command.get<Tag::drain>();
+                mode == StreamDescriptor::DrainMode::DRAIN_ALL ||
+                mode == StreamDescriptor::DrainMode::DRAIN_EARLY_NOTIFY) {
+                if (mState == StreamDescriptor::State::ACTIVE ||
+                    mState == StreamDescriptor::State::TRANSFERRING) {
+                    if (::android::status_t status = mDriver->drain(mode);
+                        status == ::android::OK) {
+                        populateReply(&reply, mIsConnected);
+                        if (mState == StreamDescriptor::State::ACTIVE && mForceSynchronousDrain) {
+                            mState = StreamDescriptor::State::IDLE;
+                        } else {
+                            switchToTransientState(StreamDescriptor::State::DRAINING);
+                        }
+                    } else {
+                        LOG(ERROR) << __func__ << ": drain failed: " << status;
+                        mState = StreamDescriptor::State::ERROR;
+                    }
+                } else if (mState == StreamDescriptor::State::TRANSFER_PAUSED) {
+                    mState = StreamDescriptor::State::DRAIN_PAUSED;
+                    populateReply(&reply, mIsConnected);
+                } else {
+                    populateReplyWrongState(&reply, command);
+                }
+            } else {
+                LOG(WARNING) << __func__ << ": invalid drain mode: " << toString(mode);
+            }
+            break;
+        case Tag::standby:
+            if (mState == StreamDescriptor::State::IDLE) {
+                if (::android::status_t status = mDriver->standby(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::STANDBY;
+                } else {
+                    LOG(ERROR) << __func__ << ": standby failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
+            } else {
+                populateReplyWrongState(&reply, command);
+            }
+            break;
+        case Tag::pause: {
+            std::optional<StreamDescriptor::State> nextState;
+            switch (mState) {
+                case StreamDescriptor::State::ACTIVE:
+                    nextState = StreamDescriptor::State::PAUSED;
+                    break;
+                case StreamDescriptor::State::DRAINING:
+                    nextState = StreamDescriptor::State::DRAIN_PAUSED;
+                    break;
+                case StreamDescriptor::State::TRANSFERRING:
+                    nextState = StreamDescriptor::State::TRANSFER_PAUSED;
+                    break;
+                default:
+                    populateReplyWrongState(&reply, command);
+            }
+            if (nextState.has_value()) {
+                if (::android::status_t status = mDriver->pause(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = nextState.value();
+                } else {
+                    LOG(ERROR) << __func__ << ": pause failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
+            }
+        } break;
+        case Tag::flush:
+            if (mState == StreamDescriptor::State::PAUSED ||
+                mState == StreamDescriptor::State::DRAIN_PAUSED ||
+                mState == StreamDescriptor::State::TRANSFER_PAUSED) {
+                if (::android::status_t status = mDriver->flush(); status == ::android::OK) {
+                    populateReply(&reply, mIsConnected);
+                    mState = StreamDescriptor::State::IDLE;
+                } else {
+                    LOG(ERROR) << __func__ << ": flush failed: " << status;
+                    mState = StreamDescriptor::State::ERROR;
+                }
+            } else {
+                populateReplyWrongState(&reply, command);
+            }
+            break;
+    }
+    reply.state = mState;
+    LOG(severity) << __func__ << ": writing reply " << reply.toString();
+    if (!mReplyMQ->writeBlocking(&reply, 1)) {
+        LOG(ERROR) << __func__ << ": writing of reply " << reply.toString() << " to MQ failed";
+        mState = StreamDescriptor::State::ERROR;
+        return Status::ABORT;
+    }
+    return Status::CONTINUE;
+}
+
+bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* reply) {
+    const size_t readByteCount = mDataMQ->availableToRead();
+    bool fatal = false;
+    int32_t latency = Module::kLatencyMs;
+    if (bool success = readByteCount > 0 ? mDataMQ->read(&mDataBuffer[0], readByteCount) : true) {
+        const bool isConnected = mIsConnected;
+        LOG(VERBOSE) << __func__ << ": reading of " << readByteCount << " bytes from data MQ"
+                     << " succeeded; connected? " << isConnected;
+        // Amount of data that the HAL module is going to actually use.
+        size_t byteCount = std::min({clientSize, readByteCount, mDataBufferSize});
+        if (byteCount >= mFrameSize && mForceTransientBurst) {
+            // In order to prevent the state machine from going to ACTIVE state,
+            // simulate partial write.
+            byteCount -= mFrameSize;
+        }
+        size_t actualFrameCount = 0;
+        if (isConnected) {
+            if (::android::status_t status = mDriver->transfer(
+                        mDataBuffer.get(), byteCount / mFrameSize, &actualFrameCount, &latency);
+                status != ::android::OK) {
+                fatal = true;
+                LOG(ERROR) << __func__ << ": write failed: " << status;
+            }
+        } else {
+            if (mAsyncCallback == nullptr) {
+                usleep(3000);  // Simulate blocking transfer delay.
+            }
+            actualFrameCount = byteCount / mFrameSize;
+        }
+        const size_t actualByteCount = actualFrameCount * mFrameSize;
+        // Frames are consumed and counted regardless of the connection status.
+        reply->fmqByteCount += actualByteCount;
+        mFrameCount += actualFrameCount;
+        populateReply(reply, isConnected);
+    } else {
+        LOG(WARNING) << __func__ << ": reading of " << readByteCount
+                     << " bytes of data from MQ failed";
+        reply->status = STATUS_NOT_ENOUGH_DATA;
+    }
+    reply->latencyMs = latency;
+    return !fatal;
+}
+
+template <class Metadata>
+StreamCommonImpl<Metadata>::~StreamCommonImpl() {
+    if (!isClosed()) {
+        LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
+        stopWorker();
+        // The worker and the context should clean up by themselves via destructors.
+    }
+}
+
+template <class Metadata>
+void StreamCommonImpl<Metadata>::createStreamCommon(
+        const std::shared_ptr<StreamCommonInterface>& delegate) {
+    if (mCommon != nullptr) {
+        LOG(FATAL) << __func__ << ": attempting to create the common interface twice";
+    }
+    mCommon = ndk::SharedRefBase::make<StreamCommon>(delegate);
+    mCommonBinder = mCommon->asBinder();
+    AIBinder_setMinSchedulerPolicy(mCommonBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
+}
+
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::getStreamCommon(
+        std::shared_ptr<IStreamCommon>* _aidl_return) {
+    if (mCommon == nullptr) {
+        LOG(FATAL) << __func__ << ": the common interface was not created";
+    }
+    *_aidl_return = mCommon;
+    LOG(DEBUG) << __func__ << ": returning " << _aidl_return->get()->asBinder().get();
+    return ndk::ScopedAStatus::ok();
+}
+
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateHwAvSyncId(int32_t in_hwAvSyncId) {
+    LOG(DEBUG) << __func__ << ": id " << in_hwAvSyncId;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::getVendorParameters(
+        const std::vector<std::string>& in_ids, std::vector<VendorParameter>* _aidl_return) {
+    LOG(DEBUG) << __func__ << ": id count: " << in_ids.size();
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::setVendorParameters(
+        const std::vector<VendorParameter>& in_parameters, bool in_async) {
+    LOG(DEBUG) << __func__ << ": parameters count " << in_parameters.size()
+               << ", async: " << in_async;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::addEffect(
+        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
+    if (in_effect == nullptr) {
+        LOG(DEBUG) << __func__ << ": null effect";
+    } else {
+        LOG(DEBUG) << __func__ << ": effect Binder" << in_effect->asBinder().get();
+    }
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::removeEffect(
+        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) {
+    if (in_effect == nullptr) {
+        LOG(DEBUG) << __func__ << ": null effect";
+    } else {
+        LOG(DEBUG) << __func__ << ": effect Binder" << in_effect->asBinder().get();
+    }
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::close() {
+    LOG(DEBUG) << __func__;
+    if (!isClosed()) {
+        stopWorker();
+        LOG(DEBUG) << __func__ << ": joining the worker thread...";
+        mWorker->stop();
+        LOG(DEBUG) << __func__ << ": worker thread joined";
+        mContext.reset();
+        mWorker->setClosed();
+        return ndk::ScopedAStatus::ok();
+    } else {
+        LOG(ERROR) << __func__ << ": stream was already closed";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+}
+
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::prepareToClose() {
+    LOG(DEBUG) << __func__;
+    if (!isClosed()) {
+        return ndk::ScopedAStatus::ok();
+    }
+    LOG(ERROR) << __func__ << ": stream was closed";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+}
+
+template <class Metadata>
+void StreamCommonImpl<Metadata>::stopWorker() {
+    if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
+        LOG(DEBUG) << __func__ << ": asking the worker to exit...";
+        auto cmd = StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::halReservedExit>(
+                mContext.getInternalCommandCookie());
+        // Note: never call 'pause' and 'resume' methods of StreamWorker
+        // in the HAL implementation. These methods are to be used by
+        // the client side only. Preventing the worker loop from running
+        // on the HAL side can cause a deadlock.
+        if (!commandMQ->writeBlocking(&cmd, 1)) {
+            LOG(ERROR) << __func__ << ": failed to write exit command to the MQ";
+        }
+        LOG(DEBUG) << __func__ << ": done";
+    }
+}
+
+template <class Metadata>
+ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateMetadata(const Metadata& metadata) {
+    LOG(DEBUG) << __func__;
+    if (!isClosed()) {
+        mMetadata = metadata;
+        return ndk::ScopedAStatus::ok();
+    }
+    LOG(ERROR) << __func__ << ": stream was closed";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+}
+
+// static
+ndk::ScopedAStatus StreamIn::initInstance(const std::shared_ptr<StreamIn>& stream) {
+    if (auto status = stream->init(); !status.isOk()) {
+        return status;
+    }
+    stream->createStreamCommon(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+namespace {
+static std::map<AudioDevice, std::string> transformMicrophones(
+        const std::vector<MicrophoneInfo>& microphones) {
+    std::map<AudioDevice, std::string> result;
+    std::transform(microphones.begin(), microphones.end(), std::inserter(result, result.begin()),
+                   [](const auto& mic) { return std::make_pair(mic.device, mic.id); });
+    return result;
+}
+}  // namespace
+
+StreamIn::StreamIn(const SinkMetadata& sinkMetadata, StreamContext&& context,
+                   const DriverInterface::CreateInstance& createDriver,
+                   const StreamWorkerInterface::CreateInstance& createWorker,
+                   const std::vector<MicrophoneInfo>& microphones)
+    : StreamCommonImpl<SinkMetadata>(sinkMetadata, std::move(context), createDriver, createWorker),
+      mMicrophones(transformMicrophones(microphones)) {
+    LOG(DEBUG) << __func__;
+}
+
+ndk::ScopedAStatus StreamIn::getActiveMicrophones(
+        std::vector<MicrophoneDynamicInfo>* _aidl_return) {
+    std::vector<MicrophoneDynamicInfo> result;
+    std::vector<MicrophoneDynamicInfo::ChannelMapping> channelMapping{
+            getChannelCount(mContext.getChannelLayout()),
+            MicrophoneDynamicInfo::ChannelMapping::DIRECT};
+    for (auto it = mConnectedDevices.begin(); it != mConnectedDevices.end(); ++it) {
+        if (auto micIt = mMicrophones.find(*it); micIt != mMicrophones.end()) {
+            MicrophoneDynamicInfo dynMic;
+            dynMic.id = micIt->second;
+            dynMic.channelMapping = channelMapping;
+            result.push_back(std::move(dynMic));
+        }
+    }
+    *_aidl_return = std::move(result);
+    LOG(DEBUG) << __func__ << ": returning " << ::android::internal::ToString(*_aidl_return);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StreamIn::getMicrophoneDirection(MicrophoneDirection* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamIn::setMicrophoneDirection(MicrophoneDirection in_direction) {
+    LOG(DEBUG) << __func__ << ": direction " << toString(in_direction);
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamIn::getMicrophoneFieldDimension(float* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamIn::setMicrophoneFieldDimension(float in_zoom) {
+    LOG(DEBUG) << __func__ << ": zoom " << in_zoom;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamIn::getHwGain(std::vector<float>* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamIn::setHwGain(const std::vector<float>& in_channelGains) {
+    LOG(DEBUG) << __func__ << ": gains " << ::android::internal::ToString(in_channelGains);
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+// static
+ndk::ScopedAStatus StreamOut::initInstance(const std::shared_ptr<StreamOut>& stream) {
+    if (auto status = stream->init(); !status.isOk()) {
+        return status;
+    }
+    stream->createStreamCommon(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+StreamOut::StreamOut(const SourceMetadata& sourceMetadata, StreamContext&& context,
+                     const DriverInterface::CreateInstance& createDriver,
+                     const StreamWorkerInterface::CreateInstance& createWorker,
+                     const std::optional<AudioOffloadInfo>& offloadInfo)
+    : StreamCommonImpl<SourceMetadata>(sourceMetadata, std::move(context), createDriver,
+                                       createWorker),
+      mOffloadInfo(offloadInfo) {
+    LOG(DEBUG) << __func__;
+}
+
+ndk::ScopedAStatus StreamOut::updateOffloadMetadata(
+        const AudioOffloadMetadata& in_offloadMetadata) {
+    LOG(DEBUG) << __func__;
+    if (isClosed()) {
+        LOG(ERROR) << __func__ << ": stream was closed";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    if (!mOffloadInfo.has_value()) {
+        LOG(ERROR) << __func__ << ": not a compressed offload stream";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    if (in_offloadMetadata.sampleRate < 0) {
+        LOG(ERROR) << __func__ << ": invalid sample rate value: " << in_offloadMetadata.sampleRate;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_offloadMetadata.averageBitRatePerSecond < 0) {
+        LOG(ERROR) << __func__
+                   << ": invalid average BPS value: " << in_offloadMetadata.averageBitRatePerSecond;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_offloadMetadata.delayFrames < 0) {
+        LOG(ERROR) << __func__
+                   << ": invalid delay frames value: " << in_offloadMetadata.delayFrames;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_offloadMetadata.paddingFrames < 0) {
+        LOG(ERROR) << __func__
+                   << ": invalid padding frames value: " << in_offloadMetadata.paddingFrames;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    mOffloadMetadata = in_offloadMetadata;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StreamOut::getHwVolume(std::vector<float>* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::setHwVolume(const std::vector<float>& in_channelVolumes) {
+    LOG(DEBUG) << __func__ << ": gains " << ::android::internal::ToString(in_channelVolumes);
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::getAudioDescriptionMixLevel(float* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::setAudioDescriptionMixLevel(float in_leveldB) {
+    LOG(DEBUG) << __func__ << ": description mix level " << in_leveldB;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::getDualMonoMode(AudioDualMonoMode* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::setDualMonoMode(AudioDualMonoMode in_mode) {
+    LOG(DEBUG) << __func__ << ": dual mono mode " << toString(in_mode);
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::getRecommendedLatencyModes(
+        std::vector<AudioLatencyMode>* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::setLatencyMode(AudioLatencyMode in_mode) {
+    LOG(DEBUG) << __func__ << ": latency mode " << toString(in_mode);
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::getPlaybackRateParameters(AudioPlaybackRate* _aidl_return) {
+    LOG(DEBUG) << __func__;
+    (void)_aidl_return;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::setPlaybackRateParameters(const AudioPlaybackRate& in_playbackRate) {
+    LOG(DEBUG) << __func__ << ": " << in_playbackRate.toString();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus StreamOut::selectPresentation(int32_t in_presentationId, int32_t in_programId) {
+    LOG(DEBUG) << __func__ << ": presentationId " << in_presentationId << ", programId "
+               << in_programId;
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/StreamStub.cpp b/audio/aidl/default/StreamStub.cpp
new file mode 100644
index 0000000..2467320
--- /dev/null
+++ b/audio/aidl/default/StreamStub.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cmath>
+
+#define LOG_TAG "AHAL_Stream"
+#include <android-base/logging.h>
+#include <audio_utils/clock.h>
+
+#include "core-impl/Module.h"
+#include "core-impl/StreamStub.h"
+
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
+
+namespace aidl::android::hardware::audio::core {
+
+DriverStub::DriverStub(const StreamContext& context, bool isInput)
+    : mFrameSizeBytes(context.getFrameSize()),
+      mSampleRate(context.getSampleRate()),
+      mIsAsynchronous(!!context.getAsyncCallback()),
+      mIsInput(isInput) {}
+
+::android::status_t DriverStub::init() {
+    usleep(500);
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::drain(StreamDescriptor::DrainMode) {
+    usleep(500);
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::flush() {
+    usleep(500);
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::pause() {
+    usleep(500);
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+                                         int32_t* latencyMs) {
+    static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
+    static constexpr float kScaleFactor = .8f;
+    if (mIsAsynchronous) {
+        usleep(500);
+    } else {
+        const size_t delayUs = static_cast<size_t>(
+                std::roundf(kScaleFactor * frameCount * kMicrosPerSecond / mSampleRate));
+        usleep(delayUs);
+    }
+    if (mIsInput) {
+        uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
+        for (size_t i = 0; i < frameCount * mFrameSizeBytes; ++i) {
+            byteBuffer[i] = std::rand() % 255;
+        }
+    }
+    *actualFrameCount = frameCount;
+    *latencyMs = Module::kLatencyMs;
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::standby() {
+    usleep(500);
+    return ::android::OK;
+}
+
+::android::status_t DriverStub::setConnectedDevices(
+        const std::vector<AudioDevice>& connectedDevices __unused) {
+    usleep(500);
+    return ::android::OK;
+}
+
+// static
+ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata,
+                                                StreamContext&& context,
+                                                const std::vector<MicrophoneInfo>& microphones,
+                                                std::shared_ptr<StreamIn>* result) {
+    std::shared_ptr<StreamIn> stream =
+            ndk::SharedRefBase::make<StreamInStub>(sinkMetadata, std::move(context), microphones);
+    if (auto status = initInstance(stream); !status.isOk()) {
+        return status;
+    }
+    *result = std::move(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context,
+                           const std::vector<MicrophoneInfo>& microphones)
+    : StreamIn(
+              sinkMetadata, std::move(context),
+              [](const StreamContext& ctx) -> DriverInterface* {
+                  return new DriverStub(ctx, true /*isInput*/);
+              },
+              [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+                  // The default worker implementation is used.
+                  return new StreamInWorker(ctx, driver);
+              },
+              microphones) {}
+
+// static
+ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMetadata,
+                                                 StreamContext&& context,
+                                                 const std::optional<AudioOffloadInfo>& offloadInfo,
+                                                 std::shared_ptr<StreamOut>* result) {
+    std::shared_ptr<StreamOut> stream = ndk::SharedRefBase::make<StreamOutStub>(
+            sourceMetadata, std::move(context), offloadInfo);
+    if (auto status = initInstance(stream); !status.isOk()) {
+        return status;
+    }
+    *result = std::move(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+StreamOutStub::StreamOutStub(const SourceMetadata& sourceMetadata, StreamContext&& context,
+                             const std::optional<AudioOffloadInfo>& offloadInfo)
+    : StreamOut(
+              sourceMetadata, std::move(context),
+              [](const StreamContext& ctx) -> DriverInterface* {
+                  return new DriverStub(ctx, false /*isInput*/);
+              },
+              [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+                  // The default worker implementation is used.
+                  return new StreamOutWorker(ctx, driver);
+              },
+              offloadInfo) {}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/Telephony.cpp b/audio/aidl/default/Telephony.cpp
new file mode 100644
index 0000000..bf05a8d
--- /dev/null
+++ b/audio/aidl/default/Telephony.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_Telephony"
+#include <android-base/logging.h>
+
+#include <Utils.h>
+#include <android/binder_to_string.h>
+
+#include "core-impl/Telephony.h"
+
+using aidl::android::hardware::audio::common::isValidAudioMode;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::Boolean;
+using aidl::android::media::audio::common::Float;
+
+namespace aidl::android::hardware::audio::core {
+
+Telephony::Telephony() {
+    mTelecomConfig.voiceVolume = Float{TelecomConfig::VOICE_VOLUME_MAX};
+    mTelecomConfig.ttyMode = TelecomConfig::TtyMode::OFF;
+    mTelecomConfig.isHacEnabled = Boolean{false};
+}
+
+ndk::ScopedAStatus Telephony::getSupportedAudioModes(std::vector<AudioMode>* _aidl_return) {
+    *_aidl_return = mSupportedAudioModes;
+    LOG(DEBUG) << __func__ << ": returning " << ::android::internal::ToString(*_aidl_return);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Telephony::switchAudioMode(AudioMode in_mode) {
+    if (!isValidAudioMode(in_mode)) {
+        LOG(ERROR) << __func__ << ": invalid mode " << toString(in_mode);
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (std::find(mSupportedAudioModes.begin(), mSupportedAudioModes.end(), in_mode) !=
+        mSupportedAudioModes.end()) {
+        LOG(DEBUG) << __func__ << ": " << toString(in_mode);
+        return ndk::ScopedAStatus::ok();
+    }
+    LOG(ERROR) << __func__ << ": unsupported mode " << toString(in_mode);
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Telephony::setTelecomConfig(const TelecomConfig& in_config,
+                                               TelecomConfig* _aidl_return) {
+    if (in_config.voiceVolume.has_value() &&
+        (in_config.voiceVolume.value().value < TelecomConfig::VOICE_VOLUME_MIN ||
+         in_config.voiceVolume.value().value > TelecomConfig::VOICE_VOLUME_MAX)) {
+        LOG(ERROR) << __func__
+                   << ": voice volume value is invalid: " << in_config.voiceVolume.value().value;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (in_config.voiceVolume.has_value()) {
+        mTelecomConfig.voiceVolume = in_config.voiceVolume;
+    }
+    if (in_config.ttyMode != TelecomConfig::TtyMode::UNSPECIFIED) {
+        mTelecomConfig.ttyMode = in_config.ttyMode;
+    }
+    if (in_config.isHacEnabled.has_value()) {
+        mTelecomConfig.isHacEnabled = in_config.isHacEnabled;
+    }
+    *_aidl_return = mTelecomConfig;
+    LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
+               << _aidl_return->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
new file mode 100644
index 0000000..63a014a
--- /dev/null
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+#include <unordered_set>
+
+#define LOG_TAG "AHAL_AcousticEchoCancelerSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "AcousticEchoCancelerSw.h"
+
+using aidl::android::hardware::audio::effect::AcousticEchoCancelerSw;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidAcousticEchoCancelerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAcousticEchoCanceler;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::Range;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAcousticEchoCancelerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<AcousticEchoCancelerSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAcousticEchoCancelerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = AcousticEchoCancelerSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string AcousticEchoCancelerSw::kEffectName = "AcousticEchoCancelerSw";
+
+const std::vector<Range::AcousticEchoCancelerRange> AcousticEchoCancelerSw::kRanges = {
+        MAKE_RANGE(AcousticEchoCanceler, echoDelayUs, 0, 500),
+        /* mobile mode not supported, and not settable */
+        MAKE_RANGE(AcousticEchoCanceler, mobileMode, false, false)};
+
+const Capability AcousticEchoCancelerSw::kCapability = {.range = AcousticEchoCancelerSw::kRanges};
+
+const Descriptor AcousticEchoCancelerSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidAcousticEchoCanceler(),
+                          .uuid = getEffectImplUuidAcousticEchoCancelerSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = AcousticEchoCancelerSw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = AcousticEchoCancelerSw::kCapability};
+
+ndk::ScopedAStatus AcousticEchoCancelerSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AcousticEchoCancelerSw::setParameterSpecific(
+        const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::acousticEchoCanceler != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& param = specific.get<Parameter::Specific::acousticEchoCanceler>();
+    RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+
+    auto tag = param.getTag();
+    switch (tag) {
+        case AcousticEchoCanceler::echoDelayUs: {
+            RETURN_IF(mContext->setEchoDelay(param.get<AcousticEchoCanceler::echoDelayUs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "echoDelayNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case AcousticEchoCanceler::mobileMode: {
+            RETURN_IF(true == param.get<AcousticEchoCanceler::mobileMode>(), EX_ILLEGAL_ARGUMENT,
+                      "SettingmobileModeSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus AcousticEchoCancelerSw::getParameterSpecific(const Parameter::Id& id,
+                                                                Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::acousticEchoCancelerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto specificId = id.get<Parameter::Id::acousticEchoCancelerTag>();
+    auto specificIdTag = specificId.getTag();
+    switch (specificIdTag) {
+        case AcousticEchoCanceler::Id::commonTag:
+            return getParameterAcousticEchoCanceler(
+                    specificId.get<AcousticEchoCanceler::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus AcousticEchoCancelerSw::getParameterAcousticEchoCanceler(
+        const AcousticEchoCanceler::Tag& tag, Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    AcousticEchoCanceler param;
+    switch (tag) {
+        case AcousticEchoCanceler::echoDelayUs: {
+            param.set<AcousticEchoCanceler::echoDelayUs>(mContext->getEchoDelay());
+            break;
+        }
+        case AcousticEchoCanceler::mobileMode: {
+            param.set<AcousticEchoCanceler::mobileMode>(false);
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::acousticEchoCanceler>(param);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> AcousticEchoCancelerSw::createContext(
+        const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<AcousticEchoCancelerSwContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> AcousticEchoCancelerSw::getContext() {
+    return mContext;
+}
+
+RetCode AcousticEchoCancelerSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status AcousticEchoCancelerSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode AcousticEchoCancelerSwContext::setEchoDelay(int echoDelayUs) {
+    mEchoDelayUs = echoDelayUs;
+    return RetCode::SUCCESS;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
new file mode 100644
index 0000000..73cf42b
--- /dev/null
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <aidl/android/hardware/audio/effect/Range.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class AcousticEchoCancelerSwContext final : public EffectContext {
+  public:
+    AcousticEchoCancelerSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setEchoDelay(int echoDelayUs);
+    int getEchoDelay() const { return mEchoDelayUs; }
+
+  private:
+    int mEchoDelayUs = 0;
+};
+
+class AcousticEchoCancelerSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    AcousticEchoCancelerSw() { LOG(DEBUG) << __func__; }
+    ~AcousticEchoCancelerSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+  private:
+    static const std::vector<Range::AcousticEchoCancelerRange> kRanges;
+    std::shared_ptr<AcousticEchoCancelerSwContext> mContext;
+    ndk::ScopedAStatus getParameterAcousticEchoCanceler(const AcousticEchoCanceler::Tag& tag,
+                                                        Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/acousticEchoCanceler/Android.bp b/audio/aidl/default/acousticEchoCanceler/Android.bp
new file mode 100644
index 0000000..bfb7212
--- /dev/null
+++ b/audio/aidl/default/acousticEchoCanceler/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libaecsw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "AcousticEchoCancelerSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/android.hardware.audio.effect.service-aidl.example.rc b/audio/aidl/default/android.hardware.audio.effect.service-aidl.example.rc
new file mode 100644
index 0000000..5f859a1
--- /dev/null
+++ b/audio/aidl/default/android.hardware.audio.effect.service-aidl.example.rc
@@ -0,0 +1,11 @@
+service vendor.audio-effect-hal-aidl /vendor/bin/hw/android.hardware.audio.effect.service-aidl.example
+    class hal
+    user audioserver
+    # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
+    group audio media
+    capabilities BLOCK_SUSPEND
+    # setting RLIMIT_RTPRIO allows binder RT priority inheritance
+    rlimit rtprio 10 10
+    ioprio rt 4
+    task_profiles ProcessCapacityHigh HighPerformance
+    onrestart restart audioserver
diff --git a/audio/aidl/default/android.hardware.audio.effect.service-aidl.xml b/audio/aidl/default/android.hardware.audio.effect.service-aidl.xml
new file mode 100644
index 0000000..fdc53a3
--- /dev/null
+++ b/audio/aidl/default/android.hardware.audio.effect.service-aidl.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+  <hal format="aidl">
+    <name>android.hardware.audio.effect</name>
+    <version>1</version>
+    <fqname>IFactory/default</fqname>
+  </hal>
+</manifest>
diff --git a/audio/aidl/default/android.hardware.audio.service-aidl.example.rc b/audio/aidl/default/android.hardware.audio.service-aidl.example.rc
new file mode 100644
index 0000000..2068735
--- /dev/null
+++ b/audio/aidl/default/android.hardware.audio.service-aidl.example.rc
@@ -0,0 +1,11 @@
+service vendor.audio-hal-aidl /vendor/bin/hw/android.hardware.audio.service-aidl.example
+    class hal
+    user audioserver
+    # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
+    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
+    capabilities BLOCK_SUSPEND
+    # setting RLIMIT_RTPRIO allows binder RT priority inheritance
+    rlimit rtprio 10 10
+    ioprio rt 4
+    task_profiles ProcessCapacityHigh HighPerformance
+    onrestart restart audioserver
diff --git a/audio/aidl/default/android.hardware.audio.service-aidl.xml b/audio/aidl/default/android.hardware.audio.service-aidl.xml
new file mode 100644
index 0000000..9636a58
--- /dev/null
+++ b/audio/aidl/default/android.hardware.audio.service-aidl.xml
@@ -0,0 +1,22 @@
+<manifest version="1.0" type="device">
+  <hal format="aidl">
+    <name>android.hardware.audio.core</name>
+    <version>1</version>
+    <fqname>IModule/default</fqname>
+  </hal>
+  <hal format="aidl">
+    <name>android.hardware.audio.core</name>
+    <version>1</version>
+    <fqname>IModule/r_submix</fqname>
+  </hal>
+  <hal format="aidl">
+    <name>android.hardware.audio.core</name>
+    <version>1</version>
+    <fqname>IModule/usb</fqname>
+  </hal>
+  <hal format="aidl">
+    <name>android.hardware.audio.core</name>
+    <version>1</version>
+    <fqname>IConfig/default</fqname>
+  </hal>
+</manifest>
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
new file mode 100644
index 0000000..6627ae7
--- /dev/null
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<audio_effects_conf version="2.0" xmlns="http://schemas.android.com/audio/audio_effects_conf/v2_0">
+    <!-- Overview.
+         This example config file was copy from existing one: frameworks/av/media/libeffects/data/
+         audio_effects.xml, with effect library names updated to AIDL libraries we currently have.
+
+         All "library" attributes in "effect" element must must match a "library" element with the
+         same value of the "name" attribute.
+         All "effect" attributes in "preprocess" and "postprocess" element must match an "effect"
+         element with the same value of the "name" attribute.
+
+         AIDL EffectFactory are relying on the "name" attribute in "effect" element to identify the
+         effect type, so it's necessary to have the mapping from name to effect type UUID. Make
+         sure to either use existing effect name as key of
+         ::android::hardware::audio::effect::kUuidNameTypeMap, or add a new {name, typeUUID} map
+         item to the kUuidNameTypeMap.
+
+         Existing audio_effects.xml should working without any change as long as:
+         1. "path" attribute of "library" element matches with the actual effect library name.
+         2. "name" attribute of "effect" and "effectProxy" element correctly added as key of
+            kUuidNameTypeMap, with value matches Identity.type in Descriptor.aidl.
+         3. "uuid" attribute of "effect" element matches Identity.uuid in Descriptor.aidl.
+         4. "uuid" attribute of "effectProxy" element matches Identity.proxy in Descriptor.aidl.
+    -->
+
+    <!-- List of effect libraries to load.
+         Each library element must contain a "name" attribute and a "path" attribute giving the
+         name of a library .so file on the target device.
+    -->
+    <libraries>
+        <library name="aecsw" path="libaecsw.so"/>
+        <library name="agc1sw" path="libagc1sw.so"/>
+        <library name="agc2sw" path="libagc2sw.so"/>
+        <library name="bassboostsw" path="libbassboostsw.so"/>
+        <library name="bundle" path="libbundleaidl.so"/>
+        <library name="downmix" path="libdownmixaidl.so"/>
+        <library name="dynamics_processing" path="libdynamicsprocessingaidl.so"/>
+        <library name="equalizersw" path="libequalizersw.so"/>
+        <library name="haptic_generator" path="libhapticgeneratoraidl.so"/>
+        <library name="loudness_enhancer" path="libloudnessenhanceraidl.so"/>
+        <library name="nssw" path="libnssw.so"/>
+        <library name="env_reverbsw" path="libenvreverbsw.so"/>
+        <library name="pre_processing" path="libpreprocessingaidl.so"/>
+        <library name="preset_reverbsw" path="libpresetreverbsw.so"/>
+        <library name="reverb" path="libreverbaidl.so"/>
+        <library name="virtualizersw" path="libvirtualizersw.so"/>
+        <library name="visualizer" path="libvisualizeraidl.so"/>
+        <library name="volumesw" path="libvolumesw.so"/>
+        <library name="extensioneffect" path="libextensioneffect.so"/>
+    </libraries>
+
+    <!-- list of effects to load.
+         Each "effect" element must contain a "name", "library" and a "uuid" attribute.
+         The value of the "library" attribute must correspond to the name of one library element in
+         the "libraries" element.
+         The "name" attribute used to specific effect type, and should be mapping to a key of
+         aidl::android::hardware::audio::effect::kUuidNameTypeMap.
+         The "uuid" attribute is the implementation specific UUID as specified by the effect vendor.
+
+         Effect proxy can be supported with "effectProxy" element, each sub-element should contain
+         "library" and "uuid" attribute, all other attributes were ignored. Framework side use
+         result of IFactory.queryEffects() to decide which effect implementation should be part of
+         proxy and which not.
+
+         Only "name", "library", and "uuid" attributes in "effects" element are meaningful and
+         parsed out by EffectConfig class, all other attributes are ignored.
+         Only "name" and "uuid" attributes in "effectProxy" element are meaningful and parsed out
+         by EffectConfig class, all other attributes are ignored.
+    -->
+
+    <effects>
+        <effect name="automatic_gain_control_v2" library="pre_processing" uuid="89f38e65-d4d2-4d64-ad0e-2b3e799ea886"/>
+        <effectProxy name="bassboost" uuid="14804144-a5ee-4d24-aa88-0002a5d5c51b">
+            <libsw library="bassboostsw" uuid="fa8181f2-588b-11ed-9b6a-0242ac120002"/>
+            <libsw library="bundle" uuid="8631f300-72e2-11df-b57e-0002a5d5c51b"/>
+        </effectProxy>
+        <effect name="downmix" library="downmix" uuid="93f04452-e4fe-41cc-91f9-e475b6d1d69f"/>
+        <effect name="dynamics_processing" library="dynamics_processing" uuid="e0e6539b-1781-7261-676f-6d7573696340"/>
+        <effect name="haptic_generator" library="haptic_generator" uuid="97c4acd1-8b82-4f2f-832e-c2fe5d7a9931"/>
+        <effect name="loudness_enhancer" library="loudness_enhancer" uuid="fa415329-2034-4bea-b5dc-5b381c8d1e2c"/>
+        <effect name="env_reverb" library="env_reverbsw" uuid="fa819886-588b-11ed-9b6a-0242ac120002"/>
+        <effect name="preset_reverb" library="preset_reverbsw" uuid="fa8199c6-588b-11ed-9b6a-0242ac120002"/>
+        <effect name="reverb_env_aux" library="reverb" uuid="4a387fc0-8ab3-11df-8bad-0002a5d5c51b"/>
+        <effect name="reverb_env_ins" library="reverb" uuid="c7a511a0-a3bb-11df-860e-0002a5d5c51b"/>
+        <effect name="reverb_pre_aux" library="reverb" uuid="f29a1400-a3bb-11df-8ddc-0002a5d5c51b"/>
+        <effect name="reverb_pre_ins" library="reverb" uuid="172cdf00-a3bc-11df-a72f-0002a5d5c51b"/>
+        <effectProxy name="virtualizer" uuid="d3467faa-acc7-4d34-acaf-0002a5d5c51b">
+            <libsw library="virtualizersw" uuid="fa819d86-588b-11ed-9b6a-0242ac120002"/>
+            <libsw library="bundle" uuid="1d4033c0-8557-11df-9f2d-0002a5d5c51b"/>
+        </effectProxy>
+        <effect name="visualizer" library="visualizer" uuid="d069d9e0-8329-11df-9168-0002a5d5c51b"/>
+        <effect name="volume" library="bundle" uuid="119341a0-8469-11df-81f9-0002a5d5c51b"/>
+        <effectProxy name="equalizer" uuid="c8e70ecd-48ca-456e-8a4f-0002a5d5c51b">
+            <libsw library="equalizersw" uuid="0bed4300-847d-11df-bb17-0002a5d5c51b"/>
+            <libsw library="bundle" uuid="ce772f20-847d-11df-bb17-0002a5d5c51b"/>
+        </effectProxy>
+        <effect name="extensioneffect" library="extensioneffect" uuid="fa81dd00-588b-11ed-9b6a-0242ac120002"/>
+        <effect name="acoustic_echo_canceler" library="aecsw" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
+        <effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
+    </effects>
+
+    <preprocess>
+        <stream type="voice_communication">
+            <apply effect="acoustic_echo_canceler"/>
+            <apply effect="noise_suppression"/>
+        </stream>
+    </preprocess>
+
+    <!-- Audio pre processor configurations.
+         The pre processor configuration is described in a "preprocess" element and consists in a
+         list of elements each describing pre processor settings for a given use case or "stream".
+         Each stream element has a "type" attribute corresponding to the input source used.
+         Valid types are these defined in system/hardware/interfaces/media/aidl/android/media/audio/
+         common/AudioSource.aidl.
+         Each "stream" element contains a list of "apply" elements indicating one effect to apply.
+         The effect to apply is designated by its name in the "effects" elements.
+         If there are more than one effect apply to one stream, the audio framework will apply them
+         in the same equence as they listed in "stream" element.
+
+        <preprocess>
+            <stream type="voice_communication">
+                <apply effect="aec"/>
+                <apply effect="ns"/>
+            </stream>
+        </preprocess>
+    -->
+
+    <!-- Audio post processor configurations.
+         The post processor configuration is described in a "postprocess" element and consists in a
+         list of elements each describing post processor settings for a given use case or "stream".
+         Each stream element has a "type" attribute corresponding to the stream type used.
+         Valid types are these defined in system/hardware/interfaces/media/aidl/android/media/audio/
+         common/AudioStreamType.aidl.
+         Each "stream" element contains a list of "apply" elements indicating one effect to apply.
+         The effect to apply is designated by its name in the "effects" elements.
+         If there are more than one effect apply to one stream, the audio framework will apply them
+         in the same equence as they listed in "stream" element.
+
+        <postprocess>
+            <stream type="music">
+                <apply effect="music_post_proc"/>
+            </stream>
+            <stream type="voice_call">
+                <apply effect="voice_post_proc"/>
+            </stream>
+            <stream type="notification">
+                <apply effect="notification_post_proc"/>
+            </stream>
+        </postprocess>
+    -->
+
+</audio_effects_conf>
diff --git a/audio/aidl/default/automaticGainControlV1/Android.bp b/audio/aidl/default/automaticGainControlV1/Android.bp
new file mode 100644
index 0000000..4ae8e63
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV1/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libagc1sw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "AutomaticGainControlV1Sw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
new file mode 100644
index 0000000..ce10ae1
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_AutomaticGainControlV1Sw"
+
+#include <android-base/logging.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "AutomaticGainControlV1Sw.h"
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV1Sw;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidAutomaticGainControlV1Sw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV1;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV1Sw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlV1Sw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV1Sw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = AutomaticGainControlV1Sw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string AutomaticGainControlV1Sw::kEffectName = "AutomaticGainControlV1Sw";
+
+const std::vector<Range::AutomaticGainControlV1Range> AutomaticGainControlV1Sw::kRanges = {
+        MAKE_RANGE(AutomaticGainControlV1, targetPeakLevelDbFs, -3100, 0),
+        MAKE_RANGE(AutomaticGainControlV1, maxCompressionGainDb, 0, 9000)};
+
+const Capability AutomaticGainControlV1Sw::kCapability = {
+        .range = AutomaticGainControlV1Sw::kRanges};
+
+const Descriptor AutomaticGainControlV1Sw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidAutomaticGainControlV1(),
+                          .uuid = getEffectImplUuidAutomaticGainControlV1Sw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = AutomaticGainControlV1Sw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = AutomaticGainControlV1Sw::kCapability};
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::setParameterSpecific(
+        const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::automaticGainControlV1 != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& param = specific.get<Parameter::Specific::automaticGainControlV1>();
+    RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = param.getTag();
+    switch (tag) {
+        case AutomaticGainControlV1::targetPeakLevelDbFs: {
+            RETURN_IF(mContext->setTargetPeakLevel(
+                              param.get<AutomaticGainControlV1::targetPeakLevelDbFs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "targetPeakLevelNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case AutomaticGainControlV1::maxCompressionGainDb: {
+            RETURN_IF(mContext->setMaxCompressionGain(
+                              param.get<AutomaticGainControlV1::maxCompressionGainDb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "maxCompressionGainNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case AutomaticGainControlV1::enableLimiter: {
+            RETURN_IF(
+                    mContext->setEnableLimiter(
+                            param.get<AutomaticGainControlV1::enableLimiter>()) != RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "enableLimiterNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::getParameterSpecific(const Parameter::Id& id,
+                                                                  Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::automaticGainControlV1Tag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto specificId = id.get<Parameter::Id::automaticGainControlV1Tag>();
+    auto specificIdTag = specificId.getTag();
+    switch (specificIdTag) {
+        case AutomaticGainControlV1::Id::commonTag:
+            return getParameterAutomaticGainControlV1(
+                    specificId.get<AutomaticGainControlV1::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::getParameterAutomaticGainControlV1(
+        const AutomaticGainControlV1::Tag& tag, Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    AutomaticGainControlV1 param;
+    switch (tag) {
+        case AutomaticGainControlV1::targetPeakLevelDbFs: {
+            param.set<AutomaticGainControlV1::targetPeakLevelDbFs>(mContext->getTargetPeakLevel());
+            break;
+        }
+        case AutomaticGainControlV1::maxCompressionGainDb: {
+            param.set<AutomaticGainControlV1::maxCompressionGainDb>(
+                    mContext->getMaxCompressionGain());
+            break;
+        }
+        case AutomaticGainControlV1::enableLimiter: {
+            param.set<AutomaticGainControlV1::enableLimiter>(mContext->getEnableLimiter());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::automaticGainControlV1>(param);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV1Sw::createContext(
+        const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext =
+                std::make_shared<AutomaticGainControlV1SwContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV1Sw::getContext() {
+    return mContext;
+}
+
+RetCode AutomaticGainControlV1Sw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status AutomaticGainControlV1Sw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode AutomaticGainControlV1SwContext::setTargetPeakLevel(int targetPeakLevel) {
+    mTargetPeakLevel = targetPeakLevel;
+    return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV1SwContext::getTargetPeakLevel() {
+    return mTargetPeakLevel;
+}
+
+RetCode AutomaticGainControlV1SwContext::setMaxCompressionGain(int maxCompressionGain) {
+    mMaxCompressionGain = maxCompressionGain;
+    return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV1SwContext::getMaxCompressionGain() {
+    return mMaxCompressionGain;
+}
+
+RetCode AutomaticGainControlV1SwContext::setEnableLimiter(bool enableLimiter) {
+    mEnableLimiter = enableLimiter;
+    return RetCode::SUCCESS;
+}
+
+bool AutomaticGainControlV1SwContext::getEnableLimiter() {
+    return mEnableLimiter;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
new file mode 100644
index 0000000..7d2a69f
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class AutomaticGainControlV1SwContext final : public EffectContext {
+  public:
+    AutomaticGainControlV1SwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setTargetPeakLevel(int targetPeakLevel);
+    int getTargetPeakLevel();
+    RetCode setMaxCompressionGain(int maxCompressionGainDb);
+    int getMaxCompressionGain();
+    RetCode setEnableLimiter(bool enableLimiter);
+    bool getEnableLimiter();
+
+  private:
+    int mTargetPeakLevel = 0;
+    int mMaxCompressionGain = 0;
+    bool mEnableLimiter = false;
+};
+
+class AutomaticGainControlV1Sw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const bool kStrengthSupported;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    AutomaticGainControlV1Sw() { LOG(DEBUG) << __func__; }
+    ~AutomaticGainControlV1Sw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+  private:
+    static const std::vector<Range::AutomaticGainControlV1Range> kRanges;
+    std::shared_ptr<AutomaticGainControlV1SwContext> mContext;
+    ndk::ScopedAStatus getParameterAutomaticGainControlV1(const AutomaticGainControlV1::Tag& tag,
+                                                          Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControlV2/Android.bp b/audio/aidl/default/automaticGainControlV2/Android.bp
new file mode 100644
index 0000000..631cf58
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV2/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libagc2sw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "AutomaticGainControlV2Sw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
new file mode 100644
index 0000000..1e336ac
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+#define LOG_TAG "AHAL_AutomaticGainControlV2Sw"
+
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "AutomaticGainControlV2Sw.h"
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV2Sw;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidAutomaticGainControlV2Sw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV2;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV2Sw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlV2Sw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidAutomaticGainControlV2Sw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = AutomaticGainControlV2Sw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string AutomaticGainControlV2Sw::kEffectName = "AutomaticGainControlV2Sw";
+
+const std::vector<Range::AutomaticGainControlV2Range> AutomaticGainControlV2Sw::kRanges = {
+        MAKE_RANGE(AutomaticGainControlV2, fixedDigitalGainMb, 0, 50000),
+        MAKE_RANGE(AutomaticGainControlV2, saturationMarginMb, 0, 10000)};
+
+const Capability AutomaticGainControlV2Sw::kCapability = {
+        .range = AutomaticGainControlV2Sw::kRanges};
+
+const Descriptor AutomaticGainControlV2Sw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidAutomaticGainControlV2(),
+                          .uuid = getEffectImplUuidAutomaticGainControlV2Sw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = AutomaticGainControlV2Sw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = AutomaticGainControlV2Sw::kCapability};
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::setParameterSpecific(
+        const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::automaticGainControlV2 != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& param = specific.get<Parameter::Specific::automaticGainControlV2>();
+    RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = param.getTag();
+    switch (tag) {
+        case AutomaticGainControlV2::fixedDigitalGainMb: {
+            RETURN_IF(mContext->setDigitalGain(
+                              param.get<AutomaticGainControlV2::fixedDigitalGainMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "digitalGainNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case AutomaticGainControlV2::levelEstimator: {
+            RETURN_IF(mContext->setLevelEstimator(
+                              param.get<AutomaticGainControlV2::levelEstimator>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "levelEstimatorNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case AutomaticGainControlV2::saturationMarginMb: {
+            RETURN_IF(mContext->setSaturationMargin(
+                              param.get<AutomaticGainControlV2::saturationMarginMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "saturationMarginNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::getParameterSpecific(const Parameter::Id& id,
+                                                                  Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::automaticGainControlV2Tag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto specificId = id.get<Parameter::Id::automaticGainControlV2Tag>();
+    auto specificIdTag = specificId.getTag();
+    switch (specificIdTag) {
+        case AutomaticGainControlV2::Id::commonTag:
+            return getParameterAutomaticGainControlV2(
+                    specificId.get<AutomaticGainControlV2::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::getParameterAutomaticGainControlV2(
+        const AutomaticGainControlV2::Tag& tag, Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    AutomaticGainControlV2 param;
+    switch (tag) {
+        case AutomaticGainControlV2::fixedDigitalGainMb: {
+            param.set<AutomaticGainControlV2::fixedDigitalGainMb>(mContext->getDigitalGain());
+            break;
+        }
+        case AutomaticGainControlV2::levelEstimator: {
+            param.set<AutomaticGainControlV2::levelEstimator>(mContext->getLevelEstimator());
+            break;
+        }
+        case AutomaticGainControlV2::saturationMarginMb: {
+            param.set<AutomaticGainControlV2::saturationMarginMb>(mContext->getSaturationMargin());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::automaticGainControlV2>(param);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV2Sw::createContext(
+        const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext =
+                std::make_shared<AutomaticGainControlV2SwContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV2Sw::getContext() {
+    return mContext;
+}
+
+RetCode AutomaticGainControlV2Sw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status AutomaticGainControlV2Sw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode AutomaticGainControlV2SwContext::setDigitalGain(int gain) {
+    mDigitalGain = gain;
+    return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV2SwContext::getDigitalGain() {
+    return mDigitalGain;
+}
+
+RetCode AutomaticGainControlV2SwContext::setLevelEstimator(
+        AutomaticGainControlV2::LevelEstimator levelEstimator) {
+    mLevelEstimator = levelEstimator;
+    return RetCode::SUCCESS;
+}
+
+AutomaticGainControlV2::LevelEstimator AutomaticGainControlV2SwContext::getLevelEstimator() {
+    return mLevelEstimator;
+}
+
+RetCode AutomaticGainControlV2SwContext::setSaturationMargin(int margin) {
+    mSaturationMargin = margin;
+    return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV2SwContext::getSaturationMargin() {
+    return mSaturationMargin;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
new file mode 100644
index 0000000..9aa60ea
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class AutomaticGainControlV2SwContext final : public EffectContext {
+  public:
+    AutomaticGainControlV2SwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setDigitalGain(int gain);
+    int getDigitalGain();
+    RetCode setLevelEstimator(AutomaticGainControlV2::LevelEstimator levelEstimator);
+    AutomaticGainControlV2::LevelEstimator getLevelEstimator();
+    RetCode setSaturationMargin(int margin);
+    int getSaturationMargin();
+
+  private:
+    int mDigitalGain = 0;
+    AutomaticGainControlV2::LevelEstimator mLevelEstimator =
+            AutomaticGainControlV2::LevelEstimator::RMS;
+    int mSaturationMargin = 0;
+};
+
+class AutomaticGainControlV2Sw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const bool kStrengthSupported;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    AutomaticGainControlV2Sw() { LOG(DEBUG) << __func__; }
+    ~AutomaticGainControlV2Sw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+  private:
+    static const std::vector<Range::AutomaticGainControlV2Range> kRanges;
+    std::shared_ptr<AutomaticGainControlV2SwContext> mContext;
+    ndk::ScopedAStatus getParameterAutomaticGainControlV2(const AutomaticGainControlV2::Tag& tag,
+                                                          Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bassboost/Android.bp b/audio/aidl/default/bassboost/Android.bp
new file mode 100644
index 0000000..82b2f20
--- /dev/null
+++ b/audio/aidl/default/bassboost/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libbassboostsw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "BassBoostSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
new file mode 100644
index 0000000..6072d89
--- /dev/null
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+
+#define LOG_TAG "AHAL_BassBoostSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "BassBoostSw.h"
+
+using aidl::android::hardware::audio::effect::BassBoostSw;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidBassBoostProxy;
+using aidl::android::hardware::audio::effect::getEffectImplUuidBassBoostSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidBassBoostSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<BassBoostSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidBassBoostSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = BassBoostSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string BassBoostSw::kEffectName = "BassBoostSw";
+
+const std::vector<Range::BassBoostRange> BassBoostSw::kRanges = {
+        MAKE_RANGE(BassBoost, strengthPm, 0, 1000)};
+const Capability BassBoostSw::kCapability = {.range = {BassBoostSw::kRanges}};
+const Descriptor BassBoostSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidBassBoost(),
+                          .uuid = getEffectImplUuidBassBoostSw()},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = BassBoostSw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = BassBoostSw::kCapability};
+
+ndk::ScopedAStatus BassBoostSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BassBoostSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::bassBoost != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& bbParam = specific.get<Parameter::Specific::bassBoost>();
+    RETURN_IF(!inRange(bbParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = bbParam.getTag();
+
+    switch (tag) {
+        case BassBoost::strengthPm: {
+            const auto strength = bbParam.get<BassBoost::strengthPm>();
+            RETURN_IF(mContext->setBbStrengthPm(strength) != RetCode::SUCCESS, EX_ILLEGAL_ARGUMENT,
+                      "strengthPmNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "BassBoostTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus BassBoostSw::getParameterSpecific(const Parameter::Id& id,
+                                                     Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::bassBoostTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto bbId = id.get<Parameter::Id::bassBoostTag>();
+    auto bbIdTag = bbId.getTag();
+    switch (bbIdTag) {
+        case BassBoost::Id::commonTag:
+            return getParameterBassBoost(bbId.get<BassBoost::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "BassBoostTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus BassBoostSw::getParameterBassBoost(const BassBoost::Tag& tag,
+                                                      Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    BassBoost bbParam;
+    switch (tag) {
+        case BassBoost::strengthPm: {
+            bbParam.set<BassBoost::strengthPm>(mContext->getBbStrengthPm());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "BassBoostTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::bassBoost>(bbParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> BassBoostSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<BassBoostSwContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> BassBoostSw::getContext() {
+    return mContext;
+}
+
+RetCode BassBoostSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status BassBoostSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode BassBoostSwContext::setBbStrengthPm(int strength) {
+    mStrength = strength;
+    return RetCode::SUCCESS;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bassboost/BassBoostSw.h b/audio/aidl/default/bassboost/BassBoostSw.h
new file mode 100644
index 0000000..1132472
--- /dev/null
+++ b/audio/aidl/default/bassboost/BassBoostSw.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class BassBoostSwContext final : public EffectContext {
+  public:
+    BassBoostSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setBbStrengthPm(int strength);
+    int getBbStrengthPm() const { return mStrength; }
+
+  private:
+    int mStrength = 0;
+};
+
+class BassBoostSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    BassBoostSw() { LOG(DEBUG) << __func__; }
+    ~BassBoostSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+  private:
+    static const std::vector<Range::BassBoostRange> kRanges;
+    std::shared_ptr<BassBoostSwContext> mContext;
+    ndk::ScopedAStatus getParameterBassBoost(const BassBoost::Tag& tag,
+                                             Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/config/audioPolicy/Android.bp b/audio/aidl/default/config/audioPolicy/Android.bp
new file mode 100644
index 0000000..6d8a148
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/Android.bp
@@ -0,0 +1,15 @@
+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"],
+}
+
+xsd_config {
+    name: "audio_policy_configuration_aidl_default",
+    srcs: ["audio_policy_configuration.xsd"],
+    package_name: "android.audio.policy.configuration",
+    nullability: true,
+}
diff --git a/audio/aidl/default/config/audioPolicy/api/current.txt b/audio/aidl/default/config/audioPolicy/api/current.txt
new file mode 100644
index 0000000..fabb93b
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/api/current.txt
@@ -0,0 +1,611 @@
+// Signature format: 2.0
+package android.audio.policy.configuration {
+
+  public class AttachedDevices {
+    ctor public AttachedDevices();
+    method @Nullable public java.util.List<java.lang.String> getItem();
+  }
+
+  public enum AudioChannelMask {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_10;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_11;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_12;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_13;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_14;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_15;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_16;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_17;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_18;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_19;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_20;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_21;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_22;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_23;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_24;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_3;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_4;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_5;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_6;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_7;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_8;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_9;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_2POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_2POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_3POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_3POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_5POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_6;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_FRONT_BACK;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_STEREO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_NONE;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_13POINT_360RA;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_22POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT4;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_BACK;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_SIDE;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_6POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT2;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT4;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_9POINT1POINT4;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_9POINT1POINT6;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_HAPTIC_AB;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_MONO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_A;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_PENTA;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_BACK;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_SIDE;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_TRI;
+    enum_constant public static final android.audio.policy.configuration.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK;
+  }
+
+  public enum AudioContentType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_MOVIE;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_MUSIC;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_SONIFICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_SPEECH;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_ULTRASOUND;
+    enum_constant public static final android.audio.policy.configuration.AudioContentType AUDIO_CONTENT_TYPE_UNKNOWN;
+  }
+
+  public enum AudioDevice {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_AMBIENT;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BACK_MIC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BUILTIN_MIC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_BUS;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_COMMUNICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_ECHO_REFERENCE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_FM_TUNER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_HDMI;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_HDMI_ARC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_HDMI_EARC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_IP;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_LINE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_LOOPBACK;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_PROXY;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_SPDIF;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_STUB;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_TELEPHONY_RX;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_TV_TUNER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_USB_ACCESSORY;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_USB_DEVICE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_USB_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_VOICE_CALL;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_IN_WIRED_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_NONE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLE_BROADCAST;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_BUS;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_EARPIECE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_ECHO_CANCELLER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_FM;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_HDMI;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_HDMI_ARC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_HDMI_EARC;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_IP;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_LINE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_PROXY;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_SPDIF;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_SPEAKER;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_STUB;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_TELEPHONY_TX;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_USB_ACCESSORY;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_USB_DEVICE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_USB_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADSET;
+  }
+
+  public enum AudioEncapsulationType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_IEC61937;
+    enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_NONE;
+    enum_constant public static final android.audio.policy.configuration.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_PCM;
+  }
+
+  public enum AudioFormat {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADIF;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_ELD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_ERLC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_LC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_LD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_LTP;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_MAIN;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_SCALABLE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_SSR;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ADTS_XHE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ELD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_ERLC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_HE_V1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_HE_V2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LATM;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LATM_LC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_LTP;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_MAIN;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_SCALABLE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_SSR;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_XHE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC4;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_ALAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_NB;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_WB;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_WB_PLUS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE_QLEA;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE_R4;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_HD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_APTX_TWSP;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_CELT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DRA;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DSD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS_HD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS_HD_MA;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS_UHD;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_DTS_UHD_P2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_EVRC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_EVRCB;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_EVRCNW;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_EVRCWB;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_E_AC3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_E_AC3_JOC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_FLAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_HE_AAC_V1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_HE_AAC_V2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IEC60958;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IEC61937;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_LC3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_LDAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_LHDC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_LHDC_LL;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MAT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MAT_1_0;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MAT_2_0;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MAT_2_1;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MP2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MP3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MPEGH_BL_L3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MPEGH_BL_L4;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MPEGH_LC_L3;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_MPEGH_LC_L4;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_OPUS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_16_BIT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_24_BIT_PACKED;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_32_BIT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_8_24_BIT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_8_BIT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_PCM_FLOAT;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_QCELP;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_SBC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_VORBIS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_WMA;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_WMA_PRO;
+  }
+
+  public enum AudioGainMode {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioGainMode AUDIO_GAIN_MODE_CHANNELS;
+    enum_constant public static final android.audio.policy.configuration.AudioGainMode AUDIO_GAIN_MODE_JOINT;
+    enum_constant public static final android.audio.policy.configuration.AudioGainMode AUDIO_GAIN_MODE_RAMP;
+  }
+
+  public enum AudioInOutFlag {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_FAST;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HOTWORD_TAP;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HW_LOOKBACK;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_RAW;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_ULTRASOUND;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_BIT_PERFECT;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_SPATIALIZER;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_ULTRASOUND;
+    enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX;
+  }
+
+  public class AudioPolicyConfiguration {
+    ctor public AudioPolicyConfiguration();
+    method @Nullable public android.audio.policy.configuration.GlobalConfiguration getGlobalConfiguration();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Modules> getModules();
+    method @Nullable public android.audio.policy.configuration.SurroundSound getSurroundSound();
+    method @Nullable public android.audio.policy.configuration.Version getVersion();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Volumes> getVolumes();
+    method public void setGlobalConfiguration(@Nullable android.audio.policy.configuration.GlobalConfiguration);
+    method public void setSurroundSound(@Nullable android.audio.policy.configuration.SurroundSound);
+    method public void setVersion(@Nullable android.audio.policy.configuration.Version);
+  }
+
+  public enum AudioSource {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_CAMCORDER;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_DEFAULT;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_ECHO_REFERENCE;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_FM_TUNER;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_HOTWORD;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_MIC;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_ULTRASOUND;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_UNPROCESSED;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_CALL;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_DOWNLINK;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_PERFORMANCE;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_RECOGNITION;
+    enum_constant public static final android.audio.policy.configuration.AudioSource AUDIO_SOURCE_VOICE_UPLINK;
+  }
+
+  public enum AudioStreamType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_ALARM;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_BLUETOOTH_SCO;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_CALL_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_DTMF;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_MUSIC;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_NOTIFICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_PATCH;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_REROUTING;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_RING;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_SYSTEM;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_TTS;
+    enum_constant public static final android.audio.policy.configuration.AudioStreamType AUDIO_STREAM_VOICE_CALL;
+  }
+
+  public enum AudioUsage {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ALARM;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ANNOUNCEMENT;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_CALL_ASSISTANT;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_EMERGENCY;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_GAME;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_MEDIA;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_NOTIFICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_NOTIFICATION_EVENT;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_SAFETY;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_UNKNOWN;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VEHICLE_STATUS;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VIRTUAL_SOURCE;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.configuration.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+  }
+
+  public enum DeviceCategory {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_EARPIECE;
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_EXT_MEDIA;
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_HEADSET;
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_HEARING_AID;
+    enum_constant public static final android.audio.policy.configuration.DeviceCategory DEVICE_CATEGORY_SPEAKER;
+  }
+
+  public class DevicePorts {
+    ctor public DevicePorts();
+    method @Nullable public java.util.List<android.audio.policy.configuration.DevicePorts.DevicePort> getDevicePort();
+  }
+
+  public static class DevicePorts.DevicePort {
+    ctor public DevicePorts.DevicePort();
+    method @Nullable public String getAddress();
+    method @Nullable public java.util.List<java.lang.String> getEncodedFormats();
+    method @Nullable public android.audio.policy.configuration.Gains getGains();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Profile> getProfile();
+    method @Nullable public android.audio.policy.configuration.Role getRole();
+    method @Nullable public String getTagName();
+    method @Nullable public String getType();
+    method @Nullable public boolean get_default();
+    method public void setAddress(@Nullable String);
+    method public void setEncodedFormats(@Nullable java.util.List<java.lang.String>);
+    method public void setGains(@Nullable android.audio.policy.configuration.Gains);
+    method public void setRole(@Nullable android.audio.policy.configuration.Role);
+    method public void setTagName(@Nullable String);
+    method public void setType(@Nullable String);
+    method public void set_default(@Nullable boolean);
+  }
+
+  public enum EngineSuffix {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.EngineSuffix _default;
+    enum_constant public static final android.audio.policy.configuration.EngineSuffix configurable;
+  }
+
+  public class Gains {
+    ctor public Gains();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Gains.Gain> getGain();
+  }
+
+  public static class Gains.Gain {
+    ctor public Gains.Gain();
+    method @Nullable public android.audio.policy.configuration.AudioChannelMask getChannel_mask();
+    method @Nullable public int getDefaultValueMB();
+    method @Nullable public int getMaxRampMs();
+    method @Nullable public int getMaxValueMB();
+    method @Nullable public int getMinRampMs();
+    method @Nullable public int getMinValueMB();
+    method @Nullable public java.util.List<android.audio.policy.configuration.AudioGainMode> getMode();
+    method @Nullable public String getName();
+    method @Nullable public int getStepValueMB();
+    method @Nullable public boolean getUseForVolume();
+    method public void setChannel_mask(@Nullable android.audio.policy.configuration.AudioChannelMask);
+    method public void setDefaultValueMB(@Nullable int);
+    method public void setMaxRampMs(@Nullable int);
+    method public void setMaxValueMB(@Nullable int);
+    method public void setMinRampMs(@Nullable int);
+    method public void setMinValueMB(@Nullable int);
+    method public void setMode(@Nullable java.util.List<android.audio.policy.configuration.AudioGainMode>);
+    method public void setName(@Nullable String);
+    method public void setStepValueMB(@Nullable int);
+    method public void setUseForVolume(@Nullable boolean);
+  }
+
+  public class GlobalConfiguration {
+    ctor public GlobalConfiguration();
+    method @Nullable public boolean getCall_screen_mode_supported();
+    method @Nullable public android.audio.policy.configuration.EngineSuffix getEngine_library();
+    method @Nullable public boolean getSpeaker_drc_enabled();
+    method public void setCall_screen_mode_supported(@Nullable boolean);
+    method public void setEngine_library(@Nullable android.audio.policy.configuration.EngineSuffix);
+    method public void setSpeaker_drc_enabled(@Nullable boolean);
+  }
+
+  public enum HalVersion {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.HalVersion _2_0;
+    enum_constant public static final android.audio.policy.configuration.HalVersion _3_0;
+  }
+
+  public class MixPorts {
+    ctor public MixPorts();
+    method @Nullable public java.util.List<android.audio.policy.configuration.MixPorts.MixPort> getMixPort();
+  }
+
+  public static class MixPorts.MixPort {
+    ctor public MixPorts.MixPort();
+    method @Nullable public java.util.List<android.audio.policy.configuration.AudioInOutFlag> getFlags();
+    method @Nullable public android.audio.policy.configuration.Gains getGains();
+    method @Nullable public long getMaxActiveCount();
+    method @Nullable public long getMaxOpenCount();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<android.audio.policy.configuration.AudioUsage> getPreferredUsage();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Profile> getProfile();
+    method @Nullable public long getRecommendedMuteDurationMs();
+    method @Nullable public android.audio.policy.configuration.Role getRole();
+    method public void setFlags(@Nullable java.util.List<android.audio.policy.configuration.AudioInOutFlag>);
+    method public void setGains(@Nullable android.audio.policy.configuration.Gains);
+    method public void setMaxActiveCount(@Nullable long);
+    method public void setMaxOpenCount(@Nullable long);
+    method public void setName(@Nullable String);
+    method public void setPreferredUsage(@Nullable java.util.List<android.audio.policy.configuration.AudioUsage>);
+    method public void setRecommendedMuteDurationMs(@Nullable long);
+    method public void setRole(@Nullable android.audio.policy.configuration.Role);
+  }
+
+  public enum MixType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.MixType mix;
+    enum_constant public static final android.audio.policy.configuration.MixType mux;
+  }
+
+  public class Modules {
+    ctor public Modules();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Modules.Module> getModule();
+  }
+
+  public static class Modules.Module {
+    ctor public Modules.Module();
+    method @Nullable public android.audio.policy.configuration.AttachedDevices getAttachedDevices();
+    method @Nullable public String getDefaultOutputDevice();
+    method @Nullable public android.audio.policy.configuration.DevicePorts getDevicePorts();
+    method @Nullable public android.audio.policy.configuration.HalVersion getHalVersion();
+    method @Nullable public android.audio.policy.configuration.MixPorts getMixPorts();
+    method @Nullable public String getName();
+    method @Nullable public android.audio.policy.configuration.Routes getRoutes();
+    method public void setAttachedDevices(@Nullable android.audio.policy.configuration.AttachedDevices);
+    method public void setDefaultOutputDevice(@Nullable String);
+    method public void setDevicePorts(@Nullable android.audio.policy.configuration.DevicePorts);
+    method public void setHalVersion(@Nullable android.audio.policy.configuration.HalVersion);
+    method public void setMixPorts(@Nullable android.audio.policy.configuration.MixPorts);
+    method public void setName(@Nullable String);
+    method public void setRoutes(@Nullable android.audio.policy.configuration.Routes);
+  }
+
+  public class Profile {
+    ctor public Profile();
+    method @Nullable public java.util.List<android.audio.policy.configuration.AudioChannelMask> getChannelMasks();
+    method @Nullable public android.audio.policy.configuration.AudioEncapsulationType getEncapsulationType();
+    method @Nullable public String getFormat();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.math.BigInteger> getSamplingRates();
+    method public void setChannelMasks(@Nullable java.util.List<android.audio.policy.configuration.AudioChannelMask>);
+    method public void setEncapsulationType(@Nullable android.audio.policy.configuration.AudioEncapsulationType);
+    method public void setFormat(@Nullable String);
+    method public void setName(@Nullable String);
+    method public void setSamplingRates(@Nullable java.util.List<java.math.BigInteger>);
+  }
+
+  public class Reference {
+    ctor public Reference();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method public void setName(@Nullable String);
+  }
+
+  public enum Role {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.Role sink;
+    enum_constant public static final android.audio.policy.configuration.Role source;
+  }
+
+  public class Routes {
+    ctor public Routes();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Routes.Route> getRoute();
+  }
+
+  public static class Routes.Route {
+    ctor public Routes.Route();
+    method @Nullable public String getSink();
+    method @Nullable public String getSources();
+    method @Nullable public android.audio.policy.configuration.MixType getType();
+    method public void setSink(@Nullable String);
+    method public void setSources(@Nullable String);
+    method public void setType(@Nullable android.audio.policy.configuration.MixType);
+  }
+
+  public class SurroundFormats {
+    ctor public SurroundFormats();
+    method @Nullable public java.util.List<android.audio.policy.configuration.SurroundFormats.Format> getFormat();
+  }
+
+  public static class SurroundFormats.Format {
+    ctor public SurroundFormats.Format();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.lang.String> getSubformats();
+    method public void setName(@Nullable String);
+    method public void setSubformats(@Nullable java.util.List<java.lang.String>);
+  }
+
+  public class SurroundSound {
+    ctor public SurroundSound();
+    method @Nullable public android.audio.policy.configuration.SurroundFormats getFormats();
+    method public void setFormats(@Nullable android.audio.policy.configuration.SurroundFormats);
+  }
+
+  public enum Version {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.configuration.Version _7_0;
+    enum_constant public static final android.audio.policy.configuration.Version _7_1;
+  }
+
+  public class Volume {
+    ctor public Volume();
+    method @Nullable public android.audio.policy.configuration.DeviceCategory getDeviceCategory();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method @Nullable public String getRef();
+    method @Nullable public android.audio.policy.configuration.AudioStreamType getStream();
+    method public void setDeviceCategory(@Nullable android.audio.policy.configuration.DeviceCategory);
+    method public void setRef(@Nullable String);
+    method public void setStream(@Nullable android.audio.policy.configuration.AudioStreamType);
+  }
+
+  public class Volumes {
+    ctor public Volumes();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Reference> getReference();
+    method @Nullable public java.util.List<android.audio.policy.configuration.Volume> getVolume();
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method @Nullable public static android.audio.policy.configuration.AudioPolicyConfiguration read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/audio/aidl/default/config/audioPolicy/api/last_current.txt b/audio/aidl/default/config/audioPolicy/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/api/last_current.txt
diff --git a/audio/aidl/default/config/audioPolicy/api/last_removed.txt b/audio/aidl/default/config/audioPolicy/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/api/last_removed.txt
diff --git a/audio/aidl/default/config/audioPolicy/api/removed.txt b/audio/aidl/default/config/audioPolicy/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
new file mode 100644
index 0000000..d57790a
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
@@ -0,0 +1,833 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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.
+-->
+<xs:schema version="2.0"
+           elementFormDefault="qualified"
+           attributeFormDefault="unqualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <!-- List the config versions supported by audio policy. -->
+    <xs:simpleType name="version">
+        <xs:restriction base="xs:decimal">
+            <xs:enumeration value="7.0"/>
+            <xs:enumeration value="7.1"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="halVersion">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Version of the interface the hal implements. Note that this
+                relates to legacy HAL API versions since HIDL APIs are versioned
+                using other mechanisms.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:decimal">
+            <!-- List of HAL versions supported by the framework. -->
+            <xs:enumeration value="2.0"/>
+            <xs:enumeration value="3.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:element name="audioPolicyConfiguration">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="globalConfiguration" type="globalConfiguration"/>
+                <xs:element name="modules" type="modules" maxOccurs="unbounded"/>
+                <xs:element name="volumes" type="volumes" maxOccurs="unbounded"/>
+                <xs:element name="surroundSound" type="surroundSound" minOccurs="0" />
+            </xs:sequence>
+            <xs:attribute name="version" type="version"/>
+        </xs:complexType>
+        <xs:key name="moduleNameKey">
+            <xs:selector xpath="modules/module"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:unique name="volumeTargetUniqueness">
+            <xs:selector xpath="volumes/volume"/>
+            <xs:field xpath="@stream"/>
+            <xs:field xpath="@deviceCategory"/>
+        </xs:unique>
+        <xs:key name="volumeCurveNameKey">
+            <xs:selector xpath="volumes/reference"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:keyref name="volumeCurveRef" refer="volumeCurveNameKey">
+            <xs:selector xpath="volumes/volume"/>
+            <xs:field xpath="@ref"/>
+        </xs:keyref>
+    </xs:element>
+    <xs:complexType name="globalConfiguration">
+        <xs:attribute name="speaker_drc_enabled" type="xs:boolean" use="required"/>
+        <xs:attribute name="call_screen_mode_supported" type="xs:boolean" use="optional"/>
+        <xs:attribute name="engine_library" type="engineSuffix" use="optional"/>
+    </xs:complexType>
+    <xs:complexType name="modules">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                There should be one section per audio HW module present on the platform.
+                Each <module/> contains two mandatory tags: “halVersion” and “name”.
+                The module "name" is the same as in previous .conf file.
+                Each module must 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.
+                   A <route/> is defined by a set of 3 attributes:
+                        -"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 this route
+                 - <attachedDevices/>: permanently attached devices.
+                   The attachedDevices section is a list of devices names.
+                   Their names correspond to device names defined in "devicePorts" section.
+                 - <defaultOutputDevice/> is the device to be used when no policy rule applies
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="module" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="attachedDevices" type="attachedDevices" minOccurs="0">
+                            <xs:unique name="attachedDevicesUniqueness">
+                                <xs:selector xpath="item"/>
+                                <xs:field xpath="."/>
+                            </xs:unique>
+                        </xs:element>
+                        <xs:element name="defaultOutputDevice" type="xs:token" minOccurs="0"/>
+                        <xs:element name="mixPorts" type="mixPorts" minOccurs="0"/>
+                        <xs:element name="devicePorts" type="devicePorts" minOccurs="0"/>
+                        <xs:element name="routes" type="routes" minOccurs="0"/>
+                    </xs:sequence>
+                    <xs:attribute name="name" type="xs:string" use="required"/>
+                    <xs:attribute name="halVersion" type="halVersion" use="required"/>
+                </xs:complexType>
+                <xs:unique name="mixPortNameUniqueness">
+                    <xs:selector xpath="mixPorts/mixPort"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
+                <xs:key name="devicePortNameKey">
+                    <xs:selector xpath="devicePorts/devicePort"/>
+                    <xs:field xpath="@tagName"/>
+                </xs:key>
+                <xs:unique name="devicePortUniqueness">
+                    <xs:selector xpath="devicePorts/devicePort"/>
+                    <xs:field xpath="@type"/>
+                    <xs:field xpath="@address"/>
+                </xs:unique>
+                <xs:keyref name="defaultOutputDeviceRef" refer="devicePortNameKey">
+                    <xs:selector xpath="defaultOutputDevice"/>
+                    <xs:field xpath="."/>
+                </xs:keyref>
+                <xs:keyref name="attachedDeviceRef" refer="devicePortNameKey">
+                    <xs:selector xpath="attachedDevices/item"/>
+                    <xs:field xpath="."/>
+                </xs:keyref>
+                <!-- The following 3 constraints try to make sure each sink port
+                     is reference in one an only one route. -->
+                <xs:key name="routeSinkKey">
+                    <!-- predicate [@type='sink'] does not work in xsd 1.0 -->
+                    <xs:selector xpath="devicePorts/devicePort|mixPorts/mixPort"/>
+                    <xs:field xpath="@tagName|@name"/>
+                </xs:key>
+                <xs:keyref name="routeSinkRef" refer="routeSinkKey">
+                    <xs:selector xpath="routes/route"/>
+                    <xs:field xpath="@sink"/>
+                </xs:keyref>
+                <xs:unique name="routeUniqueness">
+                    <xs:selector xpath="routes/route"/>
+                    <xs:field xpath="@sink"/>
+                </xs:unique>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="attachedDevices">
+        <xs:sequence>
+            <xs:element name="item" type="xs:token" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="audioInOutFlag">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+              The flags indicate suggested stream attributes supported by the profile.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_PRIMARY" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_FAST" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_DEEP_BUFFER" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_NON_BLOCKING" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_HW_AV_SYNC" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_TTS" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_RAW" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_SYNC" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_DIRECT_PCM" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_MMAP_NOIRQ" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_VOIP_RX" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_INCALL_MUSIC" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_SPATIALIZER" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_ULTRASOUND" />
+            <xs:enumeration value="AUDIO_OUTPUT_FLAG_BIT_PERFECT" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_FAST" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_HW_HOTWORD" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_RAW" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_SYNC" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_MMAP_NOIRQ" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_VOIP_TX" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_HW_AV_SYNC" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_DIRECT" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_ULTRASOUND" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_HOTWORD_TAP" />
+            <xs:enumeration value="AUDIO_INPUT_FLAG_HW_LOOKBACK" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioInOutFlags">
+        <xs:list itemType="audioInOutFlag" />
+    </xs:simpleType>
+    <xs:simpleType name="role">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="sink"/>
+            <xs:enumeration value="source"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="mixPorts">
+        <xs:sequence>
+            <xs:element name="mixPort" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
+                    </xs:sequence>
+                    <xs:attribute name="name" type="xs:token" use="required"/>
+                    <xs:attribute name="role" type="role" use="required"/>
+                    <xs:attribute name="flags" type="audioInOutFlags"/>
+                    <xs:attribute name="maxOpenCount" type="xs:unsignedInt"/>
+                    <xs:attribute name="maxActiveCount" type="xs:unsignedInt"/>
+                    <xs:attribute name="preferredUsage" type="audioUsageList">
+                        <xs:annotation>
+                            <xs:documentation xml:lang="en">
+                                When choosing the mixPort of an audio track, the audioPolicy
+                                first considers the mixPorts with a preferredUsage including
+                                the track AudioUsage preferred .
+                                If non support the track format, the other mixPorts are considered.
+                                Eg: a <mixPort preferredUsage="AUDIO_USAGE_MEDIA" /> will receive
+                                    the audio of all apps playing with a MEDIA usage.
+                                    It may receive audio from ALARM if there are no audio compatible
+                                    <mixPort preferredUsage="AUDIO_USAGE_ALARM" />.
+                             </xs:documentation>
+                        </xs:annotation>
+                    </xs:attribute>
+                    <xs:attribute name="recommendedMuteDurationMs" type="xs:unsignedInt"/>
+                </xs:complexType>
+                <xs:unique name="mixPortProfileUniqueness">
+                    <xs:selector xpath="profile"/>
+                    <xs:field xpath="format"/>
+                    <xs:field xpath="samplingRate"/>
+                    <xs:field xpath="channelMasks"/>
+                </xs:unique>
+                <xs:unique name="mixPortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="audioDevice">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_DEVICE_NONE"/>
+
+            <xs:enumeration value="AUDIO_DEVICE_OUT_EARPIECE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADPHONE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_EARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_ACCESSORY"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_DEVICE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_TELEPHONY_TX"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_ARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPDIF"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_FM"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER_SAFE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_IP"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BUS"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_PROXY"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HEARING_AID"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_ECHO_CANCELLER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_BROADCAST"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_DEFAULT"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_STUB"/>
+
+            <xs:enumeration value="AUDIO_DEVICE_IN_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_AMBIENT"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BUILTIN_MIC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_WIRED_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_AUX_DIGITAL"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_TELEPHONY_RX"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BACK_MIC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_ACCESSORY"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_DEVICE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_FM_TUNER"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_TV_TUNER"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_SPDIF"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_A2DP"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_LOOPBACK"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_IP"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BUS"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_PROXY"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_BLE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_ARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_EARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_ECHO_REFERENCE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLE_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_DEFAULT"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_STUB"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="vendorExtension">
+        <!-- Vendor extension names must be prefixed by "VX_" to distinguish them from
+             AOSP values. Vendors must namespace their names to avoid conflicts. The
+             namespace part must only use capital latin characters and decimal digits and
+             consist of at least 3 characters. The part of the extension name after the
+             namespace may in addition include underscores. Example for a hypothetical
+             Google virtual reality device:
+
+                 <devicePort tagName="VR" type="VX_GOOGLE_VR" role="sink" />
+        -->
+        <xs:restriction base="xs:string">
+            <xs:pattern value="VX_[A-Z0-9]{3,}_[_A-Z0-9]+"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="extendableAudioDevice">
+        <xs:union memberTypes="audioDevice vendorExtension"/>
+    </xs:simpleType>
+    <xs:simpleType name="audioFormat">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_FORMAT_DEFAULT" />
+            <xs:enumeration value="AUDIO_FORMAT_PCM_16_BIT" />
+            <xs:enumeration value="AUDIO_FORMAT_PCM_8_BIT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_32_BIT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_8_24_BIT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_FLOAT"/>
+            <xs:enumeration value="AUDIO_FORMAT_PCM_24_BIT_PACKED"/>
+            <xs:enumeration value="AUDIO_FORMAT_MP3"/>
+            <xs:enumeration value="AUDIO_FORMAT_AMR_NB"/>
+            <xs:enumeration value="AUDIO_FORMAT_AMR_WB"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_MAIN"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_SSR"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LTP"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_SCALABLE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ERLC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_HE_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ELD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_XHE"/>
+            <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_HE_AAC_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_VORBIS"/>
+            <xs:enumeration value="AUDIO_FORMAT_OPUS"/>
+            <xs:enumeration value="AUDIO_FORMAT_AC3"/>
+            <xs:enumeration value="AUDIO_FORMAT_E_AC3"/>
+            <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS_HD"/>
+            <xs:enumeration value="AUDIO_FORMAT_IEC61937"/>
+            <xs:enumeration value="AUDIO_FORMAT_DOLBY_TRUEHD"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRC"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRCB"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRCWB"/>
+            <xs:enumeration value="AUDIO_FORMAT_EVRCNW"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADIF"/>
+            <xs:enumeration value="AUDIO_FORMAT_WMA"/>
+            <xs:enumeration value="AUDIO_FORMAT_WMA_PRO"/>
+            <xs:enumeration value="AUDIO_FORMAT_AMR_WB_PLUS"/>
+            <xs:enumeration value="AUDIO_FORMAT_MP2"/>
+            <xs:enumeration value="AUDIO_FORMAT_QCELP"/>
+            <xs:enumeration value="AUDIO_FORMAT_DSD"/>
+            <xs:enumeration value="AUDIO_FORMAT_FLAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_ALAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_APE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_MAIN"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SSR"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LTP"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_SCALABLE"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ERLC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_LD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_HE_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_ELD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_ADTS_XHE"/>
+            <xs:enumeration value="AUDIO_FORMAT_SBC"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
+            <xs:enumeration value="AUDIO_FORMAT_AC4"/>
+            <xs:enumeration value="AUDIO_FORMAT_LDAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/>
+            <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LATM"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LATM_LC"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LATM_HE_V1"/>
+            <xs:enumeration value="AUDIO_FORMAT_AAC_LATM_HE_V2"/>
+            <xs:enumeration value="AUDIO_FORMAT_CELT"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX_ADAPTIVE"/>
+            <xs:enumeration value="AUDIO_FORMAT_LHDC"/>
+            <xs:enumeration value="AUDIO_FORMAT_LHDC_LL"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX_TWSP"/>
+            <xs:enumeration value="AUDIO_FORMAT_LC3"/>
+            <xs:enumeration value="AUDIO_FORMAT_MPEGH_BL_L3"/>
+            <xs:enumeration value="AUDIO_FORMAT_MPEGH_BL_L4"/>
+            <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L3"/>
+            <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L4"/>
+            <xs:enumeration value="AUDIO_FORMAT_IEC60958"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS_UHD"/>
+            <xs:enumeration value="AUDIO_FORMAT_DRA"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX_ADAPTIVE_QLEA"/>
+            <xs:enumeration value="AUDIO_FORMAT_APTX_ADAPTIVE_R4"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS_HD_MA"/>
+            <xs:enumeration value="AUDIO_FORMAT_DTS_UHD_P2"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="extendableAudioFormat">
+        <xs:union memberTypes="audioFormat vendorExtension"/>
+    </xs:simpleType>
+    <xs:simpleType name="audioUsage">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Audio usage specifies the intended use case for the sound being played.
+                Please consult frameworks/base/media/java/android/media/AudioAttributes.java
+                for the description of each value.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_USAGE_UNKNOWN" />
+            <xs:enumeration value="AUDIO_USAGE_MEDIA" />
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+            <xs:enumeration value="AUDIO_USAGE_ALARM" />
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION" />
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+            <xs:enumeration value="AUDIO_USAGE_GAME" />
+            <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE" />
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANT" />
+            <xs:enumeration value="AUDIO_USAGE_CALL_ASSISTANT" />
+            <xs:enumeration value="AUDIO_USAGE_EMERGENCY" />
+            <xs:enumeration value="AUDIO_USAGE_SAFETY" />
+            <xs:enumeration value="AUDIO_USAGE_VEHICLE_STATUS" />
+            <xs:enumeration value="AUDIO_USAGE_ANNOUNCEMENT" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioUsageList">
+        <xs:list itemType="audioUsage"/>
+    </xs:simpleType>
+    <xs:simpleType name="audioContentType">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Audio content type expresses the general category of the content.
+                Please consult frameworks/base/media/java/android/media/AudioAttributes.java
+                for the description of each value.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_UNKNOWN"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_ULTRASOUND"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="samplingRates">
+        <xs:list itemType="xs:nonNegativeInteger" />
+    </xs:simpleType>
+    <xs:simpleType name="audioChannelMask">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Audio channel mask specifies presence of particular channels.
+                There are two representations:
+                - representation position (traditional discrete channel specification,
+                  e.g. "left", "right");
+                - indexed (this is similar to "tracks" in audio mixing, channels
+                  are represented using numbers).
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_CHANNEL_NONE"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_TRI"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_TRI_BACK"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT0POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_2POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT0POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_3POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_QUAD"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_QUAD_BACK"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_QUAD_SIDE"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_SURROUND"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_PENTA"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1_BACK"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1_SIDE"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_5POINT1POINT4"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_6POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1POINT4"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_9POINT1POINT4"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_9POINT1POINT6"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_13POINT_360RA"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_22POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO_HAPTIC_A"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_HAPTIC_AB"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_STEREO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_FRONT_BACK"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_6"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_2POINT0POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_2POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_3POINT0POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_3POINT1POINT2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_5POINT1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_IN_VOICE_CALL_MONO"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_1"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_2"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_3"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_4"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_5"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_6"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_7"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_8"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_9"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_10"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_11"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_12"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_13"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_14"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_15"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_16"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_17"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_18"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_19"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_20"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_21"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_22"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_23"/>
+            <xs:enumeration value="AUDIO_CHANNEL_INDEX_MASK_24"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="channelMasks">
+        <xs:list itemType="audioChannelMask" />
+    </xs:simpleType>
+    <xs:simpleType name="audioEncapsulationType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_NONE"/>
+            <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_IEC61937"/>
+            <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_PCM"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="profile">
+        <xs:attribute name="name" type="xs:token" use="optional"/>
+        <xs:attribute name="format" type="extendableAudioFormat" use="optional"/>
+        <xs:attribute name="samplingRates" type="samplingRates" use="optional"/>
+        <xs:attribute name="channelMasks" type="channelMasks" use="optional"/>
+        <xs:attribute name="encapsulationType" type="audioEncapsulationType" use="optional"/>
+    </xs:complexType>
+    <xs:simpleType name="audioGainMode">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_GAIN_MODE_JOINT"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_CHANNELS"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_RAMP"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioGainModeMaskUnrestricted">
+        <xs:list itemType="audioGainMode" />
+    </xs:simpleType>
+    <xs:simpleType name='audioGainModeMask'>
+        <xs:restriction base='audioGainModeMaskUnrestricted'>
+            <xs:minLength value='1' />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="gains">
+        <xs:sequence>
+            <xs:element name="gain" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:token" use="required"/>
+                    <xs:attribute name="mode" type="audioGainModeMask" use="required"/>
+                    <xs:attribute name="channel_mask" type="audioChannelMask" use="optional"/>
+                    <xs:attribute name="minValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="defaultValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="stepValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="minRampMs" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxRampMs" type="xs:int" use="optional"/>
+                    <xs:attribute name="useForVolume" type="xs:boolean" use="optional"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="devicePorts">
+        <xs:sequence>
+            <xs:element name="devicePort" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
+                    </xs:sequence>
+                    <xs:attribute name="tagName" type="xs:token" use="required"/>
+                    <xs:attribute name="type" type="extendableAudioDevice" use="required"/>
+                    <xs:attribute name="role" type="role" use="required"/>
+                    <xs:attribute name="address" type="xs:string" use="optional" default=""/>
+                    <!-- Note that XSD 1.0 can not check that a type only has one default. -->
+                    <xs:attribute name="default" type="xs:boolean" use="optional">
+                        <xs:annotation>
+                            <xs:documentation xml:lang="en">
+                                The default device will be used if multiple have the same type
+                                and no explicit route request exists for a specific device of
+                                that type.
+                            </xs:documentation>
+                        </xs:annotation>
+                    </xs:attribute>
+                    <xs:attribute name="encodedFormats" type="audioFormatsList" use="optional"
+                                  default="" />
+                </xs:complexType>
+                <xs:unique name="devicePortProfileUniqueness">
+                    <xs:selector xpath="profile"/>
+                    <xs:field xpath="format"/>
+                    <xs:field xpath="samplingRate"/>
+                    <xs:field xpath="channelMasks"/>
+                </xs:unique>
+                <xs:unique name="devicePortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="mixType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="mix"/>
+            <xs:enumeration value="mux"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="routes">
+        <xs:sequence>
+            <xs:element name="route" minOccurs="0" maxOccurs="unbounded">
+                <xs:annotation>
+                    <xs:documentation xml:lang="en">
+                        List all available sources for a given sink.
+                    </xs:documentation>
+                </xs:annotation>
+                <xs:complexType>
+                    <xs:attribute name="type" type="mixType" use="required"/>
+                    <xs:attribute name="sink" type="xs:string" use="required"/>
+                    <xs:attribute name="sources" type="xs:string" use="required"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="volumes">
+        <xs:sequence>
+            <xs:element name="volume" type="volume" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="reference" type="reference" minOccurs="0" maxOccurs="unbounded">
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <!-- TODO: Always require a ref for better xsd validations.
+               Currently a volume could have no points nor ref
+               as it can not be forbidden by xsd 1.0.-->
+    <xs:simpleType name="volumePoint">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Comma separated pair of number.
+                The fist one is the framework level (between 0 and 100).
+                The second one is the volume to send to the HAL.
+                The framework will interpolate volumes not specified.
+                Their MUST be at least 2 points specified.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="([0-9]{1,2}|100),-?[0-9]+"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioStreamType">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Audio stream type describing the intended use case of a stream.
+                Please consult frameworks/base/media/java/android/media/AudioSystem.java
+                for the description of each value.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_STREAM_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_STREAM_SYSTEM"/>
+            <xs:enumeration value="AUDIO_STREAM_RING"/>
+            <xs:enumeration value="AUDIO_STREAM_MUSIC"/>
+            <xs:enumeration value="AUDIO_STREAM_ALARM"/>
+            <xs:enumeration value="AUDIO_STREAM_NOTIFICATION"/>
+            <xs:enumeration value="AUDIO_STREAM_BLUETOOTH_SCO"/>
+            <xs:enumeration value="AUDIO_STREAM_ENFORCED_AUDIBLE"/>
+            <xs:enumeration value="AUDIO_STREAM_DTMF"/>
+            <xs:enumeration value="AUDIO_STREAM_TTS"/>
+            <xs:enumeration value="AUDIO_STREAM_ACCESSIBILITY"/>
+            <xs:enumeration value="AUDIO_STREAM_ASSISTANT"/>
+            <xs:enumeration value="AUDIO_STREAM_REROUTING"/>
+            <xs:enumeration value="AUDIO_STREAM_PATCH"/>
+            <xs:enumeration value="AUDIO_STREAM_CALL_ASSISTANT"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="audioSource">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                An audio source defines the intended use case for the sound being recorded.
+                Please consult frameworks/base/media/java/android/media/MediaRecorder.java
+                for the description of each value.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_SOURCE_DEFAULT"/>
+            <xs:enumeration value="AUDIO_SOURCE_MIC"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_UPLINK"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_DOWNLINK"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_SOURCE_CAMCORDER"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_RECOGNITION"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_SOURCE_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_SOURCE_UNPROCESSED"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_PERFORMANCE"/>
+            <xs:enumeration value="AUDIO_SOURCE_ECHO_REFERENCE"/>
+            <xs:enumeration value="AUDIO_SOURCE_FM_TUNER"/>
+            <xs:enumeration value="AUDIO_SOURCE_HOTWORD"/>
+            <xs:enumeration value="AUDIO_SOURCE_ULTRASOUND"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <!-- Enum values of device_category from Volume.h. -->
+    <xs:simpleType name="deviceCategory">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="DEVICE_CATEGORY_HEADSET"/>
+            <xs:enumeration value="DEVICE_CATEGORY_SPEAKER"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EARPIECE"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EXT_MEDIA"/>
+            <xs:enumeration value="DEVICE_CATEGORY_HEARING_AID"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="volume">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Volume section defines a volume curve for a given use case and device category.
+                It contains a list of points of this curve expressing the attenuation in Millibels
+                for a given volume index from 0 to 100.
+                <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </volume>
+
+                It may also reference a reference/@name to avoid duplicating curves.
+                <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"
+                        ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+                <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </reference>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="stream" type="audioStreamType"/>
+        <xs:attribute name="deviceCategory" type="deviceCategory"/>
+        <xs:attribute name="ref" type="xs:token" use="optional"/>
+    </xs:complexType>
+    <xs:complexType name="reference">
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="2" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:token" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="surroundSound">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Surround Sound section provides configuration related to handling of
+                multi-channel formats.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="formats" type="surroundFormats"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="audioFormatsList">
+        <xs:list itemType="extendableAudioFormat" />
+    </xs:simpleType>
+    <xs:complexType name="surroundFormats">
+        <xs:sequence>
+            <xs:element name="format" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="extendableAudioFormat" use="required"/>
+                    <xs:attribute name="subformats" type="audioFormatsList" />
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="engineSuffix">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="default"/>
+            <xs:enumeration value="configurable"/>
+        </xs:restriction>
+    </xs:simpleType>
+</xs:schema>
diff --git a/audio/aidl/default/config/audioPolicy/engine/Android.bp b/audio/aidl/default/config/audioPolicy/engine/Android.bp
new file mode 100644
index 0000000..b2a7310
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/Android.bp
@@ -0,0 +1,15 @@
+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"],
+}
+
+xsd_config {
+    name: "audio_policy_engine_configuration_aidl_default",
+    srcs: ["audio_policy_engine_configuration.xsd"],
+    package_name: "android.audio.policy.engine.configuration",
+    nullability: true,
+}
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/current.txt b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
new file mode 100644
index 0000000..063b05d
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
@@ -0,0 +1,306 @@
+// Signature format: 2.0
+package android.audio.policy.engine.configuration {
+
+  public class AttributesGroup {
+    ctor public AttributesGroup();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesType> getAttributes_optional();
+    method @Nullable public android.audio.policy.engine.configuration.BundleType getBundle_optional();
+    method @Nullable public android.audio.policy.engine.configuration.ContentTypeType getContentType_optional();
+    method @Nullable public android.audio.policy.engine.configuration.FlagsType getFlags_optional();
+    method @Nullable public android.audio.policy.engine.configuration.SourceType getSource_optional();
+    method @Nullable public android.audio.policy.engine.configuration.Stream getStreamType();
+    method @Nullable public android.audio.policy.engine.configuration.UsageType getUsage_optional();
+    method @Nullable public String getVolumeGroup();
+    method public void setBundle_optional(@Nullable android.audio.policy.engine.configuration.BundleType);
+    method public void setContentType_optional(@Nullable android.audio.policy.engine.configuration.ContentTypeType);
+    method public void setFlags_optional(@Nullable android.audio.policy.engine.configuration.FlagsType);
+    method public void setSource_optional(@Nullable android.audio.policy.engine.configuration.SourceType);
+    method public void setStreamType(@Nullable android.audio.policy.engine.configuration.Stream);
+    method public void setUsage_optional(@Nullable android.audio.policy.engine.configuration.UsageType);
+    method public void setVolumeGroup(@Nullable String);
+  }
+
+  public class AttributesRef {
+    ctor public AttributesRef();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesRefType> getReference();
+  }
+
+  public class AttributesRefType {
+    ctor public AttributesRefType();
+    method @Nullable public android.audio.policy.engine.configuration.AttributesType getAttributes();
+    method @Nullable public String getName();
+    method public void setAttributes(@Nullable android.audio.policy.engine.configuration.AttributesType);
+    method public void setName(@Nullable String);
+  }
+
+  public class AttributesType {
+    ctor public AttributesType();
+    method @Nullable public String getAttributesRef();
+    method @Nullable public android.audio.policy.engine.configuration.BundleType getBundle();
+    method @Nullable public android.audio.policy.engine.configuration.ContentTypeType getContentType();
+    method @Nullable public android.audio.policy.engine.configuration.FlagsType getFlags();
+    method @Nullable public android.audio.policy.engine.configuration.SourceType getSource();
+    method @Nullable public android.audio.policy.engine.configuration.UsageType getUsage();
+    method public void setAttributesRef(@Nullable String);
+    method public void setBundle(@Nullable android.audio.policy.engine.configuration.BundleType);
+    method public void setContentType(@Nullable android.audio.policy.engine.configuration.ContentTypeType);
+    method public void setFlags(@Nullable android.audio.policy.engine.configuration.FlagsType);
+    method public void setSource(@Nullable android.audio.policy.engine.configuration.SourceType);
+    method public void setUsage(@Nullable android.audio.policy.engine.configuration.UsageType);
+  }
+
+  public class BundleType {
+    ctor public BundleType();
+    method @Nullable public String getKey();
+    method @Nullable public String getValue();
+    method public void setKey(@Nullable String);
+    method public void setValue(@Nullable String);
+  }
+
+  public class Configuration {
+    ctor public Configuration();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesRef> getAttributesRef();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.CriteriaType> getCriteria();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.CriterionTypesType> getCriterion_types();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.ProductStrategies> getProductStrategies();
+    method @Nullable public android.audio.policy.engine.configuration.Version getVersion();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.VolumeGroupsType> getVolumeGroups();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.VolumesType> getVolumes();
+    method public void setVersion(@Nullable android.audio.policy.engine.configuration.Version);
+  }
+
+  public enum ContentType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_MOVIE;
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_MUSIC;
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_SONIFICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_SPEECH;
+    enum_constant public static final android.audio.policy.engine.configuration.ContentType AUDIO_CONTENT_TYPE_UNKNOWN;
+  }
+
+  public class ContentTypeType {
+    ctor public ContentTypeType();
+    method @Nullable public android.audio.policy.engine.configuration.ContentType getValue();
+    method public void setValue(@Nullable android.audio.policy.engine.configuration.ContentType);
+  }
+
+  public class CriteriaType {
+    ctor public CriteriaType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.CriterionType> getCriterion();
+  }
+
+  public class CriterionType {
+    ctor public CriterionType();
+    method @Nullable public String getName();
+    method @Nullable public String getType();
+    method @Nullable public String get_default();
+    method public void setName(@Nullable String);
+    method public void setType(@Nullable String);
+    method public void set_default(@Nullable String);
+  }
+
+  public class CriterionTypeType {
+    ctor public CriterionTypeType();
+    method @Nullable public String getName();
+    method @Nullable public android.audio.policy.engine.configuration.PfwCriterionTypeEnum getType();
+    method @Nullable public android.audio.policy.engine.configuration.ValuesType getValues();
+    method public void setName(@Nullable String);
+    method public void setType(@Nullable android.audio.policy.engine.configuration.PfwCriterionTypeEnum);
+    method public void setValues(@Nullable android.audio.policy.engine.configuration.ValuesType);
+  }
+
+  public class CriterionTypesType {
+    ctor public CriterionTypesType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.CriterionTypeType> getCriterion_type();
+  }
+
+  public enum DeviceCategory {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_EARPIECE;
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_EXT_MEDIA;
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_HEADSET;
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_HEARING_AID;
+    enum_constant public static final android.audio.policy.engine.configuration.DeviceCategory DEVICE_CATEGORY_SPEAKER;
+  }
+
+  public enum FlagType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_AUDIBILITY_ENFORCED;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_BEACON;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_BYPASS_MUTE;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_CAPTURE_PRIVATE;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_DEEP_BUFFER;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_HW_AV_SYNC;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_HW_HOTWORD;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_LOW_LATENCY;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_MUTE_HAPTIC;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_NONE;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_NO_MEDIA_PROJECTION;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_NO_SYSTEM_CAPTURE;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_SCO;
+    enum_constant public static final android.audio.policy.engine.configuration.FlagType AUDIO_FLAG_SECURE;
+  }
+
+  public class FlagsType {
+    ctor public FlagsType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.FlagType> getValue();
+    method public void setValue(@Nullable java.util.List<android.audio.policy.engine.configuration.FlagType>);
+  }
+
+  public enum PfwCriterionTypeEnum {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.PfwCriterionTypeEnum exclusive;
+    enum_constant public static final android.audio.policy.engine.configuration.PfwCriterionTypeEnum inclusive;
+  }
+
+  public class ProductStrategies {
+    ctor public ProductStrategies();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.ProductStrategies.ProductStrategy> getProductStrategy();
+  }
+
+  public static class ProductStrategies.ProductStrategy {
+    ctor public ProductStrategies.ProductStrategy();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.AttributesGroup> getAttributesGroup();
+    method @Nullable public String getName();
+    method public void setName(@Nullable String);
+  }
+
+  public enum SourceEnumType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_CAMCORDER;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_DEFAULT;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_ECHO_REFERENCE;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_FM_TUNER;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_MIC;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_REMOTE_SUBMIX;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_UNPROCESSED;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_CALL;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_DOWNLINK;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_PERFORMANCE;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_RECOGNITION;
+    enum_constant public static final android.audio.policy.engine.configuration.SourceEnumType AUDIO_SOURCE_VOICE_UPLINK;
+  }
+
+  public class SourceType {
+    ctor public SourceType();
+    method @Nullable public android.audio.policy.engine.configuration.SourceEnumType getValue();
+    method public void setValue(@Nullable android.audio.policy.engine.configuration.SourceEnumType);
+  }
+
+  public enum Stream {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_ALARM;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_ASSISTANT;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_BLUETOOTH_SCO;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_DEFAULT;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_DTMF;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_ENFORCED_AUDIBLE;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_MUSIC;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_NOTIFICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_RING;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_SYSTEM;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_TTS;
+    enum_constant public static final android.audio.policy.engine.configuration.Stream AUDIO_STREAM_VOICE_CALL;
+  }
+
+  public enum UsageEnumType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ALARM;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ANNOUNCEMENT;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_ASSISTANT;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_CALL_ASSISTANT;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_EMERGENCY;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_GAME;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_MEDIA;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_EVENT;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_SAFETY;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_UNKNOWN;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_VEHICLE_STATUS;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_VIRTUAL_SOURCE;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+  }
+
+  public class UsageType {
+    ctor public UsageType();
+    method @Nullable public android.audio.policy.engine.configuration.UsageEnumType getValue();
+    method public void setValue(@Nullable android.audio.policy.engine.configuration.UsageEnumType);
+  }
+
+  public class ValueType {
+    ctor public ValueType();
+    method @Nullable public String getAndroid_type();
+    method @Nullable public String getLiteral();
+    method @Nullable public long getNumerical();
+    method public void setAndroid_type(@Nullable String);
+    method public void setLiteral(@Nullable String);
+    method public void setNumerical(@Nullable long);
+  }
+
+  public class ValuesType {
+    ctor public ValuesType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.ValueType> getValue();
+  }
+
+  public enum Version {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.audio.policy.engine.configuration.Version _1_0;
+  }
+
+  public class Volume {
+    ctor public Volume();
+    method @Nullable public android.audio.policy.engine.configuration.DeviceCategory getDeviceCategory();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method @Nullable public String getRef();
+    method public void setDeviceCategory(@Nullable android.audio.policy.engine.configuration.DeviceCategory);
+    method public void setRef(@Nullable String);
+  }
+
+  public class VolumeGroupsType {
+    ctor public VolumeGroupsType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.VolumeGroupsType.VolumeGroup> getVolumeGroup();
+  }
+
+  public static class VolumeGroupsType.VolumeGroup {
+    ctor public VolumeGroupsType.VolumeGroup();
+    method @Nullable public int getIndexMax();
+    method @Nullable public int getIndexMin();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.Volume> getVolume();
+    method public void setIndexMax(@Nullable int);
+    method public void setIndexMin(@Nullable int);
+    method public void setName(@Nullable String);
+  }
+
+  public class VolumeRef {
+    ctor public VolumeRef();
+    method @Nullable public String getName();
+    method @Nullable public java.util.List<java.lang.String> getPoint();
+    method public void setName(@Nullable String);
+  }
+
+  public class VolumesType {
+    ctor public VolumesType();
+    method @Nullable public java.util.List<android.audio.policy.engine.configuration.VolumeRef> getReference();
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method @Nullable public static android.audio.policy.engine.configuration.Configuration read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/last_current.txt b/audio/aidl/default/config/audioPolicy/engine/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/api/last_current.txt
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/last_removed.txt b/audio/aidl/default/config/audioPolicy/engine/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/api/last_removed.txt
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/removed.txt b/audio/aidl/default/config/audioPolicy/engine/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
new file mode 100644
index 0000000..40396bb
--- /dev/null
+++ b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
@@ -0,0 +1,422 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+     -->
+
+ <xs:schema version="2.0"
+            elementFormDefault="qualified"
+            attributeFormDefault="unqualified"
+            xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <!-- List the config versions supported by audio policy engine. -->
+    <xs:simpleType name="version">
+        <xs:restriction base="xs:decimal">
+            <xs:enumeration value="1.0"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:element name="configuration">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="ProductStrategies" type="ProductStrategies"  minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="criterion_types" type="criterionTypesType"  minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="criteria" type="criteriaType"  minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="volumeGroups" type="volumeGroupsType"  minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="volumes" type="volumesType" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element name="attributesRef" type="attributesRef"  minOccurs="0" maxOccurs="unbounded"/>
+            </xs:sequence>
+            <xs:attribute name="version" type="version" use="required"/>
+        </xs:complexType>
+
+        <xs:key name="volumeCurveNameKey">
+            <xs:selector xpath="volumes/reference"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:keyref name="volumeCurveRef" refer="volumeCurveNameKey">
+            <xs:selector xpath="volumeGroups/volumeGroup"/>
+            <xs:field xpath="@ref"/>
+        </xs:keyref>
+
+        <xs:key name="attributesRefNameKey">
+            <xs:selector xpath="attributesRef/reference"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:keyref name="volumeGroupAttributesRef" refer="attributesRefNameKey">
+            <xs:selector xpath="volumeGroups/volumeGroup/volume"/>
+            <xs:field xpath="@attributesRef"/>
+        </xs:keyref>
+        <xs:keyref name="ProductStrategyAttributesRef" refer="attributesRefNameKey">
+            <xs:selector xpath="ProductStrategies/ProductStrategy/Attributes"/>
+            <xs:field xpath="@attributesRef"/>
+        </xs:keyref>
+
+        <xs:unique name="productStrategyNameUniqueness">
+            <xs:selector xpath="ProductStrategies/ProductStrategy"/>
+            <xs:field xpath="@name"/>
+        </xs:unique>
+
+        <!-- ensure validity of volume group referred in product strategy-->
+        <xs:key name="volumeGroupKey">
+            <xs:selector xpath="volumeGroups/volumeGroup/name"/>
+            <xs:field xpath="."/>
+        </xs:key>
+        <xs:keyref name="volumeGroupRef" refer="volumeGroupKey">
+            <xs:selector xpath="ProductStrategies/ProductStrategy/AttributesGroup"/>
+            <xs:field xpath="@volumeGroup"/>
+        </xs:keyref>
+
+        <xs:unique name="volumeTargetUniqueness">
+            <xs:selector xpath="volumeGroups/volumeGroup"/>
+            <xs:field xpath="@name"/>
+            <xs:field xpath="@deviceCategory"/>
+        </xs:unique>
+
+        <!-- ensure validity of criterion type referred in criterion-->
+        <xs:key name="criterionTypeKey">
+            <xs:selector xpath="criterion_types/criterion_type"/>
+            <xs:field xpath="@name"/>
+        </xs:key>
+        <xs:keyref name="criterionTypeKeyRef" refer="criterionTypeKey">
+            <xs:selector xpath="criteria/criterion"/>
+            <xs:field xpath="@type"/>
+        </xs:keyref>
+
+    </xs:element>
+
+    <xs:complexType name="ProductStrategies">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="ProductStrategy" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="AttributesGroup" type="AttributesGroup" minOccurs="1" maxOccurs="unbounded"/>
+                    </xs:sequence>
+                    <xs:attribute name="name" type="xs:string" use="required"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="AttributesGroup">
+        <xs:sequence>
+            <xs:choice minOccurs="0">
+                <xs:element name="Attributes" type="AttributesType" minOccurs="1" maxOccurs="unbounded"/>
+                <xs:sequence>
+                    <xs:element name="ContentType" type="ContentTypeType" minOccurs="0" maxOccurs="1"/>
+                    <xs:element name="Usage" type="UsageType" minOccurs="1" maxOccurs="1"/>
+                    <xs:element name="Source" type="SourceType" minOccurs="0" maxOccurs="1"/>
+                    <xs:element name="Flags" type="FlagsType" minOccurs="0" maxOccurs="1"/>
+                    <xs:element name="Bundle" type="BundleType" minOccurs="0" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:choice>
+        </xs:sequence>
+        <xs:attribute name="streamType" type="stream" use="optional"/>
+        <xs:attribute name="volumeGroup" type="xs:string" use="optional"/>
+    </xs:complexType>
+
+    <xs:complexType name="volumeGroupsType">
+        <xs:sequence>
+             <xs:element name="volumeGroup" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:sequence>
+                         <xs:element name="name" type="xs:token"/>
+                         <xs:element name="indexMin" type="xs:int" minOccurs="0" maxOccurs="1"/>
+                         <xs:element name="indexMax" type="xs:int" minOccurs="0" maxOccurs="1"/>
+                         <xs:element name="volume" type="volume" minOccurs="1" maxOccurs="unbounded"/>
+                     </xs:sequence>
+                </xs:complexType>
+                <xs:unique name="volumeAttributesUniqueness">
+                    <xs:selector xpath="volume"/>
+                    <xs:field xpath="deviceCategory"/>
+                </xs:unique>
+             </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="volumesType">
+        <xs:sequence>
+            <xs:element name="reference" type="volumeRef" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="attributesRef">
+        <xs:sequence>
+            <xs:element name="reference" type="attributesRefType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="criteriaType">
+        <xs:sequence>
+            <xs:element name="criterion" type="criterionType" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="criterionType">
+        <xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="type" type="xs:string" use="required"/>
+        <xs:attribute name="default" type="xs:string" use="optional"/>
+    </xs:complexType>
+
+    <xs:complexType name="criterionTypesType">
+        <xs:sequence>
+            <xs:element name="criterion_type" type="criterionTypeType" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="criterionTypeType">
+        <xs:sequence>
+            <xs:element name="values" type="valuesType" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:token" use="required"/>
+        <xs:attribute name="type" type="pfwCriterionTypeEnum" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="valuesType">
+        <xs:sequence>
+            <xs:element name="value" type="valueType" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="valueType">
+        <xs:attribute name="literal" type="xs:string" use="required"/>
+        <xs:attribute name="numerical" type="xs:long" use="required"/>
+        <xs:attribute name="android_type" type="longDecimalOrHexType" use="optional"/>
+    </xs:complexType>
+
+    <xs:simpleType name="longDecimalOrHexType">
+      <xs:union memberTypes="xs:long longHexType" />
+    </xs:simpleType>
+
+    <xs:simpleType name="longHexType">
+      <xs:restriction base="xs:string">
+        <xs:pattern value="0x[0-9A-Fa-f]{1,16}"/>
+      </xs:restriction>
+    </xs:simpleType>
+
+    <xs:complexType name="attributesRefType">
+        <xs:sequence>
+            <xs:element name="Attributes" type="AttributesType" minOccurs="1" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:token" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="AttributesType">
+        <xs:sequence>
+            <xs:element name="ContentType" type="ContentTypeType" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="Usage" type="UsageType" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="Source" type="SourceType" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="Flags" type="FlagsType" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="Bundle" type="BundleType" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="attributesRef" type="xs:token" use="optional"/>
+        <!-- with xsd 1.1, it is impossible to make choice on either attributes or element...-->
+    </xs:complexType>
+
+    <xs:complexType name="ContentTypeType">
+        <xs:attribute name="value" type="contentType" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="UsageType">
+        <xs:attribute name="value" type="usageEnumType" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="SourceType">
+        <xs:attribute name="value" type="sourceEnumType" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="FlagsType">
+        <xs:attribute name="value" type="flagsEnumType" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="BundleType">
+        <xs:attribute name="key" type="xs:string" use="required"/>
+        <xs:attribute name="value" type="xs:string" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="volume">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Volume section defines a volume curve for a given use case and device category.
+                It contains a list of points of this curve expressing the attenuation in Millibels
+                for a given volume index from 0 to 100.
+                <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </volume>
+
+                It may also reference a reference/@name to avoid duplicating curves.
+                <volume deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+                <reference name="DEFAULT_MEDIA_VOLUME_CURVE">
+                    <point>0,-9600</point>
+                    <point>100,0</point>
+                </reference>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="deviceCategory" type="deviceCategory"/>
+        <xs:attribute name="ref" type="xs:token" use="optional"/>
+    </xs:complexType>
+
+    <xs:complexType name="volumeRef">
+        <xs:sequence>
+            <xs:element name="point" type="volumePoint" minOccurs="2" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="name" type="xs:token" use="required"/>
+    </xs:complexType>
+
+    <xs:simpleType name="volumePoint">
+        <xs:annotation>
+            <xs:documentation xml:lang="en">
+                Comma separated pair of number.
+                The fist one is the framework level (between 0 and 100).
+                The second one is the volume to send to the HAL.
+                The framework will interpolate volumes not specified.
+                Their MUST be at least 2 points specified.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:pattern value="([0-9]{1,2}|100),-?[0-9]+"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+
+    <xs:simpleType name="streamsCsv">
+        <xs:list>
+            <xs:simpleType>
+                <xs:restriction base="stream">
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:list>
+    </xs:simpleType>
+
+    <!-- Enum values of audio_stream_type_t in audio-base.h
+         TODO: avoid manual sync. -->
+    <xs:simpleType name="stream">
+        <xs:restriction base="xs:NMTOKEN">
+            <!--xs:pattern value="\c+(,\c+)*"/-->
+            <xs:enumeration value="AUDIO_STREAM_DEFAULT"/>
+            <xs:enumeration value="AUDIO_STREAM_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_STREAM_SYSTEM"/>
+            <xs:enumeration value="AUDIO_STREAM_RING"/>
+            <xs:enumeration value="AUDIO_STREAM_MUSIC"/>
+            <xs:enumeration value="AUDIO_STREAM_ALARM"/>
+            <xs:enumeration value="AUDIO_STREAM_NOTIFICATION"/>
+            <xs:enumeration value="AUDIO_STREAM_BLUETOOTH_SCO"/>
+            <xs:enumeration value="AUDIO_STREAM_ENFORCED_AUDIBLE"/>
+            <xs:enumeration value="AUDIO_STREAM_DTMF"/>
+            <xs:enumeration value="AUDIO_STREAM_TTS"/>
+            <xs:enumeration value="AUDIO_STREAM_ACCESSIBILITY"/>
+            <xs:enumeration value="AUDIO_STREAM_ASSISTANT"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="deviceCategory">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="DEVICE_CATEGORY_HEADSET"/>
+            <xs:enumeration value="DEVICE_CATEGORY_SPEAKER"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EARPIECE"/>
+            <xs:enumeration value="DEVICE_CATEGORY_EXT_MEDIA"/>
+            <xs:enumeration value="DEVICE_CATEGORY_HEARING_AID"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="contentType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_UNKNOWN"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="usageEnumType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_USAGE_UNKNOWN"/>
+            <xs:enumeration value="AUDIO_USAGE_MEDIA"/>
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/>
+            <xs:enumeration value="AUDIO_USAGE_ALARM"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+            <!-- Note: the following 3 values were deprecated in Android T (13) SDK -->
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_EVENT"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+            <xs:enumeration value="AUDIO_USAGE_GAME"/>
+            <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANT"/>
+            <xs:enumeration value="AUDIO_USAGE_CALL_ASSISTANT"/>
+            <xs:enumeration value="AUDIO_USAGE_EMERGENCY" />
+            <xs:enumeration value="AUDIO_USAGE_SAFETY" />
+            <xs:enumeration value="AUDIO_USAGE_VEHICLE_STATUS" />
+            <xs:enumeration value="AUDIO_USAGE_ANNOUNCEMENT" />
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="flagsEnumType">
+        <xs:list>
+            <xs:simpleType>
+                <xs:restriction base="flagType">
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:list>
+    </xs:simpleType>
+
+    <xs:simpleType name="flagType">
+        <xs:restriction base="xs:NMTOKEN">
+            <xs:enumeration value="AUDIO_FLAG_NONE"/>
+            <xs:enumeration value="AUDIO_FLAG_AUDIBILITY_ENFORCED"/>
+            <xs:enumeration value="AUDIO_FLAG_SECURE"/>
+            <xs:enumeration value="AUDIO_FLAG_SCO"/>
+            <xs:enumeration value="AUDIO_FLAG_BEACON"/>
+            <xs:enumeration value="AUDIO_FLAG_HW_AV_SYNC"/>
+            <xs:enumeration value="AUDIO_FLAG_HW_HOTWORD"/>
+            <xs:enumeration value="AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY"/>
+            <xs:enumeration value="AUDIO_FLAG_BYPASS_MUTE"/>
+            <xs:enumeration value="AUDIO_FLAG_LOW_LATENCY"/>
+            <xs:enumeration value="AUDIO_FLAG_DEEP_BUFFER"/>
+            <xs:enumeration value="AUDIO_FLAG_NO_MEDIA_PROJECTION"/>
+            <xs:enumeration value="AUDIO_FLAG_MUTE_HAPTIC"/>
+            <xs:enumeration value="AUDIO_FLAG_NO_SYSTEM_CAPTURE"/>
+            <xs:enumeration value="AUDIO_FLAG_CAPTURE_PRIVATE"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="sourceEnumType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_SOURCE_DEFAULT"/>
+            <xs:enumeration value="AUDIO_SOURCE_MIC"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_UPLINK"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_DOWNLINK"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_SOURCE_CAMCORDER"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_RECOGNITION"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_SOURCE_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_SOURCE_UNPROCESSED"/>
+            <xs:enumeration value="AUDIO_SOURCE_VOICE_PERFORMANCE"/>
+            <xs:enumeration value="AUDIO_SOURCE_ECHO_REFERENCE"/>
+            <xs:enumeration value="AUDIO_SOURCE_FM_TUNER"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="pfwCriterionTypeEnum">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="inclusive"/>
+            <xs:enumeration value="exclusive"/>
+        </xs:restriction>
+    </xs:simpleType>
+</xs:schema>
diff --git a/audio/aidl/default/downmix/Android.bp b/audio/aidl/default/downmix/Android.bp
new file mode 100644
index 0000000..6d15cdb
--- /dev/null
+++ b/audio/aidl/default/downmix/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libdownmixsw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "DownmixSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/downmix/DownmixSw.cpp b/audio/aidl/default/downmix/DownmixSw.cpp
new file mode 100644
index 0000000..ce5fe20
--- /dev/null
+++ b/audio/aidl/default/downmix/DownmixSw.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+
+#define LOG_TAG "AHAL_DownmixSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "DownmixSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::DownmixSw;
+using aidl::android::hardware::audio::effect::getEffectImplUuidDownmixSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDownmixSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<DownmixSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDownmixSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = DownmixSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string DownmixSw::kEffectName = "DownmixSw";
+const Descriptor DownmixSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidDownmix(),
+                          .uuid = getEffectImplUuidDownmixSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = kEffectName,
+                   .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus DownmixSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus DownmixSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::downmix != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& dmParam = specific.get<Parameter::Specific::downmix>();
+    auto tag = dmParam.getTag();
+
+    switch (tag) {
+        case Downmix::type: {
+            RETURN_IF(mContext->setDmType(dmParam.get<Downmix::type>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setTypeFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "DownmixTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus DownmixSw::getParameterSpecific(const Parameter::Id& id,
+                                                   Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::downmixTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto dmId = id.get<Parameter::Id::downmixTag>();
+    auto dmIdTag = dmId.getTag();
+    switch (dmIdTag) {
+        case Downmix::Id::commonTag:
+            return getParameterDownmix(dmId.get<Downmix::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "DownmixTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus DownmixSw::getParameterDownmix(const Downmix::Tag& tag,
+                                                  Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    Downmix dmParam;
+    switch (tag) {
+        case Downmix::type: {
+            dmParam.set<Downmix::type>(mContext->getDmType());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "DownmixTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::downmix>(dmParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> DownmixSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<DownmixSwContext>(1 /* statusFmqDepth */, common);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> DownmixSw::getContext() {
+    return mContext;
+}
+
+RetCode DownmixSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status DownmixSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/downmix/DownmixSw.h b/audio/aidl/default/downmix/DownmixSw.h
new file mode 100644
index 0000000..3f8a09b
--- /dev/null
+++ b/audio/aidl/default/downmix/DownmixSw.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class DownmixSwContext final : public EffectContext {
+  public:
+    DownmixSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setDmType(Downmix::Type type) {
+        // TODO : Add implementation to apply new type
+        mType = type;
+        return RetCode::SUCCESS;
+    }
+    Downmix::Type getDmType() const { return mType; }
+
+  private:
+    Downmix::Type mType = Downmix::Type::STRIP;
+};
+
+class DownmixSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    DownmixSw() { LOG(DEBUG) << __func__; }
+    ~DownmixSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int sample) override;
+
+  private:
+    std::shared_ptr<DownmixSwContext> mContext;
+
+    ndk::ScopedAStatus getParameterDownmix(const Downmix::Tag& tag, Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/dynamicProcessing/Android.bp b/audio/aidl/default/dynamicProcessing/Android.bp
new file mode 100644
index 0000000..1c0312d
--- /dev/null
+++ b/audio/aidl/default/dynamicProcessing/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libdynamicsprocessingsw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "DynamicsProcessingSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
new file mode 100644
index 0000000..ed6cfa0
--- /dev/null
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
@@ -0,0 +1,524 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+#include <set>
+#include <unordered_set>
+
+#define LOG_TAG "AHAL_DynamicsProcessingSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "DynamicsProcessingSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::DynamicsProcessingSw;
+using aidl::android::hardware::audio::effect::getEffectImplUuidDynamicsProcessingSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDynamicsProcessingSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<DynamicsProcessingSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidDynamicsProcessingSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = DynamicsProcessingSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string DynamicsProcessingSw::kEffectName = "DynamicsProcessingSw";
+const DynamicsProcessing::EqBandConfig DynamicsProcessingSw::kEqBandConfigMin =
+        DynamicsProcessing::EqBandConfig({.channel = 0,
+                                          .band = 0,
+                                          .enable = false,
+                                          .cutoffFrequencyHz = 220,
+                                          .gainDb = std::numeric_limits<float>::min()});
+const DynamicsProcessing::EqBandConfig DynamicsProcessingSw::kEqBandConfigMax =
+        DynamicsProcessing::EqBandConfig({.channel = std::numeric_limits<int>::max(),
+                                          .band = std::numeric_limits<int>::max(),
+                                          .enable = true,
+                                          .cutoffFrequencyHz = 20000,
+                                          .gainDb = std::numeric_limits<float>::max()});
+const Range::DynamicsProcessingRange DynamicsProcessingSw::kPreEqBandRange = {
+        .min = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+                {DynamicsProcessingSw::kEqBandConfigMin}),
+        .max = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+                {DynamicsProcessingSw::kEqBandConfigMax})};
+const Range::DynamicsProcessingRange DynamicsProcessingSw::kPostEqBandRange = {
+        .min = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
+                {DynamicsProcessingSw::kEqBandConfigMin}),
+        .max = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
+                {DynamicsProcessingSw::kEqBandConfigMax})};
+
+const std::vector<Range::DynamicsProcessingRange> DynamicsProcessingSw::kRanges = {
+        DynamicsProcessingSw::kPreEqBandRange, DynamicsProcessingSw::kPostEqBandRange};
+const Capability DynamicsProcessingSw::kCapability = {.range = DynamicsProcessingSw::kRanges};
+
+const Descriptor DynamicsProcessingSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidDynamicsProcessing(),
+                          .uuid = getEffectImplUuidDynamicsProcessingSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = DynamicsProcessingSw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = DynamicsProcessingSw::kCapability};
+
+ndk::ScopedAStatus DynamicsProcessingSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus DynamicsProcessingSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::dynamicsProcessing != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    LOG(INFO) << __func__ << specific.toString();
+    auto& dpParam = specific.get<Parameter::Specific::dynamicsProcessing>();
+    auto tag = dpParam.getTag();
+    switch (tag) {
+        case DynamicsProcessing::engineArchitecture: {
+            RETURN_IF(mContext->setEngineArchitecture(
+                              dpParam.get<DynamicsProcessing::engineArchitecture>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setEngineArchitectureFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case DynamicsProcessing::preEq: {
+            RETURN_IF(mContext->setPreEqChannelCfgs(dpParam.get<DynamicsProcessing::preEq>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setPreEqChannelCfgsFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case DynamicsProcessing::postEq: {
+            RETURN_IF(mContext->setPostEqChannelCfgs(dpParam.get<DynamicsProcessing::postEq>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setPostEqChannelCfgsFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case DynamicsProcessing::mbc: {
+            RETURN_IF(mContext->setMbcChannelCfgs(dpParam.get<DynamicsProcessing::mbc>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setMbcChannelCfgsFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case DynamicsProcessing::preEqBand: {
+            RETURN_IF(mContext->setPreEqBandCfgs(dpParam.get<DynamicsProcessing::preEqBand>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setPreEqBandCfgsFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case DynamicsProcessing::postEqBand: {
+            RETURN_IF(mContext->setPostEqBandCfgs(dpParam.get<DynamicsProcessing::postEqBand>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setPostEqBandCfgsFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case DynamicsProcessing::mbcBand: {
+            RETURN_IF(mContext->setMbcBandCfgs(dpParam.get<DynamicsProcessing::mbcBand>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setMbcBandCfgsFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case DynamicsProcessing::limiter: {
+            RETURN_IF(mContext->setLimiterCfgs(dpParam.get<DynamicsProcessing::limiter>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "limiterCfgsFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case DynamicsProcessing::inputGain: {
+            RETURN_IF(mContext->setInputGainCfgs(dpParam.get<DynamicsProcessing::inputGain>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "inputGainCfgFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case DynamicsProcessing::vendor: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "DynamicsProcessingTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus DynamicsProcessingSw::getParameterSpecific(const Parameter::Id& id,
+                                                              Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::dynamicsProcessingTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto dpId = id.get<Parameter::Id::dynamicsProcessingTag>();
+    auto dpIdTag = dpId.getTag();
+    switch (dpIdTag) {
+        case DynamicsProcessing::Id::commonTag:
+            return getParameterDynamicsProcessing(dpId.get<DynamicsProcessing::Id::commonTag>(),
+                                                  specific);
+        case DynamicsProcessing::Id::vendorExtensionTag:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(dpIdTag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "DynamicsProcessingTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus DynamicsProcessingSw::getParameterDynamicsProcessing(
+        const DynamicsProcessing::Tag& tag, Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    DynamicsProcessing dpParam;
+    switch (tag) {
+        case DynamicsProcessing::Tag::engineArchitecture: {
+            dpParam.set<DynamicsProcessing::engineArchitecture>(mContext->getEngineArchitecture());
+            break;
+        }
+        case DynamicsProcessing::Tag::preEq: {
+            dpParam.set<DynamicsProcessing::preEq>(mContext->getPreEqChannelCfgs());
+            break;
+        }
+        case DynamicsProcessing::Tag::postEq: {
+            dpParam.set<DynamicsProcessing::postEq>(mContext->getPostEqChannelCfgs());
+            break;
+        }
+        case DynamicsProcessing::Tag::mbc: {
+            dpParam.set<DynamicsProcessing::mbc>(mContext->getMbcChannelCfgs());
+            break;
+        }
+        case DynamicsProcessing::Tag::preEqBand: {
+            dpParam.set<DynamicsProcessing::preEqBand>(mContext->getPreEqBandCfgs());
+            break;
+        }
+        case DynamicsProcessing::Tag::postEqBand: {
+            dpParam.set<DynamicsProcessing::postEqBand>(mContext->getPostEqBandCfgs());
+            break;
+        }
+        case DynamicsProcessing::Tag::mbcBand: {
+            dpParam.set<DynamicsProcessing::mbcBand>(mContext->getMbcBandCfgs());
+            break;
+        }
+        case DynamicsProcessing::Tag::limiter: {
+            dpParam.set<DynamicsProcessing::limiter>(mContext->getLimiterCfgs());
+            break;
+        }
+        case DynamicsProcessing::Tag::inputGain: {
+            dpParam.set<DynamicsProcessing::inputGain>(mContext->getInputGainCfgs());
+            break;
+        }
+        case DynamicsProcessing::vendor: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "DynamicsProcessingTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::dynamicsProcessing>(dpParam);
+    LOG(INFO) << __func__ << specific->toString();
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> DynamicsProcessingSw::createContext(
+        const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<DynamicsProcessingSwContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> DynamicsProcessingSw::getContext() {
+    return mContext;
+}
+
+RetCode DynamicsProcessingSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status DynamicsProcessingSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode DynamicsProcessingSwContext::setCommon(const Parameter::Common& common) {
+    mCommon = common;
+    mChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
+            common.input.base.channelMask);
+    resizeChannels();
+    resizeBands();
+    LOG(INFO) << __func__ << mCommon.toString();
+    return RetCode::SUCCESS;
+}
+
+RetCode DynamicsProcessingSwContext::setEngineArchitecture(
+        const DynamicsProcessing::EngineArchitecture& cfg) {
+    RETURN_VALUE_IF(!validateEngineConfig(cfg), RetCode::ERROR_ILLEGAL_PARAMETER,
+                    "illegalEngineConfig");
+
+    if (mEngineSettings == cfg) {
+        LOG(INFO) << __func__ << " not change in engine, do nothing";
+        return RetCode::SUCCESS;
+    }
+    mEngineSettings = cfg;
+    resizeBands();
+    return RetCode::SUCCESS;
+}
+
+RetCode DynamicsProcessingSwContext::setChannelCfgs(
+        const std::vector<DynamicsProcessing::ChannelConfig>& cfgs,
+        std::vector<DynamicsProcessing::ChannelConfig>& targetCfgs,
+        const DynamicsProcessing::StageEnablement& stage) {
+    RETURN_VALUE_IF(!stage.inUse, RetCode::ERROR_ILLEGAL_PARAMETER, "stageNotInUse");
+
+    RetCode ret = RetCode::SUCCESS;
+    std::unordered_set<int> channelSet;
+    for (auto& cfg : cfgs) {
+        if (cfg.channel < 0 || (size_t)cfg.channel >= mChannelCount) {
+            LOG(ERROR) << __func__ << " skip illegal channel config " << cfg.toString();
+            ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+            continue;
+        }
+        if (0 != channelSet.count(cfg.channel)) {
+            LOG(WARNING) << __func__ << " duplicated channel " << cfg.channel;
+            ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+        } else {
+            channelSet.insert(cfg.channel);
+        }
+        targetCfgs[cfg.channel] = cfg;
+    }
+    return ret;
+}
+
+RetCode DynamicsProcessingSwContext::setPreEqChannelCfgs(
+        const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
+    return setChannelCfgs(cfgs, mPreEqChCfgs, mEngineSettings.preEqStage);
+}
+
+RetCode DynamicsProcessingSwContext::setPostEqChannelCfgs(
+        const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
+    return setChannelCfgs(cfgs, mPostEqChCfgs, mEngineSettings.postEqStage);
+}
+
+RetCode DynamicsProcessingSwContext::setMbcChannelCfgs(
+        const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
+    return setChannelCfgs(cfgs, mMbcChCfgs, mEngineSettings.mbcStage);
+}
+
+RetCode DynamicsProcessingSwContext::setEqBandCfgs(
+        const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
+        std::vector<DynamicsProcessing::EqBandConfig>& targetCfgs,
+        const DynamicsProcessing::StageEnablement& stage,
+        const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
+    RETURN_VALUE_IF(!stage.inUse, RetCode::ERROR_ILLEGAL_PARAMETER, "eqStageNotInUse");
+
+    RetCode ret = RetCode::SUCCESS;
+    std::set<std::pair<int /* channel */, int /* band */>> bandSet;
+
+    for (auto& cfg : cfgs) {
+        if (0 != bandSet.count({cfg.channel, cfg.band})) {
+            LOG(WARNING) << __func__ << " duplicated band " << cfg.toString();
+            ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+        } else {
+            bandSet.insert({cfg.channel, cfg.band});
+        }
+        if (!validateEqBandConfig(cfg, mChannelCount, stage.bandCount, channelConfig)) {
+            LOG(WARNING) << __func__ << " skip invalid band " << cfg.toString();
+            ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+            continue;
+        }
+        targetCfgs[cfg.channel * stage.bandCount + cfg.band] = cfg;
+    }
+    return ret;
+}
+
+RetCode DynamicsProcessingSwContext::setPreEqBandCfgs(
+        const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
+    return setEqBandCfgs(cfgs, mPreEqChBands, mEngineSettings.preEqStage, mPreEqChCfgs);
+}
+
+RetCode DynamicsProcessingSwContext::setPostEqBandCfgs(
+        const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
+    return setEqBandCfgs(cfgs, mPostEqChBands, mEngineSettings.postEqStage, mPostEqChCfgs);
+}
+
+RetCode DynamicsProcessingSwContext::setMbcBandCfgs(
+        const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs) {
+    RETURN_VALUE_IF(!mEngineSettings.mbcStage.inUse, RetCode::ERROR_ILLEGAL_PARAMETER,
+                    "mbcNotInUse");
+
+    RetCode ret = RetCode::SUCCESS;
+    std::set<std::pair<int /* channel */, int /* band */>> bandSet;
+
+    int bandCount = mEngineSettings.mbcStage.bandCount;
+    std::vector<bool> filled(mChannelCount * bandCount, false);
+    for (auto& it : cfgs) {
+        if (0 != bandSet.count({it.channel, it.band})) {
+            LOG(WARNING) << __func__ << " duplicated band " << it.toString();
+            ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+        } else {
+            bandSet.insert({it.channel, it.band});
+        }
+        if (!validateMbcBandConfig(it, mChannelCount, mEngineSettings.mbcStage.bandCount,
+                                   mMbcChCfgs)) {
+            LOG(WARNING) << __func__ << " skip invalid band " << it.toString();
+            ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+            continue;
+        }
+        mMbcChBands[it.channel * bandCount + it.band] = it;
+    }
+    return ret;
+}
+
+RetCode DynamicsProcessingSwContext::setLimiterCfgs(
+        const std::vector<DynamicsProcessing::LimiterConfig>& cfgs) {
+    RETURN_VALUE_IF(!mEngineSettings.limiterInUse, RetCode::ERROR_ILLEGAL_PARAMETER,
+                    "limiterNotInUse");
+
+    RetCode ret = RetCode::SUCCESS;
+    std::unordered_set<int> channelSet;
+
+    for (auto& it : cfgs) {
+        if (0 != channelSet.count(it.channel)) {
+            LOG(WARNING) << __func__ << " duplicated channel " << it.channel;
+            ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+        } else {
+            channelSet.insert(it.channel);
+        }
+        if (!validateLimiterConfig(it, mChannelCount)) {
+            LOG(WARNING) << __func__ << " skip invalid limiter " << it.toString();
+            ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+            continue;
+        }
+        mLimiterCfgs[it.channel] = it;
+    }
+    return ret;
+}
+
+void DynamicsProcessingSwContext::resizeChannels() {
+    if (mPreEqChCfgs.size() != mChannelCount) {
+        mPreEqChCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
+    }
+    if (mPostEqChCfgs.size() != mChannelCount) {
+        mPostEqChCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
+    }
+    if (mMbcChCfgs.size() != mChannelCount) {
+        mMbcChCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
+    }
+    if (mLimiterCfgs.size() != mChannelCount) {
+        mLimiterCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
+    }
+    if (mInputGainCfgs.size() != mChannelCount) {
+        mInputGainCfgs.resize(mChannelCount, {.channel = kInvalidChannelId});
+    }
+}
+
+void DynamicsProcessingSwContext::resizeBands() {
+    if (mPreEqChBands.size() != (size_t)(mChannelCount * mEngineSettings.preEqStage.bandCount)) {
+        mPreEqChBands.resize(mChannelCount * mEngineSettings.preEqStage.bandCount,
+                             {.channel = kInvalidChannelId});
+    }
+    if (mPostEqChBands.size() != (size_t)(mChannelCount * mEngineSettings.postEqStage.bandCount)) {
+        mPostEqChBands.resize(mChannelCount * mEngineSettings.postEqStage.bandCount,
+                              {.channel = kInvalidChannelId});
+    }
+    if (mMbcChBands.size() != (size_t)(mChannelCount * mEngineSettings.mbcStage.bandCount)) {
+        mMbcChBands.resize(mChannelCount * mEngineSettings.mbcStage.bandCount,
+                           {.channel = kInvalidChannelId});
+    }
+}
+
+RetCode DynamicsProcessingSwContext::setInputGainCfgs(
+        const std::vector<DynamicsProcessing::InputGain>& cfgs) {
+    for (const auto& cfg : cfgs) {
+        RETURN_VALUE_IF(cfg.channel < 0 || (size_t)cfg.channel >= mChannelCount,
+                        RetCode::ERROR_ILLEGAL_PARAMETER, "invalidChannel");
+        mInputGainCfgs[cfg.channel] = cfg;
+    }
+    return RetCode::SUCCESS;
+}
+
+std::vector<DynamicsProcessing::InputGain> DynamicsProcessingSwContext::getInputGainCfgs() {
+    std::vector<DynamicsProcessing::InputGain> ret;
+    std::copy_if(mInputGainCfgs.begin(), mInputGainCfgs.end(), std::back_inserter(ret),
+                 [&](const auto& gain) { return gain.channel != kInvalidChannelId; });
+    return ret;
+}
+
+bool DynamicsProcessingSwContext::validateStageEnablement(
+        const DynamicsProcessing::StageEnablement& enablement) {
+    return !enablement.inUse || (enablement.inUse && enablement.bandCount > 0);
+}
+
+bool DynamicsProcessingSwContext::validateEngineConfig(
+        const DynamicsProcessing::EngineArchitecture& engine) {
+    return engine.preferredProcessingDurationMs >= 0 &&
+           validateStageEnablement(engine.preEqStage) &&
+           validateStageEnablement(engine.postEqStage) && validateStageEnablement(engine.mbcStage);
+}
+
+bool DynamicsProcessingSwContext::validateEqBandConfig(
+        const DynamicsProcessing::EqBandConfig& band, int maxChannel, int maxBand,
+        const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
+    return band.channel >= 0 && band.channel < maxChannel &&
+           (size_t)band.channel < channelConfig.size() && channelConfig[band.channel].enable &&
+           band.band >= 0 && band.band < maxBand;
+}
+
+bool DynamicsProcessingSwContext::validateMbcBandConfig(
+        const DynamicsProcessing::MbcBandConfig& band, int maxChannel, int maxBand,
+        const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
+    return band.channel >= 0 && band.channel < maxChannel &&
+           (size_t)band.channel < channelConfig.size() && channelConfig[band.channel].enable &&
+           band.band >= 0 && band.band < maxBand && band.attackTimeMs >= 0 &&
+           band.releaseTimeMs >= 0 && band.ratio >= 0 && band.thresholdDb <= 0 &&
+           band.kneeWidthDb <= 0 && band.noiseGateThresholdDb <= 0 && band.expanderRatio >= 0;
+}
+
+bool DynamicsProcessingSwContext::validateLimiterConfig(
+        const DynamicsProcessing::LimiterConfig& limiter, int maxChannel) {
+    return limiter.channel >= 0 && limiter.channel < maxChannel && limiter.attackTimeMs >= 0 &&
+           limiter.releaseTimeMs >= 0 && limiter.ratio >= 0 && limiter.thresholdDb <= 0;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
new file mode 100644
index 0000000..641cf71
--- /dev/null
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdlib>
+#include <memory>
+#include <vector>
+
+#include <Utils.h>
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class DynamicsProcessingSwContext final : public EffectContext {
+  public:
+    DynamicsProcessingSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common),
+          mChannelCount(::aidl::android::hardware::audio::common::getChannelCount(
+                  common.input.base.channelMask)),
+          mPreEqChCfgs(mChannelCount, {.channel = kInvalidChannelId}),
+          mPostEqChCfgs(mChannelCount, {.channel = kInvalidChannelId}),
+          mMbcChCfgs(mChannelCount, {.channel = kInvalidChannelId}),
+          mLimiterCfgs(mChannelCount, {.channel = kInvalidChannelId}) {
+        LOG(DEBUG) << __func__;
+    }
+
+    // utils
+    RetCode setChannelCfgs(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs,
+                           std::vector<DynamicsProcessing::ChannelConfig>& targetCfgs,
+                           const DynamicsProcessing::StageEnablement& engineSetting);
+
+    RetCode setEqBandCfgs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
+                          std::vector<DynamicsProcessing::EqBandConfig>& targetCfgs,
+                          const DynamicsProcessing::StageEnablement& stage,
+                          const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig);
+
+    // set params
+    RetCode setCommon(const Parameter::Common& common) override;
+    RetCode setEngineArchitecture(const DynamicsProcessing::EngineArchitecture& cfg);
+    RetCode setPreEqChannelCfgs(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs);
+    RetCode setPostEqChannelCfgs(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs);
+    RetCode setMbcChannelCfgs(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs);
+    RetCode setPreEqBandCfgs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
+    RetCode setPostEqBandCfgs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
+    RetCode setMbcBandCfgs(const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs);
+    RetCode setLimiterCfgs(const std::vector<DynamicsProcessing::LimiterConfig>& cfgs);
+    RetCode setInputGainCfgs(const std::vector<DynamicsProcessing::InputGain>& cfgs);
+
+    // get params
+    DynamicsProcessing::EngineArchitecture getEngineArchitecture() { return mEngineSettings; }
+    std::vector<DynamicsProcessing::ChannelConfig> getPreEqChannelCfgs() { return mPreEqChCfgs; }
+    std::vector<DynamicsProcessing::ChannelConfig> getPostEqChannelCfgs() { return mPostEqChCfgs; }
+    std::vector<DynamicsProcessing::ChannelConfig> getMbcChannelCfgs() { return mMbcChCfgs; }
+    std::vector<DynamicsProcessing::EqBandConfig> getPreEqBandCfgs() { return mPreEqChBands; }
+    std::vector<DynamicsProcessing::EqBandConfig> getPostEqBandCfgs() { return mPostEqChBands; }
+    std::vector<DynamicsProcessing::MbcBandConfig> getMbcBandCfgs() { return mMbcChBands; }
+    std::vector<DynamicsProcessing::LimiterConfig> getLimiterCfgs() { return mLimiterCfgs; }
+    std::vector<DynamicsProcessing::InputGain> getInputGainCfgs();
+
+  private:
+    static constexpr int32_t kInvalidChannelId = -1;
+    size_t mChannelCount = 0;
+    DynamicsProcessing::EngineArchitecture mEngineSettings;
+    // Channel config vector with size of mChannelCount
+    std::vector<DynamicsProcessing::ChannelConfig> mPreEqChCfgs;
+    std::vector<DynamicsProcessing::ChannelConfig> mPostEqChCfgs;
+    std::vector<DynamicsProcessing::ChannelConfig> mMbcChCfgs;
+    std::vector<DynamicsProcessing::LimiterConfig> mLimiterCfgs;
+    std::vector<DynamicsProcessing::InputGain> mInputGainCfgs;
+    // Band config vector with size of mChannelCount * bandCount
+    std::vector<DynamicsProcessing::EqBandConfig> mPreEqChBands;
+    std::vector<DynamicsProcessing::EqBandConfig> mPostEqChBands;
+    std::vector<DynamicsProcessing::MbcBandConfig> mMbcChBands;
+    bool validateStageEnablement(const DynamicsProcessing::StageEnablement& enablement);
+    bool validateEngineConfig(const DynamicsProcessing::EngineArchitecture& engine);
+    bool validateEqBandConfig(const DynamicsProcessing::EqBandConfig& band, int maxChannel,
+                              int maxBand,
+                              const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig);
+    bool validateMbcBandConfig(const DynamicsProcessing::MbcBandConfig& band, int maxChannel,
+                               int maxBand,
+                               const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig);
+    bool validateLimiterConfig(const DynamicsProcessing::LimiterConfig& limiter, int maxChannel);
+    void resizeChannels();
+    void resizeBands();
+};  // DynamicsProcessingSwContext
+
+class DynamicsProcessingSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    DynamicsProcessingSw() { LOG(DEBUG) << __func__; }
+    ~DynamicsProcessingSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; };
+
+  private:
+    static const DynamicsProcessing::EqBandConfig kEqBandConfigMin;
+    static const DynamicsProcessing::EqBandConfig kEqBandConfigMax;
+    static const Range::DynamicsProcessingRange kPreEqBandRange;
+    static const Range::DynamicsProcessingRange kPostEqBandRange;
+    static const std::vector<Range::DynamicsProcessingRange> kRanges;
+    std::shared_ptr<DynamicsProcessingSwContext> mContext;
+    ndk::ScopedAStatus getParameterDynamicsProcessing(const DynamicsProcessing::Tag& tag,
+                                                      Parameter::Specific* specific);
+
+};  // DynamicsProcessingSw
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/envReverb/Android.bp b/audio/aidl/default/envReverb/Android.bp
new file mode 100644
index 0000000..dd4219a
--- /dev/null
+++ b/audio/aidl/default/envReverb/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libenvreverbsw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "EnvReverbSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
new file mode 100644
index 0000000..73975c6
--- /dev/null
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+#include <unordered_set>
+
+#define LOG_TAG "AHAL_EnvReverbSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "EnvReverbSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::EnvReverbSw;
+using aidl::android::hardware::audio::effect::getEffectImplUuidEnvReverbSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEnvReverbSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<EnvReverbSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEnvReverbSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = EnvReverbSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string EnvReverbSw::kEffectName = "EnvReverbSw";
+
+const std::vector<Range::EnvironmentalReverbRange> EnvReverbSw::kRanges = {
+        MAKE_RANGE(EnvironmentalReverb, roomLevelMb, -6000, 0),
+        MAKE_RANGE(EnvironmentalReverb, roomHfLevelMb, -4000, 0),
+        MAKE_RANGE(EnvironmentalReverb, decayTimeMs, 0, 7000),
+        MAKE_RANGE(EnvironmentalReverb, decayHfRatioPm, 100, 2000),
+        MAKE_RANGE(EnvironmentalReverb, reflectionsLevelMb, -6000, 0),
+        MAKE_RANGE(EnvironmentalReverb, reflectionsDelayMs, 0, 65),
+        MAKE_RANGE(EnvironmentalReverb, levelMb, -6000, 0),
+        MAKE_RANGE(EnvironmentalReverb, delayMs, 0, 65),
+        MAKE_RANGE(EnvironmentalReverb, diffusionPm, 0, 1000),
+        MAKE_RANGE(EnvironmentalReverb, densityPm, 0, 1000)};
+
+const Capability EnvReverbSw::kCapability = {
+        .range = Range::make<Range::environmentalReverb>(EnvReverbSw::kRanges)};
+
+const Descriptor EnvReverbSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidEnvReverb(),
+                          .uuid = getEffectImplUuidEnvReverbSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = EnvReverbSw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = EnvReverbSw::kCapability};
+
+ndk::ScopedAStatus EnvReverbSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EnvReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::environmentalReverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+
+    auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
+    RETURN_IF(!inRange(erParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = erParam.getTag();
+    switch (tag) {
+        case EnvironmentalReverb::roomLevelMb: {
+            RETURN_IF(mContext->setErRoomLevel(erParam.get<EnvironmentalReverb::roomLevelMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setRoomLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::roomHfLevelMb: {
+            RETURN_IF(
+                    mContext->setErRoomHfLevel(erParam.get<EnvironmentalReverb::roomHfLevelMb>()) !=
+                            RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "setRoomHfLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::decayTimeMs: {
+            RETURN_IF(mContext->setErDecayTime(erParam.get<EnvironmentalReverb::decayTimeMs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDecayTimeFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::decayHfRatioPm: {
+            RETURN_IF(
+                    mContext->setErDecayHfRatio(
+                            erParam.get<EnvironmentalReverb::decayHfRatioPm>()) != RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::reflectionsLevelMb: {
+            RETURN_IF(mContext->setErReflectionsLevel(
+                              erParam.get<EnvironmentalReverb::reflectionsLevelMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setReflectionsLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::reflectionsDelayMs: {
+            RETURN_IF(mContext->setErReflectionsDelay(
+                              erParam.get<EnvironmentalReverb::reflectionsDelayMs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setReflectionsDelayFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::levelMb: {
+            RETURN_IF(mContext->setErLevel(erParam.get<EnvironmentalReverb::levelMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setLevelFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::delayMs: {
+            RETURN_IF(mContext->setErDelay(erParam.get<EnvironmentalReverb::delayMs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDelayFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::diffusionPm: {
+            RETURN_IF(mContext->setErDiffusion(erParam.get<EnvironmentalReverb::diffusionPm>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDiffusionFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::densityPm: {
+            RETURN_IF(mContext->setErDensity(erParam.get<EnvironmentalReverb::densityPm>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDensityFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case EnvironmentalReverb::bypass: {
+            RETURN_IF(mContext->setErBypass(erParam.get<EnvironmentalReverb::bypass>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setBypassFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus EnvReverbSw::getParameterSpecific(const Parameter::Id& id,
+                                                     Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::environmentalReverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto erId = id.get<Parameter::Id::environmentalReverbTag>();
+    auto erIdTag = erId.getTag();
+    switch (erIdTag) {
+        case EnvironmentalReverb::Id::commonTag:
+            return getParameterEnvironmentalReverb(erId.get<EnvironmentalReverb::Id::commonTag>(),
+                                                   specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(erIdTag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus EnvReverbSw::getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
+                                                                Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    EnvironmentalReverb erParam;
+    switch (tag) {
+        case EnvironmentalReverb::roomLevelMb: {
+            erParam.set<EnvironmentalReverb::roomLevelMb>(mContext->getErRoomLevel());
+            break;
+        }
+        case EnvironmentalReverb::roomHfLevelMb: {
+            erParam.set<EnvironmentalReverb::roomHfLevelMb>(mContext->getErRoomHfLevel());
+            break;
+        }
+        case EnvironmentalReverb::decayTimeMs: {
+            erParam.set<EnvironmentalReverb::decayTimeMs>(mContext->getErDecayTime());
+            break;
+        }
+        case EnvironmentalReverb::decayHfRatioPm: {
+            erParam.set<EnvironmentalReverb::decayHfRatioPm>(mContext->getErDecayHfRatio());
+            break;
+        }
+        case EnvironmentalReverb::reflectionsLevelMb: {
+            erParam.set<EnvironmentalReverb::reflectionsLevelMb>(mContext->getErReflectionsLevel());
+            break;
+        }
+        case EnvironmentalReverb::reflectionsDelayMs: {
+            erParam.set<EnvironmentalReverb::reflectionsDelayMs>(mContext->getErReflectionsDelay());
+            break;
+        }
+        case EnvironmentalReverb::levelMb: {
+            erParam.set<EnvironmentalReverb::levelMb>(mContext->getErLevel());
+            break;
+        }
+        case EnvironmentalReverb::delayMs: {
+            erParam.set<EnvironmentalReverb::delayMs>(mContext->getErDelay());
+            break;
+        }
+        case EnvironmentalReverb::diffusionPm: {
+            erParam.set<EnvironmentalReverb::diffusionPm>(mContext->getErDiffusion());
+            break;
+        }
+        case EnvironmentalReverb::densityPm: {
+            erParam.set<EnvironmentalReverb::densityPm>(mContext->getErDensity());
+            break;
+        }
+        case EnvironmentalReverb::bypass: {
+            erParam.set<EnvironmentalReverb::bypass>(mContext->getErBypass());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::environmentalReverb>(erParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> EnvReverbSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<EnvReverbSwContext>(1 /* statusFmqDepth */, common);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> EnvReverbSw::getContext() {
+    return mContext;
+}
+
+RetCode EnvReverbSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status EnvReverbSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode EnvReverbSwContext::setErRoomLevel(int roomLevel) {
+    mRoomLevel = roomLevel;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErRoomHfLevel(int roomHfLevel) {
+    mRoomHfLevel = roomHfLevel;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDecayTime(int decayTime) {
+    mDecayTime = decayTime;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDecayHfRatio(int decayHfRatio) {
+    mDecayHfRatio = decayHfRatio;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErLevel(int level) {
+    mLevel = level;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDelay(int delay) {
+    mDelay = delay;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDiffusion(int diffusion) {
+    mDiffusion = diffusion;
+    return RetCode::SUCCESS;
+}
+
+RetCode EnvReverbSwContext::setErDensity(int density) {
+    mDensity = density;
+    return RetCode::SUCCESS;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
new file mode 100644
index 0000000..5e31e2f
--- /dev/null
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class EnvReverbSwContext final : public EffectContext {
+  public:
+    EnvReverbSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setErRoomLevel(int roomLevel);
+    int getErRoomLevel() const { return mRoomLevel; }
+
+    RetCode setErRoomHfLevel(int roomHfLevel);
+    int getErRoomHfLevel() const { return mRoomHfLevel; }
+
+    RetCode setErDecayTime(int decayTime);
+    int getErDecayTime() const { return mDecayTime; }
+
+    RetCode setErDecayHfRatio(int decayHfRatio);
+    int getErDecayHfRatio() const { return mDecayHfRatio; }
+
+    RetCode setErLevel(int level);
+    int getErLevel() const { return mLevel; }
+
+    RetCode setErDelay(int delay);
+    int getErDelay() const { return mDelay; }
+
+    RetCode setErDiffusion(int diffusion);
+    int getErDiffusion() const { return mDiffusion; }
+
+    RetCode setErDensity(int density);
+    int getErDensity() const { return mDensity; }
+
+    RetCode setErBypass(bool bypass) {
+        mBypass = bypass;
+        return RetCode::SUCCESS;
+    }
+    bool getErBypass() const { return mBypass; }
+
+    RetCode setErReflectionsDelay(int delay) {
+        mReflectionsDelayMs = delay;
+        return RetCode::SUCCESS;
+    }
+    bool getErReflectionsDelay() const { return mReflectionsDelayMs; }
+
+    RetCode setErReflectionsLevel(int level) {
+        mReflectionsLevelMb = level;
+        return RetCode::SUCCESS;
+    }
+    bool getErReflectionsLevel() const { return mReflectionsLevelMb; }
+
+  private:
+    int mRoomLevel = -6000;                                        // Default room level
+    int mRoomHfLevel = 0;                                          // Default room hf level
+    int mDecayTime = 1000;                                         // Default decay time
+    int mDecayHfRatio = 500;                                       // Default decay hf ratio
+    int mLevel = -6000;                                            // Default level
+    int mDelay = 40;                                               // Default delay
+    int mReflectionsLevelMb = 0;
+    int mReflectionsDelayMs = 0;
+    int mDiffusion = 1000;                                         // Default diffusion
+    int mDensity = 1000;                                           // Default density
+    bool mBypass = false;                                          // Default bypass
+};
+
+class EnvReverbSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    EnvReverbSw() { LOG(DEBUG) << __func__; }
+    ~EnvReverbSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
+  private:
+    static const std::vector<Range::EnvironmentalReverbRange> kRanges;
+    std::shared_ptr<EnvReverbSwContext> mContext;
+    ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
+                                                       Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/equalizer/Android.bp b/audio/aidl/default/equalizer/Android.bp
new file mode 100644
index 0000000..3610563
--- /dev/null
+++ b/audio/aidl/default/equalizer/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libequalizersw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "EqualizerSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/equalizer/EqualizerSw.cpp b/audio/aidl/default/equalizer/EqualizerSw.cpp
new file mode 100644
index 0000000..b2add31
--- /dev/null
+++ b/audio/aidl/default/equalizer/EqualizerSw.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+
+#define LOG_TAG "AHAL_EqualizerSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "EqualizerSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::EqualizerSw;
+using aidl::android::hardware::audio::effect::getEffectImplUuidEqualizerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEqualizerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<EqualizerSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEqualizerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = EqualizerSw::kDesc;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string EqualizerSw::kEffectName = "EqualizerSw";
+
+const std::vector<Equalizer::BandFrequency> EqualizerSw::kBandFrequency = {{0, 30000, 120000},
+                                                                           {1, 120001, 460000},
+                                                                           {2, 460001, 1800000},
+                                                                           {3, 1800001, 7000000},
+                                                                           {4, 7000001, 20000000}};
+const std::vector<Equalizer::Preset> EqualizerSw::kPresets = {
+        {0, "Normal"},      {1, "Classical"}, {2, "Dance"}, {3, "Flat"}, {4, "Folk"},
+        {5, "Heavy Metal"}, {6, "Hip Hop"},   {7, "Jazz"},  {8, "Pop"},  {9, "Rock"}};
+
+/**
+ * Use the same min and max to build a capability represented by Range.
+ */
+const std::vector<Range::EqualizerRange> EqualizerSw::kRanges = {
+        MAKE_RANGE(Equalizer, preset, 0, EqualizerSw::kPresets.size() - 1),
+        MAKE_RANGE(Equalizer, bandLevels,
+                   std::vector<Equalizer::BandLevel>{
+                           Equalizer::BandLevel({.index = 0, .levelMb = -15})},
+                   std::vector<Equalizer::BandLevel>{Equalizer::BandLevel(
+                           {.index = EqualizerSwContext::kMaxBandNumber - 1, .levelMb = 15})}),
+        /* capability definition */
+        MAKE_RANGE(Equalizer, bandFrequencies, EqualizerSw::kBandFrequency,
+                   EqualizerSw::kBandFrequency),
+        MAKE_RANGE(Equalizer, presets, EqualizerSw::kPresets, EqualizerSw::kPresets),
+        /* centerFreqMh is get only, set invalid range min > max */
+        MAKE_RANGE(Equalizer, centerFreqMh, std::vector<int>({1}), std::vector<int>({0}))};
+
+const Capability EqualizerSw::kEqCap = {.range = EqualizerSw::kRanges};
+const Descriptor EqualizerSw::kDesc = {.common = {.id = {.type = getEffectTypeUuidEqualizer(),
+                                                         .uuid = getEffectImplUuidEqualizerSw()},
+                                                  .flags = {.type = Flags::Type::INSERT,
+                                                            .insert = Flags::Insert::FIRST,
+                                                            .volume = Flags::Volume::CTRL},
+                                                  .name = EqualizerSw::kEffectName,
+                                                  .implementor = "The Android Open Source Project"},
+                                       .capability = EqualizerSw::kEqCap};
+
+ndk::ScopedAStatus EqualizerSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDesc.toString();
+    *_aidl_return = kDesc;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus EqualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::equalizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& eqParam = specific.get<Parameter::Specific::equalizer>();
+    RETURN_IF(!inRange(eqParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = eqParam.getTag();
+    switch (tag) {
+        case Equalizer::preset: {
+            RETURN_IF(mContext->setEqPreset(eqParam.get<Equalizer::preset>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setBandLevelsFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case Equalizer::bandLevels: {
+            RETURN_IF(mContext->setEqBandLevels(eqParam.get<Equalizer::bandLevels>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setBandLevelsFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "EqTagNotSupported");
+        }
+    }
+
+    LOG(ERROR) << __func__ << " unsupported eq param tag: " << toString(tag);
+    return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                            "ParamNotSupported");
+}
+
+ndk::ScopedAStatus EqualizerSw::getParameterSpecific(const Parameter::Id& id,
+                                                     Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::equalizerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto eqId = id.get<Parameter::Id::equalizerTag>();
+    auto eqIdTag = eqId.getTag();
+    switch (eqIdTag) {
+        case Equalizer::Id::commonTag:
+            return getParameterEqualizer(eqId.get<Equalizer::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " tag " << toString(eqIdTag) << " not supported";
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "EqualizerTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus EqualizerSw::getParameterEqualizer(const Equalizer::Tag& tag,
+                                                      Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    Equalizer eqParam;
+    switch (tag) {
+        case Equalizer::bandLevels: {
+            eqParam.set<Equalizer::bandLevels>(mContext->getEqBandLevels());
+            break;
+        }
+        case Equalizer::preset: {
+            eqParam.set<Equalizer::preset>(mContext->getEqPreset());
+            break;
+        }
+        case Equalizer::centerFreqMh: {
+            eqParam.set<Equalizer::centerFreqMh>(mContext->getCenterFreqs());
+            break;
+        }
+        case Equalizer::bandFrequencies: {
+            eqParam.set<Equalizer::bandFrequencies>(kBandFrequency);
+            break;
+        }
+        case Equalizer::presets: {
+            eqParam.set<Equalizer::presets>(kPresets);
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "unsupportedTag");
+        }
+    }
+
+    specific->set<Parameter::Specific::equalizer>(eqParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> EqualizerSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<EqualizerSwContext>(1 /* statusFmqDepth */, common);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> EqualizerSw::getContext() {
+    return mContext;
+}
+
+RetCode EqualizerSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status EqualizerSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/equalizer/EqualizerSw.h b/audio/aidl/default/equalizer/EqualizerSw.h
new file mode 100644
index 0000000..56af3b5
--- /dev/null
+++ b/audio/aidl/default/equalizer/EqualizerSw.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class EqualizerSwContext final : public EffectContext {
+  public:
+    EqualizerSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setEqPreset(const int& presetIdx) {
+        if (presetIdx < 0 || presetIdx >= kMaxPresetNumber) {
+            return RetCode::ERROR_ILLEGAL_PARAMETER;
+        }
+        mPreset = presetIdx;
+        return RetCode::SUCCESS;
+    }
+    int getEqPreset() { return mPreset; }
+
+    RetCode setEqBandLevels(const std::vector<Equalizer::BandLevel>& bandLevels) {
+        if (bandLevels.size() > kMaxBandNumber) {
+            LOG(ERROR) << __func__ << " return because size exceed " << kMaxBandNumber;
+            return RetCode::ERROR_ILLEGAL_PARAMETER;
+        }
+        RetCode ret = RetCode::SUCCESS;
+        for (auto& it : bandLevels) {
+            if (it.index >= kMaxBandNumber || it.index < 0) {
+                LOG(ERROR) << __func__ << " index illegal, skip: " << it.index << " - "
+                           << it.levelMb;
+                ret = RetCode::ERROR_ILLEGAL_PARAMETER;
+            } else {
+                mBandLevels[it.index] = it.levelMb;
+            }
+        }
+        return ret;
+    }
+
+    std::vector<Equalizer::BandLevel> getEqBandLevels() {
+        std::vector<Equalizer::BandLevel> bandLevels;
+        for (int i = 0; i < kMaxBandNumber; i++) {
+            bandLevels.push_back({i, mBandLevels[i]});
+        }
+        return bandLevels;
+    }
+
+    std::vector<int> getCenterFreqs() {
+        return {std::begin(kPresetsFrequencies), std::end(kPresetsFrequencies)};
+    }
+    static const int kMaxBandNumber = 5;
+    static const int kMaxPresetNumber = 10;
+    static const int kCustomPreset = -1;
+
+  private:
+    static constexpr std::array<uint16_t, kMaxBandNumber> kPresetsFrequencies = {60, 230, 910, 3600,
+                                                                                 14000};
+    // preset band level
+    int mPreset = kCustomPreset;
+    int32_t mBandLevels[kMaxBandNumber] = {3, 0, 0, 0, 3};
+
+    // Add equalizer specific context for processing here
+};
+
+class EqualizerSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kEqCap;
+    static const Descriptor kDesc;
+
+    EqualizerSw() { LOG(DEBUG) << __func__; }
+    ~EqualizerSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
+  private:
+    static const std::vector<Equalizer::BandFrequency> kBandFrequency;
+    static const std::vector<Equalizer::Preset> kPresets;
+    static const std::vector<Range::EqualizerRange> kRanges;
+    ndk::ScopedAStatus getParameterEqualizer(const Equalizer::Tag& tag,
+                                             Parameter::Specific* specific);
+    std::shared_ptr<EqualizerSwContext> mContext;
+};
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/extension/Android.bp b/audio/aidl/default/extension/Android.bp
new file mode 100644
index 0000000..4e5d352
--- /dev/null
+++ b/audio/aidl/default/extension/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libextensioneffect",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "ExtensionEffect.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/extension/ExtensionEffect.cpp b/audio/aidl/default/extension/ExtensionEffect.cpp
new file mode 100644
index 0000000..c4eebc0
--- /dev/null
+++ b/audio/aidl/default/extension/ExtensionEffect.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+#include <unordered_set>
+
+#include <aidl/android/hardware/audio/effect/DefaultExtension.h>
+#define LOG_TAG "AHAL_ExtensionEffect"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "ExtensionEffect.h"
+
+using aidl::android::hardware::audio::effect::DefaultExtension;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::ExtensionEffect;
+using aidl::android::hardware::audio::effect::getEffectUuidExtensionImpl;
+using aidl::android::hardware::audio::effect::getEffectUuidExtensionType;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::Range;
+using aidl::android::hardware::audio::effect::VendorExtension;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectUuidExtensionImpl()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<ExtensionEffect>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectUuidExtensionImpl()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = ExtensionEffect::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string ExtensionEffect::kEffectName = "ExtensionEffectExample";
+
+const Descriptor ExtensionEffect::kDescriptor = {
+        .common = {.id = {.type = getEffectUuidExtensionType(),
+                          .uuid = getEffectUuidExtensionImpl(),
+                          .proxy = std::nullopt},
+                   .name = ExtensionEffect::kEffectName,
+                   .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus ExtensionEffect::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ExtensionEffect::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::vendorEffect != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& vendorEffect = specific.get<Parameter::Specific::vendorEffect>();
+    std::optional<DefaultExtension> defaultExt;
+    RETURN_IF(STATUS_OK != vendorEffect.extension.getParcelable(&defaultExt), EX_ILLEGAL_ARGUMENT,
+              "getParcelableFailed");
+    RETURN_IF(!defaultExt.has_value(), EX_ILLEGAL_ARGUMENT, "parcelableNull");
+    RETURN_IF(mContext->setParams(defaultExt->bytes) != RetCode::SUCCESS, EX_ILLEGAL_ARGUMENT,
+              "paramNotSupported");
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ExtensionEffect::getParameterSpecific(const Parameter::Id& id,
+                                                         Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::vendorEffectTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto extensionId = id.get<Parameter::Id::vendorEffectTag>();
+    std::optional<DefaultExtension> defaultIdExt;
+    RETURN_IF(STATUS_OK != extensionId.extension.getParcelable(&defaultIdExt), EX_ILLEGAL_ARGUMENT,
+              "getIdParcelableFailed");
+    RETURN_IF(!defaultIdExt.has_value(), EX_ILLEGAL_ARGUMENT, "parcelableIdNull");
+
+    VendorExtension extension;
+    DefaultExtension defaultExt;
+    defaultExt.bytes = mContext->getParams(defaultIdExt->bytes);
+    RETURN_IF(STATUS_OK != extension.extension.setParcelable(defaultExt), EX_ILLEGAL_ARGUMENT,
+              "setParcelableFailed");
+    specific->set<Parameter::Specific::vendorEffect>(extension);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> ExtensionEffect::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<ExtensionEffectContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> ExtensionEffect::getContext() {
+    return mContext;
+}
+
+RetCode ExtensionEffect::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status ExtensionEffect::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/extension/ExtensionEffect.h b/audio/aidl/default/extension/ExtensionEffect.h
new file mode 100644
index 0000000..e7a068b
--- /dev/null
+++ b/audio/aidl/default/extension/ExtensionEffect.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <memory>
+#include <vector>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class ExtensionEffectContext final : public EffectContext {
+  public:
+    ExtensionEffectContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setParams(const std::vector<uint8_t>& params) {
+        mParams = params;
+        return RetCode::SUCCESS;
+    }
+    std::vector<uint8_t> getParams(std::vector<uint8_t> id __unused) const { return mParams; }
+
+  private:
+    std::vector<uint8_t> mParams;
+};
+
+class ExtensionEffect final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    ExtensionEffect() { LOG(DEBUG) << __func__; }
+    ~ExtensionEffect() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+  private:
+    std::shared_ptr<ExtensionEffectContext> mContext;
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/hapticGenerator/Android.bp b/audio/aidl/default/hapticGenerator/Android.bp
new file mode 100644
index 0000000..0df9a94
--- /dev/null
+++ b/audio/aidl/default/hapticGenerator/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libhapticgeneratorsw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "HapticGeneratorSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
new file mode 100644
index 0000000..27cdac8
--- /dev/null
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+
+#define LOG_TAG "AHAL_HapticGeneratorSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "HapticGeneratorSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidHapticGeneratorSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator;
+using aidl::android::hardware::audio::effect::HapticGeneratorSw;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidHapticGeneratorSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<HapticGeneratorSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidHapticGeneratorSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = HapticGeneratorSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string HapticGeneratorSw::kEffectName = "HapticGeneratorSw";
+/* Effect descriptor */
+const Descriptor HapticGeneratorSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidHapticGenerator(),
+                          .uuid = getEffectImplUuidHapticGeneratorSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = HapticGeneratorSw::kEffectName,
+                   .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus HapticGeneratorSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus HapticGeneratorSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::hapticGenerator != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& hgParam = specific.get<Parameter::Specific::hapticGenerator>();
+    auto tag = hgParam.getTag();
+
+    switch (tag) {
+        case HapticGenerator::hapticScales: {
+            RETURN_IF(mContext->setHgHapticScales(hgParam.get<HapticGenerator::hapticScales>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "HapticScaleNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case HapticGenerator::vibratorInfo: {
+            RETURN_IF(mContext->setHgVibratorInformation(
+                              hgParam.get<HapticGenerator::vibratorInfo>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "VibratorInfoNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "HapticGeneratorTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus HapticGeneratorSw::getParameterSpecific(const Parameter::Id& id,
+                                                           Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::hapticGeneratorTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto hgId = id.get<Parameter::Id::hapticGeneratorTag>();
+    auto hgIdTag = hgId.getTag();
+    switch (hgIdTag) {
+        case HapticGenerator::Id::commonTag:
+            return getParameterHapticGenerator(hgId.get<HapticGenerator::Id::commonTag>(),
+                                               specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "HapticGeneratorTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus HapticGeneratorSw::getParameterHapticGenerator(const HapticGenerator::Tag& tag,
+                                                                  Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    HapticGenerator hgParam;
+    switch (tag) {
+        case HapticGenerator::hapticScales: {
+            hgParam.set<HapticGenerator::hapticScales>(mContext->getHgHapticScales());
+            break;
+        }
+        case HapticGenerator::vibratorInfo: {
+            hgParam.set<HapticGenerator::vibratorInfo>(mContext->getHgVibratorInformation());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "HapticGeneratorTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::hapticGenerator>(hgParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> HapticGeneratorSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<HapticGeneratorSwContext>(1 /* statusFmqDepth */, common);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> HapticGeneratorSw::getContext() {
+    return mContext;
+}
+
+RetCode HapticGeneratorSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status HapticGeneratorSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode HapticGeneratorSwContext::setHgHapticScales(
+        const std::vector<HapticGenerator::HapticScale>& hapticScales) {
+    // Assume any audio track ID is valid
+    for (auto& it : hapticScales) {
+        mHapticScales[it.id] = it;
+    }
+    return RetCode::SUCCESS;
+}
+
+std::vector<HapticGenerator::HapticScale> HapticGeneratorSwContext::getHgHapticScales() const {
+    std::vector<HapticGenerator::HapticScale> result;
+    std::transform(mHapticScales.begin(), mHapticScales.end(), std::back_inserter(result),
+                   [](auto& scaleIt) { return scaleIt.second; });
+    return result;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
new file mode 100644
index 0000000..3bbe41a
--- /dev/null
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdlib>
+#include <map>
+#include <memory>
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class HapticGeneratorSwContext final : public EffectContext {
+  public:
+    HapticGeneratorSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setHgHapticScales(const std::vector<HapticGenerator::HapticScale>& hapticScales);
+    std::vector<HapticGenerator::HapticScale> getHgHapticScales() const;
+
+    RetCode setHgVibratorInformation(const HapticGenerator::VibratorInformation& vibratorInfo) {
+        // All float values are valid for resonantFrequencyHz, qFactor, maxAmplitude
+        mVibratorInformation = vibratorInfo;
+        return RetCode::SUCCESS;
+    }
+
+    HapticGenerator::VibratorInformation getHgVibratorInformation() const {
+        return mVibratorInformation;
+    }
+
+  private:
+    static constexpr float DEFAULT_RESONANT_FREQUENCY = 150.0f;
+    static constexpr float DEFAULT_Q_FACTOR = 1.0f;
+    static constexpr float DEFAULT_MAX_AMPLITUDE = 0.0f;
+    std::map<int /* trackID */, HapticGenerator::HapticScale> mHapticScales;
+    HapticGenerator::VibratorInformation mVibratorInformation = {
+            DEFAULT_RESONANT_FREQUENCY, DEFAULT_Q_FACTOR, DEFAULT_MAX_AMPLITUDE};
+};
+
+class HapticGeneratorSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Descriptor kDescriptor;
+    HapticGeneratorSw() { LOG(DEBUG) << __func__; }
+    ~HapticGeneratorSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
+  private:
+    std::shared_ptr<HapticGeneratorSwContext> mContext;
+
+    ndk::ScopedAStatus getParameterHapticGenerator(const HapticGenerator::Tag& tag,
+                                                   Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h
new file mode 100644
index 0000000..47918f0
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/AudioPolicyConfigXmlConverter.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
+#include <android_audio_policy_configuration.h>
+#include <android_audio_policy_configuration_enums.h>
+
+#include "core-impl/XmlConverter.h"
+
+namespace aidl::android::hardware::audio::core::internal {
+
+class AudioPolicyConfigXmlConverter {
+  public:
+    explicit AudioPolicyConfigXmlConverter(const std::string& configFilePath)
+        : mConverter(configFilePath, &::android::audio::policy::configuration::read) {}
+
+    std::string getError() const { return mConverter.getError(); }
+    ::android::status_t getStatus() const { return mConverter.getStatus(); }
+
+    const ::aidl::android::media::audio::common::AudioHalEngineConfig& getAidlEngineConfig();
+
+  private:
+    const std::optional<::android::audio::policy::configuration::AudioPolicyConfiguration>&
+    getXsdcConfig() const {
+        return mConverter.getXsdcConfig();
+    }
+    void addVolumeGroupstoEngineConfig();
+    void mapStreamToVolumeCurve(
+            const ::android::audio::policy::configuration::Volume& xsdcVolumeCurve);
+    void mapStreamsToVolumeCurves();
+    void parseVolumes();
+    ::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint convertCurvePointToAidl(
+            const std::string& xsdcCurvePoint);
+
+    ::aidl::android::media::audio::common::AudioHalVolumeCurve convertVolumeCurveToAidl(
+            const ::android::audio::policy::configuration::Volume& xsdcVolumeCurve);
+
+    ::aidl::android::media::audio::common::AudioHalEngineConfig mAidlEngineConfig;
+    XmlConverter<::android::audio::policy::configuration::AudioPolicyConfiguration> mConverter;
+    std::unordered_map<std::string, ::android::audio::policy::configuration::Reference>
+            mVolumesReferenceMap;
+    std::unordered_map<::android::audio::policy::configuration::AudioStreamType,
+                       std::vector<::aidl::android::media::audio::common::AudioHalVolumeCurve>>
+            mStreamToVolumeCurvesMap;
+};
+
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/Bluetooth.h b/audio/aidl/default/include/core-impl/Bluetooth.h
new file mode 100644
index 0000000..10e9045
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/Bluetooth.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/core/BnBluetooth.h>
+#include <aidl/android/hardware/audio/core/BnBluetoothA2dp.h>
+#include <aidl/android/hardware/audio/core/BnBluetoothLe.h>
+
+namespace aidl::android::hardware::audio::core {
+
+class Bluetooth : public BnBluetooth {
+  public:
+    Bluetooth();
+
+  private:
+    ndk::ScopedAStatus setScoConfig(const ScoConfig& in_config, ScoConfig* _aidl_return) override;
+    ndk::ScopedAStatus setHfpConfig(const HfpConfig& in_config, HfpConfig* _aidl_return) override;
+
+    ScoConfig mScoConfig;
+    HfpConfig mHfpConfig;
+};
+
+class BluetoothA2dp : public BnBluetoothA2dp {
+  public:
+    BluetoothA2dp() = default;
+
+  private:
+    ndk::ScopedAStatus isEnabled(bool* _aidl_return) override;
+    ndk::ScopedAStatus setEnabled(bool in_enabled) override;
+    ndk::ScopedAStatus supportsOffloadReconfiguration(bool* _aidl_return) override;
+    ndk::ScopedAStatus reconfigureOffload(
+            const std::vector<::aidl::android::hardware::audio::core::VendorParameter>&
+                    in_parameters) override;
+
+    bool mEnabled = false;
+};
+
+class BluetoothLe : public BnBluetoothLe {
+  public:
+    BluetoothLe() = default;
+
+  private:
+    ndk::ScopedAStatus isEnabled(bool* _aidl_return) override;
+    ndk::ScopedAStatus setEnabled(bool in_enabled) override;
+    ndk::ScopedAStatus supportsOffloadReconfiguration(bool* _aidl_return) override;
+    ndk::ScopedAStatus reconfigureOffload(
+            const std::vector<::aidl::android::hardware::audio::core::VendorParameter>&
+                    in_parameters) override;
+
+    bool mEnabled = false;
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Config.h b/audio/aidl/default/include/core-impl/Config.h
new file mode 100644
index 0000000..96a6cb9
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/Config.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/core/BnConfig.h>
+#include <system/audio_config.h>
+
+#include "AudioPolicyConfigXmlConverter.h"
+#include "EngineConfigXmlConverter.h"
+
+namespace aidl::android::hardware::audio::core {
+static const std::string kEngineConfigFileName = "audio_policy_engine_configuration.xml";
+
+class Config : public BnConfig {
+    ndk::ScopedAStatus getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) override;
+    ndk::ScopedAStatus getEngineConfig(
+            aidl::android::media::audio::common::AudioHalEngineConfig* _aidl_return) override;
+    internal::AudioPolicyConfigXmlConverter mAudioPolicyConverter{
+            ::android::audio_get_audio_policy_config_file()};
+    internal::EngineConfigXmlConverter mEngConfigConverter{
+            ::android::audio_find_readable_configuration_file(kEngineConfigFileName.c_str())};
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Configuration.h b/audio/aidl/default/include/core-impl/Configuration.h
new file mode 100644
index 0000000..70320e4
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/Configuration.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <aidl/android/hardware/audio/core/AudioPatch.h>
+#include <aidl/android/hardware/audio/core/AudioRoute.h>
+#include <aidl/android/media/audio/common/AudioPort.h>
+#include <aidl/android/media/audio/common/AudioPortConfig.h>
+#include <aidl/android/media/audio/common/MicrophoneInfo.h>
+
+namespace aidl::android::hardware::audio::core::internal {
+
+struct Configuration {
+    std::vector<::aidl::android::media::audio::common::MicrophoneInfo> microphones;
+    std::vector<::aidl::android::media::audio::common::AudioPort> ports;
+    std::vector<::aidl::android::media::audio::common::AudioPortConfig> portConfigs;
+    std::vector<::aidl::android::media::audio::common::AudioPortConfig> initialConfigs;
+    // Port id -> List of profiles to use when the device port state is set to 'connected'
+    // in connection simulation mode.
+    std::map<int32_t, std::vector<::aidl::android::media::audio::common::AudioProfile>>
+            connectedProfiles;
+    std::vector<AudioRoute> routes;
+    std::vector<AudioPatch> patches;
+    int32_t nextPortId = 1;
+    int32_t nextPatchId = 1;
+};
+
+std::unique_ptr<Configuration> getPrimaryConfiguration();
+std::unique_ptr<Configuration> getRSubmixConfiguration();
+std::unique_ptr<Configuration> getUsbConfiguration();
+
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h b/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h
new file mode 100644
index 0000000..b34441d
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/EngineConfigXmlConverter.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <unordered_map>
+
+#include <utils/Errors.h>
+
+#include <android_audio_policy_engine_configuration.h>
+#include <android_audio_policy_engine_configuration_enums.h>
+
+#include "core-impl/XmlConverter.h"
+
+namespace aidl::android::hardware::audio::core::internal {
+
+class EngineConfigXmlConverter {
+  public:
+    explicit EngineConfigXmlConverter(const std::string& configFilePath)
+        : mConverter(configFilePath, &::android::audio::policy::engine::configuration::read) {
+        if (mConverter.getXsdcConfig()) {
+            init();
+        }
+    }
+
+    std::string getError() const { return mConverter.getError(); }
+    ::android::status_t getStatus() const { return mConverter.getStatus(); }
+
+    ::aidl::android::media::audio::common::AudioHalEngineConfig& getAidlEngineConfig();
+
+  private:
+    const std::optional<::android::audio::policy::engine::configuration::Configuration>&
+    getXsdcConfig() {
+        return mConverter.getXsdcConfig();
+    }
+    void init();
+    void initProductStrategyMap();
+    ::aidl::android::media::audio::common::AudioAttributes convertAudioAttributesToAidl(
+            const ::android::audio::policy::engine::configuration::AttributesType&
+                    xsdcAudioAttributes);
+    ::aidl::android::media::audio::common::AudioHalAttributesGroup convertAttributesGroupToAidl(
+            const ::android::audio::policy::engine::configuration::AttributesGroup&
+                    xsdcAttributesGroup);
+    ::aidl::android::media::audio::common::AudioHalCapCriterion convertCapCriterionToAidl(
+            const ::android::audio::policy::engine::configuration::CriterionType& xsdcCriterion);
+    ::aidl::android::media::audio::common::AudioHalCapCriterionType convertCapCriterionTypeToAidl(
+            const ::android::audio::policy::engine::configuration::CriterionTypeType&
+                    xsdcCriterionType);
+    std::string convertCriterionTypeValueToAidl(
+            const ::android::audio::policy::engine::configuration::ValueType&
+                    xsdcCriterionTypeValue);
+    ::aidl::android::media::audio::common::AudioHalVolumeCurve::CurvePoint convertCurvePointToAidl(
+            const std::string& xsdcCurvePoint);
+    ::aidl::android::media::audio::common::AudioHalProductStrategy convertProductStrategyToAidl(
+            const ::android::audio::policy::engine::configuration::ProductStrategies::
+                    ProductStrategy& xsdcProductStrategy);
+    int convertProductStrategyNameToAidl(const std::string& xsdcProductStrategyName);
+    ::aidl::android::media::audio::common::AudioHalVolumeCurve convertVolumeCurveToAidl(
+            const ::android::audio::policy::engine::configuration::Volume& xsdcVolumeCurve);
+    ::aidl::android::media::audio::common::AudioHalVolumeGroup convertVolumeGroupToAidl(
+            const ::android::audio::policy::engine::configuration::VolumeGroupsType::VolumeGroup&
+                    xsdcVolumeGroup);
+
+    ::aidl::android::media::audio::common::AudioHalEngineConfig mAidlEngineConfig;
+    XmlConverter<::android::audio::policy::engine::configuration::Configuration> mConverter;
+    std::unordered_map<std::string,
+                       ::android::audio::policy::engine::configuration::AttributesRefType>
+            mAttributesReferenceMap;
+    std::unordered_map<std::string, ::android::audio::policy::engine::configuration::VolumeRef>
+            mVolumesReferenceMap;
+    std::unordered_map<std::string, int> mProductStrategyMap;
+    int mNextVendorStrategy = ::aidl::android::media::audio::common::AudioHalProductStrategy::
+            VENDOR_STRATEGY_ID_START;
+    std::optional<int> mDefaultProductStrategyId;
+};
+
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
new file mode 100644
index 0000000..83ecfaa
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <map>
+#include <memory>
+#include <set>
+
+#include <aidl/android/hardware/audio/core/BnModule.h>
+
+#include "core-impl/Configuration.h"
+#include "core-impl/Stream.h"
+
+namespace aidl::android::hardware::audio::core {
+
+class Module : public BnModule {
+  public:
+    // This value is used for all AudioPatches and reported by all streams.
+    static constexpr int32_t kLatencyMs = 10;
+    enum Type : int { DEFAULT, R_SUBMIX, USB };
+
+    explicit Module(Type type) : mType(type) {}
+
+    static std::shared_ptr<Module> createInstance(Type type);
+    static StreamIn::CreateInstance getStreamInCreator(Type type);
+    static StreamOut::CreateInstance getStreamOutCreator(Type type);
+
+  private:
+    struct VendorDebug {
+        static const std::string kForceTransientBurstName;
+        static const std::string kForceSynchronousDrainName;
+        bool forceTransientBurst = false;
+        bool forceSynchronousDrain = false;
+    };
+    // Helper used for interfaces that require a persistent instance. We hold them via a strong
+    // pointer. The binder token is retained for a call to 'setMinSchedulerPolicy'.
+    template <class C>
+    struct ChildInterface : private std::pair<std::shared_ptr<C>, ndk::SpAIBinder> {
+        ChildInterface() {}
+        ChildInterface& operator=(const std::shared_ptr<C>& c) {
+            return operator=(std::shared_ptr<C>(c));
+        }
+        ChildInterface& operator=(std::shared_ptr<C>&& c) {
+            this->first = std::move(c);
+            this->second = this->first->asBinder();
+            AIBinder_setMinSchedulerPolicy(this->second.get(), SCHED_NORMAL,
+                                           ANDROID_PRIORITY_AUDIO);
+            return *this;
+        }
+        explicit operator bool() const { return !!this->first; }
+        C& operator*() const { return *(this->first); }
+        C* operator->() const { return this->first; }
+        std::shared_ptr<C> getPtr() const { return this->first; }
+    };
+
+    ndk::ScopedAStatus setModuleDebug(
+            const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
+    ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
+    ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
+    ndk::ScopedAStatus getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _aidl_return) override;
+    ndk::ScopedAStatus getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) override;
+    ndk::ScopedAStatus connectExternalDevice(
+            const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
+            ::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
+    ndk::ScopedAStatus disconnectExternalDevice(int32_t in_portId) override;
+    ndk::ScopedAStatus getAudioPatches(std::vector<AudioPatch>* _aidl_return) override;
+    ndk::ScopedAStatus getAudioPort(
+            int32_t in_portId,
+            ::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
+    ndk::ScopedAStatus getAudioPortConfigs(
+            std::vector<::aidl::android::media::audio::common::AudioPortConfig>* _aidl_return)
+            override;
+    ndk::ScopedAStatus getAudioPorts(
+            std::vector<::aidl::android::media::audio::common::AudioPort>* _aidl_return) override;
+    ndk::ScopedAStatus getAudioRoutes(std::vector<AudioRoute>* _aidl_return) override;
+    ndk::ScopedAStatus getAudioRoutesForAudioPort(
+            int32_t in_portId,
+            std::vector<::aidl::android::hardware::audio::core::AudioRoute>* _aidl_return) override;
+    ndk::ScopedAStatus openInputStream(
+            const ::aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments&
+                    in_args,
+            ::aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn* _aidl_return)
+            override;
+    ndk::ScopedAStatus openOutputStream(
+            const ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments&
+                    in_args,
+            ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn* _aidl_return)
+            override;
+    ndk::ScopedAStatus getSupportedPlaybackRateFactors(
+            SupportedPlaybackRateFactors* _aidl_return) override;
+    ndk::ScopedAStatus setAudioPatch(const AudioPatch& in_requested,
+                                     AudioPatch* _aidl_return) override;
+    ndk::ScopedAStatus setAudioPortConfig(
+            const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
+            ::aidl::android::media::audio::common::AudioPortConfig* out_suggested,
+            bool* _aidl_return) override;
+    ndk::ScopedAStatus resetAudioPatch(int32_t in_patchId) override;
+    ndk::ScopedAStatus resetAudioPortConfig(int32_t in_portConfigId) override;
+    ndk::ScopedAStatus getMasterMute(bool* _aidl_return) override;
+    ndk::ScopedAStatus setMasterMute(bool in_mute) override;
+    ndk::ScopedAStatus getMasterVolume(float* _aidl_return) override;
+    ndk::ScopedAStatus setMasterVolume(float in_volume) override;
+    ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
+    ndk::ScopedAStatus setMicMute(bool in_mute) override;
+    ndk::ScopedAStatus getMicrophones(
+            std::vector<::aidl::android::media::audio::common::MicrophoneInfo>* _aidl_return)
+            override;
+    ndk::ScopedAStatus updateAudioMode(
+            ::aidl::android::media::audio::common::AudioMode in_mode) override;
+    ndk::ScopedAStatus updateScreenRotation(
+            ::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override;
+    ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override;
+    ndk::ScopedAStatus getSoundDose(std::shared_ptr<sounddose::ISoundDose>* _aidl_return) override;
+    ndk::ScopedAStatus generateHwAvSyncId(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids,
+                                           std::vector<VendorParameter>* _aidl_return) override;
+    ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
+                                           bool in_async) override;
+    ndk::ScopedAStatus addDeviceEffect(
+            int32_t in_portConfigId,
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect)
+            override;
+    ndk::ScopedAStatus removeDeviceEffect(
+            int32_t in_portConfigId,
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect)
+            override;
+    ndk::ScopedAStatus getMmapPolicyInfos(
+            ::aidl::android::media::audio::common::AudioMMapPolicyType mmapPolicyType,
+            std::vector<::aidl::android::media::audio::common::AudioMMapPolicyInfo>* _aidl_return)
+            override;
+    ndk::ScopedAStatus supportsVariableLatency(bool* _aidl_return) override;
+    ndk::ScopedAStatus getAAudioMixerBurstCount(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override;
+
+    void cleanUpPatch(int32_t patchId);
+    ndk::ScopedAStatus createStreamContext(
+            int32_t in_portConfigId, int64_t in_bufferSizeFrames,
+            std::shared_ptr<IStreamCallback> asyncCallback,
+            std::shared_ptr<IStreamOutEventCallback> outEventCallback,
+            ::aidl::android::hardware::audio::core::StreamContext* out_context);
+    std::vector<::aidl::android::media::audio::common::AudioDevice> findConnectedDevices(
+            int32_t portConfigId);
+    std::set<int32_t> findConnectedPortConfigIds(int32_t portConfigId);
+    ndk::ScopedAStatus findPortIdForNewStream(
+            int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port);
+    internal::Configuration& getConfig();
+    template <typename C>
+    std::set<int32_t> portIdsFromPortConfigIds(C portConfigIds);
+    void registerPatch(const AudioPatch& patch);
+    void updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch);
+    bool isMmapSupported();
+
+    // This value is used for all AudioPatches.
+    static constexpr int32_t kMinimumStreamBufferSizeFrames = 256;
+    // The maximum stream buffer size is 1 GiB = 2 ** 30 bytes;
+    static constexpr int32_t kMaximumStreamBufferSizeBytes = 1 << 30;
+
+    const Type mType;
+    std::unique_ptr<internal::Configuration> mConfig;
+    ModuleDebug mDebug;
+    VendorDebug mVendorDebug;
+    ChildInterface<ITelephony> mTelephony;
+    ChildInterface<IBluetooth> mBluetooth;
+    ChildInterface<IBluetoothA2dp> mBluetoothA2dp;
+    ChildInterface<IBluetoothLe> mBluetoothLe;
+    // ids of device ports created at runtime via 'connectExternalDevice'.
+    // Also stores ids of mix ports with dynamic profiles which got populated from the connected
+    // port.
+    std::map<int32_t, std::vector<int32_t>> mConnectedDevicePorts;
+    Streams mStreams;
+    // Maps port ids and port config ids to patch ids.
+    // Multimap because both ports and configs can be used by multiple patches.
+    std::multimap<int32_t, int32_t> mPatches;
+    bool mMicMute = false;
+    ChildInterface<sounddose::ISoundDose> mSoundDose;
+    std::optional<bool> mIsMmapSupported;
+
+  protected:
+    // If the module is unable to populate the connected device port correctly, the returned error
+    // code must correspond to the errors of `IModule.connectedExternalDevice` method.
+    virtual ndk::ScopedAStatus populateConnectedDevicePort(
+            ::aidl::android::media::audio::common::AudioPort* audioPort);
+    // If the module finds that the patch endpoints configurations are not matched, the returned
+    // error code must correspond to the errors of `IModule.setAudioPatch` method.
+    virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
+            const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
+            const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks);
+    virtual void onExternalDeviceConnectionChanged(
+            const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected);
+    virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute);
+    virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume);
+
+    bool mMasterMute = false;
+    float mMasterVolume = 1.0f;
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/ModuleUsb.h b/audio/aidl/default/include/core-impl/ModuleUsb.h
new file mode 100644
index 0000000..1aa2244
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/ModuleUsb.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "core-impl/Module.h"
+
+namespace aidl::android::hardware::audio::core {
+
+class ModuleUsb : public Module {
+  public:
+    explicit ModuleUsb(Module::Type type) : Module(type) {}
+
+  private:
+    // IModule interfaces
+    ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
+    ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
+    ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
+    ndk::ScopedAStatus setMicMute(bool in_mute) override;
+
+    // Module interfaces
+    ndk::ScopedAStatus populateConnectedDevicePort(
+            ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+    ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
+            const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
+            const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
+            override;
+    void onExternalDeviceConnectionChanged(
+            const ::aidl::android::media::audio::common::AudioPort& audioPort,
+            bool connected) override;
+    ndk::ScopedAStatus onMasterMuteChanged(bool mute) override;
+    ndk::ScopedAStatus onMasterVolumeChanged(float volume) override;
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/SoundDose.h b/audio/aidl/default/include/core-impl/SoundDose.h
new file mode 100644
index 0000000..2a069d9
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/SoundDose.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <mutex>
+
+#include <aidl/android/hardware/audio/core/sounddose/BnSoundDose.h>
+#include <aidl/android/media/audio/common/AudioDevice.h>
+
+using aidl::android::media::audio::common::AudioDevice;
+
+namespace aidl::android::hardware::audio::core::sounddose {
+
+class SoundDose : public BnSoundDose {
+  public:
+    SoundDose() : mRs2Value(DEFAULT_MAX_RS2){};
+
+    ndk::ScopedAStatus setOutputRs2UpperBound(float in_rs2ValueDbA) override;
+    ndk::ScopedAStatus getOutputRs2UpperBound(float* _aidl_return) override;
+    ndk::ScopedAStatus registerSoundDoseCallback(
+            const std::shared_ptr<ISoundDose::IHalSoundDoseCallback>& in_callback) override;
+
+  private:
+    std::shared_ptr<ISoundDose::IHalSoundDoseCallback> mCallback;
+    float mRs2Value;
+};
+
+}  // namespace aidl::android::hardware::audio::core::sounddose
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
new file mode 100644
index 0000000..65680df
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -0,0 +1,582 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <atomic>
+#include <chrono>
+#include <cstdlib>
+#include <map>
+#include <memory>
+#include <optional>
+#include <variant>
+
+#include <StreamWorker.h>
+#include <aidl/android/hardware/audio/common/SinkMetadata.h>
+#include <aidl/android/hardware/audio/common/SourceMetadata.h>
+#include <aidl/android/hardware/audio/core/BnStreamCommon.h>
+#include <aidl/android/hardware/audio/core/BnStreamIn.h>
+#include <aidl/android/hardware/audio/core/BnStreamOut.h>
+#include <aidl/android/hardware/audio/core/IStreamCallback.h>
+#include <aidl/android/hardware/audio/core/IStreamOutEventCallback.h>
+#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
+#include <aidl/android/media/audio/common/AudioDevice.h>
+#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
+#include <aidl/android/media/audio/common/MicrophoneInfo.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/thread_defs.h>
+#include <utils/Errors.h>
+
+#include "core-impl/utils.h"
+
+namespace aidl::android::hardware::audio::core {
+
+// This class is similar to StreamDescriptor, but unlike
+// the descriptor, it actually owns the objects implementing
+// data exchange: FMQs etc, whereas StreamDescriptor only
+// contains their descriptors.
+class StreamContext {
+  public:
+    typedef ::android::AidlMessageQueue<
+            StreamDescriptor::Command,
+            ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+            CommandMQ;
+    typedef ::android::AidlMessageQueue<
+            StreamDescriptor::Reply, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+            ReplyMQ;
+    typedef ::android::AidlMessageQueue<
+            int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+            DataMQ;
+
+    // Ensure that this value is not used by any of StreamDescriptor.State enums
+    static constexpr int32_t STATE_CLOSED = -1;
+
+    struct DebugParameters {
+        // An extra delay for transient states, in ms.
+        int transientStateDelayMs = 0;
+        // Force the "burst" command to move the SM to the TRANSFERRING state.
+        bool forceTransientBurst = false;
+        // Force the "drain" command to be synchronous, going directly to the IDLE state.
+        bool forceSynchronousDrain = false;
+    };
+
+    StreamContext() = default;
+    StreamContext(std::unique_ptr<CommandMQ> commandMQ, std::unique_ptr<ReplyMQ> replyMQ,
+                  const ::aidl::android::media::audio::common::AudioFormatDescription& format,
+                  const ::aidl::android::media::audio::common::AudioChannelLayout& channelLayout,
+                  int sampleRate, std::unique_ptr<DataMQ> dataMQ,
+                  std::shared_ptr<IStreamCallback> asyncCallback,
+                  std::shared_ptr<IStreamOutEventCallback> outEventCallback,
+                  DebugParameters debugParameters)
+        : mCommandMQ(std::move(commandMQ)),
+          mInternalCommandCookie(std::rand()),
+          mReplyMQ(std::move(replyMQ)),
+          mFormat(format),
+          mChannelLayout(channelLayout),
+          mSampleRate(sampleRate),
+          mDataMQ(std::move(dataMQ)),
+          mAsyncCallback(asyncCallback),
+          mOutEventCallback(outEventCallback),
+          mDebugParameters(debugParameters) {}
+    StreamContext(StreamContext&& other)
+        : mCommandMQ(std::move(other.mCommandMQ)),
+          mInternalCommandCookie(other.mInternalCommandCookie),
+          mReplyMQ(std::move(other.mReplyMQ)),
+          mFormat(other.mFormat),
+          mChannelLayout(other.mChannelLayout),
+          mSampleRate(other.mSampleRate),
+          mDataMQ(std::move(other.mDataMQ)),
+          mAsyncCallback(std::move(other.mAsyncCallback)),
+          mOutEventCallback(std::move(other.mOutEventCallback)),
+          mDebugParameters(std::move(other.mDebugParameters)) {}
+    StreamContext& operator=(StreamContext&& other) {
+        mCommandMQ = std::move(other.mCommandMQ);
+        mInternalCommandCookie = other.mInternalCommandCookie;
+        mReplyMQ = std::move(other.mReplyMQ);
+        mFormat = std::move(other.mFormat);
+        mChannelLayout = std::move(other.mChannelLayout);
+        mSampleRate = other.mSampleRate;
+        mDataMQ = std::move(other.mDataMQ);
+        mAsyncCallback = std::move(other.mAsyncCallback);
+        mOutEventCallback = std::move(other.mOutEventCallback);
+        mDebugParameters = std::move(other.mDebugParameters);
+        return *this;
+    }
+
+    void fillDescriptor(StreamDescriptor* desc);
+    std::shared_ptr<IStreamCallback> getAsyncCallback() const { return mAsyncCallback; }
+    ::aidl::android::media::audio::common::AudioChannelLayout getChannelLayout() const {
+        return mChannelLayout;
+    }
+    CommandMQ* getCommandMQ() const { return mCommandMQ.get(); }
+    DataMQ* getDataMQ() const { return mDataMQ.get(); }
+    ::aidl::android::media::audio::common::AudioFormatDescription getFormat() const {
+        return mFormat;
+    }
+    bool getForceTransientBurst() const { return mDebugParameters.forceTransientBurst; }
+    bool getForceSynchronousDrain() const { return mDebugParameters.forceSynchronousDrain; }
+    size_t getFrameSize() const;
+    int getInternalCommandCookie() const { return mInternalCommandCookie; }
+    std::shared_ptr<IStreamOutEventCallback> getOutEventCallback() const {
+        return mOutEventCallback;
+    }
+    ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
+    int getTransientStateDelayMs() const { return mDebugParameters.transientStateDelayMs; }
+    int getSampleRate() const { return mSampleRate; }
+    bool isValid() const;
+    void reset();
+
+  private:
+    std::unique_ptr<CommandMQ> mCommandMQ;
+    int mInternalCommandCookie;  // The value used to confirm that the command was posted internally
+    std::unique_ptr<ReplyMQ> mReplyMQ;
+    ::aidl::android::media::audio::common::AudioFormatDescription mFormat;
+    ::aidl::android::media::audio::common::AudioChannelLayout mChannelLayout;
+    int mSampleRate;
+    std::unique_ptr<DataMQ> mDataMQ;
+    std::shared_ptr<IStreamCallback> mAsyncCallback;
+    std::shared_ptr<IStreamOutEventCallback> mOutEventCallback;  // Only used by output streams
+    DebugParameters mDebugParameters;
+};
+
+struct DriverInterface {
+    using CreateInstance = std::function<DriverInterface*(const StreamContext&)>;
+    virtual ~DriverInterface() = default;
+    // This function is called once, on the main thread, before starting the worker thread.
+    virtual ::android::status_t init() = 0;
+    // This function is called from Binder pool thread. It must be done in a thread-safe manner
+    // if this method and other methods in this interface share data.
+    virtual ::android::status_t setConnectedDevices(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>&
+                    connectedDevices) = 0;
+    // All the functions below are called on the worker thread.
+    virtual ::android::status_t drain(StreamDescriptor::DrainMode mode) = 0;
+    virtual ::android::status_t flush() = 0;
+    virtual ::android::status_t pause() = 0;
+    virtual ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+                                         int32_t* latencyMs) = 0;
+    virtual ::android::status_t standby() = 0;
+};
+
+class StreamWorkerCommonLogic : public ::android::hardware::audio::common::StreamLogic {
+  public:
+    bool isClosed() const {
+        return static_cast<int32_t>(mState.load()) == StreamContext::STATE_CLOSED;
+    }
+    void setClosed() { mState = static_cast<StreamDescriptor::State>(StreamContext::STATE_CLOSED); }
+    void setIsConnected(bool connected) { mIsConnected = connected; }
+
+  protected:
+    using DataBufferElement = int8_t;
+
+    StreamWorkerCommonLogic(const StreamContext& context, DriverInterface* driver)
+        : mDriver(driver),
+          mInternalCommandCookie(context.getInternalCommandCookie()),
+          mFrameSize(context.getFrameSize()),
+          mCommandMQ(context.getCommandMQ()),
+          mReplyMQ(context.getReplyMQ()),
+          mDataMQ(context.getDataMQ()),
+          mAsyncCallback(context.getAsyncCallback()),
+          mTransientStateDelayMs(context.getTransientStateDelayMs()),
+          mForceTransientBurst(context.getForceTransientBurst()),
+          mForceSynchronousDrain(context.getForceSynchronousDrain()) {}
+    std::string init() override;
+    void populateReply(StreamDescriptor::Reply* reply, bool isConnected) const;
+    void populateReplyWrongState(StreamDescriptor::Reply* reply,
+                                 const StreamDescriptor::Command& command) const;
+    void switchToTransientState(StreamDescriptor::State state) {
+        mState = state;
+        mTransientStateStart = std::chrono::steady_clock::now();
+    }
+
+    DriverInterface* const mDriver;
+    // Atomic fields are used both by the main and worker threads.
+    std::atomic<bool> mIsConnected = false;
+    static_assert(std::atomic<StreamDescriptor::State>::is_always_lock_free);
+    std::atomic<StreamDescriptor::State> mState = StreamDescriptor::State::STANDBY;
+    // All fields are used on the worker thread only.
+    const int mInternalCommandCookie;
+    const size_t mFrameSize;
+    StreamContext::CommandMQ* const mCommandMQ;
+    StreamContext::ReplyMQ* const mReplyMQ;
+    StreamContext::DataMQ* const mDataMQ;
+    std::shared_ptr<IStreamCallback> mAsyncCallback;
+    const std::chrono::duration<int, std::milli> mTransientStateDelayMs;
+    std::chrono::time_point<std::chrono::steady_clock> mTransientStateStart;
+    const bool mForceTransientBurst;
+    const bool mForceSynchronousDrain;
+    // We use an array and the "size" field instead of a vector to be able to detect
+    // memory allocation issues.
+    std::unique_ptr<DataBufferElement[]> mDataBuffer;
+    size_t mDataBufferSize;
+    long mFrameCount = 0;
+};
+
+// This interface is used to decouple stream implementations from a concrete StreamWorker
+// implementation.
+struct StreamWorkerInterface {
+    using CreateInstance = std::function<StreamWorkerInterface*(const StreamContext& context,
+                                                                DriverInterface* driver)>;
+    virtual ~StreamWorkerInterface() = default;
+    virtual bool isClosed() const = 0;
+    virtual void setIsConnected(bool isConnected) = 0;
+    virtual void setClosed() = 0;
+    virtual bool start() = 0;
+    virtual void stop() = 0;
+};
+
+template <class WorkerLogic>
+class StreamWorkerImpl : public StreamWorkerInterface,
+                         public ::android::hardware::audio::common::StreamWorker<WorkerLogic> {
+    using WorkerImpl = ::android::hardware::audio::common::StreamWorker<WorkerLogic>;
+
+  public:
+    StreamWorkerImpl(const StreamContext& context, DriverInterface* driver)
+        : WorkerImpl(context, driver) {}
+    bool isClosed() const override { return WorkerImpl::isClosed(); }
+    void setIsConnected(bool isConnected) override { WorkerImpl::setIsConnected(isConnected); }
+    void setClosed() override { WorkerImpl::setClosed(); }
+    bool start() override {
+        return WorkerImpl::start(WorkerImpl::kThreadName, ANDROID_PRIORITY_AUDIO);
+    }
+    void stop() override { return WorkerImpl::stop(); }
+};
+
+class StreamInWorkerLogic : public StreamWorkerCommonLogic {
+  public:
+    static const std::string kThreadName;
+    StreamInWorkerLogic(const StreamContext& context, DriverInterface* driver)
+        : StreamWorkerCommonLogic(context, driver) {}
+
+  protected:
+    Status cycle() override;
+
+  private:
+    bool read(size_t clientSize, StreamDescriptor::Reply* reply);
+};
+using StreamInWorker = StreamWorkerImpl<StreamInWorkerLogic>;
+
+class StreamOutWorkerLogic : public StreamWorkerCommonLogic {
+  public:
+    static const std::string kThreadName;
+    StreamOutWorkerLogic(const StreamContext& context, DriverInterface* driver)
+        : StreamWorkerCommonLogic(context, driver), mEventCallback(context.getOutEventCallback()) {}
+
+  protected:
+    Status cycle() override;
+
+  private:
+    bool write(size_t clientSize, StreamDescriptor::Reply* reply);
+
+    std::shared_ptr<IStreamOutEventCallback> mEventCallback;
+};
+using StreamOutWorker = StreamWorkerImpl<StreamOutWorkerLogic>;
+
+// This provides a C++ interface with methods of the IStreamCommon Binder interface,
+// but intentionally does not inherit from it. This is needed to avoid inheriting
+// StreamIn and StreamOut from two Binder interface classes, as these parts of the class
+// will be reference counted separately.
+//
+// The implementation of these common methods is in the StreamCommonImpl template class.
+struct StreamCommonInterface {
+    virtual ~StreamCommonInterface() = default;
+    virtual ndk::ScopedAStatus close() = 0;
+    virtual ndk::ScopedAStatus prepareToClose() = 0;
+    virtual ndk::ScopedAStatus updateHwAvSyncId(int32_t in_hwAvSyncId) = 0;
+    virtual ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids,
+                                                   std::vector<VendorParameter>* _aidl_return) = 0;
+    virtual ndk::ScopedAStatus setVendorParameters(
+            const std::vector<VendorParameter>& in_parameters, bool in_async) = 0;
+    virtual ndk::ScopedAStatus addEffect(
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&
+                    in_effect) = 0;
+    virtual ndk::ScopedAStatus removeEffect(
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&
+                    in_effect) = 0;
+};
+
+class StreamCommon : public BnStreamCommon {
+  public:
+    explicit StreamCommon(const std::shared_ptr<StreamCommonInterface>& delegate)
+        : mDelegate(delegate) {}
+
+  private:
+    ndk::ScopedAStatus close() override {
+        auto delegate = mDelegate.lock();
+        return delegate != nullptr ? delegate->close()
+                                   : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    ndk::ScopedAStatus prepareToClose() override {
+        auto delegate = mDelegate.lock();
+        return delegate != nullptr ? delegate->prepareToClose()
+                                   : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    ndk::ScopedAStatus updateHwAvSyncId(int32_t in_hwAvSyncId) override {
+        auto delegate = mDelegate.lock();
+        return delegate != nullptr ? delegate->updateHwAvSyncId(in_hwAvSyncId)
+                                   : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids,
+                                           std::vector<VendorParameter>* _aidl_return) override {
+        auto delegate = mDelegate.lock();
+        return delegate != nullptr ? delegate->getVendorParameters(in_ids, _aidl_return)
+                                   : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
+                                           bool in_async) override {
+        auto delegate = mDelegate.lock();
+        return delegate != nullptr ? delegate->setVendorParameters(in_parameters, in_async)
+                                   : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    ndk::ScopedAStatus addEffect(
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect)
+            override {
+        auto delegate = mDelegate.lock();
+        return delegate != nullptr ? delegate->addEffect(in_effect)
+                                   : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    ndk::ScopedAStatus removeEffect(
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect)
+            override {
+        auto delegate = mDelegate.lock();
+        return delegate != nullptr ? delegate->removeEffect(in_effect)
+                                   : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    // It is possible that on the client side the proxy for IStreamCommon will outlive
+    // the IStream* instance, and the server side IStream* instance will get destroyed
+    // while this IStreamCommon instance is still alive.
+    std::weak_ptr<StreamCommonInterface> mDelegate;
+};
+
+template <class Metadata>
+class StreamCommonImpl : public StreamCommonInterface {
+  public:
+    ndk::ScopedAStatus close() override;
+    ndk::ScopedAStatus prepareToClose() override;
+    ndk::ScopedAStatus updateHwAvSyncId(int32_t in_hwAvSyncId) override;
+    ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids,
+                                           std::vector<VendorParameter>* _aidl_return) override;
+    ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
+                                           bool in_async) override;
+    ndk::ScopedAStatus addEffect(
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect)
+            override;
+    ndk::ScopedAStatus removeEffect(
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect)
+            override;
+
+    ndk::ScopedAStatus getStreamCommon(std::shared_ptr<IStreamCommon>* _aidl_return);
+    ndk::ScopedAStatus init() {
+        return mWorker->start() ? ndk::ScopedAStatus::ok()
+                                : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    bool isClosed() const { return mWorker->isClosed(); }
+    void setIsConnected(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
+        mWorker->setIsConnected(!devices.empty());
+        mConnectedDevices = devices;
+        mDriver->setConnectedDevices(devices);
+    }
+    ndk::ScopedAStatus updateMetadata(const Metadata& metadata);
+
+  protected:
+    StreamCommonImpl(const Metadata& metadata, StreamContext&& context,
+                     const DriverInterface::CreateInstance& createDriver,
+                     const StreamWorkerInterface::CreateInstance& createWorker)
+        : mMetadata(metadata),
+          mContext(std::move(context)),
+          mDriver(createDriver(mContext)),
+          mWorker(createWorker(mContext, mDriver.get())) {}
+    ~StreamCommonImpl();
+    void stopWorker();
+    void createStreamCommon(const std::shared_ptr<StreamCommonInterface>& delegate);
+
+    std::shared_ptr<StreamCommon> mCommon;
+    ndk::SpAIBinder mCommonBinder;
+    Metadata mMetadata;
+    StreamContext mContext;
+    std::unique_ptr<DriverInterface> mDriver;
+    std::unique_ptr<StreamWorkerInterface> mWorker;
+    std::vector<::aidl::android::media::audio::common::AudioDevice> mConnectedDevices;
+};
+
+class StreamIn : public StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata>,
+                 public BnStreamIn {
+    ndk::ScopedAStatus getStreamCommon(std::shared_ptr<IStreamCommon>* _aidl_return) override {
+        return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata>::
+                getStreamCommon(_aidl_return);
+    }
+    ndk::ScopedAStatus getActiveMicrophones(
+            std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
+            override;
+    ndk::ScopedAStatus getMicrophoneDirection(MicrophoneDirection* _aidl_return) override;
+    ndk::ScopedAStatus setMicrophoneDirection(MicrophoneDirection in_direction) override;
+    ndk::ScopedAStatus getMicrophoneFieldDimension(float* _aidl_return) override;
+    ndk::ScopedAStatus setMicrophoneFieldDimension(float in_zoom) override;
+    ndk::ScopedAStatus updateMetadata(const ::aidl::android::hardware::audio::common::SinkMetadata&
+                                              in_sinkMetadata) override {
+        return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata>::
+                updateMetadata(in_sinkMetadata);
+    }
+    ndk::ScopedAStatus getHwGain(std::vector<float>* _aidl_return) override;
+    ndk::ScopedAStatus setHwGain(const std::vector<float>& in_channelGains) override;
+
+  protected:
+    friend class ndk::SharedRefBase;
+
+    static ndk::ScopedAStatus initInstance(const std::shared_ptr<StreamIn>& stream);
+
+    StreamIn(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+             StreamContext&& context, const DriverInterface::CreateInstance& createDriver,
+             const StreamWorkerInterface::CreateInstance& createWorker,
+             const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
+    void createStreamCommon(const std::shared_ptr<StreamIn>& myPtr) {
+        StreamCommonImpl<
+                ::aidl::android::hardware::audio::common::SinkMetadata>::createStreamCommon(myPtr);
+    }
+
+    const std::map<::aidl::android::media::audio::common::AudioDevice, std::string> mMicrophones;
+
+  public:
+    using CreateInstance = std::function<ndk::ScopedAStatus(
+            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
+            std::shared_ptr<StreamIn>* result)>;
+};
+
+class StreamOut : public StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>,
+                  public BnStreamOut {
+    ndk::ScopedAStatus getStreamCommon(std::shared_ptr<IStreamCommon>* _aidl_return) override {
+        return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
+                getStreamCommon(_aidl_return);
+    }
+    ndk::ScopedAStatus updateMetadata(
+            const ::aidl::android::hardware::audio::common::SourceMetadata& in_sourceMetadata)
+            override {
+        return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
+                updateMetadata(in_sourceMetadata);
+    }
+    ndk::ScopedAStatus updateOffloadMetadata(
+            const ::aidl::android::hardware::audio::common::AudioOffloadMetadata&
+                    in_offloadMetadata) override;
+    ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
+    ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;
+    ndk::ScopedAStatus getAudioDescriptionMixLevel(float* _aidl_return) override;
+    ndk::ScopedAStatus setAudioDescriptionMixLevel(float in_leveldB) override;
+    ndk::ScopedAStatus getDualMonoMode(
+            ::aidl::android::media::audio::common::AudioDualMonoMode* _aidl_return) override;
+    ndk::ScopedAStatus setDualMonoMode(
+            ::aidl::android::media::audio::common::AudioDualMonoMode in_mode) override;
+    ndk::ScopedAStatus getRecommendedLatencyModes(
+            std::vector<::aidl::android::media::audio::common::AudioLatencyMode>* _aidl_return)
+            override;
+    ndk::ScopedAStatus setLatencyMode(
+            ::aidl::android::media::audio::common::AudioLatencyMode in_mode) override;
+    ndk::ScopedAStatus getPlaybackRateParameters(
+            ::aidl::android::media::audio::common::AudioPlaybackRate* _aidl_return) override;
+    ndk::ScopedAStatus setPlaybackRateParameters(
+            const ::aidl::android::media::audio::common::AudioPlaybackRate& in_playbackRate)
+            override;
+    ndk::ScopedAStatus selectPresentation(int32_t in_presentationId, int32_t in_programId) override;
+
+    void createStreamCommon(const std::shared_ptr<StreamOut>& myPtr) {
+        StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata>::
+                createStreamCommon(myPtr);
+    }
+
+  protected:
+    friend class ndk::SharedRefBase;
+
+    static ndk::ScopedAStatus initInstance(const std::shared_ptr<StreamOut>& stream);
+
+    StreamOut(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+              StreamContext&& context, const DriverInterface::CreateInstance& createDriver,
+              const StreamWorkerInterface::CreateInstance& createWorker,
+              const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                      offloadInfo);
+
+    std::optional<::aidl::android::media::audio::common::AudioOffloadInfo> mOffloadInfo;
+    std::optional<::aidl::android::hardware::audio::common::AudioOffloadMetadata> mOffloadMetadata;
+
+  public:
+    using CreateInstance = std::function<ndk::ScopedAStatus(
+            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+            StreamContext&& context,
+            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                    offloadInfo,
+            std::shared_ptr<StreamOut>* result)>;
+};
+
+class StreamWrapper {
+  public:
+    explicit StreamWrapper(const std::shared_ptr<StreamIn>& streamIn)
+        : mStream(streamIn), mStreamBinder(streamIn->asBinder()) {}
+    explicit StreamWrapper(const std::shared_ptr<StreamOut>& streamOut)
+        : mStream(streamOut), mStreamBinder(streamOut->asBinder()) {}
+    ndk::SpAIBinder getBinder() const { return mStreamBinder; }
+    bool isStreamOpen() const {
+        return std::visit(
+                [](auto&& ws) -> bool {
+                    auto s = ws.lock();
+                    return s && !s->isClosed();
+                },
+                mStream);
+    }
+    void setStreamIsConnected(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
+        std::visit(
+                [&](auto&& ws) {
+                    auto s = ws.lock();
+                    if (s) s->setIsConnected(devices);
+                },
+                mStream);
+    }
+
+  private:
+    std::variant<std::weak_ptr<StreamIn>, std::weak_ptr<StreamOut>> mStream;
+    ndk::SpAIBinder mStreamBinder;
+};
+
+class Streams {
+  public:
+    Streams() = default;
+    Streams(const Streams&) = delete;
+    Streams& operator=(const Streams&) = delete;
+    size_t count(int32_t id) {
+        // Streams do not remove themselves from the collection on close.
+        erase_if(mStreams, [](const auto& pair) { return !pair.second.isStreamOpen(); });
+        return mStreams.count(id);
+    }
+    void insert(int32_t portId, int32_t portConfigId, StreamWrapper sw) {
+        mStreams.insert(std::pair{portConfigId, sw});
+        mStreams.insert(std::pair{portId, std::move(sw)});
+    }
+    void setStreamIsConnected(
+            int32_t portConfigId,
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
+        if (auto it = mStreams.find(portConfigId); it != mStreams.end()) {
+            it->second.setStreamIsConnected(devices);
+        }
+    }
+
+  private:
+    // Maps port ids and port config ids to streams. Multimap because a port
+    // (not port config) can have multiple streams opened on it.
+    std::multimap<int32_t, StreamWrapper> mStreams;
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
new file mode 100644
index 0000000..df0182c
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "core-impl/Stream.h"
+
+namespace aidl::android::hardware::audio::core {
+
+class DriverStub : public DriverInterface {
+  public:
+    DriverStub(const StreamContext& context, bool isInput);
+    ::android::status_t init() override;
+    ::android::status_t setConnectedDevices(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
+            override;
+    ::android::status_t drain(StreamDescriptor::DrainMode) override;
+    ::android::status_t flush() override;
+    ::android::status_t pause() override;
+    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+                                 int32_t* latencyMs) override;
+    ::android::status_t standby() override;
+
+  private:
+    const size_t mFrameSizeBytes;
+    const int mSampleRate;
+    const bool mIsAsynchronous;
+    const bool mIsInput;
+};
+
+class StreamInStub final : public StreamIn {
+  public:
+    static ndk::ScopedAStatus createInstance(
+            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
+            std::shared_ptr<StreamIn>* result);
+
+  private:
+    friend class ndk::SharedRefBase;
+    StreamInStub(
+            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
+};
+
+class StreamOutStub final : public StreamOut {
+  public:
+    static ndk::ScopedAStatus createInstance(
+            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+            StreamContext&& context,
+            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                    offloadInfo,
+            std::shared_ptr<StreamOut>* result);
+
+  private:
+    friend class ndk::SharedRefBase;
+    StreamOutStub(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+                  StreamContext&& context,
+                  const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                          offloadInfo);
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/StreamUsb.h b/audio/aidl/default/include/core-impl/StreamUsb.h
new file mode 100644
index 0000000..36e64cb
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/StreamUsb.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <mutex>
+#include <vector>
+
+#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+
+#include "core-impl/Stream.h"
+
+extern "C" {
+#include <tinyalsa/pcm.h>
+#include "alsa_device_proxy.h"
+}
+
+namespace aidl::android::hardware::audio::core {
+
+class DriverUsb : public DriverInterface {
+  public:
+    DriverUsb(const StreamContext& context, bool isInput);
+    ::android::status_t init() override;
+    ::android::status_t setConnectedDevices(
+            const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
+            override;
+    ::android::status_t drain(StreamDescriptor::DrainMode) override;
+    ::android::status_t flush() override;
+    ::android::status_t pause() override;
+    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+                                 int32_t* latencyMs) override;
+    ::android::status_t standby() override;
+
+  private:
+    ::android::status_t exitStandby();
+
+    std::mutex mLock;
+
+    const size_t mFrameSizeBytes;
+    std::optional<struct pcm_config> mConfig;
+    const bool mIsInput;
+    // Cached device addresses for connected devices.
+    std::vector<::aidl::android::media::audio::common::AudioDeviceAddress> mConnectedDevices
+            GUARDED_BY(mLock);
+    std::vector<std::shared_ptr<alsa_device_proxy>> mAlsaDeviceProxies GUARDED_BY(mLock);
+    bool mIsStandby = true;
+};
+
+class StreamInUsb final : public StreamIn {
+    ndk::ScopedAStatus getActiveMicrophones(
+            std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
+            override;
+
+  public:
+    static ndk::ScopedAStatus createInstance(
+            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
+            std::shared_ptr<StreamIn>* result);
+
+  private:
+    friend class ndk::SharedRefBase;
+    StreamInUsb(
+            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+            StreamContext&& context,
+            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
+};
+
+class StreamOutUsb final : public StreamOut {
+  public:
+    static ndk::ScopedAStatus createInstance(
+            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+            StreamContext&& context,
+            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                    offloadInfo,
+            std::shared_ptr<StreamOut>* result);
+
+  private:
+    friend class ndk::SharedRefBase;
+    StreamOutUsb(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+                 StreamContext&& context,
+                 const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                         offloadInfo);
+
+    ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
+    ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;
+
+    int mChannelCount;
+    std::vector<float> mHwVolumes;
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Telephony.h b/audio/aidl/default/include/core-impl/Telephony.h
new file mode 100644
index 0000000..0f8e93f
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/Telephony.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_enums.h>
+
+#include <aidl/android/hardware/audio/core/BnTelephony.h>
+
+namespace aidl::android::hardware::audio::core {
+
+class Telephony : public BnTelephony {
+  public:
+    Telephony();
+
+  private:
+    ndk::ScopedAStatus getSupportedAudioModes(
+            std::vector<::aidl::android::media::audio::common::AudioMode>* _aidl_return) override;
+    ndk::ScopedAStatus switchAudioMode(
+            ::aidl::android::media::audio::common::AudioMode in_mode) override;
+    ndk::ScopedAStatus setTelecomConfig(const TelecomConfig& in_config,
+                                        TelecomConfig* _aidl_return) override;
+
+    const std::vector<::aidl::android::media::audio::common::AudioMode> mSupportedAudioModes = {
+            ::aidl::android::media::audio::common::AudioMode::NORMAL,
+            ::aidl::android::media::audio::common::AudioMode::RINGTONE,
+            ::aidl::android::media::audio::common::AudioMode::IN_CALL,
+            ::aidl::android::media::audio::common::AudioMode::IN_COMMUNICATION,
+            // Omit CALL_SCREEN for a better VTS coverage.
+    };
+    TelecomConfig mTelecomConfig;
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/XmlConverter.h b/audio/aidl/default/include/core-impl/XmlConverter.h
new file mode 100644
index 0000000..ec23edb
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/XmlConverter.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <optional>
+#include <string>
+#include <unordered_map>
+
+#include <system/audio_config.h>
+#include <utils/Errors.h>
+
+namespace aidl::android::hardware::audio::core::internal {
+
+template <typename T>
+class XmlConverter {
+  public:
+    XmlConverter(const std::string& configFilePath,
+                 std::function<std::optional<T>(const char*)> readXmlConfig)
+        : XmlConverter(configFilePath,
+                       ::android::audio_is_readable_configuration_file(configFilePath.c_str()),
+                       readXmlConfig) {}
+
+    const ::android::status_t& getStatus() const { return mStatus; }
+
+    const std::string& getError() const { return mErrorMessage; }
+
+    const std::optional<T>& getXsdcConfig() const { return mXsdcConfig; }
+
+  private:
+    XmlConverter(const std::string& configFilePath, const bool& isReadableConfigFile,
+                 const std::function<std::optional<T>(const char*)>& readXmlConfig)
+        : mXsdcConfig{isReadableConfigFile ? readXmlConfig(configFilePath.c_str()) : std::nullopt},
+          mStatus(mXsdcConfig ? ::android::OK : ::android::NO_INIT),
+          mErrorMessage(generateError(configFilePath, isReadableConfigFile, mStatus)) {}
+
+    static std::string generateError(const std::string& configFilePath,
+                                     const bool& isReadableConfigFile,
+                                     const ::android::status_t& status) {
+        std::string errorMessage;
+        if (status != ::android::OK) {
+            if (!isReadableConfigFile) {
+                errorMessage = "Could not read requested config file:" + configFilePath;
+            } else {
+                errorMessage = "Invalid config file: " + configFilePath;
+            }
+        }
+        return errorMessage;
+    }
+
+    const std::optional<T> mXsdcConfig;
+    const ::android::status_t mStatus;
+    const std::string mErrorMessage;
+};
+
+/**
+ * Converts a vector of an xsd wrapper type to a flat vector of the
+ * corresponding AIDL type.
+ *
+ * Wrapper types are used in order to have well-formed xIncludes. In the
+ * example below, Modules is the wrapper type for Module.
+ *     <Modules>
+ *         <Module> ... </Module>
+ *         <Module> ... </Module>
+ *     </Modules>
+ */
+template <typename W, typename X, typename A>
+static std::vector<A> convertWrappedCollectionToAidl(
+        const std::vector<W>& xsdcWrapperTypeVec,
+        std::function<const std::vector<X>&(const W&)> getInnerTypeVec,
+        std::function<A(const X&)> convertToAidl) {
+    std::vector<A> resultAidlTypeVec;
+    if (!xsdcWrapperTypeVec.empty()) {
+        /*
+         * xsdcWrapperTypeVec likely only contains one element; that is, it's
+         * likely that all the inner types that we need to convert are inside of
+         * xsdcWrapperTypeVec[0].
+         */
+        resultAidlTypeVec.reserve(getInnerTypeVec(xsdcWrapperTypeVec[0]).size());
+        for (const W& xsdcWrapperType : xsdcWrapperTypeVec) {
+            std::transform(getInnerTypeVec(xsdcWrapperType).begin(),
+                           getInnerTypeVec(xsdcWrapperType).end(),
+                           std::back_inserter(resultAidlTypeVec), convertToAidl);
+        }
+    }
+    return resultAidlTypeVec;
+}
+
+template <typename X, typename A>
+static std::vector<A> convertCollectionToAidl(const std::vector<X>& xsdcTypeVec,
+                                              std::function<A(const X&)> convertToAidl) {
+    std::vector<A> resultAidlTypeVec;
+    resultAidlTypeVec.reserve(xsdcTypeVec.size());
+    std::transform(xsdcTypeVec.begin(), xsdcTypeVec.end(), std::back_inserter(resultAidlTypeVec),
+                   convertToAidl);
+    return resultAidlTypeVec;
+}
+
+/**
+ * Generates a map of xsd references, keyed by reference name, given a
+ * vector of wrapper types for the reference.
+ *
+ * Wrapper types are used in order to have well-formed xIncludes. In the
+ * example below, Wrapper is the wrapper type for Reference.
+ *     <Wrapper>
+ *         <Reference> ... </Reference>
+ *         <Reference> ... </Reference>
+ *     </Wrapper>
+ */
+template <typename W, typename R>
+static std::unordered_map<std::string, R> generateReferenceMap(
+        const std::vector<W>& xsdcWrapperTypeVec) {
+    std::unordered_map<std::string, R> resultMap;
+    if (!xsdcWrapperTypeVec.empty()) {
+        /*
+         * xsdcWrapperTypeVec likely only contains one element; that is, it's
+         * likely that all the inner types that we need to convert are inside of
+         * xsdcWrapperTypeVec[0].
+         */
+        resultMap.reserve(xsdcWrapperTypeVec[0].getReference().size());
+        for (const W& xsdcWrapperType : xsdcWrapperTypeVec) {
+            for (const R& xsdcReference : xsdcWrapperType.getReference()) {
+                resultMap.insert({xsdcReference.getName(), xsdcReference});
+            }
+        }
+    }
+    return resultMap;
+}
+}  // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/utils.h b/audio/aidl/default/include/core-impl/utils.h
new file mode 100644
index 0000000..ae33227
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/utils.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <map>
+#include <set>
+#include <vector>
+
+namespace aidl::android::hardware::audio::core {
+
+// Return whether all the elements in the vector are unique.
+template <typename T>
+bool all_unique(const std::vector<T>& v) {
+    return std::set<T>(v.begin(), v.end()).size() == v.size();
+}
+
+// Erase all the specified elements from a map.
+template <typename C, typename V>
+auto erase_all(C& c, const V& keys) {
+    auto oldSize = c.size();
+    for (auto& k : keys) {
+        c.erase(k);
+    }
+    return oldSize - c.size();
+}
+
+// Erase all the elements in the container that satisfy the provided predicate.
+template <typename C, typename P>
+auto erase_if(C& c, P pred) {
+    auto oldSize = c.size();
+    for (auto it = c.begin(); it != c.end();) {
+        if (pred(*it)) {
+            it = c.erase(it);
+        } else {
+            ++it;
+        }
+    }
+    return oldSize - c.size();
+}
+
+// Erase all the elements in the map that have specified values.
+template <typename C, typename V>
+auto erase_all_values(C& c, const V& values) {
+    return erase_if(c, [values](const auto& pair) { return values.count(pair.second) != 0; });
+}
+
+// Return non-zero count of elements for any of the provided keys.
+template <typename M, typename V>
+size_t count_any(const M& m, const V& keys) {
+    for (auto& k : keys) {
+        if (size_t c = m.count(k); c != 0) return c;
+    }
+    return 0;
+}
+
+// Assuming that M is a map whose values have an 'id' field,
+// find an element with the specified id.
+template <typename M>
+auto findById(M& m, int32_t id) {
+    return std::find_if(m.begin(), m.end(), [&](const auto& p) { return p.second.id == id; });
+}
+
+// Assuming that the vector contains elements with an 'id' field,
+// find an element with the specified id.
+template <typename T>
+auto findById(std::vector<T>& v, int32_t id) {
+    return std::find_if(v.begin(), v.end(), [&](const auto& e) { return e.id == id; });
+}
+
+// Return elements from the vector that have specified ids, also
+// optionally return which ids were not found.
+template <typename T>
+std::vector<T*> selectByIds(std::vector<T>& v, const std::vector<int32_t>& ids,
+                            std::vector<int32_t>* missingIds = nullptr) {
+    std::vector<T*> result;
+    std::set<int32_t> idsSet(ids.begin(), ids.end());
+    for (size_t i = 0; i < v.size(); ++i) {
+        T& e = v[i];
+        if (idsSet.count(e.id) != 0) {
+            result.push_back(&v[i]);
+            idsSet.erase(e.id);
+        }
+    }
+    if (missingIds) {
+        *missingIds = std::vector(idsSet.begin(), idsSet.end());
+    }
+    return result;
+}
+
+// Assuming that M is a map whose keys' type is K and values' type is V,
+// return the corresponding value of the given key from the map or default
+// value if the key is not found.
+template <typename M, typename K, typename V>
+auto findValueOrDefault(const M& m, const K& key, V defaultValue) {
+    auto it = m.find(key);
+    return it == m.end() ? defaultValue : it->second;
+}
+
+// Assuming that M is a map whose keys' type is K, return the given key if it
+// is found from the map or default value.
+template <typename M, typename K>
+auto findKeyOrDefault(const M& m, const K& key, K defaultValue) {
+    auto it = m.find(key);
+    return it == m.end() ? defaultValue : key;
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
new file mode 100644
index 0000000..22cdb6b
--- /dev/null
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include <memory>
+#include <vector>
+
+#include <Utils.h>
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include "EffectTypes.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class EffectContext {
+  public:
+    typedef ::android::AidlMessageQueue<
+            IEffect::Status, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+            StatusMQ;
+    typedef ::android::AidlMessageQueue<
+            float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+            DataMQ;
+
+    EffectContext(size_t statusDepth, const Parameter::Common& common) {
+        auto& input = common.input;
+        auto& output = common.output;
+
+        LOG_ALWAYS_FATAL_IF(
+                input.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT,
+                "inputFormatNotFloat");
+        LOG_ALWAYS_FATAL_IF(output.base.format.pcm !=
+                                    aidl::android::media::audio::common::PcmType::FLOAT_32_BIT,
+                            "outputFormatNotFloat");
+        mInputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
+                input.base.format, input.base.channelMask);
+        mOutputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
+                output.base.format, output.base.channelMask);
+        // in/outBuffer size in float (FMQ data format defined for DataMQ)
+        size_t inBufferSizeInFloat = input.frameCount * mInputFrameSize / sizeof(float);
+        size_t outBufferSizeInFloat = output.frameCount * mOutputFrameSize / sizeof(float);
+
+        // only status FMQ use the EventFlag
+        mStatusMQ = std::make_shared<StatusMQ>(statusDepth, true /*configureEventFlagWord*/);
+        mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat);
+        mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat);
+
+        if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) {
+            LOG(ERROR) << __func__ << " created invalid FMQ";
+        }
+        mWorkBuffer.reserve(std::max(inBufferSizeInFloat, outBufferSizeInFloat));
+        mCommon = common;
+    }
+    virtual ~EffectContext() {}
+
+    std::shared_ptr<StatusMQ> getStatusFmq() { return mStatusMQ; }
+    std::shared_ptr<DataMQ> getInputDataFmq() { return mInputMQ; }
+    std::shared_ptr<DataMQ> getOutputDataFmq() { return mOutputMQ; }
+
+    float* getWorkBuffer() { return static_cast<float*>(mWorkBuffer.data()); }
+
+    // reset buffer status by abandon input data in FMQ
+    void resetBuffer() {
+        auto buffer = static_cast<float*>(mWorkBuffer.data());
+        std::vector<IEffect::Status> status(mStatusMQ->availableToRead());
+        mInputMQ->read(buffer, mInputMQ->availableToRead());
+    }
+
+    void dupeFmq(IEffect::OpenEffectReturn* effectRet) {
+        if (effectRet) {
+            effectRet->statusMQ = mStatusMQ->dupeDesc();
+            effectRet->inputDataMQ = mInputMQ->dupeDesc();
+            effectRet->outputDataMQ = mOutputMQ->dupeDesc();
+        }
+    }
+    size_t getInputFrameSize() { return mInputFrameSize; }
+    size_t getOutputFrameSize() { return mOutputFrameSize; }
+    int getSessionId() { return mCommon.session; }
+    int getIoHandle() { return mCommon.ioHandle; }
+
+    virtual RetCode setOutputDevice(
+            const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>&
+                    device) {
+        mOutputDevice = device;
+        return RetCode::SUCCESS;
+    }
+
+    virtual std::vector<aidl::android::media::audio::common::AudioDeviceDescription>
+    getOutputDevice() {
+        return mOutputDevice;
+    }
+
+    virtual RetCode setAudioMode(const aidl::android::media::audio::common::AudioMode& mode) {
+        mMode = mode;
+        return RetCode::SUCCESS;
+    }
+    virtual aidl::android::media::audio::common::AudioMode getAudioMode() { return mMode; }
+
+    virtual RetCode setAudioSource(const aidl::android::media::audio::common::AudioSource& source) {
+        mSource = source;
+        return RetCode::SUCCESS;
+    }
+    virtual aidl::android::media::audio::common::AudioSource getAudioSource() { return mSource; }
+
+    virtual RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) {
+        mVolumeStereo = volumeStereo;
+        return RetCode::SUCCESS;
+    }
+    virtual Parameter::VolumeStereo getVolumeStereo() { return mVolumeStereo; }
+
+    virtual RetCode setCommon(const Parameter::Common& common) {
+        mCommon = common;
+        LOG(INFO) << __func__ << mCommon.toString();
+        return RetCode::SUCCESS;
+    }
+    virtual Parameter::Common getCommon() {
+        LOG(DEBUG) << __func__ << mCommon.toString();
+        return mCommon;
+    }
+
+  protected:
+    // common parameters
+    size_t mInputFrameSize;
+    size_t mOutputFrameSize;
+    Parameter::Common mCommon;
+    std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice;
+    aidl::android::media::audio::common::AudioMode mMode;
+    aidl::android::media::audio::common::AudioSource mSource;
+    Parameter::VolumeStereo mVolumeStereo;
+
+  private:
+    // fmq and buffers
+    std::shared_ptr<StatusMQ> mStatusMQ;
+    std::shared_ptr<DataMQ> mInputMQ;
+    std::shared_ptr<DataMQ> mOutputMQ;
+    // TODO handle effect process input and output
+    // work buffer set by effect instances, the access and update are in same thread
+    std::vector<float> mWorkBuffer;
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectImpl.h b/audio/aidl/default/include/effect-impl/EffectImpl.h
new file mode 100644
index 0000000..e7d081f
--- /dev/null
+++ b/audio/aidl/default/include/effect-impl/EffectImpl.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include <cstdlib>
+#include <memory>
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "EffectContext.h"
+#include "EffectThread.h"
+#include "EffectTypes.h"
+#include "effect-impl/EffectContext.h"
+#include "effect-impl/EffectThread.h"
+#include "effect-impl/EffectTypes.h"
+
+extern "C" binder_exception_t destroyEffect(
+        const std::shared_ptr<aidl::android::hardware::audio::effect::IEffect>& instanceSp);
+
+namespace aidl::android::hardware::audio::effect {
+
+class EffectImpl : public BnEffect, public EffectThread {
+  public:
+    EffectImpl() = default;
+    virtual ~EffectImpl() = default;
+
+    virtual ndk::ScopedAStatus open(const Parameter::Common& common,
+                                    const std::optional<Parameter::Specific>& specific,
+                                    OpenEffectReturn* ret) override;
+    virtual ndk::ScopedAStatus close() override;
+    virtual ndk::ScopedAStatus command(CommandId id) override;
+
+    virtual ndk::ScopedAStatus getState(State* state) override;
+    virtual ndk::ScopedAStatus setParameter(const Parameter& param) override;
+    virtual ndk::ScopedAStatus getParameter(const Parameter::Id& id, Parameter* param) override;
+
+    virtual ndk::ScopedAStatus setParameterCommon(const Parameter& param);
+    virtual ndk::ScopedAStatus getParameterCommon(const Parameter::Tag& tag, Parameter* param);
+
+    /* Methods MUST be implemented by each effect instances */
+    virtual ndk::ScopedAStatus getDescriptor(Descriptor* desc) = 0;
+    virtual ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) = 0;
+    virtual ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                                    Parameter::Specific* specific) = 0;
+
+    virtual std::string getEffectName() = 0;
+    virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+    /**
+     * Effect context methods must be implemented by each effect.
+     * Each effect can derive from EffectContext and define its own context, but must upcast to
+     * EffectContext for EffectImpl to use.
+     */
+    virtual std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) = 0;
+    virtual std::shared_ptr<EffectContext> getContext() = 0;
+    virtual RetCode releaseContext() = 0;
+
+  protected:
+    State mState = State::INIT;
+
+    IEffect::Status status(binder_status_t status, size_t consumed, size_t produced);
+    void cleanUp();
+
+    /**
+     * Optional CommandId handling methods for effects to override.
+     * For CommandId::START, EffectImpl call commandImpl before starting the EffectThread
+     * processing.
+     * For CommandId::STOP and CommandId::RESET, EffectImpl call commandImpl after stop the
+     * EffectThread processing.
+     */
+    virtual ndk::ScopedAStatus commandImpl(CommandId id);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectRange.h b/audio/aidl/default/include/effect-impl/EffectRange.h
new file mode 100644
index 0000000..a3ea01f
--- /dev/null
+++ b/audio/aidl/default/include/effect-impl/EffectRange.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+namespace aidl::android::hardware::audio::effect {
+
+template <typename T>
+bool isInRange(const T& value, const T& low, const T& high) {
+    return (value >= low) && (value <= high);
+}
+
+template <typename T, std::size_t... Is>
+bool isTupleInRange(const T& test, const T& min, const T& max, std::index_sequence<Is...>) {
+    return (isInRange(std::get<Is>(test), std::get<Is>(min), std::get<Is>(max)) && ...);
+}
+
+template <typename T, std::size_t TupSize = std::tuple_size_v<T>>
+bool isTupleInRange(const T& test, const T& min, const T& max) {
+    return isTupleInRange(test, min, max, std::make_index_sequence<TupSize>{});
+}
+
+template <typename T, typename F>
+bool isTupleInRange(const std::vector<T>& cfgs, const T& min, const T& max, const F& func) {
+    auto minT = func(min), maxT = func(max);
+    return std::all_of(cfgs.cbegin(), cfgs.cend(),
+                       [&](const T& cfg) { return isTupleInRange(func(cfg), minT, maxT); });
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectThread.h b/audio/aidl/default/include/effect-impl/EffectThread.h
new file mode 100644
index 0000000..ae51ef7
--- /dev/null
+++ b/audio/aidl/default/include/effect-impl/EffectThread.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include <atomic>
+#include <memory>
+#include <string>
+#include <thread>
+
+#include <android-base/thread_annotations.h>
+#include <fmq/EventFlag.h>
+#include <system/thread_defs.h>
+
+#include "effect-impl/EffectContext.h"
+#include "effect-impl/EffectTypes.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class EffectThread {
+  public:
+    // default priority is same as HIDL: ANDROID_PRIORITY_URGENT_AUDIO
+    EffectThread();
+    virtual ~EffectThread();
+
+    // called by effect implementation.
+    RetCode createThread(std::shared_ptr<EffectContext> context, const std::string& name,
+                         int priority = ANDROID_PRIORITY_URGENT_AUDIO);
+    RetCode destroyThread();
+    RetCode startThread();
+    RetCode stopThread();
+
+    // Will call process() in a loop if the thread is running.
+    void threadLoop();
+
+    /**
+     * @brief effectProcessImpl is running in worker thread which created in EffectThread.
+     *
+     * Effect implementation should think about concurrency in the implementation if necessary.
+     * Parameter setting usually implemented in context (derived from EffectContext), and some
+     * parameter maybe used in the processing, then effect implementation should consider using a
+     * mutex to protect these parameter.
+     *
+     * EffectThread will make sure effectProcessImpl only be called after startThread() successful
+     * and before stopThread() successful.
+     *
+     * effectProcessImpl implementation must not call any EffectThread interface, otherwise it will
+     * cause deadlock.
+     *
+     * @param in address of input float buffer.
+     * @param out address of output float buffer.
+     * @param samples number of samples to process.
+     * @return IEffect::Status
+     */
+    virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
+
+    /**
+     * process() call effectProcessImpl() for effect data processing, it is necessary for the
+     * processing to be called under Effect thread mutex mThreadMutex, to avoid the effect state
+     * change before/during data processing, and keep the thread and effect state consistent.
+     */
+    virtual void process_l() REQUIRES(mThreadMutex);
+
+  private:
+    static constexpr int kMaxTaskNameLen = 15;
+
+    std::mutex mThreadMutex;
+    std::condition_variable mCv;
+    bool mStop GUARDED_BY(mThreadMutex) = true;
+    bool mExit GUARDED_BY(mThreadMutex) = false;
+    std::shared_ptr<EffectContext> mThreadContext GUARDED_BY(mThreadMutex);
+
+    struct EventFlagDeleter {
+        void operator()(::android::hardware::EventFlag* flag) const {
+            if (flag) {
+                ::android::hardware::EventFlag::deleteEventFlag(&flag);
+            }
+        }
+    };
+    std::unique_ptr<::android::hardware::EventFlag, EventFlagDeleter> mEfGroup;
+    std::thread mThread;
+    int mPriority;
+    std::string mName;
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectTypes.h b/audio/aidl/default/include/effect-impl/EffectTypes.h
new file mode 100644
index 0000000..4bda7be
--- /dev/null
+++ b/audio/aidl/default/include/effect-impl/EffectTypes.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include <string>
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <aidl/android/hardware/audio/effect/Range.h>
+#include <android-base/logging.h>
+#include <system/audio_effects/aidl_effects_utils.h>
+
+typedef binder_exception_t (*EffectCreateFunctor)(
+        const ::aidl::android::media::audio::common::AudioUuid*,
+        std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>*);
+typedef binder_exception_t (*EffectDestroyFunctor)(
+        const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&);
+typedef binder_exception_t (*EffectQueryFunctor)(
+        const ::aidl::android::media::audio::common::AudioUuid*,
+        ::aidl::android::hardware::audio::effect::Descriptor*);
+
+struct effect_dl_interface_s {
+    EffectCreateFunctor createEffectFunc;
+    EffectDestroyFunctor destroyEffectFunc;
+    EffectQueryFunctor queryEffectFunc;
+};
+
+namespace aidl::android::hardware::audio::effect {
+
+enum class RetCode {
+    SUCCESS,
+    ERROR_ILLEGAL_PARAMETER, /* Illegal parameter */
+    ERROR_THREAD,            /* Effect thread error */
+    ERROR_NULL_POINTER,      /* NULL pointer */
+    ERROR_ALIGNMENT_ERROR,   /* Memory alignment error */
+    ERROR_BLOCK_SIZE_EXCEED, /* Maximum block size exceeded */
+    ERROR_EFFECT_LIB_ERROR
+};
+
+static const int INVALID_AUDIO_SESSION_ID = -1;
+
+inline std::ostream& operator<<(std::ostream& out, const RetCode& code) {
+    switch (code) {
+        case RetCode::SUCCESS:
+            return out << "SUCCESS";
+        case RetCode::ERROR_ILLEGAL_PARAMETER:
+            return out << "ERROR_ILLEGAL_PARAMETER";
+        case RetCode::ERROR_THREAD:
+            return out << "ERROR_THREAD";
+        case RetCode::ERROR_NULL_POINTER:
+            return out << "ERROR_NULL_POINTER";
+        case RetCode::ERROR_ALIGNMENT_ERROR:
+            return out << "ERROR_ALIGNMENT_ERROR";
+        case RetCode::ERROR_BLOCK_SIZE_EXCEED:
+            return out << "ERROR_BLOCK_SIZE_EXCEED";
+        case RetCode::ERROR_EFFECT_LIB_ERROR:
+            return out << "ERROR_EFFECT_LIB_ERROR";
+    }
+
+    return out << "EnumError: " << code;
+}
+
+#define RETURN_IF_ASTATUS_NOT_OK(status, message)                                              \
+    do {                                                                                       \
+        const ::ndk::ScopedAStatus curr_status = (status);                                     \
+        if (!curr_status.isOk()) {                                                             \
+            LOG(ERROR) << __func__ << ":" << __LINE__                                          \
+                       << "return with status: " << curr_status.getDescription() << (message); \
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(                           \
+                    curr_status.getExceptionCode(), (message));                                \
+        }                                                                                      \
+    } while (0)
+
+#define RETURN_IF(expr, exception, message)                                                  \
+    do {                                                                                     \
+        if (expr) {                                                                          \
+            LOG(ERROR) << __func__ << ":" << __LINE__ << " return with expr " << #expr;      \
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage((exception), (message)); \
+        }                                                                                    \
+    } while (0)
+
+#define RETURN_OK_IF(expr)                                                             \
+    do {                                                                               \
+        if (expr) {                                                                    \
+            LOG(INFO) << __func__ << ":" << __LINE__ << " return with expr " << #expr; \
+            return ndk::ScopedAStatus::ok();                                           \
+        }                                                                              \
+    } while (0)
+
+#define RETURN_VALUE_IF(expr, ret, log)                                                  \
+    do {                                                                                 \
+        if (expr) {                                                                      \
+            LOG(ERROR) << __func__ << ":" << __LINE__ << " return with expr \"" << #expr \
+                       << "\":" << (log);                                                \
+            return ret;                                                                  \
+        }                                                                                \
+    } while (0)
+
+#define RETURN_IF_BINDER_EXCEPTION(functor)                                 \
+    {                                                                       \
+        binder_exception_t exception = functor;                             \
+        if (EX_NONE != exception) {                                         \
+            LOG(ERROR) << #functor << ":  failed with error " << exception; \
+            return ndk::ScopedAStatus::fromExceptionCode(exception);        \
+        }                                                                   \
+    }
+
+/**
+ * Make a Range::$EffectType$Range.
+ * T: The $EffectType$, Visualizer for example.
+ * Tag: The union tag name in $EffectType$ definition, latencyMs for example.
+ * l: The value of Range::$EffectType$Range.min.
+ * r: The value of Range::$EffectType$Range.max.
+ */
+#define MAKE_RANGE(T, Tag, l, r) \
+    { .min = T::make<T::Tag>(l), .max = T::make<T::Tag>(r) }
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectWorker.h b/audio/aidl/default/include/effect-impl/EffectWorker.h
new file mode 100644
index 0000000..b456817
--- /dev/null
+++ b/audio/aidl/default/include/effect-impl/EffectWorker.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include <algorithm>
+#include <memory>
+#include <mutex>
+#include <string>
+
+#include "EffectContext.h"
+#include "EffectThread.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+std::string toString(RetCode& code);
+
+class EffectWorker : public EffectThread {
+  public:
+    // set effect context for worker, suppose to only happen once here
+    void setContext(std::shared_ptr<EffectContext> context) {
+        std::call_once(mOnceFlag, [&]() { mContext = context; });
+    };
+
+    // handle FMQ and call effect implemented virtual function
+    void process() override {
+        RETURN_VALUE_IF(!mContext, void(), "nullContext");
+        std::shared_ptr<EffectContext::StatusMQ> statusMQ = mContext->getStatusFmq();
+        std::shared_ptr<EffectContext::DataMQ> inputMQ = mContext->getInputDataFmq();
+        std::shared_ptr<EffectContext::DataMQ> outputMQ = mContext->getOutputDataFmq();
+
+        // Only this worker will read from input data MQ and write to output data MQ.
+        auto readSamples = inputMQ->availableToRead(), writeSamples = outputMQ->availableToWrite();
+        if (readSamples && writeSamples) {
+            auto processSamples = std::min(readSamples, writeSamples);
+            LOG(DEBUG) << __func__ << " available to read " << readSamples << " available to write "
+                       << writeSamples << " process " << processSamples;
+
+            auto buffer = mContext->getWorkBuffer();
+            inputMQ->read(buffer, processSamples);
+
+            IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
+            outputMQ->write(buffer, status.fmqProduced);
+            statusMQ->writeBlocking(&status, 1);
+            LOG(DEBUG) << __func__ << " done processing, effect consumed " << status.fmqConsumed
+                       << " produced " << status.fmqProduced;
+        } else {
+            // TODO: maybe add some sleep here to avoid busy waiting
+        }
+    }
+
+    // must implement by each effect implementation
+    // TODO: consider if this interface need adjustment to handle in-place processing
+    virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
+
+  private:
+    // make sure the context only set once.
+    std::once_flag mOnceFlag;
+    std::shared_ptr<EffectContext> mContext;
+};
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectConfig.h b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
new file mode 100644
index 0000000..f8a86e1
--- /dev/null
+++ b/audio/aidl/default/include/effectFactory-impl/EffectConfig.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2017 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 <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <cutils/properties.h>
+#include <tinyxml2.h>
+
+#include <aidl/android/hardware/audio/effect/Processing.h>
+#include "effect-impl/EffectTypes.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+/**
+ *  Library contains a mapping from library name to path.
+ *  Effect contains a mapping from effect name to Libraries and implementation UUID.
+ *  Pre/post processor contains a mapping from processing name to effect names.
+ */
+class EffectConfig {
+  public:
+    explicit EffectConfig(const std::string& file);
+
+    struct LibraryUuid {
+        std::string name;  // library name
+        ::aidl::android::media::audio::common::AudioUuid uuid;
+    };
+    // <effects>
+    struct EffectLibraries {
+        std::optional<struct LibraryUuid> proxyLibrary;
+        std::vector<struct LibraryUuid> libraries;
+    };
+
+    int getSkippedElements() const { return mSkippedElements; }
+    const std::unordered_map<std::string, std::string> getLibraryMap() const { return mLibraryMap; }
+    const std::unordered_map<std::string, struct EffectLibraries> getEffectsMap() const {
+        return mEffectsMap;
+    }
+
+    static bool findUuid(const std::string& xmlEffectName,
+                         ::aidl::android::media::audio::common::AudioUuid* uuid);
+
+    using ProcessingLibrariesMap = std::map<Processing::Type, std::vector<struct EffectLibraries>>;
+    const ProcessingLibrariesMap& getProcessingMap() const;
+
+  private:
+    static constexpr const char* kEffectLibPath[] =
+#ifdef __LP64__
+            {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"};
+#else
+            {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"};
+#endif
+
+    int mSkippedElements;
+    /* Parsed Libraries result */
+    std::unordered_map<std::string, std::string> mLibraryMap;
+    /* Parsed Effects result */
+    std::unordered_map<std::string, struct EffectLibraries> mEffectsMap;
+    /**
+     * For parsed pre/post processing result: {key: AudioStreamType/AudioSource, value:
+     * EffectLibraries}
+     */
+    ProcessingLibrariesMap mProcessingMap;
+
+    /** @return all `node`s children that are elements and match the tag if provided. */
+    std::vector<std::reference_wrapper<const tinyxml2::XMLElement>> getChildren(
+            const tinyxml2::XMLNode& node, const char* childTag = nullptr);
+
+    /** Parse a library xml note and push the result in mLibraryMap or return false on failure. */
+    bool parseLibrary(const tinyxml2::XMLElement& xml);
+
+    /** Parse an effect from an xml element describing it.
+     * @return true and pushes the effect in mEffectsMap on success, false on failure.
+     */
+    bool parseEffect(const tinyxml2::XMLElement& xml);
+
+    bool parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml);
+
+    // Function to parse effect.library name and effect.uuid from xml
+    bool parseLibraryUuid(const tinyxml2::XMLElement& xml, struct LibraryUuid& libraryUuid,
+                          bool isProxy = false);
+
+    const char* dump(const tinyxml2::XMLElement& element,
+                     tinyxml2::XMLPrinter&& printer = {}) const;
+
+    bool resolveLibrary(const std::string& path, std::string* resolvedPath);
+
+    std::optional<Processing::Type> stringToProcessingType(Processing::Type::Tag typeTag,
+                                                           const std::string& type);
+};
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effectFactory-impl/EffectFactory.h b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
new file mode 100644
index 0000000..ad59ca7
--- /dev/null
+++ b/audio/aidl/default/include/effectFactory-impl/EffectFactory.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <any>
+#include <map>
+#include <optional>
+#include <set>
+#include <tuple>
+#include <vector>
+
+#include <aidl/android/hardware/audio/effect/BnFactory.h>
+#include "EffectConfig.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class Factory : public BnFactory {
+  public:
+    explicit Factory(const std::string& file);
+    /**
+     * @brief Get identity of all effects supported by the device, with the optional filter by type
+     * and/or by instance UUID.
+     *
+     * @param in_type Type UUID.
+     * @param in_instance Instance UUID.
+     * @param in_proxy Proxy UUID.
+     * @param out_descriptor List of Descriptors.
+     * @return ndk::ScopedAStatus
+     */
+    ndk::ScopedAStatus queryEffects(
+            const std::optional<::aidl::android::media::audio::common::AudioUuid>& in_type,
+            const std::optional<::aidl::android::media::audio::common::AudioUuid>& in_instance,
+            const std::optional<::aidl::android::media::audio::common::AudioUuid>& in_proxy,
+            std::vector<Descriptor>* out_descriptor) override;
+
+    /**
+     * @brief Query list of defined processing, with the optional filter by AudioStreamType
+     *
+     * @param in_type Type of processing, could be AudioStreamType or AudioSource. Optional.
+     * @param _aidl_return List of processing filtered by in_type.
+     * @return ndk::ScopedAStatus
+     */
+    ndk::ScopedAStatus queryProcessing(const std::optional<Processing::Type>& in_type,
+                                       std::vector<Processing>* _aidl_return) override;
+
+    /**
+     * @brief Create an effect instance for a certain implementation (identified by UUID).
+     *
+     * @param in_impl_uuid Effect implementation UUID.
+     * @param _aidl_return A pointer to created effect instance.
+     * @return ndk::ScopedAStatus
+     */
+    ndk::ScopedAStatus createEffect(
+            const ::aidl::android::media::audio::common::AudioUuid& in_impl_uuid,
+            std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>* _aidl_return)
+            override;
+
+    /**
+     * @brief Destroy an effect instance.
+     *
+     * @param in_handle Effect instance handle.
+     * @return ndk::ScopedAStatus
+     */
+    ndk::ScopedAStatus destroyEffect(
+            const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_handle)
+            override;
+
+  private:
+    const EffectConfig mConfig;
+    ~Factory();
+    // Set of effect descriptors supported by the devices.
+    std::set<Descriptor> mDescSet;
+    std::set<Descriptor::Identity> mIdentitySet;
+
+    static constexpr int kMapEntryHandleIndex = 0;
+    static constexpr int kMapEntryInterfaceIndex = 1;
+    static constexpr int kMapEntryLibNameIndex = 2;
+    typedef std::tuple<std::unique_ptr<void, std::function<void(void*)>> /* dlHandle */,
+                       std::unique_ptr<struct effect_dl_interface_s> /* interfaces */,
+                       std::string /* library name */>
+            DlEntry;
+
+    std::map<aidl::android::media::audio::common::AudioUuid /* implUUID */, DlEntry> mEffectLibMap;
+
+    typedef std::pair<aidl::android::media::audio::common::AudioUuid, ndk::SpAIBinder> EffectEntry;
+    std::map<std::weak_ptr<IEffect>, EffectEntry, std::owner_less<>> mEffectMap;
+
+    ndk::ScopedAStatus destroyEffectImpl(const std::shared_ptr<IEffect>& in_handle);
+    void cleanupEffectMap();
+    bool openEffectLibrary(const ::aidl::android::media::audio::common::AudioUuid& impl,
+                           const std::string& path);
+    void createIdentityWithConfig(
+            const EffectConfig::LibraryUuid& configLib,
+            const ::aidl::android::media::audio::common::AudioUuid& typeUuidStr,
+            const std::optional<::aidl::android::media::audio::common::AudioUuid> proxyUuid);
+
+    ndk::ScopedAStatus getDescriptorWithUuid(
+            const aidl::android::media::audio::common::AudioUuid& uuid, Descriptor* desc);
+
+    void loadEffectLibs();
+    /* Get effect_dl_interface_s from library handle */
+    void getDlSyms(DlEntry& entry);
+};
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/loudnessEnhancer/Android.bp b/audio/aidl/default/loudnessEnhancer/Android.bp
new file mode 100644
index 0000000..89a72fe
--- /dev/null
+++ b/audio/aidl/default/loudnessEnhancer/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libloudnessenhancersw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "LoudnessEnhancerSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
new file mode 100644
index 0000000..7954316
--- /dev/null
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+
+#define LOG_TAG "AHAL_LoudnessEnhancerSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "LoudnessEnhancerSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidLoudnessEnhancerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidLoudnessEnhancer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::LoudnessEnhancerSw;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidLoudnessEnhancerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<LoudnessEnhancerSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidLoudnessEnhancerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = LoudnessEnhancerSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string LoudnessEnhancerSw::kEffectName = "LoudnessEnhancerSw";
+const Descriptor LoudnessEnhancerSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidLoudnessEnhancer(),
+                          .uuid = getEffectImplUuidLoudnessEnhancerSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = LoudnessEnhancerSw::kEffectName,
+                   .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus LoudnessEnhancerSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus LoudnessEnhancerSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::loudnessEnhancer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& leParam = specific.get<Parameter::Specific::loudnessEnhancer>();
+    auto tag = leParam.getTag();
+
+    switch (tag) {
+        case LoudnessEnhancer::gainMb: {
+            RETURN_IF(mContext->setLeGainMb(leParam.get<LoudnessEnhancer::gainMb>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setGainMbFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus LoudnessEnhancerSw::getParameterSpecific(const Parameter::Id& id,
+                                                            Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::loudnessEnhancerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto leId = id.get<Parameter::Id::loudnessEnhancerTag>();
+    auto leIdTag = leId.getTag();
+    switch (leIdTag) {
+        case LoudnessEnhancer::Id::commonTag:
+            return getParameterLoudnessEnhancer(leId.get<LoudnessEnhancer::Id::commonTag>(),
+                                                specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(leIdTag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus LoudnessEnhancerSw::getParameterLoudnessEnhancer(
+        const LoudnessEnhancer::Tag& tag, Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    LoudnessEnhancer leParam;
+    switch (tag) {
+        case LoudnessEnhancer::gainMb: {
+            leParam.set<LoudnessEnhancer::gainMb>(mContext->getLeGainMb());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "LoudnessEnhancerTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::loudnessEnhancer>(leParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> LoudnessEnhancerSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<LoudnessEnhancerSwContext>(1 /* statusFmqDepth */, common);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> LoudnessEnhancerSw::getContext() {
+    return mContext;
+}
+
+RetCode LoudnessEnhancerSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status LoudnessEnhancerSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
new file mode 100644
index 0000000..25824f2
--- /dev/null
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class LoudnessEnhancerSwContext final : public EffectContext {
+  public:
+    LoudnessEnhancerSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setLeGainMb(int gainMb) {
+        // TODO : Add implementation to apply new gain
+        mGainMb = gainMb;
+        return RetCode::SUCCESS;
+    }
+    int getLeGainMb() const { return mGainMb; }
+
+  private:
+    int mGainMb = 0;  // Default Gain
+};
+
+class LoudnessEnhancerSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Descriptor kDescriptor;
+    LoudnessEnhancerSw() { LOG(DEBUG) << __func__; }
+    ~LoudnessEnhancerSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
+  private:
+    std::shared_ptr<LoudnessEnhancerSwContext> mContext;
+    ndk::ScopedAStatus getParameterLoudnessEnhancer(const LoudnessEnhancer::Tag& tag,
+                                                    Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp
new file mode 100644
index 0000000..af71aa8
--- /dev/null
+++ b/audio/aidl/default/main.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdlib>
+#include <ctime>
+#include <utility>
+
+#include <android-base/logging.h>
+#include <android/binder_ibinder_platform.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "core-impl/Config.h"
+#include "core-impl/Module.h"
+#include "core-impl/ModuleUsb.h"
+
+using aidl::android::hardware::audio::core::Config;
+using aidl::android::hardware::audio::core::Module;
+using aidl::android::hardware::audio::core::ModuleUsb;
+
+int main() {
+    // Random values are used in the implementation.
+    std::srand(std::time(nullptr));
+
+    // This is a debug implementation, always enable debug logging.
+    android::base::SetMinimumLogSeverity(::android::base::DEBUG);
+    // For more logs, use VERBOSE, however this may hinder performance.
+    // android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
+    ABinderProcess_setThreadPoolMaxThreadCount(16);
+
+    // Guaranteed log for b/210919187 and logd_integration_test
+    LOG(INFO) << "Init for Audio AIDL HAL";
+
+    // Make the default config service
+    auto config = ndk::SharedRefBase::make<Config>();
+    const std::string configName = std::string() + Config::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(config->asBinder().get(), configName.c_str());
+    CHECK_EQ(STATUS_OK, status);
+
+    // Make modules
+    auto createModule = [](Module::Type type, const std::string& instance) {
+        auto module = Module::createInstance(type);
+        ndk::SpAIBinder moduleBinder = module->asBinder();
+        const std::string moduleName = std::string(Module::descriptor).append("/").append(instance);
+        AIBinder_setMinSchedulerPolicy(moduleBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
+        binder_status_t status = AServiceManager_addService(moduleBinder.get(), moduleName.c_str());
+        CHECK_EQ(STATUS_OK, status);
+        return std::make_pair(module, moduleBinder);
+    };
+    auto modules = {createModule(Module::Type::DEFAULT, "default"),
+                    createModule(Module::Type::R_SUBMIX, "r_submix"),
+                    createModule(Module::Type::USB, "usb")};
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/audio/aidl/default/noiseSuppression/Android.bp b/audio/aidl/default/noiseSuppression/Android.bp
new file mode 100644
index 0000000..dad3d49
--- /dev/null
+++ b/audio/aidl/default/noiseSuppression/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libnssw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "NoiseSuppressionSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
new file mode 100644
index 0000000..9b2cb7c
--- /dev/null
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+#include <memory>
+#define LOG_TAG "AHAL_NoiseSuppressionSw"
+
+#define LOG_TAG "AHAL_NoiseSuppressionSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "NoiseSuppressionSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidNoiseSuppressionSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidNoiseSuppression;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::NoiseSuppressionSw;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidNoiseSuppressionSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<NoiseSuppressionSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidNoiseSuppressionSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = NoiseSuppressionSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string NoiseSuppressionSw::kEffectName = "NoiseSuppressionSw";
+const Descriptor NoiseSuppressionSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidNoiseSuppression(),
+                          .uuid = getEffectImplUuidNoiseSuppressionSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = NoiseSuppressionSw::kEffectName,
+                   .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus NoiseSuppressionSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus NoiseSuppressionSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::noiseSuppression != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& param = specific.get<Parameter::Specific::noiseSuppression>();
+    auto tag = param.getTag();
+
+    switch (tag) {
+        case NoiseSuppression::level: {
+            RETURN_IF(mContext->setLevel(param.get<NoiseSuppression::level>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "levelNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case NoiseSuppression::type: {
+            RETURN_IF(mContext->setType(param.get<NoiseSuppression::type>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "typeNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case NoiseSuppression::vendor: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus NoiseSuppressionSw::getParameterSpecific(const Parameter::Id& id,
+                                                            Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::noiseSuppressionTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto specificId = id.get<Parameter::Id::noiseSuppressionTag>();
+    auto specificIdTag = specificId.getTag();
+    switch (specificIdTag) {
+        case NoiseSuppression::Id::commonTag:
+            return getParameterNoiseSuppression(specificId.get<NoiseSuppression::Id::commonTag>(),
+                                                specific);
+        case NoiseSuppression::Id::vendorExtensionTag: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus NoiseSuppressionSw::getParameterNoiseSuppression(
+        const NoiseSuppression::Tag& tag, Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    NoiseSuppression param;
+    switch (tag) {
+        case NoiseSuppression::level: {
+            param.set<NoiseSuppression::level>(mContext->getLevel());
+            break;
+        }
+        case NoiseSuppression::type: {
+            param.set<NoiseSuppression::type>(mContext->getType());
+            break;
+        }
+        case NoiseSuppression::vendor: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::noiseSuppression>(param);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> NoiseSuppressionSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<NoiseSuppressionSwContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> NoiseSuppressionSw::getContext() {
+    return mContext;
+}
+
+RetCode NoiseSuppressionSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status NoiseSuppressionSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode NoiseSuppressionSwContext::setLevel(NoiseSuppression::Level level) {
+    mLevel = level;
+    return RetCode::SUCCESS;
+}
+
+NoiseSuppression::Level NoiseSuppressionSwContext::getLevel() {
+    return mLevel;
+}
+
+RetCode NoiseSuppressionSwContext::setType(NoiseSuppression::Type type) {
+    mType = type;
+    return RetCode::SUCCESS;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
new file mode 100644
index 0000000..fc1e028
--- /dev/null
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdlib>
+#include <memory>
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class NoiseSuppressionSwContext final : public EffectContext {
+  public:
+    NoiseSuppressionSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setLevel(NoiseSuppression::Level level);
+    NoiseSuppression::Level getLevel();
+    RetCode setType(NoiseSuppression::Type type);
+    NoiseSuppression::Type getType() { return mType; }
+
+  private:
+    NoiseSuppression::Level mLevel = NoiseSuppression::Level::LOW;
+    NoiseSuppression::Type mType = NoiseSuppression::Type::SINGLE_CHANNEL;
+};
+
+class NoiseSuppressionSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const bool kStrengthSupported;
+    static const Descriptor kDescriptor;
+    NoiseSuppressionSw() { LOG(DEBUG) << __func__; }
+    ~NoiseSuppressionSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+  private:
+    std::shared_ptr<NoiseSuppressionSwContext> mContext;
+    ndk::ScopedAStatus getParameterNoiseSuppression(const NoiseSuppression::Tag& tag,
+                                                    Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/presetReverb/Android.bp b/audio/aidl/default/presetReverb/Android.bp
new file mode 100644
index 0000000..18bdd17
--- /dev/null
+++ b/audio/aidl/default/presetReverb/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libpresetreverbsw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "PresetReverbSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.cpp b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
new file mode 100644
index 0000000..3f02eb7
--- /dev/null
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+
+#define LOG_TAG "AHAL_PresetReverbSw"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "PresetReverbSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidPresetReverbSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::PresetReverbSw;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidPresetReverbSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<PresetReverbSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidPresetReverbSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = PresetReverbSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string PresetReverbSw::kEffectName = "PresetReverbSw";
+
+const std::vector<PresetReverb::Presets> PresetReverbSw::kSupportedPresets{
+        ndk::enum_range<PresetReverb::Presets>().begin(),
+        ndk::enum_range<PresetReverb::Presets>().end()};
+
+const std::vector<Range::PresetReverbRange> PresetReverbSw::kRanges = {
+        MAKE_RANGE(PresetReverb, supportedPresets, PresetReverbSw::kSupportedPresets,
+                   PresetReverbSw::kSupportedPresets)};
+
+const Capability PresetReverbSw::kCapability = {
+        .range = Range::make<Range::presetReverb>(PresetReverbSw::kRanges)};
+
+const Descriptor PresetReverbSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidPresetReverb(),
+                          .uuid = getEffectImplUuidPresetReverbSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = PresetReverbSw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = PresetReverbSw::kCapability};
+
+ndk::ScopedAStatus PresetReverbSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PresetReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::presetReverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& prParam = specific.get<Parameter::Specific::presetReverb>();
+    RETURN_IF(!inRange(prParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = prParam.getTag();
+
+    switch (tag) {
+        case PresetReverb::preset: {
+            RETURN_IF(
+                    mContext->setPRPreset(prParam.get<PresetReverb::preset>()) != RetCode::SUCCESS,
+                    EX_ILLEGAL_ARGUMENT, "setPresetFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "PresetReverbTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus PresetReverbSw::getParameterSpecific(const Parameter::Id& id,
+                                                        Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::presetReverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto prId = id.get<Parameter::Id::presetReverbTag>();
+    auto prIdTag = prId.getTag();
+    switch (prIdTag) {
+        case PresetReverb::Id::commonTag:
+            return getParameterPresetReverb(prId.get<PresetReverb::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "PresetReverbTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus PresetReverbSw::getParameterPresetReverb(const PresetReverb::Tag& tag,
+                                                            Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+    PresetReverb prParam;
+    switch (tag) {
+        case PresetReverb::preset: {
+            prParam.set<PresetReverb::preset>(mContext->getPRPreset());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "PresetReverbTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::presetReverb>(prParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> PresetReverbSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<PresetReverbSwContext>(1 /* statusFmqDepth */, common);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> PresetReverbSw::getContext() {
+    return mContext;
+}
+
+RetCode PresetReverbSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status PresetReverbSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.h b/audio/aidl/default/presetReverb/PresetReverbSw.h
new file mode 100644
index 0000000..9ceee7c
--- /dev/null
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class PresetReverbSwContext final : public EffectContext {
+  public:
+    PresetReverbSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+    RetCode setPRPreset(PresetReverb::Presets preset) {
+        // TODO : Add implementation to modify Presets
+        mPreset = preset;
+        return RetCode::SUCCESS;
+    }
+    PresetReverb::Presets getPRPreset() const { return mPreset; }
+
+  private:
+    PresetReverb::Presets mPreset = PresetReverb::Presets::NONE;
+};
+
+class PresetReverbSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const std::vector<PresetReverb::Presets> kSupportedPresets;
+    static const std::vector<Range::PresetReverbRange> kRanges;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    PresetReverbSw() { LOG(DEBUG) << __func__; }
+    ~PresetReverbSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
+  private:
+    std::shared_ptr<PresetReverbSwContext> mContext;
+
+    ndk::ScopedAStatus getParameterPresetReverb(const PresetReverb::Tag& tag,
+                                                Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/usb/ModuleUsb.cpp b/audio/aidl/default/usb/ModuleUsb.cpp
new file mode 100644
index 0000000..ecdbd5c
--- /dev/null
+++ b/audio/aidl/default/usb/ModuleUsb.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_ModuleUsb"
+
+#include <vector>
+
+#include <Utils.h>
+#include <android-base/logging.h>
+#include <tinyalsa/asoundlib.h>
+
+#include "UsbAlsaMixerControl.h"
+#include "UsbAlsaUtils.h"
+#include "core-impl/ModuleUsb.h"
+
+extern "C" {
+#include "alsa_device_profile.h"
+}
+
+using aidl::android::hardware::audio::common::isUsbInputDeviceType;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioProfile;
+
+namespace aidl::android::hardware::audio::core {
+
+namespace {
+
+std::vector<AudioChannelLayout> populateChannelMasksFromProfile(const alsa_device_profile* profile,
+                                                                bool isInput) {
+    std::vector<AudioChannelLayout> channels;
+    for (size_t i = 0; i < AUDIO_PORT_MAX_CHANNEL_MASKS && profile->channel_counts[i] != 0; ++i) {
+        auto layoutMask =
+                usb::getChannelLayoutMaskFromChannelCount(profile->channel_counts[i], isInput);
+        if (layoutMask.getTag() == AudioChannelLayout::Tag::layoutMask) {
+            channels.push_back(layoutMask);
+        }
+        auto indexMask = usb::getChannelIndexMaskFromChannelCount(profile->channel_counts[i]);
+        if (indexMask.getTag() == AudioChannelLayout::Tag::indexMask) {
+            channels.push_back(indexMask);
+        }
+    }
+    return channels;
+}
+
+std::vector<int> populateSampleRatesFromProfile(const alsa_device_profile* profile) {
+    std::vector<int> sampleRates;
+    for (int i = 0; i < std::min(MAX_PROFILE_SAMPLE_RATES, AUDIO_PORT_MAX_SAMPLING_RATES) &&
+                    profile->sample_rates[i] != 0;
+         i++) {
+        sampleRates.push_back(profile->sample_rates[i]);
+    }
+    return sampleRates;
+}
+
+}  // namespace
+
+ndk::ScopedAStatus ModuleUsb::getTelephony(std::shared_ptr<ITelephony>* _aidl_return) {
+    *_aidl_return = nullptr;
+    LOG(DEBUG) << __func__ << ": returning null";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleUsb::getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) {
+    *_aidl_return = nullptr;
+    LOG(DEBUG) << __func__ << ": returning null";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleUsb::getMicMute(bool* _aidl_return __unused) {
+    LOG(DEBUG) << __func__ << ": is not supported";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus ModuleUsb::setMicMute(bool in_mute __unused) {
+    LOG(DEBUG) << __func__ << ": is not supported";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort) {
+    if (audioPort->ext.getTag() != AudioPortExt::Tag::device) {
+        LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not a device port";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    auto& devicePort = audioPort->ext.get<AudioPortExt::Tag::device>();
+    if (devicePort.device.type.connection != AudioDeviceDescription::CONNECTION_USB) {
+        LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not a usb device port";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (devicePort.device.address.getTag() != AudioDeviceAddress::Tag::alsa) {
+        LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not using alsa address";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    auto& alsaAddress = devicePort.device.address.get<AudioDeviceAddress::Tag::alsa>();
+    if (alsaAddress.size() != 2 || alsaAddress[0] < 0 || alsaAddress[1] < 0) {
+        LOG(ERROR) << __func__ << ": port id " << audioPort->id << " invalid alsa address";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    const bool isInput = isUsbInputDeviceType(devicePort.device.type.type);
+    alsa_device_profile profile;
+    profile_init(&profile, isInput ? PCM_IN : PCM_OUT);
+    profile.card = alsaAddress[0];
+    profile.device = alsaAddress[1];
+    if (!profile_read_device_info(&profile)) {
+        LOG(ERROR) << __func__ << ": failed to read device info, card=" << profile.card
+                   << ", device=" << profile.device;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+
+    std::vector<AudioChannelLayout> channels = populateChannelMasksFromProfile(&profile, isInput);
+    std::vector<int> sampleRates = populateSampleRatesFromProfile(&profile);
+
+    for (size_t i = 0; i < std::min(MAX_PROFILE_FORMATS, AUDIO_PORT_MAX_AUDIO_PROFILES) &&
+                       profile.formats[i] != PCM_FORMAT_INVALID;
+         ++i) {
+        auto audioFormatDescription =
+                usb::legacy2aidl_pcm_format_AudioFormatDescription(profile.formats[i]);
+        if (audioFormatDescription.type == AudioFormatType::DEFAULT) {
+            LOG(WARNING) << __func__ << ": unknown pcm type=" << profile.formats[i];
+            continue;
+        }
+        AudioProfile audioProfile = {.format = audioFormatDescription,
+                                     .channelMasks = channels,
+                                     .sampleRates = sampleRates};
+        audioPort->profiles.push_back(std::move(audioProfile));
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleUsb::checkAudioPatchEndpointsMatch(
+        const std::vector<AudioPortConfig*>& sources, const std::vector<AudioPortConfig*>& sinks) {
+    for (const auto& source : sources) {
+        for (const auto& sink : sinks) {
+            if (source->sampleRate != sink->sampleRate ||
+                source->channelMask != sink->channelMask || source->format != sink->format) {
+                LOG(ERROR) << __func__
+                           << ": mismatch port configuration, source=" << source->toString()
+                           << ", sink=" << sink->toString();
+                return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+            }
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+void ModuleUsb::onExternalDeviceConnectionChanged(
+        const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected) {
+    if (audioPort.ext.getTag() != AudioPortExt::Tag::device) {
+        return;
+    }
+    const auto& address = audioPort.ext.get<AudioPortExt::Tag::device>().device.address;
+    if (address.getTag() != AudioDeviceAddress::alsa) {
+        return;
+    }
+    const int card = address.get<AudioDeviceAddress::alsa>()[0];
+    usb::UsbAlsaMixerControl::getInstance().setDeviceConnectionState(card, mMasterMute,
+                                                                     mMasterVolume, connected);
+}
+
+ndk::ScopedAStatus ModuleUsb::onMasterMuteChanged(bool mute) {
+    return usb::UsbAlsaMixerControl::getInstance().setMasterMute(mute);
+}
+
+ndk::ScopedAStatus ModuleUsb::onMasterVolumeChanged(float volume) {
+    return usb::UsbAlsaMixerControl::getInstance().setMasterVolume(volume);
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/usb/StreamUsb.cpp b/audio/aidl/default/usb/StreamUsb.cpp
new file mode 100644
index 0000000..5d1d7fe
--- /dev/null
+++ b/audio/aidl/default/usb/StreamUsb.cpp
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_StreamUsb"
+#include <android-base/logging.h>
+
+#include <Utils.h>
+
+#include "UsbAlsaMixerControl.h"
+#include "UsbAlsaUtils.h"
+#include "core-impl/Module.h"
+#include "core-impl/StreamUsb.h"
+
+extern "C" {
+#include "alsa_device_profile.h"
+}
+
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
+using android::OK;
+using android::status_t;
+
+namespace aidl::android::hardware::audio::core {
+
+DriverUsb::DriverUsb(const StreamContext& context, bool isInput)
+    : mFrameSizeBytes(context.getFrameSize()), mIsInput(isInput) {
+    struct pcm_config config;
+    config.channels = usb::getChannelCountFromChannelMask(context.getChannelLayout(), isInput);
+    if (config.channels == 0) {
+        LOG(ERROR) << __func__ << ": invalid channel=" << context.getChannelLayout().toString();
+        return;
+    }
+    config.format = usb::aidl2legacy_AudioFormatDescription_pcm_format(context.getFormat());
+    if (config.format == PCM_FORMAT_INVALID) {
+        LOG(ERROR) << __func__ << ": invalid format=" << context.getFormat().toString();
+        return;
+    }
+    config.rate = context.getSampleRate();
+    if (config.rate == 0) {
+        LOG(ERROR) << __func__ << ": invalid sample rate=" << config.rate;
+        return;
+    }
+    mConfig = config;
+}
+
+::android::status_t DriverUsb::init() {
+    return mConfig.has_value() ? ::android::OK : ::android::NO_INIT;
+}
+
+::android::status_t DriverUsb::setConnectedDevices(
+        const std::vector<AudioDevice>& connectedDevices) {
+    if (mIsInput && connectedDevices.size() > 1) {
+        LOG(ERROR) << __func__ << ": wrong device size(" << connectedDevices.size()
+                   << ") for input stream";
+        return ::android::BAD_VALUE;
+    }
+    for (const auto& connectedDevice : connectedDevices) {
+        if (connectedDevice.address.getTag() != AudioDeviceAddress::alsa) {
+            LOG(ERROR) << __func__ << ": bad device address" << connectedDevice.address.toString();
+            return ::android::BAD_VALUE;
+        }
+    }
+    std::lock_guard guard(mLock);
+    mAlsaDeviceProxies.clear();
+    mConnectedDevices.clear();
+    for (const auto& connectedDevice : connectedDevices) {
+        mConnectedDevices.push_back(connectedDevice.address);
+    }
+    return ::android::OK;
+}
+
+::android::status_t DriverUsb::drain(StreamDescriptor::DrainMode) {
+    usleep(1000);
+    return ::android::OK;
+}
+
+::android::status_t DriverUsb::flush() {
+    usleep(1000);
+    return ::android::OK;
+}
+
+::android::status_t DriverUsb::pause() {
+    usleep(1000);
+    return ::android::OK;
+}
+
+::android::status_t DriverUsb::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+                                        int32_t* latencyMs) {
+    if (!mConfig.has_value() || mConnectedDevices.empty()) {
+        LOG(ERROR) << __func__ << ": failed, has config: " << mConfig.has_value()
+                   << ", has connected devices: " << mConnectedDevices.empty();
+        return ::android::NO_INIT;
+    }
+    if (mIsStandby) {
+        if (::android::status_t status = exitStandby(); status != ::android::OK) {
+            LOG(ERROR) << __func__ << ": failed to exit standby, status=" << status;
+            return status;
+        }
+    }
+    std::vector<std::shared_ptr<alsa_device_proxy>> alsaDeviceProxies;
+    {
+        std::lock_guard guard(mLock);
+        alsaDeviceProxies = mAlsaDeviceProxies;
+    }
+    const size_t bytesToTransfer = frameCount * mFrameSizeBytes;
+    if (mIsInput) {
+        // For input case, only support single device.
+        proxy_read(alsaDeviceProxies[0].get(), buffer, bytesToTransfer);
+    } else {
+        for (auto& proxy : alsaDeviceProxies) {
+            proxy_write(proxy.get(), buffer, bytesToTransfer);
+        }
+    }
+    *actualFrameCount = frameCount;
+    *latencyMs = Module::kLatencyMs;
+    return ::android::OK;
+}
+
+::android::status_t DriverUsb::standby() {
+    if (!mIsStandby) {
+        std::lock_guard guard(mLock);
+        mAlsaDeviceProxies.clear();
+        mIsStandby = true;
+    }
+    return ::android::OK;
+}
+
+::android::status_t DriverUsb::exitStandby() {
+    std::vector<AudioDeviceAddress> connectedDevices;
+    {
+        std::lock_guard guard(mLock);
+        connectedDevices = mConnectedDevices;
+    }
+    std::vector<std::shared_ptr<alsa_device_proxy>> alsaDeviceProxies;
+    for (const auto& device : connectedDevices) {
+        alsa_device_profile profile;
+        profile_init(&profile, mIsInput ? PCM_IN : PCM_OUT);
+        profile.card = device.get<AudioDeviceAddress::alsa>()[0];
+        profile.device = device.get<AudioDeviceAddress::alsa>()[1];
+        if (!profile_read_device_info(&profile)) {
+            LOG(ERROR) << __func__
+                       << ": unable to read device info, device address=" << device.toString();
+            return ::android::UNKNOWN_ERROR;
+        }
+
+        auto proxy = std::shared_ptr<alsa_device_proxy>(new alsa_device_proxy(),
+                                                        [](alsa_device_proxy* proxy) {
+                                                            proxy_close(proxy);
+                                                            free(proxy);
+                                                        });
+        // Always ask for alsa configure as required since the configuration should be supported
+        // by the connected device. That is guaranteed by `setAudioPortConfig` and
+        // `setAudioPatch`.
+        if (int err =
+                    proxy_prepare(proxy.get(), &profile, &mConfig.value(), true /*is_bit_perfect*/);
+            err != 0) {
+            LOG(ERROR) << __func__ << ": fail to prepare for device address=" << device.toString()
+                       << " error=" << err;
+            return ::android::UNKNOWN_ERROR;
+        }
+        if (int err = proxy_open(proxy.get()); err != 0) {
+            LOG(ERROR) << __func__ << ": failed to open device, address=" << device.toString()
+                       << " error=" << err;
+            return ::android::UNKNOWN_ERROR;
+        }
+        alsaDeviceProxies.push_back(std::move(proxy));
+    }
+    {
+        std::lock_guard guard(mLock);
+        mAlsaDeviceProxies = alsaDeviceProxies;
+    }
+    mIsStandby = false;
+    return ::android::OK;
+}
+
+// static
+ndk::ScopedAStatus StreamInUsb::createInstance(const SinkMetadata& sinkMetadata,
+                                               StreamContext&& context,
+                                               const std::vector<MicrophoneInfo>& microphones,
+                                               std::shared_ptr<StreamIn>* result) {
+    std::shared_ptr<StreamIn> stream =
+            ndk::SharedRefBase::make<StreamInUsb>(sinkMetadata, std::move(context), microphones);
+    if (auto status = initInstance(stream); !status.isOk()) {
+        return status;
+    }
+    *result = std::move(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+StreamInUsb::StreamInUsb(const SinkMetadata& sinkMetadata, StreamContext&& context,
+                         const std::vector<MicrophoneInfo>& microphones)
+    : StreamIn(
+              sinkMetadata, std::move(context),
+              [](const StreamContext& ctx) -> DriverInterface* {
+                  return new DriverUsb(ctx, true /*isInput*/);
+              },
+              [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+                  // The default worker implementation is used.
+                  return new StreamInWorker(ctx, driver);
+              },
+              microphones) {}
+
+ndk::ScopedAStatus StreamInUsb::getActiveMicrophones(
+        std::vector<MicrophoneDynamicInfo>* _aidl_return __unused) {
+    LOG(DEBUG) << __func__ << ": not supported";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+// static
+ndk::ScopedAStatus StreamOutUsb::createInstance(const SourceMetadata& sourceMetadata,
+                                                StreamContext&& context,
+                                                const std::optional<AudioOffloadInfo>& offloadInfo,
+                                                std::shared_ptr<StreamOut>* result) {
+    if (offloadInfo.has_value()) {
+        LOG(ERROR) << __func__ << ": offload is not supported";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    std::shared_ptr<StreamOut> stream =
+            ndk::SharedRefBase::make<StreamOutUsb>(sourceMetadata, std::move(context), offloadInfo);
+    if (auto status = initInstance(stream); !status.isOk()) {
+        return status;
+    }
+    *result = std::move(stream);
+    return ndk::ScopedAStatus::ok();
+}
+
+StreamOutUsb::StreamOutUsb(const SourceMetadata& sourceMetadata, StreamContext&& context,
+                           const std::optional<AudioOffloadInfo>& offloadInfo)
+    : StreamOut(
+              sourceMetadata, std::move(context),
+              [](const StreamContext& ctx) -> DriverInterface* {
+                  return new DriverUsb(ctx, false /*isInput*/);
+              },
+              [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+                  // The default worker implementation is used.
+                  return new StreamOutWorker(ctx, driver);
+              },
+              offloadInfo) {
+    mChannelCount = getChannelCount(mContext.getChannelLayout());
+}
+
+ndk::ScopedAStatus StreamOutUsb::getHwVolume(std::vector<float>* _aidl_return) {
+    *_aidl_return = mHwVolumes;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StreamOutUsb::setHwVolume(const std::vector<float>& in_channelVolumes) {
+    for (const auto& device : mConnectedDevices) {
+        if (device.address.getTag() != AudioDeviceAddress::alsa) {
+            LOG(DEBUG) << __func__ << ": skip as the device address is not alsa";
+            continue;
+        }
+        const int card = device.address.get<AudioDeviceAddress::alsa>()[0];
+        if (auto result =
+                    usb::UsbAlsaMixerControl::getInstance().setVolumes(card, in_channelVolumes);
+            !result.isOk()) {
+            LOG(ERROR) << __func__ << ": failed to set volume for device, card=" << card;
+            return result;
+        }
+    }
+    mHwVolumes = in_channelVolumes;
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/usb/UsbAlsaMixerControl.cpp b/audio/aidl/default/usb/UsbAlsaMixerControl.cpp
new file mode 100644
index 0000000..b5337d1
--- /dev/null
+++ b/audio/aidl/default/usb/UsbAlsaMixerControl.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_UsbAlsaMixerControl"
+#include <android-base/logging.h>
+
+#include <cmath>
+#include <string>
+#include <vector>
+
+#include <android/binder_status.h>
+
+#include "UsbAlsaMixerControl.h"
+
+namespace aidl::android::hardware::audio::core::usb {
+
+//-----------------------------------------------------------------------------
+
+MixerControl::MixerControl(struct mixer_ctl* ctl)
+    : mCtl(ctl),
+      mNumValues(mixer_ctl_get_num_values(ctl)),
+      mMinValue(mixer_ctl_get_range_min(ctl)),
+      mMaxValue(mixer_ctl_get_range_max(ctl)) {}
+
+unsigned int MixerControl::getNumValues() const {
+    return mNumValues;
+}
+
+int MixerControl::getMaxValue() const {
+    return mMaxValue;
+}
+
+int MixerControl::getMinValue() const {
+    return mMinValue;
+}
+
+int MixerControl::setArray(const void* array, size_t count) {
+    const std::lock_guard guard(mLock);
+    return mixer_ctl_set_array(mCtl, array, count);
+}
+
+//-----------------------------------------------------------------------------
+
+// static
+const std::map<AlsaMixer::Control, std::vector<AlsaMixer::ControlNamesAndExpectedCtlType>>
+        AlsaMixer::kPossibleControls = {
+                {AlsaMixer::MASTER_SWITCH, {{"Master Playback Switch", MIXER_CTL_TYPE_BOOL}}},
+                {AlsaMixer::MASTER_VOLUME, {{"Master Playback Volume", MIXER_CTL_TYPE_INT}}},
+                {AlsaMixer::HW_VOLUME,
+                 {{"Headphone Playback Volume", MIXER_CTL_TYPE_INT},
+                  {"Headset Playback Volume", MIXER_CTL_TYPE_INT},
+                  {"PCM Playback Volume", MIXER_CTL_TYPE_INT}}}};
+
+// static
+std::map<AlsaMixer::Control, std::shared_ptr<MixerControl>> AlsaMixer::initializeMixerControls(
+        struct mixer* mixer) {
+    std::map<AlsaMixer::Control, std::shared_ptr<MixerControl>> mixerControls;
+    std::string mixerCtlNames;
+    for (const auto& [control, possibleCtls] : kPossibleControls) {
+        for (const auto& [ctlName, expectedCtlType] : possibleCtls) {
+            struct mixer_ctl* ctl = mixer_get_ctl_by_name(mixer, ctlName.c_str());
+            if (ctl != nullptr && mixer_ctl_get_type(ctl) == expectedCtlType) {
+                mixerControls.emplace(control, std::make_unique<MixerControl>(ctl));
+                if (!mixerCtlNames.empty()) {
+                    mixerCtlNames += ",";
+                }
+                mixerCtlNames += ctlName;
+                break;
+            }
+        }
+    }
+    LOG(DEBUG) << __func__ << ": available mixer control names=[" << mixerCtlNames << "]";
+    return mixerControls;
+}
+
+AlsaMixer::AlsaMixer(struct mixer* mixer)
+    : mMixer(mixer), mMixerControls(initializeMixerControls(mMixer)) {}
+
+AlsaMixer::~AlsaMixer() {
+    mixer_close(mMixer);
+}
+
+namespace {
+
+int volumeFloatToInteger(float fValue, int maxValue, int minValue) {
+    return minValue + std::ceil((maxValue - minValue) * fValue);
+}
+
+float volumeIntegerToFloat(int iValue, int maxValue, int minValue) {
+    if (iValue > maxValue) {
+        return 1.0f;
+    }
+    if (iValue < minValue) {
+        return 0.0f;
+    }
+    return static_cast<float>(iValue - minValue) / (maxValue - minValue);
+}
+
+}  // namespace
+
+ndk::ScopedAStatus AlsaMixer::setMasterMute(bool muted) {
+    auto it = mMixerControls.find(AlsaMixer::MASTER_SWITCH);
+    if (it == mMixerControls.end()) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    const int numValues = it->second->getNumValues();
+    std::vector<int> values(numValues, muted ? 0 : 1);
+    if (int err = it->second->setArray(values.data(), numValues); err != 0) {
+        LOG(ERROR) << __func__ << ": failed to set master mute, err=" << err;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AlsaMixer::setMasterVolume(float volume) {
+    auto it = mMixerControls.find(AlsaMixer::MASTER_VOLUME);
+    if (it == mMixerControls.end()) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    const int numValues = it->second->getNumValues();
+    std::vector<int> values(numValues, volumeFloatToInteger(volume, it->second->getMaxValue(),
+                                                            it->second->getMinValue()));
+    if (int err = it->second->setArray(values.data(), numValues); err != 0) {
+        LOG(ERROR) << __func__ << ": failed to set master volume, err=" << err;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AlsaMixer::setVolumes(std::vector<float> volumes) {
+    auto it = mMixerControls.find(AlsaMixer::HW_VOLUME);
+    if (it == mMixerControls.end()) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    const int numValues = it->second->getNumValues();
+    const int maxValue = it->second->getMaxValue();
+    const int minValue = it->second->getMinValue();
+    std::vector<int> values;
+    size_t i = 0;
+    for (; i < numValues && i < values.size(); ++i) {
+        values.emplace_back(volumeFloatToInteger(volumes[i], maxValue, minValue));
+    }
+    if (int err = it->second->setArray(values.data(), values.size()); err != 0) {
+        LOG(ERROR) << __func__ << ": failed to set volume, err=" << err;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+//-----------------------------------------------------------------------------
+
+// static
+UsbAlsaMixerControl& UsbAlsaMixerControl::getInstance() {
+    static UsbAlsaMixerControl gInstance;
+    return gInstance;
+}
+
+void UsbAlsaMixerControl::setDeviceConnectionState(int card, bool masterMuted, float masterVolume,
+                                                   bool connected) {
+    LOG(DEBUG) << __func__ << ": card=" << card << ", connected=" << connected;
+    if (connected) {
+        struct mixer* mixer = mixer_open(card);
+        if (mixer == nullptr) {
+            PLOG(ERROR) << __func__ << ": failed to open mixer for card=" << card;
+            return;
+        }
+        auto alsaMixer = std::make_shared<AlsaMixer>(mixer);
+        alsaMixer->setMasterMute(masterMuted);
+        alsaMixer->setMasterVolume(masterVolume);
+        const std::lock_guard guard(mLock);
+        mMixerControls.emplace(card, alsaMixer);
+    } else {
+        const std::lock_guard guard(mLock);
+        mMixerControls.erase(card);
+    }
+}
+
+ndk::ScopedAStatus UsbAlsaMixerControl::setMasterMute(bool mute) {
+    auto alsaMixers = getAlsaMixers();
+    for (auto it = alsaMixers.begin(); it != alsaMixers.end(); ++it) {
+        if (auto result = it->second->setMasterMute(mute); !result.isOk()) {
+            // Return illegal state if there are multiple devices connected and one of them fails
+            // to set master mute. Otherwise, return the error from calling `setMasterMute`.
+            LOG(ERROR) << __func__ << ": failed to set master mute for card=" << it->first;
+            return alsaMixers.size() > 1 ? ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE)
+                                         : std::move(result);
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus UsbAlsaMixerControl::setMasterVolume(float volume) {
+    auto alsaMixers = getAlsaMixers();
+    for (auto it = alsaMixers.begin(); it != alsaMixers.end(); ++it) {
+        if (auto result = it->second->setMasterVolume(volume); !result.isOk()) {
+            // Return illegal state if there are multiple devices connected and one of them fails
+            // to set master volume. Otherwise, return the error from calling `setMasterVolume`.
+            LOG(ERROR) << __func__ << ": failed to set master volume for card=" << it->first;
+            return alsaMixers.size() > 1 ? ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE)
+                                         : std::move(result);
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus UsbAlsaMixerControl::setVolumes(int card, std::vector<float> volumes) {
+    auto alsaMixer = getAlsaMixer(card);
+    if (alsaMixer == nullptr) {
+        LOG(ERROR) << __func__ << ": no mixer control found for card=" << card;
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    return alsaMixer->setVolumes(volumes);
+}
+
+std::shared_ptr<AlsaMixer> UsbAlsaMixerControl::getAlsaMixer(int card) {
+    const std::lock_guard guard(mLock);
+    const auto it = mMixerControls.find(card);
+    return it == mMixerControls.end() ? nullptr : it->second;
+}
+
+std::map<int, std::shared_ptr<AlsaMixer>> UsbAlsaMixerControl::getAlsaMixers() {
+    const std::lock_guard guard(mLock);
+    return mMixerControls;
+}
+
+}  // namespace aidl::android::hardware::audio::core::usb
diff --git a/audio/aidl/default/usb/UsbAlsaMixerControl.h b/audio/aidl/default/usb/UsbAlsaMixerControl.h
new file mode 100644
index 0000000..cbcddd8
--- /dev/null
+++ b/audio/aidl/default/usb/UsbAlsaMixerControl.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <map>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <android-base/thread_annotations.h>
+#include <android/binder_auto_utils.h>
+
+extern "C" {
+#include <tinyalsa/mixer.h>
+}
+
+namespace aidl::android::hardware::audio::core::usb {
+
+class MixerControl {
+  public:
+    explicit MixerControl(struct mixer_ctl* ctl);
+
+    unsigned int getNumValues() const;
+    int getMaxValue() const;
+    int getMinValue() const;
+    int setArray(const void* array, size_t count);
+
+  private:
+    std::mutex mLock;
+    // The mixer_ctl object is owned by ALSA and will be released when the mixer is closed.
+    struct mixer_ctl* mCtl GUARDED_BY(mLock);
+    const unsigned int mNumValues;
+    const int mMinValue;
+    const int mMaxValue;
+};
+
+class AlsaMixer {
+  public:
+    explicit AlsaMixer(struct mixer* mixer);
+
+    ~AlsaMixer();
+
+    bool isValid() const { return mMixer != nullptr; }
+
+    ndk::ScopedAStatus setMasterMute(bool muted);
+    ndk::ScopedAStatus setMasterVolume(float volume);
+    ndk::ScopedAStatus setVolumes(std::vector<float> volumes);
+
+  private:
+    enum Control {
+        MASTER_SWITCH,
+        MASTER_VOLUME,
+        HW_VOLUME,
+    };
+    using ControlNamesAndExpectedCtlType = std::pair<std::string, enum mixer_ctl_type>;
+    static const std::map<Control, std::vector<ControlNamesAndExpectedCtlType>> kPossibleControls;
+    static std::map<Control, std::shared_ptr<MixerControl>> initializeMixerControls(
+            struct mixer* mixer);
+
+    // The mixer object is owned by ALSA and will be released when the mixer is closed.
+    struct mixer* mMixer;
+    // `mMixerControls` will only be initialized in constructor. After that, it wil only be
+    // read but not be modified.
+    const std::map<Control, std::shared_ptr<MixerControl>> mMixerControls;
+};
+
+class UsbAlsaMixerControl {
+  public:
+    static UsbAlsaMixerControl& getInstance();
+
+    void setDeviceConnectionState(int card, bool masterMuted, float masterVolume, bool connected);
+
+    // Master volume settings will be applied to all sound cards, it is only set by the
+    // USB module.
+    ndk::ScopedAStatus setMasterMute(bool muted);
+    ndk::ScopedAStatus setMasterVolume(float volume);
+    // The volume settings can be different on sound cards. It is controlled by streams.
+    ndk::ScopedAStatus setVolumes(int card, std::vector<float> volumes);
+
+  private:
+    std::shared_ptr<AlsaMixer> getAlsaMixer(int card);
+    std::map<int, std::shared_ptr<AlsaMixer>> getAlsaMixers();
+
+    std::mutex mLock;
+    // A map whose key is the card number and value is a shared pointer to corresponding
+    // AlsaMixer object.
+    std::map<int, std::shared_ptr<AlsaMixer>> mMixerControls GUARDED_BY(mLock);
+};
+
+}  // namespace aidl::android::hardware::audio::core::usb
diff --git a/audio/aidl/default/usb/UsbAlsaUtils.cpp b/audio/aidl/default/usb/UsbAlsaUtils.cpp
new file mode 100644
index 0000000..74d9c28
--- /dev/null
+++ b/audio/aidl/default/usb/UsbAlsaUtils.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <map>
+#include <set>
+
+#include <Utils.h>
+#include <aidl/android/media/audio/common/AudioFormatType.h>
+#include <aidl/android/media/audio/common/PcmType.h>
+
+#include "UsbAlsaUtils.h"
+#include "core-impl/utils.h"
+
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::PcmType;
+
+namespace aidl::android::hardware::audio::core::usb {
+
+namespace {
+
+using AudioChannelCountToMaskMap = std::map<unsigned int, AudioChannelLayout>;
+using AudioFormatDescToPcmFormatMap = std::map<AudioFormatDescription, enum pcm_format>;
+using PcmFormatToAudioFormatDescMap = std::map<enum pcm_format, AudioFormatDescription>;
+
+static const AudioChannelLayout INVALID_CHANNEL_LAYOUT =
+        AudioChannelLayout::make<AudioChannelLayout::Tag::invalid>(0);
+
+#define DEFINE_CHANNEL_LAYOUT_MASK(n) \
+    AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(AudioChannelLayout::LAYOUT_##n)
+
+static const std::set<AudioChannelLayout> SUPPORTED_OUT_CHANNEL_LAYOUTS = {
+        DEFINE_CHANNEL_LAYOUT_MASK(MONO),          DEFINE_CHANNEL_LAYOUT_MASK(STEREO),
+        DEFINE_CHANNEL_LAYOUT_MASK(2POINT1),       DEFINE_CHANNEL_LAYOUT_MASK(QUAD),
+        DEFINE_CHANNEL_LAYOUT_MASK(PENTA),         DEFINE_CHANNEL_LAYOUT_MASK(5POINT1),
+        DEFINE_CHANNEL_LAYOUT_MASK(6POINT1),       DEFINE_CHANNEL_LAYOUT_MASK(7POINT1),
+        DEFINE_CHANNEL_LAYOUT_MASK(7POINT1POINT4), DEFINE_CHANNEL_LAYOUT_MASK(22POINT2),
+};
+
+static const std::set<AudioChannelLayout> SUPPORTED_IN_CHANNEL_LAYOUTS = {
+        DEFINE_CHANNEL_LAYOUT_MASK(MONO),
+        DEFINE_CHANNEL_LAYOUT_MASK(STEREO),
+};
+
+#define DEFINE_CHANNEL_INDEX_MASK(n) \
+    AudioChannelLayout::make<AudioChannelLayout::Tag::indexMask>(AudioChannelLayout::INDEX_MASK_##n)
+
+static const std::set<AudioChannelLayout> SUPPORTED_INDEX_CHANNEL_LAYOUTS = {
+        DEFINE_CHANNEL_INDEX_MASK(1),  DEFINE_CHANNEL_INDEX_MASK(2),  DEFINE_CHANNEL_INDEX_MASK(3),
+        DEFINE_CHANNEL_INDEX_MASK(4),  DEFINE_CHANNEL_INDEX_MASK(5),  DEFINE_CHANNEL_INDEX_MASK(6),
+        DEFINE_CHANNEL_INDEX_MASK(7),  DEFINE_CHANNEL_INDEX_MASK(8),  DEFINE_CHANNEL_INDEX_MASK(9),
+        DEFINE_CHANNEL_INDEX_MASK(10), DEFINE_CHANNEL_INDEX_MASK(11), DEFINE_CHANNEL_INDEX_MASK(12),
+        DEFINE_CHANNEL_INDEX_MASK(13), DEFINE_CHANNEL_INDEX_MASK(14), DEFINE_CHANNEL_INDEX_MASK(15),
+        DEFINE_CHANNEL_INDEX_MASK(16), DEFINE_CHANNEL_INDEX_MASK(17), DEFINE_CHANNEL_INDEX_MASK(18),
+        DEFINE_CHANNEL_INDEX_MASK(19), DEFINE_CHANNEL_INDEX_MASK(20), DEFINE_CHANNEL_INDEX_MASK(21),
+        DEFINE_CHANNEL_INDEX_MASK(22), DEFINE_CHANNEL_INDEX_MASK(23), DEFINE_CHANNEL_INDEX_MASK(24),
+};
+
+static AudioChannelCountToMaskMap make_ChannelCountToMaskMap(
+        const std::set<AudioChannelLayout>& channelMasks) {
+    AudioChannelCountToMaskMap channelMaskToCountMap;
+    for (const auto& channelMask : channelMasks) {
+        channelMaskToCountMap.emplace(getChannelCount(channelMask), channelMask);
+    }
+    return channelMaskToCountMap;
+}
+
+const AudioChannelCountToMaskMap& getSupportedChannelOutLayoutMap() {
+    static const AudioChannelCountToMaskMap outLayouts =
+            make_ChannelCountToMaskMap(SUPPORTED_OUT_CHANNEL_LAYOUTS);
+    return outLayouts;
+}
+
+const AudioChannelCountToMaskMap& getSupportedChannelInLayoutMap() {
+    static const AudioChannelCountToMaskMap inLayouts =
+            make_ChannelCountToMaskMap(SUPPORTED_IN_CHANNEL_LAYOUTS);
+    return inLayouts;
+}
+
+const AudioChannelCountToMaskMap& getSupportedChannelIndexLayoutMap() {
+    static const AudioChannelCountToMaskMap indexLayouts =
+            make_ChannelCountToMaskMap(SUPPORTED_INDEX_CHANNEL_LAYOUTS);
+    return indexLayouts;
+}
+
+AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
+    AudioFormatDescription result;
+    result.type = type;
+    return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(PcmType pcm) {
+    auto result = make_AudioFormatDescription(AudioFormatType::PCM);
+    result.pcm = pcm;
+    return result;
+}
+
+const AudioFormatDescToPcmFormatMap& getAudioFormatDescriptorToPcmFormatMap() {
+    static const AudioFormatDescToPcmFormatMap formatDescToPcmFormatMap = {
+            {make_AudioFormatDescription(PcmType::UINT_8_BIT), PCM_FORMAT_S8},
+            {make_AudioFormatDescription(PcmType::INT_16_BIT), PCM_FORMAT_S16_LE},
+            {make_AudioFormatDescription(PcmType::FIXED_Q_8_24), PCM_FORMAT_S24_LE},
+            {make_AudioFormatDescription(PcmType::INT_24_BIT), PCM_FORMAT_S24_3LE},
+            {make_AudioFormatDescription(PcmType::INT_32_BIT), PCM_FORMAT_S32_LE},
+            {make_AudioFormatDescription(PcmType::FLOAT_32_BIT), PCM_FORMAT_FLOAT_LE},
+    };
+    return formatDescToPcmFormatMap;
+}
+
+static PcmFormatToAudioFormatDescMap make_PcmFormatToAudioFormatDescMap(
+        const AudioFormatDescToPcmFormatMap& formatDescToPcmFormatMap) {
+    PcmFormatToAudioFormatDescMap result;
+    for (const auto& formatPair : formatDescToPcmFormatMap) {
+        result.emplace(formatPair.second, formatPair.first);
+    }
+    return result;
+}
+
+const PcmFormatToAudioFormatDescMap& getPcmFormatToAudioFormatDescMap() {
+    static const PcmFormatToAudioFormatDescMap pcmFormatToFormatDescMap =
+            make_PcmFormatToAudioFormatDescMap(getAudioFormatDescriptorToPcmFormatMap());
+    return pcmFormatToFormatDescMap;
+}
+
+}  // namespace
+
+AudioChannelLayout getChannelLayoutMaskFromChannelCount(unsigned int channelCount, int isInput) {
+    return findValueOrDefault(
+            isInput ? getSupportedChannelInLayoutMap() : getSupportedChannelOutLayoutMap(),
+            channelCount, INVALID_CHANNEL_LAYOUT);
+}
+
+AudioChannelLayout getChannelIndexMaskFromChannelCount(unsigned int channelCount) {
+    return findValueOrDefault(getSupportedChannelIndexLayoutMap(), channelCount,
+                              INVALID_CHANNEL_LAYOUT);
+}
+
+unsigned int getChannelCountFromChannelMask(const AudioChannelLayout& channelMask, bool isInput) {
+    switch (channelMask.getTag()) {
+        case AudioChannelLayout::Tag::layoutMask: {
+            return findKeyOrDefault(
+                    isInput ? getSupportedChannelInLayoutMap() : getSupportedChannelOutLayoutMap(),
+                    (unsigned int)getChannelCount(channelMask), 0u /*defaultValue*/);
+        }
+        case AudioChannelLayout::Tag::indexMask: {
+            return findKeyOrDefault(getSupportedChannelIndexLayoutMap(),
+                                    (unsigned int)getChannelCount(channelMask),
+                                    0u /*defaultValue*/);
+        }
+        case AudioChannelLayout::Tag::none:
+        case AudioChannelLayout::Tag::invalid:
+        case AudioChannelLayout::Tag::voiceMask:
+        default:
+            return 0;
+    }
+}
+
+AudioFormatDescription legacy2aidl_pcm_format_AudioFormatDescription(enum pcm_format legacy) {
+    return findValueOrDefault(getPcmFormatToAudioFormatDescMap(), legacy, AudioFormatDescription());
+}
+
+pcm_format aidl2legacy_AudioFormatDescription_pcm_format(const AudioFormatDescription& aidl) {
+    return findValueOrDefault(getAudioFormatDescriptorToPcmFormatMap(), aidl, PCM_FORMAT_INVALID);
+}
+
+}  // namespace aidl::android::hardware::audio::core::usb
diff --git a/audio/aidl/default/usb/UsbAlsaUtils.h b/audio/aidl/default/usb/UsbAlsaUtils.h
new file mode 100644
index 0000000..2d2f0f4
--- /dev/null
+++ b/audio/aidl/default/usb/UsbAlsaUtils.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+
+extern "C" {
+#include <tinyalsa/pcm.h>
+}
+
+namespace aidl::android::hardware::audio::core::usb {
+
+::aidl::android::media::audio::common::AudioChannelLayout getChannelLayoutMaskFromChannelCount(
+        unsigned int channelCount, int isInput);
+::aidl::android::media::audio::common::AudioChannelLayout getChannelIndexMaskFromChannelCount(
+        unsigned int channelCount);
+unsigned int getChannelCountFromChannelMask(
+        const ::aidl::android::media::audio::common::AudioChannelLayout& channelMask, bool isInput);
+::aidl::android::media::audio::common::AudioFormatDescription
+legacy2aidl_pcm_format_AudioFormatDescription(enum pcm_format legacy);
+pcm_format aidl2legacy_AudioFormatDescription_pcm_format(
+        const ::aidl::android::media::audio::common::AudioFormatDescription& aidl);
+
+}  // namespace aidl::android::hardware::audio::core::usb
\ No newline at end of file
diff --git a/audio/aidl/default/virtualizer/Android.bp b/audio/aidl/default/virtualizer/Android.bp
new file mode 100644
index 0000000..ed0199d
--- /dev/null
+++ b/audio/aidl/default/virtualizer/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libvirtualizersw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "VirtualizerSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
new file mode 100644
index 0000000..0e8435e
--- /dev/null
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+#include <optional>
+
+#define LOG_TAG "AHAL_VirtualizerSw"
+#include <Utils.h>
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "VirtualizerSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidVirtualizerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::hardware::audio::effect::VirtualizerSw;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVirtualizerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<VirtualizerSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVirtualizerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = VirtualizerSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string VirtualizerSw::kEffectName = "VirtualizerSw";
+
+const std::vector<Range::VirtualizerRange> VirtualizerSw::kRanges = {
+        MAKE_RANGE(Virtualizer, strengthPm, 0, 1000),
+        /* speakerAngle is get-only, set min > max */
+        MAKE_RANGE(Virtualizer, speakerAngles, {Virtualizer::ChannelAngle({.channel = 1})},
+                   {Virtualizer::ChannelAngle({.channel = 0})})};
+
+const Capability VirtualizerSw::kCapability = {
+        .range = Range::make<Range::virtualizer>(VirtualizerSw::kRanges)};
+
+const Descriptor VirtualizerSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidVirtualizer(),
+                          .uuid = getEffectImplUuidVirtualizerSw()},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = VirtualizerSw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = VirtualizerSw::kCapability};
+
+ndk::ScopedAStatus VirtualizerSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VirtualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::virtualizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+
+    auto& vrParam = specific.get<Parameter::Specific::virtualizer>();
+    RETURN_IF(!inRange(vrParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = vrParam.getTag();
+
+    switch (tag) {
+        case Virtualizer::strengthPm: {
+            RETURN_IF(mContext->setVrStrength(vrParam.get<Virtualizer::strengthPm>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setStrengthPmFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case Virtualizer::device: {
+            RETURN_IF(mContext->setForcedDevice(vrParam.get<Virtualizer::device>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case Virtualizer::speakerAngles:
+            FALLTHROUGH_INTENDED;
+        case Virtualizer::vendor: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VirtualizerTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus VirtualizerSw::getParameterSpecific(const Parameter::Id& id,
+                                                       Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::virtualizerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto vrId = id.get<Parameter::Id::virtualizerTag>();
+    auto vrIdTag = vrId.getTag();
+    switch (vrIdTag) {
+        case Virtualizer::Id::commonTag:
+            return getParameterVirtualizer(vrId.get<Virtualizer::Id::commonTag>(), specific);
+        case Virtualizer::Id::speakerAnglesPayload:
+            return getSpeakerAngles(vrId.get<Virtualizer::Id::speakerAnglesPayload>(), specific);
+        case Virtualizer::Id::vendorExtensionTag: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VirtualizerTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus VirtualizerSw::getParameterVirtualizer(const Virtualizer::Tag& tag,
+                                                          Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    Virtualizer vrParam;
+    switch (tag) {
+        case Virtualizer::strengthPm: {
+            vrParam.set<Virtualizer::strengthPm>(mContext->getVrStrength());
+            break;
+        }
+        case Virtualizer::device: {
+            vrParam.set<Virtualizer::device>(mContext->getForcedDevice());
+            break;
+        }
+        case Virtualizer::speakerAngles:
+            FALLTHROUGH_INTENDED;
+        case Virtualizer::vendor: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VirtualizerTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::virtualizer>(vrParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VirtualizerSw::getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
+                                                   Parameter::Specific* specific) {
+    std::vector<Virtualizer::ChannelAngle> angles;
+    const auto chNum = ::aidl::android::hardware::audio::common::getChannelCount(payload.layout);
+    if (chNum == 1) {
+        angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
+                   .azimuthDegree = 0,
+                   .elevationDegree = 0}};
+    } else if (chNum == 2) {
+        angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
+                   .azimuthDegree = -90,
+                   .elevationDegree = 0},
+                  {.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_RIGHT,
+                   .azimuthDegree = 90,
+                   .elevationDegree = 0}};
+    } else {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "supportUpTo2Ch");
+    }
+
+    Virtualizer param = Virtualizer::make<Virtualizer::speakerAngles>(angles);
+    specific->set<Parameter::Specific::virtualizer>(param);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> VirtualizerSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<VirtualizerSwContext>(1 /* statusFmqDepth */, common);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> VirtualizerSw::getContext() {
+    return mContext;
+}
+
+RetCode VirtualizerSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status VirtualizerSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode VirtualizerSwContext::setVrStrength(int strength) {
+    mStrength = strength;
+    return RetCode::SUCCESS;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.h b/audio/aidl/default/virtualizer/VirtualizerSw.h
new file mode 100644
index 0000000..5e114d9
--- /dev/null
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class VirtualizerSwContext final : public EffectContext {
+  public:
+    VirtualizerSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+    RetCode setVrStrength(int strength);
+    int getVrStrength() const { return mStrength; }
+    RetCode setForcedDevice(
+            const ::aidl::android::media::audio::common::AudioDeviceDescription& device) {
+        mForceDevice = device;
+        return RetCode::SUCCESS;
+    }
+    aidl::android::media::audio::common::AudioDeviceDescription getForcedDevice() const {
+        return mForceDevice;
+    }
+
+  private:
+    int mStrength = 0;
+    ::aidl::android::media::audio::common::AudioDeviceDescription mForceDevice;
+};
+
+class VirtualizerSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    VirtualizerSw() { LOG(DEBUG) << __func__; }
+    ~VirtualizerSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
+  private:
+    static const std::vector<Range::VirtualizerRange> kRanges;
+    std::shared_ptr<VirtualizerSwContext> mContext;
+
+    ndk::ScopedAStatus getParameterVirtualizer(const Virtualizer::Tag& tag,
+                                               Parameter::Specific* specific);
+    ndk::ScopedAStatus getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
+                                        Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/visualizer/Android.bp b/audio/aidl/default/visualizer/Android.bp
new file mode 100644
index 0000000..091daa2
--- /dev/null
+++ b/audio/aidl/default/visualizer/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libvisualizersw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "VisualizerSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
new file mode 100644
index 0000000..0909f25
--- /dev/null
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AHAL_VisualizerSw"
+
+#include <android-base/logging.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "VisualizerSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidVisualizerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::hardware::audio::effect::VisualizerSw;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVisualizerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<VisualizerSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVisualizerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = VisualizerSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string VisualizerSw::kEffectName = "VisualizerSw";
+
+/* capabilities */
+const std::vector<Range::VisualizerRange> VisualizerSw::kRanges = {
+        MAKE_RANGE(Visualizer, latencyMs, 0, VisualizerSwContext::kMaxLatencyMs),
+        MAKE_RANGE(Visualizer, captureSamples, VisualizerSwContext::kMinCaptureSize,
+                   VisualizerSwContext::kMaxCaptureSize)};
+
+const Capability VisualizerSw::kCapability = {
+        .range = Range::make<Range::visualizer>(VisualizerSw::kRanges)};
+
+const Descriptor VisualizerSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidVisualizer(),
+                          .uuid = getEffectImplUuidVisualizerSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = VisualizerSw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = VisualizerSw::kCapability};
+
+ndk::ScopedAStatus VisualizerSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VisualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::visualizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+
+    auto& vsParam = specific.get<Parameter::Specific::visualizer>();
+    RETURN_IF(!inRange(vsParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = vsParam.getTag();
+
+    switch (tag) {
+        case Visualizer::captureSamples: {
+            RETURN_IF(mContext->setVsCaptureSize(vsParam.get<Visualizer::captureSamples>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setCaptureSizeFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case Visualizer::scalingMode: {
+            RETURN_IF(mContext->setVsScalingMode(vsParam.get<Visualizer::scalingMode>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setScalingModeFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case Visualizer::measurementMode: {
+            RETURN_IF(mContext->setVsMeasurementMode(vsParam.get<Visualizer::measurementMode>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setMeasurementModeFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        case Visualizer::latencyMs: {
+            RETURN_IF(mContext->setVsLatency(vsParam.get<Visualizer::latencyMs>()) !=
+                              RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "setLatencyFailed");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VisualizerTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus VisualizerSw::getParameterSpecific(const Parameter::Id& id,
+                                                      Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::visualizerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto vsId = id.get<Parameter::Id::visualizerTag>();
+    auto vsIdTag = vsId.getTag();
+    switch (vsIdTag) {
+        case Visualizer::Id::commonTag:
+            return getParameterVisualizer(vsId.get<Visualizer::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VisualizerTagNotSupported");
+    }
+}
+ndk::ScopedAStatus VisualizerSw::getParameterVisualizer(const Visualizer::Tag& tag,
+                                                        Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    Visualizer vsParam;
+    switch (tag) {
+        case Visualizer::captureSamples: {
+            vsParam.set<Visualizer::captureSamples>(mContext->getVsCaptureSize());
+            break;
+        }
+        case Visualizer::scalingMode: {
+            vsParam.set<Visualizer::scalingMode>(mContext->getVsScalingMode());
+            break;
+        }
+        case Visualizer::measurementMode: {
+            vsParam.set<Visualizer::measurementMode>(mContext->getVsMeasurementMode());
+            break;
+        }
+        case Visualizer::measurement: {
+            vsParam.set<Visualizer::measurement>(mContext->getVsMeasurement());
+            break;
+        }
+        case Visualizer::captureSampleBuffer: {
+            vsParam.set<Visualizer::captureSampleBuffer>(mContext->getVsCaptureSampleBuffer());
+            break;
+        }
+        case Visualizer::latencyMs: {
+            vsParam.set<Visualizer::latencyMs>(mContext->getVsLatency());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VisualizerTagNotSupported");
+        }
+    }
+    specific->set<Parameter::Specific::visualizer>(vsParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> VisualizerSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<VisualizerSwContext>(1 /* statusFmqDepth */, common);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> VisualizerSw::getContext() {
+    return mContext;
+}
+
+RetCode VisualizerSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status VisualizerSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode VisualizerSwContext::setVsCaptureSize(int captureSize) {
+    mCaptureSize = captureSize;
+    return RetCode::SUCCESS;
+}
+
+RetCode VisualizerSwContext::setVsScalingMode(Visualizer::ScalingMode scalingMode) {
+    mScalingMode = scalingMode;
+    return RetCode::SUCCESS;
+}
+
+RetCode VisualizerSwContext::setVsMeasurementMode(Visualizer::MeasurementMode measurementMode) {
+    mMeasurementMode = measurementMode;
+    return RetCode::SUCCESS;
+}
+
+RetCode VisualizerSwContext::setVsLatency(int latency) {
+    mLatency = latency;
+    return RetCode::SUCCESS;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
new file mode 100644
index 0000000..995774e
--- /dev/null
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class VisualizerSwContext final : public EffectContext {
+  public:
+    static const int kMinCaptureSize = 0x80;
+    static const int kMaxCaptureSize = 0x400;
+    static const int kMaxLatencyMs = 3000;
+    static const int kMaxCaptureBufSize = 0xffff;
+    VisualizerSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+        mCaptureSampleBuffer.resize(kMaxCaptureBufSize);
+        fill(mCaptureSampleBuffer.begin(), mCaptureSampleBuffer.end(), 0x80);
+    }
+
+    RetCode setVsCaptureSize(int captureSize);
+    int getVsCaptureSize() const { return mCaptureSize; }
+
+    RetCode setVsScalingMode(Visualizer::ScalingMode scalingMode);
+    Visualizer::ScalingMode getVsScalingMode() const { return mScalingMode; }
+
+    RetCode setVsMeasurementMode(Visualizer::MeasurementMode measurementMode);
+    Visualizer::MeasurementMode getVsMeasurementMode() const { return mMeasurementMode; }
+
+    RetCode setVsLatency(int latency);
+    int getVsLatency() const { return mLatency; }
+
+    Visualizer::Measurement getVsMeasurement() const { return mMeasurement; }
+    std::vector<uint8_t> getVsCaptureSampleBuffer() const { return mCaptureSampleBuffer; }
+
+  private:
+    int mCaptureSize = kMaxCaptureSize;
+    Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
+    Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
+    int mLatency = 0;
+    const Visualizer::Measurement mMeasurement = {0, 0};
+    std::vector<uint8_t> mCaptureSampleBuffer;
+};
+
+class VisualizerSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    VisualizerSw() { LOG(DEBUG) << __func__; }
+    ~VisualizerSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
+  private:
+    static const std::vector<Range::VisualizerRange> kRanges;
+    std::shared_ptr<VisualizerSwContext> mContext;
+    ndk::ScopedAStatus getParameterVisualizer(const Visualizer::Tag& tag,
+                                              Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/volume/Android.bp b/audio/aidl/default/volume/Android.bp
new file mode 100644
index 0000000..418bb8d
--- /dev/null
+++ b/audio/aidl/default/volume/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_shared {
+    name: "libvolumesw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+        "latest_android_media_audio_common_types_ndk_shared",
+        "latest_android_hardware_audio_effect_ndk_shared",
+    ],
+    srcs: [
+        "VolumeSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
new file mode 100644
index 0000000..8902584
--- /dev/null
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstddef>
+
+#define LOG_TAG "AHAL_VolumeSw"
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "VolumeSw.h"
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidVolumeSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVolume;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::hardware::audio::effect::VolumeSw;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVolumeSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (instanceSpp) {
+        *instanceSpp = ndk::SharedRefBase::make<VolumeSw>();
+        LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+        return EX_NONE;
+    } else {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidVolumeSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = VolumeSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string VolumeSw::kEffectName = "VolumeSw";
+
+const std::vector<Range::VolumeRange> VolumeSw::kRanges = {MAKE_RANGE(Volume, levelDb, -9600, 0)};
+
+const Capability VolumeSw::kCapability = {.range = Range::make<Range::volume>(VolumeSw::kRanges)};
+
+const Descriptor VolumeSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidVolume(),
+                          .uuid = getEffectImplUuidVolumeSw(),
+                          .proxy = std::nullopt},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .volume = Flags::Volume::CTRL},
+                   .name = VolumeSw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = VolumeSw::kCapability};
+
+ndk::ScopedAStatus VolumeSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VolumeSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::volume != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+
+    auto& volParam = specific.get<Parameter::Specific::volume>();
+    RETURN_IF(!inRange(volParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+    auto tag = volParam.getTag();
+
+    switch (tag) {
+        case Volume::levelDb: {
+            RETURN_IF(mContext->setVolLevel(volParam.get<Volume::levelDb>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "LevelNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        case Volume::mute: {
+            RETURN_IF(mContext->setVolMute(volParam.get<Volume::mute>()) != RetCode::SUCCESS,
+                      EX_ILLEGAL_ARGUMENT, "MuteNotSupported");
+            return ndk::ScopedAStatus::ok();
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VolumeTagNotSupported");
+        }
+    }
+}
+
+ndk::ScopedAStatus VolumeSw::getParameterSpecific(const Parameter::Id& id,
+                                                  Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::volumeTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto volId = id.get<Parameter::Id::volumeTag>();
+    auto volIdTag = volId.getTag();
+    switch (volIdTag) {
+        case Volume::Id::commonTag:
+            return getParameterVolume(volId.get<Volume::Id::commonTag>(), specific);
+        default:
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VolumeTagNotSupported");
+    }
+}
+
+ndk::ScopedAStatus VolumeSw::getParameterVolume(const Volume::Tag& tag,
+                                                Parameter::Specific* specific) {
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    Volume volParam;
+    switch (tag) {
+        case Volume::levelDb: {
+            volParam.set<Volume::levelDb>(mContext->getVolLevel());
+            break;
+        }
+        case Volume::mute: {
+            volParam.set<Volume::mute>(mContext->getVolMute());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "VolumeTagNotSupported");
+        }
+    }
+
+    specific->set<Parameter::Specific::volume>(volParam);
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> VolumeSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<VolumeSwContext>(1 /* statusFmqDepth */, common);
+    }
+
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> VolumeSw::getContext() {
+    return mContext;
+}
+
+RetCode VolumeSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status VolumeSw::effectProcessImpl(float* in, float* out, int samples) {
+    // TODO: get data buffer and process.
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    for (int i = 0; i < samples; i++) {
+        *out++ = *in++;
+    }
+    return {STATUS_OK, samples, samples};
+}
+
+RetCode VolumeSwContext::setVolLevel(int level) {
+    mLevel = level;
+    return RetCode::SUCCESS;
+}
+
+RetCode VolumeSwContext::setVolMute(bool mute) {
+    // TODO : Add implementation to modify mute
+    mMute = mute;
+    return RetCode::SUCCESS;
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
new file mode 100644
index 0000000..1432b2b
--- /dev/null
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <fmq/AidlMessageQueue.h>
+#include <cstdlib>
+#include <memory>
+
+#include "effect-impl/EffectImpl.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class VolumeSwContext final : public EffectContext {
+  public:
+    VolumeSwContext(int statusDepth, const Parameter::Common& common)
+        : EffectContext(statusDepth, common) {
+        LOG(DEBUG) << __func__;
+    }
+
+    RetCode setVolLevel(int level);
+
+    int getVolLevel() const { return mLevel; }
+
+    RetCode setVolMute(bool mute);
+
+    bool getVolMute() const { return mMute; }
+
+  private:
+    int mLevel = 0;
+    bool mMute = false;
+};
+
+class VolumeSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    VolumeSw() { LOG(DEBUG) << __func__; }
+    ~VolumeSw() {
+        cleanUp();
+        LOG(DEBUG) << __func__;
+    }
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+    std::string getEffectName() override { return kEffectName; }
+
+  private:
+    static const std::vector<Range::VolumeRange> kRanges;
+    std::shared_ptr<VolumeSwContext> mContext;
+
+    ndk::ScopedAStatus getParameterVolume(const Volume::Tag& tag, Parameter::Specific* specific);
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/sounddose/Android.bp b/audio/aidl/sounddose/Android.bp
new file mode 100644
index 0000000..6f2f790
--- /dev/null
+++ b/audio/aidl/sounddose/Android.bp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.audio.sounddose",
+    host_supported: true,
+    vendor_available: true,
+    stability: "vintf",
+    srcs: [
+        "android/hardware/audio/sounddose/ISoundDoseFactory.aidl",
+    ],
+    imports: [
+        latest_android_hardware_audio_core_sounddose,
+    ],
+    backend: {
+        // The C++ backend is disabled transitively due to use by core audio HAL.
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.audio.core.sounddose-V1"],
+        },
+
+        // IMPORTANT: Update latest_android_hardware_audio_sounddose every time you
+        // add the latest frozen version to versions_with_info
+    ],
+    frozen: true,
+}
+
+// Note: This should always be one version ahead of the last frozen version
+latest_android_hardware_audio_sounddose = "android.hardware.audio.sounddose-V1"
+
+// Modules that depend on android.hardware.audio.sounddose directly can include
+// the following cc_defaults to avoid explicitly managing dependency versions
+// across many scattered files.
+cc_defaults {
+    name: "latest_android_hardware_audio_sounddose_ndk_shared",
+    shared_libs: [
+        latest_android_hardware_audio_sounddose + "-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "latest_android_hardware_audio_sounddose_ndk_static",
+    static_libs: [
+        latest_android_hardware_audio_sounddose + "-ndk",
+    ],
+}
diff --git a/audio/aidl/sounddose/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/sounddose/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
new file mode 100644
index 0000000..dff17e2
--- /dev/null
+++ b/audio/aidl/sounddose/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.core;
+@VintfStability
+interface ISoundDose {
+  void setOutputRs2(float rs2ValueDbA);
+  float getOutputRs2();
+  void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
+  const int DEFAULT_MAX_RS2 = 100;
+  @VintfStability
+  interface IHalSoundDoseCallback {
+    oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
+    oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
+    @VintfStability
+    parcelable MelRecord {
+      float[] melValues;
+      long timestamp;
+    }
+  }
+}
diff --git a/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/1/.hash b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/1/.hash
new file mode 100644
index 0000000..625abab
--- /dev/null
+++ b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/1/.hash
@@ -0,0 +1 @@
+7acf835db643d39414afbbbbcda816e2d7e8c77a
diff --git a/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/1/android/hardware/audio/sounddose/ISoundDoseFactory.aidl b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/1/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
new file mode 100644
index 0000000..148720c
--- /dev/null
+++ b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/1/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.sounddose;
+@VintfStability
+interface ISoundDoseFactory {
+  @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose(in @utf8InCpp String module);
+}
diff --git a/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
new file mode 100644
index 0000000..148720c
--- /dev/null
+++ b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.audio.sounddose;
+@VintfStability
+interface ISoundDoseFactory {
+  @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose(in @utf8InCpp String module);
+}
diff --git a/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl b/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
new file mode 100644
index 0000000..4079fe8
--- /dev/null
+++ b/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.audio.sounddose;
+
+import android.hardware.audio.core.sounddose.ISoundDose;
+
+/**
+ * This interface is used to provide an easy way to implement the ISoundDose interface
+ * without switching the audio HAL to AIDL. The implementation is intended as a workaround
+ * for the certification with IEC62368-1 3rd edition and EN50332-3.
+ * Note that this interface will be deprecated in favor of the audio AIDL HAL.
+ */
+@VintfStability
+interface ISoundDoseFactory {
+    /**
+     * Retrieve the sound dose interface for a given audio HAL module name.
+     *
+     * If a device must comply to IEC62368-1 3rd edition audio safety requirements and is
+     * implementing audio offload decoding or other direct playback paths where volume control
+     * happens below the audio HAL, it must return an instance of the ISoundDose interface.
+     * The same instance must be returned during the lifetime of the HAL module.
+     * If the HAL module does not support sound dose, null must be returned, without throwing
+     * any errors.
+     *
+     * @param module for which we trigger sound dose updates.
+     * @return An instance of the ISoundDose interface implementation.
+     * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+     */
+    @nullable ISoundDose getSoundDose(in @utf8InCpp String module);
+}
diff --git a/audio/aidl/sounddose/vts/Android.bp b/audio/aidl/sounddose/vts/Android.bp
new file mode 100644
index 0000000..88be968
--- /dev/null
+++ b/audio/aidl/sounddose/vts/Android.bp
@@ -0,0 +1,36 @@
+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_test {
+    name: "VtsHalSoundDoseFactoryTargetTest",
+    defaults: [
+        "latest_android_hardware_audio_core_sounddose_ndk_static",
+        "latest_android_hardware_audio_sounddose_ndk_static",
+        "latest_android_media_audio_common_types_ndk_static",
+        "use_libaidlvintf_gtest_helper_static",
+        "VtsHalTargetTestDefaults",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcutils",
+    ],
+    srcs: [
+        "VtsHalSoundDoseFactoryTargetTest.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/audio/aidl/sounddose/vts/TEST_MAPPING b/audio/aidl/sounddose/vts/TEST_MAPPING
new file mode 100644
index 0000000..bebeed9
--- /dev/null
+++ b/audio/aidl/sounddose/vts/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalSoundDoseFactoryTargetTest"
+    }
+  ]
+}
diff --git a/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
new file mode 100644
index 0000000..7722ccf
--- /dev/null
+++ b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VtsHalSoundDose.Factory"
+#include <android-base/logging.h>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/sounddose/ISoundDoseFactory.h>
+#include <android/binder_manager.h>
+
+#include <memory>
+
+namespace android::hardware::audio::common::testing {
+
+namespace detail {
+
+inline ::testing::AssertionResult assertIsOk(const char* expr, const ::ndk::ScopedAStatus& status) {
+    if (status.isOk()) {
+        return ::testing::AssertionSuccess();
+    }
+    return ::testing::AssertionFailure()
+           << "Expected the transaction \'" << expr << "\' to succeed\n"
+           << "  but it has failed with: " << status;
+}
+
+}  // namespace detail
+
+}  // namespace android::hardware::audio::common::testing
+
+// Test that the transaction status 'isOk'
+#define EXPECT_IS_OK(ret) \
+    EXPECT_PRED_FORMAT1(::android::hardware::audio::common::testing::detail::assertIsOk, ret)
+
+using namespace android;
+
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
+using aidl::android::hardware::audio::sounddose::ISoundDoseFactory;
+
+class SoundDoseFactory : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(ConnectToService(GetParam())); }
+
+    void TearDown() override {}
+
+    void ConnectToService(const std::string& interfaceName) {
+        ndk::SpAIBinder binder =
+                ndk::SpAIBinder(AServiceManager_waitForService(interfaceName.c_str()));
+        if (binder == nullptr) {
+            LOG(ERROR) << "Failed to get service " << interfaceName;
+        } else {
+            LOG(DEBUG) << "Succeeded to get service " << interfaceName;
+        }
+        soundDoseFactory = ISoundDoseFactory::fromBinder(binder);
+        ASSERT_NE(soundDoseFactory, nullptr);
+    }
+
+    std::shared_ptr<ISoundDoseFactory> soundDoseFactory;
+};
+
+// @VsrTest = VSR-5.5-002.001
+TEST_P(SoundDoseFactory, GetSoundDoseForSameModule) {
+    const std::string module = "primary";
+
+    std::shared_ptr<ISoundDose> soundDose1;
+    EXPECT_IS_OK(soundDoseFactory->getSoundDose(module, &soundDose1));
+
+    if (soundDose1 == nullptr) {
+        LOG(WARNING) << "Primary module does not support sound dose";
+        return;
+    }
+
+    std::shared_ptr<ISoundDose> soundDose2;
+    EXPECT_IS_OK(soundDoseFactory->getSoundDose(module, &soundDose2));
+    EXPECT_NE(nullptr, soundDose2);
+    EXPECT_EQ(soundDose1->asBinder(), soundDose2->asBinder())
+            << "getSoundDose must return the same interface for the same module";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        SoundDoseFactoryTest, SoundDoseFactory,
+        testing::ValuesIn(android::getAidlHalInstanceNames(ISoundDoseFactory::descriptor)),
+        android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SoundDoseFactory);
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
new file mode 100644
index 0000000..852255d
--- /dev/null
+++ b/audio/aidl/vts/Android.bp
@@ -0,0 +1,161 @@
+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_defaults {
+    name: "VtsHalAudioTargetTestDefaults",
+    defaults: [
+        "latest_android_hardware_audio_common_ndk_static",
+        "latest_android_media_audio_common_types_ndk_static",
+        "use_libaidlvintf_gtest_helper_static",
+        "VtsHalTargetTestDefaults",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libfmq",
+    ],
+    static_libs: [
+        "android.hardware.audio.effect-V1-ndk",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+        "libaudioaidlcommon",
+        "libaidlcommonsupport",
+    ],
+    header_libs: ["libaudioaidl_headers"],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    srcs: [":effectCommonFile"],
+}
+
+cc_test {
+    name: "VtsHalAudioCoreTargetTest",
+    defaults: [
+        "VtsHalAudioTargetTestDefaults",
+        "latest_android_hardware_audio_core_ndk_static",
+        "latest_android_hardware_audio_core_sounddose_ndk_static",
+    ],
+    shared_libs: [
+        "libcutils",
+    ],
+    srcs: [
+        "ModuleConfig.cpp",
+        "VtsHalAudioCoreConfigTargetTest.cpp",
+        "VtsHalAudioCoreModuleTargetTest.cpp",
+    ],
+}
+
+cc_test {
+    name: "VtsHalAudioEffectFactoryTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalAudioEffectFactoryTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalAudioEffectTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalAudioEffectTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalBassBoostTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalBassBoostTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalDownmixTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalDownmixTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalDynamicsProcessingTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    static_libs: ["libaudioaidlranges"],
+    srcs: ["VtsHalDynamicsProcessingTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalEnvironmentalReverbTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalEnvironmentalReverbTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalEqualizerTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalEqualizerTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalHapticGeneratorTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalHapticGeneratorTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalLoudnessEnhancerTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalLoudnessEnhancerTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalPresetReverbTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalPresetReverbTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalVirtualizerTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalVirtualizerTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalVisualizerTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalVisualizerTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalVolumeTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalVolumeTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalAECTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalAECTargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalAGC1TargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalAGC1TargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalAGC2TargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalAGC2TargetTest.cpp"],
+}
+
+cc_test {
+    name: "VtsHalNSTargetTest",
+    defaults: ["VtsHalAudioTargetTestDefaults"],
+    srcs: ["VtsHalNSTargetTest.cpp"],
+}
diff --git a/audio/aidl/vts/AudioHalBinderServiceUtil.h b/audio/aidl/vts/AudioHalBinderServiceUtil.h
new file mode 100644
index 0000000..b4b4632
--- /dev/null
+++ b/audio/aidl/vts/AudioHalBinderServiceUtil.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <condition_variable>
+#include <memory>
+#include <mutex>
+
+#include <android-base/properties.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include <android-base/logging.h>
+
+class AudioHalBinderServiceUtil {
+  public:
+    ndk::SpAIBinder connectToService(const std::string& serviceName) {
+        mServiceName = serviceName;
+        mBinder = ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str()));
+        if (mBinder == nullptr) {
+            LOG(ERROR) << "Failed to get service " << serviceName;
+        } else {
+            LOG(DEBUG) << "Succeeded to get service " << serviceName;
+        }
+        return mBinder;
+    }
+
+    ndk::SpAIBinder restartService(
+            std::chrono::milliseconds timeoutMs = std::chrono::milliseconds(3000)) {
+        mDeathHandler.reset(new AidlDeathRecipient(mBinder));
+        if (STATUS_OK != mDeathHandler->linkToDeath()) {
+            LOG(ERROR) << "linkToDeath failed";
+            return nullptr;
+        }
+        if (!android::base::SetProperty("sys.audio.restart.hal", "1")) {
+            LOG(ERROR) << "SetProperty failed";
+            return nullptr;
+        }
+        if (!mDeathHandler->waitForFired(timeoutMs)) {
+            LOG(ERROR) << "Timeout wait for death";
+            return nullptr;
+        }
+        mDeathHandler.reset();
+        return connectToService(mServiceName);
+    }
+
+  private:
+    class AidlDeathRecipient {
+      public:
+        explicit AidlDeathRecipient(const ndk::SpAIBinder& binder)
+            : binder(binder), recipient(AIBinder_DeathRecipient_new(&binderDiedCallbackAidl)) {}
+
+        binder_status_t linkToDeath() {
+            return AIBinder_linkToDeath(binder.get(), recipient.get(), this);
+        }
+
+        bool waitForFired(std::chrono::milliseconds timeoutMs) {
+            std::unique_lock<std::mutex> lock(mutex);
+            condition.wait_for(lock, timeoutMs, [this]() { return fired; });
+            return fired;
+        }
+
+      private:
+        const ndk::SpAIBinder binder;
+        const ndk::ScopedAIBinder_DeathRecipient recipient;
+        std::mutex mutex;
+        std::condition_variable condition;
+        bool fired = false;
+
+        void binderDied() {
+            std::unique_lock<std::mutex> lock(mutex);
+            fired = true;
+            condition.notify_one();
+        };
+
+        static void binderDiedCallbackAidl(void* cookie) {
+            AidlDeathRecipient* self = static_cast<AidlDeathRecipient*>(cookie);
+            self->binderDied();
+        }
+    };
+
+    std::string mServiceName;
+    ndk::SpAIBinder mBinder;
+    std::unique_ptr<AidlDeathRecipient> mDeathHandler;
+};
diff --git a/audio/aidl/vts/EffectFactoryHelper.h b/audio/aidl/vts/EffectFactoryHelper.h
new file mode 100644
index 0000000..a2499fd
--- /dev/null
+++ b/audio/aidl/vts/EffectFactoryHelper.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <android/binder_auto_utils.h>
+
+#include "TestUtils.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::media::audio::common::AudioUuid;
+
+class EffectFactoryHelper {
+  public:
+    explicit EffectFactoryHelper(const std::string& name) : mServiceName(name) {}
+
+    void ConnectToFactoryService() {
+        mEffectFactory = IFactory::fromBinder(binderUtil.connectToService(mServiceName));
+        ASSERT_NE(mEffectFactory, nullptr);
+    }
+
+    void RestartFactoryService() {
+        ASSERT_NE(mEffectFactory, nullptr);
+        mEffectFactory = IFactory::fromBinder(binderUtil.restartService());
+        ASSERT_NE(mEffectFactory, nullptr);
+    }
+
+    std::shared_ptr<IFactory> GetFactory() const { return mEffectFactory; }
+
+    static std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> getAllEffectDescriptors(
+            std::string serviceName, std::optional<AudioUuid> type = std::nullopt) {
+        AudioHalBinderServiceUtil util;
+        auto names = android::getAidlHalInstanceNames(serviceName);
+        std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> result;
+
+        for (const auto& name : names) {
+            auto factory = IFactory::fromBinder(util.connectToService(name));
+            if (factory) {
+                if (std::vector<Descriptor> descs;
+                    factory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs)
+                            .isOk()) {
+                    for (const auto& desc : descs) {
+                        if (type.has_value() && desc.common.id.type != type.value()) {
+                            continue;
+                        }
+                        result.emplace_back(factory, desc);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+  private:
+    std::shared_ptr<IFactory> mEffectFactory;
+    std::string mServiceName;
+    AudioHalBinderServiceUtil binderUtil;
+};
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
new file mode 100644
index 0000000..4e84f6b
--- /dev/null
+++ b/audio/aidl/vts/EffectHelper.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <unordered_map>
+#include <vector>
+
+#include <Utils.h>
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
+#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <android/binder_auto_utils.h>
+#include <fmq/AidlMessageQueue.h>
+#include <gtest/gtest.h>
+#include <system/audio_effects/aidl_effects_utils.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include "AudioHalBinderServiceUtil.h"
+#include "EffectFactoryHelper.h"
+#include "TestUtils.h"
+
+using namespace android;
+using aidl::android::hardware::audio::effect::CommandId;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioUuid;
+using aidl::android::media::audio::common::PcmType;
+using ::android::hardware::EventFlag;
+
+const AudioFormatDescription kDefaultFormatDescription = {
+        .type = AudioFormatType::PCM, .pcm = PcmType::FLOAT_32_BIT, .encoding = ""};
+
+typedef ::android::AidlMessageQueue<IEffect::Status,
+                                    ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+        StatusMQ;
+typedef ::android::AidlMessageQueue<float,
+                                    ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+        DataMQ;
+
+class EffectHelper {
+  public:
+    static void create(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect>& effect,
+                       Descriptor& desc, binder_status_t status = EX_NONE) {
+        ASSERT_NE(factory, nullptr);
+        auto& id = desc.common.id;
+        ASSERT_STATUS(status, factory->createEffect(id.uuid, &effect));
+        if (status == EX_NONE) {
+            ASSERT_NE(effect, nullptr) << id.uuid.toString();
+        }
+    }
+
+    static void destroyIgnoreRet(std::shared_ptr<IFactory> factory,
+                                 std::shared_ptr<IEffect> effect) {
+        if (factory && effect) {
+            factory->destroyEffect(effect);
+        }
+    }
+
+    static void destroy(std::shared_ptr<IFactory> factory, std::shared_ptr<IEffect> effect,
+                        binder_status_t status = EX_NONE) {
+        ASSERT_NE(factory, nullptr);
+        ASSERT_NE(effect, nullptr);
+        ASSERT_STATUS(status, factory->destroyEffect(effect));
+    }
+
+    static void open(std::shared_ptr<IEffect> effect, const Parameter::Common& common,
+                     const std::optional<Parameter::Specific>& specific,
+                     IEffect::OpenEffectReturn* ret, binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        ASSERT_STATUS(status, effect->open(common, specific, ret));
+    }
+
+    static void open(std::shared_ptr<IEffect> effect, int session = 0,
+                     binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        Parameter::Common common = EffectHelper::createParamCommon(session);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(effect, common, std::nullopt /* specific */, &ret, status));
+    }
+
+    static void closeIgnoreRet(std::shared_ptr<IEffect> effect) {
+        if (effect) {
+            effect->close();
+        }
+    }
+    static void close(std::shared_ptr<IEffect> effect, binder_status_t status = EX_NONE) {
+        if (effect) {
+            ASSERT_STATUS(status, effect->close());
+        }
+    }
+    static void getDescriptor(std::shared_ptr<IEffect> effect, Descriptor& desc,
+                              binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        ASSERT_STATUS(status, effect->getDescriptor(&desc));
+    }
+    static void expectState(std::shared_ptr<IEffect> effect, State expectState,
+                            binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        State state;
+        ASSERT_STATUS(status, effect->getState(&state));
+        ASSERT_EQ(expectState, state);
+    }
+    static void commandIgnoreRet(std::shared_ptr<IEffect> effect, CommandId command) {
+        if (effect) {
+            effect->command(command);
+        }
+    }
+    static void command(std::shared_ptr<IEffect> effect, CommandId command,
+                        binder_status_t status = EX_NONE) {
+        ASSERT_NE(effect, nullptr);
+        ASSERT_STATUS(status, effect->command(command));
+    }
+    static void allocateInputData(const Parameter::Common common, std::unique_ptr<DataMQ>& mq,
+                                  std::vector<float>& buffer) {
+        ASSERT_NE(mq, nullptr);
+        auto frameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes(
+                common.input.base.format, common.input.base.channelMask);
+        const size_t floatsToWrite = mq->availableToWrite();
+        ASSERT_NE(0UL, floatsToWrite);
+        ASSERT_EQ(frameSize * common.input.frameCount, floatsToWrite * sizeof(float));
+        buffer.resize(floatsToWrite);
+        std::fill(buffer.begin(), buffer.end(), 0x5a);
+    }
+    static void writeToFmq(std::unique_ptr<StatusMQ>& statusMq, std::unique_ptr<DataMQ>& dataMq,
+                           const std::vector<float>& buffer) {
+        const size_t available = dataMq->availableToWrite();
+        ASSERT_NE(0Ul, available);
+        auto bufferFloats = buffer.size();
+        auto floatsToWrite = std::min(available, bufferFloats);
+        ASSERT_TRUE(dataMq->write(buffer.data(), floatsToWrite));
+
+        EventFlag* efGroup;
+        ASSERT_EQ(::android::OK,
+                  EventFlag::createEventFlag(statusMq->getEventFlagWord(), &efGroup));
+        ASSERT_NE(nullptr, efGroup);
+        efGroup->wake(kEventFlagNotEmpty);
+        ASSERT_EQ(::android::OK, EventFlag::deleteEventFlag(&efGroup));
+    }
+    static void readFromFmq(std::unique_ptr<StatusMQ>& statusMq, size_t statusNum,
+                            std::unique_ptr<DataMQ>& dataMq, size_t expectFloats,
+                            std::vector<float>& buffer,
+                            std::optional<int> expectStatus = STATUS_OK) {
+        if (0 == statusNum) {
+            ASSERT_EQ(0ul, statusMq->availableToRead());
+            return;
+        }
+        IEffect::Status status{};
+        ASSERT_TRUE(statusMq->readBlocking(&status, statusNum));
+        if (expectStatus.has_value()) {
+            ASSERT_EQ(expectStatus.value(), status.status);
+        }
+
+        ASSERT_EQ(expectFloats, (unsigned)status.fmqProduced);
+        ASSERT_EQ(expectFloats, dataMq->availableToRead());
+        if (expectFloats != 0) {
+            ASSERT_TRUE(dataMq->read(buffer.data(), expectFloats));
+        }
+    }
+    static Parameter::Common createParamCommon(
+            int session = 0, int ioHandle = -1, int iSampleRate = 48000, int oSampleRate = 48000,
+            long iFrameCount = 0x100, long oFrameCount = 0x100,
+            AudioChannelLayout inputChannelLayout =
+                    AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                            AudioChannelLayout::LAYOUT_STEREO),
+            AudioChannelLayout outputChannelLayout =
+                    AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                            AudioChannelLayout::LAYOUT_STEREO)) {
+        Parameter::Common common;
+        common.session = session;
+        common.ioHandle = ioHandle;
+
+        auto& input = common.input;
+        auto& output = common.output;
+        input.base.sampleRate = iSampleRate;
+        input.base.channelMask = inputChannelLayout;
+        input.base.format = kDefaultFormatDescription;
+        input.frameCount = iFrameCount;
+        output.base.sampleRate = oSampleRate;
+        output.base.channelMask = outputChannelLayout;
+        output.base.format = kDefaultFormatDescription;
+        output.frameCount = oFrameCount;
+        return common;
+    }
+
+    typedef ::android::AidlMessageQueue<
+            IEffect::Status, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+            StatusMQ;
+    typedef ::android::AidlMessageQueue<
+            float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+            DataMQ;
+
+    class EffectParam {
+      public:
+        std::unique_ptr<StatusMQ> statusMQ;
+        std::unique_ptr<DataMQ> inputMQ;
+        std::unique_ptr<DataMQ> outputMQ;
+    };
+
+    template <typename T, Range::Tag tag>
+    static bool isParameterValid(const T& target, const Descriptor& desc) {
+        if (desc.capability.range.getTag() != tag) {
+            return true;
+        }
+        const auto& ranges = desc.capability.range.get<tag>();
+        return inRange(target, ranges);
+    }
+
+    /**
+     * Add to test value set: (min+max)/2, minimum/maximum numeric limits, and min-1/max+1 if
+     * result still in numeric limits after -1/+1.
+     * Only use this when the type of test value is basic type (std::is_arithmetic return true).
+     */
+    template <typename S, typename = std::enable_if_t<std::is_arithmetic_v<S>>>
+    static std::set<S> expandTestValueBasic(std::set<S>& s) {
+        const auto minLimit = std::numeric_limits<S>::min(),
+                   maxLimit = std::numeric_limits<S>::max();
+        if (s.size()) {
+            const auto min = *s.begin(), max = *s.rbegin();
+            s.insert(min + (max - min) / 2);
+            if (min != minLimit) {
+                s.insert(min - 1);
+            }
+            if (max != maxLimit) {
+                s.insert(max + 1);
+            }
+        }
+        s.insert(minLimit);
+        s.insert(maxLimit);
+        return s;
+    }
+
+    template <typename T, typename S, Range::Tag R, typename T::Tag tag, typename Functor>
+    static std::set<S> getTestValueSet(
+            std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList,
+            Functor functor) {
+        std::set<S> result;
+        for (const auto& [_, desc] : kFactoryDescList) {
+            if (desc.capability.range.getTag() == R) {
+                const auto& ranges = desc.capability.range.get<R>();
+                for (const auto& range : ranges) {
+                    if (range.min.getTag() == tag) {
+                        result.insert(range.min.template get<tag>());
+                    }
+                    if (range.max.getTag() == tag) {
+                        result.insert(range.max.template get<tag>());
+                    }
+                }
+            }
+        }
+        return functor(result);
+    }
+};
diff --git a/audio/aidl/vts/ModuleConfig.cpp b/audio/aidl/vts/ModuleConfig.cpp
new file mode 100644
index 0000000..8c448a8
--- /dev/null
+++ b/audio/aidl/vts/ModuleConfig.cpp
@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <chrono>
+
+#include <Utils.h>
+#include <aidl/android/media/audio/common/AudioInputFlags.h>
+#include <aidl/android/media/audio/common/AudioIoFlags.h>
+#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+
+#include "ModuleConfig.h"
+
+using namespace android;
+using namespace std::chrono_literals;
+
+using aidl::android::hardware::audio::common::isBitPositionFlagSet;
+using aidl::android::hardware::audio::core::IModule;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioEncapsulationMode;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioInputFlags;
+using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::AudioOutputFlags;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::AudioUsage;
+using aidl::android::media::audio::common::Int;
+
+// static
+std::optional<AudioOffloadInfo> ModuleConfig::generateOffloadInfoIfNeeded(
+        const AudioPortConfig& portConfig) {
+    if (portConfig.flags.has_value() &&
+        portConfig.flags.value().getTag() == AudioIoFlags::Tag::output &&
+        isBitPositionFlagSet(portConfig.flags.value().get<AudioIoFlags::Tag::output>(),
+                             AudioOutputFlags::COMPRESS_OFFLOAD)) {
+        AudioOffloadInfo offloadInfo;
+        offloadInfo.base.sampleRate = portConfig.sampleRate.value().value;
+        offloadInfo.base.channelMask = portConfig.channelMask.value();
+        offloadInfo.base.format = portConfig.format.value();
+        offloadInfo.bitRatePerSecond = 256000;                             // Arbitrary value.
+        offloadInfo.durationUs = std::chrono::microseconds(1min).count();  // Arbitrary value.
+        offloadInfo.usage = AudioUsage::MEDIA;
+        offloadInfo.encapsulationMode = AudioEncapsulationMode::NONE;
+        return offloadInfo;
+    }
+    return {};
+}
+
+// static
+std::vector<aidl::android::media::audio::common::AudioPort> ModuleConfig::getBuiltInMicPorts(
+        const std::vector<aidl::android::media::audio::common::AudioPort>& ports) {
+    std::vector<AudioPort> result;
+    std::copy_if(ports.begin(), ports.end(), std::back_inserter(result), [](const auto& port) {
+        const auto type = port.ext.template get<AudioPortExt::Tag::device>().device.type;
+        return type.connection.empty() && (type.type == AudioDeviceType::IN_MICROPHONE ||
+                                           type.type == AudioDeviceType::IN_MICROPHONE_BACK);
+    });
+    return result;
+}
+
+template <typename T>
+auto findById(const std::vector<T>& v, int32_t id) {
+    return std::find_if(v.begin(), v.end(), [&](const auto& p) { return p.id == id; });
+}
+
+ModuleConfig::ModuleConfig(IModule* module) {
+    mStatus = module->getAudioPorts(&mPorts);
+    if (!mStatus.isOk()) return;
+    for (const auto& port : mPorts) {
+        if (port.ext.getTag() != AudioPortExt::Tag::device) continue;
+        const auto& devicePort = port.ext.get<AudioPortExt::Tag::device>();
+        if (devicePort.device.type.connection.empty()) {
+            const bool isInput = port.flags.getTag() == AudioIoFlags::Tag::input;
+            // Permanently attached device.
+            if (isInput) {
+                mAttachedSourceDevicePorts.insert(port.id);
+            } else {
+                mAttachedSinkDevicePorts.insert(port.id);
+            }
+        } else if (port.profiles.empty()) {
+            mExternalDevicePorts.insert(port.id);
+        }
+    }
+    if (!mStatus.isOk()) return;
+    mStatus = module->getAudioRoutes(&mRoutes);
+    if (!mStatus.isOk()) return;
+    mStatus = module->getAudioPortConfigs(&mInitialConfigs);
+}
+
+std::vector<AudioPort> ModuleConfig::getAttachedDevicePorts() const {
+    std::vector<AudioPort> result;
+    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
+        return mAttachedSinkDevicePorts.count(port.id) != 0 ||
+               mAttachedSourceDevicePorts.count(port.id) != 0;
+    });
+    return result;
+}
+
+std::vector<AudioPort> ModuleConfig::getExternalDevicePorts() const {
+    std::vector<AudioPort> result;
+    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result),
+                 [&](const auto& port) { return mExternalDevicePorts.count(port.id) != 0; });
+    return result;
+}
+
+std::vector<AudioPort> ModuleConfig::getInputMixPorts(bool attachedOnly) const {
+    std::vector<AudioPort> result;
+    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
+        return port.ext.getTag() == AudioPortExt::Tag::mix &&
+               port.flags.getTag() == AudioIoFlags::Tag::input &&
+               (!attachedOnly || !getAttachedSourceDevicesPortsForMixPort(port).empty());
+    });
+    return result;
+}
+
+std::vector<AudioPort> ModuleConfig::getOutputMixPorts(bool attachedOnly) const {
+    std::vector<AudioPort> result;
+    std::copy_if(mPorts.begin(), mPorts.end(), std::back_inserter(result), [&](const auto& port) {
+        return port.ext.getTag() == AudioPortExt::Tag::mix &&
+               port.flags.getTag() == AudioIoFlags::Tag::output &&
+               (!attachedOnly || !getAttachedSinkDevicesPortsForMixPort(port).empty());
+    });
+    return result;
+}
+
+std::vector<AudioPort> ModuleConfig::getNonBlockingMixPorts(bool attachedOnly,
+                                                            bool singlePort) const {
+    return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
+        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
+                                    AudioOutputFlags::NON_BLOCKING);
+    });
+}
+
+std::vector<AudioPort> ModuleConfig::getOffloadMixPorts(bool attachedOnly, bool singlePort) const {
+    return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
+        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
+                                    AudioOutputFlags::COMPRESS_OFFLOAD);
+    });
+}
+
+std::vector<AudioPort> ModuleConfig::getPrimaryMixPorts(bool attachedOnly, bool singlePort) const {
+    return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
+        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
+                                    AudioOutputFlags::PRIMARY);
+    });
+}
+
+std::vector<AudioPort> ModuleConfig::getMmapOutMixPorts(bool attachedOnly, bool singlePort) const {
+    return findMixPorts(false /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
+        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
+                                    AudioOutputFlags::MMAP_NOIRQ);
+    });
+}
+
+std::vector<AudioPort> ModuleConfig::getMmapInMixPorts(bool attachedOnly, bool singlePort) const {
+    return findMixPorts(true /*isInput*/, attachedOnly, singlePort, [&](const AudioPort& port) {
+        return isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::input>(),
+                                    AudioInputFlags::MMAP_NOIRQ);
+    });
+}
+
+std::vector<AudioPort> ModuleConfig::getAttachedDevicesPortsForMixPort(
+        bool isInput, const AudioPortConfig& mixPortConfig) const {
+    const auto mixPortIt = findById<AudioPort>(mPorts, mixPortConfig.portId);
+    if (mixPortIt != mPorts.end()) {
+        return getAttachedDevicesPortsForMixPort(isInput, *mixPortIt);
+    }
+    return {};
+}
+
+std::vector<AudioPort> ModuleConfig::getAttachedSinkDevicesPortsForMixPort(
+        const AudioPort& mixPort) const {
+    std::vector<AudioPort> result;
+    for (const auto& route : mRoutes) {
+        if (mAttachedSinkDevicePorts.count(route.sinkPortId) != 0 &&
+            std::find(route.sourcePortIds.begin(), route.sourcePortIds.end(), mixPort.id) !=
+                    route.sourcePortIds.end()) {
+            const auto devicePortIt = findById<AudioPort>(mPorts, route.sinkPortId);
+            if (devicePortIt != mPorts.end()) result.push_back(*devicePortIt);
+        }
+    }
+    return result;
+}
+
+std::vector<AudioPort> ModuleConfig::getAttachedSourceDevicesPortsForMixPort(
+        const AudioPort& mixPort) const {
+    std::vector<AudioPort> result;
+    for (const auto& route : mRoutes) {
+        if (route.sinkPortId == mixPort.id) {
+            for (const auto srcId : route.sourcePortIds) {
+                if (mAttachedSourceDevicePorts.count(srcId) != 0) {
+                    const auto devicePortIt = findById<AudioPort>(mPorts, srcId);
+                    if (devicePortIt != mPorts.end()) result.push_back(*devicePortIt);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+std::optional<AudioPort> ModuleConfig::getSourceMixPortForAttachedDevice() const {
+    for (const auto& route : mRoutes) {
+        if (mAttachedSinkDevicePorts.count(route.sinkPortId) != 0) {
+            const auto mixPortIt = findById<AudioPort>(mPorts, route.sourcePortIds[0]);
+            if (mixPortIt != mPorts.end()) return *mixPortIt;
+        }
+    }
+    return {};
+}
+
+std::optional<ModuleConfig::SrcSinkPair> ModuleConfig::getNonRoutableSrcSinkPair(
+        bool isInput) const {
+    const auto mixPorts = getMixPorts(isInput, false /*attachedOnly*/);
+    std::set<std::pair<int32_t, int32_t>> allowedRoutes;
+    for (const auto& route : mRoutes) {
+        for (const auto srcPortId : route.sourcePortIds) {
+            allowedRoutes.emplace(std::make_pair(srcPortId, route.sinkPortId));
+        }
+    }
+    auto make_pair = [isInput](auto& device, auto& mix) {
+        return isInput ? std::make_pair(device, mix) : std::make_pair(mix, device);
+    };
+    for (const auto portId : isInput ? mAttachedSourceDevicePorts : mAttachedSinkDevicePorts) {
+        const auto devicePortIt = findById<AudioPort>(mPorts, portId);
+        if (devicePortIt == mPorts.end()) continue;
+        auto devicePortConfig = getSingleConfigForDevicePort(*devicePortIt);
+        for (const auto& mixPort : mixPorts) {
+            if (std::find(allowedRoutes.begin(), allowedRoutes.end(),
+                          make_pair(portId, mixPort.id)) == allowedRoutes.end()) {
+                auto mixPortConfig = getSingleConfigForMixPort(isInput, mixPort);
+                if (mixPortConfig.has_value()) {
+                    return make_pair(devicePortConfig, mixPortConfig.value());
+                }
+            }
+        }
+    }
+    return {};
+}
+
+std::optional<ModuleConfig::SrcSinkPair> ModuleConfig::getRoutableSrcSinkPair(bool isInput) const {
+    if (isInput) {
+        for (const auto& route : mRoutes) {
+            auto srcPortIdIt = std::find_if(
+                    route.sourcePortIds.begin(), route.sourcePortIds.end(),
+                    [&](const auto& portId) { return mAttachedSourceDevicePorts.count(portId); });
+            if (srcPortIdIt == route.sourcePortIds.end()) continue;
+            const auto devicePortIt = findById<AudioPort>(mPorts, *srcPortIdIt);
+            const auto mixPortIt = findById<AudioPort>(mPorts, route.sinkPortId);
+            if (devicePortIt == mPorts.end() || mixPortIt == mPorts.end()) continue;
+            auto devicePortConfig = getSingleConfigForDevicePort(*devicePortIt);
+            auto mixPortConfig = getSingleConfigForMixPort(isInput, *mixPortIt);
+            if (!mixPortConfig.has_value()) continue;
+            return std::make_pair(devicePortConfig, mixPortConfig.value());
+        }
+    } else {
+        for (const auto& route : mRoutes) {
+            if (mAttachedSinkDevicePorts.count(route.sinkPortId) == 0) continue;
+            const auto mixPortIt = findById<AudioPort>(mPorts, route.sourcePortIds[0]);
+            const auto devicePortIt = findById<AudioPort>(mPorts, route.sinkPortId);
+            if (devicePortIt == mPorts.end() || mixPortIt == mPorts.end()) continue;
+            auto mixPortConfig = getSingleConfigForMixPort(isInput, *mixPortIt);
+            auto devicePortConfig = getSingleConfigForDevicePort(*devicePortIt);
+            if (!mixPortConfig.has_value()) continue;
+            return std::make_pair(mixPortConfig.value(), devicePortConfig);
+        }
+    }
+    return {};
+}
+
+std::vector<ModuleConfig::SrcSinkGroup> ModuleConfig::getRoutableSrcSinkGroups(bool isInput) const {
+    std::vector<SrcSinkGroup> result;
+    if (isInput) {
+        for (const auto& route : mRoutes) {
+            std::vector<int32_t> srcPortIds;
+            std::copy_if(route.sourcePortIds.begin(), route.sourcePortIds.end(),
+                         std::back_inserter(srcPortIds), [&](const auto& portId) {
+                             return mAttachedSourceDevicePorts.count(portId);
+                         });
+            if (srcPortIds.empty()) continue;
+            const auto mixPortIt = findById<AudioPort>(mPorts, route.sinkPortId);
+            if (mixPortIt == mPorts.end()) continue;
+            auto mixPortConfig = getSingleConfigForMixPort(isInput, *mixPortIt);
+            if (!mixPortConfig.has_value()) continue;
+            std::vector<SrcSinkPair> pairs;
+            for (const auto srcPortId : srcPortIds) {
+                const auto devicePortIt = findById<AudioPort>(mPorts, srcPortId);
+                if (devicePortIt == mPorts.end()) continue;
+                // Using all configs for every source would be too much.
+                auto devicePortConfig = getSingleConfigForDevicePort(*devicePortIt);
+                pairs.emplace_back(devicePortConfig, mixPortConfig.value());
+            }
+            if (!pairs.empty()) {
+                result.emplace_back(route, std::move(pairs));
+            }
+        }
+    } else {
+        for (const auto& route : mRoutes) {
+            if (mAttachedSinkDevicePorts.count(route.sinkPortId) == 0) continue;
+            const auto devicePortIt = findById<AudioPort>(mPorts, route.sinkPortId);
+            if (devicePortIt == mPorts.end()) continue;
+            auto devicePortConfig = getSingleConfigForDevicePort(*devicePortIt);
+            std::vector<SrcSinkPair> pairs;
+            for (const auto srcPortId : route.sourcePortIds) {
+                const auto mixPortIt = findById<AudioPort>(mPorts, srcPortId);
+                if (mixPortIt == mPorts.end()) continue;
+                // Using all configs for every source would be too much.
+                auto mixPortConfig = getSingleConfigForMixPort(isInput, *mixPortIt);
+                if (mixPortConfig.has_value()) {
+                    pairs.emplace_back(mixPortConfig.value(), devicePortConfig);
+                }
+            }
+            if (!pairs.empty()) {
+                result.emplace_back(route, std::move(pairs));
+            }
+        }
+    }
+    return result;
+}
+
+std::string ModuleConfig::toString() const {
+    std::string result;
+    result.append("Ports: ");
+    result.append(android::internal::ToString(mPorts));
+    result.append("\nInitial configs: ");
+    result.append(android::internal::ToString(mInitialConfigs));
+    result.append("\nAttached sink device ports: ");
+    result.append(android::internal::ToString(mAttachedSinkDevicePorts));
+    result.append("\nAttached source device ports: ");
+    result.append(android::internal::ToString(mAttachedSourceDevicePorts));
+    result.append("\nExternal device ports: ");
+    result.append(android::internal::ToString(mExternalDevicePorts));
+    result.append("\nRoutes: ");
+    result.append(android::internal::ToString(mRoutes));
+    return result;
+}
+
+static size_t combineAudioConfigs(const AudioPort& port, const AudioProfile& profile,
+                                  std::vector<AudioPortConfig>* result) {
+    const size_t newConfigCount = profile.channelMasks.size() * profile.sampleRates.size();
+    result->reserve(result->capacity() + newConfigCount);
+    for (auto channelMask : profile.channelMasks) {
+        for (auto sampleRate : profile.sampleRates) {
+            AudioPortConfig config{};
+            config.portId = port.id;
+            Int sr;
+            sr.value = sampleRate;
+            config.sampleRate = sr;
+            config.channelMask = channelMask;
+            config.format = profile.format;
+            config.flags = port.flags;
+            config.ext = port.ext;
+            result->push_back(std::move(config));
+        }
+    }
+    return newConfigCount;
+}
+
+static bool isDynamicProfile(const AudioProfile& profile) {
+    return (profile.format.type == AudioFormatType::DEFAULT && profile.format.encoding.empty()) ||
+           profile.sampleRates.empty() || profile.channelMasks.empty();
+}
+
+std::vector<AudioPort> ModuleConfig::findMixPorts(
+        bool isInput, bool attachedOnly, bool singlePort,
+        const std::function<bool(const AudioPort&)>& pred) const {
+    std::vector<AudioPort> result;
+    const auto mixPorts = getMixPorts(isInput, attachedOnly);
+    for (auto mixPortIt = mixPorts.begin(); mixPortIt != mixPorts.end();) {
+        mixPortIt = std::find_if(mixPortIt, mixPorts.end(), pred);
+        if (mixPortIt == mixPorts.end()) break;
+        result.push_back(*mixPortIt++);
+        if (singlePort) break;
+    }
+    return result;
+}
+
+std::vector<AudioPortConfig> ModuleConfig::generateAudioMixPortConfigs(
+        const std::vector<AudioPort>& ports, bool isInput, bool singleProfile) const {
+    std::vector<AudioPortConfig> result;
+    for (const auto& mixPort : ports) {
+        if (getAttachedDevicesPortsForMixPort(isInput, mixPort).empty()) {
+            continue;
+        }
+        for (const auto& profile : mixPort.profiles) {
+            if (isDynamicProfile(profile)) continue;
+            combineAudioConfigs(mixPort, profile, &result);
+            if (singleProfile && !result.empty()) {
+                result.resize(1);
+                return result;
+            }
+        }
+    }
+    return result;
+}
+
+std::vector<AudioPortConfig> ModuleConfig::generateAudioDevicePortConfigs(
+        const std::vector<AudioPort>& ports, bool singleProfile) const {
+    std::vector<AudioPortConfig> result;
+    for (const auto& devicePort : ports) {
+        const size_t resultSizeBefore = result.size();
+        for (const auto& profile : devicePort.profiles) {
+            combineAudioConfigs(devicePort, profile, &result);
+            if (singleProfile && !result.empty()) {
+                result.resize(1);
+                return result;
+            }
+        }
+        if (resultSizeBefore == result.size()) {
+            std::copy_if(mInitialConfigs.begin(), mInitialConfigs.end(), std::back_inserter(result),
+                         [&](const auto& config) { return config.portId == devicePort.id; });
+            if (resultSizeBefore == result.size()) {
+                AudioPortConfig empty;
+                empty.portId = devicePort.id;
+                empty.ext = devicePort.ext;
+                result.push_back(empty);
+            }
+        }
+        if (singleProfile) return result;
+    }
+    return result;
+}
+
+bool ModuleConfig::isMmapSupported() const {
+    const std::vector<AudioPort> mmapOutMixPorts =
+            getMmapOutMixPorts(false /*attachedOnly*/, false /*singlePort*/);
+    const std::vector<AudioPort> mmapInMixPorts =
+            getMmapInMixPorts(false /*attachedOnly*/, false /*singlePort*/);
+    return !mmapOutMixPorts.empty() || !mmapInMixPorts.empty();
+}
diff --git a/audio/aidl/vts/ModuleConfig.h b/audio/aidl/vts/ModuleConfig.h
new file mode 100644
index 0000000..6a22075
--- /dev/null
+++ b/audio/aidl/vts/ModuleConfig.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <functional>
+#include <optional>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include <aidl/android/hardware/audio/core/AudioRoute.h>
+#include <aidl/android/hardware/audio/core/IModule.h>
+#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
+#include <aidl/android/media/audio/common/AudioPort.h>
+
+class ModuleConfig {
+  public:
+    using SrcSinkPair = std::pair<aidl::android::media::audio::common::AudioPortConfig,
+                                  aidl::android::media::audio::common::AudioPortConfig>;
+    using SrcSinkGroup =
+            std::pair<aidl::android::hardware::audio::core::AudioRoute, std::vector<SrcSinkPair>>;
+
+    static std::optional<aidl::android::media::audio::common::AudioOffloadInfo>
+    generateOffloadInfoIfNeeded(
+            const aidl::android::media::audio::common::AudioPortConfig& portConfig);
+    static std::vector<aidl::android::media::audio::common::AudioPort> getBuiltInMicPorts(
+            const std::vector<aidl::android::media::audio::common::AudioPort>& ports);
+
+    explicit ModuleConfig(aidl::android::hardware::audio::core::IModule* module);
+    const ndk::ScopedAStatus& getStatus() const { return mStatus; }
+    std::string getError() const { return mStatus.getMessage(); }
+
+    std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicePorts() const;
+    std::vector<aidl::android::media::audio::common::AudioPort> getAttachedMicrophonePorts() const {
+        return getBuiltInMicPorts(getAttachedDevicePorts());
+    }
+    std::vector<aidl::android::media::audio::common::AudioPort> getExternalDevicePorts() const;
+    std::vector<aidl::android::media::audio::common::AudioPort> getInputMixPorts(
+            bool attachedOnly) const;
+    std::vector<aidl::android::media::audio::common::AudioPort> getOutputMixPorts(
+            bool attachedOnly) const;
+    std::vector<aidl::android::media::audio::common::AudioPort> getMixPorts(
+            bool isInput, bool attachedOnly) const {
+        return isInput ? getInputMixPorts(attachedOnly) : getOutputMixPorts(attachedOnly);
+    }
+    std::vector<aidl::android::media::audio::common::AudioPort> getNonBlockingMixPorts(
+            bool attachedOnly, bool singlePort) const;
+    std::vector<aidl::android::media::audio::common::AudioPort> getOffloadMixPorts(
+            bool attachedOnly, bool singlePort) const;
+    std::vector<aidl::android::media::audio::common::AudioPort> getPrimaryMixPorts(
+            bool attachedOnly, bool singlePort) const;
+    std::vector<aidl::android::media::audio::common::AudioPort> getMmapOutMixPorts(
+            bool attachedOnly, bool singlePort) const;
+    std::vector<aidl::android::media::audio::common::AudioPort> getMmapInMixPorts(
+            bool attachedOnly, bool singlePort) const;
+
+    std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicesPortsForMixPort(
+            bool isInput, const aidl::android::media::audio::common::AudioPort& mixPort) const {
+        return isInput ? getAttachedSourceDevicesPortsForMixPort(mixPort)
+                       : getAttachedSinkDevicesPortsForMixPort(mixPort);
+    }
+    std::vector<aidl::android::media::audio::common::AudioPort> getAttachedDevicesPortsForMixPort(
+            bool isInput,
+            const aidl::android::media::audio::common::AudioPortConfig& mixPortConfig) const;
+    std::vector<aidl::android::media::audio::common::AudioPort>
+    getAttachedSinkDevicesPortsForMixPort(
+            const aidl::android::media::audio::common::AudioPort& mixPort) const;
+    std::vector<aidl::android::media::audio::common::AudioPort>
+    getAttachedSourceDevicesPortsForMixPort(
+            const aidl::android::media::audio::common::AudioPort& mixPort) const;
+    std::optional<aidl::android::media::audio::common::AudioPort>
+    getSourceMixPortForAttachedDevice() const;
+
+    std::optional<SrcSinkPair> getNonRoutableSrcSinkPair(bool isInput) const;
+    std::optional<SrcSinkPair> getRoutableSrcSinkPair(bool isInput) const;
+    std::vector<SrcSinkGroup> getRoutableSrcSinkGroups(bool isInput) const;
+
+    std::vector<aidl::android::media::audio::common::AudioPortConfig>
+    getPortConfigsForAttachedDevicePorts() const {
+        return generateAudioDevicePortConfigs(getAttachedDevicePorts(), false);
+    }
+    std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts()
+            const {
+        auto inputs =
+                generateAudioMixPortConfigs(getInputMixPorts(false /*attachedOnly*/), true, false);
+        auto outputs = generateAudioMixPortConfigs(getOutputMixPorts(false /*attachedOnly*/), false,
+                                                   false);
+        inputs.insert(inputs.end(), outputs.begin(), outputs.end());
+        return inputs;
+    }
+    std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts(
+            bool isInput) const {
+        return generateAudioMixPortConfigs(getMixPorts(isInput, false /*attachedOnly*/), isInput,
+                                           false);
+    }
+    std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForMixPorts(
+            bool isInput, const aidl::android::media::audio::common::AudioPort& port) const {
+        return generateAudioMixPortConfigs({port}, isInput, false);
+    }
+    std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort(
+            bool isInput) const {
+        const auto config = generateAudioMixPortConfigs(
+                getMixPorts(isInput, false /*attachedOnly*/), isInput, true);
+        if (!config.empty()) {
+            return *config.begin();
+        }
+        return {};
+    }
+    std::optional<aidl::android::media::audio::common::AudioPortConfig> getSingleConfigForMixPort(
+            bool isInput, const aidl::android::media::audio::common::AudioPort& port) const {
+        const auto config = generateAudioMixPortConfigs({port}, isInput, true);
+        if (!config.empty()) {
+            return *config.begin();
+        }
+        return {};
+    }
+
+    std::vector<aidl::android::media::audio::common::AudioPortConfig> getPortConfigsForDevicePort(
+            const aidl::android::media::audio::common::AudioPort& port) const {
+        return generateAudioDevicePortConfigs({port}, false);
+    }
+    aidl::android::media::audio::common::AudioPortConfig getSingleConfigForDevicePort(
+            const aidl::android::media::audio::common::AudioPort& port) const {
+        const auto config = generateAudioDevicePortConfigs({port}, true);
+        return *config.begin();
+    }
+
+    bool isMmapSupported() const;
+
+    std::string toString() const;
+
+  private:
+    std::vector<aidl::android::media::audio::common::AudioPort> findMixPorts(
+            bool isInput, bool attachedOnly, bool singlePort,
+            const std::function<bool(const aidl::android::media::audio::common::AudioPort&)>& pred)
+            const;
+    std::vector<aidl::android::media::audio::common::AudioPortConfig> generateAudioMixPortConfigs(
+            const std::vector<aidl::android::media::audio::common::AudioPort>& ports, bool isInput,
+            bool singleProfile) const;
+
+    // Unlike MixPorts, the generator for DevicePorts always returns a non-empty
+    // vector for a non-empty input port list. If there are no profiles in the
+    // port, its initial configs are looked up, if there are none,
+    // then an empty config is used, assuming further negotiation via setAudioPortConfig.
+    std::vector<aidl::android::media::audio::common::AudioPortConfig>
+    generateAudioDevicePortConfigs(
+            const std::vector<aidl::android::media::audio::common::AudioPort>& ports,
+            bool singleProfile) const;
+
+    ndk::ScopedAStatus mStatus = ndk::ScopedAStatus::ok();
+    std::vector<aidl::android::media::audio::common::AudioPort> mPorts;
+    std::vector<aidl::android::media::audio::common::AudioPortConfig> mInitialConfigs;
+    std::set<int32_t> mAttachedSinkDevicePorts;
+    std::set<int32_t> mAttachedSourceDevicePorts;
+    std::set<int32_t> mExternalDevicePorts;
+    std::vector<aidl::android::hardware::audio::core::AudioRoute> mRoutes;
+};
diff --git a/audio/aidl/vts/TestUtils.h b/audio/aidl/vts/TestUtils.h
new file mode 100644
index 0000000..72ca56f
--- /dev/null
+++ b/audio/aidl/vts/TestUtils.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <initializer_list>
+#include <iostream>
+
+#include <android/binder_auto_utils.h>
+#include <gtest/gtest.h>
+
+namespace android::hardware::audio::common::testing {
+
+namespace detail {
+
+inline ::testing::AssertionResult assertIsOk(const char* expr, const ::ndk::ScopedAStatus& status) {
+    if (status.isOk()) {
+        return ::testing::AssertionSuccess();
+    }
+    return ::testing::AssertionFailure()
+           << "Expected the transaction \'" << expr << "\' to succeed\n"
+           << "  but it has failed with: " << status;
+}
+
+inline ::testing::AssertionResult assertResult(const char* exp_expr, const char* act_expr,
+                                               int32_t expected,
+                                               const ::ndk::ScopedAStatus& status) {
+    if (status.getExceptionCode() == expected) {
+        return ::testing::AssertionSuccess();
+    }
+    return ::testing::AssertionFailure()
+           << "Expected the transaction \'" << act_expr << "\' to fail with " << exp_expr
+           << "\n  but is has completed with: " << status;
+}
+
+template <typename T>
+inline ::testing::AssertionResult assertResult(const char* exp_expr, const char* act_expr,
+                                               const std::initializer_list<T>& expected,
+                                               const ::ndk::ScopedAStatus& status) {
+    if (std::find(expected.begin(), expected.end(), status.getExceptionCode()) != expected.end()) {
+        return ::testing::AssertionSuccess();
+    }
+    return ::testing::AssertionFailure() << "Expected the transaction \'" << act_expr
+                                         << "\' to complete with one of: " << exp_expr
+                                         << "\n  which is: " << ::testing::PrintToString(expected)
+                                         << "\n  but is has completed with: " << status;
+}
+
+}  // namespace detail
+
+}  // namespace android::hardware::audio::common::testing
+
+// Test that the transaction status 'isOk'
+#define ASSERT_IS_OK(ret) \
+    ASSERT_PRED_FORMAT1(::android::hardware::audio::common::testing::detail::assertIsOk, ret)
+#define EXPECT_IS_OK(ret) \
+    EXPECT_PRED_FORMAT1(::android::hardware::audio::common::testing::detail::assertIsOk, ret)
+
+// Test that the transaction status is as expected.
+#define ASSERT_STATUS(expected, ret)                                                       \
+    ASSERT_PRED_FORMAT2(::android::hardware::audio::common::testing::detail::assertResult, \
+                        expected, ret)
+#define EXPECT_STATUS(expected, ret)                                                       \
+    EXPECT_PRED_FORMAT2(::android::hardware::audio::common::testing::detail::assertResult, \
+                        expected, ret)
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
new file mode 100644
index 0000000..8828c41
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <string>
+#include <unordered_set>
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalAECParamTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+#include "effect-impl/EffectTypes.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::AcousticEchoCanceler;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAcousticEchoCanceler;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
+
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_ECHO_DELAY, PARAM_MOBILE_MODE };
+using AECParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
+                                     int /* echoDelayUs */, bool /* mobileMode */>;
+
+class AECParamTest : public ::testing::TestWithParam<AECParamTestParam>, public EffectHelper {
+  public:
+    AECParamTest()
+        : mEchoDelay(std::get<PARAM_ECHO_DELAY>(GetParam())),
+          mMobileMode(std::get<PARAM_MOBILE_MODE>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        AcousticEchoCanceler aec = AcousticEchoCanceler::make<AcousticEchoCanceler::echoDelayUs>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::acousticEchoCanceler>(aec);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+
+    int mEchoDelay;
+    bool mMobileMode;
+
+    void SetAndGetParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& aec = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid =
+                    isParameterValid<AcousticEchoCanceler, Range::acousticEchoCanceler>(aec, desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::acousticEchoCanceler>(aec);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                AcousticEchoCanceler::Id specificId;
+                specificId.set<AcousticEchoCanceler::Id::commonTag>(tag);
+                id.set<Parameter::Id::acousticEchoCancelerTag>(specificId);
+                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+                EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                                 << "\ngetParam:" << getParam.toString();
+            }
+        }
+    }
+
+    void addEchoDelayParam(int delay) {
+        AcousticEchoCanceler aec;
+        aec.set<AcousticEchoCanceler::echoDelayUs>(delay);
+        mTags.push_back({AcousticEchoCanceler::echoDelayUs, aec});
+    }
+
+    void addMobileModeParam(bool mode) {
+        AcousticEchoCanceler aec;
+        aec.set<AcousticEchoCanceler::mobileMode>(mode);
+        mTags.push_back({AcousticEchoCanceler::mobileMode, aec});
+    }
+
+    static std::unordered_set<bool> getMobileModeValues() { return {true, false}; }
+
+  private:
+    std::vector<std::pair<AcousticEchoCanceler::Tag, AcousticEchoCanceler>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(AECParamTest, SetAndGetEchoDelay) {
+    EXPECT_NO_FATAL_FAILURE(addEchoDelayParam(mEchoDelay));
+    SetAndGetParameters();
+}
+
+TEST_P(AECParamTest, SetAndGetMobileMode) {
+    EXPECT_NO_FATAL_FAILURE(addMobileModeParam(mMobileMode));
+    SetAndGetParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        AECParamTest, AECParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor,
+                                          getEffectTypeUuidAcousticEchoCanceler())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<AcousticEchoCanceler, int,
+                                                                Range::acousticEchoCanceler,
+                                                                AcousticEchoCanceler::echoDelayUs>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(EffectHelper::getTestValueSet<AcousticEchoCanceler, bool,
+                                                                Range::acousticEchoCanceler,
+                                                                AcousticEchoCanceler::mobileMode>(
+                        kDescPair, EffectHelper::expandTestValueBasic<bool>))),
+        [](const testing::TestParamInfo<AECParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string echoDelay = std::to_string(std::get<PARAM_ECHO_DELAY>(info.param));
+            std::string mobileMode = std::get<PARAM_MOBILE_MODE>(info.param) ? "true" : "false";
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_EchoDelay_" + echoDelay +
+                               "_MobileMode_" + mobileMode;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AECParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
new file mode 100644
index 0000000..edfcdf6
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalAGC1ParamTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV1;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV1;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+
+enum ParamName {
+    PARAM_INSTANCE_NAME,
+    PARAM_TARGET_PEAK_LEVEL,
+    PARAM_MAX_COMPRESSION_GAIN,
+    PARAM_ENABLE_LIMITER
+};
+using AGC1ParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int /* targetPeakLevel */,
+                   int /* maxCompressionGain */, bool /* enableLimiter */>;
+
+class AGC1ParamTest : public ::testing::TestWithParam<AGC1ParamTestParam>, public EffectHelper {
+  public:
+    AGC1ParamTest()
+        : mTargetPeakLevel(std::get<PARAM_TARGET_PEAK_LEVEL>(GetParam())),
+          mMaxCompressionGain(std::get<PARAM_MAX_COMPRESSION_GAIN>(GetParam())),
+          mEnableLimiter(std::get<PARAM_ENABLE_LIMITER>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        AutomaticGainControlV1 AGC1 =
+                AutomaticGainControlV1::make<AutomaticGainControlV1::targetPeakLevelDbFs>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::automaticGainControlV1>(AGC1);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mTargetPeakLevel;
+    int mMaxCompressionGain;
+    bool mEnableLimiter;
+
+    void SetAndGetParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& AGC1 = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid =
+                    isParameterValid<AutomaticGainControlV1, Range::automaticGainControlV1>(AGC1,
+                                                                                            desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::automaticGainControlV1>(AGC1);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                AutomaticGainControlV1::Id specificId;
+                specificId.set<AutomaticGainControlV1::Id::commonTag>(tag);
+                id.set<Parameter::Id::automaticGainControlV1Tag>(specificId);
+                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+                EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                                 << "\ngetParam:" << getParam.toString();
+            }
+        }
+    }
+
+    void addTargetPeakLevelParam(int targetPeakLevel) {
+        AutomaticGainControlV1 AGC1;
+        AGC1.set<AutomaticGainControlV1::targetPeakLevelDbFs>(targetPeakLevel);
+        mTags.push_back({AutomaticGainControlV1::targetPeakLevelDbFs, AGC1});
+    }
+    void addMaxCompressionGainParam(int maxCompressionGainDb) {
+        AutomaticGainControlV1 AGC1;
+        AGC1.set<AutomaticGainControlV1::maxCompressionGainDb>(maxCompressionGainDb);
+        mTags.push_back({AutomaticGainControlV1::maxCompressionGainDb, AGC1});
+    }
+    void addEnableLimiterParam(bool enableLimiter) {
+        AutomaticGainControlV1 AGC1;
+        AGC1.set<AutomaticGainControlV1::enableLimiter>(enableLimiter);
+        mTags.push_back({AutomaticGainControlV1::enableLimiter, AGC1});
+    }
+
+  private:
+    std::vector<std::pair<AutomaticGainControlV1::Tag, AutomaticGainControlV1>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(AGC1ParamTest, SetAndGetTargetPeakLevelParam) {
+    EXPECT_NO_FATAL_FAILURE(addTargetPeakLevelParam(mTargetPeakLevel));
+    SetAndGetParameters();
+}
+
+TEST_P(AGC1ParamTest, SetAndGetMaxCompressionGain) {
+    EXPECT_NO_FATAL_FAILURE(addMaxCompressionGainParam(mMaxCompressionGain));
+    SetAndGetParameters();
+}
+
+TEST_P(AGC1ParamTest, SetAndGetEnableLimiter) {
+    EXPECT_NO_FATAL_FAILURE(addEnableLimiterParam(mEnableLimiter));
+    SetAndGetParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        AGC1ParamTest, AGC1ParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor,
+                                          getEffectTypeUuidAutomaticGainControlV1())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  AutomaticGainControlV1, int, Range::automaticGainControlV1,
+                                  AutomaticGainControlV1::targetPeakLevelDbFs>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  AutomaticGainControlV1, int, Range::automaticGainControlV1,
+                                  AutomaticGainControlV1::maxCompressionGainDb>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::Bool()),
+        [](const testing::TestParamInfo<AGC1ParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string targetPeakLevel =
+                    std::to_string(std::get<PARAM_TARGET_PEAK_LEVEL>(info.param));
+            std::string maxCompressionGain =
+                    std::to_string(std::get<PARAM_MAX_COMPRESSION_GAIN>(info.param));
+            std::string enableLimiter = std::to_string(std::get<PARAM_ENABLE_LIMITER>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_target_peak_level_" +
+                               targetPeakLevel + "_max_compression_gain_" + maxCompressionGain +
+                               "_enable_limiter_" + enableLimiter;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AGC1ParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
new file mode 100644
index 0000000..8ba8e45
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalAGC2ParamTest"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV2;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidAutomaticGainControlV2;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+
+enum ParamName {
+    PARAM_INSTANCE_NAME,
+    PARAM_DIGITAL_GAIN,
+    PARAM_SATURATION_MARGIN,
+    PARAM_LEVEL_ESTIMATOR
+};
+using AGC2ParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int /* gain */,
+                   int /* margin */, AutomaticGainControlV2::LevelEstimator>;
+
+class AGC2ParamTest : public ::testing::TestWithParam<AGC2ParamTestParam>, public EffectHelper {
+  public:
+    AGC2ParamTest()
+        : mGain(std::get<PARAM_DIGITAL_GAIN>(GetParam())),
+          mMargin(std::get<PARAM_SATURATION_MARGIN>(GetParam())),
+          mLevelEstimator(std::get<PARAM_LEVEL_ESTIMATOR>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        AutomaticGainControlV2 AGC2 =
+                AutomaticGainControlV2::make<AutomaticGainControlV2::fixedDigitalGainMb>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::automaticGainControlV2>(AGC2);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mGain;
+    int mMargin;
+    AutomaticGainControlV2::LevelEstimator mLevelEstimator;
+
+    void SetAndGetParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& AGC2 = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid =
+                    isParameterValid<AutomaticGainControlV2, Range::automaticGainControlV2>(AGC2,
+                                                                                            desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::automaticGainControlV2>(AGC2);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                AutomaticGainControlV2::Id specificId;
+                specificId.set<AutomaticGainControlV2::Id::commonTag>(tag);
+                id.set<Parameter::Id::automaticGainControlV2Tag>(specificId);
+                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+                EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                                 << "\ngetParam:" << getParam.toString();
+            }
+        }
+    }
+
+    void addDigitalGainParam(int gain) {
+        AutomaticGainControlV2 AGC2;
+        AGC2.set<AutomaticGainControlV2::fixedDigitalGainMb>(gain);
+        mTags.push_back({AutomaticGainControlV2::fixedDigitalGainMb, AGC2});
+    }
+    void addSaturationMarginParam(int margin) {
+        AutomaticGainControlV2 AGC2;
+        AGC2.set<AutomaticGainControlV2::saturationMarginMb>(margin);
+        mTags.push_back({AutomaticGainControlV2::saturationMarginMb, AGC2});
+    }
+    void addLevelEstimatorParam(AutomaticGainControlV2::LevelEstimator levelEstimator) {
+        AutomaticGainControlV2 AGC2;
+        AGC2.set<AutomaticGainControlV2::levelEstimator>(levelEstimator);
+        mTags.push_back({AutomaticGainControlV2::levelEstimator, AGC2});
+    }
+
+    static std::set<AutomaticGainControlV2::LevelEstimator> getLevelEstimatorValues() {
+        return {ndk::enum_range<AutomaticGainControlV2::LevelEstimator>().begin(),
+                ndk::enum_range<AutomaticGainControlV2::LevelEstimator>().end()};
+    }
+
+  private:
+    std::vector<std::pair<AutomaticGainControlV2::Tag, AutomaticGainControlV2>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(AGC2ParamTest, SetAndGetDigitalGainParam) {
+    EXPECT_NO_FATAL_FAILURE(addDigitalGainParam(mGain));
+    SetAndGetParameters();
+}
+
+TEST_P(AGC2ParamTest, SetAndGetSaturationMargin) {
+    EXPECT_NO_FATAL_FAILURE(addSaturationMarginParam(mMargin));
+    SetAndGetParameters();
+}
+
+TEST_P(AGC2ParamTest, SetAndGetLevelEstimator) {
+    EXPECT_NO_FATAL_FAILURE(addLevelEstimatorParam(mLevelEstimator));
+    SetAndGetParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        AGC2ParamTest, AGC2ParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor,
+                                          getEffectTypeUuidAutomaticGainControlV2())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  AutomaticGainControlV2, int, Range::automaticGainControlV2,
+                                  AutomaticGainControlV2::fixedDigitalGainMb>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  AutomaticGainControlV2, int, Range::automaticGainControlV2,
+                                  AutomaticGainControlV2::saturationMarginMb>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(AGC2ParamTest::getLevelEstimatorValues())),
+        [](const testing::TestParamInfo<AGC2ParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string gain = std::to_string(std::get<PARAM_DIGITAL_GAIN>(info.param));
+            std::string estimator = aidl::android::hardware::audio::effect::toString(
+                    std::get<PARAM_LEVEL_ESTIMATOR>(info.param));
+            std::string margin =
+                    std::to_string(static_cast<int>(std::get<PARAM_SATURATION_MARGIN>(info.param)));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_digital_gain_" + gain +
+                               "_level_estimator_" + estimator + "_margin_" + margin;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AGC2ParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
new file mode 100644
index 0000000..e5e06eb
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/core/IConfig.h>
+#include <aidl/android/media/audio/common/AudioFlag.h>
+#include <aidl/android/media/audio/common/AudioProductStrategyType.h>
+#define LOG_TAG "VtsHalAudioCore.Config"
+#include <android-base/logging.h>
+
+#include "AudioHalBinderServiceUtil.h"
+#include "TestUtils.h"
+
+using namespace android;
+using aidl::android::hardware::audio::core::IConfig;
+using aidl::android::media::audio::common::AudioAttributes;
+using aidl::android::media::audio::common::AudioFlag;
+using aidl::android::media::audio::common::AudioHalAttributesGroup;
+using aidl::android::media::audio::common::AudioHalCapCriterion;
+using aidl::android::media::audio::common::AudioHalCapCriterionType;
+using aidl::android::media::audio::common::AudioHalEngineConfig;
+using aidl::android::media::audio::common::AudioHalProductStrategy;
+using aidl::android::media::audio::common::AudioHalVolumeCurve;
+using aidl::android::media::audio::common::AudioHalVolumeGroup;
+using aidl::android::media::audio::common::AudioProductStrategyType;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
+using aidl::android::media::audio::common::AudioUsage;
+
+class AudioCoreConfig : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(ConnectToService()); }
+    void ConnectToService() {
+        mConfig = IConfig::fromBinder(mBinderUtil.connectToService(GetParam()));
+        ASSERT_NE(mConfig, nullptr);
+    }
+
+    void RestartService() {
+        ASSERT_NE(mConfig, nullptr);
+        mEngineConfig.reset();
+        mConfig = IConfig::fromBinder(mBinderUtil.restartService());
+        ASSERT_NE(mConfig, nullptr);
+    }
+
+    void SetUpEngineConfig() {
+        if (mEngineConfig == nullptr) {
+            auto tempConfig = std::make_unique<AudioHalEngineConfig>();
+            ASSERT_IS_OK(mConfig->getEngineConfig(tempConfig.get()));
+            mEngineConfig = std::move(tempConfig);
+        }
+    }
+
+    static bool IsProductStrategyTypeReservedForSystemUse(const AudioProductStrategyType& pst) {
+        switch (pst) {
+            case AudioProductStrategyType::SYS_RESERVED_NONE:
+            case AudioProductStrategyType::SYS_RESERVED_REROUTING:
+            case AudioProductStrategyType::SYS_RESERVED_CALL_ASSISTANT:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    static bool IsStreamTypeReservedForSystemUse(const AudioStreamType& streamType) {
+        switch (streamType) {
+            case AudioStreamType::SYS_RESERVED_DEFAULT:
+            case AudioStreamType::SYS_RESERVED_REROUTING:
+            case AudioStreamType::SYS_RESERVED_PATCH:
+            case AudioStreamType::CALL_ASSISTANT:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    static bool IsAudioUsageValid(const AudioUsage& usage) {
+        switch (usage) {
+            case AudioUsage::INVALID:
+            case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_REQUEST:
+            case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_INSTANT:
+            case AudioUsage::SYS_RESERVED_NOTIFICATION_COMMUNICATION_DELAYED:
+                return false;
+            default:
+                return true;
+        }
+    }
+
+    static bool IsAudioSourceValid(const AudioSource& source) {
+        return (source != AudioSource::SYS_RESERVED_INVALID);
+    }
+
+    static const std::unordered_set<int>& GetSupportedAudioProductStrategyTypes() {
+        static const std::unordered_set<int> supportedAudioProductStrategyTypes = []() {
+            std::unordered_set<int> supportedStrategyTypes;
+            for (const auto& audioProductStrategyType :
+                 ndk::enum_range<AudioProductStrategyType>()) {
+                if (!IsProductStrategyTypeReservedForSystemUse(audioProductStrategyType)) {
+                    supportedStrategyTypes.insert(static_cast<int>(audioProductStrategyType));
+                }
+            }
+            return supportedStrategyTypes;
+        }();
+        return supportedAudioProductStrategyTypes;
+    }
+
+    static int GetSupportedAudioFlagsMask() {
+        static const int supportedAudioFlagsMask = []() {
+            int mask = 0;
+            for (const auto& audioFlag : ndk::enum_range<AudioFlag>()) {
+                mask |= static_cast<int>(audioFlag);
+            }
+            return mask;
+        }();
+        return supportedAudioFlagsMask;
+    }
+
+    /**
+     * Verify streamType is not INVALID if using default engine.
+     * Verify that streamType is a valid AudioStreamType if the associated
+     * volumeGroup minIndex/maxIndex is INDEX_DEFERRED_TO_AUDIO_SERVICE.
+     */
+    void ValidateAudioStreamType(const AudioStreamType& streamType,
+                                 const AudioHalVolumeGroup& associatedVolumeGroup) {
+        EXPECT_FALSE(IsStreamTypeReservedForSystemUse(streamType));
+        if (!mEngineConfig->capSpecificConfig ||
+            associatedVolumeGroup.minIndex ==
+                    AudioHalVolumeGroup::INDEX_DEFERRED_TO_AUDIO_SERVICE) {
+            EXPECT_NE(streamType, AudioStreamType::INVALID);
+        }
+    }
+
+    /**
+     * Verify contained enum types are valid.
+     */
+    void ValidateAudioAttributes(const AudioAttributes& attributes) {
+        // No need to check contentType; there are no INVALID or SYS_RESERVED values
+        EXPECT_TRUE(IsAudioUsageValid(attributes.usage));
+        EXPECT_TRUE(IsAudioSourceValid(attributes.source));
+        EXPECT_EQ(attributes.flags & ~GetSupportedAudioFlagsMask(), 0);
+    }
+
+    /**
+     * Verify volumeGroupName corresponds to an AudioHalVolumeGroup.
+     * Validate contained types.
+     */
+    void ValidateAudioHalAttributesGroup(
+            const AudioHalAttributesGroup& attributesGroup,
+            std::unordered_map<std::string, const AudioHalVolumeGroup&>& volumeGroupMap,
+            std::unordered_set<std::string>& volumeGroupsUsedInStrategies) {
+        bool isVolumeGroupNameValid = volumeGroupMap.count(attributesGroup.volumeGroupName);
+        EXPECT_TRUE(isVolumeGroupNameValid);
+        EXPECT_NO_FATAL_FAILURE(ValidateAudioStreamType(
+                attributesGroup.streamType, volumeGroupMap.at(attributesGroup.volumeGroupName)));
+        if (isVolumeGroupNameValid) {
+            volumeGroupsUsedInStrategies.insert(attributesGroup.volumeGroupName);
+        }
+        for (const AudioAttributes& attr : attributesGroup.attributes) {
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioAttributes(attr));
+        }
+    }
+
+    /**
+     * Default engine: verify productStrategy.id is valid AudioProductStrategyType.
+     * CAP engine: verify productStrategy.id is either valid AudioProductStrategyType
+     * or is >= VENDOR_STRATEGY_ID_START.
+     * Validate contained types.
+     */
+    void ValidateAudioHalProductStrategy(
+            const AudioHalProductStrategy& strategy,
+            std::unordered_map<std::string, const AudioHalVolumeGroup&>& volumeGroupMap,
+            std::unordered_set<std::string>& volumeGroupsUsedInStrategies) {
+        if (!mEngineConfig->capSpecificConfig ||
+            (strategy.id < AudioHalProductStrategy::VENDOR_STRATEGY_ID_START)) {
+            EXPECT_NE(GetSupportedAudioProductStrategyTypes().find(strategy.id),
+                      GetSupportedAudioProductStrategyTypes().end());
+        }
+        for (const AudioHalAttributesGroup& attributesGroup : strategy.attributesGroups) {
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalAttributesGroup(attributesGroup, volumeGroupMap,
+                                                                    volumeGroupsUsedInStrategies));
+        }
+    }
+
+    /**
+     * Verify curve point index is in [CurvePoint::MIN_INDEX, CurvePoint::MAX_INDEX].
+     */
+    void ValidateAudioHalVolumeCurve(const AudioHalVolumeCurve& volumeCurve) {
+        for (const AudioHalVolumeCurve::CurvePoint& curvePoint : volumeCurve.curvePoints) {
+            EXPECT_TRUE(curvePoint.index >= AudioHalVolumeCurve::CurvePoint::MIN_INDEX);
+            EXPECT_TRUE(curvePoint.index <= AudioHalVolumeCurve::CurvePoint::MAX_INDEX);
+        }
+    }
+
+    /**
+     * Verify minIndex, maxIndex are non-negative.
+     * Verify minIndex <= maxIndex.
+     * Verify no two volume curves use the same device category.
+     * Validate contained types.
+     */
+    void ValidateAudioHalVolumeGroup(const AudioHalVolumeGroup& volumeGroup) {
+        /**
+         * Legacy volume curves in audio_policy_configuration.xsd don't use
+         * minIndex or maxIndex. Use of audio_policy_configuration.xml still
+         * allows, and in some cases, relies on, AudioService to provide the min
+         * and max indices for a volumeGroup. From the VTS perspective, there is
+         * no way to differentiate between use of audio_policy_configuration.xml
+         * or audio_policy_engine_configuration.xml, as either one can be used
+         * for the default audio policy engine.
+         */
+        if (volumeGroup.minIndex != AudioHalVolumeGroup::INDEX_DEFERRED_TO_AUDIO_SERVICE ||
+            volumeGroup.maxIndex != AudioHalVolumeGroup::INDEX_DEFERRED_TO_AUDIO_SERVICE) {
+            EXPECT_TRUE(volumeGroup.minIndex >= 0);
+            EXPECT_TRUE(volumeGroup.maxIndex >= 0);
+        }
+        EXPECT_TRUE(volumeGroup.minIndex <= volumeGroup.maxIndex);
+        std::unordered_set<AudioHalVolumeCurve::DeviceCategory> deviceCategorySet;
+        for (const AudioHalVolumeCurve& volumeCurve : volumeGroup.volumeCurves) {
+            EXPECT_TRUE(deviceCategorySet.insert(volumeCurve.deviceCategory).second);
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalVolumeCurve(volumeCurve));
+        }
+    }
+
+    /**
+     * Verify defaultLiteralValue is empty for inclusive criterion.
+     */
+    void ValidateAudioHalCapCriterion(const AudioHalCapCriterion& criterion,
+                                      const AudioHalCapCriterionType& criterionType) {
+        if (criterionType.isInclusive) {
+            EXPECT_TRUE(criterion.defaultLiteralValue.empty());
+        }
+    }
+
+    /**
+     * Verify values only contain alphanumeric characters.
+     */
+    void ValidateAudioHalCapCriterionType(const AudioHalCapCriterionType& criterionType) {
+        auto isNotAlnum = [](const char& c) { return !isalnum(c); };
+        for (const std::string& value : criterionType.values) {
+            EXPECT_EQ(find_if(value.begin(), value.end(), isNotAlnum), value.end());
+        }
+    }
+
+    /**
+     * Verify each criterionType has a unique name.
+     * Verify each criterion has a unique name.
+     * Verify each criterion maps to a criterionType.
+     * Verify each criterionType is used in a criterion.
+     * Validate contained types.
+     */
+    void ValidateCapSpecificConfig(const AudioHalEngineConfig::CapSpecificConfig& capCfg) {
+        EXPECT_FALSE(capCfg.criteria.empty());
+        EXPECT_FALSE(capCfg.criterionTypes.empty());
+        std::unordered_map<std::string, AudioHalCapCriterionType> criterionTypeMap;
+        for (const AudioHalCapCriterionType& criterionType : capCfg.criterionTypes) {
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapCriterionType(criterionType));
+            EXPECT_TRUE(criterionTypeMap.insert({criterionType.name, criterionType}).second);
+        }
+        std::unordered_set<std::string> criterionNameSet;
+        for (const AudioHalCapCriterion& criterion : capCfg.criteria) {
+            EXPECT_TRUE(criterionNameSet.insert(criterion.name).second);
+            EXPECT_EQ(criterionTypeMap.count(criterion.criterionTypeName), 1UL);
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapCriterion(
+                    criterion, criterionTypeMap.at(criterion.criterionTypeName)));
+        }
+        EXPECT_EQ(criterionTypeMap.size(), criterionNameSet.size());
+    }
+
+    /**
+     * Verify VolumeGroups are non-empty.
+     * Verify defaultProductStrategyId matches one of the provided productStrategies.
+     * Otherwise, must be left uninitialized.
+     * Verify each volumeGroup has a unique name.
+     * Verify each productStrategy has a unique id.
+     * Verify each volumeGroup is used in a product strategy.
+     * CAP engine: verify productStrategies are non-empty.
+     * Validate contained types.
+     */
+    void ValidateAudioHalEngineConfig() {
+        EXPECT_NE(mEngineConfig->volumeGroups.size(), 0UL);
+        std::unordered_map<std::string, const AudioHalVolumeGroup&> volumeGroupMap;
+        for (const AudioHalVolumeGroup& volumeGroup : mEngineConfig->volumeGroups) {
+            EXPECT_TRUE(volumeGroupMap.insert({volumeGroup.name, volumeGroup}).second);
+            EXPECT_NO_FATAL_FAILURE(ValidateAudioHalVolumeGroup(volumeGroup));
+        }
+        if (!mEngineConfig->productStrategies.empty()) {
+            std::unordered_set<int> productStrategyIdSet;
+            std::unordered_set<std::string> volumeGroupsUsedInStrategies;
+            for (const AudioHalProductStrategy& strategy : mEngineConfig->productStrategies) {
+                EXPECT_TRUE(productStrategyIdSet.insert(strategy.id).second);
+                EXPECT_NO_FATAL_FAILURE(ValidateAudioHalProductStrategy(
+                        strategy, volumeGroupMap, volumeGroupsUsedInStrategies));
+            }
+            EXPECT_TRUE(productStrategyIdSet.count(mEngineConfig->defaultProductStrategyId))
+                    << "defaultProductStrategyId doesn't match any of the provided "
+                       "productStrategies";
+            EXPECT_EQ(volumeGroupMap.size(), volumeGroupsUsedInStrategies.size());
+        } else {
+            EXPECT_EQ(mEngineConfig->defaultProductStrategyId,
+                      static_cast<int>(AudioProductStrategyType::SYS_RESERVED_NONE))
+                    << "defaultProductStrategyId defined, but no productStrategies were provided";
+        }
+        if (mEngineConfig->capSpecificConfig) {
+            EXPECT_NO_FATAL_FAILURE(
+                    ValidateCapSpecificConfig(mEngineConfig->capSpecificConfig.value()));
+            EXPECT_FALSE(mEngineConfig->productStrategies.empty());
+        }
+    }
+
+  private:
+    std::shared_ptr<IConfig> mConfig;
+    std::unique_ptr<AudioHalEngineConfig> mEngineConfig;
+    AudioHalBinderServiceUtil mBinderUtil;
+};
+
+TEST_P(AudioCoreConfig, Published) {
+    // SetUp must complete with no failures.
+}
+
+TEST_P(AudioCoreConfig, CanBeRestarted) {
+    ASSERT_NO_FATAL_FAILURE(RestartService());
+}
+
+TEST_P(AudioCoreConfig, GetEngineConfigIsValid) {
+    ASSERT_NO_FATAL_FAILURE(SetUpEngineConfig());
+    EXPECT_NO_FATAL_FAILURE(ValidateAudioHalEngineConfig());
+}
+
+INSTANTIATE_TEST_SUITE_P(AudioCoreConfigTest, AudioCoreConfig,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IConfig::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreConfig);
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
new file mode 100644
index 0000000..825b865
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -0,0 +1,3991 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <chrono>
+#include <cmath>
+#include <condition_variable>
+#include <forward_list>
+#include <limits>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <set>
+#include <string>
+#include <string_view>
+#include <variant>
+#include <vector>
+
+#define LOG_TAG "VtsHalAudioCore.Module"
+#include <android-base/logging.h>
+
+#include <StreamWorker.h>
+#include <Utils.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/core/BnStreamCallback.h>
+#include <aidl/android/hardware/audio/core/IModule.h>
+#include <aidl/android/hardware/audio/core/ITelephony.h>
+#include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h>
+#include <aidl/android/media/audio/common/AudioIoFlags.h>
+#include <aidl/android/media/audio/common/AudioMMapPolicyInfo.h>
+#include <aidl/android/media/audio/common/AudioMMapPolicyType.h>
+#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+#include <android-base/chrono_utils.h>
+#include <android/binder_enums.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "AudioHalBinderServiceUtil.h"
+#include "ModuleConfig.h"
+#include "TestUtils.h"
+
+using namespace android;
+using aidl::android::hardware::audio::common::AudioOffloadMetadata;
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::common::isBitPositionFlagSet;
+using aidl::android::hardware::audio::common::isTelephonyDeviceType;
+using aidl::android::hardware::audio::common::isValidAudioMode;
+using aidl::android::hardware::audio::common::PlaybackTrackMetadata;
+using aidl::android::hardware::audio::common::RecordTrackMetadata;
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::audio::core::AudioPatch;
+using aidl::android::hardware::audio::core::AudioRoute;
+using aidl::android::hardware::audio::core::IBluetooth;
+using aidl::android::hardware::audio::core::IBluetoothA2dp;
+using aidl::android::hardware::audio::core::IBluetoothLe;
+using aidl::android::hardware::audio::core::IModule;
+using aidl::android::hardware::audio::core::IStreamCommon;
+using aidl::android::hardware::audio::core::IStreamIn;
+using aidl::android::hardware::audio::core::IStreamOut;
+using aidl::android::hardware::audio::core::ITelephony;
+using aidl::android::hardware::audio::core::ModuleDebug;
+using aidl::android::hardware::audio::core::StreamDescriptor;
+using aidl::android::hardware::audio::core::VendorParameter;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::media::audio::common::AudioContentType;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioDualMonoMode;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioIoFlags;
+using aidl::android::media::audio::common::AudioLatencyMode;
+using aidl::android::media::audio::common::AudioMMapPolicyInfo;
+using aidl::android::media::audio::common::AudioMMapPolicyType;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioOutputFlags;
+using aidl::android::media::audio::common::AudioPlaybackRate;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortDeviceExt;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioPortMixExt;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioUsage;
+using aidl::android::media::audio::common::Boolean;
+using aidl::android::media::audio::common::Float;
+using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
+using aidl::android::media::audio::common::Void;
+using android::hardware::audio::common::StreamLogic;
+using android::hardware::audio::common::StreamWorker;
+using ndk::enum_range;
+using ndk::ScopedAStatus;
+
+template <typename T>
+auto findById(std::vector<T>& v, int32_t id) {
+    return std::find_if(v.begin(), v.end(), [&](const auto& e) { return e.id == id; });
+}
+
+template <typename C>
+std::vector<int32_t> GetNonExistentIds(const C& allIds) {
+    if (allIds.empty()) {
+        return std::vector<int32_t>{-1, 0, 1};
+    }
+    std::vector<int32_t> nonExistentIds;
+    nonExistentIds.push_back(*std::min_element(allIds.begin(), allIds.end()) - 1);
+    nonExistentIds.push_back(*std::max_element(allIds.begin(), allIds.end()) + 1);
+    return nonExistentIds;
+}
+
+AudioDeviceAddress::Tag suggestDeviceAddressTag(const AudioDeviceDescription& description) {
+    using Tag = AudioDeviceAddress::Tag;
+    if (std::string_view connection = description.connection;
+        connection == AudioDeviceDescription::CONNECTION_BT_A2DP ||
+        // Note: BT LE Broadcast uses a "group id".
+        (description.type != AudioDeviceType::OUT_BROADCAST &&
+         connection == AudioDeviceDescription::CONNECTION_BT_LE) ||
+        connection == AudioDeviceDescription::CONNECTION_BT_SCO ||
+        connection == AudioDeviceDescription::CONNECTION_WIRELESS) {
+        return Tag::mac;
+    } else if (connection == AudioDeviceDescription::CONNECTION_IP_V4) {
+        return Tag::ipv4;
+    } else if (connection == AudioDeviceDescription::CONNECTION_USB) {
+        return Tag::alsa;
+    }
+    return Tag::id;
+}
+
+AudioPort GenerateUniqueDeviceAddress(const AudioPort& port) {
+    static int nextId = 0;
+    using Tag = AudioDeviceAddress::Tag;
+    AudioDeviceAddress address;
+    switch (suggestDeviceAddressTag(port.ext.get<AudioPortExt::Tag::device>().device.type)) {
+        case Tag::id:
+            address = AudioDeviceAddress::make<Tag::id>(std::to_string(++nextId));
+            break;
+        case Tag::mac:
+            address = AudioDeviceAddress::make<Tag::mac>(
+                    std::vector<uint8_t>{1, 2, 3, 4, 5, static_cast<uint8_t>(++nextId & 0xff)});
+            break;
+        case Tag::ipv4:
+            address = AudioDeviceAddress::make<Tag::ipv4>(
+                    std::vector<uint8_t>{192, 168, 0, static_cast<uint8_t>(++nextId & 0xff)});
+            break;
+        case Tag::ipv6:
+            address = AudioDeviceAddress::make<Tag::ipv6>(std::vector<int32_t>{
+                    0xfc00, 0x0123, 0x4567, 0x89ab, 0xcdef, 0, 0, ++nextId & 0xffff});
+            break;
+        case Tag::alsa:
+            address = AudioDeviceAddress::make<Tag::alsa>(std::vector<int32_t>{1, ++nextId});
+            break;
+    }
+    AudioPort result = port;
+    result.ext.get<AudioPortExt::Tag::device>().device.address = std::move(address);
+    return result;
+}
+
+// All 'With*' classes are move-only because they are associated with some
+// resource or state of a HAL module.
+class WithDebugFlags {
+  public:
+    static WithDebugFlags createNested(const WithDebugFlags& parent) {
+        return WithDebugFlags(parent.mFlags);
+    }
+
+    WithDebugFlags() = default;
+    explicit WithDebugFlags(const ModuleDebug& initial) : mInitial(initial), mFlags(initial) {}
+    WithDebugFlags(const WithDebugFlags&) = delete;
+    WithDebugFlags& operator=(const WithDebugFlags&) = delete;
+    ~WithDebugFlags() {
+        if (mModule != nullptr) {
+            EXPECT_IS_OK(mModule->setModuleDebug(mInitial));
+        }
+    }
+    void SetUp(IModule* module) {
+        ASSERT_IS_OK(module->setModuleDebug(mFlags));
+        mModule = module;
+    }
+    ModuleDebug& flags() { return mFlags; }
+
+  private:
+    ModuleDebug mInitial;
+    ModuleDebug mFlags;
+    IModule* mModule = nullptr;
+};
+
+template <typename T>
+class WithModuleParameter {
+  public:
+    WithModuleParameter(const std::string parameterId, const T& value)
+        : mParameterId(parameterId), mValue(value) {}
+    WithModuleParameter(const WithModuleParameter&) = delete;
+    WithModuleParameter& operator=(const WithModuleParameter&) = delete;
+    ~WithModuleParameter() {
+        if (mModule != nullptr) {
+            VendorParameter parameter{.id = mParameterId};
+            parameter.ext.setParcelable(mInitial);
+            EXPECT_IS_OK(mModule->setVendorParameters({parameter}, false));
+        }
+    }
+    ScopedAStatus SetUpNoChecks(IModule* module, bool failureExpected) {
+        std::vector<VendorParameter> parameters;
+        ScopedAStatus result = module->getVendorParameters({mParameterId}, &parameters);
+        if (result.isOk() && parameters.size() == 1) {
+            std::optional<T> maybeInitial;
+            binder_status_t status = parameters[0].ext.getParcelable(&maybeInitial);
+            if (status == STATUS_OK && maybeInitial.has_value()) {
+                mInitial = maybeInitial.value();
+                VendorParameter parameter{.id = mParameterId};
+                parameter.ext.setParcelable(mValue);
+                result = module->setVendorParameters({parameter}, false);
+                if (result.isOk()) {
+                    LOG(INFO) << __func__ << ": overriding parameter \"" << mParameterId
+                              << "\" with " << mValue.toString()
+                              << ", old value: " << mInitial.toString();
+                    mModule = module;
+                }
+            } else {
+                LOG(ERROR) << __func__ << ": error while retrieving the value of \"" << mParameterId
+                           << "\"";
+                return ScopedAStatus::fromStatus(status);
+            }
+        }
+        if (!result.isOk()) {
+            LOG(failureExpected ? INFO : ERROR)
+                    << __func__ << ": can not override vendor parameter \"" << mParameterId << "\""
+                    << result;
+        }
+        return result;
+    }
+
+  private:
+    const std::string mParameterId;
+    const T mValue;
+    IModule* mModule = nullptr;
+    T mInitial;
+};
+
+// For consistency, WithAudioPortConfig can start both with a non-existent
+// port config, and with an existing one. Existence is determined by the
+// id of the provided config. If it's not 0, then WithAudioPortConfig is
+// essentially a no-op wrapper.
+class WithAudioPortConfig {
+  public:
+    WithAudioPortConfig() = default;
+    explicit WithAudioPortConfig(const AudioPortConfig& config) : mInitialConfig(config) {}
+    WithAudioPortConfig(const WithAudioPortConfig&) = delete;
+    WithAudioPortConfig& operator=(const WithAudioPortConfig&) = delete;
+    ~WithAudioPortConfig() {
+        if (mModule != nullptr) {
+            EXPECT_IS_OK(mModule->resetAudioPortConfig(getId())) << "port config id " << getId();
+        }
+    }
+    void SetUp(IModule* module) {
+        ASSERT_NE(AudioPortExt::Tag::unspecified, mInitialConfig.ext.getTag())
+                << "config: " << mInitialConfig.toString();
+        // Negotiation is allowed for device ports because the HAL module is
+        // allowed to provide an empty profiles list for attached devices.
+        ASSERT_NO_FATAL_FAILURE(
+                SetUpImpl(module, mInitialConfig.ext.getTag() == AudioPortExt::Tag::device));
+    }
+    int32_t getId() const { return mConfig.id; }
+    const AudioPortConfig& get() const { return mConfig; }
+
+  private:
+    void SetUpImpl(IModule* module, bool negotiate) {
+        if (mInitialConfig.id == 0) {
+            AudioPortConfig suggested;
+            bool applied = false;
+            ASSERT_IS_OK(module->setAudioPortConfig(mInitialConfig, &suggested, &applied))
+                    << "Config: " << mInitialConfig.toString();
+            if (!applied && negotiate) {
+                mInitialConfig = suggested;
+                ASSERT_NO_FATAL_FAILURE(SetUpImpl(module, false))
+                        << " while applying suggested config: " << suggested.toString();
+            } else {
+                ASSERT_TRUE(applied) << "Suggested: " << suggested.toString();
+                mConfig = suggested;
+                mModule = module;
+            }
+        } else {
+            mConfig = mInitialConfig;
+        }
+    }
+
+    AudioPortConfig mInitialConfig;
+    IModule* mModule = nullptr;
+    AudioPortConfig mConfig;
+};
+
+template <typename T>
+void GenerateTestArrays(size_t validElementCount, T validMin, T validMax,
+                        std::vector<std::vector<T>>* validValues,
+                        std::vector<std::vector<T>>* invalidValues) {
+    validValues->emplace_back(validElementCount, validMin);
+    validValues->emplace_back(validElementCount, validMax);
+    validValues->emplace_back(validElementCount, (validMin + validMax) / 2.f);
+    if (validElementCount > 0) {
+        invalidValues->emplace_back(validElementCount - 1, validMin);
+    }
+    invalidValues->emplace_back(validElementCount + 1, validMin);
+    for (auto m : {-2, -1, 2}) {
+        const auto invalidMin = m * validMin;
+        if (invalidMin < validMin || invalidMin > validMax) {
+            invalidValues->emplace_back(validElementCount, invalidMin);
+        }
+        const auto invalidMax = m * validMax;
+        if (invalidMax < validMin || invalidMax > validMax) {
+            invalidValues->emplace_back(validElementCount, invalidMax);
+        }
+    }
+}
+
+template <typename PropType, class Instance, typename Getter, typename Setter>
+void TestAccessors(Instance* inst, Getter getter, Setter setter,
+                   const std::vector<PropType>& validValues,
+                   const std::vector<PropType>& invalidValues, bool* isSupported) {
+    PropType initialValue{};
+    ScopedAStatus status = (inst->*getter)(&initialValue);
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        *isSupported = false;
+        return;
+    }
+    ASSERT_TRUE(status.isOk()) << "Unexpected status from a getter: " << status;
+    *isSupported = true;
+    for (const auto v : validValues) {
+        EXPECT_IS_OK((inst->*setter)(v)) << "for a valid value: " << ::testing::PrintToString(v);
+        PropType currentValue{};
+        EXPECT_IS_OK((inst->*getter)(&currentValue));
+        EXPECT_EQ(v, currentValue);
+    }
+    for (const auto v : invalidValues) {
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, (inst->*setter)(v))
+                << "for an invalid value: " << ::testing::PrintToString(v);
+    }
+    EXPECT_IS_OK((inst->*setter)(initialValue)) << "Failed to restore the initial value";
+}
+
+template <class Instance>
+void TestGetVendorParameters(Instance* inst, bool* isSupported) {
+    static const std::vector<std::vector<std::string>> kIdsLists = {{}, {"zero"}, {"one", "two"}};
+    static const auto kStatuses = {EX_ILLEGAL_ARGUMENT, EX_ILLEGAL_STATE, EX_UNSUPPORTED_OPERATION};
+    for (const auto& ids : kIdsLists) {
+        std::vector<VendorParameter> params;
+        if (ndk::ScopedAStatus status = inst->getVendorParameters(ids, &params); status.isOk()) {
+            EXPECT_EQ(ids.size(), params.size()) << "Size of the returned parameters list must "
+                                                 << "match the size of the provided ids list";
+            for (const auto& param : params) {
+                EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), param.id))
+                        << "Returned parameter id \"" << param.id << "\" is unexpected";
+            }
+            for (const auto& id : ids) {
+                EXPECT_NE(params.end(),
+                          std::find_if(params.begin(), params.end(),
+                                       [&](const auto& param) { return param.id == id; }))
+                        << "Requested parameter with id \"" << id << "\" was not returned";
+            }
+        } else {
+            EXPECT_STATUS(kStatuses, status);
+            if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+                *isSupported = false;
+                return;
+            }
+        }
+    }
+    *isSupported = true;
+}
+
+template <class Instance>
+void TestSetVendorParameters(Instance* inst, bool* isSupported) {
+    static const auto kStatuses = {EX_NONE, EX_ILLEGAL_ARGUMENT, EX_ILLEGAL_STATE,
+                                   EX_UNSUPPORTED_OPERATION};
+    static const std::vector<std::vector<VendorParameter>> kParamsLists = {
+            {}, {VendorParameter{"zero"}}, {VendorParameter{"one"}, VendorParameter{"two"}}};
+    for (const auto& params : kParamsLists) {
+        ndk::ScopedAStatus status = inst->setVendorParameters(params, false);
+        if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+            *isSupported = false;
+            return;
+        }
+        EXPECT_STATUS(kStatuses, status)
+                << ::android::internal::ToString(params) << ", async: false";
+        EXPECT_STATUS(kStatuses, inst->setVendorParameters(params, true))
+                << ::android::internal::ToString(params) << ", async: true";
+    }
+    *isSupported = true;
+}
+
+// Can be used as a base for any test here, does not depend on the fixture GTest parameters.
+class AudioCoreModuleBase {
+  public:
+    // Default buffer sizes are used mostly for negative tests.
+    static constexpr int kDefaultBufferSizeFrames = 256;
+    static constexpr int kDefaultLargeBufferSizeFrames = 48000;
+
+    void SetUpImpl(const std::string& moduleName) {
+        ASSERT_NO_FATAL_FAILURE(ConnectToService(moduleName));
+    }
+
+    void TearDownImpl() { debug.reset(); }
+
+    void ConnectToService(const std::string& moduleName) {
+        ASSERT_EQ(module, nullptr);
+        ASSERT_EQ(debug, nullptr);
+        module = IModule::fromBinder(binderUtil.connectToService(moduleName));
+        ASSERT_NE(module, nullptr);
+        ASSERT_NO_FATAL_FAILURE(SetUpDebug());
+    }
+
+    void RestartService() {
+        ASSERT_NE(module, nullptr);
+        moduleConfig.reset();
+        debug.reset();
+        module = IModule::fromBinder(binderUtil.restartService());
+        ASSERT_NE(module, nullptr);
+        ASSERT_NO_FATAL_FAILURE(SetUpDebug());
+    }
+
+    void SetUpDebug() {
+        debug.reset(new WithDebugFlags());
+        debug->flags().simulateDeviceConnections = true;
+        ASSERT_NO_FATAL_FAILURE(debug->SetUp(module.get()));
+    }
+
+    void ApplyEveryConfig(const std::vector<AudioPortConfig>& configs) {
+        for (const auto& config : configs) {
+            ASSERT_NE(0, config.portId);
+            WithAudioPortConfig portConfig(config);
+            ASSERT_NO_FATAL_FAILURE(portConfig.SetUp(module.get()));  // calls setAudioPortConfig
+            EXPECT_EQ(config.portId, portConfig.get().portId);
+            std::vector<AudioPortConfig> retrievedPortConfigs;
+            ASSERT_IS_OK(module->getAudioPortConfigs(&retrievedPortConfigs));
+            const int32_t portConfigId = portConfig.getId();
+            auto configIt = std::find_if(
+                    retrievedPortConfigs.begin(), retrievedPortConfigs.end(),
+                    [&portConfigId](const auto& retrConf) { return retrConf.id == portConfigId; });
+            EXPECT_NE(configIt, retrievedPortConfigs.end())
+                    << "Port config id returned by setAudioPortConfig: " << portConfigId
+                    << " is not found in the list returned by getAudioPortConfigs";
+            if (configIt != retrievedPortConfigs.end()) {
+                EXPECT_EQ(portConfig.get(), *configIt)
+                        << "Applied port config returned by setAudioPortConfig: "
+                        << portConfig.get().toString()
+                        << " is not the same as retrieved via getAudioPortConfigs: "
+                        << configIt->toString();
+            }
+        }
+    }
+
+    template <typename Entity>
+    void GetAllEntityIds(std::set<int32_t>* entityIds,
+                         ScopedAStatus (IModule::*getter)(std::vector<Entity>*),
+                         const std::string& errorMessage) {
+        std::vector<Entity> entities;
+        { ASSERT_IS_OK((module.get()->*getter)(&entities)); }
+        std::transform(entities.begin(), entities.end(),
+                       std::inserter(*entityIds, entityIds->begin()),
+                       [](const auto& entity) { return entity.id; });
+        EXPECT_EQ(entities.size(), entityIds->size()) << errorMessage;
+    }
+
+    void GetAllPatchIds(std::set<int32_t>* patchIds) {
+        return GetAllEntityIds<AudioPatch>(
+                patchIds, &IModule::getAudioPatches,
+                "IDs of audio patches returned by IModule.getAudioPatches are not unique");
+    }
+
+    void GetAllPortIds(std::set<int32_t>* portIds) {
+        return GetAllEntityIds<AudioPort>(
+                portIds, &IModule::getAudioPorts,
+                "IDs of audio ports returned by IModule.getAudioPorts are not unique");
+    }
+
+    void GetAllPortConfigIds(std::set<int32_t>* portConfigIds) {
+        return GetAllEntityIds<AudioPortConfig>(
+                portConfigIds, &IModule::getAudioPortConfigs,
+                "IDs of audio port configs returned by IModule.getAudioPortConfigs are not unique");
+    }
+
+    void SetUpModuleConfig() {
+        if (moduleConfig == nullptr) {
+            moduleConfig = std::make_unique<ModuleConfig>(module.get());
+            ASSERT_EQ(EX_NONE, moduleConfig->getStatus().getExceptionCode())
+                    << "ModuleConfig init error: " << moduleConfig->getError();
+        }
+    }
+
+    std::shared_ptr<IModule> module;
+    std::unique_ptr<ModuleConfig> moduleConfig;
+    AudioHalBinderServiceUtil binderUtil;
+    std::unique_ptr<WithDebugFlags> debug;
+};
+
+class AudioCoreModule : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam())); }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+};
+
+class WithDevicePortConnectedState {
+  public:
+    explicit WithDevicePortConnectedState(const AudioPort& idAndData) : mIdAndData(idAndData) {}
+    WithDevicePortConnectedState(const WithDevicePortConnectedState&) = delete;
+    WithDevicePortConnectedState& operator=(const WithDevicePortConnectedState&) = delete;
+    ~WithDevicePortConnectedState() {
+        if (mModule != nullptr) {
+            EXPECT_IS_OK(mModule->disconnectExternalDevice(getId()))
+                    << "when disconnecting device port ID " << getId();
+        }
+    }
+    void SetUp(IModule* module) {
+        ASSERT_IS_OK(module->connectExternalDevice(mIdAndData, &mConnectedPort))
+                << "when connecting device port ID & data " << mIdAndData.toString();
+        ASSERT_NE(mIdAndData.id, getId())
+                << "ID of the connected port must not be the same as the ID of the template port";
+        mModule = module;
+    }
+    int32_t getId() const { return mConnectedPort.id; }
+    const AudioPort& get() { return mConnectedPort; }
+
+  private:
+    const AudioPort mIdAndData;
+    IModule* mModule = nullptr;
+    AudioPort mConnectedPort;
+};
+
+class StreamContext {
+  public:
+    typedef AidlMessageQueue<StreamDescriptor::Command, SynchronizedReadWrite> CommandMQ;
+    typedef AidlMessageQueue<StreamDescriptor::Reply, SynchronizedReadWrite> ReplyMQ;
+    typedef AidlMessageQueue<int8_t, SynchronizedReadWrite> DataMQ;
+
+    explicit StreamContext(const StreamDescriptor& descriptor)
+        : mFrameSizeBytes(descriptor.frameSizeBytes),
+          mCommandMQ(new CommandMQ(descriptor.command)),
+          mReplyMQ(new ReplyMQ(descriptor.reply)),
+          mBufferSizeFrames(descriptor.bufferSizeFrames),
+          mDataMQ(maybeCreateDataMQ(descriptor)) {}
+    void checkIsValid() const {
+        EXPECT_NE(0UL, mFrameSizeBytes);
+        ASSERT_NE(nullptr, mCommandMQ);
+        EXPECT_TRUE(mCommandMQ->isValid());
+        ASSERT_NE(nullptr, mReplyMQ);
+        EXPECT_TRUE(mReplyMQ->isValid());
+        if (mDataMQ != nullptr) {
+            EXPECT_TRUE(mDataMQ->isValid());
+            EXPECT_GE(mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize(),
+                      mFrameSizeBytes * mBufferSizeFrames)
+                    << "Data MQ actual buffer size is "
+                       "less than the buffer size as specified by the descriptor";
+        }
+    }
+    size_t getBufferSizeBytes() const { return mFrameSizeBytes * mBufferSizeFrames; }
+    size_t getBufferSizeFrames() const { return mBufferSizeFrames; }
+    CommandMQ* getCommandMQ() const { return mCommandMQ.get(); }
+    DataMQ* getDataMQ() const { return mDataMQ.get(); }
+    size_t getFrameSizeBytes() const { return mFrameSizeBytes; }
+    ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
+
+  private:
+    static std::unique_ptr<DataMQ> maybeCreateDataMQ(const StreamDescriptor& descriptor) {
+        using Tag = StreamDescriptor::AudioBuffer::Tag;
+        if (descriptor.audio.getTag() == Tag::fmq) {
+            return std::make_unique<DataMQ>(descriptor.audio.get<Tag::fmq>());
+        }
+        return nullptr;
+    }
+
+    const size_t mFrameSizeBytes;
+    std::unique_ptr<CommandMQ> mCommandMQ;
+    std::unique_ptr<ReplyMQ> mReplyMQ;
+    const size_t mBufferSizeFrames;
+    std::unique_ptr<DataMQ> mDataMQ;
+};
+
+struct StreamEventReceiver {
+    virtual ~StreamEventReceiver() = default;
+    enum class Event { None, DrainReady, Error, TransferReady };
+    virtual std::tuple<int, Event> getLastEvent() const = 0;
+    virtual std::tuple<int, Event> waitForEvent(int clientEventSeq) = 0;
+    static constexpr int kEventSeqInit = -1;
+};
+std::string toString(StreamEventReceiver::Event event) {
+    switch (event) {
+        case StreamEventReceiver::Event::None:
+            return "None";
+        case StreamEventReceiver::Event::DrainReady:
+            return "DrainReady";
+        case StreamEventReceiver::Event::Error:
+            return "Error";
+        case StreamEventReceiver::Event::TransferReady:
+            return "TransferReady";
+    }
+    return std::to_string(static_cast<int32_t>(event));
+}
+
+// Note: we use a reference wrapper, not a pointer, because methods of std::*list
+// return references to inserted elements. This way, we can put a returned reference
+// into the children vector without any type conversions, and this makes DAG creation
+// code more clear.
+template <typename T>
+struct DagNode : public std::pair<T, std::vector<std::reference_wrapper<DagNode<T>>>> {
+    using Children = std::vector<std::reference_wrapper<DagNode>>;
+    DagNode(const T& t, const Children& c) : std::pair<T, Children>(t, c) {}
+    DagNode(T&& t, Children&& c) : std::pair<T, Children>(std::move(t), std::move(c)) {}
+    const T& datum() const { return this->first; }
+    Children& children() { return this->second; }
+    const Children& children() const { return this->second; }
+};
+// Since DagNodes do contain references to next nodes, node links provided
+// by the list are not used. Thus, the order of the nodes in the list is not
+// important, except that the starting node must be at the front of the list,
+// which means, it must always be added last.
+template <typename T>
+struct Dag : public std::forward_list<DagNode<T>> {
+    Dag() = default;
+    // We prohibit copying and moving Dag instances because implementing that
+    // is not trivial due to references between nodes.
+    Dag(const Dag&) = delete;
+    Dag(Dag&&) = delete;
+    Dag& operator=(const Dag&) = delete;
+    Dag& operator=(Dag&&) = delete;
+};
+
+// Transition to the next state happens either due to a command from the client,
+// or after an event received from the server.
+using TransitionTrigger = std::variant<StreamDescriptor::Command, StreamEventReceiver::Event>;
+std::string toString(const TransitionTrigger& trigger) {
+    if (std::holds_alternative<StreamDescriptor::Command>(trigger)) {
+        return std::string("'")
+                .append(toString(std::get<StreamDescriptor::Command>(trigger).getTag()))
+                .append("' command");
+    }
+    return std::string("'")
+            .append(toString(std::get<StreamEventReceiver::Event>(trigger)))
+            .append("' event");
+}
+
+struct StateSequence {
+    virtual ~StateSequence() = default;
+    virtual void rewind() = 0;
+    virtual bool done() const = 0;
+    virtual TransitionTrigger getTrigger() = 0;
+    virtual std::set<StreamDescriptor::State> getExpectedStates() = 0;
+    virtual void advance(StreamDescriptor::State state) = 0;
+};
+
+// Defines the current state and the trigger to transfer to the next one,
+// thus "state" is the "from" state.
+using StateTransitionFrom = std::pair<StreamDescriptor::State, TransitionTrigger>;
+
+static const StreamDescriptor::Command kGetStatusCommand =
+        StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::getStatus>(Void{});
+static const StreamDescriptor::Command kStartCommand =
+        StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::start>(Void{});
+static const StreamDescriptor::Command kBurstCommand =
+        StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::burst>(0);
+static const StreamDescriptor::Command kDrainInCommand =
+        StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::drain>(
+                StreamDescriptor::DrainMode::DRAIN_UNSPECIFIED);
+static const StreamDescriptor::Command kDrainOutAllCommand =
+        StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::drain>(
+                StreamDescriptor::DrainMode::DRAIN_ALL);
+static const StreamDescriptor::Command kDrainOutEarlyCommand =
+        StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::drain>(
+                StreamDescriptor::DrainMode::DRAIN_EARLY_NOTIFY);
+static const StreamDescriptor::Command kStandbyCommand =
+        StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::standby>(Void{});
+static const StreamDescriptor::Command kPauseCommand =
+        StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::pause>(Void{});
+static const StreamDescriptor::Command kFlushCommand =
+        StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::flush>(Void{});
+static const StreamEventReceiver::Event kTransferReadyEvent =
+        StreamEventReceiver::Event::TransferReady;
+static const StreamEventReceiver::Event kDrainReadyEvent = StreamEventReceiver::Event::DrainReady;
+
+struct StateDag : public Dag<StateTransitionFrom> {
+    using Node = StateDag::reference;
+    using NextStates = StateDag::value_type::Children;
+
+    template <typename... Next>
+    Node makeNode(StreamDescriptor::State s, TransitionTrigger t, Next&&... next) {
+        return emplace_front(std::make_pair(s, t), NextStates{std::forward<Next>(next)...});
+    }
+    Node makeNodes(const std::vector<StateTransitionFrom>& v, Node last) {
+        auto helper = [&](auto i, auto&& h) -> Node {
+            if (i == v.end()) return last;
+            return makeNode(i->first, i->second, h(++i, h));
+        };
+        return helper(v.begin(), helper);
+    }
+    Node makeNodes(const std::vector<StateTransitionFrom>& v, StreamDescriptor::State f) {
+        return makeNodes(v, makeFinalNode(f));
+    }
+    Node makeFinalNode(StreamDescriptor::State s) {
+        // The actual command used here is irrelevant. Since it's the final node
+        // in the test sequence, no commands sent after reaching it.
+        return emplace_front(std::make_pair(s, kGetStatusCommand), NextStates{});
+    }
+};
+
+class StateSequenceFollower : public StateSequence {
+  public:
+    explicit StateSequenceFollower(std::unique_ptr<StateDag> steps)
+        : mSteps(std::move(steps)), mCurrent(mSteps->front()) {}
+    void rewind() override { mCurrent = mSteps->front(); }
+    bool done() const override { return current().children().empty(); }
+    TransitionTrigger getTrigger() override { return current().datum().second; }
+    std::set<StreamDescriptor::State> getExpectedStates() override {
+        std::set<StreamDescriptor::State> result;
+        std::transform(current().children().cbegin(), current().children().cend(),
+                       std::inserter(result, result.begin()),
+                       [](const auto& node) { return node.get().datum().first; });
+        LOG(DEBUG) << __func__ << ": " << ::android::internal::ToString(result);
+        return result;
+    }
+    void advance(StreamDescriptor::State state) override {
+        if (auto it = std::find_if(
+                    current().children().cbegin(), current().children().cend(),
+                    [&](const auto& node) { return node.get().datum().first == state; });
+            it != current().children().cend()) {
+            LOG(DEBUG) << __func__ << ": " << toString(mCurrent.get().datum().first) << " -> "
+                       << toString(it->get().datum().first);
+            mCurrent = *it;
+        } else {
+            LOG(FATAL) << __func__ << ": state " << toString(state) << " is unexpected";
+        }
+    }
+
+  private:
+    StateDag::const_reference current() const { return mCurrent.get(); }
+    std::unique_ptr<StateDag> mSteps;
+    std::reference_wrapper<StateDag::value_type> mCurrent;
+};
+
+struct StreamLogicDriver {
+    virtual ~StreamLogicDriver() = default;
+    // Return 'true' to stop the worker.
+    virtual bool done() = 0;
+    // For 'Writer' logic, if the 'actualSize' is 0, write is skipped.
+    // The 'fmqByteCount' from the returned command is passed as is to the HAL.
+    virtual TransitionTrigger getNextTrigger(int maxDataSize, int* actualSize = nullptr) = 0;
+    // Return 'true' to indicate that no further processing is needed,
+    // for example, the driver is expecting a bad status to be returned.
+    // The logic cycle will return with 'CONTINUE' status. Otherwise,
+    // the reply will be validated and then passed to 'processValidReply'.
+    virtual bool interceptRawReply(const StreamDescriptor::Reply& reply) = 0;
+    // Return 'false' to indicate that the contents of the reply are unexpected.
+    // Will abort the logic cycle.
+    virtual bool processValidReply(const StreamDescriptor::Reply& reply) = 0;
+};
+
+class StreamCommonLogic : public StreamLogic {
+  protected:
+    StreamCommonLogic(const StreamContext& context, StreamLogicDriver* driver,
+                      StreamEventReceiver* eventReceiver)
+        : mCommandMQ(context.getCommandMQ()),
+          mReplyMQ(context.getReplyMQ()),
+          mDataMQ(context.getDataMQ()),
+          mData(context.getBufferSizeBytes()),
+          mDriver(driver),
+          mEventReceiver(eventReceiver) {}
+    StreamContext::CommandMQ* getCommandMQ() const { return mCommandMQ; }
+    StreamContext::ReplyMQ* getReplyMQ() const { return mReplyMQ; }
+    StreamContext::DataMQ* getDataMQ() const { return mDataMQ; }
+    StreamLogicDriver* getDriver() const { return mDriver; }
+    StreamEventReceiver* getEventReceiver() const { return mEventReceiver; }
+
+    std::string init() override {
+        LOG(DEBUG) << __func__;
+        return "";
+    }
+    std::optional<StreamDescriptor::Command> maybeGetNextCommand(int* actualSize = nullptr) {
+        TransitionTrigger trigger = mDriver->getNextTrigger(mData.size(), actualSize);
+        if (StreamEventReceiver::Event* expEvent =
+                    std::get_if<StreamEventReceiver::Event>(&trigger);
+            expEvent != nullptr) {
+            auto [eventSeq, event] = mEventReceiver->waitForEvent(mLastEventSeq);
+            mLastEventSeq = eventSeq;
+            if (event != *expEvent) {
+                LOG(ERROR) << __func__ << ": expected event " << toString(*expEvent) << ", got "
+                           << toString(event);
+                return {};
+            }
+            // If we were waiting for an event, the new stream state must be retrieved
+            // via 'getStatus'.
+            return StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::getStatus>(
+                    Void{});
+        }
+        return std::get<StreamDescriptor::Command>(trigger);
+    }
+    bool readDataFromMQ(size_t readCount) {
+        std::vector<int8_t> data(readCount);
+        if (mDataMQ->read(data.data(), readCount)) {
+            memcpy(mData.data(), data.data(), std::min(mData.size(), data.size()));
+            return true;
+        }
+        LOG(ERROR) << __func__ << ": reading of " << readCount << " bytes from MQ failed";
+        return false;
+    }
+    bool writeDataToMQ() {
+        if (mDataMQ->write(mData.data(), mData.size())) {
+            return true;
+        }
+        LOG(ERROR) << __func__ << ": writing of " << mData.size() << " bytes to MQ failed";
+        return false;
+    }
+
+  private:
+    StreamContext::CommandMQ* mCommandMQ;
+    StreamContext::ReplyMQ* mReplyMQ;
+    StreamContext::DataMQ* mDataMQ;
+    std::vector<int8_t> mData;
+    StreamLogicDriver* const mDriver;
+    StreamEventReceiver* const mEventReceiver;
+    int mLastEventSeq = StreamEventReceiver::kEventSeqInit;
+};
+
+class StreamReaderLogic : public StreamCommonLogic {
+  public:
+    StreamReaderLogic(const StreamContext& context, StreamLogicDriver* driver,
+                      StreamEventReceiver* eventReceiver)
+        : StreamCommonLogic(context, driver, eventReceiver) {}
+
+  protected:
+    Status cycle() override {
+        if (getDriver()->done()) {
+            LOG(DEBUG) << __func__ << ": clean exit";
+            return Status::EXIT;
+        }
+        StreamDescriptor::Command command;
+        if (auto maybeCommand = maybeGetNextCommand(); maybeCommand.has_value()) {
+            command = std::move(maybeCommand.value());
+        } else {
+            LOG(ERROR) << __func__ << ": no next command";
+            return Status::ABORT;
+        }
+        LOG(DEBUG) << "Writing command: " << command.toString();
+        if (!getCommandMQ()->writeBlocking(&command, 1)) {
+            LOG(ERROR) << __func__ << ": writing of command into MQ failed";
+            return Status::ABORT;
+        }
+        StreamDescriptor::Reply reply{};
+        LOG(DEBUG) << "Reading reply...";
+        if (!getReplyMQ()->readBlocking(&reply, 1)) {
+            return Status::ABORT;
+        }
+        LOG(DEBUG) << "Reply received: " << reply.toString();
+        if (getDriver()->interceptRawReply(reply)) {
+            LOG(DEBUG) << __func__ << ": reply has been intercepted by the driver";
+            return Status::CONTINUE;
+        }
+        if (reply.status != STATUS_OK) {
+            LOG(ERROR) << __func__ << ": received error status: " << statusToString(reply.status);
+            return Status::ABORT;
+        }
+        if (reply.fmqByteCount < 0 ||
+            (command.getTag() == StreamDescriptor::Command::Tag::burst &&
+             reply.fmqByteCount > command.get<StreamDescriptor::Command::Tag::burst>())) {
+            LOG(ERROR) << __func__
+                       << ": received invalid byte count in the reply: " << reply.fmqByteCount;
+            return Status::ABORT;
+        }
+        if (static_cast<size_t>(reply.fmqByteCount) != getDataMQ()->availableToRead()) {
+            LOG(ERROR) << __func__
+                       << ": the byte count in the reply is not the same as the amount of "
+                       << "data available in the MQ: " << reply.fmqByteCount
+                       << " != " << getDataMQ()->availableToRead();
+        }
+        if (reply.latencyMs < 0 && reply.latencyMs != StreamDescriptor::LATENCY_UNKNOWN) {
+            LOG(ERROR) << __func__ << ": received invalid latency value: " << reply.latencyMs;
+            return Status::ABORT;
+        }
+        if (reply.xrunFrames < 0) {
+            LOG(ERROR) << __func__ << ": received invalid xrunFrames value: " << reply.xrunFrames;
+            return Status::ABORT;
+        }
+        if (std::find(enum_range<StreamDescriptor::State>().begin(),
+                      enum_range<StreamDescriptor::State>().end(),
+                      reply.state) == enum_range<StreamDescriptor::State>().end()) {
+            LOG(ERROR) << __func__ << ": received invalid stream state: " << toString(reply.state);
+            return Status::ABORT;
+        }
+        const bool acceptedReply = getDriver()->processValidReply(reply);
+        if (const size_t readCount = getDataMQ()->availableToRead(); readCount > 0) {
+            if (readDataFromMQ(readCount)) {
+                goto checkAcceptedReply;
+            }
+            LOG(ERROR) << __func__ << ": reading of " << readCount << " data bytes from MQ failed";
+            return Status::ABORT;
+        }  // readCount == 0
+    checkAcceptedReply:
+        if (acceptedReply) {
+            return Status::CONTINUE;
+        }
+        LOG(ERROR) << __func__ << ": unacceptable reply: " << reply.toString();
+        return Status::ABORT;
+    }
+};
+using StreamReader = StreamWorker<StreamReaderLogic>;
+
+class StreamWriterLogic : public StreamCommonLogic {
+  public:
+    StreamWriterLogic(const StreamContext& context, StreamLogicDriver* driver,
+                      StreamEventReceiver* eventReceiver)
+        : StreamCommonLogic(context, driver, eventReceiver) {}
+
+  protected:
+    Status cycle() override {
+        if (getDriver()->done()) {
+            LOG(DEBUG) << __func__ << ": clean exit";
+            return Status::EXIT;
+        }
+        int actualSize = 0;
+        StreamDescriptor::Command command;
+        if (auto maybeCommand = maybeGetNextCommand(&actualSize); maybeCommand.has_value()) {
+            command = std::move(maybeCommand.value());
+        } else {
+            LOG(ERROR) << __func__ << ": no next command";
+            return Status::ABORT;
+        }
+        if (actualSize != 0 && !writeDataToMQ()) {
+            return Status::ABORT;
+        }
+        LOG(DEBUG) << "Writing command: " << command.toString();
+        if (!getCommandMQ()->writeBlocking(&command, 1)) {
+            LOG(ERROR) << __func__ << ": writing of command into MQ failed";
+            return Status::ABORT;
+        }
+        StreamDescriptor::Reply reply{};
+        LOG(DEBUG) << "Reading reply...";
+        if (!getReplyMQ()->readBlocking(&reply, 1)) {
+            LOG(ERROR) << __func__ << ": reading of reply from MQ failed";
+            return Status::ABORT;
+        }
+        LOG(DEBUG) << "Reply received: " << reply.toString();
+        if (getDriver()->interceptRawReply(reply)) {
+            return Status::CONTINUE;
+        }
+        if (reply.status != STATUS_OK) {
+            LOG(ERROR) << __func__ << ": received error status: " << statusToString(reply.status);
+            return Status::ABORT;
+        }
+        if (reply.fmqByteCount < 0 ||
+            (command.getTag() == StreamDescriptor::Command::Tag::burst &&
+             reply.fmqByteCount > command.get<StreamDescriptor::Command::Tag::burst>())) {
+            LOG(ERROR) << __func__
+                       << ": received invalid byte count in the reply: " << reply.fmqByteCount;
+            return Status::ABORT;
+        }
+        if (getDataMQ()->availableToWrite() != getDataMQ()->getQuantumCount()) {
+            LOG(ERROR) << __func__ << ": the HAL module did not consume all data from the data MQ: "
+                       << "available to write " << getDataMQ()->availableToWrite()
+                       << ", total size: " << getDataMQ()->getQuantumCount();
+            return Status::ABORT;
+        }
+        if (reply.latencyMs < 0 && reply.latencyMs != StreamDescriptor::LATENCY_UNKNOWN) {
+            LOG(ERROR) << __func__ << ": received invalid latency value: " << reply.latencyMs;
+            return Status::ABORT;
+        }
+        if (reply.xrunFrames < 0) {
+            LOG(ERROR) << __func__ << ": received invalid xrunFrames value: " << reply.xrunFrames;
+            return Status::ABORT;
+        }
+        if (std::find(enum_range<StreamDescriptor::State>().begin(),
+                      enum_range<StreamDescriptor::State>().end(),
+                      reply.state) == enum_range<StreamDescriptor::State>().end()) {
+            LOG(ERROR) << __func__ << ": received invalid stream state: " << toString(reply.state);
+            return Status::ABORT;
+        }
+        if (getDriver()->processValidReply(reply)) {
+            return Status::CONTINUE;
+        }
+        LOG(ERROR) << __func__ << ": unacceptable reply: " << reply.toString();
+        return Status::ABORT;
+    }
+};
+using StreamWriter = StreamWorker<StreamWriterLogic>;
+
+class DefaultStreamCallback : public ::aidl::android::hardware::audio::core::BnStreamCallback,
+                              public StreamEventReceiver {
+    ndk::ScopedAStatus onTransferReady() override {
+        LOG(DEBUG) << __func__;
+        putLastEvent(Event::TransferReady);
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus onError() override {
+        LOG(DEBUG) << __func__;
+        putLastEvent(Event::Error);
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus onDrainReady() override {
+        LOG(DEBUG) << __func__;
+        putLastEvent(Event::DrainReady);
+        return ndk::ScopedAStatus::ok();
+    }
+
+  public:
+    // To avoid timing out the whole test suite in case no event is received
+    // from the HAL, use a local timeout for event waiting.
+    static constexpr auto kEventTimeoutMs = std::chrono::milliseconds(1000);
+
+    StreamEventReceiver* getEventReceiver() { return this; }
+    std::tuple<int, Event> getLastEvent() const override {
+        std::lock_guard l(mLock);
+        return getLastEvent_l();
+    }
+    std::tuple<int, Event> waitForEvent(int clientEventSeq) override {
+        std::unique_lock l(mLock);
+        android::base::ScopedLockAssertion lock_assertion(mLock);
+        LOG(DEBUG) << __func__ << ": client " << clientEventSeq << ", last " << mLastEventSeq;
+        if (mCv.wait_for(l, kEventTimeoutMs, [&]() {
+                android::base::ScopedLockAssertion lock_assertion(mLock);
+                return clientEventSeq < mLastEventSeq;
+            })) {
+        } else {
+            LOG(WARNING) << __func__ << ": timed out waiting for an event";
+            putLastEvent_l(Event::None);
+        }
+        return getLastEvent_l();
+    }
+
+  private:
+    std::tuple<int, Event> getLastEvent_l() const REQUIRES(mLock) {
+        return std::make_tuple(mLastEventSeq, mLastEvent);
+    }
+    void putLastEvent(Event event) {
+        {
+            std::lock_guard l(mLock);
+            putLastEvent_l(event);
+        }
+        mCv.notify_one();
+    }
+    void putLastEvent_l(Event event) REQUIRES(mLock) {
+        mLastEventSeq++;
+        mLastEvent = event;
+    }
+
+    mutable std::mutex mLock;
+    std::condition_variable mCv;
+    int mLastEventSeq GUARDED_BY(mLock) = kEventSeqInit;
+    Event mLastEvent GUARDED_BY(mLock) = Event::None;
+};
+
+template <typename T>
+struct IOTraits {
+    static constexpr bool is_input = std::is_same_v<T, IStreamIn>;
+    using Worker = std::conditional_t<is_input, StreamReader, StreamWriter>;
+};
+
+template <typename Stream>
+class WithStream {
+  public:
+    static ndk::ScopedAStatus callClose(std::shared_ptr<Stream> stream) {
+        std::shared_ptr<IStreamCommon> common;
+        ndk::ScopedAStatus status = stream->getStreamCommon(&common);
+        if (!status.isOk()) return status;
+        status = common->prepareToClose();
+        if (!status.isOk()) return status;
+        return common->close();
+    }
+
+    WithStream() = default;
+    explicit WithStream(const AudioPortConfig& portConfig) : mPortConfig(portConfig) {}
+    WithStream(const WithStream&) = delete;
+    WithStream& operator=(const WithStream&) = delete;
+    ~WithStream() {
+        if (mStream != nullptr) {
+            mContext.reset();
+            EXPECT_IS_OK(callClose(mStream)) << "port config id " << getPortId();
+        }
+    }
+    void SetUpPortConfig(IModule* module) { ASSERT_NO_FATAL_FAILURE(mPortConfig.SetUp(module)); }
+    ScopedAStatus SetUpNoChecks(IModule* module, long bufferSizeFrames) {
+        return SetUpNoChecks(module, mPortConfig.get(), bufferSizeFrames);
+    }
+    ScopedAStatus SetUpNoChecks(IModule* module, const AudioPortConfig& portConfig,
+                                long bufferSizeFrames);
+    void SetUp(IModule* module, long bufferSizeFrames) {
+        ASSERT_NO_FATAL_FAILURE(SetUpPortConfig(module));
+        ASSERT_IS_OK(SetUpNoChecks(module, bufferSizeFrames)) << "port config id " << getPortId();
+        ASSERT_NE(nullptr, mStream) << "port config id " << getPortId();
+        EXPECT_GE(mDescriptor.bufferSizeFrames, bufferSizeFrames)
+                << "actual buffer size must be no less than requested";
+        mContext.emplace(mDescriptor);
+        ASSERT_NO_FATAL_FAILURE(mContext.value().checkIsValid());
+    }
+    Stream* get() const { return mStream.get(); }
+    const StreamContext* getContext() const { return mContext ? &(mContext.value()) : nullptr; }
+    StreamEventReceiver* getEventReceiver() { return mStreamCallback->getEventReceiver(); }
+    std::shared_ptr<Stream> getSharedPointer() const { return mStream; }
+    const AudioPortConfig& getPortConfig() const { return mPortConfig.get(); }
+    int32_t getPortId() const { return mPortConfig.getId(); }
+
+  private:
+    WithAudioPortConfig mPortConfig;
+    std::shared_ptr<Stream> mStream;
+    StreamDescriptor mDescriptor;
+    std::optional<StreamContext> mContext;
+    std::shared_ptr<DefaultStreamCallback> mStreamCallback;
+};
+
+SinkMetadata GenerateSinkMetadata(const AudioPortConfig& portConfig) {
+    RecordTrackMetadata trackMeta;
+    trackMeta.source = AudioSource::MIC;
+    trackMeta.gain = 1.0;
+    trackMeta.channelMask = portConfig.channelMask.value();
+    SinkMetadata metadata;
+    metadata.tracks.push_back(trackMeta);
+    return metadata;
+}
+
+template <>
+ScopedAStatus WithStream<IStreamIn>::SetUpNoChecks(IModule* module,
+                                                   const AudioPortConfig& portConfig,
+                                                   long bufferSizeFrames) {
+    aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments args;
+    args.portConfigId = portConfig.id;
+    args.sinkMetadata = GenerateSinkMetadata(portConfig);
+    args.bufferSizeFrames = bufferSizeFrames;
+    auto callback = ndk::SharedRefBase::make<DefaultStreamCallback>();
+    // TODO: Uncomment when support for asynchronous input is implemented.
+    // args.callback = callback;
+    aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn ret;
+    ScopedAStatus status = module->openInputStream(args, &ret);
+    if (status.isOk()) {
+        mStream = std::move(ret.stream);
+        mDescriptor = std::move(ret.desc);
+        mStreamCallback = std::move(callback);
+    }
+    return status;
+}
+
+SourceMetadata GenerateSourceMetadata(const AudioPortConfig& portConfig) {
+    PlaybackTrackMetadata trackMeta;
+    trackMeta.usage = AudioUsage::MEDIA;
+    trackMeta.contentType = AudioContentType::MUSIC;
+    trackMeta.gain = 1.0;
+    trackMeta.channelMask = portConfig.channelMask.value();
+    SourceMetadata metadata;
+    metadata.tracks.push_back(trackMeta);
+    return metadata;
+}
+
+template <>
+ScopedAStatus WithStream<IStreamOut>::SetUpNoChecks(IModule* module,
+                                                    const AudioPortConfig& portConfig,
+                                                    long bufferSizeFrames) {
+    aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
+    args.portConfigId = portConfig.id;
+    args.sourceMetadata = GenerateSourceMetadata(portConfig);
+    args.offloadInfo = ModuleConfig::generateOffloadInfoIfNeeded(portConfig);
+    args.bufferSizeFrames = bufferSizeFrames;
+    auto callback = ndk::SharedRefBase::make<DefaultStreamCallback>();
+    args.callback = callback;
+    aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
+    ScopedAStatus status = module->openOutputStream(args, &ret);
+    if (status.isOk()) {
+        mStream = std::move(ret.stream);
+        mDescriptor = std::move(ret.desc);
+        mStreamCallback = std::move(callback);
+    }
+    return status;
+}
+
+class WithAudioPatch {
+  public:
+    WithAudioPatch() = default;
+    WithAudioPatch(const AudioPortConfig& srcPortConfig, const AudioPortConfig& sinkPortConfig)
+        : mSrcPortConfig(srcPortConfig), mSinkPortConfig(sinkPortConfig) {}
+    WithAudioPatch(bool sinkIsCfg1, const AudioPortConfig& portConfig1,
+                   const AudioPortConfig& portConfig2)
+        : mSrcPortConfig(sinkIsCfg1 ? portConfig2 : portConfig1),
+          mSinkPortConfig(sinkIsCfg1 ? portConfig1 : portConfig2) {}
+    WithAudioPatch(const WithAudioPatch&) = delete;
+    WithAudioPatch& operator=(const WithAudioPatch&) = delete;
+    ~WithAudioPatch() {
+        if (mModule != nullptr && mPatch.id != 0) {
+            EXPECT_IS_OK(mModule->resetAudioPatch(mPatch.id)) << "patch id " << getId();
+        }
+    }
+    void SetUpPortConfigs(IModule* module) {
+        ASSERT_NO_FATAL_FAILURE(mSrcPortConfig.SetUp(module));
+        ASSERT_NO_FATAL_FAILURE(mSinkPortConfig.SetUp(module));
+    }
+    ScopedAStatus SetUpNoChecks(IModule* module) {
+        mModule = module;
+        mPatch.sourcePortConfigIds = std::vector<int32_t>{mSrcPortConfig.getId()};
+        mPatch.sinkPortConfigIds = std::vector<int32_t>{mSinkPortConfig.getId()};
+        return mModule->setAudioPatch(mPatch, &mPatch);
+    }
+    void SetUp(IModule* module) {
+        ASSERT_NO_FATAL_FAILURE(SetUpPortConfigs(module));
+        ASSERT_IS_OK(SetUpNoChecks(module)) << "source port config id " << mSrcPortConfig.getId()
+                                            << "; sink port config id " << mSinkPortConfig.getId();
+        EXPECT_GT(mPatch.minimumStreamBufferSizeFrames, 0) << "patch id " << getId();
+        for (auto latencyMs : mPatch.latenciesMs) {
+            EXPECT_GT(latencyMs, 0) << "patch id " << getId();
+        }
+    }
+    int32_t getId() const { return mPatch.id; }
+    const AudioPatch& get() const { return mPatch; }
+    const AudioPortConfig& getSinkPortConfig() const { return mSinkPortConfig.get(); }
+    const AudioPortConfig& getSrcPortConfig() const { return mSrcPortConfig.get(); }
+    const AudioPortConfig& getPortConfig(bool getSink) const {
+        return getSink ? getSinkPortConfig() : getSrcPortConfig();
+    }
+
+  private:
+    WithAudioPortConfig mSrcPortConfig;
+    WithAudioPortConfig mSinkPortConfig;
+    IModule* mModule = nullptr;
+    AudioPatch mPatch;
+};
+
+TEST_P(AudioCoreModule, Published) {
+    // SetUp must complete with no failures.
+}
+
+TEST_P(AudioCoreModule, CanBeRestarted) {
+    ASSERT_NO_FATAL_FAILURE(RestartService());
+}
+
+TEST_P(AudioCoreModule, PortIdsAreUnique) {
+    std::set<int32_t> portIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortIds(&portIds));
+}
+
+TEST_P(AudioCoreModule, GetAudioPortsIsStable) {
+    std::vector<AudioPort> ports1;
+    ASSERT_IS_OK(module->getAudioPorts(&ports1));
+    std::vector<AudioPort> ports2;
+    ASSERT_IS_OK(module->getAudioPorts(&ports2));
+    ASSERT_EQ(ports1.size(), ports2.size())
+            << "Sizes of audio port arrays do not match across consequent calls to getAudioPorts";
+    std::sort(ports1.begin(), ports1.end());
+    std::sort(ports2.begin(), ports2.end());
+    EXPECT_EQ(ports1, ports2);
+}
+
+TEST_P(AudioCoreModule, GetAudioRoutesIsStable) {
+    std::vector<AudioRoute> routes1;
+    ASSERT_IS_OK(module->getAudioRoutes(&routes1));
+    std::vector<AudioRoute> routes2;
+    ASSERT_IS_OK(module->getAudioRoutes(&routes2));
+    ASSERT_EQ(routes1.size(), routes2.size())
+            << "Sizes of audio route arrays do not match across consequent calls to getAudioRoutes";
+    std::sort(routes1.begin(), routes1.end());
+    std::sort(routes2.begin(), routes2.end());
+    EXPECT_EQ(routes1, routes2);
+}
+
+TEST_P(AudioCoreModule, GetAudioRoutesAreValid) {
+    std::vector<AudioRoute> routes;
+    ASSERT_IS_OK(module->getAudioRoutes(&routes));
+    for (const auto& route : routes) {
+        std::set<int32_t> sources(route.sourcePortIds.begin(), route.sourcePortIds.end());
+        EXPECT_NE(0UL, sources.size())
+                << "empty audio port sinks in the audio route: " << route.toString();
+        EXPECT_EQ(sources.size(), route.sourcePortIds.size())
+                << "IDs of audio port sinks are not unique in the audio route: "
+                << route.toString();
+    }
+}
+
+TEST_P(AudioCoreModule, GetAudioRoutesPortIdsAreValid) {
+    std::set<int32_t> portIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortIds(&portIds));
+    std::vector<AudioRoute> routes;
+    ASSERT_IS_OK(module->getAudioRoutes(&routes));
+    for (const auto& route : routes) {
+        EXPECT_EQ(1UL, portIds.count(route.sinkPortId))
+                << route.sinkPortId << " sink port id is unknown";
+        for (const auto& source : route.sourcePortIds) {
+            EXPECT_EQ(1UL, portIds.count(source)) << source << " source port id is unknown";
+        }
+    }
+}
+
+TEST_P(AudioCoreModule, GetAudioRoutesForAudioPort) {
+    std::set<int32_t> portIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortIds(&portIds));
+    if (portIds.empty()) {
+        GTEST_SKIP() << "No ports in the module.";
+    }
+    for (const auto portId : portIds) {
+        std::vector<AudioRoute> routes;
+        EXPECT_IS_OK(module->getAudioRoutesForAudioPort(portId, &routes));
+        for (const auto& r : routes) {
+            if (r.sinkPortId != portId) {
+                const auto& srcs = r.sourcePortIds;
+                EXPECT_TRUE(std::find(srcs.begin(), srcs.end(), portId) != srcs.end())
+                        << " port ID " << portId << " does not used by the route " << r.toString();
+            }
+        }
+    }
+    for (const auto portId : GetNonExistentIds(portIds)) {
+        std::vector<AudioRoute> routes;
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->getAudioRoutesForAudioPort(portId, &routes))
+                << "port ID " << portId;
+    }
+}
+
+TEST_P(AudioCoreModule, CheckDevicePorts) {
+    std::vector<AudioPort> ports;
+    ASSERT_IS_OK(module->getAudioPorts(&ports));
+    std::optional<int32_t> defaultOutput, defaultInput;
+    std::set<AudioDevice> inputs, outputs;
+    const int defaultDeviceFlag = 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
+    for (const auto& port : ports) {
+        if (port.ext.getTag() != AudioPortExt::Tag::device) continue;
+        const auto& devicePort = port.ext.get<AudioPortExt::Tag::device>();
+        EXPECT_NE(AudioDeviceType::NONE, devicePort.device.type.type);
+        EXPECT_NE(AudioDeviceType::IN_DEFAULT, devicePort.device.type.type);
+        EXPECT_NE(AudioDeviceType::OUT_DEFAULT, devicePort.device.type.type);
+        if (devicePort.device.type.type > AudioDeviceType::IN_DEFAULT &&
+            devicePort.device.type.type < AudioDeviceType::OUT_DEFAULT) {
+            EXPECT_EQ(AudioIoFlags::Tag::input, port.flags.getTag());
+        } else if (devicePort.device.type.type > AudioDeviceType::OUT_DEFAULT) {
+            EXPECT_EQ(AudioIoFlags::Tag::output, port.flags.getTag());
+        }
+        EXPECT_FALSE((devicePort.flags & defaultDeviceFlag) != 0 &&
+                     !devicePort.device.type.connection.empty())
+                << "Device port " << port.id
+                << " must be permanently attached to be set as default";
+        if ((devicePort.flags & defaultDeviceFlag) != 0) {
+            if (port.flags.getTag() == AudioIoFlags::Tag::output) {
+                EXPECT_FALSE(defaultOutput.has_value())
+                        << "At least two output device ports are declared as default: "
+                        << defaultOutput.value() << " and " << port.id;
+                defaultOutput = port.id;
+                EXPECT_EQ(0UL, outputs.count(devicePort.device))
+                        << "Non-unique output device: " << devicePort.device.toString();
+                outputs.insert(devicePort.device);
+            } else if (port.flags.getTag() == AudioIoFlags::Tag::input) {
+                EXPECT_FALSE(defaultInput.has_value())
+                        << "At least two input device ports are declared as default: "
+                        << defaultInput.value() << " and " << port.id;
+                defaultInput = port.id;
+                EXPECT_EQ(0UL, inputs.count(devicePort.device))
+                        << "Non-unique input device: " << devicePort.device.toString();
+                inputs.insert(devicePort.device);
+            } else {
+                FAIL() << "Invalid AudioIoFlags Tag: " << toString(port.flags.getTag());
+            }
+        }
+    }
+}
+
+TEST_P(AudioCoreModule, CheckMixPorts) {
+    std::vector<AudioPort> ports;
+    ASSERT_IS_OK(module->getAudioPorts(&ports));
+    std::optional<int32_t> primaryMixPort;
+    for (const auto& port : ports) {
+        if (port.ext.getTag() != AudioPortExt::Tag::mix) continue;
+        const auto& mixPort = port.ext.get<AudioPortExt::Tag::mix>();
+        if (port.flags.getTag() == AudioIoFlags::Tag::output &&
+            isBitPositionFlagSet(port.flags.get<AudioIoFlags::Tag::output>(),
+                                 AudioOutputFlags::PRIMARY)) {
+            EXPECT_FALSE(primaryMixPort.has_value())
+                    << "At least two mix ports have PRIMARY flag set: " << primaryMixPort.value()
+                    << " and " << port.id;
+            primaryMixPort = port.id;
+            EXPECT_EQ(1, mixPort.maxOpenStreamCount)
+                    << "Primary mix port " << port.id << " can not have maxOpenStreamCount "
+                    << mixPort.maxOpenStreamCount;
+        }
+    }
+}
+
+TEST_P(AudioCoreModule, GetAudioPort) {
+    std::set<int32_t> portIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortIds(&portIds));
+    if (portIds.empty()) {
+        GTEST_SKIP() << "No ports in the module.";
+    }
+    for (const auto portId : portIds) {
+        AudioPort port;
+        EXPECT_IS_OK(module->getAudioPort(portId, &port));
+        EXPECT_EQ(portId, port.id);
+    }
+    for (const auto portId : GetNonExistentIds(portIds)) {
+        AudioPort port;
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->getAudioPort(portId, &port))
+                << "port ID " << portId;
+    }
+}
+
+TEST_P(AudioCoreModule, SetUpModuleConfig) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    // Send the module config to logcat to facilitate failures investigation.
+    LOG(INFO) << "SetUpModuleConfig: " << moduleConfig->toString();
+}
+
+// Verify that HAL module reports for a connected device port at least one non-dynamic profile,
+// that is, a profile with actual supported configuration.
+// Note: This test relies on simulation of external device connections by the HAL module.
+TEST_P(AudioCoreModule, GetAudioPortWithExternalDevices) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    std::vector<AudioPort> ports = moduleConfig->getExternalDevicePorts();
+    if (ports.empty()) {
+        GTEST_SKIP() << "No external devices in the module.";
+    }
+    for (const auto& port : ports) {
+        AudioPort portWithData = GenerateUniqueDeviceAddress(port);
+        WithDevicePortConnectedState portConnected(portWithData);
+        ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
+        const int32_t connectedPortId = portConnected.getId();
+        ASSERT_NE(portWithData.id, connectedPortId);
+        ASSERT_EQ(portWithData.ext.getTag(), portConnected.get().ext.getTag());
+        EXPECT_EQ(portWithData.ext.get<AudioPortExt::Tag::device>().device,
+                  portConnected.get().ext.get<AudioPortExt::Tag::device>().device);
+        // Verify that 'getAudioPort' and 'getAudioPorts' return the same connected port.
+        AudioPort connectedPort;
+        EXPECT_IS_OK(module->getAudioPort(connectedPortId, &connectedPort))
+                << "port ID " << connectedPortId;
+        EXPECT_EQ(portConnected.get(), connectedPort);
+        const auto& portProfiles = connectedPort.profiles;
+        EXPECT_NE(0UL, portProfiles.size())
+                << "Connected port has no profiles: " << connectedPort.toString();
+        const auto dynamicProfileIt =
+                std::find_if(portProfiles.begin(), portProfiles.end(), [](const auto& profile) {
+                    return profile.format.type == AudioFormatType::DEFAULT;
+                });
+        EXPECT_EQ(portProfiles.end(), dynamicProfileIt) << "Connected port contains dynamic "
+                                                        << "profiles: " << connectedPort.toString();
+
+        std::vector<AudioPort> allPorts;
+        ASSERT_IS_OK(module->getAudioPorts(&allPorts));
+        const auto allPortsIt = findById(allPorts, connectedPortId);
+        EXPECT_NE(allPorts.end(), allPortsIt);
+        if (allPortsIt != allPorts.end()) {
+            EXPECT_EQ(portConnected.get(), *allPortsIt);
+        }
+    }
+}
+
+TEST_P(AudioCoreModule, OpenStreamInvalidPortConfigId) {
+    std::set<int32_t> portConfigIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortConfigIds(&portConfigIds));
+    for (const auto portConfigId : GetNonExistentIds(portConfigIds)) {
+        {
+            aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments args;
+            args.portConfigId = portConfigId;
+            args.bufferSizeFrames = kDefaultBufferSizeFrames;
+            aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn ret;
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->openInputStream(args, &ret))
+                    << "port config ID " << portConfigId;
+            EXPECT_EQ(nullptr, ret.stream);
+        }
+        {
+            aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
+            args.portConfigId = portConfigId;
+            args.bufferSizeFrames = kDefaultBufferSizeFrames;
+            aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->openOutputStream(args, &ret))
+                    << "port config ID " << portConfigId;
+            EXPECT_EQ(nullptr, ret.stream);
+        }
+    }
+}
+
+TEST_P(AudioCoreModule, PortConfigIdsAreUnique) {
+    std::set<int32_t> portConfigIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortConfigIds(&portConfigIds));
+}
+
+TEST_P(AudioCoreModule, PortConfigPortIdsAreValid) {
+    std::set<int32_t> portIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortIds(&portIds));
+    std::vector<AudioPortConfig> portConfigs;
+    ASSERT_IS_OK(module->getAudioPortConfigs(&portConfigs));
+    for (const auto& config : portConfigs) {
+        EXPECT_EQ(1UL, portIds.count(config.portId))
+                << config.portId << " port id is unknown, config id " << config.id;
+    }
+}
+
+TEST_P(AudioCoreModule, ResetAudioPortConfigInvalidId) {
+    std::set<int32_t> portConfigIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortConfigIds(&portConfigIds));
+    for (const auto portConfigId : GetNonExistentIds(portConfigIds)) {
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->resetAudioPortConfig(portConfigId))
+                << "port config ID " << portConfigId;
+    }
+}
+
+// Verify that for the audio port configs provided by the HAL after init, resetting
+// the config does not delete it, but brings it back to the initial config.
+TEST_P(AudioCoreModule, ResetAudioPortConfigToInitialValue) {
+    std::vector<AudioPortConfig> portConfigsBefore;
+    ASSERT_IS_OK(module->getAudioPortConfigs(&portConfigsBefore));
+    // TODO: Change port configs according to port profiles.
+    for (const auto& c : portConfigsBefore) {
+        EXPECT_IS_OK(module->resetAudioPortConfig(c.id)) << "port config ID " << c.id;
+    }
+    std::vector<AudioPortConfig> portConfigsAfter;
+    ASSERT_IS_OK(module->getAudioPortConfigs(&portConfigsAfter));
+    for (const auto& c : portConfigsBefore) {
+        auto afterIt = findById<AudioPortConfig>(portConfigsAfter, c.id);
+        EXPECT_NE(portConfigsAfter.end(), afterIt)
+                << " port config ID " << c.id << " was removed by reset";
+        if (afterIt != portConfigsAfter.end()) {
+            EXPECT_EQ(c, *afterIt);
+        }
+    }
+}
+
+TEST_P(AudioCoreModule, SetAudioPortConfigSuggestedConfig) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    auto srcMixPort = moduleConfig->getSourceMixPortForAttachedDevice();
+    if (!srcMixPort.has_value()) {
+        GTEST_SKIP() << "No mix port for attached output devices";
+    }
+    AudioPortConfig portConfig;
+    AudioPortConfig suggestedConfig;
+    portConfig.portId = srcMixPort.value().id;
+    const int32_t kIoHandle = 42;
+    portConfig.ext = AudioPortMixExt{.handle = kIoHandle};
+    {
+        bool applied = true;
+        ASSERT_IS_OK(module->setAudioPortConfig(portConfig, &suggestedConfig, &applied))
+                << "Config: " << portConfig.toString();
+        EXPECT_FALSE(applied);
+    }
+    EXPECT_EQ(0, suggestedConfig.id);
+    EXPECT_TRUE(suggestedConfig.sampleRate.has_value());
+    EXPECT_TRUE(suggestedConfig.channelMask.has_value());
+    EXPECT_TRUE(suggestedConfig.format.has_value());
+    EXPECT_TRUE(suggestedConfig.flags.has_value());
+    ASSERT_EQ(AudioPortExt::Tag::mix, suggestedConfig.ext.getTag());
+    EXPECT_EQ(kIoHandle, suggestedConfig.ext.get<AudioPortExt::Tag::mix>().handle);
+    WithAudioPortConfig applied(suggestedConfig);
+    ASSERT_NO_FATAL_FAILURE(applied.SetUp(module.get()));
+    const AudioPortConfig& appliedConfig = applied.get();
+    EXPECT_NE(0, appliedConfig.id);
+    ASSERT_TRUE(appliedConfig.sampleRate.has_value());
+    EXPECT_EQ(suggestedConfig.sampleRate.value(), appliedConfig.sampleRate.value());
+    ASSERT_TRUE(appliedConfig.channelMask.has_value());
+    EXPECT_EQ(suggestedConfig.channelMask.value(), appliedConfig.channelMask.value());
+    ASSERT_TRUE(appliedConfig.format.has_value());
+    EXPECT_EQ(suggestedConfig.format.value(), appliedConfig.format.value());
+    ASSERT_TRUE(appliedConfig.flags.has_value());
+    EXPECT_EQ(suggestedConfig.flags.value(), appliedConfig.flags.value());
+    ASSERT_EQ(AudioPortExt::Tag::mix, appliedConfig.ext.getTag());
+    EXPECT_EQ(kIoHandle, appliedConfig.ext.get<AudioPortExt::Tag::mix>().handle);
+}
+
+TEST_P(AudioCoreModule, SetAllAttachedDevicePortConfigs) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    ASSERT_NO_FATAL_FAILURE(ApplyEveryConfig(moduleConfig->getPortConfigsForAttachedDevicePorts()));
+}
+
+// Note: This test relies on simulation of external device connections by the HAL module.
+TEST_P(AudioCoreModule, SetAllExternalDevicePortConfigs) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    std::vector<AudioPort> ports = moduleConfig->getExternalDevicePorts();
+    if (ports.empty()) {
+        GTEST_SKIP() << "No external devices in the module.";
+    }
+    for (const auto& port : ports) {
+        WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
+        ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
+        ASSERT_NO_FATAL_FAILURE(
+                ApplyEveryConfig(moduleConfig->getPortConfigsForDevicePort(portConnected.get())));
+    }
+}
+
+TEST_P(AudioCoreModule, SetAllStaticAudioPortConfigs) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    ASSERT_NO_FATAL_FAILURE(ApplyEveryConfig(moduleConfig->getPortConfigsForMixPorts()));
+}
+
+TEST_P(AudioCoreModule, SetAudioPortConfigInvalidPortId) {
+    std::set<int32_t> portIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortIds(&portIds));
+    for (const auto portId : GetNonExistentIds(portIds)) {
+        AudioPortConfig portConfig, suggestedConfig;
+        bool applied;
+        portConfig.portId = portId;
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                      module->setAudioPortConfig(portConfig, &suggestedConfig, &applied))
+                << "port ID " << portId;
+        EXPECT_FALSE(suggestedConfig.format.has_value());
+        EXPECT_FALSE(suggestedConfig.channelMask.has_value());
+        EXPECT_FALSE(suggestedConfig.sampleRate.has_value());
+    }
+}
+
+TEST_P(AudioCoreModule, SetAudioPortConfigInvalidPortConfigId) {
+    std::set<int32_t> portConfigIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortConfigIds(&portConfigIds));
+    for (const auto portConfigId : GetNonExistentIds(portConfigIds)) {
+        AudioPortConfig portConfig, suggestedConfig;
+        bool applied;
+        portConfig.id = portConfigId;
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                      module->setAudioPortConfig(portConfig, &suggestedConfig, &applied))
+                << "port config ID " << portConfigId;
+        EXPECT_FALSE(suggestedConfig.format.has_value());
+        EXPECT_FALSE(suggestedConfig.channelMask.has_value());
+        EXPECT_FALSE(suggestedConfig.sampleRate.has_value());
+    }
+}
+
+TEST_P(AudioCoreModule, TryConnectMissingDevice) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    std::vector<AudioPort> ports = moduleConfig->getExternalDevicePorts();
+    if (ports.empty()) {
+        GTEST_SKIP() << "No external devices in the module.";
+    }
+    AudioPort ignored;
+    WithDebugFlags doNotSimulateConnections = WithDebugFlags::createNested(*debug);
+    doNotSimulateConnections.flags().simulateDeviceConnections = false;
+    ASSERT_NO_FATAL_FAILURE(doNotSimulateConnections.SetUp(module.get()));
+    for (const auto& port : ports) {
+        AudioPort portWithData = GenerateUniqueDeviceAddress(port);
+        EXPECT_STATUS(EX_ILLEGAL_STATE, module->connectExternalDevice(portWithData, &ignored))
+                << "static port " << portWithData.toString();
+    }
+}
+
+TEST_P(AudioCoreModule, TryChangingConnectionSimulationMidway) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    std::vector<AudioPort> ports = moduleConfig->getExternalDevicePorts();
+    if (ports.empty()) {
+        GTEST_SKIP() << "No external devices in the module.";
+    }
+    WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(*ports.begin()));
+    ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
+    ModuleDebug midwayDebugChange = debug->flags();
+    midwayDebugChange.simulateDeviceConnections = false;
+    EXPECT_STATUS(EX_ILLEGAL_STATE, module->setModuleDebug(midwayDebugChange))
+            << "when trying to disable connections simulation while having a connected device";
+}
+
+TEST_P(AudioCoreModule, ConnectDisconnectExternalDeviceInvalidPorts) {
+    AudioPort ignored;
+    std::set<int32_t> portIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPortIds(&portIds));
+    for (const auto portId : GetNonExistentIds(portIds)) {
+        AudioPort invalidPort;
+        invalidPort.id = portId;
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->connectExternalDevice(invalidPort, &ignored))
+                << "port ID " << portId << ", when setting CONNECTED state";
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(portId))
+                << "port ID " << portId << ", when setting DISCONNECTED state";
+    }
+
+    std::vector<AudioPort> ports;
+    ASSERT_IS_OK(module->getAudioPorts(&ports));
+    for (const auto& port : ports) {
+        if (port.ext.getTag() != AudioPortExt::Tag::device) {
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->connectExternalDevice(port, &ignored))
+                    << "non-device port ID " << port.id << " when setting CONNECTED state";
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
+                    << "non-device port ID " << port.id << " when setting DISCONNECTED state";
+        } else {
+            const auto& devicePort = port.ext.get<AudioPortExt::Tag::device>();
+            if (devicePort.device.type.connection.empty()) {
+                EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->connectExternalDevice(port, &ignored))
+                        << "for a permanently attached device port ID " << port.id
+                        << " when setting CONNECTED state";
+                EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
+                        << "for a permanently attached device port ID " << port.id
+                        << " when setting DISCONNECTED state";
+            }
+        }
+    }
+}
+
+// Note: This test relies on simulation of external device connections by the HAL module.
+TEST_P(AudioCoreModule, ConnectDisconnectExternalDeviceTwice) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    AudioPort ignored;
+    std::vector<AudioPort> ports = moduleConfig->getExternalDevicePorts();
+    if (ports.empty()) {
+        GTEST_SKIP() << "No external devices in the module.";
+    }
+    for (const auto& port : ports) {
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
+                << "when disconnecting already disconnected device port ID " << port.id;
+        AudioPort portWithData = GenerateUniqueDeviceAddress(port);
+        WithDevicePortConnectedState portConnected(portWithData);
+        ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                      module->connectExternalDevice(portConnected.get(), &ignored))
+                << "when trying to connect a connected device port "
+                << portConnected.get().toString();
+        EXPECT_STATUS(EX_ILLEGAL_STATE, module->connectExternalDevice(portWithData, &ignored))
+                << "when connecting again the external device "
+                << portWithData.ext.get<AudioPortExt::Tag::device>().device.toString()
+                << "; Returned connected port " << ignored.toString() << " for template "
+                << portWithData.toString();
+    }
+}
+
+// Note: This test relies on simulation of external device connections by the HAL module.
+TEST_P(AudioCoreModule, DisconnectExternalDeviceNonResetPortConfig) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    std::vector<AudioPort> ports = moduleConfig->getExternalDevicePorts();
+    if (ports.empty()) {
+        GTEST_SKIP() << "No external devices in the module.";
+    }
+    for (const auto& port : ports) {
+        WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
+        ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
+        const auto portConfig = moduleConfig->getSingleConfigForDevicePort(portConnected.get());
+        {
+            WithAudioPortConfig config(portConfig);
+            // Note: if SetUp fails, check the status of 'GetAudioPortWithExternalDevices' test.
+            // Our test assumes that 'getAudioPort' returns at least one profile, and it
+            // is not a dynamic profile.
+            ASSERT_NO_FATAL_FAILURE(config.SetUp(module.get()));
+            EXPECT_STATUS(EX_ILLEGAL_STATE, module->disconnectExternalDevice(portConnected.getId()))
+                    << "when trying to disconnect device port ID " << port.id
+                    << " with active configuration " << config.getId();
+        }
+    }
+}
+
+TEST_P(AudioCoreModule, ExternalDevicePortRoutes) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    std::vector<AudioPort> ports = moduleConfig->getExternalDevicePorts();
+    if (ports.empty()) {
+        GTEST_SKIP() << "No external devices in the module.";
+    }
+    for (const auto& port : ports) {
+        std::vector<AudioRoute> routesBefore;
+        ASSERT_IS_OK(module->getAudioRoutes(&routesBefore));
+
+        int32_t connectedPortId;
+        {
+            WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
+            ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
+            connectedPortId = portConnected.getId();
+            std::vector<AudioRoute> connectedPortRoutes;
+            ASSERT_IS_OK(module->getAudioRoutesForAudioPort(connectedPortId, &connectedPortRoutes))
+                    << "when retrieving routes for connected port id " << connectedPortId;
+            // There must be routes for the port to be useful.
+            if (connectedPortRoutes.empty()) {
+                std::vector<AudioRoute> allRoutes;
+                ASSERT_IS_OK(module->getAudioRoutes(&allRoutes));
+                ADD_FAILURE() << " no routes returned for the connected port "
+                              << portConnected.get().toString()
+                              << "; all routes: " << android::internal::ToString(allRoutes);
+            }
+        }
+        std::vector<AudioRoute> ignored;
+        ASSERT_STATUS(EX_ILLEGAL_ARGUMENT,
+                      module->getAudioRoutesForAudioPort(connectedPortId, &ignored))
+                << "when retrieving routes for released connected port id " << connectedPortId;
+
+        std::vector<AudioRoute> routesAfter;
+        ASSERT_IS_OK(module->getAudioRoutes(&routesAfter));
+        ASSERT_EQ(routesBefore.size(), routesAfter.size())
+                << "Sizes of audio route arrays do not match after creating and "
+                << "releasing a connected port";
+        std::sort(routesBefore.begin(), routesBefore.end());
+        std::sort(routesAfter.begin(), routesAfter.end());
+        EXPECT_EQ(routesBefore, routesAfter);
+    }
+}
+
+// Note: This test relies on simulation of external device connections by the HAL module.
+TEST_P(AudioCoreModule, ExternalDeviceMixPortConfigs) {
+    // After an external device has been connected, all mix ports that can be routed
+    // to the device port for the connected device must have non-empty profiles.
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    std::vector<AudioPort> externalDevicePorts = moduleConfig->getExternalDevicePorts();
+    if (externalDevicePorts.empty()) {
+        GTEST_SKIP() << "No external devices in the module.";
+    }
+    for (const auto& port : externalDevicePorts) {
+        WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
+        ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
+        std::vector<AudioRoute> routes;
+        ASSERT_IS_OK(module->getAudioRoutesForAudioPort(portConnected.getId(), &routes));
+        std::vector<AudioPort> allPorts;
+        ASSERT_IS_OK(module->getAudioPorts(&allPorts));
+        for (const auto& r : routes) {
+            if (r.sinkPortId == portConnected.getId()) {
+                for (const auto& srcPortId : r.sourcePortIds) {
+                    const auto srcPortIt = findById(allPorts, srcPortId);
+                    ASSERT_NE(allPorts.end(), srcPortIt) << "port ID " << srcPortId;
+                    EXPECT_NE(0UL, srcPortIt->profiles.size())
+                            << " source port " << srcPortIt->toString() << " must have its profiles"
+                            << " populated following external device connection";
+                }
+            } else {
+                const auto sinkPortIt = findById(allPorts, r.sinkPortId);
+                ASSERT_NE(allPorts.end(), sinkPortIt) << "port ID " << r.sinkPortId;
+                EXPECT_NE(0UL, sinkPortIt->profiles.size())
+                        << " source port " << sinkPortIt->toString() << " must have its"
+                        << " profiles populated following external device connection";
+            }
+        }
+    }
+}
+
+TEST_P(AudioCoreModule, MasterMute) {
+    bool isSupported = false;
+    EXPECT_NO_FATAL_FAILURE(TestAccessors<bool>(module.get(), &IModule::getMasterMute,
+                                                &IModule::setMasterMute, {false, true}, {},
+                                                &isSupported));
+    if (!isSupported) {
+        GTEST_SKIP() << "Master mute is not supported";
+    }
+    // TODO: Test that master mute actually mutes output.
+}
+
+TEST_P(AudioCoreModule, MasterVolume) {
+    bool isSupported = false;
+    EXPECT_NO_FATAL_FAILURE(TestAccessors<float>(
+            module.get(), &IModule::getMasterVolume, &IModule::setMasterVolume, {0.0f, 0.5f, 1.0f},
+            {-0.1, 1.1, NAN, INFINITY, -INFINITY, 1 + std::numeric_limits<float>::epsilon()},
+            &isSupported));
+    if (!isSupported) {
+        GTEST_SKIP() << "Master volume is not supported";
+    }
+    // TODO: Test that master volume actually attenuates output.
+}
+
+TEST_P(AudioCoreModule, MicMute) {
+    bool isSupported = false;
+    EXPECT_NO_FATAL_FAILURE(TestAccessors<bool>(module.get(), &IModule::getMicMute,
+                                                &IModule::setMicMute, {false, true}, {},
+                                                &isSupported));
+    if (!isSupported) {
+        GTEST_SKIP() << "Mic mute is not supported";
+    }
+    // TODO: Test that mic mute actually mutes input.
+}
+
+TEST_P(AudioCoreModule, GetMicrophones) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    const std::vector<AudioPort> builtInMicPorts = moduleConfig->getAttachedMicrophonePorts();
+    std::vector<MicrophoneInfo> micInfos;
+    ScopedAStatus status = module->getMicrophones(&micInfos);
+    if (!status.isOk()) {
+        EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
+        ASSERT_FALSE(builtInMicPorts.empty())
+                << "When the HAL module does not have built-in microphones, IModule.getMicrophones"
+                << " must complete with no error and return an empty list";
+        GTEST_SKIP() << "Microphone info is not supported";
+    }
+    std::set<int32_t> micPortIdsWithInfo;
+    for (const auto& micInfo : micInfos) {
+        const auto& micDevice = micInfo.device;
+        const auto it =
+                std::find_if(builtInMicPorts.begin(), builtInMicPorts.end(), [&](const auto& port) {
+                    return port.ext.template get<AudioPortExt::Tag::device>().device == micDevice;
+                });
+        if (it != builtInMicPorts.end()) {
+            micPortIdsWithInfo.insert(it->id);
+        } else {
+            ADD_FAILURE() << "No device port found with a device specified for the microphone \""
+                          << micInfo.id << "\": " << micDevice.toString();
+        }
+    }
+    if (micPortIdsWithInfo.size() != builtInMicPorts.size()) {
+        std::vector<AudioPort> micPortsNoInfo;
+        std::copy_if(builtInMicPorts.begin(), builtInMicPorts.end(),
+                     std::back_inserter(micPortsNoInfo),
+                     [&](const auto& port) { return micPortIdsWithInfo.count(port.id) == 0; });
+        ADD_FAILURE() << "No MicrophoneInfo is provided for the following microphone device ports: "
+                      << ::android::internal::ToString(micPortsNoInfo);
+    }
+}
+
+TEST_P(AudioCoreModule, UpdateAudioMode) {
+    for (const auto mode : ::ndk::enum_range<AudioMode>()) {
+        if (isValidAudioMode(mode)) {
+            EXPECT_IS_OK(module->updateAudioMode(mode)) << toString(mode);
+        } else {
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->updateAudioMode(mode)) << toString(mode);
+        }
+    }
+    EXPECT_IS_OK(module->updateAudioMode(AudioMode::NORMAL));
+}
+
+TEST_P(AudioCoreModule, UpdateScreenRotation) {
+    for (const auto rotation : ::ndk::enum_range<IModule::ScreenRotation>()) {
+        EXPECT_IS_OK(module->updateScreenRotation(rotation)) << toString(rotation);
+    }
+    EXPECT_IS_OK(module->updateScreenRotation(IModule::ScreenRotation::DEG_0));
+}
+
+TEST_P(AudioCoreModule, UpdateScreenState) {
+    EXPECT_IS_OK(module->updateScreenState(false));
+    EXPECT_IS_OK(module->updateScreenState(true));
+}
+
+TEST_P(AudioCoreModule, GenerateHwAvSyncId) {
+    const auto kStatuses = {EX_NONE, EX_ILLEGAL_STATE};
+    int32_t id1;
+    ndk::ScopedAStatus status = module->generateHwAvSyncId(&id1);
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "HW AV Sync is not supported";
+    }
+    EXPECT_STATUS(kStatuses, status);
+    if (status.isOk()) {
+        int32_t id2;
+        ASSERT_IS_OK(module->generateHwAvSyncId(&id2));
+        EXPECT_NE(id1, id2) << "HW AV Sync IDs must be unique";
+    }
+}
+
+TEST_P(AudioCoreModule, GetVendorParameters) {
+    bool isGetterSupported = false;
+    EXPECT_NO_FATAL_FAILURE(TestGetVendorParameters(module.get(), &isGetterSupported));
+    ndk::ScopedAStatus status = module->setVendorParameters({}, false);
+    EXPECT_EQ(isGetterSupported, status.getExceptionCode() != EX_UNSUPPORTED_OPERATION)
+            << "Support for getting and setting of vendor parameters must be consistent";
+    if (!isGetterSupported) {
+        GTEST_SKIP() << "Vendor parameters are not supported";
+    }
+}
+
+TEST_P(AudioCoreModule, SetVendorParameters) {
+    bool isSupported = false;
+    EXPECT_NO_FATAL_FAILURE(TestSetVendorParameters(module.get(), &isSupported));
+    if (!isSupported) {
+        GTEST_SKIP() << "Vendor parameters are not supported";
+    }
+}
+
+// See b/262930731. In the absence of offloaded effect implementations,
+// currently we can only pass a nullptr, and the HAL module must either reject
+// it as an invalid argument, or say that offloaded effects are not supported.
+TEST_P(AudioCoreModule, AddRemoveEffectInvalidArguments) {
+    ndk::ScopedAStatus addEffectStatus = module->addDeviceEffect(-1, nullptr);
+    ndk::ScopedAStatus removeEffectStatus = module->removeDeviceEffect(-1, nullptr);
+    if (addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT, addEffectStatus.getExceptionCode());
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT, removeEffectStatus.getExceptionCode());
+    } else if (removeEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
+        GTEST_FAIL() << "addDeviceEffect and removeDeviceEffect must be either supported or "
+                     << "not supported together";
+    } else {
+        GTEST_SKIP() << "Offloaded effects not supported";
+    }
+    // Test rejection of a nullptr effect with a valid device port Id.
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    const auto configs = moduleConfig->getPortConfigsForAttachedDevicePorts();
+    for (const auto& config : configs) {
+        WithAudioPortConfig portConfig(config);
+        ASSERT_NO_FATAL_FAILURE(portConfig.SetUp(module.get()));
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->addDeviceEffect(portConfig.getId(), nullptr));
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->removeDeviceEffect(portConfig.getId(), nullptr));
+    }
+}
+
+TEST_P(AudioCoreModule, GetMmapPolicyInfos) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    const bool isMmapSupported = moduleConfig->isMmapSupported();
+    for (const auto mmapPolicyType :
+         {AudioMMapPolicyType::DEFAULT, AudioMMapPolicyType::EXCLUSIVE}) {
+        std::vector<AudioMMapPolicyInfo> policyInfos;
+        EXPECT_IS_OK(module->getMmapPolicyInfos(mmapPolicyType, &policyInfos))
+                << toString(mmapPolicyType);
+        EXPECT_EQ(isMmapSupported, !policyInfos.empty());
+    }
+}
+
+TEST_P(AudioCoreModule, BluetoothVariableLatency) {
+    bool isSupported = false;
+    EXPECT_IS_OK(module->supportsVariableLatency(&isSupported));
+    LOG(INFO) << "supportsVariableLatency: " << isSupported;
+}
+
+TEST_P(AudioCoreModule, GetAAudioMixerBurstCount) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    const bool isMmapSupported = moduleConfig->isMmapSupported();
+    int32_t mixerBursts = 0;
+    ndk::ScopedAStatus status = module->getAAudioMixerBurstCount(&mixerBursts);
+    EXPECT_EQ(isMmapSupported, status.getExceptionCode() != EX_UNSUPPORTED_OPERATION)
+            << "Support for AAudio MMAP and getting AAudio mixer burst count must be consistent";
+    if (!isMmapSupported) {
+        GTEST_SKIP() << "AAudio MMAP is not supported";
+    }
+    EXPECT_GE(mixerBursts, 0);
+}
+
+TEST_P(AudioCoreModule, GetAAudioHardwareBurstMinUsec) {
+    ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    const bool isMmapSupported = moduleConfig->isMmapSupported();
+    int32_t aaudioHardwareBurstMinUsec = 0;
+    ndk::ScopedAStatus status = module->getAAudioHardwareBurstMinUsec(&aaudioHardwareBurstMinUsec);
+    EXPECT_EQ(isMmapSupported, status.getExceptionCode() != EX_UNSUPPORTED_OPERATION)
+            << "Support for AAudio MMAP and getting AAudio hardware burst minimum usec "
+            << "must be consistent";
+    if (!isMmapSupported) {
+        GTEST_SKIP() << "AAudio MMAP is not supported";
+    }
+    EXPECT_GE(aaudioHardwareBurstMinUsec, 0);
+}
+
+class AudioCoreBluetooth : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+        ASSERT_IS_OK(module->getBluetooth(&bluetooth));
+    }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+    std::shared_ptr<IBluetooth> bluetooth;
+};
+
+TEST_P(AudioCoreBluetooth, SameInstance) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "Bluetooth is not supported";
+    }
+    std::shared_ptr<IBluetooth> bluetooth2;
+    EXPECT_IS_OK(module->getBluetooth(&bluetooth2));
+    ASSERT_NE(nullptr, bluetooth2.get());
+    EXPECT_EQ(bluetooth->asBinder(), bluetooth2->asBinder())
+            << "getBluetooth must return the same interface instance across invocations";
+}
+
+TEST_P(AudioCoreBluetooth, ScoConfig) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "Bluetooth is not supported";
+    }
+    ndk::ScopedAStatus status;
+    IBluetooth::ScoConfig scoConfig;
+    ASSERT_STATUS(kStatuses, status = bluetooth->setScoConfig({}, &scoConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "BT SCO is not supported";
+    }
+    EXPECT_TRUE(scoConfig.isEnabled.has_value());
+    EXPECT_TRUE(scoConfig.isNrecEnabled.has_value());
+    EXPECT_NE(IBluetooth::ScoConfig::Mode::UNSPECIFIED, scoConfig.mode);
+    IBluetooth::ScoConfig scoConfig2;
+    ASSERT_IS_OK(bluetooth->setScoConfig(scoConfig, &scoConfig2));
+    EXPECT_EQ(scoConfig, scoConfig2);
+}
+
+TEST_P(AudioCoreBluetooth, HfpConfig) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "Bluetooth is not supported";
+    }
+    ndk::ScopedAStatus status;
+    IBluetooth::HfpConfig hfpConfig;
+    ASSERT_STATUS(kStatuses, status = bluetooth->setHfpConfig({}, &hfpConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "BT HFP is not supported";
+    }
+    EXPECT_TRUE(hfpConfig.isEnabled.has_value());
+    EXPECT_TRUE(hfpConfig.sampleRate.has_value());
+    EXPECT_TRUE(hfpConfig.volume.has_value());
+    IBluetooth::HfpConfig hfpConfig2;
+    ASSERT_IS_OK(bluetooth->setHfpConfig(hfpConfig, &hfpConfig2));
+    EXPECT_EQ(hfpConfig, hfpConfig2);
+}
+
+TEST_P(AudioCoreBluetooth, HfpConfigInvalid) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "Bluetooth is not supported";
+    }
+    ndk::ScopedAStatus status;
+    IBluetooth::HfpConfig hfpConfig;
+    ASSERT_STATUS(kStatuses, status = bluetooth->setHfpConfig({}, &hfpConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "BT HFP is not supported";
+    }
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  bluetooth->setHfpConfig({.sampleRate = Int{-1}}, &hfpConfig));
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, bluetooth->setHfpConfig({.sampleRate = Int{0}}, &hfpConfig));
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  bluetooth->setHfpConfig({.volume = Float{IBluetooth::HfpConfig::VOLUME_MIN - 1}},
+                                          &hfpConfig));
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  bluetooth->setHfpConfig({.volume = Float{IBluetooth::HfpConfig::VOLUME_MAX + 1}},
+                                          &hfpConfig));
+}
+
+class AudioCoreBluetoothA2dp : public AudioCoreModuleBase,
+                               public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+        ASSERT_IS_OK(module->getBluetoothA2dp(&bluetooth));
+    }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+    std::shared_ptr<IBluetoothA2dp> bluetooth;
+};
+
+TEST_P(AudioCoreBluetoothA2dp, SameInstance) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothA2dp is not supported";
+    }
+    std::shared_ptr<IBluetoothA2dp> bluetooth2;
+    EXPECT_IS_OK(module->getBluetoothA2dp(&bluetooth2));
+    ASSERT_NE(nullptr, bluetooth2.get());
+    EXPECT_EQ(bluetooth->asBinder(), bluetooth2->asBinder())
+            << "getBluetoothA2dp must return the same interface instance across invocations";
+}
+
+TEST_P(AudioCoreBluetoothA2dp, Enabled) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothA2dp is not supported";
+    }
+    // Since enabling A2DP may require having an actual device connection,
+    // limit testing to setting back the current value.
+    bool enabled;
+    ASSERT_IS_OK(bluetooth->isEnabled(&enabled));
+    EXPECT_IS_OK(bluetooth->setEnabled(enabled))
+            << "setEnabled without actual state change must not fail";
+}
+
+TEST_P(AudioCoreBluetoothA2dp, OffloadReconfiguration) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothA2dp is not supported";
+    }
+    bool isSupported;
+    ASSERT_IS_OK(bluetooth->supportsOffloadReconfiguration(&isSupported));
+    bool isSupported2;
+    ASSERT_IS_OK(bluetooth->supportsOffloadReconfiguration(&isSupported2));
+    EXPECT_EQ(isSupported, isSupported2);
+    if (isSupported) {
+        static const auto kStatuses = {EX_NONE, EX_ILLEGAL_STATE};
+        EXPECT_STATUS(kStatuses, bluetooth->reconfigureOffload({}));
+    } else {
+        EXPECT_STATUS(EX_UNSUPPORTED_OPERATION, bluetooth->reconfigureOffload({}));
+    }
+}
+
+class AudioCoreBluetoothLe : public AudioCoreModuleBase,
+                             public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+        ASSERT_IS_OK(module->getBluetoothLe(&bluetooth));
+    }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+    std::shared_ptr<IBluetoothLe> bluetooth;
+};
+
+TEST_P(AudioCoreBluetoothLe, SameInstance) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothLe is not supported";
+    }
+    std::shared_ptr<IBluetoothLe> bluetooth2;
+    EXPECT_IS_OK(module->getBluetoothLe(&bluetooth2));
+    ASSERT_NE(nullptr, bluetooth2.get());
+    EXPECT_EQ(bluetooth->asBinder(), bluetooth2->asBinder())
+            << "getBluetoothLe must return the same interface instance across invocations";
+}
+
+TEST_P(AudioCoreBluetoothLe, Enabled) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothLe is not supported";
+    }
+    // Since enabling LE may require having an actual device connection,
+    // limit testing to setting back the current value.
+    bool enabled;
+    ASSERT_IS_OK(bluetooth->isEnabled(&enabled));
+    EXPECT_IS_OK(bluetooth->setEnabled(enabled))
+            << "setEnabled without actual state change must not fail";
+}
+
+TEST_P(AudioCoreBluetoothLe, OffloadReconfiguration) {
+    if (bluetooth == nullptr) {
+        GTEST_SKIP() << "BluetoothLe is not supported";
+    }
+    bool isSupported;
+    ASSERT_IS_OK(bluetooth->supportsOffloadReconfiguration(&isSupported));
+    bool isSupported2;
+    ASSERT_IS_OK(bluetooth->supportsOffloadReconfiguration(&isSupported2));
+    EXPECT_EQ(isSupported, isSupported2);
+    if (isSupported) {
+        static const auto kStatuses = {EX_NONE, EX_ILLEGAL_STATE};
+        EXPECT_STATUS(kStatuses, bluetooth->reconfigureOffload({}));
+    } else {
+        EXPECT_STATUS(EX_UNSUPPORTED_OPERATION, bluetooth->reconfigureOffload({}));
+    }
+}
+
+class AudioCoreTelephony : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+        ASSERT_IS_OK(module->getTelephony(&telephony));
+    }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+    std::shared_ptr<ITelephony> telephony;
+};
+
+TEST_P(AudioCoreTelephony, SameInstance) {
+    if (telephony == nullptr) {
+        GTEST_SKIP() << "Telephony is not supported";
+    }
+    std::shared_ptr<ITelephony> telephony2;
+    EXPECT_IS_OK(module->getTelephony(&telephony2));
+    ASSERT_NE(nullptr, telephony2.get());
+    EXPECT_EQ(telephony->asBinder(), telephony2->asBinder())
+            << "getTelephony must return the same interface instance across invocations";
+}
+
+TEST_P(AudioCoreTelephony, GetSupportedAudioModes) {
+    if (telephony == nullptr) {
+        GTEST_SKIP() << "Telephony is not supported";
+    }
+    std::vector<AudioMode> modes1;
+    ASSERT_IS_OK(telephony->getSupportedAudioModes(&modes1));
+    for (const auto mode : modes1) {
+        EXPECT_TRUE(isValidAudioMode(mode)) << toString(mode);
+    }
+    const std::vector<AudioMode> kMandatoryModes = {AudioMode::NORMAL, AudioMode::RINGTONE,
+                                                    AudioMode::IN_CALL,
+                                                    AudioMode::IN_COMMUNICATION};
+    for (const auto mode : kMandatoryModes) {
+        EXPECT_NE(modes1.end(), std::find(modes1.begin(), modes1.end(), mode))
+                << "Mandatory mode not supported: " << toString(mode);
+    }
+    std::vector<AudioMode> modes2;
+    ASSERT_IS_OK(telephony->getSupportedAudioModes(&modes2));
+    ASSERT_EQ(modes1.size(), modes2.size())
+            << "Sizes of audio mode arrays do not match across consequent calls to "
+            << "getSupportedAudioModes";
+    std::sort(modes1.begin(), modes1.end());
+    std::sort(modes2.begin(), modes2.end());
+    EXPECT_EQ(modes1, modes2);
+};
+
+TEST_P(AudioCoreTelephony, SwitchAudioMode) {
+    if (telephony == nullptr) {
+        GTEST_SKIP() << "Telephony is not supported";
+    }
+    std::vector<AudioMode> supportedModes;
+    ASSERT_IS_OK(telephony->getSupportedAudioModes(&supportedModes));
+    std::set<AudioMode> unsupportedModes = {
+            // Start with all, remove supported ones
+            ::ndk::enum_range<AudioMode>().begin(), ::ndk::enum_range<AudioMode>().end()};
+    for (const auto mode : supportedModes) {
+        EXPECT_IS_OK(telephony->switchAudioMode(mode)) << toString(mode);
+        unsupportedModes.erase(mode);
+    }
+    for (const auto mode : unsupportedModes) {
+        EXPECT_STATUS(isValidAudioMode(mode) ? EX_UNSUPPORTED_OPERATION : EX_ILLEGAL_ARGUMENT,
+                      telephony->switchAudioMode(mode))
+                << toString(mode);
+    }
+}
+
+TEST_P(AudioCoreTelephony, TelecomConfig) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (telephony == nullptr) {
+        GTEST_SKIP() << "Telephony is not supported";
+    }
+    ndk::ScopedAStatus status;
+    ITelephony::TelecomConfig telecomConfig;
+    ASSERT_STATUS(kStatuses, status = telephony->setTelecomConfig({}, &telecomConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "Telecom is not supported";
+    }
+    EXPECT_TRUE(telecomConfig.voiceVolume.has_value());
+    EXPECT_NE(ITelephony::TelecomConfig::TtyMode::UNSPECIFIED, telecomConfig.ttyMode);
+    EXPECT_TRUE(telecomConfig.isHacEnabled.has_value());
+    ITelephony::TelecomConfig telecomConfig2;
+    ASSERT_IS_OK(telephony->setTelecomConfig(telecomConfig, &telecomConfig2));
+    EXPECT_EQ(telecomConfig, telecomConfig2);
+}
+
+TEST_P(AudioCoreTelephony, TelecomConfigInvalid) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    if (telephony == nullptr) {
+        GTEST_SKIP() << "Telephony is not supported";
+    }
+    ndk::ScopedAStatus status;
+    ITelephony::TelecomConfig telecomConfig;
+    ASSERT_STATUS(kStatuses, status = telephony->setTelecomConfig({}, &telecomConfig));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "Telecom is not supported";
+    }
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  telephony->setTelecomConfig(
+                          {.voiceVolume = Float{ITelephony::TelecomConfig::VOICE_VOLUME_MIN - 1}},
+                          &telecomConfig));
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                  telephony->setTelecomConfig(
+                          {.voiceVolume = Float{ITelephony::TelecomConfig::VOICE_VOLUME_MAX + 1}},
+                          &telecomConfig));
+}
+
+using CommandSequence = std::vector<StreamDescriptor::Command>;
+class StreamLogicDriverInvalidCommand : public StreamLogicDriver {
+  public:
+    StreamLogicDriverInvalidCommand(const CommandSequence& commands) : mCommands(commands) {}
+
+    std::string getUnexpectedStatuses() {
+        // This method is intended to be called after the worker thread has joined,
+        // thus no extra synchronization is needed.
+        std::string s;
+        if (!mStatuses.empty()) {
+            s = std::string("Pairs of (command, actual status): ")
+                        .append((android::internal::ToString(mStatuses)));
+        }
+        return s;
+    }
+
+    bool done() override { return mNextCommand >= mCommands.size(); }
+    TransitionTrigger getNextTrigger(int, int* actualSize) override {
+        if (actualSize != nullptr) *actualSize = 0;
+        return mCommands[mNextCommand++];
+    }
+    bool interceptRawReply(const StreamDescriptor::Reply& reply) override {
+        const size_t currentCommand = mNextCommand - 1;  // increased by getNextTrigger
+        const bool isLastCommand = currentCommand == mCommands.size() - 1;
+        // All but the last command should run correctly. The last command must return 'BAD_VALUE'
+        // status.
+        if ((!isLastCommand && reply.status != STATUS_OK) ||
+            (isLastCommand && reply.status != STATUS_BAD_VALUE)) {
+            std::string s = mCommands[currentCommand].toString();
+            s.append(", ").append(statusToString(reply.status));
+            mStatuses.push_back(std::move(s));
+            // Process the reply, since the worker exits in case of an error.
+            return false;
+        }
+        return isLastCommand;
+    }
+    bool processValidReply(const StreamDescriptor::Reply&) override { return true; }
+
+  private:
+    const CommandSequence mCommands;
+    size_t mNextCommand = 0;
+    std::vector<std::string> mStatuses;
+};
+
+template <typename Stream>
+class AudioStream : public AudioCoreModule {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(AudioCoreModule::SetUp());
+        ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    }
+
+    void GetStreamCommon() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        WithStream<Stream> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        std::shared_ptr<IStreamCommon> streamCommon1;
+        EXPECT_IS_OK(stream.get()->getStreamCommon(&streamCommon1));
+        std::shared_ptr<IStreamCommon> streamCommon2;
+        EXPECT_IS_OK(stream.get()->getStreamCommon(&streamCommon2));
+        ASSERT_NE(nullptr, streamCommon1);
+        ASSERT_NE(nullptr, streamCommon2);
+        EXPECT_EQ(streamCommon1->asBinder(), streamCommon2->asBinder())
+                << "getStreamCommon must return the same interface instance across invocations";
+    }
+
+    void CloseTwice() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        std::shared_ptr<Stream> heldStream;
+        {
+            WithStream<Stream> stream(portConfig.value());
+            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+            heldStream = stream.getSharedPointer();
+        }
+        EXPECT_STATUS(EX_ILLEGAL_STATE, WithStream<Stream>::callClose(heldStream))
+                << "when closing the stream twice";
+    }
+
+    void PrepareToCloseTwice() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        std::shared_ptr<IStreamCommon> heldStreamCommon;
+        {
+            WithStream<Stream> stream(portConfig.value());
+            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+            std::shared_ptr<IStreamCommon> streamCommon;
+            ASSERT_IS_OK(stream.get()->getStreamCommon(&streamCommon));
+            heldStreamCommon = streamCommon;
+            EXPECT_IS_OK(streamCommon->prepareToClose());
+            EXPECT_IS_OK(streamCommon->prepareToClose())
+                    << "when calling prepareToClose second time";
+        }
+        EXPECT_STATUS(EX_ILLEGAL_STATE, heldStreamCommon->prepareToClose())
+                << "when calling prepareToClose on a closed stream";
+    }
+
+    void OpenAllConfigs() {
+        const auto allPortConfigs =
+                moduleConfig->getPortConfigsForMixPorts(IOTraits<Stream>::is_input);
+        for (const auto& portConfig : allPortConfigs) {
+            WithStream<Stream> stream(portConfig);
+            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        }
+    }
+
+    void OpenInvalidBufferSize() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        WithStream<Stream> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUpPortConfig(module.get()));
+        for (long bufferSize : std::array<long, 3>{-1, 0, std::numeric_limits<long>::max()}) {
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, stream.SetUpNoChecks(module.get(), bufferSize))
+                    << "for the buffer size " << bufferSize;
+            EXPECT_EQ(nullptr, stream.get());
+        }
+    }
+
+    void OpenInvalidDirection() {
+        // Important! The direction of the port config must be reversed.
+        const auto portConfig =
+                moduleConfig->getSingleConfigForMixPort(!IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        WithStream<Stream> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUpPortConfig(module.get()));
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                      stream.SetUpNoChecks(module.get(), kDefaultBufferSizeFrames))
+                << "port config ID " << stream.getPortId();
+        EXPECT_EQ(nullptr, stream.get());
+    }
+
+    void OpenOverMaxCount() {
+        constexpr bool isInput = IOTraits<Stream>::is_input;
+        auto ports = moduleConfig->getMixPorts(isInput, true /*attachedOnly*/);
+        bool hasSingleRun = false;
+        for (const auto& port : ports) {
+            const size_t maxStreamCount = port.ext.get<AudioPortExt::Tag::mix>().maxOpenStreamCount;
+            if (maxStreamCount == 0) {
+                continue;
+            }
+            auto portConfigs = moduleConfig->getPortConfigsForMixPorts(isInput, port);
+            if (portConfigs.size() < maxStreamCount + 1) {
+                // Not able to open a sufficient number of streams for this port.
+                continue;
+            }
+            hasSingleRun = true;
+            std::optional<WithStream<Stream>> streamWraps[maxStreamCount + 1];
+            for (size_t i = 0; i <= maxStreamCount; ++i) {
+                streamWraps[i].emplace(portConfigs[i]);
+                WithStream<Stream>& stream = streamWraps[i].value();
+                if (i < maxStreamCount) {
+                    ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+                } else {
+                    ASSERT_NO_FATAL_FAILURE(stream.SetUpPortConfig(module.get()));
+                    EXPECT_STATUS(EX_ILLEGAL_STATE,
+                                  stream.SetUpNoChecks(module.get(), kDefaultBufferSizeFrames))
+                            << "port config ID " << stream.getPortId() << ", maxOpenStreamCount is "
+                            << maxStreamCount;
+                }
+            }
+        }
+        if (!hasSingleRun) {
+            GTEST_SKIP() << "Not enough ports to test max open stream count";
+        }
+    }
+
+    void OpenTwiceSamePortConfig() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        EXPECT_NO_FATAL_FAILURE(OpenTwiceSamePortConfigImpl(portConfig.value()));
+    }
+
+    void ResetPortConfigWithOpenStream() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        WithStream<Stream> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        EXPECT_STATUS(EX_ILLEGAL_STATE, module->resetAudioPortConfig(stream.getPortId()))
+                << "port config ID " << stream.getPortId();
+    }
+
+    void SendInvalidCommand() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        EXPECT_NO_FATAL_FAILURE(SendInvalidCommandImpl(portConfig.value()));
+    }
+
+    void UpdateHwAvSyncId() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        WithStream<Stream> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        std::shared_ptr<IStreamCommon> streamCommon;
+        ASSERT_IS_OK(stream.get()->getStreamCommon(&streamCommon));
+        ASSERT_NE(nullptr, streamCommon);
+        const auto kStatuses = {EX_NONE, EX_ILLEGAL_ARGUMENT, EX_ILLEGAL_STATE};
+        for (const auto id : {-100, -1, 0, 1, 100}) {
+            ndk::ScopedAStatus status = streamCommon->updateHwAvSyncId(id);
+            if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+                GTEST_SKIP() << "HW AV Sync is not supported";
+            }
+            EXPECT_STATUS(kStatuses, status) << "id: " << id;
+        }
+    }
+
+    void GetVendorParameters() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        WithStream<Stream> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        std::shared_ptr<IStreamCommon> streamCommon;
+        ASSERT_IS_OK(stream.get()->getStreamCommon(&streamCommon));
+        ASSERT_NE(nullptr, streamCommon);
+
+        bool isGetterSupported = false;
+        EXPECT_NO_FATAL_FAILURE(TestGetVendorParameters(module.get(), &isGetterSupported));
+        ndk::ScopedAStatus status = module->setVendorParameters({}, false);
+        EXPECT_EQ(isGetterSupported, status.getExceptionCode() != EX_UNSUPPORTED_OPERATION)
+                << "Support for getting and setting of vendor parameters must be consistent";
+        if (!isGetterSupported) {
+            GTEST_SKIP() << "Vendor parameters are not supported";
+        }
+    }
+
+    void SetVendorParameters() {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits<Stream>::is_input);
+        if (!portConfig.has_value()) {
+            GTEST_SKIP() << "No mix port for attached devices";
+        }
+        WithStream<Stream> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        std::shared_ptr<IStreamCommon> streamCommon;
+        ASSERT_IS_OK(stream.get()->getStreamCommon(&streamCommon));
+        ASSERT_NE(nullptr, streamCommon);
+
+        bool isSupported = false;
+        EXPECT_NO_FATAL_FAILURE(TestSetVendorParameters(module.get(), &isSupported));
+        if (!isSupported) {
+            GTEST_SKIP() << "Vendor parameters are not supported";
+        }
+    }
+
+    void HwGainHwVolume() {
+        const auto ports =
+                moduleConfig->getMixPorts(IOTraits<Stream>::is_input, true /*attachedOnly*/);
+        if (ports.empty()) {
+            GTEST_SKIP() << "No mix ports";
+        }
+        bool atLeastOneSupports = false;
+        for (const auto& port : ports) {
+            const auto portConfig = moduleConfig->getSingleConfigForMixPort(true, port);
+            if (!portConfig.has_value()) continue;
+            WithStream<Stream> stream(portConfig.value());
+            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+            std::vector<std::vector<float>> validValues, invalidValues;
+            bool isSupported = false;
+            if constexpr (IOTraits<Stream>::is_input) {
+                GenerateTestArrays<float>(getChannelCount(portConfig.value().channelMask.value()),
+                                          IStreamIn::HW_GAIN_MIN, IStreamIn::HW_GAIN_MAX,
+                                          &validValues, &invalidValues);
+                EXPECT_NO_FATAL_FAILURE(TestAccessors<std::vector<float>>(
+                        stream.get(), &IStreamIn::getHwGain, &IStreamIn::setHwGain, validValues,
+                        invalidValues, &isSupported));
+            } else {
+                GenerateTestArrays<float>(getChannelCount(portConfig.value().channelMask.value()),
+                                          IStreamOut::HW_VOLUME_MIN, IStreamOut::HW_VOLUME_MAX,
+                                          &validValues, &invalidValues);
+                EXPECT_NO_FATAL_FAILURE(TestAccessors<std::vector<float>>(
+                        stream.get(), &IStreamOut::getHwVolume, &IStreamOut::setHwVolume,
+                        validValues, invalidValues, &isSupported));
+            }
+            if (isSupported) atLeastOneSupports = true;
+        }
+        if (!atLeastOneSupports) {
+            GTEST_SKIP() << "Hardware gain / volume is not supported";
+        }
+    }
+
+    // See b/262930731. In the absence of offloaded effect implementations,
+    // currently we can only pass a nullptr, and the HAL module must either reject
+    // it as an invalid argument, or say that offloaded effects are not supported.
+    void AddRemoveEffectInvalidArguments() {
+        const auto ports =
+                moduleConfig->getMixPorts(IOTraits<Stream>::is_input, true /*attachedOnly*/);
+        if (ports.empty()) {
+            GTEST_SKIP() << "No mix ports";
+        }
+        bool atLeastOneSupports = false;
+        for (const auto& port : ports) {
+            const auto portConfig = moduleConfig->getSingleConfigForMixPort(true, port);
+            if (!portConfig.has_value()) continue;
+            WithStream<Stream> stream(portConfig.value());
+            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+            std::shared_ptr<IStreamCommon> streamCommon;
+            ASSERT_IS_OK(stream.get()->getStreamCommon(&streamCommon));
+            ASSERT_NE(nullptr, streamCommon);
+            ndk::ScopedAStatus addEffectStatus = streamCommon->addEffect(nullptr);
+            ndk::ScopedAStatus removeEffectStatus = streamCommon->removeEffect(nullptr);
+            if (addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
+                EXPECT_EQ(EX_ILLEGAL_ARGUMENT, addEffectStatus.getExceptionCode());
+                EXPECT_EQ(EX_ILLEGAL_ARGUMENT, removeEffectStatus.getExceptionCode());
+                atLeastOneSupports = true;
+            } else if (removeEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
+                ADD_FAILURE() << "addEffect and removeEffect must be either supported or "
+                              << "not supported together";
+                atLeastOneSupports = true;
+            }
+        }
+        if (!atLeastOneSupports) {
+            GTEST_SKIP() << "Offloaded effects not supported";
+        }
+    }
+
+    void OpenTwiceSamePortConfigImpl(const AudioPortConfig& portConfig) {
+        WithStream<Stream> stream1(portConfig);
+        ASSERT_NO_FATAL_FAILURE(stream1.SetUp(module.get(), kDefaultBufferSizeFrames));
+        WithStream<Stream> stream2;
+        EXPECT_STATUS(EX_ILLEGAL_STATE, stream2.SetUpNoChecks(module.get(), stream1.getPortConfig(),
+                                                              kDefaultBufferSizeFrames))
+                << "when opening a stream twice for the same port config ID "
+                << stream1.getPortId();
+    }
+
+    void SendInvalidCommandImpl(const AudioPortConfig& portConfig) {
+        using TestSequence = std::pair<std::string, CommandSequence>;
+        // The last command in 'CommandSequence' is the one that must trigger
+        // an error status. All preceding commands are to put the state machine
+        // into a state which accepts the last command.
+        std::vector<TestSequence> sequences{
+                std::make_pair(std::string("HalReservedExit"),
+                               std::vector{StreamDescriptor::Command::make<
+                                       StreamDescriptor::Command::Tag::halReservedExit>(0)}),
+                std::make_pair(std::string("BurstNeg"),
+                               std::vector{kStartCommand,
+                                           StreamDescriptor::Command::make<
+                                                   StreamDescriptor::Command::Tag::burst>(-1)}),
+                std::make_pair(
+                        std::string("BurstMinInt"),
+                        std::vector{kStartCommand, StreamDescriptor::Command::make<
+                                                           StreamDescriptor::Command::Tag::burst>(
+                                                           std::numeric_limits<int32_t>::min())})};
+        if (IOTraits<Stream>::is_input) {
+            sequences.emplace_back("DrainAll",
+                                   std::vector{kStartCommand, kBurstCommand, kDrainOutAllCommand});
+            sequences.emplace_back(
+                    "DrainEarly", std::vector{kStartCommand, kBurstCommand, kDrainOutEarlyCommand});
+        } else {
+            sequences.emplace_back("DrainUnspecified",
+                                   std::vector{kStartCommand, kBurstCommand, kDrainInCommand});
+        }
+        for (const auto& seq : sequences) {
+            SCOPED_TRACE(std::string("Sequence ").append(seq.first));
+            LOG(DEBUG) << __func__ << ": Sequence " << seq.first;
+            WithStream<Stream> stream(portConfig);
+            ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+            StreamLogicDriverInvalidCommand driver(seq.second);
+            typename IOTraits<Stream>::Worker worker(*stream.getContext(), &driver,
+                                                     stream.getEventReceiver());
+            LOG(DEBUG) << __func__ << ": starting worker...";
+            ASSERT_TRUE(worker.start());
+            LOG(DEBUG) << __func__ << ": joining worker...";
+            worker.join();
+            EXPECT_EQ("", driver.getUnexpectedStatuses());
+        }
+    }
+};
+using AudioStreamIn = AudioStream<IStreamIn>;
+using AudioStreamOut = AudioStream<IStreamOut>;
+
+#define TEST_IN_AND_OUT_STREAM(method_name)     \
+    TEST_P(AudioStreamIn, method_name) {        \
+        ASSERT_NO_FATAL_FAILURE(method_name()); \
+    }                                           \
+    TEST_P(AudioStreamOut, method_name) {       \
+        ASSERT_NO_FATAL_FAILURE(method_name()); \
+    }
+
+TEST_IN_AND_OUT_STREAM(CloseTwice);
+TEST_IN_AND_OUT_STREAM(PrepareToCloseTwice);
+TEST_IN_AND_OUT_STREAM(GetStreamCommon);
+TEST_IN_AND_OUT_STREAM(OpenAllConfigs);
+TEST_IN_AND_OUT_STREAM(OpenInvalidBufferSize);
+TEST_IN_AND_OUT_STREAM(OpenInvalidDirection);
+TEST_IN_AND_OUT_STREAM(OpenOverMaxCount);
+TEST_IN_AND_OUT_STREAM(OpenTwiceSamePortConfig);
+TEST_IN_AND_OUT_STREAM(ResetPortConfigWithOpenStream);
+TEST_IN_AND_OUT_STREAM(SendInvalidCommand);
+TEST_IN_AND_OUT_STREAM(UpdateHwAvSyncId);
+TEST_IN_AND_OUT_STREAM(GetVendorParameters);
+TEST_IN_AND_OUT_STREAM(SetVendorParameters);
+TEST_IN_AND_OUT_STREAM(HwGainHwVolume);
+TEST_IN_AND_OUT_STREAM(AddRemoveEffectInvalidArguments);
+
+namespace aidl::android::hardware::audio::core {
+std::ostream& operator<<(std::ostream& os, const IStreamIn::MicrophoneDirection& md) {
+    os << toString(md);
+    return os;
+}
+}  // namespace aidl::android::hardware::audio::core
+
+TEST_P(AudioStreamIn, ActiveMicrophones) {
+    std::vector<MicrophoneInfo> micInfos;
+    ScopedAStatus status = module->getMicrophones(&micInfos);
+    if (!status.isOk()) {
+        GTEST_SKIP() << "Microphone info is not supported";
+    }
+    const auto ports = moduleConfig->getInputMixPorts(true /*attachedOnly*/);
+    if (ports.empty()) {
+        GTEST_SKIP() << "No input mix ports for attached devices";
+    }
+    for (const auto& port : ports) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(true, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for input mix port";
+        WithStream<IStreamIn> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        {
+            // The port of the stream is not connected, thus the list of active mics must be empty.
+            std::vector<MicrophoneDynamicInfo> activeMics;
+            EXPECT_IS_OK(stream.get()->getActiveMicrophones(&activeMics));
+            EXPECT_TRUE(activeMics.empty()) << "a stream on an unconnected port returns a "
+                                               "non-empty list of active microphones";
+        }
+        if (auto micDevicePorts = ModuleConfig::getBuiltInMicPorts(
+                    moduleConfig->getAttachedSourceDevicesPortsForMixPort(port));
+            !micDevicePorts.empty()) {
+            auto devicePortConfig = moduleConfig->getSingleConfigForDevicePort(micDevicePorts[0]);
+            WithAudioPatch patch(true /*isInput*/, stream.getPortConfig(), devicePortConfig);
+            ASSERT_NO_FATAL_FAILURE(patch.SetUp(module.get()));
+            std::vector<MicrophoneDynamicInfo> activeMics;
+            EXPECT_IS_OK(stream.get()->getActiveMicrophones(&activeMics));
+            for (const auto& mic : activeMics) {
+                EXPECT_NE(micInfos.end(),
+                          std::find_if(micInfos.begin(), micInfos.end(),
+                                       [&](const auto& micInfo) { return micInfo.id == mic.id; }))
+                        << "active microphone \"" << mic.id << "\" is not listed in "
+                        << "microphone infos returned by the module: "
+                        << ::android::internal::ToString(micInfos);
+                EXPECT_NE(0UL, mic.channelMapping.size())
+                        << "No channels specified for the microphone \"" << mic.id << "\"";
+            }
+        }
+        {
+            // Now the port of the stream is not connected again, re-check that there are no
+            // active microphones.
+            std::vector<MicrophoneDynamicInfo> activeMics;
+            EXPECT_IS_OK(stream.get()->getActiveMicrophones(&activeMics));
+            EXPECT_TRUE(activeMics.empty()) << "a stream on an unconnected port returns a "
+                                               "non-empty list of active microphones";
+        }
+    }
+}
+
+TEST_P(AudioStreamIn, MicrophoneDirection) {
+    using MD = IStreamIn::MicrophoneDirection;
+    const auto ports = moduleConfig->getInputMixPorts(true /*attachedOnly*/);
+    if (ports.empty()) {
+        GTEST_SKIP() << "No input mix ports for attached devices";
+    }
+    bool isSupported = false;
+    for (const auto& port : ports) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(true, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for input mix port";
+        WithStream<IStreamIn> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        EXPECT_NO_FATAL_FAILURE(
+                TestAccessors<MD>(stream.get(), &IStreamIn::getMicrophoneDirection,
+                                  &IStreamIn::setMicrophoneDirection,
+                                  std::vector<MD>(enum_range<MD>().begin(), enum_range<MD>().end()),
+                                  {}, &isSupported));
+        if (!isSupported) break;
+    }
+    if (!isSupported) {
+        GTEST_SKIP() << "Microphone direction is not supported";
+    }
+}
+
+TEST_P(AudioStreamIn, MicrophoneFieldDimension) {
+    const auto ports = moduleConfig->getInputMixPorts(true /*attachedOnly*/);
+    if (ports.empty()) {
+        GTEST_SKIP() << "No input mix ports for attached devices";
+    }
+    bool isSupported = false;
+    for (const auto& port : ports) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(true, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for input mix port";
+        WithStream<IStreamIn> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        EXPECT_NO_FATAL_FAILURE(TestAccessors<float>(
+                stream.get(), &IStreamIn::getMicrophoneFieldDimension,
+                &IStreamIn::setMicrophoneFieldDimension,
+                {IStreamIn::MIC_FIELD_DIMENSION_WIDE_ANGLE,
+                 IStreamIn::MIC_FIELD_DIMENSION_WIDE_ANGLE / 2.0f,
+                 IStreamIn::MIC_FIELD_DIMENSION_NO_ZOOM,
+                 IStreamIn::MIC_FIELD_DIMENSION_MAX_ZOOM / 2.0f,
+                 IStreamIn::MIC_FIELD_DIMENSION_MAX_ZOOM},
+                {IStreamIn::MIC_FIELD_DIMENSION_WIDE_ANGLE * 2,
+                 IStreamIn::MIC_FIELD_DIMENSION_MAX_ZOOM * 2,
+                 IStreamIn::MIC_FIELD_DIMENSION_WIDE_ANGLE * 1.1f,
+                 IStreamIn::MIC_FIELD_DIMENSION_MAX_ZOOM * 1.1f, -INFINITY, INFINITY, -NAN, NAN},
+                &isSupported));
+        if (!isSupported) break;
+    }
+    if (!isSupported) {
+        GTEST_SKIP() << "Microphone direction is not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, OpenTwicePrimary) {
+    const auto mixPorts =
+            moduleConfig->getPrimaryMixPorts(true /*attachedOnly*/, true /*singlePort*/);
+    if (mixPorts.empty()) {
+        GTEST_SKIP() << "No primary mix port which could be routed to attached devices";
+    }
+    const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, *mixPorts.begin());
+    ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for the primary mix port";
+    EXPECT_NO_FATAL_FAILURE(OpenTwiceSamePortConfigImpl(portConfig.value()));
+}
+
+TEST_P(AudioStreamOut, RequireOffloadInfo) {
+    const auto offloadMixPorts =
+            moduleConfig->getOffloadMixPorts(true /*attachedOnly*/, true /*singlePort*/);
+    if (offloadMixPorts.empty()) {
+        GTEST_SKIP()
+                << "No mix port for compressed offload that could be routed to attached devices";
+    }
+    const auto config = moduleConfig->getSingleConfigForMixPort(false, *offloadMixPorts.begin());
+    ASSERT_TRUE(config.has_value()) << "No profiles specified for the compressed offload mix port";
+    WithAudioPortConfig portConfig(config.value());
+    ASSERT_NO_FATAL_FAILURE(portConfig.SetUp(module.get()));
+    StreamDescriptor descriptor;
+    std::shared_ptr<IStreamOut> ignored;
+    aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
+    args.portConfigId = portConfig.getId();
+    args.sourceMetadata = GenerateSourceMetadata(portConfig.get());
+    args.bufferSizeFrames = kDefaultLargeBufferSizeFrames;
+    aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->openOutputStream(args, &ret))
+            << "when no offload info is provided for a compressed offload mix port";
+}
+
+TEST_P(AudioStreamOut, RequireAsyncCallback) {
+    const auto nonBlockingMixPorts =
+            moduleConfig->getNonBlockingMixPorts(true /*attachedOnly*/, true /*singlePort*/);
+    if (nonBlockingMixPorts.empty()) {
+        GTEST_SKIP()
+                << "No mix port for non-blocking output that could be routed to attached devices";
+    }
+    const auto config =
+            moduleConfig->getSingleConfigForMixPort(false, *nonBlockingMixPorts.begin());
+    ASSERT_TRUE(config.has_value()) << "No profiles specified for the non-blocking mix port";
+    WithAudioPortConfig portConfig(config.value());
+    ASSERT_NO_FATAL_FAILURE(portConfig.SetUp(module.get()));
+    StreamDescriptor descriptor;
+    std::shared_ptr<IStreamOut> ignored;
+    aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
+    args.portConfigId = portConfig.getId();
+    args.sourceMetadata = GenerateSourceMetadata(portConfig.get());
+    args.offloadInfo = ModuleConfig::generateOffloadInfoIfNeeded(portConfig.get());
+    args.bufferSizeFrames = kDefaultBufferSizeFrames;
+    aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->openOutputStream(args, &ret))
+            << "when no async callback is provided for a non-blocking mix port";
+}
+
+TEST_P(AudioStreamOut, AudioDescriptionMixLevel) {
+    const auto ports = moduleConfig->getOutputMixPorts(true /*attachedOnly*/);
+    if (ports.empty()) {
+        GTEST_SKIP() << "No output mix ports";
+    }
+    bool atLeastOneSupports = false;
+    for (const auto& port : ports) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
+        WithStream<IStreamOut> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        bool isSupported = false;
+        EXPECT_NO_FATAL_FAILURE(
+                TestAccessors<float>(stream.get(), &IStreamOut::getAudioDescriptionMixLevel,
+                                     &IStreamOut::setAudioDescriptionMixLevel,
+                                     {IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MAX,
+                                      IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MAX - 1, 0,
+                                      -INFINITY /*IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MIN*/},
+                                     {IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MAX * 2,
+                                      IStreamOut::AUDIO_DESCRIPTION_MIX_LEVEL_MAX * 1.1f},
+                                     &isSupported));
+        if (isSupported) atLeastOneSupports = true;
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Audio description mix level is not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, DualMonoMode) {
+    const auto ports = moduleConfig->getOutputMixPorts(true /*attachedOnly*/);
+    if (ports.empty()) {
+        GTEST_SKIP() << "No output mix ports";
+    }
+    bool atLeastOneSupports = false;
+    for (const auto& port : ports) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
+        WithStream<IStreamOut> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        bool isSupported = false;
+        EXPECT_NO_FATAL_FAILURE(TestAccessors<AudioDualMonoMode>(
+                stream.get(), &IStreamOut::getDualMonoMode, &IStreamOut::setDualMonoMode,
+                std::vector<AudioDualMonoMode>(enum_range<AudioDualMonoMode>().begin(),
+                                               enum_range<AudioDualMonoMode>().end()),
+                {}, &isSupported));
+        if (isSupported) atLeastOneSupports = true;
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Audio dual mono mode is not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, LatencyMode) {
+    const auto ports = moduleConfig->getOutputMixPorts(true /*attachedOnly*/);
+    if (ports.empty()) {
+        GTEST_SKIP() << "No output mix ports";
+    }
+    bool atLeastOneSupports = false;
+    for (const auto& port : ports) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
+        WithStream<IStreamOut> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        std::vector<AudioLatencyMode> supportedModes;
+        ndk::ScopedAStatus status = stream.get()->getRecommendedLatencyModes(&supportedModes);
+        if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) continue;
+        atLeastOneSupports = true;
+        if (!status.isOk()) {
+            ADD_FAILURE() << "When latency modes are supported, getRecommendedLatencyModes "
+                          << "must succeed on a non-closed stream, but it failed with " << status;
+            continue;
+        }
+        std::set<AudioLatencyMode> unsupportedModes(enum_range<AudioLatencyMode>().begin(),
+                                                    enum_range<AudioLatencyMode>().end());
+        for (const auto mode : supportedModes) {
+            unsupportedModes.erase(mode);
+            ndk::ScopedAStatus status = stream.get()->setLatencyMode(mode);
+            if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+                ADD_FAILURE() << "When latency modes are supported, both getRecommendedLatencyModes"
+                              << " and setLatencyMode must be supported";
+            }
+            EXPECT_IS_OK(status) << "Setting of supported latency mode must succeed";
+        }
+        for (const auto mode : unsupportedModes) {
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, stream.get()->setLatencyMode(mode));
+        }
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Audio latency modes are not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, PlaybackRate) {
+    static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+    const auto offloadMixPorts =
+            moduleConfig->getOffloadMixPorts(true /*attachedOnly*/, false /*singlePort*/);
+    if (offloadMixPorts.empty()) {
+        GTEST_SKIP()
+                << "No mix port for compressed offload that could be routed to attached devices";
+    }
+    ndk::ScopedAStatus status;
+    IModule::SupportedPlaybackRateFactors factors;
+    EXPECT_STATUS(kStatuses, status = module.get()->getSupportedPlaybackRateFactors(&factors));
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "Audio playback rate configuration is not supported";
+    }
+    EXPECT_LE(factors.minSpeed, factors.maxSpeed);
+    EXPECT_LE(factors.minPitch, factors.maxPitch);
+    EXPECT_LE(factors.minSpeed, 1.0f);
+    EXPECT_GE(factors.maxSpeed, 1.0f);
+    EXPECT_LE(factors.minPitch, 1.0f);
+    EXPECT_GE(factors.maxPitch, 1.0f);
+    constexpr auto tsDefault = AudioPlaybackRate::TimestretchMode::DEFAULT;
+    constexpr auto tsVoice = AudioPlaybackRate::TimestretchMode::VOICE;
+    constexpr auto fbFail = AudioPlaybackRate::TimestretchFallbackMode::FAIL;
+    constexpr auto fbMute = AudioPlaybackRate::TimestretchFallbackMode::MUTE;
+    const std::vector<AudioPlaybackRate> validValues = {
+            AudioPlaybackRate{1.0f, 1.0f, tsDefault, fbFail},
+            AudioPlaybackRate{1.0f, 1.0f, tsDefault, fbMute},
+            AudioPlaybackRate{factors.maxSpeed, factors.maxPitch, tsDefault, fbMute},
+            AudioPlaybackRate{factors.minSpeed, factors.minPitch, tsDefault, fbMute},
+            AudioPlaybackRate{1.0f, 1.0f, tsVoice, fbMute},
+            AudioPlaybackRate{1.0f, 1.0f, tsVoice, fbFail},
+            AudioPlaybackRate{factors.maxSpeed, factors.maxPitch, tsVoice, fbMute},
+            AudioPlaybackRate{factors.minSpeed, factors.minPitch, tsVoice, fbMute},
+            // Out of range speed / pitch values must not be rejected if the fallback mode is "mute"
+            AudioPlaybackRate{factors.maxSpeed * 2, factors.maxPitch * 2, tsDefault, fbMute},
+            AudioPlaybackRate{factors.minSpeed / 2, factors.minPitch / 2, tsDefault, fbMute},
+            AudioPlaybackRate{factors.maxSpeed * 2, factors.maxPitch * 2, tsVoice, fbMute},
+            AudioPlaybackRate{factors.minSpeed / 2, factors.minPitch / 2, tsVoice, fbMute},
+    };
+    const std::vector<AudioPlaybackRate> invalidValues = {
+            AudioPlaybackRate{factors.maxSpeed, factors.maxPitch * 2, tsDefault, fbFail},
+            AudioPlaybackRate{factors.maxSpeed * 2, factors.maxPitch, tsDefault, fbFail},
+            AudioPlaybackRate{factors.minSpeed, factors.minPitch / 2, tsDefault, fbFail},
+            AudioPlaybackRate{factors.minSpeed / 2, factors.minPitch, tsDefault, fbFail},
+            AudioPlaybackRate{factors.maxSpeed, factors.maxPitch * 2, tsVoice, fbFail},
+            AudioPlaybackRate{factors.maxSpeed * 2, factors.maxPitch, tsVoice, fbFail},
+            AudioPlaybackRate{factors.minSpeed, factors.minPitch / 2, tsVoice, fbFail},
+            AudioPlaybackRate{factors.minSpeed / 2, factors.minPitch, tsVoice, fbFail},
+            AudioPlaybackRate{1.0f, 1.0f, tsDefault,
+                              AudioPlaybackRate::TimestretchFallbackMode::SYS_RESERVED_CUT_REPEAT},
+            AudioPlaybackRate{1.0f, 1.0f, tsDefault,
+                              AudioPlaybackRate::TimestretchFallbackMode::SYS_RESERVED_DEFAULT},
+    };
+    bool atLeastOneSupports = false;
+    for (const auto& port : offloadMixPorts) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
+        WithStream<IStreamOut> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultLargeBufferSizeFrames));
+        bool isSupported = false;
+        EXPECT_NO_FATAL_FAILURE(TestAccessors<AudioPlaybackRate>(
+                stream.get(), &IStreamOut::getPlaybackRateParameters,
+                &IStreamOut::setPlaybackRateParameters, validValues, invalidValues, &isSupported));
+        if (isSupported) atLeastOneSupports = true;
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Audio playback rate configuration is not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, SelectPresentation) {
+    static const auto kStatuses = {EX_ILLEGAL_ARGUMENT, EX_UNSUPPORTED_OPERATION};
+    const auto offloadMixPorts =
+            moduleConfig->getOffloadMixPorts(true /*attachedOnly*/, false /*singlePort*/);
+    if (offloadMixPorts.empty()) {
+        GTEST_SKIP()
+                << "No mix port for compressed offload that could be routed to attached devices";
+    }
+    bool atLeastOneSupports = false;
+    for (const auto& port : offloadMixPorts) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
+        WithStream<IStreamOut> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultLargeBufferSizeFrames));
+        ndk::ScopedAStatus status;
+        EXPECT_STATUS(kStatuses, status = stream.get()->selectPresentation(0, 0));
+        if (status.getExceptionCode() != EX_UNSUPPORTED_OPERATION) atLeastOneSupports = true;
+    }
+    if (!atLeastOneSupports) {
+        GTEST_SKIP() << "Presentation selection is not supported";
+    }
+}
+
+TEST_P(AudioStreamOut, UpdateOffloadMetadata) {
+    const auto offloadMixPorts =
+            moduleConfig->getOffloadMixPorts(true /*attachedOnly*/, false /*singlePort*/);
+    if (offloadMixPorts.empty()) {
+        GTEST_SKIP()
+                << "No mix port for compressed offload that could be routed to attached devices";
+    }
+    for (const auto& port : offloadMixPorts) {
+        const auto portConfig = moduleConfig->getSingleConfigForMixPort(false, port);
+        ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
+        WithStream<IStreamOut> stream(portConfig.value());
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultLargeBufferSizeFrames));
+        AudioOffloadMetadata validMetadata{
+                .sampleRate = portConfig.value().sampleRate.value().value,
+                .channelMask = portConfig.value().channelMask.value(),
+                .averageBitRatePerSecond = 256000,
+                .delayFrames = 0,
+                .paddingFrames = 0};
+        EXPECT_IS_OK(stream.get()->updateOffloadMetadata(validMetadata));
+        AudioOffloadMetadata invalidMetadata{.sampleRate = -1,
+                                             .averageBitRatePerSecond = -1,
+                                             .delayFrames = -1,
+                                             .paddingFrames = -1};
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, stream.get()->updateOffloadMetadata(invalidMetadata));
+    }
+}
+
+class StreamLogicDefaultDriver : public StreamLogicDriver {
+  public:
+    StreamLogicDefaultDriver(std::shared_ptr<StateSequence> commands, size_t frameSizeBytes)
+        : mCommands(commands), mFrameSizeBytes(frameSizeBytes) {
+        mCommands->rewind();
+    }
+
+    // The three methods below is intended to be called after the worker
+    // thread has joined, thus no extra synchronization is needed.
+    bool hasObservablePositionIncrease() const { return mObservablePositionIncrease; }
+    bool hasRetrogradeObservablePosition() const { return mRetrogradeObservablePosition; }
+    std::string getUnexpectedStateTransition() const { return mUnexpectedTransition; }
+
+    bool done() override { return mCommands->done(); }
+    TransitionTrigger getNextTrigger(int maxDataSize, int* actualSize) override {
+        auto trigger = mCommands->getTrigger();
+        if (StreamDescriptor::Command* command = std::get_if<StreamDescriptor::Command>(&trigger);
+            command != nullptr) {
+            if (command->getTag() == StreamDescriptor::Command::Tag::burst) {
+                if (actualSize != nullptr) {
+                    // In the output scenario, reduce slightly the fmqByteCount to verify
+                    // that the HAL module always consumes all data from the MQ.
+                    if (maxDataSize > static_cast<int>(mFrameSizeBytes)) {
+                        LOG(DEBUG) << __func__ << ": reducing data size by " << mFrameSizeBytes;
+                        maxDataSize -= mFrameSizeBytes;
+                    }
+                    *actualSize = maxDataSize;
+                }
+                command->set<StreamDescriptor::Command::Tag::burst>(maxDataSize);
+            } else {
+                if (actualSize != nullptr) *actualSize = 0;
+            }
+        }
+        return trigger;
+    }
+    bool interceptRawReply(const StreamDescriptor::Reply&) override { return false; }
+    bool processValidReply(const StreamDescriptor::Reply& reply) override {
+        if (reply.observable.frames != StreamDescriptor::Position::UNKNOWN) {
+            if (mPreviousFrames.has_value()) {
+                if (reply.observable.frames > mPreviousFrames.value()) {
+                    mObservablePositionIncrease = true;
+                } else if (reply.observable.frames < mPreviousFrames.value()) {
+                    mRetrogradeObservablePosition = true;
+                }
+            }
+            mPreviousFrames = reply.observable.frames;
+        }
+
+        auto expected = mCommands->getExpectedStates();
+        if (expected.count(reply.state) == 0) {
+            std::string s =
+                    std::string("Unexpected transition from the state ")
+                            .append(mPreviousState.has_value() ? toString(mPreviousState.value())
+                                                               : "<initial state>")
+                            .append(" to ")
+                            .append(toString(reply.state))
+                            .append(" (expected one of ")
+                            .append(::android::internal::ToString(expected))
+                            .append(") caused by the ")
+                            .append(toString(mCommands->getTrigger()));
+            LOG(ERROR) << __func__ << ": " << s;
+            mUnexpectedTransition = std::move(s);
+            return false;
+        }
+        mCommands->advance(reply.state);
+        mPreviousState = reply.state;
+        return true;
+    }
+
+  protected:
+    std::shared_ptr<StateSequence> mCommands;
+    const size_t mFrameSizeBytes;
+    std::optional<StreamDescriptor::State> mPreviousState;
+    std::optional<int64_t> mPreviousFrames;
+    bool mObservablePositionIncrease = false;
+    bool mRetrogradeObservablePosition = false;
+    std::string mUnexpectedTransition;
+};
+
+enum { NAMED_CMD_NAME, NAMED_CMD_DELAY_MS, NAMED_CMD_STREAM_TYPE, NAMED_CMD_CMDS };
+enum class StreamTypeFilter { ANY, SYNC, ASYNC };
+using NamedCommandSequence =
+        std::tuple<std::string, int, StreamTypeFilter, std::shared_ptr<StateSequence>>;
+enum { PARAM_MODULE_NAME, PARAM_CMD_SEQ, PARAM_SETUP_SEQ };
+using StreamIoTestParameters =
+        std::tuple<std::string /*moduleName*/, NamedCommandSequence, bool /*useSetupSequence2*/>;
+template <typename Stream>
+class AudioStreamIo : public AudioCoreModuleBase,
+                      public testing::TestWithParam<StreamIoTestParameters> {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(std::get<PARAM_MODULE_NAME>(GetParam())));
+        ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    }
+
+    void Run() {
+        const auto allPortConfigs =
+                moduleConfig->getPortConfigsForMixPorts(IOTraits<Stream>::is_input);
+        if (allPortConfigs.empty()) {
+            GTEST_SKIP() << "No mix ports have attached devices";
+        }
+        for (const auto& portConfig : allPortConfigs) {
+            SCOPED_TRACE(portConfig.toString());
+            const bool isNonBlocking =
+                    IOTraits<Stream>::is_input
+                            ? false
+                            :
+                            // TODO: Uncomment when support for asynchronous input is implemented.
+                            /*isBitPositionFlagSet(
+                              portConfig.flags.value().template get<AudioIoFlags::Tag::input>(),
+                              AudioInputFlags::NON_BLOCKING) :*/
+                            isBitPositionFlagSet(portConfig.flags.value()
+                                                         .template get<AudioIoFlags::Tag::output>(),
+                                                 AudioOutputFlags::NON_BLOCKING);
+            if (auto streamType =
+                        std::get<NAMED_CMD_STREAM_TYPE>(std::get<PARAM_CMD_SEQ>(GetParam()));
+                (isNonBlocking && streamType == StreamTypeFilter::SYNC) ||
+                (!isNonBlocking && streamType == StreamTypeFilter::ASYNC)) {
+                continue;
+            }
+            WithDebugFlags delayTransientStates = WithDebugFlags::createNested(*debug);
+            delayTransientStates.flags().streamTransientStateDelayMs =
+                    std::get<NAMED_CMD_DELAY_MS>(std::get<PARAM_CMD_SEQ>(GetParam()));
+            ASSERT_NO_FATAL_FAILURE(delayTransientStates.SetUp(module.get()));
+            const auto& commandsAndStates =
+                    std::get<NAMED_CMD_CMDS>(std::get<PARAM_CMD_SEQ>(GetParam()));
+            if (!std::get<PARAM_SETUP_SEQ>(GetParam())) {
+                ASSERT_NO_FATAL_FAILURE(RunStreamIoCommandsImplSeq1(portConfig, commandsAndStates));
+            } else {
+                ASSERT_NO_FATAL_FAILURE(RunStreamIoCommandsImplSeq2(portConfig, commandsAndStates));
+            }
+            if (isNonBlocking) {
+                // Also try running the same sequence with "aosp.forceTransientBurst" set.
+                // This will only work with the default implementation. When it works, the stream
+                // tries always to move to the 'TRANSFERRING' state after a burst.
+                // This helps to check more paths for our test scenarios.
+                WithModuleParameter forceTransientBurst("aosp.forceTransientBurst", Boolean{true});
+                if (forceTransientBurst.SetUpNoChecks(module.get(), true /*failureExpected*/)
+                            .isOk()) {
+                    if (!std::get<PARAM_SETUP_SEQ>(GetParam())) {
+                        ASSERT_NO_FATAL_FAILURE(
+                                RunStreamIoCommandsImplSeq1(portConfig, commandsAndStates));
+                    } else {
+                        ASSERT_NO_FATAL_FAILURE(
+                                RunStreamIoCommandsImplSeq2(portConfig, commandsAndStates));
+                    }
+                }
+            } else if (!IOTraits<Stream>::is_input) {
+                // Also try running the same sequence with "aosp.forceSynchronousDrain" set.
+                // This will only work with the default implementation. When it works, the stream
+                // tries always to move to the 'IDLE' state after a drain.
+                // This helps to check more paths for our test scenarios.
+                WithModuleParameter forceSynchronousDrain("aosp.forceSynchronousDrain",
+                                                          Boolean{true});
+                if (forceSynchronousDrain.SetUpNoChecks(module.get(), true /*failureExpected*/)
+                            .isOk()) {
+                    if (!std::get<PARAM_SETUP_SEQ>(GetParam())) {
+                        ASSERT_NO_FATAL_FAILURE(
+                                RunStreamIoCommandsImplSeq1(portConfig, commandsAndStates));
+                    } else {
+                        ASSERT_NO_FATAL_FAILURE(
+                                RunStreamIoCommandsImplSeq2(portConfig, commandsAndStates));
+                    }
+                }
+            }
+        }
+    }
+
+    bool ValidateObservablePosition(const AudioPortConfig& devicePortConfig) {
+        return !isTelephonyDeviceType(
+                devicePortConfig.ext.get<AudioPortExt::Tag::device>().device.type.type);
+    }
+
+    // Set up a patch first, then open a stream.
+    void RunStreamIoCommandsImplSeq1(const AudioPortConfig& portConfig,
+                                     std::shared_ptr<StateSequence> commandsAndStates) {
+        auto devicePorts = moduleConfig->getAttachedDevicesPortsForMixPort(
+                IOTraits<Stream>::is_input, portConfig);
+        ASSERT_FALSE(devicePorts.empty());
+        auto devicePortConfig = moduleConfig->getSingleConfigForDevicePort(devicePorts[0]);
+        WithAudioPatch patch(IOTraits<Stream>::is_input, portConfig, devicePortConfig);
+        ASSERT_NO_FATAL_FAILURE(patch.SetUp(module.get()));
+
+        WithStream<Stream> stream(patch.getPortConfig(IOTraits<Stream>::is_input));
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        StreamLogicDefaultDriver driver(commandsAndStates,
+                                        stream.getContext()->getFrameSizeBytes());
+        typename IOTraits<Stream>::Worker worker(*stream.getContext(), &driver,
+                                                 stream.getEventReceiver());
+
+        LOG(DEBUG) << __func__ << ": starting worker...";
+        ASSERT_TRUE(worker.start());
+        LOG(DEBUG) << __func__ << ": joining worker...";
+        worker.join();
+        EXPECT_FALSE(worker.hasError()) << worker.getError();
+        EXPECT_EQ("", driver.getUnexpectedStateTransition());
+        if (ValidateObservablePosition(devicePortConfig)) {
+            EXPECT_TRUE(driver.hasObservablePositionIncrease());
+            EXPECT_FALSE(driver.hasRetrogradeObservablePosition());
+        }
+    }
+
+    // Open a stream, then set up a patch for it.
+    void RunStreamIoCommandsImplSeq2(const AudioPortConfig& portConfig,
+                                     std::shared_ptr<StateSequence> commandsAndStates) {
+        WithStream<Stream> stream(portConfig);
+        ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
+        StreamLogicDefaultDriver driver(commandsAndStates,
+                                        stream.getContext()->getFrameSizeBytes());
+        typename IOTraits<Stream>::Worker worker(*stream.getContext(), &driver,
+                                                 stream.getEventReceiver());
+
+        auto devicePorts = moduleConfig->getAttachedDevicesPortsForMixPort(
+                IOTraits<Stream>::is_input, portConfig);
+        ASSERT_FALSE(devicePorts.empty());
+        auto devicePortConfig = moduleConfig->getSingleConfigForDevicePort(devicePorts[0]);
+        WithAudioPatch patch(IOTraits<Stream>::is_input, stream.getPortConfig(), devicePortConfig);
+        ASSERT_NO_FATAL_FAILURE(patch.SetUp(module.get()));
+
+        LOG(DEBUG) << __func__ << ": starting worker...";
+        ASSERT_TRUE(worker.start());
+        LOG(DEBUG) << __func__ << ": joining worker...";
+        worker.join();
+        EXPECT_FALSE(worker.hasError()) << worker.getError();
+        EXPECT_EQ("", driver.getUnexpectedStateTransition());
+        if (ValidateObservablePosition(devicePortConfig)) {
+            EXPECT_TRUE(driver.hasObservablePositionIncrease());
+            EXPECT_FALSE(driver.hasRetrogradeObservablePosition());
+        }
+    }
+};
+using AudioStreamIoIn = AudioStreamIo<IStreamIn>;
+using AudioStreamIoOut = AudioStreamIo<IStreamOut>;
+
+#define TEST_IN_AND_OUT_STREAM_IO(method_name)  \
+    TEST_P(AudioStreamIoIn, method_name) {      \
+        ASSERT_NO_FATAL_FAILURE(method_name()); \
+    }                                           \
+    TEST_P(AudioStreamIoOut, method_name) {     \
+        ASSERT_NO_FATAL_FAILURE(method_name()); \
+    }
+
+TEST_IN_AND_OUT_STREAM_IO(Run);
+
+// Tests specific to audio patches. The fixure class is named 'AudioModulePatch'
+// to avoid clashing with 'AudioPatch' class.
+class AudioModulePatch : public AudioCoreModule {
+  public:
+    static std::string direction(bool isInput, bool capitalize) {
+        return isInput ? (capitalize ? "Input" : "input") : (capitalize ? "Output" : "output");
+    }
+
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(AudioCoreModule::SetUp());
+        ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+    }
+
+    void SetInvalidPatchHelper(int32_t expectedException, const std::vector<int32_t>& sources,
+                               const std::vector<int32_t>& sinks) {
+        AudioPatch patch;
+        patch.sourcePortConfigIds = sources;
+        patch.sinkPortConfigIds = sinks;
+        ASSERT_STATUS(expectedException, module->setAudioPatch(patch, &patch))
+                << "patch source ids: " << android::internal::ToString(sources)
+                << "; sink ids: " << android::internal::ToString(sinks);
+    }
+
+    void ResetPortConfigUsedByPatch(bool isInput) {
+        auto srcSinkGroups = moduleConfig->getRoutableSrcSinkGroups(isInput);
+        if (srcSinkGroups.empty()) {
+            GTEST_SKIP() << "No routes to any attached " << direction(isInput, false) << " devices";
+        }
+        auto srcSinkGroup = *srcSinkGroups.begin();
+        auto srcSink = *srcSinkGroup.second.begin();
+        WithAudioPatch patch(srcSink.first, srcSink.second);
+        ASSERT_NO_FATAL_FAILURE(patch.SetUp(module.get()));
+        std::vector<int32_t> sourceAndSinkPortConfigIds(patch.get().sourcePortConfigIds);
+        sourceAndSinkPortConfigIds.insert(sourceAndSinkPortConfigIds.end(),
+                                          patch.get().sinkPortConfigIds.begin(),
+                                          patch.get().sinkPortConfigIds.end());
+        for (const auto portConfigId : sourceAndSinkPortConfigIds) {
+            EXPECT_STATUS(EX_ILLEGAL_STATE, module->resetAudioPortConfig(portConfigId))
+                    << "port config ID " << portConfigId;
+        }
+    }
+
+    void SetInvalidPatch(bool isInput) {
+        auto srcSinkPair = moduleConfig->getRoutableSrcSinkPair(isInput);
+        if (!srcSinkPair.has_value()) {
+            GTEST_SKIP() << "No routes to any attached " << direction(isInput, false) << " devices";
+        }
+        WithAudioPortConfig srcPortConfig(srcSinkPair.value().first);
+        ASSERT_NO_FATAL_FAILURE(srcPortConfig.SetUp(module.get()));
+        WithAudioPortConfig sinkPortConfig(srcSinkPair.value().second);
+        ASSERT_NO_FATAL_FAILURE(sinkPortConfig.SetUp(module.get()));
+        {  // Check that the pair can actually be used for setting up a patch.
+            WithAudioPatch patch(srcPortConfig.get(), sinkPortConfig.get());
+            ASSERT_NO_FATAL_FAILURE(patch.SetUp(module.get()));
+        }
+        EXPECT_NO_FATAL_FAILURE(
+                SetInvalidPatchHelper(EX_ILLEGAL_ARGUMENT, {}, {sinkPortConfig.getId()}));
+        EXPECT_NO_FATAL_FAILURE(SetInvalidPatchHelper(
+                EX_ILLEGAL_ARGUMENT, {srcPortConfig.getId(), srcPortConfig.getId()},
+                {sinkPortConfig.getId()}));
+        EXPECT_NO_FATAL_FAILURE(
+                SetInvalidPatchHelper(EX_ILLEGAL_ARGUMENT, {srcPortConfig.getId()}, {}));
+        EXPECT_NO_FATAL_FAILURE(
+                SetInvalidPatchHelper(EX_ILLEGAL_ARGUMENT, {srcPortConfig.getId()},
+                                      {sinkPortConfig.getId(), sinkPortConfig.getId()}));
+
+        std::set<int32_t> portConfigIds;
+        ASSERT_NO_FATAL_FAILURE(GetAllPortConfigIds(&portConfigIds));
+        for (const auto portConfigId : GetNonExistentIds(portConfigIds)) {
+            EXPECT_NO_FATAL_FAILURE(SetInvalidPatchHelper(EX_ILLEGAL_ARGUMENT, {portConfigId},
+                                                          {sinkPortConfig.getId()}));
+            EXPECT_NO_FATAL_FAILURE(SetInvalidPatchHelper(EX_ILLEGAL_ARGUMENT,
+                                                          {srcPortConfig.getId()}, {portConfigId}));
+        }
+    }
+
+    void SetNonRoutablePatch(bool isInput) {
+        auto srcSinkPair = moduleConfig->getNonRoutableSrcSinkPair(isInput);
+        if (!srcSinkPair.has_value()) {
+            GTEST_SKIP() << "All possible source/sink pairs are routable";
+        }
+        WithAudioPatch patch(srcSinkPair.value().first, srcSinkPair.value().second);
+        ASSERT_NO_FATAL_FAILURE(patch.SetUpPortConfigs(module.get()));
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, patch.SetUpNoChecks(module.get()))
+                << "when setting up a patch from " << srcSinkPair.value().first.toString() << " to "
+                << srcSinkPair.value().second.toString() << " that does not have a route";
+    }
+
+    void SetPatch(bool isInput) {
+        auto srcSinkGroups = moduleConfig->getRoutableSrcSinkGroups(isInput);
+        if (srcSinkGroups.empty()) {
+            GTEST_SKIP() << "No routes to any attached " << direction(isInput, false) << " devices";
+        }
+        for (const auto& srcSinkGroup : srcSinkGroups) {
+            const auto& route = srcSinkGroup.first;
+            std::vector<std::unique_ptr<WithAudioPatch>> patches;
+            for (const auto& srcSink : srcSinkGroup.second) {
+                if (!route.isExclusive) {
+                    patches.push_back(
+                            std::make_unique<WithAudioPatch>(srcSink.first, srcSink.second));
+                    EXPECT_NO_FATAL_FAILURE(patches[patches.size() - 1]->SetUp(module.get()));
+                } else {
+                    WithAudioPatch patch(srcSink.first, srcSink.second);
+                    EXPECT_NO_FATAL_FAILURE(patch.SetUp(module.get()));
+                }
+            }
+        }
+    }
+
+    void UpdatePatch(bool isInput) {
+        auto srcSinkGroups = moduleConfig->getRoutableSrcSinkGroups(isInput);
+        if (srcSinkGroups.empty()) {
+            GTEST_SKIP() << "No routes to any attached " << direction(isInput, false) << " devices";
+        }
+        for (const auto& srcSinkGroup : srcSinkGroups) {
+            for (const auto& srcSink : srcSinkGroup.second) {
+                WithAudioPatch patch(srcSink.first, srcSink.second);
+                ASSERT_NO_FATAL_FAILURE(patch.SetUp(module.get()));
+                AudioPatch ignored;
+                EXPECT_NO_FATAL_FAILURE(module->setAudioPatch(patch.get(), &ignored));
+            }
+        }
+    }
+
+    void UpdateInvalidPatchId(bool isInput) {
+        auto srcSinkGroups = moduleConfig->getRoutableSrcSinkGroups(isInput);
+        if (srcSinkGroups.empty()) {
+            GTEST_SKIP() << "No routes to any attached " << direction(isInput, false) << " devices";
+        }
+        // First, set up a patch to ensure that its settings are accepted.
+        auto srcSinkGroup = *srcSinkGroups.begin();
+        auto srcSink = *srcSinkGroup.second.begin();
+        WithAudioPatch patch(srcSink.first, srcSink.second);
+        ASSERT_NO_FATAL_FAILURE(patch.SetUp(module.get()));
+        // Then use the same patch setting, except for having an invalid ID.
+        std::set<int32_t> patchIds;
+        ASSERT_NO_FATAL_FAILURE(GetAllPatchIds(&patchIds));
+        for (const auto patchId : GetNonExistentIds(patchIds)) {
+            AudioPatch patchWithNonExistendId = patch.get();
+            patchWithNonExistendId.id = patchId;
+            EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+                          module->setAudioPatch(patchWithNonExistendId, &patchWithNonExistendId))
+                    << "patch ID " << patchId;
+        }
+    }
+};
+
+// Not all tests require both directions, so parametrization would require
+// more abstractions.
+#define TEST_PATCH_BOTH_DIRECTIONS(method_name)      \
+    TEST_P(AudioModulePatch, method_name##Input) {   \
+        ASSERT_NO_FATAL_FAILURE(method_name(true));  \
+    }                                                \
+    TEST_P(AudioModulePatch, method_name##Output) {  \
+        ASSERT_NO_FATAL_FAILURE(method_name(false)); \
+    }
+
+TEST_PATCH_BOTH_DIRECTIONS(ResetPortConfigUsedByPatch);
+TEST_PATCH_BOTH_DIRECTIONS(SetInvalidPatch);
+TEST_PATCH_BOTH_DIRECTIONS(SetNonRoutablePatch);
+TEST_PATCH_BOTH_DIRECTIONS(SetPatch);
+TEST_PATCH_BOTH_DIRECTIONS(UpdateInvalidPatchId);
+TEST_PATCH_BOTH_DIRECTIONS(UpdatePatch);
+
+TEST_P(AudioModulePatch, ResetInvalidPatchId) {
+    std::set<int32_t> patchIds;
+    ASSERT_NO_FATAL_FAILURE(GetAllPatchIds(&patchIds));
+    for (const auto patchId : GetNonExistentIds(patchIds)) {
+        EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->resetAudioPatch(patchId))
+                << "patch ID " << patchId;
+    }
+}
+
+class AudioCoreSoundDose : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
+  public:
+    class NoOpHalSoundDoseCallback : public ISoundDose::BnHalSoundDoseCallback {
+      public:
+        ndk::ScopedAStatus onMomentaryExposureWarning(float in_currentDbA,
+                                                      const AudioDevice& in_audioDevice) override;
+        ndk::ScopedAStatus onNewMelValues(
+                const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord,
+                const AudioDevice& in_audioDevice) override;
+    };
+
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+        ASSERT_IS_OK(module->getSoundDose(&soundDose));
+        callback = ndk::SharedRefBase::make<NoOpHalSoundDoseCallback>();
+    }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+    std::shared_ptr<ISoundDose> soundDose;
+    std::shared_ptr<ISoundDose::IHalSoundDoseCallback> callback;
+};
+
+ndk::ScopedAStatus AudioCoreSoundDose::NoOpHalSoundDoseCallback::onMomentaryExposureWarning(
+        float in_currentDbA, const AudioDevice& in_audioDevice) {
+    // Do nothing
+    (void)in_currentDbA;
+    (void)in_audioDevice;
+    LOG(INFO) << "NoOpHalSoundDoseCallback::onMomentaryExposureWarning called";
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioCoreSoundDose::NoOpHalSoundDoseCallback::onNewMelValues(
+        const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord,
+        const AudioDevice& in_audioDevice) {
+    // Do nothing
+    (void)in_melRecord;
+    (void)in_audioDevice;
+    LOG(INFO) << "NoOpHalSoundDoseCallback::onNewMelValues called";
+
+    return ndk::ScopedAStatus::ok();
+}
+
+// @VsrTest = VSR-5.5-002.001
+TEST_P(AudioCoreSoundDose, SameInstance) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+    std::shared_ptr<ISoundDose> soundDose2;
+    EXPECT_IS_OK(module->getSoundDose(&soundDose2));
+    ASSERT_NE(nullptr, soundDose2.get());
+    EXPECT_EQ(soundDose->asBinder(), soundDose2->asBinder())
+            << "getSoundDose must return the same interface instance across invocations";
+}
+
+// @VsrTest = VSR-5.5-002.001
+TEST_P(AudioCoreSoundDose, GetSetOutputRs2UpperBound) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+
+    bool isSupported = false;
+    EXPECT_NO_FATAL_FAILURE(TestAccessors<float>(soundDose.get(),
+                                                 &ISoundDose::getOutputRs2UpperBound,
+                                                 &ISoundDose::setOutputRs2UpperBound,
+                                                 /*validValues=*/{80.f, 90.f, 100.f},
+                                                 /*invalidValues=*/{79.f, 101.f}, &isSupported));
+    EXPECT_TRUE(isSupported) << "Getting/Setting RS2 upper bound must be supported";
+}
+
+// @VsrTest = VSR-5.5-002.001
+TEST_P(AudioCoreSoundDose, CheckDefaultRs2UpperBound) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+
+    float rs2Value;
+    ASSERT_IS_OK(soundDose->getOutputRs2UpperBound(&rs2Value));
+    EXPECT_EQ(rs2Value, ISoundDose::DEFAULT_MAX_RS2);
+}
+
+// @VsrTest = VSR-5.5-002.001
+TEST_P(AudioCoreSoundDose, RegisterSoundDoseCallbackTwiceThrowsException) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+
+    ASSERT_IS_OK(soundDose->registerSoundDoseCallback(callback));
+    EXPECT_STATUS(EX_ILLEGAL_STATE, soundDose->registerSoundDoseCallback(callback))
+            << "Registering sound dose callback twice should throw EX_ILLEGAL_STATE";
+}
+
+// @VsrTest = VSR-5.5-002.001
+TEST_P(AudioCoreSoundDose, RegisterSoundDoseNullCallbackThrowsException) {
+    if (soundDose == nullptr) {
+        GTEST_SKIP() << "SoundDose is not supported";
+    }
+
+    EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, soundDose->registerSoundDoseCallback(nullptr))
+            << "Registering nullptr sound dose callback should throw EX_ILLEGAL_ARGUMENT";
+}
+
+INSTANTIATE_TEST_SUITE_P(AudioCoreModuleTest, AudioCoreModule,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreModule);
+INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothTest, AudioCoreBluetooth,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetooth);
+INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothA2dpTest, AudioCoreBluetoothA2dp,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetoothA2dp);
+INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothLeTest, AudioCoreBluetoothLe,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetoothLe);
+INSTANTIATE_TEST_SUITE_P(AudioCoreTelephonyTest, AudioCoreTelephony,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreTelephony);
+INSTANTIATE_TEST_SUITE_P(AudioStreamInTest, AudioStreamIn,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioStreamIn);
+INSTANTIATE_TEST_SUITE_P(AudioStreamOutTest, AudioStreamOut,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioStreamOut);
+INSTANTIATE_TEST_SUITE_P(AudioCoreSoundDoseTest, AudioCoreSoundDose,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreSoundDose);
+
+// This is the value used in test sequences for which the test needs to ensure
+// that the HAL stays in a transient state long enough to receive the next command.
+static const int kStreamTransientStateTransitionDelayMs = 3000;
+
+// TODO: Add async test cases for input once it is implemented.
+
+std::shared_ptr<StateSequence> makeBurstCommands(bool isSync) {
+    using State = StreamDescriptor::State;
+    auto d = std::make_unique<StateDag>();
+    StateDag::Node last = d->makeFinalNode(State::ACTIVE);
+    StateDag::Node active = d->makeNode(State::ACTIVE, kBurstCommand, last);
+    StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+    if (!isSync) {
+        // Allow optional routing via the TRANSFERRING state on bursts.
+        active.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, last));
+        idle.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active));
+    }
+    d->makeNode(State::STANDBY, kStartCommand, idle);
+    return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kReadSeq =
+        std::make_tuple(std::string("Read"), 0, StreamTypeFilter::ANY, makeBurstCommands(true));
+static const NamedCommandSequence kWriteSyncSeq =
+        std::make_tuple(std::string("Write"), 0, StreamTypeFilter::SYNC, makeBurstCommands(true));
+static const NamedCommandSequence kWriteAsyncSeq =
+        std::make_tuple(std::string("Write"), 0, StreamTypeFilter::ASYNC, makeBurstCommands(false));
+
+std::shared_ptr<StateSequence> makeAsyncDrainCommands(bool isInput) {
+    using State = StreamDescriptor::State;
+    auto d = std::make_unique<StateDag>();
+    if (isInput) {
+        d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+                      std::make_pair(State::IDLE, kBurstCommand),
+                      std::make_pair(State::ACTIVE, kDrainInCommand),
+                      std::make_pair(State::DRAINING, kStartCommand),
+                      std::make_pair(State::ACTIVE, kDrainInCommand)},
+                     State::DRAINING);
+    } else {
+        StateDag::Node draining =
+                d->makeNodes({std::make_pair(State::DRAINING, kBurstCommand),
+                              std::make_pair(State::TRANSFERRING, kDrainOutAllCommand)},
+                             State::DRAINING);
+        StateDag::Node idle =
+                d->makeNodes({std::make_pair(State::IDLE, kBurstCommand),
+                              std::make_pair(State::TRANSFERRING, kDrainOutAllCommand)},
+                             draining);
+        // If we get straight into ACTIVE on burst, no further testing is possible.
+        draining.children().push_back(d->makeFinalNode(State::ACTIVE));
+        idle.children().push_back(d->makeFinalNode(State::ACTIVE));
+        d->makeNode(State::STANDBY, kStartCommand, idle);
+    }
+    return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kWriteDrainAsyncSeq =
+        std::make_tuple(std::string("WriteDrain"), kStreamTransientStateTransitionDelayMs,
+                        StreamTypeFilter::ASYNC, makeAsyncDrainCommands(false));
+static const NamedCommandSequence kDrainInSeq = std::make_tuple(
+        std::string("Drain"), 0, StreamTypeFilter::ANY, makeAsyncDrainCommands(true));
+
+std::shared_ptr<StateSequence> makeDrainOutCommands(bool isSync) {
+    using State = StreamDescriptor::State;
+    auto d = std::make_unique<StateDag>();
+    StateDag::Node last = d->makeFinalNode(State::IDLE);
+    StateDag::Node active = d->makeNodes(
+            {std::make_pair(State::ACTIVE, kDrainOutAllCommand),
+             std::make_pair(State::DRAINING, isSync ? TransitionTrigger(kGetStatusCommand)
+                                                    : TransitionTrigger(kDrainReadyEvent))},
+            last);
+    StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+    if (!isSync) {
+        idle.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active));
+    } else {
+        active.children().push_back(last);
+    }
+    d->makeNode(State::STANDBY, kStartCommand, idle);
+    return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kDrainOutSyncSeq = std::make_tuple(
+        std::string("Drain"), 0, StreamTypeFilter::SYNC, makeDrainOutCommands(true));
+static const NamedCommandSequence kDrainOutAsyncSeq = std::make_tuple(
+        std::string("Drain"), 0, StreamTypeFilter::ASYNC, makeDrainOutCommands(false));
+
+std::shared_ptr<StateSequence> makeDrainPauseOutCommands(bool isSync) {
+    using State = StreamDescriptor::State;
+    auto d = std::make_unique<StateDag>();
+    StateDag::Node draining = d->makeNodes({std::make_pair(State::DRAINING, kPauseCommand),
+                                            std::make_pair(State::DRAIN_PAUSED, kStartCommand),
+                                            std::make_pair(State::DRAINING, kPauseCommand),
+                                            std::make_pair(State::DRAIN_PAUSED, kBurstCommand)},
+                                           isSync ? State::PAUSED : State::TRANSFER_PAUSED);
+    StateDag::Node active = d->makeNode(State::ACTIVE, kDrainOutAllCommand, draining);
+    StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+    if (!isSync) {
+        idle.children().push_back(d->makeNode(State::TRANSFERRING, kDrainOutAllCommand, draining));
+    } else {
+        // If we get straight into IDLE on drain, no further testing is possible.
+        active.children().push_back(d->makeFinalNode(State::IDLE));
+    }
+    d->makeNode(State::STANDBY, kStartCommand, idle);
+    return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kDrainPauseOutSyncSeq =
+        std::make_tuple(std::string("DrainPause"), kStreamTransientStateTransitionDelayMs,
+                        StreamTypeFilter::SYNC, makeDrainPauseOutCommands(true));
+static const NamedCommandSequence kDrainPauseOutAsyncSeq =
+        std::make_tuple(std::string("DrainPause"), kStreamTransientStateTransitionDelayMs,
+                        StreamTypeFilter::ASYNC, makeDrainPauseOutCommands(false));
+
+// This sequence also verifies that the capture / presentation position is not reset on standby.
+std::shared_ptr<StateSequence> makeStandbyCommands(bool isInput, bool isSync) {
+    using State = StreamDescriptor::State;
+    auto d = std::make_unique<StateDag>();
+    if (isInput) {
+        d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+                      std::make_pair(State::IDLE, kStandbyCommand),
+                      std::make_pair(State::STANDBY, kStartCommand),
+                      std::make_pair(State::IDLE, kBurstCommand),
+                      std::make_pair(State::ACTIVE, kPauseCommand),
+                      std::make_pair(State::PAUSED, kFlushCommand),
+                      std::make_pair(State::STANDBY, kStartCommand),
+                      std::make_pair(State::IDLE, kBurstCommand)},
+                     State::ACTIVE);
+    } else {
+        StateDag::Node idle3 =
+                d->makeNode(State::IDLE, kBurstCommand, d->makeFinalNode(State::ACTIVE));
+        StateDag::Node idle2 = d->makeNodes({std::make_pair(State::IDLE, kStandbyCommand),
+                                             std::make_pair(State::STANDBY, kStartCommand)},
+                                            idle3);
+        StateDag::Node active = d->makeNodes({std::make_pair(State::ACTIVE, kPauseCommand),
+                                              std::make_pair(State::PAUSED, kFlushCommand)},
+                                             idle2);
+        StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+        if (!isSync) {
+            idle3.children().push_back(d->makeFinalNode(State::TRANSFERRING));
+            StateDag::Node transferring =
+                    d->makeNodes({std::make_pair(State::TRANSFERRING, kPauseCommand),
+                                  std::make_pair(State::TRANSFER_PAUSED, kFlushCommand)},
+                                 idle2);
+            idle.children().push_back(transferring);
+        }
+        d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+                      std::make_pair(State::IDLE, kStandbyCommand),
+                      std::make_pair(State::STANDBY, kStartCommand)},
+                     idle);
+    }
+    return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kStandbyInSeq = std::make_tuple(
+        std::string("Standby"), 0, StreamTypeFilter::ANY, makeStandbyCommands(true, false));
+static const NamedCommandSequence kStandbyOutSyncSeq = std::make_tuple(
+        std::string("Standby"), 0, StreamTypeFilter::SYNC, makeStandbyCommands(false, true));
+static const NamedCommandSequence kStandbyOutAsyncSeq =
+        std::make_tuple(std::string("Standby"), kStreamTransientStateTransitionDelayMs,
+                        StreamTypeFilter::ASYNC, makeStandbyCommands(false, false));
+
+std::shared_ptr<StateSequence> makePauseCommands(bool isInput, bool isSync) {
+    using State = StreamDescriptor::State;
+    auto d = std::make_unique<StateDag>();
+    if (isInput) {
+        d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+                      std::make_pair(State::IDLE, kBurstCommand),
+                      std::make_pair(State::ACTIVE, kPauseCommand),
+                      std::make_pair(State::PAUSED, kBurstCommand),
+                      std::make_pair(State::ACTIVE, kPauseCommand),
+                      std::make_pair(State::PAUSED, kFlushCommand)},
+                     State::STANDBY);
+    } else {
+        StateDag::Node idle = d->makeNodes({std::make_pair(State::IDLE, kBurstCommand),
+                                            std::make_pair(State::ACTIVE, kPauseCommand),
+                                            std::make_pair(State::PAUSED, kStartCommand),
+                                            std::make_pair(State::ACTIVE, kPauseCommand),
+                                            std::make_pair(State::PAUSED, kBurstCommand),
+                                            std::make_pair(State::PAUSED, kStartCommand),
+                                            std::make_pair(State::ACTIVE, kPauseCommand)},
+                                           State::PAUSED);
+        if (!isSync) {
+            idle.children().push_back(
+                    d->makeNodes({std::make_pair(State::TRANSFERRING, kPauseCommand),
+                                  std::make_pair(State::TRANSFER_PAUSED, kStartCommand),
+                                  std::make_pair(State::TRANSFERRING, kPauseCommand),
+                                  std::make_pair(State::TRANSFER_PAUSED, kDrainOutAllCommand),
+                                  std::make_pair(State::DRAIN_PAUSED, kBurstCommand)},
+                                 State::TRANSFER_PAUSED));
+        }
+        d->makeNode(State::STANDBY, kStartCommand, idle);
+    }
+    return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kPauseInSeq = std::make_tuple(
+        std::string("Pause"), 0, StreamTypeFilter::ANY, makePauseCommands(true, false));
+static const NamedCommandSequence kPauseOutSyncSeq = std::make_tuple(
+        std::string("Pause"), 0, StreamTypeFilter::SYNC, makePauseCommands(false, true));
+static const NamedCommandSequence kPauseOutAsyncSeq =
+        std::make_tuple(std::string("Pause"), kStreamTransientStateTransitionDelayMs,
+                        StreamTypeFilter::ASYNC, makePauseCommands(false, false));
+
+std::shared_ptr<StateSequence> makeFlushCommands(bool isInput, bool isSync) {
+    using State = StreamDescriptor::State;
+    auto d = std::make_unique<StateDag>();
+    if (isInput) {
+        d->makeNodes({std::make_pair(State::STANDBY, kStartCommand),
+                      std::make_pair(State::IDLE, kBurstCommand),
+                      std::make_pair(State::ACTIVE, kPauseCommand),
+                      std::make_pair(State::PAUSED, kFlushCommand)},
+                     State::STANDBY);
+    } else {
+        StateDag::Node last = d->makeFinalNode(State::IDLE);
+        StateDag::Node idle = d->makeNodes({std::make_pair(State::IDLE, kBurstCommand),
+                                            std::make_pair(State::ACTIVE, kPauseCommand),
+                                            std::make_pair(State::PAUSED, kFlushCommand)},
+                                           last);
+        if (!isSync) {
+            idle.children().push_back(
+                    d->makeNodes({std::make_pair(State::TRANSFERRING, kPauseCommand),
+                                  std::make_pair(State::TRANSFER_PAUSED, kFlushCommand)},
+                                 last));
+        }
+        d->makeNode(State::STANDBY, kStartCommand, idle);
+    }
+    return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kFlushInSeq = std::make_tuple(
+        std::string("Flush"), 0, StreamTypeFilter::ANY, makeFlushCommands(true, false));
+static const NamedCommandSequence kFlushOutSyncSeq = std::make_tuple(
+        std::string("Flush"), 0, StreamTypeFilter::SYNC, makeFlushCommands(false, true));
+static const NamedCommandSequence kFlushOutAsyncSeq =
+        std::make_tuple(std::string("Flush"), kStreamTransientStateTransitionDelayMs,
+                        StreamTypeFilter::ASYNC, makeFlushCommands(false, false));
+
+std::shared_ptr<StateSequence> makeDrainPauseFlushOutCommands(bool isSync) {
+    using State = StreamDescriptor::State;
+    auto d = std::make_unique<StateDag>();
+    StateDag::Node draining = d->makeNodes({std::make_pair(State::DRAINING, kPauseCommand),
+                                            std::make_pair(State::DRAIN_PAUSED, kFlushCommand)},
+                                           State::IDLE);
+    StateDag::Node active = d->makeNode(State::ACTIVE, kDrainOutAllCommand, draining);
+    StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+    if (!isSync) {
+        idle.children().push_back(d->makeNode(State::TRANSFERRING, kDrainOutAllCommand, draining));
+    } else {
+        // If we get straight into IDLE on drain, no further testing is possible.
+        active.children().push_back(d->makeFinalNode(State::IDLE));
+    }
+    d->makeNode(State::STANDBY, kStartCommand, idle);
+    return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kDrainPauseFlushOutSyncSeq =
+        std::make_tuple(std::string("DrainPauseFlush"), kStreamTransientStateTransitionDelayMs,
+                        StreamTypeFilter::SYNC, makeDrainPauseFlushOutCommands(true));
+static const NamedCommandSequence kDrainPauseFlushOutAsyncSeq =
+        std::make_tuple(std::string("DrainPauseFlush"), kStreamTransientStateTransitionDelayMs,
+                        StreamTypeFilter::ASYNC, makeDrainPauseFlushOutCommands(false));
+
+// Note, this isn't the "official" enum printer, it is only used to make the test name suffix.
+std::string PrintStreamFilterToString(StreamTypeFilter filter) {
+    switch (filter) {
+        case StreamTypeFilter::ANY:
+            return "";
+        case StreamTypeFilter::SYNC:
+            return "Sync";
+        case StreamTypeFilter::ASYNC:
+            return "Async";
+    }
+    return std::string("Unknown").append(std::to_string(static_cast<int32_t>(filter)));
+}
+std::string GetStreamIoTestName(const testing::TestParamInfo<StreamIoTestParameters>& info) {
+    return android::PrintInstanceNameToString(
+                   testing::TestParamInfo<std::string>{std::get<PARAM_MODULE_NAME>(info.param),
+                                                       info.index})
+            .append("_")
+            .append(std::get<NAMED_CMD_NAME>(std::get<PARAM_CMD_SEQ>(info.param)))
+            .append(PrintStreamFilterToString(
+                    std::get<NAMED_CMD_STREAM_TYPE>(std::get<PARAM_CMD_SEQ>(info.param))))
+            .append("_SetupSeq")
+            .append(std::get<PARAM_SETUP_SEQ>(info.param) ? "2" : "1");
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        AudioStreamIoInTest, AudioStreamIoIn,
+        testing::Combine(testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         testing::Values(kReadSeq, kDrainInSeq, kStandbyInSeq, kPauseInSeq,
+                                         kFlushInSeq),
+                         testing::Values(false, true)),
+        GetStreamIoTestName);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioStreamIoIn);
+INSTANTIATE_TEST_SUITE_P(
+        AudioStreamIoOutTest, AudioStreamIoOut,
+        testing::Combine(testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         testing::Values(kWriteSyncSeq, kWriteAsyncSeq, kWriteDrainAsyncSeq,
+                                         kDrainOutSyncSeq, kDrainPauseOutSyncSeq,
+                                         kDrainPauseOutAsyncSeq, kStandbyOutSyncSeq,
+                                         kStandbyOutAsyncSeq,
+                                         kPauseOutSyncSeq,  // kPauseOutAsyncSeq,
+                                         kFlushOutSyncSeq, kFlushOutAsyncSeq,
+                                         kDrainPauseFlushOutSyncSeq, kDrainPauseFlushOutAsyncSeq),
+                         testing::Values(false, true)),
+        GetStreamIoTestName);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioStreamIoOut);
+
+INSTANTIATE_TEST_SUITE_P(AudioPatchTest, AudioModulePatch,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioModulePatch);
+
+class TestExecutionTracer : public ::testing::EmptyTestEventListener {
+  public:
+    void OnTestStart(const ::testing::TestInfo& test_info) override {
+        TraceTestState("Started", test_info);
+    }
+    void OnTestEnd(const ::testing::TestInfo& test_info) override {
+        TraceTestState("Completed", test_info);
+    }
+
+  private:
+    static void TraceTestState(const std::string& state, const ::testing::TestInfo& test_info) {
+        LOG(INFO) << state << " " << test_info.test_suite_name() << "::" << test_info.name();
+    }
+};
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
+    android::base::SetMinimumLogSeverity(::android::base::DEBUG);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml b/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
new file mode 100644
index 0000000..dfc1039
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs VtsHalAudioCoreTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+    <target_preparer class="com.android.tradefed.targetprep.StopServicesSetup"/>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="setprop vts.native_server.on 1"/>
+        <option name="teardown-command" value="setprop vts.native_server.on 0"/>
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalAudioCoreTargetTest" />
+        <option name="native-test-timeout" value="10m" />
+    </test>
+</configuration>
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
new file mode 100644
index 0000000..9cd6c22
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#define LOG_TAG "VtsHalAudioEffectFactory"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include <aidl/android/hardware/audio/effect/IFactory.h>
+
+#include "AudioHalBinderServiceUtil.h"
+#include "EffectFactoryHelper.h"
+#include "TestUtils.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectUuidNull;
+using aidl::android::hardware::audio::effect::getEffectUuidZero;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Processing;
+using aidl::android::media::audio::common::AudioSource;
+using aidl::android::media::audio::common::AudioStreamType;
+using aidl::android::media::audio::common::AudioUuid;
+
+/// Effect factory testing.
+class EffectFactoryTest : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        mFactoryHelper = std::make_unique<EffectFactoryHelper>(GetParam());
+        connectAndGetFactory();
+    }
+
+    void TearDown() override {
+        for (auto& effect : mEffects) {
+            const auto status = mEffectFactory->destroyEffect(effect);
+            EXPECT_STATUS(EX_NONE, status);
+        }
+    }
+
+    std::unique_ptr<EffectFactoryHelper> mFactoryHelper;
+    std::shared_ptr<IFactory> mEffectFactory;
+    std::vector<std::shared_ptr<IEffect>> mEffects;
+    const Descriptor::Identity kNullId = {.uuid = getEffectUuidNull()};
+    const Descriptor::Identity kZeroId = {.uuid = getEffectUuidZero()};
+    const Descriptor kNullDesc = {.common.id = kNullId};
+    const Descriptor kZeroDesc = {.common.id = kZeroId};
+
+    template <typename Functor>
+    void ForEachId(const std::vector<Descriptor::Identity> ids, Functor functor) {
+        for (const auto& id : ids) {
+            SCOPED_TRACE(id.toString());
+            functor(id);
+        }
+    }
+    template <typename Functor>
+    void ForEachEffect(std::vector<std::shared_ptr<IEffect>> effects, Functor functor) {
+        for (auto& effect : effects) {
+            functor(effect);
+        }
+    }
+
+    std::vector<std::shared_ptr<IEffect>> createWithDescs(
+            const std::vector<Descriptor> descs, const binder_status_t expectStatus = EX_NONE) {
+        std::vector<std::shared_ptr<IEffect>> effects;
+        for (const auto& desc : descs) {
+            const auto& uuid = desc.common.id.uuid;
+            std::shared_ptr<IEffect> effect;
+            EXPECT_STATUS(expectStatus, mEffectFactory->createEffect(uuid, &effect));
+            if (expectStatus == EX_NONE) {
+                EXPECT_NE(effect, nullptr) << " null effect with uuid: " << uuid.toString();
+                effects.push_back(std::move(effect));
+            }
+        }
+        return effects;
+    }
+    void destroyEffects(std::vector<std::shared_ptr<IEffect>> effects,
+                        const binder_status_t expectStatus = EX_NONE) {
+        for (const auto& effect : effects) {
+            EXPECT_STATUS(expectStatus, mEffectFactory->destroyEffect(effect));
+        }
+    }
+    void creatAndDestroyDescs(const std::vector<Descriptor> descs) {
+        for (const auto& desc : descs) {
+            auto effects = createWithDescs({desc});
+            ASSERT_NO_FATAL_FAILURE(destroyEffects(effects));
+        }
+    }
+    void connectAndGetFactory() {
+        ASSERT_NO_FATAL_FAILURE(mFactoryHelper->ConnectToFactoryService());
+        mEffectFactory = mFactoryHelper->GetFactory();
+        ASSERT_NE(mEffectFactory, nullptr);
+    }
+};
+
+TEST_P(EffectFactoryTest, SetupAndTearDown) {
+    // Intentionally empty test body.
+}
+
+TEST_P(EffectFactoryTest, CanBeRestarted) {
+    ASSERT_NO_FATAL_FAILURE(mFactoryHelper->RestartFactoryService());
+}
+
+/**
+ * @brief Check at least support list of effect must be supported by aosp:
+ * https://developer.android.com/reference/android/media/audiofx/AudioEffect
+ */
+TEST_P(EffectFactoryTest, ExpectAllAospEffectTypes) {
+    std::vector<Descriptor> descs;
+    std::set<AudioUuid> typeUuidSet(
+            {aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator(),
+             aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer()});
+
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs));
+    EXPECT_TRUE(descs.size() >= typeUuidSet.size());
+    for (const auto& desc : descs) {
+        typeUuidSet.erase(desc.common.id.type);
+    }
+    std::string msg = " missing type UUID:\n";
+    for (const auto& uuid : typeUuidSet) {
+        msg += (uuid.toString() + "\n");
+    }
+    SCOPED_TRACE(msg);
+    EXPECT_EQ(0UL, typeUuidSet.size());
+}
+
+TEST_P(EffectFactoryTest, QueryNullTypeUuid) {
+    std::vector<Descriptor> descs;
+    EXPECT_IS_OK(
+            mEffectFactory->queryEffects(getEffectUuidNull(), std::nullopt, std::nullopt, &descs));
+    EXPECT_EQ(descs.size(), 0UL);
+}
+
+TEST_P(EffectFactoryTest, QueriedNullImplUuid) {
+    std::vector<Descriptor> descs;
+    EXPECT_IS_OK(
+            mEffectFactory->queryEffects(std::nullopt, getEffectUuidNull(), std::nullopt, &descs));
+    EXPECT_EQ(descs.size(), 0UL);
+}
+
+TEST_P(EffectFactoryTest, QueriedNullProxyUuid) {
+    std::vector<Descriptor> descs;
+    EXPECT_IS_OK(
+            mEffectFactory->queryEffects(std::nullopt, std::nullopt, getEffectUuidNull(), &descs));
+    EXPECT_EQ(descs.size(), 0UL);
+}
+
+// create all effects, and then destroy them all together
+TEST_P(EffectFactoryTest, CreateAndDestroyEffects) {
+    std::vector<Descriptor> descs;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs));
+    EXPECT_NE(descs.size(), 0UL);
+
+    std::vector<std::shared_ptr<IEffect>> effects;
+    effects = createWithDescs(descs);
+    EXPECT_EQ(descs.size(), effects.size());
+    destroyEffects(effects);
+}
+
+TEST_P(EffectFactoryTest, CreateMultipleInstanceOfSameEffect) {
+    std::vector<Descriptor> descs;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs));
+    EXPECT_NE(descs.size(), 0UL);
+
+    std::vector<std::shared_ptr<IEffect>> effects = createWithDescs(descs);
+    EXPECT_EQ(descs.size(), effects.size());
+    std::vector<std::shared_ptr<IEffect>> effects2 = createWithDescs(descs);
+    EXPECT_EQ(descs.size(), effects2.size());
+    std::vector<std::shared_ptr<IEffect>> effects3 = createWithDescs(descs);
+    EXPECT_EQ(descs.size(), effects3.size());
+
+    destroyEffects(effects);
+    destroyEffects(effects2);
+    destroyEffects(effects3);
+}
+
+// create and destroy each effect one by one
+TEST_P(EffectFactoryTest, CreateAndDestroyEffectsOneByOne) {
+    std::vector<Descriptor> descs;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs));
+    EXPECT_NE(descs.size(), 0UL);
+
+    creatAndDestroyDescs(descs);
+}
+
+// for each effect: repeat 3 times create and destroy
+TEST_P(EffectFactoryTest, CreateAndDestroyRepeat) {
+    std::vector<Descriptor> descs;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs));
+    EXPECT_NE(descs.size(), 0UL);
+
+    creatAndDestroyDescs(descs);
+    creatAndDestroyDescs(descs);
+    creatAndDestroyDescs(descs);
+}
+
+// Expect EX_ILLEGAL_ARGUMENT when create with invalid UUID.
+TEST_P(EffectFactoryTest, CreateWithInvalidUuid) {
+    std::vector<Descriptor> descs = {kNullDesc, kZeroDesc};
+    auto effects = createWithDescs(descs, EX_ILLEGAL_ARGUMENT);
+    EXPECT_EQ(effects.size(), 0UL);
+}
+
+// Expect EX_ILLEGAL_ARGUMENT when destroy null interface.
+TEST_P(EffectFactoryTest, DestroyWithInvalidInterface) {
+    std::shared_ptr<IEffect> spDummyEffect(nullptr);
+    destroyEffects({spDummyEffect}, EX_ILLEGAL_ARGUMENT);
+}
+
+// Same descriptor ID should work after service restart.
+TEST_P(EffectFactoryTest, CreateDestroyWithRestart) {
+    std::vector<Descriptor> descs;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs));
+    EXPECT_NE(descs.size(), 0UL);
+    creatAndDestroyDescs(descs);
+
+    mFactoryHelper->RestartFactoryService();
+
+    connectAndGetFactory();
+    creatAndDestroyDescs(descs);
+}
+
+// Effect handle invalid after restart.
+TEST_P(EffectFactoryTest, EffectInvalidAfterRestart) {
+    std::vector<Descriptor> descs;
+    EXPECT_IS_OK(mEffectFactory->queryEffects(std::nullopt, std::nullopt, std::nullopt, &descs));
+    EXPECT_NE(descs.size(), 0UL);
+    std::vector<std::shared_ptr<IEffect>> effects = createWithDescs(descs);
+
+    ASSERT_NO_FATAL_FAILURE(mFactoryHelper->RestartFactoryService());
+
+    connectAndGetFactory();
+    destroyEffects(effects, EX_ILLEGAL_ARGUMENT);
+}
+
+// expect no error with the queryProcessing interface, but don't check number of processing
+TEST_P(EffectFactoryTest, QueryProcess) {
+    std::vector<Processing> processing;
+    EXPECT_IS_OK(mEffectFactory->queryProcessing(std::nullopt, &processing));
+    std::set<Processing> processingSet(processing.begin(), processing.end());
+
+    Processing::Type streamType =
+            Processing::Type::make<Processing::Type::streamType>(AudioStreamType::SYSTEM);
+    std::vector<Processing> processingFilteredByStream;
+    EXPECT_IS_OK(mEffectFactory->queryProcessing(streamType, &processingFilteredByStream));
+
+    Processing::Type source =
+            Processing::Type::make<Processing::Type::source>(AudioSource::DEFAULT);
+    std::vector<Processing> processingFilteredBySource;
+    EXPECT_IS_OK(mEffectFactory->queryProcessing(source, &processingFilteredBySource));
+
+    EXPECT_TRUE(processing.size() >= processingFilteredByStream.size());
+    EXPECT_TRUE(std::all_of(
+            processingFilteredByStream.begin(), processingFilteredByStream.end(),
+            [&](const auto& proc) { return processingSet.find(proc) != processingSet.end(); }));
+
+    EXPECT_TRUE(processing.size() >= processingFilteredBySource.size());
+    EXPECT_TRUE(std::all_of(
+            processingFilteredBySource.begin(), processingFilteredBySource.end(),
+            [&](const auto& proc) { return processingSet.find(proc) != processingSet.end(); }));
+}
+
+INSTANTIATE_TEST_SUITE_P(EffectFactoryTest, EffectFactoryTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EffectFactoryTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
new file mode 100644
index 0000000..436f2a3
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -0,0 +1,866 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VtsHalAudioEffectTargetTest"
+
+#include <chrono>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "AudioHalBinderServiceUtil.h"
+#include "EffectFactoryHelper.h"
+#include "EffectHelper.h"
+#include "TestUtils.h"
+
+using namespace android;
+
+using ndk::ScopedAStatus;
+
+using aidl::android::hardware::audio::effect::CommandId;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioSource;
+
+enum ParamName { PARAM_INSTANCE_NAME };
+using EffectTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>>;
+
+class AudioEffectTest : public testing::TestWithParam<EffectTestParam>, public EffectHelper {
+  public:
+    AudioEffectTest() {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {}
+
+    void TearDown() override {
+        // Do the cleanup for every test case
+        if (mEffect) {
+            ASSERT_NO_FATAL_FAILURE(commandIgnoreRet(mEffect, CommandId::STOP));
+            ASSERT_NO_FATAL_FAILURE(closeIgnoreRet(mEffect));
+            ASSERT_NO_FATAL_FAILURE(destroyIgnoreRet(mFactory, mEffect));
+            mEffect.reset();
+        }
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+
+    void setAndGetParameter(Parameter::Id id, const Parameter& set) {
+        Parameter get;
+        EXPECT_IS_OK(mEffect->setParameter(set));
+        EXPECT_IS_OK(mEffect->getParameter(id, &get));
+        EXPECT_EQ(set, get) << set.toString() << "\n vs \n" << get.toString();
+    }
+};
+
+TEST_P(AudioEffectTest, SetupAndTearDown) {
+    // Intentionally empty test body.
+}
+
+TEST_P(AudioEffectTest, CreateAndDestroy) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+TEST_P(AudioEffectTest, OpenAndClose) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+TEST_P(AudioEffectTest, CloseUnopenedEffect) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+TEST_P(AudioEffectTest, DoubleOpenAndClose) {
+    std::shared_ptr<IEffect> effect1, effect2;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(effect1));
+    ASSERT_NO_FATAL_FAILURE(open(effect2, 1 /* session */));
+    ASSERT_NO_FATAL_FAILURE(close(effect1));
+    ASSERT_NO_FATAL_FAILURE(close(effect2));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect1));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect2));
+}
+
+TEST_P(AudioEffectTest, TripleOpenAndClose) {
+    std::shared_ptr<IEffect> effect1, effect2, effect3;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect3, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(effect1));
+    ASSERT_NO_FATAL_FAILURE(open(effect2, 1 /* session */));
+    ASSERT_NO_FATAL_FAILURE(open(effect3, 2 /* session */));
+    ASSERT_NO_FATAL_FAILURE(close(effect1));
+    ASSERT_NO_FATAL_FAILURE(close(effect2));
+    ASSERT_NO_FATAL_FAILURE(close(effect3));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect1));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect2));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect3));
+}
+
+TEST_P(AudioEffectTest, GetDescritorBeforeOpen) {
+    Descriptor desc;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, desc));
+    EXPECT_EQ(mDescriptor.common.id.type, desc.common.id.type);
+    EXPECT_EQ(mDescriptor.common.id.uuid, desc.common.id.uuid);
+    EXPECT_EQ(mDescriptor.common.name, desc.common.name);
+    EXPECT_EQ(mDescriptor.common.implementor, desc.common.implementor);
+    // Effect implementation Must fill in implementor and name
+    EXPECT_NE("", desc.common.name);
+    EXPECT_NE("", desc.common.implementor);
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+TEST_P(AudioEffectTest, GetDescritorAfterOpen) {
+    Descriptor beforeOpen, afterOpen, afterClose;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, beforeOpen));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, afterOpen));
+    EXPECT_EQ(beforeOpen.toString(), afterOpen.toString()) << "\n"
+                                                           << beforeOpen.toString() << "\n"
+                                                           << afterOpen.toString();
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, afterClose));
+    EXPECT_EQ(beforeOpen.toString(), afterClose.toString()) << "\n"
+                                                            << beforeOpen.toString() << "\n"
+                                                            << afterClose.toString();
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+TEST_P(AudioEffectTest, DescriptorExistAndUnique) {
+    Descriptor desc;
+
+    auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor);
+    std::set<Descriptor::Identity> idSet;
+    for (const auto& it : descList) {
+        auto& id = it.second.common.id;
+        EXPECT_EQ(0ul, idSet.count(id));
+        idSet.insert(id);
+    }
+
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(getDescriptor(mEffect, desc));
+    int uuidCount = std::count_if(idSet.begin(), idSet.end(), [&](const auto& id) {
+        return id.uuid == desc.common.id.uuid && id.type == desc.common.id.type;
+    });
+
+    EXPECT_EQ(1, uuidCount);
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+/// State testing.
+// An effect instance is in INIT state by default after it was created.
+TEST_P(AudioEffectTest, InitStateAfterCreation) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// An effect instance transfer to IDLE state after IEffect.ASSERT_NO_FATAL_FAILURE(open().
+TEST_P(AudioEffectTest, IdleStateAfterOpen) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// An effect instance is in PROCESSING state after it receive an START command.
+TEST_P(AudioEffectTest, ProcessingStateAfterStart) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// An effect instance transfer to IDLE state after Command.Id.STOP in PROCESSING state.
+TEST_P(AudioEffectTest, IdleStateAfterStop) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// An effect instance transfer to IDLE state after Command.Id.RESET in PROCESSING state.
+TEST_P(AudioEffectTest, IdleStateAfterReset) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// An effect instance transfer to INIT after IEffect.ASSERT_NO_FATAL_FAILURE(close().
+TEST_P(AudioEffectTest, InitStateAfterClose) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// An effect instance shouldn't accept any command before open.
+TEST_P(AudioEffectTest, NoCommandAcceptedBeforeOpen) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET, EX_ILLEGAL_STATE));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// No-op when receive STOP command in IDLE state.
+TEST_P(AudioEffectTest, StopCommandInIdleStateNoOp) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// No-op when receive RESET command in IDLE state.
+TEST_P(AudioEffectTest, ResetCommandInIdleStateNoOp) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Repeat START and STOP command.
+TEST_P(AudioEffectTest, RepeatStartAndStop) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Repeat START and RESET command.
+TEST_P(AudioEffectTest, RepeatStartAndReset) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Try to close an effect instance at PROCESSING state.
+TEST_P(AudioEffectTest, CloseProcessingStateEffects) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect, EX_ILLEGAL_STATE));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
+TEST_P(AudioEffectTest, DestroyOpenEffects) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect, EX_ILLEGAL_STATE));
+
+    // cleanup
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
+TEST_P(AudioEffectTest, DestroyProcessingEffects) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect, EX_ILLEGAL_STATE));
+
+    // cleanup
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+TEST_P(AudioEffectTest, NormalSequenceStates) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::INIT));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+/// Parameter testing.
+// Verify parameters pass in open can be successfully get.
+TEST_P(AudioEffectTest, VerifyCommonParametersAfterOpen) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+    Parameter::Common common = EffectHelper::createParamCommon();
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+
+    Parameter get = Parameter(), expect = Parameter();
+    expect.set<Parameter::common>(common);
+    Parameter::Id id;
+    id.set<Parameter::Id::commonTag>(Parameter::common);
+    EXPECT_IS_OK(mEffect->getParameter(id, &get));
+    EXPECT_EQ(expect, get) << expect.toString() << "\n vs \n" << get.toString();
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Verify parameters pass in set can be successfully get.
+TEST_P(AudioEffectTest, SetAndGetCommonParameter) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Verify parameters set and get in PROCESSING state.
+TEST_P(AudioEffectTest, SetAndGetParameterInProcessing) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Verify parameters set and get in IDLE state.
+TEST_P(AudioEffectTest, SetAndGetParameterInIdle) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Verify Parameters kept after stop.
+TEST_P(AudioEffectTest, SetAndGetParameterAfterStop) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Verify Parameters kept after reset.
+TEST_P(AudioEffectTest, SetAndGetParameterAfterReset) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */);
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common);
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(id, Parameter::make<Parameter::common>(common)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get AudioDeviceDescription in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterDeviceDescription) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    std::vector<AudioDeviceDescription> deviceDescs = {
+            {.type = AudioDeviceType::IN_DEFAULT,
+             .connection = AudioDeviceDescription::CONNECTION_ANALOG},
+            {.type = AudioDeviceType::IN_DEVICE,
+             .connection = AudioDeviceDescription::CONNECTION_BT_A2DP}};
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::deviceDescription);
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::deviceDescription>(deviceDescs)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get AudioMode in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterAudioMode) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::mode);
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::mode>(AudioMode::NORMAL)));
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::mode>(AudioMode::IN_COMMUNICATION)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get AudioSource in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterAudioSource) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::source);
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::source>(AudioSource::DEFAULT)));
+    ASSERT_NO_FATAL_FAILURE(setAndGetParameter(
+            id, Parameter::make<Parameter::source>(AudioSource::VOICE_RECOGNITION)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Set and get VolumeStereo in Parameter
+TEST_P(AudioEffectTest, SetAndGetParameterVolume) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(open(mEffect));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    Parameter::Id id = Parameter::Id::make<Parameter::Id::commonTag>(Parameter::volumeStereo);
+    Parameter::VolumeStereo volume = {.left = 10.0, .right = 10.0};
+    ASSERT_NO_FATAL_FAILURE(
+            setAndGetParameter(id, Parameter::make<Parameter::volumeStereo>(volume)));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+/// Data processing test
+// Send data to effects and expect it to be consumed by checking statusMQ.
+TEST_P(AudioEffectTest, ConsumeDataInProcessingState) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    std::vector<float> buffer;
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Send data to effects and expect it to be consumed after effect restart.
+TEST_P(AudioEffectTest, ConsumeDataAfterRestart) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
+
+    std::vector<float> buffer;
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 0, outputMQ, buffer.size(), buffer));
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Send data to IDLE effects and expect it to be consumed after effect start.
+TEST_P(AudioEffectTest, SendDataAtIdleAndConsumeDataInProcessing) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
+
+    std::vector<float> buffer;
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Send data multiple times.
+TEST_P(AudioEffectTest, ProcessDataMultipleTimes) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
+
+    std::vector<float> buffer;
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Send data to processing state effects, stop, and restart.
+TEST_P(AudioEffectTest, ConsumeDataAndRestart) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    std::vector<float> buffer;
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
+    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Send data to closed effects and expect it not be consumed.
+TEST_P(AudioEffectTest, NotConsumeDataByClosedEffect) {
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+    Parameter::Common common = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret;
+    ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt /* specific */, &ret, EX_NONE));
+    ASSERT_NO_FATAL_FAILURE(close(mEffect));
+
+    auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(ret.statusMQ);
+    ASSERT_TRUE(statusMQ->isValid());
+    auto inputMQ = std::make_unique<EffectHelper::DataMQ>(ret.inputDataMQ);
+    ASSERT_TRUE(inputMQ->isValid());
+    auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
+    ASSERT_TRUE(outputMQ->isValid());
+
+    std::vector<float> buffer;
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, buffer));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
+
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+}
+
+// Send data to multiple effects.
+TEST_P(AudioEffectTest, ConsumeDataMultipleEffects) {
+    std::shared_ptr<IEffect> effect1, effect2;
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect1, mDescriptor));
+    ASSERT_NO_FATAL_FAILURE(create(mFactory, effect2, mDescriptor));
+
+    Parameter::Common common1 = EffectHelper::createParamCommon(
+            0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+            kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+    Parameter::Common common2 = EffectHelper::createParamCommon(
+            1 /* session */, 1 /* ioHandle */, 48000 /* iSampleRate */, 48000 /* oSampleRate */,
+            2 * kInputFrameCount /* iFrameCount */, 2 * kOutputFrameCount /* oFrameCount */);
+    IEffect::OpenEffectReturn ret1, ret2;
+    ASSERT_NO_FATAL_FAILURE(open(effect1, common1, std::nullopt /* specific */, &ret1, EX_NONE));
+    ASSERT_NO_FATAL_FAILURE(open(effect2, common2, std::nullopt /* specific */, &ret2, EX_NONE));
+    ASSERT_NO_FATAL_FAILURE(command(effect1, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect1, State::PROCESSING));
+    ASSERT_NO_FATAL_FAILURE(command(effect2, CommandId::START));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect2, State::PROCESSING));
+
+    auto statusMQ1 = std::make_unique<EffectHelper::StatusMQ>(ret1.statusMQ);
+    ASSERT_TRUE(statusMQ1->isValid());
+    auto inputMQ1 = std::make_unique<EffectHelper::DataMQ>(ret1.inputDataMQ);
+    ASSERT_TRUE(inputMQ1->isValid());
+    auto outputMQ1 = std::make_unique<EffectHelper::DataMQ>(ret1.outputDataMQ);
+    ASSERT_TRUE(outputMQ1->isValid());
+
+    std::vector<float> buffer1, buffer2;
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common1, inputMQ1, buffer1));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ1, inputMQ1, buffer1));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1));
+
+    auto statusMQ2 = std::make_unique<EffectHelper::StatusMQ>(ret2.statusMQ);
+    ASSERT_TRUE(statusMQ2->isValid());
+    auto inputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.inputDataMQ);
+    ASSERT_TRUE(inputMQ2->isValid());
+    auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ);
+    ASSERT_TRUE(outputMQ2->isValid());
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common2, inputMQ2, buffer2));
+    EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ2, inputMQ2, buffer2));
+    EXPECT_NO_FATAL_FAILURE(
+            EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2));
+
+    ASSERT_NO_FATAL_FAILURE(command(effect1, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect1, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect1));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect1));
+
+    ASSERT_NO_FATAL_FAILURE(command(effect2, CommandId::STOP));
+    ASSERT_NO_FATAL_FAILURE(expectState(effect2, State::IDLE));
+    ASSERT_NO_FATAL_FAILURE(close(effect2));
+    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, effect2));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        SingleEffectInstanceTest, AudioEffectTest,
+        ::testing::Combine(testing::ValuesIn(
+                EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor))),
+        [](const testing::TestParamInfo<AudioEffectTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_TYPE_" +
+                               descriptor.common.id.type.toString() + "_UUID_" +
+                               descriptor.common.id.uuid.toString();
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioEffectTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
new file mode 100644
index 0000000..9cfdc50
--- /dev/null
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <limits.h>
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalBassBoostTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::BassBoost;
+using aidl::android::hardware::audio::effect::Capability;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_STRENGTH };
+using BassBoostParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
+
+/*
+ * Testing parameter range, assuming the parameter supported by effect is in this range.
+ * Parameter should be within the valid range defined in the documentation,
+ * for any supported value test expects EX_NONE from IEffect.setParameter(),
+ * otherwise expect EX_ILLEGAL_ARGUMENT.
+ */
+
+class BassBoostParamTest : public ::testing::TestWithParam<BassBoostParamTestParam>,
+                           public EffectHelper {
+  public:
+    BassBoostParamTest() : mParamStrength(std::get<PARAM_STRENGTH>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        BassBoost bb = BassBoost::make<BassBoost::strengthPm>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::bassBoost>(bb);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mParamStrength = 0;
+
+    void SetAndGetBassBoostParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& bb = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid = isParameterValid<BassBoost, Range::bassBoost>(it.second, desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::bassBoost>(bb);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                BassBoost::Id bbId;
+                bbId.set<BassBoost::Id::commonTag>(tag);
+                id.set<Parameter::Id::bassBoostTag>(bbId);
+                // if set success, then get should match
+                EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+                EXPECT_EQ(expectParam, getParam);
+            }
+        }
+    }
+
+    void addStrengthParam(int strength) {
+        BassBoost bb;
+        bb.set<BassBoost::strengthPm>(strength);
+        mTags.push_back({BassBoost::strengthPm, bb});
+    }
+
+  private:
+    std::vector<std::pair<BassBoost::Tag, BassBoost>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(BassBoostParamTest, SetAndGetStrength) {
+    EXPECT_NO_FATAL_FAILURE(addStrengthParam(mParamStrength));
+    SetAndGetBassBoostParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        BassBoostTest, BassBoostParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidBassBoost())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<BassBoost, int, Range::bassBoost,
+                                                                BassBoost::strengthPm>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<BassBoostParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string strength = std::to_string(std::get<PARAM_STRENGTH>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_strength_" + strength;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BassBoostParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
new file mode 100644
index 0000000..5aeebde
--- /dev/null
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalDownmixTargetTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::Downmix;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_TYPE };
+using DownmixParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Downmix::Type>;
+
+// Testing for enum values
+const std::vector<Downmix::Type> kTypeValues = {Downmix::Type::STRIP, Downmix::Type::FOLD};
+
+class DownmixParamTest : public ::testing::TestWithParam<DownmixParamTestParam>,
+                         public EffectHelper {
+  public:
+    DownmixParamTest() : mParamType(std::get<PARAM_TYPE>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    Downmix::Type mParamType = Downmix::Type::STRIP;
+
+    void SetAndGetDownmixParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& dm = it.second;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::downmix>(dm);
+            expectParam.set<Parameter::specific>(specific);
+            // All values are valid, set parameter should succeed
+            EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // get parameter
+            Parameter getParam;
+            Parameter::Id id;
+            Downmix::Id dmId;
+            dmId.set<Downmix::Id::commonTag>(tag);
+            id.set<Parameter::Id::downmixTag>(dmId);
+            EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+            EXPECT_EQ(expectParam, getParam);
+        }
+    }
+
+    void addTypeParam(Downmix::Type type) {
+        Downmix dm;
+        dm.set<Downmix::type>(type);
+        mTags.push_back({Downmix::type, dm});
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        Downmix dm = Downmix::make<Downmix::type>(Downmix::Type::STRIP);
+        Parameter::Specific specific = Parameter::Specific::make<Parameter::Specific::downmix>(dm);
+        return specific;
+    }
+
+  private:
+    std::vector<std::pair<Downmix::Tag, Downmix>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(DownmixParamTest, SetAndGetType) {
+    EXPECT_NO_FATAL_FAILURE(addTypeParam(mParamType));
+    SetAndGetDownmixParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        DownmixTest, DownmixParamTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidDownmix())),
+                           testing::ValuesIn(kTypeValues)),
+        [](const testing::TestParamInfo<DownmixParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string type = std::to_string(static_cast<int>(std::get<PARAM_TYPE>(info.param)));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_type" + type;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
new file mode 100644
index 0000000..033e3b5
--- /dev/null
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -0,0 +1,1004 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <set>
+#include <string>
+#include <unordered_set>
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalDynamicsProcessingTest"
+#include <android-base/logging.h>
+
+#include <Utils.h>
+
+#include "EffectHelper.h"
+#include "EffectRangeSpecific.h"
+
+using namespace android;
+using namespace aidl::android::hardware::audio::effect::DynamicsProcessingRanges;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::DynamicsProcessing;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+class DynamicsProcessingTestHelper : public EffectHelper {
+  public:
+    DynamicsProcessingTestHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> pair,
+                                 int32_t channelLayOut = AudioChannelLayout::LAYOUT_STEREO) {
+        std::tie(mFactory, mDescriptor) = pair;
+        mChannelLayout = channelLayOut;
+        mChannelCount = ::aidl::android::hardware::audio::common::getChannelCount(
+                AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout));
+    }
+
+    // setup
+    void SetUpDynamicsProcessingEffect() {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                0x100 /* iFrameCount */, 0x100 /* oFrameCount */,
+                AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout),
+                AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChannelLayout));
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+        mEngineConfigApplied = mEngineConfigPreset;
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        DynamicsProcessing dp = DynamicsProcessing::make<DynamicsProcessing::engineArchitecture>(
+                mEngineConfigPreset);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::dynamicsProcessing>(dp);
+        return specific;
+    }
+
+    // teardown
+    void TearDownDynamicsProcessingEffect() {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    // utils functions for parameter checking
+    bool isParamEqual(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dpRef,
+                      const DynamicsProcessing& dpTest);
+    bool isEngineConfigEqual(const DynamicsProcessing::EngineArchitecture& refCfg,
+                             const DynamicsProcessing::EngineArchitecture& testCfg);
+
+    template <typename T>
+    std::vector<T> filterEnabledVector(const std::vector<T>& vec);
+
+    template <typename T>
+    bool isAidlVectorEqualAfterFilter(const std::vector<T>& source, const std::vector<T>& target);
+
+    template <typename T>
+    bool isAidlVectorEqual(const std::vector<T>& source, const std::vector<T>& target);
+
+    template <typename T>
+    bool isChannelConfigValid(const std::vector<T>& cfgs) {
+        auto& channelCount = mChannelCount;
+        return std::all_of(cfgs.cbegin(), cfgs.cend(), [channelCount](const T& cfg) {
+            return (cfg.channel >= 0 && cfg.channel < channelCount);
+        });
+    }
+
+    template <typename T>
+    bool isBandConfigValid(const std::vector<T>& cfgs, int bandCount);
+
+    bool isParamValid(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dp);
+
+    // get set params and validate
+    void SetAndGetDynamicsProcessingParameters();
+
+    // enqueue test parameters
+    void addEngineConfig(const DynamicsProcessing::EngineArchitecture& cfg);
+    void addPreEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
+    void addPostEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
+    void addMbcChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
+    void addPreEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
+    void addPostEqBandConfigs(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs);
+    void addMbcBandConfigs(const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs);
+    void addLimiterConfig(const std::vector<DynamicsProcessing::LimiterConfig>& cfg);
+    void addInputGain(const std::vector<DynamicsProcessing::InputGain>& inputGain);
+
+    static constexpr float kPreferredProcessingDurationMs = 10.0f;
+    static constexpr int kBandCount = 5;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    DynamicsProcessing::EngineArchitecture mEngineConfigApplied;
+    DynamicsProcessing::EngineArchitecture mEngineConfigPreset{
+            .resolutionPreference =
+                    DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
+            .preferredProcessingDurationMs = kPreferredProcessingDurationMs,
+            .preEqStage = {.inUse = true, .bandCount = kBandCount},
+            .postEqStage = {.inUse = true, .bandCount = kBandCount},
+            .mbcStage = {.inUse = true, .bandCount = kBandCount},
+            .limiterInUse = true,
+    };
+
+    std::unordered_set<int /* channelId */> mPreEqChannelEnable;
+    std::unordered_set<int /* channelId */> mPostEqChannelEnable;
+    std::unordered_set<int /* channelId */> mMbcChannelEnable;
+    std::unordered_set<int /* channelId */> mLimiterChannelEnable;
+    static const std::set<std::vector<DynamicsProcessing::ChannelConfig>> kChannelConfigTestSet;
+    static const std::set<DynamicsProcessing::StageEnablement> kStageEnablementTestSet;
+    static const std::set<std::vector<DynamicsProcessing::InputGain>> kInputGainTestSet;
+
+  protected:
+    int mChannelCount;
+
+  private:
+    int32_t mChannelLayout;
+    std::vector<std::pair<DynamicsProcessing::Tag, DynamicsProcessing>> mTags;
+    void CleanUp() {
+        mTags.clear();
+        mPreEqChannelEnable.clear();
+        mPostEqChannelEnable.clear();
+        mMbcChannelEnable.clear();
+        mLimiterChannelEnable.clear();
+    }
+};
+
+// test value set for DynamicsProcessing::StageEnablement
+const std::set<DynamicsProcessing::StageEnablement>
+        DynamicsProcessingTestHelper::kStageEnablementTestSet = {
+                {.inUse = true, .bandCount = DynamicsProcessingTestHelper::kBandCount},
+                {.inUse = true, .bandCount = 0},
+                {.inUse = true, .bandCount = -1},
+                {.inUse = false, .bandCount = 0},
+                {.inUse = false, .bandCount = -1},
+                {.inUse = false, .bandCount = DynamicsProcessingTestHelper::kBandCount}};
+
+// test value set for DynamicsProcessing::ChannelConfig
+const std::set<std::vector<DynamicsProcessing::ChannelConfig>>
+        DynamicsProcessingTestHelper::kChannelConfigTestSet = {
+                {{.channel = -1, .enable = false},
+                 {.channel = 0, .enable = true},
+                 {.channel = 1, .enable = false},
+                 {.channel = 2, .enable = true}},
+                {{.channel = -1, .enable = false}, {.channel = 2, .enable = true}},
+                {{.channel = 0, .enable = true}, {.channel = 1, .enable = true}}};
+
+// test value set for DynamicsProcessing::InputGain
+const std::set<std::vector<DynamicsProcessing::InputGain>>
+        DynamicsProcessingTestHelper::kInputGainTestSet = {
+                {{.channel = 0, .gainDb = 10.f},
+                 {.channel = 1, .gainDb = 0.f},
+                 {.channel = 2, .gainDb = -10.f}},
+                {{.channel = -1, .gainDb = -10.f}, {.channel = -2, .gainDb = 10.f}},
+                {{.channel = -1, .gainDb = 10.f}, {.channel = 0, .gainDb = -10.f}},
+                {{.channel = 0, .gainDb = 10.f}, {.channel = 1, .gainDb = -10.f}}};
+
+template <typename T>
+bool DynamicsProcessingTestHelper::isBandConfigValid(const std::vector<T>& cfgs, int bandCount) {
+    std::vector<float> freqs(cfgs.size(), -1);
+    for (auto cfg : cfgs) {
+        if (cfg.channel < 0 || cfg.channel >= mChannelCount) return false;
+        if (cfg.band < 0 || cfg.band >= bandCount) return false;
+        freqs[cfg.band] = cfg.cutoffFrequencyHz;
+    }
+    if (std::count(freqs.begin(), freqs.end(), -1)) return false;
+    return std::is_sorted(freqs.begin(), freqs.end());
+}
+
+bool DynamicsProcessingTestHelper::isParamValid(const DynamicsProcessing::Tag& tag,
+                                                const DynamicsProcessing& dp) {
+    switch (tag) {
+        case DynamicsProcessing::preEq: {
+            if (!mEngineConfigApplied.preEqStage.inUse) return false;
+            return isChannelConfigValid(dp.get<DynamicsProcessing::preEq>());
+        }
+        case DynamicsProcessing::postEq: {
+            if (!mEngineConfigApplied.postEqStage.inUse) return false;
+            return isChannelConfigValid(dp.get<DynamicsProcessing::postEq>());
+        }
+        case DynamicsProcessing::mbc: {
+            if (!mEngineConfigApplied.mbcStage.inUse) return false;
+            return isChannelConfigValid(dp.get<DynamicsProcessing::mbc>());
+        }
+        case DynamicsProcessing::preEqBand: {
+            if (!mEngineConfigApplied.preEqStage.inUse) return false;
+            return isBandConfigValid(dp.get<DynamicsProcessing::preEqBand>(),
+                                     mEngineConfigApplied.preEqStage.bandCount);
+        }
+        case DynamicsProcessing::postEqBand: {
+            if (!mEngineConfigApplied.postEqStage.inUse) return false;
+            return isBandConfigValid(dp.get<DynamicsProcessing::postEqBand>(),
+                                     mEngineConfigApplied.postEqStage.bandCount);
+        }
+        case DynamicsProcessing::mbcBand: {
+            if (!mEngineConfigApplied.mbcStage.inUse) return false;
+            return isBandConfigValid(dp.get<DynamicsProcessing::mbcBand>(),
+                                     mEngineConfigApplied.mbcStage.bandCount);
+        }
+        case DynamicsProcessing::limiter: {
+            if (!mEngineConfigApplied.limiterInUse) return false;
+            return isChannelConfigValid(dp.get<DynamicsProcessing::limiter>());
+        }
+        case DynamicsProcessing::inputGain: {
+            return isChannelConfigValid(dp.get<DynamicsProcessing::inputGain>());
+        }
+        default: {
+            return true;
+        }
+    }
+    return true;
+}
+
+bool DynamicsProcessingTestHelper::isParamEqual(const DynamicsProcessing::Tag& tag,
+                                                const DynamicsProcessing& dpRef,
+                                                const DynamicsProcessing& dpTest) {
+    switch (tag) {
+        case DynamicsProcessing::engineArchitecture: {
+            return isEngineConfigEqual(dpRef.get<DynamicsProcessing::engineArchitecture>(),
+                                       dpTest.get<DynamicsProcessing::engineArchitecture>());
+        }
+        case DynamicsProcessing::preEq: {
+            const auto& source = dpRef.get<DynamicsProcessing::preEq>();
+            const auto& target = dpTest.get<DynamicsProcessing::preEq>();
+            return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(source, target);
+        }
+        case DynamicsProcessing::postEq: {
+            return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(
+                    dpRef.get<DynamicsProcessing::postEq>(),
+                    dpTest.get<DynamicsProcessing::postEq>());
+        }
+        case DynamicsProcessing::mbc: {
+            return isAidlVectorEqualAfterFilter<DynamicsProcessing::ChannelConfig>(
+                    dpRef.get<DynamicsProcessing::mbc>(), dpTest.get<DynamicsProcessing::mbc>());
+        }
+        case DynamicsProcessing::preEqBand: {
+            return isAidlVectorEqualAfterFilter<DynamicsProcessing::EqBandConfig>(
+                    dpRef.get<DynamicsProcessing::preEqBand>(),
+                    dpTest.get<DynamicsProcessing::preEqBand>());
+        }
+        case DynamicsProcessing::postEqBand: {
+            return isAidlVectorEqualAfterFilter<DynamicsProcessing::EqBandConfig>(
+                    dpRef.get<DynamicsProcessing::postEqBand>(),
+                    dpTest.get<DynamicsProcessing::postEqBand>());
+        }
+        case DynamicsProcessing::mbcBand: {
+            return isAidlVectorEqualAfterFilter<DynamicsProcessing::MbcBandConfig>(
+                    dpRef.get<DynamicsProcessing::mbcBand>(),
+                    dpTest.get<DynamicsProcessing::mbcBand>());
+        }
+        case DynamicsProcessing::limiter: {
+            return isAidlVectorEqualAfterFilter<DynamicsProcessing::LimiterConfig>(
+                    dpRef.get<DynamicsProcessing::limiter>(),
+                    dpTest.get<DynamicsProcessing::limiter>());
+        }
+        case DynamicsProcessing::inputGain: {
+            return isAidlVectorEqual<DynamicsProcessing::InputGain>(
+                    dpRef.get<DynamicsProcessing::inputGain>(),
+                    dpTest.get<DynamicsProcessing::inputGain>());
+        }
+        case DynamicsProcessing::vendor: {
+            return false;
+        }
+    }
+}
+
+bool DynamicsProcessingTestHelper::isEngineConfigEqual(
+        const DynamicsProcessing::EngineArchitecture& ref,
+        const DynamicsProcessing::EngineArchitecture& test) {
+    return ref == test;
+}
+
+template <typename T>
+std::vector<T> DynamicsProcessingTestHelper::filterEnabledVector(const std::vector<T>& vec) {
+    std::vector<T> ret;
+    std::copy_if(vec.begin(), vec.end(), std::back_inserter(ret),
+                 [](const auto& v) { return v.enable; });
+    return ret;
+}
+
+template <typename T>
+bool DynamicsProcessingTestHelper::isAidlVectorEqual(const std::vector<T>& source,
+                                                     const std::vector<T>& target) {
+    if (source.size() != target.size()) return false;
+
+    auto tempS = source;
+    auto tempT = target;
+    std::sort(tempS.begin(), tempS.end());
+    std::sort(tempT.begin(), tempT.end());
+    return tempS == tempT;
+}
+
+template <typename T>
+bool DynamicsProcessingTestHelper::isAidlVectorEqualAfterFilter(const std::vector<T>& source,
+                                                                const std::vector<T>& target) {
+    return isAidlVectorEqual<T>(filterEnabledVector<T>(source), filterEnabledVector<T>(target));
+}
+
+void DynamicsProcessingTestHelper::SetAndGetDynamicsProcessingParameters() {
+    for (auto& it : mTags) {
+        auto& tag = it.first;
+        auto& dp = it.second;
+
+        // validate parameter
+        Descriptor desc;
+        ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+        bool valid = isParamInRange(dp, desc.capability.range.get<Range::dynamicsProcessing>());
+        if (valid) valid = isParamValid(tag, dp);
+        const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+        // set parameter
+        Parameter expectParam;
+        Parameter::Specific specific;
+        specific.set<Parameter::Specific::dynamicsProcessing>(dp);
+        expectParam.set<Parameter::specific>(specific);
+        ASSERT_STATUS(expected, mEffect->setParameter(expectParam))
+                << "\n"
+                << expectParam.toString() << "\n"
+                << desc.toString();
+
+        // only get if parameter in range and set success
+        if (expected == EX_NONE) {
+            Parameter getParam;
+            Parameter::Id id;
+            DynamicsProcessing::Id dpId;
+            dpId.set<DynamicsProcessing::Id::commonTag>(tag);
+            id.set<Parameter::Id::dynamicsProcessingTag>(dpId);
+            // if set success, then get should match
+            EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+            Parameter::Specific specificTest = getParam.get<Parameter::specific>();
+            const auto& target = specificTest.get<Parameter::Specific::dynamicsProcessing>();
+            EXPECT_TRUE(isParamEqual(tag, dp, target)) << dp.toString() << "\n"
+                                                       << target.toString();
+            // update mEngineConfigApplied after setting successfully
+            if (tag == DynamicsProcessing::engineArchitecture) {
+                mEngineConfigApplied = target.get<DynamicsProcessing::engineArchitecture>();
+            }
+        }
+    }
+}
+
+void DynamicsProcessingTestHelper::addEngineConfig(
+        const DynamicsProcessing::EngineArchitecture& cfg) {
+    DynamicsProcessing dp;
+    dp.set<DynamicsProcessing::engineArchitecture>(cfg);
+    mTags.push_back({DynamicsProcessing::engineArchitecture, dp});
+}
+
+void DynamicsProcessingTestHelper::addPreEqChannelConfig(
+        const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
+    DynamicsProcessing dp;
+    dp.set<DynamicsProcessing::preEq>(cfgs);
+    mTags.push_back({DynamicsProcessing::preEq, dp});
+    for (auto& cfg : cfgs) {
+        if (cfg.enable) mPreEqChannelEnable.insert(cfg.channel);
+    }
+}
+
+void DynamicsProcessingTestHelper::addPostEqChannelConfig(
+        const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
+    DynamicsProcessing dp;
+    dp.set<DynamicsProcessing::postEq>(cfgs);
+    mTags.push_back({DynamicsProcessing::postEq, dp});
+    for (auto& cfg : cfgs) {
+        if (cfg.enable) mPostEqChannelEnable.insert(cfg.channel);
+    }
+}
+
+void DynamicsProcessingTestHelper::addMbcChannelConfig(
+        const std::vector<DynamicsProcessing::ChannelConfig>& cfgs) {
+    DynamicsProcessing dp;
+    dp.set<DynamicsProcessing::mbc>(cfgs);
+    mTags.push_back({DynamicsProcessing::mbc, dp});
+    for (auto& cfg : cfgs) {
+        if (cfg.enable) mMbcChannelEnable.insert(cfg.channel);
+    }
+}
+
+void DynamicsProcessingTestHelper::addPreEqBandConfigs(
+        const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
+    DynamicsProcessing dp;
+    dp.set<DynamicsProcessing::preEqBand>(cfgs);
+    mTags.push_back({DynamicsProcessing::preEqBand, dp});
+}
+
+void DynamicsProcessingTestHelper::addPostEqBandConfigs(
+        const std::vector<DynamicsProcessing::EqBandConfig>& cfgs) {
+    DynamicsProcessing dp;
+    dp.set<DynamicsProcessing::postEqBand>(cfgs);
+    mTags.push_back({DynamicsProcessing::postEqBand, dp});
+}
+
+void DynamicsProcessingTestHelper::addMbcBandConfigs(
+        const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs) {
+    DynamicsProcessing dp;
+    dp.set<DynamicsProcessing::mbcBand>(cfgs);
+    mTags.push_back({DynamicsProcessing::mbcBand, dp});
+}
+
+void DynamicsProcessingTestHelper::addLimiterConfig(
+        const std::vector<DynamicsProcessing::LimiterConfig>& cfgs) {
+    DynamicsProcessing dp;
+    dp.set<DynamicsProcessing::limiter>(cfgs);
+    mTags.push_back({DynamicsProcessing::limiter, dp});
+    for (auto& cfg : cfgs) {
+        if (cfg.enable) mLimiterChannelEnable.insert(cfg.channel);
+    }
+}
+
+void DynamicsProcessingTestHelper::addInputGain(
+        const std::vector<DynamicsProcessing::InputGain>& inputGains) {
+    DynamicsProcessing dp;
+    dp.set<DynamicsProcessing::inputGain>(inputGains);
+    mTags.push_back({DynamicsProcessing::inputGain, dp});
+}
+
+/**
+ * Test DynamicsProcessing Engine Configuration
+ */
+enum EngineArchitectureTestParamName {
+    ENGINE_TEST_INSTANCE_NAME,
+    ENGINE_TEST_RESOLUTION_PREFERENCE,
+    ENGINE_TEST_PREFERRED_DURATION,
+    ENGINE_TEST_STAGE_ENABLEMENT,
+    ENGINE_TEST_LIMITER_IN_USE
+};
+using EngineArchitectureTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
+                                                DynamicsProcessing::ResolutionPreference, float,
+                                                DynamicsProcessing::StageEnablement, bool>;
+
+void fillEngineArchConfig(DynamicsProcessing::EngineArchitecture& cfg,
+                          const EngineArchitectureTestParams& params) {
+    cfg.resolutionPreference = std::get<ENGINE_TEST_RESOLUTION_PREFERENCE>(params);
+    cfg.preferredProcessingDurationMs = std::get<ENGINE_TEST_PREFERRED_DURATION>(params);
+    cfg.preEqStage = cfg.postEqStage = cfg.mbcStage =
+            std::get<ENGINE_TEST_STAGE_ENABLEMENT>(params);
+    cfg.limiterInUse = std::get<ENGINE_TEST_LIMITER_IN_USE>(params);
+}
+
+class DynamicsProcessingTestEngineArchitecture
+    : public ::testing::TestWithParam<EngineArchitectureTestParams>,
+      public DynamicsProcessingTestHelper {
+  public:
+    DynamicsProcessingTestEngineArchitecture()
+        : DynamicsProcessingTestHelper(std::get<ENGINE_TEST_INSTANCE_NAME>(GetParam())) {
+        fillEngineArchConfig(mCfg, GetParam());
+    };
+
+    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+
+    void TearDown() override { TearDownDynamicsProcessingEffect(); }
+
+    DynamicsProcessing::EngineArchitecture mCfg;
+};
+
+TEST_P(DynamicsProcessingTestEngineArchitecture, SetAndGetEngineArch) {
+    EXPECT_NO_FATAL_FAILURE(addEngineConfig(mCfg));
+    SetAndGetDynamicsProcessingParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        DynamicsProcessingTest, DynamicsProcessingTestEngineArchitecture,
+        ::testing::Combine(
+                testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                        IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                testing::Values(
+                        DynamicsProcessing::ResolutionPreference::FAVOR_TIME_RESOLUTION,
+                        DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
+                        static_cast<DynamicsProcessing::ResolutionPreference>(-1)),  // variant
+                testing::Values(-10.f, 0.f, 10.f),  // processing duration
+                testing::ValuesIn(
+                        DynamicsProcessingTestHelper::kStageEnablementTestSet),  // preEQ/postEQ/mbc
+                testing::Bool()),                                                // limiter enable
+        [](const auto& info) {
+            auto descriptor = std::get<ENGINE_TEST_INSTANCE_NAME>(info.param).second;
+            DynamicsProcessing::EngineArchitecture cfg;
+            fillEngineArchConfig(cfg, info.param);
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_Cfg_" + cfg.toString();
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEngineArchitecture);
+
+/**
+ * Test DynamicsProcessing Input Gain
+ */
+enum InputGainTestParamName {
+    INPUT_GAIN_INSTANCE_NAME,
+    INPUT_GAIN_PARAM,
+};
+class DynamicsProcessingTestInputGain
+    : public ::testing::TestWithParam<std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
+                                                 std::vector<DynamicsProcessing::InputGain>>>,
+      public DynamicsProcessingTestHelper {
+  public:
+    DynamicsProcessingTestInputGain()
+        : DynamicsProcessingTestHelper(std::get<INPUT_GAIN_INSTANCE_NAME>(GetParam())),
+          mInputGain(std::get<INPUT_GAIN_PARAM>(GetParam())){};
+
+    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+
+    void TearDown() override { TearDownDynamicsProcessingEffect(); }
+
+    const std::vector<DynamicsProcessing::InputGain> mInputGain;
+};
+
+TEST_P(DynamicsProcessingTestInputGain, SetAndGetInputGain) {
+    EXPECT_NO_FATAL_FAILURE(addInputGain(mInputGain));
+    SetAndGetDynamicsProcessingParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        DynamicsProcessingTest, DynamicsProcessingTestInputGain,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                           testing::ValuesIn(DynamicsProcessingTestInputGain::kInputGainTestSet)),
+        [](const auto& info) {
+            auto descriptor = std::get<INPUT_GAIN_INSTANCE_NAME>(info.param).second;
+            std::string gains =
+                    ::android::internal::ToString(std::get<INPUT_GAIN_PARAM>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_inputGains_" + gains;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestInputGain);
+
+/**
+ * Test DynamicsProcessing Limiter Config
+ */
+enum LimiterConfigTestParamName {
+    LIMITER_INSTANCE_NAME,
+    LIMITER_CHANNEL,
+    LIMITER_ENABLE,
+    LIMITER_LINK_GROUP,
+    LIMITER_ENGINE_IN_USE,
+    LIMITER_ADDITIONAL,
+};
+enum LimiterConfigTestAdditionalParam {
+    LIMITER_ATTACK_TIME,
+    LIMITER_RELEASE_TIME,
+    LIMITER_RATIO,
+    LIMITER_THRESHOLD,
+    LIMITER_POST_GAIN,
+    LIMITER_MAX_NUM,
+};
+using LimiterConfigTestAdditional = std::array<float, LIMITER_MAX_NUM>;
+// attackTime, releaseTime, ratio, thresh, postGain
+static constexpr std::array<LimiterConfigTestAdditional, 4> kLimiterConfigTestAdditionalParam = {
+        {{-1, -60, -2.5, -2, -3.14},
+         {-1, 60, -2.5, 2, -3.14},
+         {1, -60, 2.5, -2, 3.14},
+         {1, 60, 2.5, -2, 3.14}}};
+
+using LimiterConfigTestParams =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool, int32_t, bool,
+                   LimiterConfigTestAdditional>;
+
+void fillLimiterConfig(DynamicsProcessing::LimiterConfig& cfg,
+                       const LimiterConfigTestParams& params) {
+    const std::array<float, LIMITER_MAX_NUM> additional = std::get<LIMITER_ADDITIONAL>(params);
+    cfg.channel = std::get<LIMITER_CHANNEL>(params);
+    cfg.enable = std::get<LIMITER_ENABLE>(params);
+    cfg.linkGroup = std::get<LIMITER_LINK_GROUP>(params);
+    cfg.attackTimeMs = additional[LIMITER_ATTACK_TIME];
+    cfg.releaseTimeMs = additional[LIMITER_RELEASE_TIME];
+    cfg.ratio = additional[LIMITER_RATIO];
+    cfg.thresholdDb = additional[LIMITER_THRESHOLD];
+    cfg.postGainDb = additional[LIMITER_POST_GAIN];
+}
+
+class DynamicsProcessingTestLimiterConfig
+    : public ::testing::TestWithParam<LimiterConfigTestParams>,
+      public DynamicsProcessingTestHelper {
+  public:
+    DynamicsProcessingTestLimiterConfig()
+        : DynamicsProcessingTestHelper(std::get<LIMITER_INSTANCE_NAME>(GetParam())),
+          mLimiterInUseEngine(std::get<LIMITER_ENGINE_IN_USE>(GetParam())) {
+        fillLimiterConfig(mCfg, GetParam());
+    }
+
+    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+
+    void TearDown() override { TearDownDynamicsProcessingEffect(); }
+
+    DynamicsProcessing::LimiterConfig mCfg;
+    bool mLimiterInUseEngine;
+};
+
+TEST_P(DynamicsProcessingTestLimiterConfig, SetAndGetLimiterConfig) {
+    mEngineConfigPreset.limiterInUse = mLimiterInUseEngine;
+    EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
+    EXPECT_NO_FATAL_FAILURE(addLimiterConfig({mCfg}));
+    SetAndGetDynamicsProcessingParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        DynamicsProcessingTest, DynamicsProcessingTestLimiterConfig,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                           testing::Values(-1, 0, 1, 2),  // channel count
+                           testing::Bool(),               // enable
+                           testing::Values(3),            // link group
+                           testing::Bool(),               // engine limiter enable
+                           testing::ValuesIn(kLimiterConfigTestAdditionalParam)),  // Additional
+        [](const auto& info) {
+            auto descriptor = std::get<LIMITER_INSTANCE_NAME>(info.param).second;
+            DynamicsProcessing::LimiterConfig cfg;
+            fillLimiterConfig(cfg, info.param);
+            std::string engineLimiterInUse =
+                    std::to_string(std::get<LIMITER_ENGINE_IN_USE>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_limiterConfig_" +
+                               cfg.toString() + "_engineSetting_" + engineLimiterInUse;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestLimiterConfig);
+
+/**
+ * Test DynamicsProcessing ChannelConfig
+ */
+enum ChannelConfigTestParamName {
+    BAND_CHANNEL_TEST_INSTANCE_NAME,
+    BAND_CHANNEL_TEST_CHANNEL_CONFIG,
+    BAND_CHANNEL_TEST_ENGINE_IN_USE
+};
+using ChannelConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
+                                           std::vector<DynamicsProcessing::ChannelConfig>, bool>;
+
+class DynamicsProcessingTestChannelConfig
+    : public ::testing::TestWithParam<ChannelConfigTestParams>,
+      public DynamicsProcessingTestHelper {
+  public:
+    DynamicsProcessingTestChannelConfig()
+        : DynamicsProcessingTestHelper(std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(GetParam())),
+          mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())),
+          mInUseEngine(std::get<BAND_CHANNEL_TEST_ENGINE_IN_USE>(GetParam())) {}
+
+    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+
+    void TearDown() override { TearDownDynamicsProcessingEffect(); }
+
+    std::vector<DynamicsProcessing::ChannelConfig> mCfg;
+    const bool mInUseEngine;
+};
+
+TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPreEqChannelConfig) {
+    mEngineConfigPreset.preEqStage.inUse = mInUseEngine;
+    EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
+    EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(mCfg));
+    SetAndGetDynamicsProcessingParameters();
+}
+
+TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPostEqChannelConfig) {
+    mEngineConfigPreset.postEqStage.inUse = mInUseEngine;
+    EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
+    EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(mCfg));
+    SetAndGetDynamicsProcessingParameters();
+}
+
+TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetMbcChannelConfig) {
+    mEngineConfigPreset.mbcStage.inUse = mInUseEngine;
+    EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
+    EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(mCfg));
+    SetAndGetDynamicsProcessingParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        DynamicsProcessingTest, DynamicsProcessingTestChannelConfig,
+        ::testing::Combine(
+                testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                        IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                testing::ValuesIn(
+                        DynamicsProcessingTestHelper::kChannelConfigTestSet),  // channel config
+                testing::Bool()),                                              // Engine inUse
+        [](const auto& info) {
+            auto descriptor = std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(info.param).second;
+            std::string engineInUse =
+                    std::to_string(std::get<BAND_CHANNEL_TEST_ENGINE_IN_USE>(info.param));
+            std::string channelConfig = ::android::internal::ToString(
+                    std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_" + channelConfig +
+                               "_engineInUse_" + engineInUse;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestChannelConfig);
+
+/**
+ * Test DynamicsProcessing EqBandConfig
+ */
+enum EqBandConfigTestParamName {
+    EQ_BAND_INSTANCE_NAME,
+    EQ_BAND_CHANNEL,
+    EQ_BAND_ENABLE,
+    EQ_BAND_CUT_OFF_FREQ,
+    EQ_BAND_GAIN,
+    EQ_BAND_STAGE_IN_USE
+};
+using EqBandConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
+                                          bool, std::vector<std::pair<int, float>>, float, bool>;
+
+void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
+                      const EqBandConfigTestParams& params) {
+    const std::vector<std::pair<int, float>> cutOffFreqs = std::get<EQ_BAND_CUT_OFF_FREQ>(params);
+    int bandCount = cutOffFreqs.size();
+    cfgs.resize(bandCount);
+    for (int i = 0; i < bandCount; i++) {
+        cfgs[i].channel = std::get<EQ_BAND_CHANNEL>(params);
+        cfgs[i].band = cutOffFreqs[i].first;
+        cfgs[i].enable = std::get<EQ_BAND_ENABLE>(params);
+        cfgs[i].cutoffFrequencyHz = cutOffFreqs[i].second;
+        cfgs[i].gainDb = std::get<EQ_BAND_GAIN>(params);
+    }
+}
+
+class DynamicsProcessingTestEqBandConfig : public ::testing::TestWithParam<EqBandConfigTestParams>,
+                                           public DynamicsProcessingTestHelper {
+  public:
+    DynamicsProcessingTestEqBandConfig()
+        : DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())),
+          mStageInUse(std::get<EQ_BAND_STAGE_IN_USE>(GetParam())) {
+        fillEqBandConfig(mCfgs, GetParam());
+    }
+
+    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+
+    void TearDown() override { TearDownDynamicsProcessingEffect(); }
+
+    std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
+    const bool mStageInUse;
+};
+
+TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPreEqBandConfig) {
+    mEngineConfigPreset.preEqStage.inUse = mStageInUse;
+    mEngineConfigPreset.preEqStage.bandCount = mCfgs.size();
+    EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
+    std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
+    for (int i = 0; i < mChannelCount; i++) {
+        cfgs[i].channel = i;
+        cfgs[i].enable = true;
+    }
+    EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(cfgs));
+    EXPECT_NO_FATAL_FAILURE(addPreEqBandConfigs(mCfgs));
+    SetAndGetDynamicsProcessingParameters();
+}
+
+TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPostEqBandConfig) {
+    mEngineConfigPreset.postEqStage.inUse = mStageInUse;
+    mEngineConfigPreset.postEqStage.bandCount = mCfgs.size();
+    EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
+    std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
+    for (int i = 0; i < mChannelCount; i++) {
+        cfgs[i].channel = i;
+        cfgs[i].enable = true;
+    }
+    EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(cfgs));
+    EXPECT_NO_FATAL_FAILURE(addPostEqBandConfigs(mCfgs));
+    SetAndGetDynamicsProcessingParameters();
+}
+
+std::vector<std::vector<std::pair<int, float>>> kBands{
+        {
+                {0, 600},
+                {1, 2000},
+                {2, 6000},
+                {3, 10000},
+                {4, 16000},
+        },  // 5 bands
+        {
+                {0, 800},
+                {3, 15000},
+                {2, 6000},
+                {1, 2000},
+        },  // 4 bands, unsorted
+        {
+                {0, 650},
+                {1, 2000},
+                {2, 6000},
+                {3, 10000},
+                {3, 16000},
+        },  // 5 bands, missing band
+        {
+                {0, 900},
+                {1, 8000},
+                {2, 4000},
+                {3, 12000},
+        },  // 4 bands, cutoff freq not increasing
+        {
+                {0, 450},
+                {1, 2000},
+                {7, 6000},
+                {3, 10000},
+                {4, 16000},
+        },  // bad band index
+        {
+                {0, 1},
+                {1, 8000},
+        },  // too low cutoff freq
+        {
+                {0, 1200},
+                {1, 80000},
+        },  // too high cutoff freq
+};
+
+INSTANTIATE_TEST_SUITE_P(
+        DynamicsProcessingTest, DynamicsProcessingTestEqBandConfig,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                           testing::Values(-1, 0, 10),      // channel ID
+                           testing::Bool(),                 // band enable
+                           testing::ValuesIn(kBands),       // cut off frequencies
+                           testing::Values(-3.14f, 3.14f),  // gain
+                           testing::Values(true)),          // stage in use
+        [](const auto& info) {
+            auto descriptor = std::get<EQ_BAND_INSTANCE_NAME>(info.param).second;
+            std::vector<DynamicsProcessing::EqBandConfig> cfgs;
+            fillEqBandConfig(cfgs, info.param);
+            std::string bands = ::android::internal::ToString(cfgs);
+            std::string stageInUse = std::to_string(std::get<EQ_BAND_STAGE_IN_USE>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_bands_" + bands +
+                               "_stageInUse_" + stageInUse;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEqBandConfig);
+
+/**
+ * Test DynamicsProcessing MbcBandConfig
+ */
+
+enum MbcBandConfigParamName {
+    MBC_BAND_INSTANCE_NAME,
+    MBC_BAND_CHANNEL,
+    MBC_BAND_ENABLE,
+    MBC_BAND_CUTOFF_FREQ,
+    MBC_BAND_STAGE_IN_USE,
+    MBC_BAND_ADDITIONAL
+};
+enum MbcBandConfigAdditional {
+    MBC_ADD_ATTACK_TIME,
+    MBC_ADD_RELEASE_TIME,
+    MBC_ADD_RATIO,
+    MBC_ADD_THRESHOLD,
+    MBC_ADD_KNEE_WIDTH,
+    MBC_ADD_NOISE_GATE_THRESHOLD,
+    MBC_ADD_EXPENDER_RATIO,
+    MBC_ADD_PRE_GAIN,
+    MBC_ADD_POST_GAIN,
+    MBC_ADD_MAX_NUM
+};
+using TestParamsMbcBandConfigAdditional = std::array<float, MBC_ADD_MAX_NUM>;
+
+// attackTime, releaseTime, ratio, thresh, kneeWidth, noise, expander, preGain, postGain
+static constexpr std::array<TestParamsMbcBandConfigAdditional, 4> kMbcBandConfigAdditionalParam = {
+        {{-3, -10, -2, -2, -5, -90, -2.5, -2, -2},
+         {0, 0, 0, 0, 0, 0, 0, 0, 0},
+         {-3, 10, -2, 2, -5, 90, -2.5, 2, -2},
+         {3, 10, 2, -2, -5, 90, 2.5, 2, 2}}};
+
+using TestParamsMbcBandConfig =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool,
+                   std::vector<std::pair<int, float>>, bool, TestParamsMbcBandConfigAdditional>;
+
+void fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
+                       const TestParamsMbcBandConfig& params) {
+    const std::vector<std::pair<int, float>> cutOffFreqs = std::get<MBC_BAND_CUTOFF_FREQ>(params);
+    const std::array<float, MBC_ADD_MAX_NUM> additional = std::get<MBC_BAND_ADDITIONAL>(params);
+    int bandCount = cutOffFreqs.size();
+    cfgs.resize(bandCount);
+    for (int i = 0; i < bandCount; i++) {
+        cfgs[i] = DynamicsProcessing::MbcBandConfig{
+                .channel = std::get<MBC_BAND_CHANNEL>(params),
+                .band = cutOffFreqs[i].first,
+                .enable = std::get<MBC_BAND_ENABLE>(params),
+                .cutoffFrequencyHz = cutOffFreqs[i].second,
+                .attackTimeMs = additional[MBC_ADD_ATTACK_TIME],
+                .releaseTimeMs = additional[MBC_ADD_RELEASE_TIME],
+                .ratio = additional[MBC_ADD_RATIO],
+                .thresholdDb = additional[MBC_ADD_THRESHOLD],
+                .kneeWidthDb = additional[MBC_ADD_KNEE_WIDTH],
+                .noiseGateThresholdDb = additional[MBC_ADD_NOISE_GATE_THRESHOLD],
+                .expanderRatio = additional[MBC_ADD_EXPENDER_RATIO],
+                .preGainDb = additional[MBC_ADD_PRE_GAIN],
+                .postGainDb = additional[MBC_ADD_POST_GAIN]};
+    }
+}
+
+class DynamicsProcessingTestMbcBandConfig
+    : public ::testing::TestWithParam<TestParamsMbcBandConfig>,
+      public DynamicsProcessingTestHelper {
+  public:
+    DynamicsProcessingTestMbcBandConfig()
+        : DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())),
+          mStageInUse(std::get<MBC_BAND_STAGE_IN_USE>(GetParam())) {
+        fillMbcBandConfig(mCfgs, GetParam());
+    }
+
+    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+
+    void TearDown() override { TearDownDynamicsProcessingEffect(); }
+
+    std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
+    const bool mStageInUse;
+};
+
+TEST_P(DynamicsProcessingTestMbcBandConfig, SetAndGetMbcBandConfig) {
+    mEngineConfigPreset.mbcStage.inUse = mStageInUse;
+    mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
+    EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
+    std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
+    for (int i = 0; i < mChannelCount; i++) {
+        cfgs[i].channel = i;
+        cfgs[i].enable = true;
+    }
+    EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(cfgs));
+    EXPECT_NO_FATAL_FAILURE(addMbcBandConfigs(mCfgs));
+    SetAndGetDynamicsProcessingParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        DynamicsProcessingTest, DynamicsProcessingTestMbcBandConfig,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                           testing::Values(-1, 0, 10),  // channel count
+                           testing::Bool(),             // enable
+                           testing::ValuesIn(kBands),   // cut off frequencies
+                           testing::Bool(),             // stage in use
+                           testing::ValuesIn(kMbcBandConfigAdditionalParam)),  // Additional
+        [](const auto& info) {
+            auto descriptor = std::get<MBC_BAND_INSTANCE_NAME>(info.param).second;
+            std::vector<DynamicsProcessing::MbcBandConfig> cfgs;
+            fillMbcBandConfig(cfgs, info.param);
+            std::string mbcBands = ::android::internal::ToString(cfgs);
+            std::string stageInUse = std::to_string(std::get<MBC_BAND_STAGE_IN_USE>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_bands_" + mbcBands +
+                               "_stageInUse_" + stageInUse;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestMbcBandConfig);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
new file mode 100644
index 0000000..05c2c5b
--- /dev/null
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalEnvironmentalReverbTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::EnvironmentalReverb;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ * Testing parameter range, assuming the parameter supported by effect is in this range.
+ * This range is verified with IEffect.getDescriptor() and range defined in the documentation, for
+ * any index supported value test expects EX_NONE from IEffect.setParameter(), otherwise expects
+ * EX_ILLEGAL_ARGUMENT.
+ */
+
+class EnvironmentalReverbHelper : public EffectHelper {
+  public:
+    EnvironmentalReverbHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> pair) {
+        std::tie(mFactory, mDescriptor) = pair;
+    }
+
+    void SetUpReverb() {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDownReverb() {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        EnvironmentalReverb er = EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(-6000);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::environmentalReverb>(er);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mRoomLevel = -6000;
+    int mRoomHfLevel = 0;
+    int mDecayTime = 1000;
+    int mDecayHfRatio = 500;
+    int mLevel = -6000;
+    int mDelay = 40;
+    int mDiffusion = 1000;
+    int mDensity = 1000;
+    bool mBypass = false;
+
+    void SetAndGetReverbParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& er = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid = isParameterValid<EnvironmentalReverb, Range::environmentalReverb>(
+                    it.second, desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::environmentalReverb>(er);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                EnvironmentalReverb::Id erId;
+                erId.set<EnvironmentalReverb::Id::commonTag>(tag);
+                id.set<Parameter::Id::environmentalReverbTag>(erId);
+                // if set success, then get should match
+                EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+                EXPECT_EQ(expectParam, getParam);
+            }
+        }
+    }
+
+    void addRoomLevelParam() {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::roomLevelMb>(mRoomLevel);
+        mTags.push_back({EnvironmentalReverb::roomLevelMb, er});
+    }
+
+    void addRoomHfLevelParam(int roomHfLevel) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::roomHfLevelMb>(roomHfLevel);
+        mTags.push_back({EnvironmentalReverb::roomHfLevelMb, er});
+    }
+
+    void addDecayTimeParam(int decayTime) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::decayTimeMs>(decayTime);
+        mTags.push_back({EnvironmentalReverb::decayTimeMs, er});
+    }
+
+    void addDecayHfRatioParam(int decayHfRatio) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::decayHfRatioPm>(decayHfRatio);
+        mTags.push_back({EnvironmentalReverb::decayHfRatioPm, er});
+    }
+
+    void addLevelParam(int level) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::levelMb>(level);
+        mTags.push_back({EnvironmentalReverb::levelMb, er});
+    }
+
+    void addDelayParam(int delay) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::delayMs>(delay);
+        mTags.push_back({EnvironmentalReverb::delayMs, er});
+    }
+
+    void addDiffusionParam(int diffusion) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::diffusionPm>(diffusion);
+        mTags.push_back({EnvironmentalReverb::diffusionPm, er});
+    }
+
+    void addDensityParam(int density) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::densityPm>(density);
+        mTags.push_back({EnvironmentalReverb::densityPm, er});
+    }
+
+    void addBypassParam(bool bypass) {
+        EnvironmentalReverb er;
+        er.set<EnvironmentalReverb::bypass>(bypass);
+        mTags.push_back({EnvironmentalReverb::bypass, er});
+    }
+
+  private:
+    std::vector<std::pair<EnvironmentalReverb::Tag, EnvironmentalReverb>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+class EnvironmentalReverbRoomLevelTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbRoomLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mRoomLevel = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbRoomLevelTest, SetAndGetRoomLevel) {
+    EXPECT_NO_FATAL_FAILURE(addRoomLevelParam());
+    SetAndGetReverbParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbRoomLevelTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+                                                                Range::environmentalReverb,
+                                                                EnvironmentalReverb::roomLevelMb>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<EnvironmentalReverbRoomLevelTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string roomLevel = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_roomLevel" + roomLevel;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomLevelTest);
+
+class EnvironmentalReverbRoomHfLevelTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbRoomHfLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mRoomHfLevel = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbRoomHfLevelTest, SetAndGetRoomHfLevel) {
+    EXPECT_NO_FATAL_FAILURE(addRoomHfLevelParam(mRoomHfLevel));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbRoomHfLevelTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::roomHfLevelMb>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<EnvironmentalReverbRoomHfLevelTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string roomHfLevel = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_roomHfLevel" + roomHfLevel;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomHfLevelTest);
+
+class EnvironmentalReverbDecayTimeTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDecayTimeTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDecayTime = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDecayTimeTest, SetAndGetDecayTime) {
+    EXPECT_NO_FATAL_FAILURE(addDecayTimeParam(mDecayTime));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDecayTimeTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::decayTimeMs>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<EnvironmentalReverbDecayTimeTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string decayTime = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_decayTime" + decayTime;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayTimeTest);
+
+class EnvironmentalReverbDecayHfRatioTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDecayHfRatioTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDecayHfRatio = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDecayHfRatioTest, SetAndGetDecayHfRatio) {
+    EXPECT_NO_FATAL_FAILURE(addDecayHfRatioParam(mDecayHfRatio));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDecayHfRatioTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::decayHfRatioPm>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string decayHfRatio = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_decayHfRatio" +
+                               decayHfRatio;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayHfRatioTest);
+
+class EnvironmentalReverbLevelTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mLevel = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbLevelTest, SetAndGetLevel) {
+    EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbLevelTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::levelMb>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string level = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_level" + level;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbLevelTest);
+
+class EnvironmentalReverbDelayTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDelayTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDelay = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDelayTest, SetAndGetDelay) {
+    EXPECT_NO_FATAL_FAILURE(addDelayParam(mDelay));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDelayTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::delayMs>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<EnvironmentalReverbDelayTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string delay = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_delay" + delay;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDelayTest);
+
+class EnvironmentalReverbDiffusionTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDiffusionTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDiffusion = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDiffusionTest, SetAndGetDiffusion) {
+    EXPECT_NO_FATAL_FAILURE(addDiffusionParam(mDiffusion));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDiffusionTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::diffusionPm>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<EnvironmentalReverbDiffusionTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string diffusion = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_diffusion" + diffusion;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDiffusionTest);
+
+class EnvironmentalReverbDensityTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbDensityTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mDensity = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbDensityTest, SetAndGetDensity) {
+    EXPECT_NO_FATAL_FAILURE(addDensityParam(mDensity));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbDensityTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::ValuesIn(EffectHelper::getTestValueSet<
+                                             EnvironmentalReverb, int, Range::environmentalReverb,
+                                             EnvironmentalReverb::densityPm>(
+                                   kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<EnvironmentalReverbDensityTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string density = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_density" + density;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDensityTest);
+
+class EnvironmentalReverbBypassTest
+    : public ::testing::TestWithParam<
+              std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, bool>>,
+      public EnvironmentalReverbHelper {
+  public:
+    EnvironmentalReverbBypassTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
+        mBypass = std::get<1>(GetParam());
+    }
+
+    void SetUp() override { SetUpReverb(); }
+
+    void TearDown() override { TearDownReverb(); }
+};
+
+TEST_P(EnvironmentalReverbBypassTest, SetAndGetBypass) {
+    EXPECT_NO_FATAL_FAILURE(addBypassParam(mBypass));
+    SetAndGetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        EnvironmentalReverbTest, EnvironmentalReverbBypassTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+                           testing::Bool()),
+        [](const testing::TestParamInfo<EnvironmentalReverbBypassTest::ParamType>& info) {
+            auto descriptor = std::get<0>(info.param).second;
+            std::string bypass = std::to_string(std::get<1>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_bypass" + bypass;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbBypassTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
new file mode 100644
index 0000000..716a2c6
--- /dev/null
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <limits>
+#include <map>
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/effect/IEffect.h>
+#include <aidl/android/hardware/audio/effect/IFactory.h>
+#define LOG_TAG "VtsHalEqualizerTest"
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+
+#include "AudioHalBinderServiceUtil.h"
+#include "EffectHelper.h"
+#include "TestUtils.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::Equalizer;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+
+/**
+ * Here we focus on specific effect (equalizer) parameter checking, general IEffect interfaces
+ * testing performed in VtsAudioEfectTargetTest.
+ */
+
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESET, PARAM_BAND_LEVEL };
+using EqualizerParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
+                                           std::vector<Equalizer::BandLevel>>;
+
+/*
+Testing parameter range, assuming the parameter supported by effect is in this range.
+This range is verified with IEffect.getDescriptor(), for any index supported vts expect EX_NONE
+from IEffect.setParameter(), otherwise expect EX_ILLEGAL_ARGUMENT.
+*/
+const std::vector<int> kBandLevels = {0, -10, 10};  // needs update with implementation
+
+class EqualizerTest : public ::testing::TestWithParam<EqualizerParamTestParam>,
+                      public EffectHelper {
+  public:
+    EqualizerTest()
+        : mPresetIndex(std::get<PARAM_PRESET>(GetParam())),
+          mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mPresetIndex;
+    std::vector<Equalizer::BandLevel> mBandLevel;
+
+    void SetAndGetEqualizerParameters() {
+        ASSERT_NE(nullptr, mEffect);
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& eq = it.second;
+
+            // validate parameter
+            const bool valid = isParameterValid<Equalizer, Range::equalizer>(eq, mDescriptor);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set
+            Parameter::Specific specific =
+                    Parameter::Specific::make<Parameter::Specific::equalizer>(eq);
+            Parameter expectParam = Parameter::make<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam))
+                    << expectParam.toString() << "\n"
+                    << mDescriptor.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Equalizer::Id eqId = Equalizer::Id::make<Equalizer::Id::commonTag>(tag);
+                Parameter::Id id = Parameter::Id::make<Parameter::Id::equalizerTag>(eqId);
+                // if set success, then get should match
+                EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+                EXPECT_TRUE(isEqParameterExpected(expectParam, getParam))
+                        << "\nexpect:" << expectParam.toString()
+                        << "\ngetParam:" << getParam.toString();
+            }
+        }
+    }
+
+    bool isEqParameterExpected(const Parameter& expect, const Parameter& target) {
+        // if parameter same, then for sure they are matched
+        if (expect == target) return true;
+
+        // if not, see if target include the expect parameter, and others all default (0).
+        /*
+         * This is to verify the case of client setParameter to a single bandLevel ({3, -1} for
+         * example), and return of getParameter must be [{0, 0}, {1, 0}, {2, 0}, {3, -1}, {4, 0}]
+         */
+        EXPECT_EQ(expect.getTag(), Parameter::specific);
+        EXPECT_EQ(target.getTag(), Parameter::specific);
+
+        Parameter::Specific expectSpec = expect.get<Parameter::specific>(),
+                            targetSpec = target.get<Parameter::specific>();
+        EXPECT_EQ(expectSpec.getTag(), Parameter::Specific::equalizer);
+        EXPECT_EQ(targetSpec.getTag(), Parameter::Specific::equalizer);
+
+        Equalizer expectEq = expectSpec.get<Parameter::Specific::equalizer>(),
+                  targetEq = targetSpec.get<Parameter::Specific::equalizer>();
+        EXPECT_EQ(expectEq.getTag(), targetEq.getTag());
+
+        auto eqTag = targetEq.getTag();
+        switch (eqTag) {
+            case Equalizer::bandLevels: {
+                auto expectBl = expectEq.get<Equalizer::bandLevels>();
+                std::sort(expectBl.begin(), expectBl.end(),
+                          [](const auto& a, const auto& b) { return a.index < b.index; });
+                expectBl.erase(std::unique(expectBl.begin(), expectBl.end()), expectBl.end());
+                auto targetBl = targetEq.get<Equalizer::bandLevels>();
+                return std::includes(targetBl.begin(), targetBl.end(), expectBl.begin(),
+                                     expectBl.end());
+            }
+            case Equalizer::preset: {
+                return expectEq.get<Equalizer::preset>() == targetEq.get<Equalizer::preset>();
+            }
+            default:
+                return false;
+        }
+        return false;
+    }
+
+    void addPresetParam(int preset) {
+        mTags.push_back({Equalizer::preset, Equalizer::make<Equalizer::preset>(preset)});
+    }
+
+    void addBandLevelsParam(std::vector<Equalizer::BandLevel>& bandLevels) {
+        mTags.push_back(
+                {Equalizer::bandLevels, Equalizer::make<Equalizer::bandLevels>(bandLevels)});
+    }
+
+  private:
+    std::vector<std::pair<Equalizer::Tag, Equalizer>> mTags;
+
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(EqualizerTest, SetAndGetParams) {
+    addBandLevelsParam(mBandLevel);
+    addPresetParam(mPresetIndex);
+    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        EqualizerTest, EqualizerTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidEqualizer())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<Equalizer, int, Range::equalizer,
+                                                                Equalizer::preset>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(
+                        EffectHelper::getTestValueSet<Equalizer, std::vector<Equalizer::BandLevel>,
+                                                      Range::equalizer, Equalizer::bandLevels>(
+                                kDescPair,
+                                [](std::set<std::vector<Equalizer::BandLevel>>& bandLevels) {
+                                    return bandLevels;
+                                }))),
+        [](const testing::TestParamInfo<EqualizerTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string bandLevel =
+                    ::android::internal::ToString(std::get<PARAM_BAND_LEVEL>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_preset_" +
+                               std::to_string(std::get<PARAM_PRESET>(info.param)) + "_bandLevel_" +
+                               bandLevel;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EqualizerTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
new file mode 100644
index 0000000..7c79d1b
--- /dev/null
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <map>
+#include <utility>
+#include <vector>
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalHapticGeneratorTargetTest"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator;
+using aidl::android::hardware::audio::effect::HapticGenerator;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName {
+    PARAM_INSTANCE_NAME,
+    PARAM_HAPTIC_SCALE_ID,
+    PARAM_HAPTIC_SCALE_VIBRATOR_SCALE,
+    PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY,
+    PARAM_VIBRATION_INFORMATION_Q_FACTOR,
+    PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE,
+};
+using HapticGeneratorParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
+                   HapticGenerator::VibratorScale, float, float, float>;
+
+/*
+ * Testing parameter range, assuming the parameter supported by effect is in this range.
+ * Parameter should be within the valid range defined in the documentation,
+ * for any supported value test expects EX_NONE from IEffect.setParameter(),
+ * otherwise expect EX_ILLEGAL_ARGUMENT.
+ */
+
+// TODO : Update the test values once range/capability is updated by implementation
+const int MIN_ID = std::numeric_limits<int>::min();
+const int MAX_ID = std::numeric_limits<int>::max();
+const float MIN_FLOAT = std::numeric_limits<float>::min();
+const float MAX_FLOAT = std::numeric_limits<float>::max();
+
+const std::vector<int> kHapticScaleIdValues = {MIN_ID, 0, MAX_ID};
+const std::vector<HapticGenerator::VibratorScale> kVibratorScaleValues = {
+        ndk::enum_range<HapticGenerator::VibratorScale>().begin(),
+        ndk::enum_range<HapticGenerator::VibratorScale>().end()};
+
+const std::vector<float> kResonantFrequencyValues = {MIN_FLOAT, 100, MAX_FLOAT};
+const std::vector<float> kQFactorValues = {MIN_FLOAT, 100, MAX_FLOAT};
+const std::vector<float> kMaxAmplitude = {MIN_FLOAT, 100, MAX_FLOAT};
+
+class HapticGeneratorParamTest : public ::testing::TestWithParam<HapticGeneratorParamTestParam>,
+                                 public EffectHelper {
+  public:
+    HapticGeneratorParamTest()
+        : mParamHapticScaleId(std::get<PARAM_HAPTIC_SCALE_ID>(GetParam())),
+          mParamVibratorScale(std::get<PARAM_HAPTIC_SCALE_VIBRATOR_SCALE>(GetParam())),
+          mParamResonantFrequency(
+                  std::get<PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY>(GetParam())),
+          mParamQFactor(std::get<PARAM_VIBRATION_INFORMATION_Q_FACTOR>(GetParam())),
+          mParamMaxAmplitude(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mParamHapticScaleId = 0;
+    HapticGenerator::VibratorScale mParamVibratorScale = HapticGenerator::VibratorScale::MUTE;
+    float mParamResonantFrequency = 0;
+    float mParamQFactor = 0;
+    float mParamMaxAmplitude = 0;
+
+    void SetAndGetHapticGeneratorParameters() {
+        for (auto& it : mTags) {
+            auto& tag = std::get<ParamTestEnum::PARAM_TEST_TAG>(it);
+            auto& setHg = std::get<ParamTestEnum::PARAM_TEST_TARGET>(it);
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::hapticGenerator>(setHg);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // get parameter
+            Parameter getParam;
+            Parameter::Id id;
+            HapticGenerator::Id hgId;
+            hgId.set<HapticGenerator::Id::commonTag>(tag);
+            id.set<Parameter::Id::hapticGeneratorTag>(hgId);
+            EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+            EXPECT_EQ(expectParam, getParam) << expectParam.toString() << "\n"
+                                             << getParam.toString();
+        }
+    }
+
+    void addHapticScaleParam(int id, HapticGenerator::VibratorScale scale) {
+        HapticGenerator setHg;
+        std::vector<HapticGenerator::HapticScale> hapticScales = {{.id = id, .scale = scale}};
+        setHg.set<HapticGenerator::hapticScales>(hapticScales);
+        mTags.push_back({HapticGenerator::hapticScales, setHg});
+    }
+
+    void addVibratorInformationParam(float resonantFrequencyHz, float qFactor, float maxAmplitude) {
+        HapticGenerator hg;
+        HapticGenerator::VibratorInformation vibrationInfo = {
+                .resonantFrequencyHz = resonantFrequencyHz,
+                .qFactor = qFactor,
+                .maxAmplitude = maxAmplitude};
+        hg.set<HapticGenerator::vibratorInfo>(vibrationInfo);
+        mTags.push_back({HapticGenerator::vibratorInfo, hg});
+    }
+
+  private:
+    enum ParamTestEnum { PARAM_TEST_TAG, PARAM_TEST_TARGET };
+    std::vector<std::tuple<HapticGenerator::Tag, HapticGenerator>> mTags;
+
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(HapticGeneratorParamTest, SetAndGetHapticScale) {
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
+    SetAndGetHapticGeneratorParameters();
+}
+
+TEST_P(HapticGeneratorParamTest, SetAndGetMultipleHapticScales) {
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
+    SetAndGetHapticGeneratorParameters();
+}
+
+TEST_P(HapticGeneratorParamTest, SetAndGetVibratorInformation) {
+    EXPECT_NO_FATAL_FAILURE(addVibratorInformationParam(mParamResonantFrequency, mParamQFactor,
+                                                        mParamMaxAmplitude));
+    SetAndGetHapticGeneratorParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        HapticGeneratorValidTest, HapticGeneratorParamTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
+                           testing::ValuesIn(kHapticScaleIdValues),
+                           testing::ValuesIn(kVibratorScaleValues),
+                           testing::ValuesIn(kResonantFrequencyValues),
+                           testing::ValuesIn(kQFactorValues), testing::ValuesIn(kMaxAmplitude)),
+        [](const testing::TestParamInfo<HapticGeneratorParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string hapticScaleID = std::to_string(std::get<PARAM_HAPTIC_SCALE_ID>(info.param));
+            std::string hapticScaleVibScale = std::to_string(
+                    static_cast<int>(std::get<PARAM_HAPTIC_SCALE_VIBRATOR_SCALE>(info.param)));
+            std::string resonantFrequency = std::to_string(
+                    std::get<PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY>(info.param));
+            std::string qFactor =
+                    std::to_string(std::get<PARAM_VIBRATION_INFORMATION_Q_FACTOR>(info.param));
+            std::string maxAmplitude =
+                    std::to_string(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_hapticScaleId" +
+                               hapticScaleID + "_hapticScaleVibScale" + hapticScaleVibScale +
+                               "_resonantFrequency" + resonantFrequency + "_qFactor" + qFactor +
+                               "_maxAmplitude" + maxAmplitude;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+INSTANTIATE_TEST_SUITE_P(
+        HapticGeneratorInvalidTest, HapticGeneratorParamTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
+                           testing::Values(MIN_ID - 1),
+                           testing::Values(HapticGenerator::VibratorScale::NONE),
+                           testing::Values(MIN_FLOAT), testing::Values(MIN_FLOAT),
+                           testing::Values(MIN_FLOAT)),
+        [](const testing::TestParamInfo<HapticGeneratorParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string hapticScaleID = std::to_string(std::get<PARAM_HAPTIC_SCALE_ID>(info.param));
+            std::string hapticScaleVibScale = std::to_string(
+                    static_cast<int>(std::get<PARAM_HAPTIC_SCALE_VIBRATOR_SCALE>(info.param)));
+            std::string resonantFrequency = std::to_string(
+                    std::get<PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY>(info.param));
+            std::string qFactor =
+                    std::to_string(std::get<PARAM_VIBRATION_INFORMATION_Q_FACTOR>(info.param));
+            std::string maxAmplitude =
+                    std::to_string(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_hapticScaleId" +
+                               hapticScaleID + "_hapticScaleVibScale" + hapticScaleVibScale +
+                               "_resonantFrequency" + resonantFrequency + "_qFactor" + qFactor +
+                               "_maxAmplitude" + maxAmplitude;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorParamTest);
+
+// Test HapticScale[] hapticScales parameter
+using HapticGeneratorScalesTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>>;
+class HapticGeneratorScalesTest : public ::testing::TestWithParam<HapticGeneratorScalesTestParam>,
+                                  public EffectHelper {
+  public:
+    HapticGeneratorScalesTest() {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+        CleanUp();
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+
+    void addHapticScaleParam(std::vector<HapticGenerator::HapticScale> scales) {
+        mHapticScales.push_back(HapticGenerator::make<HapticGenerator::hapticScales>(scales));
+        for (const auto& scale : scales) {
+            expectMap.insert_or_assign(scale.id, scale.scale);
+        }
+    }
+
+    void SetHapticScaleParameters() {
+        // std::unordered_set<HapticGenerator::HapticScale> target;
+        for (auto& it : mHapticScales) {
+            Parameter::Specific specific =
+                    Parameter::Specific::make<Parameter::Specific::hapticGenerator>(it);
+            Parameter param = Parameter::make<Parameter::specific>(specific);
+            EXPECT_STATUS(EX_NONE, mEffect->setParameter(param)) << param.toString();
+        }
+    }
+
+    void checkHapticScaleParameter() {
+        // get parameter
+        Parameter targetParam;
+        HapticGenerator::Id hgId = HapticGenerator::Id::make<HapticGenerator::Id::commonTag>(
+                HapticGenerator::hapticScales);
+        Parameter::Id id = Parameter::Id::make<Parameter::Id::hapticGeneratorTag>(hgId);
+        EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &targetParam));
+        ASSERT_EQ(Parameter::specific, targetParam.getTag());
+        Parameter::Specific specific = targetParam.get<Parameter::specific>();
+        ASSERT_EQ(Parameter::Specific::hapticGenerator, specific.getTag());
+        HapticGenerator hg = specific.get<Parameter::Specific::hapticGenerator>();
+        ASSERT_EQ(HapticGenerator::hapticScales, hg.getTag());
+        std::vector<HapticGenerator::HapticScale> scales = hg.get<HapticGenerator::hapticScales>();
+        ASSERT_EQ(scales.size(), expectMap.size());
+        for (const auto& scale : scales) {
+            auto itor = expectMap.find(scale.id);
+            ASSERT_NE(expectMap.end(), itor);
+            ASSERT_EQ(scale.scale, itor->second);
+            expectMap.erase(scale.id);
+        }
+        ASSERT_EQ(0ul, expectMap.size());
+    }
+
+    const static HapticGenerator::HapticScale kHapticScaleWithMinId;
+    const static HapticGenerator::HapticScale kHapticScaleWithMinIdNew;
+    const static HapticGenerator::HapticScale kHapticScale;
+    const static HapticGenerator::HapticScale kHapticScaleNew;
+    const static HapticGenerator::HapticScale kHapticScaleWithMaxId;
+    const static HapticGenerator::HapticScale kHapticScaleWithMaxIdNew;
+
+    std::vector<HapticGenerator> mHapticScales;
+
+    void CleanUp() {
+        mHapticScales.clear();
+        expectMap.clear();
+    }
+
+  private:
+    std::map<int /* trackID */, HapticGenerator::VibratorScale> expectMap;
+};
+
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinId = {
+        .id = MIN_ID, .scale = HapticGenerator::VibratorScale::MUTE};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinIdNew = {
+        .id = MIN_ID, .scale = HapticGenerator::VibratorScale::VERY_LOW};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScale = {
+        .id = 1, .scale = HapticGenerator::VibratorScale::LOW};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleNew = {
+        .id = 1, .scale = HapticGenerator::VibratorScale::NONE};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxId = {
+        .id = MAX_ID, .scale = HapticGenerator::VibratorScale::VERY_HIGH};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxIdNew = {
+        .id = MAX_ID, .scale = HapticGenerator::VibratorScale::MUTE};
+
+TEST_P(HapticGeneratorScalesTest, SetAndUpdateOne) {
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinIdNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxIdNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetAndUpdateVector) {
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(
+            {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetAndUpdateMultipleVector) {
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(
+            {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetOneAndAddMoreVector) {
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetMultipleAndAddOneVector) {
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetMultipleVectorRepeat) {
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+    EXPECT_NO_FATAL_FAILURE(
+            addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
+    EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+    EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        HapticGeneratorScalesTest, HapticGeneratorScalesTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                IFactory::descriptor, getEffectTypeUuidHapticGenerator()))),
+        [](const testing::TestParamInfo<HapticGeneratorScalesTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString();
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorScalesTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
new file mode 100644
index 0000000..96b048e
--- /dev/null
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalLoudnessEnhancerTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidLoudnessEnhancer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::LoudnessEnhancer;
+using aidl::android::hardware::audio::effect::Parameter;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_GAIN_MB };
+using LoudnessEnhancerParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
+
+// Every int 32 bit value is a valid gain, so testing the corner cases and one regular value.
+// TODO : Update the test values once range/capability is updated by implementation.
+const std::vector<int> kGainMbValues = {std::numeric_limits<int>::min(), 100,
+                                        std::numeric_limits<int>::max()};
+
+class LoudnessEnhancerParamTest : public ::testing::TestWithParam<LoudnessEnhancerParamTestParam>,
+                                  public EffectHelper {
+  public:
+    LoudnessEnhancerParamTest() : mParamGainMb(std::get<PARAM_GAIN_MB>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        LoudnessEnhancer le = LoudnessEnhancer::make<LoudnessEnhancer::gainMb>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::loudnessEnhancer>(le);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mParamGainMb = 0;
+
+    void SetAndGetParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& le = it.second;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::loudnessEnhancer>(le);
+            expectParam.set<Parameter::specific>(specific);
+            // All values are valid, set parameter should succeed
+            EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // get parameter
+            Parameter getParam;
+            Parameter::Id id;
+            LoudnessEnhancer::Id leId;
+            leId.set<LoudnessEnhancer::Id::commonTag>(tag);
+            id.set<Parameter::Id::loudnessEnhancerTag>(leId);
+            EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+            EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                             << "\ngetParam:" << getParam.toString();
+        }
+    }
+
+    void addGainMbParam(int gainMb) {
+        LoudnessEnhancer le;
+        le.set<LoudnessEnhancer::gainMb>(gainMb);
+        mTags.push_back({LoudnessEnhancer::gainMb, le});
+    }
+
+  private:
+    std::vector<std::pair<LoudnessEnhancer::Tag, LoudnessEnhancer>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(LoudnessEnhancerParamTest, SetAndGetGainMb) {
+    EXPECT_NO_FATAL_FAILURE(addGainMbParam(mParamGainMb));
+    SetAndGetParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        LoudnessEnhancerTest, LoudnessEnhancerParamTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidLoudnessEnhancer())),
+                           testing::ValuesIn(kGainMbValues)),
+        [](const testing::TestParamInfo<LoudnessEnhancerParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string gainMb = std::to_string(std::get<PARAM_GAIN_MB>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_gainMb_" + gainMb;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LoudnessEnhancerParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
new file mode 100644
index 0000000..5525c80
--- /dev/null
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unordered_set>
+
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/audio/effect/NoiseSuppression.h>
+#define LOG_TAG "VtsHalNSParamTest"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidNoiseSuppression;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::NoiseSuppression;
+using aidl::android::hardware::audio::effect::Parameter;
+
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL, PARAM_TYPE };
+using NSParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
+                                    NoiseSuppression::Level, NoiseSuppression::Type>;
+
+class NSParamTest : public ::testing::TestWithParam<NSParamTestParam>, public EffectHelper {
+  public:
+    NSParamTest()
+        : mLevel(std::get<PARAM_LEVEL>(GetParam())), mType(std::get<PARAM_TYPE>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        NoiseSuppression ns =
+                NoiseSuppression::make<NoiseSuppression::level>(NoiseSuppression::Level::MEDIUM);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::noiseSuppression>(ns);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    NoiseSuppression::Level mLevel;
+    NoiseSuppression::Type mType;
+
+    void SetAndGetParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& ns = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const binder_exception_t expected = EX_NONE;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::noiseSuppression>(ns);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                NoiseSuppression::Id specificId;
+                specificId.set<NoiseSuppression::Id::commonTag>(tag);
+                id.set<Parameter::Id::noiseSuppressionTag>(specificId);
+                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+                EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                                 << "\ngetParam:" << getParam.toString();
+            }
+        }
+    }
+
+    void addLevelParam(NoiseSuppression::Level level) {
+        NoiseSuppression ns;
+        ns.set<NoiseSuppression::level>(level);
+        mTags.push_back({NoiseSuppression::level, ns});
+    }
+    void addTypeParam(NoiseSuppression::Type type) {
+        NoiseSuppression ns;
+        ns.set<NoiseSuppression::type>(type);
+        mTags.push_back({NoiseSuppression::type, ns});
+    }
+    static std::unordered_set<NoiseSuppression::Level> getLevelValues() {
+        return {ndk::enum_range<NoiseSuppression::Level>().begin(),
+                ndk::enum_range<NoiseSuppression::Level>().end()};
+    }
+    static std::unordered_set<NoiseSuppression::Type> getTypeValues() {
+        return {ndk::enum_range<NoiseSuppression::Type>().begin(),
+                ndk::enum_range<NoiseSuppression::Type>().end()};
+    }
+
+  private:
+    std::vector<std::pair<NoiseSuppression::Tag, NoiseSuppression>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(NSParamTest, SetAndGetLevel) {
+    EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
+    SetAndGetParameters();
+}
+
+TEST_P(NSParamTest, SetAndGetType) {
+    EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
+    SetAndGetParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        NSParamTest, NSParamTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidNoiseSuppression())),
+                           testing::ValuesIn(NSParamTest::getLevelValues()),
+                           testing::ValuesIn(NSParamTest::getTypeValues())),
+        [](const testing::TestParamInfo<NSParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string level = aidl::android::hardware::audio::effect::toString(
+                    std::get<PARAM_LEVEL>(info.param));
+            std::string type = aidl::android::hardware::audio::effect::toString(
+                    std::get<PARAM_TYPE>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_level_" + level + "_type_" +
+                               type;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NSParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
new file mode 100644
index 0000000..8fb4ebf
--- /dev/null
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalPresetReverbTargetTest"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::PresetReverb;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESETS };
+using PresetReverbParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, PresetReverb::Presets>;
+
+// Testing for enum values
+const std::vector<PresetReverb::Presets> kPresetsValues{
+        ndk::enum_range<PresetReverb::Presets>().begin(),
+        ndk::enum_range<PresetReverb::Presets>().end()};
+
+class PresetReverbParamTest : public ::testing::TestWithParam<PresetReverbParamTestParam>,
+                              public EffectHelper {
+  public:
+    PresetReverbParamTest() : mParamPresets(std::get<PARAM_PRESETS>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    PresetReverb::Presets mParamPresets = PresetReverb::Presets::NONE;
+
+    void SetAndGetPresetReverbParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& pr = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid = isParameterValid<PresetReverb, Range::presetReverb>(it.second, desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::presetReverb>(pr);
+            expectParam.set<Parameter::specific>(specific);
+            // All values are valid, set parameter should succeed
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // get parameter
+            Parameter getParam;
+            Parameter::Id id;
+            PresetReverb::Id prId;
+            prId.set<PresetReverb::Id::commonTag>(tag);
+            id.set<Parameter::Id::presetReverbTag>(prId);
+            EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+
+            EXPECT_EQ(expectParam, getParam);
+        }
+    }
+
+    void addPresetsParam(PresetReverb::Presets preset) {
+        PresetReverb pr;
+        pr.set<PresetReverb::preset>(preset);
+        mTags.push_back({PresetReverb::preset, pr});
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        PresetReverb pr = PresetReverb::make<PresetReverb::preset>(PresetReverb::Presets::NONE);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::presetReverb>(pr);
+        return specific;
+    }
+
+  private:
+    std::vector<std::pair<PresetReverb::Tag, PresetReverb>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(PresetReverbParamTest, SetAndGetPresets) {
+    EXPECT_NO_FATAL_FAILURE(addPresetsParam(mParamPresets));
+    SetAndGetPresetReverbParameters();
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        PresetReverbTest, PresetReverbParamTest,
+        ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                   IFactory::descriptor, getEffectTypeUuidPresetReverb())),
+                           testing::ValuesIn(kPresetsValues)),
+        [](const testing::TestParamInfo<PresetReverbParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string preset =
+                    std::to_string(static_cast<int>(std::get<PARAM_PRESETS>(info.param)));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_preset" + preset;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PresetReverbParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
new file mode 100644
index 0000000..6b1da63
--- /dev/null
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalVirtualizerTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Virtualizer;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_STRENGTH };
+using VirtualizerParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
+
+/*
+ * Testing parameter range, assuming the parameter supported by effect is in this range.
+ * Parameter should be within the valid range defined in the documentation,
+ * for any supported value test expects EX_NONE from IEffect.setParameter(),
+ * otherwise expect EX_ILLEGAL_ARGUMENT.
+ */
+
+class VirtualizerParamTest : public ::testing::TestWithParam<VirtualizerParamTestParam>,
+                             public EffectHelper {
+  public:
+    VirtualizerParamTest() : mParamStrength(std::get<PARAM_STRENGTH>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        Virtualizer vr = Virtualizer::make<Virtualizer::strengthPm>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::virtualizer>(vr);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mParamStrength = 0;
+
+    void SetAndGetVirtualizerParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& vr = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid = isParameterValid<Virtualizer, Range::virtualizer>(it.second, desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::virtualizer>(vr);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                Virtualizer::Id vrId;
+                vrId.set<Virtualizer::Id::commonTag>(tag);
+                id.set<Parameter::Id::virtualizerTag>(vrId);
+                // if set success, then get should match
+                EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+                EXPECT_EQ(expectParam, getParam);
+            }
+        }
+    }
+
+    void addStrengthParam(int strength) {
+        Virtualizer vr;
+        vr.set<Virtualizer::strengthPm>(strength);
+        mTags.push_back({Virtualizer::strengthPm, vr});
+    }
+
+  private:
+    std::vector<std::pair<Virtualizer::Tag, Virtualizer>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(VirtualizerParamTest, SetAndGetStrength) {
+    EXPECT_NO_FATAL_FAILURE(addStrengthParam(mParamStrength));
+    SetAndGetVirtualizerParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        VirtualizerTest, VirtualizerParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidVirtualizer())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  Virtualizer, int, Range::virtualizer, Virtualizer::strengthPm>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<VirtualizerParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string strength = std::to_string(std::get<PARAM_STRENGTH>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_strength" + strength;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VirtualizerParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
new file mode 100644
index 0000000..f41ba30
--- /dev/null
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unordered_set>
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalVisualizerTest"
+#include <android-base/logging.h>
+#include <android/binder_enums.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Visualizer;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName {
+    PARAM_INSTANCE_NAME,
+    PARAM_CAPTURE_SIZE,
+    PARAM_SCALING_MODE,
+    PARAM_MEASUREMENT_MODE,
+    PARAM_LATENCY,
+};
+using VisualizerParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int, Visualizer::ScalingMode,
+                   Visualizer::MeasurementMode, int>;
+
+class VisualizerParamTest : public ::testing::TestWithParam<VisualizerParamTestParam>,
+                            public EffectHelper {
+  public:
+    VisualizerParamTest()
+        : mCaptureSize(std::get<PARAM_CAPTURE_SIZE>(GetParam())),
+          mScalingMode(std::get<PARAM_SCALING_MODE>(GetParam())),
+          mMeasurementMode(std::get<PARAM_MEASUREMENT_MODE>(GetParam())),
+          mLatency(std::get<PARAM_LATENCY>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mCaptureSize;
+    Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
+    Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
+    int mLatency = 0;
+
+    void SetAndGetParameters() {
+        for (auto& it : mCommonTags) {
+            auto& tag = it.first;
+            auto& vs = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid = isParameterValid<Visualizer, Range::visualizer>(vs, desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::visualizer>(vs);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                Visualizer::Id vsId;
+                vsId.set<Visualizer::Id::commonTag>(tag);
+                id.set<Parameter::Id::visualizerTag>(vsId);
+                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam))
+                        << " with: " << id.toString();
+                EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                                 << "\ngetParam:" << getParam.toString();
+            }
+        }
+    }
+
+    void addCaptureSizeParam(int captureSize) {
+        mCommonTags.push_back({Visualizer::captureSamples,
+                               Visualizer::make<Visualizer::captureSamples>(captureSize)});
+    }
+
+    void addScalingModeParam(Visualizer::ScalingMode scalingMode) {
+        mCommonTags.push_back(
+                {Visualizer::scalingMode, Visualizer::make<Visualizer::scalingMode>(scalingMode)});
+    }
+
+    void addMeasurementModeParam(Visualizer::MeasurementMode measurementMode) {
+        mCommonTags.push_back({Visualizer::measurementMode,
+                               Visualizer::make<Visualizer::measurementMode>(measurementMode)});
+    }
+
+    void addLatencyParam(int latency) {
+        mCommonTags.push_back(
+                {Visualizer::latencyMs, Visualizer::make<Visualizer::latencyMs>(latency)});
+    }
+
+    static std::unordered_set<Visualizer::MeasurementMode> getMeasurementModeValues() {
+        return {ndk::enum_range<Visualizer::MeasurementMode>().begin(),
+                ndk::enum_range<Visualizer::MeasurementMode>().end()};
+    }
+
+    static std::unordered_set<Visualizer::ScalingMode> getScalingModeValues() {
+        return {ndk::enum_range<Visualizer::ScalingMode>().begin(),
+                ndk::enum_range<Visualizer::ScalingMode>().end()};
+    }
+
+  private:
+    std::vector<std::pair<Visualizer::Tag, Visualizer>> mCommonTags;
+    void CleanUp() { mCommonTags.clear(); }
+};
+
+TEST_P(VisualizerParamTest, SetAndGetCaptureSize) {
+    EXPECT_NO_FATAL_FAILURE(addCaptureSizeParam(mCaptureSize));
+    SetAndGetParameters();
+}
+
+TEST_P(VisualizerParamTest, SetAndGetScalingMode) {
+    EXPECT_NO_FATAL_FAILURE(addScalingModeParam(mScalingMode));
+    SetAndGetParameters();
+}
+
+TEST_P(VisualizerParamTest, SetAndGetMeasurementMode) {
+    EXPECT_NO_FATAL_FAILURE(addMeasurementModeParam(mMeasurementMode));
+    SetAndGetParameters();
+}
+
+TEST_P(VisualizerParamTest, SetAndGetLatency) {
+    EXPECT_NO_FATAL_FAILURE(addLatencyParam(mLatency));
+    SetAndGetParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        VisualizerParamTest, VisualizerParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidVisualizer())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<Visualizer, int, Range::visualizer,
+                                                                Visualizer::captureSamples>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(VisualizerParamTest::getScalingModeValues()),
+                testing::ValuesIn(VisualizerParamTest::getMeasurementModeValues()),
+                testing::ValuesIn(EffectHelper::getTestValueSet<Visualizer, int, Range::visualizer,
+                                                                Visualizer::latencyMs>(
+                        kDescPair, EffectHelper::expandTestValueBasic<int>))),
+        [](const testing::TestParamInfo<VisualizerParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string captureSize = std::to_string(std::get<PARAM_CAPTURE_SIZE>(info.param));
+            std::string scalingMode = aidl::android::hardware::audio::effect::toString(
+                    std::get<PARAM_SCALING_MODE>(info.param));
+            std::string measurementMode = aidl::android::hardware::audio::effect::toString(
+                    std::get<PARAM_MEASUREMENT_MODE>(info.param));
+            std::string latency = std::to_string(std::get<PARAM_LATENCY>(info.param));
+
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_captureSize" + captureSize +
+                               "_scalingMode" + scalingMode + "_measurementMode" + measurementMode +
+                               "_latency" + latency;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VisualizerParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
new file mode 100644
index 0000000..90b7f37
--- /dev/null
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Vintf.h>
+#define LOG_TAG "VtsHalVolumeTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidVolume;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Volume;
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL, PARAM_MUTE };
+using VolumeParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int, bool>;
+
+class VolumeParamTest : public ::testing::TestWithParam<VolumeParamTestParam>, public EffectHelper {
+  public:
+    VolumeParamTest()
+        : mParamLevel(std::get<PARAM_LEVEL>(GetParam())),
+          mParamMute(std::get<PARAM_MUTE>(GetParam())) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        Volume vol = Volume::make<Volume::levelDb>(-9600);
+        Parameter::Specific specific = Parameter::Specific::make<Parameter::Specific::volume>(vol);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    int mParamLevel = 0;
+    bool mParamMute = false;
+
+    void SetAndGetParameters() {
+        for (auto& it : mTags) {
+            auto& tag = it.first;
+            auto& vol = it.second;
+
+            // validate parameter
+            Descriptor desc;
+            ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+            const bool valid = isParameterValid<Volume, Range::volume>(it.second, desc);
+            const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+            // set parameter
+            Parameter expectParam;
+            Parameter::Specific specific;
+            specific.set<Parameter::Specific::volume>(vol);
+            expectParam.set<Parameter::specific>(specific);
+            EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+            // only get if parameter is in range and set success
+            if (expected == EX_NONE) {
+                Parameter getParam;
+                Parameter::Id id;
+                Volume::Id volId;
+                volId.set<Volume::Id::commonTag>(tag);
+                id.set<Parameter::Id::volumeTag>(volId);
+                EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+                EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+                                                 << "\ngetParam:" << getParam.toString();
+            }
+        }
+    }
+
+    void addLevelParam(int level) {
+        Volume vol;
+        vol.set<Volume::levelDb>(level);
+        mTags.push_back({Volume::levelDb, vol});
+    }
+
+    void addMuteParam(bool mute) {
+        Volume vol;
+        vol.set<Volume::mute>(mute);
+        mTags.push_back({Volume::mute, vol});
+    }
+
+  private:
+    std::vector<std::pair<Volume::Tag, Volume>> mTags;
+    void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(VolumeParamTest, SetAndGetLevel) {
+    EXPECT_NO_FATAL_FAILURE(addLevelParam(mParamLevel));
+    SetAndGetParameters();
+}
+
+TEST_P(VolumeParamTest, SetAndGetMute) {
+    EXPECT_NO_FATAL_FAILURE(addMuteParam(mParamMute));
+    SetAndGetParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        VolumeTest, VolumeParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidVolume())),
+                testing::ValuesIn(
+                        EffectHelper::getTestValueSet<Volume, int, Range::volume, Volume::levelDb>(
+                                kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::Bool() /* mute */),
+        [](const testing::TestParamInfo<VolumeParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string level = std::to_string(std::get<PARAM_LEVEL>(info.param));
+            std::string mute = std::to_string(std::get<PARAM_MUTE>(info.param));
+            std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+                               descriptor.common.name + "_UUID_" +
+                               descriptor.common.id.uuid.toString() + "_level" + level + "_mute" +
+                               mute;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VolumeParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/common/5.0/Android.bp b/audio/common/5.0/Android.bp
index fd8e85f..a6bb331 100644
--- a/audio/common/5.0/Android.bp
+++ b/audio/common/5.0/Android.bp
@@ -22,6 +22,6 @@
     gen_java_constants: true,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
     ],
 }
diff --git a/audio/common/7.0/enums/OWNERS b/audio/common/7.0/enums/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/7.0/enums/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/7.0/example/OWNERS b/audio/common/7.0/example/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/7.0/example/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/7.1/enums/OWNERS b/audio/common/7.1/enums/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/7.1/enums/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/all-versions/OWNERS b/audio/common/all-versions/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/all-versions/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index 0fd2947..f89c898 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -898,7 +898,7 @@
     for (const auto& transport : transports) {
         switch (transport.audioCapability.getDiscriminator()) {
             case AudioTransport::AudioCapability::hidl_discriminator::profile:
-                if (halPort->num_audio_profiles > AUDIO_PORT_MAX_AUDIO_PROFILES) {
+                if (halPort->num_audio_profiles >= AUDIO_PORT_MAX_AUDIO_PROFILES) {
                     ALOGE("%s, too many audio profiles", __func__);
                     result = BAD_VALUE;
                     break;
@@ -914,7 +914,8 @@
                                 result);
                 break;
             case AudioTransport::AudioCapability::hidl_discriminator::edid:
-                if (halPort->num_extra_audio_descriptors > AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
+                if (halPort->num_extra_audio_descriptors >=
+                    AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
                     ALOGE("%s, too many extra audio descriptors", __func__);
                     result = BAD_VALUE;
                     break;
diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h
index ad9dee2..844a651 100644
--- a/audio/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/HidlUtils.h
@@ -81,7 +81,7 @@
 #endif
 
 #if MAJOR_VERSION >= 7
-    static constexpr char sAudioTagSeparator = ';';
+    static constexpr char sAudioTagSeparator = AUDIO_ATTRIBUTES_TAGS_SEPARATOR;
 
     static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput,
                                             AudioChannelMask* channelMask);
diff --git a/audio/common/all-versions/default/OWNERS b/audio/common/all-versions/default/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/all-versions/default/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/all-versions/default/service/Android.bp b/audio/common/all-versions/default/service/Android.bp
index 9890be2..d513062 100644
--- a/audio/common/all-versions/default/service/Android.bp
+++ b/audio/common/all-versions/default/service/Android.bp
@@ -41,6 +41,10 @@
     relative_install_path: "hw",
     vendor: true,
 
+    defaults: [
+        "android_hardware_audio_config_defaults",
+    ],
+
     srcs: ["service.cpp"],
 
     cflags: [
@@ -58,10 +62,6 @@
         "libutils",
         "libhardware",
     ],
-
-    defaults: [
-        "android_hardware_audio_config_defaults",
-    ],
 }
 
 // Legacy service name, use android.hardware.audio.service instead
diff --git a/audio/common/all-versions/default/service/android.hardware.audio.service.rc b/audio/common/all-versions/default/service/android.hardware.audio.service.rc
index 45fef9a..0de4eea 100644
--- a/audio/common/all-versions/default/service/android.hardware.audio.service.rc
+++ b/audio/common/all-versions/default/service/android.hardware.audio.service.rc
@@ -3,7 +3,9 @@
     user audioserver
     # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
     group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
-    capabilities BLOCK_SUSPEND
+    capabilities BLOCK_SUSPEND SYS_NICE
+    # setting RLIMIT_RTPRIO allows binder RT priority inheritance
+    rlimit rtprio 10 10
     ioprio rt 4
     task_profiles ProcessCapacityHigh HighPerformance
     onrestart restart audioserver
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index fbf6165..1557a95 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -75,9 +75,10 @@
 int main(int /* argc */, char* /* argv */ []) {
     signal(SIGPIPE, SIG_IGN);
 
-    ::android::ProcessState::initWithDriver("/dev/vndbinder");
-    // start a threadpool for vndbinder interactions
-    ::android::ProcessState::self()->startThreadPool();
+    if (::android::ProcessState::isVndservicemanagerEnabled()) {
+        ::android::ProcessState::initWithDriver("/dev/vndbinder");
+        ::android::ProcessState::self()->startThreadPool();
+    }
 
     ABinderProcess_setThreadPoolMaxThreadCount(1);
     ABinderProcess_startThreadPool();
@@ -137,6 +138,10 @@
             "android.hardware.bluetooth.audio-impl",
             "createIBluetoothAudioProviderFactory",
         },
+        {
+            "android.hardware.audio.sounddose-vendor-impl",
+            "createISoundDoseFactory",
+        },
     };
     // clang-format on
 
diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
index ec16b02..93688fc 100644
--- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
@@ -954,6 +954,18 @@
     EXPECT_TRUE(audio_port_configs_are_equal(&halConfig, &halConfigBack));
 }
 
+static AudioProfile generateValidAudioProfile() {
+    AudioProfile profile;
+    profile.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
+    profile.sampleRates.resize(2);
+    profile.sampleRates[0] = 44100;
+    profile.sampleRates[1] = 48000;
+    profile.channelMasks.resize(2);
+    profile.channelMasks[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO);
+    profile.channelMasks[1] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
+    return profile;
+}
+
 TEST(HidlUtils, ConvertInvalidAudioTransports) {
     hidl_vec<AudioTransport> invalid;
     struct audio_port_v7 halInvalid = {};
@@ -973,20 +985,32 @@
     invalid[0].audioCapability.edid(hidl_vec<uint8_t>(EXTRA_AUDIO_DESCRIPTOR_SIZE + 1));
     invalid[1].encapsulationType = "random string";
     EXPECT_EQ(BAD_VALUE, HidlUtils::audioTransportsToHal(invalid, &halInvalid));
+
+    // The size of audio profile must not be greater than the maximum value.
+    invalid.resize(0);
+    invalid.resize(AUDIO_PORT_MAX_AUDIO_PROFILES + 1);
+    for (size_t i = 0; i < invalid.size(); ++i) {
+        invalid[i].audioCapability.profile(generateValidAudioProfile());
+        invalid[i].encapsulationType =
+                toString(xsd::AudioEncapsulationType::AUDIO_ENCAPSULATION_TYPE_NONE);
+    }
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioTransportsToHal(invalid, &halInvalid));
+
+    // The size of extra audio descriptors must not be greater than the maximum value.
+    invalid.resize(0);
+    invalid.resize(AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS + 1);
+    for (size_t i = 0; i < invalid.size(); ++i) {
+        invalid[i].audioCapability.edid({0x11, 0x06, 0x01});
+        invalid[i].encapsulationType =
+                toString(xsd::AudioEncapsulationType::AUDIO_ENCAPSULATION_TYPE_IEC61937);
+    }
+    EXPECT_EQ(BAD_VALUE, HidlUtils::audioTransportsToHal(invalid, &halInvalid));
 }
 
 TEST(HidlUtils, ConvertAudioTransports) {
     hidl_vec<AudioTransport> transports;
     transports.resize(2);
-    AudioProfile profile;
-    profile.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
-    profile.sampleRates.resize(2);
-    profile.sampleRates[0] = 44100;
-    profile.sampleRates[1] = 48000;
-    profile.channelMasks.resize(2);
-    profile.channelMasks[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO);
-    profile.channelMasks[1] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO);
-    transports[0].audioCapability.profile(profile);
+    transports[0].audioCapability.profile(generateValidAudioProfile());
     hidl_vec<uint8_t> shortAudioDescriptor({0x11, 0x06, 0x01});
     transports[0].encapsulationType =
             toString(xsd::AudioEncapsulationType::AUDIO_ENCAPSULATION_TYPE_NONE);
@@ -1103,8 +1127,12 @@
     TypeParam emptyTags;
     EXPECT_EQ(emptyTags, HidlUtils::filterOutNonVendorTags(emptyTags));
 
-    TypeParam allVendorTags = {{"VX_GOOGLE_VR_42", "VX_GOOGLE_1E100"}};
-    EXPECT_EQ(allVendorTags, HidlUtils::filterOutNonVendorTags(allVendorTags));
+    // b/248421569, allocate two vendor tags at a time can run out of memory
+    // TypeParam allVendorTags = {{"VX_GOOGLE_VR_42", "VX_GOOGLE_1E100"}};
+    TypeParam allVendorTags1 = {{"VX_GOOGLE_VR_42"}};
+    EXPECT_EQ(allVendorTags1, HidlUtils::filterOutNonVendorTags(allVendorTags1));
+    TypeParam allVendorTags2 = {{"VX_GOOGLE_1E100"}};
+    EXPECT_EQ(allVendorTags2, HidlUtils::filterOutNonVendorTags(allVendorTags2));
 
     TypeParam oneVendorTag = {{"", "VX_GOOGLE_VR", "random_string"}};
     TypeParam oneVendorTagOnly = HidlUtils::filterOutNonVendorTags(oneVendorTag);
diff --git a/audio/common/all-versions/test/utility/src/ValidateXml.cpp b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
index f111c01..4d6f003 100644
--- a/audio/common/all-versions/test/utility/src/ValidateXml.cpp
+++ b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
@@ -63,11 +63,8 @@
         xmlSetGenericErrorFunc(this, errorCb);
     }
     ~Libxml2Global() {
-        // TODO: check if all those cleanup are needed
         xmlSetGenericErrorFunc(nullptr, nullptr);
-        xmlSchemaCleanupTypes();
         xmlCleanupParser();
-        xmlCleanupThreads();
     }
 
     const std::string& getErrors() { return errors; }
diff --git a/audio/core/all-versions/OWNERS b/audio/core/all-versions/OWNERS
deleted file mode 100644
index f9a2d6b..0000000
--- a/audio/core/all-versions/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 48436
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index b954fcd..d03118a 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -30,6 +30,7 @@
 #include <algorithm>
 
 #include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
 #include <mediautils/MemoryLeakTrackUtil.h>
 #include <memunreachable/memunreachable.h>
 
@@ -183,6 +184,7 @@
     if (status == OK) {
         streamOut = new StreamOut(this, halStream);
         ++mOpenedStreamsCount;
+        android::hardware::setMinSchedulerPolicy(streamOut, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
     }
     status_t convertStatus =
             HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, suggestedConfig);
@@ -220,6 +222,7 @@
     if (status == OK) {
         streamIn = new StreamIn(this, halStream);
         ++mOpenedStreamsCount;
+        android::hardware::setMinSchedulerPolicy(streamIn, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
     }
     status_t convertStatus =
             HidlUtils::audioConfigFromHal(halConfig, true /*isInput*/, suggestedConfig);
diff --git a/audio/core/all-versions/default/DevicesFactory.cpp b/audio/core/all-versions/default/DevicesFactory.cpp
index f44daf0..011f9ac 100644
--- a/audio/core/all-versions/default/DevicesFactory.cpp
+++ b/audio/core/all-versions/default/DevicesFactory.cpp
@@ -23,6 +23,8 @@
 #include <string.h>
 
 #include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
+#include <system/thread_defs.h>
 
 namespace android {
 namespace hardware {
@@ -103,6 +105,7 @@
     int halStatus = loadAudioInterface(moduleName, &halDevice);
     if (halStatus == OK) {
         result = new DeviceShim(halDevice);
+        android::hardware::setMinSchedulerPolicy(result, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
         retval = Result::OK;
     } else if (halStatus == -EINVAL) {
         retval = Result::NOT_INITIALIZED;
diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.cpp b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
index dafd326..705932d 100644
--- a/audio/core/all-versions/vts/functional/6.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
@@ -16,6 +16,8 @@
 
 #include <android-base/macros.h>
 
+#include <IOProfile.h>
+
 #include "6.0/Generators.h"
 #include "ConfigHelper.h"
 #include "PolicyConfig.h"
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 95564e0..c4c18a4 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -715,11 +715,9 @@
     }
 
     void releasePatchIfNeeded() {
-        if (getDevice()) {
-            if (areAudioPatchesSupported() && mHasPatch) {
-                EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
-                mHasPatch = false;
-            }
+        if (getDevice() && areAudioPatchesSupported() && mHasPatch) {
+            EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
+            mHasPatch = false;
         }
     }
 
@@ -962,10 +960,16 @@
     ASSERT_NO_FATAL_FAILURE(createPatchIfNeeded());
     const int presentationeEndPrecisionMs = 1000;
     const int sampleRate = 44100;
+    // The duration of sine882hz3s.mp3 is: 3 seconds + (576 + 756) samples.
+    // This is a mono file, thus 1 frame = 1 sample for it.
+    const int fullTrackDurationMs = 3000 + (576 + 756) * 1000 / sampleRate;
     const int significantSampleNumber = (presentationeEndPrecisionMs * sampleRate) / 1000;
+    // 'delay' is the amount of frames ignored at the beginning, 'padding' is the amount of frames
+    // ignored at the end of the track. Extra 1000 samples are requested for trimming to reduce the
+    // test running time.
     const int delay = 576 + 1000;
     const int padding = 756 + 1000;
-    const int durationMs = 3000 - 44;
+    const int durationMs = fullTrackDurationMs - (delay + padding) * 1000 / sampleRate;
     auto start = std::chrono::steady_clock::now();
     auto callbacks = sp<OffloadCallbacks>::make();
     std::mutex presentationEndLock;
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
index c1d5669..f6271ff 100644
--- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
@@ -41,15 +41,10 @@
 
 class PolicyConfig {
   public:
-    explicit PolicyConfig(const std::string& configFileName)
-        : mConfigFileName{configFileName},
-          mFilePath{findExistingConfigurationFile(mConfigFileName)},
-          mConfig{xsd::read(mFilePath.c_str())} {
-        init();
-    }
     PolicyConfig(const std::string& configPath, const std::string& configFileName)
         : mConfigFileName{configFileName},
-          mFilePath{configPath + "/" + mConfigFileName},
+          mFilePath{configPath.empty() ? findExistingConfigurationFile(mConfigFileName)
+                                       : configPath + "/" + mConfigFileName},
           mConfig{xsd::read(mFilePath.c_str())} {
         init();
     }
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index daed7a8..9d93bb0 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -30,6 +30,7 @@
         "android.hardware.audio.common.test.utility",
         "audioclient-types-aidl-cpp",
         "libaudioclient_aidl_conversion",
+        "libaudio_aidl_conversion_common_cpp",
         "libstagefright_foundation",
     ],
     shared_libs: [
@@ -49,7 +50,10 @@
 
 cc_test {
     name: "VtsHalAudioV2_0TargetTest",
-    defaults: ["VtsHalAudioTargetTest_defaults"],
+    defaults: [
+        "VtsHalAudioTargetTest_defaults",
+        "latest_android_media_audio_common_types_cpp_static",
+    ],
     tidy_timeout_srcs: [
         "2.0/AudioPrimaryHidlHalTest.cpp",
     ],
@@ -62,7 +66,6 @@
         "libmedia_helper",
         "android.hardware.audio@2.0",
         "android.hardware.audio.common@2.0",
-        "android.media.audio.common.types-V1-cpp",
     ],
     cflags: [
         "-DMAJOR_VERSION=2",
@@ -79,7 +82,10 @@
 
 cc_test {
     name: "VtsHalAudioV4_0TargetTest",
-    defaults: ["VtsHalAudioTargetTest_defaults"],
+    defaults: [
+        "VtsHalAudioTargetTest_defaults",
+        "latest_android_media_audio_common_types_cpp_static",
+    ],
     tidy_timeout_srcs: [
         "4.0/AudioPrimaryHidlHalTest.cpp",
     ],
@@ -92,7 +98,6 @@
         "libmedia_helper",
         "android.hardware.audio@4.0",
         "android.hardware.audio.common@4.0",
-        "android.media.audio.common.types-V1-cpp",
     ],
     cflags: [
         "-DMAJOR_VERSION=4",
@@ -109,7 +114,10 @@
 
 cc_test {
     name: "VtsHalAudioV5_0TargetTest",
-    defaults: ["VtsHalAudioTargetTest_defaults"],
+    defaults: [
+        "VtsHalAudioTargetTest_defaults",
+        "latest_android_media_audio_common_types_cpp_static",
+    ],
     srcs: [
         "5.0/AudioPrimaryHidlHalTest.cpp",
     ],
@@ -119,7 +127,6 @@
         "libmedia_helper",
         "android.hardware.audio@5.0",
         "android.hardware.audio.common@5.0",
-        "android.media.audio.common.types-V1-cpp",
     ],
     cflags: [
         "-DMAJOR_VERSION=5",
@@ -136,7 +143,10 @@
 
 cc_test {
     name: "VtsHalAudioV6_0TargetTest",
-    defaults: ["VtsHalAudioTargetTest_defaults"],
+    defaults: [
+        "VtsHalAudioTargetTest_defaults",
+        "latest_android_media_audio_common_types_cpp_static",
+    ],
     tidy_timeout_srcs: [
         "6.0/AudioPrimaryHidlHalTest.cpp",
     ],
@@ -150,7 +160,6 @@
         "libmedia_helper",
         "android.hardware.audio@6.0",
         "android.hardware.audio.common@6.0",
-        "android.media.audio.common.types-V1-cpp",
     ],
     cflags: [
         "-DMAJOR_VERSION=6",
@@ -244,7 +253,10 @@
 
 cc_test {
     name: "HalAudioV6_0GeneratorTest",
-    defaults: ["VtsHalAudioTargetTest_defaults"],
+    defaults: [
+        "VtsHalAudioTargetTest_defaults",
+        "latest_android_media_audio_common_types_cpp_static",
+    ],
     srcs: [
         "6.0/Generators.cpp",
         "tests/generators_tests.cpp",
@@ -252,7 +264,6 @@
     static_libs: [
         "android.hardware.audio@6.0",
         "android.hardware.audio.common@6.0",
-        "android.media.audio.common.types-V1-cpp",
         "libaudiofoundation",
         "libaudiopolicycomponents",
         "libmedia_helper",
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 478482d..fabe2d2 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -195,7 +195,7 @@
 // Cached policy config after parsing for faster test startup
 const PolicyConfig& getCachedPolicyConfig() {
     static std::unique_ptr<PolicyConfig> policyConfig = [] {
-        auto config = std::make_unique<PolicyConfig>(kConfigFileName);
+        auto config = std::make_unique<PolicyConfig>("", kConfigFileName);
         return config;
     }();
     return *policyConfig;
diff --git a/audio/core/all-versions/vts/functional/OWNERS b/audio/core/all-versions/vts/functional/OWNERS
deleted file mode 100644
index 448d9fe..0000000
--- a/audio/core/all-versions/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48436
-mnaganov@google.com
diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h
index 171d03f..b08e808 100644
--- a/audio/core/all-versions/vts/functional/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/PolicyConfig.h
@@ -19,9 +19,9 @@
 #include <set>
 #include <string>
 
+#include <AudioPolicyConfig.h>
 #include <DeviceDescriptor.h>
 #include <HwModule.h>
-#include <Serializer.h>
 #include <gtest/gtest.h>
 #include <system/audio_config.h>
 
@@ -30,47 +30,35 @@
 using ::android::sp;
 using ::android::status_t;
 
-struct PolicyConfigData {
-    android::HwModuleCollection hwModules;
-    android::DeviceVector availableOutputDevices;
-    android::DeviceVector availableInputDevices;
-    sp<android::DeviceDescriptor> defaultOutputDevice;
-};
-
-class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig {
+class PolicyConfig {
   public:
-    explicit PolicyConfig(const std::string& configFileName)
-        : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
-                                     defaultOutputDevice),
-          mConfigFileName{configFileName} {
-        for (const auto& location : android::audio_get_configuration_paths()) {
-            std::string path = location + '/' + mConfigFileName;
-            if (access(path.c_str(), F_OK) == 0) {
-                mFilePath = path;
-                break;
-            }
-        }
-        init();
-    }
     PolicyConfig(const std::string& configPath, const std::string& configFileName)
-        : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
-                                     defaultOutputDevice),
-          mConfigFileName{configFileName},
-          mFilePath{configPath + "/" + mConfigFileName} {
-        init();
+        : mInitialFilePath(configPath.empty() ? configFileName
+                                              : configPath + "/" + configFileName) {
+        auto result = android::AudioPolicyConfig::loadFromCustomXmlConfigForVtsTests(
+                configPath, configFileName);
+        if (result.ok()) {
+            mStatus = ::android::OK;
+            mConfig = result.value();
+            init();
+        } else {
+            mStatus = result.error();
+        }
     }
     status_t getStatus() const { return mStatus; }
     std::string getError() const {
-        if (mFilePath.empty()) {
-            return std::string{"Could not find "} + mConfigFileName +
+        if (mConfig == nullptr) {
+            return std::string{"Could not find "} + mInitialFilePath +
                    " file in: " + testing::PrintToString(android::audio_get_configuration_paths());
         } else {
-            return "Invalid config file: " + mFilePath;
+            return "Invalid config file: " + mConfig->getSource();
         }
     }
-    const std::string& getFilePath() const { return mFilePath; }
+    const std::string& getFilePath() const {
+        return mConfig != nullptr ? mConfig->getSource() : mInitialFilePath;
+    }
     sp<const android::HwModule> getModuleFromName(const std::string& name) const {
-        return getHwModules().getModuleFromName(name.c_str());
+        return mConfig->getHwModules().getModuleFromName(name.c_str());
     }
     sp<const android::HwModule> getPrimaryModule() const { return mPrimaryModule; }
     const std::set<std::string>& getModulesWithDevicesNames() const {
@@ -86,6 +74,8 @@
         return findAttachedDevice(getAttachedDevices(moduleName),
                                   getSourceDevicesForMixPort(moduleName, mixPortName));
     }
+    const android::DeviceVector& getInputDevices() const { return mConfig->getInputDevices(); }
+    const android::DeviceVector& getOutputDevices() const { return mConfig->getOutputDevices(); }
     bool haveInputProfilesInModule(const std::string& name) const {
         auto module = getModuleFromName(name);
         return module && !module->getInputProfiles().empty();
@@ -93,29 +83,24 @@
 
   private:
     void init() {
-        mStatus = android::deserializeAudioPolicyFileForVts(mFilePath.c_str(), this);
-        if (mStatus == android::OK) {
-            mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
-            // Available devices are not 'attached' to modules at this moment.
-            // Need to go over available devices and find their module.
-            for (const auto& device : availableOutputDevices) {
-                for (const auto& module : hwModules) {
-                    if (module->getDeclaredDevices().indexOf(device) >= 0) {
-                        mModulesWithDevicesNames.insert(module->getName());
-                        mAttachedDevicesPerModule[module->getName()].push_back(
-                                device->getTagName());
-                        break;
-                    }
+        mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
+        // Available devices are not 'attached' to modules at this moment.
+        // Need to go over available devices and find their module.
+        for (const auto& device : mConfig->getOutputDevices()) {
+            for (const auto& module : mConfig->getHwModules()) {
+                if (module->getDeclaredDevices().indexOf(device) >= 0) {
+                    mModulesWithDevicesNames.insert(module->getName());
+                    mAttachedDevicesPerModule[module->getName()].push_back(device->getTagName());
+                    break;
                 }
             }
-            for (const auto& device : availableInputDevices) {
-                for (const auto& module : hwModules) {
-                    if (module->getDeclaredDevices().indexOf(device) >= 0) {
-                        mModulesWithDevicesNames.insert(module->getName());
-                        mAttachedDevicesPerModule[module->getName()].push_back(
-                                device->getTagName());
-                        break;
-                    }
+        }
+        for (const auto& device : mConfig->getInputDevices()) {
+            for (const auto& module : mConfig->getHwModules()) {
+                if (module->getDeclaredDevices().indexOf(device) >= 0) {
+                    mModulesWithDevicesNames.insert(module->getName());
+                    mAttachedDevicesPerModule[module->getName()].push_back(device->getTagName());
+                    break;
                 }
             }
         }
@@ -166,10 +151,10 @@
         return result;
     }
 
-    const std::string mConfigFileName;
+    const std::string mInitialFilePath;
     status_t mStatus = android::NO_INIT;
-    std::string mFilePath;
-    sp<const android::HwModule> mPrimaryModule = nullptr;
+    sp<android::AudioPolicyConfig> mConfig;
+    sp<const android::HwModule> mPrimaryModule;
     std::set<std::string> mModulesWithDevicesNames;
     std::map<std::string, std::vector<std::string>> mAttachedDevicesPerModule;
 };
diff --git a/audio/effect/all-versions/OWNERS b/audio/effect/all-versions/OWNERS
deleted file mode 100644
index f9a2d6b..0000000
--- a/audio/effect/all-versions/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 48436
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index 3baafc9..5aecd32 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -25,8 +25,11 @@
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 #include <HidlUtils.h>
 #include <android/log.h>
+#include <cutils/properties.h>
 #include <media/EffectsFactoryApi.h>
 #include <mediautils/ScopedStatistics.h>
+#include <sys/syscall.h>
+#include <system/audio_effects/effect_spatializer.h>
 #include <util/EffectUtils.h>
 #include <utils/Trace.h>
 
@@ -47,6 +50,160 @@
 
 namespace {
 
+/**
+ * Some basic scheduling tools.
+ */
+namespace scheduler {
+
+int getCpu() {
+    return sched_getcpu();
+}
+
+uint64_t getAffinity(pid_t tid) {
+    cpu_set_t set;
+    CPU_ZERO_S(sizeof(set), &set);
+
+    if (sched_getaffinity(tid, sizeof(set), &set)) {
+        ALOGW("%s: for tid:%d returning 0, failed %s", __func__, tid, strerror(errno));
+        return 0;
+    }
+    const int count = CPU_COUNT_S(sizeof(set), &set);
+    uint64_t mask = 0;
+    for (int i = 0; i < CPU_SETSIZE; ++i) {
+        if (CPU_ISSET_S(i, sizeof(set), &set)) {
+            mask |= 1 << i;
+        }
+    }
+    ALOGV("%s: for tid:%d returning cpu count %d mask %llu", __func__, tid, count,
+          (unsigned long long)mask);
+    return mask;
+}
+
+status_t setAffinity(pid_t tid, uint64_t mask) {
+    cpu_set_t set;
+    CPU_ZERO_S(sizeof(set), &set);
+
+    for (uint64_t m = mask; m != 0;) {
+        uint64_t tz = __builtin_ctz(m);
+        CPU_SET_S(tz, sizeof(set), &set);
+        m &= ~(1 << tz);
+    }
+    if (sched_setaffinity(tid, sizeof(set), &set)) {
+        ALOGW("%s: for tid:%d setting cpu mask %llu failed %s", __func__, tid,
+              (unsigned long long)mask, strerror(errno));
+        return -errno;
+    }
+    ALOGV("%s: for tid:%d setting cpu mask %llu", __func__, tid, (unsigned long long)mask);
+    return OK;
+}
+
+__unused status_t setPriority(pid_t tid, int policy, int priority) {
+    struct sched_param param {
+        .sched_priority = priority,
+    };
+    if (sched_setscheduler(tid, policy, &param) != 0) {
+        ALOGW("%s: Cannot set FIFO priority for tid %d to policy %d priority %d  %s", __func__, tid,
+              policy, priority, strerror(errno));
+        return -errno;
+    }
+    ALOGV("%s: Successfully set priority for tid %d to policy %d priority %d", __func__, tid,
+          policy, priority);
+    return NO_ERROR;
+}
+
+status_t setUtilMin(pid_t tid, uint32_t utilMin) {
+    // Currently, there is no wrapper in bionic: b/183240349.
+    struct {
+        uint32_t size;
+        uint32_t sched_policy;
+        uint64_t sched_flags;
+        int32_t sched_nice;
+        uint32_t sched_priority;
+        uint64_t sched_runtime;
+        uint64_t sched_deadline;
+        uint64_t sched_period;
+        uint32_t sched_util_min;
+        uint32_t sched_util_max;
+    } attr{
+            .size = sizeof(attr),
+            .sched_flags = SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP_MIN,
+            .sched_util_min = utilMin,
+    };
+
+    if (syscall(__NR_sched_setattr, tid, &attr, 0 /* flags */)) {
+        ALOGW("%s: Cannot set sched_util_min for pid %d to %u  %s", __func__, tid, utilMin,
+              strerror(errno));
+        return -errno;
+    }
+    ALOGV("%s: Successfully set sched_util_min for pid %d to %u", __func__, tid, utilMin);
+    return NO_ERROR;
+}
+
+/*
+   Attempts to raise the priority and usage of tid for spatialization.
+   Returns OK if everything works.
+*/
+status_t updateSpatializerPriority(pid_t tid) {
+    status_t status = OK;
+
+    const int cpu = getCpu();
+    ALOGV("%s: current CPU:%d", __func__, cpu);
+
+    const auto currentAffinity = getAffinity(tid);
+    ALOGV("%s: current Affinity:%llx", __func__, (unsigned long long)currentAffinity);
+
+    // Set the desired CPU core affinity.
+    // Typically this would be done to move the Spatializer effect off of the little cores.
+    // The mid cores and large cores typically have more FP/NEON units
+    // and will advantageously reduce power and prevent glitches due CPU limitations.
+    //
+    // Since this is SOC dependent, we do not set the core affinity here but
+    // prefer to set the util_clamp_min below.
+    //
+    constexpr uint64_t kDefaultAffinity = 0;
+    const int32_t desiredAffinity =
+            property_get_int32("audio.spatializer.effect.affinity", kDefaultAffinity);
+    if (desiredAffinity != 0 && (desiredAffinity & ~currentAffinity) == 0) {
+        const status_t localStatus = setAffinity(tid, desiredAffinity);
+        status = status ? status : localStatus;
+    }
+
+    // Set the util_clamp_min.
+    // This is beneficial to reduce glitches when starting up, or due to scheduler
+    // thread statistics reset (e.g. core migration), which cause the CPU frequency to drop
+    // to minimum.
+    //
+    // Experimentation has found that moving to a mid core over a little core reduces
+    // power if the mid core (e.g. A76/78) has more (e.g. 2x) FP/NEON units
+    // than the little core (e.g. A55).
+    // A possible value is 300.
+    //
+    constexpr uint32_t kUtilMin = 0;
+    const int32_t utilMin = property_get_int32("audio.spatializer.effect.util_clamp_min", kUtilMin);
+    if (utilMin > 0 && utilMin <= 1024) {
+        const status_t localStatus = setUtilMin(tid, utilMin);
+        status = status ? status : localStatus;
+    }
+
+#if 0
+    // Provided for local vendor testing but not enabled as audioserver does this for us.
+    //
+    // Set priority if specified.
+    constexpr int32_t kRTPriorityMin = 1;
+    constexpr int32_t kRTPriorityMax = 3;
+    const int32_t priorityBoost =
+            property_get_int32("audio.spatializer.priority", kRTPriorityMin);
+    if (priorityBoost >= kRTPriorityMin && priorityBoost <= kRTPriorityMax) {
+        const status_t localStatus = scheduler::setPriority(threadId, SCHED_FIFO, priorityBoost);
+        status = status ? status : localStatus;
+    }
+#endif
+
+    return status;
+}
+
+}  // namespace scheduler
+
 #define SCOPED_STATS()                                                       \
     ::android::mediautils::ScopedStatistics scopedStatistics {               \
         std::string("EffectHal::").append(__func__), mEffectHal->mStatistics \
@@ -238,12 +395,27 @@
 }
 
 // static
-std::vector<uint8_t> Effect::parameterToHal(uint32_t paramSize, const void* paramData,
-                                            uint32_t valueSize, const void** valueData) {
+bool Effect::parameterToHal(uint32_t paramSize, const void* paramData, uint32_t valueSize,
+                            const void** valueData, std::vector<uint8_t>* halParamBuffer) {
+    constexpr size_t kMaxSize = EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t);
+    if (paramSize > kMaxSize) {
+        ALOGE("%s: Parameter size is too big: %" PRIu32, __func__, paramSize);
+        return false;
+    }
     size_t valueOffsetFromData = alignedSizeIn<uint32_t>(paramSize) * sizeof(uint32_t);
+    if (valueOffsetFromData > kMaxSize) {
+        ALOGE("%s: Aligned parameter size is too big: %zu", __func__, valueOffsetFromData);
+        return false;
+    }
+    if (valueSize > kMaxSize - valueOffsetFromData) {
+        ALOGE("%s: Value size is too big: %" PRIu32 ", max size is %zu", __func__, valueSize,
+              kMaxSize - valueOffsetFromData);
+        android_errorWriteLog(0x534e4554, "237291425");
+        return false;
+    }
     size_t halParamBufferSize = sizeof(effect_param_t) + valueOffsetFromData + valueSize;
-    std::vector<uint8_t> halParamBuffer(halParamBufferSize, 0);
-    effect_param_t* halParam = reinterpret_cast<effect_param_t*>(&halParamBuffer[0]);
+    halParamBuffer->resize(halParamBufferSize, 0);
+    effect_param_t* halParam = reinterpret_cast<effect_param_t*>(halParamBuffer->data());
     halParam->psize = paramSize;
     halParam->vsize = valueSize;
     memcpy(halParam->data, paramData, paramSize);
@@ -256,7 +428,7 @@
             *valueData = halParam->data + valueOffsetFromData;
         }
     }
-    return halParamBuffer;
+    return true;
 }
 
 Result Effect::analyzeCommandStatus(const char* commandName, const char* context, status_t status) {
@@ -301,6 +473,11 @@
 
 Result Effect::getCurrentConfigImpl(uint32_t featureId, uint32_t configSize,
                                     GetCurrentConfigSuccessCallback onSuccess) {
+    if (configSize > kMaxDataSize - sizeof(uint32_t)) {
+        ALOGE("%s: Config size is too big: %" PRIu32, __func__, configSize);
+        android_errorWriteLog(0x534e4554, "240266798");
+        return Result::INVALID_ARGUMENTS;
+    }
     uint32_t halCmd = featureId;
     std::vector<uint32_t> halResult(alignedSizeIn<uint32_t>(sizeof(uint32_t) + configSize), 0);
     uint32_t halResultSize = 0;
@@ -314,11 +491,15 @@
                                 GetParameterSuccessCallback onSuccess) {
     // As it is unknown what method HAL uses for copying the provided parameter data,
     // it is safer to make sure that input and output buffers do not overlap.
-    std::vector<uint8_t> halCmdBuffer =
-        parameterToHal(paramSize, paramData, requestValueSize, nullptr);
+    std::vector<uint8_t> halCmdBuffer;
+    if (!parameterToHal(paramSize, paramData, requestValueSize, nullptr, &halCmdBuffer)) {
+        return Result::INVALID_ARGUMENTS;
+    }
     const void* valueData = nullptr;
-    std::vector<uint8_t> halParamBuffer =
-        parameterToHal(paramSize, paramData, replyValueSize, &valueData);
+    std::vector<uint8_t> halParamBuffer;
+    if (!parameterToHal(paramSize, paramData, replyValueSize, &valueData, &halParamBuffer)) {
+        return Result::INVALID_ARGUMENTS;
+    }
     uint32_t halParamBufferSize = halParamBuffer.size();
 
     return sendCommandReturningStatusAndData(
@@ -331,8 +512,12 @@
 
 Result Effect::getSupportedConfigsImpl(uint32_t featureId, uint32_t maxConfigs, uint32_t configSize,
                                        GetSupportedConfigsSuccessCallback onSuccess) {
+    if (maxConfigs != 0 && configSize > (kMaxDataSize - 2 * sizeof(uint32_t)) / maxConfigs) {
+        ALOGE("%s: Config size is too big: %" PRIu32, __func__, configSize);
+        return Result::INVALID_ARGUMENTS;
+    }
     uint32_t halCmd[2] = {featureId, maxConfigs};
-    uint32_t halResultSize = 2 * sizeof(uint32_t) + maxConfigs * sizeof(configSize);
+    uint32_t halResultSize = 2 * sizeof(uint32_t) + maxConfigs * configSize;
     std::vector<uint8_t> halResult(static_cast<size_t>(halResultSize), 0);
     return sendCommandReturningStatusAndData(
         EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS, "GET_FEATURE_SUPPORTED_CONFIGS", sizeof(halCmd),
@@ -375,6 +560,15 @@
         return Void();
     }
 
+    // For a spatializer effect, we perform scheduler adjustments to reduce glitches and power.
+    // We do it here instead of the ProcessThread::threadLoop to ensure that mHandle is valid.
+    if (effect_descriptor_t halDescriptor{};
+        (*mHandle)->get_descriptor(mHandle, &halDescriptor) == NO_ERROR &&
+        memcmp(&halDescriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0) {
+        const status_t status = scheduler::updateSpatializerPriority(mProcessThread->getTid());
+        ALOGW_IF(status != OK, "Failed to update Spatializer priority");
+    }
+
     mStatusMQ = std::move(tempStatusMQ);
     _hidl_cb(Result::OK, *mStatusMQ->getDesc());
     return Void();
@@ -472,8 +666,10 @@
 
 Result Effect::setParameterImpl(uint32_t paramSize, const void* paramData, uint32_t valueSize,
                                 const void* valueData) {
-    std::vector<uint8_t> halParamBuffer =
-        parameterToHal(paramSize, paramData, valueSize, &valueData);
+    std::vector<uint8_t> halParamBuffer;
+    if (!parameterToHal(paramSize, paramData, valueSize, &valueData, &halParamBuffer)) {
+        return Result::INVALID_ARGUMENTS;
+    }
     return sendCommandReturningStatus(EFFECT_CMD_SET_PARAM, "SET_PARAM", halParamBuffer.size(),
                                       &halParamBuffer[0]);
 }
@@ -670,8 +866,21 @@
 
     void* dataPtr = halDataSize > 0 ? &halData[0] : NULL;
     void* resultPtr = halResultSize > 0 ? &halResult[0] : NULL;
-    status_t status =
-        (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize, resultPtr);
+    status_t status = BAD_VALUE;
+    switch (commandId) {
+        case 'gtid':  // retrieve the tid, used for spatializer priority boost
+            if (halDataSize == 0 && resultMaxSize == sizeof(int32_t)) {
+                auto ptid = (int32_t*)resultPtr;
+                ptid[0] = mProcessThread ? mProcessThread->getTid() : -1;
+                status = OK;
+                break;  // we have handled 'gtid' here.
+            }
+            [[fallthrough]];  // allow 'gtid' overload (checked halDataSize and resultMaxSize).
+        default:
+            status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize,
+                                         resultPtr);
+            break;
+    }
     hidl_vec<uint8_t> result;
     if (status == OK && resultPtr != NULL) {
         result.setToExternal(&halResult[0], halResultSize);
diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h
index 011544d..5d8dccc 100644
--- a/audio/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/Effect.h
@@ -184,6 +184,9 @@
     using GetSupportedConfigsSuccessCallback =
         std::function<void(uint32_t supportedConfigs, void* configsData)>;
 
+    // Sets the limit on the maximum size of vendor-provided data structures.
+    static constexpr size_t kMaxDataSize = 1 << 20;
+
     static const char* sContextResultOfCommand;
     static const char* sContextCallToCommand;
     static const char* sContextCallFunction;
@@ -211,8 +214,8 @@
                                              channel_config_t* halConfig);
     static void effectOffloadParamToHal(const EffectOffloadParameter& offload,
                                         effect_offload_param_t* halOffload);
-    static std::vector<uint8_t> parameterToHal(uint32_t paramSize, const void* paramData,
-                                               uint32_t valueSize, const void** valueData);
+    static bool parameterToHal(uint32_t paramSize, const void* paramData, uint32_t valueSize,
+                               const void** valueData, std::vector<uint8_t>* halParamBuffer);
 
     Result analyzeCommandStatus(const char* commandName, const char* context, status_t status);
     void getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb);
diff --git a/audio/effect/all-versions/default/EffectsFactory.cpp b/audio/effect/all-versions/default/EffectsFactory.cpp
index e93ad89..9bf309c 100644
--- a/audio/effect/all-versions/default/EffectsFactory.cpp
+++ b/audio/effect/all-versions/default/EffectsFactory.cpp
@@ -32,6 +32,7 @@
 
 #include <UuidUtils.h>
 #include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
 #include <media/EffectsFactoryApi.h>
 #include <system/audio_effects/effect_aec.h>
 #include <system/audio_effects/effect_agc.h>
@@ -44,6 +45,7 @@
 #include <system/audio_effects/effect_presetreverb.h>
 #include <system/audio_effects/effect_virtualizer.h>
 #include <system/audio_effects/effect_visualizer.h>
+#include <system/thread_defs.h>
 #include <util/EffectUtils.h>
 
 namespace android {
@@ -189,6 +191,7 @@
         status = (*handle)->get_descriptor(handle, &halDescriptor);
         if (status == OK) {
             effect = dispatchEffectInstanceCreation(halDescriptor, handle);
+            android::hardware::setMinSchedulerPolicy(effect, SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
             effectId = EffectMap::getInstance().add(handle);
         } else {
             ALOGE("Error querying effect descriptor for %s: %s",
diff --git a/audio/effect/all-versions/vts/functional/OWNERS b/audio/effect/all-versions/vts/functional/OWNERS
deleted file mode 100644
index 448d9fe..0000000
--- a/audio/effect/all-versions/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48436
-mnaganov@google.com
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index e59423f..d95bb06 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -35,6 +35,7 @@
 
 #include <common/all-versions/VersionUtils.h>
 
+#include <cutils/properties.h>
 #include <gtest/gtest.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
@@ -623,6 +624,27 @@
     EXPECT_TRUE(ret.isOk());
 }
 
+TEST_P(AudioEffectHidlTest, GetParameterInvalidMaxReplySize) {
+    description("Verify that GetParameter caps the maximum reply size");
+    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+    if (!isNewDeviceLaunchingOnTPlus) {
+        GTEST_SKIP() << "The test only applies to devices launching on T or later";
+    }
+    // Use a non-empty parameter to avoid being rejected by any earlier checks.
+    hidl_vec<uint8_t> parameter;
+    parameter.resize(16);
+    // Use very large size to ensure that the service does not crash. Since parameters
+    // are specific to each effect, and some effects may not have parameters at all,
+    // simply checking the return value would not reveal an issue of using an uncapped value.
+    const uint32_t veryLargeReplySize = std::numeric_limits<uint32_t>::max() - 100;
+    Result retval = Result::OK;
+    Return<void> ret =
+            effect->getParameter(parameter, veryLargeReplySize,
+                                 [&](Result r, const hidl_vec<uint8_t>&) { retval = r; });
+    EXPECT_TRUE(ret.isOk());
+    EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
+}
+
 TEST_P(AudioEffectHidlTest, GetSupportedConfigsForFeature) {
     description("Verify that GetSupportedConfigsForFeature does not crash");
     Return<void> ret = effect->getSupportedConfigsForFeature(
@@ -643,6 +665,37 @@
     EXPECT_TRUE(ret.isOk());
 }
 
+TEST_P(AudioEffectHidlTest, GetSupportedConfigsForFeatureInvalidConfigSize) {
+    description("Verify that GetSupportedConfigsForFeature caps the maximum config size");
+    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+    if (!isNewDeviceLaunchingOnTPlus) {
+        GTEST_SKIP() << "The test only applies to devices launching on T or later";
+    }
+    // Use very large size to ensure that the service does not crash.
+    const uint32_t veryLargeConfigSize = std::numeric_limits<uint32_t>::max() - 100;
+    Result retval = Result::OK;
+    Return<void> ret = effect->getSupportedConfigsForFeature(
+            0, 1, veryLargeConfigSize,
+            [&](Result r, uint32_t, const hidl_vec<uint8_t>&) { retval = r; });
+    EXPECT_TRUE(ret.isOk());
+    EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
+}
+
+TEST_P(AudioEffectHidlTest, GetCurrentConfigForFeatureInvalidConfigSize) {
+    description("Verify that GetCurrentConfigForFeature caps the maximum config size");
+    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+    if (!isNewDeviceLaunchingOnTPlus) {
+        GTEST_SKIP() << "The test only applies to devices launching on T or later";
+    }
+    // Use very large size to ensure that the service does not crash.
+    const uint32_t veryLargeConfigSize = std::numeric_limits<uint32_t>::max() - 100;
+    Result retval = Result::OK;
+    Return<void> ret = effect->getCurrentConfigForFeature(
+            0, veryLargeConfigSize, [&](Result r, const hidl_vec<uint8_t>&) { retval = r; });
+    EXPECT_TRUE(ret.isOk());
+    EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
+}
+
 // The main test class for Equalizer Audio Effect HIDL HAL.
 class EqualizerAudioEffectHidlTest : public AudioEffectHidlTest {
   public:
diff --git a/audio/policy/1.0/vts/OWNERS b/audio/policy/1.0/vts/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/policy/1.0/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/policy/1.0/vts/functional/OWNERS b/audio/policy/1.0/vts/functional/OWNERS
deleted file mode 100644
index 448d9fe..0000000
--- a/audio/policy/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48436
-mnaganov@google.com
diff --git a/authsecret/aidl/Android.bp b/authsecret/aidl/Android.bp
index 432c1b9..90e128d 100644
--- a/authsecret/aidl/Android.bp
+++ b/authsecret/aidl/Android.bp
@@ -16,11 +16,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/automotive/OWNERS b/automotive/OWNERS
index 43c5f3e..09e257c 100644
--- a/automotive/OWNERS
+++ b/automotive/OWNERS
@@ -1,6 +1 @@
-pirozzoj@google.com
-twasilczyk@google.com
-krachuri@google.com
-gurunagarajan@google.com
-keunyoung@google.com
-felipeal@google.com
+include platform/packages/services/Car:/OWNERS
diff --git a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
index 78f5b52..4308d52 100644
--- a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
+++ b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
@@ -48,5 +48,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.automotive.audiocontrol@1.0-service binary",
+        vector: "local_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/automotive/audiocontrol/OWNERS b/automotive/audiocontrol/OWNERS
new file mode 100644
index 0000000..f55eff3
--- /dev/null
+++ b/automotive/audiocontrol/OWNERS
@@ -0,0 +1 @@
+oscarazu@google.com
diff --git a/automotive/audiocontrol/aidl/Android.bp b/automotive/audiocontrol/aidl/Android.bp
index e5f7a4f..9ae77cd 100644
--- a/automotive/audiocontrol/aidl/Android.bp
+++ b/automotive/audiocontrol/aidl/Android.bp
@@ -15,7 +15,7 @@
     srcs: ["android/hardware/automotive/audiocontrol/*.aidl"],
     imports: [
         "android.hardware.audio.common-V1",
-        "android.media.audio.common.types-V1",
+        "android.media.audio.common.types-V2",
     ],
     stability: "vintf",
     backend: {
@@ -33,17 +33,25 @@
             version: "1",
             imports: [
                 "android.hardware.audio.common-V1",
-                "android.media.audio.common.types-V1",
+                "android.media.audio.common.types-V2",
             ],
         },
         {
             version: "2",
             imports: [
                 "android.hardware.audio.common-V1",
-                "android.media.audio.common.types-V1",
+                "android.media.audio.common.types-V2",
+            ],
+        },
+        {
+            version: "3",
+            imports: [
+                "android.hardware.audio.common-V1",
+                "android.media.audio.common.types-V2",
             ],
         },
 
     ],
+    frozen: true,
 
 }
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/.hash b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/.hash
new file mode 100644
index 0000000..c8dbf1c
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/.hash
@@ -0,0 +1 @@
+bc0ead0d35057635fdb88f5353686cbbc6c65dcd
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
new file mode 100644
index 0000000..8eab521
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.automotive.audiocontrol;
+@Backing(type="int") @VintfStability
+enum AudioFocusChange {
+  NONE = 0,
+  GAIN = 1,
+  GAIN_TRANSIENT = 2,
+  GAIN_TRANSIENT_MAY_DUCK = 3,
+  GAIN_TRANSIENT_EXCLUSIVE = 4,
+  LOSS = ((-1) * GAIN) /* -1 */,
+  LOSS_TRANSIENT = ((-1) * GAIN_TRANSIENT) /* -2 */,
+  LOSS_TRANSIENT_CAN_DUCK = ((-1) * GAIN_TRANSIENT_MAY_DUCK) /* -3 */,
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/AudioGainConfigInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/AudioGainConfigInfo.aidl
new file mode 100644
index 0000000..91ce035
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/AudioGainConfigInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@VintfStability
+parcelable AudioGainConfigInfo {
+  int zoneId;
+  String devicePortAddress;
+  int volumeIndex;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/DuckingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
new file mode 100644
index 0000000..23abb46
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.audiocontrol;
+@VintfStability
+parcelable DuckingInfo {
+  int zoneId;
+  String[] deviceAddressesToDuck;
+  String[] deviceAddressesToUnduck;
+  String[] usagesHoldingFocus;
+  @nullable android.hardware.audio.common.PlaybackTrackMetadata[] playbackMetaDataHoldingFocus;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IAudioControl.aidl
new file mode 100644
index 0000000..ffd575d
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.automotive.audiocontrol;
+@VintfStability
+interface IAudioControl {
+  /**
+   * @deprecated use {@link android.hardware.audio.common.PlaybackTrackMetadata} instead.
+   */
+  oneway void onAudioFocusChange(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange);
+  oneway void onDevicesToDuckChange(in android.hardware.automotive.audiocontrol.DuckingInfo[] duckingInfos);
+  oneway void onDevicesToMuteChange(in android.hardware.automotive.audiocontrol.MutingInfo[] mutingInfos);
+  oneway void registerFocusListener(in android.hardware.automotive.audiocontrol.IFocusListener listener);
+  oneway void setBalanceTowardRight(in float value);
+  oneway void setFadeTowardFront(in float value);
+  oneway void onAudioFocusChangeWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange);
+  oneway void setAudioDeviceGainsChanged(in android.hardware.automotive.audiocontrol.Reasons[] reasons, in android.hardware.automotive.audiocontrol.AudioGainConfigInfo[] gains);
+  oneway void registerGainCallback(in android.hardware.automotive.audiocontrol.IAudioGainCallback callback);
+  void setModuleChangeCallback(in android.hardware.automotive.audiocontrol.IModuleChangeCallback callback);
+  void clearModuleChangeCallback();
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IAudioGainCallback.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IAudioGainCallback.aidl
new file mode 100644
index 0000000..17a087f
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IAudioGainCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@VintfStability
+interface IAudioGainCallback {
+  oneway void onAudioDeviceGainsChanged(in android.hardware.automotive.audiocontrol.Reasons[] reasons, in android.hardware.automotive.audiocontrol.AudioGainConfigInfo[] gains);
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IFocusListener.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IFocusListener.aidl
new file mode 100644
index 0000000..3e17552
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IFocusListener.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.automotive.audiocontrol;
+@VintfStability
+interface IFocusListener {
+  oneway void abandonAudioFocus(in String usage, in int zoneId);
+  oneway void requestAudioFocus(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusGain);
+  oneway void abandonAudioFocusWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId);
+  oneway void requestAudioFocusWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusGain);
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl
new file mode 100644
index 0000000..2bbb936
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.audiocontrol;
+@VintfStability
+interface IModuleChangeCallback {
+  oneway void onAudioPortsChanged(in android.media.audio.common.AudioPort[] audioPorts);
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/MutingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/MutingInfo.aidl
new file mode 100644
index 0000000..b25ed0f
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/MutingInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.audiocontrol;
+@VintfStability
+parcelable MutingInfo {
+  int zoneId;
+  String[] deviceAddressesToMute;
+  String[] deviceAddressesToUnmute;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/Reasons.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/Reasons.aidl
new file mode 100644
index 0000000..8d66985
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/3/android/hardware/automotive/audiocontrol/Reasons.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@Backing(type="int") @VintfStability
+enum Reasons {
+  FORCED_MASTER_MUTE = 0x1,
+  REMOTE_MUTE = 0x2,
+  TCU_MUTE = 0x4,
+  ADAS_DUCKING = 0x8,
+  NAV_DUCKING = 0x10,
+  PROJECTION_DUCKING = 0x20,
+  THERMAL_LIMITATION = 0x40,
+  SUSPEND_EXIT_VOL_LIMITATION = 0x80,
+  EXTERNAL_AMP_VOL_FEEDBACK = 0x100,
+  OTHER = 0x80000000,
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index 8dc5ffe..ffd575d 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -46,4 +46,6 @@
   oneway void onAudioFocusChangeWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange);
   oneway void setAudioDeviceGainsChanged(in android.hardware.automotive.audiocontrol.Reasons[] reasons, in android.hardware.automotive.audiocontrol.AudioGainConfigInfo[] gains);
   oneway void registerGainCallback(in android.hardware.automotive.audiocontrol.IAudioGainCallback callback);
+  void setModuleChangeCallback(in android.hardware.automotive.audiocontrol.IModuleChangeCallback callback);
+  void clearModuleChangeCallback();
 }
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl
new file mode 100644
index 0000000..2bbb936
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.audiocontrol;
+@VintfStability
+interface IModuleChangeCallback {
+  oneway void onAudioPortsChanged(in android.media.audio.common.AudioPort[] audioPorts);
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index 0ffcd5e..9564efc 100644
--- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -51,6 +51,7 @@
 import android.hardware.automotive.audiocontrol.DuckingInfo;
 import android.hardware.automotive.audiocontrol.IAudioGainCallback;
 import android.hardware.automotive.audiocontrol.IFocusListener;
+import android.hardware.automotive.audiocontrol.IModuleChangeCallback;
 import android.hardware.automotive.audiocontrol.MutingInfo;
 import android.hardware.automotive.audiocontrol.Reasons;
 
@@ -183,4 +184,26 @@
      *                 interface.
      */
     oneway void registerGainCallback(in IAudioGainCallback callback);
+
+    /**
+     * Sets callback with HAL for notifying changes to hardware module (that is:
+     * {@link android.hardware.audio.core.IModule}) configurations.
+     *
+     * @param callback The {@link android.hardware.automotive.audiocontrol.IModuleChangeCallback}
+     *                 interface to use use when new updates are available for
+     *                 {@link android.hardware.audio.core.IModule} configs
+     * @throws EX_UNSUPPORTED_OPERATION if dynamic audio configs are not supported.
+     * @throws EX_ILLEGAL_STATE if a callback already exists
+     * @throws EX_ILLEGAL_ARGUMENT if the passed callback is (@code null}
+     */
+    void setModuleChangeCallback(in IModuleChangeCallback callback);
+
+    /**
+     * Clears module change callback
+     *
+     * If no callback is registered previously, then this call should be a no-op.
+     *
+     * @throws EX_UNSUPPORTED_OPERATION if dynamic audio configs are not supported.
+     */
+    void clearModuleChangeCallback();
 }
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl
new file mode 100644
index 0000000..4282483
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.media.audio.common.AudioPort;
+
+/**
+ * Interface definition for asynchronous changes to audio configs defined
+ * for a hardware {@link android.hardware.audio.core.IModule}.
+ */
+@VintfStability
+oneway interface IModuleChangeCallback {
+    /**
+     * Used to indicate that one or more {@link android.media.audio.common.AudioPort}
+     * configs have changed. Implementations MUST return at least one AudioPort.
+     *
+     * Notes for AudioPort:
+     * 1. For V3, the support will be limited to configurable AudioGain stages - per
+     *    car audio framework support.
+     * 2. For automotive 'bus' devices, the expected settings are
+     *     AudioDevice {
+     *        AudioDeviceDescription {type: IN/OUT_DEVICE, connection: CONNECTION_BUS}
+     *        AudioDeviceAddress {id: string}}
+     *
+     * Notes for AudioGain:
+     * 1. Car audio framework only supports AudioGainMode::JOINT. Any other mode
+     *    selection will be ignored.
+     *    See {@link android.media.audio.common.AudioGainMode}
+     * 2. Implementations MUST ensure that the gain stages are identical for buses
+     *    that map to the same volume group. Any inconsistencies will result in
+     *    inferior volume-change experience to the users.
+     * 3. Implementations MUST ensure that the new gain stages are subset (do not
+     *    exceed) of the gain stage definitions provided to audio policy. If they
+     *    exceed, it can result in failure when setting value over the range
+     *    allowed by the audio policy.
+     *
+     * Other notes:
+     * 1. In case of AudioControl  service restart or resume, the implementations MUST
+     *    issue an immediate callback following registration.
+     * 2. In case of client restart, the AudioControl service MUST clear all stale
+     *    callbacks.
+     *
+     * @param audioPorts list of {@link android.media.audio.common.AudioPort} that
+     *                   are updated
+     */
+    void onAudioPortsChanged(in AudioPort[] audioPorts);
+}
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
index 6bf4b9d..435c2d6 100644
--- a/automotive/audiocontrol/aidl/default/Android.bp
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -30,8 +30,8 @@
     shared_libs: [
         "android.hardware.audio.common@7.0-enums",
         "android.hardware.audio.common-V1-ndk",
-        "android.frameworks.automotive.powerpolicy-V1-ndk",
-        "android.hardware.automotive.audiocontrol-V2-ndk",
+        "android.frameworks.automotive.powerpolicy-V2-ndk",
+        "android.hardware.automotive.audiocontrol-V3-ndk",
         "libbase",
         "libbinder_ndk",
         "libcutils",
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp
index a121f8b..cf7307d 100644
--- a/automotive/audiocontrol/aidl/default/AudioControl.cpp
+++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp
@@ -24,6 +24,7 @@
 #include <aidl/android/hardware/automotive/audiocontrol/IFocusListener.h>
 
 #include <android-base/logging.h>
+#include <android-base/parsebool.h>
 #include <android-base/parseint.h>
 #include <android-base/strings.h>
 
@@ -37,6 +38,8 @@
 namespace aidl::android::hardware::automotive::audiocontrol {
 
 using ::android::base::EqualsIgnoreCase;
+using ::android::base::ParseBool;
+using ::android::base::ParseBoolResult;
 using ::android::base::ParseInt;
 using ::std::shared_ptr;
 using ::std::string;
@@ -70,6 +73,95 @@
 }
 }  // namespace
 
+namespace {
+using ::aidl::android::media::audio::common::AudioChannelLayout;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
+using ::aidl::android::media::audio::common::AudioDeviceType;
+using ::aidl::android::media::audio::common::AudioFormatDescription;
+using ::aidl::android::media::audio::common::AudioFormatType;
+using ::aidl::android::media::audio::common::AudioGain;
+using ::aidl::android::media::audio::common::AudioGainMode;
+using ::aidl::android::media::audio::common::AudioIoFlags;
+using ::aidl::android::media::audio::common::AudioOutputFlags;
+using ::aidl::android::media::audio::common::AudioPort;
+using ::aidl::android::media::audio::common::AudioPortDeviceExt;
+using ::aidl::android::media::audio::common::AudioPortExt;
+using ::aidl::android::media::audio::common::AudioPortMixExt;
+using ::aidl::android::media::audio::common::AudioProfile;
+using ::aidl::android::media::audio::common::PcmType;
+
+// reuse common code artifacts
+void fillProfile(const std::vector<int32_t>& channelLayouts,
+                 const std::vector<int32_t>& sampleRates, AudioProfile* profile) {
+    for (auto layout : channelLayouts) {
+        profile->channelMasks.push_back(
+                AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout));
+    }
+    profile->sampleRates.insert(profile->sampleRates.end(), sampleRates.begin(), sampleRates.end());
+}
+
+AudioProfile createProfile(PcmType pcmType, const std::vector<int32_t>& channelLayouts,
+                           const std::vector<int32_t>& sampleRates) {
+    AudioProfile profile;
+    profile.format.type = AudioFormatType::PCM;
+    profile.format.pcm = pcmType;
+    fillProfile(channelLayouts, sampleRates, &profile);
+    return profile;
+}
+
+AudioProfile createProfile(const std::string& encodingType,
+                           const std::vector<int32_t>& channelLayouts,
+                           const std::vector<int32_t>& sampleRates) {
+    AudioProfile profile;
+    profile.format.encoding = encodingType;
+    fillProfile(channelLayouts, sampleRates, &profile);
+    return profile;
+}
+
+AudioPortExt createDeviceExt(AudioDeviceType devType, int32_t flags,
+                             const std::string& connection = "", const std::string& address = "") {
+    AudioPortDeviceExt deviceExt;
+    deviceExt.device.type.type = devType;
+    if (devType == AudioDeviceType::IN_MICROPHONE && connection.empty()) {
+        deviceExt.device.address = "bottom";
+    } else if (devType == AudioDeviceType::IN_MICROPHONE_BACK && connection.empty()) {
+        deviceExt.device.address = "back";
+    } else {
+        deviceExt.device.address = std::move(address);
+    }
+    deviceExt.device.type.connection = std::move(connection);
+    deviceExt.flags = flags;
+    return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
+}
+
+AudioPort createPort(int32_t id, const std::string& name, int32_t flags, bool isInput,
+                     const AudioPortExt& ext) {
+    AudioPort port;
+    port.id = id;
+    port.name = name;
+    port.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
+                         : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
+    port.ext = ext;
+    return port;
+}
+
+AudioGain createGain(int32_t mode, AudioChannelLayout channelMask, int32_t minValue,
+                     int32_t maxValue, int32_t defaultValue, int32_t stepValue,
+                     int32_t minRampMs = 100, int32_t maxRampMs = 100, bool useForVolume = true) {
+    AudioGain gain;
+    gain.mode = mode;
+    gain.channelMask = channelMask;
+    gain.minValue = minValue;
+    gain.maxValue = maxValue;
+    gain.defaultValue = defaultValue;
+    gain.stepValue = stepValue;
+    gain.minRampMs = minRampMs;
+    gain.maxRampMs = maxRampMs;
+    gain.useForVolume = useForVolume;
+    return gain;
+}
+}  // namespace
+
 ndk::ScopedAStatus AudioControl::registerFocusListener(
         const shared_ptr<IFocusListener>& in_listener) {
     LOG(DEBUG) << "registering focus listener";
@@ -190,6 +282,33 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus AudioControl::setModuleChangeCallback(
+        const std::shared_ptr<IModuleChangeCallback>& in_callback) {
+    LOG(DEBUG) << ": " << __func__;
+
+    if (in_callback.get() == nullptr) {
+        LOG(ERROR) << __func__ << ": Callback is nullptr";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (mModuleChangeCallback != nullptr) {
+        LOG(ERROR) << __func__ << ": Module change callback was already registered";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    std::atomic_store(&mModuleChangeCallback, in_callback);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::clearModuleChangeCallback() {
+    if (mModuleChangeCallback != nullptr) {
+        shared_ptr<IModuleChangeCallback> nullCallback = nullptr;
+        std::atomic_store(&mModuleChangeCallback, nullCallback);
+        LOG(DEBUG) << ":" << __func__ << ": Unregistered successfully";
+    } else {
+        LOG(DEBUG) << ":" << __func__ << ": No callback registered, no-op";
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
 binder_status_t AudioControl::dump(int fd, const char** args, uint32_t numArgs) {
     if (numArgs == 0) {
         return dumpsys(fd);
@@ -208,6 +327,8 @@
         return cmdAbandonFocusWithMetaData(fd, args, numArgs);
     } else if (EqualsIgnoreCase(option, "--audioGainCallback")) {
         return cmdOnAudioDeviceGainsChanged(fd, args, numArgs);
+    } else if (EqualsIgnoreCase(option, "--audioPortsChangedCallback")) {
+        return cmdOnAudioPortsChanged(fd, args, numArgs);
     } else {
         dprintf(fd, "Invalid option: %s\n", option.c_str());
         return STATUS_BAD_VALUE;
@@ -262,7 +383,21 @@
     dprintf(fd,
             "Tags are optional. If provided, it must follow the <key>=<value> pattern, where the "
             "value is namespaced (for example com.google.strategy=VR).\n");
-
+    dprintf(fd,
+            "--audioPortsChangedCallback <ID_1> <NAME_1> <BUS_ADDRESS_1> <CONNECTION_TYPE_1> "
+            "<AUDIO_GAINS_1> [<ID_N> <NAME_N> <BUS_ADDRESS_N> <CONNECTION_TYPE_N> "
+            "<AUDIO_GAINS_N>]: fires audio ports changed callback. Carries list of modified "
+            "AudioPorts. "
+            "For simplicity, this command accepts limited information for each AudioPort: "
+            "id(int), name(string), port address(string), connection type (string), "
+            "audio gain (csv int)\n");
+    dprintf(fd, "Notes: \n");
+    dprintf(fd,
+            "1. AudioGain csv should match definition at "
+            "android/media/audio/common/AudioPort.aidl\n");
+    dprintf(fd,
+            "2. See android/media/audio/common/AudioDeviceDescription.aidl for valid "
+            "<CONNECTION_TYPE> values.\n");
     return STATUS_OK;
 }
 
@@ -514,4 +649,166 @@
             toEnumString(reasons).c_str(), toString(agcis).c_str());
     return STATUS_OK;
 }
+
+binder_status_t AudioControl::parseAudioGains(int fd, const std::string& stringGain,
+                                              std::vector<AudioGain>& gains) {
+    const int kAudioGainSize = 9;
+    std::stringstream csvGain(stringGain);
+    std::vector<std::string> vecGain;
+    std::string value;
+    while (getline(csvGain, value, ',')) {
+        vecGain.push_back(value);
+    }
+
+    if ((vecGain.size() == 0) || ((vecGain.size() % kAudioGainSize) != 0)) {
+        dprintf(fd, "Erroneous input to generate AudioGain: %s\n", stringGain.c_str());
+        return STATUS_BAD_VALUE;
+    }
+
+    // iterate over injected AudioGains
+    for (int index = 0; index < vecGain.size(); index += kAudioGainSize) {
+        int32_t mode;
+        if (!safelyParseInt(vecGain[index], &mode)) {
+            dprintf(fd, "Non-integer index provided with request: %s\n", vecGain[index].c_str());
+            return STATUS_BAD_VALUE;
+        }
+
+        // car audio framework only supports JOINT mode.
+        // skip injected AudioGains that are not compliant with this.
+        if (mode != static_cast<int>(AudioGainMode::JOINT)) {
+            LOG(WARNING) << ":" << __func__ << ": skipping gain since it is not JOINT mode!";
+            continue;
+        }
+
+        int32_t layout;
+        if (!safelyParseInt(vecGain[index + 1], &layout)) {
+            dprintf(fd, "Non-integer index provided with request: %s\n",
+                    vecGain[index + 1].c_str());
+            return STATUS_BAD_VALUE;
+        }
+        AudioChannelLayout channelMask =
+                AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout);
+
+        int32_t minValue;
+        if (!safelyParseInt(vecGain[index + 2], &minValue)) {
+            dprintf(fd, "Non-integer index provided with request: %s\n",
+                    vecGain[index + 2].c_str());
+            return STATUS_BAD_VALUE;
+        }
+
+        int32_t maxValue;
+        if (!safelyParseInt(vecGain[index + 3], &maxValue)) {
+            dprintf(fd, "Non-integer index provided with request: %s\n",
+                    vecGain[index + 3].c_str());
+            return STATUS_BAD_VALUE;
+        }
+
+        int32_t defaultValue;
+        if (!safelyParseInt(vecGain[index + 4], &defaultValue)) {
+            dprintf(fd, "Non-integer index provided with request: %s\n",
+                    vecGain[index + 4].c_str());
+            return STATUS_BAD_VALUE;
+        }
+
+        int32_t stepValue;
+        if (!safelyParseInt(vecGain[index + 5], &stepValue)) {
+            dprintf(fd, "Non-integer index provided with request: %s\n",
+                    vecGain[index + 5].c_str());
+            return STATUS_BAD_VALUE;
+        }
+
+        int32_t minRampMs;
+        if (!safelyParseInt(vecGain[index + 6], &minRampMs)) {
+            dprintf(fd, "Non-integer index provided with request: %s\n",
+                    vecGain[index + 6].c_str());
+            return STATUS_BAD_VALUE;
+        }
+
+        int32_t maxRampMs;
+        if (!safelyParseInt(vecGain[index + 7], &maxRampMs)) {
+            dprintf(fd, "Non-integer index provided with request: %s\n",
+                    vecGain[index + 7].c_str());
+            return STATUS_BAD_VALUE;
+        }
+
+        ParseBoolResult useForVolume = ParseBool(vecGain[index + 8]);
+        if (useForVolume == ParseBoolResult::kError) {
+            dprintf(fd, "Non-boolean index provided with request: %s\n",
+                    vecGain[index + 8].c_str());
+            return STATUS_BAD_VALUE;
+        } else if (useForVolume == ParseBoolResult::kFalse) {
+            // at this level we only care about gain stages that are relevant
+            // for volume control. skip the gain stage if its flagged as false.
+            LOG(WARNING) << ":" << __func__
+                         << ": skipping gain since it is not for volume control!";
+            continue;
+        }
+
+        AudioGain gain = createGain(mode, channelMask, minValue, maxValue, defaultValue, stepValue,
+                                    minRampMs, maxRampMs, true /*useForVolume*/);
+        gains.push_back(gain);
+    }
+    return STATUS_OK;
+}
+
+binder_status_t AudioControl::cmdOnAudioPortsChanged(int fd, const char** args, uint32_t numArgs) {
+    if (!checkCallerHasWritePermissions(fd)) {
+        return STATUS_PERMISSION_DENIED;
+    }
+
+    if ((numArgs < 6) || ((numArgs - 1) % 5 != 0)) {
+        dprintf(fd,
+                "Invalid number of arguments: please provide\n"
+                "--audioPortsChangedCallback <ID_1> <NAME_1> <BUS_ADDRESS_1> <CONNECTION_TYPE_1> "
+                "<AUDIO_GAINS_1> [<ID_N> <NAME_N> <BUS_ADDRESS_N> <CONNECTION_TYPE_N> "
+                "<AUDIO_GAINS_N>]: triggers audio ports changed callback. Carries list of "
+                "modified AudioPorts. "
+                "For simplicity, this command accepts limited information for each AudioPort: "
+                "id(int), name(string), port address(string), connection type (string), "
+                "audio gain (csv int)\n");
+        return STATUS_BAD_VALUE;
+    }
+
+    std::vector<AudioPort> ports;
+    for (uint32_t i = 1; i < numArgs; i += 5) {
+        binder_status_t status;
+        int32_t id;
+        if (!safelyParseInt(std::string(args[i]), &id)) {
+            dprintf(fd, "Non-integer index provided with request: %s\n",
+                    std::string(args[i]).c_str());
+            return STATUS_BAD_VALUE;
+        }
+
+        std::string name = std::string(args[i + 1]);
+        std::string address = std::string(args[i + 2]);
+        std::string connection = std::string(args[i + 3]);
+
+        std::string stringGains = std::string(args[i + 4]);
+        std::vector<AudioGain> gains;
+        status = parseAudioGains(fd, stringGains, gains);
+        if (status != STATUS_OK) {
+            return status;
+        }
+
+        AudioPort port = createPort(
+                id, name, 0 /*flags*/, false /*isInput*/,
+                createDeviceExt(AudioDeviceType::OUT_DEVICE, 0 /*flags*/, connection, address));
+        port.gains.insert(port.gains.begin(), gains.begin(), gains.end());
+
+        ports.push_back(port);
+    }
+
+    if (mModuleChangeCallback == nullptr) {
+        dprintf(fd,
+                "Unable to trigger audio port callback for ports: %s \n"
+                " - no module change callback registered\n",
+                toString(ports).c_str());
+        return STATUS_BAD_VALUE;
+    }
+
+    // TODO (b/269139706) fix atomic read issue
+    mModuleChangeCallback->onAudioPortsChanged(ports);
+    dprintf(fd, "SUCCESS audio port callback for ports: %s \n", toString(ports).c_str());
+    return STATUS_OK;
+}
 }  // namespace aidl::android::hardware::automotive::audiocontrol
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.h b/automotive/audiocontrol/aidl/default/AudioControl.h
index 16b80e8..7eca446 100644
--- a/automotive/audiocontrol/aidl/default/AudioControl.h
+++ b/automotive/audiocontrol/aidl/default/AudioControl.h
@@ -21,11 +21,20 @@
 #include <aidl/android/hardware/automotive/audiocontrol/BnAudioControl.h>
 #include <aidl/android/hardware/automotive/audiocontrol/DuckingInfo.h>
 #include <aidl/android/hardware/automotive/audiocontrol/IAudioGainCallback.h>
+#include <aidl/android/hardware/automotive/audiocontrol/IModuleChangeCallback.h>
 #include <aidl/android/hardware/automotive/audiocontrol/MutingInfo.h>
 #include <aidl/android/hardware/automotive/audiocontrol/Reasons.h>
 
 #include <aidl/android/hardware/audio/common/PlaybackTrackMetadata.h>
 
+#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <aidl/android/media/audio/common/AudioDeviceType.h>
+#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+#include <aidl/android/media/audio/common/AudioFormatType.h>
+#include <aidl/android/media/audio/common/AudioGainMode.h>
+#include <aidl/android/media/audio/common/AudioIoFlags.h>
+#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+
 namespace aidl::android::hardware::automotive::audiocontrol {
 
 namespace audiohalcommon = ::aidl::android::hardware::audio::common;
@@ -51,6 +60,9 @@
             const std::vector<AudioGainConfigInfo>& in_gains) override;
     ndk::ScopedAStatus registerGainCallback(
             const std::shared_ptr<IAudioGainCallback>& in_callback) override;
+    ndk::ScopedAStatus setModuleChangeCallback(
+            const std::shared_ptr<IModuleChangeCallback>& in_callback) override;
+    ndk::ScopedAStatus clearModuleChangeCallback() override;
 
     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
 
@@ -67,15 +79,23 @@
      */
     std::shared_ptr<IAudioGainCallback> mAudioGainCallback = nullptr;
 
+    std::shared_ptr<IModuleChangeCallback> mModuleChangeCallback = nullptr;
+
     binder_status_t cmdHelp(int fd) const;
     binder_status_t cmdRequestFocus(int fd, const char** args, uint32_t numArgs);
     binder_status_t cmdAbandonFocus(int fd, const char** args, uint32_t numArgs);
     binder_status_t cmdRequestFocusWithMetaData(int fd, const char** args, uint32_t numArgs);
     binder_status_t cmdAbandonFocusWithMetaData(int fd, const char** args, uint32_t numArgs);
     binder_status_t cmdOnAudioDeviceGainsChanged(int fd, const char** args, uint32_t numArgs);
+    binder_status_t cmdOnAudioPortsChanged(int fd, const char** args, uint32_t numArgs);
 
     binder_status_t parseMetaData(int fd, const std::string& metadataLiteral,
                                   audiohalcommon::PlaybackTrackMetadata& trackMetadata);
+    binder_status_t parseAudioGains(
+            int fd, const std::string& stringGain,
+            std::vector<::aidl::android::media::audio::common::AudioGain>& gains);
+    binder_status_t parseSampleRates(int fd, const std::string& sampleRates,
+                                     std::vector<int32_t>& vecSampleRates);
 
     binder_status_t dumpsys(int fd);
 };
diff --git a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
index e82f6fa..95cd7f0 100644
--- a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
+++ b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
@@ -1,6 +1,7 @@
 <manifest version="2.0" type="device">
     <hal format="aidl">
         <name>android.hardware.automotive.audiocontrol</name>
+        <version>3</version>
         <fqname>IAudioControl/default</fqname>
     </hal>
 </manifest>
diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp
index 3d4be48..cfc2a3e 100644
--- a/automotive/audiocontrol/aidl/vts/Android.bp
+++ b/automotive/audiocontrol/aidl/vts/Android.bp
@@ -24,6 +24,7 @@
 cc_test {
     name: "VtsAidlHalAudioControlTest",
     defaults: [
+        "latest_android_media_audio_common_types_cpp_static",
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
     ],
@@ -37,9 +38,8 @@
         "libxml2",
     ],
     static_libs: [
-        "android.hardware.automotive.audiocontrol-V2-cpp",
+        "android.hardware.automotive.audiocontrol-V3-cpp",
         "android.hardware.audio.common-V1-cpp",
-        "android.media.audio.common.types-V1-cpp",
         "libgmock",
     ],
     test_suites: [
diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
index f4f5eef..4e7e963 100644
--- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
+++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
@@ -21,6 +21,7 @@
 
 #include <android/hardware/automotive/audiocontrol/BnAudioGainCallback.h>
 #include <android/hardware/automotive/audiocontrol/BnFocusListener.h>
+#include <android/hardware/automotive/audiocontrol/BnModuleChangeCallback.h>
 #include <android/hardware/automotive/audiocontrol/IAudioControl.h>
 #include <android/log.h>
 #include <binder/IServiceManager.h>
@@ -34,10 +35,14 @@
 using android::hardware::automotive::audiocontrol::AudioGainConfigInfo;
 using android::hardware::automotive::audiocontrol::BnAudioGainCallback;
 using android::hardware::automotive::audiocontrol::BnFocusListener;
+using android::hardware::automotive::audiocontrol::BnModuleChangeCallback;
 using android::hardware::automotive::audiocontrol::DuckingInfo;
 using android::hardware::automotive::audiocontrol::IAudioControl;
+using android::hardware::automotive::audiocontrol::IModuleChangeCallback;
 using android::hardware::automotive::audiocontrol::MutingInfo;
 using android::hardware::automotive::audiocontrol::Reasons;
+using ::testing::AnyOf;
+using ::testing::Eq;
 
 #include "android_audio_policy_configuration_V7_0.h"
 
@@ -48,15 +53,25 @@
 namespace audiohalcommon = android::hardware::audio::common;
 namespace audiomediacommon = android::media::audio::common;
 
+namespace {
+constexpr int32_t kAidlVersionThree = 3;
+}
+
 class AudioControlAidl : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
         audioControl = android::waitForDeclaredService<IAudioControl>(String16(GetParam().c_str()));
         ASSERT_NE(audioControl, nullptr);
+        aidlVersion = audioControl->getInterfaceVersion();
     }
 
+    void TearDown() override { audioControl = nullptr; }
+
+    bool isAidlVersionAtleast(int version) const { return aidlVersion >= version; }
+
     sp<IAudioControl> audioControl;
     int32_t capabilities;
+    int32_t aidlVersion;
 };
 
 TEST_P(AudioControlAidl, OnSetFadeTowardsFront) {
@@ -226,6 +241,57 @@
     ASSERT_TRUE(audioControl->registerGainCallback(gainCallback2).isOk());
 }
 
+/*
+ * Test Module change Callback registration.
+ *
+ * Verifies that:
+ * - setModuleChangeCallback succeeds
+ * - setting a double callback fails with exception
+ * - clearModuleChangeCallback succeeds
+ * - setting with nullptr callback fails with exception
+ * - closing handle does not crash
+ */
+struct ModuleChangeCallbackMock : BnModuleChangeCallback {
+    MOCK_METHOD(Status, onAudioPortsChanged,
+                (const std::vector<android::media::audio::common::AudioPort>& audioPorts));
+};
+
+TEST_P(AudioControlAidl, RegisterModuleChangeCallbackTwiceThrowsException) {
+    ALOGI("Register Module change callback test");
+    if (!isAidlVersionAtleast(kAidlVersionThree)) {
+        GTEST_SKIP() << "Device does not support the new APIs for module change callback";
+        return;
+    }
+
+    // make sure no stale callbacks.
+    audioControl->clearModuleChangeCallback();
+
+    sp<ModuleChangeCallbackMock> moduleChangeCallback = new ModuleChangeCallbackMock();
+    auto status = audioControl->setModuleChangeCallback(moduleChangeCallback);
+    EXPECT_THAT(status.exceptionCode(),
+                AnyOf(Eq(Status::EX_NONE), Eq(Status::EX_UNSUPPORTED_OPERATION)));
+    if (!status.isOk()) return;
+
+    sp<ModuleChangeCallbackMock> moduleChangeCallback2 = new ModuleChangeCallbackMock();
+    // no need to check for unsupported feature
+    EXPECT_EQ(Status::EX_ILLEGAL_STATE,
+              audioControl->setModuleChangeCallback(moduleChangeCallback2).exceptionCode());
+    ASSERT_TRUE(audioControl->clearModuleChangeCallback().isOk());
+    ASSERT_TRUE(audioControl->setModuleChangeCallback(moduleChangeCallback2).isOk());
+}
+
+TEST_P(AudioControlAidl, RegisterModuleChangeNullCallbackThrowsException) {
+    ALOGI("Register Module change callback with nullptr test");
+    if (!isAidlVersionAtleast(kAidlVersionThree)) {
+        GTEST_SKIP() << "Device does not support the new APIs for module change callback";
+        return;
+    }
+
+    auto status = audioControl->setModuleChangeCallback(nullptr);
+    EXPECT_THAT(status.exceptionCode(),
+                AnyOf(Eq(Status::EX_ILLEGAL_ARGUMENT), Eq(Status::EX_UNSUPPORTED_OPERATION)));
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlAidl);
 INSTANTIATE_TEST_SUITE_P(
         Audiocontrol, AudioControlAidl,
diff --git a/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp b/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp
index 624538b..37c863b 100644
--- a/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp
+++ b/automotive/can/1.0/default/libc++fs/src/filesystem/directory_iterator.cpp
@@ -169,8 +169,8 @@
   __dir_stream& operator=(const __dir_stream&) = delete;
 
   __dir_stream(__dir_stream&& other) noexcept : __stream_(other.__stream_),
-                                                __root_(move(other.__root_)),
-                                                __entry_(move(other.__entry_)) {
+                                                __root_(std::move(other.__root_)),
+                                                __entry_(std::move(other.__entry_)) {
     other.__stream_ = nullptr;
   }
 
@@ -252,7 +252,7 @@
 
   error_code m_ec;
   if (!__imp_->advance(m_ec)) {
-    path root = move(__imp_->__root_);
+    path root = std::move(__imp_->__root_);
     __imp_.reset();
     if (m_ec)
       err.report(m_ec, "at root \"%s\"", root);
@@ -286,7 +286,7 @@
 
   __imp_ = make_shared<__shared_imp>();
   __imp_->__options_ = opt;
-  __imp_->__stack_.push(move(new_s));
+  __imp_->__stack_.push(std::move(new_s));
 }
 
 void recursive_directory_iterator::__pop(error_code* ec) {
@@ -340,7 +340,7 @@
   }
 
   if (m_ec) {
-    path root = move(stack.top().__root_);
+    path root = std::move(stack.top().__root_);
     __imp_.reset();
     err.report(m_ec, "at root \"%s\"", root);
   } else {
@@ -374,7 +374,7 @@
   if (!skip_rec) {
     __dir_stream new_it(curr_it.__entry_.path(), __imp_->__options_, m_ec);
     if (new_it.good()) {
-      __imp_->__stack_.push(move(new_it));
+      __imp_->__stack_.push(std::move(new_it));
       return true;
     }
   }
@@ -385,7 +385,7 @@
       if (ec)
         ec->clear();
     } else {
-      path at_ent = move(curr_it.__entry_.__p_);
+      path at_ent = std::move(curr_it.__entry_.__p_);
       __imp_.reset();
       err.report(m_ec, "attempting recursion into \"%s\"", at_ent);
     }
diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp
index 083f4f0..2a0545a 100644
--- a/automotive/can/1.0/default/libnetdevice/can.cpp
+++ b/automotive/can/1.0/default/libnetdevice/can.cpp
@@ -80,7 +80,7 @@
 
     {
         auto linkinfo = req.addNested(IFLA_LINKINFO);
-        req.add(IFLA_INFO_KIND, "can");
+        req.addBuffer(IFLA_INFO_KIND, "can");
         {
             auto infodata = req.addNested(IFLA_INFO_DATA);
             /* For CAN FD, it would require to add IFLA_CAN_DATA_BITTIMING
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
index 8df6434..8471173 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
@@ -47,7 +47,7 @@
     return params;
 }
 
-bool send(unsigned long request, struct ifreq& ifr) {
+int trySend(unsigned long request, struct ifreq& ifr) {
     const auto sp = getSocketParams(socketDomain);
     base::unique_fd sock(socket(sp.domain, sp.type, sp.protocol));
     if (!sock.ok()) {
@@ -55,7 +55,12 @@
         return false;
     }
 
-    if (ioctl(sock.get(), request, &ifr) < 0) {
+    if (ioctl(sock.get(), request, &ifr) < 0) return errno;
+    return 0;
+}
+
+bool send(unsigned long request, struct ifreq& ifr) {
+    if (trySend(request, ifr) != 0) {
         PLOG(ERROR) << "ioctl(" << std::hex << request << std::dec << ") failed";
         return false;
     }
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.h b/automotive/can/1.0/default/libnetdevice/ifreqs.h
index 74e5877..d8d6fe0 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.h
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.h
@@ -28,6 +28,15 @@
 extern std::atomic_int socketDomain;
 
 /**
+ * Tries to send ioctl interface request.
+ *
+ * \param request Request type (such as SIOCGIFFLAGS)
+ * \param ifr Request data (both input and output)
+ * \return error code of the call (0 for success)
+ */
+int trySend(unsigned long request, struct ifreq& ifr);
+
+/**
  * Sends ioctl interface request.
  *
  * \param request Request type (such as SIOCGIFFLAGS)
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
index 70cb688..657f9b2 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
@@ -68,20 +68,32 @@
     PRESENT_AND_UP,
 
     /**
+     * Interface is up and with IPv4 address configured.
+     */
+    PRESENT_AND_IPV4,
+
+    /**
      * Interface is down or not present (disconnected) at all.
      */
     DOWN_OR_GONE,
 };
 
+enum class Quantifier {
+    ALL_OF,
+    ANY_OF,
+};
+
 /**
  * Listens for interface changes until anticipated condition takes place.
  *
  * \param ifnames List of interfaces to watch for.
  * \param cnd Awaited condition.
- * \param allOf true if all interfaces need to satisfy the condition, false if only one satistying
+ * \param quant Whether all interfaces need to satisfy the condition or just one satistying
  *        interface should stop the wait.
+ * \return name of one interface that satisfied the condition
  */
-void waitFor(std::set<std::string> ifnames, WaitCondition cnd, bool allOf = true);
+std::optional<std::string> waitFor(std::set<std::string> ifnames, WaitCondition cnd,
+                                   Quantifier quant = Quantifier::ALL_OF);
 
 /**
  * Brings network interface up.
diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
index 4c5b309..aad07de 100644
--- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
+++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
@@ -60,7 +60,7 @@
 
     {
         auto linkinfo = req.addNested(IFLA_LINKINFO);
-        req.add(IFLA_INFO_KIND, type);
+        req.addBuffer(IFLA_INFO_KIND, type);
     }
 
     nl::Socket sock(NETLINK_ROUTE);
@@ -100,23 +100,36 @@
     return ifr.ifr_flags & IFF_UP;
 }
 
+static bool hasIpv4(std::string ifname) {
+    auto ifr = ifreqs::fromName(ifname);
+    switch (const auto status = ifreqs::trySend(SIOCGIFADDR, ifr)) {
+        case 0:
+            return true;
+        case EADDRNOTAVAIL:
+        case ENODEV:
+            return false;
+        default:
+            PLOG(WARNING) << "Failed checking IPv4 address";
+            return false;
+    }
+}
+
 struct WaitState {
     bool present;
     bool up;
+    bool hasIpv4Addr;
 
     bool satisfied(WaitCondition cnd) const {
         switch (cnd) {
             case WaitCondition::PRESENT:
-                if (present) return true;
-                break;
+                return present;
             case WaitCondition::PRESENT_AND_UP:
-                if (present && up) return true;
-                break;
+                return present && up;
+            case WaitCondition::PRESENT_AND_IPV4:
+                return present && up && hasIpv4Addr;
             case WaitCondition::DOWN_OR_GONE:
-                if (!present || !up) return true;
-                break;
+                return !present || !up;
         }
-        return false;
     }
 };
 
@@ -126,11 +139,22 @@
             return "become present";
         case WaitCondition::PRESENT_AND_UP:
             return "come up";
+        case WaitCondition::PRESENT_AND_IPV4:
+            return "get IPv4 address";
         case WaitCondition::DOWN_OR_GONE:
             return "go down";
     }
 }
 
+static std::string toString(Quantifier quant) {
+    switch (quant) {
+        case Quantifier::ALL_OF:
+            return "all of";
+        case Quantifier::ANY_OF:
+            return "any of";
+    }
+}
+
 static std::string toString(const std::set<std::string>& ifnames) {
     std::stringstream ss;
     std::copy(ifnames.begin(), ifnames.end(), std::ostream_iterator<std::string>(ss, ","));
@@ -139,50 +163,73 @@
     return str;
 }
 
-void waitFor(std::set<std::string> ifnames, WaitCondition cnd, bool allOf) {
-    nl::Socket sock(NETLINK_ROUTE, 0, RTMGRP_LINK);
+std::optional<std::string> waitFor(std::set<std::string> ifnames, WaitCondition cnd,
+                                   Quantifier quant) {
+    nl::Socket sock(NETLINK_ROUTE, 0, RTMGRP_LINK | RTMGRP_IPV4_IFADDR);
 
     using StatesMap = std::map<std::string, WaitState>;
     StatesMap states = {};
     for (const auto ifname : ifnames) {
         const auto present = exists(ifname);
         const auto up = present && isUp(ifname).value_or(false);
-        states[ifname] = {present, up};
+        const auto hasIpv4Addr = present && hasIpv4(ifname);
+        states[ifname] = {present, up, hasIpv4Addr};
     }
 
     const auto mapConditionChecker = [cnd](const StatesMap::iterator::value_type& it) {
         return it.second.satisfied(cnd);
     };
-    const auto isFullySatisfied = [&states, allOf, mapConditionChecker]() {
-        if (allOf) {
-            return std::all_of(states.begin(), states.end(), mapConditionChecker);
-        } else {
-            return std::any_of(states.begin(), states.end(), mapConditionChecker);
+    const auto isFullySatisfied = [&states, quant,
+                                   mapConditionChecker]() -> std::optional<std::string> {
+        if (quant == Quantifier::ALL_OF) {
+            if (!std::all_of(states.begin(), states.end(), mapConditionChecker)) return {};
+            return states.begin()->first;
+        } else {  // Quantifier::ANY_OF
+            const auto it = std::find_if(states.begin(), states.end(), mapConditionChecker);
+            if (it == states.end()) return {};
+            return it->first;
         }
     };
 
-    if (isFullySatisfied()) return;
+    if (const auto iface = isFullySatisfied()) return iface;
 
-    LOG(DEBUG) << "Waiting for " << (allOf ? "" : "any of ") << toString(ifnames) << " to "
+    LOG(DEBUG) << "Waiting for " << toString(quant) << " " << toString(ifnames) << " to "
                << toString(cnd);
     for (const auto rawMsg : sock) {
-        const auto msg = nl::Message<ifinfomsg>::parse(rawMsg, {RTM_NEWLINK, RTM_DELLINK});
-        if (!msg.has_value()) continue;
+        if (const auto msg = nl::Message<ifinfomsg>::parse(rawMsg, {RTM_NEWLINK, RTM_DELLINK});
+            msg.has_value()) {
+            // Interface added / removed
+            const auto ifname = msg->attributes.get<std::string>(IFLA_IFNAME);
+            if (ifnames.count(ifname) == 0) continue;
 
-        const auto ifname = msg->attributes.get<std::string>(IFLA_IFNAME);
-        if (ifnames.count(ifname) == 0) continue;
+            auto& state = states[ifname];
+            state.present = (msg->header.nlmsg_type != RTM_DELLINK);
+            state.up = state.present && (msg->data.ifi_flags & IFF_UP) != 0;
+            if (!state.present) state.hasIpv4Addr = false;
 
-        const bool present = (msg->header.nlmsg_type != RTM_DELLINK);
-        const bool up = present && (msg->data.ifi_flags & IFF_UP) != 0;
-        states[ifname] = {present, up};
+        } else if (const auto msg =
+                           nl::Message<ifaddrmsg>::parse(rawMsg, {RTM_NEWADDR, RTM_DELADDR});
+                   msg.has_value()) {
+            // Address added / removed
+            const auto ifname = msg->attributes.get<std::string>(IFLA_IFNAME);
+            if (ifnames.count(ifname) == 0) continue;
 
-        if (isFullySatisfied()) {
-            LOG(DEBUG) << "Finished waiting for " << (allOf ? "" : "some of ") << toString(ifnames)
+            if (msg->header.nlmsg_type == RTM_NEWADDR) {
+                states[ifname].hasIpv4Addr = true;
+            } else {
+                // instead of tracking which one got deleted, let's just ask
+                states[ifname].hasIpv4Addr = hasIpv4(ifname);
+            }
+        }
+
+        if (const auto iface = isFullySatisfied()) {
+            LOG(DEBUG) << "Finished waiting for " << toString(quant) << " " << toString(ifnames)
                        << " to " << toString(cnd);
-            return;
+            return iface;
         }
     }
     LOG(FATAL) << "Can't read Netlink socket";
+    return {};
 }
 
 }  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp
index ee02f7b..35b21b8 100644
--- a/automotive/can/1.0/default/libnetdevice/vlan.cpp
+++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp
@@ -40,7 +40,7 @@
 
     {
         auto linkinfo = req.addNested(IFLA_LINKINFO);
-        req.add(IFLA_INFO_KIND, "vlan");
+        req.addBuffer(IFLA_INFO_KIND, "vlan");
 
         {
             auto linkinfo = req.addNested(IFLA_INFO_DATA);
diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp
index 2ebd1b4..01c1e55 100644
--- a/automotive/can/1.0/default/libnl++/Android.bp
+++ b/automotive/can/1.0/default/libnl++/Android.bp
@@ -37,8 +37,10 @@
         "protocols/generic/Unknown.cpp",
         "protocols/generic/families/Mac80211hwsim.cpp",
         "protocols/generic/families/Nl80211.cpp",
+        "protocols/route/Addr.cpp",
         "protocols/route/Link.cpp",
         "protocols/route/Route.cpp",
+        "protocols/route/attributes.cpp",
         "protocols/route/structs.cpp",
         "protocols/MessageDefinition.cpp",
         "protocols/NetlinkProtocol.cpp",
diff --git a/automotive/can/1.0/default/libnl++/MessageFactory.cpp b/automotive/can/1.0/default/libnl++/MessageFactory.cpp
index 6f35897..eff068e 100644
--- a/automotive/can/1.0/default/libnl++/MessageFactory.cpp
+++ b/automotive/can/1.0/default/libnl++/MessageFactory.cpp
@@ -27,8 +27,8 @@
 
 nlattr* MessageFactoryBase::add(nlmsghdr* msg, size_t maxLen, nlattrtype_t type, const void* data,
                                 size_t dataLen) {
-    const auto totalAttrLen = impl::space<nlattr>(dataLen);
-    const auto newLen = impl::align(msg->nlmsg_len) + totalAttrLen;
+    const auto totalAttrLen = impl::length<nlattr>(dataLen);
+    const auto newLen = impl::align(msg->nlmsg_len) + impl::align(totalAttrLen);
     if (newLen > maxLen) {
         LOG(ERROR) << "Can't add attribute of size " << dataLen  //
                    << " - exceeded maxLen: " << newLen << " > " << maxLen;
diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp
index cc1d839..221063d 100644
--- a/automotive/can/1.0/default/libnl++/Socket.cpp
+++ b/automotive/can/1.0/default/libnl++/Socket.cpp
@@ -47,6 +47,17 @@
     }
 }
 
+void Socket::clearPollErr() {
+    sockaddr_nl sa = {};
+    socklen_t saLen = sizeof(sa);
+    const auto bytesReceived = recvfrom(mFd.get(), mReceiveBuffer.data(), mReceiveBuffer.size(), 0,
+                                        reinterpret_cast<sockaddr*>(&sa), &saLen);
+    if (errno != EINVAL) {
+        PLOG(WARNING) << "clearPollError() caught unexpected error: ";
+    }
+    CHECK_LE(bytesReceived, 0) << "clearPollError() didn't find an error!";
+}
+
 bool Socket::send(const Buffer<nlmsghdr>& msg, const sockaddr_nl& sa) {
     if constexpr (kSuperVerbose) {
         LOG(VERBOSE) << (mFailed ? "(not) " : "") << "sending to " << sa.nl_pid << ": "
@@ -110,6 +121,13 @@
     if constexpr (kSuperVerbose) {
         LOG(VERBOSE) << "received from " << sa.nl_pid << ": " << toString(msg, mProtocol);
     }
+    long headerByteTotal = 0;
+    for (const auto hdr : msg) {
+        headerByteTotal += hdr->nlmsg_len;
+    }
+    if (bytesReceived != headerByteTotal) {
+        LOG(ERROR) << "received " << bytesReceived << " bytes, header claims " << headerByteTotal;
+    }
     return {msg, sa};
 }
 
@@ -159,6 +177,7 @@
 }
 
 pollfd Socket::preparePoll(short events) {
+    CHECK(mFd.get() > 0) << "Netlink socket fd is invalid!";
     return {mFd.get(), events, 0};
 }
 
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h
index c3d72c5..a5a425e 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h
@@ -106,18 +106,25 @@
      */
     template <class A>
     void add(nlattrtype_t type, const A& attr) {
-        add(type, &attr, sizeof(attr));
+        addInternal(type, &attr, sizeof(attr));
     }
 
+    // It will always send the last null character, otherwise use addBuffer
+    // variant instead
     template <>
     void add(nlattrtype_t type, const std::string& s) {
-        add(type, s.c_str(), s.size() + 1);
+        addInternal(type, s.c_str(), s.size() + 1);
+    }
+
+    void addBuffer(nlattrtype_t type, const std::string_view& s) {
+        addInternal(type, s.data(), s.size());
     }
 
     /** Guard class to frame nested attributes. \see addNested(nlattrtype_t). */
     class [[nodiscard]] NestedGuard {
       public:
-        NestedGuard(MessageFactory & req, nlattrtype_t type) : mReq(req), mAttr(req.add(type)) {}
+        NestedGuard(MessageFactory& req, nlattrtype_t type)
+            : mReq(req), mAttr(req.addInternal(type)) {}
         ~NestedGuard() { closeNested(&mReq.mMessage.header, mAttr); }
 
       private:
@@ -138,7 +145,7 @@
      *    MessageFactory<ifinfomsg> req(RTM_NEWLINK, NLM_F_REQUEST);
      *    {
      *        auto linkinfo = req.addNested(IFLA_LINKINFO);
-     *        req.add(IFLA_INFO_KIND, "can");
+     *        req.addBuffer(IFLA_INFO_KIND, "can");
      *        {
      *            auto infodata = req.addNested(IFLA_INFO_DATA);
      *            req.add(IFLA_CAN_BITTIMING, bitTimingStruct);
@@ -154,7 +161,7 @@
     Message mMessage = {};
     bool mIsGood = true;
 
-    nlattr* add(nlattrtype_t type, const void* data = nullptr, size_t len = 0) {
+    nlattr* addInternal(nlattrtype_t type, const void* data = nullptr, size_t len = 0) {
         if (!mIsGood) return nullptr;
         auto attr = MessageFactoryBase::add(&mMessage.header, sizeof(mMessage), type, data, len);
         if (attr == nullptr) mIsGood = false;
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
index 7ec0f7b..996a350 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
@@ -55,6 +55,12 @@
     Socket(int protocol, unsigned pid = 0, uint32_t groups = 0);
 
     /**
+     * Attempt to clear POLLERR by recv-ing.
+     * TODO(224850481): determine if this is necessary, or if the socket is locked up anyway.
+     */
+    void clearPollErr();
+
+    /**
      * Send Netlink message with incremented sequence number to the Kernel.
      *
      * \param msg Message to send. Its sequence number will be updated.
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/bits.h b/automotive/can/1.0/default/libnl++/include/libnl++/bits.h
index 4c8f1aa..b6573b3 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/bits.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/bits.h
@@ -36,11 +36,19 @@
 }
 
 /**
+ * Equivalent to NLMSG_LENGTH(len).
+ */
+template <typename H>
+constexpr size_t length(size_t len) {
+    return align(sizeof(H)) + len;
+}
+
+/**
  * Equivalent to NLMSG_SPACE(len).
  */
 template <typename H>
 constexpr size_t space(size_t len) {
-    return align(align(sizeof(H)) + len);
+    return align(length<H>(len));
 }
 
 /**
diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp
index aaf24a5..158d2a1 100644
--- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp
@@ -34,7 +34,7 @@
 
 MessageDescriptor::MessageDescriptor(const std::string& name,
                                      const MessageDetailsMap&& messageDetails,
-                                     const AttributeMap&& attrTypes, size_t contentsSize)
+                                     const AttributeMap& attrTypes, size_t contentsSize)
     : mName(name),
       mContentsSize(contentsSize),
       mMessageDetails(messageDetails),
diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h
index 8bed5e7..33ded9a 100644
--- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h
+++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h
@@ -163,7 +163,7 @@
 
   protected:
     MessageDescriptor(const std::string& name, const MessageDetailsMap&& messageDetails,
-                      const AttributeMap&& attrTypes, size_t contentsSize);
+                      const AttributeMap& attrTypes, size_t contentsSize);
 
   private:
     const std::string mName;
@@ -183,7 +183,7 @@
     MessageDefinition(  //
             const std::string& name,
             const std::initializer_list<MessageDescriptor::MessageDetailsMap::value_type> msgDet,
-            const std::initializer_list<AttributeMap::value_type> attrTypes = {})
+            const AttributeMap& attrTypes = {})
         : MessageDescriptor(name, msgDet, attrTypes, sizeof(T)) {}
 
     void dataToStream(std::stringstream& ss, const Buffer<nlmsghdr> hdr) const override {
diff --git a/automotive/can/1.0/default/libnl++/protocols/all.cpp b/automotive/can/1.0/default/libnl++/protocols/all.cpp
index a398dc8..72c60f2 100644
--- a/automotive/can/1.0/default/libnl++/protocols/all.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/all.cpp
@@ -33,12 +33,12 @@
     return map;
 }
 
-static auto all = toMap({
-        std::make_unique<generic::Generic>(),
-        std::make_unique<route::Route>(),
-});
-
 std::optional<std::reference_wrapper<NetlinkProtocol>> get(int protocol) {
+    static auto all = toMap({
+            std::make_unique<generic::Generic>(),
+            std::make_unique<route::Route>(),
+    });
+
     if (all.count(protocol) == 0) return std::nullopt;
     return *all.find(protocol)->second.get();
 }
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp
index 900560e..3ad101e 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp
@@ -30,6 +30,7 @@
     const auto familyName = msg.attributes.get<std::string>(CTRL_ATTR_FAMILY_NAME);
     const auto familyId = msg.attributes.get<uint16_t>(CTRL_ATTR_FAMILY_ID);
 
+    // TODO(224845900): NETLINK_GENERIC == 16, and (erroneously?) sets off this warning
     if (familyId < GENL_START_ALLOC) {
         LOG(WARNING) << "Invalid family ID: " << familyId;
         return true;
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp
new file mode 100644
index 0000000..024d389
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Addr.h"
+
+#include "../structs.h"
+#include "attributes.h"
+#include "structs.h"
+
+namespace android::nl::protocols::route {
+
+using DataType = AttributeDefinition::DataType;
+
+// clang-format off
+Addr::Addr() : MessageDefinition<ifaddrmsg>("addr", {
+    {RTM_NEWADDR, {"NEWADDR", MessageGenre::New}},
+    {RTM_DELADDR, {"DELADDR", MessageGenre::Delete}},
+    {RTM_GETADDR, {"GETADDR", MessageGenre::Get}},
+}, gAttributes) {}
+
+static const FlagsMap ifaFlagsMap {
+    {IFA_F_SECONDARY, "SECONDARY"},
+    {IFA_F_NODAD, "NODAD"},
+    {IFA_F_OPTIMISTIC, "OPTIMISTIC"},
+    {IFA_F_DADFAILED, "DADFAILED"},
+    {IFA_F_HOMEADDRESS, "HOMEADDRESS"},
+    {IFA_F_DEPRECATED, "DEPRECATED"},
+    {IFA_F_TENTATIVE, "TENTATIVE"},
+    {IFA_F_PERMANENT, "PERMANENT"},
+    {IFA_F_MANAGETEMPADDR, "MANAGETEMPADDR"},
+    {IFA_F_NOPREFIXROUTE, "NOPREFIXROUTE"},
+    {IFA_F_MCAUTOJOIN, "MCAUTOJOIN"},
+    {IFA_F_STABLE_PRIVACY, "STABLE_PRIVACY"},
+};
+// clang-format on
+
+void Addr::toStream(std::stringstream& ss, const ifaddrmsg& data) const {
+    ss << "ifaddrmsg{"
+       << "family=" << familyToString(data.ifa_family)
+       << ", prefixlen=" << unsigned(data.ifa_prefixlen) << ", flags=";
+    flagsToStream(ss, ifaFlagsMap, data.ifa_flags);
+    ss << ", scope=" << unsigned(data.ifa_scope) << ", index=" << data.ifa_index << "}";
+}
+
+}  // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Addr.h b/automotive/can/1.0/default/libnl++/protocols/route/Addr.h
new file mode 100644
index 0000000..b6b8bdc
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Addr.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../MessageDefinition.h"
+
+#include <linux/rtnetlink.h>
+
+namespace android::nl::protocols::route {
+
+class Addr : public MessageDefinition<ifaddrmsg> {
+  public:
+    Addr();
+    void toStream(std::stringstream& ss, const ifaddrmsg& data) const override;
+};
+
+}  // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp
index 9cc05da..3dd0066 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp
@@ -16,10 +16,7 @@
 
 #include "Link.h"
 
-#include "../structs.h"
-#include "structs.h"
-
-#include <net/if.h>
+#include "attributes.h"
 
 namespace android::nl::protocols::route {
 
@@ -30,83 +27,8 @@
     {RTM_NEWLINK, {"NEWLINK", MessageGenre::New}},
     {RTM_DELLINK, {"DELLINK", MessageGenre::Delete}},
     {RTM_GETLINK, {"GETLINK", MessageGenre::Get}},
-}, {
-    {IFLA_ADDRESS, {"ADDRESS"}},
-    {IFLA_BROADCAST, {"BROADCAST"}},
-    {IFLA_IFNAME, {"IFNAME", DataType::String}},
-    {IFLA_MTU, {"MTU", DataType::Uint}},
-    {IFLA_LINK, {"LINK", DataType::Uint}},
-    {IFLA_QDISC, {"QDISC", DataType::String}},
-    {IFLA_STATS, {"STATS", DataType::Struct, statsToStream<rtnl_link_stats>}},
-    {IFLA_COST, {"COST"}},
-    {IFLA_PRIORITY, {"PRIORITY"}},
-    {IFLA_MASTER, {"MASTER", DataType::Uint}},
-    {IFLA_WIRELESS, {"WIRELESS"}},
-    {IFLA_PROTINFO, {"PROTINFO"}},
-    {IFLA_TXQLEN, {"TXQLEN", DataType::Uint}},
-    {IFLA_MAP, {"MAP", DataType::Struct, mapToStream}},
-    {IFLA_WEIGHT, {"WEIGHT", DataType::Uint}},
-    {IFLA_OPERSTATE, {"OPERSTATE", DataType::Uint}},
-    {IFLA_LINKMODE, {"LINKMODE", DataType::Uint}},
-    {IFLA_LINKINFO, {"LINKINFO", DataType::Nested, AttributeMap{
-        {IFLA_INFO_KIND, {"INFO_KIND", DataType::String}},
-        {IFLA_INFO_DATA, {"INFO_DATA", DataType::Nested}},
-        {IFLA_INFO_XSTATS, {"INFO_XSTATS"}},
-        {IFLA_INFO_SLAVE_KIND, {"INFO_SLAVE_KIND", DataType::String}},
-        {IFLA_INFO_SLAVE_DATA, {"INFO_SLAVE_DATA"}},
-    }}},
-    {IFLA_NET_NS_PID, {"NET_NS_PID", DataType::Uint}},
-    {IFLA_IFALIAS, {"IFALIAS", DataType::String}},
-    {IFLA_NUM_VF, {"NUM_VF", DataType::Uint}},
-    {IFLA_VFINFO_LIST, {"VFINFO_LIST"}},
-    {IFLA_STATS64, {"STATS64", DataType::Struct, statsToStream<rtnl_link_stats64>}},
-    {IFLA_VF_PORTS, {"VF_PORTS"}},
-    {IFLA_PORT_SELF, {"PORT_SELF"}},
-    {IFLA_AF_SPEC, {"AF_SPEC", DataType::Nested, AttributeMap{
-        {AF_INET, {"AF_INET", DataType::Nested, AttributeMap{
-            {IFLA_INET_CONF, {"INET_CONF", DataType::Struct, arrayToStream<int32_t>}},
-        }}},
-        {AF_INET6, {"AF_INET6", DataType::Nested, AttributeMap{
-            {IFLA_INET6_FLAGS, {"INET6_FLAGS", DataType::Uint}},
-            {IFLA_INET6_CONF, {"INET6_CONF", DataType::Struct, arrayToStream<int32_t>}},
-            {IFLA_INET6_STATS, {"INET6_STATS", DataType::Struct, arrayToStream<uint64_t>}},
-            {IFLA_INET6_MCAST, {"INET6_MCAST"}},
-            {IFLA_INET6_CACHEINFO, {"INET6_CACHEINFO", DataType::Struct, ifla_cacheinfoToStream}},
-            {IFLA_INET6_ICMP6STATS, {"INET6_ICMP6STATS", DataType::Struct, arrayToStream<uint64_t>}},
-            {IFLA_INET6_TOKEN, {"INET6_TOKEN"}},
-            {IFLA_INET6_ADDR_GEN_MODE, {"INET6_ADDR_GEN_MODE", DataType::Uint}},
-        }}},
-    }}},
-    {IFLA_GROUP, {"GROUP", DataType::Uint}},
-    {IFLA_NET_NS_FD, {"NET_NS_FD", DataType::Uint}},
-    {IFLA_EXT_MASK, {"EXT_MASK", DataType::Uint}},
-    {IFLA_PROMISCUITY, {"PROMISCUITY", DataType::Uint}},
-    {IFLA_NUM_TX_QUEUES, {"NUM_TX_QUEUES", DataType::Uint}},
-    {IFLA_NUM_RX_QUEUES, {"NUM_RX_QUEUES", DataType::Uint}},
-    {IFLA_CARRIER, {"CARRIER", DataType::Uint}},
-    {IFLA_PHYS_PORT_ID, {"PHYS_PORT_ID"}},
-    {IFLA_CARRIER_CHANGES, {"CARRIER_CHANGES", DataType::Uint}},
-    {IFLA_PHYS_SWITCH_ID, {"PHYS_SWITCH_ID"}},
-    {IFLA_LINK_NETNSID, {"LINK_NETNSID"}},  // NLA_S32
-    {IFLA_PHYS_PORT_NAME, {"PHYS_PORT_NAME", DataType::String}},
-    {IFLA_PROTO_DOWN, {"PROTO_DOWN", DataType::Uint}},
-    {IFLA_GSO_MAX_SEGS, {"GSO_MAX_SEGS", DataType::Uint}},
-    {IFLA_GSO_MAX_SIZE, {"GSO_MAX_SIZE", DataType::Uint}},
-    {IFLA_PAD, {"PAD"}},
-    {IFLA_XDP, {"XDP"}},
-    {IFLA_EVENT, {"EVENT", DataType::Uint}},
-    {IFLA_NEW_NETNSID, {"NEW_NETNSID"}},  // NLA_S32
-    {IFLA_TARGET_NETNSID, {"TARGET_NETNSID"}},  // NLA_S32
-    {IFLA_CARRIER_UP_COUNT, {"CARRIER_UP_COUNT", DataType::Uint}},
-    {IFLA_CARRIER_DOWN_COUNT, {"CARRIER_DOWN_COUNT", DataType::Uint}},
-    {IFLA_NEW_IFINDEX, {"NEW_IFINDEX"}},  // NLA_S32
-    {IFLA_MIN_MTU, {"MIN_MTU", DataType::Uint}},
-    {IFLA_MAX_MTU, {"MAX_MTU", DataType::Uint}},
-    {IFLA_PROP_LIST, {"PROP_LIST"}},
-    {IFLA_ALT_IFNAME, {"ALT_IFNAME", DataType::String}},
-    {IFLA_PERM_ADDRESS, {"PERM_ADDRESS"}},
-}) {}
-// clang-format off
+}, gAttributes) {}
+// clang-format on
 
 void Link::toStream(std::stringstream& ss, const ifinfomsg& data) const {
     ss << "ifinfomsg{"
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp
index c134911..51e5b11 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp
@@ -16,10 +16,16 @@
 
 #include "Route.h"
 
+#include "Addr.h"
 #include "Link.h"
 
 namespace android::nl::protocols::route {
 
-Route::Route() : NetlinkProtocol(NETLINK_ROUTE, "ROUTE", {std::make_shared<Link>()}) {}
+// clang-format off
+Route::Route() : NetlinkProtocol(NETLINK_ROUTE, "ROUTE", {
+    std::make_shared<Addr>(),
+    std::make_shared<Link>(),
+}) {}
+// clang-format on
 
 }  // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp b/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp
new file mode 100644
index 0000000..69d9b81
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "attributes.h"
+
+#include "../structs.h"
+#include "structs.h"
+
+#include <linux/rtnetlink.h>
+#include <net/if.h>
+
+namespace android::nl::protocols::route {
+
+using DataType = AttributeDefinition::DataType;
+using Flags = AttributeDefinition::Flags;
+
+// clang-format off
+AttributeMap gAttributes = {
+    {IFLA_ADDRESS, {"ADDRESS"}},
+    {IFLA_BROADCAST, {"BROADCAST"}},
+    {IFLA_IFNAME, {"IFNAME", DataType::StringNul}},
+    {IFLA_MTU, {"MTU", DataType::Uint}},
+    {IFLA_LINK, {"LINK", DataType::Uint}},
+    {IFLA_QDISC, {"QDISC", DataType::Raw, AttributeMap{}, Flags::Verbose}},  // should be DataType::String, but looks like binary blob
+    {IFLA_STATS, {"STATS", DataType::Struct, statsToStream<rtnl_link_stats>}},
+    {IFLA_COST, {"COST", DataType::Uint}},
+    {IFLA_PRIORITY, {"PRIORITY"}},
+    {IFLA_MASTER, {"MASTER", DataType::Uint}},
+    {IFLA_WIRELESS, {"WIRELESS"}},
+    {IFLA_PROTINFO, {"PROTINFO"}},
+    {IFLA_TXQLEN, {"TXQLEN", DataType::Uint}},
+    {IFLA_MAP, {"MAP", DataType::Struct, mapToStream}},
+    {IFLA_WEIGHT, {"WEIGHT", DataType::Uint}},
+    {IFLA_OPERSTATE, {"OPERSTATE", DataType::Uint}},
+    {IFLA_LINKMODE, {"LINKMODE", DataType::Uint}},
+    {IFLA_LINKINFO, {"LINKINFO", DataType::Nested, AttributeMap{
+        {IFLA_INFO_KIND, {"INFO_KIND", DataType::String}},
+        {IFLA_INFO_DATA, {"INFO_DATA", DataType::Nested}},
+        {IFLA_INFO_XSTATS, {"INFO_XSTATS"}},
+        {IFLA_INFO_SLAVE_KIND, {"INFO_SLAVE_KIND", DataType::String}},
+        {IFLA_INFO_SLAVE_DATA, {"INFO_SLAVE_DATA"}},
+    }}},
+    {IFLA_NET_NS_PID, {"NET_NS_PID", DataType::Uint}},
+    {IFLA_IFALIAS, {"IFALIAS", DataType::String}},
+    {IFLA_NUM_VF, {"NUM_VF", DataType::Uint}},
+    {IFLA_VFINFO_LIST, {"VFINFO_LIST"}},
+    {IFLA_STATS64, {"STATS64", DataType::Struct, statsToStream<rtnl_link_stats64>}},
+    {IFLA_VF_PORTS, {"VF_PORTS"}},
+    {IFLA_PORT_SELF, {"PORT_SELF"}},
+    {IFLA_AF_SPEC, {"AF_SPEC", DataType::Nested, AttributeMap{
+        {AF_INET, {"AF_INET", DataType::Nested, AttributeMap{
+            {IFLA_INET_CONF, {"INET_CONF", DataType::Struct, arrayToStream<int32_t>}},
+        }}},
+        {AF_INET6, {"AF_INET6", DataType::Nested, AttributeMap{
+            {IFLA_INET6_FLAGS, {"INET6_FLAGS", DataType::Uint}},
+            {IFLA_INET6_CONF, {"INET6_CONF", DataType::Struct, arrayToStream<int32_t>}},
+            {IFLA_INET6_STATS, {"INET6_STATS", DataType::Struct, arrayToStream<uint64_t>}},
+            {IFLA_INET6_MCAST, {"INET6_MCAST"}},
+            {IFLA_INET6_CACHEINFO, {"INET6_CACHEINFO", DataType::Struct, ifla_cacheinfoToStream}},
+            {IFLA_INET6_ICMP6STATS, {"INET6_ICMP6STATS", DataType::Struct, arrayToStream<uint64_t>}},
+            {IFLA_INET6_TOKEN, {"INET6_TOKEN"}},
+            {IFLA_INET6_ADDR_GEN_MODE, {"INET6_ADDR_GEN_MODE", DataType::Uint}},
+        }}},
+    }}},
+    {IFLA_GROUP, {"GROUP", DataType::Uint}},
+    {IFLA_NET_NS_FD, {"NET_NS_FD", DataType::Uint}},
+    {IFLA_EXT_MASK, {"EXT_MASK", DataType::Uint}},
+    {IFLA_PROMISCUITY, {"PROMISCUITY", DataType::Uint}},
+    {IFLA_NUM_TX_QUEUES, {"NUM_TX_QUEUES", DataType::Uint}},
+    {IFLA_NUM_RX_QUEUES, {"NUM_RX_QUEUES", DataType::Uint}},
+    {IFLA_CARRIER, {"CARRIER", DataType::Uint}},
+    {IFLA_PHYS_PORT_ID, {"PHYS_PORT_ID"}},
+    {IFLA_CARRIER_CHANGES, {"CARRIER_CHANGES", DataType::Uint}},
+    {IFLA_PHYS_SWITCH_ID, {"PHYS_SWITCH_ID"}},
+    {IFLA_LINK_NETNSID, {"LINK_NETNSID"}},  // NLA_S32
+    {IFLA_PHYS_PORT_NAME, {"PHYS_PORT_NAME", DataType::String}},
+    {IFLA_PROTO_DOWN, {"PROTO_DOWN", DataType::Uint}},
+    {IFLA_GSO_MAX_SEGS, {"GSO_MAX_SEGS", DataType::Uint}},
+    {IFLA_GSO_MAX_SIZE, {"GSO_MAX_SIZE", DataType::Uint}},
+    {IFLA_PAD, {"PAD"}},
+    {IFLA_XDP, {"XDP"}},
+    {IFLA_EVENT, {"EVENT", DataType::Uint}},
+    {IFLA_NEW_NETNSID, {"NEW_NETNSID"}},  // NLA_S32
+    {IFLA_TARGET_NETNSID, {"TARGET_NETNSID"}},  // NLA_S32
+    {IFLA_CARRIER_UP_COUNT, {"CARRIER_UP_COUNT", DataType::Uint}},
+    {IFLA_CARRIER_DOWN_COUNT, {"CARRIER_DOWN_COUNT", DataType::Uint}},
+    {IFLA_NEW_IFINDEX, {"NEW_IFINDEX"}},  // NLA_S32
+    {IFLA_MIN_MTU, {"MIN_MTU", DataType::Uint}},
+    {IFLA_MAX_MTU, {"MAX_MTU", DataType::Uint}},
+    {IFLA_PROP_LIST, {"PROP_LIST"}},
+    {IFLA_ALT_IFNAME, {"ALT_IFNAME", DataType::String}},
+    {IFLA_PERM_ADDRESS, {"PERM_ADDRESS"}},
+};
+// clang-format on
+
+}  // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/attributes.h b/automotive/can/1.0/default/libnl++/protocols/route/attributes.h
new file mode 100644
index 0000000..ace9234
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/route/attributes.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../MessageDefinition.h"
+
+namespace android::nl::protocols::route {
+
+extern AttributeMap gAttributes;
+
+}  // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp b/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp
index b62cec3..269771c 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp
@@ -46,4 +46,58 @@
        << data.retrans_time << '}';
 }
 
+// clang-format off
+std::string familyToString(sa_family_t family) {
+    switch (family) {
+        case AF_UNSPEC: return "UNSPEC";
+        case AF_UNIX: return "UNIX";
+        case AF_INET: return "INET";
+        case AF_AX25: return "AX25";
+        case AF_IPX: return "IPX";
+        case AF_APPLETALK: return "APPLETALK";
+        case AF_NETROM: return "NETROM";
+        case AF_BRIDGE: return "BRIDGE";
+        case AF_ATMPVC: return "ATMPVC";
+        case AF_X25: return "X25";
+        case AF_INET6: return "INET6";
+        case AF_ROSE: return "ROSE";
+        case AF_DECnet: return "DECnet";
+        case AF_NETBEUI: return "NETBEUI";
+        case AF_SECURITY: return "SECURITY";
+        case AF_KEY: return "KEY";
+        case AF_NETLINK: return "NETLINK";
+        case AF_PACKET: return "PACKET";
+        case AF_ASH: return "ASH";
+        case AF_ECONET: return "ECONET";
+        case AF_ATMSVC: return "ATMSVC";
+        case AF_RDS: return "RDS";
+        case AF_SNA: return "SNA";
+        case AF_IRDA: return "IRDA";
+        case AF_PPPOX: return "PPPOX";
+        case AF_WANPIPE: return "WANPIPE";
+        case AF_LLC: return "LLC";
+        case 27 /*AF_IB*/: return "IB";
+        case 28 /*AF_MPLS*/: return "MPLS";
+        case AF_CAN: return "CAN";
+        case AF_TIPC: return "TIPC";
+        case AF_BLUETOOTH: return "BLUETOOTH";
+        case AF_IUCV: return "IUCV";
+        case AF_RXRPC: return "RXRPC";
+        case AF_ISDN: return "ISDN";
+        case AF_PHONET: return "PHONET";
+        case AF_IEEE802154: return "IEEE802154";
+        case AF_CAIF: return "CAIF";
+        case AF_ALG: return "ALG";
+        case AF_NFC: return "NFC";
+        case AF_VSOCK: return "VSOCK";
+        case AF_KCM: return "KCM";
+        case AF_QIPCRTR: return "QIPCRTR";
+        case 43 /*AF_SMC*/: return "SMC";
+        case 44 /*AF_XDP*/: return "XDP";
+        default:
+            return std::to_string(family);
+    }
+}
+// clang-format on
+
 }  // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.h b/automotive/can/1.0/default/libnl++/protocols/route/structs.h
index fea2ce1..c969a6c 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/structs.h
+++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.h
@@ -19,6 +19,7 @@
 #include <libnl++/Buffer.h>
 
 #include <linux/rtnetlink.h>
+#include <sys/socket.h>
 
 #include <sstream>
 
@@ -30,6 +31,8 @@
 // ifla_cacheinfo
 void ifla_cacheinfoToStream(std::stringstream& ss, const Buffer<nlattr> attr);
 
+std::string familyToString(sa_family_t family);
+
 // rtnl_link_stats or rtnl_link_stats64
 template <typename T>
 void statsToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
diff --git a/automotive/can/1.0/default/libnl++/protocols/structs.cpp b/automotive/can/1.0/default/libnl++/protocols/structs.cpp
index 8ff71f0..3f896bf 100644
--- a/automotive/can/1.0/default/libnl++/protocols/structs.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/structs.cpp
@@ -22,24 +22,27 @@
 
 AttributeDefinition::ToStream flagsToStream(FlagsMap flags) {
     return [flags](std::stringstream& ss, const Buffer<nlattr> attr) {
-        auto val = attr.data<uint64_t>().copyFirst();
+        auto value = attr.data<uint64_t>().copyFirst();
+        flagsToStream(ss, flags, value);
+    };
+}
 
-        bool first = true;
-        for (const auto& [flag, name] : flags) {
-            if ((val & flag) != flag) continue;
-            val &= ~flag;
-
-            if (!first) ss << '|';
-            first = false;
-
-            ss << name;
-        }
-
-        if (val == 0) return;
+void flagsToStream(std::stringstream& ss, const FlagsMap& flags, uint64_t val) {
+    bool first = true;
+    for (const auto& [flag, name] : flags) {
+        if ((val & flag) != flag) continue;
+        val &= ~flag;
 
         if (!first) ss << '|';
-        ss << std::hex << val << std::dec;
-    };
+        first = false;
+
+        ss << name;
+    }
+
+    if (val == 0) return;
+
+    if (!first) ss << '|';
+    ss << std::hex << val << std::dec;
 }
 
 void hwaddrToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
diff --git a/automotive/can/1.0/default/libnl++/protocols/structs.h b/automotive/can/1.0/default/libnl++/protocols/structs.h
index f3a8c44..9cf6f1a 100644
--- a/automotive/can/1.0/default/libnl++/protocols/structs.h
+++ b/automotive/can/1.0/default/libnl++/protocols/structs.h
@@ -34,6 +34,7 @@
 
 typedef std::map<uint64_t, std::string> FlagsMap;
 AttributeDefinition::ToStream flagsToStream(FlagsMap flags);
+void flagsToStream(std::stringstream& ss, const FlagsMap& flags, uint64_t value);
 
 void hwaddrToStream(std::stringstream& ss, const Buffer<nlattr> attr);
 
diff --git a/automotive/can/1.0/default/tests/fuzzer/Android.bp b/automotive/can/1.0/default/tests/fuzzer/Android.bp
index 52b43b0..de0b96f 100644
--- a/automotive/can/1.0/default/tests/fuzzer/Android.bp
+++ b/automotive/can/1.0/default/tests/fuzzer/Android.bp
@@ -50,5 +50,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.automotive.can@1.0-service",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/automotive/can/1.0/tools/configurator/Android.bp b/automotive/can/1.0/tools/configurator/Android.bp
index cc826bc..883d2a9 100644
--- a/automotive/can/1.0/tools/configurator/Android.bp
+++ b/automotive/can/1.0/tools/configurator/Android.bp
@@ -40,4 +40,5 @@
         "android.hardware.automotive.can@1.x-config-format",
         "android.hardware.automotive.can@libcanhaltools",
     ],
+    system_ext_specific: true,
 }
diff --git a/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp b/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp
index a100f06..3fb4259 100644
--- a/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp
+++ b/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp
@@ -70,6 +70,9 @@
 static bool configuratorStart(const std::string& filepath) {
     base::SetDefaultTag("CanConfigurator");
 
+    LOG(WARNING) << "The HIDL version of CAN HAL has been deprecated, if this tool fails with "
+                 << "SIGABRT, you may need canhalconfigurator-aidl instead.";
+
     auto pb_cfg = config::parseConfigFile(filepath);
     if (!pb_cfg.has_value()) {
         return false;
diff --git a/automotive/can/1.0/tools/configurator/canhalconfigurator.rc b/automotive/can/1.0/tools/configurator/canhalconfigurator.rc
index 12c2465..8ae7cb2 100644
--- a/automotive/can/1.0/tools/configurator/canhalconfigurator.rc
+++ b/automotive/can/1.0/tools/configurator/canhalconfigurator.rc
@@ -1,3 +1,4 @@
-service canhalconfigurator /system/bin/canhalconfigurator
+service canhalconfigurator /system_ext/bin/canhalconfigurator
   class core
+  user root
   oneshot
diff --git a/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp b/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp
index 9192e2f..fabe75f 100644
--- a/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp
+++ b/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp
@@ -34,8 +34,8 @@
     auto manager = hidl::manager::V1_2::IServiceManager::getService();
     hidl_vec<hidl_string> services;
     manager->listManifestByInterface(ICanController::descriptor, hidl_utils::fill(&services));
-    CHECK(services.size() > 0) << "No ICanController services registered (missing privileges?)"
-                               << std::endl;
+    CHECK(services.size() > 0) << "No ICanController services registered (missing privileges?). "
+                               << "are you using the AIDL CanController?" << std::endl;
     return services;
 }
 
diff --git a/automotive/can/OWNERS b/automotive/can/OWNERS
new file mode 100644
index 0000000..ffa4828
--- /dev/null
+++ b/automotive/can/OWNERS
@@ -0,0 +1,3 @@
+kevinme@google.com
+chrisweir@google.com
+twasilczyk@google.com
diff --git a/automotive/can/aidl/Android.bp b/automotive/can/aidl/Android.bp
new file mode 100644
index 0000000..3c4ee19
--- /dev/null
+++ b/automotive/can/aidl/Android.bp
@@ -0,0 +1,48 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.automotive.can",
+    vendor_available: true,
+    srcs: ["android/hardware/automotive/can/*.aidl"],
+    stability: "vintf",
+    host_supported: true,
+    backend: {
+        java: {
+            enabled: false,
+        },
+        rust: {
+            enabled: true,
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/.hash b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/.hash
new file mode 100644
index 0000000..441924d
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/.hash
@@ -0,0 +1 @@
+faa17409884ed5419fe73ebd24279109ca7549e1
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/BusConfig.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/BusConfig.aidl
new file mode 100644
index 0000000..0212e00
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/BusConfig.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable BusConfig {
+  String name;
+  android.hardware.automotive.can.BusConfig.InterfaceId interfaceId;
+  int bitrate;
+  union InterfaceId {
+    android.hardware.automotive.can.VirtualInterface virtualif;
+    android.hardware.automotive.can.NativeInterface nativeif;
+    android.hardware.automotive.can.SlcanInterface slcan;
+    android.hardware.automotive.can.IndexedInterface indexed;
+  }
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/ICanController.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/ICanController.aidl
new file mode 100644
index 0000000..5d032f2
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/ICanController.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+interface ICanController {
+  android.hardware.automotive.can.InterfaceType[] getSupportedInterfaceTypes();
+  String getInterfaceName(in String busName);
+  String upBus(in android.hardware.automotive.can.BusConfig config);
+  void downBus(in String name);
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/IndexedInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/IndexedInterface.aidl
new file mode 100644
index 0000000..1b00adf
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/IndexedInterface.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable IndexedInterface {
+  byte index;
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/InterfaceType.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/InterfaceType.aidl
new file mode 100644
index 0000000..a1bdb90
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/InterfaceType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@Backing(type="byte") @VintfStability
+enum InterfaceType {
+  VIRTUAL,
+  NATIVE,
+  SLCAN,
+  INDEXED,
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/NativeInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/NativeInterface.aidl
new file mode 100644
index 0000000..5d6c119
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/NativeInterface.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable NativeInterface {
+  android.hardware.automotive.can.NativeInterface.InterfaceId interfaceId;
+  union InterfaceId {
+    String ifname;
+    String[] serialno;
+  }
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/Result.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/Result.aidl
new file mode 100644
index 0000000..5669645
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/Result.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@Backing(type="int") @VintfStability
+enum Result {
+  OK,
+  UNKNOWN_ERROR,
+  INVALID_STATE,
+  NOT_SUPPORTED,
+  BAD_INTERFACE_ID,
+  BAD_BITRATE,
+  BAD_BUS_NAME,
+  INTERFACE_DOWN,
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/SlcanInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/SlcanInterface.aidl
new file mode 100644
index 0000000..af0c07d
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/SlcanInterface.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable SlcanInterface {
+  android.hardware.automotive.can.SlcanInterface.InterfaceId interfaceId;
+  union InterfaceId {
+    String ttyname;
+    String[] serialno;
+  }
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/VirtualInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/VirtualInterface.aidl
new file mode 100644
index 0000000..c870612
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/1/android/hardware/automotive/can/VirtualInterface.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable VirtualInterface {
+  String ifname;
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/BusConfig.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/BusConfig.aidl
new file mode 100644
index 0000000..0212e00
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/BusConfig.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable BusConfig {
+  String name;
+  android.hardware.automotive.can.BusConfig.InterfaceId interfaceId;
+  int bitrate;
+  union InterfaceId {
+    android.hardware.automotive.can.VirtualInterface virtualif;
+    android.hardware.automotive.can.NativeInterface nativeif;
+    android.hardware.automotive.can.SlcanInterface slcan;
+    android.hardware.automotive.can.IndexedInterface indexed;
+  }
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/ICanController.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/ICanController.aidl
new file mode 100644
index 0000000..5d032f2
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/ICanController.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+interface ICanController {
+  android.hardware.automotive.can.InterfaceType[] getSupportedInterfaceTypes();
+  String getInterfaceName(in String busName);
+  String upBus(in android.hardware.automotive.can.BusConfig config);
+  void downBus(in String name);
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/IndexedInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/IndexedInterface.aidl
new file mode 100644
index 0000000..1b00adf
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/IndexedInterface.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable IndexedInterface {
+  byte index;
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/InterfaceType.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/InterfaceType.aidl
new file mode 100644
index 0000000..44865aa
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/InterfaceType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@Backing(type="byte") @VintfStability
+enum InterfaceType {
+  VIRTUAL = 0,
+  NATIVE = 1,
+  SLCAN = 2,
+  INDEXED = 3,
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/NativeInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/NativeInterface.aidl
new file mode 100644
index 0000000..5d6c119
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/NativeInterface.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable NativeInterface {
+  android.hardware.automotive.can.NativeInterface.InterfaceId interfaceId;
+  union InterfaceId {
+    String ifname;
+    String[] serialno;
+  }
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/Result.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/Result.aidl
new file mode 100644
index 0000000..010792a
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/Result.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@Backing(type="int") @VintfStability
+enum Result {
+  OK = 0,
+  UNKNOWN_ERROR = 1,
+  INVALID_STATE = 2,
+  NOT_SUPPORTED = 3,
+  BAD_INTERFACE_ID = 4,
+  BAD_BITRATE = 5,
+  BAD_BUS_NAME = 6,
+  INTERFACE_DOWN = 7,
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/SlcanInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/SlcanInterface.aidl
new file mode 100644
index 0000000..af0c07d
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/SlcanInterface.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable SlcanInterface {
+  android.hardware.automotive.can.SlcanInterface.InterfaceId interfaceId;
+  union InterfaceId {
+    String ttyname;
+    String[] serialno;
+  }
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/VirtualInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/VirtualInterface.aidl
new file mode 100644
index 0000000..c870612
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/VirtualInterface.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable VirtualInterface {
+  String ifname;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/BusConfig.aidl b/automotive/can/aidl/android/hardware/automotive/can/BusConfig.aidl
new file mode 100644
index 0000000..4e1027b
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/BusConfig.aidl
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+import android.hardware.automotive.can.IndexedInterface;
+import android.hardware.automotive.can.NativeInterface;
+import android.hardware.automotive.can.SlcanInterface;
+import android.hardware.automotive.can.VirtualInterface;
+
+/**
+ * Configuration of the (physical or virtual) CAN bus.
+ *
+ * ISO TP and CAN FD support is dependent upon the hardware.
+ */
+@VintfStability
+parcelable BusConfig {
+    /**
+     * Name by which a given bus may be referenced.
+     *
+     * It must consist of only alphanumeric characters and underscore
+     * (a-z, A-Z, 0-9, '_'), at least 1 and at most 32 characters long.
+     *
+     * This field is *not* meant to distinguish between hardware interfaces
+     * nor preselect parameters like bitrate.
+     *
+     * This field represents a more human-friendly name for a CAN bus:
+     * e.x. rather than /some/dev/can1234, "name" might be "BodyCAN" or "CCAN"
+     */
+    String name;
+
+    /**
+     * Hardware interface configuration.
+     *
+     * This union's discriminator has an equivalent enum {@see InterfaceType} to
+     * express compatibility via getSupportedInterfaceTypes().
+     */
+    union InterfaceId {
+        /** Virtual SocketCAN interface. */
+        VirtualInterface virtualif;
+
+        /** Native SocketCAN interface. */
+        NativeInterface nativeif;
+
+        /** Serial line CAN interface. */
+        SlcanInterface slcan;
+
+        /**
+         * Proprietary, device-specific interface.
+         *
+         * Non-SocketCAN interfaces should use this variant.
+         */
+        IndexedInterface indexed;
+    }
+
+    InterfaceId interfaceId;
+
+    /**
+     * Bit rate for CAN communication.
+     *
+     * Typical bit rates are: 100000, 125000, 250000, 500000.
+     *
+     * For {@see interfaceId#virtual} interfaces, this value is ignored.
+     */
+    int bitrate;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/ICanController.aidl b/automotive/can/aidl/android/hardware/automotive/can/ICanController.aidl
new file mode 100644
index 0000000..97c2674
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/ICanController.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+import android.hardware.automotive.can.BusConfig;
+import android.hardware.automotive.can.InterfaceType;
+import android.hardware.automotive.can.Result;
+
+/**
+ * Represents a CAN controller that's capable of configuring CAN bus interfaces.
+ *
+ * The goal of this service is to configure and manage CAN interfaces.
+ *
+ * Providing an ICanController interface to configure CAN buses is optional.
+ * A system can elect to configure CAN buses manually if the hardware is
+ * dedicated to a specific application.
+ */
+@VintfStability
+interface ICanController {
+    /**
+     * Fetches the list of interface types supported by this HAL server.
+     *
+     * @return iftypes The list of supported interface types.
+     */
+    InterfaceType[] getSupportedInterfaceTypes();
+
+    /**
+     * Gets the interface name given the name of the bus. This will
+     *
+     * @param busName Name of the CAN bus who's interface name we would like
+     * (e.x. BCAN, CCAN, HS3, BodyCAN, ...)
+     * @return name of the socketcan network interface corresponding to busName
+     * (e.x. can0, vcan5, ...)
+     */
+    String getInterfaceName(in String busName);
+
+    /**
+     * Bring up a CAN bus.
+     *
+     * @param config Configuration for the CAN bus.
+     * @return name of iface if successful
+     */
+    String upBus(in BusConfig config);
+
+    /**
+     * Bring down a CAN bus.
+     *
+     * @param name Name of the bus (@see BusConfig#name} to bring down.
+     */
+    void downBus(in String name);
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/IndexedInterface.aidl b/automotive/can/aidl/android/hardware/automotive/can/IndexedInterface.aidl
new file mode 100644
index 0000000..13e223f
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/IndexedInterface.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+@VintfStability
+parcelable IndexedInterface {
+    /** Interface number, 0-based. */
+    byte index;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/InterfaceType.aidl b/automotive/can/aidl/android/hardware/automotive/can/InterfaceType.aidl
new file mode 100644
index 0000000..b13648a
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/InterfaceType.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+/**
+ * Type of an interface, an equivalent to BusConfig::InterfaceId
+ * union discriminator. Defines a number of specific standard hardware
+ * families and a generic catch-all type of {@see INDEXED}.
+ */
+@VintfStability
+@Backing(type="byte")
+enum InterfaceType {
+    /** Virtual SocketCAN interface. */
+    VIRTUAL,
+
+    /** Native SocketCAN interface. */
+    NATIVE,
+
+    /** Serial line CAN interface. */
+    SLCAN,
+
+    /** Proprietary, device-specific interface. */
+    INDEXED,
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/NativeInterface.aidl b/automotive/can/aidl/android/hardware/automotive/can/NativeInterface.aidl
new file mode 100644
index 0000000..30c24c3
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/NativeInterface.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+@VintfStability
+parcelable NativeInterface {
+    union InterfaceId {
+        /** Interface name, such as can0. */
+        String ifname;
+
+        /**
+         * Alternatively to providing {@see ifname}, one may provide a list of
+         * interface serial number suffixes. If there happens to be a device
+         * (like USB2CAN) with a matching serial number suffix, the HAL service
+         * will locate it.
+         *
+         * Client may utilize this in two ways: by matching against the
+         * entire serial number, or the last few characters (usually
+         * one). The former is better for small-scale test deployments
+         * (with just a handful of vehicles), the latter is good for
+         * larger scale (where a small suffix list may support large
+         * test fleet).
+         */
+        String[] serialno;
+    }
+
+    InterfaceId interfaceId;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/Result.aidl b/automotive/can/aidl/android/hardware/automotive/can/Result.aidl
new file mode 100644
index 0000000..cdd0066
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/Result.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+/**
+ * Possible error codes (or OK) for ICanController.
+ */
+@VintfStability
+@Backing(type="int")
+enum Result {
+    OK,
+
+    /**
+     * General error class, if others are not applicable.
+     */
+    UNKNOWN_ERROR,
+
+    /**
+     * Up request was called out of order (i.e. trying to up the interface
+     * twice).
+     */
+    INVALID_STATE,
+
+    /** Interface type is not supported. */
+    NOT_SUPPORTED,
+
+    /**
+     * Provided interface ID (index, name, device path) doesn't exist or there
+     * is no device with a given serial number.
+     */
+    BAD_INTERFACE_ID,
+
+    /** Provided bit rate is not supported by the hardware. */
+    BAD_BITRATE,
+
+    /**
+     * Provided bus name ({@see BusConfig#name}) has invalid format or doesn't exist.
+     */
+    BAD_BUS_NAME,
+
+    /**
+     * The interface for the bus you are trying to interact with is currently
+     * down. As opposed to INVALID_STATE, this serves to warn the caller
+     * _before_ they attempt an invalid operation.
+     */
+    INTERFACE_DOWN,
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/SlcanInterface.aidl b/automotive/can/aidl/android/hardware/automotive/can/SlcanInterface.aidl
new file mode 100644
index 0000000..4ed8583
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/SlcanInterface.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+@VintfStability
+parcelable SlcanInterface {
+    union InterfaceId {
+        /** Path to a device, such as /dev/ttyUSB0. */
+        String ttyname;
+
+        /**
+         * List of interface serial number suffixes.
+         * {@see Socketcan::serialno}
+         */
+        String[] serialno;
+    }
+
+    InterfaceId interfaceId;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/VirtualInterface.aidl b/automotive/can/aidl/android/hardware/automotive/can/VirtualInterface.aidl
new file mode 100644
index 0000000..7e1e5e1
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/VirtualInterface.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+@VintfStability
+parcelable VirtualInterface {
+    /**
+     * Interface name, such as vcan0. If the interface doesn't
+     * exist, HAL server must create it.
+     */
+    String ifname;
+}
diff --git a/automotive/can/aidl/default/Android.bp b/automotive/can/aidl/default/Android.bp
new file mode 100644
index 0000000..d44cb91
--- /dev/null
+++ b/automotive/can/aidl/default/Android.bp
@@ -0,0 +1,51 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+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_binary {
+    name: "android.hardware.automotive.can-service",
+    init_rc: ["android.hardware.automotive.can.rc"],
+    defaults: ["android.hardware.automotive.can@defaults"],
+    vendor: true,
+    relative_install_path: "hw",
+    srcs: [
+        "CanBus.cpp",
+        "CanBusSlcan.cpp",
+        "CanBusNative.cpp",
+        "CanBusVirtual.cpp",
+        "CanController.cpp",
+        "service.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.automotive.can-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.automotive.can@libnetdevice",
+        "android.hardware.automotive@libc++fs",
+        "libnl++",
+    ],
+    vintf_fragments: ["android.hardware.automotive.can.xml"],
+}
diff --git a/automotive/can/aidl/default/CanBus.cpp b/automotive/can/aidl/default/CanBus.cpp
new file mode 100644
index 0000000..d1f9b78
--- /dev/null
+++ b/automotive/can/aidl/default/CanBus.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanBus.h"
+
+#include <android-base/logging.h>
+#include <libnetdevice/libnetdevice.h>
+
+namespace aidl::android::hardware::automotive::can {
+
+CanBus::CanBus(std::string_view ifname) : mIfname(ifname) {}
+
+CanBus::~CanBus() {
+    std::lock_guard<std::mutex> lck(mIsUpGuard);
+    CHECK(!mIsUp) << "Interface is still up while being destroyed";
+}
+
+Result CanBus::preUp() {
+    return Result::OK;
+}
+
+bool CanBus::postDown() {
+    return true;
+}
+
+std::string CanBus::getIfaceName() {
+    return mIfname;
+}
+
+Result CanBus::up() {
+    std::lock_guard<std::mutex> lck(mIsUpGuard);
+
+    if (mIsUp) {
+        LOG(WARNING) << "Interface is already up";
+        return Result::INVALID_STATE;
+    }
+
+    const auto preResult = preUp();
+    if (preResult != Result::OK) return preResult;
+
+    const auto isUp = ::android::netdevice::isUp(mIfname);
+    if (!isUp.has_value()) {
+        // preUp() should prepare the interface (either create or make sure it's there)
+        LOG(ERROR) << "Interface " << mIfname << " didn't get prepared";
+        return Result::BAD_INTERFACE_ID;
+    }
+
+    if (!*isUp && !::android::netdevice::up(mIfname)) {
+        LOG(ERROR) << "Can't bring " << mIfname << " up";
+        return Result::UNKNOWN_ERROR;
+    }
+    mDownAfterUse = !*isUp;
+
+    mIsUp = true;
+    return Result::OK;
+}
+
+Result CanBus::down() {
+    std::lock_guard<std::mutex> lck(mIsUpGuard);
+
+    if (!mIsUp) {
+        LOG(WARNING) << "Interface is already down";
+        return Result::INVALID_STATE;
+    }
+    mIsUp = false;
+
+    Result success = Result::OK;
+
+    if (mDownAfterUse && !::android::netdevice::down(mIfname)) {
+        LOG(ERROR) << "Can't bring " << mIfname << " down";
+        // don't return yet, let's try to do best-effort cleanup
+        success = Result::UNKNOWN_ERROR;
+    }
+
+    if (!postDown()) success = Result::UNKNOWN_ERROR;
+
+    return success;
+}
+
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBus.h b/automotive/can/aidl/default/CanBus.h
new file mode 100644
index 0000000..abdbe51
--- /dev/null
+++ b/automotive/can/aidl/default/CanBus.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/automotive/can/Result.h>
+
+#include <android-base/macros.h>
+#include <utils/Mutex.h>
+
+#include <atomic>
+#include <mutex>
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanBus {
+  public:
+    /**
+     * Some interface types (such as SLCAN) don't get an interface name until after being
+     * initialized, hence ifname is optional.
+     *
+     * You MUST ensure mIfname is initialized prior to the completion of preUp().
+     */
+    CanBus(std::string_view ifname = std::string_view{""});
+
+    virtual ~CanBus();
+
+    Result up();
+    Result down();
+    std::string getIfaceName();
+
+  protected:
+    /**
+     * Prepare the SocketCAN interface.
+     *
+     * After calling this method, mIfname network interface is available and ready to be brought up.
+     *
+     * \return true upon success and false upon failure
+     */
+    virtual Result preUp();
+
+    /**
+     * Cleanup after bringing the interface down.
+     *
+     * This is a counterpart to preUp().
+     *
+     * \return true upon success and false upon failure
+     */
+    virtual bool postDown();
+
+    /** Network interface name. */
+    std::string mIfname;
+
+  private:
+    /**
+     * Guard for up flag is required to be held for entire time when the interface is being used
+     * because we don't want the interface to be torn down while executing that operation.
+     */
+    std::mutex mIsUpGuard;
+    bool mIsUp GUARDED_BY(mIsUpGuard) = false;
+
+    bool mDownAfterUse;
+};
+
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusNative.cpp b/automotive/can/aidl/default/CanBusNative.cpp
new file mode 100644
index 0000000..8a7de99
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusNative.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanBusNative.h"
+
+#include <android-base/logging.h>
+#include <libnetdevice/can.h>
+#include <libnetdevice/libnetdevice.h>
+
+namespace aidl::android::hardware::automotive::can {
+
+using namespace ::android;
+
+CanBusNative::CanBusNative(const std::string& ifname, uint32_t bitrate)
+    : CanBus(ifname), mBitrate(bitrate) {}
+
+Result CanBusNative::preUp() {
+    if (!netdevice::exists(mIfname)) {
+        LOG(ERROR) << "Interface " << mIfname << " doesn't exist";
+        return Result::BAD_INTERFACE_ID;
+    }
+
+    if (mBitrate == 0) {
+        // interface is already up and we just want to register it
+        return Result::OK;
+    }
+
+    if (!netdevice::down(mIfname)) {
+        LOG(ERROR) << "Can't bring " << mIfname << " down (to configure it)";
+        return Result::UNKNOWN_ERROR;
+    }
+
+    if (!netdevice::can::setBitrate(mIfname, mBitrate)) {
+        LOG(ERROR) << "Can't set bitrate " << mBitrate << " for " << mIfname;
+        return Result::BAD_BITRATE;
+    }
+
+    return Result::OK;
+}
+
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusNative.h b/automotive/can/aidl/default/CanBusNative.h
new file mode 100644
index 0000000..32846c7
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusNative.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "CanBus.h"
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanBusNative : public CanBus {
+  public:
+    CanBusNative(const std::string& ifname, uint32_t bitrate);
+
+  protected:
+    virtual Result preUp() override;
+
+  private:
+    const uint32_t mBitrate;
+};
+
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusSlcan.cpp b/automotive/can/aidl/default/CanBusSlcan.cpp
new file mode 100644
index 0000000..6060419
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusSlcan.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanBusSlcan.h"
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <libnetdevice/libnetdevice.h>
+
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <net/if.h>
+#include <termios.h>
+
+#include <map>
+
+namespace aidl::android::hardware::automotive::can {
+
+using namespace std::string_view_literals;
+using namespace ::android::base;
+
+namespace slcanprotocol {
+static constexpr std::string_view kOpenCommand = "O\r"sv;
+static constexpr std::string_view kCloseCommand = "C\r"sv;
+static constexpr int kSlcanDiscipline = N_SLCAN;
+static constexpr int kDefaultDiscipline = N_TTY;
+
+static const std::map<uint32_t, std::string_view> kBitrateCommands = {
+        {10000, "C\rS0\r"sv},  {20000, "C\rS1\r"sv},  {50000, "C\rS2\r"sv},
+        {100000, "C\rS3\r"sv}, {125000, "C\rS4\r"sv}, {250000, "C\rS5\r"sv},
+        {500000, "C\rS6\r"sv}, {800000, "C\rS7\r"sv}, {1000000, "C\rS8\r"sv}};
+}  // namespace slcanprotocol
+
+/**
+ * Serial Line CAN constructor
+ * \param string uartName - name of slcan device (e.x. /dev/ttyUSB0)
+ * \param uint32_t bitrate - speed of the CAN bus (125k = MSCAN, 500k = HSCAN)
+ */
+CanBusSlcan::CanBusSlcan(const std::string& uartName, uint32_t bitrate)
+    : CanBus(), mTtyPath(uartName), kBitrate(bitrate) {}
+
+/** helper function to update CanBusSlcan object's iface name */
+Result CanBusSlcan::updateIfaceName(unique_fd& uartFd) {
+    struct ifreq ifrequest = {};
+    /*
+     * Fetching the iface name with an ioctl won't interfere with an open socketCAN iface attached
+     * to this tty. This is important in the event we are trying to register a SLCAN based iface
+     * that has already been configured and brought up.
+     */
+    if (ioctl(uartFd.get(), SIOCGIFNAME, ifrequest.ifr_name) < 0) {
+        PLOG(ERROR) << "Failed to get the name of the created device";
+        return Result::UNKNOWN_ERROR;
+    }
+
+    // Update the CanBus object with name that was assigned to it
+    mIfname = ifrequest.ifr_name;
+    return Result::OK;
+}
+
+Result CanBusSlcan::preUp() {
+    // verify valid bitrate and translate to serial command format
+    std::optional<std::string_view> canBitrateCommand = std::nullopt;
+    if (kBitrate != 0) {
+        const auto lookupIt = slcanprotocol::kBitrateCommands.find(kBitrate);
+        if (lookupIt == slcanprotocol::kBitrateCommands.end()) {
+            return Result::BAD_BITRATE;
+        }
+        canBitrateCommand = lookupIt->second;
+    }
+
+    /* Attempt to open the uart in r/w without blocking or becoming the
+     * controlling terminal */
+    mFd = unique_fd(open(mTtyPath.c_str(), O_RDWR | O_NONBLOCK | O_NOCTTY | O_CLOEXEC));
+    if (!mFd.ok()) {
+        PLOG(ERROR) << "SLCAN Failed to open " << mTtyPath;
+        return Result::BAD_INTERFACE_ID;
+    }
+
+    // If the device is already up, update the iface name in our CanBusSlcan object
+    if (kBitrate == 0) {
+        return updateIfaceName(mFd);
+    }
+
+    // blank terminal settings and pull them from the device
+    struct termios terminalSettings = {};
+    if (tcgetattr(mFd.get(), &terminalSettings) < 0) {
+        PLOG(ERROR) << "Failed to read attrs of" << mTtyPath;
+        return Result::UNKNOWN_ERROR;
+    }
+
+    // change settings to raw mode
+    cfmakeraw(&terminalSettings);
+
+    // disable software flow control
+    terminalSettings.c_iflag &= ~IXOFF;
+    // enable hardware flow control
+    terminalSettings.c_cflag |= CRTSCTS;
+
+    struct serial_struct serialSettings;
+    // get serial settings
+    if (ioctl(mFd.get(), TIOCGSERIAL, &serialSettings) < 0) {
+        PLOG(ERROR) << "Failed to read serial settings from " << mTtyPath;
+        return Result::UNKNOWN_ERROR;
+    }
+    // set low latency mode
+    serialSettings.flags |= ASYNC_LOW_LATENCY;
+    // apply serial settings
+    if (ioctl(mFd.get(), TIOCSSERIAL, &serialSettings) < 0) {
+        PLOG(ERROR) << "Failed to set low latency mode on " << mTtyPath;
+        return Result::UNKNOWN_ERROR;
+    }
+
+    /* TCSADRAIN applies settings after we finish writing the rest of our
+     * changes (as opposed to TCSANOW, which changes immediately) */
+    if (tcsetattr(mFd.get(), TCSADRAIN, &terminalSettings) < 0) {
+        PLOG(ERROR) << "Failed to apply terminal settings to " << mTtyPath;
+        return Result::UNKNOWN_ERROR;
+    }
+
+    // apply speed setting for CAN
+    if (!WriteStringToFd(*canBitrateCommand, mFd)) {
+        PLOG(ERROR) << "Failed to apply CAN bitrate";
+        return Result::UNKNOWN_ERROR;
+    }
+
+    // TODO(b/144775286): set open flag & support listen only
+    if (!WriteStringToFd(slcanprotocol::kOpenCommand, mFd)) {
+        PLOG(ERROR) << "Failed to set open flag";
+        return Result::UNKNOWN_ERROR;
+    }
+
+    // set line discipline to slcan
+    if (ioctl(mFd.get(), TIOCSETD, &slcanprotocol::kSlcanDiscipline) < 0) {
+        PLOG(ERROR) << "Failed to set line discipline to slcan";
+        return Result::UNKNOWN_ERROR;
+    }
+
+    // Update the CanBus object with name that was assigned to it
+    return updateIfaceName(mFd);
+}
+
+bool CanBusSlcan::postDown() {
+    // reset the line discipline to TTY mode
+    if (ioctl(mFd.get(), TIOCSETD, &slcanprotocol::kDefaultDiscipline) < 0) {
+        LOG(ERROR) << "Failed to reset line discipline!";
+        return false;
+    }
+
+    // issue the close command
+    if (!WriteStringToFd(slcanprotocol::kCloseCommand, mFd)) {
+        LOG(ERROR) << "Failed to close tty!";
+        return false;
+    }
+
+    // close our unique_fd
+    mFd.reset();
+
+    return true;
+}
+
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusSlcan.h b/automotive/can/aidl/default/CanBusSlcan.h
new file mode 100644
index 0000000..a1c908c
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusSlcan.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "CanBus.h"
+
+#include <android-base/unique_fd.h>
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanBusSlcan : public CanBus {
+  public:
+    CanBusSlcan(const std::string& uartName, uint32_t bitrate);
+
+  protected:
+    virtual Result preUp() override;
+    virtual bool postDown() override;
+
+  private:
+    Result updateIfaceName(::android::base::unique_fd& uartFd);
+
+    const std::string mTtyPath;
+    const uint32_t kBitrate;
+    ::android::base::unique_fd mFd;
+};
+
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusVirtual.cpp b/automotive/can/aidl/default/CanBusVirtual.cpp
new file mode 100644
index 0000000..28a1258
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusVirtual.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanBusVirtual.h"
+
+#include <android-base/logging.h>
+#include <libnetdevice/libnetdevice.h>
+
+namespace aidl::android::hardware::automotive::can {
+
+using namespace ::android;
+
+CanBusVirtual::CanBusVirtual(const std::string& ifname) : CanBus(ifname) {}
+
+Result CanBusVirtual::preUp() {
+    if (netdevice::exists(mIfname)) return Result::OK;
+
+    LOG(DEBUG) << "Virtual interface " << mIfname << " doesn't exist, creating...";
+    mWasCreated = true;
+    if (!netdevice::add(mIfname, "vcan")) {
+        LOG(ERROR) << "Can't create vcan interface " << mIfname;
+        return Result::UNKNOWN_ERROR;
+    }
+
+    return Result::OK;
+}
+
+bool CanBusVirtual::postDown() {
+    if (mWasCreated) {
+        mWasCreated = false;
+        if (!netdevice::del(mIfname)) {
+            LOG(ERROR) << "Couldn't remove vcan interface " << mIfname;
+            return false;
+        }
+    }
+    return true;
+}
+
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusVirtual.h b/automotive/can/aidl/default/CanBusVirtual.h
new file mode 100644
index 0000000..9c5d35d
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusVirtual.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "CanBus.h"
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanBusVirtual : public CanBus {
+  public:
+    CanBusVirtual(const std::string& ifname);
+
+  protected:
+    virtual Result preUp() override;
+    virtual bool postDown() override;
+
+  private:
+    bool mWasCreated = false;
+};
+
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanController.cpp b/automotive/can/aidl/default/CanController.cpp
new file mode 100644
index 0000000..e4b5306
--- /dev/null
+++ b/automotive/can/aidl/default/CanController.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanController.h"
+
+#include "CanBusNative.h"
+#include "CanBusSlcan.h"
+#include "CanBusVirtual.h"
+
+#include <android-base/format.h>
+#include <android-base/logging.h>
+
+#include <automotive/filesystem>
+#include <fstream>
+#include <regex>
+
+namespace aidl::android::hardware::automotive::can {
+
+namespace fs = ::android::hardware::automotive::filesystem;
+
+namespace fsErrors {
+static const std::error_code ok;
+static const std::error_code eperm(EPERM, std::generic_category());
+static const std::error_code enoent(ENOENT, std::generic_category());
+static const std::error_code eacces(EACCES, std::generic_category());
+}  // namespace fsErrors
+
+/* In the /sys/devices tree, there are files called "serial", which contain the serial numbers
+ * for various devices. The exact location inside of this directory is dependent upon the
+ * hardware we are running on, so we have to start from /sys/devices and work our way down. */
+static const fs::path kDevPath("/sys/devices/");
+static const std::regex kTtyRe("^tty[A-Z]+[0-9]+$");
+static constexpr auto kOpts = ~(fs::directory_options::follow_directory_symlink |
+                                fs::directory_options::skip_permission_denied);
+
+constexpr auto ok = &ndk::ScopedAStatus::ok;
+
+/**
+ * A helper object to associate the interface name and type of a USB to CAN adapter.
+ */
+struct UsbCanIface {
+    InterfaceType iftype;
+    std::string ifaceName;
+};
+
+static bool isValidName(const std::string& name) {
+    static const std::regex nameRE("^[a-zA-Z0-9_]{1,32}$");
+    return std::regex_match(name, nameRE);
+}
+
+/**
+ * Given a path, get the last element from it.
+ *
+ * \param itrPath - the path we want the last element of
+ * \return - the last element in the path (in string form).
+ */
+static std::string getLeaf(const fs::path& itrPath) {
+    /* end() returns an iterator one past the leaf of the path, so we've overshot
+    decrement (--) to go back one to the leaf
+    dereference and now we have our leaf. */
+    return *(--(itrPath.end()));
+}
+
+static ndk::ScopedAStatus resultToStatus(Result res, const std::string& msg = "") {
+    if (msg.empty()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(static_cast<int>(res)));
+    }
+    return ndk::ScopedAStatus(
+            AStatus_fromServiceSpecificErrorWithMessage(static_cast<int>(res), msg.c_str()));
+}
+
+/**
+ * Given a UsbCanIface object, get the ifaceName given the serialPath.
+ *
+ * \param serialPath - Absolute path to a "serial" file for a given device in /sys.
+ * \return A populated UsbCanIface. On failure, nullopt is returned.
+ */
+static std::optional<UsbCanIface> getIfaceName(const fs::path& serialPath) {
+    std::error_code fsStatus;
+    // Since the path is to a file called "serial", we need to search its parent directory.
+    fs::recursive_directory_iterator fsItr(serialPath.parent_path(), kOpts, fsStatus);
+    if (fsStatus != fsErrors::ok) {
+        LOG(ERROR) << "Failed to open " << serialPath.parent_path();
+        return std::nullopt;
+    }
+
+    for (; fsStatus == fsErrors::ok && fsItr != fs::recursive_directory_iterator();
+         fsItr.increment(fsStatus)) {
+        /* We want either a directory called "net" or a directory that looks like tty<something>, so
+         * skip files. */
+        bool isDir = fsItr->is_directory(fsStatus);
+        if (fsStatus != fsErrors::ok || !isDir) continue;
+
+        std::string currentDir = getLeaf(fsItr->path());
+        if (currentDir == "net") {
+            /* This device is a SocketCAN device. The iface name is the only directory under
+             * net/. Multiple directories under net/ is an error.*/
+            fs::directory_iterator netItr(fsItr->path(), kOpts, fsStatus);
+            if (fsStatus != fsErrors::ok) {
+                LOG(ERROR) << "Failed to open " << fsItr->path() << " to get net name!";
+                return std::nullopt;
+            }
+
+            // The leaf of our path should be the interface name.
+            std::string netName = getLeaf(netItr->path());
+
+            // Check if there is more than one item in net/
+            netItr.increment(fsStatus);
+            if (fsStatus != fsErrors::ok) {
+                // It's possible we have a valid net name, but this is most likely an error.
+                LOG(ERROR) << "Failed to verify " << fsItr->path() << " has valid net name!";
+                return std::nullopt;
+            }
+            if (netItr != fs::directory_iterator()) {
+                // There should never be more than one name under net/
+                LOG(ERROR) << "Found more than one net name in " << fsItr->path() << "!";
+                return std::nullopt;
+            }
+            return {{InterfaceType::NATIVE, netName}};
+        } else if (std::regex_match(currentDir, kTtyRe)) {
+            // This device is a USB serial device, and currentDir is the tty name.
+            return {{InterfaceType::SLCAN, "/dev/" + currentDir}};
+        }
+    }
+
+    // check if the loop above exited due to a c++fs error.
+    if (fsStatus != fsErrors::ok) {
+        LOG(ERROR) << "Failed search filesystem: " << fsStatus;
+    }
+    return std::nullopt;
+}
+
+/**
+ * A helper function to read the serial number from a "serial" file in /sys/devices/
+ *
+ * \param serialnoPath - path to the file to read.
+ * \return the serial number, or nullopt on failure.
+ */
+static std::optional<std::string> readSerialNo(const std::string& serialnoPath) {
+    std::ifstream serialnoStream(serialnoPath);
+    std::string serialno;
+    if (!serialnoStream.good()) {
+        LOG(ERROR) << "Failed to read serial number from " << serialnoPath;
+        return std::nullopt;
+    }
+    std::getline(serialnoStream, serialno);
+    return serialno;
+}
+
+/**
+ * Searches for USB devices found in /sys/devices/, and attempts to find a device matching the
+ * provided list of serial numbers.
+ *
+ * \param configSerialnos - a list of serial number (suffixes) from the HAL config.
+ * \param iftype - the type of the interface to be located.
+ * \return a matching USB device. On failure, std::nullopt is returned.
+ */
+static std::optional<UsbCanIface> findUsbDevice(const std::vector<std::string>& configSerialnos) {
+    std::error_code fsStatus;
+    fs::recursive_directory_iterator fsItr(kDevPath, kOpts, fsStatus);
+    if (fsStatus != fsErrors::ok) {
+        LOG(ERROR) << "Failed to open " << kDevPath;
+        return std::nullopt;
+    }
+
+    for (; fsStatus == fsErrors::ok && fsItr != fs::recursive_directory_iterator();
+         fsItr.increment(fsStatus)) {
+        // We want to find a file called "serial", which is in a directory somewhere. Skip files.
+        bool isDir = fsItr->is_directory(fsStatus);
+        if (fsStatus != fsErrors::ok) {
+            LOG(ERROR) << "Failed check if " << fsStatus;
+            return std::nullopt;
+        }
+        if (!isDir) continue;
+
+        auto serialnoPath = fsItr->path() / "serial";
+        bool isReg = fs::is_regular_file(serialnoPath, fsStatus);
+
+        /* Make sure we have permissions to this directory, ignore enoent, since the file
+         * "serial" may not exist, which is ok. */
+        if (fsStatus == fsErrors::eperm || fsStatus == fsErrors::eacces) {
+            /* This means we  don't have access to this directory. If we recurse into it, this
+             * will cause the iterator to loose its state and we'll crash. */
+            fsItr.disable_recursion_pending();
+            continue;
+        }
+        if (fsStatus == fsErrors::enoent) continue;
+        if (fsStatus != fsErrors::ok) {
+            LOG(WARNING) << "An unexpected error occurred while checking for serialno: "
+                         << fsStatus;
+            continue;
+        }
+        if (!isReg) continue;
+
+        // we found a serial number
+        auto serialno = readSerialNo(serialnoPath);
+        if (!serialno.has_value()) continue;
+
+        // see if the serial number exists in the config
+        for (auto&& cfgSn : configSerialnos) {
+            if (serialno->ends_with(std::string(cfgSn))) {
+                auto ifaceInfo = getIfaceName(serialnoPath);
+                if (!ifaceInfo.has_value()) break;
+                return ifaceInfo;
+            }
+        }
+    }
+    if (fsStatus != fsErrors::ok) {
+        LOG(ERROR) << "Error searching filesystem: " << fsStatus;
+        return std::nullopt;
+    }
+    return std::nullopt;
+}
+
+ndk::ScopedAStatus CanController::getSupportedInterfaceTypes(
+        std::vector<InterfaceType>* supportedTypes) {
+    *supportedTypes = {InterfaceType::VIRTUAL, InterfaceType::NATIVE, InterfaceType::SLCAN};
+    return ok();
+}
+
+ndk::ScopedAStatus CanController::getInterfaceName(const std::string& busName,
+                                                   std::string* ifaceName) {
+    *ifaceName = {};
+    if (mBusesByName.find(busName) == mBusesByName.end()) {
+        return resultToStatus(Result::BAD_BUS_NAME, fmt::format("{} doesn't exist", busName));
+    }
+    *ifaceName = std::string(mBusesByName[busName]->getIfaceName());
+    return ok();
+}
+
+ndk::ScopedAStatus CanController::upBus(const BusConfig& config, std::string* ifaceName) {
+    if (!isValidName(config.name)) {
+        LOG(ERROR) << "Bus name " << config.name << " is invalid";
+        return resultToStatus(Result::BAD_BUS_NAME,
+                              fmt::format("{} is not a valid bus name", config.name));
+    } else if (mBusesByName.find(config.name) != mBusesByName.end()) {
+        LOG(ERROR) << "A bus named " << config.name << " already exists!";
+        return resultToStatus(Result::INVALID_STATE,
+                              fmt::format("A bus named {} already exists", config.name));
+    }
+
+    if (config.interfaceId.getTag() == BusConfig::InterfaceId::Tag::virtualif) {
+        auto& virtualif = config.interfaceId.get<BusConfig::InterfaceId::Tag::virtualif>();
+        mBusesByName[config.name] = std::make_unique<CanBusVirtual>(virtualif.ifname);
+    }
+
+    else if (config.interfaceId.getTag() == BusConfig::InterfaceId::Tag::nativeif) {
+        auto& nativeif = config.interfaceId.get<BusConfig::InterfaceId::Tag::nativeif>();
+        std::string ifaceName;
+        if (nativeif.interfaceId.getTag() == NativeInterface::InterfaceId::Tag::serialno) {
+            // Configure by serial number.
+            auto selectedDevice = findUsbDevice(
+                    nativeif.interfaceId.get<NativeInterface::InterfaceId::Tag::serialno>());
+            // verify the returned device is the correct one
+            if (!selectedDevice.has_value() || selectedDevice->iftype != InterfaceType::NATIVE) {
+                return resultToStatus(
+                        Result::BAD_INTERFACE_ID,
+                        "Couldn't find a native socketcan device with the given serial number(s)");
+            }
+            ifaceName = selectedDevice->ifaceName;
+        } else {
+            // configure by iface name.
+            ifaceName = nativeif.interfaceId.get<NativeInterface::InterfaceId::Tag::ifname>();
+        }
+        mBusesByName[config.name] = std::make_unique<CanBusNative>(ifaceName, config.bitrate);
+    }
+
+    else if (config.interfaceId.getTag() == BusConfig::InterfaceId::Tag::slcan) {
+        auto& slcanif = config.interfaceId.get<BusConfig::InterfaceId::Tag::slcan>();
+        std::string ttyName;
+        if (slcanif.interfaceId.getTag() == SlcanInterface::InterfaceId::Tag::serialno) {
+            // Configure by serial number.
+            auto selectedDevice = findUsbDevice(
+                    slcanif.interfaceId.get<SlcanInterface::InterfaceId::Tag::serialno>());
+            if (!selectedDevice.has_value() || selectedDevice->iftype != InterfaceType::SLCAN) {
+                return resultToStatus(
+                        Result::BAD_INTERFACE_ID,
+                        "Couldn't find a slcan device with the given serial number(s)");
+            }
+            ttyName = selectedDevice->ifaceName;
+        } else {
+            // Configure by tty name.
+            ttyName = slcanif.interfaceId.get<SlcanInterface::InterfaceId::Tag::ttyname>();
+        }
+        mBusesByName[config.name] = std::make_unique<CanBusSlcan>(ttyName, config.bitrate);
+    }
+
+    else if (config.interfaceId.getTag() == BusConfig::InterfaceId::Tag::indexed) {
+        return resultToStatus(Result::NOT_SUPPORTED,
+                              "Indexed devices are not supported in this implementation");
+    } else {
+        // this shouldn't happen.
+        return resultToStatus(Result::UNKNOWN_ERROR, "Unknown interface id type");
+    }
+
+    Result result = mBusesByName[config.name]->up();
+    if (result != Result::OK) {
+        // the bus failed to come up, don't leave a broken entry in the map.
+        mBusesByName.erase(config.name);
+        return resultToStatus(result, fmt::format("CanBus::up failed for {}", config.name));
+    }
+
+    *ifaceName = mBusesByName[config.name]->getIfaceName();
+    return ok();
+}
+
+ndk::ScopedAStatus CanController::downBus(const std::string& busName) {
+    if (mBusesByName.find(busName) == mBusesByName.end()) {
+        return resultToStatus(
+                Result::UNKNOWN_ERROR,
+                fmt::format("Couldn't bring down {}, because it doesn't exist", busName));
+    }
+    Result result = mBusesByName[busName]->down();
+    if (result != Result::OK) {
+        return resultToStatus(result, fmt::format("Couldn't bring down {}!", busName));
+    }
+    mBusesByName.erase(busName);
+    return ok();
+}
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanController.h b/automotive/can/aidl/default/CanController.h
new file mode 100644
index 0000000..784906e
--- /dev/null
+++ b/automotive/can/aidl/default/CanController.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/can/BnCanController.h>
+
+#include "CanBus.h"
+
+#include <aidl/android/hardware/automotive/can/Result.h>
+
+#include <map>
+#include <string>
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanController : public BnCanController {
+  public:
+    ndk::ScopedAStatus getSupportedInterfaceTypes(
+            std::vector<InterfaceType>* supportedTypes) override;
+
+    ndk::ScopedAStatus getInterfaceName(const std::string& busName,
+                                        std::string* ifaceName) override;
+
+    ndk::ScopedAStatus upBus(const BusConfig& config, std::string* ifaceName) override;
+
+    ndk::ScopedAStatus downBus(const std::string& busName) override;
+
+  private:
+    std::map<std::string, std::unique_ptr<CanBus>> mBusesByName = {};
+};
+}  // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/android.hardware.automotive.can.rc b/automotive/can/aidl/default/android.hardware.automotive.can.rc
new file mode 100644
index 0000000..f843752
--- /dev/null
+++ b/automotive/can/aidl/default/android.hardware.automotive.can.rc
@@ -0,0 +1,5 @@
+service android.hardware.automotive.can /vendor/bin/hw/android.hardware.automotive.can-service
+    class hal
+    capabilities NET_ADMIN
+    user vehicle_network
+    group system inet
diff --git a/automotive/can/aidl/default/android.hardware.automotive.can.xml b/automotive/can/aidl/default/android.hardware.automotive.can.xml
new file mode 100644
index 0000000..873f333
--- /dev/null
+++ b/automotive/can/aidl/default/android.hardware.automotive.can.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.can</name>
+        <version>1</version>
+        <interface>
+            <name>ICanController</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/automotive/can/aidl/default/service.cpp b/automotive/can/aidl/default/service.cpp
new file mode 100644
index 0000000..eb45167
--- /dev/null
+++ b/automotive/can/aidl/default/service.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanController.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+namespace android::hardware::automotive::can {
+
+using namespace std::string_literals;
+using ::aidl::android::hardware::automotive::can::CanController;
+
+extern "C" int main() {
+    base::SetDefaultTag("CanController");
+    base::SetMinimumLogSeverity(base::VERBOSE);
+
+    LOG(VERBOSE) << "Starting up...";
+    auto service = ndk::SharedRefBase::make<CanController>();
+    const auto instance = CanController::descriptor + "/default"s;
+    const auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance;
+    LOG(VERBOSE) << "Started successfully!";
+
+    ABinderProcess_joinThreadPool();
+    LOG(FATAL) << "CanController exited unexpectedly!";
+    return EXIT_FAILURE;
+}
+}  // namespace android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/tools/configurator/Android.bp b/automotive/can/aidl/default/tools/configurator/Android.bp
new file mode 100644
index 0000000..4c569e6
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/Android.bp
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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_binary {
+    name: "canhalconfigurator-aidl",
+    init_rc: ["canhalconfigurator-aidl.rc"],
+    defaults: ["android.hardware.automotive.can@defaults"],
+    srcs: [
+        "canhalconfigurator.cpp",
+        "canprototools.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libprotobuf-cpp-full",
+    ],
+    static_libs: [
+        "android.hardware.automotive.can-V1-ndk",
+        "android.hardware.automotive.can-aidl-config-format",
+    ],
+    system_ext_specific: true,
+}
diff --git a/automotive/can/aidl/default/tools/configurator/canhalconfigurator-aidl.rc b/automotive/can/aidl/default/tools/configurator/canhalconfigurator-aidl.rc
new file mode 100644
index 0000000..08b1e7b
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/canhalconfigurator-aidl.rc
@@ -0,0 +1,3 @@
+service canhalconfigurator /system_ext/bin/canhalconfigurator-aidl
+  class core
+  oneshot
diff --git a/automotive/can/aidl/default/tools/configurator/canhalconfigurator.cpp b/automotive/can/aidl/default/tools/configurator/canhalconfigurator.cpp
new file mode 100644
index 0000000..94e77b4
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/canhalconfigurator.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "canbus_config.pb.h"
+#include "canprototools.h"
+
+#include <aidl/android/hardware/automotive/can/ICanController.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include <chrono>
+#include <thread>
+
+namespace android::hardware::automotive::can {
+
+using namespace std::string_literals;
+using ::aidl::android::hardware::automotive::can::ICanController;
+
+static constexpr std::string_view kDefaultConfigPath = "/etc/canbus_config.pb";
+
+/**
+ * Takes output from parsed protobuf config and uses it to configure the CAN HAL.
+ *
+ * \param pb_cfg is an instance of the autogenerated protobuf object for our configuration.
+ * \return boolean status, true on success, false on failure.
+ */
+static bool processPbCfg(const config::CanBusConfig& pb_cfg) {
+    for (auto const& bus : pb_cfg.buses()) {
+        if (bus.name().empty()) {
+            LOG(ERROR) << "Invalid config: Bus config must have a valid name field";
+            return false;
+        }
+
+        auto busCfgMaybe = config::fromPbBus(bus);
+        if (!busCfgMaybe.has_value()) {
+            return false;
+        }
+        auto busCfg = *busCfgMaybe;
+
+        const auto instance = ICanController::descriptor + "/default"s;
+        const auto service = ICanController::fromBinder(
+                ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str())));
+        if (service == nullptr) {
+            LOG(FATAL) << "Can't find CAN HAL! (has it started yet?)";
+            return false;
+        }
+
+        LOG(VERBOSE) << "Bringing up a " << busCfg.name << " @ " << busCfg.bitrate;
+
+        std::string ifaceName;
+        const auto status = service->upBus(busCfg, &ifaceName);
+        if (!status.isOk() && status.getExceptionCode() != EX_SERVICE_SPECIFIC) {
+            LOG(FATAL) << "Binder transaction failed!" << status.getStatus();
+            return false;
+        } else if (!status.isOk()) {
+            LOG(ERROR) << "upBus failed: " << config::resultStringFromStatus(status) << ": "
+                       << status.getMessage();
+            continue;
+        }
+
+        LOG(INFO) << bus.name() << " has been successfully configured on " << ifaceName;
+    }
+    return true;
+}
+
+/**
+ * This kicks off the CAN HAL configuration process. This starts the following:
+ *     1. Reading the config file
+ *     2. Setting up CAN buses
+ *     3. Handling services
+ * \param filepath is a string specifying the absolute path of the config file
+ * \return boolean status, true on success, false on failure
+ */
+static bool configuratorStart(const std::string& filepath) {
+    base::SetDefaultTag("CanConfigurator");
+    auto pbCfg = config::parseConfigFile(filepath);
+    if (!pbCfg.has_value()) {
+        return false;
+    }
+    // process the rest of the config file data and configure the CAN buses.
+    if (!processPbCfg(*pbCfg)) {
+        return false;
+    }
+    LOG(INFO) << "CAN HAL has been configured!";
+    return true;
+}
+
+extern "C" int main(int argc, char* argv[]) {
+    std::string configFilepath = static_cast<std::string>(kDefaultConfigPath);
+
+    // allow for CLI specification of a config file.
+    if (argc == 2) {
+        configFilepath = argv[1];
+    } else if (argc > 2) {
+        std::cerr << "usage: " << argv[0] << " [optional config filepath]";
+        return 1;
+    }
+
+    if (!configuratorStart(configFilepath)) {
+        return 1;
+    }
+    return 0;
+}
+
+}  // namespace android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/tools/configurator/canprototools.cpp b/automotive/can/aidl/default/tools/configurator/canprototools.cpp
new file mode 100644
index 0000000..84edd94
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/canprototools.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "canprototools.h"
+
+#include <aidl/android/hardware/automotive/can/IndexedInterface.h>
+#include <aidl/android/hardware/automotive/can/NativeInterface.h>
+#include <aidl/android/hardware/automotive/can/SlcanInterface.h>
+#include <aidl/android/hardware/automotive/can/VirtualInterface.h>
+
+#include <android-base/logging.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/text_format.h>
+
+#include <fstream>
+
+namespace android::hardware::automotive::can::config {
+
+using ::aidl::android::hardware::automotive::can::BusConfig;
+using ::aidl::android::hardware::automotive::can::IndexedInterface;
+using ::aidl::android::hardware::automotive::can::InterfaceType;
+using ::aidl::android::hardware::automotive::can::NativeInterface;
+using ::aidl::android::hardware::automotive::can::Result;
+using ::aidl::android::hardware::automotive::can::SlcanInterface;
+using ::aidl::android::hardware::automotive::can::VirtualInterface;
+
+/**
+ * Helper function for parseConfigFile. readString is used to get the fist n characters (n) from an
+ * istream object (s) and return it as a string object.
+ *
+ * \param s istream of the file you intend to read.
+ * \param n streamsize object of the number of characters you'd like.
+ * \return optional string containing up to n characters from the stream(s) you provided.
+ */
+static std::optional<std::string> readString(std::istream& s, std::streamsize n) {
+    char buff[n];
+    auto got = s.read(buff, n).gcount();
+    if (!s.good() && !s.eof()) return std::nullopt;
+    return std::string(buff, 0, std::min(n, got));
+}
+
+/*
+  parseConfigFile *used to* contain the body of parseConfigStream. However, it seems there's some
+  sort of odd behavior with IstreamInputStream and/or TextFormat::Parse, which causes HW Address
+  Sanitizer to flag a "tag-mismatch" in this function. Having the ifstream defined in a wrapper
+  function seems to solve this problem. The exact cause of this problem is yet unknown, but probably
+  lies somewhere in the protobuf implementation.
+*/
+static __attribute__((noinline)) std::optional<CanBusConfig> parseConfigStream(
+        std::ifstream& cfg_stream) {
+    static const std::array<std::string, 3> text_headers = {"buses", "#", "controller"};
+    auto cfg_file_snippet = readString(cfg_stream, 10);
+
+    if (!cfg_file_snippet.has_value()) {
+        LOG(ERROR) << "Can't read config from stream (maybe failed to open file?)";
+        return std::nullopt;
+    }
+    cfg_stream.seekg(0);
+
+    // check if any of the textHeaders are at the start of the config file.
+    bool text_format = false;
+    for (auto const& header : text_headers) {
+        if (cfg_file_snippet->compare(0, header.length(), header) == 0) {
+            text_format = true;
+            break;
+        }
+    }
+
+    CanBusConfig config;
+    if (text_format) {
+        google::protobuf::io::IstreamInputStream pb_stream(&cfg_stream);
+        if (!google::protobuf::TextFormat::Parse(&pb_stream, &config)) {
+            LOG(ERROR) << "Parsing text format config failed";
+            return std::nullopt;
+        }
+    } else if (!config.ParseFromIstream(&cfg_stream)) {
+        LOG(ERROR) << "Parsing binary format config failed";
+        return std::nullopt;
+    }
+    return config;
+}
+
+std::optional<CanBusConfig> parseConfigFile(const std::string& filepath) {
+    std::ifstream cfg_stream(filepath);
+    auto cfg_maybe = parseConfigStream(cfg_stream);
+    if (!cfg_maybe.has_value()) {
+        LOG(ERROR) << "Failed to parse " << filepath;
+    }
+    return cfg_maybe;
+}
+
+std::optional<BusConfig> fromPbBus(const Bus& pb_bus) {
+    BusConfig bus_cfg = {};
+    bus_cfg.name = pb_bus.name();
+
+    switch (pb_bus.iface_type_case()) {
+        case Bus::kNative: {
+            const std::string ifname = pb_bus.native().ifname();
+            const std::vector<std::string> serials = {pb_bus.native().serialno().begin(),
+                                                      pb_bus.native().serialno().end()};
+            if (ifname.empty() == serials.empty()) {
+                LOG(ERROR) << "Invalid config: native type bus must have an iface name xor a "
+                           << "serial number";
+                return std::nullopt;
+            }
+            bus_cfg.bitrate = pb_bus.bitrate();
+            NativeInterface nativeif = {};
+            if (!ifname.empty())
+                nativeif.interfaceId.set<NativeInterface::InterfaceId::Tag::ifname>(ifname);
+            if (!serials.empty())
+                nativeif.interfaceId.set<NativeInterface::InterfaceId::Tag::serialno>(serials);
+            bus_cfg.interfaceId.set<BusConfig::InterfaceId::Tag::nativeif>(nativeif);
+            break;
+        }
+        case Bus::kSlcan: {
+            const std::string ttyname = pb_bus.slcan().ttyname();
+            const std::vector<std::string> serials = {pb_bus.slcan().serialno().begin(),
+                                                      pb_bus.slcan().serialno().end()};
+            if (ttyname.empty() == serials.empty()) {
+                LOG(ERROR) << "Invalid config: slcan type bus must have a tty name xor a serial "
+                           << "number";
+                return std::nullopt;
+            }
+            bus_cfg.bitrate = pb_bus.bitrate();
+            SlcanInterface slcan = {};
+            if (!ttyname.empty())
+                slcan.interfaceId.set<SlcanInterface::InterfaceId::Tag::ttyname>(ttyname);
+            if (!serials.empty())
+                slcan.interfaceId.set<SlcanInterface::InterfaceId::Tag::serialno>(serials);
+            bus_cfg.interfaceId.set<BusConfig::InterfaceId::Tag::slcan>(slcan);
+            break;
+        }
+        case Bus::kVirtual: {
+            // Theoretically, we could just create the next available vcan iface.
+            const std::string ifname = pb_bus.virtual_().ifname();
+            if (ifname.empty()) {
+                LOG(ERROR) << "Invalid config: native type bus must have an iface name";
+                return std::nullopt;
+            }
+            VirtualInterface virtualif = {};
+            virtualif.ifname = ifname;
+            bus_cfg.interfaceId.set<BusConfig::InterfaceId::Tag::virtualif>(virtualif);
+            break;
+        }
+        case Bus::kIndexed: {
+            const uint8_t index = pb_bus.indexed().index();
+            if (index > UINT8_MAX) {
+                LOG(ERROR) << "Interface index out of range: " << index;
+                return std::nullopt;
+            }
+            IndexedInterface indexedif = {};
+            indexedif.index = index;
+            bus_cfg.interfaceId.set<BusConfig::InterfaceId::Tag::indexed>(indexedif);
+            break;
+        }
+        default:
+            LOG(ERROR) << "Invalid config: bad interface type for " << bus_cfg.name;
+            return std::nullopt;
+    }
+    return bus_cfg;
+}
+
+std::optional<InterfaceType> getHalIftype(const Bus& pb_bus) {
+    switch (pb_bus.iface_type_case()) {
+        case Bus::kNative:
+            return InterfaceType::NATIVE;
+        case Bus::kSlcan:
+            return InterfaceType::SLCAN;
+        case Bus::kVirtual:
+            return InterfaceType::VIRTUAL;
+        case Bus::kIndexed:
+            return InterfaceType::INDEXED;
+        default:
+            return std::nullopt;
+    }
+}
+
+std::string resultStringFromStatus(const ndk::ScopedAStatus& status) {
+    const auto res = static_cast<Result>(status.getServiceSpecificError());
+    switch (res) {
+        case Result::OK:
+            return "OK";
+        case Result::UNKNOWN_ERROR:
+            return "UNKNOWN_ERROR";
+        case Result::INVALID_STATE:
+            return "INVALID_STATE";
+        case Result::NOT_SUPPORTED:
+            return "NOT_SUPPORTED";
+        case Result::BAD_INTERFACE_ID:
+            return "BAD_INTERFACE_ID";
+        case Result::BAD_BITRATE:
+            return "BAD_BITRATE";
+        case Result::BAD_BUS_NAME:
+            return "BAD_BUS_NAME";
+        case Result::INTERFACE_DOWN:
+            return "INTERFACE_DOWN";
+        default:
+            return "Invalid Result!";
+    }
+}
+
+}  // namespace android::hardware::automotive::can::config
diff --git a/automotive/can/aidl/default/tools/configurator/canprototools.h b/automotive/can/aidl/default/tools/configurator/canprototools.h
new file mode 100644
index 0000000..377ee7f
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/canprototools.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "canbus_config.pb.h"
+
+#include <aidl/android/hardware/automotive/can/BusConfig.h>
+#include <aidl/android/hardware/automotive/can/InterfaceType.h>
+#include <aidl/android/hardware/automotive/can/Result.h>
+
+namespace android::hardware::automotive::can::config {
+
+/**
+ * This reads the protobuf config file into a protobuf object. Both text based protobuf files as
+ * well as binary format protobuf files are supported.
+ *
+ * \param filepath string containing the name of the config file to read.
+ * \return a CanBusConfig protobuf object constructed from the config file.
+ */
+std::optional<CanBusConfig> parseConfigFile(const std::string& filepath);
+
+/**
+ * Converts protobuf format single-bus config object to a HAL bus config object.
+ *
+ * \param pb_bus is the protobuf object representing a the configuration of one CAN bus.
+ * \return a converted HAL bus config object.
+ */
+std::optional<::aidl::android::hardware::automotive::can::BusConfig> fromPbBus(const Bus& pb_bus);
+
+/**
+ * Get the CAN HAL interface type specified by a given protobuf config object.
+ *
+ * \param pb_bus is the protobuf object representing a the configuration of one CAN bus.
+ * \return the CAN HAL interface type.
+ */
+std::optional<::aidl::android::hardware::automotive::can::InterfaceType> getHalIftype(
+        const Bus& pb_bus);
+
+std::string resultStringFromStatus(const ndk::ScopedAStatus& status);
+
+}  // namespace android::hardware::automotive::can::config
diff --git a/automotive/can/aidl/default/tools/configurator/proto/Android.bp b/automotive/can/aidl/default/tools/configurator/proto/Android.bp
new file mode 100644
index 0000000..da1b37c
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/proto/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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_static {
+    name: "android.hardware.automotive.can-aidl-config-format",
+    defaults: ["android.hardware.automotive.can@defaults"],
+    proto: {
+        export_proto_headers: true,
+        type: "full",
+    },
+    strip: {
+        keep_symbols: true,
+    },
+    srcs: ["canbus_config.proto"],
+}
diff --git a/automotive/can/aidl/default/tools/configurator/proto/canbus_config.proto b/automotive/can/aidl/default/tools/configurator/proto/canbus_config.proto
new file mode 100644
index 0000000..b03b035
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/proto/canbus_config.proto
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.can.config;
+
+message IfaceNative {
+    string ifname = 1;
+    repeated string serialno = 2;
+};
+
+message IfaceSlcan {
+    string ttyname = 1;
+    repeated string serialno = 2;
+};
+
+message IfaceVirtual {
+    string ifname = 1;
+};
+
+message IfaceIndexed {
+    uint32 index = 1;
+};
+
+message Bus {
+    string name = 1;  // this is the name presented in the HAL
+    oneof iface_type {
+        IfaceNative native = 2;
+        IfaceSlcan slcan = 3;
+        IfaceVirtual virtual = 4;
+        IfaceIndexed indexed = 5;
+    }
+    uint32 bitrate = 6;
+};
+
+message CanBusConfig {
+    repeated Bus buses = 1;
+};
diff --git a/automotive/can/aidl/vts/functional/Android.bp b/automotive/can/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..b816a49
--- /dev/null
+++ b/automotive/can/aidl/vts/functional/Android.bp
@@ -0,0 +1,51 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+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_test {
+    name: "VtsHalCanControllerV1_0Test",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "android.hardware.automotive.can@defaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    cpp_std: "experimental",
+    srcs: [
+        "CanControllerAidlTest.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.automotive.can-V1-ndk",
+        "android.hardware.automotive.can@libnetdevice",
+        "libnl++",
+        "libgmock",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/automotive/can/aidl/vts/functional/CanControllerAidlTest.cpp b/automotive/can/aidl/vts/functional/CanControllerAidlTest.cpp
new file mode 100644
index 0000000..c2b2879
--- /dev/null
+++ b/automotive/can/aidl/vts/functional/CanControllerAidlTest.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/automotive/can/BusConfig.h>
+#include <aidl/android/hardware/automotive/can/ICanController.h>
+#include <aidl/android/hardware/automotive/can/Result.h>
+#include <aidl/android/hardware/automotive/can/VirtualInterface.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <libnetdevice/libnetdevice.h>
+#include <libnl++/MessageFactory.h>
+#include <libnl++/Socket.h>
+#include <libnl++/printer.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <chrono>
+#include <thread>
+
+using aidl::android::hardware::automotive::can::BusConfig;
+using aidl::android::hardware::automotive::can::ICanController;
+using aidl::android::hardware::automotive::can::VirtualInterface;
+using namespace std::chrono_literals;
+using namespace std::string_literals;
+
+class CanControllerAidlTest : public ::testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        android::base::SetDefaultTag("CAN_HAL_VTS");
+        android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+        const auto instance = ICanController::descriptor + "/default"s;
+        mCanControllerService = ICanController::fromBinder(
+                ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str())));
+
+        ASSERT_NE(mCanControllerService, nullptr);
+    }
+    virtual void TearDown() override {}
+
+    static bool mTestCaseInitialized;
+    std::shared_ptr<ICanController> mCanControllerService;
+};
+
+// we can't test a real bus, since we can't make any assumptions about hardware
+// this checks upBus, getInterfaceName, and downBus
+TEST_P(CanControllerAidlTest, ToggleBus) {
+    const std::string_view canIface = "vcan50";
+    const std::string busName = "VTS_CAN";
+
+    std::string upBusReturn;  // should be vcan50
+    BusConfig config = {};
+    VirtualInterface iface = {};
+    iface.ifname = canIface;
+    config.interfaceId.set<BusConfig::InterfaceId::Tag::virtualif>(iface);
+    config.name = busName;
+    auto aidlStatus = mCanControllerService->upBus(config, &upBusReturn);
+    ASSERT_TRUE(aidlStatus.isOk());
+    EXPECT_EQ(upBusReturn, canIface);
+
+    std::string ifaceName;
+    aidlStatus = mCanControllerService->getInterfaceName(busName, &ifaceName);
+    ASSERT_TRUE(aidlStatus.isOk());
+    EXPECT_EQ(ifaceName, canIface);
+
+    aidlStatus = mCanControllerService->downBus(busName);
+    ASSERT_TRUE(aidlStatus.isOk());
+}
+
+TEST_P(CanControllerAidlTest, GetSupported) {
+    LOG(VERBOSE) << "Get the supported iface types";
+    std::vector<::aidl::android::hardware::automotive::can::InterfaceType> supportedTypes;
+    auto aidlStatus = mCanControllerService->getSupportedInterfaceTypes(&supportedTypes);
+    ASSERT_TRUE(aidlStatus.isOk());
+    EXPECT_FALSE(supportedTypes.empty());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CanControllerAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, CanControllerAidlTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(ICanController::descriptor)),
+        android::PrintInstanceNameToString);
diff --git a/automotive/can/aidl/vts/functional/OWNERS b/automotive/can/aidl/vts/functional/OWNERS
new file mode 100644
index 0000000..85257a3
--- /dev/null
+++ b/automotive/can/aidl/vts/functional/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 533426
+twasilczyk@google.com
+chrisweir@google.com
diff --git a/automotive/evs/1.1/default/Android.bp b/automotive/evs/1.1/default/Android.bp
index 4c08ef3..4172e63 100644
--- a/automotive/evs/1.1/default/Android.bp
+++ b/automotive/evs/1.1/default/Android.bp
@@ -13,6 +13,7 @@
     proprietary: true,
     relative_install_path: "hw",
     srcs: [
+        ":libgui_frame_event_aidl",
         "*.cpp",
     ],
     init_rc: ["android.hardware.automotive.evs@1.1-service.rc"],
diff --git a/automotive/evs/1.1/default/GlWrapper.cpp b/automotive/evs/1.1/default/GlWrapper.cpp
index 357b67c..9ad5729 100644
--- a/automotive/evs/1.1/default/GlWrapper.cpp
+++ b/automotive/evs/1.1/default/GlWrapper.cpp
@@ -37,28 +37,23 @@
 constexpr float kDisplayAreaRatio = 0.8f;
 
 constexpr const char vertexShaderSource[] =
-        ""
-        "#version 300 es                    \n"
-        "layout(location = 0) in vec4 pos;  \n"
-        "layout(location = 1) in vec2 tex;  \n"
-        "out vec2 uv;                       \n"
-        "void main()                        \n"
-        "{                                  \n"
-        "   gl_Position = pos;              \n"
-        "   uv = tex;                       \n"
-        "}                                  \n";
+        "attribute vec4 pos;                    \n"
+        "attribute vec2 tex;                    \n"
+        "varying vec2 uv;                       \n"
+        "void main()                            \n"
+        "{                                      \n"
+        "   gl_Position = pos;                  \n"
+        "   uv = tex;                           \n"
+        "}                                      \n";
 
 constexpr const char pixelShaderSource[] =
-        "#version 300 es                    \n"
-        "precision mediump float;           \n"
-        "uniform sampler2D tex;             \n"
-        "in vec2 uv;                        \n"
-        "out vec4 color;                    \n"
-        "void main()                        \n"
-        "{                                  \n"
-        "    vec4 texel = texture(tex, uv); \n"
-        "    color = texel;                 \n"
-        "}                                  \n";
+        "precision mediump float;               \n"
+        "uniform sampler2D tex;                 \n"
+        "varying vec2 uv;                       \n"
+        "void main()                            \n"
+        "{                                      \n"
+        "    gl_FragColor = texture2D(tex, uv); \n"
+        "}                                      \n";
 
 const char* getEGLError(void) {
     switch (eglGetError()) {
@@ -157,6 +152,9 @@
     glAttachShader(program, vertexShader);
     glAttachShader(program, pixelShader);
 
+    glBindAttribLocation(program, 0, "pos");
+    glBindAttribLocation(program, 1, "tex");
+
     // Link the program
     glLinkProgram(program);
     GLint linked = 0;
@@ -235,7 +233,7 @@
         return false;
     }
 
-    EGLint major = 3;
+    EGLint major = 2;
     EGLint minor = 0;
     if (!eglInitialize(mDisplay, &major, &minor)) {
         LOG(ERROR) << "Failed to initialize EGL: " << getEGLError();
diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS
index b973e91..15de48f 100644
--- a/automotive/evs/OWNERS
+++ b/automotive/evs/OWNERS
@@ -1,3 +1,2 @@
 ankitarora@google.com
-changyeon@google.com
 jwhpryor@google.com
diff --git a/automotive/evs/aidl/Android.bp b/automotive/evs/aidl/Android.bp
index 1c908aa..bafb4af 100644
--- a/automotive/evs/aidl/Android.bp
+++ b/automotive/evs/aidl/Android.bp
@@ -30,7 +30,7 @@
     stability: "vintf",
     imports: [
         "android.hardware.common-V2",
-        "android.hardware.graphics.common-V3",
+        "android.hardware.graphics.common-V4",
     ],
     backend: {
         java: {
@@ -53,9 +53,18 @@
             version: "1",
             imports: [
                 "android.hardware.common-V2",
-                "android.hardware.graphics.common-V3",
+                "android.hardware.graphics.common-V4",
             ],
         },
+        {
+            version: "2",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.graphics.common-V4",
+            ],
+        },
+
     ],
+    frozen: true,
 
 }
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/.hash b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/.hash
new file mode 100644
index 0000000..406943e
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/.hash
@@ -0,0 +1 @@
+36c9e7c4f9a0e7264c1e5dd61359cb6397fcd182
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/BufferDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/BufferDesc.aidl
new file mode 100644
index 0000000..332aca3
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/BufferDesc.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable BufferDesc {
+  android.hardware.graphics.common.HardwareBuffer buffer;
+  int pixelSizeBytes;
+  int bufferId;
+  @utf8InCpp String deviceId;
+  long timestamp;
+  byte[] metadata;
+  @nullable android.hardware.automotive.evs.ExposureParameters[] exposureSettings;
+  @nullable android.hardware.automotive.evs.Histogram[] histograms;
+  @nullable android.hardware.automotive.evs.GridStatistics[] grids;
+  @nullable android.hardware.automotive.evs.EmbeddedData embeddedData;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/CameraDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/CameraDesc.aidl
new file mode 100644
index 0000000..4dadeb8
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/CameraDesc.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable CameraDesc {
+  @utf8InCpp String id;
+  int vendorFlags;
+  byte[] metadata;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/CameraParam.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/CameraParam.aidl
new file mode 100644
index 0000000..21207b3
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/CameraParam.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@Backing(type="int") @VintfStability
+enum CameraParam {
+  BRIGHTNESS,
+  CONTRAST,
+  AUTOGAIN,
+  GAIN,
+  AUTO_WHITE_BALANCE,
+  WHITE_BALANCE_TEMPERATURE,
+  SHARPNESS,
+  AUTO_EXPOSURE,
+  ABSOLUTE_EXPOSURE,
+  ABSOLUTE_FOCUS,
+  AUTO_FOCUS,
+  ABSOLUTE_ZOOM,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/ColorChannel.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/ColorChannel.aidl
new file mode 100644
index 0000000..e59db4c
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/ColorChannel.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@Backing(type="int") @VintfStability
+enum ColorChannel {
+  R,
+  G_EVEN,
+  B,
+  G_ODD_OR_Y,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DeviceStatus.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DeviceStatus.aidl
new file mode 100644
index 0000000..cc066ac
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DeviceStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable DeviceStatus {
+  @utf8InCpp String id;
+  android.hardware.automotive.evs.DeviceStatusType status;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DeviceStatusType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DeviceStatusType.aidl
new file mode 100644
index 0000000..92c2247
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DeviceStatusType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@Backing(type="int") @VintfStability
+enum DeviceStatusType {
+  CAMERA_AVAILABLE,
+  CAMERA_NOT_AVAILABLE,
+  DISPLAY_AVAILABLE,
+  DISPLAY_NOT_AVAILABLE,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DisplayDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DisplayDesc.aidl
new file mode 100644
index 0000000..4ac029e
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DisplayDesc.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable DisplayDesc {
+  @utf8InCpp String id;
+  int width;
+  int height;
+  android.hardware.automotive.evs.Rotation orientation;
+  int vendorFlags;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DisplayState.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DisplayState.aidl
new file mode 100644
index 0000000..5f03f43
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/DisplayState.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@Backing(type="int") @VintfStability
+enum DisplayState {
+  NOT_OPEN = 0,
+  NOT_VISIBLE,
+  VISIBLE_ON_NEXT_FRAME,
+  VISIBLE,
+  DEAD,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EmbeddedData.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EmbeddedData.aidl
new file mode 100644
index 0000000..e1f50d2
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EmbeddedData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable EmbeddedData {
+  int widthInBytes;
+  int heightInLines;
+  android.hardware.common.Ashmem data;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EvsEventDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EvsEventDesc.aidl
new file mode 100644
index 0000000..09b2b9d
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EvsEventDesc.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable EvsEventDesc {
+  android.hardware.automotive.evs.EvsEventType aType;
+  @utf8InCpp String deviceId;
+  int[] payload;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EvsEventType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EvsEventType.aidl
new file mode 100644
index 0000000..2e75a25
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EvsEventType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@Backing(type="int") @VintfStability
+enum EvsEventType {
+  STREAM_STARTED = 0,
+  STREAM_STOPPED,
+  FRAME_DROPPED,
+  TIMEOUT,
+  PARAMETER_CHANGED,
+  MASTER_RELEASED,
+  STREAM_ERROR,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EvsResult.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EvsResult.aidl
new file mode 100644
index 0000000..1f04750
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/EvsResult.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@Backing(type="int") @VintfStability
+enum EvsResult {
+  OK = 0,
+  INVALID_ARG,
+  STREAM_ALREADY_RUNNING,
+  BUFFER_NOT_AVAILABLE,
+  OWNERSHIP_LOST,
+  UNDERLYING_SERVICE_ERROR,
+  PERMISSION_DENIED,
+  RESOURCE_NOT_AVAILABLE,
+  RESOURCE_BUSY,
+  NOT_IMPLEMENTED,
+  NOT_SUPPORTED,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/ExposureParameters.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/ExposureParameters.aidl
new file mode 100644
index 0000000..28289ae
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/ExposureParameters.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable ExposureParameters {
+  float[4] analogGain;
+  float[4] digitalGain;
+  long coarseIntegrationTimeInLines;
+  long fineIntegrationTimeInPixelClocks;
+  int coarseIntegrationTimeLShift;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/GridStatisticDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/GridStatisticDesc.aidl
new file mode 100644
index 0000000..f9fadd9
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/GridStatisticDesc.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable GridStatisticDesc {
+  android.hardware.automotive.evs.ColorChannel channel;
+  android.hardware.automotive.evs.GridStatisticType type;
+  android.hardware.graphics.common.Rect roi;
+  android.hardware.automotive.evs.Size cellSize;
+  int bitDepth;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/GridStatisticType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/GridStatisticType.aidl
new file mode 100644
index 0000000..c2b2d66
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/GridStatisticType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@Backing(type="int") @VintfStability
+enum GridStatisticType {
+  USER_DEFINED,
+  AVERAGE,
+  SUM,
+  SATURATION_COUNT,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/GridStatistics.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/GridStatistics.aidl
new file mode 100644
index 0000000..d87cff3
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/GridStatistics.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable GridStatistics {
+  android.hardware.automotive.evs.GridStatisticDesc[] descriptors;
+  android.hardware.common.Ashmem data;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Histogram.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Histogram.aidl
new file mode 100644
index 0000000..cb73eba
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Histogram.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable Histogram {
+  android.hardware.automotive.evs.ColorChannel channel;
+  android.hardware.graphics.common.Rect roi;
+  int size;
+  int capacity;
+  long[] bins;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsCamera.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsCamera.aidl
new file mode 100644
index 0000000..ce1b97d
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsCamera.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+interface IEvsCamera {
+  void doneWithFrame(in android.hardware.automotive.evs.BufferDesc[] buffer);
+  void forcePrimaryClient(in android.hardware.automotive.evs.IEvsDisplay display);
+  android.hardware.automotive.evs.CameraDesc getCameraInfo();
+  byte[] getExtendedInfo(in int opaqueIdentifier);
+  int[] getIntParameter(in android.hardware.automotive.evs.CameraParam id);
+  android.hardware.automotive.evs.ParameterRange getIntParameterRange(in android.hardware.automotive.evs.CameraParam id);
+  android.hardware.automotive.evs.CameraParam[] getParameterList();
+  android.hardware.automotive.evs.CameraDesc getPhysicalCameraInfo(in String deviceId);
+  int importExternalBuffers(in android.hardware.automotive.evs.BufferDesc[] buffers);
+  void pauseVideoStream();
+  void resumeVideoStream();
+  void setExtendedInfo(in int opaqueIdentifier, in byte[] opaqueValue);
+  int[] setIntParameter(in android.hardware.automotive.evs.CameraParam id, in int value);
+  void setPrimaryClient();
+  void setMaxFramesInFlight(in int bufferCount);
+  void startVideoStream(in android.hardware.automotive.evs.IEvsCameraStream receiver);
+  void stopVideoStream();
+  void unsetPrimaryClient();
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsCameraStream.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsCameraStream.aidl
new file mode 100644
index 0000000..6e2e64a
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsCameraStream.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+interface IEvsCameraStream {
+  oneway void deliverFrame(in android.hardware.automotive.evs.BufferDesc[] buffer);
+  oneway void notify(in android.hardware.automotive.evs.EvsEventDesc event);
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsDisplay.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsDisplay.aidl
new file mode 100644
index 0000000..9b538d4
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsDisplay.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+interface IEvsDisplay {
+  android.hardware.automotive.evs.DisplayDesc getDisplayInfo();
+  android.hardware.automotive.evs.DisplayState getDisplayState();
+  android.hardware.automotive.evs.BufferDesc getTargetBuffer();
+  void returnTargetBufferForDisplay(in android.hardware.automotive.evs.BufferDesc buffer);
+  void setDisplayState(in android.hardware.automotive.evs.DisplayState state);
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsEnumerator.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsEnumerator.aidl
new file mode 100644
index 0000000..4cefdf2
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsEnumerator.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+interface IEvsEnumerator {
+  void closeCamera(in android.hardware.automotive.evs.IEvsCamera carCamera);
+  void closeDisplay(in android.hardware.automotive.evs.IEvsDisplay display);
+  void closeUltrasonicsArray(in android.hardware.automotive.evs.IEvsUltrasonicsArray evsUltrasonicsArray);
+  android.hardware.automotive.evs.CameraDesc[] getCameraList();
+  byte[] getDisplayIdList();
+  android.hardware.automotive.evs.DisplayState getDisplayState();
+  android.hardware.automotive.evs.Stream[] getStreamList(in android.hardware.automotive.evs.CameraDesc description);
+  android.hardware.automotive.evs.UltrasonicsArrayDesc[] getUltrasonicsArrayList();
+  boolean isHardware();
+  android.hardware.automotive.evs.IEvsCamera openCamera(in String cameraId, in android.hardware.automotive.evs.Stream streamCfg);
+  android.hardware.automotive.evs.IEvsDisplay openDisplay(in int id);
+  android.hardware.automotive.evs.IEvsUltrasonicsArray openUltrasonicsArray(in String ultrasonicsArrayId);
+  void registerStatusCallback(in android.hardware.automotive.evs.IEvsEnumeratorStatusCallback callback);
+  android.hardware.automotive.evs.DisplayState getDisplayStateById(in int id);
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsEnumeratorStatusCallback.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsEnumeratorStatusCallback.aidl
new file mode 100644
index 0000000..c39a4e8
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsEnumeratorStatusCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+interface IEvsEnumeratorStatusCallback {
+  oneway void deviceStatusChanged(in android.hardware.automotive.evs.DeviceStatus[] status);
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsUltrasonicsArray.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsUltrasonicsArray.aidl
new file mode 100644
index 0000000..1183ab3
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsUltrasonicsArray.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+interface IEvsUltrasonicsArray {
+  void doneWithDataFrame(in android.hardware.automotive.evs.UltrasonicsDataFrameDesc dataFrameDesc);
+  android.hardware.automotive.evs.UltrasonicsArrayDesc getUltrasonicArrayInfo();
+  void setMaxFramesInFlight(in int bufferCount);
+  void startStream(in android.hardware.automotive.evs.IEvsUltrasonicsArrayStream stream);
+  void stopStream();
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsUltrasonicsArrayStream.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsUltrasonicsArrayStream.aidl
new file mode 100644
index 0000000..510b0a4
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/IEvsUltrasonicsArrayStream.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+interface IEvsUltrasonicsArrayStream {
+  oneway void deliverDataFrame(in android.hardware.automotive.evs.UltrasonicsDataFrameDesc dataFrameDesc);
+  oneway void notify(in android.hardware.automotive.evs.EvsEventDesc event);
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/ParameterRange.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/ParameterRange.aidl
new file mode 100644
index 0000000..44e9b59
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/ParameterRange.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable ParameterRange {
+  int min;
+  int max;
+  int step;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Rotation.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Rotation.aidl
new file mode 100644
index 0000000..91971fc
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Rotation.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@Backing(type="int") @VintfStability
+enum Rotation {
+  ROTATION_0 = 0,
+  ROTATION_90 = 1,
+  ROTATION_180 = 2,
+  ROTATION_270 = 3,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/RotationQuaternion.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/RotationQuaternion.aidl
new file mode 100644
index 0000000..d9c8b6e
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/RotationQuaternion.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable RotationQuaternion {
+  float x;
+  float y;
+  float z;
+  float w;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/SensorPose.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/SensorPose.aidl
new file mode 100644
index 0000000..4ead9ea
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/SensorPose.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable SensorPose {
+  android.hardware.automotive.evs.RotationQuaternion rotation;
+  android.hardware.automotive.evs.Translation translation;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Size.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Size.aidl
new file mode 100644
index 0000000..aa113f7
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Size.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable Size {
+  int widthInPixels = (-1) /* -1 */;
+  int heightInPixels = (-1) /* -1 */;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Stream.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Stream.aidl
new file mode 100644
index 0000000..154a693
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Stream.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable Stream {
+  int id;
+  android.hardware.automotive.evs.StreamType streamType;
+  int width;
+  int height;
+  int framerate;
+  android.hardware.graphics.common.PixelFormat format;
+  android.hardware.graphics.common.BufferUsage usage;
+  android.hardware.automotive.evs.Rotation rotation;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/StreamType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/StreamType.aidl
new file mode 100644
index 0000000..9819c89
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/StreamType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@Backing(type="int") @VintfStability
+enum StreamType {
+  OUTPUT = 0,
+  INPUT = 1,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Translation.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Translation.aidl
new file mode 100644
index 0000000..488d80f
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/Translation.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable Translation {
+  float x;
+  float y;
+  float z;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/UltrasonicSensor.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/UltrasonicSensor.aidl
new file mode 100644
index 0000000..23f81f8
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/UltrasonicSensor.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable UltrasonicSensor {
+  android.hardware.automotive.evs.SensorPose pose;
+  float maxRangeMm;
+  float angleOfMeasurement;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/UltrasonicsArrayDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/UltrasonicsArrayDesc.aidl
new file mode 100644
index 0000000..4a98875
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/UltrasonicsArrayDesc.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable UltrasonicsArrayDesc {
+  @utf8InCpp String ultrasonicsArrayId;
+  int maxReadingsPerSensorCount;
+  int maxReceiversCount;
+  android.hardware.automotive.evs.UltrasonicSensor[] sensors;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/UltrasonicsDataFrameDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/UltrasonicsDataFrameDesc.aidl
new file mode 100644
index 0000000..35ec84b
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/2/android/hardware/automotive/evs/UltrasonicsDataFrameDesc.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.evs;
+@VintfStability
+parcelable UltrasonicsDataFrameDesc {
+  long timestampNs;
+  int id;
+  byte[] transmittersIdList;
+  byte[] receiversIdList;
+  int[] receiversReadingsCountList;
+  android.hardware.common.Ashmem waveformsData;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/BufferDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/BufferDesc.aidl
index 31acdb8..332aca3 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/BufferDesc.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/BufferDesc.aidl
@@ -40,4 +40,8 @@
   @utf8InCpp String deviceId;
   long timestamp;
   byte[] metadata;
+  @nullable android.hardware.automotive.evs.ExposureParameters[] exposureSettings;
+  @nullable android.hardware.automotive.evs.Histogram[] histograms;
+  @nullable android.hardware.automotive.evs.GridStatistics[] grids;
+  @nullable android.hardware.automotive.evs.EmbeddedData embeddedData;
 }
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/CameraParam.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/CameraParam.aidl
index ae4ce77..21207b3 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/CameraParam.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/CameraParam.aidl
@@ -34,16 +34,16 @@
 package android.hardware.automotive.evs;
 @Backing(type="int") @VintfStability
 enum CameraParam {
-  BRIGHTNESS = 0,
-  CONTRAST = 1,
-  AUTOGAIN = 2,
-  GAIN = 3,
-  AUTO_WHITE_BALANCE = 4,
-  WHITE_BALANCE_TEMPERATURE = 5,
-  SHARPNESS = 6,
-  AUTO_EXPOSURE = 7,
-  ABSOLUTE_EXPOSURE = 8,
-  ABSOLUTE_FOCUS = 9,
-  AUTO_FOCUS = 10,
-  ABSOLUTE_ZOOM = 11,
+  BRIGHTNESS,
+  CONTRAST,
+  AUTOGAIN,
+  GAIN,
+  AUTO_WHITE_BALANCE,
+  WHITE_BALANCE_TEMPERATURE,
+  SHARPNESS,
+  AUTO_EXPOSURE,
+  ABSOLUTE_EXPOSURE,
+  ABSOLUTE_FOCUS,
+  AUTO_FOCUS,
+  ABSOLUTE_ZOOM,
 }
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ColorChannel.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ColorChannel.aidl
new file mode 100644
index 0000000..e59db4c
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ColorChannel.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@Backing(type="int") @VintfStability
+enum ColorChannel {
+  R,
+  G_EVEN,
+  B,
+  G_ODD_OR_Y,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DeviceStatusType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DeviceStatusType.aidl
index d0f1d8e..92c2247 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DeviceStatusType.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DeviceStatusType.aidl
@@ -34,8 +34,8 @@
 package android.hardware.automotive.evs;
 @Backing(type="int") @VintfStability
 enum DeviceStatusType {
-  CAMERA_AVAILABLE = 0,
-  CAMERA_NOT_AVAILABLE = 1,
-  DISPLAY_AVAILABLE = 2,
-  DISPLAY_NOT_AVAILABLE = 3,
+  CAMERA_AVAILABLE,
+  CAMERA_NOT_AVAILABLE,
+  DISPLAY_AVAILABLE,
+  DISPLAY_NOT_AVAILABLE,
 }
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DisplayState.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DisplayState.aidl
index a5f4309..5f03f43 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DisplayState.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DisplayState.aidl
@@ -35,8 +35,8 @@
 @Backing(type="int") @VintfStability
 enum DisplayState {
   NOT_OPEN = 0,
-  NOT_VISIBLE = 1,
-  VISIBLE_ON_NEXT_FRAME = 2,
-  VISIBLE = 3,
-  DEAD = 4,
+  NOT_VISIBLE,
+  VISIBLE_ON_NEXT_FRAME,
+  VISIBLE,
+  DEAD,
 }
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EmbeddedData.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EmbeddedData.aidl
new file mode 100644
index 0000000..e1f50d2
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EmbeddedData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable EmbeddedData {
+  int widthInBytes;
+  int heightInLines;
+  android.hardware.common.Ashmem data;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsEventType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsEventType.aidl
index 052a6b3..2e75a25 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsEventType.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsEventType.aidl
@@ -35,10 +35,10 @@
 @Backing(type="int") @VintfStability
 enum EvsEventType {
   STREAM_STARTED = 0,
-  STREAM_STOPPED = 1,
-  FRAME_DROPPED = 2,
-  TIMEOUT = 3,
-  PARAMETER_CHANGED = 4,
-  MASTER_RELEASED = 5,
-  STREAM_ERROR = 6,
+  STREAM_STOPPED,
+  FRAME_DROPPED,
+  TIMEOUT,
+  PARAMETER_CHANGED,
+  MASTER_RELEASED,
+  STREAM_ERROR,
 }
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsResult.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsResult.aidl
index a0418a9..1f04750 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsResult.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsResult.aidl
@@ -35,14 +35,14 @@
 @Backing(type="int") @VintfStability
 enum EvsResult {
   OK = 0,
-  INVALID_ARG = 1,
-  STREAM_ALREADY_RUNNING = 2,
-  BUFFER_NOT_AVAILABLE = 3,
-  OWNERSHIP_LOST = 4,
-  UNDERLYING_SERVICE_ERROR = 5,
-  PERMISSION_DENIED = 6,
-  RESOURCE_NOT_AVAILABLE = 7,
-  RESOURCE_BUSY = 8,
-  NOT_IMPLEMENTED = 9,
-  NOT_SUPPORTED = 10,
+  INVALID_ARG,
+  STREAM_ALREADY_RUNNING,
+  BUFFER_NOT_AVAILABLE,
+  OWNERSHIP_LOST,
+  UNDERLYING_SERVICE_ERROR,
+  PERMISSION_DENIED,
+  RESOURCE_NOT_AVAILABLE,
+  RESOURCE_BUSY,
+  NOT_IMPLEMENTED,
+  NOT_SUPPORTED,
 }
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ExposureParameters.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ExposureParameters.aidl
new file mode 100644
index 0000000..28289ae
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ExposureParameters.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable ExposureParameters {
+  float[4] analogGain;
+  float[4] digitalGain;
+  long coarseIntegrationTimeInLines;
+  long fineIntegrationTimeInPixelClocks;
+  int coarseIntegrationTimeLShift;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticDesc.aidl
new file mode 100644
index 0000000..f9fadd9
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticDesc.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable GridStatisticDesc {
+  android.hardware.automotive.evs.ColorChannel channel;
+  android.hardware.automotive.evs.GridStatisticType type;
+  android.hardware.graphics.common.Rect roi;
+  android.hardware.automotive.evs.Size cellSize;
+  int bitDepth;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticType.aidl
new file mode 100644
index 0000000..c2b2d66
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@Backing(type="int") @VintfStability
+enum GridStatisticType {
+  USER_DEFINED,
+  AVERAGE,
+  SUM,
+  SATURATION_COUNT,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatistics.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatistics.aidl
new file mode 100644
index 0000000..d87cff3
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatistics.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable GridStatistics {
+  android.hardware.automotive.evs.GridStatisticDesc[] descriptors;
+  android.hardware.common.Ashmem data;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Histogram.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Histogram.aidl
new file mode 100644
index 0000000..cb73eba
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Histogram.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable Histogram {
+  android.hardware.automotive.evs.ColorChannel channel;
+  android.hardware.graphics.common.Rect roi;
+  int size;
+  int capacity;
+  long[] bins;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/IEvsEnumerator.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/IEvsEnumerator.aidl
index 225b504..4cefdf2 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/IEvsEnumerator.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/IEvsEnumerator.aidl
@@ -47,4 +47,5 @@
   android.hardware.automotive.evs.IEvsDisplay openDisplay(in int id);
   android.hardware.automotive.evs.IEvsUltrasonicsArray openUltrasonicsArray(in String ultrasonicsArrayId);
   void registerStatusCallback(in android.hardware.automotive.evs.IEvsEnumeratorStatusCallback callback);
+  android.hardware.automotive.evs.DisplayState getDisplayStateById(in int id);
 }
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Size.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Size.aidl
new file mode 100644
index 0000000..aa113f7
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Size.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.evs;
+@VintfStability
+parcelable Size {
+  int widthInPixels = (-1) /* -1 */;
+  int heightInPixels = (-1) /* -1 */;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/BufferDesc.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/BufferDesc.aidl
index 0604abe..b6c697d 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/BufferDesc.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/BufferDesc.aidl
@@ -16,7 +16,12 @@
 
 package android.hardware.automotive.evs;
 
+import android.hardware.automotive.evs.EmbeddedData;
+import android.hardware.automotive.evs.ExposureParameters;
+import android.hardware.automotive.evs.GridStatistics;
+import android.hardware.automotive.evs.Histogram;
 import android.hardware.graphics.common.HardwareBuffer;
+import android.hardware.graphics.common.Rect;
 
 /**
  * Structure representing an image buffer through our APIs
@@ -57,4 +62,28 @@
      * Frame metadata.  This is opaque to EvsManager.
      */
     byte[] metadata;
+    /**
+     * ExposureParameters are expected to be in the ascending
+     * order of their exposure time; from the shortest to the
+     * longest.  For example, if the imaging sensor output has
+     * two exposures, a shorter exposure setting is at index 0
+     * and a longer exposure setting is at index 1.
+     */
+    @nullable ExposureParameters[] exposureSettings;
+    /**
+     * Histogram statistics calculated on this buffer.  This
+     * may contain zero or more histograms.
+     */
+    @nullable Histogram[] histograms;
+    /**
+     * Grid statistics calculated on this buffer.  This field
+     * also may contain zero or more grid statistics.
+     */
+    @nullable GridStatistics[] grids;
+    /**
+     * This may contain raw embedded data lines and can be
+     * used to share data other than exposure parameters,
+     * histograms, or grid statistics.
+     */
+    @nullable EmbeddedData embeddedData;
 }
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/ColorChannel.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/ColorChannel.aidl
new file mode 100644
index 0000000..9aba465
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/ColorChannel.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.evs;
+
+/**
+ * Color channels.
+ */
+@VintfStability
+@Backing(type="int")
+enum ColorChannel {
+    R,
+    G_EVEN,      // The green channel in even lines.
+    B,
+    G_ODD_OR_Y,  // The green channel in odd lines of
+                 // color formats that have two green (or
+                 // equivalent) channels, or the luminance
+                 // if it exists in associated data.
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/EmbeddedData.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/EmbeddedData.aidl
new file mode 100644
index 0000000..422cef2
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/EmbeddedData.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.evs;
+
+import android.hardware.common.Ashmem;
+
+/**
+ * This structure contains raw embedded data lines and can
+ * used to share sensor embedded data that is not a type of
+ * histogram or grid statistics.
+ */
+@VintfStability
+parcelable EmbeddedData {
+    /** Width of the embedded data lines. */
+    int widthInBytes;
+    /** Number of the embedded data lines. */
+    int heightInLines;
+    /** Raw embedded data lines. */
+    Ashmem data;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
index ebff98f..3abdb54 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
@@ -33,7 +33,9 @@
     @utf8InCpp
     String deviceId;
     /**
-     * Possible additional vendor information that is opaque to the EvsManager
+     * Possible additional vendor information that is opaque to the EvsManager.
+     * The size of the payload must not exceed 16-byte if the HIDL recipients are
+     * expected to exist.
      */
     int[] payload;
 }
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/ExposureParameters.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/ExposureParameters.aidl
new file mode 100644
index 0000000..e644fed
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/ExposureParameters.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.evs;
+
+/**
+ * Parameters that determine the exposure value.
+ *
+ * This data structure assumes that the imaging sensor has 4 channels at most.
+ */
+@VintfStability
+parcelable ExposureParameters {
+    /**
+     * Analog gain applied on each channel.
+     *
+     * A value for each channel will be indexed by android.hardware.automotive.evs.ColorChannel
+     * enum type.
+     */
+    float[4] analogGain;
+    /**
+     * Digital gain applied on each channel.
+     *
+     * A value for each channel will be indexed by android.hardware.automotive.evs.ColorChannel
+     * enum type.
+     */
+    float[4] digitalGain;
+    /** Exposure time in lines. */
+    long coarseIntegrationTimeInLines;
+    /** Remainder exposure time in clocks. */
+    long fineIntegrationTimeInPixelClocks;
+    /**
+     * Logarithm value of coarse integration time multiplier.
+     */
+    int coarseIntegrationTimeLShift;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticDesc.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticDesc.aidl
new file mode 100644
index 0000000..1cd8a1c
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticDesc.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.evs;
+
+import android.hardware.automotive.evs.ColorChannel;
+import android.hardware.automotive.evs.GridStatisticType;
+import android.hardware.automotive.evs.Size;
+import android.hardware.graphics.common.Rect;
+
+/**
+ * This data structure describes a grid statistic such as the low resolution luminance map.
+ */
+@VintfStability
+parcelable GridStatisticDesc {
+    /** Source color channel this statistics is calculated from. */
+    ColorChannel channel;
+    /** Type of this grad statistics. */
+    GridStatisticType type;
+    /** Region this statistics is calculated from. */
+    Rect roi;
+    /** Size of a grid cell. */
+    Size cellSize;
+    /** Bit-depth of a single value. */
+    int bitDepth;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticType.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticType.aidl
new file mode 100644
index 0000000..1b307c7
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticType.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.evs;
+
+/**
+ * Type of grid statistics.
+ */
+@VintfStability
+@Backing(type="int")
+enum GridStatisticType {
+    /** Custom statistics type. */
+    USER_DEFINED,
+    /** Average pixel values of each cell. */
+    AVERAGE,
+    /** Sum of pixel values in each cell. */
+    SUM,
+    /** Number of saturated pixels in each cell. */
+    SATURATION_COUNT,
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/GridStatistics.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatistics.aidl
new file mode 100644
index 0000000..57f72ea
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatistics.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.evs;
+
+import android.hardware.automotive.evs.GridStatisticDesc;
+import android.hardware.common.Ashmem;
+
+/**
+ * This data type represents grid-type statistics such as
+ * the luminance map in low-resolution.
+ */
+@VintfStability
+parcelable GridStatistics {
+    /** Descriptors of grid statistics in shared memory. */
+    GridStatisticDesc[] descriptors;
+    /**
+     * Shared memory object containing one or more grid statistics.
+     *
+     * When multiple statistics exist, they are in the same order with descriptors. For example,
+     * if the first descriptor represents a statistic whose size is in VGA resolution (640x480)
+     * and bitdepth (or precision) is 8-bit, the offset to the second statistic is 640x480x1-byte
+     * = 307200 bytes.
+     */
+    Ashmem data;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/Histogram.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/Histogram.aidl
new file mode 100644
index 0000000..3f3c5a3
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/Histogram.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.evs;
+
+import android.hardware.automotive.evs.ColorChannel;
+import android.hardware.graphics.common.Rect;
+
+/**
+ * This data type represents 1D histogram statistics.
+ */
+@VintfStability
+parcelable Histogram {
+    /**
+     * Source color channel this histogram is calculated from.
+     */
+    ColorChannel channel;
+    /** A region of interests, where this histogram is calculated from. */
+    Rect roi;
+    /** Size of each histogram bin. */
+    int size;
+    /** Capacity of each histogram bin. */
+    int capacity;
+    /**
+     * Histogram bins; each bin contains values calculated from each ColorChannel.
+     *
+     * The size of the histogram data is inversely proportional to the size of a histogram bin.
+     * When a bin is sized as 1, a histogram has pow(2, bitdepth of the source data) and
+     * therefore could occupy more than a few kilobytes of 1 megabyte buffer that is shared with
+     * other processes. To avoid influencing other processes, we strongly recommend keeping the
+     * number of histogram bins less than 128. If a higher resolution is needed, please consider
+     * using android.hardware.automotive.evs.EmbeddedData instead.
+     */
+    long[] bins;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl
index 2c2b44c..c599d58 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl
@@ -47,7 +47,10 @@
     /**
      * Receives calls from the HAL each time an event happens.
      *
-     * @param in event EVS event with possible event information.
+     * @param in event EVS event with possible event information.  If ths HIDL
+     *                 recipients are expected to exist, the size of the event
+     *                 payload must not exceed 16 bytes; otherwise, a notification
+     *                 will not reach them.
      */
     void notify(in EvsEventDesc event);
 }
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsEnumerator.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsEnumerator.aidl
index 8698700..37b8ea5 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsEnumerator.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsEnumerator.aidl
@@ -78,12 +78,12 @@
     byte[] getDisplayIdList();
 
     /**
-     * This call requests the current state of the display
+     * This call requests the current state of the primary display
      *
      * If there is no open display, this returns DisplayState::NOT_OPEN. otherwise, it returns
-     * the actual state of the active display.  This call is replicated on the IEvsEnumerator
-     * interface in order to allow secondary clients to monitor the state of the EVS display
-     * without acquiring exclusive ownership of the display.
+     * the actual state of the active primary display.  This call is replicated on the
+     * IEvsEnumerator interface in order to allow secondary clients to monitor the state of the EVS
+     * display without acquiring exclusive ownership of the display.
      *
      * @return Current DisplayState of this Display.
      * @throws EvsResult::OWNERSHIP_LOST if current display is inactive
@@ -163,4 +163,19 @@
      * @param in callback IEvsEnumeratorStatusCallback implementation
      */
     void registerStatusCallback(in IEvsEnumeratorStatusCallback callback);
+
+    /**
+     * This call requests the current state of the display
+     *
+     * If the requested display is not active, this returns DisplayState::NOT_OPEN. otherwise, it
+     * returns the actual state of the active display.  This call is replicated on the
+     * IEvsEnumerator interface in order to allow secondary clients to monitor the state of the EVS
+     * display without acquiring exclusive ownership of the display.
+     *
+     * @param in id ID of the requested display.
+     * @return Current DisplayState of this Display.
+     * @throws EvsResult::OWNERSHIP_LOST if current display is inactive
+     *        EvsResult::PERMISSION_DENIED if the process is not permitted to do this operation.
+     */
+    DisplayState getDisplayStateById(in int id);
 }
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/Size.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/Size.aidl
new file mode 100644
index 0000000..4924ec8
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/Size.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.evs;
+
+/**
+ * This type represents the size of the 2D area.
+ */
+@VintfStability
+parcelable Size {
+    /** Width of a target 2D area in pixels. */
+    int widthInPixels = -1;
+    /** Width of a target 2D area in pixels. */
+    int heightInPixels = -1;
+}
diff --git a/automotive/evs/aidl/impl/Android.bp b/automotive/evs/aidl/impl/Android.bp
index 7eb0116..fa44ebb 100644
--- a/automotive/evs/aidl/impl/Android.bp
+++ b/automotive/evs/aidl/impl/Android.bp
@@ -20,10 +20,10 @@
 
 cc_defaults {
     name: "EvsHalDefaults",
+    defaults: ["android.hardware.graphics.common-ndk_static"],
     static_libs: [
-        "android.hardware.automotive.evs-V1-ndk",
+        "android.hardware.automotive.evs-V2-ndk",
         "android.hardware.common-V2-ndk",
-        "android.hardware.graphics.common-V3-ndk",
     ],
     shared_libs: [
         "libbase",
diff --git a/automotive/evs/aidl/impl/default/Android.bp b/automotive/evs/aidl/impl/default/Android.bp
index dbe0314..70c523b 100644
--- a/automotive/evs/aidl/impl/default/Android.bp
+++ b/automotive/evs/aidl/impl/default/Android.bp
@@ -24,13 +24,56 @@
 cc_binary {
     name: "android.hardware.automotive.evs-aidl-default-service",
     defaults: ["EvsHalDefaults"],
-    local_include_dirs: ["include"],
-    vintf_fragments: ["evs-default-service.xml"],
+    vintf_fragments: ["manifest_evs-default-service.xml"],
     init_rc: ["evs-default-service.rc"],
     vendor: true,
     relative_install_path: "hw",
-    srcs: ["src/*.cpp"],
-    shared_libs: [
-        "libbinder_ndk",
+    cflags: [
+        "-DGL_GLEXT_PROTOTYPES",
+        "-DEGL_EGLEXT_PROTOTYPES",
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
     ],
+    srcs: [
+        ":libgui_frame_event_aidl",
+        "src/*.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.graphics.bufferqueue@2.0",
+        "android.hidl.token@1.0-utils",
+        "libEGL",
+        "libGLESv2",
+        "libbase",
+        "libbinder_ndk",
+        "libbufferqueueconverter",
+        "libcamera_metadata",
+        "libhardware_legacy",
+        "libhidlbase",
+        "liblog",
+        "libnativewindow",
+        "libtinyxml2",
+        "libui",
+        "libutils",
+        "libyuv",
+    ],
+    static_libs: [
+        "android.frameworks.automotive.display-V1-ndk",
+        "android.hardware.automotive.evs-V2-ndk",
+        "android.hardware.common-V2-ndk",
+        "libaidlcommonsupport",
+        "libcutils",
+    ],
+    local_include_dirs: ["include"],
+    include_dirs: ["frameworks/native/include/"],
+    required: ["evs_mock_hal_configuration.xml"],
+}
+
+prebuilt_etc {
+    name: "evs_mock_hal_configuration.xml",
+    soc_specific: true,
+    src: "resources/evs_mock_configuration.xml",
+    sub_dir: "automotive/evs",
 }
diff --git a/automotive/evs/aidl/impl/default/evs-default-service.rc b/automotive/evs/aidl/impl/default/evs-default-service.rc
index ea8e689..3da41ff 100644
--- a/automotive/evs/aidl/impl/default/evs-default-service.rc
+++ b/automotive/evs/aidl/impl/default/evs-default-service.rc
@@ -1,5 +1,8 @@
 service vendor.evs-hal-default /vendor/bin/hw/android.hardware.automotive.evs-aidl-default-service
     class early_hal
-    user automotive_evs
-    group automotive_evs
+    priority -20
+    user graphics
+    group automotive_evs camera
+    onrestart restart cardisplayproxyd
+    onrestart restart evsmanagerd
     disabled
diff --git a/automotive/evs/aidl/impl/default/evs-default-service.xml b/automotive/evs/aidl/impl/default/evs-default-service.xml
deleted file mode 100644
index 96ff9f6..0000000
--- a/automotive/evs/aidl/impl/default/evs-default-service.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest version="1.0" type="device">
-    <hal format="aidl">
-        <name>android.hardware.automotive.evs</name>
-        <transport>hwbinder</transport>
-        <version>1</version>
-        <interface>
-            <name>IEvsEnumerator</name>
-            <instance>hw/0</instance>
-        </interface>
-    </hal>
-</manifest>
diff --git a/automotive/evs/aidl/impl/default/include/ConfigManager.h b/automotive/evs/aidl/impl/default/include/ConfigManager.h
new file mode 100644
index 0000000..1d5fe77
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/ConfigManager.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "ConfigManagerUtil.h"
+
+#include <aidl/android/hardware/automotive/evs/CameraParam.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <android-base/logging.h>
+#include <system/camera_metadata.h>
+
+#include <tinyxml2.h>
+
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+/*
+ * Please note that this is different from what is defined in
+ * libhardware/modules/camera/3_4/metadata/types.h; this has one additional
+ * field to store a framerate.
+ */
+typedef struct {
+    int id;
+    int width;
+    int height;
+    ::aidl::android::hardware::graphics::common::PixelFormat format;
+    int type;
+    int framerate;
+} StreamConfiguration;
+
+class ConfigManager final {
+  public:
+    static std::unique_ptr<ConfigManager> Create();
+    ConfigManager(const ConfigManager&) = delete;
+    ConfigManager& operator=(const ConfigManager&) = delete;
+
+    /* Camera device's capabilities and metadata */
+    class CameraInfo {
+      public:
+        CameraInfo() : characteristics(nullptr) {}
+
+        virtual ~CameraInfo();
+
+        /* Allocate memory for camera_metadata_t */
+        bool allocate(size_t entry_cap, size_t data_cap) {
+            if (characteristics != nullptr) {
+                LOG(ERROR) << "Camera metadata is already allocated";
+                return false;
+            }
+
+            characteristics = allocate_camera_metadata(entry_cap, data_cap);
+            return characteristics != nullptr;
+        }
+
+        /*
+         * List of supported controls that the primary client can program.
+         * Paraemters are stored with its valid range
+         */
+        std::unordered_map<::aidl::android::hardware::automotive::evs::CameraParam,
+                           std::tuple<int32_t, int32_t, int32_t>>
+                controls;
+
+        /*
+         * List of supported output stream configurations.
+         */
+        std::unordered_map<int32_t, StreamConfiguration> streamConfigurations;
+
+        /*
+         * Internal storage for camera metadata.  Each entry holds a pointer to
+         * data and number of elements
+         */
+        std::unordered_map<camera_metadata_tag_t, std::pair<void*, size_t>> cameraMetadata;
+
+        /* Camera module characteristics */
+        camera_metadata_t* characteristics;
+    };
+
+    class CameraGroupInfo : public CameraInfo {
+      public:
+        CameraGroupInfo() {}
+
+        /* ID of member camera devices */
+        std::unordered_set<std::string> devices;
+
+        /* The capture operation of member camera devices are synchronized */
+        int32_t synchronized = 0;
+    };
+
+    class SystemInfo {
+      public:
+        /* number of available cameras */
+        int32_t numCameras = 0;
+    };
+
+    class DisplayInfo {
+      public:
+        /*
+         * List of supported input stream configurations.
+         */
+        std::unordered_map<int32_t, StreamConfiguration> streamConfigurations;
+    };
+
+    /*
+     * Return system information
+     *
+     * @return SystemInfo
+     *         Constant reference of SystemInfo.
+     */
+    const SystemInfo& getSystemInfo() {
+        std::unique_lock<std::mutex> lock(mConfigLock);
+        mConfigCond.wait(lock, [this] { return mIsReady; });
+        return mSystemInfo;
+    }
+
+    /*
+     * Return a list of camera identifiers
+     *
+     * This function assumes that it is not being called frequently.
+     *
+     * @return std::vector<std::string>
+     *         A vector that contains unique camera device identifiers.
+     */
+    std::vector<std::string> getCameraIdList() {
+        std::unique_lock<std::mutex> lock(mConfigLock);
+        mConfigCond.wait(lock, [this] { return mIsReady; });
+
+        std::vector<std::string> aList;
+        aList.reserve(mCameraInfo.size());
+        for (auto&& v : mCameraInfo) {
+            aList.push_back(v.first);
+        }
+
+        return aList;
+    }
+
+    /*
+     * Return a list of camera group identifiers
+     *
+     * This function assumes that it is not being called frequently.
+     *
+     * @return std::vector<std::string>
+     *         A vector that contains unique camera device identifiers.
+     */
+    std::vector<std::string> getCameraGroupIdList() {
+        std::unique_lock<std::mutex> lock(mConfigLock);
+        mConfigCond.wait(lock, [this] { return mIsReady; });
+
+        std::vector<std::string> aList;
+        aList.reserve(mCameraGroups.size());
+        for (auto&& v : mCameraGroups) {
+            aList.push_back(v.first);
+        }
+
+        return aList;
+    }
+
+    /*
+     * Return a pointer to the camera group
+     *
+     * @return CameraGroup
+     *         A pointer to a camera group identified by a given id.
+     */
+    std::unique_ptr<CameraGroupInfo>& getCameraGroupInfo(const std::string& gid) {
+        std::unique_lock<std::mutex> lock(mConfigLock);
+        mConfigCond.wait(lock, [this] { return mIsReady; });
+
+        return mCameraGroups[gid];
+    }
+
+    /*
+     * Return a camera metadata
+     *
+     * @param  cameraId
+     *         Unique camera node identifier in string
+     *
+     * @return unique_ptr<CameraInfo>
+     *         A pointer to CameraInfo that is associated with a given camera
+     *         ID.  This returns a null pointer if this does not recognize a
+     *         given camera identifier.
+     */
+    std::unique_ptr<CameraInfo>& getCameraInfo(const std::string& cameraId) noexcept {
+        std::unique_lock<std::mutex> lock(mConfigLock);
+        mConfigCond.wait(lock, [this] { return mIsReady; });
+
+        return mCameraInfo[cameraId];
+    }
+
+    /*
+     * Tell whether the configuration data is ready to be used
+     *
+     * @return bool
+     *         True if configuration data is ready to be consumed.
+     */
+    bool isReady() const { return mIsReady; }
+
+  private:
+    /* Constructors */
+    ConfigManager() : mBinaryFilePath("") {}
+
+    static std::string_view sConfigDefaultPath;
+    static std::string_view sConfigOverridePath;
+
+    /* System configuration */
+    SystemInfo mSystemInfo;
+
+    /* Internal data structure for camera device information */
+    std::unordered_map<std::string, std::unique_ptr<CameraInfo>> mCameraInfo;
+
+    /* Internal data structure for camera device information */
+    std::unordered_map<std::string, std::unique_ptr<DisplayInfo>> mDisplayInfo;
+
+    /* Camera groups are stored in <groud id, CameraGroup> hash map */
+    std::unordered_map<std::string, std::unique_ptr<CameraGroupInfo>> mCameraGroups;
+
+    /*
+     * Camera positions are stored in <position, camera id set> hash map.
+     * The position must be one of front, rear, left, and right.
+     */
+    std::unordered_map<std::string, std::unordered_set<std::string>> mCameraPosition;
+
+    /* Configuration data lock */
+    mutable std::mutex mConfigLock;
+
+    /*
+     * This condition is signalled when it completes a configuration data
+     * preparation.
+     */
+    std::condition_variable mConfigCond;
+
+    /* A path to a binary configuration file */
+    const char* mBinaryFilePath;
+
+    /* Configuration data readiness */
+    bool mIsReady = false;
+
+    /*
+     * Parse a given EVS configuration file and store the information
+     * internally.
+     *
+     * @return bool
+     *         True if it completes parsing a file successfully.
+     */
+    bool readConfigDataFromXML() noexcept;
+
+    /*
+     * read the information of the vehicle
+     *
+     * @param  aSysElem
+     *         A pointer to "system" XML element.
+     */
+    void readSystemInfo(const tinyxml2::XMLElement* const aSysElem);
+
+    /*
+     * read the information of camera devices
+     *
+     * @param  aCameraElem
+     *         A pointer to "camera" XML element that may contain multiple
+     *         "device" elements.
+     */
+    void readCameraInfo(const tinyxml2::XMLElement* const aCameraElem);
+
+    /*
+     * read display device information
+     *
+     * @param  aDisplayElem
+     *         A pointer to "display" XML element that may contain multiple
+     *         "device" elements.
+     */
+    void readDisplayInfo(const tinyxml2::XMLElement* const aDisplayElem);
+
+    /*
+     * read camera device information
+     *
+     * @param  aCamera
+     *         A pointer to CameraInfo that will be completed by this
+     *         method.
+     *         aDeviceElem
+     *         A pointer to "device" XML element that contains camera module
+     *         capability info and its characteristics.
+     *
+     * @return bool
+     *         Return false upon any failure in reading and processing camera
+     *         device information.
+     */
+    bool readCameraDeviceInfo(CameraInfo* aCamera, const tinyxml2::XMLElement* aDeviceElem);
+
+    /*
+     * read camera metadata
+     *
+     * @param  aCapElem
+     *         A pointer to "cap" XML element.
+     * @param  aCamera
+     *         A pointer to CameraInfo that is being filled by this method.
+     * @param  dataSize
+     *         Required size of memory to store camera metadata found in this
+     *         method.  This is calculated in this method and returned to the
+     *         caller for camera_metadata allocation.
+     *
+     * @return size_t
+     *         Number of camera metadata entries
+     */
+    size_t readCameraCapabilities(const tinyxml2::XMLElement* const aCapElem, CameraInfo* aCamera,
+                                  size_t& dataSize);
+
+    /*
+     * read camera metadata
+     *
+     * @param  aParamElem
+     *         A pointer to "characteristics" XML element.
+     * @param  aCamera
+     *         A pointer to CameraInfo that is being filled by this method.
+     * @param  dataSize
+     *         Required size of memory to store camera metadata found in this
+     *         method.
+     *
+     * @return size_t
+     *         Number of camera metadata entries
+     */
+    size_t readCameraMetadata(const tinyxml2::XMLElement* const aParamElem, CameraInfo* aCamera,
+                              size_t& dataSize);
+
+    /*
+     * construct camera_metadata_t from camera capabilities and metadata
+     *
+     * @param  aCamera
+     *         A pointer to CameraInfo that is being filled by this method.
+     * @param  totalEntries
+     *         Number of camera metadata entries to be added.
+     * @param  totalDataSize
+     *         Sum of sizes of camera metadata entries to be added.
+     *
+     * @return bool
+     *         False if either it fails to allocate memory for camera metadata
+     *         or its size is not large enough to add all found camera metadata
+     *         entries.
+     */
+    bool constructCameraMetadata(CameraInfo* aCamera, const size_t totalEntries,
+                                 const size_t totalDataSize);
+
+    /*
+     * Read configuration data from the binary file
+     *
+     * @return bool
+     *         True if it succeeds to read configuration data from a binary
+     *         file.
+     */
+    bool readConfigDataFromBinary();
+
+    /*
+     * Store configuration data to the file
+     *
+     * @return bool
+     *         True if it succeeds to serialize mCameraInfo to the file.
+     */
+    bool writeConfigDataToBinary();
+
+    /*
+     * debugging method to print out all XML elements and their attributes in
+     * logcat message.
+     *
+     * @param  aNode
+     *         A pointer to the root XML element to navigate.
+     * @param  prefix
+     *         A prefix to XML string.
+     */
+    void printElementNames(const tinyxml2::XMLElement* aNode, const std::string& prefix = "") const;
+};
diff --git a/automotive/evs/aidl/impl/default/include/ConfigManagerUtil.h b/automotive/evs/aidl/impl/default/include/ConfigManagerUtil.h
new file mode 100644
index 0000000..32b50d3
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/ConfigManagerUtil.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/evs/CameraParam.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <android-base/macros.h>
+#include <system/camera_metadata.h>
+
+#include <string>
+#include <utility>
+
+class ConfigManagerUtil final {
+  public:
+    /**
+     * Convert a given string into V4L2_CID_*
+     */
+    static bool convertToEvsCameraParam(
+            const std::string& id,
+            ::aidl::android::hardware::automotive::evs::CameraParam& camParam);
+    /**
+     * Convert a given string into android.hardware.graphics.common.PixelFormat
+     */
+    static bool convertToPixelFormat(const std::string& in,
+                                     ::aidl::android::hardware::graphics::common::PixelFormat& out);
+    /**
+     * Convert a given string into corresponding camera metadata data tag defined in
+     * system/media/camera/include/system/camera_metadata_tags.h
+     */
+    static bool convertToMetadataTag(const char* name, camera_metadata_tag& aTag);
+    /**
+     * Convert a given string into a floating value array
+     */
+    static float* convertFloatArray(const char* sz, const char* vals, size_t& count,
+                                    const char delimiter = ',');
+    /**
+     * Trim a string
+     */
+    static std::string trimString(const std::string& src, const std::string& ws = " \n\r\t\f\v");
+
+    /**
+     * Convert a given string to corresponding camera capabilities
+     */
+    static bool convertToCameraCapability(
+            const char* name, camera_metadata_enum_android_request_available_capabilities_t& cap);
+
+    DISALLOW_IMPLICIT_CONSTRUCTORS(ConfigManagerUtil);
+};
diff --git a/automotive/evs/aidl/impl/default/include/DefaultEvsEnumerator.h b/automotive/evs/aidl/impl/default/include/DefaultEvsEnumerator.h
deleted file mode 100644
index 03a578d..0000000
--- a/automotive/evs/aidl/impl/default/include/DefaultEvsEnumerator.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef android_hardware_automotive_evs_aidl_impl_evshal_include_DefaultEvsHal_H_
-#define android_hardware_automotive_evs_aidl_impl_evshal_include_DefaultEvsHal_H_
-
-#include <aidl/android/hardware/automotive/evs/BnEvsEnumerator.h>
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-class DefaultEvsEnumerator final
-    : public ::aidl::android::hardware::automotive::evs::BnEvsEnumerator {
-    ::ndk::ScopedAStatus isHardware(bool* flag) override;
-    ::ndk::ScopedAStatus openCamera(
-            const std::string& cameraId,
-            const ::aidl::android::hardware::automotive::evs::Stream& streamConfig,
-            std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsCamera>* obj) override;
-    ::ndk::ScopedAStatus closeCamera(
-            const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsCamera>& obj)
-            override;
-    ::ndk::ScopedAStatus getCameraList(
-            std::vector<::aidl::android::hardware::automotive::evs::CameraDesc>* list) override;
-    ::ndk::ScopedAStatus getStreamList(
-            const ::aidl::android::hardware::automotive::evs::CameraDesc& desc,
-            std::vector<::aidl::android::hardware::automotive::evs::Stream>* _aidl_return) override;
-    ::ndk::ScopedAStatus openDisplay(
-            int32_t displayId,
-            std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsDisplay>* obj) override;
-    ::ndk::ScopedAStatus closeDisplay(
-            const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsDisplay>& obj)
-            override;
-    ::ndk::ScopedAStatus getDisplayIdList(std::vector<uint8_t>* list) override;
-    ::ndk::ScopedAStatus getDisplayState(
-            ::aidl::android::hardware::automotive::evs::DisplayState* state) override;
-    ::ndk::ScopedAStatus registerStatusCallback(
-            const std::shared_ptr<
-                    ::aidl::android::hardware::automotive::evs::IEvsEnumeratorStatusCallback>&
-                    callback) override;
-    ::ndk::ScopedAStatus openUltrasonicsArray(
-            const std::string& id,
-            std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsUltrasonicsArray>* obj)
-            override;
-    ::ndk::ScopedAStatus closeUltrasonicsArray(
-            const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsUltrasonicsArray>&
-                    arr) override;
-    ::ndk::ScopedAStatus getUltrasonicsArrayList(
-            std::vector<::aidl::android::hardware::automotive::evs::UltrasonicsArrayDesc>* list)
-            override;
-};
-
-}  // namespace aidl::android::hardware::automotive::evs::implementation
-
-#endif  // android_hardware_automotive_evs_aidl_impl_evshal_include_DefaultEvsHal_H_
diff --git a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
new file mode 100644
index 0000000..259c266
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "ConfigManager.h"
+#include "EvsGlDisplay.h"
+#include "EvsMockCamera.h"
+
+#include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
+#include <aidl/android/hardware/automotive/evs/BnEvsEnumerator.h>
+#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
+#include <aidl/android/hardware/automotive/evs/DeviceStatusType.h>
+#include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumeratorStatusCallback.h>
+#include <aidl/android/hardware/automotive/evs/Stream.h>
+#include <utils/Thread.h>
+
+#include <atomic>
+#include <mutex>
+#include <optional>
+#include <thread>
+#include <unordered_map>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+class EvsEnumerator final : public ::aidl::android::hardware::automotive::evs::BnEvsEnumerator {
+  public:
+    // Methods from ::aidl::android::hardware::automotive::evs::IEvsEnumerator
+    ndk::ScopedAStatus isHardware(bool* flag) override;
+    ndk::ScopedAStatus openCamera(const std::string& cameraId, const evs::Stream& streamConfig,
+                                  std::shared_ptr<evs::IEvsCamera>* obj) override;
+    ndk::ScopedAStatus closeCamera(const std::shared_ptr<evs::IEvsCamera>& obj) override;
+    ndk::ScopedAStatus getCameraList(std::vector<evs::CameraDesc>* _aidl_return) override;
+    ndk::ScopedAStatus getStreamList(const evs::CameraDesc& desc,
+                                     std::vector<evs::Stream>* _aidl_return) override;
+    ndk::ScopedAStatus openDisplay(int32_t displayId,
+                                   std::shared_ptr<evs::IEvsDisplay>* obj) override;
+    ndk::ScopedAStatus closeDisplay(const std::shared_ptr<evs::IEvsDisplay>& obj) override;
+    ndk::ScopedAStatus getDisplayIdList(std::vector<uint8_t>* list) override;
+    ndk::ScopedAStatus getDisplayState(evs::DisplayState* state) override;
+    ndk::ScopedAStatus getDisplayStateById(int32_t displayId, evs::DisplayState* state) override;
+    ndk::ScopedAStatus registerStatusCallback(
+            const std::shared_ptr<evs::IEvsEnumeratorStatusCallback>& callback) override;
+    ndk::ScopedAStatus openUltrasonicsArray(
+            const std::string& id, std::shared_ptr<evs::IEvsUltrasonicsArray>* obj) override;
+    ndk::ScopedAStatus closeUltrasonicsArray(
+            const std::shared_ptr<evs::IEvsUltrasonicsArray>& obj) override;
+    ndk::ScopedAStatus getUltrasonicsArrayList(
+            std::vector<evs::UltrasonicsArrayDesc>* list) override;
+
+    // Implementation details
+    EvsEnumerator(const std::shared_ptr<
+                  ::aidl::android::frameworks::automotive::display::ICarDisplayProxy>&
+                          proxyService);
+
+    void notifyDeviceStatusChange(const std::string_view& deviceName, evs::DeviceStatusType type);
+
+  private:
+    struct CameraRecord {
+        evs::CameraDesc desc;
+        std::weak_ptr<EvsMockCamera> activeInstance;
+
+        CameraRecord(const char* cameraId) : desc() { desc.id = cameraId; }
+    };
+
+    class ActiveDisplays {
+      public:
+        struct DisplayInfo {
+            int32_t id{-1};
+            std::weak_ptr<EvsGlDisplay> displayWeak;
+            uintptr_t internalDisplayRawAddr;
+        };
+
+        std::optional<DisplayInfo> popDisplay(int32_t id);
+
+        std::optional<DisplayInfo> popDisplay(const std::shared_ptr<IEvsDisplay>& display);
+
+        std::unordered_map<int32_t, DisplayInfo> getAllDisplays();
+
+        bool tryInsert(int32_t id, const std::shared_ptr<EvsGlDisplay>& display);
+
+      private:
+        std::mutex mMutex;
+        std::unordered_map<int32_t, DisplayInfo> mIdToDisplay GUARDED_BY(mMutex);
+        std::unordered_map<uintptr_t, int32_t> mDisplayToId GUARDED_BY(mMutex);
+    };
+
+    bool checkPermission();
+    void closeCamera_impl(const std::shared_ptr<evs::IEvsCamera>& pCamera,
+                          const std::string& cameraId);
+    ndk::ScopedAStatus getDisplayStateImpl(std::optional<int32_t> displayId,
+                                           evs::DisplayState* state);
+
+    static bool qualifyCaptureDevice(const char* deviceName);
+    static CameraRecord* findCameraById(const std::string& cameraId);
+    static void enumerateCameras();
+    static bool addCaptureDevice(const std::string& deviceName);
+    static bool removeCaptureDevice(const std::string& deviceName);
+    // Enumerate available displays and return an id of the internal display
+    static uint64_t enumerateDisplays();
+
+    static ActiveDisplays& mutableActiveDisplays();
+
+    // NOTE:  All members values are static so that all clients operate on the same state
+    //        That is to say, this is effectively a singleton despite the fact that HIDL
+    //        constructs a new instance for each client.
+    //        Because our server has a single thread in the thread pool, these values are
+    //        never accessed concurrently despite potentially having multiple instance objects
+    //        using them.
+    static std::unordered_map<std::string, CameraRecord> sCameraList;
+    // Object destructs if client dies.
+    static std::mutex sLock;                               // Mutex on shared camera device list.
+    static std::condition_variable sCameraSignal;          // Signal on camera device addition.
+    static std::unique_ptr<ConfigManager> sConfigManager;  // ConfigManager
+    static std::shared_ptr<::aidl::android::frameworks::automotive::display::ICarDisplayProxy>
+            sDisplayProxy;
+    static std::unordered_map<uint8_t, uint64_t> sDisplayPortList;
+
+    uint64_t mInternalDisplayId;
+    std::shared_ptr<evs::IEvsEnumeratorStatusCallback> mCallback;
+};
+
+}  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h b/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h
new file mode 100644
index 0000000..ceabd9e
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "GlWrapper.h"
+
+#include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
+#include <aidl/android/hardware/automotive/evs/BnEvsDisplay.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/DisplayDesc.h>
+#include <aidl/android/hardware/automotive/evs/DisplayState.h>
+
+#include <thread>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+class EvsGlDisplay final : public BnEvsDisplay {
+  public:
+    // Methods from ::aidl::android::hardware::automotive::evs::IEvsDisplay
+    // follow.
+    ndk::ScopedAStatus getDisplayInfo(evs::DisplayDesc* _aidl_return) override;
+    ndk::ScopedAStatus getDisplayState(evs::DisplayState* _aidl_return) override;
+    ndk::ScopedAStatus getTargetBuffer(evs::BufferDesc* _aidl_return) override;
+    ndk::ScopedAStatus returnTargetBufferForDisplay(const evs::BufferDesc& buffer) override;
+    ndk::ScopedAStatus setDisplayState(evs::DisplayState state) override;
+
+    // Implementation details
+    EvsGlDisplay(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& service,
+                 uint64_t displayId);
+    virtual ~EvsGlDisplay() override;
+
+    // This gets called if another caller "steals" ownership of the display
+    void forceShutdown();
+
+  private:
+    // A graphics buffer into which we'll store images.  This member variable
+    // will be protected by semaphores.
+    struct BufferRecord {
+        ::aidl::android::hardware::graphics::common::HardwareBufferDescription description;
+        buffer_handle_t handle;
+        int fingerprint;
+    } mBuffer;
+
+    // State of a rendering thread
+    enum RenderThreadStates {
+        STOPPED = 0,
+        STOPPING = 1,
+        RUN = 2,
+    };
+
+    uint64_t mDisplayId;
+    evs::DisplayDesc mInfo;
+    evs::DisplayState mRequestedState GUARDED_BY(mLock) = evs::DisplayState::NOT_VISIBLE;
+    std::shared_ptr<automotivedisplay::ICarDisplayProxy> mDisplayProxy;
+
+    GlWrapper mGlWrapper;
+    mutable std::mutex mLock;
+
+    // This tells us whether or not our buffer is in use.  Protected by
+    // semaphores.
+    bool mBufferBusy = false;
+
+    // Variables to synchronize a rendering thread w/ main and binder threads
+    std::thread mRenderThread;
+    RenderThreadStates mState GUARDED_BY(mLock) = STOPPED;
+    bool mBufferReady = false;
+    void renderFrames();
+    bool initializeGlContextLocked() REQUIRES(mLock);
+
+    std::condition_variable mBufferReadyToUse;
+    std::condition_variable mBufferReadyToRender;
+    std::condition_variable mBufferDone;
+};
+
+}  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
new file mode 100644
index 0000000..7e010a2
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "ConfigManager.h"
+
+#include <aidl/android/hardware/automotive/evs/BnEvsCamera.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
+#include <aidl/android/hardware/automotive/evs/CameraParam.h>
+#include <aidl/android/hardware/automotive/evs/EvsResult.h>
+#include <aidl/android/hardware/automotive/evs/IEvsCameraStream.h>
+#include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
+#include <aidl/android/hardware/automotive/evs/ParameterRange.h>
+#include <aidl/android/hardware/automotive/evs/Stream.h>
+// #include <android-base/result.h>
+#include <android/hardware_buffer.h>
+#include <ui/GraphicBuffer.h>
+
+#include <functional>
+#include <thread>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+class EvsMockCamera : public evs::BnEvsCamera {
+    // This prevents constructors from direct access while it allows this class to
+    // be instantiated via ndk::SharedRefBase::make<>.
+  private:
+    struct Sigil {
+        explicit Sigil() = default;
+    };
+
+  public:
+    // Methods from ::android::hardware::automotive::evs::IEvsCamera follow.
+    ndk::ScopedAStatus doneWithFrame(const std::vector<evs::BufferDesc>& buffers) override;
+    ndk::ScopedAStatus forcePrimaryClient(
+            const std::shared_ptr<evs::IEvsDisplay>& display) override;
+    ndk::ScopedAStatus getCameraInfo(evs::CameraDesc* _aidl_return) override;
+    ndk::ScopedAStatus getExtendedInfo(int32_t opaqueIdentifier,
+                                       std::vector<uint8_t>* value) override;
+    ndk::ScopedAStatus getIntParameter(evs::CameraParam id, std::vector<int32_t>* value) override;
+    ndk::ScopedAStatus getIntParameterRange(evs::CameraParam id,
+                                            evs::ParameterRange* _aidl_return) override;
+    ndk::ScopedAStatus getParameterList(std::vector<evs::CameraParam>* _aidl_return) override;
+    ndk::ScopedAStatus getPhysicalCameraInfo(const std::string& deviceId,
+                                             evs::CameraDesc* _aidl_return) override;
+    ndk::ScopedAStatus importExternalBuffers(const std::vector<evs::BufferDesc>& buffers,
+                                             int32_t* _aidl_return) override;
+    ndk::ScopedAStatus pauseVideoStream() override;
+    ndk::ScopedAStatus resumeVideoStream() override;
+    ndk::ScopedAStatus setExtendedInfo(int32_t opaqueIdentifier,
+                                       const std::vector<uint8_t>& opaqueValue) override;
+    ndk::ScopedAStatus setIntParameter(evs::CameraParam id, int32_t value,
+                                       std::vector<int32_t>* effectiveValue) override;
+    ndk::ScopedAStatus setPrimaryClient() override;
+    ndk::ScopedAStatus setMaxFramesInFlight(int32_t bufferCount) override;
+    ndk::ScopedAStatus startVideoStream(
+            const std::shared_ptr<evs::IEvsCameraStream>& receiver) override;
+    ndk::ScopedAStatus stopVideoStream() override;
+    ndk::ScopedAStatus unsetPrimaryClient() override;
+
+    static std::shared_ptr<EvsMockCamera> Create(const char* deviceName);
+    static std::shared_ptr<EvsMockCamera> Create(
+            const char* deviceName, std::unique_ptr<ConfigManager::CameraInfo>& camInfo,
+            const evs::Stream* streamCfg = nullptr);
+    EvsMockCamera(const EvsMockCamera&) = delete;
+    EvsMockCamera& operator=(const EvsMockCamera&) = delete;
+
+    virtual ~EvsMockCamera() override;
+    void shutdown();
+
+    const evs::CameraDesc& getDesc() { return mDescription; }
+
+    // Constructors
+    EvsMockCamera(Sigil sigil, const char* deviceName,
+                  std::unique_ptr<ConfigManager::CameraInfo>& camInfo);
+
+  private:
+    // These three functions are expected to be called while mAccessLock is held
+    bool setAvailableFrames_Locked(unsigned bufferCount);
+    unsigned increaseAvailableFrames_Locked(unsigned numToAdd);
+    unsigned decreaseAvailableFrames_Locked(unsigned numToRemove);
+
+    void generateFrames();
+    void fillMockFrame(buffer_handle_t handle, const AHardwareBuffer_Desc* pDesc);
+    void returnBufferLocked(const uint32_t bufferId);
+    ndk::ScopedAStatus stopVideoStream_impl();
+
+    CameraDesc mDescription = {};  // The properties of this camera
+
+    std::thread mCaptureThread;  // The thread we'll use to synthesize frames
+
+    // The callback used to deliver each frame
+    std::shared_ptr<evs::IEvsCameraStream> mStream;
+
+    // Horizontal pixel count in the buffers
+    uint32_t mWidth = 0;
+    // Vertical pixel count in the buffers
+    uint32_t mHeight = 0;
+    // Values from android_pixel_format_t
+    uint32_t mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+    // Values from from Gralloc.h
+    uint64_t mUsage =
+            GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
+    // Bytes per line in the buffers
+    uint32_t mStride = 0;
+
+    struct BufferRecord {
+        buffer_handle_t handle;
+        bool inUse;
+
+        explicit BufferRecord(buffer_handle_t h) : handle(h), inUse(false){};
+    };
+
+    std::vector<BufferRecord> mBuffers;  // Graphics buffers to transfer images
+    unsigned mFramesAllowed;             // How many buffers are we currently using
+    unsigned mFramesInUse;               // How many buffers are currently outstanding
+
+    enum StreamStateValues {
+        STOPPED,
+        RUNNING,
+        STOPPING,
+        DEAD,
+    };
+    StreamStateValues mStreamState;
+
+    // Synchronization necessary to deconflict mCaptureThread from the main service thread
+    std::mutex mAccessLock;
+
+    // Static camera module information
+    std::unique_ptr<ConfigManager::CameraInfo>& mCameraInfo;
+
+    // For the extended info
+    std::unordered_map<uint32_t, std::vector<uint8_t>> mExtInfo;
+
+    // For the camera parameters.
+    struct CameraParameterDesc {
+        CameraParameterDesc(int min = 0, int max = 0, int step = 0, int value = 0) {
+            this->range.min = min;
+            this->range.max = max;
+            this->range.step = step;
+            this->value = value;
+        }
+
+        ParameterRange range;
+        int32_t value;
+    };
+    std::unordered_map<CameraParam, std::shared_ptr<CameraParameterDesc>> mParams;
+    void initializeParameters();
+};
+
+}  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/GlWrapper.h b/automotive/evs/aidl/impl/default/include/GlWrapper.h
new file mode 100644
index 0000000..adb250c
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/GlWrapper.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
+#include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <android-base/logging.h>
+#include <bufferqueueconverter/BufferQueueConverter.h>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+namespace automotivedisplay = ::aidl::android::frameworks::automotive::display;
+
+class GlWrapper {
+  public:
+    GlWrapper() : mSurfaceHolder(::android::SurfaceHolderUniquePtr(nullptr, nullptr)) {}
+    bool initialize(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
+                    uint64_t displayId);
+    void shutdown();
+
+    bool updateImageTexture(
+            buffer_handle_t handle,
+            const ::aidl::android::hardware::graphics::common::HardwareBufferDescription&
+                    description);
+    void renderImageToScreen();
+
+    void showWindow(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
+                    uint64_t displayId);
+    void hideWindow(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
+                    uint64_t displayId);
+
+    unsigned getWidth() { return mWidth; };
+    unsigned getHeight() { return mHeight; };
+
+  private:
+    ::android::sp<::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer>
+            mGfxBufferProducer;
+
+    EGLDisplay mDisplay;
+    EGLSurface mSurface;
+    EGLContext mContext;
+
+    unsigned mWidth = 0;
+    unsigned mHeight = 0;
+
+    EGLImageKHR mKHRimage = EGL_NO_IMAGE_KHR;
+
+    GLuint mTextureMap = 0;
+    GLuint mShaderProgram = 0;
+
+    // Opaque handle for a native hardware buffer defined in
+    // frameworks/native/opengl/include/EGL/eglplatform.h
+    ANativeWindow* mWindow;
+
+    // Pointer to a Surface wrapper.
+    ::android::SurfaceHolderUniquePtr mSurfaceHolder;
+};
+
+}  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml b/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml
new file mode 100644
index 0000000..50692f7
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.evs</name>
+        <fqname>IEvsEnumerator/hw/0</fqname>
+        <version>1</version>
+    </hal>
+</manifest>
diff --git a/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml b/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml
new file mode 100644
index 0000000..6cbc18e
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml
@@ -0,0 +1,68 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Exterior View System Example Configuration
+
+     Android Automotive axes are used to define coordinates.
+     See https://source.android.com/devices/sensors/sensor-types#auto_axes
+
+     Use evs_configuration.dtd with xmllint tool, to validate XML configuration file
+-->
+
+<configuration>
+    <!-- system configuration -->
+    <system>
+        <!-- number of cameras available to EVS -->
+        <num_cameras value='1'/>
+    </system>
+
+    <!-- camera information -->
+    <camera>
+        <!-- camera device starts -->
+        <device id='/dev/video10' position='rear'>
+            <caps>
+                <!-- list of supported controls -->
+                <supported_controls>
+                    <control name='BRIGHTNESS' min='0' max='255'/>
+                    <control name='CONTRAST' min='0' max='255'/>
+                </supported_controls>
+
+                <stream id='0' width='640'  height='360'  format='RGBA_8888' framerate='30'/>
+            </caps>
+
+            <!-- list of parameters -->
+            <characteristics>
+                <!-- Camera intrinsic calibration matrix. See
+                     https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#LENS_INTRINSIC_CALIBRATION
+                -->
+                <parameter
+                    name='LENS_INTRINSIC_CALIBRATION'
+                    type='float'
+                    size='5'
+                    value='0.0,0.0,0.0,0.0,0.0'
+                />
+            </characteristics>
+        </device>
+    </camera>
+    <display>
+        <device id='display0' position='driver'>
+            <caps>
+                <!-- list of supported inpu stream configurations -->
+                <stream id='0' width='1280' height='720' format='RGBA_8888' framerate='30'/>
+            </caps>
+        </device>
+    </display>
+</configuration>
+
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
new file mode 100644
index 0000000..da791ed
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
@@ -0,0 +1,992 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ConfigManager.h"
+
+#include <android-base/parseint.h>
+#include <hardware/gralloc.h>
+#include <utils/SystemClock.h>
+
+#include <fstream>
+#include <sstream>
+#include <string_view>
+#include <thread>
+
+namespace {
+
+using ::aidl::android::hardware::automotive::evs::CameraParam;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+using ::tinyxml2::XMLAttribute;
+using ::tinyxml2::XMLDocument;
+using ::tinyxml2::XMLElement;
+
+}  // namespace
+
+std::string_view ConfigManager::sConfigDefaultPath =
+        "/vendor/etc/automotive/evs/evs_mock_hal_configuration.xml";
+std::string_view ConfigManager::sConfigOverridePath =
+        "/vendor/etc/automotive/evs/evs_configuration_override.xml";
+
+void ConfigManager::printElementNames(const XMLElement* rootElem, const std::string& prefix) const {
+    const XMLElement* curElem = rootElem;
+
+    while (curElem != nullptr) {
+        LOG(VERBOSE) << "[ELEM] " << prefix << curElem->Name();
+        const XMLAttribute* curAttr = curElem->FirstAttribute();
+        while (curAttr) {
+            LOG(VERBOSE) << "[ATTR] " << prefix << curAttr->Name() << ": " << curAttr->Value();
+            curAttr = curAttr->Next();
+        }
+
+        /* recursively go down to descendants */
+        printElementNames(curElem->FirstChildElement(), prefix + "\t");
+
+        curElem = curElem->NextSiblingElement();
+    }
+}
+
+void ConfigManager::readCameraInfo(const XMLElement* const aCameraElem) {
+    if (aCameraElem == nullptr) {
+        LOG(WARNING) << "XML file does not have required camera element";
+        return;
+    }
+
+    const XMLElement* curElem = aCameraElem->FirstChildElement();
+    while (curElem != nullptr) {
+        if (!strcmp(curElem->Name(), "group")) {
+            /* camera group identifier */
+            const char* id = curElem->FindAttribute("id")->Value();
+
+            /* create a camera group to be filled */
+            CameraGroupInfo* aCamera = new CameraGroupInfo();
+
+            /* read camera device information */
+            if (!readCameraDeviceInfo(aCamera, curElem)) {
+                LOG(WARNING) << "Failed to read a camera information of " << id;
+                delete aCamera;
+                continue;
+            }
+
+            /* camera group synchronization */
+            const char* sync = curElem->FindAttribute("synchronized")->Value();
+            if (!strcmp(sync, "CALIBRATED")) {
+                aCamera->synchronized = ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED;
+            } else if (!strcmp(sync, "APPROXIMATE")) {
+                aCamera->synchronized = ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE;
+            } else {
+                aCamera->synchronized = 0;  // Not synchronized
+            }
+
+            /* add a group to hash map */
+            mCameraGroups.insert_or_assign(id, std::unique_ptr<CameraGroupInfo>(aCamera));
+        } else if (!std::strcmp(curElem->Name(), "device")) {
+            /* camera unique identifier */
+            const char* id = curElem->FindAttribute("id")->Value();
+
+            /* camera mount location */
+            const char* pos = curElem->FindAttribute("position")->Value();
+
+            /* create a camera device to be filled */
+            CameraInfo* aCamera = new CameraInfo();
+
+            /* read camera device information */
+            if (!readCameraDeviceInfo(aCamera, curElem)) {
+                LOG(WARNING) << "Failed to read a camera information of " << id;
+                delete aCamera;
+                continue;
+            }
+
+            /* store read camera module information */
+            mCameraInfo.insert_or_assign(id, std::unique_ptr<CameraInfo>(aCamera));
+
+            /* assign a camera device to a position group */
+            mCameraPosition[pos].insert(id);
+        } else {
+            /* ignore other device types */
+            LOG(DEBUG) << "Unknown element " << curElem->Name() << " is ignored";
+        }
+
+        curElem = curElem->NextSiblingElement();
+    }
+}
+
+bool ConfigManager::readCameraDeviceInfo(CameraInfo* aCamera, const XMLElement* aDeviceElem) {
+    if (aCamera == nullptr || aDeviceElem == nullptr) {
+        return false;
+    }
+
+    /* size information to allocate camera_metadata_t */
+    size_t totalEntries = 0;
+    size_t totalDataSize = 0;
+
+    /* read device capabilities */
+    totalEntries +=
+            readCameraCapabilities(aDeviceElem->FirstChildElement("caps"), aCamera, totalDataSize);
+
+    /* read camera metadata */
+    totalEntries += readCameraMetadata(aDeviceElem->FirstChildElement("characteristics"), aCamera,
+                                       totalDataSize);
+
+    /* construct camera_metadata_t */
+    if (!constructCameraMetadata(aCamera, totalEntries, totalDataSize)) {
+        LOG(WARNING) << "Either failed to allocate memory or "
+                     << "allocated memory was not large enough";
+    }
+
+    return true;
+}
+
+size_t ConfigManager::readCameraCapabilities(const XMLElement* const aCapElem, CameraInfo* aCamera,
+                                             size_t& dataSize) {
+    if (aCapElem == nullptr || aCamera == nullptr) {
+        return 0;
+    }
+
+    std::string token;
+    const XMLElement* curElem = nullptr;
+
+    /* a list of supported camera parameters/controls */
+    curElem = aCapElem->FirstChildElement("supported_controls");
+    if (curElem != nullptr) {
+        const XMLElement* ctrlElem = curElem->FirstChildElement("control");
+        while (ctrlElem != nullptr) {
+            const char* nameAttr = ctrlElem->FindAttribute("name")->Value();
+            int32_t minVal = INT32_MIN, maxVal = INT32_MAX;
+            if (!android::base::ParseInt(ctrlElem->FindAttribute("min")->Value(), &minVal)) {
+                LOG(WARNING) << "Failed to parse " << ctrlElem->FindAttribute("min")->Value();
+            }
+
+            if (!android::base::ParseInt(ctrlElem->FindAttribute("max")->Value(), &maxVal)) {
+                LOG(WARNING) << "Failed to parse " << ctrlElem->FindAttribute("max")->Value();
+            }
+
+            int32_t stepVal = 1;
+            const XMLAttribute* stepAttr = ctrlElem->FindAttribute("step");
+            if (stepAttr != nullptr) {
+                if (!android::base::ParseInt(stepAttr->Value(), &stepVal)) {
+                    LOG(WARNING) << "Failed to parse " << stepAttr->Value();
+                }
+            }
+
+            CameraParam aParam;
+            if (ConfigManagerUtil::convertToEvsCameraParam(nameAttr, aParam)) {
+                aCamera->controls.insert_or_assign(
+                        aParam, std::move(std::make_tuple(minVal, maxVal, stepVal)));
+            }
+
+            ctrlElem = ctrlElem->NextSiblingElement("control");
+        }
+    }
+
+    /* a list of camera stream configurations */
+    curElem = aCapElem->FirstChildElement("stream");
+    while (curElem != nullptr) {
+        /* read 5 attributes */
+        const XMLAttribute* idAttr = curElem->FindAttribute("id");
+        const XMLAttribute* widthAttr = curElem->FindAttribute("width");
+        const XMLAttribute* heightAttr = curElem->FindAttribute("height");
+        const XMLAttribute* fmtAttr = curElem->FindAttribute("format");
+        const XMLAttribute* fpsAttr = curElem->FindAttribute("framerate");
+
+        int32_t id = -1;
+        int32_t framerate = 0;
+        if (!android::base::ParseInt(idAttr->Value(), &id)) {
+            LOG(WARNING) << "Failed to parse " << idAttr->Value();
+        }
+        if (fpsAttr != nullptr) {
+            if (!android::base::ParseInt(fpsAttr->Value(), &framerate)) {
+                LOG(WARNING) << "Failed to parse " << fpsAttr->Value();
+            }
+        }
+
+        PixelFormat format = PixelFormat::UNSPECIFIED;
+        if (ConfigManagerUtil::convertToPixelFormat(fmtAttr->Value(), format)) {
+            StreamConfiguration cfg = {
+                    .id = id,
+                    .format = format,
+                    .type = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+                    .framerate = framerate,
+            };
+
+            if (!android::base::ParseInt(widthAttr->Value(), &cfg.width) ||
+                !android::base::ParseInt(heightAttr->Value(), &cfg.height)) {
+                LOG(WARNING) << "Failed to parse " << widthAttr->Value() << " and "
+                             << heightAttr->Value();
+            }
+            aCamera->streamConfigurations.insert_or_assign(id, cfg);
+        }
+
+        curElem = curElem->NextSiblingElement("stream");
+    }
+
+    dataSize = calculate_camera_metadata_entry_data_size(
+            get_camera_metadata_tag_type(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS),
+            aCamera->streamConfigurations.size() * sizeof(StreamConfiguration));
+
+    /* a single camera metadata entry contains multiple stream configurations */
+    return dataSize > 0 ? 1 : 0;
+}
+
+size_t ConfigManager::readCameraMetadata(const XMLElement* const aParamElem, CameraInfo* aCamera,
+                                         size_t& dataSize) {
+    if (aParamElem == nullptr || aCamera == nullptr) {
+        return 0;
+    }
+
+    const XMLElement* curElem = aParamElem->FirstChildElement("parameter");
+    size_t numEntries = 0;
+    camera_metadata_tag_t tag;
+    while (curElem != nullptr) {
+        if (ConfigManagerUtil::convertToMetadataTag(curElem->FindAttribute("name")->Value(), tag)) {
+            switch (tag) {
+                case ANDROID_LENS_DISTORTION:
+                case ANDROID_LENS_POSE_ROTATION:
+                case ANDROID_LENS_POSE_TRANSLATION:
+                case ANDROID_LENS_INTRINSIC_CALIBRATION: {
+                    /* float[] */
+                    size_t count = 0;
+                    void* data = ConfigManagerUtil::convertFloatArray(
+                            curElem->FindAttribute("size")->Value(),
+                            curElem->FindAttribute("value")->Value(), count);
+
+                    aCamera->cameraMetadata.insert_or_assign(tag, std::make_pair(data, count));
+
+                    ++numEntries;
+                    dataSize += calculate_camera_metadata_entry_data_size(
+                            get_camera_metadata_tag_type(tag), count);
+
+                    break;
+                }
+
+                case ANDROID_REQUEST_AVAILABLE_CAPABILITIES: {
+                    camera_metadata_enum_android_request_available_capabilities_t* data =
+                            new camera_metadata_enum_android_request_available_capabilities_t[1];
+                    if (ConfigManagerUtil::convertToCameraCapability(
+                                curElem->FindAttribute("value")->Value(), *data)) {
+                        aCamera->cameraMetadata.insert_or_assign(tag,
+                                                                 std::make_pair((void*)data, 1));
+
+                        ++numEntries;
+                        dataSize += calculate_camera_metadata_entry_data_size(
+                                get_camera_metadata_tag_type(tag), 1);
+                    }
+                    break;
+                }
+
+                case ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS: {
+                    /* a comma-separated list of physical camera devices */
+                    size_t len = strlen(curElem->FindAttribute("value")->Value());
+                    char* data = new char[len + 1];
+                    memcpy(data, curElem->FindAttribute("value")->Value(), len * sizeof(char));
+
+                    /* replace commas with null char */
+                    char* p = data;
+                    while (*p != '\0') {
+                        if (*p == ',') {
+                            *p = '\0';
+                        }
+                        ++p;
+                    }
+
+                    aCamera->cameraMetadata.insert_or_assign(tag,
+                                                             std::make_pair((void*)data, len + 1));
+
+                    ++numEntries;
+                    dataSize += calculate_camera_metadata_entry_data_size(
+                            get_camera_metadata_tag_type(tag), len);
+                    break;
+                }
+
+                /* TODO(b/140416878): add vendor-defined/custom tag support */
+                default:
+                    LOG(WARNING) << "Parameter " << curElem->FindAttribute("name")->Value()
+                                 << " is not supported";
+                    break;
+            }
+        } else {
+            LOG(WARNING) << "Unsupported metadata tag " << curElem->FindAttribute("name")->Value()
+                         << " is found.";
+        }
+
+        curElem = curElem->NextSiblingElement("parameter");
+    }
+
+    return numEntries;
+}
+
+bool ConfigManager::constructCameraMetadata(CameraInfo* aCamera, size_t totalEntries,
+                                            size_t totalDataSize) {
+    if (aCamera == nullptr || !aCamera->allocate(totalEntries, totalDataSize)) {
+        LOG(ERROR) << "Failed to allocate memory for camera metadata";
+        return false;
+    }
+
+    const size_t numStreamConfigs = aCamera->streamConfigurations.size();
+    std::unique_ptr<int32_t[]> data(new int32_t[sizeof(StreamConfiguration) * numStreamConfigs]);
+    int32_t* ptr = data.get();
+    for (auto& cfg : aCamera->streamConfigurations) {
+        memcpy(ptr, &cfg.second, sizeof(StreamConfiguration));
+        ptr += sizeof(StreamConfiguration);
+    }
+    int32_t err = add_camera_metadata_entry(
+            aCamera->characteristics, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, data.get(),
+            numStreamConfigs * sizeof(StreamConfiguration));
+
+    if (err) {
+        LOG(ERROR) << "Failed to add stream configurations to metadata, ignored";
+        return false;
+    }
+
+    bool success = true;
+    for (auto& [tag, entry] : aCamera->cameraMetadata) {
+        /* try to add new camera metadata entry */
+        int32_t err =
+                add_camera_metadata_entry(aCamera->characteristics, tag, entry.first, entry.second);
+        if (err) {
+            LOG(ERROR) << "Failed to add an entry with a tag, " << std::hex << tag;
+
+            /* may exceed preallocated capacity */
+            LOG(ERROR) << "Camera metadata has "
+                       << get_camera_metadata_entry_count(aCamera->characteristics) << " / "
+                       << get_camera_metadata_entry_capacity(aCamera->characteristics)
+                       << " entries and "
+                       << get_camera_metadata_data_count(aCamera->characteristics) << " / "
+                       << get_camera_metadata_data_capacity(aCamera->characteristics)
+                       << " bytes are filled.";
+            LOG(ERROR) << "\tCurrent metadata entry requires "
+                       << calculate_camera_metadata_entry_data_size(tag, entry.second) << " bytes.";
+
+            success = false;
+        }
+    }
+
+    LOG(VERBOSE) << "Camera metadata has "
+                 << get_camera_metadata_entry_count(aCamera->characteristics) << " / "
+                 << get_camera_metadata_entry_capacity(aCamera->characteristics) << " entries and "
+                 << get_camera_metadata_data_count(aCamera->characteristics) << " / "
+                 << get_camera_metadata_data_capacity(aCamera->characteristics)
+                 << " bytes are filled.";
+    return success;
+}
+
+void ConfigManager::readSystemInfo(const XMLElement* const aSysElem) {
+    if (aSysElem == nullptr) {
+        return;
+    }
+
+    /*
+     * Please note that this function assumes that a given system XML element
+     * and its child elements follow DTD.  If it does not, it will cause a
+     * segmentation fault due to the failure of finding expected attributes.
+     */
+
+    /* read number of cameras available in the system */
+    const XMLElement* xmlElem = aSysElem->FirstChildElement("num_cameras");
+    if (xmlElem != nullptr) {
+        if (!android::base::ParseInt(xmlElem->FindAttribute("value")->Value(),
+                                     &mSystemInfo.numCameras)) {
+            LOG(WARNING) << "Failed to parse " << xmlElem->FindAttribute("value")->Value();
+        }
+    }
+}
+
+void ConfigManager::readDisplayInfo(const XMLElement* const aDisplayElem) {
+    if (aDisplayElem == nullptr) {
+        LOG(WARNING) << "XML file does not have required camera element";
+        return;
+    }
+
+    const XMLElement* curDev = aDisplayElem->FirstChildElement("device");
+    while (curDev != nullptr) {
+        const char* id = curDev->FindAttribute("id")->Value();
+        std::unique_ptr<DisplayInfo> dpy(new DisplayInfo());
+        if (dpy == nullptr) {
+            LOG(ERROR) << "Failed to allocate memory for DisplayInfo";
+            return;
+        }
+
+        const XMLElement* cap = curDev->FirstChildElement("caps");
+        if (cap != nullptr) {
+            const XMLElement* curStream = cap->FirstChildElement("stream");
+            while (curStream != nullptr) {
+                /* read 4 attributes */
+                const XMLAttribute* idAttr = curStream->FindAttribute("id");
+                const XMLAttribute* widthAttr = curStream->FindAttribute("width");
+                const XMLAttribute* heightAttr = curStream->FindAttribute("height");
+                const XMLAttribute* fmtAttr = curStream->FindAttribute("format");
+
+                int32_t id = -1;
+                if (!android::base::ParseInt(idAttr->Value(), &id)) {
+                    LOG(WARNING) << "Failed to parse " << idAttr->Value();
+                }
+                PixelFormat format = PixelFormat::UNSPECIFIED;
+                if (ConfigManagerUtil::convertToPixelFormat(fmtAttr->Value(), format)) {
+                    StreamConfiguration cfg = {
+                            .id = id,
+                            .format = format,
+                            .type = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT,
+                    };
+                    if (!android::base::ParseInt(widthAttr->Value(), &cfg.width) ||
+                        !android::base::ParseInt(heightAttr->Value(), &cfg.height)) {
+                        LOG(WARNING) << "Failed to parse " << widthAttr->Value() << " and "
+                                     << heightAttr->Value();
+                    }
+                    dpy->streamConfigurations.insert_or_assign(id, cfg);
+                }
+
+                curStream = curStream->NextSiblingElement("stream");
+            }
+        }
+
+        mDisplayInfo.insert_or_assign(id, std::move(dpy));
+        curDev = curDev->NextSiblingElement("device");
+    }
+
+    return;
+}
+
+bool ConfigManager::readConfigDataFromXML() noexcept {
+    XMLDocument xmlDoc;
+
+    const int64_t parsingStart = android::elapsedRealtimeNano();
+
+    /* load and parse a configuration file */
+    xmlDoc.LoadFile(sConfigOverridePath.data());
+    if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
+        xmlDoc.LoadFile(sConfigDefaultPath.data());
+        if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
+            LOG(ERROR) << "Failed to load and/or parse a configuration file, " << xmlDoc.ErrorStr();
+            return false;
+        }
+    }
+
+    /* retrieve the root element */
+    const XMLElement* rootElem = xmlDoc.RootElement();
+    if (std::strcmp(rootElem->Name(), "configuration") != 0) {
+        LOG(ERROR) << "A configuration file is not in the required format.  "
+                   << "See /etc/automotive/evs/evs_configuration.dtd";
+        return false;
+    }
+
+    std::unique_lock<std::mutex> lock(mConfigLock);
+
+    /*
+     * parse camera information; this needs to be done before reading system
+     * information
+     */
+    readCameraInfo(rootElem->FirstChildElement("camera"));
+
+    /* parse system information */
+    readSystemInfo(rootElem->FirstChildElement("system"));
+
+    /* parse display information */
+    readDisplayInfo(rootElem->FirstChildElement("display"));
+
+    /* configuration data is ready to be consumed */
+    mIsReady = true;
+
+    /* notify that configuration data is ready */
+    lock.unlock();
+    mConfigCond.notify_all();
+
+    const int64_t parsingEnd = android::elapsedRealtimeNano();
+    LOG(INFO) << "Parsing configuration file takes " << std::scientific
+              << (double)(parsingEnd - parsingStart) / 1000000.0 << " ms.";
+
+    return true;
+}
+
+bool ConfigManager::readConfigDataFromBinary() {
+    /* Temporary buffer to hold configuration data read from a binary file */
+    char mBuffer[1024];
+
+    std::fstream srcFile;
+    const int64_t readStart = android::elapsedRealtimeNano();
+
+    srcFile.open(mBinaryFilePath, std::fstream::in | std::fstream::binary);
+    if (!srcFile) {
+        LOG(ERROR) << "Failed to open a source binary file, " << mBinaryFilePath;
+        return false;
+    }
+
+    std::unique_lock<std::mutex> lock(mConfigLock);
+    mIsReady = false;
+
+    /* read configuration data into the internal buffer */
+    srcFile.read(mBuffer, sizeof(mBuffer));
+    LOG(VERBOSE) << __FUNCTION__ << ": " << srcFile.gcount() << " bytes are read.";
+    char* p = mBuffer;
+    size_t sz = 0;
+
+    /* read number of camera group information entries */
+    const size_t ngrps = *(reinterpret_cast<size_t*>(p));
+    p += sizeof(size_t);
+
+    /* read each camera information entry */
+    for (size_t cidx = 0; cidx < ngrps; ++cidx) {
+        /* read camera identifier */
+        std::string cameraId = *(reinterpret_cast<std::string*>(p));
+        p += sizeof(std::string);
+
+        /* size of camera_metadata_t */
+        const size_t num_entry = *(reinterpret_cast<size_t*>(p));
+        p += sizeof(size_t);
+        const size_t num_data = *(reinterpret_cast<size_t*>(p));
+        p += sizeof(size_t);
+
+        /* create CameraInfo and add it to hash map */
+        std::unique_ptr<ConfigManager::CameraGroupInfo> aCamera;
+        if (aCamera == nullptr || !aCamera->allocate(num_entry, num_data)) {
+            LOG(ERROR) << "Failed to create new CameraInfo object";
+            mCameraInfo.clear();
+            return false;
+        }
+
+        /* controls */
+        typedef struct {
+            CameraParam cid;
+            int32_t min;
+            int32_t max;
+            int32_t step;
+        } CameraCtrl;
+        sz = *(reinterpret_cast<size_t*>(p));
+        p += sizeof(size_t);
+        CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
+        for (size_t idx = 0; idx < sz; ++idx) {
+            CameraCtrl temp = *ptr++;
+            aCamera->controls.insert_or_assign(
+                    temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
+        }
+        p = reinterpret_cast<char*>(ptr);
+
+        /* stream configurations */
+        sz = *(reinterpret_cast<size_t*>(p));
+        p += sizeof(size_t);
+        int32_t* i32_ptr = reinterpret_cast<int32_t*>(p);
+        for (size_t idx = 0; idx < sz; ++idx) {
+            const int32_t id = *i32_ptr++;
+
+            StreamConfiguration temp;
+            memcpy(&temp, i32_ptr, sizeof(StreamConfiguration));
+            i32_ptr += sizeof(StreamConfiguration);
+            aCamera->streamConfigurations.insert_or_assign(id, temp);
+        }
+        p = reinterpret_cast<char*>(i32_ptr);
+
+        /* synchronization */
+        aCamera->synchronized = *(reinterpret_cast<int32_t*>(p));
+        p += sizeof(int32_t);
+
+        for (size_t idx = 0; idx < num_entry; ++idx) {
+            /* Read camera metadata entries */
+            camera_metadata_tag_t tag = *reinterpret_cast<camera_metadata_tag_t*>(p);
+            p += sizeof(camera_metadata_tag_t);
+            const size_t count = *reinterpret_cast<size_t*>(p);
+            p += sizeof(size_t);
+
+            const int32_t type = get_camera_metadata_tag_type(tag);
+            switch (type) {
+                case TYPE_BYTE: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(uint8_t);
+                    break;
+                }
+                case TYPE_INT32: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(int32_t);
+                    break;
+                }
+                case TYPE_FLOAT: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(float);
+                    break;
+                }
+                case TYPE_INT64: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(int64_t);
+                    break;
+                }
+                case TYPE_DOUBLE: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(double);
+                    break;
+                }
+                case TYPE_RATIONAL:
+                    p += count * sizeof(camera_metadata_rational_t);
+                    break;
+                default:
+                    LOG(WARNING) << "Type " << type << " is unknown; "
+                                 << "data may be corrupted.";
+                    break;
+            }
+        }
+
+        mCameraInfo.insert_or_assign(cameraId, std::move(aCamera));
+    }
+
+    /* read number of camera information entries */
+    const size_t ncams = *(reinterpret_cast<size_t*>(p));
+    p += sizeof(size_t);
+
+    /* read each camera information entry */
+    for (size_t cidx = 0; cidx < ncams; ++cidx) {
+        /* read camera identifier */
+        std::string cameraId = *(reinterpret_cast<std::string*>(p));
+        p += sizeof(std::string);
+
+        /* size of camera_metadata_t */
+        const size_t num_entry = *(reinterpret_cast<size_t*>(p));
+        p += sizeof(size_t);
+        const size_t num_data = *(reinterpret_cast<size_t*>(p));
+        p += sizeof(size_t);
+
+        /* create CameraInfo and add it to hash map */
+        std::unique_ptr<ConfigManager::CameraInfo> aCamera;
+        if (aCamera == nullptr || !aCamera->allocate(num_entry, num_data)) {
+            LOG(ERROR) << "Failed to create new CameraInfo object";
+            mCameraInfo.clear();
+            return false;
+        }
+
+        /* controls */
+        typedef struct {
+            CameraParam cid;
+            int32_t min;
+            int32_t max;
+            int32_t step;
+        } CameraCtrl;
+        sz = *(reinterpret_cast<size_t*>(p));
+        p += sizeof(size_t);
+        CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
+        for (size_t idx = 0; idx < sz; ++idx) {
+            CameraCtrl temp = *ptr++;
+            aCamera->controls.insert_or_assign(
+                    temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
+        }
+        p = reinterpret_cast<char*>(ptr);
+
+        /* stream configurations */
+        sz = *(reinterpret_cast<size_t*>(p));
+        p += sizeof(size_t);
+        int32_t* i32_ptr = reinterpret_cast<int32_t*>(p);
+        for (size_t idx = 0; idx < sz; ++idx) {
+            const int32_t id = *i32_ptr++;
+
+            StreamConfiguration temp;
+            memcpy(&temp, i32_ptr, sizeof(StreamConfiguration));
+            i32_ptr += sizeof(StreamConfiguration);
+            aCamera->streamConfigurations.insert_or_assign(id, temp);
+        }
+        p = reinterpret_cast<char*>(i32_ptr);
+
+        for (size_t idx = 0; idx < num_entry; ++idx) {
+            /* Read camera metadata entries */
+            camera_metadata_tag_t tag = *reinterpret_cast<camera_metadata_tag_t*>(p);
+            p += sizeof(camera_metadata_tag_t);
+            const size_t count = *reinterpret_cast<size_t*>(p);
+            p += sizeof(size_t);
+
+            const int32_t type = get_camera_metadata_tag_type(tag);
+            switch (type) {
+                case TYPE_BYTE: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(uint8_t);
+                    break;
+                }
+                case TYPE_INT32: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(int32_t);
+                    break;
+                }
+                case TYPE_FLOAT: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(float);
+                    break;
+                }
+                case TYPE_INT64: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(int64_t);
+                    break;
+                }
+                case TYPE_DOUBLE: {
+                    add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+                    p += count * sizeof(double);
+                    break;
+                }
+                case TYPE_RATIONAL:
+                    p += count * sizeof(camera_metadata_rational_t);
+                    break;
+                default:
+                    LOG(WARNING) << "Type " << type << " is unknown; "
+                                 << "data may be corrupted.";
+                    break;
+            }
+        }
+
+        mCameraInfo.insert_or_assign(cameraId, std::move(aCamera));
+    }
+
+    mIsReady = true;
+
+    /* notify that configuration data is ready */
+    lock.unlock();
+    mConfigCond.notify_all();
+
+    int64_t readEnd = android::elapsedRealtimeNano();
+    LOG(INFO) << __FUNCTION__ << " takes " << std::scientific
+              << (double)(readEnd - readStart) / 1000000.0 << " ms.";
+
+    return true;
+}
+
+bool ConfigManager::writeConfigDataToBinary() {
+    std::fstream outFile;
+
+    const int64_t writeStart = android::elapsedRealtimeNano();
+
+    outFile.open(mBinaryFilePath, std::fstream::out | std::fstream::binary);
+    if (!outFile) {
+        LOG(ERROR) << "Failed to open a destination binary file, " << mBinaryFilePath;
+        return false;
+    }
+
+    /* lock a configuration data while it's being written to the filesystem */
+    std::lock_guard<std::mutex> lock(mConfigLock);
+
+    /* write camera group information */
+    size_t sz = mCameraGroups.size();
+    outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+    for (auto&& [camId, camInfo] : mCameraGroups) {
+        LOG(INFO) << "Storing camera group " << camId;
+
+        /* write a camera identifier string */
+        outFile.write(reinterpret_cast<const char*>(&camId), sizeof(std::string));
+
+        /* controls */
+        sz = camInfo->controls.size();
+        outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+        for (auto&& [ctrl, range] : camInfo->controls) {
+            outFile.write(reinterpret_cast<const char*>(&ctrl), sizeof(CameraParam));
+            outFile.write(reinterpret_cast<const char*>(&std::get<0>(range)), sizeof(int32_t));
+            outFile.write(reinterpret_cast<const char*>(&std::get<1>(range)), sizeof(int32_t));
+            outFile.write(reinterpret_cast<const char*>(&std::get<2>(range)), sizeof(int32_t));
+        }
+
+        /* stream configurations */
+        sz = camInfo->streamConfigurations.size();
+        outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+        for (auto&& [sid, cfg] : camInfo->streamConfigurations) {
+            outFile.write(reinterpret_cast<const char*>(sid), sizeof(int32_t));
+            outFile.write(reinterpret_cast<const char*>(&cfg), sizeof(cfg));
+        }
+
+        /* synchronization */
+        outFile.write(reinterpret_cast<const char*>(&camInfo->synchronized), sizeof(int32_t));
+
+        /* size of camera_metadata_t */
+        size_t num_entry = 0;
+        size_t num_data = 0;
+        if (camInfo->characteristics != nullptr) {
+            num_entry = get_camera_metadata_entry_count(camInfo->characteristics);
+            num_data = get_camera_metadata_data_count(camInfo->characteristics);
+        }
+        outFile.write(reinterpret_cast<const char*>(&num_entry), sizeof(size_t));
+        outFile.write(reinterpret_cast<const char*>(&num_data), sizeof(size_t));
+
+        /* write each camera metadata entry */
+        if (num_entry > 0) {
+            camera_metadata_entry_t entry;
+            for (size_t idx = 0; idx < num_entry; ++idx) {
+                if (get_camera_metadata_entry(camInfo->characteristics, idx, &entry)) {
+                    LOG(ERROR) << "Failed to retrieve camera metadata entry " << idx;
+                    outFile.close();
+                    return false;
+                }
+
+                outFile.write(reinterpret_cast<const char*>(&entry.tag), sizeof(entry.tag));
+                outFile.write(reinterpret_cast<const char*>(&entry.count), sizeof(entry.count));
+
+                int32_t type = get_camera_metadata_tag_type(entry.tag);
+                switch (type) {
+                    case TYPE_BYTE:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.u8),
+                                      sizeof(uint8_t) * entry.count);
+                        break;
+                    case TYPE_INT32:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.i32),
+                                      sizeof(int32_t) * entry.count);
+                        break;
+                    case TYPE_FLOAT:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.f),
+                                      sizeof(float) * entry.count);
+                        break;
+                    case TYPE_INT64:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.i64),
+                                      sizeof(int64_t) * entry.count);
+                        break;
+                    case TYPE_DOUBLE:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.d),
+                                      sizeof(double) * entry.count);
+                        break;
+                    case TYPE_RATIONAL:
+                        [[fallthrough]];
+                    default:
+                        LOG(WARNING) << "Type " << type << " is not supported.";
+                        break;
+                }
+            }
+        }
+    }
+
+    /* write camera device information */
+    sz = mCameraInfo.size();
+    outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+    for (auto&& [camId, camInfo] : mCameraInfo) {
+        LOG(INFO) << "Storing camera " << camId;
+
+        /* write a camera identifier string */
+        outFile.write(reinterpret_cast<const char*>(&camId), sizeof(std::string));
+
+        /* controls */
+        sz = camInfo->controls.size();
+        outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+        for (auto& [ctrl, range] : camInfo->controls) {
+            outFile.write(reinterpret_cast<const char*>(&ctrl), sizeof(CameraParam));
+            outFile.write(reinterpret_cast<const char*>(&std::get<0>(range)), sizeof(int32_t));
+            outFile.write(reinterpret_cast<const char*>(&std::get<1>(range)), sizeof(int32_t));
+            outFile.write(reinterpret_cast<const char*>(&std::get<2>(range)), sizeof(int32_t));
+        }
+
+        /* stream configurations */
+        sz = camInfo->streamConfigurations.size();
+        outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+        for (auto&& [sid, cfg] : camInfo->streamConfigurations) {
+            outFile.write(reinterpret_cast<const char*>(sid), sizeof(int32_t));
+            outFile.write(reinterpret_cast<const char*>(&cfg), sizeof(cfg));
+        }
+
+        /* size of camera_metadata_t */
+        size_t num_entry = 0;
+        size_t num_data = 0;
+        if (camInfo->characteristics != nullptr) {
+            num_entry = get_camera_metadata_entry_count(camInfo->characteristics);
+            num_data = get_camera_metadata_data_count(camInfo->characteristics);
+        }
+        outFile.write(reinterpret_cast<const char*>(&num_entry), sizeof(size_t));
+        outFile.write(reinterpret_cast<const char*>(&num_data), sizeof(size_t));
+
+        /* write each camera metadata entry */
+        if (num_entry > 0) {
+            camera_metadata_entry_t entry;
+            for (size_t idx = 0; idx < num_entry; ++idx) {
+                if (get_camera_metadata_entry(camInfo->characteristics, idx, &entry)) {
+                    LOG(ERROR) << "Failed to retrieve camera metadata entry " << idx;
+                    outFile.close();
+                    return false;
+                }
+
+                outFile.write(reinterpret_cast<const char*>(&entry.tag), sizeof(entry.tag));
+                outFile.write(reinterpret_cast<const char*>(&entry.count), sizeof(entry.count));
+
+                int32_t type = get_camera_metadata_tag_type(entry.tag);
+                switch (type) {
+                    case TYPE_BYTE:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.u8),
+                                      sizeof(uint8_t) * entry.count);
+                        break;
+                    case TYPE_INT32:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.i32),
+                                      sizeof(int32_t) * entry.count);
+                        break;
+                    case TYPE_FLOAT:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.f),
+                                      sizeof(float) * entry.count);
+                        break;
+                    case TYPE_INT64:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.i64),
+                                      sizeof(int64_t) * entry.count);
+                        break;
+                    case TYPE_DOUBLE:
+                        outFile.write(reinterpret_cast<const char*>(entry.data.d),
+                                      sizeof(double) * entry.count);
+                        break;
+                    case TYPE_RATIONAL:
+                        [[fallthrough]];
+                    default:
+                        LOG(WARNING) << "Type " << type << " is not supported.";
+                        break;
+                }
+            }
+        }
+    }
+
+    outFile.close();
+    int64_t writeEnd = android::elapsedRealtimeNano();
+    LOG(INFO) << __FUNCTION__ << " takes " << std::scientific
+              << (double)(writeEnd - writeStart) / 1000000.0 << " ms.";
+
+    return true;
+}
+
+std::unique_ptr<ConfigManager> ConfigManager::Create() {
+    std::unique_ptr<ConfigManager> cfgMgr(new ConfigManager());
+
+    /*
+     * Read a configuration from XML file
+     *
+     * If this is too slow, ConfigManager::readConfigDataFromBinary() and
+     * ConfigManager::writeConfigDataToBinary()can serialize CameraInfo object
+     * to the filesystem and construct CameraInfo instead; this was
+     * evaluated as 10x faster.
+     */
+    if (!cfgMgr->readConfigDataFromXML()) {
+        return nullptr;
+    } else {
+        return cfgMgr;
+    }
+}
+
+ConfigManager::CameraInfo::~CameraInfo() {
+    free_camera_metadata(characteristics);
+
+    for (auto&& [tag, val] : cameraMetadata) {
+        switch (tag) {
+            case ANDROID_LENS_DISTORTION:
+            case ANDROID_LENS_POSE_ROTATION:
+            case ANDROID_LENS_POSE_TRANSLATION:
+            case ANDROID_LENS_INTRINSIC_CALIBRATION: {
+                delete[] reinterpret_cast<float*>(val.first);
+                break;
+            }
+
+            case ANDROID_REQUEST_AVAILABLE_CAPABILITIES: {
+                delete[] reinterpret_cast<
+                        camera_metadata_enum_android_request_available_capabilities_t*>(val.first);
+                break;
+            }
+
+            case ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS: {
+                delete[] reinterpret_cast<char*>(val.first);
+                break;
+            }
+
+            default:
+                LOG(WARNING) << "Tag " << std::hex << tag << " is not supported.  "
+                             << "Data may be corrupted?";
+                break;
+        }
+    }
+}
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManagerUtil.cpp b/automotive/evs/aidl/impl/default/src/ConfigManagerUtil.cpp
new file mode 100644
index 0000000..e5fe6ef
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/ConfigManagerUtil.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ConfigManagerUtil.h"
+
+#include <android-base/logging.h>
+#include <android-base/parsedouble.h>
+#include <android-base/parseint.h>
+#include <linux/videodev2.h>
+
+#include <sstream>
+#include <string>
+
+#include <system/graphics-base-v1.0.h>
+
+using ::aidl::android::hardware::automotive::evs::CameraParam;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+
+bool ConfigManagerUtil::convertToEvsCameraParam(const std::string& id, CameraParam& camParam) {
+    std::string trimmed = ConfigManagerUtil::trimString(id);
+    bool success = true;
+
+    if (!trimmed.compare("BRIGHTNESS")) {
+        camParam = CameraParam::BRIGHTNESS;
+    } else if (!trimmed.compare("CONTRAST")) {
+        camParam = CameraParam::CONTRAST;
+    } else if (!trimmed.compare("AUTOGAIN")) {
+        camParam = CameraParam::AUTOGAIN;
+    } else if (!trimmed.compare("GAIN")) {
+        camParam = CameraParam::GAIN;
+    } else if (!trimmed.compare("AUTO_WHITE_BALANCE")) {
+        camParam = CameraParam::AUTO_WHITE_BALANCE;
+    } else if (!trimmed.compare("WHITE_BALANCE_TEMPERATURE")) {
+        camParam = CameraParam::WHITE_BALANCE_TEMPERATURE;
+    } else if (!trimmed.compare("SHARPNESS")) {
+        camParam = CameraParam::SHARPNESS;
+    } else if (!trimmed.compare("AUTO_EXPOSURE")) {
+        camParam = CameraParam::AUTO_EXPOSURE;
+    } else if (!trimmed.compare("ABSOLUTE_EXPOSURE")) {
+        camParam = CameraParam::ABSOLUTE_EXPOSURE;
+    } else if (!trimmed.compare("ABSOLUTE_FOCUS")) {
+        camParam = CameraParam::ABSOLUTE_FOCUS;
+    } else if (!trimmed.compare("AUTO_FOCUS")) {
+        camParam = CameraParam::AUTO_FOCUS;
+    } else if (!trimmed.compare("ABSOLUTE_ZOOM")) {
+        camParam = CameraParam::ABSOLUTE_ZOOM;
+    } else {
+        success = false;
+    }
+
+    return success;
+}
+
+bool ConfigManagerUtil::convertToPixelFormat(const std::string& in, PixelFormat& out) {
+    std::string trimmed = ConfigManagerUtil::trimString(in);
+    bool success = true;
+
+    if (!trimmed.compare("RGBA_8888")) {
+        out = PixelFormat::RGBA_8888;
+    } else if (!trimmed.compare("YCRCB_420_SP")) {
+        out = PixelFormat::YCRCB_420_SP;
+    } else if (!trimmed.compare("YCBCR_422_I")) {
+        out = PixelFormat::YCBCR_422_I;
+    } else {
+        out = PixelFormat::UNSPECIFIED;
+        success = false;
+    }
+
+    return success;
+}
+
+bool ConfigManagerUtil::convertToMetadataTag(const char* name, camera_metadata_tag& aTag) {
+    if (!std::strcmp(name, "LENS_DISTORTION")) {
+        aTag = ANDROID_LENS_DISTORTION;
+    } else if (!std::strcmp(name, "LENS_INTRINSIC_CALIBRATION")) {
+        aTag = ANDROID_LENS_INTRINSIC_CALIBRATION;
+    } else if (!std::strcmp(name, "LENS_POSE_ROTATION")) {
+        aTag = ANDROID_LENS_POSE_ROTATION;
+    } else if (!std::strcmp(name, "LENS_POSE_TRANSLATION")) {
+        aTag = ANDROID_LENS_POSE_TRANSLATION;
+    } else if (!std::strcmp(name, "REQUEST_AVAILABLE_CAPABILITIES")) {
+        aTag = ANDROID_REQUEST_AVAILABLE_CAPABILITIES;
+    } else if (!std::strcmp(name, "LOGICAL_MULTI_CAMERA_PHYSICAL_IDS")) {
+        aTag = ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS;
+    } else {
+        return false;
+    }
+
+    return true;
+}
+
+bool ConfigManagerUtil::convertToCameraCapability(
+        const char* name, camera_metadata_enum_android_request_available_capabilities_t& cap) {
+    if (!std::strcmp(name, "DEPTH_OUTPUT")) {
+        cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT;
+    } else if (!std::strcmp(name, "LOGICAL_MULTI_CAMERA")) {
+        cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA;
+    } else if (!std::strcmp(name, "MONOCHROME")) {
+        cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME;
+    } else if (!std::strcmp(name, "SECURE_IMAGE_DATA")) {
+        cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA;
+    } else {
+        return false;
+    }
+
+    return true;
+}
+
+float* ConfigManagerUtil::convertFloatArray(const char* sz, const char* vals, size_t& count,
+                                            const char delimiter) {
+    std::string size_string(sz);
+    std::string value_string(vals);
+
+    if (!android::base::ParseUint(size_string, &count)) {
+        LOG(ERROR) << "Failed to parse " << size_string;
+        return nullptr;
+    }
+    float* result = new float[count];
+    std::stringstream values(value_string);
+
+    int32_t idx = 0;
+    std::string token;
+    while (getline(values, token, delimiter)) {
+        if (!android::base::ParseFloat(token, &result[idx++])) {
+            LOG(WARNING) << "Failed to parse " << token;
+        }
+    }
+
+    return result;
+}
+
+std::string ConfigManagerUtil::trimString(const std::string& src, const std::string& ws) {
+    const auto s = src.find_first_not_of(ws);
+    if (s == std::string::npos) {
+        return "";
+    }
+
+    const auto e = src.find_last_not_of(ws);
+    const auto r = e - s + 1;
+
+    return src.substr(s, r);
+}
diff --git a/automotive/evs/aidl/impl/default/src/DefaultEvsEnumerator.cpp b/automotive/evs/aidl/impl/default/src/DefaultEvsEnumerator.cpp
deleted file mode 100644
index 5a81d05..0000000
--- a/automotive/evs/aidl/impl/default/src/DefaultEvsEnumerator.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO(b/203661081): Remove below lines to disable compiler warnings.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-parameter"
-
-#define LOG_TAG "DefaultEvsEnumerator"
-
-#include <DefaultEvsEnumerator.h>
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-using ::ndk::ScopedAStatus;
-
-ScopedAStatus DefaultEvsEnumerator::isHardware(bool* flag) {
-    // This returns true always.
-    *flag = true;
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::openCamera(const std::string& cameraId,
-                                               const Stream& streamConfig,
-                                               std::shared_ptr<IEvsCamera>* obj) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::closeCamera(const std::shared_ptr<IEvsCamera>& obj) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getCameraList(std::vector<CameraDesc>* list) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getStreamList(const CameraDesc& desc,
-                                                  std::vector<Stream>* _aidl_return) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::openDisplay(int32_t displayId,
-                                                std::shared_ptr<IEvsDisplay>* obj) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::closeDisplay(const std::shared_ptr<IEvsDisplay>& state) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getDisplayIdList(std::vector<uint8_t>* list) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getDisplayState(DisplayState* state) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::registerStatusCallback(
-        const std::shared_ptr<IEvsEnumeratorStatusCallback>& callback) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::openUltrasonicsArray(
-        const std::string& id, std::shared_ptr<IEvsUltrasonicsArray>* obj) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::closeUltrasonicsArray(
-        const std::shared_ptr<IEvsUltrasonicsArray>& obj) {
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getUltrasonicsArrayList(
-        std::vector<UltrasonicsArrayDesc>* list) {
-    return ScopedAStatus::ok();
-}
-
-}  // namespace aidl::android::hardware::automotive::evs::implementation
-
-#pragma clang diagnostic pop
diff --git a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
new file mode 100644
index 0000000..5178958
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EvsEnumerator.h"
+
+#include "ConfigManager.h"
+#include "EvsGlDisplay.h"
+#include "EvsMockCamera.h"
+
+#include <aidl/android/hardware/automotive/evs/EvsResult.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <cutils/android_filesystem_config.h>
+
+#include <set>
+#include <string_view>
+
+namespace {
+
+using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::ndk::ScopedAStatus;
+using std::chrono_literals::operator""s;
+
+// Constants
+constexpr std::chrono::seconds kEnumerationTimeout = 10s;
+constexpr uint64_t kInvalidDisplayId = std::numeric_limits<uint64_t>::max();
+const std::set<uid_t> kAllowedUids = {AID_AUTOMOTIVE_EVS, AID_SYSTEM, AID_ROOT};
+
+}  // namespace
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+// NOTE:  All members values are static so that all clients operate on the same state
+//        That is to say, this is effectively a singleton despite the fact that HIDL
+//        constructs a new instance for each client.
+std::unordered_map<std::string, EvsEnumerator::CameraRecord> EvsEnumerator::sCameraList;
+std::mutex EvsEnumerator::sLock;
+std::condition_variable EvsEnumerator::sCameraSignal;
+std::unique_ptr<ConfigManager> EvsEnumerator::sConfigManager;
+std::shared_ptr<ICarDisplayProxy> EvsEnumerator::sDisplayProxy;
+std::unordered_map<uint8_t, uint64_t> EvsEnumerator::sDisplayPortList;
+
+EvsEnumerator::ActiveDisplays& EvsEnumerator::mutableActiveDisplays() {
+    static ActiveDisplays active_displays;
+    return active_displays;
+}
+
+EvsEnumerator::EvsEnumerator(const std::shared_ptr<ICarDisplayProxy>& proxyService) {
+    LOG(DEBUG) << "EvsEnumerator is created.";
+
+    if (!sConfigManager) {
+        /* loads and initializes ConfigManager in a separate thread */
+        sConfigManager = ConfigManager::Create();
+    }
+
+    if (!sDisplayProxy) {
+        /* sets a car-window service handle */
+        sDisplayProxy = proxyService;
+    }
+
+    // Enumerate existing devices
+    enumerateCameras();
+    mInternalDisplayId = enumerateDisplays();
+}
+
+bool EvsEnumerator::checkPermission() {
+    const auto uid = AIBinder_getCallingUid();
+    if (kAllowedUids.find(uid) == kAllowedUids.end()) {
+        LOG(ERROR) << "EVS access denied: "
+                   << "pid = " << AIBinder_getCallingPid() << ", uid = " << uid;
+        return false;
+    }
+
+    return true;
+}
+
+void EvsEnumerator::enumerateCameras() {
+    if (!sConfigManager) {
+        return;
+    }
+
+    for (auto id : sConfigManager->getCameraIdList()) {
+        CameraRecord rec(id.data());
+        std::unique_ptr<ConfigManager::CameraInfo>& pInfo = sConfigManager->getCameraInfo(id);
+        if (pInfo) {
+            uint8_t* ptr = reinterpret_cast<uint8_t*>(pInfo->characteristics);
+            const size_t len = get_camera_metadata_size(pInfo->characteristics);
+            rec.desc.metadata.insert(rec.desc.metadata.end(), ptr, ptr + len);
+        }
+        sCameraList.insert_or_assign(id, std::move(rec));
+    }
+}
+
+uint64_t EvsEnumerator::enumerateDisplays() {
+    LOG(INFO) << __FUNCTION__ << ": Starting display enumeration";
+    uint64_t internalDisplayId = kInvalidDisplayId;
+    if (!sDisplayProxy) {
+        LOG(ERROR) << "ICarDisplayProxy is not available!";
+        return internalDisplayId;
+    }
+
+    std::vector<int64_t> displayIds;
+    if (auto status = sDisplayProxy->getDisplayIdList(&displayIds); !status.isOk()) {
+        LOG(ERROR) << "Failed to retrieve a display id list"
+                   << ::android::statusToString(status.getStatus());
+        return internalDisplayId;
+    }
+
+    if (displayIds.size() > 0) {
+        // The first entry of the list is the internal display.  See
+        // SurfaceFlinger::getPhysicalDisplayIds() implementation.
+        internalDisplayId = displayIds[0];
+        for (const auto& id : displayIds) {
+            const auto port = id & 0xFF;
+            LOG(INFO) << "Display " << std::hex << id << " is detected on the port, " << port;
+            sDisplayPortList.insert_or_assign(port, id);
+        }
+    }
+
+    LOG(INFO) << "Found " << sDisplayPortList.size() << " displays";
+    return internalDisplayId;
+}
+
+// Methods from ::android::hardware::automotive::evs::IEvsEnumerator follow.
+ScopedAStatus EvsEnumerator::getCameraList(std::vector<CameraDesc>* _aidl_return) {
+    LOG(DEBUG) << __FUNCTION__;
+    if (!checkPermission()) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::PERMISSION_DENIED));
+    }
+
+    {
+        std::unique_lock<std::mutex> lock(sLock);
+        if (sCameraList.size() < 1) {
+            // No qualified device has been found.  Wait until new device is ready,
+            // for 10 seconds.
+            if (!sCameraSignal.wait_for(lock, kEnumerationTimeout,
+                                        [] { return sCameraList.size() > 0; })) {
+                LOG(DEBUG) << "Timer expired.  No new device has been added.";
+            }
+        }
+    }
+
+    // Build up a packed array of CameraDesc for return
+    _aidl_return->resize(sCameraList.size());
+    unsigned i = 0;
+    for (const auto& [key, cam] : sCameraList) {
+        (*_aidl_return)[i++] = cam.desc;
+    }
+
+    if (sConfigManager) {
+        // Adding camera groups that represent logical camera devices
+        auto camGroups = sConfigManager->getCameraGroupIdList();
+        for (auto&& id : camGroups) {
+            if (sCameraList.find(id) != sCameraList.end()) {
+                // Already exists in the _aidl_return
+                continue;
+            }
+
+            std::unique_ptr<ConfigManager::CameraGroupInfo>& tempInfo =
+                    sConfigManager->getCameraGroupInfo(id);
+            CameraRecord cam(id.data());
+            if (tempInfo) {
+                uint8_t* ptr = reinterpret_cast<uint8_t*>(tempInfo->characteristics);
+                const size_t len = get_camera_metadata_size(tempInfo->characteristics);
+                cam.desc.metadata.insert(cam.desc.metadata.end(), ptr, ptr + len);
+            }
+
+            sCameraList.insert_or_assign(id, cam);
+            _aidl_return->push_back(cam.desc);
+        }
+    }
+
+    // Send back the results
+    LOG(DEBUG) << "Reporting " << sCameraList.size() << " cameras available";
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::getStreamList(const CameraDesc& desc,
+                                           std::vector<Stream>* _aidl_return) {
+    using AidlPixelFormat = ::aidl::android::hardware::graphics::common::PixelFormat;
+
+    camera_metadata_t* pMetadata = const_cast<camera_metadata_t*>(
+            reinterpret_cast<const camera_metadata_t*>(desc.metadata.data()));
+    camera_metadata_entry_t streamConfig;
+    if (!find_camera_metadata_entry(pMetadata, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+                                    &streamConfig)) {
+        const unsigned numStreamConfigs = streamConfig.count / sizeof(StreamConfiguration);
+        _aidl_return->resize(numStreamConfigs);
+        const StreamConfiguration* pCurrentConfig =
+                reinterpret_cast<StreamConfiguration*>(streamConfig.data.i32);
+        for (unsigned i = 0; i < numStreamConfigs; ++i, ++pCurrentConfig) {
+            // Build ::aidl::android::hardware::automotive::evs::Stream from
+            // StreamConfiguration.
+            Stream current = {
+                    .id = pCurrentConfig->id,
+                    .streamType =
+                            pCurrentConfig->type ==
+                                            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT
+                                    ? StreamType::INPUT
+                                    : StreamType::OUTPUT,
+                    .width = pCurrentConfig->width,
+                    .height = pCurrentConfig->height,
+                    .format = static_cast<AidlPixelFormat>(pCurrentConfig->format),
+                    .usage = BufferUsage::CAMERA_INPUT,
+                    .rotation = Rotation::ROTATION_0,
+            };
+
+            (*_aidl_return)[i] = current;
+        }
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::openCamera(const std::string& id, const Stream& cfg,
+                                        std::shared_ptr<IEvsCamera>* obj) {
+    LOG(DEBUG) << __FUNCTION__;
+    if (!checkPermission()) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::PERMISSION_DENIED));
+    }
+
+    // Is this a recognized camera id?
+    CameraRecord* pRecord = findCameraById(id);
+    if (!pRecord) {
+        LOG(ERROR) << id << " does not exist!";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    }
+
+    // Has this camera already been instantiated by another caller?
+    std::shared_ptr<EvsMockCamera> pActiveCamera = pRecord->activeInstance.lock();
+    if (pActiveCamera) {
+        LOG(WARNING) << "Killing previous camera because of new caller";
+        closeCamera(pActiveCamera);
+    }
+
+    // Construct a camera instance for the caller
+    if (!sConfigManager) {
+        pActiveCamera = EvsMockCamera::Create(id.data());
+    } else {
+        pActiveCamera = EvsMockCamera::Create(id.data(), sConfigManager->getCameraInfo(id), &cfg);
+    }
+
+    pRecord->activeInstance = pActiveCamera;
+    if (!pActiveCamera) {
+        LOG(ERROR) << "Failed to create new EvsMockCamera object for " << id;
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+    }
+
+    *obj = pActiveCamera;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::closeCamera(const std::shared_ptr<IEvsCamera>& cameraObj) {
+    LOG(DEBUG) << __FUNCTION__;
+
+    if (!cameraObj) {
+        LOG(ERROR) << "Ignoring call to closeCamera with null camera ptr";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    }
+
+    // Get the camera id so we can find it in our list
+    CameraDesc desc;
+    auto status = cameraObj->getCameraInfo(&desc);
+    if (!status.isOk()) {
+        LOG(ERROR) << "Failed to read a camera descriptor";
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+    }
+    auto cameraId = desc.id;
+    closeCamera_impl(cameraObj, cameraId);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::openDisplay(int32_t id, std::shared_ptr<IEvsDisplay>* displayObj) {
+    LOG(DEBUG) << __FUNCTION__;
+    if (!checkPermission()) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::PERMISSION_DENIED));
+    }
+
+    auto& displays = mutableActiveDisplays();
+
+    if (auto existing_display_search = displays.popDisplay(id)) {
+        // If we already have a display active, then we need to shut it down so we can
+        // give exclusive access to the new caller.
+        std::shared_ptr<EvsGlDisplay> pActiveDisplay = existing_display_search->displayWeak.lock();
+        if (pActiveDisplay) {
+            LOG(WARNING) << "Killing previous display because of new caller";
+            pActiveDisplay->forceShutdown();
+        }
+    }
+
+    // Create a new display interface and return it
+    uint64_t targetDisplayId = mInternalDisplayId;
+    auto it = sDisplayPortList.find(id);
+    if (it != sDisplayPortList.end()) {
+        targetDisplayId = it->second;
+    } else {
+        LOG(WARNING) << "No display is available on the port " << static_cast<int32_t>(id)
+                     << ". The main display " << mInternalDisplayId << " will be used instead";
+    }
+
+    // Create a new display interface and return it.
+    std::shared_ptr<EvsGlDisplay> pActiveDisplay =
+            ndk::SharedRefBase::make<EvsGlDisplay>(sDisplayProxy, targetDisplayId);
+
+    if (auto insert_result = displays.tryInsert(id, pActiveDisplay); !insert_result) {
+        LOG(ERROR) << "Display ID " << id << " has been used by another caller.";
+        pActiveDisplay->forceShutdown();
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::RESOURCE_BUSY));
+    }
+
+    LOG(DEBUG) << "Returning new EvsGlDisplay object " << pActiveDisplay.get();
+    *displayObj = pActiveDisplay;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::closeDisplay(const std::shared_ptr<IEvsDisplay>& obj) {
+    LOG(DEBUG) << __FUNCTION__;
+
+    auto& displays = mutableActiveDisplays();
+    const auto display_search = displays.popDisplay(obj);
+
+    if (!display_search) {
+        LOG(WARNING) << "Ignoring close of previously orphaned display - why did a client steal?";
+        return ScopedAStatus::ok();
+    }
+
+    auto pActiveDisplay = display_search->displayWeak.lock();
+
+    if (!pActiveDisplay) {
+        LOG(ERROR) << "Somehow a display is being destroyed "
+                   << "when the enumerator didn't know one existed";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+    }
+
+    pActiveDisplay->forceShutdown();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::getDisplayState(DisplayState* state) {
+    LOG(DEBUG) << __FUNCTION__;
+    return getDisplayStateImpl(std::nullopt, state);
+}
+
+ScopedAStatus EvsEnumerator::getDisplayStateById(int32_t displayId, DisplayState* state) {
+    LOG(DEBUG) << __FUNCTION__;
+    return getDisplayStateImpl(displayId, state);
+}
+
+ScopedAStatus EvsEnumerator::getDisplayStateImpl(std::optional<int32_t> displayId,
+                                                 DisplayState* state) {
+    if (!checkPermission()) {
+        *state = DisplayState::DEAD;
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::PERMISSION_DENIED));
+    }
+
+    const auto& all_displays = mutableActiveDisplays().getAllDisplays();
+
+    const auto display_search = displayId ? all_displays.find(*displayId) : all_displays.begin();
+
+    if (display_search == all_displays.end()) {
+        *state = DisplayState::NOT_OPEN;
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+    }
+
+    std::shared_ptr<IEvsDisplay> pActiveDisplay = display_search->second.displayWeak.lock();
+    if (pActiveDisplay) {
+        return pActiveDisplay->getDisplayState(state);
+    } else {
+        *state = DisplayState::NOT_OPEN;
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+    }
+}
+
+ScopedAStatus EvsEnumerator::getDisplayIdList(std::vector<uint8_t>* list) {
+    std::vector<uint8_t>& output = *list;
+    if (sDisplayPortList.size() > 0) {
+        output.resize(sDisplayPortList.size());
+        unsigned i = 0;
+        output[i++] = mInternalDisplayId & 0xFF;
+        for (const auto& [port, id] : sDisplayPortList) {
+            if (mInternalDisplayId != id) {
+                output[i++] = port;
+            }
+        }
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::isHardware(bool* flag) {
+    *flag = true;
+    return ScopedAStatus::ok();
+}
+
+void EvsEnumerator::notifyDeviceStatusChange(const std::string_view& deviceName,
+                                             DeviceStatusType type) {
+    std::lock_guard lock(sLock);
+    if (!mCallback) {
+        return;
+    }
+
+    std::vector<DeviceStatus> status{{.id = std::string(deviceName), .status = type}};
+    if (!mCallback->deviceStatusChanged(status).isOk()) {
+        LOG(WARNING) << "Failed to notify a device status change, name = " << deviceName
+                     << ", type = " << static_cast<int>(type);
+    }
+}
+
+ScopedAStatus EvsEnumerator::registerStatusCallback(
+        const std::shared_ptr<IEvsEnumeratorStatusCallback>& callback) {
+    std::lock_guard lock(sLock);
+    if (mCallback) {
+        LOG(INFO) << "Replacing an existing device status callback";
+    }
+    mCallback = callback;
+    return ScopedAStatus::ok();
+}
+
+void EvsEnumerator::closeCamera_impl(const std::shared_ptr<IEvsCamera>& pCamera,
+                                     const std::string& cameraId) {
+    // Find the named camera
+    CameraRecord* pRecord = findCameraById(cameraId);
+
+    // Is the display being destroyed actually the one we think is active?
+    if (!pRecord) {
+        LOG(ERROR) << "Asked to close a camera whose name isn't recognized";
+    } else {
+        std::shared_ptr<EvsMockCamera> pActiveCamera = pRecord->activeInstance.lock();
+        if (!pActiveCamera) {
+            LOG(WARNING) << "Somehow a camera is being destroyed "
+                         << "when the enumerator didn't know one existed";
+        } else if (pActiveCamera != pCamera) {
+            // This can happen if the camera was aggressively reopened,
+            // orphaning this previous instance
+            LOG(WARNING) << "Ignoring close of previously orphaned camera "
+                         << "- why did a client steal?";
+        } else {
+            // Shutdown the active camera
+            pActiveCamera->shutdown();
+        }
+    }
+
+    return;
+}
+
+EvsEnumerator::CameraRecord* EvsEnumerator::findCameraById(const std::string& cameraId) {
+    // Find the named camera
+    auto found = sCameraList.find(cameraId);
+    if (found != sCameraList.end()) {
+        // Found a match!
+        return &found->second;
+    }
+
+    // We didn't find a match
+    return nullptr;
+}
+
+std::optional<EvsEnumerator::ActiveDisplays::DisplayInfo> EvsEnumerator::ActiveDisplays::popDisplay(
+        int32_t id) {
+    std::lock_guard lck(mMutex);
+    const auto search = mIdToDisplay.find(id);
+    if (search == mIdToDisplay.end()) {
+        return std::nullopt;
+    }
+    const auto display_info = search->second;
+    mIdToDisplay.erase(search);
+    mDisplayToId.erase(display_info.internalDisplayRawAddr);
+    return display_info;
+}
+
+std::optional<EvsEnumerator::ActiveDisplays::DisplayInfo> EvsEnumerator::ActiveDisplays::popDisplay(
+        const std::shared_ptr<IEvsDisplay>& display) {
+    const auto display_ptr_val = reinterpret_cast<uintptr_t>(display.get());
+    std::lock_guard lck(mMutex);
+    const auto display_to_id_search = mDisplayToId.find(display_ptr_val);
+    if (display_to_id_search == mDisplayToId.end()) {
+        LOG(ERROR) << "Unknown display.";
+        return std::nullopt;
+    }
+    const auto id = display_to_id_search->second;
+    const auto id_to_display_search = mIdToDisplay.find(id);
+    mDisplayToId.erase(display_to_id_search);
+    if (id_to_display_search == mIdToDisplay.end()) {
+        LOG(ERROR) << "No correspsonding ID for the display, probably orphaned.";
+        return std::nullopt;
+    }
+    const auto display_info = id_to_display_search->second;
+    mIdToDisplay.erase(id);
+    return display_info;
+}
+
+std::unordered_map<int32_t, EvsEnumerator::ActiveDisplays::DisplayInfo>
+EvsEnumerator::ActiveDisplays::getAllDisplays() {
+    std::lock_guard lck(mMutex);
+    auto id_to_display_map_copy = mIdToDisplay;
+    return id_to_display_map_copy;
+}
+
+bool EvsEnumerator::ActiveDisplays::tryInsert(int32_t id,
+                                              const std::shared_ptr<EvsGlDisplay>& display) {
+    std::lock_guard lck(mMutex);
+    const auto display_ptr_val = reinterpret_cast<uintptr_t>(display.get());
+
+    auto id_to_display_insert_result =
+            mIdToDisplay.emplace(id, DisplayInfo{
+                                             .id = id,
+                                             .displayWeak = display,
+                                             .internalDisplayRawAddr = display_ptr_val,
+                                     });
+    if (!id_to_display_insert_result.second) {
+        return false;
+    }
+    auto display_to_id_insert_result = mDisplayToId.emplace(display_ptr_val, id);
+    if (!display_to_id_insert_result.second) {
+        mIdToDisplay.erase(id);
+        return false;
+    }
+    return true;
+}
+
+ScopedAStatus EvsEnumerator::getUltrasonicsArrayList(
+        [[maybe_unused]] std::vector<UltrasonicsArrayDesc>* list) {
+    // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::openUltrasonicsArray(
+        [[maybe_unused]] const std::string& id,
+        [[maybe_unused]] std::shared_ptr<IEvsUltrasonicsArray>* obj) {
+    // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::closeUltrasonicsArray(
+        [[maybe_unused]] const std::shared_ptr<IEvsUltrasonicsArray>& obj) {
+    // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
+    return ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
new file mode 100644
index 0000000..e5f8e4c
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EvsGlDisplay.h"
+
+#include <aidl/android/hardware/automotive/evs/EvsResult.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android-base/thread_annotations.h>
+#include <linux/time.h>
+#include <ui/DisplayMode.h>
+#include <ui/DisplayState.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicBufferMapper.h>
+#include <utils/SystemClock.h>
+
+#include <chrono>
+
+namespace {
+
+using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+using ::android::base::ScopedLockAssertion;
+using ::ndk::ScopedAStatus;
+
+constexpr auto kTimeout = std::chrono::seconds(1);
+
+bool debugFirstFrameDisplayed = false;
+
+int generateFingerPrint(buffer_handle_t handle) {
+    return static_cast<int>(reinterpret_cast<long>(handle) & 0xFFFFFFFF);
+}
+
+}  // namespace
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+EvsGlDisplay::EvsGlDisplay(const std::shared_ptr<ICarDisplayProxy>& pDisplayProxy,
+                           uint64_t displayId)
+    : mDisplayId(displayId), mDisplayProxy(pDisplayProxy) {
+    LOG(DEBUG) << "EvsGlDisplay instantiated";
+
+    // Set up our self description
+    // NOTE:  These are arbitrary values chosen for testing
+    mInfo.id = std::to_string(displayId);
+    mInfo.vendorFlags = 3870;
+
+    // Start a thread to render images on this display
+    {
+        std::lock_guard lock(mLock);
+        mState = RUN;
+    }
+    mRenderThread = std::thread([this]() { renderFrames(); });
+}
+
+EvsGlDisplay::~EvsGlDisplay() {
+    LOG(DEBUG) << "EvsGlDisplay being destroyed";
+    forceShutdown();
+}
+
+/**
+ * This gets called if another caller "steals" ownership of the display
+ */
+void EvsGlDisplay::forceShutdown() {
+    LOG(DEBUG) << "EvsGlDisplay forceShutdown";
+    {
+        std::lock_guard lock(mLock);
+
+        // If the buffer isn't being held by a remote client, release it now as an
+        // optimization to release the resources more quickly than the destructor might
+        // get called.
+        if (mBuffer.handle != nullptr) {
+            // Report if we're going away while a buffer is outstanding
+            if (mBufferBusy || mState == RUN) {
+                LOG(ERROR) << "EvsGlDisplay going down while client is holding a buffer";
+            }
+            mState = STOPPING;
+        }
+
+        // Put this object into an unrecoverable error state since somebody else
+        // is going to own the display now.
+        mRequestedState = DisplayState::DEAD;
+    }
+    mBufferReadyToRender.notify_all();
+
+    if (mRenderThread.joinable()) {
+        mRenderThread.join();
+    }
+}
+
+/**
+ * Initialize GL in the context of a caller's thread and prepare a graphic
+ * buffer to use.
+ */
+bool EvsGlDisplay::initializeGlContextLocked() {
+    // Initialize our display window
+    // NOTE:  This will cause the display to become "VISIBLE" before a frame is actually
+    // returned, which is contrary to the spec and will likely result in a black frame being
+    // (briefly) shown.
+    if (!mGlWrapper.initialize(mDisplayProxy, mDisplayId)) {
+        // Report the failure
+        LOG(ERROR) << "Failed to initialize GL display";
+        return false;
+    }
+
+    // Assemble the buffer description we'll use for our render target
+    static_assert(::aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888 ==
+                  static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(
+                          HAL_PIXEL_FORMAT_RGBA_8888));
+    mBuffer.description = {
+            .width = static_cast<int>(mGlWrapper.getWidth()),
+            .height = static_cast<int>(mGlWrapper.getHeight()),
+            .layers = 1,
+            .format = PixelFormat::RGBA_8888,
+            // FIXME: Below line is not using
+            // ::aidl::android::hardware::graphics::common::BufferUsage because
+            // BufferUsage enum does not support a bitwise-OR operation; they
+            // should be BufferUsage::GPU_RENDER_TARGET |
+            // BufferUsage::COMPOSER_OVERLAY
+            .usage = static_cast<BufferUsage>(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER),
+    };
+
+    ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+    uint32_t stride = static_cast<uint32_t>(mBuffer.description.stride);
+    buffer_handle_t handle = nullptr;
+    const ::android::status_t result =
+            alloc.allocate(mBuffer.description.width, mBuffer.description.height,
+                           static_cast<::android::PixelFormat>(mBuffer.description.format),
+                           mBuffer.description.layers,
+                           static_cast<uint64_t>(mBuffer.description.usage), &handle, &stride,
+                           /* requestorName= */ "EvsGlDisplay");
+    mBuffer.description.stride = stride;
+    mBuffer.fingerprint = generateFingerPrint(mBuffer.handle);
+    if (result != ::android::NO_ERROR) {
+        LOG(ERROR) << "Error " << result << " allocating " << mBuffer.description.width << " x "
+                   << mBuffer.description.height << " graphics buffer.";
+        mGlWrapper.shutdown();
+        return false;
+    }
+
+    mBuffer.handle = handle;
+    if (mBuffer.handle == nullptr) {
+        LOG(ERROR) << "We didn't get a buffer handle back from the allocator";
+        mGlWrapper.shutdown();
+        return false;
+    }
+
+    LOG(DEBUG) << "Allocated new buffer " << mBuffer.handle << " with stride "
+               << mBuffer.description.stride;
+    return true;
+}
+
+/**
+ * This method runs in a separate thread and renders the contents of the buffer.
+ */
+void EvsGlDisplay::renderFrames() {
+    {
+        std::lock_guard lock(mLock);
+
+        if (!initializeGlContextLocked()) {
+            LOG(ERROR) << "Failed to initialize GL context";
+            return;
+        }
+
+        // Display buffer is ready.
+        mBufferBusy = false;
+    }
+    mBufferReadyToUse.notify_all();
+
+    while (true) {
+        {
+            std::unique_lock lock(mLock);
+            ScopedLockAssertion lock_assertion(mLock);
+            mBufferReadyToRender.wait(
+                    lock, [this]() REQUIRES(mLock) { return mBufferReady || mState != RUN; });
+            if (mState != RUN) {
+                LOG(DEBUG) << "A rendering thread is stopping";
+                break;
+            }
+            mBufferReady = false;
+        }
+
+        // Update the texture contents with the provided data
+        if (!mGlWrapper.updateImageTexture(mBuffer.handle, mBuffer.description)) {
+            LOG(WARNING) << "Failed to update the image texture";
+            continue;
+        }
+
+        // Put the image on the screen
+        mGlWrapper.renderImageToScreen();
+        if (!debugFirstFrameDisplayed) {
+            LOG(DEBUG) << "EvsFirstFrameDisplayTiming start time: " << ::android::elapsedRealtime()
+                       << " ms.";
+            debugFirstFrameDisplayed = true;
+        }
+
+        // Mark current frame is consumed.
+        {
+            std::lock_guard lock(mLock);
+            mBufferBusy = false;
+        }
+        mBufferDone.notify_all();
+    }
+
+    LOG(DEBUG) << "A rendering thread is stopped.";
+
+    // Drop the graphics buffer we've been using
+    ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+    alloc.free(mBuffer.handle);
+    mBuffer.handle = nullptr;
+
+    mGlWrapper.hideWindow(mDisplayProxy, mDisplayId);
+    mGlWrapper.shutdown();
+
+    std::lock_guard lock(mLock);
+    mState = STOPPED;
+}
+
+/**
+ * Returns basic information about the EVS display provided by the system.
+ * See the description of the DisplayDesc structure for details.
+ */
+ScopedAStatus EvsGlDisplay::getDisplayInfo(DisplayDesc* _aidl_return) {
+    if (!mDisplayProxy) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+    }
+
+    ::aidl::android::frameworks::automotive::display::DisplayDesc proxyDisplay;
+    auto status = mDisplayProxy->getDisplayInfo(mDisplayId, &proxyDisplay);
+    if (!status.isOk()) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+    }
+
+    _aidl_return->width = proxyDisplay.width;
+    _aidl_return->height = proxyDisplay.height;
+    _aidl_return->orientation = static_cast<Rotation>(proxyDisplay.orientation);
+    _aidl_return->id = mInfo.id;  // FIXME: what should be ID here?
+    _aidl_return->vendorFlags = mInfo.vendorFlags;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+/**
+ * Clients may set the display state to express their desired state.
+ * The HAL implementation must gracefully accept a request for any state
+ * while in any other state, although the response may be to ignore the request.
+ * The display is defined to start in the NOT_VISIBLE state upon initialization.
+ * The client is then expected to request the VISIBLE_ON_NEXT_FRAME state, and
+ * then begin providing video.  When the display is no longer required, the client
+ * is expected to request the NOT_VISIBLE state after passing the last video frame.
+ */
+ScopedAStatus EvsGlDisplay::setDisplayState(DisplayState state) {
+    LOG(DEBUG) << __FUNCTION__;
+    std::lock_guard lock(mLock);
+
+    if (mRequestedState == DisplayState::DEAD) {
+        // This object no longer owns the display -- it's been superceeded!
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+    }
+
+    // Ensure we recognize the requested state so we don't go off the rails
+    static constexpr ::ndk::enum_range<DisplayState> kDisplayStateRange;
+    if (std::find(kDisplayStateRange.begin(), kDisplayStateRange.end(), state) ==
+        kDisplayStateRange.end()) {
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    }
+
+    switch (state) {
+        case DisplayState::NOT_VISIBLE:
+            mGlWrapper.hideWindow(mDisplayProxy, mDisplayId);
+            break;
+        case DisplayState::VISIBLE:
+            mGlWrapper.showWindow(mDisplayProxy, mDisplayId);
+            break;
+        default:
+            break;
+    }
+
+    // Record the requested state
+    mRequestedState = state;
+
+    return ScopedAStatus::ok();
+}
+
+/**
+ * The HAL implementation should report the actual current state, which might
+ * transiently differ from the most recently requested state.  Note, however, that
+ * the logic responsible for changing display states should generally live above
+ * the device layer, making it undesirable for the HAL implementation to
+ * spontaneously change display states.
+ */
+ScopedAStatus EvsGlDisplay::getDisplayState(DisplayState* _aidl_return) {
+    LOG(DEBUG) << __FUNCTION__;
+    std::lock_guard lock(mLock);
+    *_aidl_return = mRequestedState;
+    return ScopedAStatus::ok();
+}
+
+/**
+ * This call returns a handle to a frame buffer associated with the display.
+ * This buffer may be locked and written to by software and/or GL.  This buffer
+ * must be returned via a call to returnTargetBufferForDisplay() even if the
+ * display is no longer visible.
+ */
+ScopedAStatus EvsGlDisplay::getTargetBuffer(BufferDesc* _aidl_return) {
+    LOG(DEBUG) << __FUNCTION__;
+    std::unique_lock lock(mLock);
+    ScopedLockAssertion lock_assertion(mLock);
+    if (mRequestedState == DisplayState::DEAD) {
+        LOG(ERROR) << "Rejecting buffer request from object that lost ownership of the display.";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+    }
+
+    // If we don't already have a buffer, allocate one now
+    // mBuffer.memHandle is a type of buffer_handle_t, which is equal to
+    // native_handle_t*.
+    mBufferReadyToUse.wait(lock, [this]() REQUIRES(mLock) { return !mBufferBusy; });
+
+    // Do we have a frame available?
+    if (mBufferBusy) {
+        // This means either we have a 2nd client trying to compete for buffers
+        // (an unsupported mode of operation) or else the client hasn't returned
+        // a previously issued buffer yet (they're behaving badly).
+        // NOTE:  We have to make the callback even if we have nothing to provide
+        LOG(ERROR) << "getTargetBuffer called while no buffers available.";
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));
+    }
+
+    // Mark our buffer as busy
+    mBufferBusy = true;
+
+    // Send the buffer to the client
+    LOG(VERBOSE) << "Providing display buffer handle " << mBuffer.handle;
+
+    BufferDesc bufferDescToSend = {
+            .buffer =
+                    {
+                            .handle = std::move(::android::dupToAidl(mBuffer.handle)),
+                            .description = mBuffer.description,
+                    },
+            .pixelSizeBytes = 4,  // RGBA_8888 is 4-byte-per-pixel format
+            .bufferId = mBuffer.fingerprint,
+    };
+    *_aidl_return = std::move(bufferDescToSend);
+
+    return ScopedAStatus::ok();
+}
+
+/**
+ * This call tells the display that the buffer is ready for display.
+ * The buffer is no longer valid for use by the client after this call.
+ */
+ScopedAStatus EvsGlDisplay::returnTargetBufferForDisplay(const BufferDesc& buffer) {
+    LOG(VERBOSE) << __FUNCTION__;
+    std::unique_lock lock(mLock);
+    ScopedLockAssertion lock_assertion(mLock);
+
+    // Nobody should call us with a null handle
+    if (buffer.buffer.handle.fds.size() < 1) {
+        LOG(ERROR) << __FUNCTION__ << " called without a valid buffer handle.";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    }
+    if (buffer.bufferId != mBuffer.fingerprint) {
+        LOG(ERROR) << "Got an unrecognized frame returned.";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    }
+    if (!mBufferBusy) {
+        LOG(ERROR) << "A frame was returned with no outstanding frames.";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    }
+
+    // If we've been displaced by another owner of the display, then we can't do anything else
+    if (mRequestedState == DisplayState::DEAD) {
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+    }
+
+    // If we were waiting for a new frame, this is it!
+    if (mRequestedState == DisplayState::VISIBLE_ON_NEXT_FRAME) {
+        mRequestedState = DisplayState::VISIBLE;
+        mGlWrapper.showWindow(mDisplayProxy, mDisplayId);
+    }
+
+    // Validate we're in an expected state
+    if (mRequestedState != DisplayState::VISIBLE) {
+        // Not sure why a client would send frames back when we're not visible.
+        LOG(WARNING) << "Got a frame returned while not visible - ignoring.";
+        return ScopedAStatus::ok();
+    }
+    mBufferReady = true;
+    mBufferReadyToRender.notify_all();
+
+    if (!mBufferDone.wait_for(lock, kTimeout, [this]() REQUIRES(mLock) { return !mBufferBusy; })) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+    }
+
+    return ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/EvsMockCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsMockCamera.cpp
new file mode 100644
index 0000000..797b221
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/EvsMockCamera.cpp
@@ -0,0 +1,735 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EvsMockCamera.h"
+#include "ConfigManager.h"
+#include "EvsEnumerator.h"
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicBufferMapper.h>
+#include <utils/SystemClock.h>
+
+#include <memory>
+
+namespace {
+
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::ndk::ScopedAStatus;
+
+// Arbitrary limit on number of graphics buffers allowed to be allocated
+// Safeguards against unreasonable resource consumption and provides a testable limit
+constexpr unsigned kMaxBuffersInFlight = 100;
+
+// Minimum number of buffers to run a video stream
+constexpr int kMinimumBuffersInFlight = 1;
+
+// Colors for the colorbar test pattern in ABGR format
+constexpr uint32_t kColors[] = {
+        0xFFFFFFFF,  // white
+        0xFF00FFFF,  // yellow
+        0xFFFFFF00,  // cyan
+        0xFF00FF00,  // green
+        0xFFFF00FF,  // fuchsia
+        0xFF0000FF,  // red
+        0xFFFF0000,  // blue
+        0xFF000000,  // black
+};
+constexpr size_t kNumColors = sizeof(kColors) / sizeof(kColors[0]);
+
+}  // namespace
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+EvsMockCamera::EvsMockCamera([[maybe_unused]] Sigil sigil, const char* id,
+                             std::unique_ptr<ConfigManager::CameraInfo>& camInfo)
+    : mFramesAllowed(0), mFramesInUse(0), mStreamState(STOPPED), mCameraInfo(camInfo) {
+    LOG(DEBUG) << __FUNCTION__;
+
+    /* set a camera id */
+    mDescription.id = id;
+
+    /* set camera metadata */
+    if (camInfo) {
+        uint8_t* ptr = reinterpret_cast<uint8_t*>(camInfo->characteristics);
+        const size_t len = get_camera_metadata_size(camInfo->characteristics);
+        mDescription.metadata.insert(mDescription.metadata.end(), ptr, ptr + len);
+    }
+
+    // Initialize parameters.
+    initializeParameters();
+}
+
+EvsMockCamera::~EvsMockCamera() {
+    LOG(DEBUG) << __FUNCTION__;
+    shutdown();
+}
+
+void EvsMockCamera::initializeParameters() {
+    mParams.emplace(
+            CameraParam::BRIGHTNESS,
+            new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255));
+    mParams.emplace(
+            CameraParam::CONTRAST,
+            new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255));
+    mParams.emplace(
+            CameraParam::SHARPNESS,
+            new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255));
+}
+
+// This gets called if another caller "steals" ownership of the camera
+void EvsMockCamera::shutdown() {
+    LOG(DEBUG) << __FUNCTION__;
+
+    // Make sure our output stream is cleaned up
+    // (It really should be already)
+    stopVideoStream_impl();
+
+    // Claim the lock while we work on internal state
+    std::lock_guard lock(mAccessLock);
+
+    // Drop all the graphics buffers we've been using
+    if (mBuffers.size() > 0) {
+        ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+        for (auto&& rec : mBuffers) {
+            if (rec.inUse) {
+                LOG(WARNING) << "WARNING: releasing a buffer remotely owned.";
+            }
+            alloc.free(rec.handle);
+            rec.handle = nullptr;
+        }
+        mBuffers.clear();
+    }
+
+    // Put this object into an unrecoverable error state since somebody else
+    // is going to own the underlying camera now
+    mStreamState = DEAD;
+}
+
+// Methods from ::aidl::android::hardware::automotive::evs::IEvsCamera follow.
+ScopedAStatus EvsMockCamera::getCameraInfo(CameraDesc* _aidl_return) {
+    LOG(DEBUG) << __FUNCTION__;
+
+    // Send back our self description
+    *_aidl_return = mDescription;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::setMaxFramesInFlight(int32_t bufferCount) {
+    LOG(DEBUG) << __FUNCTION__ << ", bufferCount = " << bufferCount;
+    ;
+
+    std::lock_guard lock(mAccessLock);
+
+    // If we've been displaced by another owner of the camera, then we can't do anything else
+    if (mStreamState == DEAD) {
+        LOG(ERROR) << "Ignoring setMaxFramesInFlight call when camera has been lost.";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+    }
+
+    // We cannot function without at least one video buffer to send data
+    if (bufferCount < 1) {
+        LOG(ERROR) << "Ignoring setMaxFramesInFlight with less than one buffer requested.";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    }
+
+    // Update our internal state
+    if (!setAvailableFrames_Locked(bufferCount)) {
+        LOG(ERROR) << "Failed to adjust the maximum number of frames in flight.";
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::startVideoStream(const std::shared_ptr<IEvsCameraStream>& cb) {
+    LOG(DEBUG) << __FUNCTION__;
+
+    if (!cb) {
+        LOG(ERROR) << "A given stream callback is invalid.";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    }
+
+    std::lock_guard lock(mAccessLock);
+
+    // If we've been displaced by another owner of the camera, then we can't do anything else
+    if (mStreamState == DEAD) {
+        LOG(ERROR) << "Ignoring startVideoStream call when camera has been lost.";
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+    }
+
+    if (mStreamState != STOPPED) {
+        LOG(ERROR) << "Ignoring startVideoStream call when a stream is already running.";
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::STREAM_ALREADY_RUNNING));
+    }
+
+    // If the client never indicated otherwise, configure ourselves for a single streaming buffer
+    if (mFramesAllowed < kMinimumBuffersInFlight &&
+        !setAvailableFrames_Locked(kMinimumBuffersInFlight)) {
+        LOG(ERROR) << "Failed to start stream because we couldn't get a graphics buffer";
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));
+    }
+
+    // Record the user's callback for use when we have a frame ready
+    mStream = cb;
+
+    // Start the frame generation thread
+    mStreamState = RUNNING;
+    mCaptureThread = std::thread([this]() { generateFrames(); });
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::doneWithFrame(const std::vector<BufferDesc>& list) {
+    std::lock_guard lock(mAccessLock);
+    for (const auto& desc : list) {
+        returnBufferLocked(desc.bufferId);
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::stopVideoStream() {
+    LOG(DEBUG) << __FUNCTION__;
+    return stopVideoStream_impl();
+}
+
+ScopedAStatus EvsMockCamera::stopVideoStream_impl() {
+    std::unique_lock lock(mAccessLock);
+
+    if (mStreamState != RUNNING) {
+        // Safely return here because a stream is not running.
+        return ScopedAStatus::ok();
+    }
+
+    // Tell the GenerateFrames loop we want it to stop
+    mStreamState = STOPPING;
+
+    // Block outside the mutex until the "stop" flag has been acknowledged
+    // We won't send any more frames, but the client might still get some already in flight
+    LOG(DEBUG) << "Waiting for stream thread to end...";
+    lock.unlock();
+    if (mCaptureThread.joinable()) {
+        mCaptureThread.join();
+    }
+    lock.lock();
+
+    mStreamState = STOPPED;
+    mStream = nullptr;
+    LOG(DEBUG) << "Stream marked STOPPED.";
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getExtendedInfo(int32_t opaqueIdentifier,
+                                             std::vector<uint8_t>* opaqueValue) {
+    const auto it = mExtInfo.find(opaqueIdentifier);
+    if (it == mExtInfo.end()) {
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    } else {
+        *opaqueValue = mExtInfo[opaqueIdentifier];
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::setExtendedInfo(int32_t opaqueIdentifier,
+                                             const std::vector<uint8_t>& opaqueValue) {
+    mExtInfo.insert_or_assign(opaqueIdentifier, opaqueValue);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getPhysicalCameraInfo([[maybe_unused]] const std::string& id,
+                                                   CameraDesc* _aidl_return) {
+    LOG(DEBUG) << __FUNCTION__;
+
+    // This method works exactly same as getCameraInfo() in EVS HW module.
+    *_aidl_return = mDescription;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::pauseVideoStream() {
+    return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+}
+
+ScopedAStatus EvsMockCamera::resumeVideoStream() {
+    return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+}
+
+ScopedAStatus EvsMockCamera::setPrimaryClient() {
+    /* Because EVS HW module reference implementation expects a single client at
+     * a time, this returns a success code always.
+     */
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::forcePrimaryClient(const std::shared_ptr<IEvsDisplay>&) {
+    /* Because EVS HW module reference implementation expects a single client at
+     * a time, this returns a success code always.
+     */
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::unsetPrimaryClient() {
+    /* Because EVS HW module reference implementation expects a single client at
+     * a time, there is no chance that this is called by the secondary client and
+     * therefore returns a success code always.
+     */
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getParameterList(std::vector<CameraParam>* _aidl_return) {
+    if (mCameraInfo) {
+        _aidl_return->resize(mCameraInfo->controls.size());
+        auto idx = 0;
+        for (auto& [name, range] : mCameraInfo->controls) {
+            (*_aidl_return)[idx++] = name;
+        }
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getIntParameterRange(CameraParam id, ParameterRange* _aidl_return) {
+    auto it = mParams.find(id);
+    if (it == mParams.end()) {
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+    }
+
+    _aidl_return->min = it->second->range.min;
+    _aidl_return->max = it->second->range.max;
+    _aidl_return->step = it->second->range.step;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::setIntParameter(CameraParam id, int32_t value,
+                                             std::vector<int32_t>* effectiveValue) {
+    auto it = mParams.find(id);
+    if (it == mParams.end()) {
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+    }
+
+    // Rounding down to the closest value.
+    int32_t candidate = value / it->second->range.step * it->second->range.step;
+    if (candidate < it->second->range.min || candidate > it->second->range.max) {
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+    }
+
+    it->second->value = candidate;
+    effectiveValue->push_back(candidate);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getIntParameter(CameraParam id, std::vector<int32_t>* value) {
+    auto it = mParams.find(id);
+    if (it == mParams.end()) {
+        return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+    }
+
+    value->push_back(it->second->value);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::importExternalBuffers(const std::vector<BufferDesc>& buffers,
+                                                   int32_t* _aidl_return) {
+    size_t numBuffersToAdd = buffers.size();
+    if (numBuffersToAdd < 1) {
+        LOG(DEBUG) << "Ignoring a request to import external buffers with an empty list.";
+        return ScopedAStatus::ok();
+    }
+
+    std::lock_guard lock(mAccessLock);
+    if (numBuffersToAdd > (kMaxBuffersInFlight - mFramesAllowed)) {
+        numBuffersToAdd -= (kMaxBuffersInFlight - mFramesAllowed);
+        LOG(WARNING) << "Exceed the limit on the number of buffers. " << numBuffersToAdd
+                     << " buffers will be imported only.";
+    }
+
+    ::android::GraphicBufferMapper& mapper = ::android::GraphicBufferMapper::get();
+    const size_t before = mFramesAllowed;
+    for (size_t i = 0; i < numBuffersToAdd; ++i) {
+        auto& b = buffers[i];
+        const AHardwareBuffer_Desc* pDesc =
+                reinterpret_cast<const AHardwareBuffer_Desc*>(&b.buffer.description);
+
+        buffer_handle_t handleToImport = ::android::dupFromAidl(b.buffer.handle);
+        buffer_handle_t handleToStore = nullptr;
+        if (handleToImport == nullptr) {
+            LOG(WARNING) << "Failed to duplicate a memory handle. Ignoring a buffer " << b.bufferId;
+            continue;
+        }
+
+        ::android::status_t result =
+                mapper.importBuffer(handleToImport, pDesc->width, pDesc->height, pDesc->layers,
+                                    pDesc->format, pDesc->usage, pDesc->stride, &handleToStore);
+        if (result != ::android::NO_ERROR || handleToStore == nullptr) {
+            LOG(WARNING) << "Failed to import a buffer " << b.bufferId;
+            continue;
+        }
+
+        bool stored = false;
+        for (auto&& rec : mBuffers) {
+            if (rec.handle != nullptr) {
+                continue;
+            }
+
+            // Use this existing entry.
+            rec.handle = handleToStore;
+            rec.inUse = false;
+            stored = true;
+            break;
+        }
+
+        if (!stored) {
+            // Add a BufferRecord wrapping this handle to our set of available buffers.
+            mBuffers.push_back(BufferRecord(handleToStore));
+        }
+        ++mFramesAllowed;
+    }
+
+    *_aidl_return = mFramesAllowed - before;
+    return ScopedAStatus::ok();
+}
+
+bool EvsMockCamera::setAvailableFrames_Locked(unsigned bufferCount) {
+    if (bufferCount < 1) {
+        LOG(ERROR) << "Ignoring request to set buffer count to zero";
+        return false;
+    }
+    if (bufferCount > kMaxBuffersInFlight) {
+        LOG(ERROR) << "Rejecting buffer request in excess of internal limit";
+        return false;
+    }
+
+    // Is an increase required?
+    if (mFramesAllowed < bufferCount) {
+        // An increase is required
+        auto needed = bufferCount - mFramesAllowed;
+        LOG(INFO) << "Allocating " << needed << " buffers for camera frames";
+
+        auto added = increaseAvailableFrames_Locked(needed);
+        if (added != needed) {
+            // If we didn't add all the frames we needed, then roll back to the previous state
+            LOG(ERROR) << "Rolling back to previous frame queue size";
+            decreaseAvailableFrames_Locked(added);
+            return false;
+        }
+    } else if (mFramesAllowed > bufferCount) {
+        // A decrease is required
+        auto framesToRelease = mFramesAllowed - bufferCount;
+        LOG(INFO) << "Returning " << framesToRelease << " camera frame buffers";
+
+        auto released = decreaseAvailableFrames_Locked(framesToRelease);
+        if (released != framesToRelease) {
+            // This shouldn't happen with a properly behaving client because the client
+            // should only make this call after returning sufficient outstanding buffers
+            // to allow a clean resize.
+            LOG(ERROR) << "Buffer queue shrink failed -- too many buffers currently in use?";
+        }
+    }
+
+    return true;
+}
+
+unsigned EvsMockCamera::increaseAvailableFrames_Locked(unsigned numToAdd) {
+    // Acquire the graphics buffer allocator
+    ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+
+    unsigned added = 0;
+    while (added < numToAdd) {
+        unsigned pixelsPerLine = 0;
+        buffer_handle_t memHandle = nullptr;
+        auto result = alloc.allocate(mWidth, mHeight, mFormat, 1, mUsage, &memHandle,
+                                     &pixelsPerLine, 0, "EvsMockCamera");
+        if (result != ::android::NO_ERROR) {
+            LOG(ERROR) << "Error " << result << " allocating " << mWidth << " x " << mHeight
+                       << " graphics buffer";
+            break;
+        }
+        if (memHandle == nullptr) {
+            LOG(ERROR) << "We didn't get a buffer handle back from the allocator";
+            break;
+        }
+        if (mStride > 0) {
+            if (mStride != pixelsPerLine) {
+                LOG(ERROR) << "We did not expect to get buffers with different strides!";
+            }
+        } else {
+            // Gralloc defines stride in terms of pixels per line
+            mStride = pixelsPerLine;
+        }
+
+        // Find a place to store the new buffer
+        auto stored = false;
+        for (auto&& rec : mBuffers) {
+            if (rec.handle == nullptr) {
+                // Use this existing entry
+                rec.handle = memHandle;
+                rec.inUse = false;
+                stored = true;
+                break;
+            }
+        }
+        if (!stored) {
+            // Add a BufferRecord wrapping this handle to our set of available buffers
+            mBuffers.push_back(BufferRecord(memHandle));
+        }
+
+        ++mFramesAllowed;
+        ++added;
+    }
+
+    return added;
+}
+
+unsigned EvsMockCamera::decreaseAvailableFrames_Locked(unsigned numToRemove) {
+    // Acquire the graphics buffer allocator
+    ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+
+    unsigned removed = 0;
+    for (auto&& rec : mBuffers) {
+        // Is this record not in use, but holding a buffer that we can free?
+        if ((rec.inUse == false) && (rec.handle != nullptr)) {
+            // Release buffer and update the record so we can recognize it as "empty"
+            alloc.free(rec.handle);
+            rec.handle = nullptr;
+
+            --mFramesAllowed;
+            ++removed;
+
+            if (removed == numToRemove) {
+                break;
+            }
+        }
+    }
+
+    return removed;
+}
+
+// This is the asynchronous frame generation thread that runs in parallel with the
+// main serving thread.  There is one for each active camera instance.
+void EvsMockCamera::generateFrames() {
+    LOG(DEBUG) << "Frame generation loop started.";
+
+    unsigned idx = 0;
+    while (true) {
+        bool timeForFrame = false;
+        const nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+
+        // Lock scope for updating shared state
+        {
+            std::lock_guard lock(mAccessLock);
+
+            if (mStreamState != RUNNING) {
+                // Break out of our main thread loop
+                break;
+            }
+
+            // Are we allowed to issue another buffer?
+            if (mFramesInUse >= mFramesAllowed) {
+                // Can't do anything right now -- skip this frame
+                LOG(WARNING) << "Skipped a frame because too many are in flight.";
+            } else {
+                // Identify an available buffer to fill
+                for (idx = 0; idx < mBuffers.size(); idx++) {
+                    if (!mBuffers[idx].inUse) {
+                        if (mBuffers[idx].handle != nullptr) {
+                            // Found an available record, so stop looking
+                            break;
+                        }
+                    }
+                }
+                if (idx >= mBuffers.size()) {
+                    // This shouldn't happen since we already checked mFramesInUse vs mFramesAllowed
+                    ALOGE("Failed to find an available buffer slot\n");
+                } else {
+                    // We're going to make the frame busy
+                    mBuffers[idx].inUse = true;
+                    mFramesInUse++;
+                    timeForFrame = true;
+                }
+            }
+        }
+
+        if (timeForFrame) {
+            using AidlPixelFormat = ::aidl::android::hardware::graphics::common::PixelFormat;
+
+            // Assemble the buffer description we'll transmit below
+            buffer_handle_t memHandle = mBuffers[idx].handle;
+            BufferDesc newBuffer = {
+                    .buffer =
+                            {
+                                    .description =
+                                            {
+                                                    .width = static_cast<int32_t>(mWidth),
+                                                    .height = static_cast<int32_t>(mHeight),
+                                                    .layers = 1,
+                                                    .format = static_cast<AidlPixelFormat>(mFormat),
+                                                    .usage = static_cast<BufferUsage>(mUsage),
+                                                    .stride = static_cast<int32_t>(mStride),
+                                            },
+                                    .handle = ::android::dupToAidl(memHandle),
+                            },
+                    .bufferId = static_cast<int32_t>(idx),
+                    .deviceId = mDescription.id,
+                    .timestamp = static_cast<int64_t>(::android::elapsedRealtimeNano() *
+                                                      1e+3),  // timestamps is in microseconds
+            };
+
+            // Write test data into the image buffer
+            fillMockFrame(memHandle, reinterpret_cast<const AHardwareBuffer_Desc*>(
+                                             &newBuffer.buffer.description));
+
+            // Issue the (asynchronous) callback to the client -- can't be holding the lock
+            auto flag = false;
+            if (mStream) {
+                std::vector<BufferDesc> frames;
+                frames.push_back(std::move(newBuffer));
+                flag = mStream->deliverFrame(frames).isOk();
+            }
+
+            if (flag) {
+                LOG(DEBUG) << "Delivered " << memHandle << ", id = " << mBuffers[idx].handle;
+            } else {
+                // This can happen if the client dies and is likely unrecoverable.
+                // To avoid consuming resources generating failing calls, we stop sending
+                // frames.  Note, however, that the stream remains in the "STREAMING" state
+                // until cleaned up on the main thread.
+                LOG(ERROR) << "Frame delivery call failed in the transport layer.";
+
+                // Since we didn't actually deliver it, mark the frame as available
+                std::lock_guard<std::mutex> lock(mAccessLock);
+                mBuffers[idx].inUse = false;
+                mFramesInUse--;
+            }
+        }
+
+        // We arbitrarily choose to generate frames at 15 fps to ensure we pass the 10fps test
+        // requirement
+        static const int kTargetFrameRate = 15;
+        static const nsecs_t kTargetFrameIntervalUs = 1000 * 1000 / kTargetFrameRate;
+        const nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+        const nsecs_t elapsedTimeUs = (now - startTime) / 1000;
+        const nsecs_t sleepDurationUs = kTargetFrameIntervalUs - elapsedTimeUs;
+        if (sleepDurationUs > 0) {
+            usleep(sleepDurationUs);
+        }
+    }
+
+    // If we've been asked to stop, send an event to signal the actual end of stream
+    EvsEventDesc event = {
+            .aType = EvsEventType::STREAM_STOPPED,
+    };
+    if (!mStream->notify(event).isOk()) {
+        ALOGE("Error delivering end of stream marker");
+    }
+
+    return;
+}
+
+void EvsMockCamera::fillMockFrame(buffer_handle_t handle, const AHardwareBuffer_Desc* pDesc) {
+    // Lock our output buffer for writing
+    uint32_t* pixels = nullptr;
+    ::android::GraphicBufferMapper& mapper = ::android::GraphicBufferMapper::get();
+    mapper.lock(handle, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_NEVER,
+                ::android::Rect(pDesc->width, pDesc->height), (void**)&pixels);
+
+    // If we failed to lock the pixel buffer, we're about to crash, but log it first
+    if (!pixels) {
+        ALOGE("Camera failed to gain access to image buffer for writing");
+        return;
+    }
+
+    // Fill in the test pixels; the colorbar in ABGR format
+    for (unsigned row = 0; row < pDesc->height; row++) {
+        for (unsigned col = 0; col < pDesc->width; col++) {
+            const uint32_t index = col * kNumColors / pDesc->width;
+            pixels[col] = kColors[index];
+        }
+        // Point to the next row
+        // NOTE:  stride retrieved from gralloc is in units of pixels
+        pixels = pixels + pDesc->stride;
+    }
+
+    // Release our output buffer
+    mapper.unlock(handle);
+}
+
+void EvsMockCamera::returnBufferLocked(const uint32_t bufferId) {
+    if (bufferId >= mBuffers.size()) {
+        ALOGE("ignoring doneWithFrame called with invalid bufferId %d (max is %zu)", bufferId,
+              mBuffers.size() - 1);
+        return;
+    }
+
+    if (!mBuffers[bufferId].inUse) {
+        ALOGE("ignoring doneWithFrame called on frame %d which is already free", bufferId);
+        return;
+    }
+
+    // Mark the frame as available
+    mBuffers[bufferId].inUse = false;
+    mFramesInUse--;
+
+    // If this frame's index is high in the array, try to move it down
+    // to improve locality after mFramesAllowed has been reduced.
+    if (bufferId >= mFramesAllowed) {
+        // Find an empty slot lower in the array (which should always exist in this case)
+        for (auto&& rec : mBuffers) {
+            if (rec.handle == nullptr) {
+                rec.handle = mBuffers[bufferId].handle;
+                mBuffers[bufferId].handle = nullptr;
+                break;
+            }
+        }
+    }
+}
+
+std::shared_ptr<EvsMockCamera> EvsMockCamera::Create(const char* deviceName) {
+    std::unique_ptr<ConfigManager::CameraInfo> nullCamInfo = nullptr;
+
+    return Create(deviceName, nullCamInfo);
+}
+
+std::shared_ptr<EvsMockCamera> EvsMockCamera::Create(
+        const char* deviceName, std::unique_ptr<ConfigManager::CameraInfo>& camInfo,
+        [[maybe_unused]] const Stream* streamCfg) {
+    std::shared_ptr<EvsMockCamera> c =
+            ndk::SharedRefBase::make<EvsMockCamera>(Sigil{}, deviceName, camInfo);
+    if (!c) {
+        LOG(ERROR) << "Failed to instantiate EvsMockCamera.";
+        return nullptr;
+    }
+
+    // Use the first resolution from the list for the testing
+    // TODO(b/214835237): Uses a given Stream configuration to choose the best
+    // stream configuration.
+    auto it = camInfo->streamConfigurations.begin();
+    c->mWidth = it->second.width;
+    c->mHeight = it->second.height;
+    c->mDescription.vendorFlags = 0xFFFFFFFF;  // Arbitrary test value
+
+    c->mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+    c->mUsage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE |
+                GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY;
+
+    return c;
+}
+
+}  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/GlWrapper.cpp b/automotive/evs/aidl/impl/default/src/GlWrapper.cpp
new file mode 100644
index 0000000..0ee5ecb
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/GlWrapper.cpp
@@ -0,0 +1,465 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GlWrapper.h"
+
+#include <aidl/android/frameworks/automotive/display/DisplayDesc.h>
+#include <aidl/android/hardware/graphics/common/HardwareBufferDescription.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <ui/DisplayMode.h>
+#include <ui/DisplayState.h>
+#include <ui/GraphicBuffer.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+
+#include <utility>
+
+namespace {
+
+using ::aidl::android::frameworks::automotive::display::DisplayDesc;
+using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
+using ::aidl::android::frameworks::automotive::display::Rotation;
+using ::aidl::android::hardware::common::NativeHandle;
+using ::aidl::android::hardware::graphics::common::HardwareBufferDescription;
+using ::android::GraphicBuffer;
+using ::android::sp;
+
+constexpr const char vertexShaderSource[] =
+        "attribute vec4 pos;                  \n"
+        "attribute vec2 tex;                  \n"
+        "varying vec2 uv;                     \n"
+        "void main()                          \n"
+        "{                                    \n"
+        "   gl_Position = pos;                \n"
+        "   uv = tex;                         \n"
+        "}                                    \n";
+
+constexpr const char pixelShaderSource[] =
+        "precision mediump float;              \n"
+        "uniform sampler2D tex;                \n"
+        "varying vec2 uv;                      \n"
+        "void main()                           \n"
+        "{                                     \n"
+        "    gl_FragColor = texture2D(tex, uv);\n"
+        "}                                     \n";
+
+const char* getEGLError(void) {
+    switch (eglGetError()) {
+        case EGL_SUCCESS:
+            return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:
+            return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:
+            return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:
+            return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:
+            return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONTEXT:
+            return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CONFIG:
+            return "EGL_BAD_CONFIG";
+        case EGL_BAD_CURRENT_SURFACE:
+            return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:
+            return "EGL_BAD_DISPLAY";
+        case EGL_BAD_SURFACE:
+            return "EGL_BAD_SURFACE";
+        case EGL_BAD_MATCH:
+            return "EGL_BAD_MATCH";
+        case EGL_BAD_PARAMETER:
+            return "EGL_BAD_PARAMETER";
+        case EGL_BAD_NATIVE_PIXMAP:
+            return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW:
+            return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_CONTEXT_LOST:
+            return "EGL_CONTEXT_LOST";
+        default:
+            return "Unknown error";
+    }
+}
+
+// Given shader source, load and compile it
+GLuint loadShader(GLenum type, const char* shaderSrc) {
+    // Create the shader object
+    GLuint shader = glCreateShader(type);
+    if (shader == 0) {
+        return 0;
+    }
+
+    // Load and compile the shader
+    glShaderSource(shader, 1, &shaderSrc, nullptr);
+    glCompileShader(shader);
+
+    // Verify the compilation worked as expected
+    GLint compiled = 0;
+    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+    if (!compiled) {
+        LOG(ERROR) << "Error compiling shader";
+
+        GLint size = 0;
+        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
+        if (size > 0) {
+            // Get and report the error message
+            char* infoLog = (char*)malloc(size);
+            glGetShaderInfoLog(shader, size, nullptr, infoLog);
+            LOG(ERROR) << "  msg:" << std::endl << infoLog;
+            free(infoLog);
+        }
+
+        glDeleteShader(shader);
+        return 0;
+    }
+
+    return shader;
+}
+
+// Create a program object given vertex and pixels shader source
+GLuint buildShaderProgram(const char* vtxSrc, const char* pxlSrc) {
+    GLuint program = glCreateProgram();
+    if (program == 0) {
+        LOG(ERROR) << "Failed to allocate program object";
+        return 0;
+    }
+
+    // Compile the shaders and bind them to this program
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vtxSrc);
+    if (vertexShader == 0) {
+        LOG(ERROR) << "Failed to load vertex shader";
+        glDeleteProgram(program);
+        return 0;
+    }
+    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pxlSrc);
+    if (pixelShader == 0) {
+        LOG(ERROR) << "Failed to load pixel shader";
+        glDeleteProgram(program);
+        glDeleteShader(vertexShader);
+        return 0;
+    }
+    glAttachShader(program, vertexShader);
+    glAttachShader(program, pixelShader);
+
+    glBindAttribLocation(program, 0, "pos");
+    glBindAttribLocation(program, 1, "tex");
+
+    // Link the program
+    glLinkProgram(program);
+    GLint linked = 0;
+    glGetProgramiv(program, GL_LINK_STATUS, &linked);
+    if (!linked) {
+        LOG(ERROR) << "Error linking program";
+        GLint size = 0;
+        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &size);
+        if (size > 0) {
+            // Get and report the error message
+            char* infoLog = (char*)malloc(size);
+            glGetProgramInfoLog(program, size, nullptr, infoLog);
+            LOG(ERROR) << "  msg:  " << infoLog;
+            free(infoLog);
+        }
+
+        glDeleteProgram(program);
+        glDeleteShader(vertexShader);
+        glDeleteShader(pixelShader);
+        return 0;
+    }
+
+    return program;
+}
+
+::android::sp<HGraphicBufferProducer> convertNativeHandleToHGBP(const NativeHandle& aidlHandle) {
+    native_handle_t* handle = ::android::dupFromAidl(aidlHandle);
+    if (handle->numFds != 0 || handle->numInts < std::ceil(sizeof(size_t) / sizeof(int))) {
+        LOG(ERROR) << "Invalid native handle";
+        return nullptr;
+    }
+    ::android::hardware::hidl_vec<uint8_t> halToken;
+    halToken.setToExternal(reinterpret_cast<uint8_t*>(const_cast<int*>(&(handle->data[1]))),
+                           handle->data[0]);
+    ::android::sp<HGraphicBufferProducer> hgbp =
+            HGraphicBufferProducer::castFrom(::android::retrieveHalInterface(halToken));
+    return std::move(hgbp);
+}
+
+}  // namespace
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+// Main entry point
+bool GlWrapper::initialize(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy,
+                           uint64_t displayId) {
+    LOG(DEBUG) << __FUNCTION__;
+
+    if (!pWindowProxy) {
+        LOG(ERROR) << "Could not get ICarDisplayProxy.";
+        return false;
+    }
+
+    DisplayDesc displayDesc;
+    auto status = pWindowProxy->getDisplayInfo(displayId, &displayDesc);
+    if (!status.isOk()) {
+        LOG(ERROR) << "Failed to read the display information";
+        return false;
+    }
+
+    mWidth = displayDesc.width;
+    mHeight = displayDesc.height;
+    if ((displayDesc.orientation != Rotation::ROTATION_0) &&
+        (displayDesc.orientation != Rotation::ROTATION_180)) {
+        std::swap(mWidth, mHeight);
+    }
+    LOG(INFO) << "Display resolution is " << mWidth << "x" << mHeight;
+
+    NativeHandle aidlHandle;
+    status = pWindowProxy->getHGraphicBufferProducer(displayId, &aidlHandle);
+    if (!status.isOk()) {
+        LOG(ERROR) << "Failed to get IGraphicBufferProducer from ICarDisplayProxy.";
+        return false;
+    }
+
+    mGfxBufferProducer = convertNativeHandleToHGBP(aidlHandle);
+    if (!mGfxBufferProducer) {
+        LOG(ERROR) << "Failed to convert a NativeHandle to HGBP.";
+        return false;
+    }
+
+    mSurfaceHolder = getSurfaceFromHGBP(mGfxBufferProducer);
+    if (mSurfaceHolder == nullptr) {
+        LOG(ERROR) << "Failed to get a Surface from HGBP.";
+        return false;
+    }
+
+    mWindow = getNativeWindow(mSurfaceHolder.get());
+    if (mWindow == nullptr) {
+        LOG(ERROR) << "Failed to get a native window from Surface.";
+        return false;
+    }
+
+    // Set up our OpenGL ES context associated with the default display
+    mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    if (mDisplay == EGL_NO_DISPLAY) {
+        LOG(ERROR) << "Failed to get egl display";
+        return false;
+    }
+
+    EGLint major = 2;
+    EGLint minor = 0;
+    if (!eglInitialize(mDisplay, &major, &minor)) {
+        LOG(ERROR) << "Failed to initialize EGL: " << getEGLError();
+        return false;
+    }
+
+    const EGLint config_attribs[] = {
+            // clang-format off
+            // Tag          Value
+            EGL_RED_SIZE,   8,
+            EGL_GREEN_SIZE, 8,
+            EGL_BLUE_SIZE,  8,
+            EGL_DEPTH_SIZE, 0,
+            EGL_NONE
+            // clang-format on
+    };
+
+    // Pick the default configuration without constraints (is this good enough?)
+    EGLConfig egl_config = {0};
+    EGLint numConfigs = -1;
+    eglChooseConfig(mDisplay, config_attribs, &egl_config, 1, &numConfigs);
+    if (numConfigs != 1) {
+        LOG(ERROR) << "Didn't find a suitable format for our display window, " << getEGLError();
+        return false;
+    }
+
+    // Create the EGL render target surface
+    mSurface = eglCreateWindowSurface(mDisplay, egl_config, mWindow, nullptr);
+    if (mSurface == EGL_NO_SURFACE) {
+        LOG(ERROR) << "eglCreateWindowSurface failed, " << getEGLError();
+        return false;
+    }
+
+    // Create the EGL context
+    // NOTE:  Our shader is (currently at least) written to require version 3, so this
+    //        is required.
+    const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
+    mContext = eglCreateContext(mDisplay, egl_config, EGL_NO_CONTEXT, context_attribs);
+    if (mContext == EGL_NO_CONTEXT) {
+        LOG(ERROR) << "Failed to create OpenGL ES Context: " << getEGLError();
+        return false;
+    }
+
+    // Activate our render target for drawing
+    if (!eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)) {
+        LOG(ERROR) << "Failed to make the OpenGL ES Context current: " << getEGLError();
+        return false;
+    }
+
+    // Create the shader program for our simple pipeline
+    mShaderProgram = buildShaderProgram(vertexShaderSource, pixelShaderSource);
+    if (!mShaderProgram) {
+        LOG(ERROR) << "Failed to build shader program: " << getEGLError();
+        return false;
+    }
+
+    // Create a GL texture that will eventually wrap our externally created texture surface(s)
+    glGenTextures(1, &mTextureMap);
+    if (mTextureMap <= 0) {
+        LOG(ERROR) << "Didn't get a texture handle allocated: " << getEGLError();
+        return false;
+    }
+
+    // Turn off mip-mapping for the created texture surface
+    // (the inbound camera imagery doesn't have MIPs)
+    glBindTexture(GL_TEXTURE_2D, mTextureMap);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glBindTexture(GL_TEXTURE_2D, 0);
+
+    return true;
+}
+
+void GlWrapper::shutdown() {
+    // Drop our device textures
+    if (mKHRimage != EGL_NO_IMAGE_KHR) {
+        eglDestroyImageKHR(mDisplay, mKHRimage);
+        mKHRimage = EGL_NO_IMAGE_KHR;
+    }
+
+    // Release all GL resources
+    if (eglGetCurrentContext() == mContext) {
+        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    }
+    eglDestroySurface(mDisplay, mSurface);
+    eglDestroyContext(mDisplay, mContext);
+    eglTerminate(mDisplay);
+    mSurface = EGL_NO_SURFACE;
+    mContext = EGL_NO_CONTEXT;
+    mDisplay = EGL_NO_DISPLAY;
+
+    // Release the window
+    mSurfaceHolder = nullptr;
+}
+
+void GlWrapper::showWindow(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy, uint64_t id) {
+    if (pWindowProxy) {
+        pWindowProxy->showWindow(id);
+    } else {
+        LOG(ERROR) << "ICarDisplayProxy is not available.";
+    }
+}
+
+void GlWrapper::hideWindow(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy, uint64_t id) {
+    if (pWindowProxy) {
+        pWindowProxy->hideWindow(id);
+    } else {
+        LOG(ERROR) << "ICarDisplayProxy is not available.";
+    }
+}
+
+bool GlWrapper::updateImageTexture(buffer_handle_t handle,
+                                   const HardwareBufferDescription& description) {
+    if (mKHRimage != EGL_NO_IMAGE_KHR) {
+        return true;
+    }
+
+    // Create a temporary GraphicBuffer to wrap the provided handle.
+    sp<GraphicBuffer> pGfxBuffer =
+            new GraphicBuffer(description.width, description.height,
+                              static_cast<::android::PixelFormat>(description.format),
+                              description.layers, static_cast<uint32_t>(description.usage),
+                              description.stride, const_cast<native_handle_t*>(handle),
+                              /* keepOwnership= */ false);
+    if (!pGfxBuffer) {
+        LOG(ERROR) << "Failed to allocate GraphicBuffer to wrap our native handle";
+        return false;
+    }
+
+    // Get a GL compatible reference to the graphics buffer we've been given
+    EGLint eglImageAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
+    EGLClientBuffer cbuf = static_cast<EGLClientBuffer>(pGfxBuffer->getNativeBuffer());
+    mKHRimage = eglCreateImageKHR(mDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, cbuf,
+                                  eglImageAttributes);
+    if (mKHRimage == EGL_NO_IMAGE_KHR) {
+        LOG(ERROR) << "Error creating EGLImage: " << getEGLError();
+        return false;
+    }
+
+    // Update the texture handle we already created to refer to this gralloc buffer
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, mTextureMap);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, static_cast<GLeglImageOES>(mKHRimage));
+
+    return true;
+}
+
+void GlWrapper::renderImageToScreen() {
+    // Set the viewport
+    glViewport(0, 0, mWidth, mHeight);
+
+    // Clear the color buffer
+    glClearColor(0.1f, 0.5f, 0.1f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    // Select our screen space simple texture shader
+    glUseProgram(mShaderProgram);
+
+    // Bind the texture and assign it to the shader's sampler
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, mTextureMap);
+    GLint sampler = glGetUniformLocation(mShaderProgram, "tex");
+    glUniform1i(sampler, 0);
+
+    // We want our image to show up opaque regardless of alpha values
+    glDisable(GL_BLEND);
+
+    // Draw a rectangle on the screen
+    GLfloat vertsCarPos[] = {
+            // clang-format off
+            -0.8,  0.8, 0.0f,  // left top in window space
+             0.8,  0.8, 0.0f,  // right top
+            -0.8, -0.8, 0.0f,  // left bottom
+             0.8, -0.8, 0.0f   // right bottom
+            // clang-format on
+    };
+
+    // NOTE:  We didn't flip the image in the texture, so V=0 is actually the top of the image
+    GLfloat vertsCarTex[] = {
+            // clang-format off
+            0.0f, 0.0f,  // left top
+            1.0f, 0.0f,  // right top
+            0.0f, 1.0f,  // left bottom
+            1.0f, 1.0f   // right bottom
+            // clang-format on
+    };
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertsCarPos);
+    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vertsCarTex);
+    glEnableVertexAttribArray(0);
+    glEnableVertexAttribArray(1);
+
+    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+    // Clean up and flip the rendered result to the front so it is visible
+    glDisableVertexAttribArray(0);
+    glDisableVertexAttribArray(1);
+
+    glFinish();
+
+    if (eglSwapBuffers(mDisplay, mSurface) == EGL_FALSE) {
+        LOG(WARNING) << "Failed to swap EGL buffers, " << getEGLError();
+    }
+}
+
+}  // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/service.cpp b/automotive/evs/aidl/impl/default/src/service.cpp
index 0a0913f..7532d87 100644
--- a/automotive/evs/aidl/impl/default/src/service.cpp
+++ b/automotive/evs/aidl/impl/default/src/service.cpp
@@ -14,38 +14,75 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "EvsService"
-
-#include <DefaultEvsEnumerator.h>
+#include "EvsEnumerator.h"
+#include "EvsGlDisplay.h"
 
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <utils/Log.h>
 
-using ::aidl::android::hardware::automotive::evs::implementation::DefaultEvsEnumerator;
+#include <unistd.h>
 
-int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) {
-    std::shared_ptr<DefaultEvsEnumerator> vhal = ndk::SharedRefBase::make<DefaultEvsEnumerator>();
+#include <atomic>
+#include <cstdlib>
+#include <string_view>
 
-    ALOGI("Registering as service...");
-    binder_exception_t err =
-            AServiceManager_addService(vhal->asBinder().get(), "android.hardware.automotive.evs");
+namespace {
+
+using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
+using ::aidl::android::hardware::automotive::evs::implementation::EvsEnumerator;
+
+constexpr std::string_view kDisplayServiceInstanceName = "/default";
+constexpr std::string_view kHwInstanceName = "/hw/0";
+constexpr int kNumBinderThreads = 1;
+
+}  // namespace
+
+int main() {
+    LOG(INFO) << "EVS Hardware Enumerator service is starting";
+
+    const std::string displayServiceInstanceName =
+            std::string(ICarDisplayProxy::descriptor) + std::string(kDisplayServiceInstanceName);
+    if (!AServiceManager_isDeclared(displayServiceInstanceName.data())) {
+        // TODO: We may just want to disable EVS display.
+        LOG(ERROR) << displayServiceInstanceName << " is required.";
+        return EXIT_FAILURE;
+    }
+
+    std::shared_ptr<ICarDisplayProxy> displayService = ICarDisplayProxy::fromBinder(
+            ::ndk::SpAIBinder(AServiceManager_waitForService(displayServiceInstanceName.data())));
+    if (!displayService) {
+        LOG(ERROR) << "Cannot use " << displayServiceInstanceName << ".  Exiting.";
+        return EXIT_FAILURE;
+    }
+
+    // Register our service -- if somebody is already registered by our name,
+    // they will be killed (their thread pool will throw an exception).
+    std::shared_ptr<EvsEnumerator> service =
+            ndk::SharedRefBase::make<EvsEnumerator>(displayService);
+    if (!service) {
+        LOG(ERROR) << "Failed to instantiate the service";
+        return EXIT_FAILURE;
+    }
+
+    const std::string instanceName =
+            std::string(EvsEnumerator::descriptor) + std::string(kHwInstanceName);
+    auto err = AServiceManager_addService(service->asBinder().get(), instanceName.data());
     if (err != EX_NONE) {
-        ALOGE("failed to register android.hardware.automotive.evs service, exception: %d", err);
-        return 1;
+        LOG(ERROR) << "Failed to register " << instanceName << ", exception = " << err;
+        return EXIT_FAILURE;
     }
 
-    if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
-        ALOGE("%s", "failed to set thread pool max thread count");
-        return 1;
+    if (!ABinderProcess_setThreadPoolMaxThreadCount(kNumBinderThreads)) {
+        LOG(ERROR) << "Failed to set thread pool";
+        return EXIT_FAILURE;
     }
+
     ABinderProcess_startThreadPool();
-
-    ALOGI("Evs Service Ready");
+    LOG(INFO) << "EVS Hardware Enumerator is ready";
 
     ABinderProcess_joinThreadPool();
-
-    ALOGI("Evs Service Exiting");
-
-    return 0;
+    // In normal operation, we don't expect the thread pool to exit
+    LOG(INFO) << "EVS Hardware Enumerator is shutting down";
+    return EXIT_SUCCESS;
 }
diff --git a/automotive/evs/aidl/vts/Android.bp b/automotive/evs/aidl/vts/Android.bp
index 980c6d5..e50c913 100644
--- a/automotive/evs/aidl/vts/Android.bp
+++ b/automotive/evs/aidl/vts/Android.bp
@@ -14,23 +14,23 @@
 // limitations under the License.
 //
 
-package{
+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"],
+    default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
 cc_test {
-name:
-    "VtsHalEvsTargetTest",
+    name: "VtsHalEvsTargetTest",
     srcs: [
         "*.cpp",
     ],
     defaults: [
         "VtsHalTargetTestDefaults",
+        "android.hardware.graphics.common-ndk_static",
         "use_libaidlvintf_gtest_helper_static",
     ],
     shared_libs: [
@@ -41,9 +41,8 @@
     ],
     static_libs: [
         "android.hardware.automotive.evs@common-default-lib",
-        "android.hardware.automotive.evs-V1-ndk",
+        "android.hardware.automotive.evs-V2-ndk",
         "android.hardware.common-V2-ndk",
-        "android.hardware.graphics.common-V3-ndk",
         "libaidlcommonsupport",
     ],
     test_suites: [
diff --git a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
index 3cab204..3419b3c 100644
--- a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
+++ b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
@@ -51,6 +51,7 @@
 #include <ui/GraphicBufferAllocator.h>
 #include <utils/Timers.h>
 
+#include <chrono>
 #include <deque>
 #include <thread>
 #include <unordered_set>
@@ -619,6 +620,7 @@
         getPhysicalCameraIds(cam.id, isLogicalCam);
         if (mIsHwModule && isLogicalCam) {
             LOG(INFO) << "Skip a logical device " << cam.id << " for HW target.";
+            ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
             continue;
         }
 
@@ -1437,7 +1439,8 @@
         ASSERT_TRUE(pCam1->getParameterList(&cam1Cmds).isOk());
         if (cam0Cmds.size() < 1 || cam1Cmds.size() < 1) {
             // Cannot execute this test.
-            return;
+            ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
+            continue;
         }
 
         // Set up a frame receiver object which will fire up its own thread.
@@ -2195,6 +2198,207 @@
     }
 }
 
+/*
+ * DisplayOpen:
+ * Test both clean shut down and "aggressive open" device stealing behavior.
+ */
+TEST_P(EvsAidlTest, DisplayOpen) {
+    LOG(INFO) << "Starting DisplayOpen test";
+
+    // Request available display IDs.
+    std::vector<uint8_t> displayIds;
+    ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
+    EXPECT_GT(displayIds.size(), 0);
+
+    for (const auto displayId : displayIds) {
+        std::shared_ptr<IEvsDisplay> pDisplay;
+
+        // Request exclusive access to each EVS display, then let it go.
+        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+        ASSERT_NE(pDisplay, nullptr);
+
+        {
+            // Ask the display what its name is.
+            DisplayDesc desc;
+            ASSERT_TRUE(pDisplay->getDisplayInfo(&desc).isOk());
+            LOG(DEBUG) << "Found display " << desc.id;
+        }
+
+        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
+
+        // Ensure we can reopen the display after it has been closed.
+        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+        ASSERT_NE(pDisplay, nullptr);
+
+        // Open the display while its already open -- ownership should be transferred.
+        std::shared_ptr<IEvsDisplay> pDisplay2;
+        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay2).isOk());
+        ASSERT_NE(pDisplay2, nullptr);
+
+        {
+            // Ensure the old display properly reports its assassination.
+            DisplayState badState;
+            EXPECT_TRUE(pDisplay->getDisplayState(&badState).isOk());
+            EXPECT_EQ(badState, DisplayState::DEAD);
+        }
+
+        // Close only the newest display instance -- the other should already be a zombie.
+        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay2).isOk());
+
+        // Finally, validate that we can open the display after the provoked failure above.
+        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+        ASSERT_NE(pDisplay, nullptr);
+        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
+    }
+}
+
+/*
+ * DisplayStates:
+ * Validate that display states transition as expected and can be queried from either the display
+ * object itself or the owning enumerator.
+ */
+TEST_P(EvsAidlTest, DisplayStates) {
+    using std::literals::chrono_literals::operator""ms;
+
+    LOG(INFO) << "Starting DisplayStates test";
+
+    // Request available display IDs.
+    std::vector<uint8_t> displayIds;
+    ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
+    EXPECT_GT(displayIds.size(), 0);
+
+    for (const auto displayId : displayIds) {
+        // Ensure the display starts in the expected state.
+        {
+            DisplayState state;
+            EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
+        }
+        for (const auto displayIdToQuery : displayIds) {
+            DisplayState state;
+            EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+        }
+
+        // Scope to limit the lifetime of the pDisplay pointer, and thus the IEvsDisplay object.
+        {
+            // Request exclusive access to the EVS display.
+            std::shared_ptr<IEvsDisplay> pDisplay;
+            ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+            ASSERT_NE(pDisplay, nullptr);
+            {
+                DisplayState state;
+                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+                EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+            }
+            for (const auto displayIdToQuery : displayIds) {
+                DisplayState state;
+                bool get_state_ok =
+                        mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk();
+                if (displayIdToQuery != displayId) {
+                    EXPECT_FALSE(get_state_ok);
+                } else if (get_state_ok) {
+                    EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+                }
+            }
+
+            // Activate the display.
+            EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME).isOk());
+            {
+                DisplayState state;
+                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+                EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
+            }
+            {
+                DisplayState state;
+                EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
+                EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
+            }
+            for (const auto displayIdToQuery : displayIds) {
+                DisplayState state;
+                bool get_state_ok =
+                        mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk();
+                if (displayIdToQuery != displayId) {
+                    EXPECT_FALSE(get_state_ok);
+                } else if (get_state_ok) {
+                    EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
+                }
+            }
+
+            // Get the output buffer we'd use to display the imagery.
+            BufferDesc tgtBuffer;
+            ASSERT_TRUE(pDisplay->getTargetBuffer(&tgtBuffer).isOk());
+
+            // Send the target buffer back for display (we didn't actually fill anything).
+            EXPECT_TRUE(pDisplay->returnTargetBufferForDisplay(tgtBuffer).isOk());
+
+            // Sleep for a tenth of a second to ensure the driver has time to get the image
+            // displayed.
+            std::this_thread::sleep_for(100ms);
+            {
+                DisplayState state;
+                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+                EXPECT_EQ(state, DisplayState::VISIBLE);
+            }
+            {
+                DisplayState state;
+                EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
+                EXPECT_EQ(state, DisplayState::VISIBLE);
+            }
+            for (const auto displayIdToQuery : displayIds) {
+                DisplayState state;
+                bool get_state_ok =
+                        mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk();
+                if (displayIdToQuery != displayId) {
+                    EXPECT_FALSE(get_state_ok);
+                } else if (get_state_ok) {
+                    EXPECT_EQ(state, DisplayState::VISIBLE);
+                }
+            }
+
+            // Turn off the display.
+            EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::NOT_VISIBLE).isOk());
+            std::this_thread::sleep_for(100ms);
+            {
+                DisplayState state;
+                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+                EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+            }
+            {
+                DisplayState state;
+                EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
+                EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+            }
+            for (const auto displayIdToQuery : displayIds) {
+                DisplayState state;
+                bool get_state_ok =
+                        mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk();
+                if (displayIdToQuery != displayId) {
+                    EXPECT_FALSE(get_state_ok);
+                } else if (get_state_ok) {
+                    EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+                }
+            }
+
+            // Close the display.
+            mEnumerator->closeDisplay(pDisplay);
+        }
+
+        // Now that the display pointer has gone out of scope, causing the IEvsDisplay interface
+        // object to be destroyed, we should be back to the "not open" state.
+        // NOTE:  If we want this to pass without the sleep above, we'd have to add the
+        //        (now recommended) closeDisplay() call instead of relying on the smarter pointer
+        //        going out of scope.  I've not done that because I want to verify that the deletion
+        //        of the object does actually clean up (eventually).
+        {
+            DisplayState state;
+            EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
+        }
+        for (const auto displayIdToQuery : displayIds) {
+            DisplayState state;
+            EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+        }
+    }
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EvsAidlTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, EvsAidlTest,
diff --git a/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp b/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp
index 58423c8..7f90501 100644
--- a/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp
+++ b/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp
@@ -32,9 +32,10 @@
 
     // API have a requirement that width must be divied by 16 except yuyvtorgb
     int min_height = 2;
-    int max_height = (image_pixel_size / 16) & ~(1);  // must be even number
+    int max_height = (image_pixel_size / 16);
     int height = fdp.ConsumeIntegralInRange<uint32_t>(min_height, max_height);
-    int width = (image_pixel_size / height) & ~(16);  // must be divisible by 16
+    height &= ~(1);  // must be even number
+    int width = (image_pixel_size / height) & ~(0xF);  // must be divisible by 16
 
     uint8_t* src = (uint8_t*)(data + 4);
     uint32_t* tgt = (uint32_t*)malloc(sizeof(uint32_t) * image_pixel_size);
diff --git a/automotive/ivn_android_device/aidl/Android.bp b/automotive/ivn_android_device/aidl/Android.bp
new file mode 100644
index 0000000..9af709f
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/Android.bp
@@ -0,0 +1,51 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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"],
+}
+
+aidl_interface {
+    name: "android.hardware.automotive.ivn",
+    vendor_available: true,
+    srcs: [
+        "android/hardware/automotive/ivn/*.aidl",
+    ],
+    frozen: true,
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.car.framework",
+            ],
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/.hash b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/.hash
new file mode 100644
index 0000000..58de5d6
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/.hash
@@ -0,0 +1 @@
+50960edf7eaa130e8103dba62c96f62d7eac84bf
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/ConnectProtocol.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/ConnectProtocol.aidl
new file mode 100644
index 0000000..80d7a2a
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/ConnectProtocol.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@Backing(type="int") @VintfStability
+enum ConnectProtocol {
+  TCP_IP = 0,
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/EndpointInfo.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/EndpointInfo.aidl
new file mode 100644
index 0000000..5693520
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/EndpointInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable EndpointInfo {
+  android.hardware.automotive.ivn.ConnectProtocol connectProtocol;
+  String ipAddress;
+  int portNumber;
+  android.hardware.automotive.ivn.HardwareIdentifiers hardwareId;
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/HardwareIdentifiers.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/HardwareIdentifiers.aidl
new file mode 100644
index 0000000..1a8b21d
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/HardwareIdentifiers.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable HardwareIdentifiers {
+  @nullable String brandName;
+  @nullable String deviceName;
+  @nullable String productName;
+  @nullable String manufacturerName;
+  @nullable String modelName;
+  @nullable String serialNumber;
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl
new file mode 100644
index 0000000..a04d829
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@VintfStability
+interface IIvnAndroidDevice {
+  int getMyDeviceId();
+  int[] getOtherDeviceIds();
+  int getDeviceIdForOccupantZone(int zoneId);
+  android.hardware.automotive.ivn.OccupantZoneInfo[] getOccupantZonesForDevice(int androidDeviceId);
+  android.hardware.automotive.ivn.EndpointInfo getMyEndpointInfo();
+  android.hardware.automotive.ivn.EndpointInfo getEndpointInfoForDevice(int androidDeviceId);
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/OccupantType.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/OccupantType.aidl
new file mode 100644
index 0000000..6dd0c07
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/OccupantType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@Backing(type="int") @VintfStability
+enum OccupantType {
+  DRIVER = 1,
+  FRONT_PASSENGER = 2,
+  REAR_PASSENGER = 3,
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/OccupantZoneInfo.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/OccupantZoneInfo.aidl
new file mode 100644
index 0000000..41108e9
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/1/android/hardware/automotive/ivn/OccupantZoneInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable OccupantZoneInfo {
+  int zoneId;
+  android.hardware.automotive.ivn.OccupantType occupantType;
+  int seat;
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/ConnectProtocol.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/ConnectProtocol.aidl
new file mode 100644
index 0000000..80d7a2a
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/ConnectProtocol.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@Backing(type="int") @VintfStability
+enum ConnectProtocol {
+  TCP_IP = 0,
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/EndpointInfo.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/EndpointInfo.aidl
new file mode 100644
index 0000000..5693520
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/EndpointInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable EndpointInfo {
+  android.hardware.automotive.ivn.ConnectProtocol connectProtocol;
+  String ipAddress;
+  int portNumber;
+  android.hardware.automotive.ivn.HardwareIdentifiers hardwareId;
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/HardwareIdentifiers.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/HardwareIdentifiers.aidl
new file mode 100644
index 0000000..1a8b21d
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/HardwareIdentifiers.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable HardwareIdentifiers {
+  @nullable String brandName;
+  @nullable String deviceName;
+  @nullable String productName;
+  @nullable String manufacturerName;
+  @nullable String modelName;
+  @nullable String serialNumber;
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl
new file mode 100644
index 0000000..a04d829
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@VintfStability
+interface IIvnAndroidDevice {
+  int getMyDeviceId();
+  int[] getOtherDeviceIds();
+  int getDeviceIdForOccupantZone(int zoneId);
+  android.hardware.automotive.ivn.OccupantZoneInfo[] getOccupantZonesForDevice(int androidDeviceId);
+  android.hardware.automotive.ivn.EndpointInfo getMyEndpointInfo();
+  android.hardware.automotive.ivn.EndpointInfo getEndpointInfoForDevice(int androidDeviceId);
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantType.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantType.aidl
new file mode 100644
index 0000000..6dd0c07
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@Backing(type="int") @VintfStability
+enum OccupantType {
+  DRIVER = 1,
+  FRONT_PASSENGER = 2,
+  REAR_PASSENGER = 3,
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantZoneInfo.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantZoneInfo.aidl
new file mode 100644
index 0000000..41108e9
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantZoneInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.ivn;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable OccupantZoneInfo {
+  int zoneId;
+  android.hardware.automotive.ivn.OccupantType occupantType;
+  int seat;
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/ConnectProtocol.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/ConnectProtocol.aidl
new file mode 100644
index 0000000..9f621b3
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/ConnectProtocol.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.ivn;
+
+/**
+ * Connect protocol for In-vehicle network Android device.
+ */
+@VintfStability
+@Backing(type="int")
+enum ConnectProtocol {
+    TCP_IP = 0,
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/EndpointInfo.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/EndpointInfo.aidl
new file mode 100644
index 0000000..32f6971
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/EndpointInfo.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.ivn;
+
+import android.hardware.automotive.ivn.ConnectProtocol;
+import android.hardware.automotive.ivn.HardwareIdentifiers;
+
+/**
+ * Network endpoint information for an Android instance running on a difference device.
+ *
+ * The device is in the same vehicle as this device.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable EndpointInfo {
+    /**
+     * The connection protocol. Only supports TCP/IP for now.
+     */
+    ConnectProtocol connectProtocol;
+    /**
+     * The IP address.
+     */
+    String ipAddress;
+    /**
+     * The port number exposed for connecting.
+     */
+    int portNumber;
+    /**
+     * Hardware identifiers.
+     *
+     * The hardware identifiers for the endpoint as defined in [Attestation Hardware Identifiers]
+     * {@link
+     * https://source.android.com/docs/security/features/keystore/attestation#hardware-identifiers}
+     */
+    HardwareIdentifiers hardwareId;
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/HardwareIdentifiers.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/HardwareIdentifiers.aidl
new file mode 100644
index 0000000..ffa09e6
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/HardwareIdentifiers.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.ivn;
+
+/**
+ * Hardware Identifiers for an Android device.
+ *
+ * <p>These identifiers are embedded in the ID attestation certificate and are
+ * used to restrict what devices this device can connect to. All fields are
+ * optional but at least one of the fields must be specified.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable HardwareIdentifiers {
+    /**
+     * Optional brand name, as returned by {@code Build.BRAND} in Android.
+     *
+     * If unspecified, we assume the other device has the same brand name as this device.
+     */
+    @nullable String brandName;
+    /**
+     * Optional brand name, as returned by {@code Build.DEVICE} in Android.
+     *
+     * If unspecified, we assume the other device has the same device name as this device.
+     */
+    @nullable String deviceName;
+    /**
+     * Optional model name, as returned by {@code Build.PRODUCT} in Android.
+     *
+     * If unspecified, we assume the other device has the same product name as this device.
+     */
+    @nullable String productName;
+    /**
+     * Optional manufacturer name, as returned by {@code Build.MANUFACTURER} in Android.
+     *
+     * If unspecified, we assume the other device has the same manufacturer name as this device.
+     */
+    @nullable String manufacturerName;
+    /**
+     * Optional model name, as returned by {@code Build.MODEL} in Android.
+     *
+     * If unspecified, we assume the other device has the same model name as this device.
+     */
+    @nullable String modelName;
+    /**
+     * Optional serial number.
+     *
+     * If unspecified, we allow the endpoint to have any serial number.
+     */
+    @nullable String serialNumber;
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl
new file mode 100644
index 0000000..107b7a6
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.ivn;
+
+import android.hardware.automotive.ivn.EndpointInfo;
+import android.hardware.automotive.ivn.OccupantZoneInfo;
+
+/**
+ * Interface for In-Vehicle Network(IVN) Android devices.
+ *
+ * This is used in a multi-zone multi-SoC environment where there are multiple
+ * SoCs running Android in a vehicle. Each support one or multiple occupant
+ * zones. E.g., one SoC for front passenger, one SoC for backseat left-zone
+ * and middle/right zone passengers.
+ */
+@VintfStability
+interface IIvnAndroidDevice {
+    /**
+     * Returns the unique ID for this Android device.
+     *
+     * <p>This ID has to be unique among all the android devices in the whole vehicle. It is usually
+     * a hard-coded value, e.g. serial number.
+     *
+     * @return an ID representing this device.
+     */
+    int getMyDeviceId();
+
+    /**
+     * Returns a list of unique IDs for other IVN Android devices.
+     *
+     * The returned list does not contain the current Android device ID. This list is usually
+     * pre-configured for this HAL, either hard-coded or read from configuration file.
+     *
+     * @return A list of IDs representing connected Android devices.
+     */
+    int[] getOtherDeviceIds();
+
+    /**
+     * Returns the Android device ID for a specified occupant zone.
+     *
+     * @pararm zoneID the occupant zone ID returned from {@link android.car.CarOccupantZoneManager}.
+     * @return an ID representing an Android device.
+     */
+    int getDeviceIdForOccupantZone(int zoneId);
+
+    /**
+     * Returns all the occupant zones supported for a specified IVN Android device.
+     *
+     * @param androidDeviceId the android device ID.
+     * @return A list of supported occupant zone info.
+     */
+    OccupantZoneInfo[] getOccupantZonesForDevice(int androidDeviceId);
+
+    /**
+     * Returns the connection endpoint info for this android device.
+     *
+     * @return The endpoint info.
+     */
+    EndpointInfo getMyEndpointInfo();
+
+    /**
+     * Returns the connection endpoint info for the specified IVN Android device.
+     *
+     * @return The endpoint info.
+     */
+    EndpointInfo getEndpointInfoForDevice(int androidDeviceId);
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantType.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantType.aidl
new file mode 100644
index 0000000..72542a7
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.ivn;
+
+/**
+ * Occupant type.
+ *
+ * This enum might be extended in the future.
+ */
+@VintfStability
+@Backing(type="int")
+enum OccupantType {
+    /**
+     * Represents the driver. There can be one or zero driver for the system. Zero driver situation
+     * can happen if the system is configured to support only passengers.
+     */
+    DRIVER = 1,
+    /**
+     * Represents front passengers who sit in front side of car. Most cars will have only
+     * one passenger of this type but this can be multiple.
+     */
+    FRONT_PASSENGER = 2,
+    /** Represents passengers in rear seats. There can be multiple passengers of this type. */
+    REAR_PASSENGER = 3,
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantZoneInfo.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantZoneInfo.aidl
new file mode 100644
index 0000000..af45444
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantZoneInfo.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.ivn;
+
+import android.hardware.automotive.ivn.OccupantType;
+
+/**
+ * Represents an occupant zone in a car.
+ *
+ * <p>Each occupant does not necessarily represent single person but it is for mapping to one
+ * set of displays. For example, for display located in center rear seat, both left and right
+ * side passengers may use it but it is abstracted as a single occupant zone.</p>
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable OccupantZoneInfo {
+    /**
+     * This is an unique id to distinguish each occupant zone.
+     *
+     * <p>This can be helpful to distinguish different zones when {@link #occupantType} and
+     * {@link #seat} are the same for multiple occupant / passenger zones.</p>
+     *
+     * <p>This id will remain the same for the same zone across configuration changes like
+     * user switching or display changes</p>
+     */
+    int zoneId;
+    /** Represents type of passenger */
+    OccupantType occupantType;
+    /**
+     * Represents seat assigned for the occupant. In some system, this can have value of
+     * {@code VehicleAreaSeat#SEAT_UNKNOWN}.
+     *
+     * <p>This might be one of {@code VehicleAreaSeat} or a combination of {@code VehicleAreaSeat}.
+     */
+    int seat;
+}
diff --git a/automotive/ivn_android_device/impl/default/Android.bp b/automotive/ivn_android_device/impl/default/Android.bp
new file mode 100644
index 0000000..98c1f58
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/Android.bp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "IvnAndroidDeviceService",
+    vendor_available: true,
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    srcs: [
+        "src/IvnAndroidDeviceService.cpp",
+    ],
+    whole_static_libs: [
+        "android.hardware.automotive.ivn-V1-ndk",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libjsoncpp",
+        "liblog",
+        "libutils",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.automotive.ivn@V1-default-service",
+    vendor: true,
+    relative_install_path: "hw",
+    local_include_dirs: ["include"],
+    srcs: ["src/IvnAndroidDeviceImpl.cpp"],
+    whole_static_libs: ["IvnAndroidDeviceService"],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libjsoncpp",
+        "liblog",
+        "libutils",
+    ],
+    required: ["Prebuilt_IvnAndroidDeviceServiceDefaultConfig_JSON"],
+    vintf_fragments: ["ivn-default-service.xml"],
+    init_rc: ["ivn-default-service.rc"],
+}
diff --git a/automotive/ivn_android_device/impl/default/config/Android.bp b/automotive/ivn_android_device/impl/default/config/Android.bp
new file mode 100644
index 0000000..03c4d1b
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/config/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+    name: "IvnAndroidDeviceServiceDefaultConfig_Json",
+    srcs: ["DefaultConfig.json"],
+}
+
+prebuilt_etc {
+    name: "Prebuilt_IvnAndroidDeviceServiceDefaultConfig_JSON",
+    filename_from_src: true,
+    src: "DefaultConfig.json",
+    sub_dir: "automotive/IvnConfig/",
+    vendor: true,
+}
diff --git a/automotive/ivn_android_device/impl/default/config/DefaultConfig.json b/automotive/ivn_android_device/impl/default/config/DefaultConfig.json
new file mode 100644
index 0000000..45663e2
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/config/DefaultConfig.json
@@ -0,0 +1,61 @@
+{
+    "MyDeviceId": 0,
+    "Devices": [
+        {
+            "DeviceId": 0,
+            "OccupantZones": [
+                {
+                    "ZoneId": 0,
+                    "OccupantType": "DRIVER",
+                    "Seat": 1,
+                    "Comments": "Occupant zone for driver and FRONT_LEFT seat"
+                },
+                {
+                    "ZoneId": 1,
+                    "OccupantType": "FRONT_PASSENGER",
+                    "Seat": 4,
+                    "Comments": "Occupant zone for FRONT_RIGHT passenger"
+                }
+            ],
+            "EndpointInfo": {
+                "IpAddress": "10.10.10.1",
+                "PortNumber": 1234,
+                "BrandName": "MyBrand",
+                "DeviceName": "MyDevice",
+                "ProductName": "MyProduct",
+                "ManufacturerName": "MyCompany",
+                "ModelName": "MyModel",
+                "SerialNumber": "Serial1234"
+            },
+            "Comments": "Device for front row"
+        },
+        {
+            "DeviceId": 1,
+            "OccupantZones": [
+                {
+                    "ZoneId": 2,
+                    "OccupantType": "REAR_PASSENGER",
+                    "Seat": 16
+                },
+                {
+                    "ZoneId": 3,
+                    "OccupantType": "REAR_PASSENGER",
+                    "Seat": 64
+                }
+            ],
+            "EndpointInfo": {
+                "IpAddress": "10.10.10.2",
+                "PortNumber": 2345,
+                "BrandName": "MyBrand",
+                "DeviceName": "MyDevice",
+                "ProductName": "MyProduct",
+                "ManufacturerName": "MyCompany",
+                "ModelName": "MyModel",
+                "SerialNumber": "Serial2345"
+            },
+            "Comments": "Device for back row"
+        }
+    ],
+    "Comment":
+            "This simulates a vehicle with two Android devices, one for front row, one for back row"
+}
diff --git a/automotive/ivn_android_device/impl/default/include/IvnAndroidDeviceService.h b/automotive/ivn_android_device/impl/default/include/IvnAndroidDeviceService.h
new file mode 100644
index 0000000..0cff8fe
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/include/IvnAndroidDeviceService.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/ivn/BnIvnAndroidDevice.h>
+#include <aidl/android/hardware/automotive/ivn/EndpointInfo.h>
+#include <aidl/android/hardware/automotive/ivn/OccupantZoneInfo.h>
+#include <android/binder_auto_utils.h>
+#include <json/json.h>
+#include <vector>
+
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace ivn {
+
+struct DeviceInfo {
+    std::vector<aidl::android::hardware::automotive::ivn::OccupantZoneInfo> occupantZones;
+    aidl::android::hardware::automotive::ivn::EndpointInfo endpointInfo;
+};
+
+class IvnAndroidDeviceService
+    : public aidl::android::hardware::automotive::ivn::BnIvnAndroidDevice {
+  public:
+    explicit IvnAndroidDeviceService(std::string_view configPath);
+
+    // Initialize the service, returns true on success.
+    bool init();
+
+    ndk::ScopedAStatus getMyDeviceId(int* deviceId) override;
+
+    ndk::ScopedAStatus getOtherDeviceIds(std::vector<int>* deviceIds) override;
+
+    ndk::ScopedAStatus getDeviceIdForOccupantZone(int zoneId, int* deviceId) override;
+
+    ndk::ScopedAStatus getOccupantZonesForDevice(
+            int androidDeviceId,
+            std::vector<aidl::android::hardware::automotive::ivn::OccupantZoneInfo>* occupantZones)
+            override;
+
+    ndk::ScopedAStatus getMyEndpointInfo(
+            aidl::android::hardware::automotive::ivn::EndpointInfo* endpointInfo) override;
+
+    ndk::ScopedAStatus getEndpointInfoForDevice(
+            int androidDeviceId,
+            aidl::android::hardware::automotive::ivn::EndpointInfo* endpointInfo) override;
+
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+  private:
+    Json::Value mConfigRootNode;
+    int mMyDeviceId;
+    std::unordered_map<int, DeviceInfo> mDeviceInfoById;
+    std::string_view mConfigPath;
+};
+
+}  // namespace ivn
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/ivn_android_device/impl/default/ivn-default-service.rc b/automotive/ivn_android_device/impl/default/ivn-default-service.rc
new file mode 100644
index 0000000..070b259
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/ivn-default-service.rc
@@ -0,0 +1,4 @@
+service vendor.ivn-default /vendor/bin/hw/android.hardware.automotive.ivn@V1-default-service
+    class hal
+    user vehicle_network
+    group system inet
diff --git a/automotive/ivn_android_device/impl/default/ivn-default-service.xml b/automotive/ivn_android_device/impl/default/ivn-default-service.xml
new file mode 100644
index 0000000..481bc0a
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/ivn-default-service.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.ivn</name>
+        <version>1</version>
+        <fqname>IIvnAndroidDevice/default</fqname>
+    </hal>
+</manifest>
diff --git a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceImpl.cpp b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceImpl.cpp
new file mode 100644
index 0000000..fdf6776
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceImpl.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "IvnAndroidDeviceImpl"
+
+#include "IvnAndroidDeviceService.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <stdlib.h>
+
+constexpr char SERVICE_NAME[] = "android.hardware.automotive.ivn.IIvnAndroidDevice/default";
+constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/IvnConfig/DefaultConfig.json";
+
+int main(int /* argc */, char* /* argv */[]) {
+    LOG(INFO) << "Registering IvnAndroidDeviceService as service...";
+    auto service =
+            ndk::SharedRefBase::make<android::hardware::automotive::ivn::IvnAndroidDeviceService>(
+                    DEFAULT_CONFIG_DIR);
+    if (!service->init()) {
+        LOG(ERROR) << "Failed to init IvnAndroidDeviceService";
+        exit(1);
+    }
+
+    binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME);
+    if (err != EX_NONE) {
+        LOG(ERROR) << "Failed to register IvnAndroidDeviceService service, exception: " << err;
+        exit(1);
+    }
+
+    if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
+        LOG(ERROR) << "Failed to set thread pool max thread count";
+        exit(1);
+    }
+    ABinderProcess_startThreadPool();
+
+    LOG(INFO) << "IvnAndroidDeviceService Ready";
+
+    ABinderProcess_joinThreadPool();
+
+    LOG(ERROR) << "IvnAndroidDeviceService init failed! Should not reach here";
+
+    return 0;
+}
diff --git a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
new file mode 100644
index 0000000..81f18b2
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "IvnAndroidDeviceService.h"
+
+#include <aidl/android/hardware/automotive/ivn/ConnectProtocol.h>
+#include <aidl/android/hardware/automotive/ivn/HardwareIdentifiers.h>
+#include <aidl/android/hardware/automotive/ivn/OccupantType.h>
+#include <android-base/logging.h>
+#include <android/binder_status.h>
+#include <json/json.h>
+
+#include <fstream>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace ivn {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::ivn::ConnectProtocol;
+using ::aidl::android::hardware::automotive::ivn::EndpointInfo;
+using ::aidl::android::hardware::automotive::ivn::HardwareIdentifiers;
+using ::aidl::android::hardware::automotive::ivn::OccupantType;
+using ::aidl::android::hardware::automotive::ivn::OccupantZoneInfo;
+using ::ndk::ScopedAStatus;
+
+constexpr int IVN_ERROR_GENERIC = -1;
+
+}  // namespace
+
+IvnAndroidDeviceService::IvnAndroidDeviceService(std::string_view configPath) {
+    mConfigPath = configPath;
+}
+
+bool IvnAndroidDeviceService::init() {
+    std::ifstream configStream(mConfigPath);
+    if (!configStream) {
+        LOG(ERROR) << "couldn't open " << mConfigPath << " for parsing.";
+        return false;
+    }
+    Json::CharReaderBuilder builder;
+    std::string errs;
+    if (!Json::parseFromStream(builder, configStream, &mConfigRootNode, &errs)) {
+        LOG(ERROR) << "Failed to parse config JSON stream, error: " << errs;
+        return false;
+    }
+    if (!mConfigRootNode.isObject()) {
+        LOG(ERROR) << "Root must be an object";
+        return false;
+    }
+    if (!mConfigRootNode.isMember("MyDeviceId")) {
+        LOG(ERROR) << "Must contain 'MyDeviceId' field";
+        return false;
+    }
+    mMyDeviceId = mConfigRootNode["MyDeviceId"].asInt();
+    if (!mConfigRootNode.isMember("Devices") || !mConfigRootNode["Devices"].isArray()) {
+        LOG(ERROR) << "Must contain 'Devices' field as array";
+        return false;
+    }
+    Json::Value& devices = mConfigRootNode["Devices"];
+    for (unsigned int i = 0; i < devices.size(); i++) {
+        Json::Value& device = devices[i];
+        int deviceId = device["DeviceId"].asInt();
+        DeviceInfo deviceInfo = {};
+        Json::Value& occupantZones = device["OccupantZones"];
+        for (unsigned int j = 0; j < occupantZones.size(); j++) {
+            Json::Value& occupantZone = occupantZones[j];
+            int zoneId = occupantZone["ZoneId"].asInt();
+            std::string occupantTypeStr = occupantZone["OccupantType"].asString();
+            int seat = occupantZone["Seat"].asInt();
+            OccupantType occupantType;
+            if (occupantTypeStr == "DRIVER") {
+                occupantType = OccupantType::DRIVER;
+            } else if (occupantTypeStr == "FRONT_PASSENGER") {
+                occupantType = OccupantType::FRONT_PASSENGER;
+            } else if (occupantTypeStr == "REAR_PASSENGER") {
+                occupantType = OccupantType::REAR_PASSENGER;
+            } else {
+                LOG(ERROR) << "Unknown occupant type: " << occupantTypeStr;
+                return false;
+            }
+            OccupantZoneInfo occupantZoneInfo = {
+                    .zoneId = zoneId, .occupantType = occupantType, .seat = seat};
+            deviceInfo.occupantZones.push_back(std::move(occupantZoneInfo));
+        }
+        Json::Value& ep = device["EndpointInfo"];
+        EndpointInfo endpointInfo = {};
+        endpointInfo.connectProtocol = ConnectProtocol::TCP_IP;
+        endpointInfo.ipAddress = ep["IpAddress"].asString();
+        endpointInfo.portNumber = ep["PortNumber"].asInt();
+        HardwareIdentifiers hardwareId = {};
+        if (ep.isMember("BrandName")) {
+            hardwareId.brandName = ep["BrandName"].asString();
+        }
+        if (ep.isMember("DeviceName")) {
+            hardwareId.deviceName = ep["DeviceName"].asString();
+        }
+        if (ep.isMember("ProductName")) {
+            hardwareId.productName = ep["ProductName"].asString();
+        }
+        if (ep.isMember("ManufacturerName")) {
+            hardwareId.manufacturerName = ep["ManufacturerName"].asString();
+        }
+        if (ep.isMember("ModelName")) {
+            hardwareId.modelName = ep["ModelName"].asString();
+        }
+        if (ep.isMember("SerialNumber")) {
+            hardwareId.serialNumber = ep["SerialNumber"].asString();
+        }
+        endpointInfo.hardwareId = hardwareId;
+        deviceInfo.endpointInfo = endpointInfo;
+        mDeviceInfoById[deviceId] = deviceInfo;
+    }
+    if (mDeviceInfoById.find(mMyDeviceId) == mDeviceInfoById.end()) {
+        LOG(ERROR) << "My device ID is not in the device info list";
+        return false;
+    }
+    return true;
+}
+
+ScopedAStatus IvnAndroidDeviceService::getMyDeviceId(int* deviceId) {
+    *deviceId = mMyDeviceId;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus IvnAndroidDeviceService::getOtherDeviceIds(std::vector<int>* deviceIds) {
+    deviceIds->clear();
+    for (const auto& [deviceId, _] : mDeviceInfoById) {
+        if (deviceId == mMyDeviceId) {
+            continue;
+        }
+        deviceIds->push_back(deviceId);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus IvnAndroidDeviceService::getDeviceIdForOccupantZone(int zoneId, int* outDeviceId) {
+    for (const auto& [deviceId, deviceInfo] : mDeviceInfoById) {
+        for (const auto& occupantZoneInfo : deviceInfo.occupantZones) {
+            if (occupantZoneInfo.zoneId == zoneId) {
+                *outDeviceId = deviceId;
+                return ScopedAStatus::ok();
+            }
+        }
+    }
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(IVN_ERROR_GENERIC,
+                                                              "Occupant zone not found");
+}
+
+ScopedAStatus IvnAndroidDeviceService::getOccupantZonesForDevice(
+        int androidDeviceId, std::vector<OccupantZoneInfo>* occupantZones) {
+    if (mDeviceInfoById.find(androidDeviceId) == mDeviceInfoById.end()) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(IVN_ERROR_GENERIC,
+                                                                  "Android device ID not found");
+    }
+    for (const auto& occupantZoneInfo : mDeviceInfoById[androidDeviceId].occupantZones) {
+        occupantZones->push_back(occupantZoneInfo);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus IvnAndroidDeviceService::getMyEndpointInfo(EndpointInfo* endpointInfo) {
+    *endpointInfo = mDeviceInfoById[mMyDeviceId].endpointInfo;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus IvnAndroidDeviceService::getEndpointInfoForDevice(int androidDeviceId,
+                                                                EndpointInfo* endpointInfo) {
+    if (mDeviceInfoById.find(androidDeviceId) == mDeviceInfoById.end()) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(IVN_ERROR_GENERIC,
+                                                                  "Android device ID not found");
+    }
+    *endpointInfo = mDeviceInfoById[androidDeviceId].endpointInfo;
+    return ScopedAStatus::ok();
+}
+
+binder_status_t IvnAndroidDeviceService::dump(int fd, [[maybe_unused]] const char** args,
+                                              [[maybe_unused]] uint32_t numArgs) {
+    dprintf(fd, "IVN Android Device debug interface, Config: \n%s\n",
+            mConfigRootNode.toStyledString().c_str());
+    return STATUS_OK;
+}
+
+}  // namespace ivn
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/ivn_android_device/impl/default/test/Android.bp b/automotive/ivn_android_device/impl/default/test/Android.bp
new file mode 100644
index 0000000..a100575
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/test/Android.bp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "IvnAndroidDeviceServiceUnitTest",
+    vendor: true,
+    srcs: ["*.cpp"],
+    whole_static_libs: [
+        "IvnAndroidDeviceService",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libjsoncpp",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "libgtest",
+    ],
+    data: [
+        ":IvnAndroidDeviceServiceDefaultConfig_Json",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/ivn_android_device/impl/default/test/IvnAndroidDeviceServiceUnittest.cpp b/automotive/ivn_android_device/impl/default/test/IvnAndroidDeviceServiceUnittest.cpp
new file mode 100644
index 0000000..6a4d26d
--- /dev/null
+++ b/automotive/ivn_android_device/impl/default/test/IvnAndroidDeviceServiceUnittest.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "IvnAndroidDeviceService.h"
+
+#include <aidl/android/hardware/automotive/ivn/EndpointInfo.h>
+#include <aidl/android/hardware/automotive/ivn/OccupantType.h>
+#include <aidl/android/hardware/automotive/ivn/OccupantZoneInfo.h>
+#include <android-base/file.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace ivn {
+
+using ::aidl::android::hardware::automotive::ivn::ConnectProtocol;
+using ::aidl::android::hardware::automotive::ivn::EndpointInfo;
+using ::aidl::android::hardware::automotive::ivn::OccupantType;
+using ::aidl::android::hardware::automotive::ivn::OccupantZoneInfo;
+using ::ndk::ScopedAStatus;
+
+class IvnAndroidDeviceServiceUnitTest : public ::testing::Test {
+  public:
+    virtual void SetUp() override {
+        mService = ndk::SharedRefBase::make<IvnAndroidDeviceService>(
+                android::base::GetExecutableDirectory() + "/DefaultConfig.json");
+        mService->init();
+    }
+
+    std::shared_ptr<IvnAndroidDeviceService> mService;
+};
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetMyDeviceId) {
+    int deviceId = -1;
+
+    ScopedAStatus status = mService->getMyDeviceId(&deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    ASSERT_EQ(deviceId, 0);
+}
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetOtherDeviceIds) {
+    std::vector<int> deviceIds;
+
+    ScopedAStatus status = mService->getOtherDeviceIds(&deviceIds);
+
+    ASSERT_TRUE(status.isOk());
+    ASSERT_EQ(deviceIds, std::vector<int>({1}));
+}
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetDeviceIdForOccupantZone) {
+    int deviceId = -1;
+
+    ScopedAStatus status = mService->getDeviceIdForOccupantZone(/*zoneId=*/0, &deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(deviceId, 0);
+
+    status = mService->getDeviceIdForOccupantZone(/*zoneId=*/1, &deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(deviceId, 0);
+
+    status = mService->getDeviceIdForOccupantZone(/*zoneId=*/2, &deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(deviceId, 1);
+
+    status = mService->getDeviceIdForOccupantZone(/*zoneId=*/3, &deviceId);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(deviceId, 1);
+
+    status = mService->getDeviceIdForOccupantZone(/*zoneId=*/4, &deviceId);
+
+    ASSERT_FALSE(status.isOk());
+}
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetOccupantZonesForDevice) {
+    std::vector<OccupantZoneInfo> occupantZones;
+
+    ScopedAStatus status =
+            mService->getOccupantZonesForDevice(/*androidDeviceId=*/0, &occupantZones);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(occupantZones.size(), 2);
+    if (occupantZones.size() == 2) {
+        EXPECT_EQ(occupantZones[0].zoneId, 0);
+        EXPECT_EQ(occupantZones[0].occupantType, OccupantType::DRIVER);
+        EXPECT_EQ(occupantZones[0].seat, 1);
+        EXPECT_EQ(occupantZones[1].zoneId, 1);
+        EXPECT_EQ(occupantZones[1].occupantType, OccupantType::FRONT_PASSENGER);
+        EXPECT_EQ(occupantZones[1].seat, 4);
+    }
+}
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetMyEndpointInfo) {
+    EndpointInfo endpointInfo;
+
+    ScopedAStatus status = mService->getMyEndpointInfo(&endpointInfo);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP);
+    EXPECT_EQ(endpointInfo.ipAddress, "10.10.10.1");
+    EXPECT_EQ(endpointInfo.portNumber, 1234);
+    EXPECT_EQ(endpointInfo.hardwareId.brandName, "MyBrand");
+    EXPECT_EQ(endpointInfo.hardwareId.deviceName, "MyDevice");
+    EXPECT_EQ(endpointInfo.hardwareId.productName, "MyProduct");
+    EXPECT_EQ(endpointInfo.hardwareId.manufacturerName, "MyCompany");
+    EXPECT_EQ(endpointInfo.hardwareId.modelName, "MyModel");
+    EXPECT_EQ(endpointInfo.hardwareId.serialNumber, "Serial1234");
+}
+
+TEST_F(IvnAndroidDeviceServiceUnitTest, TestGetEndpointInfoForDevice) {
+    EndpointInfo endpointInfo;
+
+    ScopedAStatus status = mService->getEndpointInfoForDevice(/*androidDeviceId=*/0, &endpointInfo);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP);
+    EXPECT_EQ(endpointInfo.ipAddress, "10.10.10.1");
+    EXPECT_EQ(endpointInfo.portNumber, 1234);
+
+    status = mService->getEndpointInfoForDevice(/*androidDeviceId=*/1, &endpointInfo);
+
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP);
+    EXPECT_EQ(endpointInfo.ipAddress, "10.10.10.2");
+    EXPECT_EQ(endpointInfo.portNumber, 2345);
+}
+
+}  // namespace ivn
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/ivn_android_device/vts/Android.bp b/automotive/ivn_android_device/vts/Android.bp
new file mode 100644
index 0000000..e4b9d64
--- /dev/null
+++ b/automotive/ivn_android_device/vts/Android.bp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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_test {
+    name: "VtsHalIvnTargetTest",
+    srcs: [
+        "src/*.cpp",
+    ],
+    defaults: ["use_libaidlvintf_gtest_helper_static"],
+    static_libs: [
+        "libgmock",
+        "libgtest",
+        "android.hardware.automotive.ivn-V1-ndk",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+        "automotive-tests",
+        "automotive-general-tests",
+    ],
+    require_root: true,
+}
diff --git a/automotive/ivn_android_device/vts/OWNERS b/automotive/ivn_android_device/vts/OWNERS
new file mode 100644
index 0000000..d6969e5
--- /dev/null
+++ b/automotive/ivn_android_device/vts/OWNERS
@@ -0,0 +1,2 @@
+ericjeong@google.com
+shanyu@google.com
diff --git a/automotive/ivn_android_device/vts/src/VtsHalIvnTargetTest.cpp b/automotive/ivn_android_device/vts/src/VtsHalIvnTargetTest.cpp
new file mode 100644
index 0000000..73b9a5e
--- /dev/null
+++ b/automotive/ivn_android_device/vts/src/VtsHalIvnTargetTest.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/automotive/ivn/ConnectProtocol.h>
+#include <aidl/android/hardware/automotive/ivn/EndpointInfo.h>
+#include <aidl/android/hardware/automotive/ivn/IIvnAndroidDevice.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <gmock/gmock.h>
+#include <unordered_set>
+
+namespace aidl::android::hardware::automotive::ivn {
+
+using ::ndk::ScopedAStatus;
+using ::ndk::SpAIBinder;
+
+using ::testing::Contains;
+using ::testing::Not;
+
+class VtsHalIvnTargetTest : public ::testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        std::string descriptor = GetParam();
+        AIBinder* binder = AServiceManager_checkService(descriptor.c_str());
+        ASSERT_NE(binder, nullptr) << "Failed to connect to IVN HAL";
+        mIvnHal = IIvnAndroidDevice::fromBinder(SpAIBinder(binder));
+    }
+
+    std::shared_ptr<IIvnAndroidDevice> getHal() { return mIvnHal; }
+
+  private:
+    std::shared_ptr<IIvnAndroidDevice> mIvnHal;
+
+  protected:
+    ScopedAStatus getAllDeviceIds(std::unordered_set<int>* deviceIds);
+};
+
+TEST_P(VtsHalIvnTargetTest, testDeviceIdIsUnique) {
+    std::unordered_set<int> foundDeviceIds;
+    int myDeviceId = 0;
+
+    ScopedAStatus status = getHal()->getMyDeviceId(&myDeviceId);
+
+    ASSERT_TRUE(status.isOk()) << "Failed to call getMyDeviceId, status: " << status;
+    foundDeviceIds.insert(myDeviceId);
+
+    std::vector<int> otherDeviceIds;
+
+    status = getHal()->getOtherDeviceIds(&otherDeviceIds);
+
+    ASSERT_TRUE(status.isOk()) << "Failed to call getOtherDeviceIds, status: " << status;
+
+    for (int deviceId : otherDeviceIds) {
+        EXPECT_THAT(foundDeviceIds, Not(Contains(deviceId))) << "Duplicate device ID: " << deviceId;
+        foundDeviceIds.insert(deviceId);
+    }
+}
+
+ScopedAStatus VtsHalIvnTargetTest::getAllDeviceIds(std::unordered_set<int>* deviceIds) {
+    int myDeviceId = 0;
+    ScopedAStatus status = getHal()->getMyDeviceId(&myDeviceId);
+
+    if (!status.isOk()) {
+        return status;
+    }
+    deviceIds->insert(myDeviceId);
+    std::vector<int> otherDeviceIds;
+    status = getHal()->getOtherDeviceIds(&otherDeviceIds);
+    if (!status.isOk()) {
+        return status;
+    }
+    for (int otherDeviceId : otherDeviceIds) {
+        deviceIds->insert(otherDeviceId);
+    }
+    return ScopedAStatus::ok();
+}
+
+TEST_P(VtsHalIvnTargetTest, testDeviceIdOccupantZoneMapping) {
+    std::unordered_set<int> allDeviceIds;
+
+    ScopedAStatus status = getAllDeviceIds(&allDeviceIds);
+
+    ASSERT_FALSE(allDeviceIds.empty());
+    ASSERT_TRUE(status.isOk()) << "Failed to get all device IDs, status: " << status;
+
+    std::unordered_set<int> foundOccupantZoneIds;
+
+    for (int deviceId : allDeviceIds) {
+        std::vector<OccupantZoneInfo> occupantZones;
+        status = getHal()->getOccupantZonesForDevice(deviceId, &occupantZones);
+
+        ASSERT_TRUE(status.isOk())
+                << "Failed to call getOccupantZonesForDevice, status: " << status;
+        ASSERT_FALSE(occupantZones.empty()) << "No occupant zones for device: " << deviceId;
+
+        for (const OccupantZoneInfo& occupantZone : occupantZones) {
+            int zoneId = occupantZone.zoneId;
+
+            EXPECT_THAT(foundOccupantZoneIds, Not(Contains(zoneId)))
+                    << "Duplicate zone ID: " << zoneId;
+
+            foundOccupantZoneIds.insert(zoneId);
+
+            int gotDeviceId = 0;
+            status = getHal()->getDeviceIdForOccupantZone(zoneId, &gotDeviceId);
+
+            ASSERT_TRUE(status.isOk())
+                    << "Failed to call getDeviceIdForOccupantZone, status: " << status;
+            EXPECT_EQ(deviceId, gotDeviceId);
+        }
+    }
+}
+
+TEST_P(VtsHalIvnTargetTest, testGetEndpointInfo) {
+    EndpointInfo endpointInfo;
+    std::vector<EndpointInfo> foundEndpointInfo;
+
+    ScopedAStatus status = getHal()->getMyEndpointInfo(&endpointInfo);
+
+    foundEndpointInfo.push_back(endpointInfo);
+
+    ASSERT_TRUE(status.isOk()) << "Failed to call getMyEndpointInfo, status: " << status;
+    EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP);
+
+    std::vector<int> otherDeviceIds;
+    status = getHal()->getOtherDeviceIds(&otherDeviceIds);
+
+    ASSERT_TRUE(status.isOk()) << "Failed to call getOtherDeviceIds, status: " << status;
+
+    for (int deviceId : otherDeviceIds) {
+        status = getHal()->getEndpointInfoForDevice(deviceId, &endpointInfo);
+
+        ASSERT_TRUE(status.isOk()) << "Failed to call getEndpointInfoForDevice, status: " << status;
+        EXPECT_EQ(endpointInfo.connectProtocol, ConnectProtocol::TCP_IP);
+
+        for (EndpointInfo foundInfo : foundEndpointInfo) {
+            ASSERT_NE(foundInfo, endpointInfo)
+                    << "Found duplicate endpoint info" << endpointInfo.toString();
+        }
+
+        foundEndpointInfo.push_back(endpointInfo);
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalIvnTargetTest);
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, VtsHalIvnTargetTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IIvnAndroidDevice::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+}  // namespace aidl::android::hardware::automotive::ivn
diff --git a/automotive/occupant_awareness/aidl/Android.bp b/automotive/occupant_awareness/aidl/Android.bp
index 6ddc127..1a8124c 100644
--- a/automotive/occupant_awareness/aidl/Android.bp
+++ b/automotive/occupant_awareness/aidl/Android.bp
@@ -23,11 +23,6 @@
                 "com.android.car.framework",
             ],
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp
index 66af9de..dc280df 100644
--- a/automotive/occupant_awareness/aidl/default/Android.bp
+++ b/automotive/occupant_awareness/aidl/default/Android.bp
@@ -26,6 +26,7 @@
 cc_binary {
     name: "android.hardware.automotive.occupant_awareness@1.0-service",
     init_rc: ["android.hardware.automotive.occupant_awareness@1.0-service.rc"],
+    vintf_fragments: ["android.hardware.automotive.occupant_awareness-service.xml"],
     relative_install_path: "hw",
     vendor: true,
     srcs: [
@@ -39,3 +40,21 @@
         "android.hardware.automotive.occupant_awareness-V1-ndk",
     ],
 }
+
+cc_fuzz {
+    name: "android.hardware.automotive.occupant_awareness-service.fuzzer",
+    defaults: ["service_fuzzer_defaults"],
+    static_libs: [
+        "android.hardware.automotive.occupant_awareness-V1-ndk",
+        "liblog",
+    ],
+    srcs: [
+        "fuzzer.cpp",
+        "OccupantAwareness.cpp",
+    ],
+    fuzz_config: {
+        cc: [
+            "keithmok@google.com",
+        ],
+    },
+}
diff --git a/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness-service.xml b/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness-service.xml
new file mode 100644
index 0000000..b4f8fa5
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/android.hardware.automotive.occupant_awareness-service.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.occupant_awareness</name>
+        <version>1</version>
+        <fqname>IOccupantAwareness/default</fqname>
+    </hal>
+</manifest>
diff --git a/automotive/occupant_awareness/aidl/default/fuzzer.cpp b/automotive/occupant_awareness/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..551b83a
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/fuzzer.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "OccupantAwareness.h"
+
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwareness;
+using ::android::fuzzService;
+using ::android::hardware::automotive::occupant_awareness::V1_0::implementation::OccupantAwareness;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto occupantAwareness = SharedRefBase::make<OccupantAwareness>();
+
+    fuzzService(occupantAwareness->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/automotive/remoteaccess/Android.bp b/automotive/remoteaccess/Android.bp
new file mode 100644
index 0000000..7cd6f60
--- /dev/null
+++ b/automotive/remoteaccess/Android.bp
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.automotive.remoteaccess",
+    vendor_available: true,
+    srcs: [
+        "android/hardware/automotive/remoteaccess/**/*.aidl",
+    ],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+            min_sdk_version: "31",
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.car.framework",
+            ],
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/automotive/remoteaccess/OWNERS b/automotive/remoteaccess/OWNERS
new file mode 100644
index 0000000..d6969e5
--- /dev/null
+++ b/automotive/remoteaccess/OWNERS
@@ -0,0 +1,2 @@
+ericjeong@google.com
+shanyu@google.com
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/.hash b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/.hash
new file mode 100644
index 0000000..66eed7f
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/.hash
@@ -0,0 +1 @@
+67d4a3a069e9240732d2945a4b5f7868f266431b
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/android/hardware/automotive/remoteaccess/ApState.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/android/hardware/automotive/remoteaccess/ApState.aidl
new file mode 100644
index 0000000..da4f1d4
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/android/hardware/automotive/remoteaccess/ApState.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.remoteaccess;
+@VintfStability
+parcelable ApState {
+  boolean isReadyForRemoteTask;
+  boolean isWakeupRequired;
+}
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
new file mode 100644
index 0000000..b0935c2
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.remoteaccess;
+@VintfStability
+interface IRemoteAccess {
+  String getVehicleId();
+  String getWakeupServiceName();
+  String getProcessorId();
+  void setRemoteTaskCallback(android.hardware.automotive.remoteaccess.IRemoteTaskCallback callback);
+  void clearRemoteTaskCallback();
+  void notifyApStateChange(in android.hardware.automotive.remoteaccess.ApState state);
+}
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
new file mode 100644
index 0000000..295100e
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/1/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.remoteaccess;
+@VintfStability
+interface IRemoteTaskCallback {
+  oneway void onRemoteTaskRequested(String clientId, in byte[] data);
+}
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ApState.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ApState.aidl
new file mode 100644
index 0000000..da4f1d4
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ApState.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.remoteaccess;
+@VintfStability
+parcelable ApState {
+  boolean isReadyForRemoteTask;
+  boolean isWakeupRequired;
+}
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
new file mode 100644
index 0000000..b0935c2
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.remoteaccess;
+@VintfStability
+interface IRemoteAccess {
+  String getVehicleId();
+  String getWakeupServiceName();
+  String getProcessorId();
+  void setRemoteTaskCallback(android.hardware.automotive.remoteaccess.IRemoteTaskCallback callback);
+  void clearRemoteTaskCallback();
+  void notifyApStateChange(in android.hardware.automotive.remoteaccess.ApState state);
+}
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
new file mode 100644
index 0000000..295100e
--- /dev/null
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.remoteaccess;
+@VintfStability
+interface IRemoteTaskCallback {
+  oneway void onRemoteTaskRequested(String clientId, in byte[] data);
+}
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ApState.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ApState.aidl
new file mode 100644
index 0000000..c8eb3ef
--- /dev/null
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ApState.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.remoteaccess;
+
+@VintfStability
+parcelable ApState {
+    /**
+     * Whether AP (application processor) is ready to receive remote tasks.
+     *
+     * If this is true. AP is powered on and the car service is ready to handle
+     * remote tasks.
+     */
+    boolean isReadyForRemoteTask;
+    /**
+     * Whether AP (application processor) needs to be woken up.
+     *
+     * While the AP is shutting down, this will be set to false to prevent the
+     * wakeup signal to interrupt the shutdown process. At the last step of the
+     * shutdown process, this will be set to true so that AP will be waken
+     * up when task arrives. After AP starts up, this will be set to false
+     * to prevent unnecessary wakeup signal.
+     */
+    boolean isWakeupRequired;
+}
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
new file mode 100644
index 0000000..0f4125f
--- /dev/null
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.remoteaccess;
+
+import android.hardware.automotive.remoteaccess.ApState;
+import android.hardware.automotive.remoteaccess.IRemoteTaskCallback;
+
+/**
+ * Interface representing a remote wakeup client.
+ *
+ * A wakeup client is a binary outside Android framework that communicates with
+ * a wakeup server and receives wake up command.
+ */
+@VintfStability
+interface IRemoteAccess {
+    /**
+     * Gets a unique vehicle ID that could be recognized by wake up server.
+     *
+     * <p>This vehicle ID is provisioned during car production and is registered
+     * with the wake up server.
+     *
+     * @return a unique vehicle ID.
+     */
+    String getVehicleId();
+
+    /**
+     * Gets the name for the remote wakeup server.
+     *
+     * <p>This name will be provided to remote task server during registration
+     * and used by remote task server to find the remote wakeup server to
+     * use for waking up the device. This name must be pre-negotiated between
+     * the remote wakeup server/client and the remote task server/client and
+     * must be unique. We recommend the format to be a human readable string
+     * with reverse domain name notation (reverse-DNS), e.g.
+     * "com.google.vehicle.wakeup".
+     */
+    String getWakeupServiceName();
+
+    /**
+     * Gets a unique processor ID that could be recognized by wake up client.
+     *
+     * <p>This processor ID is used to identify each processor in the vehicle.
+     * The wake up client which handles many processors determines which
+     * processor to wake up from the processor ID.
+     *
+     * <p> The processor ID must be unique in the vehicle.
+     */
+    String getProcessorId();
+
+    /**
+     * Sets a callback to be called when a remote task is requested.
+     *
+     * @param callback A callback to be called when a remote task is requested.
+     */
+    void setRemoteTaskCallback(IRemoteTaskCallback callback);
+
+    /**
+     * Clears a previously set remote task callback.
+     *
+     * If no callback was set, this operation is no-op.
+     */
+    void clearRemoteTaskCallback();
+
+    /**
+     * Notifies whether AP is ready to receive remote tasks.
+     *
+     * <p>Wakeup client should store and use this state until a new call with a
+     * different state arrives.
+     *
+     * <p>If {@code isReadyForRemoteTask} is true, the wakeup client may send
+     * the task received from the server to AP immediately.
+     *
+     * <p>If {@code isReadyForRemoteTask} is false, it must store the received
+     * remote tasks and wait until AP is ready to receive tasks. If it takes too
+     * long for AP to become ready, the task must be reported to remote task
+     * server as failed. Implementation must make sure no duplicate tasks are
+     * delivered to AP.
+     *
+     * <p>If {@code isWakeupRequired} is true, it must try to wake up AP when a
+     * remote task arrives or when there are pending requests.
+     *
+     * <p>If {@code isWakeupRequired} is false, it must not try to wake up AP.
+     */
+    void notifyApStateChange(in ApState state);
+}
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
new file mode 100644
index 0000000..2cd7a5d
--- /dev/null
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.remoteaccess;
+
+/**
+ * The callback interface for car service to receive tasks from wakup client.
+ */
+@VintfStability
+interface IRemoteTaskCallback {
+    /**
+     * A callback that is called when a remote task is requested.
+     *
+     * The data is passed down from the remote server to the remote task client
+     * which is an Android application, and is not interpreted/parsed by the
+     * Android system.
+     *
+     * @param clientId An ID to uniquely identify a remote task client.
+     * @param data Opaque task data passed to the remote task client.
+     */
+    oneway void onRemoteTaskRequested(String clientId, in byte[] data);
+}
diff --git a/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp b/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp
new file mode 100644
index 0000000..cde0219
--- /dev/null
+++ b/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+    name: "BindToDeviceSocketMutatorDefaults",
+    static_libs: [
+        "android.hardware.automotive.can@libnetdevice",
+        "libnl++",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libgrpc++",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
+
+cc_library {
+    name: "BindToDeviceSocketMutatorLib",
+    vendor_available: true,
+    srcs: ["src/BindToDeviceSocketMutator.cpp"],
+    export_include_dirs: ["include"],
+    defaults: ["BindToDeviceSocketMutatorDefaults"],
+    header_libs: ["libgrpc++_internal_headers"],
+}
diff --git a/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h b/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h
new file mode 100644
index 0000000..5974c4b
--- /dev/null
+++ b/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <grpc/grpc.h>
+#include <string_view>
+
+namespace android::hardware::automotive::remoteaccess {
+
+grpc_socket_mutator* MakeBindToDeviceSocketMutator(std::string_view interface_name);
+
+}  // namespace android::hardware::automotive::remoteaccess
diff --git a/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp b/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp
new file mode 100644
index 0000000..04a4c5b
--- /dev/null
+++ b/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BindToDeviceSocketMutator.h"
+
+#include <android-base/logging.h>
+#include <errno.h>
+#include <src/core/lib/iomgr/socket_mutator.h>
+#include <sys/socket.h>
+
+#include <memory>
+
+namespace android::hardware::automotive::remoteaccess {
+namespace {
+
+struct BindToDeviceMutator : grpc_socket_mutator {
+    std::string ifname;
+};
+
+bool MutateFd(int fd, grpc_socket_mutator* mutator) {
+    auto* bdm = static_cast<BindToDeviceMutator*>(mutator);
+    int ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, bdm->ifname.c_str(), bdm->ifname.size());
+    if (ret != 0) {
+        PLOG(ERROR) << "Can't bind socket to interface " << bdm->ifname;
+        return false;
+    }
+    return true;
+}
+
+int Compare(grpc_socket_mutator* a, grpc_socket_mutator* b) {
+    return ((a) < (b) ? -1 : ((a) > (b) ? 1 : 0));
+}
+
+void Destroy(grpc_socket_mutator* mutator) {
+    auto* bdm = static_cast<BindToDeviceMutator*>(mutator);
+    delete bdm;
+}
+
+constexpr grpc_socket_mutator_vtable kMutatorVtable = {
+        .mutate_fd = MutateFd,
+        .compare = Compare,
+        .destroy = Destroy,
+};
+
+}  // namespace
+
+grpc_socket_mutator* MakeBindToDeviceSocketMutator(std::string_view interface_name) {
+    auto* bdm = new BindToDeviceMutator;
+    grpc_socket_mutator_init(bdm, &kMutatorVtable);
+    bdm->ifname = interface_name;
+    return bdm;
+}
+
+}  // namespace android::hardware::automotive::remoteaccess
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
new file mode 100644
index 0000000..0155667
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+    name: "remote-access-hal-defaults",
+    vendor: true,
+    relative_install_path: "hw",
+    srcs: [
+        "src/RemoteAccessImpl.cpp",
+    ],
+    whole_static_libs: [
+        "RemoteAccessService",
+    ],
+    static_libs: [
+        "BindToDeviceSocketMutatorLib",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libutils",
+        "libprotobuf-cpp-full",
+    ],
+    defaults: [
+        "vhalclient_defaults",
+        "BindToDeviceSocketMutatorDefaults",
+    ],
+    cflags: [
+        // This is already included in BindToDeviceSocketMutatorDefaults but
+        // might be overridden by vhalclient_defaults.
+        "-Wno-unused-parameter",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.automotive.remoteaccess@V1-default-service",
+    defaults: ["remote-access-hal-defaults"],
+    vintf_fragments: ["remoteaccess-default-service.xml"],
+    init_rc: ["remoteaccess-default-service.rc"],
+    cflags: [
+        "-DGRPC_SERVICE_ADDRESS=\"localhost:50051\"",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.automotive.remoteaccess@V1-tcu-test-service",
+    defaults: ["remote-access-hal-defaults"],
+    vintf_fragments: ["remoteaccess-default-service.xml"],
+    init_rc: ["remoteaccess-tcu-test-service.rc"],
+    cflags: [
+        "-DGRPC_SERVICE_ADDRESS=\"10.10.10.1:50051\"",
+        "-DGRPC_SERVICE_IFNAME=\"eth1\"",
+    ],
+}
+
+cc_library {
+    name: "RemoteAccessService",
+    vendor_available: true,
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    srcs: [
+        "src/RemoteAccessService.cpp",
+    ],
+    whole_static_libs: [
+        "android.hardware.automotive.remoteaccess-V1-ndk",
+        "wakeup_client_protos",
+        "libvhalclient",
+    ],
+    defaults: [
+        "vhalclient_defaults",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "liblog",
+        "libutils",
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
+
+cc_fuzz {
+    name: "android.hardware.automotive.remoteaccess@V1-default-service.aidl_fuzzer",
+    srcs: ["fuzzer/fuzzer.cpp"],
+    whole_static_libs: [
+        "RemoteAccessService",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    defaults: [
+        "vhalclient_defaults",
+        "service_fuzzer_defaults",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+        "-DGRPC_SERVICE_ADDRESS=\"localhost:50051\"",
+    ],
+    fuzz_config: {
+        cc: [
+            "shanyu@google.com",
+        ],
+    },
+}
diff --git a/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
new file mode 100644
index 0000000..292c80e
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <RemoteAccessService.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <gmock/gmock.h>
+#include <grpcpp/test/mock_stream.h>
+#include <wakeup_client.grpc.pb.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace remoteaccess {
+
+using ::grpc::ClientAsyncReaderInterface;
+using ::grpc::ClientAsyncResponseReaderInterface;
+using ::grpc::ClientContext;
+using ::grpc::ClientReader;
+using ::grpc::ClientReaderInterface;
+using ::grpc::CompletionQueue;
+using ::grpc::Status;
+using ::grpc::testing::MockClientReader;
+using ::testing::_;
+using ::testing::Return;
+
+class MockGrpcClientStub : public WakeupClient::StubInterface {
+  public:
+    ClientReaderInterface<GetRemoteTasksResponse>* GetRemoteTasksRaw(
+            [[maybe_unused]] ClientContext* context,
+            [[maybe_unused]] const GetRemoteTasksRequest& request) override {
+        MockClientReader<GetRemoteTasksResponse>* mockClientReader =
+                new MockClientReader<GetRemoteTasksResponse>();
+        ON_CALL(*mockClientReader, Finish()).WillByDefault(Return(Status::OK));
+        ON_CALL(*mockClientReader, Read(_)).WillByDefault(Return(false));
+        return mockClientReader;
+    }
+
+    Status NotifyWakeupRequired([[maybe_unused]] ClientContext* context,
+                                [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+                                [[maybe_unused]] NotifyWakeupRequiredResponse* response) {
+        return Status::OK;
+    }
+
+    // Async methods which we do not care.
+    ClientAsyncReaderInterface<GetRemoteTasksResponse>* AsyncGetRemoteTasksRaw(
+            [[maybe_unused]] ClientContext* context,
+            [[maybe_unused]] const GetRemoteTasksRequest& request,
+            [[maybe_unused]] CompletionQueue* cq, [[maybe_unused]] void* tag) {
+        return nullptr;
+    }
+
+    ClientAsyncReaderInterface<GetRemoteTasksResponse>* PrepareAsyncGetRemoteTasksRaw(
+            [[maybe_unused]] ClientContext* context,
+            [[maybe_unused]] const GetRemoteTasksRequest& request,
+            [[maybe_unused]] CompletionQueue* cq) {
+        return nullptr;
+    }
+
+    ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>* AsyncNotifyWakeupRequiredRaw(
+            [[maybe_unused]] ClientContext* context,
+            [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+            [[maybe_unused]] CompletionQueue* cq) {
+        return nullptr;
+    }
+
+    ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>*
+    PrepareAsyncNotifyWakeupRequiredRaw([[maybe_unused]] ClientContext* context,
+                                        [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+                                        [[maybe_unused]] CompletionQueue* c) {
+        return nullptr;
+    }
+};
+
+}  // namespace remoteaccess
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    android::hardware::automotive::remoteaccess::MockGrpcClientStub stub;
+    std::shared_ptr<android::hardware::automotive::remoteaccess::RemoteAccessService> service =
+            ndk::SharedRefBase::make<
+                    android::hardware::automotive::remoteaccess::RemoteAccessService>(&stub);
+    android::fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
new file mode 100644
index 0000000..b18986a
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <IVhalClient.h>
+#include <aidl/android/hardware/automotive/remoteaccess/ApState.h>
+#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteAccess.h>
+#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteTaskCallback.h>
+#include <aidl/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.h>
+#include <android-base/thread_annotations.h>
+#include <android/binder_auto_utils.h>
+#include <utils/SystemClock.h>
+#include <wakeup_client.grpc.pb.h>
+
+#include <string>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace remoteaccess {
+
+// A IRemoteTaskCallback implementation for debug purpose.
+class DebugRemoteTaskCallback final
+    : public aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback {
+  public:
+    DebugRemoteTaskCallback() { mStartTimeMillis = android::uptimeMillis(); };
+
+    ndk::ScopedAStatus onRemoteTaskRequested(const std::string& clientId,
+                                             const std::vector<uint8_t>& data) override;
+    std::string printTasks();
+
+  private:
+    struct TaskData {
+        std::string clientId;
+        std::vector<uint8_t> data;
+    };
+
+    std::mutex mLock;
+    int64_t mStartTimeMillis;
+    std::vector<TaskData> mTasks;
+};
+
+class RemoteAccessService
+    : public aidl::android::hardware::automotive::remoteaccess::BnRemoteAccess {
+  public:
+    explicit RemoteAccessService(WakeupClient::StubInterface* grpcStub);
+
+    ~RemoteAccessService();
+
+    ndk::ScopedAStatus getVehicleId(std::string* vehicleId) override;
+
+    ndk::ScopedAStatus getProcessorId(std::string* processorId) override;
+
+    ndk::ScopedAStatus getWakeupServiceName(std::string* wakeupServiceName) override;
+
+    ndk::ScopedAStatus setRemoteTaskCallback(
+            const std::shared_ptr<
+                    aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback>&
+                    callback) override;
+
+    ndk::ScopedAStatus clearRemoteTaskCallback() override;
+
+    ndk::ScopedAStatus notifyApStateChange(
+            const aidl::android::hardware::automotive::remoteaccess::ApState& newState) override;
+
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+  private:
+    // For testing.
+    friend class RemoteAccessServiceUnitTest;
+
+    static bool checkDumpPermission();
+
+    WakeupClient::StubInterface* mGrpcStub;
+    std::thread mThread;
+    std::mutex mLock;
+    std::condition_variable mCv;
+    std::shared_ptr<aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback>
+            mRemoteTaskCallback GUARDED_BY(mLock);
+    std::unique_ptr<grpc::ClientContext> mGetRemoteTasksContext GUARDED_BY(mLock);
+    // Associated with mCv to notify the task loop to stop waiting and exit.
+    bool mTaskWaitStopped GUARDED_BY(mLock);
+    // A mutex to make sure startTaskLoop does not overlap with stopTaskLoop.
+    std::mutex mStartStopTaskLoopLock;
+    bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock) = false;
+    bool mGrpcConnected GUARDED_BY(mLock) = false;
+    std::unordered_map<std::string, size_t> mClientIdToTaskCount GUARDED_BY(mLock);
+
+    // Default wait time before retry connecting to remote access client is 10s.
+    size_t mRetryWaitInMs = 10'000;
+    std::shared_ptr<DebugRemoteTaskCallback> mDebugCallback;
+
+    std::thread mInjectDebugTaskThread;
+
+    void runTaskLoop();
+    void maybeStartTaskLoop();
+    void maybeStopTaskLoop();
+    ndk::ScopedAStatus getVehicleIdWithClient(
+            android::frameworks::automotive::vhal::IVhalClient& client, std::string* vehicleId);
+
+    void setRetryWaitInMs(size_t retryWaitInMs) { mRetryWaitInMs = retryWaitInMs; }
+    void dumpHelp(int fd);
+    void printCurrentStatus(int fd);
+    std::string clientIdToTaskCountToStringLocked() REQUIRES(mLock);
+    void debugInjectTask(int fd, std::string_view clientId, std::string_view taskData);
+    void debugInjectTaskNextReboot(int fd, std::string_view clientId, std::string_view taskData,
+                                   const char* latencyInSecStr);
+    void updateGrpcConnected(bool connected);
+    android::base::Result<void> deliverRemoteTaskThroughCallback(const std::string& clientId,
+                                                                 std::string_view taskData);
+};
+
+}  // namespace remoteaccess
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/remoteaccess/hal/default/proto/Android.bp b/automotive/remoteaccess/hal/default/proto/Android.bp
new file mode 100644
index 0000000..3e0dba1
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/proto/Android.bp
@@ -0,0 +1,79 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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"],
+}
+
+genrule {
+    name: "wakeup_client_pb_h",
+    tools: [
+        "aprotoc",
+        "protoc-gen-grpc-cpp-plugin",
+    ],
+    cmd: "$(location aprotoc) -I$$(dirname $(in)) -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    srcs: [
+        "wakeup_client.proto",
+    ],
+    out: [
+        "wakeup_client.pb.h",
+        "wakeup_client.grpc.pb.h",
+    ],
+}
+
+genrule {
+    name: "wakeup_client_pb_cc",
+    tools: [
+        "aprotoc",
+        "protoc-gen-grpc-cpp-plugin",
+    ],
+    cmd: "$(location aprotoc) -I$$(dirname $(in)) -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    srcs: [
+        "wakeup_client.proto",
+    ],
+    out: [
+        "wakeup_client.pb.cc",
+        "wakeup_client.grpc.pb.cc",
+    ],
+}
+
+cc_library_static {
+    name: "wakeup_client_protos",
+    vendor_available: true,
+    host_supported: true,
+    include_dirs: [
+        "external/protobuf/src",
+    ],
+    generated_headers: [
+        "wakeup_client_pb_h",
+    ],
+    export_generated_headers: [
+        "wakeup_client_pb_h",
+    ],
+    generated_sources: [
+        "wakeup_client_pb_cc",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
diff --git a/automotive/remoteaccess/hal/default/proto/wakeup_client.proto b/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
new file mode 100644
index 0000000..4fe0d01
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.remoteaccess;
+
+/**
+ * Service provided by a wakeup client running on TCU.
+ */
+service WakeupClient {
+    /**
+     * Establish a long-live connection to receive remote tasks.
+     *
+     * <p>For the server, whenever a remote task arrives, if the connection is
+     * alive, it will use the return stream to return a task's information.
+     *
+     * <p>If the connection is not alive, the server must stores the remote task
+     * until a new connection is established (which means AP is ready to
+     * receive remote task again) and send the stored tasks.
+     *
+     * <p>If the server closes the connection, the client will try to
+     * reestablish the connection.
+     */
+    rpc GetRemoteTasks(GetRemoteTasksRequest) returns (stream GetRemoteTasksResponse) {}
+
+    /**
+     * Notifies whether AP is required to be waken up when remote task arrives.
+     *
+     * <p>Wakeup client should store and use this state until a new call with a
+     * different state arrives.
+     *
+     * <p>If {@code isWakeupRequired} in the request is true, it must wake up AP
+     * when a remote task arrives.
+     *
+     * <p>If {@code isWakeupRequired} in the request is false, it must not try
+     * to wake up AP.
+     */
+    rpc NotifyWakeupRequired(NotifyWakeupRequiredRequest) returns (NotifyWakeupRequiredResponse) {}
+}
+
+message GetRemoteTasksRequest {}
+
+message GetRemoteTasksResponse {
+    string clientId = 1;
+    bytes data = 2;
+}
+
+message NotifyWakeupRequiredRequest {
+    bool isWakeupRequired = 1;
+}
+
+message NotifyWakeupRequiredResponse {}
diff --git a/automotive/remoteaccess/hal/default/remoteaccess-default-service.rc b/automotive/remoteaccess/hal/default/remoteaccess-default-service.rc
new file mode 100644
index 0000000..b7a9cdc
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/remoteaccess-default-service.rc
@@ -0,0 +1,4 @@
+service vendor.remoteaccess-default /vendor/bin/hw/android.hardware.automotive.remoteaccess@V1-default-service
+    class hal
+    user vehicle_network
+    group system inet
diff --git a/automotive/remoteaccess/hal/default/remoteaccess-default-service.xml b/automotive/remoteaccess/hal/default/remoteaccess-default-service.xml
new file mode 100644
index 0000000..d050a1b
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/remoteaccess-default-service.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.remoteaccess</name>
+        <version>1</version>
+        <fqname>IRemoteAccess/default</fqname>
+    </hal>
+</manifest>
diff --git a/automotive/remoteaccess/hal/default/remoteaccess-tcu-test-service.rc b/automotive/remoteaccess/hal/default/remoteaccess-tcu-test-service.rc
new file mode 100644
index 0000000..59315eb
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/remoteaccess-tcu-test-service.rc
@@ -0,0 +1,5 @@
+service vendor.remoteaccess-default /vendor/bin/hw/android.hardware.automotive.remoteaccess@V1-tcu-test-service
+    class hal
+    user vehicle_network
+    group system inet
+    capabilities NET_RAW
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
new file mode 100644
index 0000000..b091162
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "RemoteAccessImpl"
+
+#include "RemoteAccessService.h"
+
+#include "BindToDeviceSocketMutator.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <grpcpp/create_channel.h>
+#include <libnetdevice/libnetdevice.h>
+#include <stdlib.h>
+
+constexpr char SERVICE_NAME[] = "android.hardware.automotive.remoteaccess.IRemoteAccess/default";
+
+int main(int /* argc */, char* /* argv */[]) {
+    LOG(INFO) << "Registering RemoteAccessService as service...";
+
+#ifndef GRPC_SERVICE_ADDRESS
+    LOG(ERROR) << "GRPC_SERVICE_ADDRESS is not defined, exiting";
+    exit(1);
+#endif
+    grpc::ChannelArguments grpcargs = {};
+
+#ifdef GRPC_SERVICE_IFNAME
+    grpcargs.SetSocketMutator(
+            android::hardware::automotive::remoteaccess::MakeBindToDeviceSocketMutator(
+                    GRPC_SERVICE_IFNAME));
+    LOG(DEBUG) << "GRPC_SERVICE_IFNAME specified as: " << GRPC_SERVICE_IFNAME;
+    LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME;
+    android::netdevice::waitFor({GRPC_SERVICE_IFNAME},
+                                android::netdevice::WaitCondition::PRESENT_AND_UP);
+    LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME << " done";
+#endif
+    auto channel = grpc::CreateCustomChannel(GRPC_SERVICE_ADDRESS,
+                                             grpc::InsecureChannelCredentials(), grpcargs);
+    auto clientStub = android::hardware::automotive::remoteaccess::WakeupClient::NewStub(channel);
+    auto service = ndk::SharedRefBase::make<
+            android::hardware::automotive::remoteaccess::RemoteAccessService>(clientStub.get());
+
+    binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME);
+    if (err != EX_NONE) {
+        LOG(ERROR) << "failed to register android.hardware.automotive.remote.IRemoteAccess service"
+                   << ", exception: " << err;
+        exit(1);
+    }
+
+    if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
+        LOG(ERROR) << "failed to set thread pool max thread count";
+        exit(1);
+    }
+    ABinderProcess_startThreadPool();
+
+    LOG(INFO) << "RemoteAccess service Ready";
+
+    ABinderProcess_joinThreadPool();
+
+    LOG(ERROR) << "Should not reach here";
+
+    return 0;
+}
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
new file mode 100644
index 0000000..5081ac0
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RemoteAccessService.h"
+
+#include <VehicleUtils.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
+#include <android/binder_status.h>
+#include <grpc++/grpc++.h>
+#include <private/android_filesystem_config.h>
+#include <sys/stat.h>
+#include <utils/Log.h>
+#include <chrono>
+#include <fstream>
+#include <iostream>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace remoteaccess {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::remoteaccess::ApState;
+using ::aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback;
+using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using ::android::base::Error;
+using ::android::base::ParseInt;
+using ::android::base::Result;
+using ::android::base::ScopedLockAssertion;
+using ::android::base::StringAppendF;
+using ::android::base::StringPrintf;
+using ::android::frameworks::automotive::vhal::IVhalClient;
+using ::android::hardware::automotive::vehicle::toInt;
+using ::grpc::ClientContext;
+using ::grpc::ClientReaderInterface;
+using ::grpc::Status;
+using ::grpc::StatusCode;
+using ::ndk::ScopedAStatus;
+
+const std::string WAKEUP_SERVICE_NAME = "com.google.vehicle.wakeup";
+const std::string PROCESSOR_ID = "application_processor";
+constexpr char COMMAND_SET_AP_STATE[] = "--set-ap-state";
+constexpr char COMMAND_START_DEBUG_CALLBACK[] = "--start-debug-callback";
+constexpr char COMMAND_STOP_DEBUG_CALLBACK[] = "--stop-debug-callback";
+constexpr char COMMAND_SHOW_TASK[] = "--show-task";
+constexpr char COMMAND_GET_VEHICLE_ID[] = "--get-vehicle-id";
+constexpr char COMMAND_INJECT_TASK[] = "--inject-task";
+constexpr char COMMAND_INJECT_TASK_NEXT_REBOOT[] = "--inject-task-next-reboot";
+constexpr char COMMAND_STATUS[] = "--status";
+
+constexpr char DEBUG_TASK_FILE[] = "/data/vendor/remoteaccess/debugTask";
+
+std::vector<uint8_t> stringToBytes(std::string_view s) {
+    const char* data = s.data();
+    return std::vector<uint8_t>(data, data + s.size());
+}
+
+ScopedAStatus rpcStatusToScopedAStatus(const Status& status, const std::string& errorMsg) {
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            status.error_code(), (errorMsg + ", error: " + status.error_message()).c_str());
+}
+
+std::string printBytes(const std::vector<uint8_t>& bytes) {
+    std::string s;
+    for (size_t i = 0; i < bytes.size(); i++) {
+        StringAppendF(&s, "%02x", bytes[i]);
+    }
+    return s;
+}
+
+bool checkBoolFlag(const char* flag) {
+    return !strcmp(flag, "1") || !strcmp(flag, "0");
+}
+
+void dprintErrorStatus(int fd, const char* detail, const ScopedAStatus& status) {
+    dprintf(fd, "%s, code: %d, error: %s\n", detail, status.getStatus(), status.getMessage());
+}
+
+std::string boolToString(bool x) {
+    return x ? "true" : "false";
+}
+
+}  // namespace
+
+RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub)
+    : mGrpcStub(grpcStub) {
+    std::ifstream debugTaskFile;
+    debugTaskFile.open(DEBUG_TASK_FILE, std::ios::in);
+    if (!debugTaskFile.is_open()) {
+        ALOGD("No debug task available");
+        return;
+    }
+
+    char buffer[1024] = {};
+    debugTaskFile.getline(buffer, sizeof(buffer));
+    std::string clientId = std::string(buffer);
+    debugTaskFile.getline(buffer, sizeof(buffer));
+    std::string taskData = std::string(buffer);
+    int latencyInSec;
+    debugTaskFile >> latencyInSec;
+    debugTaskFile.close();
+
+    ALOGD("Task for client: %s, data: [%s], latency: %d\n", clientId.c_str(), taskData.c_str(),
+          latencyInSec);
+
+    mInjectDebugTaskThread = std::thread([this, clientId, taskData, latencyInSec] {
+        std::this_thread::sleep_for(std::chrono::seconds(latencyInSec));
+        if (auto result = deliverRemoteTaskThroughCallback(clientId, taskData); !result.ok()) {
+            ALOGE("Failed to inject debug task, clientID: %s, taskData: %s, error: %s",
+                  clientId.c_str(), taskData.c_str(), result.error().message().c_str());
+            return;
+        }
+        ALOGD("Task for client: %s, data: [%s] successfully injected\n", clientId.c_str(),
+              taskData.c_str());
+    });
+}
+
+RemoteAccessService::~RemoteAccessService() {
+    maybeStopTaskLoop();
+    if (mInjectDebugTaskThread.joinable()) {
+        mInjectDebugTaskThread.join();
+    }
+}
+
+void RemoteAccessService::maybeStartTaskLoop() {
+    std::lock_guard<std::mutex> lockGuard(mStartStopTaskLoopLock);
+    if (mTaskLoopRunning) {
+        return;
+    }
+
+    mThread = std::thread([this]() { runTaskLoop(); });
+
+    mTaskLoopRunning = true;
+}
+
+void RemoteAccessService::maybeStopTaskLoop() {
+    std::lock_guard<std::mutex> lockGuard(mStartStopTaskLoopLock);
+    if (!mTaskLoopRunning) {
+        return;
+    }
+
+    {
+        std::lock_guard<std::mutex> lockGuard(mLock);
+        // Try to stop the reading stream.
+        if (mGetRemoteTasksContext) {
+            mGetRemoteTasksContext->TryCancel();
+            // Don't reset mGetRemoteTaskContext here since the read stream might still be affective
+            // and might still be using it. This will cause reader->Read to return false and
+            // mGetRemoteTasksContext will be cleared after reader->Finish() is called.
+        }
+        mTaskWaitStopped = true;
+        mCv.notify_all();
+    }
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+
+    mTaskLoopRunning = false;
+}
+
+void RemoteAccessService::updateGrpcConnected(bool connected) {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    mGrpcConnected = connected;
+}
+
+Result<void> RemoteAccessService::deliverRemoteTaskThroughCallback(const std::string& clientId,
+                                                                   std::string_view taskData) {
+    std::shared_ptr<IRemoteTaskCallback> callback;
+    {
+        std::lock_guard<std::mutex> lockGuard(mLock);
+        callback = mRemoteTaskCallback;
+        mClientIdToTaskCount[clientId] += 1;
+    }
+    if (callback == nullptr) {
+        return Error() << "No callback registered, task ignored";
+    }
+    ALOGD("Calling onRemoteTaskRequested callback for client ID: %s", clientId.c_str());
+    ScopedAStatus callbackStatus =
+            callback->onRemoteTaskRequested(clientId, stringToBytes(taskData));
+    if (!callbackStatus.isOk()) {
+        return Error() << "Failed to call onRemoteTaskRequested callback, status: "
+                       << callbackStatus.getStatus()
+                       << ", message: " << callbackStatus.getMessage();
+    }
+    return {};
+}
+
+void RemoteAccessService::runTaskLoop() {
+    GetRemoteTasksRequest request = {};
+    std::unique_ptr<ClientReaderInterface<GetRemoteTasksResponse>> reader;
+    while (true) {
+        {
+            std::lock_guard<std::mutex> lockGuard(mLock);
+            mGetRemoteTasksContext.reset(new ClientContext());
+            reader = mGrpcStub->GetRemoteTasks(mGetRemoteTasksContext.get(), request);
+        }
+        updateGrpcConnected(true);
+        GetRemoteTasksResponse response;
+        while (reader->Read(&response)) {
+            ALOGI("Receiving one task from remote task client");
+
+            if (auto result =
+                        deliverRemoteTaskThroughCallback(response.clientid(), response.data());
+                !result.ok()) {
+                ALOGE("%s", result.error().message().c_str());
+                continue;
+            }
+        }
+        updateGrpcConnected(false);
+        Status status = reader->Finish();
+        mGetRemoteTasksContext.reset();
+
+        ALOGE("GetRemoteTasks stream breaks, code: %d, message: %s, sleeping for 10s and retry",
+              status.error_code(), status.error_message().c_str());
+        // The long lasting connection should not return. But if the server returns, retry after
+        // 10s.
+        {
+            std::unique_lock lk(mLock);
+            if (mCv.wait_for(lk, std::chrono::milliseconds(mRetryWaitInMs), [this] {
+                    ScopedLockAssertion lockAssertion(mLock);
+                    return mTaskWaitStopped;
+                })) {
+                // If the stopped flag is set, we are quitting, exit the loop.
+                break;
+            }
+        }
+    }
+}
+
+ScopedAStatus RemoteAccessService::getVehicleId(std::string* vehicleId) {
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    auto vhalClient = IVhalClient::tryCreate();
+    if (vhalClient == nullptr) {
+        ALOGE("Failed to connect to VHAL");
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                /*errorCode=*/0, "Failed to connect to VHAL to get vehicle ID");
+    }
+    return getVehicleIdWithClient(*vhalClient.get(), vehicleId);
+#else
+    // Don't use VHAL client in fuzzing since IPC is not allowed.
+    return ScopedAStatus::ok();
+#endif
+}
+
+ScopedAStatus RemoteAccessService::getVehicleIdWithClient(IVhalClient& vhalClient,
+                                                          std::string* vehicleId) {
+    auto result = vhalClient.getValueSync(
+            *vhalClient.createHalPropValue(toInt(VehicleProperty::INFO_VIN)));
+    if (!result.ok()) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                /*errorCode=*/0,
+                ("failed to get INFO_VIN from VHAL: " + result.error().message()).c_str());
+    }
+    *vehicleId = (*result)->getStringValue();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus RemoteAccessService::getProcessorId(std::string* processorId) {
+    *processorId = PROCESSOR_ID;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus RemoteAccessService::getWakeupServiceName(std::string* wakeupServiceName) {
+    *wakeupServiceName = WAKEUP_SERVICE_NAME;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus RemoteAccessService::setRemoteTaskCallback(
+        const std::shared_ptr<IRemoteTaskCallback>& callback) {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    mRemoteTaskCallback = callback;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus RemoteAccessService::clearRemoteTaskCallback() {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    mRemoteTaskCallback.reset();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus RemoteAccessService::notifyApStateChange(const ApState& newState) {
+    ClientContext context;
+    NotifyWakeupRequiredRequest request = {};
+    request.set_iswakeuprequired(newState.isWakeupRequired);
+    NotifyWakeupRequiredResponse response = {};
+    Status status = mGrpcStub->NotifyWakeupRequired(&context, request, &response);
+    if (!status.ok()) {
+        return rpcStatusToScopedAStatus(status, "Failed to notify isWakeupRequired");
+    }
+
+    if (newState.isReadyForRemoteTask) {
+        maybeStartTaskLoop();
+    } else {
+        maybeStopTaskLoop();
+    }
+    return ScopedAStatus::ok();
+}
+
+bool RemoteAccessService::checkDumpPermission() {
+    uid_t uid = AIBinder_getCallingUid();
+    return uid == AID_ROOT || uid == AID_SHELL || uid == AID_SYSTEM;
+}
+
+void RemoteAccessService::dumpHelp(int fd) {
+    dprintf(fd,
+            "RemoteAccess HAL debug interface, Usage: \n"
+            "%s [0/1](isReadyForRemoteTask) [0/1](isWakeupRequired): Set the new AP state\n"
+            "%s: Start a debug callback that will record the received tasks\n"
+            "%s: Stop the debug callback\n"
+            "%s: Show tasks received by debug callback\n"
+            "%s: Get vehicle id\n"
+            "%s [client_id] [task_data]: Inject a task\n"
+            "%s [client_id] [task_data] [latencyInSec]: "
+            "Inject a task on next reboot after latencyInSec seconds\n"
+            "%s: Show status\n",
+            COMMAND_SET_AP_STATE, COMMAND_START_DEBUG_CALLBACK, COMMAND_STOP_DEBUG_CALLBACK,
+            COMMAND_SHOW_TASK, COMMAND_GET_VEHICLE_ID, COMMAND_INJECT_TASK,
+            COMMAND_INJECT_TASK_NEXT_REBOOT, COMMAND_STATUS);
+}
+
+binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t numArgs) {
+    if (!checkDumpPermission()) {
+        dprintf(fd, "Caller must be root, system or shell\n");
+        return STATUS_PERMISSION_DENIED;
+    }
+
+    if (numArgs == 0) {
+        dumpHelp(fd);
+        printCurrentStatus(fd);
+        return STATUS_OK;
+    }
+
+    if (!strcmp(args[0], COMMAND_SET_AP_STATE)) {
+        if (numArgs < 3) {
+            dumpHelp(fd);
+            return STATUS_OK;
+        }
+        ApState apState = {};
+        const char* remoteTaskFlag = args[1];
+        if (!strcmp(remoteTaskFlag, "1") && !strcmp(remoteTaskFlag, "0")) {
+            dumpHelp(fd);
+            return STATUS_OK;
+        }
+        if (!checkBoolFlag(args[1])) {
+            dumpHelp(fd);
+            return STATUS_OK;
+        }
+        if (!strcmp(args[1], "1")) {
+            apState.isReadyForRemoteTask = true;
+        }
+        if (!checkBoolFlag(args[2])) {
+            dumpHelp(fd);
+            return STATUS_OK;
+        }
+        if (!strcmp(args[2], "1")) {
+            apState.isWakeupRequired = true;
+        }
+        auto status = notifyApStateChange(apState);
+        if (!status.isOk()) {
+            dprintErrorStatus(fd, "Failed to set AP state", status);
+        } else {
+            dprintf(fd, "successfully set the new AP state\n");
+        }
+    } else if (!strcmp(args[0], COMMAND_START_DEBUG_CALLBACK)) {
+        mDebugCallback = ndk::SharedRefBase::make<DebugRemoteTaskCallback>();
+        setRemoteTaskCallback(mDebugCallback);
+        dprintf(fd, "Debug callback registered\n");
+    } else if (!strcmp(args[0], COMMAND_STOP_DEBUG_CALLBACK)) {
+        if (mDebugCallback) {
+            mDebugCallback.reset();
+        }
+        clearRemoteTaskCallback();
+        dprintf(fd, "Debug callback unregistered\n");
+    } else if (!strcmp(args[0], COMMAND_SHOW_TASK)) {
+        if (mDebugCallback) {
+            dprintf(fd, "%s", mDebugCallback->printTasks().c_str());
+        } else {
+            dprintf(fd, "Debug callback is not currently used, use \"%s\" first.\n",
+                    COMMAND_START_DEBUG_CALLBACK);
+        }
+    } else if (!strcmp(args[0], COMMAND_GET_VEHICLE_ID)) {
+        std::string vehicleId;
+        auto status = getVehicleId(&vehicleId);
+        if (!status.isOk()) {
+            dprintErrorStatus(fd, "Failed to get vehicle ID", status);
+        } else {
+            dprintf(fd, "Vehicle Id: %s\n", vehicleId.c_str());
+        }
+    } else if (!strcmp(args[0], COMMAND_INJECT_TASK)) {
+        if (numArgs < 3) {
+            dumpHelp(fd);
+            return STATUS_OK;
+        }
+        debugInjectTask(fd, args[1], args[2]);
+    } else if (!strcmp(args[0], COMMAND_INJECT_TASK_NEXT_REBOOT)) {
+        if (numArgs < 4) {
+            dumpHelp(fd);
+            return STATUS_OK;
+        }
+        debugInjectTaskNextReboot(fd, args[1], args[2], args[3]);
+    } else if (!strcmp(args[0], COMMAND_STATUS)) {
+        printCurrentStatus(fd);
+    } else {
+        dumpHelp(fd);
+    }
+
+    return STATUS_OK;
+}
+
+void RemoteAccessService::printCurrentStatus(int fd) {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    dprintf(fd,
+            "\nRemoteAccess HAL status \n"
+            "Remote task callback registered: %s\n"
+            "Task receiving GRPC connection established: %s\n"
+            "Received task count by clientId: \n%s\n",
+            boolToString(mRemoteTaskCallback.get()).c_str(), boolToString(mGrpcConnected).c_str(),
+            clientIdToTaskCountToStringLocked().c_str());
+}
+
+void RemoteAccessService::debugInjectTask(int fd, std::string_view clientId,
+                                          std::string_view taskData) {
+    std::string clientIdCopy = std::string(clientId);
+    if (auto result = deliverRemoteTaskThroughCallback(clientIdCopy, taskData); !result.ok()) {
+        dprintf(fd, "Failed to inject task: %s\n", result.error().message().c_str());
+        return;
+    }
+    dprintf(fd, "Task for client: %s, data: [%s] successfully injected\n", clientId.data(),
+            taskData.data());
+}
+
+void RemoteAccessService::debugInjectTaskNextReboot(int fd, std::string_view clientId,
+                                                    std::string_view taskData,
+                                                    const char* latencyInSecStr) {
+    int latencyInSec;
+    if (!ParseInt(latencyInSecStr, &latencyInSec)) {
+        dprintf(fd, "The input latency in second is not a valid integer");
+        return;
+    }
+    std::ofstream debugTaskFile;
+    debugTaskFile.open(DEBUG_TASK_FILE, std::ios::out);
+    if (!debugTaskFile.is_open()) {
+        dprintf(fd,
+                "Failed to open debug task file, please run the command: "
+                "'adb shell touch %s' first\n",
+                DEBUG_TASK_FILE);
+        return;
+    }
+    if (taskData.find("\n") != std::string::npos) {
+        dprintf(fd, "Task data must not contain newline\n");
+        return;
+    }
+    debugTaskFile << clientId << "\n" << taskData << "\n" << latencyInSec;
+    debugTaskFile.close();
+    dprintf(fd,
+            "Task with clientId: %s, task data: %s, latency: %d sec scheduled for next reboot\n",
+            clientId.data(), taskData.data(), latencyInSec);
+}
+
+std::string RemoteAccessService::clientIdToTaskCountToStringLocked() {
+    // Print the table header
+    std::string output = "| ClientId | Count |\n";
+    for (const auto& [clientId, taskCount] : mClientIdToTaskCount) {
+        output += StringPrintf("  %-9s  %-6zu\n", clientId.c_str(), taskCount);
+    }
+    return output;
+}
+
+ScopedAStatus DebugRemoteTaskCallback::onRemoteTaskRequested(const std::string& clientId,
+                                                             const std::vector<uint8_t>& data) {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    mTasks.push_back({
+            .clientId = clientId,
+            .data = data,
+    });
+    return ScopedAStatus::ok();
+}
+
+std::string DebugRemoteTaskCallback::printTasks() {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    std::string s = StringPrintf("Received %zu tasks in %f seconds", mTasks.size(),
+                                 (android::uptimeMillis() - mStartTimeMillis) / 1000.);
+    for (size_t i = 0; i < mTasks.size(); i++) {
+        StringAppendF(&s, "Client Id: %s, Data: %s\n", mTasks[i].clientId.c_str(),
+                      printBytes(mTasks[i].data).c_str());
+    }
+    return s;
+}
+
+}  // namespace remoteaccess
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/remoteaccess/hal/default/test/Android.bp b/automotive/remoteaccess/hal/default/test/Android.bp
new file mode 100644
index 0000000..227175a
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/test/Android.bp
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "RemoteAccessServiceUnitTest",
+    vendor: true,
+    srcs: ["*.cpp"],
+    whole_static_libs: [
+        "RemoteAccessService",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    // libgrpc++.so is installed as root, require root to access it.
+    require_root: true,
+    static_libs: [
+        "libgtest",
+        "libgmock",
+    ],
+    defaults: [
+        "vhalclient_defaults",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
new file mode 100644
index 0000000..c5afd63
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RemoteAccessService.h"
+
+#include <AidlHalPropValue.h>
+#include <IVhalClient.h>
+#include <aidl/android/hardware/automotive/remoteaccess/ApState.h>
+#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteTaskCallback.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropValue.h>
+#include <gmock/gmock.h>
+#include <grpcpp/test/mock_stream.h>
+#include <gtest/gtest.h>
+#include <wakeup_client.grpc.pb.h>
+#include <chrono>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace remoteaccess {
+
+namespace {
+
+using ::android::base::ScopedLockAssertion;
+using ::android::frameworks::automotive::vhal::AidlHalPropValue;
+using ::android::frameworks::automotive::vhal::IHalPropConfig;
+using ::android::frameworks::automotive::vhal::IHalPropValue;
+using ::android::frameworks::automotive::vhal::ISubscriptionCallback;
+using ::android::frameworks::automotive::vhal::ISubscriptionClient;
+using ::android::frameworks::automotive::vhal::IVhalClient;
+using ::android::frameworks::automotive::vhal::VhalClientResult;
+
+using ::aidl::android::hardware::automotive::remoteaccess::ApState;
+using ::aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+
+using ::grpc::ClientAsyncReaderInterface;
+using ::grpc::ClientAsyncResponseReaderInterface;
+using ::grpc::ClientContext;
+using ::grpc::ClientReader;
+using ::grpc::ClientReaderInterface;
+using ::grpc::CompletionQueue;
+using ::grpc::Status;
+using ::grpc::testing::MockClientReader;
+using ::ndk::ScopedAStatus;
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+
+constexpr char kTestVin[] = "test_VIN";
+
+}  // namespace
+
+class MockGrpcClientStub : public WakeupClient::StubInterface {
+  public:
+    MOCK_METHOD(ClientReaderInterface<GetRemoteTasksResponse>*, GetRemoteTasksRaw,
+                (ClientContext * context, const GetRemoteTasksRequest& request));
+    MOCK_METHOD(Status, NotifyWakeupRequired,
+                (ClientContext * context, const NotifyWakeupRequiredRequest& request,
+                 NotifyWakeupRequiredResponse* response));
+    // Async methods which we do not care.
+    MOCK_METHOD(ClientAsyncReaderInterface<GetRemoteTasksResponse>*, AsyncGetRemoteTasksRaw,
+                (ClientContext * context, const GetRemoteTasksRequest& request, CompletionQueue* cq,
+                 void* tag));
+    MOCK_METHOD(ClientAsyncReaderInterface<GetRemoteTasksResponse>*, PrepareAsyncGetRemoteTasksRaw,
+                (ClientContext * context, const GetRemoteTasksRequest& request,
+                 CompletionQueue* cq));
+    MOCK_METHOD(ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>*,
+                AsyncNotifyWakeupRequiredRaw,
+                (ClientContext * context, const NotifyWakeupRequiredRequest& request,
+                 CompletionQueue* cq));
+    MOCK_METHOD(ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>*,
+                PrepareAsyncNotifyWakeupRequiredRaw,
+                (ClientContext * context, const NotifyWakeupRequiredRequest& request,
+                 CompletionQueue* cq));
+};
+
+class FakeVhalClient final : public android::frameworks::automotive::vhal::IVhalClient {
+  public:
+    inline bool isAidlVhal() { return true; }
+
+    VhalClientResult<std::unique_ptr<IHalPropValue>> getValueSync(
+            const IHalPropValue& requestValue) override {
+        auto propValue = std::make_unique<AidlHalPropValue>(requestValue.getPropId());
+        propValue->setStringValue(kTestVin);
+        return propValue;
+    }
+
+    std::unique_ptr<IHalPropValue> createHalPropValue(int32_t propId) override {
+        return std::make_unique<AidlHalPropValue>(propId);
+    }
+
+    // Functions we do not care.
+    std::unique_ptr<IHalPropValue> createHalPropValue([[maybe_unused]] int32_t propId,
+                                                      [[maybe_unused]] int32_t areaId) override {
+        return nullptr;
+    }
+
+    void getValue([[maybe_unused]] const IHalPropValue& requestValue,
+                  [[maybe_unused]] std::shared_ptr<GetValueCallbackFunc> callback) override {}
+
+    void setValue([[maybe_unused]] const IHalPropValue& requestValue,
+                  [[maybe_unused]] std::shared_ptr<SetValueCallbackFunc> callback) override {}
+
+    VhalClientResult<void> setValueSync([[maybe_unused]] const IHalPropValue& requestValue) {
+        return {};
+    }
+
+    VhalClientResult<void> addOnBinderDiedCallback(
+            [[maybe_unused]] std::shared_ptr<OnBinderDiedCallbackFunc> callback) override {
+        return {};
+    }
+
+    VhalClientResult<void> removeOnBinderDiedCallback(
+            [[maybe_unused]] std::shared_ptr<OnBinderDiedCallbackFunc> callback) override {
+        return {};
+    }
+
+    VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> getAllPropConfigs() override {
+        return std::vector<std::unique_ptr<IHalPropConfig>>();
+    }
+
+    VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> getPropConfigs(
+            [[maybe_unused]] std::vector<int32_t> propIds) override {
+        return std::vector<std::unique_ptr<IHalPropConfig>>();
+    }
+
+    std::unique_ptr<ISubscriptionClient> getSubscriptionClient(
+            [[maybe_unused]] std::shared_ptr<ISubscriptionCallback> callback) override {
+        return nullptr;
+    }
+};
+
+class FakeRemoteTaskCallback : public BnRemoteTaskCallback {
+  public:
+    ScopedAStatus onRemoteTaskRequested(const std::string& clientId,
+                                        const std::vector<uint8_t>& data) override {
+        std::lock_guard<std::mutex> lockGuard(mLock);
+        mDataByClientId[clientId] = data;
+        mTaskCount++;
+        mCv.notify_all();
+        return ScopedAStatus::ok();
+    }
+
+    std::vector<uint8_t> getData(const std::string& clientId) { return mDataByClientId[clientId]; }
+
+    bool wait(size_t taskCount, size_t timeoutInSec) {
+        std::unique_lock<std::mutex> lock(mLock);
+        return mCv.wait_for(lock, std::chrono::seconds(timeoutInSec), [taskCount, this] {
+            ScopedLockAssertion lockAssertion(mLock);
+            return mTaskCount >= taskCount;
+        });
+    }
+
+  private:
+    std::mutex mLock;
+    std::unordered_map<std::string, std::vector<uint8_t>> mDataByClientId GUARDED_BY(mLock);
+    size_t mTaskCount GUARDED_BY(mLock) = 0;
+    std::condition_variable mCv;
+};
+
+class RemoteAccessServiceUnitTest : public ::testing::Test {
+  public:
+    virtual void SetUp() override {
+        mGrpcWakeupClientStub = std::make_unique<MockGrpcClientStub>();
+        mService = ndk::SharedRefBase::make<RemoteAccessService>(mGrpcWakeupClientStub.get());
+    }
+
+    MockGrpcClientStub* getGrpcWakeupClientStub() { return mGrpcWakeupClientStub.get(); }
+
+    RemoteAccessService* getService() { return mService.get(); }
+
+    void setRetryWaitInMs(size_t retryWaitInMs) { mService->setRetryWaitInMs(retryWaitInMs); }
+
+    ScopedAStatus getVehicleIdWithClient(IVhalClient& vhalClient, std::string* vehicleId) {
+        return mService->getVehicleIdWithClient(vhalClient, vehicleId);
+    }
+
+  private:
+    std::unique_ptr<MockGrpcClientStub> mGrpcWakeupClientStub;
+    std::shared_ptr<RemoteAccessService> mService;
+};
+
+TEST_F(RemoteAccessServiceUnitTest, TestGetWakeupServiceName) {
+    std::string serviceName;
+
+    ScopedAStatus status = getService()->getWakeupServiceName(&serviceName);
+
+    EXPECT_TRUE(status.isOk());
+    EXPECT_EQ(serviceName, "com.google.vehicle.wakeup");
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestNotifyApStateChangeWakeupRequired) {
+    bool isWakeupRequired = false;
+    EXPECT_CALL(*getGrpcWakeupClientStub(), NotifyWakeupRequired)
+            .WillOnce([&isWakeupRequired]([[maybe_unused]] ClientContext* context,
+                                          const NotifyWakeupRequiredRequest& request,
+                                          [[maybe_unused]] NotifyWakeupRequiredResponse* response) {
+                isWakeupRequired = request.iswakeuprequired();
+                return Status();
+            });
+
+    ApState newState = {
+            .isWakeupRequired = true,
+    };
+    ScopedAStatus status = getService()->notifyApStateChange(newState);
+
+    EXPECT_TRUE(status.isOk());
+    EXPECT_TRUE(isWakeupRequired);
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestGetRemoteTasks) {
+    GetRemoteTasksResponse response1;
+    std::vector<uint8_t> testData = {0xde, 0xad, 0xbe, 0xef};
+    response1.set_clientid("1");
+    response1.set_data(testData.data(), testData.size());
+    GetRemoteTasksResponse response2;
+    response2.set_clientid("2");
+    std::shared_ptr<FakeRemoteTaskCallback> callback =
+            ndk::SharedRefBase::make<FakeRemoteTaskCallback>();
+
+    ON_CALL(*getGrpcWakeupClientStub(), GetRemoteTasksRaw)
+            .WillByDefault(
+                    [response1, response2]([[maybe_unused]] ClientContext* context,
+                                           [[maybe_unused]] const GetRemoteTasksRequest& request) {
+                        // mockReader ownership will be transferred to the client so we don't own it
+                        // here.
+                        MockClientReader<GetRemoteTasksResponse>* mockClientReader =
+                                new MockClientReader<GetRemoteTasksResponse>();
+                        EXPECT_CALL(*mockClientReader, Finish()).WillOnce(Return(Status::OK));
+                        EXPECT_CALL(*mockClientReader, Read(_))
+                                .WillOnce(DoAll(SetArgPointee<0>(response1), Return(true)))
+                                .WillOnce(DoAll(SetArgPointee<0>(response2), Return(true)))
+                                .WillRepeatedly(Return(false));
+                        return mockClientReader;
+                    });
+
+    getService()->setRemoteTaskCallback(callback);
+    // Start the long live connection to receive tasks.
+    ApState newState = {
+            .isReadyForRemoteTask = true,
+    };
+    ASSERT_TRUE(getService()->notifyApStateChange(newState).isOk());
+
+    ASSERT_TRUE(callback->wait(/*taskCount=*/2, /*timeoutInSec=*/10))
+            << "Did not receive enough tasks";
+    EXPECT_EQ(callback->getData("1"), testData);
+    EXPECT_EQ(callback->getData("2"), std::vector<uint8_t>());
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestGetRemoteTasksRetryConnection) {
+    GetRemoteTasksResponse response;
+    std::shared_ptr<FakeRemoteTaskCallback> callback =
+            ndk::SharedRefBase::make<FakeRemoteTaskCallback>();
+
+    ON_CALL(*getGrpcWakeupClientStub(), GetRemoteTasksRaw)
+            .WillByDefault([response]([[maybe_unused]] ClientContext* context,
+                                      [[maybe_unused]] const GetRemoteTasksRequest& request) {
+                // mockReader ownership will be transferred to the client so we don't own it here.
+                MockClientReader<GetRemoteTasksResponse>* mockClientReader =
+                        new MockClientReader<GetRemoteTasksResponse>();
+                EXPECT_CALL(*mockClientReader, Finish()).WillOnce(Return(Status::OK));
+                // Connection fails after receiving one task. Should retry after some time.
+                EXPECT_CALL(*mockClientReader, Read(_))
+                        .WillOnce(DoAll(SetArgPointee<0>(response), Return(true)))
+                        .WillRepeatedly(Return(false));
+                return mockClientReader;
+            });
+
+    getService()->setRemoteTaskCallback(callback);
+    setRetryWaitInMs(100);
+    // Start the long live connection to receive tasks.
+    ApState newState = {
+            .isReadyForRemoteTask = true,
+    };
+    ASSERT_TRUE(getService()->notifyApStateChange(newState).isOk());
+
+    ASSERT_TRUE(callback->wait(/*taskCount=*/2, /*timeoutInSec=*/10))
+            << "Did not receive enough tasks";
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestGetRemoteTasksDefaultNotReady) {
+    GetRemoteTasksResponse response1;
+    std::vector<uint8_t> testData = {0xde, 0xad, 0xbe, 0xef};
+    response1.set_clientid("1");
+    response1.set_data(testData.data(), testData.size());
+    GetRemoteTasksResponse response2;
+    response2.set_clientid("2");
+    std::shared_ptr<FakeRemoteTaskCallback> callback =
+            ndk::SharedRefBase::make<FakeRemoteTaskCallback>();
+
+    EXPECT_CALL(*getGrpcWakeupClientStub(), GetRemoteTasksRaw).Times(0);
+
+    // Default state is not ready for remote tasks, so no callback will be called.
+    getService()->setRemoteTaskCallback(callback);
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestGetRemoteTasksNotReadyAfterReady) {
+    GetRemoteTasksResponse response1;
+    std::vector<uint8_t> testData = {0xde, 0xad, 0xbe, 0xef};
+    response1.set_clientid("1");
+    response1.set_data(testData.data(), testData.size());
+    GetRemoteTasksResponse response2;
+    response2.set_clientid("2");
+    std::shared_ptr<FakeRemoteTaskCallback> callback =
+            ndk::SharedRefBase::make<FakeRemoteTaskCallback>();
+
+    ON_CALL(*getGrpcWakeupClientStub(), GetRemoteTasksRaw)
+            .WillByDefault(
+                    [response1, response2]([[maybe_unused]] ClientContext* context,
+                                           [[maybe_unused]] const GetRemoteTasksRequest& request) {
+                        // mockReader ownership will be transferred to the client so we don't own it
+                        // here.
+                        MockClientReader<GetRemoteTasksResponse>* mockClientReader =
+                                new MockClientReader<GetRemoteTasksResponse>();
+                        EXPECT_CALL(*mockClientReader, Finish()).WillOnce(Return(Status::OK));
+                        EXPECT_CALL(*mockClientReader, Read(_))
+                                .WillOnce(DoAll(SetArgPointee<0>(response1), Return(true)))
+                                .WillOnce(DoAll(SetArgPointee<0>(response2), Return(true)))
+                                .WillRepeatedly(Return(false));
+                        return mockClientReader;
+                    });
+    // Should only be called once when is is ready for remote task.
+    EXPECT_CALL(*getGrpcWakeupClientStub(), GetRemoteTasksRaw).Times(1);
+
+    getService()->setRemoteTaskCallback(callback);
+    setRetryWaitInMs(100);
+    // Start the long live connection to receive tasks.
+    ApState newState = {
+            .isReadyForRemoteTask = true,
+    };
+    ASSERT_TRUE(getService()->notifyApStateChange(newState).isOk());
+    ASSERT_TRUE(callback->wait(/*taskCount=*/2, /*timeoutInSec=*/10))
+            << "Did not receive enough tasks";
+
+    // Stop the long live connection.
+    newState.isReadyForRemoteTask = false;
+    ASSERT_TRUE(getService()->notifyApStateChange(newState).isOk());
+
+    // Wait for the retry delay, but the loop should already exit.
+    std::this_thread::sleep_for(std::chrono::milliseconds(150));
+}
+
+TEST_F(RemoteAccessServiceUnitTest, testGetVehicleId) {
+    std::string vehicleId;
+
+    FakeVhalClient vhalClient;
+
+    ASSERT_TRUE(getVehicleIdWithClient(vhalClient, &vehicleId).isOk());
+    ASSERT_EQ(vehicleId, kTestVin);
+}
+
+}  // namespace remoteaccess
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/remoteaccess/test_grpc_server/README.md b/automotive/remoteaccess/test_grpc_server/README.md
new file mode 100644
index 0000000..af3d54a
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/README.md
@@ -0,0 +1,332 @@
+# Test GRPC Server.
+
+A test GRPC server that implements wakeup_client.proto. This test server acts
+as a reference implementation for a remote wakeup client running on TCU. The
+test server does not communicate with any actual network server. It has the
+following behavior:
+
+* It starts a GRPC server on 'DGRPC_SERVICE_ADDRESS' compile flag which is
+  localhost:50051. The GRPC server provides the service according to
+  hardware/interfaces/automotive/remoteaccess/hal/default/proto/wakeup_client.proto.
+
+  In real implementation, DGRPC_SERVICE_ADDRESS can be specified to any IP
+  address where the TCU can be exposed to Application Processor. The default
+  remote access HAL implementation
+  (hardware/interfaces/automotive/remoteaccess/hal/default/Android.bp) also
+  uses DGRPC_SERVICE_ADDRESS to find this GRPC server, so it must have the
+  same IP address.
+
+* It generates a fake task using FakeTaskGenerator every 'kTaskIntervalInMs' ms.
+
+  In real implementation, it should receive task from the remote server.
+
+* Each fake task has an increasing unique client ID. The task data is always
+  what's defined for 'DATA' variable.
+
+  In real implementation, the client ID and task data should come from the
+  remote server.
+
+* The generated tasks are put into a task queue which is a priority queue sorted
+  by task received time.
+
+  In real implementation, if the server provides a task timestamp, then this
+  queue can be sorted by that task timestamp instead.
+
+* When the Application processor is started, the remote access HAL running on
+  Android will call 'GetRemoteTasks' to establish a long-live connection. This
+  connection is used to deliver all task data from remote wakeup client to
+  remote access HAL, which eventually to car service and applications.
+
+  When the 'GetRemoteTasks' is called, the wakeup client must send all the
+  pending tasks through the 'ServerWriter'. If no task is pending, then it must
+  block and wait for a new task to arrive.
+
+  If one task data fails to be sent through the channel, it likely means
+  the other side (Application processor) is shutting down or has closed the
+  channel. The wakeup client must put the task back to the pending queue and
+  wait for a new 'GetRemoteTasks' request to retry sending the task.
+
+* When a new task arrives, if 'WakeupRequired' is true, then try to wakeup
+  the Application Processor by sending a specific CAN message. It is possible that
+  the waking up is already in progress. This is okay since Vehicle Processor
+  should ignore wakeup message if a wakeup is already in progress.
+
+* When 'WakeupRequired' is updated from false to true, if there are unexpired
+  pending tasks in the task queue, try to wakeup Application Processor.
+
+  This is to handle the situation when a task arrives while the device is
+  shutting down. During the device shutdown, the channel to deliver the remote
+  tasks to Application Processor is shutdown so the new task will be added to the
+  task queue. 'WakeupRequired' will be set to false to prevent the wakeup
+  message preventing the shutdown. After the shutdown is complete,
+  'WakeupRequired' will be set to true and this wakeup client must try to wake
+  up the device again to execute the pending tasks.
+
+* Every pending task has a timeout: 'kTaskTimeoutInMs'. If the pending task
+  is not delivered to remote access HAL before the timeout (through
+  GetRemoteTasks), the task timed out and a warning message is logged.
+
+  In real implementation, this kTaskTimeoutInMs has to be set long enough to
+  allow an Android bootup to happen. 20s is a reasonable value. When a task
+  timed out, the wakeup client should also report to remote task server about
+  the task timeout failure.
+
+## How to build the test wakeup client
+
+* Under android root: `source build/envsetup.sh`
+
+* Add
+  ```
+  PRODUCT_SOONG_NAMESPACES += hardware/interfaces/automotive/remoteaccess/test_grpc_server/lib`
+  ```
+
+  to `device/generic/car/common/car.mk`.
+
+* `lunch sdk_car_x86_64-userdebug`
+
+* `make -j TestWakeupClientServer`
+
+* `make -j ApPOwerControlLib`
+
+## How to push the test wakeup client to a TCU which runs Android.
+
+* Make the target device writable:
+
+  `adb root`
+
+  `adb remount` (remount might take a while)
+
+  `adb reboot`
+
+  `adb root`
+
+  `adb remount`
+
+* Under android root: `cd $ANDROID_PRODUCT_OUT`
+
+* `adb push vendor/bin/TestWakeupClientServer /vendor/bin`
+
+* `adb push vendor/lib64/ApPowerControlLib.so /vendor/lib64`
+
+* `adb shell`
+
+* `su`
+
+* `/vendor/bin/TestWakeupClientServer`
+
+## How to build and test the test wakeup client using one car emulator.
+
+In this test setup we will use one car emulator
+(sdk_car_x86_64-userdebug). We assume both the TCU and the remote access HAL
+runs on the same Android system, and they communicate through local loopback
+interface.
+
+* Under android root, `source build/envsetup.sh`
+
+* Add
+  ```
+  PRODUCT_SOONG_NAMESPACES += hardware/interfaces/automotive/remoteaccess/test_grpc_server/lib`
+  ```
+
+  to `device/generic/car/common/car.mk`.
+
+* `lunch sdk_car_x86_64-userdebug`
+
+* `m -j`
+
+* Run the emulator, the '-read-only' flag is required to run multiple instances:
+
+  `emulator -writable-system -read-only`
+
+* The android lunch target: sdk_car_x86_64-userdebug and
+  cf_x86_64_auto-userdebug already contains the default remote access HAL. For
+  other lunch target, you can add the default remote access HAL by adding
+  'android.hardware.automotive.remoteaccess@V1-default-service' to
+  'PRODUCT_PACKAGES' variable in mk file, see `device/generic/car/common/car.mk`
+  as example.
+
+  To verify whether remote access HAL is running, you can use the following
+  command to check:
+
+  `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default`
+
+* Make the target device writable:
+
+  `adb root`
+
+  `adb remount` (remount might take a while)
+
+  `adb reboot`
+
+  `adb root`
+
+  `adb remount`
+
+* `make -j TestWakeupClientServer`
+
+* `make -j ApPOwerControlLib`
+
+* `adb push $ANDROID_PRODUCT_OUT/vendor/bin/TestWakeupClientServer /vendor/bin`
+
+* `adb push $ANDROID_PRODUCT_OUT/vendor/lib64/ApPowerControlLib.so /vendor/lib64`
+
+* `adb shell`
+
+* `emulator_car_x86_64:/ # su`
+
+* `emulator_car_x86_64:/ # /vendor/bin/TestWakeupClientServer`
+
+* Remote access HAL should start by default when the car emulator starts. Now
+  the test wake up client should also be running and generating fake tasks.
+
+  Start a new session under android root
+
+  `source build/envsetup.sh`
+
+  `lunch sdk_car_x86_64-userdebug`
+
+  `adb shell`
+
+  `emulator_car_x86_64:/ # su`
+
+* Issue the command to start a simple debug callback that will capture all the
+  received tasks at the remote access HAL side:
+
+  `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --start-debug-callback`
+
+* Issue the following debug command to remote access HAL to establish the
+  communication channel between it and the test wakeup client. This command
+  also notifies that wakeup is not required:
+
+  `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 1 0`
+
+* Wait for a while, issue the following command to show the received fake tasks:
+
+  `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task`
+
+  You should expect to see some received tasks printed out.
+
+* Simulate the Application Processor is shutting down by issuing the following
+  command:
+
+  `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 0 0`
+
+* Wait for a while, issue the following command to show received tasks again:
+
+  `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task`
+
+  You should expect to see no new tasks received since remote access HAL already
+  closed the communication channel.
+
+* Simulate the Application Processor is already shutdown and wake up is required
+  now:
+
+  `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 0 1`
+
+  Now you should expect to see the test wakeup client printing out messages
+  that it is trying to wake up application processor.
+
+* Simulate the Application Processor is waken up:
+
+  `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 1 0`
+
+* A new communication channel should have been established and all pending
+  non-expired tasks should be delivered to the remote access HAL.
+
+  `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task`
+
+* Now you can issue `ctrl c` on the first adb shell to stop the test wakeup
+  client.
+
+* After the test, you can use `ctrl D` to exit the adb shell.
+
+## How to build and test the test wakeup client using two car emulators.
+
+In this test case, we are going to use two car emulators, one as the
+Application Processor, one as the TCU.
+
+* Change the IP address to allow IP communication between different emulator
+  instances. For detail about why we change it this way, see [interconnecting
+  emulator instance](https://developer.android.com/studio/run/emulator-networking#connecting).
+
+  Change 'DGRPC_SERVICE_ADDRESS' in `[android_root]/hardware/interfaces/automotive/remoteaccess/test_grpc_server/impl/Android.bp` to
+  `10.0.2.15:50051`.
+
+  Change `DGRPC_SERVICE_ADDRESS` in '[android_root]/hardware/interfaces/automotive/remoteaccess/hal/defaut/Android.bp' to
+  `10.0.2.2:50051`.
+
+* Under android root: `source build/envsetup.sh`
+
+* `lunch sdk_car_x86_64-userdebug`
+
+*  `m -j`
+
+* Start one car emulator as TCU
+
+  `emulator -writable-system -read-only`
+
+* Start a new shell session. Connect to the emulator's console,
+  see [Start and stop a console session](https://developer.android.com/studio/run/emulator-console#console-session)
+  for detail.
+
+  `telnet localhost 5554`
+
+* `auth auth_token` where auth_token must match the contents of the
+  `~/.emulator_console_auth_token` file.
+
+* `redir add tcp:50051:50051`
+
+* Exit the telnet session using 'ctrl-C'
+
+  Make the target device writable:
+
+  Under android root:
+
+  `source build/envsetup.sh`
+
+  `lunch sdk_car_x86_64-userdebug`
+
+  `adb root`
+
+  `adb remount` (remount might take a while)
+
+  `adb reboot`
+
+  `adb root`
+
+  `adb remount`
+
+* `make -j TestWakeupClientServer`
+
+* `adb push $ANDROID_PRODUCT_OUT/vendor/bin/TestWakeupClientServer /vendor/bin`
+
+* `adb shell`
+
+* `emulator_car_x86_64:/ # su`
+
+* `emulator_car_x86_64:/ # /vendor/bin/TestWakeupClientServer`
+
+* Start a new shell under android root, start another car emulator as the Application Processor:
+
+  `source build/envsetup.sh`
+
+  `lunch sdk_car_x86_64-userdebug`
+
+  `emulator -writable-system -read-only`
+
+* Open a new shell under android root:
+
+  `source build/envsetup.sh`
+
+  `lunch sdk_car_x86_64-userdebug`
+
+* Connect to adb shell for the application processor:
+
+  `adb -s emulator-5556 shell`
+
+  `emulator_car_x86_64:/ # su`
+
+* Follow the test instructions for one car emulator using the 'dumpsys'
+  commands.
+
+* After the test, you can use `ctrl D` to exit the adb shell.
diff --git a/automotive/remoteaccess/test_grpc_server/impl/Android.bp b/automotive/remoteaccess/test_grpc_server/impl/Android.bp
new file mode 100644
index 0000000..152b528
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/impl/Android.bp
@@ -0,0 +1,43 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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_binary {
+    name: "TestWakeupClientServer",
+    vendor: true,
+    srcs: ["src/*.cpp"],
+    local_include_dirs: ["include"],
+    shared_libs: [
+        "libbase",
+        "libutils",
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+        "//hardware/interfaces/automotive/remoteaccess/test_grpc_server/lib:ApPowerControlLib",
+    ],
+    whole_static_libs: [
+        "wakeup_client_protos",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+        "-DGRPC_SERVICE_ADDRESS=\"localhost:50051\"",
+    ],
+}
diff --git a/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h b/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
new file mode 100644
index 0000000..6b86b35
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/thread_annotations.h>
+#include <utils/Looper.h>
+#include <wakeup_client.grpc.pb.h>
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+#include <string>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace remoteaccess {
+
+// A class to generate fake task for testing. Not required for real implementation. In real
+// implementation, the task should come from remote task server. This class is thread-safe.
+class FakeTaskGenerator final {
+  public:
+    GetRemoteTasksResponse generateTask();
+
+  private:
+    // Simulates the client ID for each task.
+    std::atomic<int> mCurrentClientId = 0;
+    constexpr static uint8_t DATA[] = {0xde, 0xad, 0xbe, 0xef};
+};
+
+struct TaskInfo {
+    // This is unique per-task. Note that a task might be popped and put back into the task queue,
+    // it will have a new task ID but the same clientId in the task data.
+    int taskId;
+    int64_t timestampInMs;
+    GetRemoteTasksResponse taskData;
+};
+
+struct TaskInfoComparator {
+    // We want the smallest timestamp and smallest task ID on top.
+    bool operator()(const TaskInfo& l, const TaskInfo& r) {
+        return l.timestampInMs > r.timestampInMs ||
+               (l.timestampInMs == r.timestampInMs && l.taskId > r.taskId);
+    }
+};
+
+// forward-declaration.
+class TaskQueue;
+
+class TaskTimeoutMessageHandler final : public android::MessageHandler {
+  public:
+    TaskTimeoutMessageHandler(TaskQueue* taskQueue);
+    void handleMessage(const android::Message& message) override;
+
+  private:
+    TaskQueue* mTaskQueue;
+};
+
+// TaskQueue is thread-safe.
+class TaskQueue final {
+  public:
+    TaskQueue();
+    ~TaskQueue();
+
+    void add(const GetRemoteTasksResponse& response);
+    std::optional<GetRemoteTasksResponse> maybePopOne();
+    void waitForTask();
+    void stopWait();
+    void handleTaskTimeout();
+    bool isEmpty();
+
+  private:
+    std::thread mCheckTaskTimeoutThread;
+    std::mutex mLock;
+    std::priority_queue<TaskInfo, std::vector<TaskInfo>, TaskInfoComparator> mTasks
+            GUARDED_BY(mLock);
+    // A variable to notify mTasks is not empty.
+    std::condition_variable mTasksNotEmptyCv;
+    bool mStopped GUARDED_BY(mLock);
+    android::sp<Looper> mLooper;
+    android::sp<TaskTimeoutMessageHandler> mTaskTimeoutMessageHandler;
+    std::atomic<int> mTaskIdCounter = 0;
+
+    void checkForTestTimeoutLoop();
+    void waitForTaskWithLock(std::unique_lock<std::mutex>& lock);
+};
+
+class TestWakeupClientServiceImpl final : public WakeupClient::Service {
+  public:
+    TestWakeupClientServiceImpl();
+
+    ~TestWakeupClientServiceImpl();
+
+    grpc::Status GetRemoteTasks(grpc::ServerContext* context, const GetRemoteTasksRequest* request,
+                                grpc::ServerWriter<GetRemoteTasksResponse>* writer) override;
+
+    grpc::Status NotifyWakeupRequired(grpc::ServerContext* context,
+                                      const NotifyWakeupRequiredRequest* request,
+                                      NotifyWakeupRequiredResponse* response) override;
+
+  private:
+    // This is a thread for communicating with remote wakeup server (via network) and receive tasks
+    // from it.
+    std::thread mThread;
+    // A variable to notify server is stopping.
+    std::condition_variable mServerStoppedCv;
+    // Whether wakeup AP is required for executing tasks.
+    std::atomic<bool> mWakeupRequired = true;
+    std::mutex mLock;
+    bool mServerStopped GUARDED_BY(mLock);
+
+    // Thread-safe. For test impl only.
+    FakeTaskGenerator mFakeTaskGenerator;
+    // Thread-sfae.
+    TaskQueue mTaskQueue;
+
+    void fakeTaskGenerateLoop();
+
+    void wakeupApplicationProcessor();
+};
+
+}  // namespace remoteaccess
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
new file mode 100644
index 0000000..7dcd31e
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TestWakeupClientServiceImpl.h"
+
+#include "ApPowerControl.h"
+
+#include <android-base/stringprintf.h>
+#include <inttypes.h>
+#include <utils/Looper.h>
+#include <utils/SystemClock.h>
+#include <chrono>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace remoteaccess {
+
+namespace {
+
+using ::android::uptimeMillis;
+using ::android::base::ScopedLockAssertion;
+using ::android::base::StringPrintf;
+using ::grpc::ServerContext;
+using ::grpc::ServerWriter;
+using ::grpc::Status;
+
+constexpr int kTaskIntervalInMs = 5'000;
+constexpr int64_t KTaskTimeoutInMs = 20'000;
+
+}  // namespace
+
+GetRemoteTasksResponse FakeTaskGenerator::generateTask() {
+    int clientId = mCurrentClientId++;
+    GetRemoteTasksResponse response;
+    response.set_data(std::string(reinterpret_cast<const char*>(DATA), sizeof(DATA)));
+    std::string clientIdStr = StringPrintf("%d", clientId);
+    response.set_clientid(clientIdStr);
+    return response;
+}
+
+TaskTimeoutMessageHandler::TaskTimeoutMessageHandler(TaskQueue* taskQueue)
+    : mTaskQueue(taskQueue) {}
+
+void TaskTimeoutMessageHandler::handleMessage(const android::Message& message) {
+    mTaskQueue->handleTaskTimeout();
+}
+
+TaskQueue::TaskQueue() {
+    mTaskTimeoutMessageHandler = android::sp<TaskTimeoutMessageHandler>::make(this);
+    mLooper = Looper::prepare(/*opts=*/0);
+    mCheckTaskTimeoutThread = std::thread([this] { checkForTestTimeoutLoop(); });
+}
+
+TaskQueue::~TaskQueue() {
+    {
+        std::lock_guard<std::mutex> lockGuard(mLock);
+        mStopped = true;
+    }
+    while (true) {
+        // Remove all pending timeout handlers from queue.
+        if (!maybePopOne().has_value()) {
+            break;
+        }
+    }
+    if (mCheckTaskTimeoutThread.joinable()) {
+        mCheckTaskTimeoutThread.join();
+    }
+}
+
+std::optional<GetRemoteTasksResponse> TaskQueue::maybePopOne() {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    if (mTasks.size() == 0) {
+        return std::nullopt;
+    }
+    TaskInfo response = std::move(mTasks.top());
+    mTasks.pop();
+    mLooper->removeMessages(mTaskTimeoutMessageHandler, response.taskId);
+    return std::move(response.taskData);
+}
+
+void TaskQueue::add(const GetRemoteTasksResponse& task) {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    if (mStopped) {
+        return;
+    }
+    int taskId = mTaskIdCounter++;
+    mTasks.push(TaskInfo{
+            .taskId = taskId,
+            .timestampInMs = uptimeMillis(),
+            .taskData = task,
+    });
+    android::Message message(taskId);
+    mLooper->sendMessageDelayed(KTaskTimeoutInMs * 1000, mTaskTimeoutMessageHandler, message);
+    mTasksNotEmptyCv.notify_all();
+}
+
+void TaskQueue::waitForTask() {
+    std::unique_lock<std::mutex> lock(mLock);
+    waitForTaskWithLock(lock);
+}
+
+void TaskQueue::waitForTaskWithLock(std::unique_lock<std::mutex>& lock) {
+    mTasksNotEmptyCv.wait(lock, [this] {
+        ScopedLockAssertion lockAssertion(mLock);
+        return mTasks.size() > 0 || mStopped;
+    });
+}
+
+void TaskQueue::stopWait() {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    mStopped = true;
+    mTasksNotEmptyCv.notify_all();
+}
+
+bool TaskQueue::isEmpty() {
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    return mTasks.size() == 0 || mStopped;
+}
+
+void TaskQueue::checkForTestTimeoutLoop() {
+    Looper::setForThread(mLooper);
+
+    while (true) {
+        {
+            std::unique_lock<std::mutex> lock(mLock);
+            if (mStopped) {
+                return;
+            }
+        }
+
+        mLooper->pollAll(/*timeoutMillis=*/-1);
+    }
+}
+
+void TaskQueue::handleTaskTimeout() {
+    // We know which task timed-out from the taskId in the message. However, there is no easy way
+    // to remove a specific task with the task ID from the priority_queue, so we just check from
+    // the top of the queue (which have the oldest tasks).
+    std::lock_guard<std::mutex> lockGuard(mLock);
+    int64_t now = uptimeMillis();
+    while (mTasks.size() > 0) {
+        const TaskInfo& taskInfo = mTasks.top();
+        if (taskInfo.timestampInMs + KTaskTimeoutInMs > now) {
+            break;
+        }
+        // In real implementation, this should report task failure to remote wakeup server.
+        printf("Task for client ID: %s timed-out, added at %" PRId64 " ms, now %" PRId64 " ms",
+               taskInfo.taskData.clientid().c_str(), taskInfo.timestampInMs, now);
+        mTasks.pop();
+    }
+}
+
+TestWakeupClientServiceImpl::TestWakeupClientServiceImpl() {
+    mThread = std::thread([this] { fakeTaskGenerateLoop(); });
+}
+
+TestWakeupClientServiceImpl::~TestWakeupClientServiceImpl() {
+    {
+        std::lock_guard<std::mutex> lockGuard(mLock);
+        mServerStopped = true;
+        mServerStoppedCv.notify_all();
+    }
+    mTaskQueue.stopWait();
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+}
+
+void TestWakeupClientServiceImpl::fakeTaskGenerateLoop() {
+    // In actual implementation, this should communicate with the remote server and receives tasks
+    // from it. Here we simulate receiving one remote task every {kTaskIntervalInMs}ms.
+    while (true) {
+        mTaskQueue.add(mFakeTaskGenerator.generateTask());
+        printf("Received a new task\n");
+        if (mWakeupRequired) {
+            wakeupApplicationProcessor();
+        }
+
+        printf("Sleeping for %d seconds until next task\n", kTaskIntervalInMs);
+
+        std::unique_lock lk(mLock);
+        if (mServerStoppedCv.wait_for(lk, std::chrono::milliseconds(kTaskIntervalInMs), [this] {
+                ScopedLockAssertion lockAssertion(mLock);
+                return mServerStopped;
+            })) {
+            // If the stopped flag is set, we are quitting, exit the loop.
+            return;
+        }
+    }
+}
+
+Status TestWakeupClientServiceImpl::GetRemoteTasks(ServerContext* context,
+                                                   const GetRemoteTasksRequest* request,
+                                                   ServerWriter<GetRemoteTasksResponse>* writer) {
+    printf("GetRemoteTasks called\n");
+    while (true) {
+        mTaskQueue.waitForTask();
+
+        while (true) {
+            auto maybeTask = mTaskQueue.maybePopOne();
+            if (!maybeTask.has_value()) {
+                // No task left, loop again and wait for another task(s).
+                break;
+            }
+            // Loop through all the task in the queue but obtain lock for each element so we don't
+            // hold lock while writing the response.
+            const GetRemoteTasksResponse& response = maybeTask.value();
+            if (!writer->Write(response)) {
+                // Broken stream, maybe the client is shutting down.
+                printf("Failed to deliver remote task to remote access HAL\n");
+                // The task failed to be sent, add it back to the queue. The order might change, but
+                // it is okay.
+                mTaskQueue.add(response);
+                return Status::CANCELLED;
+            }
+        }
+    }
+    return Status::OK;
+}
+
+Status TestWakeupClientServiceImpl::NotifyWakeupRequired(ServerContext* context,
+                                                         const NotifyWakeupRequiredRequest* request,
+                                                         NotifyWakeupRequiredResponse* response) {
+    if (request->iswakeuprequired() && !mWakeupRequired && !mTaskQueue.isEmpty()) {
+        // If wakeup is now required and previously not required, this means we have finished
+        // shutting down the device. If there are still pending tasks, try waking up AP again
+        // to finish executing those tasks.
+        wakeupApplicationProcessor();
+    }
+    mWakeupRequired = request->iswakeuprequired();
+    return Status::OK;
+}
+
+void TestWakeupClientServiceImpl::wakeupApplicationProcessor() {
+    wakeupAp();
+}
+
+}  // namespace remoteaccess
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp
new file mode 100644
index 0000000..d3f519c
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include "TestWakeupClientServiceImpl.h"
+
+#include <grpc/grpc.h>
+#include <grpcpp/security/server_credentials.h>
+#include <grpcpp/server.h>
+#include <grpcpp/server_builder.h>
+
+using ::android::hardware::automotive::remoteaccess::TestWakeupClientServiceImpl;
+using ::grpc::Server;
+using ::grpc::ServerBuilder;
+using ::grpc::ServerWriter;
+
+void RunServer(const std::string& serviceAddr) {
+    std::shared_ptr<TestWakeupClientServiceImpl> service =
+            std::make_unique<TestWakeupClientServiceImpl>();
+
+    ServerBuilder builder;
+    builder.AddListeningPort(serviceAddr, grpc::InsecureServerCredentials());
+    builder.RegisterService(service.get());
+    std::unique_ptr<Server> server(builder.BuildAndStart());
+    printf("Test Remote Access GRPC Server listening on %s\n", serviceAddr.c_str());
+    server->Wait();
+}
+
+int main(int argc, char** argv) {
+    std::string serviceAddr = GRPC_SERVICE_ADDRESS;
+    if (argc > 1) {
+        serviceAddr = argv[1];
+    }
+    RunServer(serviceAddr);
+    return 0;
+}
diff --git a/automotive/remoteaccess/test_grpc_server/lib/Android.bp b/automotive/remoteaccess/test_grpc_server/lib/Android.bp
new file mode 100644
index 0000000..7e95f53
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/lib/Android.bp
@@ -0,0 +1,32 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+soong_namespace {}
+
+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_shared {
+    name: "ApPowerControlLib",
+    vendor: true,
+    srcs: ["*.cpp"],
+    local_include_dirs: ["."],
+    export_include_dirs: ["."],
+}
diff --git a/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.cpp b/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.cpp
new file mode 100644
index 0000000..862fed1
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ApPowerControl.h"
+
+#include <cstdio>
+
+void wakeupAp() {
+    printf("Waking up application processor...\n");
+}
diff --git a/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.h b/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.h
new file mode 100644
index 0000000..9560576
--- /dev/null
+++ b/automotive/remoteaccess/test_grpc_server/lib/ApPowerControl.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Wakeup application processor if not already waken up.
+void wakeupAp();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/automotive/sv/1.0/default/tests/fuzzer/Android.bp b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
index 394c532..696bfad 100644
--- a/automotive/sv/1.0/default/tests/fuzzer/Android.bp
+++ b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
@@ -47,5 +47,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.automotive.sv@1.0-service",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/automotive/sv/OWNERS b/automotive/sv/OWNERS
new file mode 100644
index 0000000..af6788b
--- /dev/null
+++ b/automotive/sv/OWNERS
@@ -0,0 +1 @@
+tanmayp@google.com
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 0d3253b..586a98e 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -84,7 +84,10 @@
     name: "android.hardware.automotive.vehicle@2.0-default-impl-lib",
     vendor: true,
     defaults: ["vhal_v2_0_target_defaults"],
-    cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
+    cflags: [
+        "-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING",
+        "-DENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS",
+    ],
     srcs: [
         "impl/vhal_v2_0/DefaultVehicleHal.cpp",
         "impl/vhal_v2_0/VehicleHalClient.cpp",
@@ -225,6 +228,25 @@
     test_suites: ["general-tests"],
 }
 
+cc_test {
+    name: "android.hardware.automotive.vehicle@2.0-default-config-test",
+    vendor: true,
+    defaults: ["vhal_v2_0_target_defaults"],
+    srcs: [
+        "impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp",
+    ],
+    cflags: [
+        "-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING",
+        "-DENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS",
+    ],
+    static_libs: [
+        "android.hardware.automotive.vehicle@2.0-default-impl-lib",
+        "libgtest",
+        "libgmock",
+    ],
+    test_suites: ["general-tests"],
+}
+
 cc_binary {
     name: "android.hardware.automotive.vehicle@2.0-default-service",
     defaults: ["vhal_v2_0_target_defaults"],
@@ -270,5 +292,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.automotive.vehicle@2.0-manager-lib",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp
index 12e15f9..2968232 100644
--- a/automotive/vehicle/2.0/default/VehicleService.cpp
+++ b/automotive/vehicle/2.0/default/VehicleService.cpp
@@ -33,7 +33,7 @@
     auto store = std::make_unique<VehiclePropertyStore>();
     auto connector = std::make_unique<DefaultVehicleConnector>();
     auto hal = std::make_unique<DefaultVehicleHal>(store.get(), connector.get());
-    auto service = std::make_unique<VehicleHalManager>(hal.get());
+    auto service = android::sp<VehicleHalManager>::make(hal.get());
     connector->setValuePool(hal->getValuePool());
 
     android::hardware::configureRpcThreadpool(4, true /* callerWillJoin */);
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index cfbbbd3..cfa3b0c 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -144,7 +144,7 @@
                                          (int)VehicleUnit::MILES_PER_HOUR,
                                          (int)VehicleUnit::KILOMETERS_PER_HOUR},
                  },
-         .initialValue = {.int32Values = {(int)VehicleUnit::KILOMETERS_PER_HOUR}}},
+         .initialValue = {.int32Values = {(int)VehicleUnit::MILES_PER_HOUR}}},
 
         {.config =
                  {
@@ -374,6 +374,15 @@
 
         {.config =
                  {
+                         .prop = toInt(VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS),
+                         .access = VehiclePropertyAccess::READ_WRITE,
+                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                         .configArray = {(int)VehicleUnit::LITER, (int)VehicleUnit::US_GALLON},
+                 },
+         .initialValue = {.int32Values = {(int)VehicleUnit::US_GALLON}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::HW_KEY_INPUT),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -1109,6 +1118,19 @@
                         },
                 .initialValue = {.stringValue = {"Test"}},
         },
+        // This property is later defined in the AIDL VHAL interface. However, HIDL VHAL might
+        // require support for this property to meet EU regulation.
+        {
+                .config =
+                        {
+                                // GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT
+                                .prop = 0x11400F47,
+                                .access = VehiclePropertyAccess::READ,
+                                .changeMode = VehiclePropertyChangeMode::STATIC,
+                        },
+                // GsrComplianceRequirementType::GSR_COMPLIANCE_REQUIRED_V1
+                .initialValue = {.int32Values = {1}},
+        },
 #ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
         // Vendor propetry for E2E ClusterHomeService testing.
         {
@@ -1157,6 +1179,47 @@
                         },
         },
 #endif  // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+#ifdef ENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS
+        {
+                .config =
+                        {
+                                // SUPPORTED_PROPERTY_IDS
+                                .prop = 289476424,
+                                .access = VehiclePropertyAccess::READ,
+                                .changeMode = VehiclePropertyChangeMode::STATIC,
+                                // Fetch 100 configs in one request. This number is just arbitrarily
+                                // chosen here. But some HAL impl with bigger config data may need a
+                                // smaller number to make sure the configs returned in one request
+                                // fits the binder data size limitation.
+                                .configArray = {100},
+                        },
+                // All supported property IDs. This list is checked by
+                // DefaultConfigSupportedPropertyIds_test.
+                .initialValue =
+                        {.int32Values =
+                                 {291504388, 289472773, 291504390, 289472775, 289407240, 289407241,
+                                  289472780, 286261505, 286261506, 289407235, 289472779, 291504647,
+                                  289408517, 356518832, 356516106, 291504644, 291504649, 291504656,
+                                  291504901, 291504903, 287310600, 291504905, 287310602, 287310603,
+                                  291504908, 291504904, 392168201, 392168202, 289408514, 289408001,
+                                  287310850, 287310851, 287310853, 289408513, 289475088, 289475104,
+                                  289475120, 354419984, 320865540, 320865556, 354419975, 354419976,
+                                  354419986, 354419973, 354419974, 354419978, 354419977, 356517120,
+                                  356517121, 356582673, 356517139, 289408269, 356517131, 358614275,
+                                  291570965, 291505923, 289408270, 289408512, 287310855, 289408000,
+                                  289408008, 289408009, 289407747, 291504900, 568332561, 371198722,
+                                  373295872, 320867268, 322964416, 290521862, 287310858, 287310859,
+                                  289475072, 289475073, 289409539, 299896064, 299896065, 299896066,
+                                  299896067, 289410560, 289410561, 289410562, 289410563, 289410576,
+                                  289410577, 289410578, 289410579, 289476368, 299895808, 639631617,
+                                  627048706, 591397123, 554696964, 289410873, 289410874, 287313669,
+                                  299896583, 299896584, 299896585, 299896586, 299896587, 286265121,
+                                  286265122, 286265123, 290457094, 290459441, 299896626, 290459443,
+                                  289410868, 289476405, 299896630, 289410871, 292556600, 557853201,
+                                  559950353, 555756049, 554707473, 289410887, 557846324, 557911861,
+                                  568332086, 557846327, 560992056, 289476424}},
+        },
+#endif  // ENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS
 };
 
 }  // impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
index 9be9ea7..503afd2 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
@@ -28,11 +28,18 @@
 
 namespace impl {
 
-GeneratorHub::GeneratorHub(const OnHalEvent& onHalEvent)
-    : mOnHalEvent(onHalEvent), mThread(&GeneratorHub::run, this) {}
+GeneratorHub::GeneratorHub(const OnHalEvent& onHalEvent) : mOnHalEvent(onHalEvent) {
+    mThread = std::thread(&GeneratorHub::run, this);
+}
 
 GeneratorHub::~GeneratorHub() {
-    mShuttingDownFlag.store(true);
+    {
+        // Even if the shared variable is atomic, it must be modified under the
+        // mutex in order to correctly publish the modification to the waiting
+        // thread.
+        std::unique_lock<std::mutex> g(mLock);
+        mShuttingDownFlag.store(true);
+    }
     mCond.notify_all();
     if (mThread.joinable()) {
         mThread.join();
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp
new file mode 100644
index 0000000..aa05daa
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <vector>
+
+#include "vhal_v2_0/DefaultConfig.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+namespace impl {
+
+using ::testing::ElementsAreArray;
+
+// Test that VHAL_SUPPORTED_PROPERTY_IDS contains all supported property IDs.
+TEST(DefaultConfigSupportedPropertyIdsTest, testIncludeAllSupportedIds) {
+    const int32_t vhalSupportedPropertyIdsPropId = 289476424;
+
+    std::vector<int32_t> allSupportedIds;
+    std::vector<int32_t> configuredSupportedIds;
+
+    for (const auto& property : impl::kVehicleProperties) {
+        int propId = property.config.prop;
+        allSupportedIds.push_back(propId);
+
+        if (propId == vhalSupportedPropertyIdsPropId) {
+            configuredSupportedIds = property.initialValue.int32Values;
+        }
+    }
+
+    ASSERT_THAT(allSupportedIds, ElementsAreArray(configuredSupportedIds));
+}
+
+}  // namespace impl
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
index e3c8dd6..edd4484 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
@@ -124,6 +124,17 @@
     android::ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
     android::ConcurrentQueue<VehiclePropValuePtr> mHeartBeatQueue;
 
+    // Wait until receive enough events in receivedEvents.
+    void waitForEvents(std::vector<VehiclePropValuePtr>* receivedEvents, size_t count) {
+        while (receivedEvents->size() < count) {
+            mEventQueue.waitForItems();
+            auto newEvents = mEventQueue.flush();
+            for (size_t i = 0; i < newEvents.size(); i++) {
+                receivedEvents->push_back(std::move(newEvents[i]));
+            }
+        }
+    }
+
   private:
     void onHalEvent(VehiclePropValuePtr v) {
         if (v->prop != toInt(VehicleProperty::VHAL_HEARTBEAT)) {
@@ -141,7 +152,7 @@
 TEST_F(DefaultVhalImplTest, testListProperties) {
     std::vector<VehiclePropConfig> configs = mHal->listProperties();
 
-    EXPECT_EQ((size_t)121, configs.size());
+    EXPECT_EQ((size_t)124, configs.size());
 }
 
 TEST_F(DefaultVhalImplTest, testGetDefaultPropertyFloat) {
@@ -314,26 +325,25 @@
 
     ASSERT_EQ(StatusCode::OK, status);
 
-    std::this_thread::sleep_for(std::chrono::milliseconds(500));
+    std::vector<VehiclePropValuePtr> receivedEvents;
+    waitForEvents(&receivedEvents, 5);
 
-    // Modify the speed after 0.5 seconds.
+    // Modify the speed after 5 events arrive.
     VehiclePropValue value;
     value.prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
     value.value.floatValues.resize(1);
     value.value.floatValues[0] = 1.0f;
     ASSERT_EQ(StatusCode::OK, mHal->set(value));
 
-    std::this_thread::sleep_for(std::chrono::milliseconds(500));
-
-    auto events = mEventQueue.flush();
-    ASSERT_LE((size_t)10, events.size());
+    waitForEvents(&receivedEvents, 10);
 
     // The first event should be the default value.
-    ASSERT_EQ((size_t)1, events[0]->value.floatValues.size());
-    EXPECT_EQ(0.0f, events[0]->value.floatValues[0]);
+    ASSERT_EQ((size_t)1, receivedEvents[0]->value.floatValues.size());
+    EXPECT_EQ(0.0f, receivedEvents[0]->value.floatValues[0]);
     // The last event should be the value after update.
-    ASSERT_EQ((size_t)1, events[events.size() - 1]->value.floatValues.size());
-    EXPECT_EQ(1.0f, events[events.size() - 1]->value.floatValues[0]);
+    const auto& lastEvent = receivedEvents[receivedEvents.size() - 1];
+    ASSERT_EQ((size_t)1, lastEvent->value.floatValues.size());
+    EXPECT_EQ(1.0f, lastEvent->value.floatValues[0]);
 }
 
 TEST_F(DefaultVhalImplTest, testSubscribeInvalidProp) {
@@ -402,7 +412,7 @@
     gotValue->timestamp = 0;
 
     std::string infoMake = toString(*gotValue);
-    EXPECT_THAT(std::string(buf), HasSubstr(infoMake));
+    EXPECT_THAT(std::string(buf, sizeof(buf)), HasSubstr(infoMake));
 }
 
 TEST_F(DefaultVhalImplTest, testSetPropInvalidAreaId) {
@@ -746,8 +756,9 @@
     // Clear existing events.
     mEventQueue.flush();
     std::this_thread::sleep_for(std::chrono::milliseconds(500));
-    // There should be no new events generated.
-    EXPECT_EQ((size_t)0, mEventQueue.flush().size());
+    // Technically there should be no new events generated, however, there might still be one event
+    // in the queue while we are stopping the generator.
+    EXPECT_LE(mEventQueue.flush().size(), 1u);
 }
 
 std::string getTestFilePath(const char* filename) {
diff --git a/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp b/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp
index d7547f6..2e59dbf 100644
--- a/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp
@@ -69,7 +69,7 @@
     std::this_thread::sleep_for(milliseconds(100));
     // This test is unstable, so set the tolerance to 50.
     ASSERT_EQ_WITH_TOLERANCE(100, counter1ms.load(), 50);
-    ASSERT_EQ_WITH_TOLERANCE(20, counter5ms.load(), 5);
+    ASSERT_EQ_WITH_TOLERANCE(20, counter5ms.load(), 10);
 }
 
 }  // anonymous namespace
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 7c8e1f5..5b0a505 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -57,46 +57,25 @@
 };
 
 /**
- * Vehicle Areas
+ * List of different supported area types for vehicle properties.
  * Used to construct property IDs in the VehicleProperty enum.
  *
- * Some properties may be associated with particular vehicle areas. For
- * example, VehicleProperty:DOOR_LOCK property must be associated with
- * particular door, thus this property must be marked with
- * VehicleArea:DOOR flag.
+ * Some properties may be associated with particular areas in the vehicle. For example,
+ * VehicleProperty#DOOR_LOCK property must be associated with a particular door, thus this property
+ * must be of the VehicleArea#DOOR area type.
  *
- * Other properties may not be associated with particular vehicle area.
- * These kinds of properties must have VehicleArea:GLOBAL flag.
+ * Other properties may not be associated with a particular area in the vehicle. These kinds of
+ * properties must be of the VehicleArea#GLOBAL area type.
  *
- * [Definition] Area: An area represents a unique element of an AreaType.
- *   For instance, if AreaType is WINDOW, then an area may be FRONT_WINDSHIELD.
- *
- * [Definition] AreaID: An AreaID is a combination of one or more areas,
- *   and is represented using a bitmask of Area enums. Different AreaTypes may
- *   not be mixed in a single AreaID. For instance, a window area cannot be
- *   combined with a seat area in an AreaID.
- *
- * Rules for mapping a zoned property to AreaIDs:
- *  - A property must be mapped to an array of AreaIDs that are impacted when
- *    the property value changes.
- *  - Each element in the array must represent an AreaID, in which the
- *    property value can only be changed together in all the areas within
- *    the AreaID and never independently. That is, when the property value
- *    changes in one of the areas in an AreaID in the array, then it must
- *    automatically change in all other areas in the AreaID.
- *  - The property value must be independently controllable in any two
- *    different AreaIDs in the array.
- *  - An area must only appear once in the array of AreaIDs. That is, an
- *    area must only be part of a single AreaID in the array.
- *
- * [Definition] Global Property: A property that applies to the entire car
- *   and is not associated with a specific area. For example, FUEL_LEVEL,
- *   HVAC_STEERING_WHEEL_HEAT.
- *
- * Rules for mapping a global property to AreaIDs:
- *  - A global property must not be mapped to AreaIDs.
-*/
+ * Note: This is not the same as areaId used in VehicleAreaConfig. E.g. for a global property, the
+ * property ID is of the VehicleArea#GLOBAL area type, however, the area ID must be 0.
+ */
+// A better name would be VehicleAreaType
 enum VehicleArea : int32_t {
+    /**
+     * A global property is a property that applies to the entire vehicle and is not associated with
+     * a specific area. For example, FUEL_LEVEL, HVAC_STEERING_WHEEL_HEAT are global properties.
+     */
     GLOBAL      = 0x01000000,
     /** WINDOW maps to enum VehicleAreaWindow */
     WINDOW      = 0x03000000,
@@ -829,10 +808,10 @@
     /*
      * HVAC Properties
      *
-     * Additional rules for mapping a zoned HVAC property (except
-     * HVAC_MAX_DEFROST_ON) to AreaIDs:
-     *  - Every seat in VehicleAreaSeat that is available in the car, must be
-     *    part of an AreaID in the AreaID array.
+     * Additional rules for mapping non-GLOBAL VehicleArea type HVAC properties
+     * to AreaIDs:
+     *  - Every “area” for a specific VehicleArea type that is affected by the
+     *    property, must be included in an area ID for that property.
      *
      * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
      *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
@@ -860,6 +839,16 @@
      *     - ROW_1_LEFT
      *     - ROW_1_RIGHT
      *     - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
+     *
+     * Example 3: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). Suppose the car
+     *  supports HVAC_AUTO_ON for just the two front seats.
+     *   - A valid mapping set of AreaIDs for HVAC_AUTO_ON would be:
+     *      - ROW_1_LEFT | ROW_1_RIGHT
+     *   - If HVAC_AUTO_ON had two separate control units for the driver side
+     *     and passenger side, an alternative mapping would be:
+     *      - ROW_1_LEFT
+     *      - ROW_1_RIGHT
      */
 
     /**
@@ -1632,10 +1621,8 @@
      *
      * The Android properties are:
      *
-     * int32Values[0] : Input code identifying the function representing this event. Valid event
-     *                  types are defined by CustomInputType.CUSTOM_EVENT_F1 up to
-     *                  CustomInputType.CUSTOM_EVENT_F10. They represent the custom event to be
-     *                  defined by OEM partners.
+     * int32Values[0] : Input code identifying the function representing this event. OEMs are free
+     *                  to use any signed 32 bits number to represent the input code value.
      * int32Values[1] : target display type defined in VehicleDisplay. Events not tied to specific
      *                  display must be sent to VehicleDisplay#MAIN.
      * int32Values[2] : repeat counter, if 0 then event is not repeated. Values 1 or above means
@@ -1802,11 +1789,11 @@
      *
      * This parameter selects the memory preset to use to select the seat
      * position. The minValue is always 0, and the maxValue determines the
-     * number of seat positions available.
+     * number of seat positions available (i.e. numSeatPositions - 1).
      *
      * For instance, if the driver's seat has 3 memory presets, the maxValue
-     * will be 3. When the user wants to select a preset, the desired preset
-     * number (1, 2, or 3) is set.
+     * will be 2. When the user wants to select a preset, the desired preset
+     * number (0, 1, or 2) is set.
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:WRITE
@@ -2119,6 +2106,12 @@
         | VehicleArea:SEAT),
 
     /**
+     * DO NOT USE
+     *
+     * This property is defined as type VehicleArea:GLOBAL, which means all seats use the same
+     * value. Use SEAT_HEADREST_HEIGHT_POS_V2 instead which fixes this issue by being defined as
+     * type VehicleArea:SEAT.
+     *
      * Headrest height position
      *
      * Sets the headrest height.
@@ -5326,10 +5319,11 @@
  */
 enum CustomInputType : int32_t {
     /**
-     * Ten functions representing the custom input code to be defined and implemented by OEM
-     * partners.
+     * Ten optional function codes to be used in case OEM don't need more than 10 input code values.
      *
-     * OEMs need to formally contact Android team if more than 10 functions are required.
+     * OEMs are free to use any signed 32 bits number to represent the input code value.
+     * The following function keys are only for convenience and any other integer values are
+     * also allowed.
      */
     CUSTOM_EVENT_F1 = 1001,
     CUSTOM_EVENT_F2 = 1002,
diff --git a/automotive/vehicle/Android.bp b/automotive/vehicle/Android.bp
new file mode 100644
index 0000000..c0d71d7
--- /dev/null
+++ b/automotive/vehicle/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+    name: "VehicleHalInterfaceDefaults",
+    static_libs: [
+        "android.hardware.automotive.vehicle-V2-ndk",
+        "android.hardware.automotive.vehicle.property-V2-ndk",
+    ],
+}
diff --git a/automotive/vehicle/README.md b/automotive/vehicle/README.md
new file mode 100644
index 0000000..e0f03e2
--- /dev/null
+++ b/automotive/vehicle/README.md
@@ -0,0 +1,26 @@
+# Vehicle Hardware Abstraction Layer (VHAL)
+---
+
+This directory stores the VHAL interface definition and VHAL reference
+implementation.
+
+## 2.0 (deprecated)
+
+HIDL based VHAL interface and reference implementation. 
+
+## aidl
+
+AIDL based VHAL interfadce and reference implementation.
+
+## proto
+
+Protobuf used to pass message between emulator VHAL and emulator.
+
+## tools
+
+Dev tools related to VHAL.
+
+## vts
+
+VTS test for VHAL. The VTS test works for both AIDL and HIDL VHAL
+implementation. Vendor implementation of VHAL must passes VTS.
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index 7e42554..da8416c 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -7,9 +7,24 @@
       "name": "VehicleHalDefaultConfigTest"
     },
     {
+      "name": "VehicleHalDefaultConfigTestEnableTestProperties"
+    },
+    {
+      "name": "JsonConfigLoaderUnitTest"
+    },
+    {
+      "name": "JsonConfigLoaderUnitTestEnableTestProperties"
+    },
+    {
       "name": "VehicleHalVehicleUtilsTest"
     },
     {
+      "name": "VehiclePropertyAnnotationCppTest"
+    },
+    {
+      "name": "VehiclePropertyAnnotationJavaTest"
+    },
+    {
       "name": "FakeVehicleHardwareTest"
     },
     {
diff --git a/automotive/vehicle/aidl/Android.bp b/automotive/vehicle/aidl/Android.bp
index 9aeb4d2..3b93bca 100644
--- a/automotive/vehicle/aidl/Android.bp
+++ b/automotive/vehicle/aidl/Android.bp
@@ -25,8 +25,9 @@
     name: "android.hardware.automotive.vehicle",
     vendor_available: true,
     srcs: [
-        "android/hardware/automotive/vehicle/**/*.aidl",
+        "android/hardware/automotive/vehicle/*.aidl",
     ],
+    frozen: true,
     stability: "vintf",
     backend: {
         cpp: {
@@ -46,6 +47,11 @@
             version: "1",
             imports: [],
         },
+        {
+            version: "2",
+            imports: [],
+        },
+
     ],
 
 }
diff --git a/automotive/vehicle/aidl/README.md b/automotive/vehicle/aidl/README.md
new file mode 100644
index 0000000..09f03b4
--- /dev/null
+++ b/automotive/vehicle/aidl/README.md
@@ -0,0 +1,23 @@
+# AIDL Vehicle Hardware Abstraction Layer (VHAL)
+---
+
+This directory stores the AIDL VHAL interface and reference implementation.
+
+## aidl_api
+
+Auto-generated current and previous versions of AIDL VHAL api.
+
+## aidl_test
+
+Contains a test to test that all HIDL VHAL properties are supported in
+AIDL VHAL.
+
+## android
+
+Contains AIDL VHAL interface definition. The main interface file is
+`android/hardware/automotive/vehicle/IVehicle.aidl`.
+
+## impl
+
+Reference implementation for AIDL VHAL and useful libraries for implementing
+vendor AIDL VHAL.
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/.hash b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/.hash
index f478504..d9fd5ad 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/.hash
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/.hash
@@ -1 +1,2 @@
 8610b651e162c614a97542d6f4ed039c969823e5
+0678e142246842695c1ba0524592fe2c3b789fc6
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/.hash b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/.hash
new file mode 100644
index 0000000..b04a6b5
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/.hash
@@ -0,0 +1 @@
+a741c2814ba6e9852e106bc26e820d741f66ebb8
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequest.aidl
new file mode 100644
index 0000000..d88cd8b
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable GetValueRequest {
+  long requestId;
+  android.hardware.automotive.vehicle.VehiclePropValue prop;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequests.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequests.aidl
new file mode 100644
index 0000000..a7df2ff
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueRequests.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable GetValueRequests {
+  android.hardware.automotive.vehicle.GetValueRequest[] payloads;
+  @nullable ParcelFileDescriptor sharedMemoryFd;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResult.aidl
new file mode 100644
index 0000000..25f3575
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable GetValueResult {
+  long requestId;
+  android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
+  @nullable android.hardware.automotive.vehicle.VehiclePropValue prop;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResults.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResults.aidl
new file mode 100644
index 0000000..4c365b1
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/GetValueResults.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable GetValueResults {
+  android.hardware.automotive.vehicle.GetValueResult[] payloads;
+  @nullable ParcelFileDescriptor sharedMemoryFd;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/IVehicle.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/IVehicle.aidl
new file mode 100644
index 0000000..b5f62aa
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/IVehicle.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.automotive.vehicle;
+@VintfStability
+interface IVehicle {
+  android.hardware.automotive.vehicle.VehiclePropConfigs getAllPropConfigs();
+  android.hardware.automotive.vehicle.VehiclePropConfigs getPropConfigs(in int[] props);
+  void getValues(android.hardware.automotive.vehicle.IVehicleCallback callback, in android.hardware.automotive.vehicle.GetValueRequests requests);
+  void setValues(android.hardware.automotive.vehicle.IVehicleCallback callback, in android.hardware.automotive.vehicle.SetValueRequests requests);
+  void subscribe(in android.hardware.automotive.vehicle.IVehicleCallback callback, in android.hardware.automotive.vehicle.SubscribeOptions[] options, int maxSharedMemoryFileCount);
+  void unsubscribe(in android.hardware.automotive.vehicle.IVehicleCallback callback, in int[] propIds);
+  void returnSharedMemory(in android.hardware.automotive.vehicle.IVehicleCallback callback, long sharedMemoryId);
+  const long INVALID_MEMORY_ID = 0;
+  const int MAX_SHARED_MEMORY_FILES_PER_CLIENT = 3;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/IVehicleCallback.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/IVehicleCallback.aidl
new file mode 100644
index 0000000..2c5a333
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/IVehicleCallback.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@VintfStability
+interface IVehicleCallback {
+  oneway void onGetValues(in android.hardware.automotive.vehicle.GetValueResults responses);
+  oneway void onSetValues(in android.hardware.automotive.vehicle.SetValueResults responses);
+  oneway void onPropertyEvent(in android.hardware.automotive.vehicle.VehiclePropValues propValues, int sharedMemoryFileCount);
+  oneway void onPropertySetError(in android.hardware.automotive.vehicle.VehiclePropErrors errors);
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/RawPropValues.aidl
new file mode 100644
index 0000000..e7b0a13
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable RawPropValues {
+  int[] int32Values = {};
+  float[] floatValues;
+  long[] int64Values;
+  byte[] byteValues;
+  @utf8InCpp String stringValue;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequest.aidl
new file mode 100644
index 0000000..6a65307
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SetValueRequest {
+  long requestId;
+  android.hardware.automotive.vehicle.VehiclePropValue value;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequests.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequests.aidl
new file mode 100644
index 0000000..15fd7ea
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueRequests.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SetValueRequests {
+  android.hardware.automotive.vehicle.SetValueRequest[] payloads;
+  @nullable ParcelFileDescriptor sharedMemoryFd;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResult.aidl
new file mode 100644
index 0000000..ec5fabb
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SetValueResult {
+  long requestId;
+  android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResults.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResults.aidl
new file mode 100644
index 0000000..47f1656
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SetValueResults.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SetValueResults {
+  android.hardware.automotive.vehicle.SetValueResult[] payloads;
+  @nullable ParcelFileDescriptor sharedMemoryFd;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/StatusCode.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/StatusCode.aidl
new file mode 100644
index 0000000..f7e8c5a
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/StatusCode.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum StatusCode {
+  OK = 0,
+  TRY_AGAIN = 1,
+  INVALID_ARG = 2,
+  NOT_AVAILABLE = 3,
+  ACCESS_DENIED = 4,
+  INTERNAL_ERROR = 5,
+  NOT_AVAILABLE_DISABLED = 6,
+  NOT_AVAILABLE_SPEED_LOW = 7,
+  NOT_AVAILABLE_SPEED_HIGH = 8,
+  NOT_AVAILABLE_POOR_VISIBILITY = 9,
+  NOT_AVAILABLE_SAFETY = 10,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SubscribeOptions.aidl
new file mode 100644
index 0000000..91e7c14
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SubscribeOptions {
+  int propId;
+  int[] areaIds;
+  float sampleRate;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
new file mode 100644
index 0000000..6960894
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VehicleAreaConfig {
+  int areaId;
+  int minInt32Value;
+  int maxInt32Value;
+  long minInt64Value;
+  long maxInt64Value;
+  float minFloatValue;
+  float maxFloatValue;
+  @nullable long[] supportedEnumValues;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
new file mode 100644
index 0000000..8602d2d
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VehiclePropConfig {
+  int prop;
+  android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
+  android.hardware.automotive.vehicle.VehiclePropertyChangeMode changeMode = android.hardware.automotive.vehicle.VehiclePropertyChangeMode.STATIC;
+  android.hardware.automotive.vehicle.VehicleAreaConfig[] areaConfigs;
+  int[] configArray;
+  @utf8InCpp String configString;
+  float minSampleRate;
+  float maxSampleRate;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
new file mode 100644
index 0000000..04c8006
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VehiclePropConfigs {
+  android.hardware.automotive.vehicle.VehiclePropConfig[] payloads;
+  @nullable ParcelFileDescriptor sharedMemoryFd;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropError.aidl
new file mode 100644
index 0000000..9835295
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VehiclePropError {
+  int propId;
+  int areaId;
+  android.hardware.automotive.vehicle.StatusCode errorCode = android.hardware.automotive.vehicle.StatusCode.OK;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropErrors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
new file mode 100644
index 0000000..9dcb10b
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VehiclePropErrors {
+  android.hardware.automotive.vehicle.VehiclePropError[] payloads;
+  @nullable ParcelFileDescriptor sharedMemoryFd;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValue.aidl
new file mode 100644
index 0000000..c87379f
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VehiclePropValue {
+  long timestamp;
+  int areaId;
+  int prop;
+  android.hardware.automotive.vehicle.VehiclePropertyStatus status = android.hardware.automotive.vehicle.VehiclePropertyStatus.AVAILABLE;
+  android.hardware.automotive.vehicle.RawPropValues value;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValues.aidl
new file mode 100644
index 0000000..e09a6b9
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropValues.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VehiclePropValues {
+  android.hardware.automotive.vehicle.VehiclePropValue[] payloads;
+  long sharedMemoryId;
+  @nullable ParcelFileDescriptor sharedMemoryFd;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
new file mode 100644
index 0000000..dde9a88
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehiclePropertyAccess {
+  NONE = 0x00,
+  READ = 0x01,
+  WRITE = 0x02,
+  READ_WRITE = 0x03,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
new file mode 100644
index 0000000..2f9d107
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehiclePropertyChangeMode {
+  STATIC = 0x00,
+  ON_CHANGE = 0x01,
+  CONTINUOUS = 0x02,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
new file mode 100644
index 0000000..642ce83
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/2/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehiclePropertyStatus {
+  AVAILABLE = 0x00,
+  UNAVAILABLE = 0x01,
+  ERROR = 0x02,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceType.aidl
deleted file mode 100644
index 1363a64..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceType.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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum EvsServiceType {
-  REARVIEW = 0,
-  SURROUNDVIEW = 1,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
deleted file mode 100644
index 73d4a14..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum Obd2CommonIgnitionMonitors {
-  COMPONENTS_AVAILABLE = 1,
-  COMPONENTS_INCOMPLETE = 2,
-  FUEL_SYSTEM_AVAILABLE = 4,
-  FUEL_SYSTEM_INCOMPLETE = 8,
-  MISFIRE_AVAILABLE = 16,
-  MISFIRE_INCOMPLETE = 32,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
deleted file mode 100644
index 01104c1..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
+++ /dev/null
@@ -1,55 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum Obd2CompressionIgnitionMonitors {
-  COMPONENTS_AVAILABLE = 1,
-  COMPONENTS_INCOMPLETE = 2,
-  FUEL_SYSTEM_AVAILABLE = 4,
-  FUEL_SYSTEM_INCOMPLETE = 8,
-  MISFIRE_AVAILABLE = 16,
-  MISFIRE_INCOMPLETE = 32,
-  EGR_OR_VVT_AVAILABLE = 64,
-  EGR_OR_VVT_INCOMPLETE = 128,
-  PM_FILTER_AVAILABLE = 256,
-  PM_FILTER_INCOMPLETE = 512,
-  EXHAUST_GAS_SENSOR_AVAILABLE = 1024,
-  EXHAUST_GAS_SENSOR_INCOMPLETE = 2048,
-  BOOST_PRESSURE_AVAILABLE = 4096,
-  BOOST_PRESSURE_INCOMPLETE = 8192,
-  NOx_SCR_AVAILABLE = 16384,
-  NOx_SCR_INCOMPLETE = 32768,
-  NMHC_CATALYST_AVAILABLE = 65536,
-  NMHC_CATALYST_INCOMPLETE = 131072,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
deleted file mode 100644
index badc29c..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
+++ /dev/null
@@ -1,59 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum Obd2SparkIgnitionMonitors {
-  COMPONENTS_AVAILABLE = 1,
-  COMPONENTS_INCOMPLETE = 2,
-  FUEL_SYSTEM_AVAILABLE = 4,
-  FUEL_SYSTEM_INCOMPLETE = 8,
-  MISFIRE_AVAILABLE = 16,
-  MISFIRE_INCOMPLETE = 32,
-  EGR_AVAILABLE = 64,
-  EGR_INCOMPLETE = 128,
-  OXYGEN_SENSOR_HEATER_AVAILABLE = 256,
-  OXYGEN_SENSOR_HEATER_INCOMPLETE = 512,
-  OXYGEN_SENSOR_AVAILABLE = 1024,
-  OXYGEN_SENSOR_INCOMPLETE = 2048,
-  AC_REFRIGERANT_AVAILABLE = 4096,
-  AC_REFRIGERANT_INCOMPLETE = 8192,
-  SECONDARY_AIR_SYSTEM_AVAILABLE = 16384,
-  SECONDARY_AIR_SYSTEM_INCOMPLETE = 32768,
-  EVAPORATIVE_SYSTEM_AVAILABLE = 65536,
-  EVAPORATIVE_SYSTEM_INCOMPLETE = 131072,
-  HEATED_CATALYST_AVAILABLE = 262144,
-  HEATED_CATALYST_INCOMPLETE = 524288,
-  CATALYST_AVAILABLE = 1048576,
-  CATALYST_INCOMPLETE = 2097152,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl
index 9b72412..f7e8c5a 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl
@@ -40,4 +40,9 @@
   NOT_AVAILABLE = 3,
   ACCESS_DENIED = 4,
   INTERNAL_ERROR = 5,
+  NOT_AVAILABLE_DISABLED = 6,
+  NOT_AVAILABLE_SPEED_LOW = 7,
+  NOT_AVAILABLE_SPEED_HIGH = 8,
+  NOT_AVAILABLE_POOR_VISIBILITY = 9,
+  NOT_AVAILABLE_SAFETY = 10,
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
deleted file mode 100644
index f47d5e7..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
+++ /dev/null
@@ -1,45 +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.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable UserInfo {
-  int userId = 0;
-  int flags;
-  const int USER_FLAG_SYSTEM = 1;
-  const int USER_FLAG_GUEST = 2;
-  const int USER_FLAG_EPHEMERAL = 4;
-  const int USER_FLAG_ADMIN = 8;
-  const int USER_FLAG_DISABLED = 16;
-  const int USER_FLAG_PROFILE = 32;
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
deleted file mode 100644
index d7b874a..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
+++ /dev/null
@@ -1,40 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleApPowerStateConfigFlag {
-  ENABLE_DEEP_SLEEP_FLAG = 1,
-  CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 2,
-  ENABLE_HIBERNATION_FLAG = 4,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
deleted file mode 100644
index fc669ec..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
+++ /dev/null
@@ -1,47 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleApPowerStateReport {
-  WAIT_FOR_VHAL = 1,
-  DEEP_SLEEP_ENTRY = 2,
-  DEEP_SLEEP_EXIT = 3,
-  SHUTDOWN_POSTPONE = 4,
-  SHUTDOWN_START = 5,
-  ON = 6,
-  SHUTDOWN_PREPARE = 7,
-  SHUTDOWN_CANCELLED = 8,
-  HIBERNATION_ENTRY = 9,
-  HIBERNATION_EXIT = 10,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleArea.aidl
deleted file mode 100644
index 4f8b917..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleArea.aidl
+++ /dev/null
@@ -1,44 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleArea {
-  GLOBAL = 16777216,
-  WINDOW = 50331648,
-  MIRROR = 67108864,
-  SEAT = 83886080,
-  DOOR = 100663296,
-  WHEEL = 117440512,
-  MASK = 251658240,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index b93a11b..6960894 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -41,4 +41,5 @@
   long maxInt64Value;
   float minFloatValue;
   float maxFloatValue;
+  @nullable long[] supportedEnumValues;
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
deleted file mode 100644
index 11139f9..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
+++ /dev/null
@@ -1,45 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaDoor {
-  ROW_1_LEFT = 1,
-  ROW_1_RIGHT = 4,
-  ROW_2_LEFT = 16,
-  ROW_2_RIGHT = 64,
-  ROW_3_LEFT = 256,
-  ROW_3_RIGHT = 1024,
-  HOOD = 268435456,
-  REAR = 536870912,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
deleted file mode 100644
index c1e2fbd..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
+++ /dev/null
@@ -1,40 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaMirror {
-  DRIVER_LEFT = 1,
-  DRIVER_RIGHT = 2,
-  DRIVER_CENTER = 4,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
deleted file mode 100644
index e76de32..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaSeat.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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaSeat {
-  ROW_1_LEFT = 1,
-  ROW_1_CENTER = 2,
-  ROW_1_RIGHT = 4,
-  ROW_2_LEFT = 16,
-  ROW_2_CENTER = 32,
-  ROW_2_RIGHT = 64,
-  ROW_3_LEFT = 256,
-  ROW_3_CENTER = 512,
-  ROW_3_RIGHT = 1024,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
deleted file mode 100644
index 9e83434..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWheel.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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaWheel {
-  UNKNOWN = 0,
-  LEFT_FRONT = 1,
-  RIGHT_FRONT = 2,
-  LEFT_REAR = 4,
-  RIGHT_REAR = 8,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
deleted file mode 100644
index 6ec26fe..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
+++ /dev/null
@@ -1,47 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaWindow {
-  FRONT_WINDSHIELD = 1,
-  REAR_WINDSHIELD = 2,
-  ROW_1_LEFT = 16,
-  ROW_1_RIGHT = 64,
-  ROW_2_LEFT = 256,
-  ROW_2_RIGHT = 1024,
-  ROW_3_LEFT = 4096,
-  ROW_3_RIGHT = 16384,
-  ROOF_TOP_1 = 65536,
-  ROOF_TOP_2 = 131072,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl
deleted file mode 100644
index 5aeafa4..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleDisplay.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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleDisplay {
-  MAIN = 0,
-  INSTRUMENT_CLUSTER = 1,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleGear.aidl
deleted file mode 100644
index db4760d..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleGear.aidl
+++ /dev/null
@@ -1,51 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleGear {
-  GEAR_UNKNOWN = 0,
-  GEAR_NEUTRAL = 1,
-  GEAR_REVERSE = 2,
-  GEAR_PARK = 4,
-  GEAR_DRIVE = 8,
-  GEAR_1 = 16,
-  GEAR_2 = 32,
-  GEAR_3 = 64,
-  GEAR_4 = 128,
-  GEAR_5 = 256,
-  GEAR_6 = 512,
-  GEAR_7 = 1024,
-  GEAR_8 = 2048,
-  GEAR_9 = 4096,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
deleted file mode 100644
index a85751f..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleHvacFanDirection {
-  UNKNOWN = 0,
-  FACE = 1,
-  FLOOR = 2,
-  FACE_AND_FLOOR = 3,
-  DEFROST = 4,
-  DEFROST_AND_FLOOR = 6,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
deleted file mode 100644
index 09d5423..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleIgnitionState.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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleIgnitionState {
-  UNDEFINED = 0,
-  LOCK = 1,
-  OFF = 2,
-  ACC = 3,
-  ON = 4,
-  START = 5,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
deleted file mode 100644
index 0d3c636..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
+++ /dev/null
@@ -1,41 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleLightSwitch {
-  OFF = 0,
-  ON = 1,
-  DAYTIME_RUNNING = 2,
-  AUTOMATIC = 256,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
deleted file mode 100644
index 04f8fa3..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ /dev/null
@@ -1,209 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleProperty {
-  INVALID = 0,
-  INFO_VIN = 286261504,
-  INFO_MAKE = 286261505,
-  INFO_MODEL = 286261506,
-  INFO_MODEL_YEAR = 289407235,
-  INFO_FUEL_CAPACITY = 291504388,
-  INFO_FUEL_TYPE = 289472773,
-  INFO_EV_BATTERY_CAPACITY = 291504390,
-  INFO_EV_CONNECTOR_TYPE = 289472775,
-  INFO_FUEL_DOOR_LOCATION = 289407240,
-  INFO_EV_PORT_LOCATION = 289407241,
-  INFO_DRIVER_SEAT = 356516106,
-  INFO_EXTERIOR_DIMENSIONS = 289472779,
-  INFO_MULTI_EV_PORT_LOCATIONS = 289472780,
-  PERF_ODOMETER = 291504644,
-  PERF_VEHICLE_SPEED = 291504647,
-  PERF_VEHICLE_SPEED_DISPLAY = 291504648,
-  PERF_STEERING_ANGLE = 291504649,
-  PERF_REAR_STEERING_ANGLE = 291504656,
-  ENGINE_COOLANT_TEMP = 291504897,
-  ENGINE_OIL_LEVEL = 289407747,
-  ENGINE_OIL_TEMP = 291504900,
-  ENGINE_RPM = 291504901,
-  WHEEL_TICK = 290521862,
-  FUEL_LEVEL = 291504903,
-  FUEL_DOOR_OPEN = 287310600,
-  EV_BATTERY_LEVEL = 291504905,
-  EV_CHARGE_PORT_OPEN = 287310602,
-  EV_CHARGE_PORT_CONNECTED = 287310603,
-  EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = 291504908,
-  RANGE_REMAINING = 291504904,
-  TIRE_PRESSURE = 392168201,
-  CRITICALLY_LOW_TIRE_PRESSURE = 392168202,
-  GEAR_SELECTION = 289408000,
-  CURRENT_GEAR = 289408001,
-  PARKING_BRAKE_ON = 287310850,
-  PARKING_BRAKE_AUTO_APPLY = 287310851,
-  FUEL_LEVEL_LOW = 287310853,
-  NIGHT_MODE = 287310855,
-  TURN_SIGNAL_STATE = 289408008,
-  IGNITION_STATE = 289408009,
-  ABS_ACTIVE = 287310858,
-  TRACTION_CONTROL_ACTIVE = 287310859,
-  HVAC_FAN_SPEED = 356517120,
-  HVAC_FAN_DIRECTION = 356517121,
-  HVAC_TEMPERATURE_CURRENT = 358614274,
-  HVAC_TEMPERATURE_SET = 358614275,
-  HVAC_DEFROSTER = 320865540,
-  HVAC_AC_ON = 354419973,
-  HVAC_MAX_AC_ON = 354419974,
-  HVAC_MAX_DEFROST_ON = 354419975,
-  HVAC_RECIRC_ON = 354419976,
-  HVAC_DUAL_ON = 354419977,
-  HVAC_AUTO_ON = 354419978,
-  HVAC_SEAT_TEMPERATURE = 356517131,
-  HVAC_SIDE_MIRROR_HEAT = 339739916,
-  HVAC_STEERING_WHEEL_HEAT = 289408269,
-  HVAC_TEMPERATURE_DISPLAY_UNITS = 289408270,
-  HVAC_ACTUAL_FAN_SPEED_RPM = 356517135,
-  HVAC_POWER_ON = 354419984,
-  HVAC_FAN_DIRECTION_AVAILABLE = 356582673,
-  HVAC_AUTO_RECIRC_ON = 354419986,
-  HVAC_SEAT_VENTILATION = 356517139,
-  HVAC_ELECTRIC_DEFROSTER_ON = 320865556,
-  HVAC_TEMPERATURE_VALUE_SUGGESTION = 291570965,
-  DISTANCE_DISPLAY_UNITS = 289408512,
-  FUEL_VOLUME_DISPLAY_UNITS = 289408513,
-  TIRE_PRESSURE_DISPLAY_UNITS = 289408514,
-  EV_BATTERY_DISPLAY_UNITS = 289408515,
-  FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 287311364,
-  VEHICLE_SPEED_DISPLAY_UNITS = 289408517,
-  EXTERNAL_CAR_TIME = 290457096,
-  ANDROID_EPOCH_TIME = 290457094,
-  STORAGE_ENCRYPTION_BINDING_SEED = 292554247,
-  ENV_OUTSIDE_TEMPERATURE = 291505923,
-  AP_POWER_STATE_REQ = 289475072,
-  AP_POWER_STATE_REPORT = 289475073,
-  AP_POWER_BOOTUP_REASON = 289409538,
-  DISPLAY_BRIGHTNESS = 289409539,
-  HW_KEY_INPUT = 289475088,
-  HW_ROTARY_INPUT = 289475104,
-  HW_CUSTOM_INPUT = 289475120,
-  DOOR_POS = 373295872,
-  DOOR_MOVE = 373295873,
-  DOOR_LOCK = 371198722,
-  MIRROR_Z_POS = 339741504,
-  MIRROR_Z_MOVE = 339741505,
-  MIRROR_Y_POS = 339741506,
-  MIRROR_Y_MOVE = 339741507,
-  MIRROR_LOCK = 287312708,
-  MIRROR_FOLD = 287312709,
-  SEAT_MEMORY_SELECT = 356518784,
-  SEAT_MEMORY_SET = 356518785,
-  SEAT_BELT_BUCKLED = 354421634,
-  SEAT_BELT_HEIGHT_POS = 356518787,
-  SEAT_BELT_HEIGHT_MOVE = 356518788,
-  SEAT_FORE_AFT_POS = 356518789,
-  SEAT_FORE_AFT_MOVE = 356518790,
-  SEAT_BACKREST_ANGLE_1_POS = 356518791,
-  SEAT_BACKREST_ANGLE_1_MOVE = 356518792,
-  SEAT_BACKREST_ANGLE_2_POS = 356518793,
-  SEAT_BACKREST_ANGLE_2_MOVE = 356518794,
-  SEAT_HEIGHT_POS = 356518795,
-  SEAT_HEIGHT_MOVE = 356518796,
-  SEAT_DEPTH_POS = 356518797,
-  SEAT_DEPTH_MOVE = 356518798,
-  SEAT_TILT_POS = 356518799,
-  SEAT_TILT_MOVE = 356518800,
-  SEAT_LUMBAR_FORE_AFT_POS = 356518801,
-  SEAT_LUMBAR_FORE_AFT_MOVE = 356518802,
-  SEAT_LUMBAR_SIDE_SUPPORT_POS = 356518803,
-  SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 356518804,
-  SEAT_HEADREST_HEIGHT_POS = 289409941,
-  SEAT_HEADREST_HEIGHT_MOVE = 356518806,
-  SEAT_HEADREST_ANGLE_POS = 356518807,
-  SEAT_HEADREST_ANGLE_MOVE = 356518808,
-  SEAT_HEADREST_FORE_AFT_POS = 356518809,
-  SEAT_HEADREST_FORE_AFT_MOVE = 356518810,
-  SEAT_OCCUPANCY = 356518832,
-  WINDOW_POS = 322964416,
-  WINDOW_MOVE = 322964417,
-  WINDOW_LOCK = 320867268,
-  VEHICLE_MAP_SERVICE = 299895808,
-  OBD2_LIVE_FRAME = 299896064,
-  OBD2_FREEZE_FRAME = 299896065,
-  OBD2_FREEZE_FRAME_INFO = 299896066,
-  OBD2_FREEZE_FRAME_CLEAR = 299896067,
-  HEADLIGHTS_STATE = 289410560,
-  HIGH_BEAM_LIGHTS_STATE = 289410561,
-  FOG_LIGHTS_STATE = 289410562,
-  HAZARD_LIGHTS_STATE = 289410563,
-  HEADLIGHTS_SWITCH = 289410576,
-  HIGH_BEAM_LIGHTS_SWITCH = 289410577,
-  FOG_LIGHTS_SWITCH = 289410578,
-  HAZARD_LIGHTS_SWITCH = 289410579,
-  CABIN_LIGHTS_STATE = 289410817,
-  CABIN_LIGHTS_SWITCH = 289410818,
-  READING_LIGHTS_STATE = 356519683,
-  READING_LIGHTS_SWITCH = 356519684,
-  SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 287313669,
-  DISABLED_OPTIONAL_FEATURES = 286265094,
-  INITIAL_USER_INFO = 299896583,
-  SWITCH_USER = 299896584,
-  CREATE_USER = 299896585,
-  REMOVE_USER = 299896586,
-  USER_IDENTIFICATION_ASSOCIATION = 299896587,
-  EVS_SERVICE_REQUEST = 289476368,
-  POWER_POLICY_REQ = 286265121,
-  POWER_POLICY_GROUP_REQ = 286265122,
-  CURRENT_POWER_POLICY = 286265123,
-  WATCHDOG_ALIVE = 290459441,
-  WATCHDOG_TERMINATED_PROCESS = 299896626,
-  VHAL_HEARTBEAT = 290459443,
-  CLUSTER_SWITCH_UI = 289410868,
-  CLUSTER_DISPLAY_STATE = 289476405,
-  CLUSTER_REPORT_STATE = 299896630,
-  CLUSTER_REQUEST_DISPLAY = 289410871,
-  CLUSTER_NAVIGATION_STATE = 292556600,
-  ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = 289410873,
-  ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = 289410874,
-  FRONT_FOG_LIGHTS_STATE = 289410875,
-  FRONT_FOG_LIGHTS_SWITCH = 289410876,
-  REAR_FOG_LIGHTS_STATE = 289410877,
-  REAR_FOG_LIGHTS_SWITCH = 289410878,
-  EV_CHARGE_CURRENT_DRAW_LIMIT = 291508031,
-  EV_CHARGE_PERCENT_LIMIT = 291508032,
-  EV_CHARGE_STATE = 289410881,
-  EV_CHARGE_SWITCH = 287313730,
-  EV_CHARGE_TIME_REMAINING = 289410883,
-  EV_REGENERATIVE_BRAKING_STATE = 289410884,
-  TRAILER_PRESENT = 289410885,
-  VEHICLE_CURB_WEIGHT = 289410886,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
index ec9587f..dde9a88 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
@@ -34,8 +34,8 @@
 package android.hardware.automotive.vehicle;
 @Backing(type="int") @VintfStability
 enum VehiclePropertyAccess {
-  NONE = 0,
-  READ = 1,
-  WRITE = 2,
-  READ_WRITE = 3,
+  NONE = 0x00,
+  READ = 0x01,
+  WRITE = 0x02,
+  READ_WRITE = 0x03,
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
index 5455fdd..2f9d107 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
@@ -34,7 +34,7 @@
 package android.hardware.automotive.vehicle;
 @Backing(type="int") @VintfStability
 enum VehiclePropertyChangeMode {
-  STATIC = 0,
-  ON_CHANGE = 1,
-  CONTINUOUS = 2,
+  STATIC = 0x00,
+  ON_CHANGE = 0x01,
+  CONTINUOUS = 0x02,
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
deleted file mode 100644
index 0c049c4..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
+++ /dev/null
@@ -1,40 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehiclePropertyGroup {
-  SYSTEM = 268435456,
-  VENDOR = 536870912,
-  MASK = -268435456,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
index 6d0e041..642ce83 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
@@ -34,7 +34,7 @@
 package android.hardware.automotive.vehicle;
 @Backing(type="int") @VintfStability
 enum VehiclePropertyStatus {
-  AVAILABLE = 0,
-  UNAVAILABLE = 1,
-  ERROR = 2,
+  AVAILABLE = 0x00,
+  UNAVAILABLE = 0x01,
+  ERROR = 0x02,
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
deleted file mode 100644
index da6d2c2..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyType.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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehiclePropertyType {
-  STRING = 1048576,
-  BOOLEAN = 2097152,
-  INT32 = 4194304,
-  INT32_VEC = 4259840,
-  INT64 = 5242880,
-  INT64_VEC = 5308416,
-  FLOAT = 6291456,
-  FLOAT_VEC = 6356992,
-  BYTES = 7340032,
-  MIXED = 14680064,
-  MASK = 16711680,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
deleted file mode 100644
index 78c1795..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
+++ /dev/null
@@ -1,40 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleTurnSignal {
-  NONE = 0,
-  RIGHT = 1,
-  LEFT = 2,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleUnit.aidl
deleted file mode 100644
index c80fdbb..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleUnit.aidl
+++ /dev/null
@@ -1,70 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleUnit {
-  SHOULD_NOT_USE = 0,
-  METER_PER_SEC = 1,
-  RPM = 2,
-  HERTZ = 3,
-  PERCENTILE = 16,
-  MILLIMETER = 32,
-  METER = 33,
-  KILOMETER = 35,
-  MILE = 36,
-  CELSIUS = 48,
-  FAHRENHEIT = 49,
-  KELVIN = 50,
-  MILLILITER = 64,
-  LITER = 65,
-  GALLON = 66,
-  US_GALLON = 66,
-  IMPERIAL_GALLON = 67,
-  NANO_SECS = 80,
-  SECS = 83,
-  YEAR = 89,
-  WATT_HOUR = 96,
-  MILLIAMPERE = 97,
-  MILLIVOLT = 98,
-  MILLIWATTS = 99,
-  AMPERE_HOURS = 100,
-  KILOWATT_HOUR = 101,
-  AMPERE = 102,
-  KILOPASCAL = 112,
-  PSI = 113,
-  BAR = 114,
-  DEGREES = 128,
-  MILES_PER_HOUR = 144,
-  KILOMETERS_PER_HOUR = 145,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
deleted file mode 100644
index 58524f3..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
+++ /dev/null
@@ -1,75 +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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleVendorPermission {
-  PERMISSION_DEFAULT = 0,
-  PERMISSION_SET_VENDOR_CATEGORY_WINDOW = 1,
-  PERMISSION_GET_VENDOR_CATEGORY_WINDOW = 2,
-  PERMISSION_SET_VENDOR_CATEGORY_DOOR = 3,
-  PERMISSION_GET_VENDOR_CATEGORY_DOOR = 4,
-  PERMISSION_SET_VENDOR_CATEGORY_SEAT = 5,
-  PERMISSION_GET_VENDOR_CATEGORY_SEAT = 6,
-  PERMISSION_SET_VENDOR_CATEGORY_MIRROR = 7,
-  PERMISSION_GET_VENDOR_CATEGORY_MIRROR = 8,
-  PERMISSION_SET_VENDOR_CATEGORY_INFO = 9,
-  PERMISSION_GET_VENDOR_CATEGORY_INFO = 10,
-  PERMISSION_SET_VENDOR_CATEGORY_ENGINE = 11,
-  PERMISSION_GET_VENDOR_CATEGORY_ENGINE = 12,
-  PERMISSION_SET_VENDOR_CATEGORY_HVAC = 13,
-  PERMISSION_GET_VENDOR_CATEGORY_HVAC = 14,
-  PERMISSION_SET_VENDOR_CATEGORY_LIGHT = 15,
-  PERMISSION_GET_VENDOR_CATEGORY_LIGHT = 16,
-  PERMISSION_SET_VENDOR_CATEGORY_1 = 65536,
-  PERMISSION_GET_VENDOR_CATEGORY_1 = 69632,
-  PERMISSION_SET_VENDOR_CATEGORY_2 = 131072,
-  PERMISSION_GET_VENDOR_CATEGORY_2 = 135168,
-  PERMISSION_SET_VENDOR_CATEGORY_3 = 196608,
-  PERMISSION_GET_VENDOR_CATEGORY_3 = 200704,
-  PERMISSION_SET_VENDOR_CATEGORY_4 = 262144,
-  PERMISSION_GET_VENDOR_CATEGORY_4 = 266240,
-  PERMISSION_SET_VENDOR_CATEGORY_5 = 327680,
-  PERMISSION_GET_VENDOR_CATEGORY_5 = 331776,
-  PERMISSION_SET_VENDOR_CATEGORY_6 = 393216,
-  PERMISSION_GET_VENDOR_CATEGORY_6 = 397312,
-  PERMISSION_SET_VENDOR_CATEGORY_7 = 458752,
-  PERMISSION_GET_VENDOR_CATEGORY_7 = 462848,
-  PERMISSION_SET_VENDOR_CATEGORY_8 = 524288,
-  PERMISSION_GET_VENDOR_CATEGORY_8 = 528384,
-  PERMISSION_SET_VENDOR_CATEGORY_9 = 589824,
-  PERMISSION_GET_VENDOR_CATEGORY_9 = 593920,
-  PERMISSION_SET_VENDOR_CATEGORY_10 = 655360,
-  PERMISSION_GET_VENDOR_CATEGORY_10 = 659456,
-  PERMISSION_NOT_ACCESSIBLE = -268435456,
-}
diff --git a/automotive/vehicle/aidl/aidl_test/Android.bp b/automotive/vehicle/aidl/aidl_test/Android.bp
index 5284a0a..44d7445 100644
--- a/automotive/vehicle/aidl/aidl_test/Android.bp
+++ b/automotive/vehicle/aidl/aidl_test/Android.bp
@@ -20,7 +20,7 @@
 
 cc_test {
     name: "VehicleHalAidlHidlCompatibilityTest",
-    srcs: ["*.cpp"],
+    srcs: ["AidlHidlCompatibilityTest.cpp"],
     shared_libs: [
         "libbinder_ndk",
         "libhidlbase",
@@ -35,3 +35,26 @@
     test_suites: ["device-tests"],
     vendor: true,
 }
+
+cc_test {
+    name: "VehiclePropertyAnnotationCppTest",
+    srcs: ["VehiclePropertyAnnotationCppTest.cpp"],
+    header_libs: ["IVehicleGeneratedHeaders"],
+    defaults: ["VehicleHalInterfaceDefaults"],
+    test_suites: ["general-tests"],
+}
+
+android_test {
+    name: "VehiclePropertyAnnotationJavaTest",
+    srcs: [
+        "VehiclePropertyAnnotationJavaTest.java",
+        ":IVehicleGeneratedJavaFiles",
+    ],
+    static_libs: [
+        "android.hardware.automotive.vehicle-V2-java",
+        "android.hardware.automotive.vehicle.property-V2-java",
+        "androidx.test.runner",
+        "truth-prebuilt",
+    ],
+    test_suites: ["general-tests"],
+}
diff --git a/automotive/vehicle/aidl/aidl_test/AndroidManifest.xml b/automotive/vehicle/aidl/aidl_test/AndroidManifest.xml
new file mode 100644
index 0000000..00fdf50
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_test/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.hardware.automotive.vehicle" >
+
+    <application/>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.hardware.automotive.vehicle"
+                     android:label="test to verify VHAL annotation"/>
+
+</manifest>
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationCppTest.cpp b/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationCppTest.cpp
new file mode 100644
index 0000000..a4bbbe8
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationCppTest.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <AccessForVehicleProperty.h>
+#include <ChangeModeForVehicleProperty.h>
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <gtest/gtest.h>
+#include <unordered_set>
+
+namespace aidl_vehicle = ::aidl::android::hardware::automotive::vehicle;
+using aidl_vehicle::AccessForVehicleProperty;
+using aidl_vehicle::ChangeModeForVehicleProperty;
+using aidl_vehicle::VehicleProperty;
+
+namespace {
+    template<class T>
+    bool doesAnnotationMapContainsAllProps(std::unordered_map<VehicleProperty, T> annotationMap) {
+        for (const VehicleProperty& v : ::ndk::enum_range<VehicleProperty>()) {
+            std::string name = aidl_vehicle::toString(v);
+            if (name == "INVALID") {
+                continue;
+            }
+            if (annotationMap.find(v) == annotationMap.end()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}  // namespace
+
+TEST(VehiclePropertyAnnotationCppTest, testChangeMode) {
+    ASSERT_TRUE(doesAnnotationMapContainsAllProps(ChangeModeForVehicleProperty))
+            << "Outdated annotation-generated AIDL files. Please run "
+            << "generate_annotation_enums.py to update.";
+}
+
+TEST(VehiclePropertyAnnotationCppTest, testAccess) {
+    ASSERT_TRUE(doesAnnotationMapContainsAllProps(AccessForVehicleProperty))
+            << "Outdated annotation-generated AIDL files. Please run "
+            << "generate_annotation_enums.py to update.";
+}
diff --git a/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationJavaTest.java b/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationJavaTest.java
new file mode 100644
index 0000000..ef49299
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationJavaTest.java
@@ -0,0 +1,60 @@
+package android.hardware.automotive.vehicle;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.fail;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+
+@RunWith(JUnit4.class)
+public class VehiclePropertyAnnotationJavaTest {
+
+    private boolean doesAnnotationMapContainsAllProps(Map<Integer, Integer> annotationMap) {
+        for (Field field : VehicleProperty.class.getDeclaredFields()) {
+            int modifiers = field.getModifiers();
+            try {
+                if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)
+                        && Modifier.isPublic(modifiers) && field.getType().equals(int.class)) {
+                    int propId = field.getInt(/* obj= */ null);
+                    if (propId == VehicleProperty.INVALID) {
+                        // Skip INVALID_PROP.
+                        continue;
+                    }
+                    if (annotationMap.get(propId) == null) {
+                        return false;
+                    }
+                }
+            } catch (IllegalAccessException e) {
+                throw new IllegalStateException(
+                        "Cannot access a member for VehicleProperty.class", e);
+            }
+        }
+        return true;
+    }
+
+    @Test
+    @SmallTest
+    public void testChangeMode() {
+        assertWithMessage("Outdated annotation-generated AIDL files. Please run "
+                + "generate_annotation_enums.py to update.")
+                .that(doesAnnotationMapContainsAllProps(ChangeModeForVehicleProperty.values))
+                .isTrue();
+    }
+
+    @Test
+    @SmallTest
+    public void testAccess() {
+        assertWithMessage("Outdated annotation-generated AIDL files. Please run "
+                + "generate_annotation_enums.py to update.")
+                .that(doesAnnotationMapContainsAllProps(AccessForVehicleProperty.values))
+                .isTrue();
+    }
+}
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceType.aidl
deleted file mode 100644
index 6c621f7..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceType.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.automotive.vehicle;
-
-/**
- * Used by EVS_SERVICE_REQUEST to enumerate the service's type.
- */
-@VintfStability
-@Backing(type="int")
-enum EvsServiceType {
-    REARVIEW = 0,
-    SURROUNDVIEW = 1,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
index 47fc54b..c896d14 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
@@ -190,6 +190,14 @@
      * what the sampleRate specified in {@code options}, the timestamp for
      * the timestamp is updated 10 times/s.
      *
+     * If a property is unavailable for reading because it depends on some power
+     * state which is off, property change event may not be generated until the
+     * property becomes available. For ON_CHANGE property, if the property
+     * changes from NOT_AVAILABLE to OKAY for reading some or all area(s), for
+     * each area that becomes available for reading, one property change event
+     * must be generated. The event must contain the current value for the area
+     * and must have {@code AVAILABLE} status.
+     *
      * @param callback The subscription callbacks.
      *    {@link IVehicleCallback#onPropertyEvent} would be called when a new
      *    property event arrives.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
index 9c6875b..28ccc1d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -20,8 +20,8 @@
 @JavaDerive(equals=true, toString=true)
 parcelable RawPropValues {
     /**
-     * This is used for properties of types VehiclePropertyType#INT
-     * and VehiclePropertyType#INT_VEC
+     * This is used for properties of types VehiclePropertyType#INT32,
+     * VehiclePropertyType#BOOLEAN and VehiclePropertyType#INT32_VEC
      */
     int[] int32Values = {};
 
@@ -31,7 +31,10 @@
      */
     float[] floatValues;
 
-    /** This is used for properties of type VehiclePropertyType#INT64 */
+    /**
+     * This is used for properties of type VehiclePropertyType#INT64 and
+     * VehiclePropertyType#INT64_VEC
+     */
     long[] int64Values;
 
     /** This is used for properties of type VehiclePropertyType#BYTES */
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
index 23019ca..fd4b199 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
@@ -17,14 +17,21 @@
 package android.hardware.automotive.vehicle;
 
 /**
- * Error codes used in vehicle HAL interface.
+ * Error codes used in vehicle HAL interface. System defined error codes will have the range from
+ * 0x0000 to 0xffff and vendor error codes will have the range from 0x0001 to 0xffff. The error code
+ * is formatted as [VENDOR_ERROR] << 16 | [SYSTEM_ERROR]. A vendor error code of 0 indicates vendor
+ * code not set.
  */
 @VintfStability
 @Backing(type="int")
 enum StatusCode {
     OK = 0,
     /**
-     * Try again.
+     * Caller should try again.
+     *
+     * This code must be returned when an ephemeral error happens and a retry
+     * will likely succeed. E.g., when the device is currently booting up
+     * and the property is not ready yet.
      */
     TRY_AGAIN = 1,
     /**
@@ -32,9 +39,22 @@
      */
     INVALID_ARG = 2,
     /**
+     * The property is currently unavailable and will be unavailable unless
+     * some other state changes.
+     *
      * This code must be returned when device that associated with the vehicle
      * property is not available. For example, when client tries to set HVAC
      * temperature when the whole HVAC unit is turned OFF.
+     *
+     * The difference between this and TRY_AGAIN is that if NOT_AVAILABLE is
+     * returned for a property, it will remain NOT_AVAILABLE unless some other
+     * state changes. This means a retry will likely still return NOT_AVAILABLE.
+     * However, for TRY_AGAIN error, a retry will likely return OK.
+     *
+     * When subscribing to a property that is currently unavailable for getting.
+     * VHAL must return OK even if getting/setting must return NOT_AVAILABLE.
+     * VHAL must not generate property change event when the property is not
+     * available for getting.
      */
     NOT_AVAILABLE = 3,
     /**
@@ -45,4 +65,35 @@
      * Something unexpected has happened in Vehicle HAL
      */
     INTERNAL_ERROR = 5,
+
+    /**
+     * The following error codes were added in version 2 of this interface.
+     */
+
+    /**
+     * For features that are not available because the underlying feature is
+     * disabled.
+     */
+    NOT_AVAILABLE_DISABLED = 6,
+    /**
+     * For features that are not available because the vehicle speed is too low.
+     */
+    NOT_AVAILABLE_SPEED_LOW = 7,
+    /**
+     * For features that are not available because the vehicle speed is too
+     * high.
+     */
+    NOT_AVAILABLE_SPEED_HIGH = 8,
+    /**
+     * For features that are not available because of bad camera or sensor
+     * visibility. Examples might be bird poop blocking the camera or a bumper
+     * cover blocking an ultrasonic sensor.
+     */
+    NOT_AVAILABLE_POOR_VISIBILITY = 9,
+    /**
+     * The feature cannot be accessed due to safety reasons. Eg. System could be
+     * in a faulty state, an object or person could be blocking the requested
+     * operation such as closing a trunk door, etc.
+     */
+    NOT_AVAILABLE_SAFETY = 10,
 }
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/TrailerState.aidl
deleted file mode 100644
index fd42062..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/TrailerState.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.automotive.vehicle;
-
-/**
- * Used by the trailer present property to enumerate the current state
- * of the trailer.
- */
-@VintfStability
-@Backing(type="int")
-enum TrailerState {
-    UNKNOWN = 0,
-    NOT_PRESENT = 1,
-    PRESENT = 2,
-    ERROR = 3,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleArea.aidl
deleted file mode 100644
index dab0349..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleArea.aidl
+++ /dev/null
@@ -1,35 +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.automotive.vehicle;
-
-@VintfStability
-@Backing(type="int")
-enum VehicleArea {
-    GLOBAL = 0x01000000,
-    /** WINDOW maps to enum VehicleAreaWindow */
-    WINDOW = 0x03000000,
-    /** MIRROR maps to enum VehicleAreaMirror */
-    MIRROR = 0x04000000,
-    /** SEAT maps to enum VehicleAreaSeat */
-    SEAT = 0x05000000,
-    /** DOOR maps to enum VehicleAreaDoor */
-    DOOR = 0x06000000,
-    /** WHEEL maps to enum VehicleAreaWheel */
-    WHEEL = 0x07000000,
-
-    MASK = 0x0f000000,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index b44996d..20c046d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -20,7 +20,7 @@
 @JavaDerive(equals=true, toString=true)
 parcelable VehicleAreaConfig {
     /**
-     * Area id is ignored for VehiclePropertyGroup:GLOBAL properties.
+     * Area id is always 0 for VehicleArea#GLOBAL properties.
      */
     int areaId;
 
@@ -40,4 +40,11 @@
 
     float minFloatValue;
     float maxFloatValue;
+
+    /**
+     * If the property has a @data_enum, then it is possible to specify a supported subset of the
+     * @data_enum. If the property has a @data_enum and supportedEnumValues is null, then it is
+     * assumed all @data_enum values are supported unless specified through another mechanism.
+     */
+    @nullable long[] supportedEnumValues;
 }
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleDisplay.aidl
deleted file mode 100644
index 1759a90..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleDisplay.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.automotive.vehicle;
-
-@VintfStability
-@Backing(type="int")
-enum VehicleDisplay {
-    /**
-     * The primary Android display (for example, center console)
-     */
-    MAIN = 0,
-    INSTRUMENT_CLUSTER = 1,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
deleted file mode 100644
index fa5d711..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
+++ /dev/null
@@ -1,37 +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.automotive.vehicle;
-
-/**
- * Bit flags for fan direction
- */
-@VintfStability
-@Backing(type="int")
-enum VehicleHvacFanDirection {
-    UNKNOWN = 0x0,
-    FACE = 0x1,
-    FLOOR = 0x2,
-    /**
-     * FACE_AND_FLOOR = FACE | FLOOR
-     */
-    FACE_AND_FLOOR = 0x3,
-    DEFROST = 0x4,
-    /**
-     * DEFROST_AND_FLOOR = DEFROST | FLOOR
-     */
-    DEFROST_AND_FLOOR = 0x06,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
deleted file mode 100644
index bf3c858..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleOilLevel.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.automotive.vehicle;
-
-@VintfStability
-@Backing(type="int")
-enum VehicleOilLevel {
-    /**
-     * Oil level values
-     */
-    CRITICALLY_LOW = 0,
-    LOW = 1,
-    NORMAL = 2,
-    HIGH = 3,
-    ERROR = 4,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 1b48f0b..61b9369 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -37,7 +37,25 @@
     VehiclePropertyChangeMode changeMode = VehiclePropertyChangeMode.STATIC;
 
     /**
-     * Contains per-area configuration.
+     * Contains per-areaId configuration.
+     *
+     * [Definition] area: An area represents a unique element of a VehicleArea. For instance, if the
+     *   VehicleArea is WINDOW, then an example area is FRONT_WINDSHIELD.
+     *
+     * [Definition] area ID: An area ID is a combination of one or more areas, and is created by
+     *   bitwise "OR"ing the areas together. Areas from different VehicleArea values may not be
+     *   mixed in a single area ID. For example, a VehicleAreaWindow area cannot be combined with a
+     *   VehicleAreaSeat area in an area ID.
+     *
+     * For VehicleArea#GLOBAL properties, they must map only to a single area ID of 0.
+     *
+     * Rules for mapping a non VehicleArea#GLOBAL property to area IDs:
+     *  - A property must be mapped to a set of area IDs that are impacted when the property value
+     *    changes.
+     *  - An area cannot be part of multiple area IDs, it must only be part of a single area ID.
+     *  - When the property value changes in one of the areas in an area ID, then it must
+     *    automatically change in all other areas in the area ID.
+     *  - The property value must be independently controllable in any two different area IDs.
      */
     VehicleAreaConfig[] areaConfigs;
 
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
deleted file mode 100644
index 727b949..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ /dev/null
@@ -1,2843 +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.automotive.vehicle;
-
-import android.hardware.automotive.vehicle.VehiclePropertyType;
-/**
- * Declares all vehicle properties. VehicleProperty has a bitwise structure.
- * Each property must have:
- *  - a unique id from range 0x0100 - 0xffff
- *  - associated data type using VehiclePropertyType
- *  - property group (VehiclePropertyGroup)
- *  - vehicle area (VehicleArea)
- *
- * Vendors are allowed to extend this enum with their own properties. In this
- * case they must use VehiclePropertyGroup:VENDOR flag when the property is
- * declared.
- *
- * When a property's status field is not set to AVAILABLE:
- *  - IVehicle#set may return StatusCode::NOT_AVAILABLE.
- *  - IVehicle#get is not guaranteed to work.
- *
- * Properties set to values out of range must be ignored and no action taken
- * in response to such ill formed requests.
- */
-@VintfStability
-@Backing(type="int")
-enum VehicleProperty {
-    /**
-     * Undefined property.
-     */
-    INVALID = 0x00000000,
-    /**
-     * VIN of vehicle
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     */
-    INFO_VIN = 0x0100 + 0x10000000 + 0x01000000
-            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
-    /**
-     * Manufacturer of vehicle
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     */
-    INFO_MAKE = 0x0101 + 0x10000000 + 0x01000000
-            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
-    /**
-     * Model of vehicle
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     */
-    INFO_MODEL = 0x0102 + 0x10000000 + 0x01000000
-            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
-    /**
-     * Model year of vehicle.
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:YEAR
-     */
-    INFO_MODEL_YEAR = 0x0103 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Fuel capacity of the vehicle in milliliters
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:MILLILITER
-     */
-    INFO_FUEL_CAPACITY = 0x0104 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * List of fuels the vehicle may use
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @data_enum FuelType
-     */
-    INFO_FUEL_TYPE = 0x0105 + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Battery capacity of the vehicle, if EV or hybrid.  This is the nominal
-     * battery capacity when the vehicle is new.
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:WH
-     */
-    INFO_EV_BATTERY_CAPACITY = 0x0106 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * List of connectors this EV may use
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @data_enum EvConnectorType
-     * @access VehiclePropertyAccess:READ
-     */
-    INFO_EV_CONNECTOR_TYPE = 0x0107 + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Fuel door location
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @data_enum PortLocationType
-     * @access VehiclePropertyAccess:READ
-     */
-    INFO_FUEL_DOOR_LOCATION = 0x0108 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * EV port location
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @data_enum PortLocationType
-     */
-    INFO_EV_PORT_LOCATION = 0x0109 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Driver's seat location
-     * VHAL implementations must ignore the areaId. Use VehicleArea:GLOBAL.
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @data_enum VehicleAreaSeat
-     * @access VehiclePropertyAccess:READ
-     */
-    INFO_DRIVER_SEAT = 0x010A + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Exterior dimensions of vehicle.
-     *
-     *  int32Values[0] = height
-     *  int32Values[1] = length
-     *  int32Values[2] = width
-     *  int32Values[3] = width including mirrors
-     *  int32Values[4] = wheel base
-     *  int32Values[5] = track width front
-     *  int32Values[6] = track width rear
-     *  int32Values[7] = curb to curb turning radius
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:MILLIMETER
-     */
-    INFO_EXTERIOR_DIMENSIONS = 0x010B + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Multiple EV port locations
-     *
-     * Implement this property if the vehicle has multiple EV ports.
-     * Port locations are defined in PortLocationType.
-     * For example, a car has one port in front left and one port in rear left:
-     *   int32Values[0] = PortLocationType::FRONT_LEFT
-     *   int32Values[0] = PortLocationType::REAR_LEFT
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @data_enum PortLocationType
-     */
-    INFO_MULTI_EV_PORT_LOCATIONS = 0x010C + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Current odometer value of the vehicle
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:KILOMETER
-     */
-    PERF_ODOMETER = 0x0204 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Speed of the vehicle
-     *
-     * The value must be positive when the vehicle is moving forward and negative when
-     * the vehicle is moving backward. This value is independent of gear value
-     * (CURRENT_GEAR or GEAR_SELECTION), for example, if GEAR_SELECTION is GEAR_NEUTRAL,
-     * PERF_VEHICLE_SPEED is positive when the vehicle is moving forward, negative when moving
-     * backward, and zero when not moving.
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:METER_PER_SEC
-     */
-    PERF_VEHICLE_SPEED = 0x0207 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Speed of the vehicle for displays
-     *
-     * Some cars display a slightly slower speed than the actual speed.  This is
-     * usually displayed on the speedometer.
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:METER_PER_SEC
-     */
-    PERF_VEHICLE_SPEED_DISPLAY = 0x0208 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Front bicycle model steering angle for vehicle
-     *
-     * Angle is in degrees.  Left is negative.
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:DEGREES
-     */
-    PERF_STEERING_ANGLE = 0x0209 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Rear bicycle model steering angle for vehicle
-     *
-     * Angle is in degrees.  Left is negative.
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:DEGREES
-     */
-    PERF_REAR_STEERING_ANGLE = 0x0210 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Temperature of engine coolant
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:CELSIUS
-     */
-    ENGINE_COOLANT_TEMP = 0x0301 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Engine oil level
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleOilLevel
-     */
-    ENGINE_OIL_LEVEL = 0x0303 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Temperature of engine oil
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:CELSIUS
-     */
-    ENGINE_OIL_TEMP = 0x0304 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Engine rpm
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:RPM
-     */
-    ENGINE_RPM = 0x0305 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Reports wheel ticks
-     *
-     * The first element in the vector is a reset count.  A reset indicates
-     * previous tick counts are not comparable with this and future ones.  Some
-     * sort of discontinuity in tick counting has occurred.
-     *
-     * The next four elements represent ticks for individual wheels in the
-     * following order: front left, front right, rear right, rear left.  All
-     * tick counts are cumulative.  Tick counts increment when the vehicle
-     * moves forward, and decrement when vehicles moves in reverse.  The ticks
-     * should be reset to 0 when the vehicle is started by the user.
-     *
-     *  int64Values[0] = reset count
-     *  int64Values[1] = front left ticks
-     *  int64Values[2] = front right ticks
-     *  int64Values[3] = rear right ticks
-     *  int64Values[4] = rear left ticks
-     *
-     * configArray is used to indicate the micrometers-per-wheel-tick value and
-     * which wheels are supported.  configArray is set as follows:
-     *
-     *  configArray[0], bits [0:3] = supported wheels.  Uses enum Wheel.
-     *  configArray[1] = micrometers per front left wheel tick
-     *  configArray[2] = micrometers per front right wheel tick
-     *  configArray[3] = micrometers per rear right wheel tick
-     *  configArray[4] = micrometers per rear left wheel tick
-     *
-     * NOTE:  If a wheel is not supported, its value shall always be set to 0.
-     *
-     * VehiclePropValue.timestamp must be correctly filled in.
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     */
-    WHEEL_TICK = 0x0306 + 0x10000000 + 0x01000000
-            + 0x00510000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64_VEC
-    /**
-     * Fuel remaining in the vehicle, in milliliters
-     *
-     * Value may not exceed INFO_FUEL_CAPACITY
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:MILLILITER
-     */
-    FUEL_LEVEL = 0x0307 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Fuel door open
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    FUEL_DOOR_OPEN = 0x0308 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * EV battery level in WH, if EV or hybrid
-     *
-     * Value may not exceed INFO_EV_BATTERY_CAPACITY
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:WH
-     */
-    EV_BATTERY_LEVEL = 0x0309 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * EV charge port open
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    EV_CHARGE_PORT_OPEN = 0x030A + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * EV charge port connected
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    EV_CHARGE_PORT_CONNECTED = 0x030B + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * EV instantaneous charge rate in milliwatts
-     *
-     * Positive value indicates battery is being charged.
-     * Negative value indicates battery being discharged.
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:MW
-     */
-    EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = 0x030C + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Range remaining
-     *
-     * Meters remaining of fuel and charge.  Range remaining shall account for
-     * all energy sources in a vehicle.  For example, a hybrid car's range will
-     * be the sum of the ranges based on fuel and battery.
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @unit VehicleUnit:METER
-     */
-    RANGE_REMAINING = 0x0308 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Tire pressure
-     *
-     * Each tires is identified by its areaConfig.areaId config and their
-     * minFloatValue/maxFloatValue are used to store OEM recommended pressure
-     * range.
-     * The Min value in the areaConfig data represents the lower bound of
-     * the recommended tire pressure.
-     * The Max value in the areaConfig data represents the upper bound of
-     * the recommended tire pressure.
-     * For example:
-     * The following areaConfig indicates the recommended tire pressure
-     * of left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL.
-     * .areaConfigs = {
-     *      VehicleAreaConfig {
-     *          .areaId = VehicleAreaWheel::LEFT_FRONT,
-     *          .minFloatValue = 200.0,
-     *          .maxFloatValue = 240.0,
-     *      }
-     * },
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:KILOPASCAL
-     */
-    TIRE_PRESSURE = 0x0309 + 0x10000000 + 0x07000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
-    /**
-     * Critically low tire pressure
-     *
-     * This property indicates the critically low pressure threshold for each tire.
-     * It indicates when it is time for tires to be replaced or fixed. The value
-     * must be less than or equal to minFloatValue in TIRE_PRESSURE.
-     * Minimum and maximum property values (that is, minFloatValue, maxFloatValue)
-     * are not applicable to this property.
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:KILOPASCAL
-     */
-    CRITICALLY_LOW_TIRE_PRESSURE = 0x030A + 0x10000000 + 0x07000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
-    /**
-     * Currently selected gear
-     *
-     * This is the gear selected by the user.
-     *
-     * Values in the config data must represent the list of supported gears
-     * for this vehicle.  For example, config data for an automatic transmission
-     * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_DRIVE,
-     * GEAR_1, GEAR_2,...} and for manual transmission the list must be
-     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleGear
-     */
-    GEAR_SELECTION = 0x0400 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Current gear. In non-manual case, selected gear may not
-     * match the current gear. For example, if the selected gear is GEAR_DRIVE,
-     * the current gear will be one of GEAR_1, GEAR_2 etc, which reflects
-     * the actual gear the transmission is currently running in.
-     *
-     * Values in the config data must represent the list of supported gears
-     * for this vehicle.  For example, config data for an automatic transmission
-     * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...}
-     * and for manual transmission the list must be
-     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the
-     * same as that of the supported gears reported in GEAR_SELECTION.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleGear
-     */
-    CURRENT_GEAR = 0x0401 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Parking brake state.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    PARKING_BRAKE_ON = 0x0402 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * Auto-apply parking brake.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    PARKING_BRAKE_AUTO_APPLY = 0x0403 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * Warning for fuel low level.
-     *
-     * This property corresponds to the low fuel warning on the dashboard.
-     * Once FUEL_LEVEL_LOW is set, it should not be cleared until more fuel is
-     * added to the vehicle.  This property may take into account all fuel
-     * sources for a vehicle - for example:
-     *
-     *   For a gas powered vehicle, this property is based soley on gas level.
-     *   For a battery powered vehicle, this property is based solely on battery level.
-     *   For a hybrid vehicle, this property may be based on the combination of gas and battery
-     *      levels, at the OEM's discretion.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    FUEL_LEVEL_LOW = 0x0405 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * Night mode
-     *
-     * True indicates that the night mode sensor has detected that the car cabin environment has
-     * low light. The platform could use this, for example, to enable appropriate UI for
-     * better viewing in dark or low light environments.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    NIGHT_MODE = 0x0407 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * State of the vehicles turn signals
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleTurnSignal
-     */
-    TURN_SIGNAL_STATE = 0x0408 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Represents ignition state
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleIgnitionState
-     */
-    IGNITION_STATE = 0x0409 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * ABS is active
-     *
-     * Set to true when ABS is active.  Reset to false when ABS is off.  This
-     * property may be intermittently set (pulsing) based on the real-time
-     * state of the ABS system.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    ABS_ACTIVE = 0x040A + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * Traction Control is active
-     *
-     * Set to true when traction control (TC) is active.  Reset to false when
-     * TC is off.  This property may be intermittently set (pulsing) based on
-     * the real-time state of the TC system.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    TRACTION_CONTROL_ACTIVE = 0x040B + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /*
-     * HVAC Properties
-     *
-     * Additional rules for mapping a zoned HVAC property (except
-     * HVAC_MAX_DEFROST_ON) to AreaIDs:
-     *  - Every seat in VehicleAreaSeat that is available in the car, must be
-     *    part of an AreaID in the AreaID array.
-     *
-     * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
-     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
-     *  temperature control units -- driver side and passenger side.
-     *   - A valid mapping set of AreaIDs for HVAC_TEMPERATURE_SET would be a
-     *     two element array:
-     *      - ROW_1_LEFT  | ROW_2_LEFT
-     *      - ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT
-     *   - An alternative mapping for the same hardware configuration would be:
-     *      - ROW_1_LEFT  | ROW_2_CENTER | ROW_2_LEFT
-     *      - ROW_1_RIGHT | ROW_2_RIGHT
-     *  The temperature controllers are assigned to the seats which they
-     *  "most influence", but every seat must be included exactly once. The
-     *  assignment of the center rear seat to the left or right AreaID may seem
-     *  arbitrary, but the inclusion of every seat in exactly one AreaID ensures
-     *  that the seats in the car are all expressed and that a "reasonable" way
-     *  to affect each seat is available.
-     *
-     * Example 2: A car has three seat rows with two seats in the front row (ROW_1_LEFT,
-     *  ROW_1_RIGHT) and three seats in the second (ROW_2_LEFT, ROW_2_CENTER,
-     *  ROW_2_RIGHT) and third rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). There
-     *  are three temperature control units -- driver side, passenger side, and rear.
-     *   - A reasonable way to map HVAC_TEMPERATURE_SET to AreaIDs is a three
-     *     element array:
-     *     - ROW_1_LEFT
-     *     - ROW_1_RIGHT
-     *     - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
-     *
-     *
-     * Fan speed setting
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_FAN_SPEED = 0x0500 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Fan direction setting
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleHvacFanDirection
-     */
-    HVAC_FAN_DIRECTION = 0x0501 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * HVAC current temperature.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:CELSIUS
-     */
-    HVAC_TEMPERATURE_CURRENT = 0x0502 + 0x10000000 + 0x05000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
-    /**
-     * HVAC, target temperature set.
-     *
-     * The configArray is used to indicate the valid values for HVAC in Fahrenheit and Celsius.
-     * Android might use it in the HVAC app UI.
-     * The configArray is set as follows:
-     *      configArray[0] = [the lower bound of the supported temperature in Celsius] * 10.
-     *      configArray[1] = [the upper bound of the supported temperature in Celsius] * 10.
-     *      configArray[2] = [the increment in Celsius] * 10.
-     *      configArray[3] = [the lower bound of the supported temperature in Fahrenheit] * 10.
-     *      configArray[4] = [the upper bound of the supported temperature in Fahrenheit] * 10.
-     *      configArray[5] = [the increment in Fahrenheit] * 10.
-     * For example, if the vehicle supports temperature values as:
-     *      [16.0, 16.5, 17.0 ,..., 28.0] in Celsius
-     *      [60.5, 61.5, 62.5 ,..., 85.5] in Fahrenheit.
-     * The configArray should be configArray = {160, 280, 5, 605, 825, 10}.
-     *
-     * If the vehicle supports HVAC_TEMPERATURE_VALUE_SUGGESTION, the application can use
-     * that property to get the suggested value before setting HVAC_TEMPERATURE_SET. Otherwise,
-     * the application may choose the value in HVAC_TEMPERATURE_SET configArray by itself.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @unit VehicleUnit:CELSIUS
-     */
-    HVAC_TEMPERATURE_SET = 0x0503 + 0x10000000 + 0x05000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
-    /**
-     * Fan-based defrost for designated window.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_DEFROSTER = 0x0504 + 0x10000000 + 0x03000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
-    /**
-     * On/off AC for designated areaId
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @config_flags Supported areaIds
-     */
-    HVAC_AC_ON = 0x0505 + 0x10000000 + 0x05000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
-    /**
-     * On/off max AC
-     *
-     * When MAX AC is on, the ECU may adjust the vent position, fan speed,
-     * temperature, etc as necessary to cool the vehicle as quickly as possible.
-     * Any parameters modified as a side effect of turning on/off the MAX AC
-     * parameter shall generate onPropertyEvent() callbacks to the VHAL.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_MAX_AC_ON = 0x0506 + 0x10000000 + 0x05000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
-    /**
-     * On/off max defrost
-     *
-     * When MAX DEFROST is on, the ECU may adjust the vent position, fan speed,
-     * temperature, etc as necessary to defrost the windows as quickly as
-     * possible.  Any parameters modified as a side effect of turning on/off
-     * the MAX DEFROST parameter shall generate onPropertyEvent() callbacks to
-     * the VHAL.
-     * The AreaIDs for HVAC_MAX_DEFROST_ON indicate MAX DEFROST can be controlled
-     * in the area.
-     * For example:
-     * areaConfig.areaId = {ROW_1_LEFT | ROW_1_RIGHT} indicates HVAC_MAX_DEFROST_ON
-     * only can be controlled for the front rows.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_MAX_DEFROST_ON = 0x0507 + 0x10000000 + 0x05000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
-    /**
-     * Recirculation on/off
-     *
-     * Controls the supply of exterior air to the cabin.  Recirc “on” means the
-     * majority of the airflow into the cabin is originating in the cabin.
-     * Recirc “off” means the majority of the airflow into the cabin is coming
-     * from outside the car.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_RECIRC_ON = 0x0508 + 0x10000000 + 0x05000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
-    /**
-     * Enable temperature coupling between areas.
-     *
-     * The AreaIDs for HVAC_DUAL_ON property shall contain a combination of
-     * HVAC_TEMPERATURE_SET AreaIDs that can be coupled together. If
-     * HVAC_TEMPERATURE_SET is mapped to AreaIDs [a_1, a_2, ..., a_n], and if
-     * HVAC_DUAL_ON can be enabled to couple a_i and a_j, then HVAC_DUAL_ON
-     * property must be mapped to [a_i | a_j]. Further, if a_k and a_l can also
-     * be coupled together separately then HVAC_DUAL_ON must be mapped to
-     * [a_i | a_j, a_k | a_l].
-     *
-     * Example: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
-     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
-     *  temperature control units -- driver side and passenger side -- which can
-     *  be optionally synchronized. This may be expressed in the AreaIDs this way:
-     *  - HVAC_TEMPERATURE_SET->[ROW_1_LEFT | ROW_2_LEFT, ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
-     *  - HVAC_DUAL_ON->[ROW_1_LEFT | ROW_2_LEFT | ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
-     *
-     * When the property is enabled, the ECU must synchronize the temperature
-     * for the affected areas. Any parameters modified as a side effect
-     * of turning on/off the DUAL_ON parameter shall generate
-     * onPropertyEvent() callbacks to the VHAL. In addition, if setting
-     * a temperature (i.e. driver's temperature) changes another temperature
-     * (i.e. front passenger's temperature), then the appropriate
-     * onPropertyEvent() callbacks must be generated.  If a user changes a
-     * temperature that breaks the coupling (e.g. setting the passenger
-     * temperature independently) then the VHAL must send the appropriate
-     * onPropertyEvent() callbacks (i.e. HVAC_DUAL_ON = false,
-     * HVAC_TEMPERATURE_SET[AreaID] = xxx, etc).
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_DUAL_ON = 0x0509 + 0x10000000 + 0x05000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
-    /**
-     * On/off automatic mode
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_AUTO_ON = 0x050A + 0x10000000 + 0x05000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
-    /**
-     * Seat heating/cooling
-     *
-     * Negative values indicate cooling.
-     * 0 indicates off.
-     * Positive values indicate heating.
-     *
-     * Some vehicles may have multiple levels of heating and cooling. The
-     * min/max range defines the allowable range and number of steps in each
-     * direction.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_SEAT_TEMPERATURE = 0x050B + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Side Mirror Heat
-     *
-     * Increasing values denote higher heating levels for side mirrors.
-     * The Max value in the config data represents the highest heating level.
-     * The Min value in the config data MUST be zero and indicates no heating.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_SIDE_MIRROR_HEAT = 0x050C + 0x10000000 + 0x04000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
-    /**
-     * Steering Wheel Heating/Cooling
-     *
-     * Sets the amount of heating/cooling for the steering wheel
-     * config data Min and Max MUST be set appropriately.
-     * Positive value indicates heating.
-     * Negative value indicates cooling.
-     * 0 indicates temperature control is off.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_STEERING_WHEEL_HEAT = 0x050D + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Temperature units for display
-     *
-     * Indicates whether the vehicle is displaying temperature to the user as
-     * Celsius or Fahrenheit.
-     * VehiclePropConfig.configArray is used to indicate the supported temperature display units.
-     * For example: configArray[0] = CELSIUS
-     *              configArray[1] = FAHRENHEIT
-     *
-     * This parameter MAY be used for displaying any HVAC temperature in the system.
-     * Values must be one of VehicleUnit::CELSIUS or VehicleUnit::FAHRENHEIT
-     * Note that internally, all temperatures are represented in floating point Celsius.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleUnit
-     */
-    HVAC_TEMPERATURE_DISPLAY_UNITS = 0x050E + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Actual fan speed
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    HVAC_ACTUAL_FAN_SPEED_RPM = 0x050F + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Represents global power state for HVAC. Setting this property to false
-     * MAY mark some properties that control individual HVAC features/subsystems
-     * to UNAVAILABLE state. Setting this property to true MAY mark some
-     * properties that control individual HVAC features/subsystems to AVAILABLE
-     * state (unless any/all of them are UNAVAILABLE on their own individual
-     * merits).
-     *
-     * [Definition] HvacPower_DependentProperties: Properties that need HVAC to be
-     *   powered on in order to enable their functionality. For example, in some cars,
-     *   in order to turn on the AC, HVAC must be powered on first.
-     *
-     * HvacPower_DependentProperties list must be set in the
-     * VehiclePropConfig.configArray. HvacPower_DependentProperties must only contain
-     * properties that are associated with VehicleArea:SEAT. Properties that are not
-     * associated with VehicleArea:SEAT, for example, HVAC_DEFROSTER, must never
-     * depend on HVAC_POWER_ON property and must never be part of
-     * HvacPower_DependentProperties list.
-     *
-     * AreaID mapping for HVAC_POWER_ON property must contain all AreaIDs that
-     * HvacPower_DependentProperties are mapped to.
-     *
-     * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three back
-     *  seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). If the HVAC features (AC,
-     *  Temperature etc.) throughout the car are dependent on a single HVAC power
-     *  controller then HVAC_POWER_ON must be mapped to
-     *  [ROW_1_LEFT | ROW_1_RIGHT | ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT].
-     *
-     * Example 2: A car has two seats in the front row (ROW_1_LEFT, ROW_1_RIGHT) and
-     *   three seats in the second (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT) and third
-     *   rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). If the car has temperature
-     *   controllers in the front row which can operate entirely independently of
-     *   temperature controllers in the back of the vehicle, then HVAC_POWER_ON
-     *   must be mapped to a two element array:
-     *   - ROW_1_LEFT | ROW_1_RIGHT
-     *   - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_POWER_ON = 0x0510 + 0x10000000 + 0x05000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
-    /**
-     * Fan Positions Available
-     *
-     * This is a bit mask of fan positions available for the zone.  Each
-     * available fan direction is denoted by a separate entry in the vector.  A
-     * fan direction may have multiple bits from vehicle_hvac_fan_direction set.
-     * For instance, a typical car may have the following fan positions:
-     *   - FAN_DIRECTION_FACE (0x1)
-     *   - FAN_DIRECTION_FLOOR (0x2)
-     *   - FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR (0x3)
-     *   - FAN_DIRECTION_DEFROST (0x4)
-     *   - FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST (0x6)
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleHvacFanDirection
-     */
-    HVAC_FAN_DIRECTION_AVAILABLE = 0x0511 + 0x10000000 + 0x05000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32_VEC
-    /**
-     * Automatic recirculation on/off
-     *
-     * When automatic recirculation is ON, the HVAC system may automatically
-     * switch to recirculation mode if the vehicle detects poor incoming air
-     * quality.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_AUTO_RECIRC_ON = 0x0512 + 0x10000000 + 0x05000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
-    /**
-     * Seat ventilation
-     *
-     * 0 indicates off.
-     * Positive values indicates ventilation level.
-     *
-     * Used by HVAC apps and Assistant to enable, change, or read state of seat
-     * ventilation.  This is different than seating cooling. It can be on at the
-     * same time as cooling, or not.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_SEAT_VENTILATION = 0x0513 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Electric defrosters' status
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_ELECTRIC_DEFROSTER_ON = 0x0514 + 0x10000000 + 0x03000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
-    /**
-     * Suggested values for setting HVAC temperature.
-     *
-     * Implement the property to help applications understand the closest supported temperature
-     * value in Celsius or Fahrenheit.
-     *
-     *      floatValues[0] = the requested value that an application wants to set a temperature to.
-     *      floatValues[1] = the unit for floatValues[0]. It should be one of
-     *                       {VehicleUnit:CELSIUS, VehicleUnit:FAHRENHEIT}.
-     *      floatValues[2] = the value OEMs suggested in CELSIUS. This value is not included
-     *                       in the request.
-     *      floatValues[3] = the value OEMs suggested in FAHRENHEIT. This value is not included
-     *                       in the request.
-     *
-     * An application calls set(VehiclePropValue propValue) with the requested value and unit for
-     * the value. OEMs need to return the suggested values in floatValues[2] and floatValues[3] by
-     * onPropertyEvent() callbacks.
-     *
-     * For example, when a user uses the voice assistant to set HVAC temperature to 66.2 in
-     * Fahrenheit.
-     * First, an application will set this property with the value
-     * [66.2, (float)VehicleUnit:FAHRENHEIT,0,0].
-     * If OEMs suggest to set 19.0 in Celsius or 66.5 in Fahrenheit for user's request, then VHAL
-     * must generate a callback with property value
-     * [66.2, (float)VehicleUnit:FAHRENHEIT, 19.0, 66.5]. After the voice assistant gets the
-     * callback, it will inform the user and set HVAC temperature to the suggested value.
-     *
-     * Another example, an application receives 21 Celsius as the current temperature value by
-     * querying HVC_TEMPERATURE_SET. But the application wants to know what value is displayed on
-     * the car's UI in Fahrenheit.
-     * For this, the application sets the property to [21, (float)VehicleUnit:CELSIUS, 0, 0]. If
-     * the suggested value by the OEM for 21 Celsius is 70 Fahrenheit, then VHAL must generate a
-     * callback with property value [21, (float)VehicleUnit:CELSIUS, 21.0, 70.0].
-     * In this case, the application can know that the value is 70.0 Fahrenheit in the car’s UI.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    HVAC_TEMPERATURE_VALUE_SUGGESTION = 0x0515 + 0x10000000 + 0x01000000
-            + 0x00610000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT_VEC
-    /**
-     * Distance units for display
-     *
-     * Indicates which units the car is using to display distances to the user. Eg. Mile, Meter
-     * Kilometer.
-     *
-     * Distance units are defined in VehicleUnit.
-     * VehiclePropConfig.configArray is used to indicate the supported distance display units.
-     * For example: configArray[0] = METER
-     *              configArray[1] = KILOMETER
-     *              configArray[2] = MILE
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleUnit
-     */
-    DISTANCE_DISPLAY_UNITS = 0x0600 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Fuel volume units for display
-     *
-     * Indicates which units the car is using to display fuel volume to the user. Eg. Liter or
-     * Gallon.
-     *
-     * VehiclePropConfig.configArray is used to indicate the supported fuel volume display units.
-     * Volume units are defined in VehicleUnit.
-     * For example: configArray[0] = LITER
-     *              configArray[1] = GALLON
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleUnit
-     */
-    FUEL_VOLUME_DISPLAY_UNITS = 0x0601 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Tire pressure units for display
-     *
-     * Indicates which units the car is using to display tire pressure to the user. Eg. PSI, Bar or
-     * Kilopascal.
-     *
-     * VehiclePropConfig.configArray is used to indicate the supported pressure display units.
-     * Pressure units are defined in VehicleUnit.
-     * For example: configArray[0] = KILOPASCAL
-     *              configArray[1] = PSI
-     *              configArray[2] = BAR
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleUnit
-     */
-    TIRE_PRESSURE_DISPLAY_UNITS = 0x0602 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * EV battery units for display
-     *
-     * Indicates which units the car is using to display EV battery information to the user. Eg.
-     * watt-hours(Wh), kilowatt-hours(kWh) or ampere-hours(Ah).
-     *
-     * VehiclePropConfig.configArray is used to indicate the supported electrical energy units.
-     * Electrical energy units are defined in VehicleUnit.
-     * For example: configArray[0] = WATT_HOUR
-     *              configArray[1] = AMPERE_HOURS
-     *              configArray[2] = KILOWATT_HOUR
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleUnit
-     */
-    EV_BATTERY_DISPLAY_UNITS = 0x0603 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Fuel consumption units for display
-     *
-     * Indicates type of units the car is using to display fuel consumption information to user
-     * True indicates units are distance over volume such as MPG.
-     * False indicates units are volume over distance such as L/100KM.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 0x0604 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * Speed units for display
-     *
-     * Indicates type of units the car is using to display speed to user. Eg. m/s, km/h, or mph.
-     *
-     * VehiclePropConfig.configArray is used to indicate the supported speed display units.
-     * Pressure units are defined in VehicleUnit.
-     * For example: configArray[0] = METER_PER_SEC
-     *              configArray[1] = MILES_PER_HOUR
-     *              configArray[2] = KILOMETERS_PER_HOUR
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Current date and time suggestion for the Car, encoded as Epoch time
-     * (in milliseconds). This value denotes the number of milliseconds seconds
-     * that have elapsed since 1/1/1970 UTC.
-     *
-     * This property signals a change in CarTime to Android. If the property is supported, VHAL
-     * must report the most accurate current CarTime when this property is read, and publish a
-     * change to this property when the CarTime value has changed. An on-change event for this
-     * property must be published when CarTime changes for any reason other than the natural elapse
-     * of time (time delta smaller than 500ms should not trigger an on change event). Android will
-     * read and subscribe to this property to fetch time from VHAL. This can be useful to
-     * synchronize Android's time with other vehicle systems (dash clock etc).
-     *     int64Values[0] = provided Epoch time (in milliseconds)
-     *
-     * Whenever a new Value for the property is received, AAOS will create
-     * and send an "ExternalTimeSuggestion" to the "TimeDetectorService".
-     * If other sources do not have a higher priority, Android will use this
-     * to set the system time. For information on how to adjust time source
-     * priorities and how time suggestions are handled (including how Android
-     * handles gitter, drift, and minimum resolution) see Time Detector Service
-     * documentation.
-     *
-     * Note that the property may take >0 ms to get propagated through the stack
-     * and, having a timestamped property helps reduce any time drift. So,
-     * for all reads to the property, the timestamp can be used to negate this
-     * drift:
-     *     drift = elapsedTime - PropValue.timestamp
-     *     effectiveTime = PropValue.value.int64Values[0] + drift
-     *
-     * It is strongly recommended that this property must not be used to retrieve
-     * time from ECUs using protocols (GNSS, NTP, Telephony etc). Since these
-     * protocols are already supported by Android, it is recommended to use
-     * Android’s own systems for them instead of wiring those through the VHAL
-     * using this property.
-     *
-     * WARNING: The value available through this property should not be dependent
-     * on value written by Android to ANDROID_EPOCH_TIME property in any way.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_ONLY
-     * @unit VehicleUnit:MILLI_SECS
-     */
-    EXTERNAL_CAR_TIME = 0x0608 + 0x10000000 // VehiclePropertyGroup:SYSTEM
-            + 0x01000000 // VehicleArea:GLOBAL
-            + 0x00500000, // VehiclePropertyType:INT64
-    /**
-     * Current date and time, encoded as Epoch time (in milliseconds).
-     * This value denotes the number of milliseconds seconds that have
-     * elapsed since 1/1/1970 UTC.
-     *
-     * CarServices will write to this value to give VHAL the Android system's
-     * time, if the VHAL supports this property. This can be useful to
-     * synchronize other vehicle systems (dash clock etc) with Android's time.
-     *
-     * AAOS writes to this property once during boot, and
-     * will thereafter write only when some time-source changes are propagated.
-     * AAOS will fill in VehiclePropValue.timestamp correctly.
-     * Note that AAOS will not send updates for natural elapse of time.
-     *     int64Values[0] = provided Unix time (in milliseconds)
-     *
-     * Note that the property may take >0 ms to get propagated through the stack
-     * and, having a timestamped property helps reduce any time drift. So,
-     * for all writes to the property, the timestamp can be used to negate this
-     * drift:
-     *     drift = elapsedTime - PropValue.timestamp
-     *     effectiveTime = PropValue.value.int64Values[0] + drift
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:WRITE_ONLY
-     * @unit VehicleUnit:MILLI_SECS
-     */
-    ANDROID_EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000
-            + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
-    /**
-     * External encryption binding seed.
-     *
-     * This value is mixed with the local key storage encryption key.
-     * This property holds 16 bytes, and is expected to be persisted on an ECU separate from
-     * the IVI. The property is initially set by AAOS, who generates it using a CSRNG.
-     * AAOS will then read the property on subsequent boots. The binding seed is expected to be
-     * reliably persisted. Any loss of the seed results in a factory reset of the IVI.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    STORAGE_ENCRYPTION_BINDING_SEED = 0x0607 + 0x10000000 + 0x01000000
-            + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
-    /**
-     * Outside temperature
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:CELSIUS
-     */
-    ENV_OUTSIDE_TEMPERATURE = 0x0703 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-    /**
-     * Property to control power state of application processor
-     *
-     * It is assumed that AP's power state is controlled by a separate power
-     * controller.
-     *
-     * For configuration information, VehiclePropConfig.configArray can have bit flag combining
-     * values in VehicleApPowerStateConfigFlag.
-     *
-     *   int32Values[0] : VehicleApPowerStateReq enum value
-     *   int32Values[1] : additional parameter relevant for each state,
-     *                    0 if not used.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    AP_POWER_STATE_REQ = 0x0A00 + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Property to report power state of application processor
-     *
-     * It is assumed that AP's power state is controller by separate power
-     * controller.
-     *
-     *   int32Values[0] : VehicleApPowerStateReport enum value
-     *   int32Values[1] : Time in ms to wake up, if necessary.  Otherwise 0.
-
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    AP_POWER_STATE_REPORT = 0x0A01 + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Property to report bootup reason for the current power on. This is a
-     * static property that will not change for the whole duration until power
-     * off. For example, even if user presses power on button after automatic
-     * power on with door unlock, bootup reason must stay with
-     * VehicleApPowerBootupReason#USER_UNLOCK.
-     *
-     * int32Values[0] must be VehicleApPowerBootupReason.
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     */
-    AP_POWER_BOOTUP_REASON = 0x0A02 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Property to represent brightness of the display. Some cars have single
-     * control for the brightness of all displays and this property is to share
-     * change in that control.
-     *
-     * If this is writable, android side can set this value when user changes
-     * display brightness from Settings. If this is read only, user may still
-     * change display brightness from Settings, but that must not be reflected
-     * to other displays.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    DISPLAY_BRIGHTNESS = 0x0A03 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Property to feed H/W input events to android
-     *
-     * int32Values[0] : action defined by VehicleHwKeyInputAction
-     * int32Values[1] : key code, must use standard android key code
-     * int32Values[2] : target display defined in VehicleDisplay. Events not
-     *                  tied to specific display must be sent to
-     *                  VehicleDisplay#MAIN.
-     * int32Values[3] : [optional] Number of ticks. The value must be equal or
-     *                  greater than 1. When omitted, Android will default to 1.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @config_flags
-     */
-    HW_KEY_INPUT = 0x0A10 + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Property to feed H/W rotary events to android
-     *
-     * int32Values[0] : RotaryInputType identifying which rotary knob rotated
-     * int32Values[1] : number of detents (clicks), positive for clockwise,
-     *                  negative for counterclockwise
-     * int32Values[2] : target display defined in VehicleDisplay. Events not
-     *                  tied to specific display must be sent to
-     *                  VehicleDisplay#MAIN.
-     * int32values[3 .. 3 + abs(number of detents) - 2]:
-     *                  nanosecond deltas between pairs of consecutive detents,
-     *                  if the number of detents is > 1 or < -1
-     *
-     * VehiclePropValue.timestamp: when the rotation occurred. If the number of
-     *                             detents is > 1 or < -1, this is when the
-     *                             first detent of rotation occurred.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @data_enum RotaryInputType
-     * @access VehiclePropertyAccess:READ
-     */
-    HW_ROTARY_INPUT = 0x0A20 + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Defines a custom OEM partner input event.
-     *
-     * This input event must be used by OEM partners who wish to propagate events not supported
-     * by Android. It is composed by an array of int32 values only.
-     *
-     * The Android properties are:
-     *
-     * int32Values[0] : Input code identifying the function representing this event. Valid event
-     *                  types are defined by CustomInputType.CUSTOM_EVENT_F1 up to
-     *                  CustomInputType.CUSTOM_EVENT_F10. They represent the custom event to be
-     *                  defined by OEM partners.
-     * int32Values[1] : target display type defined in VehicleDisplay. Events not tied to specific
-     *                  display must be sent to VehicleDisplay#MAIN.
-     * int32Values[2] : repeat counter, if 0 then event is not repeated. Values 1 or above means
-     *                  how many times this event repeated.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @data_enum CustomInputType
-     * @access VehiclePropertyAccess:READ
-     */
-    HW_CUSTOM_INPUT = 0X0A30 + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /***************************************************************************
-     * Most Car Cabin properties have both a POSition and MOVE parameter.  These
-     * are used to control the various movements for seats, doors, and windows
-     * in a vehicle.
-     *
-     * A POS parameter allows the user to set the absolution position.  For
-     * instance, for a door, 0 indicates fully closed and max value indicates
-     * fully open.  Thus, a value halfway between min and max must indicate
-     * the door is halfway open.
-     *
-     * A MOVE parameter moves the device in a particular direction.  The sign
-     * indicates direction, and the magnitude indicates speed (if multiple
-     * speeds are available).  For a door, a move of -1 will close the door, and
-     * a move of +1 will open it.  Once a door reaches the limit of open/close,
-     * the door should automatically stop moving.  The user must NOT need to
-     * send a MOVE(0) command to stop the door at the end of its range.
-     **************************************************************************/
-
-    /**
-     * Door position
-     *
-     * This is an integer in case a door may be set to a particular position.
-     * Max value indicates fully open, min value (0) indicates fully closed.
-     *
-     * Some vehicles (minivans) can open the door electronically.  Hence, the
-     * ability to write this property.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    DOOR_POS = 0x0B00 + 0x10000000 + 0x06000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
-    /**
-     * Door move
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    DOOR_MOVE = 0x0B01 + 0x10000000 + 0x06000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
-    /**
-     * Door lock
-     *
-     * 'true' indicates door is locked
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    DOOR_LOCK = 0x0B02 + 0x10000000 + 0x06000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:BOOLEAN
-    /**
-     * Mirror Z Position
-     *
-     * Positive value indicates tilt upwards, negative value is downwards
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    MIRROR_Z_POS = 0x0B40 + 0x10000000 + 0x04000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
-    /**
-     * Mirror Z Move
-     *
-     * Positive value indicates tilt upwards, negative value is downwards
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    MIRROR_Z_MOVE = 0x0B41 + 0x10000000 + 0x04000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
-    /**
-     * Mirror Y Position
-     *
-     * Positive value indicate tilt right, negative value is left
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    MIRROR_Y_POS = 0x0B42 + 0x10000000 + 0x04000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
-    /**
-     * Mirror Y Move
-     *
-     * Positive value indicate tilt right, negative value is left
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    MIRROR_Y_MOVE = 0x0B43 + 0x10000000 + 0x04000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
-    /**
-     * Mirror Lock
-     *
-     * True indicates mirror positions are locked and not changeable
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    MIRROR_LOCK = 0x0B44 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * Mirror Fold
-     *
-     * True indicates mirrors are folded
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    MIRROR_FOLD = 0x0B45 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * Seat memory select
-     *
-     * This parameter selects the memory preset to use to select the seat
-     * position. The minValue is always 0, and the maxValue determines the
-     * number of seat positions available.
-     *
-     * For instance, if the driver's seat has 3 memory presets, the maxValue
-     * will be 3. When the user wants to select a preset, the desired preset
-     * number (1, 2, or 3) is set.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:WRITE
-     */
-    SEAT_MEMORY_SELECT = 0x0B80 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat memory set
-     *
-     * This setting allows the user to save the current seat position settings
-     * into the selected preset slot.  The maxValue for each seat position
-     * must match the maxValue for SEAT_MEMORY_SELECT.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:WRITE
-     */
-    SEAT_MEMORY_SET = 0x0B81 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seatbelt buckled
-     *
-     * True indicates belt is buckled.
-     *
-     * Write access indicates automatic seat buckling capabilities.  There are
-     * no known cars at this time, but you never know...
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_BELT_BUCKLED = 0x0B82 + 0x10000000 + 0x05000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
-    /**
-     * Seatbelt height position
-     *
-     * Adjusts the shoulder belt anchor point.
-     * Max value indicates highest position
-     * Min value indicates lowest position
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_BELT_HEIGHT_POS = 0x0B83 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seatbelt height move
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_BELT_HEIGHT_MOVE = 0x0B84 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat fore/aft position
-     *
-     * Sets the seat position forward (closer to steering wheel) and backwards.
-     * Max value indicates closest to wheel, min value indicates most rearward
-     * position.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_FORE_AFT_POS = 0x0B85 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat fore/aft move
-     *
-     * Moves the seat position forward and aft.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_FORE_AFT_MOVE = 0x0B86 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat backrest angle 1 position
-     *
-     * Backrest angle 1 is the actuator closest to the bottom of the seat.
-     * Max value indicates angling forward towards the steering wheel.
-     * Min value indicates full recline.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_BACKREST_ANGLE_1_POS = 0x0B87 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat backrest angle 1 move
-     *
-     * Moves the backrest forward or recline.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_BACKREST_ANGLE_1_MOVE = 0x0B88 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat backrest angle 2 position
-     *
-     * Backrest angle 2 is the next actuator up from the bottom of the seat.
-     * Max value indicates angling forward towards the steering wheel.
-     * Min value indicates full recline.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_BACKREST_ANGLE_2_POS = 0x0B89 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat backrest angle 2 move
-     *
-     * Moves the backrest forward or recline.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_BACKREST_ANGLE_2_MOVE = 0x0B8A + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat height position
-     *
-     * Sets the seat height.
-     * Max value indicates highest position.
-     * Min value indicates lowest position.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_HEIGHT_POS = 0x0B8B + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat height move
-     *
-     * Moves the seat height.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_HEIGHT_MOVE = 0x0B8C + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat depth position
-     *
-     * Sets the seat depth, distance from back rest to front edge of seat.
-     * Max value indicates longest depth position.
-     * Min value indicates shortest position.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_DEPTH_POS = 0x0B8D + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat depth move
-     *
-     * Adjusts the seat depth.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_DEPTH_MOVE = 0x0B8E + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat tilt position
-     *
-     * Sets the seat tilt.
-     * Max value indicates front edge of seat higher than back edge.
-     * Min value indicates front edge of seat lower than back edge.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_TILT_POS = 0x0B8F + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat tilt move
-     *
-     * Tilts the seat.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_TILT_MOVE = 0x0B90 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Lumber fore/aft position
-     *
-     * Pushes the lumbar support forward and backwards
-     * Max value indicates most forward position.
-     * Min value indicates most rearward position.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_LUMBAR_FORE_AFT_POS = 0x0B91 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Lumbar fore/aft move
-     *
-     * Adjusts the lumbar support.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_LUMBAR_FORE_AFT_MOVE = 0x0B92 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Lumbar side support position
-     *
-     * Sets the amount of lateral lumbar support.
-     * Max value indicates widest lumbar setting (i.e. least support)
-     * Min value indicates thinnest lumbar setting.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_LUMBAR_SIDE_SUPPORT_POS = 0x0B93 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Lumbar side support move
-     *
-     * Adjusts the amount of lateral lumbar support.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 0x0B94 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Headrest height position
-     *
-     * Sets the headrest height.
-     * Max value indicates tallest setting.
-     * Min value indicates shortest setting.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_HEADREST_HEIGHT_POS = 0x0B95 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Headrest height move
-     *
-     * Moves the headrest up and down.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_HEADREST_HEIGHT_MOVE = 0x0B96 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Headrest angle position
-     *
-     * Sets the angle of the headrest.
-     * Max value indicates most upright angle.
-     * Min value indicates shallowest headrest angle.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_HEADREST_ANGLE_POS = 0x0B97 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Headrest angle move
-     *
-     * Adjusts the angle of the headrest
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_HEADREST_ANGLE_MOVE = 0x0B98 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Headrest fore/aft position
-     *
-     * Adjusts the headrest forwards and backwards.
-     * Max value indicates position closest to front of car.
-     * Min value indicates position closest to rear of car.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_HEADREST_FORE_AFT_POS = 0x0B99 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Headrest fore/aft move
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SEAT_HEADREST_FORE_AFT_MOVE = 0x0B9A + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Seat Occupancy
-     *
-     * Indicates whether a particular seat is occupied or not, to the best of the car's ability
-     * to determine. Valid values are from the VehicleSeatOccupancyState enum.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleSeatOccupancyState
-     */
-    SEAT_OCCUPANCY = 0x0BB0 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Window Position
-     *
-     * Min = window up / closed
-     * Max = window down / open
-     *
-     * For a window that may open out of plane (i.e. vent mode of sunroof) this
-     * parameter will work with negative values as follows:
-     *  Max = sunroof completely open
-     *  0 = sunroof closed.
-     *  Min = sunroof vent completely open
-     *
-     *  Note that in this mode, 0 indicates the window is closed.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    WINDOW_POS = 0x0BC0 + 0x10000000 + 0x03000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-    /**
-     * Window Move
-     *
-     * Max = Open the window as fast as possible
-     * Min = Close the window as fast as possible
-     * Magnitude denotes relative speed.  I.e. +2 is faster than +1 in closing
-     * the window.
-     *
-     * For a window that may open out of plane (i.e. vent mode of sunroof) this
-     * parameter will work as follows:
-     *
-     * If sunroof is open:
-     *   Max = open the sunroof further, automatically stop when fully open.
-     *   Min = close the sunroof, automatically stop when sunroof is closed.
-     *
-     * If vent is open:
-     *   Max = close the vent, automatically stop when vent is closed.
-     *   Min = open the vent further, automatically stop when vent is fully open.
-     *
-     * If sunroof is in the closed position:
-     *   Max = open the sunroof, automatically stop when sunroof is fully open.
-     *   Min = open the vent, automatically stop when vent is fully open.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    WINDOW_MOVE = 0x0BC1 + 0x10000000 + 0x03000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-    /**
-     * Window Lock
-     *
-     * True indicates windows are locked and can't be moved.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    WINDOW_LOCK = 0x0BC4 + 0x10000000 + 0x03000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
-    /**
-     * Vehicle Maps Service (VMS) message
-     *
-     * This property uses MIXED data to communicate vms messages.
-     *
-     * Its contents are to be interpreted as follows:
-     * the indices defined in VmsMessageIntegerValuesIndex are to be used to
-     * read from int32Values;
-     * bytes is a serialized VMS message as defined in the vms protocol
-     * which is opaque to the framework;
-     *
-     * IVehicle#get must always return StatusCode::NOT_AVAILABLE.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    VEHICLE_MAP_SERVICE = 0x0C00 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * OBD2 Live Sensor Data
-     *
-     * Reports a snapshot of the current (live) values of the OBD2 sensors available.
-     *
-     * The configArray is set as follows:
-     *   configArray[0] = number of vendor-specific integer-valued sensors
-     *   configArray[1] = number of vendor-specific float-valued sensors
-     *
-     * The values of this property are to be interpreted as in the following example.
-     * Considering a configArray = {2,3}
-     * int32Values must be a vector containing Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 2
-     * elements (that is, 33 elements);
-     * floatValues must be a vector containing Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 3
-     * elements (that is, 73 elements);
-     *
-     * It is possible for each frame to contain a different subset of sensor values, both system
-     * provided sensors, and vendor-specific ones. In order to support that, the bytes element
-     * of the property value is used as a bitmask,.
-     *
-     * bytes must have a sufficient number of bytes to represent the total number of possible
-     * sensors (in this case, 14 bytes to represent 106 possible values); it is to be read as
-     * a contiguous bitmask such that each bit indicates the presence or absence of a sensor
-     * from the frame, starting with as many bits as the size of int32Values, immediately
-     * followed by as many bits as the size of floatValues.
-     *
-     * For example, should bytes[0] = 0x4C (0b01001100) it would mean that:
-     *   int32Values[0 and 1] are not valid sensor values
-     *   int32Values[2 and 3] are valid sensor values
-     *   int32Values[4 and 5] are not valid sensor values
-     *   int32Values[6] is a valid sensor value
-     *   int32Values[7] is not a valid sensor value
-     * Should bytes[5] = 0x61 (0b01100001) it would mean that:
-     *   int32Values[32] is a valid sensor value
-     *   floatValues[0 thru 3] are not valid sensor values
-     *   floatValues[4 and 5] are valid sensor values
-     *   floatValues[6] is not a valid sensor value
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    OBD2_LIVE_FRAME = 0x0D00 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * OBD2 Freeze Frame Sensor Data
-     *
-     * Reports a snapshot of the value of the OBD2 sensors available at the time that a fault
-     * occurred and was detected.
-     *
-     * A configArray must be provided with the same meaning as defined for OBD2_LIVE_FRAME.
-     *
-     * The values of this property are to be interpreted in a similar fashion as those for
-     * OBD2_LIVE_FRAME, with the exception that the stringValue field may contain a non-empty
-     * diagnostic troubleshooting code (DTC).
-     *
-     * A IVehicle#get request of this property must provide a value for int64Values[0].
-     * This will be interpreted as the timestamp of the freeze frame to retrieve. A list of
-     * timestamps can be obtained by a IVehicle#get of OBD2_FREEZE_FRAME_INFO.
-     *
-     * Should no freeze frame be available at the given timestamp, a response of NOT_AVAILABLE
-     * must be returned by the implementation. Because vehicles may have limited storage for
-     * freeze frames, it is possible for a frame request to respond with NOT_AVAILABLE even if
-     * the associated timestamp has been recently obtained via OBD2_FREEZE_FRAME_INFO.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    OBD2_FREEZE_FRAME = 0x0D01 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * OBD2 Freeze Frame Information
-     *
-     * This property describes the current freeze frames stored in vehicle
-     * memory and available for retrieval via OBD2_FREEZE_FRAME.
-     *
-     * The values are to be interpreted as follows:
-     * each element of int64Values must be the timestamp at which a a fault code
-     * has been detected and the corresponding freeze frame stored, and each
-     * such element can be used as the key to OBD2_FREEZE_FRAME to retrieve
-     * the corresponding freeze frame.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    OBD2_FREEZE_FRAME_INFO = 0x0D02 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * OBD2 Freeze Frame Clear
-     *
-     * This property allows deletion of any of the freeze frames stored in
-     * vehicle memory, as described by OBD2_FREEZE_FRAME_INFO.
-     *
-     * The configArray is set as follows:
-     *  configArray[0] = 1 if the implementation is able to clear individual freeze frames
-     *                   by timestamp, 0 otherwise
-     *
-     * IVehicle#set of this property is to be interpreted as follows:
-     *   if int64Values contains no elements, then all frames stored must be cleared;
-     *   if int64Values contains one or more elements, then frames at the timestamps
-     *   stored in int64Values must be cleared, and the others not cleared. Should the
-     *   vehicle not support selective clearing of freeze frames, this latter mode must
-     *   return NOT_AVAILABLE.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:WRITE
-     */
-    OBD2_FREEZE_FRAME_CLEAR = 0x0D03 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * Headlights State
-     *
-     * Return the current state of headlights.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleLightState
-     */
-    HEADLIGHTS_STATE = 0x0E00 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * High beam lights state
-     *
-     * Return the current state of high beam lights.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleLightState
-     */
-    HIGH_BEAM_LIGHTS_STATE = 0x0E01 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Fog light state
-     *
-     * Return the current state of fog lights.
-     *
-     * If the car has both front and rear fog lights:
-     *   If front and rear fog lights can only be controlled together: FOG_LIGHTS_STATE must be
-     *   implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must not be implemented.
-     *
-     *   If the front and rear fog lights can only be controlled independently: FOG_LIGHTS_STATE
-     *   must not be implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must be
-     *   implemented.
-     *
-     * If the car has only front fog lights:
-     * Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented and not both.
-     * REAR_FOG_LIGHTS_STATE must not be implemented.
-     *
-     * If the car has only rear fog lights:
-     * Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented and not both.
-     * FRONT_FOG_LIGHTS_STATE must not be implemented.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleLightState
-     */
-    FOG_LIGHTS_STATE = 0x0E02 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Hazard light status
-     *
-     * Return the current status of hazard lights.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleLightState
-     */
-    HAZARD_LIGHTS_STATE = 0x0E03 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Headlight switch
-     *
-     * The setting that the user wants.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleLightSwitch
-     */
-    HEADLIGHTS_SWITCH = 0x0E10 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * High beam light switch
-     *
-     * The setting that the user wants.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleLightSwitch
-     */
-    HIGH_BEAM_LIGHTS_SWITCH = 0x0E11 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Fog light switch
-     *
-     * The setting that the user wants.
-     *
-     * If the car has both front and rear fog lights:
-     *   If front and rear fog lights can only be controlled together: FOG_LIGHTS_SWITCH must be
-     *   implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must not be implemented.
-     *
-     *   If the front and rear fog lights can only be controlled independently: FOG_LIGHTS_SWITCH
-     *   must not be implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must be
-     *   implemented.
-     *
-     * If the car has only front fog lights:
-     * Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented and not both.
-     * REAR_FOG_LIGHTS_SWITCH must not be implemented.
-     *
-     * If the car has only rear fog lights:
-     * Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented and not both.
-     * FRONT_FOG_LIGHTS_SWITCH must not be implemented.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleLightSwitch
-     */
-    FOG_LIGHTS_SWITCH = 0x0E12 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Hazard light switch
-     *
-     * The setting that the user wants.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleLightSwitch
-     */
-    HAZARD_LIGHTS_SWITCH = 0x0E13 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Cabin lights
-     *
-     * Return current status of cabin lights.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleLightState
-     */
-    CABIN_LIGHTS_STATE = 0x0F01 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Cabin lights switch
-     *
-     * The position of the physical switch which controls the cabin lights.
-     * This might be different than the CABIN_LIGHTS_STATE if the lights are on because a door
-     * is open or because of a voice command.
-     * For example, while the switch is in the "off" or "automatic" position.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleLightSwitch
-     */
-    CABIN_LIGHTS_SWITCH = 0x0F02 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Reading lights
-     *
-     * Return current status of reading lights.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleLightState
-     */
-    READING_LIGHTS_STATE = 0x0F03 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Reading lights switch
-     *
-     * The position of the physical switch which controls the reading lights.
-     * This might be different than the READING_LIGHTS_STATE if the lights are on because a door
-     * is open or because of a voice command.
-     * For example, while the switch is in the "off" or "automatic" position.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleLightSwitch
-     */
-    READING_LIGHTS_SWITCH = 0x0F04 + 0x10000000 + 0x05000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
-    /**
-     * Support customize permissions for vendor properties
-     *
-     * Implement this property if vehicle hal support customize vendor permissions feature.
-     * VehiclePropConfig.configArray is used to indicate vendor properties and permissions
-     * which selected for this vendor property. The permission must be one of enum in
-     * VehicleVendorPermission.
-     * The configArray is set as follows:
-     *      configArray[n] = propId : property ID for the vendor property
-     *      configArray[n+1] = one of enums in VehicleVendorPermission. It indicates the permission
-     *      for reading value of the property.
-     *      configArray[n+2] = one of enums in VehicleVendorPermission. It indicates the permission
-     *      for writing value of the property.
-     *
-     * For example:
-     * configArray = {
-     *      vendor_prop_1, PERMISSION_VENDOR_SEAT_READ, PERMISSION_VENDOR_SEAT_WRITE,
-     *      vendor_prop_2, PERMISSION_VENDOR_INFO, PERMISSION_NOT_ACCESSIBLE,
-     * }
-     * If vendor properties are not in this array, they will have the default vendor permission.
-     * If vendor chose PERMISSION_NOT_ACCESSIBLE, android will not have access to the property. In
-     * the example, Android can not write value for vendor_prop_2.
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     */
-    SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 0x0F05 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-    /**
-     * Allow disabling optional featurs from vhal.
-     *
-     * This property reports optional features that should be disabled.
-     * All allowed optional features for the system is declared in Car service overlay,
-     * config_allowed_optional_car_features.
-     * This property allows disabling features defined in the overlay. Without this property,
-     * all the features declared in the overlay will be enabled.
-     *
-     * Value read should include all features disabled with ',' separation.
-     * ex) "com.android.car.user.CarUserNoticeService,storage_monitoring"
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     */
-    DISABLED_OPTIONAL_FEATURES = 0x0F06 + 0x10000000 + 0x01000000
-            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
-    /**
-     * Defines the initial Android user to be used during initialization.
-     *
-     * This property is called by the Android system when it initializes and it lets the HAL
-     * define which Android user should be started.
-     *
-     * This request is made by setting a VehiclePropValue (defined by InitialUserInfoRequest),
-     * and the HAL must respond with a property change event (defined by InitialUserInfoResponse).
-     * If the HAL doesn't respond after some time (defined by the Android system), the Android
-     * system will proceed as if HAL returned a response of action
-     * InitialUserInfoResponseAction:DEFAULT.
-     *
-     * For example, on first boot, the request could be:
-     *
-     * int32[0]: 42  // request id (arbitrary number set by Android system)
-     * int32[1]: 1   // InitialUserInfoRequestType::FIRST_BOOT
-     * int32[2]: 0   // id of current user (usersInfo.currentUser.userId)
-     * int32[3]: 1   // flag of current user (usersInfo.currentUser.flags = SYSTEM)
-     * int32[4]: 1   // number of existing users (usersInfo.numberUsers);
-     * int32[5]: 0   // user #0  (usersInfo.existingUsers[0].userId)
-     * int32[6]: 1   // flags of user #0  (usersInfo.existingUsers[0].flags)
-     *
-     * And if the HAL want to respond with the creation of an admin user called "Owner", the
-     * response would be:
-     *
-     * int32[0]: 42      // must match the request id from the request
-     * int32[1]:  2      // action = InitialUserInfoResponseAction::CREATE
-     * int32[2]: -10000  // userToSwitchOrCreate.userId (not used as user will be created)
-     * int32[3]:  8      // userToSwitchOrCreate.flags = ADMIN
-     * string: "||Owner" // userLocales + separator + userNameToCreate
-     *
-     * Notice the string value represents multiple values, separated by ||. The first value is the
-     * (optional) system locales for the user to be created (in this case, it's empty, meaning it
-     * will use Android's default value), while the second value is the (also optional) name of the
-     * to user to be created (when the type of response is InitialUserInfoResponseAction:CREATE).
-     * For example, to create the same "Owner" user with "en-US" and "pt-BR" locales, the string
-     * value of the response would be "en-US,pt-BR||Owner". As such, neither the locale nor the
-     * name can have || on it, although a single | is fine.
-     *
-     * NOTE: if the HAL doesn't support user management, then it should not define this property,
-     * which in turn would disable the other user-related properties (for example, the Android
-     * system would never issue them and user-related requests from the HAL layer would be ignored
-     * by the Android System). But if it supports user management, then it must support all core
-     * user-related properties (INITIAL_USER_INFO, SWITCH_USER, CREATE_USER, and REMOVE_USER).
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    INITIAL_USER_INFO = 0x0F07 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * Defines a request to switch the foreground Android user.
-     *
-     * This property is used primarily by the Android System to inform the HAL that the
-     * current foreground Android user is switching, but it could also be used by the HAL to request
-     * the Android system to switch users - the
-     *
-     * When the request is made by Android, it sets a VehiclePropValue and the HAL must responde
-     * with a property change event; when the HAL is making the request, it must also do it through
-     * a property change event (the main difference is that the request id will be positive in the
-     * former case, and negative in the latter; the SwitchUserMessageType will also be different).
-     *
-     * The format of both request is defined by SwitchUserRequest and the format of the response
-     * (when needed) is defined by SwitchUserResponse. How the HAL (or Android System) should
-     * proceed depends on the message type (which is defined by the SwitchUserMessageType
-     * parameter), as defined below.
-     *
-     * 1.LEGACY_ANDROID_SWITCH
-     * -----------------------
-     *
-     * Called by the Android System to indicate the Android user is about to change, when the change
-     * request was made in a way that is not integrated with the HAL (for example, through
-     * adb shell am switch-user).
-     *
-     * The HAL can switch its internal user once it receives this request, but it doesn't need to
-     * reply back to the Android System. If its internal user cannot be changed for some reason,
-     * then it must wait for the SWITCH_USER(type=ANDROID_POST_SWITCH) call to recover
-     * (for example, it could issue a SWITCH_USER(type=VEHICLE_REQUEST) to switch back to
-     * the previous user), but ideally it should never fail (as switching back could result in a
-     * confusing experience for the end user).
-     *
-     * For example, if the system have users (0, 10, 11) and it's switching from 0 to 11 (where none
-     * of them have any special flag), the request would be:
-     *
-     * int32[0]:  42  // request id
-     * int32[1]:  1   // SwitchUserMessageType::LEGACY_ANDROID_SWITCH
-     * int32[2]:  11  // target user id
-     * int32[3]:  0   // target user flags (none)
-     * int32[4]:  10  // current user
-     * int32[5]:  0   // current user flags (none)
-     * int32[6]:  3   // number of users
-     * int32[7]:  0   // user #0 (Android user id 0)
-     * int32[8]:  0   // flags of user #0 (none)
-     * int32[9]:  10  // user #1 (Android user id 10)
-     * int32[10]: 0   // flags of user #1 (none)
-     * int32[11]: 11  // user #2 (Android user id 11)
-     * int32[12]: 0   // flags of user #2 (none)
-     *
-     * 2.ANDROID_SWITCH
-     * ----------------
-     * Called by the Android System to indicate the Android user is about to change, but Android
-     * will wait for the HAL's response (up to some time) before proceeding.
-     *
-     * The HAL must switch its internal user once it receives this request, then respond back to
-     * Android with a SWITCH_USER(type=VEHICLE_RESPONSE) indicating whether its internal
-     * user was switched or not (through the SwitchUserStatus enum).
-     *
-     * For example, if Android has users (0, 10, 11) and it's switching from 10 to 11 (where
-     * none of them have any special flag), the request would be:
-     *
-     * int32[0]:  42  // request id
-     * int32[1]:  2   // SwitchUserMessageType::ANDROID_SWITCH
-     * int32[2]:  11  // target user id
-     * int32[3]:  0   // target user flags (none)
-     * int32[4]:  10  // current user
-     * int32[5]:  0   // current user flags (none)
-     * int32[6]:  3   // number of users
-     * int32[7]:  0   // 1st user (user 0)
-     * int32[8]:  1   // 1st user flags (SYSTEM)
-     * int32[9]:  10  // 2nd user (user 10)
-     * int32[10]: 0   // 2nd user flags (none)
-     * int32[11]: 11  // 3rd user (user 11)
-     * int32[12]: 0   // 3rd user flags (none)
-     *
-     * If the request succeeded, the HAL must update the property with:
-     *
-     * int32[0]: 42  // request id
-     * int32[1]: 3   // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
-     * int32[2]: 1   // status = SwitchUserStatus::SUCCESS
-     *
-     * But if it failed, the response would be something like:
-     *
-     * int32[0]: 42   // request id
-     * int32[1]: 3    // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
-     * int32[2]: 2    // status = SwitchUserStatus::FAILURE
-     * string: "108-D'OH!" // OEM-specific error message
-     *
-     * 3.VEHICLE_RESPONSE
-     * ------------------
-     * Called by the HAL to indicate whether a request of type ANDROID_SWITCH should proceed or
-     * abort - see the ANDROID_SWITCH section above for more info.
-     *
-     * 4.VEHICLE_REQUEST
-     * ------------------
-     * Called by the HAL to request that the current foreground Android user is switched.
-     *
-     * This is useful in situations where Android started as one user, but the vehicle identified
-     * the driver as another user. For example, user A unlocked the car using the key fob of user B;
-     * the INITIAL_USER_INFO request returned user B, but then a face recognition subsubsystem
-     * identified the user as A.
-     *
-     * The HAL makes this request by a property change event (passing a negative request id), and
-     * the Android system will response by issue an ANDROID_POST_SWITCH call which the same
-     * request id.
-     *
-     * For example, if the current foreground Android user is 10 and the HAL asked it to switch to
-     * 11, the request would be:
-     *
-     * int32[0]: -108  // request id
-     * int32[1]: 4     // messageType = SwitchUserMessageType::VEHICLE_REQUEST
-     * int32[2]: 11    // Android user id
-     *
-     * If the request succeeded and Android has 3 users (0, 10, 11), the response would be:
-     *
-     * int32[0]: -108 // request id
-     * int32[1]:  5   // messageType = SwitchUserMessageType::ANDROID_POST_SWITCH
-     * int32[2]:  11  // target user id
-     * int32[3]:  0   // target user id flags (none)
-     * int32[4]:  11  // current user
-     * int32[5]:  0   // current user flags (none)
-     * int32[6]:  3   // number of users
-     * int32[7]:  0   // 1st user (user 0)
-     * int32[8]:  0   // 1st user flags (none)
-     * int32[9]:  10  // 2nd user (user 10)
-     * int32[10]: 4   // 2nd user flags (none)
-     * int32[11]: 11  // 3rd user (user 11)
-     * int32[12]: 3   // 3rd user flags (none)
-     *
-     * Notice that both the current and target user ids are the same - if the request failed, then
-     * they would be different (i.e, target user would be 11, but current user would still be 10).
-     *
-     * 5.ANDROID_POST_SWITCH
-     * ---------------------
-     * Called by the Android System after a request to switch a user was made.
-     *
-     * This property is called after switch requests of any type (i.e., LEGACY_ANDROID_SWITCH,
-     * ANDROID_SWITCH, or VEHICLE_REQUEST) and can be used to determine if the request succeeded or
-     * failed:
-     *
-     * 1. When it succeeded, it's called when the Android user is in the unlocked state and the
-     *    value of the current and target users ids in the response are the same. This would be
-     *    equivalent to receiving an Intent.ACTION_USER_UNLOCKED in an Android app.
-     * 2. When it failed it's called right away and the value of the current and target users ids
-     *    in the response are different (as the current user didn't change to the target).
-     * 3. If a new switch request is made before the HAL responded to the previous one or before
-     *    the user was unlocked, then the ANDROID_POST_SWITCH request is not made. For example,
-     *    the driver could accidentally switch to the wrong user which has lock credentials, then
-     *    switch to the right one before entering the credentials.
-     *
-     * The HAL can update its internal state once it receives this request, but it doesn't need to
-     * reply back to the Android System.
-     *
-     * Request: the first N values as defined by INITIAL_USER_INFO (where the request-specific
-     * value at index 1 is SwitchUserMessageType::ANDROID_POST_SWITCH), then 2 more values for the
-     * target user id (i.e., the Android user id that was requested to be switched to) and its flags
-     * (as defined by  UserFlags).
-     *
-     * Response: none.
-     *
-     * Example: see VEHICLE_REQUEST section above.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    SWITCH_USER = 0x0F08 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * Called by the Android System after an Android user was created.
-     *
-     * The HAL can use this property to create its equivalent user.
-     *
-     * This is an async request: Android makes the request by setting a VehiclePropValue, and HAL
-     * must respond with a property change indicating whether the request succeeded or failed. If
-     * it failed, the Android system will remove the user.
-     *
-     * The format of the request is defined by CreateUserRequest and the format of the response by
-     * CreateUserResponse.
-     *
-     * For example, if system had 2 users (0 and 10) and a 3rd one (which is an ephemeral guest) was
-     * created, the request would be:
-     *
-     * int32[0]: 42  // request id
-     * int32[1]: 11  // Android id of the created user
-     * int32[2]: 6   // Android flags (ephemeral guest) of the created user
-     * int32[3]: 10  // current user
-     * int32[4]: 0   // current user flags (none)
-     * int32[5]: 3   // number of users
-     * int32[6]: 0   // 1st user (user 0)
-     * int32[7]: 0   // 1st user flags (none)
-     * int32[8]: 10  // 2nd user (user 10)
-     * int32[9]: 0   // 2nd user flags (none)
-     * int32[19]: 11 // 3rd user (user 11)
-     * int32[11]: 6  // 3rd user flags (ephemeral guest)
-     * string: "ElGuesto" // name of the new user
-     *
-     * Then if the request succeeded, the HAL would return:
-     *
-     * int32[0]: 42  // request id
-     * int32[1]: 1   // CreateUserStatus::SUCCESS
-     *
-     * But if it failed:
-     *
-     * int32[0]: 42  // request id
-     * int32[1]: 2   // CreateUserStatus::FAILURE
-     * string: "D'OH!" // The meaning is a blackbox - it's passed to the caller (like Settings UI),
-     *                 // which in turn can take the proper action.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    CREATE_USER = 0x0F09 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * Called by the Android System after an Android user was removed.
-     *
-     * The HAL can use this property to remove its equivalent user.
-     *
-     * This is write-only call - the Android System is not expecting a reply from the HAL. Hence,
-     * this request should not fail - if the equivalent HAL user cannot be removed, then HAL should
-     * mark it as inactive or recover in some other way.
-     *
-     * The request is made by setting the VehiclePropValue with the contents defined by
-     * RemoveUserRequest.
-     *
-     * For example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request
-     * would be:
-     *
-     * int32[0]: 42  // request id
-     * int32[1]: 11  // (Android user id of the removed user)
-     * int32[2]: 0   // (Android user flags of the removed user)
-     * int32[3]: 10  // current user
-     * int32[4]: 0   // current user flags (none)
-     * int32[5]: 2   // number of users
-     * int32[6]: 0   // 1st user (user 0)
-     * int32[7]: 0   // 1st user flags (none)
-     * int32[8]: 10  // 2nd user (user 10)
-     * int32[9]: 0   // 2nd user flags (none)
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:WRITE
-     */
-    REMOVE_USER = 0x0F0A + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * Property used to associate (or query the association) the current user with vehicle-specific
-     * identification mechanisms (such as key FOB).
-     *
-     * This is an optional user management property - the OEM could still support user management
-     * without defining it. In fact, this property could be used without supporting the core
-     * user-related functions described on INITIAL_USER_INFO.
-     *
-     * To query the association, the Android system gets the property, passing a VehiclePropValue
-     * containing the types of associations are being queried, as defined by
-     * UserIdentificationGetRequest. The HAL must return right away, returning a VehiclePropValue
-     * with a UserIdentificationResponse. Notice that user identification should have already
-     * happened while system is booting up and the VHAL implementation should only return the
-     * already identified association (like the key FOB used to unlock the car), instead of starting
-     * a new association from the get call.
-     *
-     * To associate types, the Android system sets the property, passing a VehiclePropValue
-     * containing the types and values of associations being set, as defined by the
-     * UserIdentificationSetRequest. The HAL will then use a property change event (whose
-     * VehiclePropValue is defined by UserIdentificationResponse) indicating the current status of
-     * the types after the request.
-     *
-     * For example, to query if the current user (10) is associated with the FOB that unlocked the
-     * car and a custom mechanism provided by the OEM, the request would be:
-     *
-     * int32[0]: 42  // request id
-     * int32[1]: 10  (Android user id)
-     * int32[2]: 0   (Android user flags)
-     * int32[3]: 2   (number of types queried)
-     * int32[4]: 1   (1st type queried, UserIdentificationAssociationType::KEY_FOB)
-     * int32[5]: 101 (2nd type queried, UserIdentificationAssociationType::CUSTOM_1)
-     *
-     * If the user is associated with the FOB but not with the custom mechanism, the response would
-     * be:
-     *
-     * int32[0]: 42  // request id
-     * int32[1]: 2   (number of associations in the response)
-     * int32[2]: 1   (1st type: UserIdentificationAssociationType::KEY_FOB)
-     * int32[3]: 2   (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
-     * int32[4]: 101 (2st type: UserIdentificationAssociationType::CUSTOM_1)
-     * int32[5]: 4   (2nd value: UserIdentificationAssociationValue::NOT_ASSOCIATED_ANY_USER)
-     *
-     * Then to associate the user with the custom mechanism, a set request would be made:
-     *
-     * int32[0]: 43  // request id
-     * int32[1]: 10  (Android user id)
-     * int32[2]: 0   (Android user flags)
-     * int32[3]: 1   (number of associations being set)
-     * int32[4]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
-     * int32[5]: 1   (1st value: UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER)
-     *
-     * If the request succeeded, the response would be simply:
-     *
-     * int32[0]: 43  // request id
-     * int32[1]: 1   (number of associations in the response)
-     * int32[2]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
-     * int32[3]: 1   (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
-     *
-     * Notice that the set request adds associations, but doesn't remove the existing ones. In the
-     * example above, the end state would be 2 associations (FOB and CUSTOM_1). If we wanted to
-     * associate the user with just CUSTOM_1 but not FOB, then the request should have been:
-     *
-     * int32[0]: 43  // request id
-     * int32[1]: 10  (Android user id)
-     * int32[2]: 2   (number of types set)
-     * int32[3]: 1   (1st type: UserIdentificationAssociationType::KEY_FOB)
-     * int32[4]: 2   (1st value: UserIdentificationAssociationValue::DISASSOCIATE_CURRENT_USER)
-     * int32[5]: 101 (2nd type: UserIdentificationAssociationType::CUSTOM_1)
-     * int32[6]: 1   (2nd value: UserIdentificationAssociationValue::ASSOCIATE_CURRENT_USER)
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    USER_IDENTIFICATION_ASSOCIATION = 0x0F0B + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * Enable/request an EVS service.
-     *
-     * The property provides a generalized way to trigger EVS services.  VHAL
-     * should use this property to request Android to start or stop EVS service.
-     *
-     *  int32Values[0] = a type of the EVS service. The value must be one of enums in
-     *                   EvsServiceType.
-     *  int32Values[1] = the state of the EVS service. The value must be one of enums in
-     *                   EvsServiceState.
-     *
-     * For example, to enable rear view EVS service, android side can set the property value as
-     * [EvsServiceType::REAR_VIEW, EvsServiceState::ON].
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    EVS_SERVICE_REQUEST = 0x0F10 + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Defines a request to apply power policy.
-     *
-     * VHAL sets this property to change car power policy. Car power policy service subscribes to
-     * this property and actually changes the power policy.
-     * The request is made by setting the VehiclePropValue with the ID of a power policy which is
-     * defined at /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy
-     * service ignores the request and the current power policy is maintained.
-     *
-     *   string: "sample_policy_id" // power policy ID
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    POWER_POLICY_REQ = 0x0F21 + 0x10000000 + 0x01000000
-            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
-    /**
-     * Defines a request to set the power polic group used to decide a default power policy per
-     * power status transition.
-     *
-     * VHAL sets this property with the ID of a power policy group in order to set the default power
-     * policy applied at power status transition. Power policy groups are defined at
-     * /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy service
-     * ignores the request.
-     * Car power policy service subscribes to this property and sets the power policy group.
-     * The actual application of power policy takes place when the system power status changes and
-     * there is a valid mapped power policy for the new power status.
-     *
-     *   string: "sample_policy_group_id" // power policy group ID
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    POWER_POLICY_GROUP_REQ = 0x0F22 + 0x10000000 + 0x01000000
-            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
-    /**
-     * Notifies the current power policy to VHAL layer.
-     *
-     * Car power policy service sets this property when the current power policy is changed.
-     *
-     *   string: "sample_policy_id" // power policy ID
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    CURRENT_POWER_POLICY = 0x0F23 + 0x10000000 + 0x01000000
-            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
-    /**
-     * Defines an event that car watchdog updates to tell it's alive.
-     *
-     * Car watchdog sets this property to system uptime in milliseconds at every 3 second.
-     * During the boot, the update may take longer time.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:WRITE
-     */
-    WATCHDOG_ALIVE = 0xF31 + 0x10000000 + 0x01000000
-            + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
-    /**
-     * Defines a process terminated by car watchdog and the reason of termination.
-     *
-     *   int32Values[0]: 1         // ProcessTerminationReason showing why a process is terminated.
-     *   string: "/system/bin/log" // Process execution command.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:WRITE
-     */
-    WATCHDOG_TERMINATED_PROCESS = 0x0F32 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * Defines an event that VHAL signals to car watchdog as a heartbeat.
-     *
-     * If VHAL supports this property, VHAL should write system uptime to this property at every 3
-     * second. Car watchdog subscribes to this property and checks if the property is updated at
-     * every 3 second. With the buffer time of 3 second, car watchdog waits for a heart beat to be
-     * signaled up to 6 seconds from the last heart beat. If it isn’t, car watchdog considers
-     * VHAL unhealthy and terminates it.
-     * If this property is not supported by VHAL, car watchdog doesn't check VHAL health status.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    VHAL_HEARTBEAT = 0x0F33 + 0x10000000 + 0x01000000
-            + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
-    /**
-     * Starts the ClusterUI in cluster display.
-     *
-     * int32: the type of ClusterUI to show
-     *    0 indicates ClusterHome, that is a home screen of cluster display, and provides
-     *        the default UI and a kind of launcher functionality for cluster display.
-     *    the other values are followed by OEM's definition.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    CLUSTER_SWITCH_UI = 0x0F34 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Changes the state of the cluster display.
-     *
-     * Bounds: the area to render the cluster Activity.
-     * Inset: the area which Activity should avoid from placing any important
-     *     information.
-     *
-     * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care
-     * int32[1]: Bounds - left: positive number - left position in pixels
-                                -1 - don't care (should set all Bounds fields)
-     * int32[2]: Bounds - top:    same format with 'left'
-     * int32[3]: Bounds - right:  same format with 'left'
-     * int32[4]: Bounds - bottom: same format with 'left'
-     * int32[5]: Inset - left: positive number - actual left inset value in pixels
-                               -1 - don't care (should set "don't care" all Inset fields)
-     * int32[6]: Inset - top:    same format with 'left'
-     * int32[7]: Inset - right:  same format with 'left'
-     * int32[8]: Inset - bottom: same format with 'left'
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     */
-    CLUSTER_DISPLAY_STATE = 0x0F35 + 0x10000000 + 0x01000000
-            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    /**
-     * Reports the current display state and ClusterUI state.
-     *
-     * ClusterHome will send this message when it handles CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE.
-     *
-     * In addition, ClusterHome should send this message when it starts for the first time.
-     * When ClusterOS receives this message and if the internal expectation is different with the
-     * received message, then it should send CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE again to
-     * match the state.
-     *
-     * int32[0]: on/off: 0 - off, 1 - on
-     * int32[1]: Bounds - left
-     * int32[2]: Bounds - top
-     * int32[3]: Bounds - right
-     * int32[4]: Bounds - bottom
-     * int32[5]: Inset - left
-     * int32[6]: Inset - top
-     * int32[7]: Inset - right
-     * int32[8]: Inset - bottom
-     * int32[9]: the type of ClusterUI in the fullscreen or main screen.
-     *    0 indicates ClusterHome.
-     *    the other values are followed by OEM's definition.
-     * int32[10]: the type of ClusterUI in sub screen if the currently two UIs are shown.
-     *    -1 indicates the area isn't used any more.
-     * bytes: the array to represent the availability of ClusterUI.
-     *     0 indicates non-available and 1 indicates available.
-     *     For example, let's assume a car supports 3 OEM defined ClusterUI like HOME, MAPS, CALL,
-     *     and it only supports CALL UI only when the cellular network is available. Then, if the
-     *     nework is avaibale, it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:WRITE
-     */
-    CLUSTER_REPORT_STATE = 0x0F36 + 0x10000000 + 0x01000000
-            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
-    /**
-     * Requests to change the cluster display state to show some ClusterUI.
-     *
-     * When the current display state is off and ClusterHome sends this message to ClusterOS to
-     * request to turn the display on to show some specific ClusterUI.
-     * ClusterOS should response this with CLUSTER_DISPLAY_STATE.
-     *
-     * int32: the type of ClusterUI to show
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:WRITE
-     */
-    CLUSTER_REQUEST_DISPLAY = 0x0F37 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Informs the current navigation state.
-     *
-     * bytes: the serialized message of NavigationStateProto.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:WRITE
-     */
-    CLUSTER_NAVIGATION_STATE = 0x0F38 + 0x10000000 + 0x01000000
-            + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
-    /**
-     * Electronic Toll Collection card type.
-     *
-     * This property indicates the type of ETC card in this vehicle.
-     * If the head unit is aware of an ETC card attached to the vehicle, this property should
-     * return the type of card attached; otherwise, this property should be UNAVAILABLE.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum ElectronicTollCollectionCardType
-     */
-    ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = 0x0F39 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Electronic Toll Collection card status.
-     *
-     * This property indicates the status of ETC card in this vehicle.
-     * If the head unit is aware of an ETC card attached to the vehicle,
-     * ELECTRONIC_TOLL_COLLECTION_CARD_TYPE gives that status of the card; otherwise,
-     * this property should be UNAVAILABLE.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum ElectronicTollCollectionCardStatus
-     */
-    ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = 0x0F3A + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-    /**
-     * Front fog lights state
-     *
-     * Return the current state of the front fog lights.
-     * Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented. Please refer to
-     * the documentation on FOG_LIGHTS_STATE for more information.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleLightState
-     */
-    FRONT_FOG_LIGHTS_STATE = 0x0F3B + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-    /**
-     * Front fog lights switch
-     *
-     * The setting that the user wants.
-     * Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented. Please refer to
-     * the documentation on FOG_LIGHTS_SWITCH for more information.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleLightSwitch
-     */
-    FRONT_FOG_LIGHTS_SWITCH = 0x0F3C + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-    /**
-     * Rear fog lights state
-     *
-     * Return the current state of the rear fog lights.
-     * Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented. Please refer to
-     * the documentation on FOG_LIGHTS_STATE for more information.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum VehicleLightState
-     */
-    REAR_FOG_LIGHTS_STATE = 0x0F3D + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-    /**
-     * Rear fog lights switch
-     *
-     * The setting that the user wants.
-     * Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented. Please refer to
-     * the documentation on FOG_LIGHTS_SWITCH for more information.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @data_enum VehicleLightSwitch
-     */
-    REAR_FOG_LIGHTS_SWITCH = 0x0F3E + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-    /**
-     * Indicates the maximum current draw threshold for charging set by the user
-     *
-     * configArray[0] is used to specify the max current draw allowed by
-     * the vehicle in Amperes.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     * @unit VehicleUnit:AMPERE
-     */
-    EV_CHARGE_CURRENT_DRAW_LIMIT = 0x0F3F + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-
-    /**
-     * Indicates the maximum charge percent threshold set by the user
-     *
-     * Returns a float value from 0 to 100.
-     *
-     * configArray is used to specify the valid values.
-     *   For example, if the vehicle supports the following charge percent limit values:
-     *     [20, 40, 60, 80, 100]
-     *   then the configArray should be {20, 40, 60, 80, 100}
-     * If the configArray is empty then all values from 0 to 100 must be valid.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    EV_CHARGE_PERCENT_LIMIT = 0x0F40 + 0x10000000 + 0x01000000
-            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-
-    /**
-     * Charging state of the car
-     *
-     * Returns the current charging state of the car.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum EvChargeState
-     */
-    EV_CHARGE_STATE = 0x0F41 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-    /**
-     * Start or stop charging the EV battery
-     *
-     * The setting that the user wants. Setting this property to true starts the battery charging
-     * and setting to false stops charging.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ_WRITE
-     */
-    EV_CHARGE_SWITCH = 0x0F42 + 0x10000000 + 0x01000000
-            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-
-    /**
-     * Estimated charge time remaining in seconds
-     *
-     * Returns 0 if the vehicle is not charging.
-     *
-     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:SECS
-     */
-    EV_CHARGE_TIME_REMAINING = 0x0F43 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-    /**
-     * Regenerative braking or one-pedal drive state of the car
-     *
-     * Returns the current state associated with the regenerative braking
-     * setting in the car
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum EvRegenerativeBrakingState
-     */
-    EV_REGENERATIVE_BRAKING_STATE = 0x0F44 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-    /**
-     * Indicates if there is a trailer present or not.
-     *
-     * Returns the trailer state of the car.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
-     * @access VehiclePropertyAccess:READ
-     * @data_enum TrailerState
-     */
-    TRAILER_PRESENT = 0x0F45 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-    /**
-     * Vehicle’s curb weight
-     *
-     * Returns the vehicle's curb weight in kilograms. Curb weight is
-     * the total weight of the vehicle with standard equipment and all
-     * necessary operating consumables such as motor oil,transmission oil,
-     * brake fluid, coolant, air conditioning refrigerant, and weight of
-     * fuel at nominal tank capacity, while not loaded with either passengers
-     * or cargo.
-     *
-     * configArray[0] is used to specify the vehicle’s gross weight in kilograms.
-     * The vehicle’s gross weight is the maximum operating weight of the vehicle
-     * as specified by the manufacturer including the vehicle's chassis, body, engine,
-     * engine fluids, fuel, accessories, driver, passengers and cargo but excluding
-     * that of any trailers.
-     *
-     * @change_mode VehiclePropertyChangeMode:STATIC
-     * @access VehiclePropertyAccess:READ
-     * @unit VehicleUnit:KILOGRAM
-     */
-
-    VEHICLE_CURB_WEIGHT = 0x0F46 + 0x10000000 + 0x01000000
-            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
deleted file mode 100644
index 62d26de..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
+++ /dev/null
@@ -1,59 +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.automotive.vehicle;
-
-/**
- * Enumerates supported data type for VehicleProperty.
- *
- * Used to create property ID in VehicleProperty enum.
- */
-@VintfStability
-@Backing(type="int")
-enum VehiclePropertyType {
-    STRING = 0x00100000,
-    BOOLEAN = 0x00200000,
-    INT32 = 0x00400000,
-    INT32_VEC = 0x00410000,
-    INT64 = 0x00500000,
-    INT64_VEC = 0x00510000,
-    FLOAT = 0x00600000,
-    FLOAT_VEC = 0x00610000,
-    BYTES = 0x00700000,
-
-    /**
-     * Any combination of scalar or vector types. The exact format must be
-     * provided in the description of the property.
-     *
-     * For vendor MIXED type properties, configArray needs to be formatted in this
-     * structure.
-     * configArray[0], 1 indicates the property has a String value
-     * configArray[1], 1 indicates the property has a Boolean value .
-     * configArray[2], 1 indicates the property has an Integer value.
-     * configArray[3], the number indicates the size of Integer[] in the property.
-     * configArray[4], 1 indicates the property has a Long value.
-     * configArray[5], the number indicates the size of Long[] in the property.
-     * configArray[6], 1 indicates the property has a Float value.
-     * configArray[7], the number indicates the size of Float[] in the property.
-     * configArray[8], the number indicates the size of byte[] in the property.
-     * For example:
-     * {@code configArray = {1, 1, 1, 3, 0, 0, 0, 0, 0}} indicates the property has
-     * a String value, a Boolean value, an Integer value and an array with 3 integers.
-     */
-    MIXED = 0x00e00000,
-
-    MASK = 0x00ff0000,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleUnit.aidl
deleted file mode 100644
index 3817b74..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleUnit.aidl
+++ /dev/null
@@ -1,61 +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.automotive.vehicle;
-
-/**
- * Units used for int or float type with no attached enum types.
- */
-@VintfStability
-@Backing(type="int")
-enum VehicleUnit {
-    SHOULD_NOT_USE = 0x000,
-    METER_PER_SEC = 0x01,
-    RPM = 0x02,
-    HERTZ = 0x03,
-    PERCENTILE = 0x10,
-    MILLIMETER = 0x20,
-    METER = 0x21,
-    KILOMETER = 0x23,
-    MILE = 0x24,
-    CELSIUS = 0x30,
-    FAHRENHEIT = 0x31,
-    KELVIN = 0x32,
-    MILLILITER = 0x40,
-    LITER = 0x41,
-    /**
-     * deprecated. Use US_GALLON instead.
-     */
-    GALLON = 0x42,
-    US_GALLON = 0x42,
-    IMPERIAL_GALLON = 0x43,
-    NANO_SECS = 0x50,
-    SECS = 0x53,
-    YEAR = 0x59,
-    WATT_HOUR = 0x60,
-    MILLIAMPERE = 0x61,
-    MILLIVOLT = 0x62,
-    MILLIWATTS = 0x63,
-    AMPERE_HOURS = 0x64,
-    KILOWATT_HOUR = 0x65,
-    AMPERE = 0x66,
-    KILOPASCAL = 0x70,
-    PSI = 0x71,
-    BAR = 0x72,
-    DEGREES = 0x80,
-    MILES_PER_HOUR = 0x90,
-    KILOMETERS_PER_HOUR = 0x91,
-}
diff --git a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
new file mode 100644
index 0000000..e312a3a
--- /dev/null
+++ b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
@@ -0,0 +1,3460 @@
+[
+  {
+    "name": "VehicleApPowerStateReqIndex",
+    "values": [
+      {
+        "name": "STATE",
+        "value": 0
+      },
+      {
+        "name": "ADDITIONAL",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "name": "EvChargeState",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "CHARGING",
+        "value": 1
+      },
+      {
+        "name": "FULLY_CHARGED",
+        "value": 2
+      },
+      {
+        "name": "NOT_CHARGING",
+        "value": 3
+      },
+      {
+        "name": "ERROR",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "name": "TrailerState",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "NOT_PRESENT",
+        "value": 1
+      },
+      {
+        "name": "PRESENT",
+        "value": 2
+      },
+      {
+        "name": "ERROR",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "ProcessTerminationReason",
+    "values": [
+      {
+        "name": "NOT_RESPONDING",
+        "value": 1
+      },
+      {
+        "name": "IO_OVERUSE",
+        "value": 2
+      },
+      {
+        "name": "MEMORY_OVERUSE",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "VehicleApPowerStateConfigFlag",
+    "values": [
+      {
+        "name": "ENABLE_DEEP_SLEEP_FLAG",
+        "value": 1
+      },
+      {
+        "name": "CONFIG_SUPPORT_TIMER_POWER_ON_FLAG",
+        "value": 2
+      },
+      {
+        "name": "ENABLE_HIBERNATION_FLAG",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "Obd2FuelType",
+    "values": [
+      {
+        "name": "NOT_AVAILABLE",
+        "value": 0
+      },
+      {
+        "name": "GASOLINE",
+        "value": 1
+      },
+      {
+        "name": "METHANOL",
+        "value": 2
+      },
+      {
+        "name": "ETHANOL",
+        "value": 3
+      },
+      {
+        "name": "DIESEL",
+        "value": 4
+      },
+      {
+        "name": "LPG",
+        "value": 5
+      },
+      {
+        "name": "CNG",
+        "value": 6
+      },
+      {
+        "name": "PROPANE",
+        "value": 7
+      },
+      {
+        "name": "ELECTRIC",
+        "value": 8
+      },
+      {
+        "name": "BIFUEL_RUNNING_GASOLINE",
+        "value": 9
+      },
+      {
+        "name": "BIFUEL_RUNNING_METHANOL",
+        "value": 10
+      },
+      {
+        "name": "BIFUEL_RUNNING_ETHANOL",
+        "value": 11
+      },
+      {
+        "name": "BIFUEL_RUNNING_LPG",
+        "value": 12
+      },
+      {
+        "name": "BIFUEL_RUNNING_CNG",
+        "value": 13
+      },
+      {
+        "name": "BIFUEL_RUNNING_PROPANE",
+        "value": 14
+      },
+      {
+        "name": "BIFUEL_RUNNING_ELECTRIC",
+        "value": 15
+      },
+      {
+        "name": "BIFUEL_RUNNING_ELECTRIC_AND_COMBUSTION",
+        "value": 16
+      },
+      {
+        "name": "HYBRID_GASOLINE",
+        "value": 17
+      },
+      {
+        "name": "HYBRID_ETHANOL",
+        "value": 18
+      },
+      {
+        "name": "HYBRID_DIESEL",
+        "value": 19
+      },
+      {
+        "name": "HYBRID_ELECTRIC",
+        "value": 20
+      },
+      {
+        "name": "HYBRID_RUNNING_ELECTRIC_AND_COMBUSTION",
+        "value": 21
+      },
+      {
+        "name": "HYBRID_REGENERATIVE",
+        "value": 22
+      },
+      {
+        "name": "BIFUEL_RUNNING_DIESEL",
+        "value": 23
+      }
+    ]
+  },
+  {
+    "name": "VmsSubscriptionsStateIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "SEQUENCE_NUMBER",
+        "value": 1
+      },
+      {
+        "name": "NUMBER_OF_LAYERS",
+        "value": 2
+      },
+      {
+        "name": "NUMBER_OF_ASSOCIATED_LAYERS",
+        "value": 3
+      },
+      {
+        "name": "SUBSCRIPTIONS_START",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "name": "VehicleArea",
+    "values": [
+      {
+        "name": "GLOBAL",
+        "value": 16777216
+      },
+      {
+        "name": "WINDOW",
+        "value": 50331648
+      },
+      {
+        "name": "MIRROR",
+        "value": 67108864
+      },
+      {
+        "name": "SEAT",
+        "value": 83886080
+      },
+      {
+        "name": "DOOR",
+        "value": 100663296
+      },
+      {
+        "name": "WHEEL",
+        "value": 117440512
+      },
+      {
+        "name": "MASK",
+        "value": 251658240
+      }
+    ]
+  },
+  {
+    "name": "VehicleAreaWindow",
+    "values": [
+      {
+        "name": "FRONT_WINDSHIELD",
+        "value": 1
+      },
+      {
+        "name": "REAR_WINDSHIELD",
+        "value": 2
+      },
+      {
+        "name": "ROW_1_LEFT",
+        "value": 16
+      },
+      {
+        "name": "ROW_1_RIGHT",
+        "value": 64
+      },
+      {
+        "name": "ROW_2_LEFT",
+        "value": 256
+      },
+      {
+        "name": "ROW_2_RIGHT",
+        "value": 1024
+      },
+      {
+        "name": "ROW_3_LEFT",
+        "value": 4096
+      },
+      {
+        "name": "ROW_3_RIGHT",
+        "value": 16384
+      },
+      {
+        "name": "ROOF_TOP_1",
+        "value": 65536
+      },
+      {
+        "name": "ROOF_TOP_2",
+        "value": 131072
+      }
+    ]
+  },
+  {
+    "name": "ElectronicTollCollectionCardStatus",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "ELECTRONIC_TOLL_COLLECTION_CARD_VALID",
+        "value": 1
+      },
+      {
+        "name": "ELECTRONIC_TOLL_COLLECTION_CARD_INVALID",
+        "value": 2
+      },
+      {
+        "name": "ELECTRONIC_TOLL_COLLECTION_CARD_NOT_INSERTED",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "VehiclePropertyType",
+    "values": [
+      {
+        "name": "STRING",
+        "value": 1048576
+      },
+      {
+        "name": "BOOLEAN",
+        "value": 2097152
+      },
+      {
+        "name": "INT32",
+        "value": 4194304
+      },
+      {
+        "name": "INT32_VEC",
+        "value": 4259840
+      },
+      {
+        "name": "INT64",
+        "value": 5242880
+      },
+      {
+        "name": "INT64_VEC",
+        "value": 5308416
+      },
+      {
+        "name": "FLOAT",
+        "value": 6291456
+      },
+      {
+        "name": "FLOAT_VEC",
+        "value": 6356992
+      },
+      {
+        "name": "BYTES",
+        "value": 7340032
+      },
+      {
+        "name": "MIXED",
+        "value": 14680064
+      },
+      {
+        "name": "MASK",
+        "value": 16711680
+      }
+    ]
+  },
+  {
+    "name": "StatusCode",
+    "values": [
+      {
+        "name": "OK",
+        "value": 0
+      },
+      {
+        "name": "TRY_AGAIN",
+        "value": 1
+      },
+      {
+        "name": "INVALID_ARG",
+        "value": 2
+      },
+      {
+        "name": "NOT_AVAILABLE",
+        "value": 3
+      },
+      {
+        "name": "ACCESS_DENIED",
+        "value": 4
+      },
+      {
+        "name": "INTERNAL_ERROR",
+        "value": 5
+      }
+    ]
+  },
+  {
+    "name": "CreateUserStatus",
+    "values": [
+      {
+        "name": "SUCCESS",
+        "value": 1
+      },
+      {
+        "name": "FAILURE",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "ElectronicTollCollectionCardType",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD",
+        "value": 1
+      },
+      {
+        "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD_V2",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "VehicleAreaMirror",
+    "values": [
+      {
+        "name": "DRIVER_LEFT",
+        "value": 1
+      },
+      {
+        "name": "DRIVER_RIGHT",
+        "value": 2
+      },
+      {
+        "name": "DRIVER_CENTER",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "name": "InitialUserInfoResponseAction",
+    "values": [
+      {
+        "name": "DEFAULT",
+        "value": 0
+      },
+      {
+        "name": "SWITCH",
+        "value": 1
+      },
+      {
+        "name": "CREATE",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "VehicleHvacFanDirection",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "FACE",
+        "value": 1
+      },
+      {
+        "name": "FLOOR",
+        "value": 2
+      },
+      {
+        "name": "FACE_AND_FLOOR",
+        "value": 3
+      },
+      {
+        "name": "DEFROST",
+        "value": 4
+      },
+      {
+        "name": "DEFROST_AND_FLOOR",
+        "value": 6
+      }
+    ]
+  },
+  {
+    "name": "Obd2SecondaryAirStatus",
+    "values": [
+      {
+        "name": "UPSTREAM",
+        "value": 1
+      },
+      {
+        "name": "DOWNSTREAM_OF_CATALYCIC_CONVERTER",
+        "value": 2
+      },
+      {
+        "name": "FROM_OUTSIDE_OR_OFF",
+        "value": 4
+      },
+      {
+        "name": "PUMP_ON_FOR_DIAGNOSTICS",
+        "value": 8
+      }
+    ]
+  },
+  {
+    "name": "VmsStartSessionMessageIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "SERVICE_ID",
+        "value": 1
+      },
+      {
+        "name": "CLIENT_ID",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "VehicleOilLevel",
+    "values": [
+      {
+        "name": "CRITICALLY_LOW",
+        "value": 0
+      },
+      {
+        "name": "LOW",
+        "value": 1
+      },
+      {
+        "name": "NORMAL",
+        "value": 2
+      },
+      {
+        "name": "HIGH",
+        "value": 3
+      },
+      {
+        "name": "ERROR",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "name": "VehicleUnit",
+    "values": [
+      {
+        "name": "SHOULD_NOT_USE",
+        "value": 0
+      },
+      {
+        "name": "METER_PER_SEC",
+        "value": 1
+      },
+      {
+        "name": "RPM",
+        "value": 2
+      },
+      {
+        "name": "HERTZ",
+        "value": 3
+      },
+      {
+        "name": "PERCENTILE",
+        "value": 16
+      },
+      {
+        "name": "MILLIMETER",
+        "value": 32
+      },
+      {
+        "name": "METER",
+        "value": 33
+      },
+      {
+        "name": "KILOMETER",
+        "value": 35
+      },
+      {
+        "name": "MILE",
+        "value": 36
+      },
+      {
+        "name": "CELSIUS",
+        "value": 48
+      },
+      {
+        "name": "FAHRENHEIT",
+        "value": 49
+      },
+      {
+        "name": "KELVIN",
+        "value": 50
+      },
+      {
+        "name": "MILLILITER",
+        "value": 64
+      },
+      {
+        "name": "LITER",
+        "value": 65
+      },
+      {
+        "name": "GALLON",
+        "value": 66
+      },
+      {
+        "name": "US_GALLON",
+        "value": 66
+      },
+      {
+        "name": "IMPERIAL_GALLON",
+        "value": 67
+      },
+      {
+        "name": "NANO_SECS",
+        "value": 80
+      },
+      {
+        "name": "SECS",
+        "value": 83
+      },
+      {
+        "name": "YEAR",
+        "value": 89
+      },
+      {
+        "name": "WATT_HOUR",
+        "value": 96
+      },
+      {
+        "name": "MILLIAMPERE",
+        "value": 97
+      },
+      {
+        "name": "MILLIVOLT",
+        "value": 98
+      },
+      {
+        "name": "MILLIWATTS",
+        "value": 99
+      },
+      {
+        "name": "AMPERE_HOURS",
+        "value": 100
+      },
+      {
+        "name": "KILOWATT_HOUR",
+        "value": 101
+      },
+      {
+        "name": "AMPERE",
+        "value": 102
+      },
+      {
+        "name": "KILOPASCAL",
+        "value": 112
+      },
+      {
+        "name": "PSI",
+        "value": 113
+      },
+      {
+        "name": "BAR",
+        "value": 114
+      },
+      {
+        "name": "DEGREES",
+        "value": 128
+      },
+      {
+        "name": "MILES_PER_HOUR",
+        "value": 144
+      },
+      {
+        "name": "KILOMETERS_PER_HOUR",
+        "value": 145
+      }
+    ]
+  },
+  {
+    "name": "VehicleAreaWheel",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "LEFT_FRONT",
+        "value": 1
+      },
+      {
+        "name": "RIGHT_FRONT",
+        "value": 2
+      },
+      {
+        "name": "LEFT_REAR",
+        "value": 4
+      },
+      {
+        "name": "RIGHT_REAR",
+        "value": 8
+      }
+    ]
+  },
+  {
+    "name": "EvsServiceState",
+    "values": [
+      {
+        "name": "OFF",
+        "value": 0
+      },
+      {
+        "name": "ON",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "name": "EvsServiceRequestIndex",
+    "values": [
+      {
+        "name": "TYPE",
+        "value": 0
+      },
+      {
+        "name": "STATE",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "name": "VehicleSeatOccupancyState",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "VACANT",
+        "value": 1
+      },
+      {
+        "name": "OCCUPIED",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "VehicleProperty",
+    "values": [
+      {
+        "name": "Undefined property.",
+        "value": 0
+      },
+      {
+        "name": "VIN of vehicle",
+        "value": 286261504,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Manufacturer of vehicle",
+        "value": 286261505,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Model of vehicle",
+        "value": 286261506,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Model year of vehicle.",
+        "value": 289407235,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:YEAR"
+      },
+      {
+        "name": "Fuel capacity of the vehicle in milliliters",
+        "value": 291504388,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MILLILITER"
+      },
+      {
+        "name": "List of fuels the vehicle may use",
+        "value": 289472773,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "FuelType"
+      },
+      {
+        "name": "INFO_EV_BATTERY_CAPACITY",
+        "value": 291504390,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:WH"
+      },
+      {
+        "name": "List of connectors this EV may use",
+        "value": 289472775,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "data_enum": "EvConnectorType",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Fuel door location",
+        "value": 289407240,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "data_enum": "PortLocationType",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "EV port location",
+        "value": 289407241,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "PortLocationType"
+      },
+      {
+        "name": "INFO_DRIVER_SEAT",
+        "value": 356516106,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "data_enum": "VehicleAreaSeat",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Exterior dimensions of vehicle.",
+        "value": 289472779,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MILLIMETER"
+      },
+      {
+        "name": "Multiple EV port locations",
+        "value": 289472780,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "PortLocationType"
+      },
+      {
+        "name": "Current odometer value of the vehicle",
+        "value": 291504644,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:KILOMETER"
+      },
+      {
+        "name": "Speed of the vehicle",
+        "value": 291504647,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:METER_PER_SEC"
+      },
+      {
+        "name": "Speed of the vehicle for displays",
+        "value": 291504648,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:METER_PER_SEC"
+      },
+      {
+        "name": "Front bicycle model steering angle for vehicle",
+        "value": 291504649,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:DEGREES"
+      },
+      {
+        "name": "Rear bicycle model steering angle for vehicle",
+        "value": 291504656,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:DEGREES"
+      },
+      {
+        "name": "Temperature of engine coolant",
+        "value": 291504897,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "Engine oil level",
+        "value": 289407747,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleOilLevel"
+      },
+      {
+        "name": "Temperature of engine oil",
+        "value": 291504900,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "Engine rpm",
+        "value": 291504901,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:RPM"
+      },
+      {
+        "name": "Reports wheel ticks",
+        "value": 290521862,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "FUEL_LEVEL",
+        "value": 291504903,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MILLILITER"
+      },
+      {
+        "name": "Fuel door open",
+        "value": 287310600,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "EV_BATTERY_LEVEL",
+        "value": 291504905,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:WH"
+      },
+      {
+        "name": "EV charge port open",
+        "value": 287310602,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "EV charge port connected",
+        "value": 287310603,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "EV instantaneous charge rate in milliwatts",
+        "value": 291504908,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MW"
+      },
+      {
+        "name": "Range remaining",
+        "value": 291504904,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "unit": "VehicleUnit:METER"
+      },
+      {
+        "name": "Tire pressure",
+        "value": 392168201,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:KILOPASCAL"
+      },
+      {
+        "name": "Critically low tire pressure",
+        "value": 392168202,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:KILOPASCAL"
+      },
+      {
+        "name": "Currently selected gear",
+        "value": 289408000,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleGear"
+      },
+      {
+        "name": "CURRENT_GEAR",
+        "value": 289408001,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleGear"
+      },
+      {
+        "name": "Parking brake state.",
+        "value": 287310850,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "PARKING_BRAKE_AUTO_APPLY",
+        "value": 287310851,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Warning for fuel low level.",
+        "value": 287310853,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Night mode",
+        "value": 287310855,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "State of the vehicles turn signals",
+        "value": 289408008,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleTurnSignal"
+      },
+      {
+        "name": "Represents ignition state",
+        "value": 289408009,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleIgnitionState"
+      },
+      {
+        "name": "ABS is active",
+        "value": 287310858,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Traction Control is active",
+        "value": 287310859,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "HVAC_FAN_SPEED",
+        "value": 356517120
+      },
+      {
+        "name": "Fan direction setting",
+        "value": 356517121,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleHvacFanDirection"
+      },
+      {
+        "name": "HVAC current temperature.",
+        "value": 358614274,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "HVAC_TEMPERATURE_SET",
+        "value": 358614275,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "HVAC_DEFROSTER",
+        "value": 320865540,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_AC_ON",
+        "value": 354419973,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "config_flags": "Supported"
+      },
+      {
+        "name": "HVAC_MAX_AC_ON",
+        "value": 354419974,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_MAX_DEFROST_ON",
+        "value": 354419975,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_RECIRC_ON",
+        "value": 354419976,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Enable temperature coupling between areas.",
+        "value": 354419977,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_AUTO_ON",
+        "value": 354419978,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_SEAT_TEMPERATURE",
+        "value": 356517131,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Side Mirror Heat",
+        "value": 339739916,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_STEERING_WHEEL_HEAT",
+        "value": 289408269,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Temperature units for display",
+        "value": 289408270,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "Actual fan speed",
+        "value": 356517135,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "HVAC_POWER_ON",
+        "value": 354419984,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Fan Positions Available",
+        "value": 356582673,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleHvacFanDirection"
+      },
+      {
+        "name": "HVAC_AUTO_RECIRC_ON",
+        "value": 354419986,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat ventilation",
+        "value": 356517139,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_ELECTRIC_DEFROSTER_ON",
+        "value": 320865556,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Suggested values for setting HVAC temperature.",
+        "value": 291570965,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Distance units for display",
+        "value": 289408512,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "Fuel volume units for display",
+        "value": 289408513,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "Tire pressure units for display",
+        "value": 289408514,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "EV battery units for display",
+        "value": 289408515,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "Fuel consumption units for display",
+        "value": 287311364,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Speed units for display",
+        "value": 289408517,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "ANDROID_EPOCH_TIME",
+        "value": 290457094,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE_ONLY",
+        "unit": "VehicleUnit:MILLI_SECS"
+      },
+      {
+        "name": "External encryption binding seed.",
+        "value": 292554247,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Outside temperature",
+        "value": 291505923,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "Property to control power state of application processor",
+        "value": 289475072,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Property to report power state of application processor",
+        "value": 289475073,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "AP_POWER_BOOTUP_REASON",
+        "value": 289409538,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "DISPLAY_BRIGHTNESS",
+        "value": 289409539,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HW_KEY_INPUT",
+        "value": 289475088,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "config_flags": ""
+      },
+      {
+        "name": "HW_ROTARY_INPUT",
+        "value": 289475104,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "data_enum": "RotaryInputType",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Defines a custom OEM partner input event.",
+        "value": 289475120,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "data_enum": "CustomInputType",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "DOOR_POS",
+        "value": 373295872,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Door move",
+        "value": 373295873,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Door lock",
+        "value": 371198722,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Z Position",
+        "value": 339741504,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Z Move",
+        "value": 339741505,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Y Position",
+        "value": 339741506,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Y Move",
+        "value": 339741507,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Lock",
+        "value": 287312708,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Fold",
+        "value": 287312709,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat memory select",
+        "value": 356518784,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Seat memory set",
+        "value": 356518785,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Seatbelt buckled",
+        "value": 354421634,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seatbelt height position",
+        "value": 356518787,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seatbelt height move",
+        "value": 356518788,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_FORE_AFT_POS",
+        "value": 356518789,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_FORE_AFT_MOVE",
+        "value": 356518790,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat backrest angle 1 position",
+        "value": 356518791,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat backrest angle 1 move",
+        "value": 356518792,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat backrest angle 2 position",
+        "value": 356518793,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat backrest angle 2 move",
+        "value": 356518794,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat height position",
+        "value": 356518795,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat height move",
+        "value": 356518796,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat depth position",
+        "value": 356518797,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat depth move",
+        "value": 356518798,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat tilt position",
+        "value": 356518799,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat tilt move",
+        "value": 356518800,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_LUMBAR_FORE_AFT_POS",
+        "value": 356518801,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_LUMBAR_FORE_AFT_MOVE",
+        "value": 356518802,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Lumbar side support position",
+        "value": 356518803,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Lumbar side support move",
+        "value": 356518804,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Headrest height position",
+        "value": 289409941,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Headrest height move",
+        "value": 356518806,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Headrest angle position",
+        "value": 356518807,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Headrest angle move",
+        "value": 356518808,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_HEADREST_FORE_AFT_POS",
+        "value": 356518809,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_HEADREST_FORE_AFT_MOVE",
+        "value": 356518810,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat Occupancy",
+        "value": 356518832,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleSeatOccupancyState"
+      },
+      {
+        "name": "Window Position",
+        "value": 322964416,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Window Move",
+        "value": 322964417,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Window Lock",
+        "value": 320867268,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "VEHICLE_MAP_SERVICE",
+        "value": 299895808,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "OBD2 Live Sensor Data",
+        "value": 299896064,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "OBD2 Freeze Frame Sensor Data",
+        "value": 299896065,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "OBD2 Freeze Frame Information",
+        "value": 299896066,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "OBD2 Freeze Frame Clear",
+        "value": 299896067,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Headlights State",
+        "value": 289410560,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "High beam lights state",
+        "value": 289410561,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Fog light state",
+        "value": 289410562,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Hazard light status",
+        "value": 289410563,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Headlight switch",
+        "value": 289410576,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "High beam light switch",
+        "value": 289410577,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Fog light switch",
+        "value": 289410578,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Hazard light switch",
+        "value": 289410579,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Cabin lights",
+        "value": 289410817,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Cabin lights switch",
+        "value": 289410818,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Reading lights",
+        "value": 356519683,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Reading lights switch",
+        "value": 356519684,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Support customize permissions for vendor properties",
+        "value": 287313669,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Allow disabling optional featurs from vhal.",
+        "value": 286265094,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Defines the initial Android user to be used during initialization.",
+        "value": 299896583,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Defines a request to switch the foreground Android user.",
+        "value": 299896584,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Called by the Android System after an Android user was created.",
+        "value": 299896585,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Called by the Android System after an Android user was removed.",
+        "value": 299896586,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "USER_IDENTIFICATION_ASSOCIATION",
+        "value": 299896587,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "EVS_SERVICE_REQUEST",
+        "value": 289476368,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Defines a request to apply power policy.",
+        "value": 286265121,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "POWER_POLICY_GROUP_REQ",
+        "value": 286265122,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Notifies the current power policy to VHAL layer.",
+        "value": 286265123,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "WATCHDOG_ALIVE",
+        "value": 290459441,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Defines a process terminated by car watchdog and the reason of termination.",
+        "value": 299896626,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Defines an event that VHAL signals to car watchdog as a heartbeat.",
+        "value": 290459443,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Starts the ClusterUI in cluster display.",
+        "value": 289410868,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Changes the state of the cluster display.",
+        "value": 289476405,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Reports the current display state and ClusterUI state.",
+        "value": 299896630,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Requests to change the cluster display state to show some ClusterUI.",
+        "value": 289410871,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Informs the current navigation state.",
+        "value": 292556600,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Electronic Toll Collection card type.",
+        "value": 289410873,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ElectronicTollCollectionCardType"
+      },
+      {
+        "name": "Electronic Toll Collection card status.",
+        "value": 289410874,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ElectronicTollCollectionCardStatus"
+      },
+      {
+        "name": "Front fog lights state",
+        "value": 289410875,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Front fog lights switch",
+        "value": 289410876,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Rear fog lights state",
+        "value": 289410877,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Rear fog lights switch",
+        "value": 289410878,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Indicates the maximum current draw threshold for charging set by the user",
+        "value": 291508031,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "unit": "VehicleUnit:AMPERE"
+      },
+      {
+        "name": "Indicates the maximum charge percent threshold set by the user",
+        "value": 291508032,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Charging state of the car",
+        "value": 289410881,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "EvChargeState"
+      },
+      {
+        "name": "Start or stop charging the EV battery",
+        "value": 287313730,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Estimated charge time remaining in seconds",
+        "value": 289410883,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:SECS"
+      },
+      {
+        "name": "EV_REGENERATIVE_BRAKING_STATE",
+        "value": 289410884,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "EvRegenerativeBrakingState"
+      },
+      {
+        "name": "Indicates if there is a trailer present or not.",
+        "value": 289410885,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "TrailerState"
+      },
+      {
+        "name": "VEHICLE_CURB_WEIGHT",
+        "value": 289410886,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:KILOGRAM"
+      }
+    ]
+  },
+  {
+    "name": "EvsServiceType",
+    "values": [
+      {
+        "name": "REARVIEW",
+        "value": 0
+      },
+      {
+        "name": "SURROUNDVIEW",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "name": "VehiclePropertyChangeMode",
+    "values": [
+      {
+        "name": "STATIC",
+        "value": 0
+      },
+      {
+        "name": "ON_CHANGE",
+        "value": 1
+      },
+      {
+        "name": "CONTINUOUS",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "Obd2CompressionIgnitionMonitors",
+    "values": []
+  },
+  {
+    "name": "VehicleLightState",
+    "values": [
+      {
+        "name": "OFF",
+        "value": 0
+      },
+      {
+        "name": "ON",
+        "value": 1
+      },
+      {
+        "name": "DAYTIME_RUNNING",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "SwitchUserMessageType",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "LEGACY_ANDROID_SWITCH",
+        "value": 1
+      },
+      {
+        "name": "ANDROID_SWITCH",
+        "value": 2
+      },
+      {
+        "name": "VEHICLE_RESPONSE",
+        "value": 3
+      },
+      {
+        "name": "VEHICLE_REQUEST",
+        "value": 4
+      },
+      {
+        "name": "ANDROID_POST_SWITCH",
+        "value": 5
+      }
+    ]
+  },
+  {
+    "name": "PortLocationType",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "FRONT_LEFT",
+        "value": 1
+      },
+      {
+        "name": "FRONT_RIGHT",
+        "value": 2
+      },
+      {
+        "name": "REAR_RIGHT",
+        "value": 3
+      },
+      {
+        "name": "REAR_LEFT",
+        "value": 4
+      },
+      {
+        "name": "FRONT",
+        "value": 5
+      },
+      {
+        "name": "REAR",
+        "value": 6
+      }
+    ]
+  },
+  {
+    "name": "VehiclePropertyStatus",
+    "values": [
+      {
+        "name": "AVAILABLE",
+        "value": 0
+      },
+      {
+        "name": "UNAVAILABLE",
+        "value": 1
+      },
+      {
+        "name": "ERROR",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "VehicleDisplay",
+    "values": [
+      {
+        "name": "MAIN",
+        "value": 0
+      },
+      {
+        "name": "INSTRUMENT_CLUSTER",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "name": "SwitchUserStatus",
+    "values": [
+      {
+        "name": "SUCCESS",
+        "value": 1
+      },
+      {
+        "name": "FAILURE",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "InitialUserInfoRequestType",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "FIRST_BOOT",
+        "value": 1
+      },
+      {
+        "name": "FIRST_BOOT_AFTER_OTA",
+        "value": 2
+      },
+      {
+        "name": "COLD_BOOT",
+        "value": 3
+      },
+      {
+        "name": "RESUME",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "name": "UserIdentificationAssociationSetValue",
+    "values": [
+      {
+        "name": "INVALID",
+        "value": 0
+      },
+      {
+        "name": "ASSOCIATE_CURRENT_USER",
+        "value": 1
+      },
+      {
+        "name": "DISASSOCIATE_CURRENT_USER",
+        "value": 2
+      },
+      {
+        "name": "DISASSOCIATE_ALL_USERS",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "VehicleAreaDoor",
+    "values": [
+      {
+        "name": "ROW_1_LEFT",
+        "value": 1
+      },
+      {
+        "name": "ROW_1_RIGHT",
+        "value": 4
+      },
+      {
+        "name": "ROW_2_LEFT",
+        "value": 16
+      },
+      {
+        "name": "ROW_2_RIGHT",
+        "value": 64
+      },
+      {
+        "name": "ROW_3_LEFT",
+        "value": 256
+      },
+      {
+        "name": "ROW_3_RIGHT",
+        "value": 1024
+      },
+      {
+        "name": "HOOD",
+        "value": 268435456
+      },
+      {
+        "name": "REAR",
+        "value": 536870912
+      }
+    ]
+  },
+  {
+    "name": "VehicleLightSwitch",
+    "values": [
+      {
+        "name": "OFF",
+        "value": 0
+      },
+      {
+        "name": "ON",
+        "value": 1
+      },
+      {
+        "name": "DAYTIME_RUNNING",
+        "value": 2
+      },
+      {
+        "name": "AUTOMATIC",
+        "value": 256
+      }
+    ]
+  },
+  {
+    "name": "VehicleGear",
+    "values": [
+      {
+        "name": "GEAR_UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "GEAR_NEUTRAL",
+        "value": 1
+      },
+      {
+        "name": "GEAR_REVERSE",
+        "value": 2
+      },
+      {
+        "name": "GEAR_PARK",
+        "value": 4
+      },
+      {
+        "name": "GEAR_DRIVE",
+        "value": 8
+      },
+      {
+        "name": "GEAR_1",
+        "value": 16
+      },
+      {
+        "name": "GEAR_2",
+        "value": 32
+      },
+      {
+        "name": "GEAR_3",
+        "value": 64
+      },
+      {
+        "name": "GEAR_4",
+        "value": 128
+      },
+      {
+        "name": "GEAR_5",
+        "value": 256
+      },
+      {
+        "name": "GEAR_6",
+        "value": 512
+      },
+      {
+        "name": "GEAR_7",
+        "value": 1024
+      },
+      {
+        "name": "GEAR_8",
+        "value": 2048
+      },
+      {
+        "name": "GEAR_9",
+        "value": 4096
+      }
+    ]
+  },
+  {
+    "name": "Obd2IgnitionMonitorKind",
+    "values": [
+      {
+        "name": "SPARK",
+        "value": 0
+      },
+      {
+        "name": "COMPRESSION",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "name": "CustomInputType",
+    "values": [
+      {
+        "name": "CUSTOM_EVENT_F1",
+        "value": 1001
+      },
+      {
+        "name": "CUSTOM_EVENT_F2",
+        "value": 1002
+      },
+      {
+        "name": "CUSTOM_EVENT_F3",
+        "value": 1003
+      },
+      {
+        "name": "CUSTOM_EVENT_F4",
+        "value": 1004
+      },
+      {
+        "name": "CUSTOM_EVENT_F5",
+        "value": 1005
+      },
+      {
+        "name": "CUSTOM_EVENT_F6",
+        "value": 1006
+      },
+      {
+        "name": "CUSTOM_EVENT_F7",
+        "value": 1007
+      },
+      {
+        "name": "CUSTOM_EVENT_F8",
+        "value": 1008
+      },
+      {
+        "name": "CUSTOM_EVENT_F9",
+        "value": 1009
+      },
+      {
+        "name": "CUSTOM_EVENT_F10",
+        "value": 1010
+      }
+    ]
+  },
+  {
+    "name": "VehicleApPowerStateReport",
+    "values": [
+      {
+        "name": "WAIT_FOR_VHAL",
+        "value": 1
+      },
+      {
+        "name": "DEEP_SLEEP_ENTRY",
+        "value": 2
+      },
+      {
+        "name": "DEEP_SLEEP_EXIT",
+        "value": 3
+      },
+      {
+        "name": "SHUTDOWN_POSTPONE",
+        "value": 4
+      },
+      {
+        "name": "SHUTDOWN_START",
+        "value": 5
+      },
+      {
+        "name": "ON",
+        "value": 6
+      },
+      {
+        "name": "SHUTDOWN_PREPARE",
+        "value": 7
+      },
+      {
+        "name": "SHUTDOWN_CANCELLED",
+        "value": 8
+      },
+      {
+        "name": "HIBERNATION_ENTRY",
+        "value": 9
+      },
+      {
+        "name": "HIBERNATION_EXIT",
+        "value": 10
+      }
+    ]
+  },
+  {
+    "name": "VmsMessageWithLayerIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "LAYER_TYPE",
+        "value": 1
+      },
+      {
+        "name": "LAYER_SUBTYPE",
+        "value": 2
+      },
+      {
+        "name": "LAYER_VERSION",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "EvRegenerativeBrakingState",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "DISABLED",
+        "value": 1
+      },
+      {
+        "name": "PARTIALLY_ENABLED",
+        "value": 2
+      },
+      {
+        "name": "FULLY_ENABLED",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "VehiclePropertyGroup",
+    "values": [
+      {
+        "name": "SYSTEM",
+        "value": 268435456
+      },
+      {
+        "name": "VENDOR",
+        "value": 536870912
+      },
+      {
+        "name": "MASK",
+        "value": 4026531840
+      }
+    ]
+  },
+  {
+    "name": "VehicleIgnitionState",
+    "values": [
+      {
+        "name": "UNDEFINED",
+        "value": 0
+      },
+      {
+        "name": "LOCK",
+        "value": 1
+      },
+      {
+        "name": "OFF",
+        "value": 2
+      },
+      {
+        "name": "ACC",
+        "value": 3
+      },
+      {
+        "name": "ON",
+        "value": 4
+      },
+      {
+        "name": "START",
+        "value": 5
+      }
+    ]
+  },
+  {
+    "name": "VehicleHwKeyInputAction",
+    "values": [
+      {
+        "name": "ACTION_DOWN",
+        "value": 0
+      },
+      {
+        "name": "ACTION_UP",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "name": "DiagnosticIntegerSensorIndex",
+    "values": [
+      {
+        "name": "FUEL_SYSTEM_STATUS",
+        "value": 0
+      },
+      {
+        "name": "MALFUNCTION_INDICATOR_LIGHT_ON",
+        "value": 1
+      },
+      {
+        "name": "IGNITION_MONITORS_SUPPORTED",
+        "value": 2
+      },
+      {
+        "name": "IGNITION_SPECIFIC_MONITORS",
+        "value": 3
+      },
+      {
+        "name": "INTAKE_AIR_TEMPERATURE",
+        "value": 4
+      },
+      {
+        "name": "COMMANDED_SECONDARY_AIR_STATUS",
+        "value": 5
+      },
+      {
+        "name": "NUM_OXYGEN_SENSORS_PRESENT",
+        "value": 6
+      },
+      {
+        "name": "RUNTIME_SINCE_ENGINE_START",
+        "value": 7
+      },
+      {
+        "name": "DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON",
+        "value": 8
+      },
+      {
+        "name": "WARMUPS_SINCE_CODES_CLEARED",
+        "value": 9
+      },
+      {
+        "name": "DISTANCE_TRAVELED_SINCE_CODES_CLEARED",
+        "value": 10
+      },
+      {
+        "name": "ABSOLUTE_BAROMETRIC_PRESSURE",
+        "value": 11
+      },
+      {
+        "name": "CONTROL_MODULE_VOLTAGE",
+        "value": 12
+      },
+      {
+        "name": "AMBIENT_AIR_TEMPERATURE",
+        "value": 13
+      },
+      {
+        "name": "TIME_WITH_MALFUNCTION_LIGHT_ON",
+        "value": 14
+      },
+      {
+        "name": "TIME_SINCE_TROUBLE_CODES_CLEARED",
+        "value": 15
+      },
+      {
+        "name": "MAX_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 16
+      },
+      {
+        "name": "MAX_OXYGEN_SENSOR_VOLTAGE",
+        "value": 17
+      },
+      {
+        "name": "MAX_OXYGEN_SENSOR_CURRENT",
+        "value": 18
+      },
+      {
+        "name": "MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE",
+        "value": 19
+      },
+      {
+        "name": "MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR",
+        "value": 20
+      },
+      {
+        "name": "FUEL_TYPE",
+        "value": 21
+      },
+      {
+        "name": "FUEL_RAIL_ABSOLUTE_PRESSURE",
+        "value": 22
+      },
+      {
+        "name": "ENGINE_OIL_TEMPERATURE",
+        "value": 23
+      },
+      {
+        "name": "DRIVER_DEMAND_PERCENT_TORQUE",
+        "value": 24
+      },
+      {
+        "name": "ENGINE_ACTUAL_PERCENT_TORQUE",
+        "value": 25
+      },
+      {
+        "name": "ENGINE_REFERENCE_PERCENT_TORQUE",
+        "value": 26
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_IDLE",
+        "value": 27
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT1",
+        "value": 28
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT2",
+        "value": 29
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT3",
+        "value": 30
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT4",
+        "value": 31
+      }
+    ]
+  },
+  {
+    "name": "UserIdentificationAssociationValue",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 1
+      },
+      {
+        "name": "ASSOCIATED_CURRENT_USER",
+        "value": 2
+      },
+      {
+        "name": "ASSOCIATED_ANOTHER_USER",
+        "value": 3
+      },
+      {
+        "name": "NOT_ASSOCIATED_ANY_USER",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "name": "VmsBaseMessageIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      }
+    ]
+  },
+  {
+    "name": "DiagnosticFloatSensorIndex",
+    "values": [
+      {
+        "name": "CALCULATED_ENGINE_LOAD",
+        "value": 0
+      },
+      {
+        "name": "ENGINE_COOLANT_TEMPERATURE",
+        "value": 1
+      },
+      {
+        "name": "SHORT_TERM_FUEL_TRIM_BANK1",
+        "value": 2
+      },
+      {
+        "name": "LONG_TERM_FUEL_TRIM_BANK1",
+        "value": 3
+      },
+      {
+        "name": "SHORT_TERM_FUEL_TRIM_BANK2",
+        "value": 4
+      },
+      {
+        "name": "LONG_TERM_FUEL_TRIM_BANK2",
+        "value": 5
+      },
+      {
+        "name": "FUEL_PRESSURE",
+        "value": 6
+      },
+      {
+        "name": "INTAKE_MANIFOLD_ABSOLUTE_PRESSURE",
+        "value": 7
+      },
+      {
+        "name": "ENGINE_RPM",
+        "value": 8
+      },
+      {
+        "name": "VEHICLE_SPEED",
+        "value": 9
+      },
+      {
+        "name": "TIMING_ADVANCE",
+        "value": 10
+      },
+      {
+        "name": "MAF_AIR_FLOW_RATE",
+        "value": 11
+      },
+      {
+        "name": "THROTTLE_POSITION",
+        "value": 12
+      },
+      {
+        "name": "OXYGEN_SENSOR1_VOLTAGE",
+        "value": 13
+      },
+      {
+        "name": "OXYGEN_SENSOR1_SHORT_TERM_FUEL_TRIM",
+        "value": 14
+      },
+      {
+        "name": "OXYGEN_SENSOR1_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 15
+      },
+      {
+        "name": "OXYGEN_SENSOR2_VOLTAGE",
+        "value": 16
+      },
+      {
+        "name": "OXYGEN_SENSOR2_SHORT_TERM_FUEL_TRIM",
+        "value": 17
+      },
+      {
+        "name": "OXYGEN_SENSOR2_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 18
+      },
+      {
+        "name": "OXYGEN_SENSOR3_VOLTAGE",
+        "value": 19
+      },
+      {
+        "name": "OXYGEN_SENSOR3_SHORT_TERM_FUEL_TRIM",
+        "value": 20
+      },
+      {
+        "name": "OXYGEN_SENSOR3_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 21
+      },
+      {
+        "name": "OXYGEN_SENSOR4_VOLTAGE",
+        "value": 22
+      },
+      {
+        "name": "OXYGEN_SENSOR4_SHORT_TERM_FUEL_TRIM",
+        "value": 23
+      },
+      {
+        "name": "OXYGEN_SENSOR4_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 24
+      },
+      {
+        "name": "OXYGEN_SENSOR5_VOLTAGE",
+        "value": 25
+      },
+      {
+        "name": "OXYGEN_SENSOR5_SHORT_TERM_FUEL_TRIM",
+        "value": 26
+      },
+      {
+        "name": "OXYGEN_SENSOR5_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 27
+      },
+      {
+        "name": "OXYGEN_SENSOR6_VOLTAGE",
+        "value": 28
+      },
+      {
+        "name": "OXYGEN_SENSOR6_SHORT_TERM_FUEL_TRIM",
+        "value": 29
+      },
+      {
+        "name": "OXYGEN_SENSOR6_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 30
+      },
+      {
+        "name": "OXYGEN_SENSOR7_VOLTAGE",
+        "value": 31
+      },
+      {
+        "name": "OXYGEN_SENSOR7_SHORT_TERM_FUEL_TRIM",
+        "value": 32
+      },
+      {
+        "name": "OXYGEN_SENSOR7_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 33
+      },
+      {
+        "name": "OXYGEN_SENSOR8_VOLTAGE",
+        "value": 34
+      },
+      {
+        "name": "OXYGEN_SENSOR8_SHORT_TERM_FUEL_TRIM",
+        "value": 35
+      },
+      {
+        "name": "OXYGEN_SENSOR8_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 36
+      },
+      {
+        "name": "FUEL_RAIL_PRESSURE",
+        "value": 37
+      },
+      {
+        "name": "FUEL_RAIL_GAUGE_PRESSURE",
+        "value": 38
+      },
+      {
+        "name": "COMMANDED_EXHAUST_GAS_RECIRCULATION",
+        "value": 39
+      },
+      {
+        "name": "EXHAUST_GAS_RECIRCULATION_ERROR",
+        "value": 40
+      },
+      {
+        "name": "COMMANDED_EVAPORATIVE_PURGE",
+        "value": 41
+      },
+      {
+        "name": "FUEL_TANK_LEVEL_INPUT",
+        "value": 42
+      },
+      {
+        "name": "EVAPORATION_SYSTEM_VAPOR_PRESSURE",
+        "value": 43
+      },
+      {
+        "name": "CATALYST_TEMPERATURE_BANK1_SENSOR1",
+        "value": 44
+      },
+      {
+        "name": "CATALYST_TEMPERATURE_BANK2_SENSOR1",
+        "value": 45
+      },
+      {
+        "name": "CATALYST_TEMPERATURE_BANK1_SENSOR2",
+        "value": 46
+      },
+      {
+        "name": "CATALYST_TEMPERATURE_BANK2_SENSOR2",
+        "value": 47
+      },
+      {
+        "name": "ABSOLUTE_LOAD_VALUE",
+        "value": 48
+      },
+      {
+        "name": "FUEL_AIR_COMMANDED_EQUIVALENCE_RATIO",
+        "value": 49
+      },
+      {
+        "name": "RELATIVE_THROTTLE_POSITION",
+        "value": 50
+      },
+      {
+        "name": "ABSOLUTE_THROTTLE_POSITION_B",
+        "value": 51
+      },
+      {
+        "name": "ABSOLUTE_THROTTLE_POSITION_C",
+        "value": 52
+      },
+      {
+        "name": "ACCELERATOR_PEDAL_POSITION_D",
+        "value": 53
+      },
+      {
+        "name": "ACCELERATOR_PEDAL_POSITION_E",
+        "value": 54
+      },
+      {
+        "name": "ACCELERATOR_PEDAL_POSITION_F",
+        "value": 55
+      },
+      {
+        "name": "COMMANDED_THROTTLE_ACTUATOR",
+        "value": 56
+      },
+      {
+        "name": "ETHANOL_FUEL_PERCENTAGE",
+        "value": 57
+      },
+      {
+        "name": "ABSOLUTE_EVAPORATION_SYSTEM_VAPOR_PRESSURE",
+        "value": 58
+      },
+      {
+        "name": "SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK1",
+        "value": 59
+      },
+      {
+        "name": "SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK2",
+        "value": 60
+      },
+      {
+        "name": "SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK3",
+        "value": 61
+      },
+      {
+        "name": "SHORT_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK4",
+        "value": 62
+      },
+      {
+        "name": "LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK1",
+        "value": 63
+      },
+      {
+        "name": "LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK2",
+        "value": 64
+      },
+      {
+        "name": "LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK3",
+        "value": 65
+      },
+      {
+        "name": "LONG_TERM_SECONDARY_OXYGEN_SENSOR_TRIM_BANK4",
+        "value": 66
+      },
+      {
+        "name": "RELATIVE_ACCELERATOR_PEDAL_POSITION",
+        "value": 67
+      },
+      {
+        "name": "HYBRID_BATTERY_PACK_REMAINING_LIFE",
+        "value": 68
+      },
+      {
+        "name": "FUEL_INJECTION_TIMING",
+        "value": 69
+      },
+      {
+        "name": "ENGINE_FUEL_RATE",
+        "value": 70
+      }
+    ]
+  },
+  {
+    "name": "VmsMessageWithLayerAndPublisherIdIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "LAYER_TYPE",
+        "value": 1
+      },
+      {
+        "name": "LAYER_SUBTYPE",
+        "value": 2
+      },
+      {
+        "name": "LAYER_VERSION",
+        "value": 3
+      },
+      {
+        "name": "PUBLISHER_ID",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "name": "FuelType",
+    "values": [
+      {
+        "name": "FUEL_TYPE_UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "FUEL_TYPE_UNLEADED",
+        "value": 1
+      },
+      {
+        "name": "FUEL_TYPE_LEADED",
+        "value": 2
+      },
+      {
+        "name": "FUEL_TYPE_DIESEL_1",
+        "value": 3
+      },
+      {
+        "name": "FUEL_TYPE_DIESEL_2",
+        "value": 4
+      },
+      {
+        "name": "FUEL_TYPE_BIODIESEL",
+        "value": 5
+      },
+      {
+        "name": "FUEL_TYPE_E85",
+        "value": 6
+      },
+      {
+        "name": "FUEL_TYPE_LPG",
+        "value": 7
+      },
+      {
+        "name": "FUEL_TYPE_CNG",
+        "value": 8
+      },
+      {
+        "name": "FUEL_TYPE_LNG",
+        "value": 9
+      },
+      {
+        "name": "FUEL_TYPE_ELECTRIC",
+        "value": 10
+      },
+      {
+        "name": "FUEL_TYPE_HYDROGEN",
+        "value": 11
+      },
+      {
+        "name": "FUEL_TYPE_OTHER",
+        "value": 12
+      }
+    ]
+  },
+  {
+    "name": "VehicleApPowerStateReq",
+    "values": [
+      {
+        "name": "ON",
+        "value": 0
+      },
+      {
+        "name": "SHUTDOWN_PREPARE",
+        "value": 1
+      },
+      {
+        "name": "CANCEL_SHUTDOWN",
+        "value": 2
+      },
+      {
+        "name": "FINISHED",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "VmsMessageType",
+    "values": [
+      {
+        "name": "SUBSCRIBE",
+        "value": 1
+      },
+      {
+        "name": "SUBSCRIBE_TO_PUBLISHER",
+        "value": 2
+      },
+      {
+        "name": "UNSUBSCRIBE",
+        "value": 3
+      },
+      {
+        "name": "UNSUBSCRIBE_TO_PUBLISHER",
+        "value": 4
+      },
+      {
+        "name": "OFFERING",
+        "value": 5
+      },
+      {
+        "name": "AVAILABILITY_REQUEST",
+        "value": 6
+      },
+      {
+        "name": "SUBSCRIPTIONS_REQUEST",
+        "value": 7
+      },
+      {
+        "name": "AVAILABILITY_RESPONSE",
+        "value": 8
+      },
+      {
+        "name": "AVAILABILITY_CHANGE",
+        "value": 9
+      },
+      {
+        "name": "SUBSCRIPTIONS_RESPONSE",
+        "value": 10
+      },
+      {
+        "name": "SUBSCRIPTIONS_CHANGE",
+        "value": 11
+      },
+      {
+        "name": "DATA",
+        "value": 12
+      },
+      {
+        "name": "PUBLISHER_ID_REQUEST",
+        "value": 13
+      },
+      {
+        "name": "PUBLISHER_ID_RESPONSE",
+        "value": 14
+      },
+      {
+        "name": "PUBLISHER_INFORMATION_REQUEST",
+        "value": 15
+      },
+      {
+        "name": "PUBLISHER_INFORMATION_RESPONSE",
+        "value": 16
+      },
+      {
+        "name": "START_SESSION",
+        "value": 17
+      }
+    ]
+  },
+  {
+    "name": "Obd2CommonIgnitionMonitors",
+    "values": []
+  },
+  {
+    "name": "UserIdentificationAssociationType",
+    "values": [
+      {
+        "name": "INVALID",
+        "value": 0
+      },
+      {
+        "name": "KEY_FOB",
+        "value": 1
+      },
+      {
+        "name": "CUSTOM_1",
+        "value": 101
+      },
+      {
+        "name": "CUSTOM_2",
+        "value": 102
+      },
+      {
+        "name": "CUSTOM_3",
+        "value": 103
+      },
+      {
+        "name": "CUSTOM_4",
+        "value": 104
+      }
+    ]
+  },
+  {
+    "name": "EvConnectorType",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "IEC_TYPE_1_AC",
+        "value": 1
+      },
+      {
+        "name": "IEC_TYPE_2_AC",
+        "value": 2
+      },
+      {
+        "name": "IEC_TYPE_3_AC",
+        "value": 3
+      },
+      {
+        "name": "IEC_TYPE_4_DC",
+        "value": 4
+      },
+      {
+        "name": "IEC_TYPE_1_CCS_DC",
+        "value": 5
+      },
+      {
+        "name": "IEC_TYPE_2_CCS_DC",
+        "value": 6
+      },
+      {
+        "name": "TESLA_ROADSTER",
+        "value": 7
+      },
+      {
+        "name": "TESLA_HPWC",
+        "value": 8
+      },
+      {
+        "name": "TESLA_SUPERCHARGER",
+        "value": 9
+      },
+      {
+        "name": "GBT_AC",
+        "value": 10
+      },
+      {
+        "name": "GBT_DC",
+        "value": 11
+      },
+      {
+        "name": "OTHER",
+        "value": 101
+      }
+    ]
+  },
+  {
+    "name": "VehicleApPowerStateShutdownParam",
+    "values": [
+      {
+        "name": "SHUTDOWN_IMMEDIATELY",
+        "value": 1
+      },
+      {
+        "name": "CAN_SLEEP",
+        "value": 2
+      },
+      {
+        "name": "SHUTDOWN_ONLY",
+        "value": 3
+      },
+      {
+        "name": "SLEEP_IMMEDIATELY",
+        "value": 4
+      },
+      {
+        "name": "HIBERNATE_IMMEDIATELY",
+        "value": 5
+      },
+      {
+        "name": "CAN_HIBERNATE",
+        "value": 6
+      }
+    ]
+  },
+  {
+    "name": "VmsOfferingMessageIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "PUBLISHER_ID",
+        "value": 1
+      },
+      {
+        "name": "NUMBER_OF_OFFERS",
+        "value": 2
+      },
+      {
+        "name": "OFFERING_START",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "VehicleAreaSeat",
+    "values": [
+      {
+        "name": "ROW_1_LEFT",
+        "value": 1
+      },
+      {
+        "name": "ROW_1_CENTER",
+        "value": 2
+      },
+      {
+        "name": "ROW_1_RIGHT",
+        "value": 4
+      },
+      {
+        "name": "ROW_2_LEFT",
+        "value": 16
+      },
+      {
+        "name": "ROW_2_CENTER",
+        "value": 32
+      },
+      {
+        "name": "ROW_2_RIGHT",
+        "value": 64
+      },
+      {
+        "name": "ROW_3_LEFT",
+        "value": 256
+      },
+      {
+        "name": "ROW_3_CENTER",
+        "value": 512
+      },
+      {
+        "name": "ROW_3_RIGHT",
+        "value": 1024
+      }
+    ]
+  },
+  {
+    "name": "VehicleVendorPermission",
+    "values": [
+      {
+        "name": "PERMISSION_DEFAULT",
+        "value": 0
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_WINDOW",
+        "value": 1
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_WINDOW",
+        "value": 2
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_DOOR",
+        "value": 3
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_DOOR",
+        "value": 4
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_SEAT",
+        "value": 5
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_SEAT",
+        "value": 6
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_MIRROR",
+        "value": 7
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_MIRROR",
+        "value": 8
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_INFO",
+        "value": 9
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_INFO",
+        "value": 10
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_ENGINE",
+        "value": 11
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_ENGINE",
+        "value": 12
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_HVAC",
+        "value": 13
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_HVAC",
+        "value": 14
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_LIGHT",
+        "value": 15
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_LIGHT",
+        "value": 16
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_1",
+        "value": 65536
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_1",
+        "value": 69632
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_2",
+        "value": 131072
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_2",
+        "value": 135168
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_3",
+        "value": 196608
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_3",
+        "value": 200704
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_4",
+        "value": 262144
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_4",
+        "value": 266240
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_5",
+        "value": 327680
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_5",
+        "value": 331776
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_6",
+        "value": 393216
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_6",
+        "value": 397312
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_7",
+        "value": 458752
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_7",
+        "value": 462848
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_8",
+        "value": 524288
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_8",
+        "value": 528384
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_9",
+        "value": 589824
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_9",
+        "value": 593920
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_10",
+        "value": 655360
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_10",
+        "value": 659456
+      },
+      {
+        "name": "PERMISSION_NOT_ACCESSIBLE",
+        "value": 4026531840
+      }
+    ]
+  },
+  {
+    "name": "VehiclePropertyAccess",
+    "values": [
+      {
+        "name": "NONE",
+        "value": 0
+      },
+      {
+        "name": "READ",
+        "value": 1
+      },
+      {
+        "name": "WRITE",
+        "value": 2
+      },
+      {
+        "name": "READ_WRITE",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "VmsAvailabilityStateIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "SEQUENCE_NUMBER",
+        "value": 1
+      },
+      {
+        "name": "NUMBER_OF_ASSOCIATED_LAYERS",
+        "value": 2
+      },
+      {
+        "name": "LAYERS_START",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "name": "Obd2SparkIgnitionMonitors",
+    "values": []
+  },
+  {
+    "name": "VehicleTurnSignal",
+    "values": [
+      {
+        "name": "NONE",
+        "value": 0
+      },
+      {
+        "name": "RIGHT",
+        "value": 1
+      },
+      {
+        "name": "LEFT",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "name": "VmsPublisherInformationIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "PUBLISHER_ID",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "name": "RotaryInputType",
+    "values": [
+      {
+        "name": "ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION",
+        "value": 0
+      },
+      {
+        "name": "ROTARY_INPUT_TYPE_AUDIO_VOLUME",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "name": "Obd2FuelSystemStatus",
+    "values": [
+      {
+        "name": "OPEN_INSUFFICIENT_ENGINE_TEMPERATURE",
+        "value": 1
+      },
+      {
+        "name": "CLOSED_LOOP",
+        "value": 2
+      },
+      {
+        "name": "OPEN_ENGINE_LOAD_OR_DECELERATION",
+        "value": 4
+      },
+      {
+        "name": "OPEN_SYSTEM_FAILURE",
+        "value": 8
+      },
+      {
+        "name": "CLOSED_LOOP_BUT_FEEDBACK_FAULT",
+        "value": 16
+      }
+    ]
+  }
+]
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py b/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py
new file mode 100755
index 0000000..b2eb172
--- /dev/null
+++ b/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python3
+
+#
+# Script for generation of VHAL properties metadata .json from AIDL interface
+#
+# This metadata is used to display human property names, names of enum
+# data types for their values, change and access modes and other information,
+# available from AIDL block comments, but not at runtime.
+#
+# Usage example:
+#  ./emu_metadata/generate_emulator_metadata.py android/hardware/automotive/vehicle $OUT/android.hardware.automotive.vehicle-types-meta.json
+#  (Note, that the resulting file has to match a '*types-meta.json' pattern to be parsed by the emulator).
+#
+
+import json
+import os
+import re
+import sys
+
+from pathlib import Path
+
+RE_ENUM = re.compile(r"\s*enum\s+(\w*) {\n(.*)}", re.MULTILINE | re.DOTALL)
+RE_COMMENT = re.compile(r"(?:(?:\/\*\*)((?:.|\n)*?)(?:\*\/))?(?:\n|^)\s*(\w*)(?:\s+=\s*)?((?:[a-zA-Z0-9]|\s|\+|)*),", re.DOTALL)
+RE_BLOCK_COMMENT_TITLE = re.compile("^(?:\s|\*)*((?:\w|\s|\.)*)\n(?:\s|\*)*(?:\n|$)")
+RE_BLOCK_COMMENT_ANNOTATION = re.compile("^(?:\s|\*)*@(\w*)\s+((?:\w|:)*)", re.MULTILINE)
+RE_HEX_NUMBER = re.compile("([0-9A-Fa-fxX]+)")
+
+
+class JEnum:
+    def __init__(self, name):
+        self.name = name
+        self.values = []
+
+
+class Converter:
+    # Only addition is supported for now, but that covers all existing properties except
+    # OBD diagnostics, which use bitwise shifts
+    def calculateValue(self, expression, default_value):
+        numbers = RE_HEX_NUMBER.findall(expression)
+        if len(numbers) == 0:
+            return default_value
+        result = 0
+        base = 10
+        if numbers[0].lower().startswith("0x"):
+            base = 16
+        for number in numbers:
+            result += int(number, base)
+        return result
+
+    def parseBlockComment(self, value, blockComment):
+        titles = RE_BLOCK_COMMENT_TITLE.findall(blockComment)
+        for title in titles:
+            value['name'] = title
+            break
+        annots_res = RE_BLOCK_COMMENT_ANNOTATION.findall(blockComment)
+        for annot in annots_res:
+            value[annot[0]] = annot[1]
+
+    def parseEnumContents(self, enum: JEnum, enumValue):
+        matches = RE_COMMENT.findall(enumValue)
+        defaultValue = 0
+        for match in matches:
+            value = dict()
+            value['name'] = match[1]
+            value['value'] = self.calculateValue(match[2], defaultValue)
+            defaultValue = value['value'] + 1
+            if enum.name == "VehicleProperty":
+                block_comment = match[0]
+                self.parseBlockComment(value, block_comment)
+            enum.values.append(value)
+
+    def convert(self, input):
+        text = Path(input).read_text()
+        matches = RE_ENUM.findall(text)
+        jenums = []
+        for match in matches:
+            enum = JEnum(match[0])
+            self.parseEnumContents(enum, match[1])
+            jenums.append(enum)
+        return jenums
+
+def main():
+    if (len(sys.argv) != 3):
+        print("Usage: ", sys.argv[0], " INPUT_PATH OUTPUT")
+        sys.exit(1)
+    aidl_path = sys.argv[1]
+    out_path = sys.argv[2]
+    result = []
+    for file in os.listdir(aidl_path):
+        result.extend(Converter().convert(os.path.join(aidl_path, file)))
+    json_result = json.dumps(result, default=vars, indent=2)
+    with open(out_path, 'w') as f:
+        f.write(json_result)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
new file mode 100644
index 0000000..d0c6e83
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehicleProperty = {
+        {VehicleProperty::INFO_VIN, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_MAKE, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_MODEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_MODEL_YEAR, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_FUEL_CAPACITY, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_FUEL_TYPE, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_EV_BATTERY_CAPACITY, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_EV_CONNECTOR_TYPE, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_FUEL_DOOR_LOCATION, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_EV_PORT_LOCATION, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_DRIVER_SEAT, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_ODOMETER, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_VEHICLE_SPEED, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_STEERING_ANGLE, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_REAR_STEERING_ANGLE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_COOLANT_TEMP, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_OIL_LEVEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_OIL_TEMP, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_RPM, VehiclePropertyAccess::READ},
+        {VehicleProperty::WHEEL_TICK, VehiclePropertyAccess::READ},
+        {VehicleProperty::FUEL_LEVEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::FUEL_DOOR_OPEN, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_BATTERY_LEVEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_CHARGE_PORT_OPEN, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::RANGE_REMAINING, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::TIRE_PRESSURE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::GEAR_SELECTION, VehiclePropertyAccess::READ},
+        {VehicleProperty::CURRENT_GEAR, VehiclePropertyAccess::READ},
+        {VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyAccess::READ},
+        {VehicleProperty::PARKING_BRAKE_AUTO_APPLY, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FUEL_LEVEL_LOW, VehiclePropertyAccess::READ},
+        {VehicleProperty::NIGHT_MODE, VehiclePropertyAccess::READ},
+        {VehicleProperty::TURN_SIGNAL_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::IGNITION_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ABS_ACTIVE, VehiclePropertyAccess::READ},
+        {VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess::READ},
+        {VehicleProperty::HVAC_TEMPERATURE_SET, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_DEFROSTER, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_AC_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_MAX_AC_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_MAX_DEFROST_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_RECIRC_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_DUAL_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_AUTO_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_SEAT_TEMPERATURE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_SIDE_MIRROR_HEAT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_STEERING_WHEEL_HEAT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyAccess::READ},
+        {VehicleProperty::HVAC_POWER_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HVAC_AUTO_RECIRC_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_SEAT_VENTILATION, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DISTANCE_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_BATTERY_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EXTERNAL_CAR_TIME, VehiclePropertyAccess::READ},
+        {VehicleProperty::ANDROID_EPOCH_TIME, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::ENV_OUTSIDE_TEMPERATURE, VehiclePropertyAccess::READ},
+        {VehicleProperty::AP_POWER_STATE_REQ, VehiclePropertyAccess::READ},
+        {VehicleProperty::AP_POWER_STATE_REPORT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyAccess::READ},
+        {VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HW_KEY_INPUT, VehiclePropertyAccess::READ},
+        {VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyAccess::READ},
+        {VehicleProperty::HW_MOTION_INPUT, VehiclePropertyAccess::READ},
+        {VehicleProperty::HW_ROTARY_INPUT, VehiclePropertyAccess::READ},
+        {VehicleProperty::HW_CUSTOM_INPUT, VehiclePropertyAccess::READ},
+        {VehicleProperty::DOOR_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DOOR_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DOOR_LOCK, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DOOR_CHILD_LOCK_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_Z_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_Z_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_Y_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_Y_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_LOCK, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_FOLD, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_AUTO_TILT_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_MEMORY_SELECT, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::SEAT_MEMORY_SET, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::SEAT_BELT_BUCKLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BELT_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BELT_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_DEPTH_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_DEPTH_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_TILT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_TILT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyAccess::READ},
+        {VehicleProperty::WINDOW_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::WINDOW_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::WINDOW_LOCK, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::WINDSHIELD_WIPERS_PERIOD, VehiclePropertyAccess::READ},
+        {VehicleProperty::WINDSHIELD_WIPERS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::WINDSHIELD_WIPERS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::GLOVE_BOX_DOOR_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyAccess::READ},
+        {VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyAccess::READ},
+        {VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyAccess::READ},
+        {VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess::READ},
+        {VehicleProperty::OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::HEADLIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::FOG_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HAZARD_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HEADLIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FOG_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HAZARD_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CABIN_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CABIN_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::READING_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::READING_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyAccess::READ},
+        {VehicleProperty::DISABLED_OPTIONAL_FEATURES, VehiclePropertyAccess::READ},
+        {VehicleProperty::INITIAL_USER_INFO, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SWITCH_USER, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CREATE_USER, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::REMOVE_USER, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EVS_SERVICE_REQUEST, VehiclePropertyAccess::READ},
+        {VehicleProperty::POWER_POLICY_REQ, VehiclePropertyAccess::READ},
+        {VehicleProperty::POWER_POLICY_GROUP_REQ, VehiclePropertyAccess::READ},
+        {VehicleProperty::CURRENT_POWER_POLICY, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::WATCHDOG_ALIVE, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::WATCHDOG_TERMINATED_PROCESS, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::VHAL_HEARTBEAT, VehiclePropertyAccess::READ},
+        {VehicleProperty::CLUSTER_SWITCH_UI, VehiclePropertyAccess::READ},
+        {VehicleProperty::CLUSTER_DISPLAY_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CLUSTER_REPORT_STATE, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::CLUSTER_REQUEST_DISPLAY, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::CLUSTER_NAVIGATION_STATE, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyAccess::READ},
+        {VehicleProperty::FRONT_FOG_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::REAR_FOG_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::REAR_FOG_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_PERCENT_LIMIT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_CHARGE_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_TIME_REMAINING, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::TRAILER_PRESENT, VehiclePropertyAccess::READ},
+        {VehicleProperty::VEHICLE_CURB_WEIGHT, VehiclePropertyAccess::READ},
+        {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyAccess::READ},
+        {VehicleProperty::SUPPORTED_PROPERTY_IDS, VehiclePropertyAccess::READ},
+        {VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::VEHICLE_IN_USE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::BLIND_SPOT_WARNING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CRUISE_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CRUISE_CONTROL_TYPE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CRUISE_CONTROL_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CRUISE_CONTROL_COMMAND, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyAccess::READ},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess::READ},
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+}  // aidl
+
+#endif  // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp b/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
new file mode 100644
index 0000000..11d3693
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_headers {
+    name: "IVehicleGeneratedHeaders",
+    vendor_available: true,
+    local_include_dirs: ["."],
+    export_include_dirs: ["."],
+    defaults: ["VehicleHalInterfaceDefaults"],
+}
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
new file mode 100644
index 0000000..48532c9
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehicleProperty = {
+        {VehicleProperty::INFO_VIN, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_MAKE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_MODEL, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_MODEL_YEAR, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_FUEL_CAPACITY, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_FUEL_TYPE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_EV_BATTERY_CAPACITY, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_EV_CONNECTOR_TYPE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_FUEL_DOOR_LOCATION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_EV_PORT_LOCATION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_DRIVER_SEAT, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::PERF_ODOMETER, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::PERF_VEHICLE_SPEED, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::PERF_STEERING_ANGLE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::PERF_REAR_STEERING_ANGLE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::ENGINE_COOLANT_TEMP, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::ENGINE_OIL_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ENGINE_OIL_TEMP, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::ENGINE_RPM, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::WHEEL_TICK, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::FUEL_LEVEL, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::FUEL_DOOR_OPEN, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_BATTERY_LEVEL, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_PORT_OPEN, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::RANGE_REMAINING, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::TIRE_PRESSURE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::GEAR_SELECTION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CURRENT_GEAR, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::PARKING_BRAKE_AUTO_APPLY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FUEL_LEVEL_LOW, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::NIGHT_MODE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TURN_SIGNAL_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::IGNITION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ABS_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_TEMPERATURE_SET, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_DEFROSTER, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_AC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_MAX_AC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_MAX_DEFROST_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_RECIRC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_DUAL_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_AUTO_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_SEAT_TEMPERATURE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_SIDE_MIRROR_HEAT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_STEERING_WHEEL_HEAT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_POWER_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::HVAC_AUTO_RECIRC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_SEAT_VENTILATION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DISTANCE_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_BATTERY_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EXTERNAL_CAR_TIME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ANDROID_EPOCH_TIME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ENV_OUTSIDE_TEMPERATURE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::AP_POWER_STATE_REQ, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::AP_POWER_STATE_REPORT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_KEY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_MOTION_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_ROTARY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_CUSTOM_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DOOR_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DOOR_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DOOR_LOCK, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DOOR_CHILD_LOCK_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_Z_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_Z_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_Y_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_Y_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_LOCK, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_FOLD, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_AUTO_TILT_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_MEMORY_SELECT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_MEMORY_SET, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BELT_BUCKLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BELT_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BELT_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_DEPTH_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_DEPTH_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_TILT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_TILT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDOW_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDOW_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDOW_LOCK, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDSHIELD_WIPERS_PERIOD, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDSHIELD_WIPERS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDSHIELD_WIPERS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::GLOVE_BOX_DOOR_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HEADLIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FOG_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HAZARD_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HEADLIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HAZARD_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CABIN_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CABIN_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::READING_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::READING_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::DISABLED_OPTIONAL_FEATURES, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INITIAL_USER_INFO, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SWITCH_USER, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CREATE_USER, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::REMOVE_USER, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EVS_SERVICE_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::POWER_POLICY_REQ, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::POWER_POLICY_GROUP_REQ, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CURRENT_POWER_POLICY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WATCHDOG_ALIVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WATCHDOG_TERMINATED_PROCESS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VHAL_HEARTBEAT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_SWITCH_UI, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_DISPLAY_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_REPORT_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_REQUEST_DISPLAY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_NAVIGATION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FRONT_FOG_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::REAR_FOG_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::REAR_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_PERCENT_LIMIT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_TIME_REMAINING, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TRAILER_PRESENT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_CURB_WEIGHT, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::SUPPORTED_PROPERTY_IDS, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_IN_USE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::BLIND_SPOT_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_TYPE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_COMMAND, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+}  // aidl
+
+#endif  // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
new file mode 100644
index 0000000..758670d
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class AccessForVehicleProperty {
+
+    public static final Map<Integer, Integer> values = Map.ofEntries(
+        Map.entry(VehicleProperty.INFO_VIN, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_MAKE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_MODEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_MODEL_YEAR, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_FUEL_CAPACITY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_FUEL_TYPE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_EV_BATTERY_CAPACITY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_EV_CONNECTOR_TYPE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_FUEL_DOOR_LOCATION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_EV_PORT_LOCATION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_DRIVER_SEAT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_EXTERIOR_DIMENSIONS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_ODOMETER, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_VEHICLE_SPEED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_STEERING_ANGLE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_REAR_STEERING_ANGLE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_COOLANT_TEMP, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_OIL_TEMP, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_RPM, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.WHEEL_TICK, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FUEL_LEVEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FUEL_DOOR_OPEN, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_BATTERY_LEVEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_CHARGE_PORT_OPEN, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_PORT_CONNECTED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.RANGE_REMAINING, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PARKING_BRAKE_AUTO_APPLY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FUEL_LEVEL_LOW, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.NIGHT_MODE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.TURN_SIGNAL_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.IGNITION_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_SET, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_DEFROSTER, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_AC_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_MAX_AC_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_MAX_DEFROST_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_RECIRC_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_DUAL_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_AUTO_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_SEAT_TEMPERATURE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_SIDE_MIRROR_HEAT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_STEERING_WHEEL_HEAT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HVAC_POWER_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HVAC_AUTO_RECIRC_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_SEAT_VENTILATION, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DISTANCE_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_BATTERY_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EXTERNAL_CAR_TIME, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ANDROID_EPOCH_TIME, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.ENV_OUTSIDE_TEMPERATURE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.AP_POWER_STATE_REQ, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.AP_POWER_STATE_REPORT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HW_ROTARY_INPUT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HW_CUSTOM_INPUT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DOOR_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DOOR_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DOOR_LOCK, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DOOR_CHILD_LOCK_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_Z_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_Z_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_Y_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_Y_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_LOCK, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_FOLD, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_AUTO_TILT_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_MEMORY_SELECT, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.SEAT_MEMORY_SET, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.SEAT_BELT_BUCKLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_DEPTH_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_DEPTH_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_TILT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_TILT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_WALK_IN_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.WINDOW_LOCK, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_PERIOD, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LOCKED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.GLOVE_BOX_DOOR_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.HEADLIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FOG_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HAZARD_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HEADLIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FOG_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HAZARD_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CABIN_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CABIN_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.READING_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.READING_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DISABLED_OPTIONAL_FEATURES, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SWITCH_USER, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CREATE_USER, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EVS_SERVICE_REQUEST, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.POWER_POLICY_REQ, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.POWER_POLICY_GROUP_REQ, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CURRENT_POWER_POLICY, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.WATCHDOG_ALIVE, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.WATCHDOG_TERMINATED_PROCESS, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.VHAL_HEARTBEAT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CLUSTER_SWITCH_UI, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CLUSTER_DISPLAY_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CLUSTER_REPORT_STATE, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.CLUSTER_REQUEST_DISPLAY, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.CLUSTER_NAVIGATION_STATE, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.REAR_FOG_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.REAR_FOG_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_PERCENT_LIMIT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_CHARGE_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_TIME_REMAINING, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.TRAILER_PRESENT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.VEHICLE_CURB_WEIGHT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.SUPPORTED_PROPERTY_IDS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_TYPE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_COMMAND, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess.READ)
+    );
+
+}
diff --git a/automotive/vehicle/aidl/generated_lib/java/Android.bp b/automotive/vehicle/aidl/generated_lib/java/Android.bp
new file mode 100644
index 0000000..1d612e8
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/java/Android.bp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+    name: "IVehicleGeneratedJavaFiles",
+    srcs: [
+        "*.java",
+    ],
+}
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
new file mode 100644
index 0000000..29069f8
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class ChangeModeForVehicleProperty {
+
+    public static final Map<Integer, Integer> values = Map.ofEntries(
+        Map.entry(VehicleProperty.INFO_VIN, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_MAKE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_MODEL, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_MODEL_YEAR, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_FUEL_CAPACITY, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_FUEL_TYPE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_EV_BATTERY_CAPACITY, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_EV_CONNECTOR_TYPE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_FUEL_DOOR_LOCATION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_EV_PORT_LOCATION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_DRIVER_SEAT, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_EXTERIOR_DIMENSIONS, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.PERF_ODOMETER, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.PERF_VEHICLE_SPEED, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.PERF_STEERING_ANGLE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.PERF_REAR_STEERING_ANGLE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.ENGINE_COOLANT_TEMP, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ENGINE_OIL_TEMP, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.ENGINE_RPM, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.WHEEL_TICK, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.FUEL_LEVEL, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.FUEL_DOOR_OPEN, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_BATTERY_LEVEL, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_PORT_OPEN, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_PORT_CONNECTED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.RANGE_REMAINING, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.PARKING_BRAKE_AUTO_APPLY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FUEL_LEVEL_LOW, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.NIGHT_MODE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TURN_SIGNAL_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.IGNITION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_SET, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_DEFROSTER, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_AC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_MAX_AC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_MAX_DEFROST_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_RECIRC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_DUAL_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_AUTO_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_SEAT_TEMPERATURE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_SIDE_MIRROR_HEAT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_STEERING_WHEEL_HEAT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_POWER_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.HVAC_AUTO_RECIRC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_SEAT_VENTILATION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DISTANCE_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_BATTERY_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EXTERNAL_CAR_TIME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ANDROID_EPOCH_TIME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ENV_OUTSIDE_TEMPERATURE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.AP_POWER_STATE_REQ, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.AP_POWER_STATE_REPORT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_ROTARY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_CUSTOM_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DOOR_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DOOR_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DOOR_LOCK, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DOOR_CHILD_LOCK_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_Z_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_Z_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_Y_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_Y_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_LOCK, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_FOLD, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_AUTO_TILT_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_MEMORY_SELECT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_MEMORY_SET, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BELT_BUCKLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_DEPTH_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_DEPTH_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_TILT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_TILT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_WALK_IN_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDOW_LOCK, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_PERIOD, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LOCKED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.GLOVE_BOX_DOOR_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HEADLIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FOG_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HAZARD_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HEADLIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HAZARD_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CABIN_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CABIN_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.READING_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.READING_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.DISABLED_OPTIONAL_FEATURES, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SWITCH_USER, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CREATE_USER, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EVS_SERVICE_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.POWER_POLICY_REQ, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.POWER_POLICY_GROUP_REQ, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CURRENT_POWER_POLICY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WATCHDOG_ALIVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WATCHDOG_TERMINATED_PROCESS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VHAL_HEARTBEAT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_SWITCH_UI, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_DISPLAY_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_REPORT_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_REQUEST_DISPLAY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_NAVIGATION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.REAR_FOG_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.REAR_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_PERCENT_LIMIT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_TIME_REMAINING, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TRAILER_PRESENT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_CURB_WEIGHT, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.SUPPORTED_PROPERTY_IDS, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_TYPE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_COMMAND, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE)
+    );
+
+}
diff --git a/automotive/vehicle/aidl/impl/Android.bp b/automotive/vehicle/aidl/impl/Android.bp
index d24a739..d2c5145 100644
--- a/automotive/vehicle/aidl/impl/Android.bp
+++ b/automotive/vehicle/aidl/impl/Android.bp
@@ -22,7 +22,6 @@
     name: "VehicleHalDefaults",
     static_libs: [
         "android-automotive-large-parcelable-lib",
-        "android.hardware.automotive.vehicle-V1-ndk",
         "libmath",
     ],
     shared_libs: [
@@ -37,6 +36,7 @@
         "-Wthread-safety",
     ],
     defaults: [
+        "VehicleHalInterfaceDefaults",
         "android-automotive-large-parcelable-defaults",
     ],
 }
diff --git a/automotive/vehicle/aidl/impl/README.md b/automotive/vehicle/aidl/impl/README.md
new file mode 100644
index 0000000..121ffd1
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/README.md
@@ -0,0 +1,58 @@
+# AIDL VHAL libraries and reference implementation.
+---
+
+This directory stores the libraries useful for implementing vendor AIDL VHAL.
+This directory also stores a reference fake implementation for AIDL VHAL.
+
+## default_config
+
+Stores the default vehicle property configurations for reference vehicle HAL.
+Vendor implementation could copy this library but must update the configuration
+to meet their own requirements, e.g. enable or disable certain properties or
+update the initial value for certain properties.
+
+##	fake_impl
+
+Contains libraries used specifically for the fake reference VHAL implementation.
+These libraries are for test only and must not be directly used for vendor
+VHAL implementation.
+
+These libraries contain test-spcific logic and must not run directly on a real
+vehicle.
+
+## grpc
+
+Stores code for GRPC based VHAL implementation.
+
+## hardware
+
+Defines an interface `IVehicleHardware.h` which vendor must implement for
+vehicle-specific logic if they want to follow our reference VHAL design.
+
+## proto
+
+Stores Some protobuf files translated from AIDL VHAL interface types. These
+files are used in GRPC VHAL implementation.
+
+## utils
+
+Defines a library `VehicleHalUtils` which provides useful utility functions for
+VHAL implementation. Vendor VHAL could use this library.
+
+## vhal
+
+Defines a library `DefaultVehicleHal` which provides generic logic for all VHAL
+implementations (including reference VHAL). Vendor VHAL implementation could
+use this library, along with their own implementation for `IVehicleHardware`
+interface.
+
+Also defines a binary `android.hardware.automotive.vehicle@V1-default-service`
+which is the reference VHAL implementation. It implements `IVehicle.aidl`
+interface. It uses `DefaultVehicleHal`, along with `FakeVehicleHardware`
+(in fake_impl). It simulates the vehicle bus interaction by using an
+in-memory map. Meaning that all properties (except for some special ones) are
+just written into a hash map and read from a hash map without relying on any
+hardware. As a result, the reference implementation can run on emulator or
+any host environment.
+
+Vendor must not directly use the reference implementation for a real vehicle.
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/default_config/Android.bp b/automotive/vehicle/aidl/impl/default_config/Android.bp
deleted file mode 100644
index 0feaf23..0000000
--- a/automotive/vehicle/aidl/impl/default_config/Android.bp
+++ /dev/null
@@ -1,31 +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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-cc_library_headers {
-    name: "VehicleHalDefaultConfig",
-    vendor: true,
-    local_include_dirs: ["include"],
-    export_include_dirs: ["include"],
-    defaults: ["VehicleHalDefaults"],
-    static_libs: ["VehicleHalUtils"],
-    header_libs: ["VehicleHalTestUtilHeaders"],
-    export_static_lib_headers: ["VehicleHalUtils"],
-    export_header_lib_headers: ["VehicleHalTestUtilHeaders"],
-}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
new file mode 100644
index 0000000..6984d5e
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "VehicleHalJsonConfigLoader",
+    vendor: true,
+    srcs: ["src/*.cpp"],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults"],
+    static_libs: ["VehicleHalUtils"],
+    header_libs: [
+        "IVehicleGeneratedHeaders",
+    ],
+    shared_libs: ["libjsoncpp"],
+}
+
+cc_library {
+    name: "VehicleHalJsonConfigLoaderEnableTestProperties",
+    vendor: true,
+    srcs: ["src/*.cpp"],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults"],
+    static_libs: ["VehicleHalUtils"],
+    header_libs: [
+        "VehicleHalTestUtilHeaders",
+        "IVehicleGeneratedHeaders",
+    ],
+    cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
+    shared_libs: ["libjsoncpp"],
+}
+
+cc_library_headers {
+    name: "VehicleHalJsonConfigLoaderHeaders",
+    vendor: true,
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults"],
+    static_libs: ["VehicleHalUtils"],
+    header_libs: [
+        "IVehicleGeneratedHeaders",
+    ],
+    shared_libs: ["libjsoncpp"],
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h
new file mode 100644
index 0000000..40ac129
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_ConfigDeclaration_H_
+#define android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_ConfigDeclaration_H_
+
+#include <VehicleHalTypes.h>
+
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+// ConfigDeclaration represents one property config, its optional initial value and its optional
+// area configs and initial values for each area.
+struct ConfigDeclaration {
+    aidl::android::hardware::automotive::vehicle::VehiclePropConfig config;
+
+    // This value will be used as an initial value for the property. If this field is specified for
+    // property that supports multiple areas then it will be used for all areas unless particular
+    // area is overridden in initialAreaValue field.
+    aidl::android::hardware::automotive::vehicle::RawPropValues initialValue;
+    // Use initialAreaValues if it is necessary to specify different values per each area.
+    std::unordered_map<int32_t, aidl::android::hardware::automotive::vehicle::RawPropValues>
+            initialAreaValues;
+
+    inline bool operator==(const ConfigDeclaration& other) const {
+        return (config == other.config && initialValue == other.initialValue &&
+                initialAreaValues == other.initialAreaValues);
+    }
+
+    friend std::ostream& operator<<(std::ostream& os, const ConfigDeclaration& c) {
+        return os << "Config Declaration for property: "
+                  << aidl::android::hardware::automotive::vehicle::toString(
+                             static_cast<
+                                     aidl::android::hardware::automotive::vehicle::VehicleProperty>(
+                                     c.config.prop));
+    }
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_ConfigDeclaration_H_
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h
new file mode 100644
index 0000000..f3bdbd2
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_JsonConfigLoader_H_
+#define android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_JsonConfigLoader_H_
+
+#include <ConfigDeclaration.h>
+#include <VehicleHalTypes.h>
+
+#include <android-base/result.h>
+#include <json/json.h>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+// private namespace
+namespace jsonconfigloader_impl {
+
+// An abstract interface that represents a ValueParser for any constant value types.
+class ConstantParserInterface {
+  public:
+    // Parses a constant variable name to its actual value.
+    virtual android::base::Result<int> parseValue(const std::string& name) const = 0;
+    virtual ~ConstantParserInterface() = default;
+};
+
+// A class to parse a value field in JSON config file.
+// If the field is a string and the field is in the format of "XX::XX", the value will be parsed
+// as a constant value in the format of "TYPE::NAME". Otherwise, the field will be return as is
+// converted to the expected type.
+class JsonValueParser final {
+  public:
+    JsonValueParser();
+
+    android::base::Result<std::string> parseStringValue(const std::string& fieldName,
+                                                        const Json::Value& value) const;
+
+    template <class T>
+    android::base::Result<std::vector<T>> parseArray(const std::string& fieldName,
+                                                     const Json::Value& value) const;
+
+    template <class T>
+    android::base::Result<T> parseValue(const std::string& fieldName,
+                                        const Json::Value& value) const;
+
+  private:
+    template <class T>
+    static android::base::Result<T> convertValueToType(const std::string& fieldName,
+                                                       const Json::Value& value);
+
+    std::optional<std::pair<std::string, std::string>> maybeGetTypeAndValueName(
+            const std::string& jsonFieldValue) const;
+
+    android::base::Result<int> parseConstantValue(
+            const std::pair<std::string, std::string>& typeValueName) const;
+
+    const ConstantParserInterface* getParser(const std::string& type) const {
+        auto it = mConstantParsersByType.find(type);
+        if (it == mConstantParsersByType.end()) {
+            return nullptr;
+        }
+        return it->second.get();
+    }
+
+  private:
+    inline static const std::string DELIMITER = "::";
+    std::unordered_map<std::string, std::unique_ptr<ConstantParserInterface>>
+            mConstantParsersByType;
+};
+
+// The main class to parse a VHAL config file in JSON format.
+class JsonConfigParser {
+  public:
+    android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>> parseJsonConfig(
+            std::istream& is);
+
+  private:
+    JsonValueParser mValueParser;
+
+    // Parses configuration for each property.
+    std::optional<ConfigDeclaration> parseEachProperty(const Json::Value& propJsonValue,
+                                                       std::vector<std::string>* errors);
+    // Tries to parse a JSON value to a specific type.
+    //
+    // If fieldIsOptional is True, then if the field specified by "fieldName" does not exist,
+    // this method will return true without doing anything, otherwise, it will return false.
+    //
+    // @param parentJsonNode The parent node of the field you are going to parse.
+    // @param fieldName The name for the field.
+    // @param fieldIsOptional Whether the field is optional.
+    // @param outPtr The pointer to output to if the field exists and parsing succeeded.
+    // @param errors The error array to append error to if errors are found.
+    // @return true if the field is optional and does not exist or parsed successfully.
+    template <class T>
+    bool tryParseJsonValueToVariable(const Json::Value& parentJsonNode,
+                                     const std::string& fieldName, bool fieldIsOptional, T* outPtr,
+                                     std::vector<std::string>* errors);
+    // Tries to parse a JSON value to an array of specific type.
+    //
+    // If fieldIsOptional is True, then if the field specified by "fieldName" does not exist,
+    // this method will return true without doing anything, otherwise, it will return false.
+    //
+    // @param parentJsonNode The parent node of the field you are going to parse.
+    // @param fieldName The name for the field.
+    // @param fieldIsOptional Whether the field is optional.
+    // @param outPtr The pointer to output to if the field exists and parsing succeeded.
+    // @param errors The error array to append error to if errors are found.
+    // @return true if the field is optional and does not exist or parsed successfully.
+    template <class T>
+    bool tryParseJsonArrayToVariable(const Json::Value& parentJsonNode,
+                                     const std::string& fieldName, bool fieldIsOptional,
+                                     std::vector<T>* outPtr, std::vector<std::string>* errors);
+    // Parses a JSON field to VehiclePropertyAccess or VehiclePropertyChangeMode.
+    template <class T>
+    void parseAccessChangeMode(
+            const Json::Value& parentJsonNode, const std::string& fieldName, int propId,
+            const std::string& propStr,
+            const std::unordered_map<aidl::android::hardware::automotive::vehicle::VehicleProperty,
+                                     T>& defaultMap,
+            T* outPtr, std::vector<std::string>* errors);
+
+    // Parses a JSON field to RawPropValues.
+    //
+    // @return True if the field exist and can be parsed to a RawPropValues.
+    bool parsePropValues(const Json::Value& parentJsonNode, const std::string& fieldName,
+                         aidl::android::hardware::automotive::vehicle::RawPropValues* outPtr,
+                         std::vector<std::string>* errors);
+
+    // Prase a JSON field as an array of area configs.
+    void parseAreas(const Json::Value& parentJsonNode, const std::string& fieldName,
+                    ConfigDeclaration* outPtr, std::vector<std::string>* errors);
+};
+
+}  // namespace jsonconfigloader_impl
+
+// A class to load vehicle property configs and initial values in JSON format.
+class JsonConfigLoader final {
+  public:
+    JsonConfigLoader();
+
+    // Loads a JSON file stream and parses it to a map from propId to ConfigDeclarations.
+    android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>> loadPropConfig(
+            std::istream& is);
+
+    // Loads a JSON config file and parses it to a map from propId to ConfigDeclarations.
+    android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>> loadPropConfig(
+            const std::string& configPath);
+
+  private:
+    std::unique_ptr<jsonconfigloader_impl::JsonConfigParser> mParser;
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_JsonConfigLoader_H_
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
new file mode 100644
index 0000000..0a1f904
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -0,0 +1,631 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <JsonConfigLoader.h>
+
+#include <AccessForVehicleProperty.h>
+#include <ChangeModeForVehicleProperty.h>
+#include <PropertyUtils.h>
+
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+#include <TestPropertyUtils.h>
+#endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+
+#include <android-base/strings.h>
+#include <fstream>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace jsonconfigloader_impl {
+
+using ::aidl::android::hardware::automotive::vehicle::AccessForVehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::AutomaticEmergencyBrakingState;
+using ::aidl::android::hardware::automotive::vehicle::BlindSpotWarningState;
+using ::aidl::android::hardware::automotive::vehicle::ChangeModeForVehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
+using ::aidl::android::hardware::automotive::vehicle::CruiseControlState;
+using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
+using ::aidl::android::hardware::automotive::vehicle::EmergencyLaneKeepAssistState;
+using ::aidl::android::hardware::automotive::vehicle::ErrorState;
+using ::aidl::android::hardware::automotive::vehicle::EvConnectorType;
+using ::aidl::android::hardware::automotive::vehicle::EvsServiceState;
+using ::aidl::android::hardware::automotive::vehicle::EvsServiceType;
+using ::aidl::android::hardware::automotive::vehicle::ForwardCollisionWarningState;
+using ::aidl::android::hardware::automotive::vehicle::FuelType;
+using ::aidl::android::hardware::automotive::vehicle::GsrComplianceRequirementType;
+using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionDriverState;
+using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionWarning;
+using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistCommand;
+using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistState;
+using ::aidl::android::hardware::automotive::vehicle::LaneDepartureWarningState;
+using ::aidl::android::hardware::automotive::vehicle::LaneKeepAssistState;
+using ::aidl::android::hardware::automotive::vehicle::LocationCharacterization;
+using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
+using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
+using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
+using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
+using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
+using ::aidl::android::hardware::automotive::vehicle::VehicleIgnitionState;
+using ::aidl::android::hardware::automotive::vehicle::VehicleOilLevel;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
+using ::aidl::android::hardware::automotive::vehicle::VehicleSeatOccupancyState;
+using ::aidl::android::hardware::automotive::vehicle::VehicleTurnSignal;
+using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
+using ::aidl::android::hardware::automotive::vehicle::VehicleVendorPermission;
+using ::aidl::android::hardware::automotive::vehicle::WindshieldWipersState;
+using ::aidl::android::hardware::automotive::vehicle::WindshieldWipersSwitch;
+
+using ::android::base::Error;
+using ::android::base::Result;
+
+// Defines a map from constant names to constant values, the values defined here corresponds to
+// the "Constants::XXXX" used in JSON config file.
+const std::unordered_map<std::string, int> CONSTANTS_BY_NAME = {
+        {"DOOR_1_RIGHT", DOOR_1_RIGHT},
+        {"DOOR_1_LEFT", DOOR_1_LEFT},
+        {"DOOR_2_RIGHT", DOOR_2_RIGHT},
+        {"DOOR_2_LEFT", DOOR_2_LEFT},
+        {"DOOR_REAR", DOOR_REAR},
+        {"HVAC_ALL", HVAC_ALL},
+        {"HVAC_LEFT", HVAC_LEFT},
+        {"HVAC_RIGHT", HVAC_RIGHT},
+        {"VENDOR_EXTENSION_INT_PROPERTY", VENDOR_EXTENSION_INT_PROPERTY},
+        {"VENDOR_EXTENSION_BOOLEAN_PROPERTY", VENDOR_EXTENSION_BOOLEAN_PROPERTY},
+        {"VENDOR_EXTENSION_STRING_PROPERTY", VENDOR_EXTENSION_STRING_PROPERTY},
+        {"VENDOR_EXTENSION_FLOAT_PROPERTY", VENDOR_EXTENSION_FLOAT_PROPERTY},
+        {"WINDOW_1_LEFT", WINDOW_1_LEFT},
+        {"WINDOW_1_RIGHT", WINDOW_1_RIGHT},
+        {"WINDOW_2_LEFT", WINDOW_2_LEFT},
+        {"WINDOW_2_RIGHT", WINDOW_2_RIGHT},
+        {"WINDOW_ROOF_TOP_1", WINDOW_ROOF_TOP_1},
+        {"WINDOW_1_RIGHT_2_LEFT_2_RIGHT", WINDOW_1_RIGHT | WINDOW_2_LEFT | WINDOW_2_RIGHT},
+        {"SEAT_1_LEFT", SEAT_1_LEFT},
+        {"SEAT_1_RIGHT", SEAT_1_RIGHT},
+        {"SEAT_2_LEFT", SEAT_2_LEFT},
+        {"SEAT_2_RIGHT", SEAT_2_RIGHT},
+        {"SEAT_2_CENTER", SEAT_2_CENTER},
+        {"SEAT_2_LEFT_2_RIGHT_2_CENTER", SEAT_2_LEFT | SEAT_2_RIGHT | SEAT_2_CENTER},
+        {"WHEEL_REAR_RIGHT", WHEEL_REAR_RIGHT},
+        {"WHEEL_REAR_LEFT", WHEEL_REAR_LEFT},
+        {"WHEEL_FRONT_RIGHT", WHEEL_FRONT_RIGHT},
+        {"WHEEL_FRONT_LEFT", WHEEL_FRONT_LEFT},
+        {"CHARGE_PORT_FRONT_LEFT", CHARGE_PORT_FRONT_LEFT},
+        {"CHARGE_PORT_REAR_LEFT", CHARGE_PORT_REAR_LEFT},
+        {"FAN_DIRECTION_UNKNOWN", toInt(VehicleHvacFanDirection::UNKNOWN)},
+        {"FAN_DIRECTION_FLOOR", FAN_DIRECTION_FLOOR},
+        {"FAN_DIRECTION_FACE", FAN_DIRECTION_FACE},
+        {"FAN_DIRECTION_DEFROST", FAN_DIRECTION_DEFROST},
+        {"FAN_DIRECTION_FACE_FLOOR", FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR},
+        {"FAN_DIRECTION_FACE_DEFROST", FAN_DIRECTION_FACE | FAN_DIRECTION_DEFROST},
+        {"FAN_DIRECTION_FLOOR_DEFROST", FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST},
+        {"FAN_DIRECTION_FLOOR_DEFROST_FACE",
+         FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST | FAN_DIRECTION_FACE},
+        {"FUEL_DOOR_REAR_LEFT", FUEL_DOOR_REAR_LEFT},
+        {"LIGHT_STATE_ON", LIGHT_STATE_ON},
+        {"LIGHT_STATE_OFF", LIGHT_STATE_OFF},
+        {"LIGHT_SWITCH_OFF", LIGHT_SWITCH_OFF},
+        {"LIGHT_SWITCH_ON", LIGHT_SWITCH_ON},
+        {"LIGHT_SWITCH_AUTO", LIGHT_SWITCH_AUTO},
+        {"EV_STOPPING_MODE_CREEP", EV_STOPPING_MODE_CREEP},
+        {"EV_STOPPING_MODE_ROLL", EV_STOPPING_MODE_ROLL},
+        {"EV_STOPPING_MODE_HOLD", EV_STOPPING_MODE_HOLD},
+        {"MIRROR_DRIVER_LEFT_RIGHT",
+         toInt(VehicleAreaMirror::DRIVER_LEFT) | toInt(VehicleAreaMirror::DRIVER_RIGHT)},
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+        // Following are test properties:
+        {"ECHO_REVERSE_BYTES", ECHO_REVERSE_BYTES},
+        {"VENDOR_PROPERTY_ID", VENDOR_PROPERTY_ID},
+        {"kMixedTypePropertyForTest", kMixedTypePropertyForTest},
+        {"VENDOR_CLUSTER_NAVIGATION_STATE", VENDOR_CLUSTER_NAVIGATION_STATE},
+        {"VENDOR_CLUSTER_REQUEST_DISPLAY", VENDOR_CLUSTER_REQUEST_DISPLAY},
+        {"VENDOR_CLUSTER_SWITCH_UI", VENDOR_CLUSTER_SWITCH_UI},
+        {"VENDOR_CLUSTER_DISPLAY_STATE", VENDOR_CLUSTER_DISPLAY_STATE},
+        {"VENDOR_CLUSTER_REPORT_STATE", VENDOR_CLUSTER_REPORT_STATE},
+        {"PLACEHOLDER_PROPERTY_INT", PLACEHOLDER_PROPERTY_INT},
+        {"PLACEHOLDER_PROPERTY_FLOAT", PLACEHOLDER_PROPERTY_FLOAT},
+        {"PLACEHOLDER_PROPERTY_BOOLEAN", PLACEHOLDER_PROPERTY_BOOLEAN},
+        {"PLACEHOLDER_PROPERTY_STRING", PLACEHOLDER_PROPERTY_STRING}
+#endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+};
+
+// A class to parse constant values for type T.
+template <class T>
+class ConstantParser final : public ConstantParserInterface {
+  public:
+    ConstantParser() {
+        for (const T& v : ndk::enum_range<T>()) {
+            std::string name = aidl::android::hardware::automotive::vehicle::toString(v);
+            // We use the same constant for both VehicleUnit::GALLON and VehicleUnit::US_GALLON,
+            // which caused toString() not work properly for US_GALLON. So we explicitly add the
+            // map here.
+            if (name == "GALLON") {
+                mValueByName["US_GALLON"] = toInt(v);
+            }
+            mValueByName[name] = toInt(v);
+        }
+    }
+
+    ~ConstantParser() = default;
+
+    Result<int> parseValue(const std::string& name) const override {
+        auto it = mValueByName.find(name);
+        if (it == mValueByName.end()) {
+            return Error() << "Constant name: " << name << " is not defined";
+        }
+        return it->second;
+    }
+
+  private:
+    std::unordered_map<std::string, int> mValueByName;
+};
+
+// A class to parse constant values defined in CONSTANTS_BY_NAME map.
+class LocalVariableParser final : public ConstantParserInterface {
+  public:
+    ~LocalVariableParser() = default;
+
+    Result<int> parseValue(const std::string& name) const override {
+        auto constantsIt = CONSTANTS_BY_NAME.find(name);
+        if (constantsIt == CONSTANTS_BY_NAME.end()) {
+            return Error() << "Constant variable name: " << name << " is not defined";
+        }
+        return constantsIt->second;
+    }
+};
+
+JsonValueParser::JsonValueParser() {
+    mConstantParsersByType["VehiclePropertyAccess"] =
+            std::make_unique<ConstantParser<VehiclePropertyAccess>>();
+    mConstantParsersByType["VehiclePropertyChangeMode"] =
+            std::make_unique<ConstantParser<VehiclePropertyChangeMode>>();
+    mConstantParsersByType["LocationCharacterization"] =
+            std::make_unique<ConstantParser<LocationCharacterization>>();
+    mConstantParsersByType["VehicleGear"] = std::make_unique<ConstantParser<VehicleGear>>();
+    mConstantParsersByType["VehicleAreaWindow"] =
+            std::make_unique<ConstantParser<VehicleAreaWindow>>();
+    mConstantParsersByType["VehicleAreaMirror"] =
+            std::make_unique<ConstantParser<VehicleAreaMirror>>();
+    mConstantParsersByType["VehicleOilLevel"] = std::make_unique<ConstantParser<VehicleOilLevel>>();
+    mConstantParsersByType["VehicleUnit"] = std::make_unique<ConstantParser<VehicleUnit>>();
+    mConstantParsersByType["VehicleSeatOccupancyState"] =
+            std::make_unique<ConstantParser<VehicleSeatOccupancyState>>();
+    mConstantParsersByType["VehicleHvacFanDirection"] =
+            std::make_unique<ConstantParser<VehicleHvacFanDirection>>();
+    mConstantParsersByType["VehicleApPowerStateReport"] =
+            std::make_unique<ConstantParser<VehicleApPowerStateReport>>();
+    mConstantParsersByType["VehicleTurnSignal"] =
+            std::make_unique<ConstantParser<VehicleTurnSignal>>();
+    mConstantParsersByType["VehicleVendorPermission"] =
+            std::make_unique<ConstantParser<VehicleVendorPermission>>();
+    mConstantParsersByType["EvsServiceType"] = std::make_unique<ConstantParser<EvsServiceType>>();
+    mConstantParsersByType["EvsServiceState"] = std::make_unique<ConstantParser<EvsServiceState>>();
+    mConstantParsersByType["EvConnectorType"] = std::make_unique<ConstantParser<EvConnectorType>>();
+    mConstantParsersByType["VehicleProperty"] = std::make_unique<ConstantParser<VehicleProperty>>();
+    mConstantParsersByType["GsrComplianceRequirementType"] =
+            std::make_unique<ConstantParser<GsrComplianceRequirementType>>();
+    mConstantParsersByType["VehicleIgnitionState"] =
+            std::make_unique<ConstantParser<VehicleIgnitionState>>();
+    mConstantParsersByType["FuelType"] = std::make_unique<ConstantParser<FuelType>>();
+    mConstantParsersByType["WindshieldWipersState"] =
+            std::make_unique<ConstantParser<WindshieldWipersState>>();
+    mConstantParsersByType["WindshieldWipersSwitch"] =
+            std::make_unique<ConstantParser<WindshieldWipersSwitch>>();
+    mConstantParsersByType["EmergencyLaneKeepAssistState"] =
+            std::make_unique<ConstantParser<EmergencyLaneKeepAssistState>>();
+    mConstantParsersByType["CruiseControlType"] =
+            std::make_unique<ConstantParser<CruiseControlType>>();
+    mConstantParsersByType["CruiseControlState"] =
+            std::make_unique<ConstantParser<CruiseControlState>>();
+    mConstantParsersByType["CruiseControlCommand"] =
+            std::make_unique<ConstantParser<CruiseControlCommand>>();
+    mConstantParsersByType["HandsOnDetectionDriverState"] =
+            std::make_unique<ConstantParser<HandsOnDetectionDriverState>>();
+    mConstantParsersByType["HandsOnDetectionWarning"] =
+            std::make_unique<ConstantParser<HandsOnDetectionWarning>>();
+    mConstantParsersByType["ErrorState"] = std::make_unique<ConstantParser<ErrorState>>();
+    mConstantParsersByType["AutomaticEmergencyBrakingState"] =
+            std::make_unique<ConstantParser<AutomaticEmergencyBrakingState>>();
+    mConstantParsersByType["ForwardCollisionWarningState"] =
+            std::make_unique<ConstantParser<ForwardCollisionWarningState>>();
+    mConstantParsersByType["BlindSpotWarningState"] =
+            std::make_unique<ConstantParser<BlindSpotWarningState>>();
+    mConstantParsersByType["LaneDepartureWarningState"] =
+            std::make_unique<ConstantParser<LaneDepartureWarningState>>();
+    mConstantParsersByType["LaneKeepAssistState"] =
+            std::make_unique<ConstantParser<LaneKeepAssistState>>();
+    mConstantParsersByType["LaneCenteringAssistCommand"] =
+            std::make_unique<ConstantParser<LaneCenteringAssistCommand>>();
+    mConstantParsersByType["LaneCenteringAssistState"] =
+            std::make_unique<ConstantParser<LaneCenteringAssistState>>();
+    mConstantParsersByType["Constants"] = std::make_unique<LocalVariableParser>();
+}
+
+template <>
+Result<int32_t> JsonValueParser::convertValueToType<int32_t>(const std::string& fieldName,
+                                                             const Json::Value& value) {
+    if (!value.isInt()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect int";
+    }
+    return static_cast<int32_t>(value.asInt());
+}
+
+template <>
+Result<float> JsonValueParser::convertValueToType<float>(const std::string& fieldName,
+                                                         const Json::Value& value) {
+    // isFloat value does not exist, so we use isDouble here.
+    if (!value.isDouble()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect float";
+    }
+    return value.asFloat();
+}
+
+template <>
+Result<int64_t> JsonValueParser::convertValueToType<int64_t>(const std::string& fieldName,
+                                                             const Json::Value& value) {
+    if (!value.isInt64()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect int64";
+    }
+    return static_cast<int64_t>(value.asInt64());
+}
+
+template <>
+Result<std::string> JsonValueParser::convertValueToType<std::string>(const std::string& fieldName,
+                                                                     const Json::Value& value) {
+    if (!value.isString()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect string";
+    }
+    return value.asString();
+}
+
+Result<std::string> JsonValueParser::parseStringValue(const std::string& fieldName,
+                                                      const Json::Value& value) const {
+    return convertValueToType<std::string>(fieldName, value);
+}
+
+template <class T>
+Result<T> JsonValueParser::parseValue(const std::string& fieldName,
+                                      const Json::Value& value) const {
+    if (!value.isString()) {
+        return convertValueToType<T>(fieldName, value);
+    }
+    auto maybeTypeAndValue = maybeGetTypeAndValueName(value.asString());
+    if (!maybeTypeAndValue.has_value()) {
+        return Error() << "Invalid constant value: " << value << " for field: " << fieldName;
+    }
+    auto constantParseResult = parseConstantValue(maybeTypeAndValue.value());
+    if (!constantParseResult.ok()) {
+        return constantParseResult.error();
+    }
+    int constantValue = constantParseResult.value();
+    return static_cast<T>(constantValue);
+}
+
+template <>
+Result<std::string> JsonValueParser::parseValue<std::string>(const std::string& fieldName,
+                                                             const Json::Value& value) const {
+    return parseStringValue(fieldName, value);
+}
+
+template <class T>
+Result<std::vector<T>> JsonValueParser::parseArray(const std::string& fieldName,
+                                                   const Json::Value& value) const {
+    if (!value.isArray()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect array";
+    }
+    std::vector<T> parsedValues;
+    for (unsigned int i = 0; i < value.size(); i++) {
+        auto result = parseValue<T>(fieldName, value[i]);
+        if (!result.ok()) {
+            return result.error();
+        }
+        parsedValues.push_back(result.value());
+    }
+    return std::move(parsedValues);
+}
+
+std::optional<std::pair<std::string, std::string>> JsonValueParser::maybeGetTypeAndValueName(
+        const std::string& jsonFieldValue) const {
+    size_t pos = jsonFieldValue.find(DELIMITER);
+    if (pos == std::string::npos) {
+        return {};
+    }
+    std::string type = jsonFieldValue.substr(0, pos);
+    std::string valueName = jsonFieldValue.substr(pos + DELIMITER.length(), std::string::npos);
+    if (type != "Constants" && mConstantParsersByType.find(type) == mConstantParsersByType.end()) {
+        return {};
+    }
+    return std::make_pair(type, valueName);
+}
+
+Result<int> JsonValueParser::parseConstantValue(
+        const std::pair<std::string, std::string>& typeValueName) const {
+    const std::string& type = typeValueName.first;
+    const std::string& valueName = typeValueName.second;
+    auto it = mConstantParsersByType.find(type);
+    if (it == mConstantParsersByType.end()) {
+        return Error() << "Unrecognized type: " << type;
+    }
+    auto result = it->second->parseValue(valueName);
+    if (!result.ok()) {
+        return Error() << type << "::" << valueName << " undefined";
+    }
+    return result;
+}
+
+template <class T>
+bool JsonConfigParser::tryParseJsonValueToVariable(const Json::Value& parentJsonNode,
+                                                   const std::string& fieldName,
+                                                   bool fieldIsOptional, T* outPtr,
+                                                   std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return false;
+    }
+    if (!parentJsonNode.isMember(fieldName)) {
+        if (!fieldIsOptional) {
+            errors->push_back("Missing required field: " + fieldName +
+                              " in node: " + parentJsonNode.toStyledString());
+            return false;
+        }
+        return true;
+    }
+    auto result = mValueParser.parseValue<T>(fieldName, parentJsonNode[fieldName]);
+    if (!result.ok()) {
+        errors->push_back(result.error().message());
+        return false;
+    }
+    *outPtr = std::move(result.value());
+    return true;
+}
+
+template <class T>
+bool JsonConfigParser::tryParseJsonArrayToVariable(const Json::Value& parentJsonNode,
+                                                   const std::string& fieldName,
+                                                   bool fieldIsOptional, std::vector<T>* outPtr,
+                                                   std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return false;
+    }
+    if (!parentJsonNode.isMember(fieldName)) {
+        if (!fieldIsOptional) {
+            errors->push_back("Missing required field: " + fieldName +
+                              " in node: " + parentJsonNode.toStyledString());
+            return false;
+        }
+        return true;
+    }
+    auto result = mValueParser.parseArray<T>(fieldName, parentJsonNode[fieldName]);
+    if (!result.ok()) {
+        errors->push_back(result.error().message());
+        return false;
+    }
+    *outPtr = std::move(result.value());
+    return true;
+}
+
+template <class T>
+void JsonConfigParser::parseAccessChangeMode(
+        const Json::Value& parentJsonNode, const std::string& fieldName, int propId,
+        const std::string& propStr, const std::unordered_map<VehicleProperty, T>& defaultMap,
+        T* outPtr, std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return;
+    }
+    if (parentJsonNode.isMember(fieldName)) {
+        auto result = mValueParser.parseValue<int32_t>(fieldName, parentJsonNode[fieldName]);
+        if (!result.ok()) {
+            errors->push_back(result.error().message());
+            return;
+        }
+        *outPtr = static_cast<T>(result.value());
+        return;
+    }
+    auto it = defaultMap.find(static_cast<VehicleProperty>(propId));
+    if (it == defaultMap.end()) {
+        errors->push_back("No " + fieldName + " specified for property: " + propStr);
+        return;
+    }
+    *outPtr = it->second;
+    return;
+}
+
+bool JsonConfigParser::parsePropValues(const Json::Value& parentJsonNode,
+                                       const std::string& fieldName, RawPropValues* outPtr,
+                                       std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return false;
+    }
+    if (!parentJsonNode.isMember(fieldName)) {
+        return false;
+    }
+    const Json::Value& jsonValue = parentJsonNode[fieldName];
+    bool success = true;
+    success &= tryParseJsonArrayToVariable(jsonValue, "int32Values",
+                                           /*optional=*/true, &(outPtr->int32Values), errors);
+    success &= tryParseJsonArrayToVariable(jsonValue, "floatValues",
+                                           /*optional=*/true, &(outPtr->floatValues), errors);
+    success &= tryParseJsonArrayToVariable(jsonValue, "int64Values",
+                                           /*optional=*/true, &(outPtr->int64Values), errors);
+    // We don't support "byteValues" yet.
+    success &= tryParseJsonValueToVariable(jsonValue, "stringValue",
+                                           /*optional=*/true, &(outPtr->stringValue), errors);
+    return success;
+}
+
+void JsonConfigParser::parseAreas(const Json::Value& parentJsonNode, const std::string& fieldName,
+                                  ConfigDeclaration* config, std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return;
+    }
+    if (!parentJsonNode.isMember(fieldName)) {
+        return;
+    }
+    const Json::Value& jsonValue = parentJsonNode[fieldName];
+
+    if (!jsonValue.isArray()) {
+        errors->push_back("Field: " + fieldName + " is not an array");
+        return;
+    }
+    for (unsigned int i = 0; i < jsonValue.size(); i++) {
+        int32_t areaId;
+        const Json::Value& jsonAreaConfig = jsonValue[i];
+        if (!tryParseJsonValueToVariable(jsonAreaConfig, "areaId",
+                                         /*optional=*/false, &areaId, errors)) {
+            continue;
+        }
+        VehicleAreaConfig areaConfig = {};
+        areaConfig.areaId = areaId;
+        tryParseJsonValueToVariable(jsonAreaConfig, "minInt32Value", /*optional=*/true,
+                                    &areaConfig.minInt32Value, errors);
+        tryParseJsonValueToVariable(jsonAreaConfig, "maxInt32Value", /*optional=*/true,
+                                    &areaConfig.maxInt32Value, errors);
+        tryParseJsonValueToVariable(jsonAreaConfig, "minInt64Value", /*optional=*/true,
+                                    &areaConfig.minInt64Value, errors);
+        tryParseJsonValueToVariable(jsonAreaConfig, "maxInt64Value", /*optional=*/true,
+                                    &areaConfig.maxInt64Value, errors);
+        tryParseJsonValueToVariable(jsonAreaConfig, "minFloatValue", /*optional=*/true,
+                                    &areaConfig.minFloatValue, errors);
+        tryParseJsonValueToVariable(jsonAreaConfig, "maxFloatValue", /*optional=*/true,
+                                    &areaConfig.maxFloatValue, errors);
+
+        std::vector<int64_t> supportedEnumValues;
+        tryParseJsonArrayToVariable(jsonAreaConfig, "supportedEnumValues", /*optional=*/true,
+                                    &supportedEnumValues, errors);
+        if (!supportedEnumValues.empty()) {
+            areaConfig.supportedEnumValues = std::move(supportedEnumValues);
+        }
+        config->config.areaConfigs.push_back(std::move(areaConfig));
+
+        RawPropValues areaValue = {};
+        if (parsePropValues(jsonAreaConfig, "defaultValue", &areaValue, errors)) {
+            config->initialAreaValues[areaId] = std::move(areaValue);
+        }
+    }
+}
+
+std::optional<ConfigDeclaration> JsonConfigParser::parseEachProperty(
+        const Json::Value& propJsonValue, std::vector<std::string>* errors) {
+    size_t initialErrorCount = errors->size();
+    ConfigDeclaration configDecl = {};
+    int32_t propId;
+
+    if (!tryParseJsonValueToVariable(propJsonValue, "property", /*optional=*/false, &propId,
+                                     errors)) {
+        return std::nullopt;
+    }
+
+    configDecl.config.prop = propId;
+    std::string propStr = propJsonValue["property"].toStyledString();
+
+    parseAccessChangeMode(propJsonValue, "access", propId, propStr, AccessForVehicleProperty,
+                          &configDecl.config.access, errors);
+
+    parseAccessChangeMode(propJsonValue, "changeMode", propId, propStr,
+                          ChangeModeForVehicleProperty, &configDecl.config.changeMode, errors);
+
+    tryParseJsonValueToVariable(propJsonValue, "configString", /*optional=*/true,
+                                &configDecl.config.configString, errors);
+
+    tryParseJsonArrayToVariable(propJsonValue, "configArray", /*optional=*/true,
+                                &configDecl.config.configArray, errors);
+
+    parsePropValues(propJsonValue, "defaultValue", &configDecl.initialValue, errors);
+
+    tryParseJsonValueToVariable(propJsonValue, "minSampleRate", /*optional=*/true,
+                                &configDecl.config.minSampleRate, errors);
+
+    tryParseJsonValueToVariable(propJsonValue, "maxSampleRate", /*optional=*/true,
+                                &configDecl.config.maxSampleRate, errors);
+
+    parseAreas(propJsonValue, "areas", &configDecl, errors);
+
+    if (errors->size() != initialErrorCount) {
+        return std::nullopt;
+    }
+    return configDecl;
+}
+
+Result<std::unordered_map<int32_t, ConfigDeclaration>> JsonConfigParser::parseJsonConfig(
+        std::istream& is) {
+    Json::CharReaderBuilder builder;
+    Json::Value root;
+    std::unordered_map<int32_t, ConfigDeclaration> configsByPropId;
+    std::string errs;
+    if (!Json::parseFromStream(builder, is, &root, &errs)) {
+        return Error() << "Failed to parse property config file as JSON, error: " << errs;
+    }
+    if (!root.isObject()) {
+        return Error() << "root element must be an object";
+    }
+    if (!root.isMember("properties") || !root["properties"].isArray()) {
+        return Error() << "Missing 'properties' field in root or the field is not an array";
+    }
+    Json::Value properties = root["properties"];
+    std::vector<std::string> errors;
+    for (unsigned int i = 0; i < properties.size(); i++) {
+        if (auto maybeConfig = parseEachProperty(properties[i], &errors); maybeConfig.has_value()) {
+            configsByPropId[maybeConfig.value().config.prop] = std::move(maybeConfig.value());
+        }
+    }
+    if (!errors.empty()) {
+        return Error() << android::base::Join(errors, '\n');
+    }
+    return configsByPropId;
+}
+
+}  // namespace jsonconfigloader_impl
+
+JsonConfigLoader::JsonConfigLoader() {
+    mParser = std::make_unique<jsonconfigloader_impl::JsonConfigParser>();
+}
+
+android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>>
+JsonConfigLoader::loadPropConfig(std::istream& is) {
+    return mParser->parseJsonConfig(is);
+}
+
+android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>>
+JsonConfigLoader::loadPropConfig(const std::string& configPath) {
+    std::ifstream ifs(configPath.c_str());
+    if (!ifs) {
+        return android::base::Error() << "couldn't open " << configPath << " for parsing.";
+    }
+
+    return loadPropConfig(ifs);
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp
new file mode 100644
index 0000000..dae37b9
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "JsonConfigLoaderUnitTest",
+    vendor: true,
+    srcs: ["*.cpp"],
+    static_libs: [
+        "VehicleHalJsonConfigLoader",
+        "VehicleHalUtils",
+        "libgtest",
+    ],
+    shared_libs: [
+        "libjsoncpp",
+    ],
+    defaults: ["VehicleHalDefaults"],
+    test_suites: ["device-tests"],
+}
+
+cc_test {
+    name: "JsonConfigLoaderUnitTestEnableTestProperties",
+    vendor: true,
+    srcs: ["*.cpp"],
+    static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties",
+        "VehicleHalUtils",
+        "libgtest",
+    ],
+    shared_libs: [
+        "libjsoncpp",
+    ],
+    defaults: ["VehicleHalDefaults"],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
new file mode 100644
index 0000000..9882653
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
@@ -0,0 +1,705 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <JsonConfigLoader.h>
+
+#include <PropertyUtils.h>
+
+#include <gtest/gtest.h>
+#include <sstream>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
+
+class JsonConfigLoaderUnitTest : public ::testing::Test {
+  protected:
+    JsonConfigLoader mLoader;
+};
+
+TEST_F(JsonConfigLoaderUnitTest, testBasic) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": 291504388
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+    ASSERT_EQ(configs.begin()->second.config.prop, 291504388);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testRootNotObject) {
+    std::istringstream iss(R"(
+    []
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok()) << "root is not an object must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMissingPropertiesField) {
+    std::istringstream iss(R"(
+    {
+        "abcd": 1234
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok()) << "Missing 'properties' field must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testPropertiesFieldNotArray) {
+    std::istringstream iss(R"(
+    {
+        "properties': {'a': 'b'}
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "'properties' field is not an array must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testPropertyIsEnum) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY"
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+    ASSERT_EQ(configs.begin()->second.config.prop, toInt(VehicleProperty::INFO_FUEL_CAPACITY));
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testPropertyEnum_FailInvalidEnum) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::BLAH"
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "Invalid VehicleProperty enum must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testPropertyEnum_FailInvalidType) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "test"
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "Invalid VehicleProperty type must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testProperty_FailInvalidJson) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok()) << "Invalid JSON format must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArray) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "configArray": [1, 2, 3]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+    ASSERT_EQ(configs.begin()->second.config.configArray, std::vector<int>({1, 2, 3}));
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArrayConstants) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "configArray": [1, 2, "Constants::FUEL_DOOR_REAR_LEFT"]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+    ASSERT_EQ(configs.begin()->second.config.configArray,
+              std::vector<int>({1, 2, FUEL_DOOR_REAR_LEFT}));
+}
+
+// We have special logic to deal with GALLON and US_GALLON since they share the same value.
+TEST_F(JsonConfigLoaderUnitTest, testConfigArrayUnitGallon) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "configArray": [1, 2, "VehicleUnit::GALLON"]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArrayUnitUsGallon) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "configArray": [1, 2, "VehicleUnit::US_GALLON"]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArray_FailInvalidEnum) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "configArray": [1, 2, "VehicleUnits::BLAH"]
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "Invalid enum in ConfigArray must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArray_FailNotArray) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "configArray": "123"
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "ConfigArray is not an array must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigString) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "configString": "test"
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+    ASSERT_EQ(configs.begin()->second.config.configString, "test");
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigString_FailNotString) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "configString": 1234
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "ConfigString is not a String must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testCheckDefaultAccessChangeMode) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY"
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& propConfig = configs.begin()->second.config;
+    ASSERT_EQ(propConfig.access, VehiclePropertyAccess::READ);
+    ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAccessOverride) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "access": "VehiclePropertyAccess::WRITE"
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& propConfig = configs.begin()->second.config;
+    ASSERT_EQ(propConfig.access, VehiclePropertyAccess::WRITE);
+    ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testChangeModeOverride) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& propConfig = configs.begin()->second.config;
+    ASSERT_EQ(propConfig.access, VehiclePropertyAccess::READ);
+    ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::ON_CHANGE);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testCustomProp) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": 1234,
+            "access": "VehiclePropertyAccess::WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& propConfig = configs.begin()->second.config;
+    ASSERT_EQ(propConfig.access, VehiclePropertyAccess::WRITE);
+    ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::ON_CHANGE);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testCustomProp_FailMissingAccess) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": 1234,
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "Missing access for custom property must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testCustomProp_FailMissingChangeMode) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": 1234,
+            "access": "VehiclePropertyAccess::WRITE"
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "Missing change mode for custom property must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMinSampleRate) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "minSampleRate": 1,
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+    ASSERT_EQ(configs.begin()->second.config.minSampleRate, 1);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMinSampleRate_FailInvalidType) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "minSampleRate": "abcd",
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "Wrong type for MinSampleRate must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMaxSampleRate) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "maxSampleRate": 1,
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+    ASSERT_EQ(configs.begin()->second.config.maxSampleRate, 1);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMaxSampleRate_FailInvalidType) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "maxSampleRate": "abcd",
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "Wrong type for MaxSampleRate must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testDefaultValue_Simple) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "defaultValue": {
+                "int32Values": [1, 2]
+            }
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+    ASSERT_EQ(configs.begin()->second.initialValue.int32Values, std::vector<int32_t>({1, 2}));
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testDefaultValue_Mixed) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "defaultValue": {
+                "int32Values": [1, "Constants::FUEL_DOOR_REAR_LEFT"],
+                "int64Values": [2, "Constants::FUEL_DOOR_REAR_LEFT"],
+                "floatValues": [3.0, "Constants::FUEL_DOOR_REAR_LEFT"],
+                "stringValue": "abcd"
+            }
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const RawPropValues& initialValue = configs.begin()->second.initialValue;
+    ASSERT_EQ(initialValue.int32Values, std::vector<int32_t>({1, FUEL_DOOR_REAR_LEFT}));
+    ASSERT_EQ(initialValue.int64Values,
+              std::vector<int64_t>({2, static_cast<int64_t>(FUEL_DOOR_REAR_LEFT)}));
+    ASSERT_EQ(initialValue.floatValues,
+              std::vector<float>({3.0, static_cast<float>(FUEL_DOOR_REAR_LEFT)}));
+    ASSERT_EQ(initialValue.stringValue, "abcd");
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testDefaultValue_FailNotObject) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "defaultValue": []
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "DefaultValue is not an object must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testDefaultValue_FailInvalidType) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "defaultValue": {
+                "int32Values": [1.1]
+            }
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "Wrong type for DefaultValue must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_Simple) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "areas": [{
+                "areaId": "Constants::HVAC_ALL",
+                "minInt32Value": 1,
+                "maxInt32Value": 7
+            }]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& config = configs.begin()->second.config;
+    ASSERT_EQ(config.areaConfigs.size(), 1u);
+    const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+    ASSERT_EQ(areaConfig.minInt32Value, 1);
+    ASSERT_EQ(areaConfig.maxInt32Value, 7);
+    ASSERT_EQ(areaConfig.areaId, HVAC_ALL);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_DefaultValueForEachArea) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "areas": [{
+                "areaId": "Constants::HVAC_LEFT",
+                "defaultValue": {
+                    "int32Values": [1]
+                }
+            }, {
+                "areaId": "Constants::HVAC_RIGHT",
+                "defaultValue": {
+                    "int32Values": [2]
+                }
+            }]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& config = configs.begin()->second.config;
+    ASSERT_EQ(config.areaConfigs.size(), 2u);
+    ASSERT_EQ(config.areaConfigs[0].areaId, HVAC_LEFT);
+    ASSERT_EQ(config.areaConfigs[1].areaId, HVAC_RIGHT);
+    ASSERT_EQ(configs.begin()->second.initialAreaValues[HVAC_LEFT],
+              RawPropValues{.int32Values = {1}});
+    ASSERT_EQ(configs.begin()->second.initialAreaValues[HVAC_RIGHT],
+              RawPropValues{.int32Values = {2}});
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_FailInvalidTypeForOneAreaValue) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "areas": [{
+                "areaId": "Constants::HVAC_LEFT",
+                "defaultValue": {
+                    "int32Values": [1]
+                }
+            }, {
+                "areaId": "Constants::HVAC_RIGHT",
+                "defaultValue": {
+                    "int32Values": [2.1]
+                }
+            }]
+        }]
+    }
+    )");
+
+    ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+            << "Wrong type for DefaultValue for one area must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_HandlesNoSupportedEnumValuesDeclared) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::CABIN_LIGHTS_STATE",
+            "areas": [{
+                "areaId": 0,
+            }]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+    ASSERT_TRUE(result.ok());
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& config = configs.begin()->second.config;
+    ASSERT_EQ(config.areaConfigs.size(), 1u);
+
+    const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+    ASSERT_EQ(areaConfig.areaId, 0);
+    ASSERT_FALSE(areaConfig.supportedEnumValues);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_HandlesSupportedEnumValues) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::CABIN_LIGHTS_STATE",
+            "areas": [{
+                "areaId": 0,
+                "supportedEnumValues": ["Constants::LIGHT_STATE_ON", "Constants::LIGHT_STATE_OFF"]
+            }]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+    ASSERT_TRUE(result.ok());
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& config = configs.begin()->second.config;
+    ASSERT_EQ(config.areaConfigs.size(), 1u);
+
+    const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+    ASSERT_EQ(areaConfig.areaId, 0);
+    ASSERT_TRUE(areaConfig.supportedEnumValues);
+    ASSERT_EQ(areaConfig.supportedEnumValues.value().size(), 2u);
+    ASSERT_EQ(areaConfig.supportedEnumValues.value(),
+              std::vector<int64_t>({LIGHT_STATE_ON, LIGHT_STATE_OFF}));
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_HandlesEmptySupportedEnumValues) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::CABIN_LIGHTS_STATE",
+            "areas": [{
+                "areaId": 0,
+                "supportedEnumValues": []
+            }]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+    ASSERT_TRUE(result.ok());
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& config = configs.begin()->second.config;
+    ASSERT_EQ(config.areaConfigs.size(), 1u);
+
+    const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+    ASSERT_EQ(areaConfig.areaId, 0);
+    ASSERT_FALSE(areaConfig.supportedEnumValues);
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/default_config/config/Android.bp b/automotive/vehicle/aidl/impl/default_config/config/Android.bp
new file mode 100644
index 0000000..8f1c7d1
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/Android.bp
@@ -0,0 +1,47 @@
+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"],
+}
+
+filegroup {
+    name: "VehicleHalDefaultProperties_JSON",
+    srcs: ["DefaultProperties.json"],
+}
+
+filegroup {
+    name: "VehicleHalTestProperties_JSON",
+    srcs: ["TestProperties.json"],
+}
+
+filegroup {
+    name: "VehicleHalVendorClusterTestProperties_JSON",
+    srcs: ["VendorClusterTestProperties.json"],
+}
+
+prebuilt_etc {
+    name: "Prebuilt_VehicleHalDefaultProperties_JSON",
+    filename_from_src: true,
+    src: "DefaultProperties.json",
+    sub_dir: "automotive/vhalconfig/",
+    vendor: true,
+}
+
+prebuilt_etc {
+    name: "Prebuilt_VehicleHalTestProperties_JSON",
+    filename_from_src: true,
+    src: "TestProperties.json",
+    sub_dir: "automotive/vhalconfig/",
+    vendor: true,
+}
+
+prebuilt_etc {
+    name: "Prebuilt_VehicleHalVendorClusterTestProperties_JSON",
+    filename_from_src: true,
+    src: "VendorClusterTestProperties.json",
+    sub_dir: "automotive/vhalconfig/",
+    vendor: true,
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
new file mode 100644
index 0000000..5503de2
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -0,0 +1,3831 @@
+{
+    "apiVersion": 1,
+    "properties": [
+        {
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "defaultValue": {
+                "floatValues": [
+                    15000.0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_FUEL_TYPE",
+            "defaultValue": {
+                "int32Values": [
+                    "FuelType::FUEL_TYPE_UNLEADED"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_EV_BATTERY_CAPACITY",
+            "defaultValue": {
+                "floatValues": [
+                    150000.0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_EV_CONNECTOR_TYPE",
+            "defaultValue": {
+                "int32Values": [
+                    "EvConnectorType::IEC_TYPE_1_AC"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_FUEL_DOOR_LOCATION",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::FUEL_DOOR_REAR_LEFT"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_EV_PORT_LOCATION",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::CHARGE_PORT_FRONT_LEFT"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::CHARGE_PORT_FRONT_LEFT",
+                    "Constants::CHARGE_PORT_REAR_LEFT"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_VIN",
+            "defaultValue": {
+                "stringValue": "1GCARVIN123456789"
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MAKE",
+            "defaultValue": {
+                "stringValue": "Toy Vehicle"
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MODEL",
+            "defaultValue": {
+                "stringValue": "Speedy Model"
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MODEL_YEAR",
+            "defaultValue": {
+                "int32Values": [
+                    2023
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_EXTERIOR_DIMENSIONS",
+            "defaultValue": {
+                "int32Values": [
+                    1776,
+                    4950,
+                    2008,
+                    2140,
+                    2984,
+                    1665,
+                    1667,
+                    11800
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::PERF_VEHICLE_SPEED",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::MILES_PER_HOUR"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::METER_PER_SEC",
+                "VehicleUnit::MILES_PER_HOUR",
+                "VehicleUnit::KILOMETERS_PER_HOUR"
+            ]
+        },
+        {
+            "property": "VehicleProperty::EV_BATTERY_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::KILOWATT_HOUR"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::WATT_HOUR",
+                "VehicleUnit::AMPERE_HOURS",
+                "VehicleUnit::KILOWATT_HOUR"
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_MEMORY_SELECT",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_MEMORY_SET",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BELT_BUCKLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BELT_HEIGHT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    10
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BELT_HEIGHT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_FORE_AFT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_FORE_AFT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEIGHT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEIGHT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_DEPTH_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_DEPTH_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_TILT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_TILT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_ANGLE_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_ANGLE_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_EASY_ACCESS_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_AIRBAG_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_WALK_IN_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 5
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 5
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_OCCUPANCY",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleSeatOccupancyState::VACANT"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::INFO_DRIVER_SEAT",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::SEAT_1_LEFT"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::PERF_ODOMETER",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::PERF_STEERING_ANGLE",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::PERF_REAR_STEERING_ANGLE",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::ENGINE_RPM",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::FUEL_LEVEL",
+            "defaultValue": {
+                "floatValues": [
+                    15000.0
+                ]
+            },
+            "maxSampleRate": 100.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::FUEL_DOOR_OPEN",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_BATTERY_LEVEL",
+            "defaultValue": {
+                "floatValues": [
+                    150000.0
+                ]
+            },
+            "maxSampleRate": 100.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::EV_CURRENT_BATTERY_CAPACITY",
+            "defaultValue": {
+                "floatValues": [
+                    150000.0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_PORT_OPEN",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_PORT_CONNECTED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT",
+            "defaultValue": {
+                "floatValues": [
+                    12.5
+                ]
+            },
+            "comment": "ConfigArray specifies Max current draw allowed by vehicle in amperes",
+            "configArray": [
+                20
+            ]
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_PERCENT_LIMIT",
+            "defaultValue": {
+                "floatValues": [
+                    40.0
+                ]
+            },
+            "configArray": [
+                20,
+                40,
+                60,
+                80,
+                100
+            ]
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    2
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_TIME_REMAINING",
+            "defaultValue": {
+                "int32Values": [
+                    20
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::EV_REGENERATIVE_BRAKING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    2
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::TRAILER_PRESENT",
+            "defaultValue": {
+                "int32Values": [
+                    2
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_CURB_WEIGHT",
+            "defaultValue": {
+                "int32Values": [
+                    2211
+                ]
+            },
+            "configArray": [
+                2948
+            ],
+            "comment": "unit is kg"
+        },
+        {
+            "property": "VehicleProperty::RANGE_REMAINING",
+            "defaultValue": {
+                "floatValues": [
+                    50000.0
+                ]
+            },
+            "comment": "units in meter",
+            "maxSampleRate": 2.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::TIRE_PRESSURE",
+            "defaultValue": {
+                "floatValues": [
+                    200.0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::WHEEL_FRONT_LEFT",
+                    "minFloatValue": 193.0,
+                    "maxFloatValue": 300.0
+                },
+                {
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT",
+                    "minFloatValue": 193.0,
+                    "maxFloatValue": 300.0
+                },
+                {
+                    "areaId": "Constants::WHEEL_REAR_LEFT",
+                    "minFloatValue": 193.0,
+                    "maxFloatValue": 300.0
+                },
+                {
+                    "areaId": "Constants::WHEEL_REAR_RIGHT",
+                    "minFloatValue": 193.0,
+                    "maxFloatValue": 300.0
+                }
+            ],
+            "comment": "Units in kpa",
+            "maxSampleRate": 2.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            137.0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_FRONT_LEFT"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            137.0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            137.0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_REAR_RIGHT"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            137.0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_REAR_LEFT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::PSI"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::KILOPASCAL",
+                "VehicleUnit::PSI",
+                "VehicleUnit::BAR"
+            ]
+        },
+        {
+            "property": "VehicleProperty::CURRENT_GEAR",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleGear::GEAR_PARK"
+                ]
+            },
+            "configArray": [
+                "VehicleGear::GEAR_PARK",
+                "VehicleGear::GEAR_NEUTRAL",
+                "VehicleGear::GEAR_REVERSE",
+                "VehicleGear::GEAR_1",
+                "VehicleGear::GEAR_2",
+                "VehicleGear::GEAR_3",
+                "VehicleGear::GEAR_4",
+                "VehicleGear::GEAR_5"
+            ]
+        },
+        {
+            "property": "VehicleProperty::PARKING_BRAKE_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::PARKING_BRAKE_AUTO_APPLY",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_BRAKE_REGENERATION_LEVEL",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::EV_STOPPING_MODE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::EV_STOPPING_MODE_CREEP"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "Constants::EV_STOPPING_MODE_CREEP",
+                        "Constants::EV_STOPPING_MODE_ROLL",
+                        "Constants::EV_STOPPING_MODE_HOLD"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::FUEL_LEVEL_LOW",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::US_GALLON"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::LITER",
+                "VehicleUnit::US_GALLON"
+            ]
+        },
+        {
+            "property": "VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HW_KEY_INPUT",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HW_KEY_INPUT_V2",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0,
+                    0
+                ],
+                "int64Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HW_MOTION_INPUT",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0,
+                    0,
+                    1,
+                    0,
+                    0
+                ],
+                "floatValues": [
+                    0,
+                    0,
+                    0,
+                    0
+                ],
+                "int64Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HW_ROTARY_INPUT",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HW_CUSTOM_INPUT",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0
+                ]
+            },
+            "configArray": [
+                0,
+                0,
+                0,
+                3,
+                0,
+                0,
+                0,
+                0,
+                0
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM",
+            "defaultValue": {
+                "int32Values": [
+                    50
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_POWER_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ],
+            "configArray": [
+                "VehicleProperty::HVAC_FAN_SPEED",
+                "VehicleProperty::HVAC_FAN_DIRECTION"
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_DEFROSTER",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
+                }
+            ],
+            "comment": "0 means using for all areas"
+        },
+        {
+            "property": "VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
+                }
+            ],
+            "comment": "0 means using for all areas"
+        },
+        {
+            "property": "VehicleProperty::HVAC_MAX_DEFROST_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_RECIRC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_AUTO_RECIRC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_AC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_MAX_AC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_AUTO_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_DUAL_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_FAN_SPEED",
+            "defaultValue": {
+                "int32Values": [
+                    3
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_FAN_DIRECTION",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleHvacFanDirection::FACE"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::FAN_DIRECTION_UNKNOWN",
+                    "Constants::FAN_DIRECTION_FACE",
+                    "Constants::FAN_DIRECTION_FLOOR",
+                    "Constants::FAN_DIRECTION_FACE_FLOOR",
+                    "Constants::FAN_DIRECTION_DEFROST",
+                    "Constants::FAN_DIRECTION_FACE_DEFROST",
+                    "Constants::FAN_DIRECTION_FLOOR_DEFROST",
+                    "Constants::FAN_DIRECTION_FLOOR_DEFROST_FACE"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_SEAT_VENTILATION",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                }
+            ],
+            "comment": "0 is off and +ve values indicate ventilation level."
+        },
+        {
+            "property": "VehicleProperty::HVAC_STEERING_WHEEL_HEAT",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                }
+            ],
+            "comment": "+ve values for heating and -ve for cooling"
+        },
+        {
+            "property": "VehicleProperty::HVAC_SEAT_TEMPERATURE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                }
+            ],
+            "comment": "+ve values for heating and -ve for cooling"
+        },
+        {
+            "property": "VehicleProperty::HVAC_SIDE_MIRROR_HEAT",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 2
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_CURRENT",
+            "defaultValue": {
+                "floatValues": [
+                    19.1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_SET",
+            "defaultValue": {
+                "floatValues": [
+                    17.0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                }
+            ],
+            "comment":
+                    "minFloatValue and maxFloatValue in area config should match corresponding values in configArray",
+            "configArray": [
+                160,
+                280,
+                5,
+                600,
+                840,
+                10
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION",
+            "defaultValue": {
+                "floatValues": [
+                    66.19999694824219,
+                    "VehicleUnit::FAHRENHEIT",
+                    19.0,
+                    66.0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ENV_OUTSIDE_TEMPERATURE",
+            "defaultValue": {
+                "floatValues": [
+                    25.0
+                ]
+            },
+            "maxSampleRate": 2.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::FAHRENHEIT"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::FAHRENHEIT",
+                "VehicleUnit::CELSIUS"
+            ]
+        },
+        {
+            "property": "VehicleProperty::DISTANCE_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::MILE"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0
+                }
+            ],
+            "configArray": [
+                "VehicleUnit::KILOMETER",
+                "VehicleUnit::MILE"
+            ]
+        },
+        {
+            "property": "VehicleProperty::NIGHT_MODE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::GEAR_SELECTION",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleGear::GEAR_PARK"
+                ]
+            },
+            "configArray": [
+                "VehicleGear::GEAR_PARK",
+                "VehicleGear::GEAR_NEUTRAL",
+                "VehicleGear::GEAR_REVERSE",
+                "VehicleGear::GEAR_DRIVE",
+                "VehicleGear::GEAR_1",
+                "VehicleGear::GEAR_2",
+                "VehicleGear::GEAR_3",
+                "VehicleGear::GEAR_4",
+                "VehicleGear::GEAR_5"
+            ]
+        },
+        {
+            "property": "VehicleProperty::TURN_SIGNAL_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleTurnSignal::NONE"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::IGNITION_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleIgnitionState::ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ENGINE_COOLANT_TEMP",
+            "defaultValue": {
+                "floatValues": [
+                    75.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::ENGINE_OIL_LEVEL",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleOilLevel::NORMAL"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ENGINE_OIL_TEMP",
+            "defaultValue": {
+                "floatValues": [
+                    101.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 0.10000000149011612
+        },
+        {
+            "property": "VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::DOOR_LOCK",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_1_LEFT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_1_RIGHT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_2_LEFT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_2_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DOOR_CHILD_LOCK_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::DOOR_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::DOOR_2_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DOOR_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::DOOR_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_REAR",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DOOR_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::DOOR_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_Z_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_Z_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_Y_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_Y_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_LOCK",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::MIRROR_FOLD",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::MIRROR_AUTO_FOLD_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_AUTO_TILT_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDOW_LOCK",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            0
+                        ]
+                    },
+                    "areaId": "Constants::WINDOW_1_RIGHT_2_LEFT_2_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDOW_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::WINDOW_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::WINDOW_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::WINDOW_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::WINDOW_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::WINDOW_ROOF_TOP_1",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDOW_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::WINDOW_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::WINDOW_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::WINDOW_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::WINDOW_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::WINDOW_ROOF_TOP_1",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDSHIELD_WIPERS_PERIOD",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3000
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3000
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDSHIELD_WIPERS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "WindshieldWipersState::OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+                    "supportedEnumValues": [
+                        "WindshieldWipersState::OFF",
+                        "WindshieldWipersState::ON",
+                        "WindshieldWipersState::SERVICE"
+                    ]
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+                    "supportedEnumValues": [
+                        "WindshieldWipersState::OFF",
+                        "WindshieldWipersState::ON"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDSHIELD_WIPERS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "WindshieldWipersSwitch::OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+                    "supportedEnumValues": [
+                        "WindshieldWipersSwitch::OFF",
+                        "WindshieldWipersSwitch::MIST",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_1",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_2",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_3",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_4",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_5",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_1",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_2",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_3",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_4",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_5",
+                        "WindshieldWipersSwitch::AUTO",
+                        "WindshieldWipersSwitch::SERVICE"
+                    ]
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+                    "supportedEnumValues": [
+                        "WindshieldWipersSwitch::OFF",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_1",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_2",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_1",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_2",
+                        "WindshieldWipersSwitch::AUTO",
+                        "WindshieldWipersSwitch::SERVICE"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_DEPTH_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_DEPTH_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_LOCKED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::GLOVE_BOX_DOOR_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::GLOVE_BOX_LOCKED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WHEEL_TICK",
+            "defaultValue": {
+                "int64Values": [
+                    0,
+                    100000,
+                    200000,
+                    300000,
+                    400000
+                ]
+            },
+            "configArray": [
+                15,
+                50000,
+                50000,
+                50000,
+                50000
+            ],
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::ABS_ACTIVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::TRACTION_CONTROL_ACTIVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::AP_POWER_STATE_REQ",
+            "configArray": [
+                0
+            ]
+        },
+        {
+            "property": "VehicleProperty::AP_POWER_STATE_REPORT",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleApPowerStateReport::WAIT_FOR_VHAL",
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::DISPLAY_BRIGHTNESS",
+            "defaultValue": {
+                "int32Values": [
+                    100
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": 0,
+                    "maxInt32Value": 100
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::OBD2_LIVE_FRAME",
+            "configArray": [
+                0,
+                0
+            ]
+        },
+        {
+            "property": "VehicleProperty::OBD2_FREEZE_FRAME",
+            "configArray": [
+                0,
+                0
+            ]
+        },
+        {
+            "property": "VehicleProperty::OBD2_FREEZE_FRAME_INFO"
+        },
+        {
+            "property": "VehicleProperty::OBD2_FREEZE_FRAME_CLEAR",
+            "configArray": [
+                1
+            ]
+        },
+        {
+            "property": "VehicleProperty::HEADLIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HIGH_BEAM_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FRONT_FOG_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::REAR_FOG_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HAZARD_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::CABIN_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::READING_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HEADLIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FRONT_FOG_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::REAR_FOG_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HAZARD_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::CABIN_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_OFF"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::READING_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::EVS_SERVICE_REQUEST",
+            "defaultValue": {
+                "int32Values": [
+                    "EvsServiceType::REARVIEW",
+                    "EvsServiceState::OFF"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_MAP_SERVICE"
+        },
+        {
+            "property": "VehicleProperty::LOCATION_CHARACTERIZATION",
+            "defaultValue": {
+                "int32Values": [
+                    "LocationCharacterization::RAW_GNSS_ONLY"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "EmergencyLaneKeepAssistState::ENABLED"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "EmergencyLaneKeepAssistState::ENABLED",
+                        "EmergencyLaneKeepAssistState::WARNING_LEFT",
+                        "EmergencyLaneKeepAssistState::WARNING_RIGHT",
+                        "EmergencyLaneKeepAssistState::ACTIVATED_STEER_LEFT",
+                        "EmergencyLaneKeepAssistState::ACTIVATED_STEER_RIGHT",
+                        "EmergencyLaneKeepAssistState::USER_OVERRIDE"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CRUISE_CONTROL_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::CRUISE_CONTROL_TYPE",
+            "defaultValue": {
+                "int32Values": [
+                    "CruiseControlType::STANDARD"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "CruiseControlType::STANDARD",
+                        "CruiseControlType::ADAPTIVE",
+                        "CruiseControlType::PREDICTIVE"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CRUISE_CONTROL_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "CruiseControlState::ENABLED"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "CruiseControlState::ENABLED",
+                        "CruiseControlState::ACTIVATED",
+                        "CruiseControlState::USER_OVERRIDE",
+                        "CruiseControlState::SUSPENDED",
+                        "CruiseControlState::FORCED_DEACTIVATION_WARNING"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CRUISE_CONTROL_COMMAND",
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "CruiseControlCommand::ACTIVATE",
+                        "CruiseControlCommand::SUSPEND",
+                        "CruiseControlCommand::INCREASE_TARGET_SPEED",
+                        "CruiseControlCommand::DECREASE_TARGET_SPEED",
+                        "CruiseControlCommand::INCREASE_TARGET_TIME_GAP",
+                        "CruiseControlCommand::DECREASE_TARGET_TIME_GAP"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CRUISE_CONTROL_TARGET_SPEED",
+            "defaultValue": {
+                "floatValues": [
+                    25.0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minFloatValue": 20.0,
+                    "maxFloatValue": 35.0
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP",
+            "defaultValue": {
+                "int32Values": [
+                    1200
+                ]
+            },
+            "configArray": [
+                1200,
+                1400,
+                1600,
+                1800,
+                2000,
+                2200
+            ]
+        },
+        {
+            "property": "VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE",
+            "defaultValue": {
+                "int32Values": [
+                    100000
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": 0,
+                    "maxInt32Value": 200000
+                }
+            ],
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::HANDS_ON_DETECTION_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "HandsOnDetectionDriverState::HANDS_ON"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "HandsOnDetectionDriverState::HANDS_ON",
+                        "HandsOnDetectionDriverState::HANDS_OFF"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HANDS_ON_DETECTION_WARNING",
+            "defaultValue": {
+                "int32Values": [
+                    "HandsOnDetectionWarning::NO_WARNING"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "HandsOnDetectionWarning::NO_WARNING",
+                        "HandsOnDetectionWarning::WARNING"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::INITIAL_USER_INFO"
+        },
+        {
+            "property": "VehicleProperty::SWITCH_USER"
+        },
+        {
+            "property": "VehicleProperty::CREATE_USER"
+        },
+        {
+            "property": "VehicleProperty::REMOVE_USER"
+        },
+        {
+            "property": "VehicleProperty::USER_IDENTIFICATION_ASSOCIATION"
+        },
+        {
+            "property": "VehicleProperty::POWER_POLICY_REQ"
+        },
+        {
+            "property": "VehicleProperty::POWER_POLICY_GROUP_REQ"
+        },
+        {
+            "property": "VehicleProperty::CURRENT_POWER_POLICY"
+        },
+        {
+            "property": "VehicleProperty::ANDROID_EPOCH_TIME"
+        },
+        {
+            "property": "VehicleProperty::WATCHDOG_ALIVE"
+        },
+        {
+            "property": "VehicleProperty::WATCHDOG_TERMINATED_PROCESS"
+        },
+        {
+            "property": "VehicleProperty::VHAL_HEARTBEAT"
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_SWITCH_UI",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "comment": "0 means ClusterHome"
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_DISPLAY_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1
+                ]
+            },
+            "comment":
+                    "Value means: 0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1, -1, -1 /* Insets */"
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_REPORT_STATE",
+            "configArray": [
+                0,
+                0,
+                0,
+                11,
+                0,
+                0,
+                0,
+                0,
+                16
+            ]
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_REQUEST_DISPLAY"
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_NAVIGATION_STATE"
+        },
+        {
+            "property": "VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT",
+            "defaultValue": {
+                "int32Values": [
+                    "GsrComplianceRequirementType::GSR_COMPLIANCE_REQUIRED_V1"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "ErrorState::NOT_AVAILABLE_DISABLED"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "AutomaticEmergencyBrakingState::ENABLED",
+                        "AutomaticEmergencyBrakingState::ACTIVATED",
+                        "AutomaticEmergencyBrakingState::USER_OVERRIDE"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FORWARD_COLLISION_WARNING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "ForwardCollisionWarningState::NO_WARNING"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "ForwardCollisionWarningState::NO_WARNING",
+                        "ForwardCollisionWarningState::WARNING"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::BLIND_SPOT_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::BLIND_SPOT_WARNING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "BlindSpotWarningState::NO_WARNING"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "BlindSpotWarningState::NO_WARNING",
+                        "BlindSpotWarningState::WARNING"
+                    ]
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "BlindSpotWarningState::NO_WARNING",
+                        "BlindSpotWarningState::WARNING"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LANE_DEPARTURE_WARNING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "LaneDepartureWarningState::NO_WARNING"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "LaneDepartureWarningState::NO_WARNING",
+                        "LaneDepartureWarningState::WARNING_LEFT",
+                        "LaneDepartureWarningState::WARNING_RIGHT"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::LANE_KEEP_ASSIST_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LANE_KEEP_ASSIST_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "LaneKeepAssistState::ENABLED"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "LaneKeepAssistState::ENABLED",
+                        "LaneKeepAssistState::ACTIVATED_STEER_LEFT",
+                        "LaneKeepAssistState::ACTIVATED_STEER_RIGHT",
+                        "LaneKeepAssistState::USER_OVERRIDE"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::LANE_CENTERING_ASSIST_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LANE_CENTERING_ASSIST_COMMAND"
+        },
+        {
+            "property": "VehicleProperty::LANE_CENTERING_ASSIST_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "LaneCenteringAssistState::ENABLED"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_SAFETY",
+                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "LaneCenteringAssistState::ENABLED",
+                        "LaneCenteringAssistState::ACTIVATION_REQUESTED",
+                        "LaneCenteringAssistState::ACTIVATED",
+                        "LaneCenteringAssistState::USER_OVERRIDE",
+                        "LaneCenteringAssistState::FORCED_DEACTIVATION_WARNING"
+                    ]
+                }
+            ]
+        }
+    ]
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/config/README.md b/automotive/vehicle/aidl/impl/default_config/config/README.md
new file mode 100644
index 0000000..6e82de5
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/README.md
@@ -0,0 +1,171 @@
+# Property Configuration Files
+
+Each JSON file in this folder is a property configuration file for reference
+Vehicle HAL. They contain VehiclePropConfig information along with initial
+value information.
+
+## JSON schema
+
+Each JSON file must be in a schema like the following example:
+(The comment starting with "//" is for documentation only and must be removed
+from the actual JSON file. The "comment" field is used for comment in the
+actual JSON file and will be ignored by the parser)
+
+```
+{
+    // (number) The version for the JSON schema.
+    "apiVersion": 1,
+    // (non-empty array of objects) The property configuration list.
+    //
+    // Each object is a configuration for one property.
+    "properties": [
+        {
+            // (number/string) The ID for the property.
+            // This value is defined in a string value
+            // which represents a constant value, see the "JSON Number-type
+            // Field Values" section for detail.
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            // (optional, number/string) The access mode for the property.
+            // If specified, this overwrite the default access mode specified in
+            // VehicleProperty.aidl. Must be specified for vendor properties.
+            "access": "VehiclePropertyAccess::READ",
+            // (optional, number/string) The change mode for the property.
+            // If specified, this overwrite the default change mode specified in
+            // VehicleProperty.aidl. Must be specified for vendor properties.
+            "changeMode": "VehiclePropertyChangeMode::STATIC",
+            // (optional, string) The config string.
+            "configString": "blahblah",
+            // (optional, array of number/string) The config array.
+            "configArray": [1, 2, "Constants::HVAC_ALL"],
+            // (optional, object) The default value for the property.
+            // If not specified, the property will be shown as unavailable
+            // until its value is set.
+            "defaultValue": {
+                // (optional, array of int number/string) Int values.
+                "int32Values": [1, 2, "Constants::HVAC_ALL"],
+                // (optional, array of int number/string) Long values.
+                "int64Values": [1, 2],
+                // (optional, array of float number/string) Float values.
+                "floatValues": [1.1, 2.2],
+                // (optional, string) String value.
+                "stringValue": "test"
+            },
+            // (optional, number/string) The minimum sample rate in HZ.
+            // Only work for VehiclePropertyChangeMode::CONTINUOUS property.
+            // Must be specified for continuous property.
+            "minSampleRate": 1,
+            // (optional, number/string) The maximum sample rate in HZ.
+            // Only work for VehiclePropertyChangeMode::CONTINUOUS property.
+            // Must be specified for continuous property.
+            "maxSampleRate": 10,
+            // (optional, array of objects) The area configs.
+            "areas:" [
+                {
+                    // (number/string) The area ID.
+                    "areaId": "Constants::DOOR_1_LEFT",
+                    // (optional number/string) The minimum int value.
+                    "minInt32Value": 1,
+                    // (optional number/string) The maximum int value.
+                    "maxInt32Value": 10,
+                    // (optional number/string) The minimum long value.
+                    "minInt64Value": 1,
+                    // (optional number/string) The maximum long value.
+                    "maxInt64Value": 10,
+                    // (optional number/string) The minimum float value.
+                    "minFloatValue": 1,
+                    // (optional number/string) The maximum float value.
+                    "maxFloatValue": 10,
+                    // (optional object) The default value for this area.
+                    // Uses the same format as the "defaultValue" field for
+                    // property object. If specified, this overwrite the global
+                    // defaultValue.
+                    "defaultValue": {
+                        "int32Values": [1, 2, "Constants::HVAC_ALL"],
+                        "int64Values": [1, 2],
+                        "floatValues": [1.1, 2.2],
+                        "stringValue": "test"
+                    }
+                }
+            ]
+        }
+     ]
+}
+```
+
+## JSON Number-type Field Values
+
+For number type field values, they can either be defined as a numeric number,
+e.g., `{"minInt32Value": 1}` or be defined as a string which represents a
+defined constant value, e.g.,
+`{"property": "VehicleProperty::INFO_FUEL_CAPACITY"}`.
+
+For constant values, they must be a string in the format of `XXX::XXX`, where
+the field before `::` is the constant type, and the field after `::` is the
+variable name.
+
+We support the following constant types:
+
+* VehiclePropertyAccess
+
+* VehiclePropertyChangeMode
+
+* VehicleGear
+
+* VehicleAreaWindow
+
+* VehicleOilLevel
+
+* VehicleUnit
+
+* VehicleSeatOccupancyState
+
+* VehicleHvacFanDirection
+
+* VehicleApPowerStateReport
+
+* VehicleTurnSignal
+
+* VehicleVendorPermission
+
+* EvsServiceType
+
+* EvsServiceState
+
+* EvConnectorType
+
+* VehicleProperty
+
+* GsrComplianceRequirementType
+
+* VehicleIgnitionState
+
+* FuelType
+
+* AutomaticEmergencyBrakingState
+
+* ForwardCollisionWarningState
+
+* BlindSpotWarningState
+
+* LaneDepartureWarningState
+
+* LaneKeepAssistState
+
+* LaneCenteringAssistCommand
+
+* LaneCenteringAssistState
+
+* ErrorState
+
+* WindshieldWipersState
+
+* WindshieldWipersSwitch
+
+* Constants
+
+Every constant type except "Constants" corresponds to a enum defined in Vehicle
+HAL interfac. E.g. "VehicleProperty" corresponds to the enums defined in
+"VehicleProperty.aidl".
+
+"Constants" type refers to the constant variables defined in the paresr.
+Specifically, the "CONSTANTS_BY_NAME" map defined in "JsonConfigLoader.cpp".
diff --git a/automotive/vehicle/aidl/impl/default_config/config/TestProperties.json b/automotive/vehicle/aidl/impl/default_config/config/TestProperties.json
new file mode 100644
index 0000000..fd4b002
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/TestProperties.json
@@ -0,0 +1,209 @@
+{
+    "properties": [
+        {
+            "property": "Constants::kMixedTypePropertyForTest",
+            "defaultValue": {
+                "floatValues": [
+                    4.5
+                ],
+                "int32Values": [
+                    1,
+                    2,
+                    3
+                ],
+                "stringValue": "MIXED property"
+            },
+            "configArray": [
+                1,
+                1,
+                0,
+                2,
+                0,
+                0,
+                1,
+                0,
+                0
+            ],
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::VENDOR_EXTENSION_BOOLEAN_PROPERTY",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_1_LEFT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_1_RIGHT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            0
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_2_LEFT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            0
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_2_RIGHT"
+                }
+            ],
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::VENDOR_EXTENSION_FLOAT_PROPERTY",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            1.0
+                        ]
+                    },
+                    "areaId": "Constants::HVAC_LEFT",
+                    "minFloatValue": -10.0,
+                    "maxFloatValue": 10.0
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            2.0
+                        ]
+                    },
+                    "areaId": "Constants::HVAC_RIGHT",
+                    "minFloatValue": -10.0,
+                    "maxFloatValue": 10.0
+                }
+            ],
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::VENDOR_EXTENSION_INT_PROPERTY",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+                    "minInt32Value": -100,
+                    "maxInt32Value": 100
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            0
+                        ]
+                    },
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+                    "minInt32Value": -100,
+                    "maxInt32Value": 100
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            -1
+                        ]
+                    },
+                    "areaId": "VehicleAreaWindow::ROOF_TOP_1",
+                    "minInt32Value": -100,
+                    "maxInt32Value": 100
+                }
+            ],
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::VENDOR_EXTENSION_STRING_PROPERTY",
+            "defaultValue": {
+                "stringValue": "Vendor String Property"
+            },
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::PLACEHOLDER_PROPERTY_INT",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::PLACEHOLDER_PROPERTY_FLOAT",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::PLACEHOLDER_PROPERTY_BOOLEAN",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::PLACEHOLDER_PROPERTY_STRING",
+            "defaultValue": {
+                "stringValue": "Test"
+            },
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::ECHO_REVERSE_BYTES",
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::VENDOR_PROPERTY_ID",
+            "access": "VehiclePropertyAccess::READ_WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "configArray": [
+                "Constants::kMixedTypePropertyForTest",
+                "VehicleVendorPermission::PERMISSION_GET_VENDOR_CATEGORY_INFO",
+                "VehicleVendorPermission::PERMISSION_SET_VENDOR_CATEGORY_INFO",
+                "Constants::VENDOR_EXTENSION_INT_PROPERTY",
+                "VehicleVendorPermission::PERMISSION_GET_VENDOR_CATEGORY_SEAT",
+                "VehicleVendorPermission::PERMISSION_NOT_ACCESSIBLE",
+                "Constants::VENDOR_EXTENSION_FLOAT_PROPERTY",
+                "VehicleVendorPermission::PERMISSION_DEFAULT",
+                "VehicleVendorPermission::PERMISSION_DEFAULT"
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json b/automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json
new file mode 100644
index 0000000..3a1a783
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json
@@ -0,0 +1,63 @@
+{
+    "properties": [
+        {
+            "property": "Constants::VENDOR_CLUSTER_SWITCH_UI",
+            "access": "VehiclePropertyAccess::WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::VENDOR_CLUSTER_DISPLAY_STATE",
+            "access": "VehiclePropertyAccess::WRITE",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        },
+        {
+            "property": "Constants::VENDOR_CLUSTER_REPORT_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    0,
+                    -1
+                ]
+            },
+            "configArray": [
+                0,
+                0,
+                0,
+                11,
+                0,
+                0,
+                0,
+                0,
+                16
+            ],
+            "access": "VehiclePropertyAccess::READ",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE",
+            "comment":
+                    "Value means 0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1, -1, -1 /* Insets */, 0 /* ClusterHome */, -1 /* ClusterNone */"
+        },
+        {
+            "property": "Constants::VENDOR_CLUSTER_REQUEST_DISPLAY",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "access": "VehiclePropertyAccess::READ",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE",
+            "comment": "0 means ClusterHome"
+        },
+        {
+            "property": "Constants::VENDOR_CLUSTER_NAVIGATION_STATE",
+            "access": "VehiclePropertyAccess::READ",
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
deleted file mode 100644
index e00f775..0000000
--- a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
+++ /dev/null
@@ -1,1307 +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.
- */
-
-#ifndef android_hardware_automotive_vehicle_aidl_impl_default_config_include_DefaultConfig_H_
-#define android_hardware_automotive_vehicle_aidl_impl_default_config_include_DefaultConfig_H_
-
-#include <PropertyUtils.h>
-#include <TestPropertyUtils.h>
-#include <VehicleHalTypes.h>
-
-#include <map>
-#include <vector>
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-
-// Types used in configs, not to be exposed as public API.
-namespace defaultconfig_impl {
-
-using ::aidl::android::hardware::automotive::vehicle::EvConnectorType;
-using ::aidl::android::hardware::automotive::vehicle::EvsServiceState;
-using ::aidl::android::hardware::automotive::vehicle::EvsServiceType;
-using ::aidl::android::hardware::automotive::vehicle::FuelType;
-using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
-using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
-using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
-using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
-using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
-using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
-using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
-using ::aidl::android::hardware::automotive::vehicle::VehicleIgnitionState;
-using ::aidl::android::hardware::automotive::vehicle::VehicleOilLevel;
-using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
-using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
-using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
-using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
-using ::aidl::android::hardware::automotive::vehicle::VehicleSeatOccupancyState;
-using ::aidl::android::hardware::automotive::vehicle::VehicleTurnSignal;
-using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
-using ::aidl::android::hardware::automotive::vehicle::VehicleVendorPermission;
-
-struct ConfigDeclaration {
-    VehiclePropConfig config;
-
-    // This value will be used as an initial value for the property. If this field is specified for
-    // property that supports multiple areas then it will be used for all areas unless particular
-    // area is overridden in initialAreaValue field.
-    RawPropValues initialValue;
-    // Use initialAreaValues if it is necessary to specify different values per each area.
-    std::map<int32_t, RawPropValues> initialAreaValues;
-};
-
-const std::vector<ConfigDeclaration> kVehicleProperties = {
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.floatValues = {15000.0f}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_FUEL_TYPE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.int32Values = {toInt(FuelType::FUEL_TYPE_UNLEADED)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_EV_BATTERY_CAPACITY),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.floatValues = {150000.0f}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_EV_CONNECTOR_TYPE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.int32Values = {toInt(EvConnectorType::IEC_TYPE_1_AC)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_FUEL_DOOR_LOCATION),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.int32Values = {FUEL_DOOR_REAR_LEFT}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_EV_PORT_LOCATION),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.int32Values = {CHARGE_PORT_FRONT_LEFT}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.int32Values = {CHARGE_PORT_FRONT_LEFT, CHARGE_PORT_REAR_LEFT}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_MAKE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.stringValue = "Toy Vehicle"}},
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_MODEL),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.stringValue = "Speedy Model"}},
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_MODEL_YEAR),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.int32Values = {2020}}},
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_EXTERIOR_DIMENSIONS),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.int32Values = {1776, 4950, 2008, 2140, 2984, 1665, 1667, 11800}}},
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 10.0f,
-                 },
-         .initialValue = {.floatValues = {0.0f}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .configArray = {toInt(VehicleUnit::METER_PER_SEC),
-                                         toInt(VehicleUnit::MILES_PER_HOUR),
-                                         toInt(VehicleUnit::KILOMETERS_PER_HOUR)},
-                 },
-         .initialValue = {.int32Values = {toInt(VehicleUnit::KILOMETERS_PER_HOUR)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::SEAT_OCCUPANCY),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .areaConfigs = {VehicleAreaConfig{.areaId = (SEAT_1_LEFT)},
-                                         VehicleAreaConfig{.areaId = (SEAT_1_RIGHT)}},
-                 },
-         .initialAreaValues = {{SEAT_1_LEFT,
-                                {.int32Values = {toInt(VehicleSeatOccupancyState::VACANT)}}},
-                               {SEAT_1_RIGHT,
-                                {.int32Values = {toInt(VehicleSeatOccupancyState::VACANT)}}}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::INFO_DRIVER_SEAT),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                         // this was a zoned property on an old vhal, but it is meant to be global
-                         .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
-                 },
-         .initialValue = {.int32Values = {SEAT_1_LEFT}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::PERF_ODOMETER),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 10.0f,
-                 },
-         .initialValue = {.floatValues = {0.0f}}},
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::PERF_STEERING_ANGLE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 10.0f,
-                 },
-         .initialValue = {.floatValues = {0.0f}}},
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::PERF_REAR_STEERING_ANGLE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 10.0f,
-                 },
-         .initialValue = {.floatValues = {0.0f}}},
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::ENGINE_RPM),
-                                .access = VehiclePropertyAccess::READ,
-                                .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                                .minSampleRate = 1.0f,
-                                .maxSampleRate = 10.0f,
-                        },
-                .initialValue = {.floatValues = {0.0f}},
-        },
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::FUEL_LEVEL),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 100.0f,
-                 },
-         .initialValue = {.floatValues = {15000.0f}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::FUEL_DOOR_OPEN),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {0}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_BATTERY_LEVEL),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 100.0f,
-                 },
-         .initialValue = {.floatValues = {150000.0f}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_CHARGE_PORT_OPEN),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {0}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_CHARGE_PORT_CONNECTED),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {0}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 10.0f,
-                 },
-         .initialValue = {.floatValues = {0.0f}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .configArray = {/*max current draw allowed by vehicle in amperes=*/20},
-                 },
-         .initialValue = {.floatValues = {(float)12.5}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_CHARGE_PERCENT_LIMIT),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .configArray = {20, 40, 60, 80, 100},
-                 },
-         .initialValue = {.floatValues = {40}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_CHARGE_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {2}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_CHARGE_SWITCH),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {0 /* false */}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_CHARGE_TIME_REMAINING),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 10.0f,
-                 },
-         .initialValue = {.int32Values = {20}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EV_REGENERATIVE_BRAKING_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {2}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::TRAILER_PRESENT),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {2}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::VEHICLE_CURB_WEIGHT),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.int32Values = {30}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::RANGE_REMAINING),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 2.0f,
-                 },
-         .initialValue = {.floatValues = {50000.0f}}},  // units in meters
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::TIRE_PRESSURE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .areaConfigs = {VehicleAreaConfig{
-                                                 .areaId = WHEEL_FRONT_LEFT,
-                                                 .minFloatValue = 193.0f,
-                                                 .maxFloatValue = 300.0f,
-                                         },
-                                         VehicleAreaConfig{
-                                                 .areaId = WHEEL_FRONT_RIGHT,
-                                                 .minFloatValue = 193.0f,
-                                                 .maxFloatValue = 300.0f,
-                                         },
-                                         VehicleAreaConfig{
-                                                 .areaId = WHEEL_REAR_LEFT,
-                                                 .minFloatValue = 193.0f,
-                                                 .maxFloatValue = 300.0f,
-                                         },
-                                         VehicleAreaConfig{
-                                                 .areaId = WHEEL_REAR_RIGHT,
-                                                 .minFloatValue = 193.0f,
-                                                 .maxFloatValue = 300.0f,
-                                         }},
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 2.0f,
-                 },
-         .initialValue = {.floatValues = {200.0f}}},  // units in kPa
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                         .areaConfigs = {VehicleAreaConfig{.areaId = WHEEL_FRONT_LEFT},
-                                         VehicleAreaConfig{.areaId = WHEEL_FRONT_RIGHT},
-                                         VehicleAreaConfig{.areaId = WHEEL_REAR_RIGHT},
-                                         VehicleAreaConfig{.areaId = WHEEL_REAR_LEFT}},
-                 },
-         .initialAreaValues = {{WHEEL_FRONT_LEFT, {.floatValues = {137.0f}}},
-                               {WHEEL_FRONT_RIGHT, {.floatValues = {137.0f}}},
-                               {WHEEL_REAR_RIGHT, {.floatValues = {137.0f}}},
-                               {WHEEL_REAR_LEFT, {.floatValues = {137.0f}}}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .configArray = {toInt(VehicleUnit::KILOPASCAL), toInt(VehicleUnit::PSI),
-                                         toInt(VehicleUnit::BAR)},
-                 },
-         .initialValue = {.int32Values = {toInt(VehicleUnit::PSI)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::CURRENT_GEAR),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .configArray = {toInt(VehicleGear::GEAR_PARK),
-                                         toInt(VehicleGear::GEAR_NEUTRAL),
-                                         toInt(VehicleGear::GEAR_REVERSE),
-                                         toInt(VehicleGear::GEAR_1), toInt(VehicleGear::GEAR_2),
-                                         toInt(VehicleGear::GEAR_3), toInt(VehicleGear::GEAR_4),
-                                         toInt(VehicleGear::GEAR_5)},
-                 },
-         .initialValue = {.int32Values = {toInt(VehicleGear::GEAR_PARK)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::PARKING_BRAKE_ON),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {1}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::PARKING_BRAKE_AUTO_APPLY),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {1}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::FUEL_LEVEL_LOW),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {0}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HW_KEY_INPUT),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {0, 0, 0}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HW_ROTARY_INPUT),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {0, 0, 0}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HW_CUSTOM_INPUT),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .configArray = {0, 0, 0, 3, 0, 0, 0, 0, 0},
-                 },
-         .initialValue =
-                 {
-                         .int32Values = {0, 0, 0},
-                 }},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_POWER_ON),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}},
-                    // TODO(bryaneyler): Ideally, this is generated dynamically from
-                    // kHvacPowerProperties.
-                    .configArray = {toInt(VehicleProperty::HVAC_FAN_SPEED),
-                                    toInt(VehicleProperty::HVAC_FAN_DIRECTION)}},
-         .initialValue = {.int32Values = {1}}},
-
-        {
-                .config = {.prop = toInt(VehicleProperty::HVAC_DEFROSTER),
-                           .access = VehiclePropertyAccess::READ_WRITE,
-                           .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                           .areaConfigs =
-                                   {VehicleAreaConfig{
-                                            .areaId = toInt(VehicleAreaWindow::FRONT_WINDSHIELD)},
-                                    VehicleAreaConfig{
-                                            .areaId = toInt(VehicleAreaWindow::REAR_WINDSHIELD)}}},
-                .initialValue = {.int32Values = {0}}  // Will be used for all areas.
-        },
-        {
-                .config = {.prop = toInt(VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON),
-                           .access = VehiclePropertyAccess::READ_WRITE,
-                           .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                           .areaConfigs =
-                                   {VehicleAreaConfig{
-                                            .areaId = toInt(VehicleAreaWindow::FRONT_WINDSHIELD)},
-                                    VehicleAreaConfig{
-                                            .areaId = toInt(VehicleAreaWindow::REAR_WINDSHIELD)}}},
-                .initialValue = {.int32Values = {0}}  // Will be used for all areas.
-        },
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_MAX_DEFROST_ON),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_RECIRC_ON),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
-         .initialValue = {.int32Values = {1}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_AUTO_RECIRC_ON),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_AC_ON),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
-         .initialValue = {.int32Values = {1}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_MAX_AC_ON),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_AUTO_ON),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
-         .initialValue = {.int32Values = {1}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_DUAL_ON),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{
-                            .areaId = HVAC_ALL, .minInt32Value = 1, .maxInt32Value = 7}}},
-         .initialValue = {.int32Values = {3}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
-         .initialValue = {.int32Values = {toInt(VehicleHvacFanDirection::FACE)}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE),
-                    .access = VehiclePropertyAccess::READ,
-                    .changeMode = VehiclePropertyChangeMode::STATIC,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
-         .initialValue = {.int32Values = {FAN_DIRECTION_FACE, FAN_DIRECTION_FLOOR,
-                                          FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR,
-                                          FAN_DIRECTION_DEFROST,
-                                          FAN_DIRECTION_FACE | FAN_DIRECTION_DEFROST,
-                                          FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST,
-                                          FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST |
-                                                  FAN_DIRECTION_FACE}}},
-        {.config = {.prop = toInt(VehicleProperty::HVAC_SEAT_VENTILATION),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{
-                                            .areaId = SEAT_1_LEFT,
-                                            .minInt32Value = 0,
-                                            .maxInt32Value = 3,
-                                    },
-                                    VehicleAreaConfig{
-                                            .areaId = SEAT_1_RIGHT,
-                                            .minInt32Value = 0,
-                                            .maxInt32Value = 3,
-                                    }}},
-         .initialValue =
-                 {.int32Values = {0}}},  // 0 is off and +ve values indicate ventilation level.
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_STEERING_WHEEL_HEAT),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{
-                            .areaId = (0), .minInt32Value = -2, .maxInt32Value = 2}}},
-         .initialValue = {.int32Values = {0}}},  // +ve values for heating and -ve for cooling
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_SEAT_TEMPERATURE),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{
-                                            .areaId = SEAT_1_LEFT,
-                                            .minInt32Value = -2,
-                                            .maxInt32Value = 2,
-                                    },
-                                    VehicleAreaConfig{
-                                            .areaId = SEAT_1_RIGHT,
-                                            .minInt32Value = -2,
-                                            .maxInt32Value = 2,
-                                    }}},
-         .initialValue = {.int32Values = {0}}},  // +ve values for heating and -ve for cooling
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .configArray = {160, 280, 5, 605, 825, 10},
-                    .areaConfigs = {VehicleAreaConfig{
-                                            .areaId = HVAC_LEFT,
-                                            .minFloatValue = 16,
-                                            .maxFloatValue = 32,
-                                    },
-                                    VehicleAreaConfig{
-                                            .areaId = HVAC_RIGHT,
-                                            .minFloatValue = 16,
-                                            .maxFloatValue = 32,
-                                    }}},
-         .initialAreaValues = {{HVAC_LEFT, {.floatValues = {16}}},
-                               {HVAC_RIGHT, {.floatValues = {20}}}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.floatValues = {66.2f, (float)VehicleUnit::FAHRENHEIT, 19.0f, 66.5f}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE),
-                         .access = VehiclePropertyAccess::READ,
-                         // TODO(bryaneyler): Support ON_CHANGE as well.
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 2.0f,
-                 },
-         .initialValue = {.floatValues = {25.0f}}},
-
-        {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .configArray = {toInt(VehicleUnit::FAHRENHEIT), toInt(VehicleUnit::CELSIUS)}},
-         .initialValue = {.int32Values = {toInt(VehicleUnit::FAHRENHEIT)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::DISTANCE_DISPLAY_UNITS),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
-                         .configArray = {toInt(VehicleUnit::KILOMETER), toInt(VehicleUnit::MILE)},
-                 },
-         .initialValue = {.int32Values = {toInt(VehicleUnit::MILE)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::NIGHT_MODE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {0}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::GEAR_SELECTION),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .configArray = {toInt(VehicleGear::GEAR_PARK),
-                                         toInt(VehicleGear::GEAR_NEUTRAL),
-                                         toInt(VehicleGear::GEAR_REVERSE),
-                                         toInt(VehicleGear::GEAR_DRIVE), toInt(VehicleGear::GEAR_1),
-                                         toInt(VehicleGear::GEAR_2), toInt(VehicleGear::GEAR_3),
-                                         toInt(VehicleGear::GEAR_4), toInt(VehicleGear::GEAR_5)},
-                 },
-         .initialValue = {.int32Values = {toInt(VehicleGear::GEAR_PARK)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::TURN_SIGNAL_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {toInt(VehicleTurnSignal::NONE)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::IGNITION_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {toInt(VehicleIgnitionState::ON)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::ENGINE_OIL_LEVEL),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {toInt(VehicleOilLevel::NORMAL)}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::ENGINE_OIL_TEMP),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .minSampleRate = 0.1,  // 0.1 Hz, every 10 seconds
-                         .maxSampleRate = 10,   // 10 Hz, every 100 ms
-                 },
-         .initialValue = {.floatValues = {101.0f}}},
-
-        {
-                .config = {.prop = kMixedTypePropertyForTest,
-                           .access = VehiclePropertyAccess::READ_WRITE,
-                           .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                           .configArray = {1, 1, 0, 2, 0, 0, 1, 0, 0}},
-                .initialValue =
-                        {
-                                .int32Values = {1 /* indicate TRUE boolean value */, 2, 3},
-                                .floatValues = {4.5f},
-                                .stringValue = "MIXED property",
-                        },
-        },
-
-        {.config = {.prop = toInt(VehicleProperty::DOOR_LOCK),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = DOOR_1_LEFT},
-                                    VehicleAreaConfig{.areaId = DOOR_1_RIGHT},
-                                    VehicleAreaConfig{.areaId = DOOR_2_LEFT},
-                                    VehicleAreaConfig{.areaId = DOOR_2_RIGHT}}},
-         .initialAreaValues = {{DOOR_1_LEFT, {.int32Values = {1}}},
-                               {DOOR_1_RIGHT, {.int32Values = {1}}},
-                               {DOOR_2_LEFT, {.int32Values = {1}}},
-                               {DOOR_2_RIGHT, {.int32Values = {1}}}}},
-
-        {.config = {.prop = toInt(VehicleProperty::DOOR_POS),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs =
-                            {VehicleAreaConfig{
-                                     .areaId = DOOR_1_LEFT, .minInt32Value = 0, .maxInt32Value = 1},
-                             VehicleAreaConfig{.areaId = DOOR_1_RIGHT,
-                                               .minInt32Value = 0,
-                                               .maxInt32Value = 1},
-                             VehicleAreaConfig{
-                                     .areaId = DOOR_2_LEFT, .minInt32Value = 0, .maxInt32Value = 1},
-                             VehicleAreaConfig{.areaId = DOOR_2_RIGHT,
-                                               .minInt32Value = 0,
-                                               .maxInt32Value = 1},
-                             VehicleAreaConfig{
-                                     .areaId = DOOR_REAR, .minInt32Value = 0, .maxInt32Value = 1}}},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config = {.prop = toInt(VehicleProperty::WINDOW_LOCK),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = WINDOW_1_RIGHT | WINDOW_2_LEFT |
-                                                                WINDOW_2_RIGHT}}},
-         .initialAreaValues = {{WINDOW_1_RIGHT | WINDOW_2_LEFT | WINDOW_2_RIGHT,
-                                {.int32Values = {0}}}}},
-
-        {.config = {.prop = toInt(VehicleProperty::WINDOW_POS),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = WINDOW_1_LEFT,
-                                                      .minInt32Value = 0,
-                                                      .maxInt32Value = 10},
-                                    VehicleAreaConfig{.areaId = WINDOW_1_RIGHT,
-                                                      .minInt32Value = 0,
-                                                      .maxInt32Value = 10},
-                                    VehicleAreaConfig{.areaId = WINDOW_2_LEFT,
-                                                      .minInt32Value = 0,
-                                                      .maxInt32Value = 10},
-                                    VehicleAreaConfig{.areaId = WINDOW_2_RIGHT,
-                                                      .minInt32Value = 0,
-                                                      .maxInt32Value = 10},
-                                    VehicleAreaConfig{.areaId = WINDOW_ROOF_TOP_1,
-                                                      .minInt32Value = -10,
-                                                      .maxInt32Value = 10}}},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config =
-                 {
-                         .prop = WHEEL_TICK,
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-                         .configArray = {ALL_WHEELS, 50000, 50000, 50000, 50000},
-                         .minSampleRate = 1.0f,
-                         .maxSampleRate = 10.0f,
-                 },
-         .initialValue = {.int64Values = {0, 100000, 200000, 300000, 400000}}},
-
-        {.config = {.prop = ABS_ACTIVE,
-                    .access = VehiclePropertyAccess::READ,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config = {.prop = TRACTION_CONTROL_ACTIVE,
-                    .access = VehiclePropertyAccess::READ,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
-                    .access = VehiclePropertyAccess::READ,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .configArray = {3}}},
-
-        {.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
-         .initialValue = {.int32Values = {toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL), 0}}},
-
-        {.config = {.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.minInt32Value = 0, .maxInt32Value = 100}}},
-         .initialValue = {.int32Values = {100}}},
-
-        {
-                .config = {.prop = OBD2_LIVE_FRAME,
-                           .access = VehiclePropertyAccess::READ,
-                           .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                           .configArray = {0, 0}},
-        },
-
-        {
-                .config = {.prop = OBD2_FREEZE_FRAME,
-                           .access = VehiclePropertyAccess::READ,
-                           .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                           .configArray = {0, 0}},
-        },
-
-        {
-                .config = {.prop = OBD2_FREEZE_FRAME_INFO,
-                           .access = VehiclePropertyAccess::READ,
-                           .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
-        },
-
-        {
-                .config = {.prop = OBD2_FREEZE_FRAME_CLEAR,
-                           .access = VehiclePropertyAccess::WRITE,
-                           .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                           .configArray = {1}},
-        },
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HEADLIGHTS_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HIGH_BEAM_LIGHTS_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::FOG_LIGHTS_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HAZARD_LIGHTS_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HEADLIGHTS_SWITCH),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::FOG_LIGHTS_SWITCH),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_SWITCH),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_SWITCH),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::HAZARD_LIGHTS_SWITCH),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::EVS_SERVICE_REQUEST),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {toInt(EvsServiceType::REARVIEW),
-                                          toInt(EvsServiceState::OFF)}}},
-
-        {.config = {.prop = VEHICLE_MAP_SERVICE,
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE}},
-
-        // Example Vendor Extension properties for testing
-        {.config = {.prop = VENDOR_EXTENSION_BOOLEAN_PROPERTY,
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = DOOR_1_LEFT},
-                                    VehicleAreaConfig{.areaId = DOOR_1_RIGHT},
-                                    VehicleAreaConfig{.areaId = DOOR_2_LEFT},
-                                    VehicleAreaConfig{.areaId = DOOR_2_RIGHT}}},
-         .initialAreaValues = {{DOOR_1_LEFT, {.int32Values = {1}}},
-                               {DOOR_1_RIGHT, {.int32Values = {1}}},
-                               {DOOR_2_LEFT, {.int32Values = {0}}},
-                               {DOOR_2_RIGHT, {.int32Values = {0}}}}},
-
-        {.config = {.prop = VENDOR_EXTENSION_FLOAT_PROPERTY,
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_LEFT,
-                                                      .minFloatValue = -10,
-                                                      .maxFloatValue = 10},
-                                    VehicleAreaConfig{.areaId = HVAC_RIGHT,
-                                                      .minFloatValue = -10,
-                                                      .maxFloatValue = 10}}},
-         .initialAreaValues = {{HVAC_LEFT, {.floatValues = {1}}},
-                               {HVAC_RIGHT, {.floatValues = {2}}}}},
-
-        {.config = {.prop = VENDOR_EXTENSION_INT_PROPERTY,
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs =
-                            {VehicleAreaConfig{.areaId = toInt(VehicleAreaWindow::FRONT_WINDSHIELD),
-                                               .minInt32Value = -100,
-                                               .maxInt32Value = 100},
-                             VehicleAreaConfig{.areaId = toInt(VehicleAreaWindow::REAR_WINDSHIELD),
-                                               .minInt32Value = -100,
-                                               .maxInt32Value = 100},
-                             VehicleAreaConfig{.areaId = toInt(VehicleAreaWindow::ROOF_TOP_1),
-                                               .minInt32Value = -100,
-                                               .maxInt32Value = 100}}},
-         .initialAreaValues = {{toInt(VehicleAreaWindow::FRONT_WINDSHIELD), {.int32Values = {1}}},
-                               {toInt(VehicleAreaWindow::REAR_WINDSHIELD), {.int32Values = {0}}},
-                               {toInt(VehicleAreaWindow::ROOF_TOP_1), {.int32Values = {-1}}}}},
-
-        {.config = {.prop = VENDOR_EXTENSION_STRING_PROPERTY,
-                    .access = VehiclePropertyAccess::READ_WRITE,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
-         .initialValue = {.stringValue = "Vendor String Property"}},
-
-        {.config = {.prop = toInt(VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE),
-                    .access = VehiclePropertyAccess::READ,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config = {.prop = toInt(VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS),
-                    .access = VehiclePropertyAccess::READ,
-                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
-         .initialValue = {.int32Values = {0}}},
-
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                         .configArray = {kMixedTypePropertyForTest,
-                                         toInt(VehicleVendorPermission::
-                                                       PERMISSION_GET_VENDOR_CATEGORY_INFO),
-                                         toInt(VehicleVendorPermission::
-                                                       PERMISSION_SET_VENDOR_CATEGORY_INFO),
-                                         VENDOR_EXTENSION_INT_PROPERTY,
-                                         toInt(VehicleVendorPermission::
-                                                       PERMISSION_GET_VENDOR_CATEGORY_SEAT),
-                                         toInt(VehicleVendorPermission::PERMISSION_NOT_ACCESSIBLE),
-                                         VENDOR_EXTENSION_FLOAT_PROPERTY,
-                                         toInt(VehicleVendorPermission::PERMISSION_DEFAULT),
-                                         toInt(VehicleVendorPermission::PERMISSION_DEFAULT)},
-                 },
-         .initialValue = {.int32Values = {1}}},
-
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::SWITCH_USER),
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::CREATE_USER),
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::REMOVE_USER),
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION),
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::POWER_POLICY_REQ),
-                                .access = VehiclePropertyAccess::READ,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::POWER_POLICY_GROUP_REQ),
-                                .access = VehiclePropertyAccess::READ,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::CURRENT_POWER_POLICY),
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::ANDROID_EPOCH_TIME),
-                                .access = VehiclePropertyAccess::WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::WATCHDOG_ALIVE),
-                                .access = VehiclePropertyAccess::WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::WATCHDOG_TERMINATED_PROCESS),
-                                .access = VehiclePropertyAccess::WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::VHAL_HEARTBEAT),
-                                .access = VehiclePropertyAccess::READ,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::CLUSTER_SWITCH_UI),
-                                .access = VehiclePropertyAccess::READ,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-                .initialValue = {.int32Values = {0 /* ClusterHome */}},
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::CLUSTER_DISPLAY_STATE),
-                                .access = VehiclePropertyAccess::READ,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-                .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1,
-                                                 -1, -1 /* Insets */}},
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::CLUSTER_REPORT_STATE),
-                                .access = VehiclePropertyAccess::WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                                .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16},
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::CLUSTER_REQUEST_DISPLAY),
-                                .access = VehiclePropertyAccess::WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = toInt(VehicleProperty::CLUSTER_NAVIGATION_STATE),
-                                .access = VehiclePropertyAccess::WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = PLACEHOLDER_PROPERTY_INT,
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-                .initialValue = {.int32Values = {0}},
-        },
-        {
-                .config =
-                        {
-                                .prop = PLACEHOLDER_PROPERTY_FLOAT,
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-                .initialValue = {.floatValues = {0.0f}},
-        },
-        {
-                .config =
-                        {
-                                .prop = PLACEHOLDER_PROPERTY_BOOLEAN,
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-                .initialValue = {.int32Values = {0 /* false */}},
-        },
-        {
-                .config =
-                        {
-                                .prop = PLACEHOLDER_PROPERTY_STRING,
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-                .initialValue = {.stringValue = {"Test"}},
-        },
-        {
-                .config =
-                        {
-                                .prop = ECHO_REVERSE_BYTES,
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
-        // Vendor propetry for E2E ClusterHomeService testing.
-        {
-                .config =
-                        {
-                                .prop = VENDOR_CLUSTER_SWITCH_UI,
-                                .access = VehiclePropertyAccess::WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = VENDOR_CLUSTER_DISPLAY_STATE,
-                                .access = VehiclePropertyAccess::WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
-                                .prop = VENDOR_CLUSTER_REPORT_STATE,
-                                .access = VehiclePropertyAccess::READ,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                                .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16},
-                        },
-                .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1,
-                                                 -1, -1 /* Insets */, 0 /* ClusterHome */,
-                                                 -1 /* ClusterNone */}},
-        },
-        {
-                .config =
-                        {
-                                .prop = VENDOR_CLUSTER_REQUEST_DISPLAY,
-                                .access = VehiclePropertyAccess::READ,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-                .initialValue = {.int32Values = {0 /* ClusterHome */}},
-        },
-        {
-                .config =
-                        {
-                                .prop = VENDOR_CLUSTER_NAVIGATION_STATE,
-                                .access = VehiclePropertyAccess::READ,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-#endif  // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
-};
-
-}  // namespace defaultconfig_impl
-
-// public namespace
-namespace defaultconfig {
-
-typedef defaultconfig_impl::ConfigDeclaration ConfigDeclaration;
-
-inline constexpr const std::vector<ConfigDeclaration>& getDefaultConfigs() {
-    return defaultconfig_impl::kVehicleProperties;
-}
-
-}  // namespace defaultconfig
-
-}  // namespace vehicle
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
-
-#endif  // android_hardware_automotive_vehicle_aidl_impl_default_config_include_DefaultConfig_H_
diff --git a/automotive/vehicle/aidl/impl/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
index 771472c..8702eae 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
@@ -24,11 +24,47 @@
     defaults: ["VehicleHalDefaults"],
     srcs: ["*.cpp"],
     static_libs: [
+        "VehicleHalJsonConfigLoader",
         "VehicleHalUtils",
+        "libgmock",
         "libgtest",
     ],
     header_libs: [
-        "VehicleHalDefaultConfig",
+        "IVehicleGeneratedHeaders",
+    ],
+    shared_libs: [
+        "libjsoncpp",
+    ],
+    data: [
+        ":VehicleHalDefaultProperties_JSON",
+    ],
+    test_suites: ["device-tests"],
+}
+
+cc_test {
+    name: "VehicleHalDefaultConfigTestEnableTestProperties",
+    vendor: true,
+    defaults: ["VehicleHalDefaults"],
+    srcs: ["*.cpp"],
+    static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties",
+        "VehicleHalUtils",
+        "libgmock",
+        "libgtest",
+    ],
+    cflags: [
+        "-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
+    ],
+    header_libs: [
+        "IVehicleGeneratedHeaders",
+    ],
+    shared_libs: [
+        "libjsoncpp",
+    ],
+    data: [
+        ":VehicleHalDefaultProperties_JSON",
+        ":VehicleHalTestProperties_JSON",
+        ":VehicleHalVendorClusterTestProperties_JSON",
     ],
     test_suites: ["device-tests"],
 }
diff --git a/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp b/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
index baaae75..95fecfe 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
@@ -14,27 +14,75 @@
  * limitations under the License.
  */
 
-#include <DefaultConfig.h>
+#include <JsonConfigLoader.h>
 #include <VehicleUtils.h>
+#include <android-base/file.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
+#include <fstream>
+#include <unordered_map>
 
 namespace android {
 namespace hardware {
 namespace automotive {
 namespace vehicle {
-namespace defaultconfig {
 
 namespace test {
 
-TEST(DefaultConfigTest, loadDefaultConfigs) {
-    for (ConfigDeclaration config : getDefaultConfigs()) {
-        ASSERT_NE(0, config.config.prop);
-    }
+using ::android::base::Error;
+using ::android::base::Result;
+using ::testing::UnorderedElementsAreArray;
+
+constexpr char kDefaultPropertiesConfigFile[] = "DefaultProperties.json";
+
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+constexpr char kTestPropertiesConfigFile[] = "TestProperties.json";
+constexpr char kVendorClusterTestPropertiesConfigFile[] = "VendorClusterTestProperties.json";
+#endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+
+std::string getTestFilePath(const char* filename) {
+    static std::string baseDir = android::base::GetExecutableDirectory();
+    return baseDir + "/" + filename;
 }
 
+Result<std::unordered_map<int32_t, ConfigDeclaration>> loadConfig(JsonConfigLoader& loader,
+                                                                  const char* path) {
+    std::string configPath = getTestFilePath(path);
+    std::ifstream ifs(configPath.c_str());
+    if (!ifs) {
+        return Error() << "couldn't open %s for parsing." << configPath;
+    }
+
+    return loader.loadPropConfig(ifs);
+}
+
+TEST(DefaultConfigTest, TestloadDefaultProperties) {
+    JsonConfigLoader loader;
+    auto result = loadConfig(loader, kDefaultPropertiesConfigFile);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+
+TEST(DefaultConfigTest, TestloadTestProperties) {
+    JsonConfigLoader loader;
+    auto result = loadConfig(loader, kTestPropertiesConfigFile);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+TEST(DefaultConfigTest, TestloadVendorClusterTestProperties) {
+    JsonConfigLoader loader;
+    auto result = loadConfig(loader, kVendorClusterTestPropertiesConfigFile);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+#endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+
 }  // namespace test
 
-}  // namespace defaultconfig
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h
index 9f112ae..f96b6ec 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h
@@ -54,8 +54,8 @@
     void registerGenerator(int32_t generatorId, std::unique_ptr<FakeValueGenerator> generator);
 
     // Unregister a generator with the generatorId. If no registered generator is found, this
-    // function does nothing.
-    void unregisterGenerator(int32_t generatorId);
+    // function does nothing. Returns true if the generator is unregistered.
+    bool unregisterGenerator(int32_t generatorId);
 
   private:
     struct VhalEvent {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
index d421ac5..42b1bd3 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
@@ -45,6 +45,9 @@
     // Create a new JSON fake value generator using the specified JSON file path. All the events
     // in the JSON file would be generated once.
     explicit JsonFakeValueGenerator(const std::string& path);
+    // Create a new JSON fake value generator using the JSON content. The first argument is just
+    // used to differentiate this function with the one that takes path as input.
+    explicit JsonFakeValueGenerator(bool unused, const std::string& content, int32_t iteration);
 
     ~JsonFakeValueGenerator() = default;
 
@@ -53,6 +56,9 @@
     const std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
     getAllEvents();
 
+    // Whether there are events left to replay for this generator.
+    bool hasNext();
+
   private:
     size_t mEventIndex = 0;
     std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue> mEvents;
@@ -60,7 +66,8 @@
     int32_t mNumOfIterations = 0;
 
     void setBit(std::vector<uint8_t>& bytes, size_t idx);
-    void init(const std::string& path, int32_t iteration);
+    void initWithPath(const std::string& path, int32_t iteration);
+    void initWithStream(std::istream& is, int32_t iteration);
 };
 
 }  // namespace fake
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp
index 0c182d9..d815456 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp
@@ -29,11 +29,18 @@
 
 using ::android::base::ScopedLockAssertion;
 
-GeneratorHub::GeneratorHub(OnHalEvent&& onHalEvent)
-    : mOnHalEvent(onHalEvent), mThread(&GeneratorHub::run, this) {}
+GeneratorHub::GeneratorHub(OnHalEvent&& onHalEvent) : mOnHalEvent(onHalEvent) {
+    mThread = std::thread(&GeneratorHub::run, this);
+}
 
 GeneratorHub::~GeneratorHub() {
-    mShuttingDownFlag.store(true);
+    {
+        // Even if the shared variable is atomic, it must be modified under the
+        // mutex in order to correctly publish the modification to the waiting
+        // thread.
+        std::unique_lock<std::mutex> lock(mGeneratorsLock);
+        mShuttingDownFlag.store(true);
+    }
     mCond.notify_all();
     if (mThread.joinable()) {
         mThread.join();
@@ -58,13 +65,15 @@
     mCond.notify_one();
 }
 
-void GeneratorHub::unregisterGenerator(int32_t id) {
+bool GeneratorHub::unregisterGenerator(int32_t id) {
+    bool removed;
     {
         std::scoped_lock<std::mutex> lockGuard(mGeneratorsLock);
-        mGenerators.erase(id);
+        removed = mGenerators.erase(id);
     }
     mCond.notify_one();
     ALOGI("%s: Unregistered generator, id: %d", __func__, id);
+    return removed;
 }
 
 void GeneratorHub::run() {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
index d4d52a5..cb42317 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
@@ -173,12 +173,11 @@
 
 }  // namespace
 
-JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path) {
-    init(path, 1);
-}
+JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path)
+    : JsonFakeValueGenerator(path, /*iteration=*/1) {}
 
 JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path, int32_t iteration) {
-    init(path, iteration);
+    initWithPath(path, iteration);
 }
 
 JsonFakeValueGenerator::JsonFakeValueGenerator(const VehiclePropValue& request) {
@@ -186,16 +185,26 @@
     // Iterate infinitely if iteration number is not provided
     int32_t numOfIterations = v.int32Values.size() < 2 ? -1 : v.int32Values[1];
 
-    init(v.stringValue, numOfIterations);
+    initWithPath(v.stringValue, numOfIterations);
 }
 
-void JsonFakeValueGenerator::init(const std::string& path, int32_t iteration) {
+JsonFakeValueGenerator::JsonFakeValueGenerator([[maybe_unused]] bool unused,
+                                               const std::string& content, int32_t iteration) {
+    std::istringstream iss(content);
+    initWithStream(iss, iteration);
+}
+
+void JsonFakeValueGenerator::initWithPath(const std::string& path, int32_t iteration) {
     std::ifstream ifs(path);
     if (!ifs) {
         ALOGE("%s: couldn't open %s for parsing.", __func__, path.c_str());
         return;
     }
-    mEvents = parseFakeValueJson(ifs);
+    initWithStream(ifs, iteration);
+}
+
+void JsonFakeValueGenerator::initWithStream(std::istream& is, int32_t iteration) {
+    mEvents = parseFakeValueJson(is);
     mNumOfIterations = iteration;
 }
 
@@ -235,12 +244,15 @@
             mNumOfIterations--;
         }
     }
-
     generatedValue.timestamp = mLastEventTimestamp;
 
     return generatedValue;
 }
 
+bool JsonFakeValueGenerator::hasNext() {
+    return mNumOfIterations != 0 && mEvents.size() > 0;
+}
+
 }  // namespace fake
 }  // namespace vehicle
 }  // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/fake_impl/README.md b/automotive/vehicle/aidl/impl/fake_impl/README.md
new file mode 100644
index 0000000..e86dcee
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/README.md
@@ -0,0 +1,28 @@
+# Fake reference AIDL VHAL implementation libraries
+---
+
+This directory stores libraries for implementing a fake reference AIDL VHAL.
+
+WARNING: All the libraries here are for TEST ONLY.
+
+## GeneratorHub
+
+Defines a library `FakeVehicleHalValueGenerators` that could generate fake
+vehicle property values for testing.
+
+## hardware
+
+Defines a fake implementation for device-specifc interface `IVehicleHardware`:
+`FakeVehicleHardware`. This implementation uses a in-memory map for storing
+property values and does not communicate with or depending on any specific
+vehicle bus.
+
+## obd2frame
+
+Defines a library `FakeObd2Frame` that generates fake OBD2 frame for OBD2
+properties.
+
+## userhal
+
+Defines a library `FakeUserHal` that emulates a real User HAL behavior by
+parsing debug commands.
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
index dcd9208..4c17cde 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
@@ -24,6 +24,7 @@
     srcs: ["src/*.cpp"],
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
+    cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
     defaults: [
         "VehicleHalDefaults",
         "FakeVehicleHardwareDefaults",
@@ -32,18 +33,23 @@
 
 cc_defaults {
     name: "FakeVehicleHardwareDefaults",
-    cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
     header_libs: [
         "IVehicleHardware",
-        "VehicleHalDefaultConfig",
+        "VehicleHalTestUtilHeaders",
     ],
     export_header_lib_headers: ["IVehicleHardware"],
     static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties",
         "VehicleHalUtils",
         "FakeVehicleHalValueGenerators",
         "FakeObd2Frame",
         "FakeUserHal",
     ],
+    required: [
+        "Prebuilt_VehicleHalDefaultProperties_JSON",
+        "Prebuilt_VehicleHalTestProperties_JSON",
+        "Prebuilt_VehicleHalVendorClusterTestProperties_JSON",
+    ],
     shared_libs: [
         "libjsoncpp",
     ],
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 34b2b24..c3ebd3b 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -18,21 +18,24 @@
 #define android_hardware_automotive_vehicle_aidl_impl_fake_impl_hardware_include_FakeVehicleHardware_H_
 
 #include <ConcurrentQueue.h>
-#include <DefaultConfig.h>
+#include <ConfigDeclaration.h>
 #include <FakeObd2Frame.h>
 #include <FakeUserHal.h>
+#include <GeneratorHub.h>
 #include <IVehicleHardware.h>
+#include <JsonConfigLoader.h>
 #include <RecurrentTimer.h>
 #include <VehicleHalTypes.h>
 #include <VehiclePropertyStore.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.h>
 #include <android-base/parseint.h>
 #include <android-base/result.h>
 #include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
 
-#include <map>
 #include <memory>
 #include <mutex>
+#include <unordered_map>
 #include <vector>
 
 namespace android {
@@ -47,7 +50,8 @@
 
     FakeVehicleHardware();
 
-    explicit FakeVehicleHardware(std::unique_ptr<VehiclePropValuePool> valuePool);
+    FakeVehicleHardware(std::string defaultConfigDir, std::string overrideConfigDir,
+                        bool forceOverride);
 
     ~FakeVehicleHardware();
 
@@ -132,11 +136,18 @@
     const std::unique_ptr<FakeUserHal> mFakeUserHal;
     // RecurrentTimer is thread-safe.
     std::unique_ptr<RecurrentTimer> mRecurrentTimer;
+    // GeneratorHub is thread-safe.
+    std::unique_ptr<GeneratorHub> mGeneratorHub;
+
+    // Only allowed to set once.
+    std::unique_ptr<const PropertyChangeCallback> mOnPropertyChangeCallback;
+    std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback;
+
     std::mutex mLock;
-    std::unique_ptr<const PropertyChangeCallback> mOnPropertyChangeCallback GUARDED_BY(mLock);
-    std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback GUARDED_BY(mLock);
     std::unordered_map<PropIdAreaId, std::shared_ptr<RecurrentTimer::Callback>, PropIdAreaIdHash>
             mRecurrentActions GUARDED_BY(mLock);
+    std::unordered_map<PropIdAreaId, VehiclePropValuePool::RecyclableType, PropIdAreaIdHash>
+            mSavedProps GUARDED_BY(mLock);
     // PendingRequestHandler is thread-safe.
     mutable PendingRequestHandler<GetValuesCallback,
                                   aidl::android::hardware::automotive::vehicle::GetValueRequest>
@@ -145,18 +156,36 @@
                                   aidl::android::hardware::automotive::vehicle::SetValueRequest>
             mPendingSetValueRequests;
 
+    const std::string mDefaultConfigDir;
+    const std::string mOverrideConfigDir;
+    const bool mForceOverride;
+    bool mAddExtraTestVendorConfigs;
+
+    // Only used during initialization.
+    JsonConfigLoader mLoader;
+
     void init();
     // Stores the initial value to property store.
-    void storePropInitialValue(const defaultconfig::ConfigDeclaration& config);
+    void storePropInitialValue(const ConfigDeclaration& config);
     // The callback that would be called when a vehicle property value change happens.
     void onValueChangeCallback(
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
-    // If property "persist.vendor.vhal_init_value_override" is set to true, override the properties
-    // using config files in 'overrideDir'.
-    void maybeOverrideProperties(const char* overrideDir);
-    // Override the properties using config files in 'overrideDir'.
-    void overrideProperties(const char* overrideDir);
+    // Load the config files in format '*.json' from the directory and parse the config files
+    // into a map from property ID to ConfigDeclarations.
+    void loadPropConfigsFromDir(const std::string& dirPath,
+                                std::unordered_map<int32_t, ConfigDeclaration>* configs);
+    // Function to be called when a value change event comes from vehicle bus. In our fake
+    // implementation, this function is only called during "--inject-event" dump command.
+    void eventFromVehicleBus(
+            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
 
+    int getHvacTempNumIncrements(int requestedTemp, int minTemp, int maxTemp, int increment);
+    void updateHvacTemperatureValueSuggestionInput(
+            const std::vector<int>& hvacTemperatureSetConfigArray,
+            std::vector<float>* hvacTemperatureValueSuggestionInput);
+    VhalResult<void> setHvacTemperatureValueSuggestion(
+            const aidl::android::hardware::automotive::vehicle::VehiclePropValue&
+                    hvacTemperatureValueSuggestion);
     VhalResult<void> maybeSetSpecialValue(
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
             bool* isSpecialValue);
@@ -167,13 +196,18 @@
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
     VehiclePropValuePool::RecyclableType createApPowerStateReq(
             aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq state);
+    VehiclePropValuePool::RecyclableType createAdasStateReq(int32_t propertyId, int32_t areaId,
+                                                            int32_t state);
     VhalResult<void> setUserHalProp(
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
     ValueResultType getUserHalProp(
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
     ValueResultType getEchoReverseBytes(
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
-    bool isHvacPropAndHvacNotAvailable(int32_t propId);
+    bool isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const;
+    VhalResult<void> isAdasPropertyAvailable(int32_t adasStatePropertyId) const;
+
+    std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations();
 
     std::string dumpAllProperties();
     std::string dumpOnePropertyByConfig(
@@ -184,6 +218,10 @@
     std::string dumpListProperties();
     std::string dumpSpecificProperty(const std::vector<std::string>& options);
     std::string dumpSetProperties(const std::vector<std::string>& options);
+    std::string dumpGetPropertyWithArg(const std::vector<std::string>& options);
+    std::string dumpSaveProperty(const std::vector<std::string>& options);
+    std::string dumpRestoreProperty(const std::vector<std::string>& options);
+    std::string dumpInjectEvent(const std::vector<std::string>& options);
 
     template <typename T>
     android::base::Result<T> safelyParseInt(int index, const std::string& s) {
@@ -198,7 +236,7 @@
     std::vector<std::string> getOptionValues(const std::vector<std::string>& options,
                                              size_t* index);
     android::base::Result<aidl::android::hardware::automotive::vehicle::VehiclePropValue>
-    parseSetPropOptions(const std::vector<std::string>& options);
+    parsePropOptions(const std::vector<std::string>& options);
     android::base::Result<std::vector<uint8_t>> parseHexString(const std::string& s);
 
     android::base::Result<void> checkArgumentsSize(const std::vector<std::string>& options,
@@ -207,6 +245,26 @@
             const aidl::android::hardware::automotive::vehicle::GetValueRequest& request);
     aidl::android::hardware::automotive::vehicle::SetValueResult handleSetValueRequest(
             const aidl::android::hardware::automotive::vehicle::SetValueRequest& request);
+
+    std::string genFakeDataCommand(const std::vector<std::string>& options);
+    void sendHvacPropertiesCurrentValues(int32_t areaId);
+    void sendAdasPropertiesState(int32_t propertyId, int32_t state);
+    void generateVendorConfigs(
+            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>&) const;
+
+    static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
+            aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
+            int32_t keyCode, int32_t targetDisplay);
+    static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwKeyInputV2Prop(
+            int32_t area, int32_t targetDisplay, int32_t keyCode, int32_t action,
+            int32_t repeatCount);
+    static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwMotionInputProp(
+            int32_t area, int32_t display, int32_t inputType, int32_t action, int32_t buttonState,
+            int32_t pointerCount, int32_t pointerId[], int32_t toolType[], float xData[],
+            float yData[], float pressure[], float size[]);
+
+    static std::string genFakeDataHelp();
+    static std::string parseErrMsg(std::string fieldName, std::string value, std::string type);
 };
 
 }  // namespace fake
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index b64c1a6..3f5e4c4 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -15,24 +15,29 @@
  */
 
 #define LOG_TAG "FakeVehicleHardware"
+#define ATRACE_TAG ATRACE_TAG_HAL
 #define FAKE_VEHICLEHARDWARE_DEBUG false  // STOPSHIP if true.
 
 #include "FakeVehicleHardware.h"
 
-#include <DefaultConfig.h>
 #include <FakeObd2Frame.h>
 #include <JsonFakeValueGenerator.h>
+#include <LinearFakeValueGenerator.h>
 #include <PropertyUtils.h>
 #include <TestPropertyUtils.h>
 #include <VehicleHalTypes.h>
 #include <VehicleUtils.h>
+
+#include <android-base/file.h>
 #include <android-base/parsedouble.h>
 #include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
+#include <utils/Trace.h>
 
 #include <dirent.h>
+#include <inttypes.h>
 #include <sys/types.h>
 #include <fstream>
 #include <regex>
@@ -47,6 +52,7 @@
 
 namespace {
 
+using ::aidl::android::hardware::automotive::vehicle::ErrorState;
 using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
 using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
 using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
@@ -55,24 +61,50 @@
 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
+using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
 
 using ::android::base::EqualsIgnoreCase;
 using ::android::base::Error;
+using ::android::base::GetIntProperty;
 using ::android::base::ParseFloat;
 using ::android::base::Result;
 using ::android::base::ScopedLockAssertion;
 using ::android::base::StartsWith;
 using ::android::base::StringPrintf;
 
-const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/automotive/vhaloverride/";
-const char* OVERRIDE_PROPERTY = "persist.vendor.vhal_init_value_override";
-
+// In order to test large number of vehicle property configs, we might generate additional fake
+// property config start from this ID. These fake properties are for getPropertyList,
+//  getPropertiesAsync, and setPropertiesAsync.
+// 0x21403000
+constexpr int32_t STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST =
+        0x3000 | toInt(testpropertyutils_impl::VehiclePropertyGroup::VENDOR) |
+        toInt(testpropertyutils_impl::VehicleArea::GLOBAL) |
+        toInt(testpropertyutils_impl::VehiclePropertyType::INT32);
+// 0x21405000
+constexpr int32_t ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST =
+        0x5000 | toInt(testpropertyutils_impl::VehiclePropertyGroup::VENDOR) |
+        toInt(testpropertyutils_impl::VehicleArea::GLOBAL) |
+        toInt(testpropertyutils_impl::VehiclePropertyType::INT32);
+// The directory for default property configuration file.
+// For config file format, see impl/default_config/config/README.md.
+constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/vhalconfig/";
+// The directory for property configuration file that overrides the default configuration file.
+// For config file format, see impl/default_config/config/README.md.
+constexpr char OVERRIDE_CONFIG_DIR[] = "/vendor/etc/automotive/vhaloverride/";
+// If OVERRIDE_PROPERTY is set, we will use the configuration files from OVERRIDE_CONFIG_DIR to
+// overwrite the default configs.
+constexpr char OVERRIDE_PROPERTY[] = "persist.vendor.vhal_init_value_override";
+constexpr char POWER_STATE_REQ_CONFIG_PROPERTY[] = "ro.vendor.fake_vhal.ap_power_state_req.config";
+// The value to be returned if VENDOR_PROPERTY_ID is set as the property
+constexpr int VENDOR_ERROR_CODE = 0x00ab0005;
 // A list of supported options for "--set" command.
 const std::unordered_set<std::string> SET_PROP_OPTIONS = {
         // integer.
@@ -86,11 +118,81 @@
         // bytes in hex format, e.g. 0xDEADBEEF.
         "-b",
         // Area id in integer.
-        "-a"};
+        "-a",
+        // Timestamp in int64.
+        "-t"};
 
+// ADAS _ENABLED property to list of ADAS state properties using ErrorState enum.
+const std::unordered_map<int32_t, std::vector<int32_t>> mAdasEnabledPropToAdasPropWithErrorState = {
+        // AEB
+        {
+                toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
+                {
+                        toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE),
+                },
+        },
+        // FCW
+        {
+                toInt(VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED),
+                {
+                        toInt(VehicleProperty::FORWARD_COLLISION_WARNING_STATE),
+                },
+        },
+        // BSW
+        {
+                toInt(VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
+                {
+                        toInt(VehicleProperty::BLIND_SPOT_WARNING_STATE),
+                },
+        },
+        // LDW
+        {
+                toInt(VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED),
+                {
+                        toInt(VehicleProperty::LANE_DEPARTURE_WARNING_STATE),
+                },
+        },
+        // LKA
+        {
+                toInt(VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
+                {
+                        toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE),
+                },
+        },
+        // LCA
+        {
+                toInt(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
+                {
+                        toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE),
+                },
+        },
+        // ELKA
+        {
+                toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
+                {
+                        toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE),
+                },
+        },
+        // CC
+        {
+                toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
+                {
+                        toInt(VehicleProperty::CRUISE_CONTROL_TYPE),
+                        toInt(VehicleProperty::CRUISE_CONTROL_STATE),
+                },
+        },
+        // HOD
+        {
+                toInt(VehicleProperty::HANDS_ON_DETECTION_ENABLED),
+                {
+                        toInt(VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE),
+                        toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING),
+                },
+        },
+};
 }  // namespace
 
-void FakeVehicleHardware::storePropInitialValue(const defaultconfig::ConfigDeclaration& config) {
+void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config) {
     const VehiclePropConfig& vehiclePropConfig = config.config;
     int propId = vehiclePropConfig.prop;
 
@@ -132,30 +234,50 @@
 }
 
 FakeVehicleHardware::FakeVehicleHardware()
-    : FakeVehicleHardware(std::make_unique<VehiclePropValuePool>()) {}
+    : FakeVehicleHardware(DEFAULT_CONFIG_DIR, OVERRIDE_CONFIG_DIR, false) {}
 
-FakeVehicleHardware::FakeVehicleHardware(std::unique_ptr<VehiclePropValuePool> valuePool)
-    : mValuePool(std::move(valuePool)),
+FakeVehicleHardware::FakeVehicleHardware(std::string defaultConfigDir,
+                                         std::string overrideConfigDir, bool forceOverride)
+    : mValuePool(std::make_unique<VehiclePropValuePool>()),
       mServerSidePropStore(new VehiclePropertyStore(mValuePool)),
       mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)),
       mFakeUserHal(new FakeUserHal(mValuePool)),
       mRecurrentTimer(new RecurrentTimer()),
+      mGeneratorHub(new GeneratorHub(
+              [this](const VehiclePropValue& value) { eventFromVehicleBus(value); })),
       mPendingGetValueRequests(this),
-      mPendingSetValueRequests(this) {
+      mPendingSetValueRequests(this),
+      mDefaultConfigDir(defaultConfigDir),
+      mOverrideConfigDir(overrideConfigDir),
+      mForceOverride(forceOverride) {
     init();
 }
 
 FakeVehicleHardware::~FakeVehicleHardware() {
     mPendingGetValueRequests.stop();
     mPendingSetValueRequests.stop();
+    mGeneratorHub.reset();
+}
+
+std::unordered_map<int32_t, ConfigDeclaration> FakeVehicleHardware::loadConfigDeclarations() {
+    std::unordered_map<int32_t, ConfigDeclaration> configsByPropId;
+    loadPropConfigsFromDir(mDefaultConfigDir, &configsByPropId);
+    if (mForceOverride ||
+        android::base::GetBoolProperty(OVERRIDE_PROPERTY, /*default_value=*/false)) {
+        loadPropConfigsFromDir(mOverrideConfigDir, &configsByPropId);
+    }
+    return configsByPropId;
 }
 
 void FakeVehicleHardware::init() {
-    for (auto& it : defaultconfig::getDefaultConfigs()) {
-        VehiclePropConfig cfg = it.config;
+    for (auto& [_, configDeclaration] : loadConfigDeclarations()) {
+        VehiclePropConfig cfg = configDeclaration.config;
         VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
 
-        if (cfg.prop == OBD2_FREEZE_FRAME) {
+        if (cfg.prop == toInt(VehicleProperty::AP_POWER_STATE_REQ)) {
+            int config = GetIntProperty(POWER_STATE_REQ_CONFIG_PROPERTY, /*default_value=*/0);
+            cfg.configArray[0] = config;
+        } else if (cfg.prop == OBD2_FREEZE_FRAME) {
             tokenFunction = [](const VehiclePropValue& propValue) { return propValue.timestamp; };
         }
 
@@ -165,22 +287,29 @@
             // logic.
             continue;
         }
-        storePropInitialValue(it);
+        storePropInitialValue(configDeclaration);
     }
 
-    maybeOverrideProperties(VENDOR_OVERRIDE_DIR);
-
     // OBD2_LIVE_FRAME and OBD2_FREEZE_FRAME must be configured in default configs.
-    mFakeObd2Frame->initObd2LiveFrame(*mServerSidePropStore->getConfig(OBD2_LIVE_FRAME).value());
-    mFakeObd2Frame->initObd2FreezeFrame(
-            *mServerSidePropStore->getConfig(OBD2_FREEZE_FRAME).value());
+    auto maybeObd2LiveFrame = mServerSidePropStore->getConfig(OBD2_LIVE_FRAME);
+    if (maybeObd2LiveFrame.has_value()) {
+        mFakeObd2Frame->initObd2LiveFrame(*maybeObd2LiveFrame.value());
+    }
+    auto maybeObd2FreezeFrame = mServerSidePropStore->getConfig(OBD2_FREEZE_FRAME);
+    if (maybeObd2FreezeFrame.has_value()) {
+        mFakeObd2Frame->initObd2FreezeFrame(*maybeObd2FreezeFrame.value());
+    }
 
     mServerSidePropStore->setOnValueChangeCallback(
             [this](const VehiclePropValue& value) { return onValueChangeCallback(value); });
 }
 
 std::vector<VehiclePropConfig> FakeVehicleHardware::getAllPropertyConfigs() const {
-    return mServerSidePropStore->getAllConfigs();
+    std::vector<VehiclePropConfig> allConfigs = mServerSidePropStore->getAllConfigs();
+    if (mAddExtraTestVendorConfigs) {
+        generateVendorConfigs(/* outAllConfigs= */ allConfigs);
+    }
+    return allConfigs;
 }
 
 VehiclePropValuePool::RecyclableType FakeVehicleHardware::createApPowerStateReq(
@@ -196,6 +325,18 @@
     return req;
 }
 
+VehiclePropValuePool::RecyclableType FakeVehicleHardware::createAdasStateReq(int32_t propertyId,
+                                                                             int32_t areaId,
+                                                                             int32_t state) {
+    auto req = mValuePool->obtain(VehiclePropertyType::INT32);
+    req->prop = propertyId;
+    req->areaId = areaId;
+    req->timestamp = elapsedRealtimeNano();
+    req->status = VehiclePropertyStatus::AVAILABLE;
+    req->value.int32Values[0] = state;
+    return req;
+}
+
 VhalResult<void> FakeVehicleHardware::setApPowerStateReport(const VehiclePropValue& value) {
     auto updatedValue = mValuePool->obtain(value);
     updatedValue->timestamp = elapsedRealtimeNano();
@@ -217,17 +358,16 @@
             [[fallthrough]];
         case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL):
             // CPMS is in WAIT_FOR_VHAL state, simply move to ON and send back to HAL.
-            // Must erase existing state because in the case when Car Service crashes, the power
-            // state would already be ON when we receive WAIT_FOR_VHAL and thus new property change
-            // event would be generated. However, Car Service always expect a property change event
-            // even though there is not actual state change.
-            mServerSidePropStore->removeValuesForProperty(
-                    toInt(VehicleProperty::AP_POWER_STATE_REQ));
             prop = createApPowerStateReq(VehicleApPowerStateReq::ON);
 
-            // ALWAYS update status for generated property value
+            // ALWAYS update status for generated property value, and force a property update event
+            // because in the case when Car Service crashes, the power state would already be ON
+            // when we receive WAIT_FOR_VHAL and thus new property change event would be generated.
+            // However, Car Service always expect a property change event even though there is no
+            // actual state change.
             if (auto writeResult =
-                        mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true);
+                        mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true,
+                                                         VehiclePropertyStore::EventMode::ALWAYS);
                 !writeResult.ok()) {
                 return StatusError(getErrorCode(writeResult))
                        << "failed to write AP_POWER_STATE_REQ into property store, error: "
@@ -258,21 +398,155 @@
     return {};
 }
 
-bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId) {
+int FakeVehicleHardware::getHvacTempNumIncrements(int requestedTemp, int minTemp, int maxTemp,
+                                                  int increment) {
+    requestedTemp = std::max(requestedTemp, minTemp);
+    requestedTemp = std::min(requestedTemp, maxTemp);
+    int numIncrements = (requestedTemp - minTemp) / increment;
+    return numIncrements;
+}
+
+void FakeVehicleHardware::updateHvacTemperatureValueSuggestionInput(
+        const std::vector<int>& hvacTemperatureSetConfigArray,
+        std::vector<float>* hvacTemperatureValueSuggestionInput) {
+    int minTempInCelsius = hvacTemperatureSetConfigArray[0];
+    int maxTempInCelsius = hvacTemperatureSetConfigArray[1];
+    int incrementInCelsius = hvacTemperatureSetConfigArray[2];
+
+    int minTempInFahrenheit = hvacTemperatureSetConfigArray[3];
+    int maxTempInFahrenheit = hvacTemperatureSetConfigArray[4];
+    int incrementInFahrenheit = hvacTemperatureSetConfigArray[5];
+
+    // The HVAC_TEMPERATURE_SET config array values are temperature values that have been multiplied
+    // by 10 and converted to integers. Therefore, requestedTemp must also be multiplied by 10 and
+    // converted to an integer in order for them to be the same units.
+    int requestedTemp = static_cast<int>((*hvacTemperatureValueSuggestionInput)[0] * 10.0f);
+    int numIncrements =
+            (*hvacTemperatureValueSuggestionInput)[1] == toInt(VehicleUnit::CELSIUS)
+                    ? getHvacTempNumIncrements(requestedTemp, minTempInCelsius, maxTempInCelsius,
+                                               incrementInCelsius)
+                    : getHvacTempNumIncrements(requestedTemp, minTempInFahrenheit,
+                                               maxTempInFahrenheit, incrementInFahrenheit);
+
+    int suggestedTempInCelsius = minTempInCelsius + incrementInCelsius * numIncrements;
+    int suggestedTempInFahrenheit = minTempInFahrenheit + incrementInFahrenheit * numIncrements;
+    // HVAC_TEMPERATURE_VALUE_SUGGESTION specifies the temperature values to be in the original
+    // floating point form so we divide by 10 and convert to float.
+    (*hvacTemperatureValueSuggestionInput)[2] = static_cast<float>(suggestedTempInCelsius) / 10.0f;
+    (*hvacTemperatureValueSuggestionInput)[3] =
+            static_cast<float>(suggestedTempInFahrenheit) / 10.0f;
+}
+
+VhalResult<void> FakeVehicleHardware::setHvacTemperatureValueSuggestion(
+        const VehiclePropValue& hvacTemperatureValueSuggestion) {
+    auto hvacTemperatureSetConfigResult =
+            mServerSidePropStore->getConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
+
+    if (!hvacTemperatureSetConfigResult.ok()) {
+        return StatusError(getErrorCode(hvacTemperatureSetConfigResult)) << StringPrintf(
+                       "Failed to set HVAC_TEMPERATURE_VALUE_SUGGESTION because"
+                       " HVAC_TEMPERATURE_SET could not be retrieved. Error: %s",
+                       getErrorMsg(hvacTemperatureSetConfigResult).c_str());
+    }
+
+    const auto& originalInput = hvacTemperatureValueSuggestion.value.floatValues;
+    if (originalInput.size() != 4) {
+        return StatusError(StatusCode::INVALID_ARG) << StringPrintf(
+                       "Failed to set HVAC_TEMPERATURE_VALUE_SUGGESTION because float"
+                       " array value is not size 4.");
+    }
+
+    bool isTemperatureUnitSpecified = originalInput[1] == toInt(VehicleUnit::CELSIUS) ||
+                                      originalInput[1] == toInt(VehicleUnit::FAHRENHEIT);
+    if (!isTemperatureUnitSpecified) {
+        return StatusError(StatusCode::INVALID_ARG) << StringPrintf(
+                       "Failed to set HVAC_TEMPERATURE_VALUE_SUGGESTION because float"
+                       " value at index 1 is not any of %d or %d, which corresponds to"
+                       " VehicleUnit#CELSIUS and VehicleUnit#FAHRENHEIT respectively.",
+                       toInt(VehicleUnit::CELSIUS), toInt(VehicleUnit::FAHRENHEIT));
+    }
+
+    auto updatedValue = mValuePool->obtain(hvacTemperatureValueSuggestion);
+    const auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfigResult.value()->configArray;
+    auto& hvacTemperatureValueSuggestionInput = updatedValue->value.floatValues;
+
+    updateHvacTemperatureValueSuggestionInput(hvacTemperatureSetConfigArray,
+                                              &hvacTemperatureValueSuggestionInput);
+
+    updatedValue->timestamp = elapsedRealtimeNano();
+    auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue),
+                                                        /* updateStatus = */ true,
+                                                        VehiclePropertyStore::EventMode::ALWAYS);
+    if (!writeResult.ok()) {
+        return StatusError(getErrorCode(writeResult))
+               << StringPrintf("failed to write value into property store, error: %s",
+                               getErrorMsg(writeResult).c_str());
+    }
+
+    return {};
+}
+
+bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const {
     std::unordered_set<int32_t> powerProps(std::begin(HVAC_POWER_PROPERTIES),
                                            std::end(HVAC_POWER_PROPERTIES));
     if (powerProps.count(propId)) {
-        auto hvacPowerOnResult =
-                mServerSidePropStore->readValue(toInt(VehicleProperty::HVAC_POWER_ON), HVAC_ALL);
-
-        if (hvacPowerOnResult.ok() && hvacPowerOnResult.value()->value.int32Values.size() == 1 &&
-            hvacPowerOnResult.value()->value.int32Values[0] == 0) {
-            return true;
+        auto hvacPowerOnResults =
+                mServerSidePropStore->readValuesForProperty(toInt(VehicleProperty::HVAC_POWER_ON));
+        if (!hvacPowerOnResults.ok()) {
+            ALOGW("failed to get HVAC_POWER_ON 0x%x, error: %s",
+                  toInt(VehicleProperty::HVAC_POWER_ON), getErrorMsg(hvacPowerOnResults).c_str());
+            return false;
+        }
+        auto& hvacPowerOnValues = hvacPowerOnResults.value();
+        for (size_t j = 0; j < hvacPowerOnValues.size(); j++) {
+            auto hvacPowerOnValue = std::move(hvacPowerOnValues[j]);
+            if ((hvacPowerOnValue->areaId & areaId) == areaId) {
+                if (hvacPowerOnValue->value.int32Values.size() == 1 &&
+                    hvacPowerOnValue->value.int32Values[0] == 0) {
+                    return true;
+                }
+                break;
+            }
         }
     }
     return false;
 }
 
+VhalResult<void> FakeVehicleHardware::isAdasPropertyAvailable(int32_t adasStatePropertyId) const {
+    auto adasStateResult = mServerSidePropStore->readValue(adasStatePropertyId);
+    if (!adasStateResult.ok()) {
+        ALOGW("Failed to get ADAS ENABLED property 0x%x, error: %s", adasStatePropertyId,
+              getErrorMsg(adasStateResult).c_str());
+        return {};
+    }
+
+    if (adasStateResult.value()->value.int32Values.size() == 1 &&
+        adasStateResult.value()->value.int32Values[0] < 0) {
+        auto errorState = adasStateResult.value()->value.int32Values[0];
+        switch (errorState) {
+            case toInt(ErrorState::NOT_AVAILABLE_DISABLED):
+                return StatusError(StatusCode::NOT_AVAILABLE_DISABLED)
+                       << "ADAS feature is disabled.";
+            case toInt(ErrorState::NOT_AVAILABLE_SPEED_LOW):
+                return StatusError(StatusCode::NOT_AVAILABLE_SPEED_LOW)
+                       << "ADAS feature is disabled because the vehicle speed is too low.";
+            case toInt(ErrorState::NOT_AVAILABLE_SPEED_HIGH):
+                return StatusError(StatusCode::NOT_AVAILABLE_SPEED_HIGH)
+                       << "ADAS feature is disabled because the vehicle speed is too high.";
+            case toInt(ErrorState::NOT_AVAILABLE_POOR_VISIBILITY):
+                return StatusError(StatusCode::NOT_AVAILABLE_POOR_VISIBILITY)
+                       << "ADAS feature is disabled because the visibility is too poor.";
+            case toInt(ErrorState::NOT_AVAILABLE_SAFETY):
+                return StatusError(StatusCode::NOT_AVAILABLE_SAFETY)
+                       << "ADAS feature is disabled because of safety reasons.";
+            default:
+                return StatusError(StatusCode::NOT_AVAILABLE) << "ADAS feature is not available.";
+        }
+    }
+
+    return {};
+}
+
 VhalResult<void> FakeVehicleHardware::setUserHalProp(const VehiclePropValue& value) {
     auto result = mFakeUserHal->onSetProperty(value);
     if (!result.ok()) {
@@ -283,7 +557,11 @@
     if (updatedValue != nullptr) {
         ALOGI("onSetProperty(): updating property returned by HAL: %s",
               updatedValue->toString().c_str());
-        if (auto writeResult = mServerSidePropStore->writeValue(std::move(result.value()));
+        // Update timestamp otherwise writeValue might fail because the timestamp is outdated.
+        updatedValue->timestamp = elapsedRealtimeNano();
+        if (auto writeResult = mServerSidePropStore->writeValue(
+                    std::move(result.value()),
+                    /*updateStatus=*/true, VehiclePropertyStore::EventMode::ALWAYS);
             !writeResult.ok()) {
             return StatusError(getErrorCode(writeResult))
                    << "failed to write value into property store, error: "
@@ -320,11 +598,27 @@
     int32_t propId = value.prop;
     ValueResultType result;
 
+    if (propId >= STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST &&
+        propId < ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST) {
+        *isSpecialValue = true;
+        result = mValuePool->obtainInt32(/* value= */ 5);
+
+        result.value()->prop = propId;
+        result.value()->areaId = 0;
+        result.value()->timestamp = elapsedRealtimeNano();
+        return result;
+    }
+
     if (mFakeUserHal->isSupported(propId)) {
         *isSpecialValue = true;
         return getUserHalProp(value);
     }
 
+    if (isHvacPropAndHvacNotAvailable(propId, value.areaId)) {
+        *isSpecialValue = true;
+        return StatusError(StatusCode::NOT_AVAILABLE_DISABLED) << "hvac not available";
+    }
+
     switch (propId) {
         case OBD2_FREEZE_FRAME:
             *isSpecialValue = true;
@@ -343,6 +637,22 @@
         case ECHO_REVERSE_BYTES:
             *isSpecialValue = true;
             return getEchoReverseBytes(value);
+        case VENDOR_PROPERTY_ID:
+            *isSpecialValue = true;
+            return StatusError((StatusCode)VENDOR_ERROR_CODE);
+        case toInt(VehicleProperty::CRUISE_CONTROL_TARGET_SPEED):
+            [[fallthrough]];
+        case toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP):
+            [[fallthrough]];
+        case toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE): {
+            auto isAdasPropertyAvailableResult =
+                    isAdasPropertyAvailable(toInt(VehicleProperty::CRUISE_CONTROL_STATE));
+            if (!isAdasPropertyAvailableResult.ok()) {
+                *isSpecialValue = true;
+                return isAdasPropertyAvailableResult.error();
+            }
+            return nullptr;
+        }
         default:
             // Do nothing.
             break;
@@ -367,20 +677,85 @@
     return std::move(gotValue);
 }
 
+void FakeVehicleHardware::sendHvacPropertiesCurrentValues(int32_t areaId) {
+    for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+        int powerPropId = HVAC_POWER_PROPERTIES[i];
+        auto powerPropResults = mServerSidePropStore->readValuesForProperty(powerPropId);
+        if (!powerPropResults.ok()) {
+            ALOGW("failed to get power prop 0x%x, error: %s", powerPropId,
+                  getErrorMsg(powerPropResults).c_str());
+            continue;
+        }
+        auto& powerPropValues = powerPropResults.value();
+        for (size_t j = 0; j < powerPropValues.size(); j++) {
+            auto powerPropValue = std::move(powerPropValues[j]);
+            if ((powerPropValue->areaId & areaId) == powerPropValue->areaId) {
+                powerPropValue->status = VehiclePropertyStatus::AVAILABLE;
+                powerPropValue->timestamp = elapsedRealtimeNano();
+                // This will trigger a property change event for the current hvac property value.
+                mServerSidePropStore->writeValue(std::move(powerPropValue), /*updateStatus=*/true,
+                                                 VehiclePropertyStore::EventMode::ALWAYS);
+            }
+        }
+    }
+}
+
+void FakeVehicleHardware::sendAdasPropertiesState(int32_t propertyId, int32_t state) {
+    auto& adasDependentPropIds = mAdasEnabledPropToAdasPropWithErrorState.find(propertyId)->second;
+    for (auto dependentPropId : adasDependentPropIds) {
+        auto dependentPropConfigResult = mServerSidePropStore->getConfig(dependentPropId);
+        if (!dependentPropConfigResult.ok()) {
+            ALOGW("Failed to get config for ADAS property 0x%x, error: %s", dependentPropId,
+                  getErrorMsg(dependentPropConfigResult).c_str());
+            continue;
+        }
+        auto& dependentPropConfig = dependentPropConfigResult.value();
+        for (auto& areaConfig : dependentPropConfig->areaConfigs) {
+            auto propValue = createAdasStateReq(dependentPropId, areaConfig.areaId, state);
+            // This will trigger a property change event for the current ADAS property value.
+            mServerSidePropStore->writeValue(std::move(propValue), /*updateStatus=*/true,
+                                             VehiclePropertyStore::EventMode::ALWAYS);
+        }
+    }
+}
+
 VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value,
                                                            bool* isSpecialValue) {
     *isSpecialValue = false;
     VehiclePropValuePool::RecyclableType updatedValue;
     int32_t propId = value.prop;
 
+    if (propId >= STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST &&
+        propId < ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST) {
+        *isSpecialValue = true;
+        return {};
+    }
+
     if (mFakeUserHal->isSupported(propId)) {
         *isSpecialValue = true;
         return setUserHalProp(value);
     }
 
-    if (isHvacPropAndHvacNotAvailable(propId)) {
+    if (propId == toInt(VehicleProperty::HVAC_POWER_ON) && value.value.int32Values.size() == 1 &&
+        value.value.int32Values[0] == 1) {
+        // If we are turning HVAC power on, send current hvac property values through on change
+        // event.
+        sendHvacPropertiesCurrentValues(value.areaId);
+    }
+
+    if (isHvacPropAndHvacNotAvailable(propId, value.areaId)) {
         *isSpecialValue = true;
-        return StatusError(StatusCode::NOT_AVAILABLE) << "hvac not available";
+        return StatusError(StatusCode::NOT_AVAILABLE_DISABLED) << "hvac not available";
+    }
+
+    if (mAdasEnabledPropToAdasPropWithErrorState.count(propId) &&
+        value.value.int32Values.size() == 1) {
+        if (value.value.int32Values[0] == 1) {
+            // Set default state to 1 when ADAS feature is enabled.
+            sendAdasPropertiesState(propId, /* state = */ 1);
+        } else {
+            sendAdasPropertiesState(propId, toInt(ErrorState::NOT_AVAILABLE_DISABLED));
+        }
     }
 
     switch (propId) {
@@ -395,8 +770,32 @@
         case OBD2_FREEZE_FRAME_CLEAR:
             *isSpecialValue = true;
             return mFakeObd2Frame->clearObd2FreezeFrames(value);
+        case VENDOR_PROPERTY_ID:
+            *isSpecialValue = true;
+            return StatusError((StatusCode)VENDOR_ERROR_CODE);
+        case toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION):
+            *isSpecialValue = true;
+            return setHvacTemperatureValueSuggestion(value);
+        case toInt(VehicleProperty::LANE_CENTERING_ASSIST_COMMAND): {
+            auto isAdasPropertyAvailableResult =
+                    isAdasPropertyAvailable(toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE));
+            if (!isAdasPropertyAvailableResult.ok()) {
+                *isSpecialValue = true;
+            }
+            return isAdasPropertyAvailableResult;
+        }
+        case toInt(VehicleProperty::CRUISE_CONTROL_COMMAND):
+            [[fallthrough]];
+        case toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP): {
+            auto isAdasPropertyAvailableResult =
+                    isAdasPropertyAvailable(toInt(VehicleProperty::CRUISE_CONTROL_STATE));
+            if (!isAdasPropertyAvailableResult.ok()) {
+                *isSpecialValue = true;
+            }
+            return isAdasPropertyAvailableResult;
+        }
 
-#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
         case toInt(VehicleProperty::CLUSTER_REPORT_STATE):
             [[fallthrough]];
         case toInt(VehicleProperty::CLUSTER_REQUEST_DISPLAY):
@@ -424,7 +823,7 @@
                        << getErrorMsg(writeResult);
             }
             return {};
-#endif  // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+#endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
 
         default:
             break;
@@ -455,7 +854,6 @@
     // Here we are just updating mValuePool.
     bool isSpecialValue = false;
     auto setSpecialValueResult = maybeSetSpecialValue(value, &isSpecialValue);
-
     if (isSpecialValue) {
         if (!setSpecialValueResult.ok()) {
             return StatusError(getErrorCode(setSpecialValueResult))
@@ -575,34 +973,447 @@
         result.buffer = dumpListProperties();
     } else if (EqualsIgnoreCase(option, "--get")) {
         result.buffer = dumpSpecificProperty(options);
+    } else if (EqualsIgnoreCase(option, "--getWithArg")) {
+        result.buffer = dumpGetPropertyWithArg(options);
     } else if (EqualsIgnoreCase(option, "--set")) {
         result.buffer = dumpSetProperties(options);
+    } else if (EqualsIgnoreCase(option, "--save-prop")) {
+        result.buffer = dumpSaveProperty(options);
+    } else if (EqualsIgnoreCase(option, "--restore-prop")) {
+        result.buffer = dumpRestoreProperty(options);
+    } else if (EqualsIgnoreCase(option, "--inject-event")) {
+        result.buffer = dumpInjectEvent(options);
     } else if (EqualsIgnoreCase(option, kUserHalDumpOption)) {
-        if (options.size() == 1) {
-            result.buffer = mFakeUserHal->showDumpHelp();
-        } else {
-            result.buffer = mFakeUserHal->dump(options[1]);
-        }
+        result.buffer = mFakeUserHal->dump();
+    } else if (EqualsIgnoreCase(option, "--genfakedata")) {
+        result.buffer = genFakeDataCommand(options);
+    } else if (EqualsIgnoreCase(option, "--genTestVendorConfigs")) {
+        mAddExtraTestVendorConfigs = true;
+        result.refreshPropertyConfigs = true;
+    } else if (EqualsIgnoreCase(option, "--restoreVendorConfigs")) {
+        mAddExtraTestVendorConfigs = false;
+        result.refreshPropertyConfigs = true;
     } else {
         result.buffer = StringPrintf("Invalid option: %s\n", option.c_str());
     }
     return result;
 }
 
+std::string FakeVehicleHardware::genFakeDataHelp() {
+    return R"(
+Generate Fake Data Usage:
+--genfakedata --startlinear [propID] [mValue] [cValue] [dispersion] [increment] [interval]: "
+Start a linear generator that generates event with floatValue within range:
+[mValue - disperson, mValue + dispersion].
+propID(int32): ID for the property to generate event for.
+mValue(float): The middle of the possible values for the property.
+cValue(float): The start value for the property, must be within the range.
+dispersion(float): The range the value can change.
+increment(float): The step the value would increase by for each generated event,
+if exceed the range, the value would loop back.
+interval(int64): The interval in nanoseconds the event would generate by.
+
+--genfakedata --stoplinear [propID(int32)]: Stop a linear generator
+
+--genfakedata --startjson --path [jsonFilePath] [repetition]:
+Start a JSON generator that would generate events according to a JSON file.
+jsonFilePath(string): The path to a JSON file. The JSON content must be in the format of
+[{
+    "timestamp": 1000000,
+    "areaId": 0,
+    "value": 8,
+    "prop": 289408000
+}, {...}]
+Each event in the JSON file would be generated by the same interval their timestamp is relative to
+the first event's timestamp.
+repetition(int32, optional): how many iterations the events would be generated. If it is not
+provided, it would iterate indefinitely.
+
+--genfakedata --startjson --content [jsonContent]: Start a JSON generator using the content.
+
+--genfakedata --stopjson [generatorID(string)]: Stop a JSON generator.
+
+--genfakedata --keypress [keyCode(int32)] [display[int32]]: Generate key press.
+
+--genfakedata --keyinputv2 [area(int32)] [display(int32)] [keyCode[int32]] [action[int32]]
+  [repeatCount(int32)]
+
+--genfakedata --motioninput [area(int32)] [display(int32)] [inputType[int32]] [action[int32]]
+  [buttonState(int32)] --pointer [pointerId(int32)] [toolType(int32)] [xData(float)] [yData(float)]
+  [pressure(float)] [size(float)]
+  Generate a motion input event. --pointer option can be specified multiple times.
+
+--genTestVendorConfigs: Generates fake VehiclePropConfig ranging from 0x5000 to 0x8000 all with
+  vendor property group, global vehicle area, and int32 vehicle property type. This is mainly used
+  for testing
+
+--restoreVendorConfigs: Restores to to the default state if genTestVendorConfigs was used.
+  Otherwise this will do nothing.
+
+)";
+}
+
+std::string FakeVehicleHardware::parseErrMsg(std::string fieldName, std::string value,
+                                             std::string type) {
+    return StringPrintf("failed to parse %s as %s: \"%s\"\n%s", fieldName.c_str(), type.c_str(),
+                        value.c_str(), genFakeDataHelp().c_str());
+}
+
+void FakeVehicleHardware::generateVendorConfigs(
+        std::vector<VehiclePropConfig>& outAllConfigs) const {
+    for (int i = STARTING_VENDOR_CODE_PROPERTIES_FOR_TEST;
+         i < ENDING_VENDOR_CODE_PROPERTIES_FOR_TEST; i++) {
+        VehiclePropConfig config;
+        config.prop = i;
+        config.access = VehiclePropertyAccess::READ_WRITE;
+        outAllConfigs.push_back(config);
+    }
+}
+
+std::string FakeVehicleHardware::genFakeDataCommand(const std::vector<std::string>& options) {
+    if (options.size() < 2) {
+        return "No subcommand specified for genfakedata\n" + genFakeDataHelp();
+    }
+
+    std::string command = options[1];
+    if (command == "--startlinear") {
+        // --genfakedata --startlinear [propID(int32)] [middleValue(float)]
+        // [currentValue(float)] [dispersion(float)] [increment(float)] [interval(int64)]
+        if (options.size() != 8) {
+            return "incorrect argument count, need 8 arguments for --genfakedata --startlinear\n" +
+                   genFakeDataHelp();
+        }
+        int32_t propId;
+        float middleValue;
+        float currentValue;
+        float dispersion;
+        float increment;
+        int64_t interval;
+        if (!android::base::ParseInt(options[2], &propId)) {
+            return parseErrMsg("propId", options[2], "int");
+        }
+        if (!android::base::ParseFloat(options[3], &middleValue)) {
+            return parseErrMsg("middleValue", options[3], "float");
+        }
+        if (!android::base::ParseFloat(options[4], &currentValue)) {
+            return parseErrMsg("currentValue", options[4], "float");
+        }
+        if (!android::base::ParseFloat(options[5], &dispersion)) {
+            return parseErrMsg("dispersion", options[5], "float");
+        }
+        if (!android::base::ParseFloat(options[6], &increment)) {
+            return parseErrMsg("increment", options[6], "float");
+        }
+        if (!android::base::ParseInt(options[7], &interval)) {
+            return parseErrMsg("interval", options[7], "int");
+        }
+        auto generator = std::make_unique<LinearFakeValueGenerator>(
+                propId, middleValue, currentValue, dispersion, increment, interval);
+        mGeneratorHub->registerGenerator(propId, std::move(generator));
+        return "Linear event generator started successfully";
+    } else if (command == "--stoplinear") {
+        // --genfakedata --stoplinear [propID(int32)]
+        if (options.size() != 3) {
+            return "incorrect argument count, need 3 arguments for --genfakedata --stoplinear\n" +
+                   genFakeDataHelp();
+        }
+        int32_t propId;
+        if (!android::base::ParseInt(options[2], &propId)) {
+            return parseErrMsg("propId", options[2], "int");
+        }
+        if (mGeneratorHub->unregisterGenerator(propId)) {
+            return "Linear event generator stopped successfully";
+        }
+        return StringPrintf("No linear event generator found for property: %d", propId);
+    } else if (command == "--startjson") {
+        // --genfakedata --startjson --path path repetition
+        // or
+        // --genfakedata --startjson --content content repetition.
+        if (options.size() != 4 && options.size() != 5) {
+            return "incorrect argument count, need 4 or 5 arguments for --genfakedata "
+                   "--startjson\n";
+        }
+        // Iterate infinitely if repetition number is not provided
+        int32_t repetition = -1;
+        if (options.size() == 5) {
+            if (!android::base::ParseInt(options[4], &repetition)) {
+                return parseErrMsg("repetition", options[4], "int");
+            }
+        }
+        std::unique_ptr<JsonFakeValueGenerator> generator;
+        if (options[2] == "--path") {
+            const std::string& fileName = options[3];
+            generator = std::make_unique<JsonFakeValueGenerator>(fileName, repetition);
+            if (!generator->hasNext()) {
+                return "invalid JSON file, no events";
+            }
+        } else if (options[2] == "--content") {
+            const std::string& content = options[3];
+            generator =
+                    std::make_unique<JsonFakeValueGenerator>(/*unused=*/true, content, repetition);
+            if (!generator->hasNext()) {
+                return "invalid JSON content, no events";
+            }
+        }
+        int32_t cookie = std::hash<std::string>()(options[3]);
+        mGeneratorHub->registerGenerator(cookie, std::move(generator));
+        return StringPrintf("JSON event generator started successfully, ID: %" PRId32, cookie);
+    } else if (command == "--stopjson") {
+        // --genfakedata --stopjson [generatorID(string)]
+        if (options.size() != 3) {
+            return "incorrect argument count, need 3 arguments for --genfakedata --stopjson\n";
+        }
+        int32_t cookie;
+        if (!android::base::ParseInt(options[2], &cookie)) {
+            return parseErrMsg("cookie", options[2], "int");
+        }
+        if (mGeneratorHub->unregisterGenerator(cookie)) {
+            return "JSON event generator stopped successfully";
+        } else {
+            return StringPrintf("No JSON event generator found for ID: %s", options[2].c_str());
+        }
+    } else if (command == "--keypress") {
+        int32_t keyCode;
+        int32_t display;
+        // --genfakedata --keypress [keyCode(int32)] [display[int32]]
+        if (options.size() != 4) {
+            return "incorrect argument count, need 4 arguments for --genfakedata --keypress\n";
+        }
+        if (!android::base::ParseInt(options[2], &keyCode)) {
+            return parseErrMsg("keyCode", options[2], "int");
+        }
+        if (!android::base::ParseInt(options[3], &display)) {
+            return parseErrMsg("display", options[3], "int");
+        }
+        // Send back to HAL
+        onValueChangeCallback(
+                createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display));
+        onValueChangeCallback(
+                createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display));
+        return "keypress event generated successfully";
+    } else if (command == "--keyinputv2") {
+        int32_t area;
+        int32_t display;
+        int32_t keyCode;
+        int32_t action;
+        int32_t repeatCount;
+        // --genfakedata --keyinputv2 [area(int32)] [display(int32)] [keyCode[int32]]
+        // [action[int32]] [repeatCount(int32)]
+        if (options.size() != 7) {
+            return "incorrect argument count, need 7 arguments for --genfakedata --keyinputv2\n";
+        }
+        if (!android::base::ParseInt(options[2], &area)) {
+            return parseErrMsg("area", options[2], "int");
+        }
+        if (!android::base::ParseInt(options[3], &display)) {
+            return parseErrMsg("display", options[3], "int");
+        }
+        if (!android::base::ParseInt(options[4], &keyCode)) {
+            return parseErrMsg("keyCode", options[4], "int");
+        }
+        if (!android::base::ParseInt(options[5], &action)) {
+            return parseErrMsg("action", options[5], "int");
+        }
+        if (!android::base::ParseInt(options[6], &repeatCount)) {
+            return parseErrMsg("repeatCount", options[6], "int");
+        }
+        // Send back to HAL
+        onValueChangeCallback(createHwKeyInputV2Prop(area, display, keyCode, action, repeatCount));
+        return StringPrintf(
+                "keyinputv2 event generated successfully with area:%d, display:%d,"
+                " keyCode:%d, action:%d, repeatCount:%d",
+                area, display, keyCode, action, repeatCount);
+
+    } else if (command == "--motioninput") {
+        int32_t area;
+        int32_t display;
+        int32_t inputType;
+        int32_t action;
+        int32_t buttonState;
+        int32_t pointerCount;
+
+        // --genfakedata --motioninput [area(int32)] [display(int32)] [inputType[int32]]
+        // [action[int32]] [buttonState(int32)] [pointerCount(int32)]
+        // --pointer [pointerId(int32)] [toolType(int32)] [xData(float)] [yData(float)]
+        // [pressure(float)] [size(float)]
+        int optionsSize = (int)options.size();
+        if (optionsSize / 7 < 2) {
+            return "incorrect argument count, need at least 14 arguments for --genfakedata "
+                   "--motioninput including at least 1 --pointer\n";
+        }
+
+        if (optionsSize % 7 != 0) {
+            return "incorrect argument count, need 6 arguments for every --pointer\n";
+        }
+        pointerCount = (int)optionsSize / 7 - 1;
+
+        if (!android::base::ParseInt(options[2], &area)) {
+            return parseErrMsg("area", options[2], "int");
+        }
+        if (!android::base::ParseInt(options[3], &display)) {
+            return parseErrMsg("display", options[3], "int");
+        }
+        if (!android::base::ParseInt(options[4], &inputType)) {
+            return parseErrMsg("inputType", options[4], "int");
+        }
+        if (!android::base::ParseInt(options[5], &action)) {
+            return parseErrMsg("action", options[5], "int");
+        }
+        if (!android::base::ParseInt(options[6], &buttonState)) {
+            return parseErrMsg("buttonState", options[6], "int");
+        }
+
+        int32_t pointerId[pointerCount];
+        int32_t toolType[pointerCount];
+        float xData[pointerCount];
+        float yData[pointerCount];
+        float pressure[pointerCount];
+        float size[pointerCount];
+
+        for (int i = 7, pc = 0; i < optionsSize; i += 7, pc += 1) {
+            int offset = i;
+            if (options[offset] != "--pointer") {
+                return "--pointer is needed for the motion input\n";
+            }
+            offset += 1;
+            if (!android::base::ParseInt(options[offset], &pointerId[pc])) {
+                return parseErrMsg("pointerId", options[offset], "int");
+            }
+            offset += 1;
+            if (!android::base::ParseInt(options[offset], &toolType[pc])) {
+                return parseErrMsg("toolType", options[offset], "int");
+            }
+            offset += 1;
+            if (!android::base::ParseFloat(options[offset], &xData[pc])) {
+                return parseErrMsg("xData", options[offset], "float");
+            }
+            offset += 1;
+            if (!android::base::ParseFloat(options[offset], &yData[pc])) {
+                return parseErrMsg("yData", options[offset], "float");
+            }
+            offset += 1;
+            if (!android::base::ParseFloat(options[offset], &pressure[pc])) {
+                return parseErrMsg("pressure", options[offset], "float");
+            }
+            offset += 1;
+            if (!android::base::ParseFloat(options[offset], &size[pc])) {
+                return parseErrMsg("size", options[offset], "float");
+            }
+        }
+
+        // Send back to HAL
+        onValueChangeCallback(createHwMotionInputProp(area, display, inputType, action, buttonState,
+                                                      pointerCount, pointerId, toolType, xData,
+                                                      yData, pressure, size));
+
+        std::string successMessage = StringPrintf(
+                "motion event generated successfully with area:%d, display:%d,"
+                " inputType:%d, action:%d, buttonState:%d, pointerCount:%d\n",
+                area, display, inputType, action, buttonState, pointerCount);
+        for (int i = 0; i < pointerCount; i++) {
+            successMessage += StringPrintf(
+                    "Pointer #%d {\n"
+                    " id:%d , tooltype:%d \n"
+                    " x:%f , y:%f\n"
+                    " pressure: %f, data: %f\n"
+                    "}\n",
+                    i, pointerId[i], toolType[i], xData[i], yData[i], pressure[i], size[i]);
+        }
+        return successMessage;
+    }
+
+    return StringPrintf("Unknown command: \"%s\"\n%s", command.c_str(), genFakeDataHelp().c_str());
+}
+
+VehiclePropValue FakeVehicleHardware::createHwInputKeyProp(VehicleHwKeyInputAction action,
+                                                           int32_t keyCode, int32_t targetDisplay) {
+    VehiclePropValue value = {
+            .prop = toInt(VehicleProperty::HW_KEY_INPUT),
+            .areaId = 0,
+            .timestamp = elapsedRealtimeNano(),
+            .status = VehiclePropertyStatus::AVAILABLE,
+            .value.int32Values = {toInt(action), keyCode, targetDisplay},
+    };
+    return value;
+}
+
+VehiclePropValue FakeVehicleHardware::createHwKeyInputV2Prop(int32_t area, int32_t targetDisplay,
+                                                             int32_t keyCode, int32_t action,
+                                                             int32_t repeatCount) {
+    VehiclePropValue value = {.prop = toInt(VehicleProperty::HW_KEY_INPUT_V2),
+                              .areaId = area,
+                              .timestamp = elapsedRealtimeNano(),
+                              .status = VehiclePropertyStatus::AVAILABLE,
+                              .value.int32Values = {targetDisplay, keyCode, action, repeatCount},
+                              .value.int64Values = {elapsedRealtimeNano()}};
+    return value;
+}
+
+VehiclePropValue FakeVehicleHardware::createHwMotionInputProp(
+        int32_t area, int32_t display, int32_t inputType, int32_t action, int32_t buttonState,
+        int32_t pointerCount, int32_t pointerId[], int32_t toolType[], float xData[], float yData[],
+        float pressure[], float size[]) {
+    std::vector<int> intValues;
+    intValues.push_back(display);
+    intValues.push_back(inputType);
+    intValues.push_back(action);
+    intValues.push_back(buttonState);
+    intValues.push_back(pointerCount);
+    for (int i = 0; i < pointerCount; i++) {
+        intValues.push_back(pointerId[i]);
+    }
+    for (int i = 0; i < pointerCount; i++) {
+        intValues.push_back(toolType[i]);
+    }
+
+    std::vector<float> floatValues;
+    for (int i = 0; i < pointerCount; i++) {
+        floatValues.push_back(xData[i]);
+    }
+    for (int i = 0; i < pointerCount; i++) {
+        floatValues.push_back(yData[i]);
+    }
+    for (int i = 0; i < pointerCount; i++) {
+        floatValues.push_back(pressure[i]);
+    }
+    for (int i = 0; i < pointerCount; i++) {
+        floatValues.push_back(size[i]);
+    }
+
+    VehiclePropValue value = {.prop = toInt(VehicleProperty::HW_MOTION_INPUT),
+                              .areaId = area,
+                              .timestamp = elapsedRealtimeNano(),
+                              .status = VehiclePropertyStatus::AVAILABLE,
+                              .value.int32Values = intValues,
+                              .value.floatValues = floatValues,
+                              .value.int64Values = {elapsedRealtimeNano()}};
+    return value;
+}
+
+void FakeVehicleHardware::eventFromVehicleBus(const VehiclePropValue& value) {
+    mServerSidePropStore->writeValue(mValuePool->obtain(value));
+}
+
 std::string FakeVehicleHardware::dumpHelp() {
     return "Usage: \n\n"
            "[no args]: dumps (id and value) all supported properties \n"
            "--help: shows this help\n"
            "--list: lists the ids of all supported properties\n"
-           "--get <PROP1> [PROP2] [PROPN]: dumps the value of specific properties \n"
-           "--set <PROP> [-i INT_VALUE [INT_VALUE ...]] [-i64 INT64_VALUE [INT64_VALUE ...]] "
-           "[-f FLOAT_VALUE [FLOAT_VALUE ...]] [-s STR_VALUE] "
-           "[-b BYTES_VALUE] [-a AREA_ID] : sets the value of property PROP. "
+           "--get <PROP1> [PROP2] [PROPN]: dumps the value of specific properties. \n"
+           "--getWithArg <PROP> [ValueArguments]: gets the value for a specific property with "
+           "arguments. \n"
+           "--set <PROP> [ValueArguments]: sets the value of property PROP. \n"
+           "--save-prop <prop> [-a AREA_ID]: saves the current value for PROP, integration test"
+           " that modifies prop value must call this before test and restore-prop after test. \n"
+           "--restore-prop <prop> [-a AREA_ID]: restores a previously saved property value. \n"
+           "--inject-event <PROP> [ValueArguments]: inject a property update event from car\n\n"
+           "ValueArguments are in the format of [-i INT_VALUE [INT_VALUE ...]] "
+           "[-i64 INT64_VALUE [INT64_VALUE ...]] [-f FLOAT_VALUE [FLOAT_VALUE ...]] [-s STR_VALUE] "
+           "[-b BYTES_VALUE] [-a AREA_ID].\n"
            "Notice that the string, bytes and area value can be set just once, while the other can"
            " have multiple values (so they're used in the respective array), "
-           "BYTES_VALUE is in the form of 0xXXXX, e.g. 0xdeadbeef.\n\n"
-           "Fake user HAL usage: \n" +
-           mFakeUserHal->showDumpHelp();
+           "BYTES_VALUE is in the form of 0xXXXX, e.g. 0xdeadbeef.\n" +
+           genFakeDataHelp() + "Fake user HAL usage: \n" + mFakeUserHal->showDumpHelp();
 }
 
 std::string FakeVehicleHardware::dumpAllProperties() {
@@ -720,10 +1531,11 @@
     return std::move(values);
 }
 
-Result<VehiclePropValue> FakeVehicleHardware::parseSetPropOptions(
+Result<VehiclePropValue> FakeVehicleHardware::parsePropOptions(
         const std::vector<std::string>& options) {
     // Options format:
-    // --set PROP [-f f1 f2...] [-i i1 i2...] [-i64 i1 i2...] [-s s1 s2...] [-b b1 b2...] [-a a]
+    // --set/get/inject-event PROP [-f f1 f2...] [-i i1 i2...] [-i64 i1 i2...] [-s s1 s2...]
+    // [-b b1 b2...] [-a a] [-t timestamp]
     size_t optionIndex = 1;
     auto result = safelyParseInt<int32_t>(optionIndex, options[optionIndex]);
     if (!result.ok()) {
@@ -737,83 +1549,98 @@
     std::unordered_set<std::string> parsedOptions;
 
     while (optionIndex < options.size()) {
-        std::string type = options[optionIndex];
+        std::string argType = options[optionIndex];
         optionIndex++;
+
         size_t currentIndex = optionIndex;
-        std::vector<std::string> values = getOptionValues(options, &optionIndex);
-        if (parsedOptions.find(type) != parsedOptions.end()) {
-            return Error() << StringPrintf("Duplicate \"%s\" options\n", type.c_str());
+        std::vector<std::string> argValues = getOptionValues(options, &optionIndex);
+        if (parsedOptions.find(argType) != parsedOptions.end()) {
+            return Error() << StringPrintf("Duplicate \"%s\" options\n", argType.c_str());
         }
-        parsedOptions.insert(type);
-        if (EqualsIgnoreCase(type, "-i")) {
-            if (values.size() == 0) {
+        parsedOptions.insert(argType);
+        size_t argValuesSize = argValues.size();
+        if (EqualsIgnoreCase(argType, "-i")) {
+            if (argValuesSize == 0) {
                 return Error() << "No values specified when using \"-i\"\n";
             }
-            prop.value.int32Values.resize(values.size());
-            for (size_t i = 0; i < values.size(); i++) {
-                auto int32Result = safelyParseInt<int32_t>(currentIndex + i, values[i]);
+            prop.value.int32Values.resize(argValuesSize);
+            for (size_t i = 0; i < argValuesSize; i++) {
+                auto int32Result = safelyParseInt<int32_t>(currentIndex + i, argValues[i]);
                 if (!int32Result.ok()) {
                     return Error()
                            << StringPrintf("Value: \"%s\" is not a valid int: %s\n",
-                                           values[i].c_str(), getErrorMsg(int32Result).c_str());
+                                           argValues[i].c_str(), getErrorMsg(int32Result).c_str());
                 }
                 prop.value.int32Values[i] = int32Result.value();
             }
-        } else if (EqualsIgnoreCase(type, "-i64")) {
-            if (values.size() == 0) {
+        } else if (EqualsIgnoreCase(argType, "-i64")) {
+            if (argValuesSize == 0) {
                 return Error() << "No values specified when using \"-i64\"\n";
             }
-            prop.value.int64Values.resize(values.size());
-            for (size_t i = 0; i < values.size(); i++) {
-                auto int64Result = safelyParseInt<int64_t>(currentIndex + i, values[i]);
+            prop.value.int64Values.resize(argValuesSize);
+            for (size_t i = 0; i < argValuesSize; i++) {
+                auto int64Result = safelyParseInt<int64_t>(currentIndex + i, argValues[i]);
                 if (!int64Result.ok()) {
                     return Error()
                            << StringPrintf("Value: \"%s\" is not a valid int64: %s\n",
-                                           values[i].c_str(), getErrorMsg(int64Result).c_str());
+                                           argValues[i].c_str(), getErrorMsg(int64Result).c_str());
                 }
                 prop.value.int64Values[i] = int64Result.value();
             }
-        } else if (EqualsIgnoreCase(type, "-f")) {
-            if (values.size() == 0) {
+        } else if (EqualsIgnoreCase(argType, "-f")) {
+            if (argValuesSize == 0) {
                 return Error() << "No values specified when using \"-f\"\n";
             }
-            prop.value.floatValues.resize(values.size());
-            for (size_t i = 0; i < values.size(); i++) {
-                auto floatResult = safelyParseFloat(currentIndex + i, values[i]);
+            prop.value.floatValues.resize(argValuesSize);
+            for (size_t i = 0; i < argValuesSize; i++) {
+                auto floatResult = safelyParseFloat(currentIndex + i, argValues[i]);
                 if (!floatResult.ok()) {
                     return Error()
                            << StringPrintf("Value: \"%s\" is not a valid float: %s\n",
-                                           values[i].c_str(), getErrorMsg(floatResult).c_str());
+                                           argValues[i].c_str(), getErrorMsg(floatResult).c_str());
                 }
                 prop.value.floatValues[i] = floatResult.value();
             }
-        } else if (EqualsIgnoreCase(type, "-s")) {
-            if (values.size() != 1) {
+        } else if (EqualsIgnoreCase(argType, "-s")) {
+            if (argValuesSize != 1) {
                 return Error() << "Expect exact one value when using \"-s\"\n";
             }
-            prop.value.stringValue = values[0];
-        } else if (EqualsIgnoreCase(type, "-b")) {
-            if (values.size() != 1) {
+            prop.value.stringValue = argValues[0];
+        } else if (EqualsIgnoreCase(argType, "-b")) {
+            if (argValuesSize != 1) {
                 return Error() << "Expect exact one value when using \"-b\"\n";
             }
-            auto bytesResult = parseHexString(values[0]);
+            auto bytesResult = parseHexString(argValues[0]);
             if (!bytesResult.ok()) {
                 return Error() << StringPrintf("value: \"%s\" is not a valid hex string: %s\n",
-                                               values[0].c_str(), getErrorMsg(bytesResult).c_str());
+                                               argValues[0].c_str(),
+                                               getErrorMsg(bytesResult).c_str());
             }
             prop.value.byteValues = std::move(bytesResult.value());
-        } else if (EqualsIgnoreCase(type, "-a")) {
-            if (values.size() != 1) {
+        } else if (EqualsIgnoreCase(argType, "-a")) {
+            if (argValuesSize != 1) {
                 return Error() << "Expect exact one value when using \"-a\"\n";
             }
-            auto int32Result = safelyParseInt<int32_t>(currentIndex, values[0]);
+            auto int32Result = safelyParseInt<int32_t>(currentIndex, argValues[0]);
             if (!int32Result.ok()) {
                 return Error() << StringPrintf("Area ID: \"%s\" is not a valid int: %s\n",
-                                               values[0].c_str(), getErrorMsg(int32Result).c_str());
+                                               argValues[0].c_str(),
+                                               getErrorMsg(int32Result).c_str());
             }
             prop.areaId = int32Result.value();
+        } else if (EqualsIgnoreCase(argType, "-t")) {
+            if (argValuesSize != 1) {
+                return Error() << "Expect exact one value when using \"-t\"\n";
+            }
+            auto int64Result = safelyParseInt<int64_t>(currentIndex, argValues[0]);
+            if (!int64Result.ok()) {
+                return Error() << StringPrintf("Timestamp: \"%s\" is not a valid int64: %s\n",
+                                               argValues[0].c_str(),
+                                               getErrorMsg(int64Result).c_str());
+            }
+            prop.timestamp = int64Result.value();
         } else {
-            return Error() << StringPrintf("Unknown option: %s\n", type.c_str());
+            return Error() << StringPrintf("Unknown option: %s\n", argType.c_str());
         }
     }
 
@@ -825,7 +1652,7 @@
         return getErrorMsg(result);
     }
 
-    auto parseResult = parseSetPropOptions(options);
+    auto parseResult = parsePropOptions(options);
     if (!parseResult.ok()) {
         return getErrorMsg(parseResult);
     }
@@ -848,6 +1675,123 @@
                         getErrorMsg(setResult).c_str());
 }
 
+std::string FakeVehicleHardware::dumpGetPropertyWithArg(const std::vector<std::string>& options) {
+    if (auto result = checkArgumentsSize(options, 3); !result.ok()) {
+        return getErrorMsg(result);
+    }
+
+    auto parseResult = parsePropOptions(options);
+    if (!parseResult.ok()) {
+        return getErrorMsg(parseResult);
+    }
+    VehiclePropValue prop = std::move(parseResult.value());
+    ALOGD("Dump: Getting property: %s", prop.toString().c_str());
+
+    bool isSpecialValue = false;
+    auto result = maybeGetSpecialValue(prop, &isSpecialValue);
+
+    if (!isSpecialValue) {
+        result = mServerSidePropStore->readValue(prop);
+    }
+
+    if (!result.ok()) {
+        return StringPrintf("failed to read property value: %d, error: %s, code: %d\n", prop.prop,
+                            getErrorMsg(result).c_str(), getIntErrorCode(result));
+    }
+    return StringPrintf("Get property result: %s\n", result.value()->toString().c_str());
+}
+
+std::string FakeVehicleHardware::dumpSaveProperty(const std::vector<std::string>& options) {
+    // Format: --save-prop PROP [-a areaID]
+    if (auto result = checkArgumentsSize(options, 2); !result.ok()) {
+        return getErrorMsg(result);
+    }
+
+    auto parseResult = parsePropOptions(options);
+    if (!parseResult.ok()) {
+        return getErrorMsg(parseResult);
+    }
+    // We are only using the prop and areaId option.
+    VehiclePropValue value = std::move(parseResult.value());
+    int32_t propId = value.prop;
+    int32_t areaId = value.areaId;
+
+    auto readResult = mServerSidePropStore->readValue(value);
+    if (!readResult.ok()) {
+        return StringPrintf("Failed to save current property value, error: %s",
+                            getErrorMsg(readResult).c_str());
+    }
+
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    mSavedProps[PropIdAreaId{
+            .propId = propId,
+            .areaId = areaId,
+    }] = std::move(readResult.value());
+
+    return StringPrintf("Property: %" PRId32 ", areaID: %" PRId32 " saved", propId, areaId);
+}
+
+std::string FakeVehicleHardware::dumpRestoreProperty(const std::vector<std::string>& options) {
+    // Format: --restore-prop PROP [-a areaID]
+    if (auto result = checkArgumentsSize(options, 2); !result.ok()) {
+        return getErrorMsg(result);
+    }
+
+    auto parseResult = parsePropOptions(options);
+    if (!parseResult.ok()) {
+        return getErrorMsg(parseResult);
+    }
+    // We are only using the prop and areaId option.
+    VehiclePropValue value = std::move(parseResult.value());
+    int32_t propId = value.prop;
+    int32_t areaId = value.areaId;
+    VehiclePropValuePool::RecyclableType savedValue;
+
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        auto it = mSavedProps.find(PropIdAreaId{
+                .propId = propId,
+                .areaId = areaId,
+        });
+        if (it == mSavedProps.end()) {
+            return StringPrintf("No saved property for property: %" PRId32 ", areaID: %" PRId32,
+                                propId, areaId);
+        }
+
+        savedValue = std::move(it->second);
+        // Remove the saved property after restoring it.
+        mSavedProps.erase(it);
+    }
+
+    // Update timestamp.
+    savedValue->timestamp = elapsedRealtimeNano();
+
+    auto writeResult = mServerSidePropStore->writeValue(std::move(savedValue));
+    if (!writeResult.ok()) {
+        return StringPrintf("Failed to restore property value, error: %s",
+                            getErrorMsg(writeResult).c_str());
+    }
+
+    return StringPrintf("Property: %" PRId32 ", areaID: %" PRId32 " restored", propId, areaId);
+}
+
+std::string FakeVehicleHardware::dumpInjectEvent(const std::vector<std::string>& options) {
+    if (auto result = checkArgumentsSize(options, 3); !result.ok()) {
+        return getErrorMsg(result);
+    }
+
+    auto parseResult = parsePropOptions(options);
+    if (!parseResult.ok()) {
+        return getErrorMsg(parseResult);
+    }
+    VehiclePropValue prop = std::move(parseResult.value());
+    ALOGD("Dump: Injecting event from vehicle bus: %s", prop.toString().c_str());
+
+    eventFromVehicleBus(prop);
+
+    return StringPrintf("Event for property: %d injected", prop.prop);
+}
+
 StatusCode FakeVehicleHardware::checkHealth() {
     // Always return OK for checkHealth.
     return StatusCode::OK;
@@ -855,13 +1799,19 @@
 
 void FakeVehicleHardware::registerOnPropertyChangeEvent(
         std::unique_ptr<const PropertyChangeCallback> callback) {
-    std::scoped_lock<std::mutex> lockGuard(mLock);
+    if (mOnPropertyChangeCallback != nullptr) {
+        ALOGE("registerOnPropertyChangeEvent must only be called once");
+        return;
+    }
     mOnPropertyChangeCallback = std::move(callback);
 }
 
 void FakeVehicleHardware::registerOnPropertySetErrorEvent(
         std::unique_ptr<const PropertySetErrorCallback> callback) {
-    std::scoped_lock<std::mutex> lockGuard(mLock);
+    if (mOnPropertySetErrorCallback != nullptr) {
+        ALOGE("registerOnPropertySetErrorEvent must only be called once");
+        return;
+    }
     mOnPropertySetErrorCallback = std::move(callback);
 }
 
@@ -894,10 +1844,10 @@
             return;
         }
         result.value()->timestamp = elapsedRealtimeNano();
-        // Must remove the value before writing, otherwise, we would generate no update event since
-        // the value is the same.
-        mServerSidePropStore->removeValue(*result.value());
-        mServerSidePropStore->writeValue(std::move(result.value()));
+        // For continuous properties, we must generate a new onPropertyChange event periodically
+        // according to the sample rate.
+        mServerSidePropStore->writeValue(std::move(result.value()), /*updateStatus=*/true,
+                                         VehiclePropertyStore::EventMode::ALWAYS);
     });
     mRecurrentTimer->registerTimerCallback(interval, action);
     mRecurrentActions[propIdAreaId] = action;
@@ -905,8 +1855,6 @@
 }
 
 void FakeVehicleHardware::onValueChangeCallback(const VehiclePropValue& value) {
-    std::scoped_lock<std::mutex> lockGuard(mLock);
-
     if (mOnPropertyChangeCallback == nullptr) {
         return;
     }
@@ -916,33 +1864,26 @@
     (*mOnPropertyChangeCallback)(std::move(updatedValues));
 }
 
-void FakeVehicleHardware::maybeOverrideProperties(const char* overrideDir) {
-    if (android::base::GetBoolProperty(OVERRIDE_PROPERTY, false)) {
-        overrideProperties(overrideDir);
-    }
-}
-
-void FakeVehicleHardware::overrideProperties(const char* overrideDir) {
-    ALOGI("loading vendor override properties from %s", overrideDir);
-    if (auto dir = opendir(overrideDir); dir != NULL) {
+void FakeVehicleHardware::loadPropConfigsFromDir(
+        const std::string& dirPath,
+        std::unordered_map<int32_t, ConfigDeclaration>* configsByPropId) {
+    ALOGI("loading properties from %s", dirPath.c_str());
+    if (auto dir = opendir(dirPath.c_str()); dir != NULL) {
         std::regex regJson(".*[.]json", std::regex::icase);
         while (auto f = readdir(dir)) {
             if (!std::regex_match(f->d_name, regJson)) {
                 continue;
             }
-            std::string file = overrideDir + std::string(f->d_name);
-            JsonFakeValueGenerator tmpGenerator(file);
-
-            std::vector<VehiclePropValue> propValues = tmpGenerator.getAllEvents();
-            for (const VehiclePropValue& prop : propValues) {
-                auto propToStore = mValuePool->obtain(prop);
-                propToStore->timestamp = elapsedRealtimeNano();
-                if (auto result = mServerSidePropStore->writeValue(std::move(propToStore),
-                                                                   /*updateStatus=*/true);
-                    !result.ok()) {
-                    ALOGW("failed to write vendor override properties: %d, error: %s, code: %d",
-                          prop.prop, getErrorMsg(result).c_str(), getIntErrorCode(result));
-                }
+            std::string filePath = dirPath + "/" + std::string(f->d_name);
+            ALOGI("loading properties from %s", filePath.c_str());
+            auto result = mLoader.loadPropConfig(filePath);
+            if (!result.ok()) {
+                ALOGE("failed to load config file: %s, error: %s", filePath.c_str(),
+                      result.error().message().c_str());
+                continue;
+            }
+            for (auto& [propId, configDeclaration] : result.value()) {
+                (*configsByPropId)[propId] = std::move(configDeclaration);
             }
         }
         closedir(dir);
@@ -1028,11 +1969,15 @@
     std::unordered_map<std::shared_ptr<const GetValuesCallback>, std::vector<GetValueResult>>
             callbackToResults;
     for (const auto& rwc : mRequests.flush()) {
+        ATRACE_BEGIN("FakeVehicleHardware:handleGetValueRequest");
         auto result = mHardware->handleGetValueRequest(rwc.request);
+        ATRACE_END();
         callbackToResults[rwc.callback].push_back(std::move(result));
     }
     for (const auto& [callback, results] : callbackToResults) {
+        ATRACE_BEGIN("FakeVehicleHardware:call get value result callback");
         (*callback)(std::move(results));
+        ATRACE_END();
     }
 }
 
@@ -1042,11 +1987,15 @@
     std::unordered_map<std::shared_ptr<const SetValuesCallback>, std::vector<SetValueResult>>
             callbackToResults;
     for (const auto& rwc : mRequests.flush()) {
+        ATRACE_BEGIN("FakeVehicleHardware:handleSetValueRequest");
         auto result = mHardware->handleSetValueRequest(rwc.request);
+        ATRACE_END();
         callbackToResults[rwc.callback].push_back(std::move(result));
     }
     for (const auto& [callback, results] : callbackToResults) {
+        ATRACE_BEGIN("FakeVehicleHardware:call set value result callback");
         (*callback)(std::move(results));
+        ATRACE_END();
     }
 }
 
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
index 90d1516..8d8fcf5 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
@@ -22,13 +22,13 @@
     name: "FakeVehicleHardwareTest",
     vendor: true,
     srcs: ["*.cpp"],
-    cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
+    cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
     header_libs: [
         "IVehicleHardware",
-        "VehicleHalDefaultConfig",
         "VehicleHalTestUtilHeaders",
     ],
     static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties",
         "VehicleHalUtils",
         "FakeVehicleHardware",
         "FakeVehicleHalValueGenerators",
@@ -41,7 +41,11 @@
         "libjsoncpp",
     ],
     data: [
+        ":VehicleHalDefaultProperties_JSON",
+        ":VehicleHalTestProperties_JSON",
+        ":VehicleHalVendorClusterTestProperties_JSON",
         ":FakeVehicleHardwareTestOverrideJson",
+        ":FakeVehicleHardwareTestPropJson",
     ],
     defaults: ["VehicleHalDefaults"],
     test_suites: ["device-tests"],
@@ -51,3 +55,8 @@
     name: "FakeVehicleHardwareTestOverrideJson",
     srcs: ["override/*"],
 }
+
+filegroup {
+    name: "FakeVehicleHardwareTestPropJson",
+    srcs: ["fakedata/prop.json"],
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 3e8f634..8d385dd 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -16,7 +16,6 @@
 
 #include <FakeVehicleHardware.h>
 
-#include <DefaultConfig.h>
 #include <FakeObd2Frame.h>
 #include <FakeUserHal.h>
 #include <PropertyUtils.h>
@@ -38,6 +37,22 @@
 #include <unordered_set>
 #include <vector>
 
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+void PrintTo(const VehiclePropValue& value, std::ostream* os) {
+    *os << "\n( " << value.toString() << " )\n";
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
 namespace android {
 namespace hardware {
 namespace automotive {
@@ -45,6 +60,7 @@
 namespace fake {
 namespace {
 
+using ::aidl::android::hardware::automotive::vehicle::ErrorState;
 using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
 using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
 using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
@@ -53,17 +69,23 @@
 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
+using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
 using ::android::base::expected;
 using ::android::base::ScopedLockAssertion;
 using ::android::base::StringPrintf;
 using ::android::base::unexpected;
+using ::testing::AnyOfArray;
 using ::testing::ContainerEq;
 using ::testing::ContainsRegex;
 using ::testing::Eq;
+using ::testing::HasSubstr;
+using ::testing::IsSubsetOf;
 using ::testing::WhenSortedBy;
 
 using std::chrono::milliseconds;
@@ -78,7 +100,9 @@
   public:
     FakeVehicleHardwareTestHelper(FakeVehicleHardware* hardware) { mHardware = hardware; }
 
-    void overrideProperties(const char* overrideDir) { mHardware->overrideProperties(overrideDir); }
+    std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations() {
+        return mHardware->loadConfigDeclarations();
+    }
 
   private:
     FakeVehicleHardware* mHardware;
@@ -87,6 +111,9 @@
 class FakeVehicleHardwareTest : public ::testing::Test {
   protected:
     void SetUp() override {
+        mHardware = std::make_unique<FakeVehicleHardware>(android::base::GetExecutableDirectory(),
+                                                          /*overrideConfigDir=*/"",
+                                                          /*forceOverride=*/false);
         auto callback = std::make_unique<IVehicleHardware::PropertyChangeCallback>(
                 [this](const std::vector<VehiclePropValue>& values) {
                     onPropertyChangeEvent(values);
@@ -98,7 +125,17 @@
                 [this](std::vector<GetValueResult> results) { onGetValues(results); });
     }
 
-    FakeVehicleHardware* getHardware() { return &mHardware; }
+    void TearDown() override {
+        // mHardware uses callback which contains reference to 'this', so it has to be destroyed
+        // before 'this'.
+        mHardware.reset();
+    }
+
+    FakeVehicleHardware* getHardware() { return mHardware.get(); }
+
+    void setHardware(std::unique_ptr<FakeVehicleHardware> hardware) {
+        mHardware = std::move(hardware);
+    }
 
     StatusCode setValues(const std::vector<SetValueRequest>& requests) {
         {
@@ -251,6 +288,14 @@
         return mChangedProperties;
     }
 
+    bool waitForChangedProperties(size_t count, milliseconds timeout) {
+        std::unique_lock<std::mutex> lk(mLock);
+        return mCv.wait_for(lk, timeout, [this, count] {
+            ScopedLockAssertion lockAssertion(mLock);
+            return mChangedProperties.size() >= count;
+        });
+    }
+
     bool waitForChangedProperties(int32_t propId, int32_t areaId, size_t count,
                                   milliseconds timeout) {
         PropIdAreaId propIdAreaId{
@@ -270,6 +315,15 @@
         mChangedProperties.clear();
     }
 
+    size_t getEventCount(int32_t propId, int32_t areaId) {
+        PropIdAreaId propIdAreaId{
+                .propId = propId,
+                .areaId = areaId,
+        };
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        return mEventCount[propIdAreaId];
+    }
+
     static void addSetValueRequest(std::vector<SetValueRequest>& requests,
                                    std::vector<SetValueResult>& expectedResults, int64_t requestId,
                                    const VehiclePropValue& value, StatusCode expectedStatus) {
@@ -332,7 +386,7 @@
     } mPropValueCmp;
 
   private:
-    FakeVehicleHardware mHardware;
+    std::unique_ptr<FakeVehicleHardware> mHardware;
     std::shared_ptr<IVehicleHardware::SetValuesCallback> mSetValuesCallback;
     std::shared_ptr<IVehicleHardware::GetValuesCallback> mGetValuesCallback;
     std::condition_variable mCv;
@@ -348,7 +402,8 @@
 TEST_F(FakeVehicleHardwareTest, testGetAllPropertyConfigs) {
     std::vector<VehiclePropConfig> configs = getHardware()->getAllPropertyConfigs();
 
-    ASSERT_EQ(configs.size(), defaultconfig::getDefaultConfigs().size());
+    FakeVehicleHardwareTestHelper helper(getHardware());
+    ASSERT_EQ(configs.size(), helper.loadConfigDeclarations().size());
 }
 
 TEST_F(FakeVehicleHardwareTest, testGetDefaultValues) {
@@ -356,7 +411,8 @@
     std::vector<GetValueResult> expectedGetValueResults;
     int64_t requestId = 1;
 
-    for (auto& config : defaultconfig::getDefaultConfigs()) {
+    FakeVehicleHardwareTestHelper helper(getHardware());
+    for (auto& [propId, config] : helper.loadConfigDeclarations()) {
         if (obd2frame::FakeObd2Frame::isDiagnosticProperty(config.config)) {
             // Ignore storing default value for diagnostic property. They have special get/set
             // logic.
@@ -368,12 +424,16 @@
             continue;
         }
 
-        if (config.config.prop == ECHO_REVERSE_BYTES) {
+        if (propId == ECHO_REVERSE_BYTES) {
             // Ignore ECHO_REVERSE_BYTES, it has special logic.
             continue;
         }
 
-        int propId = config.config.prop;
+        if (propId == VENDOR_PROPERTY_ID) {
+            // Ignore VENDOR_PROPERTY_ID, it has special logic.
+            continue;
+        }
+
         if (isGlobalProp(propId)) {
             if (config.initialValue == RawPropValues{}) {
                 addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++,
@@ -631,10 +691,12 @@
 }
 
 TEST_F(FakeVehicleHardwareTest, testVendorOverrideProperties) {
-    std::string overrideDir = android::base::GetExecutableDirectory() + "/override/";
+    std::string currentDir = android::base::GetExecutableDirectory();
+    std::string overrideDir = currentDir + "/override/";
     // Set vendor override directory.
-    FakeVehicleHardwareTestHelper helper(getHardware());
-    helper.overrideProperties(overrideDir.c_str());
+    std::unique_ptr<FakeVehicleHardware> hardware =
+            std::make_unique<FakeVehicleHardware>(currentDir, overrideDir, /*forceOverride=*/true);
+    setHardware(std::move(hardware));
 
     // This is the same as the prop in 'gear_selection.json'.
     int gearProp = toInt(VehicleProperty::GEAR_SELECTION);
@@ -669,10 +731,12 @@
 }
 
 TEST_F(FakeVehicleHardwareTest, testVendorOverridePropertiesMultipleAreas) {
-    std::string overrideDir = android::base::GetExecutableDirectory() + "/override/";
+    std::string currentDir = android::base::GetExecutableDirectory();
+    std::string overrideDir = currentDir + "/override/";
     // Set vendor override directory.
-    FakeVehicleHardwareTestHelper helper(getHardware());
-    helper.overrideProperties(overrideDir.c_str());
+    std::unique_ptr<FakeVehicleHardware> hardware =
+            std::make_unique<FakeVehicleHardware>(currentDir, overrideDir, /*forceOverride=*/true);
+    setHardware(std::move(hardware));
 
     // This is the same as the prop in 'hvac_temperature_set.json'.
     int hvacProp = toInt(VehicleProperty::HVAC_TEMPERATURE_SET);
@@ -685,22 +749,16 @@
     ASSERT_TRUE(result.ok()) << "expect to get the overridden property ok: " << getStatus(result);
     ASSERT_EQ(static_cast<size_t>(1), result.value().value.floatValues.size());
     ASSERT_EQ(30.0f, result.value().value.floatValues[0]);
-
-    // HVAC_RIGHT should not be affected and return the default value.
-    result = getValue(VehiclePropValue{
-            .prop = hvacProp,
-            .areaId = HVAC_RIGHT,
-    });
-
-    ASSERT_TRUE(result.ok()) << "expect to get the default property ok: " << getStatus(result);
-    ASSERT_EQ(static_cast<size_t>(1), result.value().value.floatValues.size());
-    ASSERT_EQ(20.0f, result.value().value.floatValues[0]);
 }
 
 TEST_F(FakeVehicleHardwareTest, testVendorOverridePropertiesDirDoesNotExist) {
-    // Set vendor override directory to a non-existing dir
-    FakeVehicleHardwareTestHelper helper(getHardware());
-    helper.overrideProperties("123");
+    std::string currentDir = android::base::GetExecutableDirectory();
+    std::string overrideDir = currentDir + "/override/";
+    // Set vendor override directory to a non-existing dir.
+    std::unique_ptr<FakeVehicleHardware> hardware =
+            std::make_unique<FakeVehicleHardware>(currentDir, "1234", /*forceOverride=*/true);
+    setHardware(std::move(hardware));
+
     auto result = getValue(VehiclePropValue{
             .prop = toInt(VehicleProperty::GEAR_SELECTION),
     });
@@ -979,6 +1037,488 @@
                                     },
                             },
             },
+            SetSpecialValueTestCase{
+                    .name = "set_automatic_emergency_braking_enabled_false",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            AUTOMATIC_EMERGENCY_BRAKING_STATE),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_automatic_emergency_braking_enabled_true",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            AUTOMATIC_EMERGENCY_BRAKING_STATE),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_forward_collision_warning_enabled_false",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            FORWARD_COLLISION_WARNING_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            FORWARD_COLLISION_WARNING_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  FORWARD_COLLISION_WARNING_STATE),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_forward_collision_warning_enabled_true",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            FORWARD_COLLISION_WARNING_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            FORWARD_COLLISION_WARNING_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  FORWARD_COLLISION_WARNING_STATE),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_blind_spot_warning_enabled_false",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::BLIND_SPOT_WARNING_STATE),
+                                            .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::BLIND_SPOT_WARNING_STATE),
+                                            .areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_blind_spot_warning_enabled_true",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::BLIND_SPOT_WARNING_STATE),
+                                            .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::BLIND_SPOT_WARNING_STATE),
+                                            .areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_lane_departure_warning_enabled_false",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  LANE_DEPARTURE_WARNING_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  LANE_DEPARTURE_WARNING_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_DEPARTURE_WARNING_STATE),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_lane_departure_warning_enabled_true",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  LANE_DEPARTURE_WARNING_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  LANE_DEPARTURE_WARNING_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_DEPARTURE_WARNING_STATE),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_lane_keep_assist_enabled_false",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_lane_keep_assist_enabled_true",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_lane_centering_assist_enabled_false",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_CENTERING_ASSIST_STATE),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_lane_centering_assist_enabled_true",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::LANE_CENTERING_ASSIST_STATE),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_emergency_lane_keep_assist_enabled_false",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  EMERGENCY_LANE_KEEP_ASSIST_STATE),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_emergency_lane_keep_assist_enabled_true",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  EMERGENCY_LANE_KEEP_ASSIST_STATE),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_cruise_control_enabled_false",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::CRUISE_CONTROL_TYPE),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::CRUISE_CONTROL_STATE),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_cruise_control_enabled_true",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::CRUISE_CONTROL_TYPE),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::CRUISE_CONTROL_STATE),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_hands_on_detection_enabled_false",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::HANDS_ON_DETECTION_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::HANDS_ON_DETECTION_ENABLED),
+                                            .value.int32Values = {0},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  HANDS_ON_DETECTION_DRIVER_STATE),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::HANDS_ON_DETECTION_WARNING),
+                                            .value.int32Values = {toInt(
+                                                    ErrorState::NOT_AVAILABLE_DISABLED)},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "set_hands_on_detection_enabled_true",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::HANDS_ON_DETECTION_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::HANDS_ON_DETECTION_ENABLED),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::
+                                                                  HANDS_ON_DETECTION_DRIVER_STATE),
+                                            .value.int32Values = {1},
+                                    },
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::HANDS_ON_DETECTION_WARNING),
+                                            .value.int32Values = {1},
+                                    },
+                            },
+            },
     };
 }
 
@@ -996,7 +1536,7 @@
     std::vector<VehiclePropValue> gotValues;
 
     for (const auto& value : tc.expectedValuesToGet) {
-        auto result = getValue(VehiclePropValue{.prop = value.prop});
+        auto result = getValue(VehiclePropValue{.prop = value.prop, .areaId = value.areaId});
 
         ASSERT_TRUE(result.ok()) << "failed to get property " << value.prop
                                  << " status:" << getStatus(result);
@@ -1011,7 +1551,7 @@
     // Some of the updated properties might be the same as default config, thus not causing
     // a property change event. So the changed properties should be a subset of all the updated
     // properties.
-    ASSERT_THAT(getChangedProperties(), WhenSortedBy(mPropValueCmp, Eq(gotValues)));
+    ASSERT_THAT(getChangedProperties(), IsSubsetOf(gotValues));
 }
 
 INSTANTIATE_TEST_SUITE_P(
@@ -1040,11 +1580,12 @@
     ASSERT_EQ(events.size(), 1u);
     // Erase the timestamp for comparison.
     events[0].timestamp = 0;
-    ASSERT_EQ(events[0], (VehiclePropValue{
-                                 .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
-                                 .status = VehiclePropertyStatus::AVAILABLE,
-                                 .value.int32Values = {toInt(VehicleApPowerStateReq::ON), 0},
-                         }));
+    auto expectedValue = VehiclePropValue{
+            .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
+            .status = VehiclePropertyStatus::AVAILABLE,
+            .value.int32Values = {toInt(VehicleApPowerStateReq::ON), 0},
+    };
+    ASSERT_EQ(events[0], expectedValue);
 }
 
 TEST_F(FakeVehicleHardwareTest, testGetObd2FreezeFrame) {
@@ -1108,6 +1649,255 @@
     EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE);
 }
 
+TEST_F(FakeVehicleHardwareTest, testGetHvacPropNotAvailable) {
+    int seatAreaIds[5] = {SEAT_1_LEFT, SEAT_1_RIGHT, SEAT_2_LEFT, SEAT_2_CENTER, SEAT_2_RIGHT};
+    for (int areaId : seatAreaIds) {
+        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                                      .areaId = areaId,
+                                                      .value.int32Values = {0}});
+
+        ASSERT_EQ(status, StatusCode::OK);
+
+        for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+            int powerPropId = HVAC_POWER_PROPERTIES[i];
+            for (int powerDependentAreaId : seatAreaIds) {
+                auto getValueResult = getValue(VehiclePropValue{
+                        .prop = powerPropId,
+                        .areaId = powerDependentAreaId,
+                });
+
+                if (areaId == powerDependentAreaId) {
+                    EXPECT_FALSE(getValueResult.ok());
+                    EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE_DISABLED);
+                } else {
+                    EXPECT_TRUE(getValueResult.ok());
+                }
+            }
+        }
+
+        // Resetting HVAC_POWER_ON at areaId back to ON state to ensure that there's no dependence
+        // on this value from any power dependent property values other than those with the same
+        // areaId.
+        setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                  .areaId = areaId,
+                                  .value.int32Values = {1}});
+    }
+}
+
+TEST_F(FakeVehicleHardwareTest, testSetHvacPropNotAvailable) {
+    int seatAreaIds[5] = {SEAT_1_LEFT, SEAT_1_RIGHT, SEAT_2_LEFT, SEAT_2_CENTER, SEAT_2_RIGHT};
+    for (int areaId : seatAreaIds) {
+        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                                      .areaId = areaId,
+                                                      .value.int32Values = {0}});
+
+        ASSERT_EQ(status, StatusCode::OK);
+
+        for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+            int powerPropId = HVAC_POWER_PROPERTIES[i];
+            for (int powerDependentAreaId : seatAreaIds) {
+                StatusCode status = setValue(VehiclePropValue{.prop = powerPropId,
+                                                              .areaId = powerDependentAreaId,
+                                                              .value.int32Values = {1}});
+
+                if (areaId == powerDependentAreaId) {
+                    EXPECT_EQ(status, StatusCode::NOT_AVAILABLE_DISABLED);
+                } else {
+                    EXPECT_EQ(status, StatusCode::OK);
+                }
+            }
+        }
+
+        // Resetting HVAC_POWER_ON at areaId back to ON state to ensure that there's no dependence
+        // on this value from any power dependent property values other than those with the same
+        // areaId.
+        setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                  .areaId = areaId,
+                                  .value.int32Values = {1}});
+    }
+}
+
+TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) {
+    int seatAreaIds[5] = {SEAT_1_LEFT, SEAT_1_RIGHT, SEAT_2_LEFT, SEAT_2_CENTER, SEAT_2_RIGHT};
+    for (int areaId : seatAreaIds) {
+        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                                      .areaId = areaId,
+                                                      .value.int32Values = {0}});
+
+        ASSERT_EQ(status, StatusCode::OK);
+
+        clearChangedProperties();
+        setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                  .areaId = areaId,
+                                  .value.int32Values = {1}});
+
+        auto events = getChangedProperties();
+        // If we turn HVAC power on, we expect to receive one property event for every HVAC prop
+        // areas plus one event for HVAC_POWER_ON.
+        std::vector<int32_t> changedPropIds;
+        for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+            changedPropIds.push_back(HVAC_POWER_PROPERTIES[i]);
+        }
+        changedPropIds.push_back(toInt(VehicleProperty::HVAC_POWER_ON));
+
+        for (const auto& event : events) {
+            EXPECT_EQ(event.areaId, areaId);
+            EXPECT_THAT(event.prop, AnyOfArray(changedPropIds));
+        }
+    }
+}
+
+TEST_F(FakeVehicleHardwareTest, testGetAdasPropNotAvailable) {
+    std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToDependentProps = {
+            {
+                    toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
+                    {
+                            toInt(VehicleProperty::CRUISE_CONTROL_TARGET_SPEED),
+                            toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP),
+                            toInt(VehicleProperty::
+                                          ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE),
+                    },
+            },
+    };
+    for (auto& enabledToDependents : adasEnabledPropToDependentProps) {
+        int32_t adasEnabledPropertyId = enabledToDependents.first;
+        StatusCode status =
+                setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {0}});
+        EXPECT_EQ(status, StatusCode::OK);
+
+        auto& dependentProps = enabledToDependents.second;
+        for (auto dependentProp : dependentProps) {
+            auto getValueResult = getValue(VehiclePropValue{.prop = dependentProp});
+            EXPECT_FALSE(getValueResult.ok());
+            EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE_DISABLED);
+        }
+    }
+}
+
+TEST_F(FakeVehicleHardwareTest, testSetAdasPropNotAvailable) {
+    std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToDependentProps = {
+            {
+                    toInt(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
+                    {
+                            toInt(VehicleProperty::LANE_CENTERING_ASSIST_COMMAND),
+                    },
+            },
+            {
+                    toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
+                    {
+                            toInt(VehicleProperty::CRUISE_CONTROL_COMMAND),
+                            toInt(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP),
+                    },
+            },
+    };
+    for (auto& enabledToDependents : adasEnabledPropToDependentProps) {
+        int32_t adasEnabledPropertyId = enabledToDependents.first;
+        StatusCode status =
+                setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {0}});
+        EXPECT_EQ(status, StatusCode::OK);
+
+        auto& dependentProps = enabledToDependents.second;
+        for (auto dependentProp : dependentProps) {
+            StatusCode status = setValue(VehiclePropValue{.prop = dependentProp});
+            EXPECT_EQ(status, StatusCode::NOT_AVAILABLE_DISABLED);
+        }
+    }
+}
+
+TEST_F(FakeVehicleHardwareTest, testSendAdasPropertiesState) {
+    std::unordered_map<int32_t, std::vector<int32_t>> adasEnabledPropToAdasPropWithErrorState = {
+            // AEB
+            {
+                    toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
+                    {
+                            toInt(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE),
+                    },
+            },
+            // FCW
+            {
+                    toInt(VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED),
+                    {
+                            toInt(VehicleProperty::FORWARD_COLLISION_WARNING_STATE),
+                    },
+            },
+            // BSW
+            {
+                    toInt(VehicleProperty::BLIND_SPOT_WARNING_ENABLED),
+                    {
+                            toInt(VehicleProperty::BLIND_SPOT_WARNING_STATE),
+                    },
+            },
+            // LDW
+            {
+                    toInt(VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED),
+                    {
+                            toInt(VehicleProperty::LANE_DEPARTURE_WARNING_STATE),
+                    },
+            },
+            // LKA
+            {
+                    toInt(VehicleProperty::LANE_KEEP_ASSIST_ENABLED),
+                    {
+                            toInt(VehicleProperty::LANE_KEEP_ASSIST_STATE),
+                    },
+            },
+            // LCA
+            {
+                    toInt(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED),
+                    {
+                            toInt(VehicleProperty::LANE_CENTERING_ASSIST_STATE),
+                    },
+            },
+            // ELKA
+            {
+                    toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED),
+                    {
+                            toInt(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE),
+                    },
+            },
+            // CC
+            {
+                    toInt(VehicleProperty::CRUISE_CONTROL_ENABLED),
+                    {
+                            toInt(VehicleProperty::CRUISE_CONTROL_TYPE),
+                            toInt(VehicleProperty::CRUISE_CONTROL_STATE),
+                    },
+            },
+            // HOD
+            {
+                    toInt(VehicleProperty::HANDS_ON_DETECTION_ENABLED),
+                    {
+                            toInt(VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE),
+                            toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING),
+                    },
+            },
+    };
+    for (auto& enabledToErrorStateProps : adasEnabledPropToAdasPropWithErrorState) {
+        int32_t adasEnabledPropertyId = enabledToErrorStateProps.first;
+        StatusCode status =
+                setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {0}});
+        EXPECT_EQ(status, StatusCode::OK);
+
+        clearChangedProperties();
+        status =
+                setValue(VehiclePropValue{.prop = adasEnabledPropertyId, .value.int32Values = {1}});
+        EXPECT_EQ(status, StatusCode::OK);
+
+        // If we enable the ADAS feature, we expect to receive one property event for every ADAS
+        // state property plus one event for enabling the feature.
+        std::unordered_set<int32_t> expectedChangedPropIds(enabledToErrorStateProps.second.begin(),
+                                                           enabledToErrorStateProps.second.end());
+        expectedChangedPropIds.insert(adasEnabledPropertyId);
+
+        std::unordered_set<int32_t> changedPropIds;
+        auto events = getChangedProperties();
+        for (const auto& event : events) {
+            changedPropIds.insert(event.prop);
+        }
+        EXPECT_EQ(changedPropIds, expectedChangedPropIds);
+    }
+}
+
 TEST_F(FakeVehicleHardwareTest, testGetUserPropertySetOnly) {
     for (VehicleProperty prop : std::vector<VehicleProperty>({
                  VehicleProperty::INITIAL_USER_INFO,
@@ -1191,6 +1981,8 @@
     ASSERT_EQ(events.size(), static_cast<size_t>(1));
 
     events[0].timestamp = 0;
+    // The returned event will have area ID 0.
+    valueToSet.areaId = 0;
     ASSERT_EQ(events[0], valueToSet);
 
     // Try to get switch_user again, should return default value.
@@ -1201,19 +1993,20 @@
     events = getChangedProperties();
     ASSERT_EQ(events.size(), static_cast<size_t>(1));
     events[0].timestamp = 0;
-    ASSERT_EQ(events[0], (VehiclePropValue{
-                                 .areaId = 0,
-                                 .prop = toInt(VehicleProperty::SWITCH_USER),
-                                 .value.int32Values =
-                                         {
-                                                 // Request ID
-                                                 666,
-                                                 // VEHICLE_RESPONSE
-                                                 3,
-                                                 // SUCCESS
-                                                 1,
-                                         },
-                         }));
+    auto expectedValue = VehiclePropValue{
+            .areaId = 0,
+            .prop = toInt(VehicleProperty::SWITCH_USER),
+            .value.int32Values =
+                    {
+                            // Request ID
+                            666,
+                            // VEHICLE_RESPONSE
+                            3,
+                            // SUCCESS
+                            1,
+                    },
+    };
+    ASSERT_EQ(events[0], expectedValue);
 }
 
 TEST_F(FakeVehicleHardwareTest, testCreateUser) {
@@ -1245,6 +2038,8 @@
     auto events = getChangedProperties();
     ASSERT_EQ(events.size(), static_cast<size_t>(1));
     events[0].timestamp = 0;
+    // The returned event will have area ID 0.
+    valueToSet.areaId = 0;
     EXPECT_EQ(events[0], valueToSet);
 
     // Try to get create_user again, should return default value.
@@ -1255,17 +2050,18 @@
     events = getChangedProperties();
     ASSERT_EQ(events.size(), static_cast<size_t>(1));
     events[0].timestamp = 0;
-    ASSERT_EQ(events[0], (VehiclePropValue{
-                                 .areaId = 0,
-                                 .prop = toInt(VehicleProperty::CREATE_USER),
-                                 .value.int32Values =
-                                         {
-                                                 // Request ID
-                                                 666,
-                                                 // SUCCESS
-                                                 1,
-                                         },
-                         }));
+    auto expectedValue = VehiclePropValue{
+            .areaId = 0,
+            .prop = toInt(VehicleProperty::CREATE_USER),
+            .value.int32Values =
+                    {
+                            // Request ID
+                            666,
+                            // SUCCESS
+                            1,
+                    },
+    };
+    ASSERT_EQ(events[0], expectedValue);
 }
 
 TEST_F(FakeVehicleHardwareTest, testInitialUserInfo) {
@@ -1297,11 +2093,12 @@
     auto events = getChangedProperties();
     ASSERT_EQ(events.size(), static_cast<size_t>(1));
     events[0].timestamp = 0;
-    EXPECT_EQ(events[0], (VehiclePropValue{
-                                 .areaId = 1,
-                                 .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
-                                 .value.int32Values = {3, 1, 11},
-                         }));
+    auto expectedValue = VehiclePropValue{
+            .areaId = 0,
+            .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
+            .value.int32Values = {3, 1, 11},
+    };
+    EXPECT_EQ(events[0], expectedValue);
 
     // Try to get create_user again, should return default value.
     clearChangedProperties();
@@ -1311,22 +2108,23 @@
     events = getChangedProperties();
     ASSERT_EQ(events.size(), static_cast<size_t>(1));
     events[0].timestamp = 0;
-    EXPECT_EQ(events[0], (VehiclePropValue{
-                                 .areaId = 0,
-                                 .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
-                                 .value.int32Values =
-                                         {
-                                                 // Request ID
-                                                 3,
-                                                 // ACTION: DEFAULT
-                                                 0,
-                                                 // User id: 0
-                                                 0,
-                                                 // Flags: 0
-                                                 0,
-                                         },
-                                 .value.stringValue = "||",
-                         }));
+    expectedValue = VehiclePropValue{
+            .areaId = 0,
+            .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
+            .value.int32Values =
+                    {
+                            // Request ID
+                            3,
+                            // ACTION: DEFAULT
+                            0,
+                            // User id: 0
+                            0,
+                            // Flags: 0
+                            0,
+                    },
+            .value.stringValue = "||",
+    };
+    EXPECT_EQ(events[0], expectedValue);
 }
 
 TEST_F(FakeVehicleHardwareTest, testDumpAllProperties) {
@@ -1395,6 +2193,85 @@
     ASSERT_THAT(result.buffer, ContainsRegex("Invalid number of arguments"));
 }
 
+TEST_F(FakeVehicleHardwareTest, testDumpSpecificPropertyWithArg) {
+    auto getValueResult = getValue(VehiclePropValue{.prop = OBD2_FREEZE_FRAME_INFO});
+    ASSERT_TRUE(getValueResult.ok());
+    auto propValue = getValueResult.value();
+    ASSERT_EQ(propValue.value.int64Values.size(), static_cast<size_t>(3))
+            << "expect 3 obd2 freeze frames stored";
+
+    std::string propIdStr = StringPrintf("%d", OBD2_FREEZE_FRAME);
+    DumpResult result;
+    for (int64_t timestamp : propValue.value.int64Values) {
+        result = getHardware()->dump(
+                {"--getWithArg", propIdStr, "-i64", StringPrintf("%" PRId64, timestamp)});
+
+        ASSERT_FALSE(result.callerShouldDumpState);
+        ASSERT_NE(result.buffer, "");
+        ASSERT_THAT(result.buffer, ContainsRegex("Get property result:"));
+    }
+
+    // Set the timestamp argument to 0.
+    result = getHardware()->dump({"--getWithArg", propIdStr, "-i64", "0"});
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    // There is no freeze obd2 frame at timestamp 0.
+    ASSERT_THAT(result.buffer, ContainsRegex("failed to read property value"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testSaveRestoreProp) {
+    int32_t prop = toInt(VehicleProperty::TIRE_PRESSURE);
+    std::string propIdStr = std::to_string(prop);
+    std::string areaIdStr = std::to_string(WHEEL_FRONT_LEFT);
+
+    DumpResult result = getHardware()->dump({"--save-prop", propIdStr, "-a", areaIdStr});
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, ContainsRegex("saved"));
+
+    ASSERT_EQ(setValue(VehiclePropValue{
+                      .prop = prop,
+                      .areaId = WHEEL_FRONT_LEFT,
+                      .value =
+                              {
+                                      .floatValues = {210.0},
+                              },
+              }),
+              StatusCode::OK);
+
+    result = getHardware()->dump({"--restore-prop", propIdStr, "-a", areaIdStr});
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, ContainsRegex("restored"));
+
+    auto getResult = getValue(VehiclePropValue{.prop = prop, .areaId = WHEEL_FRONT_LEFT});
+
+    ASSERT_TRUE(getResult.ok());
+    // The default value is 200.0.
+    ASSERT_EQ(getResult.value().value.floatValues, std::vector<float>{200.0});
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpInjectEvent) {
+    int32_t prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
+    std::string propIdStr = std::to_string(prop);
+
+    int64_t timestamp = elapsedRealtimeNano();
+    // Inject an event with float value 123.4 and timestamp.
+    DumpResult result = getHardware()->dump(
+            {"--inject-event", propIdStr, "-f", "123.4", "-t", std::to_string(timestamp)});
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer,
+                ContainsRegex(StringPrintf("Event for property: %d injected", prop)));
+    ASSERT_TRUE(waitForChangedProperties(prop, 0, /*count=*/1, milliseconds(1000)))
+            << "No changed event received for injected event from vehicle bus";
+    auto events = getChangedProperties();
+    ASSERT_EQ(events.size(), 1u);
+    auto event = events[0];
+    ASSERT_EQ(event.timestamp, timestamp);
+    ASSERT_EQ(event.value.floatValues, std::vector<float>({123.4}));
+}
+
 TEST_F(FakeVehicleHardwareTest, testDumpInvalidOptions) {
     std::vector<std::string> options;
     options.push_back("--invalid");
@@ -1405,26 +2282,16 @@
     ASSERT_THAT(result.buffer, ContainsRegex("Invalid option: --invalid"));
 }
 
-TEST_F(FakeVehicleHardwareTest, testDumpFakeUserHalHelp) {
-    std::vector<std::string> options;
-    options.push_back("--user-hal");
-
-    DumpResult result = getHardware()->dump(options);
-    ASSERT_FALSE(result.callerShouldDumpState);
-    ASSERT_NE(result.buffer, "");
-    ASSERT_THAT(result.buffer, ContainsRegex("dumps state used for user management"));
-}
-
 TEST_F(FakeVehicleHardwareTest, testDumpFakeUserHal) {
     std::vector<std::string> options;
     options.push_back("--user-hal");
-    // Indent: " ".
-    options.push_back(" ");
 
     DumpResult result = getHardware()->dump(options);
     ASSERT_FALSE(result.callerShouldDumpState);
     ASSERT_NE(result.buffer, "");
-    ASSERT_THAT(result.buffer, ContainsRegex(" No InitialUserInfo response\n"));
+    ASSERT_THAT(result.buffer,
+                ContainsRegex("No InitialUserInfo response\nNo SwitchUser response\nNo CreateUser "
+                              "response\nNo SetUserIdentificationAssociation response\n"));
 }
 
 struct SetPropTestCase {
@@ -1606,6 +2473,386 @@
     ASSERT_EQ(3.402823466E+38f, value.value.floatValues[2]);
 }
 
+struct OptionsTestCase {
+    std::string name;
+    std::vector<std::string> options;
+    std::string expectMsg;
+};
+
+class FakeVehicleHardwareOptionsTest : public FakeVehicleHardwareTest,
+                                       public testing::WithParamInterface<OptionsTestCase> {};
+
+std::vector<OptionsTestCase> GenInvalidOptions() {
+    return {{"unknown_command", {"--unknown"}, "Invalid option: --unknown"},
+            {"help", {"--help"}, "Usage:"},
+            {"genfakedata_no_subcommand",
+             {"--genfakedata"},
+             "No subcommand specified for genfakedata"},
+            {"genfakedata_unknown_subcommand",
+             {"--genfakedata", "--unknown"},
+             "Unknown command: \"--unknown\""},
+            {"genfakedata_start_linear_no_args",
+             {"--genfakedata", "--startlinear"},
+             "incorrect argument count"},
+            {"genfakedata_start_linear_invalid_propId",
+             {"--genfakedata", "--startlinear", "abcd", "0.1", "0.1", "0.1", "0.1", "100000000"},
+             "failed to parse propId as int: \"abcd\""},
+            {"genfakedata_start_linear_invalid_middleValue",
+             {"--genfakedata", "--startlinear", "1", "abcd", "0.1", "0.1", "0.1", "100000000"},
+             "failed to parse middleValue as float: \"abcd\""},
+            {"genfakedata_start_linear_invalid_currentValue",
+             {"--genfakedata", "--startlinear", "1", "0.1", "abcd", "0.1", "0.1", "100000000"},
+             "failed to parse currentValue as float: \"abcd\""},
+            {"genfakedata_start_linear_invalid_dispersion",
+             {"--genfakedata", "--startlinear", "1", "0.1", "0.1", "abcd", "0.1", "100000000"},
+             "failed to parse dispersion as float: \"abcd\""},
+            {"genfakedata_start_linear_invalid_increment",
+             {"--genfakedata", "--startlinear", "1", "0.1", "0.1", "0.1", "abcd", "100000000"},
+             "failed to parse increment as float: \"abcd\""},
+            {"genfakedata_start_linear_invalid_interval",
+             {"--genfakedata", "--startlinear", "1", "0.1", "0.1", "0.1", "0.1", "0.1"},
+             "failed to parse interval as int: \"0.1\""},
+            {"genfakedata_stop_linear_no_args",
+             {"--genfakedata", "--stoplinear"},
+             "incorrect argument count"},
+            {"genfakedata_stop_linear_invalid_propId",
+             {"--genfakedata", "--stoplinear", "abcd"},
+             "failed to parse propId as int: \"abcd\""},
+            {"genfakedata_startjson_no_args",
+             {"--genfakedata", "--startjson"},
+             "incorrect argument count"},
+            {"genfakedata_startjson_invalid_repetition",
+             {"--genfakedata", "--startjson", "--path", "file", "0.1"},
+             "failed to parse repetition as int: \"0.1\""},
+            {"genfakedata_startjson_invalid_json_file",
+             {"--genfakedata", "--startjson", "--path", "file", "1"},
+             "invalid JSON file"},
+            {"genfakedata_stopjson_no_args",
+             {"--genfakedata", "--stopjson"},
+             "incorrect argument count"},
+            {"genfakedata_keypress_no_args",
+             {"--genfakedata", "--keypress"},
+             "incorrect argument count"},
+            {"genfakedata_keypress_invalid_keyCode",
+             {"--genfakedata", "--keypress", "0.1", "1"},
+             "failed to parse keyCode as int: \"0.1\""},
+            {"genfakedata_keypress_invalid_display",
+             {"--genfakedata", "--keypress", "1", "0.1"},
+             "failed to parse display as int: \"0.1\""},
+            {"genfakedata_keyinputv2_incorrect_arguments",
+             {"--genfakedata", "--keyinputv2", "1", "1"},
+             "incorrect argument count, need 7 arguments for --genfakedata --keyinputv2\n"},
+            {"genfakedata_keyinputv2_invalid_area",
+             {"--genfakedata", "--keyinputv2", "0.1", "1", "1", "1", "1"},
+             "failed to parse area as int: \"0.1\""},
+            {"genfakedata_keyinputv2_invalid_display",
+             {"--genfakedata", "--keyinputv2", "1", "0.1", "1", "1", "1"},
+             "failed to parse display as int: \"0.1\""},
+            {"genfakedata_keyinputv2_invalid_keycode",
+             {"--genfakedata", "--keyinputv2", "1", "1", "0.1", "1", "1"},
+             "failed to parse keyCode as int: \"0.1\""},
+            {"genfakedata_keyinputv2_invalid_action",
+             {"--genfakedata", "--keyinputv2", "1", "1", "1", "0.1", "1"},
+             "failed to parse action as int: \"0.1\""},
+            {"genfakedata_keyinputv2_invalid_repeatcount",
+             {"--genfakedata", "--keyinputv2", "1", "1", "1", "1", "0.1"},
+             "failed to parse repeatCount as int: \"0.1\""},
+            {"genfakedata_motioninput_invalid_argument_count",
+             {"--genfakedata", "--motioninput", "1", "1", "1", "1", "1"},
+             "incorrect argument count, need at least 14 arguments for --genfakedata "
+             "--motioninput including at least 1 --pointer\n"},
+            {"genfakedata_motioninput_pointer_invalid_argument_count",
+             {"--genfakedata", "--motioninput", "1", "1", "1", "1", "1", "--pointer", "1", "1", "1",
+              "1", "1", "1", "--pointer"},
+             "incorrect argument count, need 6 arguments for every --pointer\n"},
+            {"genfakedata_motioninput_invalid_area",
+             {"--genfakedata", "--motioninput", "0.1", "1", "1", "1", "1", "--pointer", "1", "1",
+              "1", "1", "1", "1"},
+             "failed to parse area as int: \"0.1\""},
+            {"genfakedata_motioninput_invalid_display",
+             {"--genfakedata", "--motioninput", "1", "0.1", "1", "1", "1", "--pointer", "1", "1",
+              "1", "1", "1", "1"},
+             "failed to parse display as int: \"0.1\""},
+            {"genfakedata_motioninput_invalid_inputtype",
+             {"--genfakedata", "--motioninput", "1", "1", "0.1", "1", "1", "--pointer", "1", "1",
+              "1", "1", "1", "1"},
+             "failed to parse inputType as int: \"0.1\""},
+            {"genfakedata_motioninput_invalid_action",
+             {"--genfakedata", "--motioninput", "1", "1", "1", "0.1", "1", "--pointer", "1", "1",
+              "1", "1", "1", "1"},
+             "failed to parse action as int: \"0.1\""},
+            {"genfakedata_motioninput_invalid_buttonstate",
+             {"--genfakedata", "--motioninput", "1", "1", "1", "1", "0.1", "--pointer", "1", "1",
+              "1.2", "1.2", "1.2", "1.2"},
+             "failed to parse buttonState as int: \"0.1\""},
+            {"genfakedata_motioninput_invalid_pointerid",
+             {"--genfakedata", "--motioninput", "1", "1", "1", "1", "1", "--pointer", "0.1", "1",
+              "1.2", "1", "1", "1"},
+             "failed to parse pointerId as int: \"0.1\""},
+            {"genfakedata_motioninput_invalid_tooltype",
+             {"--genfakedata", "--motioninput", "1", "1", "1", "1", "1", "--pointer", "1", "0.1",
+              "1.2", "1", "1", "1"},
+             "failed to parse toolType as int: \"0.1\""}};
+}
+
+TEST_P(FakeVehicleHardwareOptionsTest, testInvalidOptions) {
+    auto tc = GetParam();
+
+    DumpResult result = getHardware()->dump(tc.options);
+
+    EXPECT_FALSE(result.callerShouldDumpState);
+    EXPECT_THAT(result.buffer, HasSubstr(tc.expectMsg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        FakeVehicleHardwareOptionsTests, FakeVehicleHardwareOptionsTest,
+        testing::ValuesIn(GenInvalidOptions()),
+        [](const testing::TestParamInfo<FakeVehicleHardwareOptionsTest::ParamType>& info) {
+            return info.param.name;
+        });
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataLinear) {
+    // Start a fake linear data generator for vehicle speed at 0.1s interval.
+    // range: 0 - 100, current value: 30, step: 20.
+    std::string propIdString = StringPrintf("%d", toInt(VehicleProperty::PERF_VEHICLE_SPEED));
+    std::vector<std::string> options = {"--genfakedata",         "--startlinear", propIdString,
+                                        /*middleValue=*/"50",
+                                        /*currentValue=*/"30",
+                                        /*dispersion=*/"50",
+                                        /*increment=*/"20",
+                                        /*interval=*/"100000000"};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+    ASSERT_TRUE(waitForChangedProperties(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 0, /*count=*/5,
+                                         milliseconds(1000)))
+            << "not enough events generated for linear data generator";
+
+    int32_t value = 30;
+    auto events = getChangedProperties();
+    for (size_t i = 0; i < 5; i++) {
+        ASSERT_EQ(1u, events[i].value.floatValues.size());
+        EXPECT_EQ(static_cast<float>(value), events[i].value.floatValues[0]);
+        value = (value + 20) % 100;
+    }
+
+    // Stop the linear generator.
+    options = {"--genfakedata", "--stoplinear", propIdString};
+
+    result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+    clearChangedProperties();
+    std::this_thread::sleep_for(std::chrono::milliseconds(200));
+
+    // There should be no new events generated.
+    EXPECT_EQ(0u, getEventCount(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 0));
+}
+
+std::string getTestFilePath(const char* filename) {
+    static std::string baseDir = android::base::GetExecutableDirectory();
+    return baseDir + "/fakedata/" + filename;
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJson) {
+    std::vector<std::string> options = {"--genfakedata", "--startjson", "--path",
+                                        getTestFilePath("prop.json"), "2"};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+    ASSERT_TRUE(waitForChangedProperties(/*count=*/8, milliseconds(1000)))
+            << "not enough events generated for JSON data generator";
+
+    auto events = getChangedProperties();
+    ASSERT_EQ(8u, events.size());
+    // First set of events, we test 1st and the last.
+    EXPECT_EQ(1u, events[0].value.int32Values.size());
+    EXPECT_EQ(8, events[0].value.int32Values[0]);
+    EXPECT_EQ(1u, events[3].value.int32Values.size());
+    EXPECT_EQ(10, events[3].value.int32Values[0]);
+    // Second set of the same events.
+    EXPECT_EQ(1u, events[4].value.int32Values.size());
+    EXPECT_EQ(8, events[4].value.int32Values[0]);
+    EXPECT_EQ(1u, events[7].value.int32Values.size());
+    EXPECT_EQ(10, events[7].value.int32Values[0]);
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonByContent) {
+    std::vector<std::string> options = {
+            "--genfakedata", "--startjson", "--content",
+            "[{\"timestamp\":1000000,\"areaId\":0,\"value\":8,\"prop\":289408000}]", "1"};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+    ASSERT_TRUE(waitForChangedProperties(/*count=*/1, milliseconds(1000)))
+            << "not enough events generated for JSON data generator";
+
+    auto events = getChangedProperties();
+    ASSERT_EQ(1u, events.size());
+    EXPECT_EQ(1u, events[0].value.int32Values.size());
+    EXPECT_EQ(8, events[0].value.int32Values[0]);
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonInvalidContent) {
+    std::vector<std::string> options = {"--genfakedata", "--startjson", "--content", "[{", "2"};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("invalid JSON content"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonInvalidFile) {
+    std::vector<std::string> options = {"--genfakedata", "--startjson", "--path",
+                                        getTestFilePath("blahblah.json"), "2"};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("invalid JSON file"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonStop) {
+    // No iteration number provided, would loop indefinitely.
+    std::vector<std::string> options = {"--genfakedata", "--startjson", "--path",
+                                        getTestFilePath("prop.json")};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+    std::string id = result.buffer.substr(result.buffer.find("ID: ") + 4);
+
+    result = getHardware()->dump({"--genfakedata", "--stopjson", id});
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonStopInvalidFile) {
+    // No iteration number provided, would loop indefinitely.
+    std::vector<std::string> options = {"--genfakedata", "--startjson", "--path",
+                                        getTestFilePath("prop.json")};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+    result = getHardware()->dump({"--genfakedata", "--stopjson", "1234"});
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("No JSON event generator found"));
+
+    // TearDown function should destroy the generator which stops the iteration.
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataKeyPress) {
+    std::vector<std::string> options = {"--genfakedata", "--keypress", "1", "2"};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+    auto events = getChangedProperties();
+    ASSERT_EQ(2u, events.size());
+    EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT), events[0].prop);
+    EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT), events[1].prop);
+    ASSERT_EQ(3u, events[0].value.int32Values.size());
+    ASSERT_EQ(3u, events[1].value.int32Values.size());
+    EXPECT_EQ(toInt(VehicleHwKeyInputAction::ACTION_DOWN), events[0].value.int32Values[0]);
+    EXPECT_EQ(1, events[0].value.int32Values[1]);
+    EXPECT_EQ(2, events[0].value.int32Values[2]);
+    EXPECT_EQ(toInt(VehicleHwKeyInputAction::ACTION_UP), events[1].value.int32Values[0]);
+    EXPECT_EQ(1, events[1].value.int32Values[1]);
+    EXPECT_EQ(2, events[1].value.int32Values[2]);
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataKeyInputV2) {
+    std::vector<std::string> options = {"--genfakedata", "--keyinputv2", "1", "2", "3", "4", "5"};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+    auto events = getChangedProperties();
+    ASSERT_EQ(1u, events.size());
+    EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT_V2), events[0].prop);
+    ASSERT_EQ(4u, events[0].value.int32Values.size());
+    EXPECT_EQ(2, events[0].value.int32Values[0]);
+    EXPECT_EQ(3, events[0].value.int32Values[1]);
+    EXPECT_EQ(4, events[0].value.int32Values[2]);
+    EXPECT_EQ(5, events[0].value.int32Values[3]);
+    ASSERT_EQ(1u, events[0].value.int64Values.size());
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataMotionInput) {
+    std::vector<std::string> options = {"--genfakedata",
+                                        "--motioninput",
+                                        "1",
+                                        "2",
+                                        "3",
+                                        "4",
+                                        "5",
+                                        "--pointer",
+                                        "11",
+                                        "22",
+                                        "33.3",
+                                        "44.4",
+                                        "55.5",
+                                        "66.6",
+                                        "--pointer",
+                                        "21",
+                                        "32",
+                                        "43.3",
+                                        "54.4",
+                                        "65.5",
+                                        "76.6"};
+
+    DumpResult result = getHardware()->dump(options);
+
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+    auto events = getChangedProperties();
+    ASSERT_EQ(1u, events.size());
+    EXPECT_EQ(toInt(VehicleProperty::HW_MOTION_INPUT), events[0].prop);
+    ASSERT_EQ(9u, events[0].value.int32Values.size());
+    EXPECT_EQ(2, events[0].value.int32Values[0]);
+    EXPECT_EQ(3, events[0].value.int32Values[1]);
+    EXPECT_EQ(4, events[0].value.int32Values[2]);
+    EXPECT_EQ(5, events[0].value.int32Values[3]);
+    EXPECT_EQ(2, events[0].value.int32Values[4]);
+    EXPECT_EQ(11, events[0].value.int32Values[5]);
+    EXPECT_EQ(21, events[0].value.int32Values[6]);
+    EXPECT_EQ(22, events[0].value.int32Values[7]);
+    EXPECT_EQ(32, events[0].value.int32Values[8]);
+    ASSERT_EQ(8u, events[0].value.floatValues.size());
+    EXPECT_FLOAT_EQ(33.3, events[0].value.floatValues[0]);
+    EXPECT_FLOAT_EQ(43.3, events[0].value.floatValues[1]);
+    EXPECT_FLOAT_EQ(44.4, events[0].value.floatValues[2]);
+    EXPECT_FLOAT_EQ(54.4, events[0].value.floatValues[3]);
+    EXPECT_FLOAT_EQ(55.5, events[0].value.floatValues[4]);
+    EXPECT_FLOAT_EQ(65.5, events[0].value.floatValues[5]);
+    EXPECT_FLOAT_EQ(66.6, events[0].value.floatValues[6]);
+    EXPECT_FLOAT_EQ(76.6, events[0].value.floatValues[7]);
+    ASSERT_EQ(1u, events[0].value.int64Values.size());
+}
+
 TEST_F(FakeVehicleHardwareTest, testGetEchoReverseBytes) {
     ASSERT_EQ(setValue(VehiclePropValue{
                       .prop = ECHO_REVERSE_BYTES,
@@ -1653,6 +2900,348 @@
     }
 }
 
+TEST_F(FakeVehicleHardwareTest, testSetHvacTemperatureValueSuggestion) {
+    float CELSIUS = static_cast<float>(toInt(VehicleUnit::CELSIUS));
+    float FAHRENHEIT = static_cast<float>(toInt(VehicleUnit::FAHRENHEIT));
+
+    VehiclePropValue floatArraySizeFour = {
+            .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
+            .areaId = HVAC_ALL,
+            .value.floatValues = {0, CELSIUS, 0, 0},
+    };
+    StatusCode status = setValue(floatArraySizeFour);
+    EXPECT_EQ(status, StatusCode::OK);
+
+    VehiclePropValue floatArraySizeZero = {
+            .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
+            .areaId = HVAC_ALL,
+    };
+    status = setValue(floatArraySizeZero);
+    EXPECT_EQ(status, StatusCode::INVALID_ARG);
+
+    VehiclePropValue floatArraySizeFive = {
+            .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
+            .areaId = HVAC_ALL,
+            .value.floatValues = {0, CELSIUS, 0, 0, 0},
+    };
+    status = setValue(floatArraySizeFive);
+    EXPECT_EQ(status, StatusCode::INVALID_ARG);
+
+    VehiclePropValue invalidUnit = {
+            .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
+            .areaId = HVAC_ALL,
+            .value.floatValues = {0, 0, 0, 0},
+    };
+    status = setValue(floatArraySizeFive);
+    EXPECT_EQ(status, StatusCode::INVALID_ARG);
+    clearChangedProperties();
+
+    // Config array values from HVAC_TEMPERATURE_SET in DefaultProperties.json
+    auto configs = getHardware()->getAllPropertyConfigs();
+    VehiclePropConfig* hvacTemperatureSetConfig = nullptr;
+    for (auto& config : configs) {
+        if (config.prop == toInt(VehicleProperty::HVAC_TEMPERATURE_SET)) {
+            hvacTemperatureSetConfig = &config;
+            break;
+        }
+    }
+    EXPECT_NE(hvacTemperatureSetConfig, nullptr);
+
+    auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfig->configArray;
+    // The HVAC_TEMPERATURE_SET config array values are temperature values that have been multiplied
+    // by 10 and converted to integers. HVAC_TEMPERATURE_VALUE_SUGGESTION specifies the temperature
+    // values to be in the original floating point form so we divide by 10 and convert to float.
+    float minTempInCelsius = hvacTemperatureSetConfigArray[0] / 10.0f;
+    float maxTempInCelsius = hvacTemperatureSetConfigArray[1] / 10.0f;
+    float incrementInCelsius = hvacTemperatureSetConfigArray[2] / 10.0f;
+    float minTempInFahrenheit = hvacTemperatureSetConfigArray[3] / 10.0f;
+    float maxTempInFahrenheit = hvacTemperatureSetConfigArray[4] / 10.0f;
+    float incrementInFahrenheit = hvacTemperatureSetConfigArray[5] / 10.0f;
+
+    auto testCases = {
+            SetSpecialValueTestCase{
+                    .name = "min_celsius_temperature",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInCelsius, CELSIUS, 0, 0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInCelsius, CELSIUS,
+                                                                  minTempInCelsius,
+                                                                  minTempInFahrenheit},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "min_fahrenheit_temperature",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInFahrenheit, FAHRENHEIT,
+                                                                  0, 0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInFahrenheit, FAHRENHEIT,
+                                                                  minTempInCelsius,
+                                                                  minTempInFahrenheit},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "max_celsius_temperature",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {maxTempInCelsius, CELSIUS, 0, 0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {maxTempInCelsius, CELSIUS,
+                                                                  maxTempInCelsius,
+                                                                  maxTempInFahrenheit},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "max_fahrenheit_temperature",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {maxTempInFahrenheit, FAHRENHEIT,
+                                                                  0, 0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {maxTempInFahrenheit, FAHRENHEIT,
+                                                                  maxTempInCelsius,
+                                                                  maxTempInFahrenheit},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "below_min_celsius_temperature",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInCelsius - 1, CELSIUS, 0,
+                                                                  0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInCelsius - 1, CELSIUS,
+                                                                  minTempInCelsius,
+                                                                  minTempInFahrenheit},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "below_min_fahrenheit_temperature",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInFahrenheit - 1,
+                                                                  FAHRENHEIT, 0, 0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInFahrenheit - 1,
+                                                                  FAHRENHEIT, minTempInCelsius,
+                                                                  minTempInFahrenheit},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "above_max_celsius_temperature",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {maxTempInCelsius + 1, CELSIUS, 0,
+                                                                  0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {maxTempInCelsius + 1, CELSIUS,
+                                                                  maxTempInCelsius,
+                                                                  maxTempInFahrenheit},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "above_max_fahrenheit_temperature",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {maxTempInFahrenheit + 1,
+                                                                  FAHRENHEIT, 0, 0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {maxTempInFahrenheit + 1,
+                                                                  FAHRENHEIT, maxTempInCelsius,
+                                                                  maxTempInFahrenheit},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "inbetween_value_celsius",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInCelsius +
+                                                                          incrementInCelsius * 2.5f,
+                                                                  CELSIUS, 0, 0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues =
+                                                    {minTempInCelsius + incrementInCelsius * 2.5f,
+                                                     CELSIUS,
+                                                     minTempInCelsius + incrementInCelsius * 2,
+                                                     minTempInFahrenheit +
+                                                             incrementInFahrenheit * 2},
+                                    },
+                            },
+            },
+            SetSpecialValueTestCase{
+                    .name = "inbetween_value_fahrenheit",
+                    .valuesToSet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues = {minTempInFahrenheit +
+                                                                          incrementInFahrenheit *
+                                                                                  2.5f,
+                                                                  FAHRENHEIT, 0, 0},
+                                    },
+                            },
+                    .expectedValuesToGet =
+                            {
+                                    VehiclePropValue{
+                                            .prop = toInt(
+                                                    VehicleProperty::
+                                                            HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                                            .areaId = HVAC_ALL,
+                                            .value.floatValues =
+                                                    {minTempInFahrenheit +
+                                                             incrementInFahrenheit * 2.5f,
+                                                     FAHRENHEIT,
+                                                     minTempInCelsius + incrementInCelsius * 2,
+                                                     minTempInFahrenheit +
+                                                             incrementInFahrenheit * 2},
+                                    },
+                            },
+            },
+    };
+
+    for (auto& tc : testCases) {
+        StatusCode status = setValue(tc.valuesToSet[0]);
+        EXPECT_EQ(status, StatusCode::OK);
+
+        auto events = getChangedProperties();
+        EXPECT_EQ(events.size(), static_cast<size_t>(1));
+        events[0].timestamp = 0;
+
+        EXPECT_EQ(events[0], tc.expectedValuesToGet[0]);
+        clearChangedProperties();
+    }
+}
+
 }  // namespace fake
 }  // namespace vehicle
 }  // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
new file mode 100644
index 0000000..7123a00
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
@@ -0,0 +1,26 @@
+[
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": 8,
+        "prop": 289408000
+    },
+    {
+        "timestamp": 2000000,
+        "areaId": 0,
+        "value": 4,
+        "prop": 289408000
+    },
+    {
+        "timestamp": 3000000,
+        "areaId": 0,
+        "value": 16,
+        "prop": 289408000
+    },
+    {
+        "timestamp": 4000000,
+        "areaId": 0,
+        "value": 10,
+        "prop": 289408000
+    }
+]
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json
index 59666b8..693f1e2 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json
@@ -1,9 +1,13 @@
-[
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": 8,
-    // GEAR_SELECTION
-    "prop": 289408000
-  }
-]
+{
+    "apiVersion": 1,
+    "properties": [
+        {
+            "property": "VehicleProperty::GEAR_SELECTION",
+            "defaultValue": {
+                "int32Values": [
+                    8
+                ]
+            }
+        }
+    ]
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json
index 93a97ed..07cfebb 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json
@@ -1,10 +1,20 @@
-[
-  {
-    "timestamp": 1000000,
-    // HVAC_LEFT
-    "areaId": 49,
-    "value": 30,
-    // HVAC_TEMPERATURE_SET
-    "prop": 358614275
-  }
-]
+{
+    "apiVersion": 1,
+    "properties": [
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_SET",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            30.0
+                        ]
+                    },
+                    "areaId": 49,
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 32.0
+                }
+            ]
+        }
+    ]
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h b/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h
index 4ae9c8c..fcbe8fd 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h
@@ -64,7 +64,7 @@
     std::string showDumpHelp() const;
 
     // Dump its contents.
-    std::string dump(std::string indent) const;
+    std::string dump() const;
 
   private:
     const std::shared_ptr<VehiclePropValuePool> mValuePool;
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp b/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp
index 7748fb6..878c2e7 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp
@@ -328,6 +328,9 @@
                    << "invalid action on lshal response: " << response->toString();
     }
 
+    // Update area ID to 0 since this is a global property (and the area ID was only set to emulate
+    // the request id behavior).
+    response->areaId = 0;
     ALOGD("updating property to: %s", response->toString().c_str());
     return response;
 }
@@ -336,33 +339,31 @@
     return fmt::format("{}: dumps state used for user management\n", kUserHalDumpOption);
 }
 
-std::string FakeUserHal::dump(std::string indent) const {
+std::string FakeUserHal::dump() const {
     std::scoped_lock<std::mutex> lockGuard(mLock);
 
     std::string info;
     if (mInitialUserResponseFromCmd != nullptr) {
-        info += fmt::format("{}InitialUserInfo response: {}\n", indent,
+        info += fmt::format("InitialUserInfo response: {}\n",
                             mInitialUserResponseFromCmd->toString());
     } else {
-        info += fmt::format("{}No InitialUserInfo response\n", indent);
+        info += "No InitialUserInfo response\n";
     }
     if (mSwitchUserResponseFromCmd != nullptr) {
-        info += fmt::format("{}SwitchUser response: {}\n", indent,
-                            mSwitchUserResponseFromCmd->toString());
+        info += fmt::format("SwitchUser response: {}\n", mSwitchUserResponseFromCmd->toString());
     } else {
-        info += fmt::format("{}No SwitchUser response\n", indent);
+        info += "No SwitchUser response\n";
     }
     if (mCreateUserResponseFromCmd != nullptr) {
-        info += fmt::format("{}CreateUser response: {}\n", indent,
-                            mCreateUserResponseFromCmd->toString());
+        info += fmt::format("CreateUser response: {}\n", mCreateUserResponseFromCmd->toString());
     } else {
-        info += fmt::format("{}No CreateUser response\n", indent);
+        info += "No CreateUser response\n";
     }
     if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
-        info += fmt::format("{}SetUserIdentificationAssociation response: {}\n", indent,
+        info += fmt::format("SetUserIdentificationAssociation response: {}\n",
                             mSetUserIdentificationAssociationResponseFromCmd->toString());
     } else {
-        info += fmt::format("{}No SetUserIdentificationAssociation response\n", indent);
+        info += "No SetUserIdentificationAssociation response\n";
     }
     return info;
 }
diff --git a/automotive/vehicle/aidl/impl/grpc/Android.bp b/automotive/vehicle/aidl/impl/grpc/Android.bp
new file mode 100644
index 0000000..06c9600
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/Android.bp
@@ -0,0 +1,126 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+genrule {
+    name: "VehicleServerProtoStub_h@default-grpc",
+    tools: [
+        "aprotoc",
+        "protoc-gen-grpc-cpp-plugin",
+    ],
+    cmd: "$(location aprotoc) -I$$(dirname $(in)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    srcs: [
+        "proto/VehicleServer.proto",
+    ],
+    out: [
+        "VehicleServer.pb.h",
+        "VehicleServer.grpc.pb.h",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+genrule {
+    name: "VehicleServerProtoStub_cc@default-grpc",
+    tools: [
+        "aprotoc",
+        "protoc-gen-grpc-cpp-plugin",
+    ],
+    cmd: "$(location aprotoc) -I$$(dirname $(in)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    srcs: [
+        "proto/VehicleServer.proto",
+    ],
+    out: [
+        "VehicleServer.pb.cc",
+        "VehicleServer.grpc.pb.cc",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+cc_library_static {
+    name: "android.hardware.automotive.vehicle@default-grpc-libgrpc",
+    vendor: true,
+    host_supported: true,
+    include_dirs: [
+        "external/protobuf/src",
+    ],
+    generated_headers: [
+        "VehicleServerProtoStub_h@default-grpc",
+    ],
+    export_generated_headers: [
+        "VehicleServerProtoStub_h@default-grpc",
+    ],
+    generated_sources: [
+        "VehicleServerProtoStub_cc@default-grpc",
+    ],
+    whole_static_libs: [
+        "VehicleHalProtos",
+    ],
+    shared_libs: [
+        "libgrpc++",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
+
+cc_library_static {
+    name: "android.hardware.automotive.vehicle@default-grpc-hardware-lib",
+    defaults: ["VehicleHalDefaults"],
+    vendor: true,
+    srcs: [
+        "GRPCVehicleHardware.cpp",
+    ],
+    whole_static_libs: [
+        "android.hardware.automotive.vehicle@default-grpc-libgrpc",
+        "VehicleHalProtoMessageConverter",
+    ],
+    header_libs: [
+        "IVehicleHardware",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    export_include_dirs: ["."],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
+
+cc_library_static {
+    name: "android.hardware.automotive.vehicle@default-grpc-server-lib",
+    defaults: ["VehicleHalDefaults"],
+    vendor: true,
+    srcs: [
+        "GRPCVehicleProxyServer.cpp",
+    ],
+    whole_static_libs: [
+        "android.hardware.automotive.vehicle@default-grpc-libgrpc",
+        "VehicleHalProtoMessageConverter",
+    ],
+    header_libs: [
+        "IVehicleHardware",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    export_include_dirs: ["."],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+}
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
new file mode 100644
index 0000000..0742283
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <GRPCVehicleHardware.h>
+
+#include "ProtoMessageConverter.h"
+
+#include <android-base/logging.h>
+#include <grpc++/grpc++.h>
+
+#include <cstdlib>
+#include <mutex>
+#include <shared_mutex>
+#include <utility>
+
+namespace android::hardware::automotive::vehicle::virtualization {
+
+static std::shared_ptr<::grpc::ChannelCredentials> getChannelCredentials() {
+    // TODO(chenhaosjtuacm): get secured credentials here
+    return ::grpc::InsecureChannelCredentials();
+}
+
+GRPCVehicleHardware::GRPCVehicleHardware(std::string service_addr)
+    : mServiceAddr(std::move(service_addr)),
+      mGrpcChannel(::grpc::CreateChannel(mServiceAddr, getChannelCredentials())),
+      mGrpcStub(proto::VehicleServer::NewStub(mGrpcChannel)),
+      mValuePollingThread([this] { ValuePollingLoop(); }) {}
+
+GRPCVehicleHardware::~GRPCVehicleHardware() {
+    {
+        std::lock_guard lck(mShutdownMutex);
+        mShuttingDownFlag.store(true);
+    }
+    mShutdownCV.notify_all();
+    mValuePollingThread.join();
+}
+
+std::vector<aidlvhal::VehiclePropConfig> GRPCVehicleHardware::getAllPropertyConfigs() const {
+    std::vector<aidlvhal::VehiclePropConfig> configs;
+    ::grpc::ClientContext context;
+    auto config_stream = mGrpcStub->GetAllPropertyConfig(&context, ::google::protobuf::Empty());
+    proto::VehiclePropConfig protoConfig;
+    while (config_stream->Read(&protoConfig)) {
+        aidlvhal::VehiclePropConfig config;
+        proto_msg_converter::protoToAidl(protoConfig, &config);
+        configs.push_back(std::move(config));
+    }
+    auto grpc_status = config_stream->Finish();
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__
+                   << ": GRPC GetAllPropertyConfig Failed: " << grpc_status.error_message();
+    }
+    return configs;
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::setValues(
+        std::shared_ptr<const SetValuesCallback> callback,
+        const std::vector<aidlvhal::SetValueRequest>& requests) {
+    ::grpc::ClientContext context;
+    proto::VehiclePropValueRequests protoRequests;
+    proto::SetValueResults protoResults;
+    for (const auto& request : requests) {
+        auto& protoRequest = *protoRequests.add_requests();
+        protoRequest.set_request_id(request.requestId);
+        proto_msg_converter::aidlToProto(request.value, protoRequest.mutable_value());
+    }
+    // TODO(chenhaosjtuacm): Make it Async.
+    auto grpc_status = mGrpcStub->SetValues(&context, protoRequests, &protoResults);
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__ << ": GRPC SetValues Failed: " << grpc_status.error_message();
+        {
+            std::shared_lock lck(mCallbackMutex);
+            // TODO(chenhaosjtuacm): call on-set-error callback.
+        }
+        return aidlvhal::StatusCode::INTERNAL_ERROR;
+    }
+    std::vector<aidlvhal::SetValueResult> results;
+    for (const auto& protoResult : protoResults.results()) {
+        auto& result = results.emplace_back();
+        result.requestId = protoResult.request_id();
+        result.status = static_cast<aidlvhal::StatusCode>(protoResult.status());
+        // TODO(chenhaosjtuacm): call on-set-error callback.
+    }
+    (*callback)(std::move(results));
+
+    return aidlvhal::StatusCode::OK;
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::getValues(
+        std::shared_ptr<const GetValuesCallback> callback,
+        const std::vector<aidlvhal::GetValueRequest>& requests) const {
+    ::grpc::ClientContext context;
+    proto::VehiclePropValueRequests protoRequests;
+    proto::GetValueResults protoResults;
+    for (const auto& request : requests) {
+        auto& protoRequest = *protoRequests.add_requests();
+        protoRequest.set_request_id(request.requestId);
+        proto_msg_converter::aidlToProto(request.prop, protoRequest.mutable_value());
+    }
+    // TODO(chenhaosjtuacm): Make it Async.
+    auto grpc_status = mGrpcStub->GetValues(&context, protoRequests, &protoResults);
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__ << ": GRPC GetValues Failed: " << grpc_status.error_message();
+        return aidlvhal::StatusCode::INTERNAL_ERROR;
+    }
+    std::vector<aidlvhal::GetValueResult> results;
+    for (const auto& protoResult : protoResults.results()) {
+        auto& result = results.emplace_back();
+        result.requestId = protoResult.request_id();
+        result.status = static_cast<aidlvhal::StatusCode>(protoResult.status());
+        if (protoResult.has_value()) {
+            aidlvhal::VehiclePropValue value;
+            proto_msg_converter::protoToAidl(protoResult.value(), &value);
+            result.prop = std::move(value);
+        }
+    }
+    (*callback)(std::move(results));
+
+    return aidlvhal::StatusCode::OK;
+}
+
+void GRPCVehicleHardware::registerOnPropertyChangeEvent(
+        std::unique_ptr<const PropertyChangeCallback> callback) {
+    std::lock_guard lck(mCallbackMutex);
+    if (mOnPropChange) {
+        LOG(ERROR) << __func__ << " must only be called once.";
+        return;
+    }
+    mOnPropChange = std::move(callback);
+}
+
+void GRPCVehicleHardware::registerOnPropertySetErrorEvent(
+        std::unique_ptr<const PropertySetErrorCallback> callback) {
+    std::lock_guard lck(mCallbackMutex);
+    if (mOnSetErr) {
+        LOG(ERROR) << __func__ << " must only be called once.";
+        return;
+    }
+    mOnSetErr = std::move(callback);
+}
+
+DumpResult GRPCVehicleHardware::dump(const std::vector<std::string>& options) {
+    ::grpc::ClientContext context;
+    proto::DumpOptions protoDumpOptions;
+    proto::DumpResult protoDumpResult;
+    for (const auto& option : options) {
+        protoDumpOptions.add_options(option);
+    }
+    auto grpc_status = mGrpcStub->Dump(&context, protoDumpOptions, &protoDumpResult);
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__ << ": GRPC Dump Failed: " << grpc_status.error_message();
+        return {};
+    }
+    return {
+            .callerShouldDumpState = protoDumpResult.caller_should_dump_state(),
+            .buffer = protoDumpResult.buffer(),
+    };
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::checkHealth() {
+    ::grpc::ClientContext context;
+    proto::VehicleHalCallStatus protoStatus;
+    auto grpc_status = mGrpcStub->CheckHealth(&context, ::google::protobuf::Empty(), &protoStatus);
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__ << ": GRPC CheckHealth Failed: " << grpc_status.error_message();
+        return aidlvhal::StatusCode::INTERNAL_ERROR;
+    }
+    return static_cast<aidlvhal::StatusCode>(protoStatus.status_code());
+}
+
+aidlvhal::StatusCode GRPCVehicleHardware::updateSampleRate(int32_t propId, int32_t areaId,
+                                                           float sampleRate) {
+    ::grpc::ClientContext context;
+    proto::UpdateSampleRateRequest request;
+    proto::VehicleHalCallStatus protoStatus;
+    request.set_prop(propId);
+    request.set_area_id(areaId);
+    request.set_sample_rate(sampleRate);
+    auto grpc_status = mGrpcStub->UpdateSampleRate(&context, request, &protoStatus);
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__ << ": GRPC UpdateSampleRate Failed: " << grpc_status.error_message();
+        return aidlvhal::StatusCode::INTERNAL_ERROR;
+    }
+    return static_cast<aidlvhal::StatusCode>(protoStatus.status_code());
+}
+
+bool GRPCVehicleHardware::waitForConnected(std::chrono::milliseconds waitTime) {
+    return mGrpcChannel->WaitForConnected(gpr_time_add(
+            gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_millis(waitTime.count(), GPR_TIMESPAN)));
+}
+
+void GRPCVehicleHardware::ValuePollingLoop() {
+    while (!mShuttingDownFlag.load()) {
+        ::grpc::ClientContext context;
+
+        bool rpc_stopped{false};
+        std::thread shuttingdown_watcher([this, &rpc_stopped, &context]() {
+            std::unique_lock<std::mutex> lck(mShutdownMutex);
+            mShutdownCV.wait(lck, [this, &rpc_stopped]() {
+                return rpc_stopped || mShuttingDownFlag.load();
+            });
+            context.TryCancel();
+        });
+
+        auto value_stream =
+                mGrpcStub->StartPropertyValuesStream(&context, ::google::protobuf::Empty());
+        LOG(INFO) << __func__ << ": GRPC Value Streaming Started";
+        proto::VehiclePropValues protoValues;
+        while (!mShuttingDownFlag.load() && value_stream->Read(&protoValues)) {
+            std::vector<aidlvhal::VehiclePropValue> values;
+            for (const auto protoValue : protoValues.values()) {
+                values.push_back(aidlvhal::VehiclePropValue());
+                proto_msg_converter::protoToAidl(protoValue, &values.back());
+            }
+            std::shared_lock lck(mCallbackMutex);
+            if (mOnPropChange) {
+                (*mOnPropChange)(values);
+            }
+        }
+
+        {
+            std::lock_guard lck(mShutdownMutex);
+            rpc_stopped = true;
+        }
+        mShutdownCV.notify_all();
+        shuttingdown_watcher.join();
+
+        auto grpc_status = value_stream->Finish();
+        // never reach here until connection lost
+        LOG(ERROR) << __func__ << ": GRPC Value Streaming Failed: " << grpc_status.error_message();
+
+        // try to reconnect
+    }
+}
+
+}  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
new file mode 100644
index 0000000..90588aa
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <IVehicleHardware.h>
+#include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
+#include <android-base/result.h>
+
+#include "VehicleServer.grpc.pb.h"
+#include "VehicleServer.pb.h"
+
+#include <atomic>
+#include <chrono>
+#include <condition_variable>
+#include <memory>
+#include <shared_mutex>
+#include <string>
+#include <thread>
+#include <vector>
+
+namespace android::hardware::automotive::vehicle::virtualization {
+
+namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
+
+class GRPCVehicleHardware : public IVehicleHardware {
+  public:
+    explicit GRPCVehicleHardware(std::string service_addr);
+
+    ~GRPCVehicleHardware();
+
+    // Get all the property configs.
+    std::vector<aidlvhal::VehiclePropConfig> getAllPropertyConfigs() const override;
+
+    // Set property values asynchronously. Server could return before the property set requests
+    // are sent to vehicle bus or before property set confirmation is received. The callback is
+    // safe to be called after the function returns and is safe to be called in a different thread.
+    aidlvhal::StatusCode setValues(std::shared_ptr<const SetValuesCallback> callback,
+                                   const std::vector<aidlvhal::SetValueRequest>& requests) override;
+
+    // Get property values asynchronously. Server could return before the property values are ready.
+    // The callback is safe to be called after the function returns and is safe to be called in a
+    // different thread.
+    aidlvhal::StatusCode getValues(
+            std::shared_ptr<const GetValuesCallback> callback,
+            const std::vector<aidlvhal::GetValueRequest>& requests) const override;
+
+    // Dump debug information in the server.
+    DumpResult dump(const std::vector<std::string>& options) override;
+
+    // Check whether the system is healthy, return {@code StatusCode::OK} for healthy.
+    aidlvhal::StatusCode checkHealth() override;
+
+    // Register a callback that would be called when there is a property change event from vehicle.
+    void registerOnPropertyChangeEvent(
+            std::unique_ptr<const PropertyChangeCallback> callback) override;
+
+    // Register a callback that would be called when there is a property set error event from
+    // vehicle.
+    void registerOnPropertySetErrorEvent(
+            std::unique_ptr<const PropertySetErrorCallback> callback) override;
+
+    // Update the sample rate for the [propId, areaId] pair.
+    aidlvhal::StatusCode updateSampleRate(int32_t propId, int32_t areaId,
+                                          float sampleRate) override;
+
+    bool waitForConnected(std::chrono::milliseconds waitTime);
+
+  private:
+    void ValuePollingLoop();
+
+    std::string mServiceAddr;
+    std::shared_ptr<::grpc::Channel> mGrpcChannel;
+    std::unique_ptr<proto::VehicleServer::Stub> mGrpcStub;
+    std::thread mValuePollingThread;
+
+    std::shared_mutex mCallbackMutex;
+    std::unique_ptr<const PropertyChangeCallback> mOnPropChange;
+    std::unique_ptr<const PropertySetErrorCallback> mOnSetErr;
+
+    std::mutex mShutdownMutex;
+    std::condition_variable mShutdownCV;
+    std::atomic<bool> mShuttingDownFlag{false};
+};
+
+}  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
new file mode 100644
index 0000000..af3dd59
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GRPCVehicleProxyServer.h"
+
+#include "ProtoMessageConverter.h"
+
+#include <grpc++/grpc++.h>
+
+#include <android-base/logging.h>
+
+#include <algorithm>
+#include <condition_variable>
+#include <mutex>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+namespace android::hardware::automotive::vehicle::virtualization {
+
+std::atomic<uint64_t> GrpcVehicleProxyServer::ConnectionDescriptor::connection_id_counter_{0};
+
+static std::shared_ptr<::grpc::ServerCredentials> getServerCredentials() {
+    // TODO(chenhaosjtuacm): get secured credentials here
+    return ::grpc::InsecureServerCredentials();
+}
+
+GrpcVehicleProxyServer::GrpcVehicleProxyServer(std::string serverAddr,
+                                               std::unique_ptr<IVehicleHardware>&& hardware)
+    : mServiceAddr(std::move(serverAddr)), mHardware(std::move(hardware)) {
+    mHardware->registerOnPropertyChangeEvent(
+            std::make_unique<const IVehicleHardware::PropertyChangeCallback>(
+                    [this](std::vector<aidlvhal::VehiclePropValue> values) {
+                        OnVehiclePropChange(values);
+                    }));
+}
+
+::grpc::Status GrpcVehicleProxyServer::GetAllPropertyConfig(
+        ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
+        ::grpc::ServerWriter<proto::VehiclePropConfig>* stream) {
+    for (const auto& config : mHardware->getAllPropertyConfigs()) {
+        proto::VehiclePropConfig protoConfig;
+        proto_msg_converter::aidlToProto(config, &protoConfig);
+        if (!stream->Write(protoConfig)) {
+            return ::grpc::Status(::grpc::StatusCode::ABORTED, "Connection lost.");
+        }
+    }
+    return ::grpc::Status::OK;
+}
+
+::grpc::Status GrpcVehicleProxyServer::SetValues(::grpc::ServerContext* context,
+                                                 const proto::VehiclePropValueRequests* requests,
+                                                 proto::SetValueResults* results) {
+    std::vector<aidlvhal::SetValueRequest> aidlRequests;
+    for (const auto& protoRequest : requests->requests()) {
+        auto& aidlRequest = aidlRequests.emplace_back();
+        aidlRequest.requestId = protoRequest.request_id();
+        proto_msg_converter::protoToAidl(protoRequest.value(), &aidlRequest.value);
+    }
+    auto waitMtx = std::make_shared<std::mutex>();
+    auto waitCV = std::make_shared<std::condition_variable>();
+    auto complete = std::make_shared<bool>(false);
+    auto tmpResults = std::make_shared<proto::SetValueResults>();
+    auto aidlStatus = mHardware->setValues(
+            std::make_shared<const IVehicleHardware::SetValuesCallback>(
+                    [waitMtx, waitCV, complete,
+                     tmpResults](std::vector<aidlvhal::SetValueResult> setValueResults) {
+                        for (const auto& aidlResult : setValueResults) {
+                            auto& protoResult = *tmpResults->add_results();
+                            protoResult.set_request_id(aidlResult.requestId);
+                            protoResult.set_status(
+                                    static_cast<proto::StatusCode>(aidlResult.status));
+                        }
+                        {
+                            std::lock_guard lck(*waitMtx);
+                            *complete = true;
+                        }
+                        waitCV->notify_all();
+                    }),
+            aidlRequests);
+    if (aidlStatus != aidlvhal::StatusCode::OK) {
+        return ::grpc::Status(::grpc::StatusCode::INTERNAL,
+                              "The underlying hardware fails to set values, VHAL status: " +
+                                      toString(aidlStatus));
+    }
+    std::unique_lock lck(*waitMtx);
+    bool success = waitCV->wait_for(lck, kHardwareOpTimeout, [complete] { return *complete; });
+    if (!success) {
+        return ::grpc::Status(::grpc::StatusCode::INTERNAL,
+                              "The underlying hardware set values timeout.");
+    }
+    *results = std::move(*tmpResults);
+    return ::grpc::Status::OK;
+}
+
+::grpc::Status GrpcVehicleProxyServer::GetValues(::grpc::ServerContext* context,
+                                                 const proto::VehiclePropValueRequests* requests,
+                                                 proto::GetValueResults* results) {
+    std::vector<aidlvhal::GetValueRequest> aidlRequests;
+    for (const auto& protoRequest : requests->requests()) {
+        auto& aidlRequest = aidlRequests.emplace_back();
+        aidlRequest.requestId = protoRequest.request_id();
+        proto_msg_converter::protoToAidl(protoRequest.value(), &aidlRequest.prop);
+    }
+    auto waitMtx = std::make_shared<std::mutex>();
+    auto waitCV = std::make_shared<std::condition_variable>();
+    auto complete = std::make_shared<bool>(false);
+    auto tmpResults = std::make_shared<proto::GetValueResults>();
+    auto aidlStatus = mHardware->getValues(
+            std::make_shared<const IVehicleHardware::GetValuesCallback>(
+                    [waitMtx, waitCV, complete,
+                     tmpResults](std::vector<aidlvhal::GetValueResult> getValueResults) {
+                        for (const auto& aidlResult : getValueResults) {
+                            auto& protoResult = *tmpResults->add_results();
+                            protoResult.set_request_id(aidlResult.requestId);
+                            protoResult.set_status(
+                                    static_cast<proto::StatusCode>(aidlResult.status));
+                            if (aidlResult.prop) {
+                                auto* valuePtr = protoResult.mutable_value();
+                                proto_msg_converter::aidlToProto(*aidlResult.prop, valuePtr);
+                            }
+                        }
+                        {
+                            std::lock_guard lck(*waitMtx);
+                            *complete = true;
+                        }
+                        waitCV->notify_all();
+                    }),
+            aidlRequests);
+    if (aidlStatus != aidlvhal::StatusCode::OK) {
+        return ::grpc::Status(::grpc::StatusCode::INTERNAL,
+                              "The underlying hardware fails to get values, VHAL status: " +
+                                      toString(aidlStatus));
+    }
+    std::unique_lock lck(*waitMtx);
+    bool success = waitCV->wait_for(lck, kHardwareOpTimeout, [complete] { return *complete; });
+    if (!success) {
+        return ::grpc::Status(::grpc::StatusCode::INTERNAL,
+                              "The underlying hardware get values timeout.");
+    }
+    *results = std::move(*tmpResults);
+    return ::grpc::Status::OK;
+}
+
+::grpc::Status GrpcVehicleProxyServer::UpdateSampleRate(
+        ::grpc::ServerContext* context, const proto::UpdateSampleRateRequest* request,
+        proto::VehicleHalCallStatus* status) {
+    const auto status_code = mHardware->updateSampleRate(request->prop(), request->area_id(),
+                                                         request->sample_rate());
+    status->set_status_code(static_cast<proto::StatusCode>(status_code));
+    return ::grpc::Status::OK;
+}
+
+::grpc::Status GrpcVehicleProxyServer::CheckHealth(::grpc::ServerContext* context,
+                                                   const ::google::protobuf::Empty*,
+                                                   proto::VehicleHalCallStatus* status) {
+    status->set_status_code(static_cast<proto::StatusCode>(mHardware->checkHealth()));
+    return ::grpc::Status::OK;
+}
+
+::grpc::Status GrpcVehicleProxyServer::Dump(::grpc::ServerContext* context,
+                                            const proto::DumpOptions* options,
+                                            proto::DumpResult* result) {
+    std::vector<std::string> dumpOptionStrings(options->options().begin(),
+                                               options->options().end());
+    auto dumpResult = mHardware->dump(dumpOptionStrings);
+    result->set_caller_should_dump_state(dumpResult.callerShouldDumpState);
+    result->set_buffer(dumpResult.buffer);
+    return ::grpc::Status::OK;
+}
+
+::grpc::Status GrpcVehicleProxyServer::StartPropertyValuesStream(
+        ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
+        ::grpc::ServerWriter<proto::VehiclePropValues>* stream) {
+    auto conn = std::make_shared<ConnectionDescriptor>(stream);
+    {
+        std::lock_guard lck(mConnectionMutex);
+        mValueStreamingConnections.push_back(conn);
+    }
+    conn->Wait();
+    LOG(ERROR) << __func__ << ": Stream lost, ID : " << conn->ID();
+    return ::grpc::Status(::grpc::StatusCode::ABORTED, "Connection lost.");
+}
+
+void GrpcVehicleProxyServer::OnVehiclePropChange(
+        const std::vector<aidlvhal::VehiclePropValue>& values) {
+    std::unordered_set<uint64_t> brokenConn;
+    proto::VehiclePropValues protoValues;
+    for (const auto& value : values) {
+        auto* protoValuePtr = protoValues.add_values();
+        proto_msg_converter::aidlToProto(value, protoValuePtr);
+    }
+    {
+        std::shared_lock read_lock(mConnectionMutex);
+        for (auto& connection : mValueStreamingConnections) {
+            auto writeOK = connection->Write(protoValues);
+            if (!writeOK) {
+                LOG(ERROR) << __func__
+                           << ": Server Write failed, connection lost. ID: " << connection->ID();
+                brokenConn.insert(connection->ID());
+            }
+        }
+    }
+    if (brokenConn.empty()) {
+        return;
+    }
+    std::unique_lock write_lock(mConnectionMutex);
+    mValueStreamingConnections.erase(
+            std::remove_if(mValueStreamingConnections.begin(), mValueStreamingConnections.end(),
+                           [&brokenConn](const auto& conn) {
+                               return brokenConn.find(conn->ID()) != brokenConn.end();
+                           }),
+            mValueStreamingConnections.end());
+}
+
+GrpcVehicleProxyServer& GrpcVehicleProxyServer::Start() {
+    if (mServer) {
+        LOG(WARNING) << __func__ << ": GrpcVehicleProxyServer has already started.";
+        return *this;
+    }
+    ::grpc::ServerBuilder builder;
+    builder.RegisterService(this);
+    builder.AddListeningPort(mServiceAddr, getServerCredentials());
+    mServer = builder.BuildAndStart();
+    CHECK(mServer) << __func__ << ": failed to create the GRPC server, "
+                   << "please make sure the configuration and permissions are correct";
+    return *this;
+}
+
+GrpcVehicleProxyServer& GrpcVehicleProxyServer::Shutdown() {
+    std::shared_lock read_lock(mConnectionMutex);
+    for (auto& conn : mValueStreamingConnections) {
+        conn->Shutdown();
+    }
+    if (mServer) {
+        mServer->Shutdown();
+    }
+    return *this;
+}
+
+void GrpcVehicleProxyServer::Wait() {
+    if (mServer) {
+        mServer->Wait();
+    }
+    mServer.reset();
+}
+
+GrpcVehicleProxyServer::ConnectionDescriptor::~ConnectionDescriptor() {
+    Shutdown();
+}
+
+bool GrpcVehicleProxyServer::ConnectionDescriptor::Write(const proto::VehiclePropValues& values) {
+    if (!mStream) {
+        LOG(ERROR) << __func__ << ": Empty stream. ID: " << ID();
+        Shutdown();
+        return false;
+    }
+    {
+        std::lock_guard lck(*mMtx);
+        if (!mShutdownFlag && mStream->Write(values)) {
+            return true;
+        } else {
+            LOG(ERROR) << __func__ << ": Server Write failed, connection lost. ID: " << ID();
+        }
+    }
+    Shutdown();
+    return false;
+}
+
+void GrpcVehicleProxyServer::ConnectionDescriptor::Wait() {
+    std::unique_lock lck(*mMtx);
+    mCV->wait(lck, [this] { return mShutdownFlag; });
+}
+
+void GrpcVehicleProxyServer::ConnectionDescriptor::Shutdown() {
+    {
+        std::lock_guard lck(*mMtx);
+        mShutdownFlag = true;
+    }
+    mCV->notify_all();
+}
+
+}  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h
new file mode 100644
index 0000000..3596354
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "IVehicleHardware.h"
+
+#include "VehicleServer.grpc.pb.h"
+#include "VehicleServer.pb.h"
+
+#include <grpc++/grpc++.h>
+
+#include <atomic>
+#include <chrono>
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <shared_mutex>
+#include <string>
+#include <utility>
+
+namespace android::hardware::automotive::vehicle::virtualization {
+
+namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
+
+// Connect other GRPC vehicle hardware(s) to the underlying vehicle hardware.
+class GrpcVehicleProxyServer : public proto::VehicleServer::Service {
+  public:
+    GrpcVehicleProxyServer(std::string serverAddr, std::unique_ptr<IVehicleHardware>&& hardware);
+
+    ::grpc::Status GetAllPropertyConfig(
+            ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
+            ::grpc::ServerWriter<proto::VehiclePropConfig>* stream) override;
+
+    ::grpc::Status SetValues(::grpc::ServerContext* context,
+                             const proto::VehiclePropValueRequests* requests,
+                             proto::SetValueResults* results) override;
+
+    ::grpc::Status GetValues(::grpc::ServerContext* context,
+                             const proto::VehiclePropValueRequests* requests,
+                             proto::GetValueResults* results) override;
+
+    ::grpc::Status UpdateSampleRate(::grpc::ServerContext* context,
+                                    const proto::UpdateSampleRateRequest* request,
+                                    proto::VehicleHalCallStatus* status) override;
+
+    ::grpc::Status CheckHealth(::grpc::ServerContext* context, const ::google::protobuf::Empty*,
+                               proto::VehicleHalCallStatus* status) override;
+
+    ::grpc::Status Dump(::grpc::ServerContext* context, const proto::DumpOptions* options,
+                        proto::DumpResult* result) override;
+
+    ::grpc::Status StartPropertyValuesStream(
+            ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
+            ::grpc::ServerWriter<proto::VehiclePropValues>* stream) override;
+
+    GrpcVehicleProxyServer& Start();
+
+    GrpcVehicleProxyServer& Shutdown();
+
+    void Wait();
+
+  private:
+    void OnVehiclePropChange(const std::vector<aidlvhal::VehiclePropValue>& values);
+
+    // We keep long-lasting connection for streaming the prop values.
+    struct ConnectionDescriptor {
+        explicit ConnectionDescriptor(::grpc::ServerWriter<proto::VehiclePropValues>* stream)
+            : mStream(stream),
+              mConnectionID(connection_id_counter_.fetch_add(1) + 1),
+              mMtx(std::make_unique<std::mutex>()),
+              mCV(std::make_unique<std::condition_variable>()) {}
+
+        ConnectionDescriptor(const ConnectionDescriptor&) = delete;
+        ConnectionDescriptor(ConnectionDescriptor&& cd) = default;
+        ConnectionDescriptor& operator=(const ConnectionDescriptor&) = delete;
+        ConnectionDescriptor& operator=(ConnectionDescriptor&& cd) = default;
+
+        ~ConnectionDescriptor();
+
+        uint64_t ID() const { return mConnectionID; }
+
+        bool Write(const proto::VehiclePropValues& values);
+
+        void Wait();
+
+        void Shutdown();
+
+      private:
+        ::grpc::ServerWriter<proto::VehiclePropValues>* mStream;
+        uint64_t mConnectionID{0};
+        std::unique_ptr<std::mutex> mMtx;
+        std::unique_ptr<std::condition_variable> mCV;
+        bool mShutdownFlag{false};
+
+        static std::atomic<uint64_t> connection_id_counter_;
+    };
+
+    std::string mServiceAddr;
+    std::unique_ptr<::grpc::Server> mServer{nullptr};
+    std::unique_ptr<IVehicleHardware> mHardware;
+
+    std::shared_mutex mConnectionMutex;
+    std::vector<std::shared_ptr<ConnectionDescriptor>> mValueStreamingConnections;
+
+    static constexpr auto kHardwareOpTimeout = std::chrono::seconds(1);
+};
+
+}  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/OWNERS b/automotive/vehicle/aidl/impl/grpc/OWNERS
new file mode 100644
index 0000000..7a96f23
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/OWNERS
@@ -0,0 +1,3 @@
+shanyu@google.com
+chenhaosjtuacm@google.com
+egranata@google.com
diff --git a/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto b/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto
new file mode 100644
index 0000000..22b11d8
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+import "android/hardware/automotive/vehicle/DumpOptions.proto";
+import "android/hardware/automotive/vehicle/DumpResult.proto";
+import "android/hardware/automotive/vehicle/StatusCode.proto";
+import "android/hardware/automotive/vehicle/VehiclePropConfig.proto";
+import "android/hardware/automotive/vehicle/VehiclePropValue.proto";
+import "android/hardware/automotive/vehicle/VehiclePropValueRequest.proto";
+import "google/protobuf/empty.proto";
+
+service VehicleServer {
+    rpc GetAllPropertyConfig(google.protobuf.Empty) returns (stream VehiclePropConfig) {}
+
+    rpc SetValues(VehiclePropValueRequests) returns (SetValueResults) {}
+
+    rpc GetValues(VehiclePropValueRequests) returns (GetValueResults) {}
+
+    rpc UpdateSampleRate(UpdateSampleRateRequest) returns (VehicleHalCallStatus) {}
+
+    rpc CheckHealth(google.protobuf.Empty) returns (VehicleHalCallStatus) {}
+
+    rpc Dump(DumpOptions) returns (DumpResult) {}
+
+    rpc StartPropertyValuesStream(google.protobuf.Empty) returns (stream VehiclePropValues) {}
+}
diff --git a/automotive/vehicle/aidl/impl/grpc/test/Android.bp b/automotive/vehicle/aidl/impl/grpc/test/Android.bp
new file mode 100644
index 0000000..e53826f
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/test/Android.bp
@@ -0,0 +1,74 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "GRPCVehicleHardwareUnitTest",
+    vendor: true,
+    srcs: ["GRPCVehicleHardwareUnitTest.cpp"],
+    whole_static_libs: [
+        "android.hardware.automotive.vehicle@default-grpc-hardware-lib",
+    ],
+    header_libs: [
+        "IVehicleHardware",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    // libgrpc++.so is installed as root, require root to access it.
+    require_root: true,
+    defaults: [
+        "VehicleHalDefaults",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+    test_suites: ["device-tests"],
+}
+
+cc_test {
+    name: "GRPCVehicleProxyServerUnitTest",
+    vendor: true,
+    srcs: ["GRPCVehicleProxyServerUnitTest.cpp"],
+    header_libs: [
+        "IVehicleHardware",
+    ],
+    static_libs: [
+        "android.hardware.automotive.vehicle@default-grpc-hardware-lib",
+        "android.hardware.automotive.vehicle@default-grpc-server-lib",
+        "libgtest",
+        "libgmock",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    // libgrpc++.so is installed as root, require root to access it.
+    require_root: true,
+    defaults: [
+        "VehicleHalDefaults",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
new file mode 100644
index 0000000..f578021
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
@@ -0,0 +1,94 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "GRPCVehicleHardware.h"
+#include "VehicleServer.grpc.pb.h"
+#include "VehicleServer.pb.h"
+
+#include <gmock/gmock.h>
+#include <grpc++/grpc++.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <memory>
+#include <string>
+
+namespace android::hardware::automotive::vehicle::virtualization {
+
+const std::string kFakeServerAddr = "0.0.0.0:54321";
+
+class FakeVehicleServer : public proto::VehicleServer::Service {
+  public:
+    ::grpc::Status StartPropertyValuesStream(
+            ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
+            ::grpc::ServerWriter<proto::VehiclePropValues>* stream) override {
+        stream->Write(proto::VehiclePropValues());
+        // A fake disconnection.
+        return ::grpc::Status(::grpc::StatusCode::ABORTED, "Connection lost.");
+    }
+
+    // Functions that we do not care.
+    ::grpc::Status GetAllPropertyConfig(
+            ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
+            ::grpc::ServerWriter<proto::VehiclePropConfig>* stream) override {
+        return ::grpc::Status::OK;
+    }
+
+    ::grpc::Status SetValues(::grpc::ServerContext* context,
+                             const proto::VehiclePropValueRequests* requests,
+                             proto::SetValueResults* results) override {
+        return ::grpc::Status::OK;
+    }
+
+    ::grpc::Status GetValues(::grpc::ServerContext* context,
+                             const proto::VehiclePropValueRequests* requests,
+                             proto::GetValueResults* results) override {
+        return ::grpc::Status::OK;
+    }
+};
+
+TEST(GRPCVehicleHardwareUnitTest, Reconnect) {
+    auto receivedUpdate = std::make_shared<std::atomic<int>>(0);
+    auto vehicleHardware = std::make_unique<GRPCVehicleHardware>(kFakeServerAddr);
+    vehicleHardware->registerOnPropertyChangeEvent(
+            std::make_unique<const IVehicleHardware::PropertyChangeCallback>(
+                    [receivedUpdate](const auto&) { receivedUpdate->fetch_add(1); }));
+
+    constexpr size_t kServerRestartTimes = 5;
+    for (size_t serverStart = 0; serverStart < kServerRestartTimes; ++serverStart) {
+        EXPECT_EQ(receivedUpdate->load(), 0);
+        auto fakeServer = std::make_unique<FakeVehicleServer>();
+        ::grpc::ServerBuilder builder;
+        builder.RegisterService(fakeServer.get());
+        builder.AddListeningPort(kFakeServerAddr, ::grpc::InsecureServerCredentials());
+        auto grpcServer = builder.BuildAndStart();
+
+        // Wait until the vehicle hardware received the second update (after one fake
+        // disconnection).
+        constexpr auto kMaxWaitTime = std::chrono::seconds(5);
+        auto startTime = std::chrono::steady_clock::now();
+        while (receivedUpdate->load() <= 1 &&
+               std::chrono::steady_clock::now() - startTime < kMaxWaitTime)
+            ;
+
+        grpcServer->Shutdown();
+        grpcServer->Wait();
+        EXPECT_GT(receivedUpdate->load(), 1);
+
+        // Reset for the next round.
+        receivedUpdate->store(0);
+    }
+}
+
+}  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
new file mode 100644
index 0000000..49e6fc9
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
@@ -0,0 +1,147 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "GRPCVehicleHardware.h"
+#include "GRPCVehicleProxyServer.h"
+#include "IVehicleHardware.h"
+#include "VehicleServer.grpc.pb.h"
+#include "VehicleServer.pb.h"
+
+#include <gmock/gmock.h>
+#include <grpc++/grpc++.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <memory>
+#include <string>
+#include <thread>
+#include <utility>
+
+namespace android::hardware::automotive::vehicle::virtualization {
+
+const std::string kFakeServerAddr = "0.0.0.0:54321";
+
+class VehicleHardwareForTest : public IVehicleHardware {
+  public:
+    void registerOnPropertyChangeEvent(
+            std::unique_ptr<const PropertyChangeCallback> callback) override {
+        mOnProp = std::move(callback);
+    }
+
+    void onPropertyEvent(
+            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue> values) {
+        if (mOnProp) {
+            (*mOnProp)(std::move(values));
+        }
+    }
+
+    // Functions that we do not care.
+    std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
+    getAllPropertyConfigs() const override {
+        return {};
+    }
+
+    aidl::android::hardware::automotive::vehicle::StatusCode setValues(
+            std::shared_ptr<const SetValuesCallback> callback,
+            const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
+                    requests) override {
+        return aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+    }
+
+    aidl::android::hardware::automotive::vehicle::StatusCode getValues(
+            std::shared_ptr<const GetValuesCallback> callback,
+            const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>&
+                    requests) const override {
+        return aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+    }
+
+    DumpResult dump(const std::vector<std::string>& options) override { return {}; }
+
+    aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() override {
+        return aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+    }
+
+    void registerOnPropertySetErrorEvent(
+            std::unique_ptr<const PropertySetErrorCallback> callback) override {}
+
+  private:
+    std::unique_ptr<const PropertyChangeCallback> mOnProp;
+};
+
+TEST(GRPCVehicleProxyServerUnitTest, ClientConnectDisconnect) {
+    auto testHardware = std::make_unique<VehicleHardwareForTest>();
+    // HACK: manipulate the underlying hardware via raw pointer for testing.
+    auto* testHardwareRaw = testHardware.get();
+    auto vehicleServer =
+            std::make_unique<GrpcVehicleProxyServer>(kFakeServerAddr, std::move(testHardware));
+    vehicleServer->Start();
+
+    constexpr auto kWaitForConnectionMaxTime = std::chrono::seconds(5);
+    constexpr auto kWaitForStreamStartTime = std::chrono::seconds(1);
+    constexpr auto kWaitForUpdateDeliveryTime = std::chrono::milliseconds(100);
+
+    auto updateReceived1 = std::make_shared<bool>(false);
+    auto vehicleHardware1 = std::make_unique<GRPCVehicleHardware>(kFakeServerAddr);
+    vehicleHardware1->registerOnPropertyChangeEvent(
+            std::make_unique<const IVehicleHardware::PropertyChangeCallback>(
+                    [updateReceived1](const auto&) { *updateReceived1 = true; }));
+    EXPECT_TRUE(vehicleHardware1->waitForConnected(kWaitForConnectionMaxTime));
+    std::this_thread::sleep_for(kWaitForStreamStartTime);
+
+    // Client hardware 1 received update from the server.
+    EXPECT_FALSE(*updateReceived1);
+    testHardwareRaw->onPropertyEvent({});
+    // Wait for the update delivery.
+    std::this_thread::sleep_for(kWaitForUpdateDeliveryTime);
+    EXPECT_TRUE(*updateReceived1);
+
+    // Reset.
+    *updateReceived1 = false;
+
+    auto updateReceived2 = std::make_shared<bool>(false);
+    auto vehicleHardware2 = std::make_unique<GRPCVehicleHardware>(kFakeServerAddr);
+    vehicleHardware2->registerOnPropertyChangeEvent(
+            std::make_unique<const IVehicleHardware::PropertyChangeCallback>(
+                    [updateReceived2](const auto&) { *updateReceived2 = true; }));
+    EXPECT_TRUE(vehicleHardware2->waitForConnected(kWaitForConnectionMaxTime));
+    std::this_thread::sleep_for(kWaitForStreamStartTime);
+
+    // Both client hardware 1 and 2 received update from the server.
+    EXPECT_FALSE(*updateReceived1);
+    EXPECT_FALSE(*updateReceived2);
+    testHardwareRaw->onPropertyEvent({});
+    // Wait for the update delivery.
+    std::this_thread::sleep_for(kWaitForUpdateDeliveryTime);
+    EXPECT_TRUE(*updateReceived1);
+    EXPECT_TRUE(*updateReceived2);
+
+    // Reset.
+    *updateReceived1 = false;
+    *updateReceived2 = false;
+
+    vehicleHardware1.reset();
+
+    // Client 1 exited, only client hardware 2 received update from the server.
+    EXPECT_FALSE(*updateReceived1);
+    EXPECT_FALSE(*updateReceived2);
+    testHardwareRaw->onPropertyEvent({});
+    // Wait for the update delivery.
+    std::this_thread::sleep_for(kWaitForUpdateDeliveryTime);
+    EXPECT_FALSE(*updateReceived1);
+    EXPECT_TRUE(*updateReceived2);
+
+    vehicleServer->Shutdown().Wait();
+}
+
+}  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
index 7670c25..2b4059c 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
@@ -47,13 +47,19 @@
     ],
     vendor: true,
     defaults: ["VehicleHalDefaults"],
-    shared_libs: ["libprotobuf-cpp-full"],
+    shared_libs: [
+        "libprotobuf-cpp-full",
+        "libjsoncpp",
+    ],
     static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties",
         "VehicleHalProtoMessageConverter",
         "VehicleHalProtos",
         "VehicleHalUtils",
         "libgtest",
     ],
-    header_libs: ["VehicleHalDefaultConfig"],
+    data: [
+        ":VehicleHalDefaultProperties_JSON",
+    ],
     test_suites: ["device-tests"],
 }
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
index c742db5..308be46 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
@@ -16,9 +16,11 @@
 
 #include <vector>
 
-#include <DefaultConfig.h>
+#include <JsonConfigLoader.h>
 #include <ProtoMessageConverter.h>
 #include <VehicleHalTypes.h>
+
+#include <android-base/file.h>
 #include <android-base/format.h>
 #include <android/hardware/automotive/vehicle/VehiclePropConfig.pb.h>
 #include <android/hardware/automotive/vehicle/VehiclePropValue.pb.h>
@@ -35,23 +37,39 @@
 namespace proto = ::android::hardware::automotive::vehicle::proto;
 namespace aidl_vehicle = ::aidl::android::hardware::automotive::vehicle;
 
+constexpr char DEFAULT_PROPERTIES_CONFIG[] = "DefaultProperties.json";
+
+inline std::string getConfigPath(const std::string& name) {
+    return android::base::GetExecutableDirectory() + "/" + name;
+}
+
 std::vector<aidl_vehicle::VehiclePropConfig> prepareTestConfigs() {
+    JsonConfigLoader loader;
+    auto result = loader.loadPropConfig(getConfigPath(DEFAULT_PROPERTIES_CONFIG));
+    if (!result.ok()) {
+        return {};
+    }
     std::vector<aidl_vehicle::VehiclePropConfig> configs;
-    for (auto& property : defaultconfig::getDefaultConfigs()) {
-        configs.push_back(property.config);
+    for (auto& [_, configDeclaration] : result.value()) {
+        configs.push_back(configDeclaration.config);
     }
     return configs;
 }
 
 std::vector<aidl_vehicle::VehiclePropValue> prepareTestValues() {
+    JsonConfigLoader loader;
+    auto result = loader.loadPropConfig(getConfigPath(DEFAULT_PROPERTIES_CONFIG));
+    if (!result.ok()) {
+        return {};
+    }
     std::vector<aidl_vehicle::VehiclePropValue> values;
     int64_t timestamp = 1;
-    for (auto& property : defaultconfig::getDefaultConfigs()) {
+    for (auto& [_, configDeclaration] : result.value()) {
         values.push_back({
                 .timestamp = timestamp,
                 .areaId = 123,
-                .prop = property.config.prop,
-                .value = property.initialValue,
+                .prop = configDeclaration.config.prop,
+                .value = configDeclaration.initialValue,
                 .status = aidl_vehicle::VehiclePropertyStatus::ERROR,
         });
     }
diff --git a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
index 759db41..e53947e 100644
--- a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
@@ -35,6 +35,8 @@
     bool callerShouldDumpState;
     // The dumped information for the caller to print.
     std::string buffer;
+    // To pass if DefaultVehicleHal should refresh the property configs
+    bool refreshPropertyConfigs = false;
 };
 
 // A structure to represent a set value error event reported from vehicle.
@@ -116,11 +118,12 @@
     virtual aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() = 0;
 
     // Register a callback that would be called when there is a property change event from vehicle.
+    // Must only be called once during initialization.
     virtual void registerOnPropertyChangeEvent(
             std::unique_ptr<const PropertyChangeCallback> callback) = 0;
 
     // Register a callback that would be called when there is a property set error event from
-    // vehicle.
+    // vehicle. Must only be called once during initialization.
     virtual void registerOnPropertySetErrorEvent(
             std::unique_ptr<const PropertySetErrorCallback> callback) = 0;
 };
diff --git a/automotive/vehicle/aidl/impl/proto/Android.bp b/automotive/vehicle/aidl/impl/proto/Android.bp
index 709307d..56fad7e 100644
--- a/automotive/vehicle/aidl/impl/proto/Android.bp
+++ b/automotive/vehicle/aidl/impl/proto/Android.bp
@@ -40,6 +40,7 @@
         ":VehicleHalProtoFiles",
     ],
     out: [
+        "android/hardware/automotive/vehicle/DumpOptions.pb.h",
         "android/hardware/automotive/vehicle/DumpResult.pb.h",
         "android/hardware/automotive/vehicle/StatusCode.pb.h",
         "android/hardware/automotive/vehicle/VehicleAreaConfig.pb.h",
@@ -63,6 +64,7 @@
         ":VehicleHalProtoFiles",
     ],
     out: [
+        "android/hardware/automotive/vehicle/DumpOptions.pb.cc",
         "android/hardware/automotive/vehicle/DumpResult.pb.cc",
         "android/hardware/automotive/vehicle/StatusCode.pb.cc",
         "android/hardware/automotive/vehicle/VehicleAreaConfig.pb.cc",
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpOptions.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpOptions.proto
new file mode 100644
index 0000000..4bed927
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpOptions.proto
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+message DumpOptions {
+    repeated string options = 1;
+}
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/StatusCode.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/StatusCode.proto
index 97cb0f8..63d7933 100644
--- a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/StatusCode.proto
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/StatusCode.proto
@@ -39,3 +39,7 @@
     /* Something unexpected has happened in Vehicle HAL */
     INTERNAL_ERROR = 5;
 };
+
+message VehicleHalCallStatus {
+    StatusCode status_code = 1;
+}
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto
index 80c73cb..dda9ff5 100644
--- a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto
@@ -52,3 +52,7 @@
     /* This is used for properties of type VehiclePropertyType#STRING */
     string string_value = 9;
 };
+
+message VehiclePropValues {
+    repeated VehiclePropValue values = 1;
+}
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
index b16daa8..c347a80 100644
--- a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
@@ -18,9 +18,44 @@
 
 package android.hardware.automotive.vehicle.proto;
 
+import "android/hardware/automotive/vehicle/StatusCode.proto";
 import "android/hardware/automotive/vehicle/VehiclePropValue.proto";
 
 message VehiclePropValueRequest {
-    int32 request_id = 1;
+    int64 request_id = 1;
     VehiclePropValue value = 2;
 };
+
+message UpdateSampleRateRequest {
+    /* Property identifier */
+    int32 prop = 1;
+
+    /* Area type(s) for non-global property it must be one of the value from
+     * VehicleArea* enums or 0 for global properties. */
+    int32 area_id = 2;
+
+    float sample_rate = 3;
+};
+
+message SetValueResult {
+    int64 request_id = 1;
+    StatusCode status = 2;
+};
+
+message GetValueResult {
+    int64 request_id = 1;
+    StatusCode status = 2;
+    VehiclePropValue value = 3;
+};
+
+message VehiclePropValueRequests {
+    repeated VehiclePropValueRequest requests = 1;
+};
+
+message SetValueResults {
+    repeated SetValueResult results = 1;
+};
+
+message GetValueResults {
+    repeated GetValueResult results = 1;
+};
diff --git a/automotive/vehicle/aidl/impl/utils/README.md b/automotive/vehicle/aidl/impl/utils/README.md
new file mode 100644
index 0000000..87bb7e3
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/utils/README.md
@@ -0,0 +1,62 @@
+# Utility classes for VHAL implementation
+---
+
+This directory stores utility classes for VHAL implementation. Vendor
+implementation could use utility classes from `common` folder in their
+VHAL implementation.
+
+## common
+
+Defines common utility libraries.
+
+### ConcurrentQueue
+
+Provides a thread-safe concurrent queue object. Useful for adding object to
+a queue in one thread (usually binder thread) and handle the objects in a
+separate handler thread.
+
+### ParcelableUtils
+
+Provides functions to convert between a regular parcelable and a
+`LargeParcelabe`.
+
+A `LargeParcelable` is a parcelable that marshals the payload
+into a shared memory file if the payload is too large to pass across binder.
+It is used to pass large data across binder. Before sending the data, VHAL
+impl should convert a regular parcelabe to a `LargeParcelable`. After receving
+data, VHAL impl should convert a `LargeParcelable` back to regular parcelabe.
+
+### PendingRequestPool
+
+Defines A class for managing pending requests and automatically call timeout
+callback if the request timed-out.
+
+### PropertyUtils
+
+Defines some useful constants.
+
+### RecurrentTimer
+
+Defines a thread-safe recurrent timer that can call a function periodically.
+
+### VehicleHalTypes
+
+Provides a header file that includes many commonly used header files. Useful
+when you are using multiple types defined in VHAL interface.
+
+### VehicleObjectPool
+
+Defines a reusable in-memory pool for `VehiclePropValue`.
+
+### VehiclePropertyStore
+
+Defines an in-memory map for storing vehicle properties. Allows easier insert,
+delete and lookup.
+
+### VehicleUtils
+
+Defines many useful utility functions.
+
+## test
+
+Defines utility libraries for test only.
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h b/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h
index 3f8db93..28cf08e 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h
@@ -21,7 +21,6 @@
 #include <android-base/result.h>
 #include <android-base/thread_annotations.h>
 
-#include <atomic>
 #include <list>
 #include <mutex>
 #include <thread>
@@ -85,7 +84,7 @@
     std::unordered_map<const void*, std::list<PendingRequest>> mPendingRequestsByClient
             GUARDED_BY(mLock);
     std::thread mThread;
-    std::atomic<bool> mThreadStop = false;
+    bool mThreadStop = false;
     std::condition_variable mCv;
     std::mutex mCvLock;
 
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
index 2743578..7275ba3 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
@@ -28,6 +28,7 @@
 namespace propertyutils_impl {
 
 // These names are not part of the API since we only expose ints.
+using ::aidl::android::hardware::automotive::vehicle::EvStoppingMode;
 using ::aidl::android::hardware::automotive::vehicle::PortLocationType;
 using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaDoor;
@@ -96,7 +97,13 @@
 constexpr int CHARGE_PORT_FRONT_LEFT = toInt(propertyutils_impl::PortLocationType::FRONT_LEFT);
 constexpr int CHARGE_PORT_REAR_LEFT = toInt(propertyutils_impl::PortLocationType::REAR_LEFT);
 constexpr int LIGHT_STATE_ON = toInt(propertyutils_impl::VehicleLightState::ON);
+constexpr int LIGHT_STATE_OFF = toInt(propertyutils_impl::VehicleLightState::OFF);
+constexpr int LIGHT_SWITCH_OFF = toInt(propertyutils_impl::VehicleLightSwitch::OFF);
+constexpr int LIGHT_SWITCH_ON = toInt(propertyutils_impl::VehicleLightSwitch::ON);
 constexpr int LIGHT_SWITCH_AUTO = toInt(propertyutils_impl::VehicleLightSwitch::AUTOMATIC);
+constexpr int EV_STOPPING_MODE_CREEP = toInt(propertyutils_impl::EvStoppingMode::CREEP);
+constexpr int EV_STOPPING_MODE_ROLL = toInt(propertyutils_impl::EvStoppingMode::ROLL);
+constexpr int EV_STOPPING_MODE_HOLD = toInt(propertyutils_impl::EvStoppingMode::HOLD);
 constexpr int WHEEL_FRONT_LEFT = toInt(propertyutils_impl::VehicleAreaWheel::LEFT_FRONT);
 constexpr int WHEEL_FRONT_RIGHT = toInt(propertyutils_impl::VehicleAreaWheel::RIGHT_FRONT);
 constexpr int WHEEL_REAR_LEFT = toInt(propertyutils_impl::VehicleAreaWheel::LEFT_REAR);
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
index 5f0f716..cd2b727 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
@@ -83,8 +83,9 @@
     // each time we might introduce outdated elements to the top. We must make sure the heap is
     // always valid from the top.
     void removeInvalidCallbackLocked() REQUIRES(mLock);
-    // Pops the next closest callback (must be valid) from the heap.
-    std::unique_ptr<CallbackInfo> popNextCallbackLocked() REQUIRES(mLock);
+    // Gets the next calblack to run (must be valid) from the heap, update its nextTime and put
+    // it back to the heap.
+    std::shared_ptr<Callback> getNextCallbackLocked(int64_t now) REQUIRES(mLock);
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index a7fcdcf..e6d657d 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -17,15 +17,32 @@
 #ifndef android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
 #define android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
 
+#include <aidl/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.h>
+#include <aidl/android/hardware/automotive/vehicle/BlindSpotWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/CruiseControlCommand.h>
+#include <aidl/android/hardware/automotive/vehicle/CruiseControlState.h>
+#include <aidl/android/hardware/automotive/vehicle/CruiseControlType.h>
 #include <aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.h>
 #include <aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.h>
+#include <aidl/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.h>
+#include <aidl/android/hardware/automotive/vehicle/ErrorState.h>
 #include <aidl/android/hardware/automotive/vehicle/EvConnectorType.h>
+#include <aidl/android/hardware/automotive/vehicle/EvStoppingMode.h>
 #include <aidl/android/hardware/automotive/vehicle/EvsServiceState.h>
 #include <aidl/android/hardware/automotive/vehicle/EvsServiceType.h>
+#include <aidl/android/hardware/automotive/vehicle/ForwardCollisionWarningState.h>
 #include <aidl/android/hardware/automotive/vehicle/FuelType.h>
 #include <aidl/android/hardware/automotive/vehicle/GetValueRequest.h>
 #include <aidl/android/hardware/automotive/vehicle/GetValueResult.h>
 #include <aidl/android/hardware/automotive/vehicle/GetValueResults.h>
+#include <aidl/android/hardware/automotive/vehicle/GsrComplianceRequirementType.h>
+#include <aidl/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.h>
+#include <aidl/android/hardware/automotive/vehicle/HandsOnDetectionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.h>
+#include <aidl/android/hardware/automotive/vehicle/LaneCenteringAssistState.h>
+#include <aidl/android/hardware/automotive/vehicle/LaneDepartureWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/LaneKeepAssistState.h>
+#include <aidl/android/hardware/automotive/vehicle/LocationCharacterization.h>
 #include <aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.h>
 #include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
 #include <aidl/android/hardware/automotive/vehicle/Obd2FuelType.h>
@@ -42,6 +59,7 @@
 #include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleArea.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.h>
@@ -65,5 +83,7 @@
 #include <aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleUnit.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.h>
+#include <aidl/android/hardware/automotive/vehicle/WindshieldWipersState.h>
+#include <aidl/android/hardware/automotive/vehicle/WindshieldWipersSwitch.h>
 
 #endif  // android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
index ddc4f68..3d25cd3 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
@@ -46,6 +46,33 @@
     using ValueResultType = VhalResult<VehiclePropValuePool::RecyclableType>;
     using ValuesResultType = VhalResult<std::vector<VehiclePropValuePool::RecyclableType>>;
 
+    enum class EventMode : uint8_t {
+        /**
+         * Only invoke OnValueChangeCallback if the new property value (ignoring timestamp) is
+         * different than the existing value.
+         *
+         * This should be used for regular cases.
+         */
+        ON_VALUE_CHANGE,
+        /**
+         * Always invoke OnValueChangeCallback.
+         *
+         * This should be used for the special properties that are used for delivering event, e.g.
+         * HW_KEY_INPUT.
+         */
+        ALWAYS,
+        /**
+         * Never invoke OnValueChangeCallback.
+         *
+         * This should be used for continuous property subscription when the sample rate for the
+         * subscription is smaller than the refresh rate for the property. E.g., the vehicle speed
+         * is refreshed at 20hz, but we are only subscribing at 10hz. In this case, we want to
+         * generate the property change event at 10hz, not 20hz, but we still want to refresh the
+         * timestamp (via writeValue) at 20hz.
+         */
+        NEVER,
+    };
+
     explicit VehiclePropertyStore(std::shared_ptr<VehiclePropValuePool> valuePool)
         : mValuePool(valuePool) {}
 
@@ -72,8 +99,10 @@
     // 'status' would be initialized to {@code VehiclePropertyStatus::AVAILABLE}, if this is to
     // override an existing value, the status for the existing value would be used for the
     // overridden value.
+    // 'EventMode' controls whether the 'OnValueChangeCallback' will be called for this operation.
     VhalResult<void> writeValue(VehiclePropValuePool::RecyclableType propValue,
-                                bool updateStatus = false);
+                                bool updateStatus = false,
+                                EventMode mode = EventMode::ON_VALUE_CHANGE);
 
     // Remove a given property value from the property store. The 'propValue' would be used to
     // generate the key for the value to remove.
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp b/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp
index 0196edd..ab50499 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp
@@ -39,20 +39,27 @@
 
 }  // namespace
 
-PendingRequestPool::PendingRequestPool(int64_t timeoutInNano)
-    : mTimeoutInNano(timeoutInNano), mThread([this] {
-          // [this] must be alive within this thread because destructor would wait for this thread
-          // to exit.
-          int64_t sleepTime = std::min(mTimeoutInNano, static_cast<int64_t>(CHECK_TIME_IN_NANO));
-          std::unique_lock<std::mutex> lk(mCvLock);
-          while (!mCv.wait_for(lk, std::chrono::nanoseconds(sleepTime),
-                               [this] { return mThreadStop.load(); })) {
-              checkTimeout();
-          }
-      }) {}
+PendingRequestPool::PendingRequestPool(int64_t timeoutInNano) : mTimeoutInNano(timeoutInNano) {
+    mThread = std::thread([this] {
+        // [this] must be alive within this thread because destructor would wait for this thread
+        // to exit.
+        int64_t sleepTime = std::min(mTimeoutInNano, static_cast<int64_t>(CHECK_TIME_IN_NANO));
+        std::unique_lock<std::mutex> lk(mCvLock);
+        while (!mCv.wait_for(lk, std::chrono::nanoseconds(sleepTime),
+                             [this] { return mThreadStop; })) {
+            checkTimeout();
+        }
+    });
+}
 
 PendingRequestPool::~PendingRequestPool() {
-    mThreadStop = true;
+    {
+        // Even if the shared variable is atomic, it must be modified under the
+        // mutex in order to correctly publish the modification to the waiting
+        // thread.
+        std::unique_lock<std::mutex> lk(mCvLock);
+        mThreadStop = true;
+    }
     mCv.notify_all();
     if (mThread.joinable()) {
         mThread.join();
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
index 8521c4d..c6d3687 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
@@ -29,7 +29,9 @@
 
 using ::android::base::ScopedLockAssertion;
 
-RecurrentTimer::RecurrentTimer() : mThread(&RecurrentTimer::loop, this) {}
+RecurrentTimer::RecurrentTimer() {
+    mThread = std::thread(&RecurrentTimer::loop, this);
+}
 
 RecurrentTimer::~RecurrentTimer() {
     {
@@ -48,7 +50,7 @@
         std::scoped_lock<std::mutex> lockGuard(mLock);
 
         // Aligns the nextTime to multiply of interval.
-        int64_t nextTime = ceil(elapsedRealtimeNano() / intervalInNano) * intervalInNano;
+        int64_t nextTime = ceil(uptimeNanos() / intervalInNano) * intervalInNano;
 
         std::unique_ptr<CallbackInfo> info = std::make_unique<CallbackInfo>();
         info->callback = callback;
@@ -101,68 +103,71 @@
     }
 }
 
-std::unique_ptr<RecurrentTimer::CallbackInfo> RecurrentTimer::popNextCallbackLocked() {
+std::shared_ptr<RecurrentTimer::Callback> RecurrentTimer::getNextCallbackLocked(int64_t now) {
     std::pop_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
-    std::unique_ptr<CallbackInfo> info = std::move(mCallbackQueue[mCallbackQueue.size() - 1]);
-    mCallbackQueue.pop_back();
+    auto& callbackInfo = mCallbackQueue[mCallbackQueue.size() - 1];
+    auto nextCallback = callbackInfo->callback;
+    // intervalCount is the number of interval we have to advance until we pass now.
+    size_t intervalCount = (now - callbackInfo->nextTime) / callbackInfo->interval + 1;
+    callbackInfo->nextTime += intervalCount * callbackInfo->interval;
+    std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
+
     // Make sure the first element is always valid.
     removeInvalidCallbackLocked();
-    return info;
+
+    return nextCallback;
 }
 
 void RecurrentTimer::loop() {
-    std::unique_lock<std::mutex> uniqueLock(mLock);
-
+    std::vector<std::shared_ptr<Callback>> callbacksToRun;
     while (true) {
-        // Wait until the timer exits or we have at least one recurrent callback.
-        mCond.wait(uniqueLock, [this] {
-            ScopedLockAssertion lockAssertion(mLock);
-            return mStopRequested || mCallbackQueue.size() != 0;
-        });
-
-        int64_t interval;
         {
+            std::unique_lock<std::mutex> uniqueLock(mLock);
             ScopedLockAssertion lockAssertion(mLock);
+            // Wait until the timer exits or we have at least one recurrent callback.
+            mCond.wait(uniqueLock, [this] {
+                ScopedLockAssertion lockAssertion(mLock);
+                return mStopRequested || mCallbackQueue.size() != 0;
+            });
+
+            int64_t interval;
             if (mStopRequested) {
                 return;
             }
             // The first element is the nearest next event.
             int64_t nextTime = mCallbackQueue[0]->nextTime;
-            int64_t now = elapsedRealtimeNano();
+            int64_t now = uptimeNanos();
+
             if (nextTime > now) {
                 interval = nextTime - now;
             } else {
                 interval = 0;
             }
-        }
 
-        // Wait for the next event or the timer exits.
-        if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] {
-                ScopedLockAssertion lockAssertion(mLock);
-                return mStopRequested;
-            })) {
-            return;
-        }
+            // Wait for the next event or the timer exits.
+            if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] {
+                    ScopedLockAssertion lockAssertion(mLock);
+                    return mStopRequested;
+                })) {
+                return;
+            }
 
-        {
-            ScopedLockAssertion lockAssertion(mLock);
-            int64_t now = elapsedRealtimeNano();
+            now = uptimeNanos();
+            callbacksToRun.clear();
             while (mCallbackQueue.size() > 0) {
                 int64_t nextTime = mCallbackQueue[0]->nextTime;
                 if (nextTime > now) {
                     break;
                 }
 
-                std::unique_ptr<CallbackInfo> info = popNextCallbackLocked();
-                info->nextTime += info->interval;
-
-                auto callback = info->callback;
-                mCallbackQueue.push_back(std::move(info));
-                std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
-
-                (*callback)();
+                callbacksToRun.push_back(getNextCallbackLocked(now));
             }
         }
+
+        // Do not execute the callback while holding the lock.
+        for (size_t i = 0; i < callbacksToRun.size(); i++) {
+            (*callbacksToRun[i])();
+        }
     }
 }
 
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index c8fb994..646dc0e 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -106,7 +106,8 @@
 }
 
 VhalResult<void> VehiclePropertyStore::writeValue(VehiclePropValuePool::RecyclableType propValue,
-                                                  bool updateStatus) {
+                                                  bool updateStatus,
+                                                  VehiclePropertyStore::EventMode eventMode) {
     std::scoped_lock<std::mutex> g(mLock);
 
     int32_t propId = propValue->prop;
@@ -145,7 +146,12 @@
     }
 
     record->values[recId] = std::move(propValue);
-    if (valueUpdated && mOnValueChangeCallback != nullptr) {
+
+    if (eventMode == EventMode::NEVER) {
+        return {};
+    }
+
+    if ((eventMode == EventMode::ALWAYS || valueUpdated) && mOnValueChangeCallback != nullptr) {
         mOnValueChangeCallback(*(record->values[recId]));
     }
     return {};
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
index a033a24..141efc1 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
@@ -186,6 +186,33 @@
     ASSERT_EQ(countTimerCallbackQueue(&timer), static_cast<size_t>(0));
 }
 
+TEST_F(RecurrentTimerTest, testRegisterCallbackMultipleTimesNoDeadLock) {
+    // We want to avoid the following situation:
+    // Caller holds a lock while calling registerTimerCallback, registerTimerCallback will try
+    // to obtain an internal lock inside timer.
+    // Meanwhile an recurrent action happens with timer holding an internal lock. The action
+    // tries to obtain the lock currently hold by the caller.
+    // The solution is that while calling recurrent actions, timer must not hold the internal lock.
+
+    std::unique_ptr<RecurrentTimer> timer = std::make_unique<RecurrentTimer>();
+    std::mutex lock;
+    for (size_t i = 0; i < 1000; i++) {
+        std::scoped_lock<std::mutex> lockGuard(lock);
+        auto action = std::make_shared<RecurrentTimer::Callback>([&lock] {
+            // While calling this function, the timer must not hold lock in order not to dead
+            // lock.
+            std::scoped_lock<std::mutex> lockGuard(lock);
+        });
+        // 10ms
+        int64_t interval = 10'000'000;
+        timer->registerTimerCallback(interval, action);
+        // Sleep for a little while to let the recurrent actions begin.
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+    }
+    // Make sure we stop the timer before we destroy lock.
+    timer.reset();
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 4d6f811..fea5034 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
@@ -448,6 +448,67 @@
     ASSERT_EQ(updatedValue.prop, INVALID_PROP_ID);
 }
 
+TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackNoUpdateForTimestampChange) {
+    VehiclePropValue updatedValue{
+            .prop = INVALID_PROP_ID,
+    };
+    VehiclePropValue fuelCapacity = {
+            .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+            .value = {.floatValues = {1.0}},
+    };
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+    mStore->setOnValueChangeCallback(
+            [&updatedValue](const VehiclePropValue& value) { updatedValue = value; });
+
+    // Write the same value with different timestamp should succeed but should not trigger callback.
+    fuelCapacity.timestamp = 1;
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+    ASSERT_EQ(updatedValue.prop, INVALID_PROP_ID);
+}
+
+TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackForceUpdate) {
+    VehiclePropValue updatedValue{
+            .prop = INVALID_PROP_ID,
+    };
+    VehiclePropValue fuelCapacity = {
+            .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+            .value = {.floatValues = {1.0}},
+    };
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+    mStore->setOnValueChangeCallback(
+            [&updatedValue](const VehiclePropValue& value) { updatedValue = value; });
+
+    fuelCapacity.timestamp = 1;
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), /*updateStatus=*/false,
+                                        VehiclePropertyStore::EventMode::ALWAYS));
+
+    ASSERT_EQ(updatedValue, fuelCapacity);
+}
+
+TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackForceNoUpdate) {
+    VehiclePropValue updatedValue{
+            .prop = INVALID_PROP_ID,
+    };
+    VehiclePropValue fuelCapacity = {
+            .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+            .value = {.floatValues = {1.0}},
+    };
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+    mStore->setOnValueChangeCallback(
+            [&updatedValue](const VehiclePropValue& value) { updatedValue = value; });
+    fuelCapacity.value.floatValues[0] = 2.0;
+    fuelCapacity.timestamp = 1;
+
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), /*updateStatus=*/false,
+                                        VehiclePropertyStore::EventMode::NEVER));
+
+    ASSERT_EQ(updatedValue.prop, INVALID_PROP_ID);
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h b/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h
index d512713..1400288 100644
--- a/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h
@@ -35,7 +35,6 @@
 
 }  // namespace testpropertyutils_impl
 
-#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
 // Converts the system property to the vendor property.
 // WARNING: This is only for the end-to-end testing, Should NOT include in the user build.
 inline constexpr int32_t toVendor(
@@ -55,7 +54,6 @@
         toVendor(testpropertyutils_impl::VehicleProperty::CLUSTER_REQUEST_DISPLAY);
 constexpr int32_t VENDOR_CLUSTER_NAVIGATION_STATE =
         toVendor(testpropertyutils_impl::VehicleProperty::CLUSTER_NAVIGATION_STATE);
-#endif  // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
 
 // These properties are placeholder properties for developers to test new features without
 // implementing a real property.
@@ -86,6 +84,13 @@
                                        toInt(testpropertyutils_impl::VehicleArea::GLOBAL) |
                                        toInt(testpropertyutils_impl::VehiclePropertyType::BYTES);
 
+// This property is used for testing vendor error codes end to end.
+// 0x21402a13
+constexpr int32_t VENDOR_PROPERTY_ID = 0x2a13 |
+                                       toInt(testpropertyutils_impl::VehiclePropertyGroup::VENDOR) |
+                                       toInt(testpropertyutils_impl::VehicleArea::GLOBAL) |
+                                       toInt(testpropertyutils_impl::VehiclePropertyType::INT32);
+
 // This property is used for test purpose. End to end tests use this property to test set and get
 // method for MIXED type properties.
 constexpr int32_t kMixedTypePropertyForTest =
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index 5abcaf6..4feea79 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -66,3 +66,25 @@
         "libbinder_ndk",
     ],
 }
+
+cc_fuzz {
+    name: "android.hardware.automotive.vehicle@V1-default-service_fuzzer",
+    vendor: true,
+    defaults: [
+        "FakeVehicleHardwareDefaults",
+        "VehicleHalDefaults",
+        "android-automotive-large-parcelable-defaults",
+        "service_fuzzer_defaults",
+    ],
+    static_libs: [
+        "DefaultVehicleHal",
+        "FakeVehicleHardware",
+        "VehicleHalUtils",
+    ],
+    srcs: ["src/fuzzer.cpp"],
+    fuzz_config: {
+        cc: [
+            "keithmok@google.com",
+        ],
+    },
+}
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 9c29816..2c2cf1a 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -123,10 +123,10 @@
         std::shared_ptr<PendingRequestPool> mPendingRequestPool;
     };
 
-    // A wrapper for binder operations to enable stubbing for test.
-    class IBinder {
+    // A wrapper for binder lifecycle operations to enable stubbing for test.
+    class BinderLifecycleInterface {
       public:
-        virtual ~IBinder() = default;
+        virtual ~BinderLifecycleInterface() = default;
 
         virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
                                             void* cookie) = 0;
@@ -134,8 +134,8 @@
         virtual bool isAlive(const AIBinder* binder) = 0;
     };
 
-    // A real implementation for IBinder.
-    class AIBinderImpl final : public IBinder {
+    // A real implementation for BinderLifecycleInterface.
+    class BinderLifecycleHandler final : public BinderLifecycleInterface {
       public:
         binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
                                     void* cookie) override;
@@ -154,7 +154,7 @@
     // BinderDiedUnlinkedEvent represents either an onBinderDied or an onBinderUnlinked event.
     struct BinderDiedUnlinkedEvent {
         // true for onBinderDied, false for onBinderUnlinked.
-        bool onBinderDied;
+        bool forOnBinderDied;
         const AIBinder* clientId;
     };
 
@@ -164,6 +164,7 @@
     static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000;
     // heart beat event interval: 3s
     static constexpr int64_t HEART_BEAT_INTERVAL_IN_NANO = 3'000'000'000;
+    bool mShouldRefreshPropertyConfigs;
     std::unique_ptr<IVehicleHardware> mVehicleHardware;
 
     // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to
@@ -186,8 +187,8 @@
             GUARDED_BY(mLock);
     // SubscriptionClients is thread-safe.
     std::shared_ptr<SubscriptionClients> mSubscriptionClients;
-    // mBinderImpl is only going to be changed in test.
-    std::unique_ptr<IBinder> mBinderImpl;
+    // mBinderLifecycleHandler is only going to be changed in test.
+    std::unique_ptr<BinderLifecycleInterface> mBinderLifecycleHandler;
 
     // Only initialized once.
     std::shared_ptr<std::function<void()>> mRecurrentAction;
@@ -212,7 +213,6 @@
     android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
             const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
                     requests);
-
     VhalResult<void> checkSubscribeOptions(
             const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
                     options);
@@ -236,6 +236,8 @@
 
     bool checkDumpPermission();
 
+    bool getAllPropConfigsFromHardware();
+
     // The looping handler function to process all onBinderDied or onBinderUnlinked events in
     // mBinderEvents.
     void onBinderDiedUnlinkedHandler();
@@ -263,7 +265,7 @@
     void setTimeout(int64_t timeoutInNano);
 
     // Test-only
-    void setBinderImpl(std::unique_ptr<IBinder> impl);
+    void setBinderLifecycleHandler(std::unique_ptr<BinderLifecycleInterface> impl);
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h b/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
index 7c8f1b4..14799d9 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
@@ -41,15 +41,15 @@
   public:
     using ClientIdType = const AIBinder*;
 
-    void addClient(const ClientIdType& clientId, float sampleRate);
+    void addClient(const ClientIdType& clientId, float sampleRateHz);
     void removeClient(const ClientIdType& clientId);
-    float getMaxSampleRate();
+    float getMaxSampleRateHz() const;
 
   private:
-    float mMaxSampleRate = 0.;
-    std::unordered_map<ClientIdType, float> mSampleRates;
+    float mMaxSampleRateHz = 0.;
+    std::unordered_map<ClientIdType, float> mSampleRateHzByClient;
 
-    void refreshMaxSampleRate();
+    void refreshMaxSampleRateHz();
 };
 
 // A thread-safe subscription manager that manages all VHAL subscriptions.
@@ -59,7 +59,7 @@
     using CallbackType =
             std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
 
-    explicit SubscriptionManager(IVehicleHardware* hardware);
+    explicit SubscriptionManager(IVehicleHardware* vehicleHardware);
     ~SubscriptionManager();
 
     // Subscribes to properties according to {@code SubscribeOptions}. Note that all option must
@@ -99,13 +99,8 @@
             const std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
                     updatedValues);
 
-    // Gets the sample rate for the continuous property. Returns {@code std::nullopt} if the
-    // property has not been subscribed before or is not a continuous property.
-    std::optional<float> getSampleRate(const ClientIdType& clientId, int32_t propId,
-                                       int32_t areaId);
-
     // Checks whether the sample rate is valid.
-    static bool checkSampleRate(float sampleRate);
+    static bool checkSampleRateHz(float sampleRateHz);
 
   private:
     // Friend class for testing.
@@ -122,17 +117,21 @@
     std::unordered_map<PropIdAreaId, ContSubConfigs, PropIdAreaIdHash> mContSubConfigsByPropIdArea
             GUARDED_BY(mLock);
 
-    VhalResult<void> updateSampleRateLocked(const ClientIdType& clientId,
-                                            const PropIdAreaId& propIdAreaId, float sampleRate)
+    VhalResult<void> addContinuousSubscriberLocked(const ClientIdType& clientId,
+                                                   const PropIdAreaId& propIdAreaId,
+                                                   float sampleRateHz) REQUIRES(mLock);
+    VhalResult<void> removeContinuousSubscriberLocked(const ClientIdType& clientId,
+                                                      const PropIdAreaId& propIdAreaId)
             REQUIRES(mLock);
-    VhalResult<void> removeSampleRateLocked(const ClientIdType& clientId,
-                                            const PropIdAreaId& propIdAreaId) REQUIRES(mLock);
+
+    VhalResult<void> updateContSubConfigs(const PropIdAreaId& PropIdAreaId,
+                                          const ContSubConfigs& newConfig) REQUIRES(mLock);
 
     // Checks whether the manager is empty. For testing purpose.
     bool isEmpty();
 
     // Get the interval in nanoseconds accroding to sample rate.
-    static android::base::Result<int64_t> getInterval(float sampleRate);
+    static android::base::Result<int64_t> getIntervalNanos(float sampleRateHz);
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index b191aef..98cfc39 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "DefaultVehicleHal"
+#define ATRACE_TAG ATRACE_TAG_HAL
 
 #include <DefaultVehicleHal.h>
 
@@ -28,6 +29,7 @@
 #include <private/android_filesystem_config.h>
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
+#include <utils/Trace.h>
 
 #include <inttypes.h>
 #include <set>
@@ -78,14 +80,14 @@
     return str;
 }
 
-float getDefaultSampleRate(float sampleRate, float minSampleRate, float maxSampleRate) {
-    if (sampleRate < minSampleRate) {
-        return minSampleRate;
+float getDefaultSampleRateHz(float sampleRateHz, float minSampleRateHz, float maxSampleRateHz) {
+    if (sampleRateHz < minSampleRateHz) {
+        return minSampleRateHz;
     }
-    if (sampleRate > maxSampleRate) {
-        return maxSampleRate;
+    if (sampleRateHz > maxSampleRateHz) {
+        return maxSampleRateHz;
     }
-    return sampleRate;
+    return sampleRateHz;
 }
 
 }  // namespace
@@ -123,32 +125,18 @@
     return mClients.size();
 }
 
-DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware)
-    : mVehicleHardware(std::move(hardware)),
+DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
+    : mVehicleHardware(std::move(vehicleHardware)),
       mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)) {
-    auto configs = mVehicleHardware->getAllPropertyConfigs();
-    for (auto& config : configs) {
-        mConfigsByPropId[config.prop] = config;
-    }
-    VehiclePropConfigs vehiclePropConfigs;
-    vehiclePropConfigs.payloads = std::move(configs);
-    auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
-    if (!result.ok()) {
-        ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
-              result.error().message().c_str(), static_cast<int>(result.error().code()));
+    if (!getAllPropConfigsFromHardware()) {
         return;
     }
 
-    if (result.value() != nullptr) {
-        mConfigFile = std::move(result.value());
-    }
-
-    mSubscriptionClients = std::make_shared<SubscriptionClients>(mPendingRequestPool);
     mSubscriptionClients = std::make_shared<SubscriptionClients>(mPendingRequestPool);
 
     auto subscribeIdByClient = std::make_shared<SubscribeIdByClient>();
-    IVehicleHardware* hardwarePtr = mVehicleHardware.get();
-    mSubscriptionManager = std::make_shared<SubscriptionManager>(hardwarePtr);
+    IVehicleHardware* vehicleHardwarePtr = mVehicleHardware.get();
+    mSubscriptionManager = std::make_shared<SubscriptionManager>(vehicleHardwarePtr);
 
     std::weak_ptr<SubscriptionManager> subscriptionManagerCopy = mSubscriptionManager;
     mVehicleHardware->registerOnPropertyChangeEvent(
@@ -158,13 +146,13 @@
                     }));
 
     // Register heartbeat event.
-    mRecurrentAction =
-            std::make_shared<std::function<void()>>([hardwarePtr, subscriptionManagerCopy]() {
-                checkHealth(hardwarePtr, subscriptionManagerCopy);
+    mRecurrentAction = std::make_shared<std::function<void()>>(
+            [vehicleHardwarePtr, subscriptionManagerCopy]() {
+                checkHealth(vehicleHardwarePtr, subscriptionManagerCopy);
             });
     mRecurrentTimer.registerTimerCallback(HEART_BEAT_INTERVAL_IN_NANO, mRecurrentAction);
 
-    mBinderImpl = std::make_unique<AIBinderImpl>();
+    mBinderLifecycleHandler = std::make_unique<BinderLifecycleHandler>();
     mOnBinderDiedUnlinkedHandlerThread = std::thread([this] { onBinderDiedUnlinkedHandler(); });
     mDeathRecipient = ScopedAIBinder_DeathRecipient(
             AIBinder_DeathRecipient_new(&DefaultVehicleHal::onBinderDied));
@@ -220,7 +208,7 @@
 bool DefaultVehicleHal::monitorBinderLifeCycleLocked(const AIBinder* clientId) {
     OnBinderDiedContext* contextPtr = nullptr;
     if (mOnBinderDiedContexts.find(clientId) != mOnBinderDiedContexts.end()) {
-        return mBinderImpl->isAlive(clientId);
+        return mBinderLifecycleHandler->isAlive(clientId);
     } else {
         std::unique_ptr<OnBinderDiedContext> context = std::make_unique<OnBinderDiedContext>(
                 OnBinderDiedContext{.vhal = this, .clientId = clientId});
@@ -232,7 +220,7 @@
     }
 
     // If this function fails, onBinderUnlinked would be called to remove the added context.
-    binder_status_t status = mBinderImpl->linkToDeath(
+    binder_status_t status = mBinderLifecycleHandler->linkToDeath(
             const_cast<AIBinder*>(clientId), mDeathRecipient.get(), static_cast<void*>(contextPtr));
     if (status == STATUS_OK) {
         return true;
@@ -246,7 +234,8 @@
     OnBinderDiedContext* context = reinterpret_cast<OnBinderDiedContext*>(cookie);
     // To be handled in mOnBinderDiedUnlinkedHandlerThread. We cannot handle the event in the same
     // thread because we might be holding the mLock the handler requires.
-    context->vhal->mBinderEvents.push(BinderDiedUnlinkedEvent{true, context->clientId});
+    context->vhal->mBinderEvents.push(
+            BinderDiedUnlinkedEvent{/*forOnBinderDied=*/true, context->clientId});
 }
 
 void DefaultVehicleHal::onBinderDiedWithContext(const AIBinder* clientId) {
@@ -262,7 +251,8 @@
     OnBinderDiedContext* context = reinterpret_cast<OnBinderDiedContext*>(cookie);
     // To be handled in mOnBinderDiedUnlinkedHandlerThread. We cannot handle the event in the same
     // thread because we might be holding the mLock the handler requires.
-    context->vhal->mBinderEvents.push(BinderDiedUnlinkedEvent{false, context->clientId});
+    context->vhal->mBinderEvents.push(
+            BinderDiedUnlinkedEvent{/*forOnBinderDied=*/false, context->clientId});
 }
 
 void DefaultVehicleHal::onBinderUnlinkedWithContext(const AIBinder* clientId) {
@@ -275,7 +265,7 @@
 void DefaultVehicleHal::onBinderDiedUnlinkedHandler() {
     while (mBinderEvents.waitForItems()) {
         for (BinderDiedUnlinkedEvent& event : mBinderEvents.flush()) {
-            if (event.onBinderDied) {
+            if (event.forOnBinderDied) {
                 onBinderDiedWithContext(event.clientId);
             } else {
                 onBinderUnlinkedWithContext(event.clientId);
@@ -301,6 +291,27 @@
     mPendingRequestPool = std::make_unique<PendingRequestPool>(timeoutInNano);
 }
 
+bool DefaultVehicleHal::getAllPropConfigsFromHardware() {
+    auto configs = mVehicleHardware->getAllPropertyConfigs();
+    for (auto& config : configs) {
+        mConfigsByPropId[config.prop] = config;
+    }
+    VehiclePropConfigs vehiclePropConfigs;
+    vehiclePropConfigs.payloads = std::move(configs);
+    auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
+    if (!result.ok()) {
+        ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
+              result.error().message().c_str(), static_cast<int>(result.error().code()));
+        mConfigFile = nullptr;
+        return false;
+    }
+
+    if (result.value() != nullptr) {
+        mConfigFile = std::move(result.value());
+    }
+    return true;
+}
+
 ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
     if (mConfigFile != nullptr) {
         output->payloads.clear();
@@ -349,6 +360,10 @@
 
 ScopedAStatus DefaultVehicleHal::getValues(const CallbackType& callback,
                                            const GetValueRequests& requests) {
+    ATRACE_CALL();
+    if (callback == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
     expected<LargeParcelableBase::BorrowedOwnedObject<GetValueRequests>, ScopedAStatus>
             deserializedResults = fromStableLargeParcelable(requests);
     if (!deserializedResults.ok()) {
@@ -432,6 +447,10 @@
 
 ScopedAStatus DefaultVehicleHal::setValues(const CallbackType& callback,
                                            const SetValueRequests& requests) {
+    ATRACE_CALL();
+    if (callback == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
     expected<LargeParcelableBase::BorrowedOwnedObject<SetValueRequests>, ScopedAStatus>
             deserializedResults = fromStableLargeParcelable(requests);
     if (!deserializedResults.ok()) {
@@ -589,18 +608,20 @@
         }
 
         if (config.changeMode == VehiclePropertyChangeMode::CONTINUOUS) {
-            float sampleRate = option.sampleRate;
-            float minSampleRate = config.minSampleRate;
-            float maxSampleRate = config.maxSampleRate;
-            if (sampleRate < minSampleRate || sampleRate > maxSampleRate) {
-                float defaultRate = getDefaultSampleRate(sampleRate, minSampleRate, maxSampleRate);
-                ALOGW("sample rate: %f out of range, must be within %f and %f, set to %f",
-                      sampleRate, minSampleRate, maxSampleRate, defaultRate);
-                sampleRate = defaultRate;
+            float sampleRateHz = option.sampleRate;
+            float minSampleRateHz = config.minSampleRate;
+            float maxSampleRateHz = config.maxSampleRate;
+            float defaultRateHz =
+                    getDefaultSampleRateHz(sampleRateHz, minSampleRateHz, maxSampleRateHz);
+            if (sampleRateHz != defaultRateHz) {
+                ALOGW("sample rate: %f HZ out of range, must be within %f HZ and %f HZ , set to %f "
+                      "HZ",
+                      sampleRateHz, minSampleRateHz, maxSampleRateHz, defaultRateHz);
+                sampleRateHz = defaultRateHz;
             }
-            if (!SubscriptionManager::checkSampleRate(sampleRate)) {
+            if (!SubscriptionManager::checkSampleRateHz(sampleRateHz)) {
                 return StatusError(StatusCode::INVALID_ARG)
-                       << "invalid sample rate: " << sampleRate;
+                       << "invalid sample rate: " << sampleRateHz << " HZ";
             }
         }
 
@@ -625,11 +646,13 @@
                                            const std::vector<SubscribeOptions>& options,
                                            [[maybe_unused]] int32_t maxSharedMemoryFileCount) {
     // TODO(b/205189110): Use shared memory file count.
+    if (callback == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
     if (auto result = checkSubscribeOptions(options); !result.ok()) {
         ALOGE("subscribe: invalid subscribe options: %s", getErrorMsg(result).c_str());
         return toScopedAStatus(result);
     }
-
     std::vector<SubscribeOptions> onChangeSubscriptions;
     std::vector<SubscribeOptions> continuousSubscriptions;
     for (const auto& option : options) {
@@ -650,7 +673,7 @@
         }
 
         if (config.changeMode == VehiclePropertyChangeMode::CONTINUOUS) {
-            optionCopy.sampleRate = getDefaultSampleRate(
+            optionCopy.sampleRate = getDefaultSampleRateHz(
                     optionCopy.sampleRate, config.minSampleRate, config.maxSampleRate);
             continuousSubscriptions.push_back(std::move(optionCopy));
         } else {
@@ -685,6 +708,9 @@
 
 ScopedAStatus DefaultVehicleHal::unsubscribe(const CallbackType& callback,
                                              const std::vector<int32_t>& propIds) {
+    if (callback == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
     return toScopedAStatus(mSubscriptionManager->unsubscribe(callback->asBinder().get(), propIds));
 }
 
@@ -729,9 +755,9 @@
     return {};
 }
 
-void DefaultVehicleHal::checkHealth(IVehicleHardware* hardware,
+void DefaultVehicleHal::checkHealth(IVehicleHardware* vehicleHardware,
                                     std::weak_ptr<SubscriptionManager> subscriptionManager) {
-    StatusCode status = hardware->checkHealth();
+    StatusCode status = vehicleHardware->checkHealth();
     if (status != StatusCode::OK) {
         ALOGE("VHAL check health returns non-okay status");
         return;
@@ -746,18 +772,18 @@
     return;
 }
 
-binder_status_t DefaultVehicleHal::AIBinderImpl::linkToDeath(AIBinder* binder,
-                                                             AIBinder_DeathRecipient* recipient,
-                                                             void* cookie) {
+binder_status_t DefaultVehicleHal::BinderLifecycleHandler::linkToDeath(
+        AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) {
     return AIBinder_linkToDeath(binder, recipient, cookie);
 }
 
-bool DefaultVehicleHal::AIBinderImpl::isAlive(const AIBinder* binder) {
+bool DefaultVehicleHal::BinderLifecycleHandler::isAlive(const AIBinder* binder) {
     return AIBinder_isAlive(binder);
 }
 
-void DefaultVehicleHal::setBinderImpl(std::unique_ptr<IBinder> impl) {
-    mBinderImpl = std::move(impl);
+void DefaultVehicleHal::setBinderLifecycleHandler(
+        std::unique_ptr<BinderLifecycleInterface> handler) {
+    mBinderLifecycleHandler = std::move(handler);
 }
 
 bool DefaultVehicleHal::checkDumpPermission() {
@@ -775,10 +801,16 @@
     for (uint32_t i = 0; i < numArgs; i++) {
         options.push_back(args[i]);
     }
+    if (options.size() == 1 && options[0] == "-a") {
+        // Ignore "-a" option. Bugreport will call with this option.
+        options.clear();
+    }
     DumpResult result = mVehicleHardware->dump(options);
+    if (result.refreshPropertyConfigs) {
+        getAllPropConfigsFromHardware();
+    }
     dprintf(fd, "%s", (result.buffer + "\n").c_str());
     if (!result.callerShouldDumpState) {
-        dprintf(fd, "Skip dumping Vehicle HAL State.\n");
         return STATUS_OK;
     }
     dprintf(fd, "Vehicle HAL State: \n");
diff --git a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp b/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
index 2694401..bba730f 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
@@ -42,7 +42,8 @@
 using ::android::base::StringPrintf;
 using ::ndk::ScopedAStatus;
 
-SubscriptionManager::SubscriptionManager(IVehicleHardware* hardware) : mVehicleHardware(hardware) {}
+SubscriptionManager::SubscriptionManager(IVehicleHardware* vehicleHardware)
+    : mVehicleHardware(vehicleHardware) {}
 
 SubscriptionManager::~SubscriptionManager() {
     std::scoped_lock<std::mutex> lockGuard(mLock);
@@ -51,94 +52,82 @@
     mSubscribedPropsByClient.clear();
 }
 
-bool SubscriptionManager::checkSampleRate(float sampleRate) {
-    return getInterval(sampleRate).ok();
+bool SubscriptionManager::checkSampleRateHz(float sampleRateHz) {
+    return getIntervalNanos(sampleRateHz).ok();
 }
 
-Result<int64_t> SubscriptionManager::getInterval(float sampleRate) {
-    int64_t interval = 0;
-    if (sampleRate <= 0) {
+Result<int64_t> SubscriptionManager::getIntervalNanos(float sampleRateHz) {
+    int64_t intervalNanos = 0;
+    if (sampleRateHz <= 0) {
         return Error() << "invalid sample rate, must be a positive number";
     }
-    if (sampleRate <= (ONE_SECOND_IN_NANO / static_cast<float>(INT64_MAX))) {
-        return Error() << "invalid sample rate: " << sampleRate << ", too small";
+    if (sampleRateHz <= (ONE_SECOND_IN_NANO / static_cast<float>(INT64_MAX))) {
+        return Error() << "invalid sample rate: " << sampleRateHz << ", too small";
     }
-    interval = static_cast<int64_t>(ONE_SECOND_IN_NANO / sampleRate);
-    return interval;
+    intervalNanos = static_cast<int64_t>(ONE_SECOND_IN_NANO / sampleRateHz);
+    return intervalNanos;
 }
 
-void ContSubConfigs::refreshMaxSampleRate() {
-    float maxSampleRate = 0.;
+void ContSubConfigs::refreshMaxSampleRateHz() {
+    float maxSampleRateHz = 0.;
     // This is not called frequently so a brute-focre is okay. More efficient way exists but this
     // is simpler.
-    for (const auto& [_, sampleRate] : mSampleRates) {
-        if (sampleRate > maxSampleRate) {
-            maxSampleRate = sampleRate;
+    for (const auto& [_, sampleRateHz] : mSampleRateHzByClient) {
+        if (sampleRateHz > maxSampleRateHz) {
+            maxSampleRateHz = sampleRateHz;
         }
     }
-    mMaxSampleRate = maxSampleRate;
+    mMaxSampleRateHz = maxSampleRateHz;
 }
 
-void ContSubConfigs::addClient(const ClientIdType& clientId, float sampleRate) {
-    mSampleRates[clientId] = sampleRate;
-    refreshMaxSampleRate();
+void ContSubConfigs::addClient(const ClientIdType& clientId, float sampleRateHz) {
+    mSampleRateHzByClient[clientId] = sampleRateHz;
+    refreshMaxSampleRateHz();
 }
 
 void ContSubConfigs::removeClient(const ClientIdType& clientId) {
-    mSampleRates.erase(clientId);
-    refreshMaxSampleRate();
+    mSampleRateHzByClient.erase(clientId);
+    refreshMaxSampleRateHz();
 }
 
-float ContSubConfigs::getMaxSampleRate() {
-    return mMaxSampleRate;
+float ContSubConfigs::getMaxSampleRateHz() const {
+    return mMaxSampleRateHz;
 }
 
-VhalResult<void> SubscriptionManager::updateSampleRateLocked(const ClientIdType& clientId,
-                                                             const PropIdAreaId& propIdAreaId,
-                                                             float sampleRate) {
+VhalResult<void> SubscriptionManager::addContinuousSubscriberLocked(
+        const ClientIdType& clientId, const PropIdAreaId& propIdAreaId, float sampleRateHz) {
     // Make a copy so that we don't modify 'mContSubConfigsByPropIdArea' on failure cases.
-    ContSubConfigs infoCopy = mContSubConfigsByPropIdArea[propIdAreaId];
-    infoCopy.addClient(clientId, sampleRate);
-    if (infoCopy.getMaxSampleRate() ==
-        mContSubConfigsByPropIdArea[propIdAreaId].getMaxSampleRate()) {
-        mContSubConfigsByPropIdArea[propIdAreaId] = infoCopy;
+    ContSubConfigs newConfig = mContSubConfigsByPropIdArea[propIdAreaId];
+    newConfig.addClient(clientId, sampleRateHz);
+    return updateContSubConfigs(propIdAreaId, newConfig);
+}
+
+VhalResult<void> SubscriptionManager::removeContinuousSubscriberLocked(
+        const ClientIdType& clientId, const PropIdAreaId& propIdAreaId) {
+    // Make a copy so that we don't modify 'mContSubConfigsByPropIdArea' on failure cases.
+    ContSubConfigs newConfig = mContSubConfigsByPropIdArea[propIdAreaId];
+    newConfig.removeClient(clientId);
+    return updateContSubConfigs(propIdAreaId, newConfig);
+}
+
+VhalResult<void> SubscriptionManager::updateContSubConfigs(const PropIdAreaId& propIdAreaId,
+                                                           const ContSubConfigs& newConfig) {
+    if (newConfig.getMaxSampleRateHz() ==
+        mContSubConfigsByPropIdArea[propIdAreaId].getMaxSampleRateHz()) {
+        mContSubConfigsByPropIdArea[propIdAreaId] = newConfig;
         return {};
     }
-    float newRate = infoCopy.getMaxSampleRate();
+    float newRateHz = newConfig.getMaxSampleRateHz();
     int32_t propId = propIdAreaId.propId;
     int32_t areaId = propIdAreaId.areaId;
-    if (auto status = mVehicleHardware->updateSampleRate(propId, areaId, newRate);
+    if (auto status = mVehicleHardware->updateSampleRate(propId, areaId, newRateHz);
         status != StatusCode::OK) {
         return StatusError(status) << StringPrintf("failed to update sample rate for prop: %" PRId32
                                                    ", area"
-                                                   ": %" PRId32 ", sample rate: %f",
-                                                   propId, areaId, newRate);
+                                                   ": %" PRId32 ", sample rate: %f HZ",
+                                                   propId, areaId, newRateHz);
     }
-    mContSubConfigsByPropIdArea[propIdAreaId] = infoCopy;
-    return {};
-}
-
-VhalResult<void> SubscriptionManager::removeSampleRateLocked(const ClientIdType& clientId,
-                                                             const PropIdAreaId& propIdAreaId) {
-    // Make a copy so that we don't modify 'mContSubConfigsByPropIdArea' on failure cases.
-    ContSubConfigs infoCopy = mContSubConfigsByPropIdArea[propIdAreaId];
-    infoCopy.removeClient(clientId);
-    if (infoCopy.getMaxSampleRate() ==
-        mContSubConfigsByPropIdArea[propIdAreaId].getMaxSampleRate()) {
-        mContSubConfigsByPropIdArea[propIdAreaId] = infoCopy;
-        return {};
-    }
-    float newRate = infoCopy.getMaxSampleRate();
-    int32_t propId = propIdAreaId.propId;
-    int32_t areaId = propIdAreaId.areaId;
-    if (auto status = mVehicleHardware->updateSampleRate(propId, areaId, newRate);
-        status != StatusCode::OK) {
-        return StatusError(status) << StringPrintf("failed to update sample rate for prop: %" PRId32
-                                                   ", area"
-                                                   ": %" PRId32 ", sample rate: %f",
-                                                   propId, areaId, newRate);
-    }
-    mContSubConfigsByPropIdArea[propIdAreaId] = infoCopy;
+    mContSubConfigsByPropIdArea[propIdAreaId] = newConfig;
     return {};
 }
 
@@ -147,14 +136,12 @@
                                                 bool isContinuousProperty) {
     std::scoped_lock<std::mutex> lockGuard(mLock);
 
-    std::vector<int64_t> intervals;
     for (const auto& option : options) {
-        float sampleRate = option.sampleRate;
+        float sampleRateHz = option.sampleRate;
 
         if (isContinuousProperty) {
-            auto intervalResult = getInterval(sampleRate);
-            if (!intervalResult.ok()) {
-                return StatusError(StatusCode::INVALID_ARG) << intervalResult.error().message();
+            if (auto result = getIntervalNanos(sampleRateHz); !result.ok()) {
+                return StatusError(StatusCode::INVALID_ARG) << result.error().message();
             }
         }
 
@@ -176,7 +163,8 @@
                     .areaId = areaId,
             };
             if (isContinuousProperty) {
-                if (auto result = updateSampleRateLocked(clientId, propIdAreaId, option.sampleRate);
+                if (auto result = addContinuousSubscriberLocked(clientId, propIdAreaId,
+                                                                option.sampleRate);
                     !result.ok()) {
                     return result;
                 }
@@ -214,7 +202,7 @@
     while (it != propIdAreaIds.end()) {
         int32_t propId = it->propId;
         if (std::find(propIds.begin(), propIds.end(), propId) != propIds.end()) {
-            if (auto result = removeSampleRateLocked(clientId, *it); !result.ok()) {
+            if (auto result = removeContinuousSubscriberLocked(clientId, *it); !result.ok()) {
                 return result;
             }
 
@@ -244,7 +232,7 @@
 
     auto& subscriptions = mSubscribedPropsByClient[clientId];
     for (auto const& propIdAreaId : subscriptions) {
-        if (auto result = removeSampleRateLocked(clientId, propIdAreaId); !result.ok()) {
+        if (auto result = removeContinuousSubscriberLocked(clientId, propIdAreaId); !result.ok()) {
             return result;
         }
 
diff --git a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
index c8b5c65..f8a4e7d 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
@@ -27,6 +27,13 @@
 using ::android::hardware::automotive::vehicle::fake::FakeVehicleHardware;
 
 int main(int /* argc */, char* /* argv */[]) {
+    ALOGI("Starting thread pool...");
+    if (!ABinderProcess_setThreadPoolMaxThreadCount(4)) {
+        ALOGE("%s", "failed to set thread pool max thread count");
+        return 1;
+    }
+    ABinderProcess_startThreadPool();
+
     std::unique_ptr<FakeVehicleHardware> hardware = std::make_unique<FakeVehicleHardware>();
     std::shared_ptr<DefaultVehicleHal> vhal =
             ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
@@ -39,12 +46,6 @@
         return 1;
     }
 
-    if (!ABinderProcess_setThreadPoolMaxThreadCount(4)) {
-        ALOGE("%s", "failed to set thread pool max thread count");
-        return 1;
-    }
-    ABinderProcess_startThreadPool();
-
     ALOGI("Vehicle Service Ready");
 
     ABinderProcess_joinThreadPool();
diff --git a/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp b/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp
new file mode 100644
index 0000000..ac1e3b1
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <DefaultVehicleHal.h>
+#include <FakeVehicleHardware.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using ::android::fuzzService;
+using ::android::hardware::automotive::vehicle::DefaultVehicleHal;
+using ::android::hardware::automotive::vehicle::fake::FakeVehicleHardware;
+using ::ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    std::unique_ptr<FakeVehicleHardware> hardware = std::make_unique<FakeVehicleHardware>();
+    std::shared_ptr<DefaultVehicleHal> vhal =
+            ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+
+    fuzzService(vhal->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index f48b906..05e569a 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -324,9 +324,9 @@
         mCallbackClient = IVehicleCallback::fromBinder(mBinder);
 
         // Set the linkToDeath to a fake implementation that always returns OK.
-        auto binderImpl = std::make_unique<TestBinderImpl>();
-        mBinderImpl = binderImpl.get();
-        mVhal->setBinderImpl(std::move(binderImpl));
+        auto handler = std::make_unique<TestBinderLifecycleHandler>();
+        mBinderLifecycleHandler = handler.get();
+        mVhal->setBinderLifecycleHandler(std::move(handler));
     }
 
     void TearDown() override {
@@ -370,7 +370,7 @@
 
     bool hasNoSubscriptions() { return mVhal->mSubscriptionManager->isEmpty(); }
 
-    void setBinderAlive(bool isAlive) { mBinderImpl->setAlive(isAlive); };
+    void setBinderAlive(bool isAlive) { mBinderLifecycleHandler->setAlive(isAlive); };
 
     static Result<void> getValuesTestCases(size_t size, GetValueRequests& requests,
                                            std::vector<GetValueResult>& expectedResults,
@@ -444,7 +444,7 @@
     }
 
   private:
-    class TestBinderImpl final : public DefaultVehicleHal::IBinder {
+    class TestBinderLifecycleHandler final : public DefaultVehicleHal::BinderLifecycleInterface {
       public:
         binder_status_t linkToDeath(AIBinder*, AIBinder_DeathRecipient*, void*) override {
             if (mIsAlive) {
@@ -468,7 +468,7 @@
     std::shared_ptr<MockVehicleCallback> mCallback;
     std::shared_ptr<IVehicleCallback> mCallbackClient;
     SpAIBinder mBinder;
-    TestBinderImpl* mBinderImpl;
+    TestBinderLifecycleHandler* mBinderLifecycleHandler;
 };
 
 TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
@@ -671,8 +671,8 @@
 }
 
 TEST_F(DefaultVehicleHalTest, testGetValuesFinishBeforeTimeout) {
-    // timeout: 0.1s
-    int64_t timeout = 100000000;
+    // timeout: 1s
+    int64_t timeout = 1000000000;
     setTimeout(timeout);
 
     GetValueRequests requests;
@@ -681,17 +681,15 @@
 
     ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
 
-    // The response would be returned after 0.05s.
-    getHardware()->setSleepTime(timeout / 2);
+    // The response would be returned after 0.01s.
+    getHardware()->setSleepTime(timeout / 100);
     getHardware()->addGetValueResponses(expectedResults);
 
     auto status = getClient()->getValues(getCallbackClient(), requests);
 
     ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
 
-    // Wait for the response.
-    std::this_thread::sleep_for(std::chrono::nanoseconds(timeout));
-
+    ASSERT_TRUE(getCallback()->waitForGetValueResults(1, timeout)) << "no results in callback";
     auto maybeGetValueResults = getCallback()->nextGetValueResults();
     ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
     EXPECT_EQ(maybeGetValueResults.value().payloads, expectedResults) << "results mismatch";
@@ -699,8 +697,8 @@
 }
 
 TEST_F(DefaultVehicleHalTest, testGetValuesFinishAfterTimeout) {
-    // timeout: 0.1s
-    int64_t timeout = 100000000;
+    // timeout: 0.01s
+    int64_t timeout = 10000000;
     setTimeout(timeout);
 
     GetValueRequests requests;
@@ -709,17 +707,14 @@
 
     ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
 
-    // The response would be returned after 0.2s.
-    getHardware()->setSleepTime(timeout * 2);
+    // The response would be returned after 0.1s.
+    getHardware()->setSleepTime(timeout * 10);
     getHardware()->addGetValueResponses(expectedResults);
 
     auto status = getClient()->getValues(getCallbackClient(), requests);
 
     ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
 
-    // Wait for the response.
-    std::this_thread::sleep_for(std::chrono::nanoseconds(timeout * 5));
-
     for (size_t i = 0; i < expectedResults.size(); i++) {
         expectedResults[i] = {
                 .requestId = expectedResults[i].requestId,
@@ -728,6 +723,8 @@
         };
     }
 
+    ASSERT_TRUE(getCallback()->waitForGetValueResults(1, timeout * 100))
+            << "no results in callback";
     auto maybeGetValueResults = getCallback()->nextGetValueResults();
     ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
     ASSERT_THAT(maybeGetValueResults.value().payloads, UnorderedElementsAreArray(expectedResults))
@@ -960,8 +957,8 @@
 }
 
 TEST_F(DefaultVehicleHalTest, testSetValuesFinishBeforeTimeout) {
-    // timeout: 0.1s
-    int64_t timeout = 100000000;
+    // timeout: 1s
+    int64_t timeout = 1000000000;
     setTimeout(timeout);
 
     SetValueRequests requests;
@@ -970,17 +967,15 @@
 
     ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
 
-    // The response would be returned after 0.05s.
-    getHardware()->setSleepTime(timeout / 2);
+    // The response would be returned after 0.01s.
+    getHardware()->setSleepTime(timeout / 100);
     getHardware()->addSetValueResponses(expectedResults);
 
     auto status = getClient()->setValues(getCallbackClient(), requests);
 
     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
 
-    // Wait for the response.
-    std::this_thread::sleep_for(std::chrono::nanoseconds(timeout));
-
+    ASSERT_TRUE(getCallback()->waitForSetValueResults(1, timeout)) << "no set value results";
     auto maybeSetValueResults = getCallback()->nextSetValueResults();
     ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
     EXPECT_EQ(maybeSetValueResults.value().payloads, expectedResults) << "results mismatch";
@@ -988,8 +983,8 @@
 }
 
 TEST_F(DefaultVehicleHalTest, testSetValuesFinishAfterTimeout) {
-    // timeout: 0.1s
-    int64_t timeout = 100000000;
+    // timeout: 0.01s
+    int64_t timeout = 10000000;
     setTimeout(timeout);
 
     SetValueRequests requests;
@@ -998,17 +993,14 @@
 
     ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
 
-    // The response would be returned after 0.2s.
-    getHardware()->setSleepTime(timeout * 2);
+    // The response would be returned after 0.1s.
+    getHardware()->setSleepTime(timeout * 10);
     getHardware()->addSetValueResponses(expectedResults);
 
     auto status = getClient()->setValues(getCallbackClient(), requests);
 
     ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
 
-    // Wait for the response.
-    std::this_thread::sleep_for(std::chrono::nanoseconds(timeout * 5));
-
     for (size_t i = 0; i < expectedResults.size(); i++) {
         expectedResults[i] = {
                 .requestId = expectedResults[i].requestId,
@@ -1016,6 +1008,7 @@
         };
     }
 
+    ASSERT_TRUE(getCallback()->waitForSetValueResults(1, timeout * 100)) << "no set value results";
     auto maybeSetValueResults = getCallback()->nextSetValueResults();
     ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
     ASSERT_THAT(maybeSetValueResults.value().payloads, UnorderedElementsAreArray(expectedResults))
@@ -1456,7 +1449,7 @@
     std::vector<SubscribeOptions> options = {
             {
                     .propId = GLOBAL_CONTINUOUS_PROP,
-                    .sampleRate = 20.0,
+                    .sampleRate = 100.0,
             },
     };
 
@@ -1469,16 +1462,20 @@
 
     ASSERT_TRUE(status.isOk()) << "unsubscribe failed: " << status.getMessage();
 
+    // Wait for the last events to come.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
     // Clear existing events.
     while (getCallback()->nextOnPropertyEventResults().has_value()) {
         // Do nothing.
     }
 
-    // Wait for a while, make sure no new events are generated.
+    // Wait for a while, make sure no new events are generated. If still subscribed, this should
+    // generate around 10 events.
     std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
-    ASSERT_FALSE(getCallback()->nextOnPropertyEventResults().has_value())
-            << "No property event should be generated after unsubscription";
+    ASSERT_EQ(getCallback()->countOnPropertyEventResults(), 0u)
+            << "Property event generation must stop after unsubscription";
 }
 
 class SubscribeInvalidOptionsTest
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
index 0e46357..f51ce5c 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
@@ -16,6 +16,9 @@
 
 #include "MockVehicleCallback.h"
 
+#include <android-base/thread_annotations.h>
+#include <chrono>
+
 namespace android {
 namespace hardware {
 namespace automotive {
@@ -27,6 +30,7 @@
 using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
+using ::android::base::ScopedLockAssertion;
 using ::ndk::ScopedAStatus;
 using ::ndk::ScopedFileDescriptor;
 
@@ -46,21 +50,35 @@
 }  // namespace
 
 ScopedAStatus MockVehicleCallback::onGetValues(const GetValueResults& results) {
-    std::scoped_lock<std::mutex> lockGuard(mLock);
-    return storeResults(results, &mGetValueResults);
+    ScopedAStatus result;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        result = storeResults(results, &mGetValueResults);
+    }
+    mCond.notify_all();
+    return result;
 }
 
 ScopedAStatus MockVehicleCallback::onSetValues(const SetValueResults& results) {
-    std::scoped_lock<std::mutex> lockGuard(mLock);
-    return storeResults(results, &mSetValueResults);
+    ScopedAStatus result;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        result = storeResults(results, &mSetValueResults);
+    }
+    mCond.notify_all();
+    return result;
 }
 
 ScopedAStatus MockVehicleCallback::onPropertyEvent(const VehiclePropValues& results,
                                                    int32_t sharedMemoryFileCount) {
-    std::scoped_lock<std::mutex> lockGuard(mLock);
-
-    mSharedMemoryFileCount = sharedMemoryFileCount;
-    return storeResults(results, &mOnPropertyEventResults);
+    ScopedAStatus result;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        mSharedMemoryFileCount = sharedMemoryFileCount;
+        result = storeResults(results, &mOnPropertyEventResults);
+    }
+    mCond.notify_all();
+    return result;
 }
 
 ScopedAStatus MockVehicleCallback::onPropertySetError(const VehiclePropErrors&) {
@@ -87,6 +105,22 @@
     return mOnPropertyEventResults.size();
 }
 
+bool MockVehicleCallback::waitForSetValueResults(size_t size, size_t timeoutInNano) {
+    std::unique_lock lk(mLock);
+    return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
+        ScopedLockAssertion lockAssertion(mLock);
+        return mSetValueResults.size() >= size;
+    });
+}
+
+bool MockVehicleCallback::waitForGetValueResults(size_t size, size_t timeoutInNano) {
+    std::unique_lock lk(mLock);
+    return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
+        ScopedLockAssertion lockAssertion(mLock);
+        return mGetValueResults.size() >= size;
+    });
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
index 0faaa1f..f17b273 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
@@ -22,6 +22,7 @@
 #include <aidl/android/hardware/automotive/vehicle/BnVehicleCallback.h>
 #include <android-base/thread_annotations.h>
 
+#include <condition_variable>
 #include <list>
 #include <mutex>
 #include <optional>
@@ -63,9 +64,12 @@
     std::optional<aidl::android::hardware::automotive::vehicle::VehiclePropValues>
     nextOnPropertyEventResults();
     size_t countOnPropertyEventResults();
+    bool waitForSetValueResults(size_t size, size_t timeoutInNano);
+    bool waitForGetValueResults(size_t size, size_t timeoutInNano);
 
   private:
     std::mutex mLock;
+    std::condition_variable mCond;
     std::list<aidl::android::hardware::automotive::vehicle::GetValueResults> mGetValueResults
             GUARDED_BY(mLock);
     std::list<aidl::android::hardware::automotive::vehicle::SetValueResults> mSetValueResults
diff --git a/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
index 3f59363..cb8c8d1 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
@@ -231,7 +231,7 @@
     std::vector<SubscribeOptions> options = {{
             .propId = 0,
             .areaIds = {0},
-            .sampleRate = 10.0,
+            .sampleRate = 100.0,
     }};
 
     auto result = getManager()->subscribe(getCallbackClient(), options, true);
@@ -240,11 +240,13 @@
     result = getManager()->unsubscribe(getCallbackClient()->asBinder().get());
     ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
 
+    // Wait for the last events to come.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
     clearEvents();
 
-    std::this_thread::sleep_for(std::chrono::milliseconds(200));
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
-    // Theoretically trigger 10 times, but check for at least 9 times to be stable.
     ASSERT_TRUE(getEvents().empty());
 }
 
@@ -269,6 +271,9 @@
                                        std::vector<int32_t>({0}));
     ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
 
+    // Wait for the last events to come.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
     clearEvents();
 
     std::this_thread::sleep_for(std::chrono::seconds(1));
@@ -301,6 +306,9 @@
     result = getManager()->unsubscribe(getCallbackClient()->asBinder().get());
     ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
 
+    // Wait for the last events to come.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
     clearEvents();
 
     std::this_thread::sleep_for(std::chrono::seconds(1));
@@ -477,16 +485,16 @@
     ASSERT_THAT(clients[getCallbackClient()], ElementsAre(&updatedValues[1]));
 }
 
-TEST_F(SubscriptionManagerTest, testCheckSampleRateValid) {
-    ASSERT_TRUE(SubscriptionManager::checkSampleRate(1.0));
+TEST_F(SubscriptionManagerTest, testCheckSampleRateHzValid) {
+    ASSERT_TRUE(SubscriptionManager::checkSampleRateHz(1.0));
 }
 
-TEST_F(SubscriptionManagerTest, testCheckSampleRateInvalidTooSmall) {
-    ASSERT_FALSE(SubscriptionManager::checkSampleRate(FLT_MIN));
+TEST_F(SubscriptionManagerTest, testCheckSampleRateHzInvalidTooSmall) {
+    ASSERT_FALSE(SubscriptionManager::checkSampleRateHz(FLT_MIN));
 }
 
-TEST_F(SubscriptionManagerTest, testCheckSampleRateInvalidZero) {
-    ASSERT_FALSE(SubscriptionManager::checkSampleRate(0));
+TEST_F(SubscriptionManagerTest, testCheckSampleRateHzInvalidZero) {
+    ASSERT_FALSE(SubscriptionManager::checkSampleRateHz(0));
 }
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
index 4d587ee..9834cdb 100644
--- a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
+++ b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.automotive.vehicle</name>
-        <version>1</version>
+        <version>2</version>
         <fqname>IVehicle/default</fqname>
     </hal>
 </manifest>
diff --git a/automotive/vehicle/aidl_property/Android.bp b/automotive/vehicle/aidl_property/Android.bp
new file mode 100644
index 0000000..19fa4a3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/Android.bp
@@ -0,0 +1,58 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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"],
+}
+
+aidl_interface {
+    name: "android.hardware.automotive.vehicle.property",
+    vendor_available: true,
+    srcs: [
+        // This HAL was originally part of android.hardware.automotive.vehicle
+        "android/hardware/automotive/vehicle/*.aidl",
+    ],
+    frozen: true,
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+            min_sdk_version: "31",
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.car.framework",
+            ],
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+        {
+            version: "2",
+            imports: [],
+        },
+
+    ],
+
+}
diff --git a/automotive/vehicle/aidl_property/OWNERS b/automotive/vehicle/aidl_property/OWNERS
new file mode 100644
index 0000000..73e45ca
--- /dev/null
+++ b/automotive/vehicle/aidl_property/OWNERS
@@ -0,0 +1 @@
+tylertrephan@google.com
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/.hash b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/.hash
new file mode 100644
index 0000000..02d7352
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/.hash
@@ -0,0 +1,2 @@
+8610b651e162c614a97542d6f4ed039c969823e5
+d80c4423311162bf7e4fdda8c7be2bad2371cc00
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CustomInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CustomInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CustomInputType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CustomInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvChargeState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvChargeState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvChargeState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvChargeState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvConnectorType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvConnectorType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvConnectorType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/FuelType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/FuelType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/PortLocationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/PortLocationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/PortLocationType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/PortLocationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RotaryInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/RotaryInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RotaryInputType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/RotaryInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/TrailerState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/TrailerState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/TrailerState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserInfo.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserInfo.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UsersInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UsersInfo.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UsersInfo.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleArea.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleArea.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleArea.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleDisplay.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleDisplay.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleDisplay.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleGear.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleGear.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleGear.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleLightState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleLightState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleProperty.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleProperty.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleProperty.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleUnit.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleUnit.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleUnit.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/.hash b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/.hash
new file mode 100644
index 0000000..46c03c3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/.hash
@@ -0,0 +1 @@
+666fd8f93217775f55c3eb6ef9897cdde7e43da9
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
new file mode 100644
index 0000000..b316df7
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum AutomaticEmergencyBrakingState {
+  OTHER = 0,
+  ENABLED = 1,
+  ACTIVATED = 2,
+  USER_OVERRIDE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
new file mode 100644
index 0000000..535b0b1
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum BlindSpotWarningState {
+  OTHER = 0,
+  NO_WARNING = 1,
+  WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CreateUserRequest.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CreateUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CreateUserResponse.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CreateUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CreateUserStatus.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CreateUserStatus.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CruiseControlCommand.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
new file mode 100644
index 0000000..d6a104d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum CruiseControlCommand {
+  ACTIVATE = 1,
+  SUSPEND = 2,
+  INCREASE_TARGET_SPEED = 3,
+  DECREASE_TARGET_SPEED = 4,
+  INCREASE_TARGET_TIME_GAP = 5,
+  DECREASE_TARGET_TIME_GAP = 6,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CruiseControlState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CruiseControlState.aidl
new file mode 100644
index 0000000..ddaffa3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CruiseControlState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum CruiseControlState {
+  OTHER = 0,
+  ENABLED = 1,
+  ACTIVATED = 2,
+  USER_OVERRIDE = 3,
+  SUSPENDED = 4,
+  FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CruiseControlType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CruiseControlType.aidl
new file mode 100644
index 0000000..aab9dfe
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CruiseControlType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum CruiseControlType {
+  OTHER = 0,
+  STANDARD = 1,
+  ADAPTIVE = 2,
+  PREDICTIVE = 3,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CustomInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CustomInputType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CustomInputType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/CustomInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
new file mode 100644
index 0000000..078acde1
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum EmergencyLaneKeepAssistState {
+  OTHER = 0,
+  ENABLED = 1,
+  WARNING_LEFT = 2,
+  WARNING_RIGHT = 3,
+  ACTIVATED_STEER_LEFT = 4,
+  ACTIVATED_STEER_RIGHT = 5,
+  USER_OVERRIDE = 6,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ErrorState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ErrorState.aidl
new file mode 100644
index 0000000..dd950ce
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ErrorState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum ErrorState {
+  OTHER_ERROR_STATE = (-1) /* -1 */,
+  NOT_AVAILABLE_DISABLED = (-2) /* -2 */,
+  NOT_AVAILABLE_SPEED_LOW = (-3) /* -3 */,
+  NOT_AVAILABLE_SPEED_HIGH = (-4) /* -4 */,
+  NOT_AVAILABLE_POOR_VISIBILITY = (-5) /* -5 */,
+  NOT_AVAILABLE_SAFETY = (-6) /* -6 */,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvChargeState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvChargeState.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvChargeState.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvChargeState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvConnectorType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvConnectorType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvConnectorType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvStoppingMode.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvStoppingMode.aidl
new file mode 100644
index 0000000..3be8d12
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvStoppingMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum EvStoppingMode {
+  OTHER = 0,
+  CREEP = 1,
+  ROLL = 2,
+  HOLD = 3,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvsServiceState.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceState.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvsServiceState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvsServiceType.aidl
new file mode 100644
index 0000000..285732c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/EvsServiceType.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum EvsServiceType {
+  REARVIEW = 0,
+  SURROUNDVIEW = 1,
+  FRONTVIEW = 2,
+  LEFTVIEW = 3,
+  RIGHTVIEW = 4,
+  DRIVERVIEW = 5,
+  FRONTPASSENGERSVIEW = 6,
+  REARPASSENGERSVIEW = 7,
+  USER_DEFINED = 1000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
new file mode 100644
index 0000000..371885d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum ForwardCollisionWarningState {
+  OTHER = 0,
+  NO_WARNING = 1,
+  WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/FuelType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/FuelType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/FuelType.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
new file mode 100644
index 0000000..9c565ee
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum GsrComplianceRequirementType {
+  GSR_COMPLIANCE_NOT_REQUIRED = 0,
+  GSR_COMPLIANCE_REQUIRED_V1 = 1,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
new file mode 100644
index 0000000..bb390f2
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum HandsOnDetectionDriverState {
+  OTHER = 0,
+  HANDS_ON = 1,
+  HANDS_OFF = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
new file mode 100644
index 0000000..4ea4d1d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum HandsOnDetectionWarning {
+  OTHER = 0,
+  NO_WARNING = 1,
+  WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
new file mode 100644
index 0000000..9e72605
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneCenteringAssistCommand {
+  ACTIVATE = 1,
+  DEACTIVATE = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
new file mode 100644
index 0000000..c5afe2b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneCenteringAssistState {
+  OTHER = 0,
+  ENABLED = 1,
+  ACTIVATION_REQUESTED = 2,
+  ACTIVATED = 3,
+  USER_OVERRIDE = 4,
+  FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
new file mode 100644
index 0000000..cdddb6f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneDepartureWarningState {
+  OTHER = 0,
+  NO_WARNING = 1,
+  WARNING_LEFT = 2,
+  WARNING_RIGHT = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
new file mode 100644
index 0000000..9c92ff6
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneKeepAssistState {
+  OTHER = 0,
+  ENABLED = 1,
+  ACTIVATED_STEER_LEFT = 2,
+  ACTIVATED_STEER_RIGHT = 3,
+  USER_OVERRIDE = 4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LocationCharacterization.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LocationCharacterization.aidl
new file mode 100644
index 0000000..27abe41
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/LocationCharacterization.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LocationCharacterization {
+  PRIOR_LOCATIONS = 0x1,
+  GYROSCOPE_FUSION = 0x2,
+  ACCELEROMETER_FUSION = 0x4,
+  COMPASS_FUSION = 0x8,
+  WHEEL_SPEED_FUSION = 0x10,
+  STEERING_ANGLE_FUSION = 0x20,
+  CAR_SPEED_FUSION = 0x40,
+  DEAD_RECKONED = 0x80,
+  RAW_GNSS_ONLY = 0x100,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
new file mode 100644
index 0000000..7d12224
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum Obd2CommonIgnitionMonitors {
+  COMPONENTS_AVAILABLE = (0x1 << 0) /* 1 */,
+  COMPONENTS_INCOMPLETE = (0x1 << 1) /* 2 */,
+  FUEL_SYSTEM_AVAILABLE = (0x1 << 2) /* 4 */,
+  FUEL_SYSTEM_INCOMPLETE = (0x1 << 3) /* 8 */,
+  MISFIRE_AVAILABLE = (0x1 << 4) /* 16 */,
+  MISFIRE_INCOMPLETE = (0x1 << 5) /* 32 */,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
new file mode 100644
index 0000000..90240bf
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum Obd2CompressionIgnitionMonitors {
+  COMPONENTS_AVAILABLE = (0x1 << 0) /* 1 */,
+  COMPONENTS_INCOMPLETE = (0x1 << 1) /* 2 */,
+  FUEL_SYSTEM_AVAILABLE = (0x1 << 2) /* 4 */,
+  FUEL_SYSTEM_INCOMPLETE = (0x1 << 3) /* 8 */,
+  MISFIRE_AVAILABLE = (0x1 << 4) /* 16 */,
+  MISFIRE_INCOMPLETE = (0x1 << 5) /* 32 */,
+  EGR_OR_VVT_AVAILABLE = (0x1 << 6) /* 64 */,
+  EGR_OR_VVT_INCOMPLETE = (0x1 << 7) /* 128 */,
+  PM_FILTER_AVAILABLE = (0x1 << 8) /* 256 */,
+  PM_FILTER_INCOMPLETE = (0x1 << 9) /* 512 */,
+  EXHAUST_GAS_SENSOR_AVAILABLE = (0x1 << 10) /* 1024 */,
+  EXHAUST_GAS_SENSOR_INCOMPLETE = (0x1 << 11) /* 2048 */,
+  BOOST_PRESSURE_AVAILABLE = (0x1 << 12) /* 4096 */,
+  BOOST_PRESSURE_INCOMPLETE = (0x1 << 13) /* 8192 */,
+  NOx_SCR_AVAILABLE = (0x1 << 14) /* 16384 */,
+  NOx_SCR_INCOMPLETE = (0x1 << 15) /* 32768 */,
+  NMHC_CATALYST_AVAILABLE = (0x1 << 16) /* 65536 */,
+  NMHC_CATALYST_INCOMPLETE = (0x1 << 17) /* 131072 */,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2FuelType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2FuelType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
new file mode 100644
index 0000000..51e321b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum Obd2SparkIgnitionMonitors {
+  COMPONENTS_AVAILABLE = (0x1 << 0) /* 1 */,
+  COMPONENTS_INCOMPLETE = (0x1 << 1) /* 2 */,
+  FUEL_SYSTEM_AVAILABLE = (0x1 << 2) /* 4 */,
+  FUEL_SYSTEM_INCOMPLETE = (0x1 << 3) /* 8 */,
+  MISFIRE_AVAILABLE = (0x1 << 4) /* 16 */,
+  MISFIRE_INCOMPLETE = (0x1 << 5) /* 32 */,
+  EGR_AVAILABLE = (0x1 << 6) /* 64 */,
+  EGR_INCOMPLETE = (0x1 << 7) /* 128 */,
+  OXYGEN_SENSOR_HEATER_AVAILABLE = (0x1 << 8) /* 256 */,
+  OXYGEN_SENSOR_HEATER_INCOMPLETE = (0x1 << 9) /* 512 */,
+  OXYGEN_SENSOR_AVAILABLE = (0x1 << 10) /* 1024 */,
+  OXYGEN_SENSOR_INCOMPLETE = (0x1 << 11) /* 2048 */,
+  AC_REFRIGERANT_AVAILABLE = (0x1 << 12) /* 4096 */,
+  AC_REFRIGERANT_INCOMPLETE = (0x1 << 13) /* 8192 */,
+  SECONDARY_AIR_SYSTEM_AVAILABLE = (0x1 << 14) /* 16384 */,
+  SECONDARY_AIR_SYSTEM_INCOMPLETE = (0x1 << 15) /* 32768 */,
+  EVAPORATIVE_SYSTEM_AVAILABLE = (0x1 << 16) /* 65536 */,
+  EVAPORATIVE_SYSTEM_INCOMPLETE = (0x1 << 17) /* 131072 */,
+  HEATED_CATALYST_AVAILABLE = (0x1 << 18) /* 262144 */,
+  HEATED_CATALYST_INCOMPLETE = (0x1 << 19) /* 524288 */,
+  CATALYST_AVAILABLE = (0x1 << 20) /* 1048576 */,
+  CATALYST_INCOMPLETE = (0x1 << 21) /* 2097152 */,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/PortLocationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/PortLocationType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/PortLocationType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/PortLocationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RotaryInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/RotaryInputType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RotaryInputType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/RotaryInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/TrailerState.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/TrailerState.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/TrailerState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserInfo.aidl
new file mode 100644
index 0000000..feb5a73
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UserInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable UserInfo {
+  int userId = 0;
+  int flags;
+  const int USER_FLAG_SYSTEM = 0x01;
+  const int USER_FLAG_GUEST = 0x02;
+  const int USER_FLAG_EPHEMERAL = 0x04;
+  const int USER_FLAG_ADMIN = 0x08;
+  const int USER_FLAG_DISABLED = 0x10;
+  const int USER_FLAG_PROFILE = 0x20;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UsersInfo.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UsersInfo.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/UsersInfo.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
new file mode 100644
index 0000000..9720aca
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleApPowerBootupReason {
+  USER_POWER_ON = 0,
+  SYSTEM_USER_DETECTION = 1,
+  SYSTEM_REMOTE_ACCESS = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
new file mode 100644
index 0000000..cc12490
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleApPowerStateConfigFlag {
+  ENABLE_DEEP_SLEEP_FLAG = 0x1,
+  CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 0x2,
+  ENABLE_HIBERNATION_FLAG = 0x4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
new file mode 100644
index 0000000..e4f7e54
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleApPowerStateReport {
+  WAIT_FOR_VHAL = 0x1,
+  DEEP_SLEEP_ENTRY = 0x2,
+  DEEP_SLEEP_EXIT = 0x3,
+  SHUTDOWN_POSTPONE = 0x4,
+  SHUTDOWN_START = 0x5,
+  ON = 0x6,
+  SHUTDOWN_PREPARE = 0x7,
+  SHUTDOWN_CANCELLED = 0x8,
+  HIBERNATION_ENTRY = 0x9,
+  HIBERNATION_EXIT = 0xA,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleArea.aidl
new file mode 100644
index 0000000..db867f4
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleArea {
+  GLOBAL = 0x01000000,
+  WINDOW = 0x03000000,
+  MIRROR = 0x04000000,
+  SEAT = 0x05000000,
+  DOOR = 0x06000000,
+  WHEEL = 0x07000000,
+  MASK = 0x0f000000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
new file mode 100644
index 0000000..04976d6
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaDoor {
+  ROW_1_LEFT = 0x00000001,
+  ROW_1_RIGHT = 0x00000004,
+  ROW_2_LEFT = 0x00000010,
+  ROW_2_RIGHT = 0x00000040,
+  ROW_3_LEFT = 0x00000100,
+  ROW_3_RIGHT = 0x00000400,
+  HOOD = 0x10000000,
+  REAR = 0x20000000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
new file mode 100644
index 0000000..2d1c048
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaMirror {
+  DRIVER_LEFT = 0x00000001,
+  DRIVER_RIGHT = 0x00000002,
+  DRIVER_CENTER = 0x00000004,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
new file mode 100644
index 0000000..44c9d54
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaSeat {
+  ROW_1_LEFT = 0x0001,
+  ROW_1_CENTER = 0x0002,
+  ROW_1_RIGHT = 0x0004,
+  ROW_2_LEFT = 0x0010,
+  ROW_2_CENTER = 0x0020,
+  ROW_2_RIGHT = 0x0040,
+  ROW_3_LEFT = 0x0100,
+  ROW_3_CENTER = 0x0200,
+  ROW_3_RIGHT = 0x0400,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
new file mode 100644
index 0000000..d1b314e
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaWheel {
+  UNKNOWN = 0x0,
+  LEFT_FRONT = 0x1,
+  RIGHT_FRONT = 0x2,
+  LEFT_REAR = 0x4,
+  RIGHT_REAR = 0x8,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
new file mode 100644
index 0000000..2afcca3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaWindow {
+  FRONT_WINDSHIELD = 0x00000001,
+  REAR_WINDSHIELD = 0x00000002,
+  ROW_1_LEFT = 0x00000010,
+  ROW_1_RIGHT = 0x00000040,
+  ROW_2_LEFT = 0x00000100,
+  ROW_2_RIGHT = 0x00000400,
+  ROW_3_LEFT = 0x00001000,
+  ROW_3_RIGHT = 0x00004000,
+  ROOF_TOP_1 = 0x00010000,
+  ROOF_TOP_2 = 0x00020000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleDisplay.aidl
new file mode 100644
index 0000000..be335ec
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleDisplay.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleDisplay {
+  MAIN = 0,
+  INSTRUMENT_CLUSTER = 1,
+  HUD = 2,
+  INPUT = 3,
+  AUXILIARY = 4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleGear.aidl
new file mode 100644
index 0000000..b8a299c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleGear.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleGear {
+  GEAR_UNKNOWN = 0x0000,
+  GEAR_NEUTRAL = 0x0001,
+  GEAR_REVERSE = 0x0002,
+  GEAR_PARK = 0x0004,
+  GEAR_DRIVE = 0x0008,
+  GEAR_1 = 0x0010,
+  GEAR_2 = 0x0020,
+  GEAR_3 = 0x0040,
+  GEAR_4 = 0x0080,
+  GEAR_5 = 0x0100,
+  GEAR_6 = 0x0200,
+  GEAR_7 = 0x0400,
+  GEAR_8 = 0x0800,
+  GEAR_9 = 0x1000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
new file mode 100644
index 0000000..4f9870a
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHvacFanDirection {
+  UNKNOWN = 0x0,
+  FACE = 0x1,
+  FLOOR = 0x2,
+  FACE_AND_FLOOR = 0x3,
+  DEFROST = 0x4,
+  DEFROST_AND_FLOOR = 0x06,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
new file mode 100644
index 0000000..29c5ed6
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionButtonStateFlag {
+  BUTTON_PRIMARY = 0x0001,
+  BUTTON_SECONDARY = 0x0002,
+  BUTTON_TERTIARY = 0x0004,
+  BUTTON_BACK = 0x0008,
+  BUTTON_FORWARD = 0x0010,
+  BUTTON_STYLUS_PRIMARY = 0x0020,
+  BUTTON_STYLUS_SECONDARY = 0x0040,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
new file mode 100644
index 0000000..db4b41e
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionInputAction {
+  ACTION_DOWN = 0,
+  ACTION_UP = 1,
+  ACTION_MOVE = 2,
+  ACTION_CANCEL = 3,
+  ACTION_OUTSIDE = 4,
+  ACTION_POINTER_DOWN = 5,
+  ACTION_POINTER_UP = 6,
+  ACTION_HOVER_MOVE = 7,
+  ACTION_SCROLL = 8,
+  ACTION_HOVER_ENTER = 9,
+  ACTION_HOVER_EXIT = 10,
+  ACTION_BUTTON_PRESS = 11,
+  ACTION_BUTTON_RELEASE = 12,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
new file mode 100644
index 0000000..88c7873
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionInputSource {
+  SOURCE_UNKNOWN = 0,
+  SOURCE_KEYBOARD = 1,
+  SOURCE_DPAD = 2,
+  SOURCE_GAMEPAD = 3,
+  SOURCE_TOUCHSCREEN = 4,
+  SOURCE_MOUSE = 5,
+  SOURCE_STYLUS = 6,
+  SOURCE_BLUETOOTH_STYLUS = 7,
+  SOURCE_TRACKBALL = 8,
+  SOURCE_MOUSE_RELATIVE = 9,
+  SOURCE_TOUCHPAD = 10,
+  SOURCE_TOUCH_NAVIGATION = 11,
+  SOURCE_ROTARY_ENCODER = 12,
+  SOURCE_JOYSTICK = 13,
+  SOURCE_HDMI = 14,
+  SOURCE_SENSOR = 15,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl
new file mode 100644
index 0000000..2b3bc7f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionToolType {
+  TOOL_TYPE_UNKNOWN = 0,
+  TOOL_TYPE_FINGER = 1,
+  TOOL_TYPE_STYLUS = 2,
+  TOOL_TYPE_MOUSE = 3,
+  TOOL_TYPE_ERASER = 4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
new file mode 100644
index 0000000..f572a12
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleIgnitionState {
+  UNDEFINED = 0,
+  LOCK = 1,
+  OFF,
+  ACC,
+  ON,
+  START,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleLightState.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightState.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleLightState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
new file mode 100644
index 0000000..f244884
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleLightSwitch {
+  OFF = 0,
+  ON = 1,
+  DAYTIME_RUNNING = 2,
+  AUTOMATIC = 0x100,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleProperty.aidl
new file mode 100644
index 0000000..ba75e7b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -0,0 +1,273 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleProperty {
+  INVALID = 0x00000000,
+  INFO_VIN = (((0x0100 + 0x10000000) + 0x01000000) + 0x00100000) /* 286261504 */,
+  INFO_MAKE = (((0x0101 + 0x10000000) + 0x01000000) + 0x00100000) /* 286261505 */,
+  INFO_MODEL = (((0x0102 + 0x10000000) + 0x01000000) + 0x00100000) /* 286261506 */,
+  INFO_MODEL_YEAR = (((0x0103 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407235 */,
+  INFO_FUEL_CAPACITY = (((0x0104 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504388 */,
+  INFO_FUEL_TYPE = (((0x0105 + 0x10000000) + 0x01000000) + 0x00410000) /* 289472773 */,
+  INFO_EV_BATTERY_CAPACITY = (((0x0106 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504390 */,
+  INFO_EV_CONNECTOR_TYPE = (((0x0107 + 0x10000000) + 0x01000000) + 0x00410000) /* 289472775 */,
+  INFO_FUEL_DOOR_LOCATION = (((0x0108 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407240 */,
+  INFO_EV_PORT_LOCATION = (((0x0109 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407241 */,
+  INFO_DRIVER_SEAT = (((0x010A + 0x10000000) + 0x05000000) + 0x00400000) /* 356516106 */,
+  INFO_EXTERIOR_DIMENSIONS = (((0x010B + 0x10000000) + 0x01000000) + 0x00410000) /* 289472779 */,
+  INFO_MULTI_EV_PORT_LOCATIONS = (((0x010C + 0x10000000) + 0x01000000) + 0x00410000) /* 289472780 */,
+  PERF_ODOMETER = (((0x0204 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504644 */,
+  PERF_VEHICLE_SPEED = (((0x0207 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504647 */,
+  PERF_VEHICLE_SPEED_DISPLAY = (((0x0208 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504648 */,
+  PERF_STEERING_ANGLE = (((0x0209 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504649 */,
+  PERF_REAR_STEERING_ANGLE = (((0x0210 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504656 */,
+  ENGINE_COOLANT_TEMP = (((0x0301 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504897 */,
+  ENGINE_OIL_LEVEL = (((0x0303 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407747 */,
+  ENGINE_OIL_TEMP = (((0x0304 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504900 */,
+  ENGINE_RPM = (((0x0305 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504901 */,
+  WHEEL_TICK = (((0x0306 + 0x10000000) + 0x01000000) + 0x00510000) /* 290521862 */,
+  FUEL_LEVEL = (((0x0307 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504903 */,
+  FUEL_DOOR_OPEN = (((0x0308 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310600 */,
+  EV_BATTERY_LEVEL = (((0x0309 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504905 */,
+  EV_CURRENT_BATTERY_CAPACITY = (((0x030D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504909 */,
+  EV_CHARGE_PORT_OPEN = (((0x030A + 0x10000000) + 0x01000000) + 0x00200000) /* 287310602 */,
+  EV_CHARGE_PORT_CONNECTED = (((0x030B + 0x10000000) + 0x01000000) + 0x00200000) /* 287310603 */,
+  EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = (((0x030C + 0x10000000) + 0x01000000) + 0x00600000) /* 291504908 */,
+  RANGE_REMAINING = (((0x0308 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504904 */,
+  TIRE_PRESSURE = (((0x0309 + 0x10000000) + 0x07000000) + 0x00600000) /* 392168201 */,
+  CRITICALLY_LOW_TIRE_PRESSURE = (((0x030A + 0x10000000) + 0x07000000) + 0x00600000) /* 392168202 */,
+  ENGINE_IDLE_AUTO_STOP_ENABLED = (((0x0320 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310624 */,
+  GEAR_SELECTION = (((0x0400 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408000 */,
+  CURRENT_GEAR = (((0x0401 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408001 */,
+  PARKING_BRAKE_ON = (((0x0402 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310850 */,
+  PARKING_BRAKE_AUTO_APPLY = (((0x0403 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310851 */,
+  EV_BRAKE_REGENERATION_LEVEL = (((0x040C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408012 */,
+  FUEL_LEVEL_LOW = (((0x0405 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310853 */,
+  NIGHT_MODE = (((0x0407 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310855 */,
+  TURN_SIGNAL_STATE = (((0x0408 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408008 */,
+  IGNITION_STATE = (((0x0409 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408009 */,
+  ABS_ACTIVE = (((0x040A + 0x10000000) + 0x01000000) + 0x00200000) /* 287310858 */,
+  TRACTION_CONTROL_ACTIVE = (((0x040B + 0x10000000) + 0x01000000) + 0x00200000) /* 287310859 */,
+  EV_STOPPING_MODE = (((0x040D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408013 */,
+  HVAC_FAN_SPEED = (((0x0500 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517120 */,
+  HVAC_FAN_DIRECTION = (((0x0501 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517121 */,
+  HVAC_TEMPERATURE_CURRENT = (((0x0502 + 0x10000000) + 0x05000000) + 0x00600000) /* 358614274 */,
+  HVAC_TEMPERATURE_SET = (((0x0503 + 0x10000000) + 0x05000000) + 0x00600000) /* 358614275 */,
+  HVAC_DEFROSTER = (((0x0504 + 0x10000000) + 0x03000000) + 0x00200000) /* 320865540 */,
+  HVAC_AC_ON = (((0x0505 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419973 */,
+  HVAC_MAX_AC_ON = (((0x0506 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419974 */,
+  HVAC_MAX_DEFROST_ON = (((0x0507 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419975 */,
+  HVAC_RECIRC_ON = (((0x0508 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419976 */,
+  HVAC_DUAL_ON = (((0x0509 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419977 */,
+  HVAC_AUTO_ON = (((0x050A + 0x10000000) + 0x05000000) + 0x00200000) /* 354419978 */,
+  HVAC_SEAT_TEMPERATURE = (((0x050B + 0x10000000) + 0x05000000) + 0x00400000) /* 356517131 */,
+  HVAC_SIDE_MIRROR_HEAT = (((0x050C + 0x10000000) + 0x04000000) + 0x00400000) /* 339739916 */,
+  HVAC_STEERING_WHEEL_HEAT = (((0x050D + 0x10000000) + 0x01000000) + 0x00400000) /* 289408269 */,
+  HVAC_TEMPERATURE_DISPLAY_UNITS = (((0x050E + 0x10000000) + 0x01000000) + 0x00400000) /* 289408270 */,
+  HVAC_ACTUAL_FAN_SPEED_RPM = (((0x050F + 0x10000000) + 0x05000000) + 0x00400000) /* 356517135 */,
+  HVAC_POWER_ON = (((0x0510 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419984 */,
+  HVAC_FAN_DIRECTION_AVAILABLE = (((0x0511 + 0x10000000) + 0x05000000) + 0x00410000) /* 356582673 */,
+  HVAC_AUTO_RECIRC_ON = (((0x0512 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419986 */,
+  HVAC_SEAT_VENTILATION = (((0x0513 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517139 */,
+  HVAC_ELECTRIC_DEFROSTER_ON = (((0x0514 + 0x10000000) + 0x03000000) + 0x00200000) /* 320865556 */,
+  HVAC_TEMPERATURE_VALUE_SUGGESTION = (((0x0515 + 0x10000000) + 0x01000000) + 0x00610000) /* 291570965 */,
+  DISTANCE_DISPLAY_UNITS = (((0x0600 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408512 */,
+  FUEL_VOLUME_DISPLAY_UNITS = (((0x0601 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408513 */,
+  TIRE_PRESSURE_DISPLAY_UNITS = (((0x0602 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408514 */,
+  EV_BATTERY_DISPLAY_UNITS = (((0x0603 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408515 */,
+  FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = (((0x0604 + 0x10000000) + 0x01000000) + 0x00200000) /* 287311364 */,
+  VEHICLE_SPEED_DISPLAY_UNITS = (((0x0605 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408517 */,
+  EXTERNAL_CAR_TIME = (((0x0608 + 0x10000000) + 0x01000000) + 0x00500000) /* 290457096 */,
+  ANDROID_EPOCH_TIME = (((0x0606 + 0x10000000) + 0x01000000) + 0x00500000) /* 290457094 */,
+  STORAGE_ENCRYPTION_BINDING_SEED = (((0x0607 + 0x10000000) + 0x01000000) + 0x00700000) /* 292554247 */,
+  ENV_OUTSIDE_TEMPERATURE = (((0x0703 + 0x10000000) + 0x01000000) + 0x00600000) /* 291505923 */,
+  AP_POWER_STATE_REQ = (((0x0A00 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475072 */,
+  AP_POWER_STATE_REPORT = (((0x0A01 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475073 */,
+  AP_POWER_BOOTUP_REASON = (((0x0A02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409538 */,
+  DISPLAY_BRIGHTNESS = (((0x0A03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409539 */,
+  PER_DISPLAY_BRIGHTNESS = (((0x0A04 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475076 */,
+  HW_KEY_INPUT = (((0x0A10 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475088 */,
+  HW_KEY_INPUT_V2 = (((0x0A11 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004177 */,
+  HW_MOTION_INPUT = (((0x0A12 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004178 */,
+  HW_ROTARY_INPUT = (((0x0A20 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475104 */,
+  HW_CUSTOM_INPUT = (((0X0A30 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475120 */,
+  DOOR_POS = (((0x0B00 + 0x10000000) + 0x06000000) + 0x00400000) /* 373295872 */,
+  DOOR_MOVE = (((0x0B01 + 0x10000000) + 0x06000000) + 0x00400000) /* 373295873 */,
+  DOOR_LOCK = (((0x0B02 + 0x10000000) + 0x06000000) + 0x00200000) /* 371198722 */,
+  DOOR_CHILD_LOCK_ENABLED = (((0x0B03 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.DOOR) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 371198723 */,
+  MIRROR_Z_POS = (((0x0B40 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741504 */,
+  MIRROR_Z_MOVE = (((0x0B41 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741505 */,
+  MIRROR_Y_POS = (((0x0B42 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741506 */,
+  MIRROR_Y_MOVE = (((0x0B43 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741507 */,
+  MIRROR_LOCK = (((0x0B44 + 0x10000000) + 0x01000000) + 0x00200000) /* 287312708 */,
+  MIRROR_FOLD = (((0x0B45 + 0x10000000) + 0x01000000) + 0x00200000) /* 287312709 */,
+  MIRROR_AUTO_FOLD_ENABLED = (((0x0B46 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.MIRROR) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 337644358 */,
+  MIRROR_AUTO_TILT_ENABLED = (((0x0B47 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.MIRROR) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 337644359 */,
+  SEAT_MEMORY_SELECT = (((0x0B80 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518784 */,
+  SEAT_MEMORY_SET = (((0x0B81 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518785 */,
+  SEAT_BELT_BUCKLED = (((0x0B82 + 0x10000000) + 0x05000000) + 0x00200000) /* 354421634 */,
+  SEAT_BELT_HEIGHT_POS = (((0x0B83 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518787 */,
+  SEAT_BELT_HEIGHT_MOVE = (((0x0B84 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518788 */,
+  SEAT_FORE_AFT_POS = (((0x0B85 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518789 */,
+  SEAT_FORE_AFT_MOVE = (((0x0B86 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518790 */,
+  SEAT_BACKREST_ANGLE_1_POS = (((0x0B87 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518791 */,
+  SEAT_BACKREST_ANGLE_1_MOVE = (((0x0B88 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518792 */,
+  SEAT_BACKREST_ANGLE_2_POS = (((0x0B89 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518793 */,
+  SEAT_BACKREST_ANGLE_2_MOVE = (((0x0B8A + 0x10000000) + 0x05000000) + 0x00400000) /* 356518794 */,
+  SEAT_HEIGHT_POS = (((0x0B8B + 0x10000000) + 0x05000000) + 0x00400000) /* 356518795 */,
+  SEAT_HEIGHT_MOVE = (((0x0B8C + 0x10000000) + 0x05000000) + 0x00400000) /* 356518796 */,
+  SEAT_DEPTH_POS = (((0x0B8D + 0x10000000) + 0x05000000) + 0x00400000) /* 356518797 */,
+  SEAT_DEPTH_MOVE = (((0x0B8E + 0x10000000) + 0x05000000) + 0x00400000) /* 356518798 */,
+  SEAT_TILT_POS = (((0x0B8F + 0x10000000) + 0x05000000) + 0x00400000) /* 356518799 */,
+  SEAT_TILT_MOVE = (((0x0B90 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518800 */,
+  SEAT_LUMBAR_FORE_AFT_POS = (((0x0B91 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518801 */,
+  SEAT_LUMBAR_FORE_AFT_MOVE = (((0x0B92 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518802 */,
+  SEAT_LUMBAR_SIDE_SUPPORT_POS = (((0x0B93 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518803 */,
+  SEAT_LUMBAR_SIDE_SUPPORT_MOVE = (((0x0B94 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518804 */,
+  SEAT_HEADREST_HEIGHT_POS = (((0x0B95 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409941 */,
+  SEAT_HEADREST_HEIGHT_POS_V2 = (((0x0BA4 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518820 */,
+  SEAT_HEADREST_HEIGHT_MOVE = (((0x0B96 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518806 */,
+  SEAT_HEADREST_ANGLE_POS = (((0x0B97 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518807 */,
+  SEAT_HEADREST_ANGLE_MOVE = (((0x0B98 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518808 */,
+  SEAT_HEADREST_FORE_AFT_POS = (((0x0B99 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518809 */,
+  SEAT_HEADREST_FORE_AFT_MOVE = (((0x0B9A + 0x10000000) + 0x05000000) + 0x00400000) /* 356518810 */,
+  SEAT_FOOTWELL_LIGHTS_STATE = (((0x0B9B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518811 */,
+  SEAT_FOOTWELL_LIGHTS_SWITCH = (((0x0B9C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518812 */,
+  SEAT_EASY_ACCESS_ENABLED = (((0x0B9D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421661 */,
+  SEAT_AIRBAG_ENABLED = (((0x0B9E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421662 */,
+  SEAT_CUSHION_SIDE_SUPPORT_POS = (((0x0B9F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518815 */,
+  SEAT_CUSHION_SIDE_SUPPORT_MOVE = (((0x0BA0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518816 */,
+  SEAT_LUMBAR_VERTICAL_POS = (((0x0BA1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518817 */,
+  SEAT_LUMBAR_VERTICAL_MOVE = (((0x0BA2 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518818 */,
+  SEAT_WALK_IN_POS = (((0x0BA3 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518819 */,
+  SEAT_OCCUPANCY = (((0x0BB0 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518832 */,
+  WINDOW_POS = (((0x0BC0 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964416 */,
+  WINDOW_MOVE = (((0x0BC1 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964417 */,
+  WINDOW_LOCK = (((0x0BC4 + 0x10000000) + 0x03000000) + 0x00200000) /* 320867268 */,
+  WINDSHIELD_WIPERS_PERIOD = (((0x0BC5 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WINDOW) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 322964421 */,
+  WINDSHIELD_WIPERS_STATE = (((0x0BC6 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WINDOW) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 322964422 */,
+  WINDSHIELD_WIPERS_SWITCH = (((0x0BC7 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WINDOW) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 322964423 */,
+  STEERING_WHEEL_DEPTH_POS = (((0x0BE0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410016 */,
+  STEERING_WHEEL_DEPTH_MOVE = (((0x0BE1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410017 */,
+  STEERING_WHEEL_HEIGHT_POS = (((0x0BE2 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410018 */,
+  STEERING_WHEEL_HEIGHT_MOVE = (((0x0BE3 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410019 */,
+  STEERING_WHEEL_THEFT_LOCK_ENABLED = (((0x0BE4 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312868 */,
+  STEERING_WHEEL_LOCKED = (((0x0BE5 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312869 */,
+  STEERING_WHEEL_EASY_ACCESS_ENABLED = (((0x0BE6 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312870 */,
+  GLOVE_BOX_DOOR_POS = (((0x0BF0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518896 */,
+  GLOVE_BOX_LOCKED = (((0x0BF1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421745 */,
+  VEHICLE_MAP_SERVICE = (((0x0C00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299895808 */,
+  LOCATION_CHARACTERIZATION = (((0x0C10 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410064 */,
+  OBD2_LIVE_FRAME = (((0x0D00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896064 */,
+  OBD2_FREEZE_FRAME = (((0x0D01 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896065 */,
+  OBD2_FREEZE_FRAME_INFO = (((0x0D02 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896066 */,
+  OBD2_FREEZE_FRAME_CLEAR = (((0x0D03 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896067 */,
+  HEADLIGHTS_STATE = (((0x0E00 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410560 */,
+  HIGH_BEAM_LIGHTS_STATE = (((0x0E01 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410561 */,
+  FOG_LIGHTS_STATE = (((0x0E02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410562 */,
+  HAZARD_LIGHTS_STATE = (((0x0E03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410563 */,
+  HEADLIGHTS_SWITCH = (((0x0E10 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410576 */,
+  HIGH_BEAM_LIGHTS_SWITCH = (((0x0E11 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410577 */,
+  FOG_LIGHTS_SWITCH = (((0x0E12 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410578 */,
+  HAZARD_LIGHTS_SWITCH = (((0x0E13 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410579 */,
+  CABIN_LIGHTS_STATE = (((0x0F01 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410817 */,
+  CABIN_LIGHTS_SWITCH = (((0x0F02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410818 */,
+  READING_LIGHTS_STATE = (((0x0F03 + 0x10000000) + 0x05000000) + 0x00400000) /* 356519683 */,
+  READING_LIGHTS_SWITCH = (((0x0F04 + 0x10000000) + 0x05000000) + 0x00400000) /* 356519684 */,
+  STEERING_WHEEL_LIGHTS_STATE = (((0x0F0C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410828 */,
+  STEERING_WHEEL_LIGHTS_SWITCH = (((0x0F0D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410829 */,
+  SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = (((0x0F05 + 0x10000000) + 0x01000000) + 0x00200000) /* 287313669 */,
+  DISABLED_OPTIONAL_FEATURES = (((0x0F06 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265094 */,
+  INITIAL_USER_INFO = (((0x0F07 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896583 */,
+  SWITCH_USER = (((0x0F08 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896584 */,
+  CREATE_USER = (((0x0F09 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896585 */,
+  REMOVE_USER = (((0x0F0A + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896586 */,
+  USER_IDENTIFICATION_ASSOCIATION = (((0x0F0B + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896587 */,
+  EVS_SERVICE_REQUEST = (((0x0F10 + 0x10000000) + 0x01000000) + 0x00410000) /* 289476368 */,
+  POWER_POLICY_REQ = (((0x0F21 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265121 */,
+  POWER_POLICY_GROUP_REQ = (((0x0F22 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265122 */,
+  CURRENT_POWER_POLICY = (((0x0F23 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265123 */,
+  WATCHDOG_ALIVE = (((0xF31 + 0x10000000) + 0x01000000) + 0x00500000) /* 290459441 */,
+  WATCHDOG_TERMINATED_PROCESS = (((0x0F32 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896626 */,
+  VHAL_HEARTBEAT = (((0x0F33 + 0x10000000) + 0x01000000) + 0x00500000) /* 290459443 */,
+  CLUSTER_SWITCH_UI = (((0x0F34 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410868 */,
+  CLUSTER_DISPLAY_STATE = (((0x0F35 + 0x10000000) + 0x01000000) + 0x00410000) /* 289476405 */,
+  CLUSTER_REPORT_STATE = (((0x0F36 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896630 */,
+  CLUSTER_REQUEST_DISPLAY = (((0x0F37 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410871 */,
+  CLUSTER_NAVIGATION_STATE = (((0x0F38 + 0x10000000) + 0x01000000) + 0x00700000) /* 292556600 */,
+  ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = (((0x0F39 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410873 */,
+  ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = (((0x0F3A + 0x10000000) + 0x01000000) + 0x00400000) /* 289410874 */,
+  FRONT_FOG_LIGHTS_STATE = (((0x0F3B + 0x10000000) + 0x01000000) + 0x00400000) /* 289410875 */,
+  FRONT_FOG_LIGHTS_SWITCH = (((0x0F3C + 0x10000000) + 0x01000000) + 0x00400000) /* 289410876 */,
+  REAR_FOG_LIGHTS_STATE = (((0x0F3D + 0x10000000) + 0x01000000) + 0x00400000) /* 289410877 */,
+  REAR_FOG_LIGHTS_SWITCH = (((0x0F3E + 0x10000000) + 0x01000000) + 0x00400000) /* 289410878 */,
+  EV_CHARGE_CURRENT_DRAW_LIMIT = (((0x0F3F + 0x10000000) + 0x01000000) + 0x00600000) /* 291508031 */,
+  EV_CHARGE_PERCENT_LIMIT = (((0x0F40 + 0x10000000) + 0x01000000) + 0x00600000) /* 291508032 */,
+  EV_CHARGE_STATE = (((0x0F41 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410881 */,
+  EV_CHARGE_SWITCH = (((0x0F42 + 0x10000000) + 0x01000000) + 0x00200000) /* 287313730 */,
+  EV_CHARGE_TIME_REMAINING = (((0x0F43 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410883 */,
+  EV_REGENERATIVE_BRAKING_STATE = (((0x0F44 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410884 */,
+  TRAILER_PRESENT = (((0x0F45 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410885 */,
+  VEHICLE_CURB_WEIGHT = (((0x0F46 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410886 */,
+  GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = (((0x0F47 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410887 */,
+  SUPPORTED_PROPERTY_IDS = (((0x0F48 + 0x10000000) + 0x01000000) + 0x00410000) /* 289476424 */,
+  SHUTDOWN_REQUEST = (((0x0F49 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410889 */,
+  VEHICLE_IN_USE = (((0x0F4A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313738 */,
+  AUTOMATIC_EMERGENCY_BRAKING_ENABLED = (((0x1000 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313920 */,
+  AUTOMATIC_EMERGENCY_BRAKING_STATE = (((0x1001 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411073 */,
+  FORWARD_COLLISION_WARNING_ENABLED = (((0x1002 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313922 */,
+  FORWARD_COLLISION_WARNING_STATE = (((0x1003 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411075 */,
+  BLIND_SPOT_WARNING_ENABLED = (((0x1004 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313924 */,
+  BLIND_SPOT_WARNING_STATE = (((0x1005 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.MIRROR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 339742725 */,
+  LANE_DEPARTURE_WARNING_ENABLED = (((0x1006 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313926 */,
+  LANE_DEPARTURE_WARNING_STATE = (((0x1007 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411079 */,
+  LANE_KEEP_ASSIST_ENABLED = (((0x1008 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313928 */,
+  LANE_KEEP_ASSIST_STATE = (((0x1009 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411081 */,
+  LANE_CENTERING_ASSIST_ENABLED = (((0x100A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313930 */,
+  LANE_CENTERING_ASSIST_COMMAND = (((0x100B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411083 */,
+  LANE_CENTERING_ASSIST_STATE = (((0x100C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411084 */,
+  EMERGENCY_LANE_KEEP_ASSIST_ENABLED = (((0x100D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313933 */,
+  EMERGENCY_LANE_KEEP_ASSIST_STATE = (((0x100E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411086 */,
+  CRUISE_CONTROL_ENABLED = (((0x100F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313935 */,
+  CRUISE_CONTROL_TYPE = (((0x1010 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411088 */,
+  CRUISE_CONTROL_STATE = (((0x1011 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411089 */,
+  CRUISE_CONTROL_COMMAND = (((0x1012 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411090 */,
+  CRUISE_CONTROL_TARGET_SPEED = (((0x1013 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291508243 */,
+  ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP = (((0x1014 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411092 */,
+  ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE = (((0x1015 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411093 */,
+  HANDS_ON_DETECTION_ENABLED = (((0x1016 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313942 */,
+  HANDS_ON_DETECTION_DRIVER_STATE = (((0x1017 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411095 */,
+  HANDS_ON_DETECTION_WARNING = (((0x1018 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411096 */,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
new file mode 100644
index 0000000..714d514
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehiclePropertyGroup {
+  SYSTEM = 0x10000000,
+  VENDOR = 0x20000000,
+  MASK = 0xf0000000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
new file mode 100644
index 0000000..7525cbb
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehiclePropertyType {
+  STRING = 0x00100000,
+  BOOLEAN = 0x00200000,
+  INT32 = 0x00400000,
+  INT32_VEC = 0x00410000,
+  INT64 = 0x00500000,
+  INT64_VEC = 0x00510000,
+  FLOAT = 0x00600000,
+  FLOAT_VEC = 0x00610000,
+  BYTES = 0x00700000,
+  MIXED = 0x00e00000,
+  MASK = 0x00ff0000,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
new file mode 100644
index 0000000..0431b45
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleTurnSignal {
+  NONE = 0x00,
+  RIGHT = 0x01,
+  LEFT = 0x02,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleUnit.aidl
new file mode 100644
index 0000000..9aca98b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleUnit.aidl
@@ -0,0 +1,71 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleUnit {
+  SHOULD_NOT_USE = 0x000,
+  METER_PER_SEC = 0x01,
+  RPM = 0x02,
+  HERTZ = 0x03,
+  PERCENTILE = 0x10,
+  MILLIMETER = 0x20,
+  METER = 0x21,
+  KILOMETER = 0x23,
+  MILE = 0x24,
+  CELSIUS = 0x30,
+  FAHRENHEIT = 0x31,
+  KELVIN = 0x32,
+  MILLILITER = 0x40,
+  LITER = 0x41,
+  GALLON = 0x42,
+  US_GALLON = 0x42,
+  IMPERIAL_GALLON = 0x43,
+  NANO_SECS = 0x50,
+  MILLI_SECS = 0x51,
+  SECS = 0x53,
+  YEAR = 0x59,
+  WATT_HOUR = 0x60,
+  MILLIAMPERE = 0x61,
+  MILLIVOLT = 0x62,
+  MILLIWATTS = 0x63,
+  AMPERE_HOURS = 0x64,
+  KILOWATT_HOUR = 0x65,
+  AMPERE = 0x66,
+  KILOPASCAL = 0x70,
+  PSI = 0x71,
+  BAR = 0x72,
+  DEGREES = 0x80,
+  MILES_PER_HOUR = 0x90,
+  KILOMETERS_PER_HOUR = 0x91,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
new file mode 100644
index 0000000..3aa326c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
@@ -0,0 +1,75 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleVendorPermission {
+  PERMISSION_DEFAULT = 0x00000000,
+  PERMISSION_SET_VENDOR_CATEGORY_WINDOW = 0X00000001,
+  PERMISSION_GET_VENDOR_CATEGORY_WINDOW = 0x00000002,
+  PERMISSION_SET_VENDOR_CATEGORY_DOOR = 0x00000003,
+  PERMISSION_GET_VENDOR_CATEGORY_DOOR = 0x00000004,
+  PERMISSION_SET_VENDOR_CATEGORY_SEAT = 0x00000005,
+  PERMISSION_GET_VENDOR_CATEGORY_SEAT = 0x00000006,
+  PERMISSION_SET_VENDOR_CATEGORY_MIRROR = 0x00000007,
+  PERMISSION_GET_VENDOR_CATEGORY_MIRROR = 0x00000008,
+  PERMISSION_SET_VENDOR_CATEGORY_INFO = 0x00000009,
+  PERMISSION_GET_VENDOR_CATEGORY_INFO = 0x0000000A,
+  PERMISSION_SET_VENDOR_CATEGORY_ENGINE = 0x0000000B,
+  PERMISSION_GET_VENDOR_CATEGORY_ENGINE = 0x0000000C,
+  PERMISSION_SET_VENDOR_CATEGORY_HVAC = 0x0000000D,
+  PERMISSION_GET_VENDOR_CATEGORY_HVAC = 0x0000000E,
+  PERMISSION_SET_VENDOR_CATEGORY_LIGHT = 0x0000000F,
+  PERMISSION_GET_VENDOR_CATEGORY_LIGHT = 0x00000010,
+  PERMISSION_SET_VENDOR_CATEGORY_1 = 0x00010000,
+  PERMISSION_GET_VENDOR_CATEGORY_1 = 0x00011000,
+  PERMISSION_SET_VENDOR_CATEGORY_2 = 0x00020000,
+  PERMISSION_GET_VENDOR_CATEGORY_2 = 0x00021000,
+  PERMISSION_SET_VENDOR_CATEGORY_3 = 0x00030000,
+  PERMISSION_GET_VENDOR_CATEGORY_3 = 0x00031000,
+  PERMISSION_SET_VENDOR_CATEGORY_4 = 0x00040000,
+  PERMISSION_GET_VENDOR_CATEGORY_4 = 0x00041000,
+  PERMISSION_SET_VENDOR_CATEGORY_5 = 0x00050000,
+  PERMISSION_GET_VENDOR_CATEGORY_5 = 0x00051000,
+  PERMISSION_SET_VENDOR_CATEGORY_6 = 0x00060000,
+  PERMISSION_GET_VENDOR_CATEGORY_6 = 0x00061000,
+  PERMISSION_SET_VENDOR_CATEGORY_7 = 0x00070000,
+  PERMISSION_GET_VENDOR_CATEGORY_7 = 0x00071000,
+  PERMISSION_SET_VENDOR_CATEGORY_8 = 0x00080000,
+  PERMISSION_GET_VENDOR_CATEGORY_8 = 0x00081000,
+  PERMISSION_SET_VENDOR_CATEGORY_9 = 0x00090000,
+  PERMISSION_GET_VENDOR_CATEGORY_9 = 0x00091000,
+  PERMISSION_SET_VENDOR_CATEGORY_10 = 0x000A0000,
+  PERMISSION_GET_VENDOR_CATEGORY_10 = 0x000A1000,
+  PERMISSION_NOT_ACCESSIBLE = 0xF0000000,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsMessageType.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageType.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
similarity index 100%
copy from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/WindshieldWipersState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
new file mode 100644
index 0000000..d0c1e8d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum WindshieldWipersState {
+  OTHER = 0,
+  OFF = 1,
+  ON = 2,
+  SERVICE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
new file mode 100644
index 0000000..6c170fe
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/2/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum WindshieldWipersSwitch {
+  OTHER = 0,
+  OFF = 1,
+  MIST = 2,
+  INTERMITTENT_LEVEL_1 = 3,
+  INTERMITTENT_LEVEL_2 = 4,
+  INTERMITTENT_LEVEL_3 = 5,
+  INTERMITTENT_LEVEL_4 = 6,
+  INTERMITTENT_LEVEL_5 = 7,
+  CONTINUOUS_LEVEL_1 = 8,
+  CONTINUOUS_LEVEL_2 = 9,
+  CONTINUOUS_LEVEL_3 = 10,
+  CONTINUOUS_LEVEL_4 = 11,
+  CONTINUOUS_LEVEL_5 = 12,
+  AUTO = 13,
+  SERVICE = 14,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
new file mode 100644
index 0000000..b316df7
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum AutomaticEmergencyBrakingState {
+  OTHER = 0,
+  ENABLED = 1,
+  ACTIVATED = 2,
+  USER_OVERRIDE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
new file mode 100644
index 0000000..535b0b1
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum BlindSpotWarningState {
+  OTHER = 0,
+  NO_WARNING = 1,
+  WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserStatus.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlCommand.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
new file mode 100644
index 0000000..d6a104d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum CruiseControlCommand {
+  ACTIVATE = 1,
+  SUSPEND = 2,
+  INCREASE_TARGET_SPEED = 3,
+  DECREASE_TARGET_SPEED = 4,
+  INCREASE_TARGET_TIME_GAP = 5,
+  DECREASE_TARGET_TIME_GAP = 6,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlState.aidl
new file mode 100644
index 0000000..ddaffa3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum CruiseControlState {
+  OTHER = 0,
+  ENABLED = 1,
+  ACTIVATED = 2,
+  USER_OVERRIDE = 3,
+  SUSPENDED = 4,
+  FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlType.aidl
new file mode 100644
index 0000000..aab9dfe
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum CruiseControlType {
+  OTHER = 0,
+  STANDARD = 1,
+  ADAPTIVE = 2,
+  PREDICTIVE = 3,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CustomInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CustomInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CustomInputType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CustomInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
new file mode 100644
index 0000000..078acde1
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum EmergencyLaneKeepAssistState {
+  OTHER = 0,
+  ENABLED = 1,
+  WARNING_LEFT = 2,
+  WARNING_RIGHT = 3,
+  ACTIVATED_STEER_LEFT = 4,
+  ACTIVATED_STEER_RIGHT = 5,
+  USER_OVERRIDE = 6,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ErrorState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ErrorState.aidl
new file mode 100644
index 0000000..dd950ce
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ErrorState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum ErrorState {
+  OTHER_ERROR_STATE = (-1) /* -1 */,
+  NOT_AVAILABLE_DISABLED = (-2) /* -2 */,
+  NOT_AVAILABLE_SPEED_LOW = (-3) /* -3 */,
+  NOT_AVAILABLE_SPEED_HIGH = (-4) /* -4 */,
+  NOT_AVAILABLE_POOR_VISIBILITY = (-5) /* -5 */,
+  NOT_AVAILABLE_SAFETY = (-6) /* -6 */,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvChargeState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvChargeState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvChargeState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvChargeState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvConnectorType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvConnectorType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvConnectorType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvStoppingMode.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvStoppingMode.aidl
new file mode 100644
index 0000000..3be8d12
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvStoppingMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum EvStoppingMode {
+  OTHER = 0,
+  CREEP = 1,
+  ROLL = 2,
+  HOLD = 3,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceType.aidl
new file mode 100644
index 0000000..285732c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceType.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum EvsServiceType {
+  REARVIEW = 0,
+  SURROUNDVIEW = 1,
+  FRONTVIEW = 2,
+  LEFTVIEW = 3,
+  RIGHTVIEW = 4,
+  DRIVERVIEW = 5,
+  FRONTPASSENGERSVIEW = 6,
+  REARPASSENGERSVIEW = 7,
+  USER_DEFINED = 1000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
new file mode 100644
index 0000000..371885d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum ForwardCollisionWarningState {
+  OTHER = 0,
+  NO_WARNING = 1,
+  WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/FuelType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/FuelType.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
new file mode 100644
index 0000000..9c565ee
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum GsrComplianceRequirementType {
+  GSR_COMPLIANCE_NOT_REQUIRED = 0,
+  GSR_COMPLIANCE_REQUIRED_V1 = 1,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
new file mode 100644
index 0000000..bb390f2
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum HandsOnDetectionDriverState {
+  OTHER = 0,
+  HANDS_ON = 1,
+  HANDS_OFF = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
new file mode 100644
index 0000000..4ea4d1d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum HandsOnDetectionWarning {
+  OTHER = 0,
+  NO_WARNING = 1,
+  WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
new file mode 100644
index 0000000..9e72605
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneCenteringAssistCommand {
+  ACTIVATE = 1,
+  DEACTIVATE = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
new file mode 100644
index 0000000..c5afe2b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneCenteringAssistState {
+  OTHER = 0,
+  ENABLED = 1,
+  ACTIVATION_REQUESTED = 2,
+  ACTIVATED = 3,
+  USER_OVERRIDE = 4,
+  FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
new file mode 100644
index 0000000..cdddb6f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneDepartureWarningState {
+  OTHER = 0,
+  NO_WARNING = 1,
+  WARNING_LEFT = 2,
+  WARNING_RIGHT = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
new file mode 100644
index 0000000..9c92ff6
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneKeepAssistState {
+  OTHER = 0,
+  ENABLED = 1,
+  ACTIVATED_STEER_LEFT = 2,
+  ACTIVATED_STEER_RIGHT = 3,
+  USER_OVERRIDE = 4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LocationCharacterization.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LocationCharacterization.aidl
new file mode 100644
index 0000000..27abe41
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LocationCharacterization.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LocationCharacterization {
+  PRIOR_LOCATIONS = 0x1,
+  GYROSCOPE_FUSION = 0x2,
+  ACCELEROMETER_FUSION = 0x4,
+  COMPASS_FUSION = 0x8,
+  WHEEL_SPEED_FUSION = 0x10,
+  STEERING_ANGLE_FUSION = 0x20,
+  CAR_SPEED_FUSION = 0x40,
+  DEAD_RECKONED = 0x80,
+  RAW_GNSS_ONLY = 0x100,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
new file mode 100644
index 0000000..7d12224
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum Obd2CommonIgnitionMonitors {
+  COMPONENTS_AVAILABLE = (0x1 << 0) /* 1 */,
+  COMPONENTS_INCOMPLETE = (0x1 << 1) /* 2 */,
+  FUEL_SYSTEM_AVAILABLE = (0x1 << 2) /* 4 */,
+  FUEL_SYSTEM_INCOMPLETE = (0x1 << 3) /* 8 */,
+  MISFIRE_AVAILABLE = (0x1 << 4) /* 16 */,
+  MISFIRE_INCOMPLETE = (0x1 << 5) /* 32 */,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
new file mode 100644
index 0000000..90240bf
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum Obd2CompressionIgnitionMonitors {
+  COMPONENTS_AVAILABLE = (0x1 << 0) /* 1 */,
+  COMPONENTS_INCOMPLETE = (0x1 << 1) /* 2 */,
+  FUEL_SYSTEM_AVAILABLE = (0x1 << 2) /* 4 */,
+  FUEL_SYSTEM_INCOMPLETE = (0x1 << 3) /* 8 */,
+  MISFIRE_AVAILABLE = (0x1 << 4) /* 16 */,
+  MISFIRE_INCOMPLETE = (0x1 << 5) /* 32 */,
+  EGR_OR_VVT_AVAILABLE = (0x1 << 6) /* 64 */,
+  EGR_OR_VVT_INCOMPLETE = (0x1 << 7) /* 128 */,
+  PM_FILTER_AVAILABLE = (0x1 << 8) /* 256 */,
+  PM_FILTER_INCOMPLETE = (0x1 << 9) /* 512 */,
+  EXHAUST_GAS_SENSOR_AVAILABLE = (0x1 << 10) /* 1024 */,
+  EXHAUST_GAS_SENSOR_INCOMPLETE = (0x1 << 11) /* 2048 */,
+  BOOST_PRESSURE_AVAILABLE = (0x1 << 12) /* 4096 */,
+  BOOST_PRESSURE_INCOMPLETE = (0x1 << 13) /* 8192 */,
+  NOx_SCR_AVAILABLE = (0x1 << 14) /* 16384 */,
+  NOx_SCR_INCOMPLETE = (0x1 << 15) /* 32768 */,
+  NMHC_CATALYST_AVAILABLE = (0x1 << 16) /* 65536 */,
+  NMHC_CATALYST_INCOMPLETE = (0x1 << 17) /* 131072 */,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2FuelType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2FuelType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
new file mode 100644
index 0000000..51e321b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum Obd2SparkIgnitionMonitors {
+  COMPONENTS_AVAILABLE = (0x1 << 0) /* 1 */,
+  COMPONENTS_INCOMPLETE = (0x1 << 1) /* 2 */,
+  FUEL_SYSTEM_AVAILABLE = (0x1 << 2) /* 4 */,
+  FUEL_SYSTEM_INCOMPLETE = (0x1 << 3) /* 8 */,
+  MISFIRE_AVAILABLE = (0x1 << 4) /* 16 */,
+  MISFIRE_INCOMPLETE = (0x1 << 5) /* 32 */,
+  EGR_AVAILABLE = (0x1 << 6) /* 64 */,
+  EGR_INCOMPLETE = (0x1 << 7) /* 128 */,
+  OXYGEN_SENSOR_HEATER_AVAILABLE = (0x1 << 8) /* 256 */,
+  OXYGEN_SENSOR_HEATER_INCOMPLETE = (0x1 << 9) /* 512 */,
+  OXYGEN_SENSOR_AVAILABLE = (0x1 << 10) /* 1024 */,
+  OXYGEN_SENSOR_INCOMPLETE = (0x1 << 11) /* 2048 */,
+  AC_REFRIGERANT_AVAILABLE = (0x1 << 12) /* 4096 */,
+  AC_REFRIGERANT_INCOMPLETE = (0x1 << 13) /* 8192 */,
+  SECONDARY_AIR_SYSTEM_AVAILABLE = (0x1 << 14) /* 16384 */,
+  SECONDARY_AIR_SYSTEM_INCOMPLETE = (0x1 << 15) /* 32768 */,
+  EVAPORATIVE_SYSTEM_AVAILABLE = (0x1 << 16) /* 65536 */,
+  EVAPORATIVE_SYSTEM_INCOMPLETE = (0x1 << 17) /* 131072 */,
+  HEATED_CATALYST_AVAILABLE = (0x1 << 18) /* 262144 */,
+  HEATED_CATALYST_INCOMPLETE = (0x1 << 19) /* 524288 */,
+  CATALYST_AVAILABLE = (0x1 << 20) /* 1048576 */,
+  CATALYST_INCOMPLETE = (0x1 << 21) /* 2097152 */,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/PortLocationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/PortLocationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/PortLocationType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/PortLocationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RotaryInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/RotaryInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RotaryInputType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/RotaryInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/TrailerState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/TrailerState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/TrailerState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserInfo.aidl
new file mode 100644
index 0000000..feb5a73
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable UserInfo {
+  int userId = 0;
+  int flags;
+  const int USER_FLAG_SYSTEM = 0x01;
+  const int USER_FLAG_GUEST = 0x02;
+  const int USER_FLAG_EPHEMERAL = 0x04;
+  const int USER_FLAG_ADMIN = 0x08;
+  const int USER_FLAG_DISABLED = 0x10;
+  const int USER_FLAG_PROFILE = 0x20;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UsersInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UsersInfo.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
new file mode 100644
index 0000000..9720aca
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleApPowerBootupReason {
+  USER_POWER_ON = 0,
+  SYSTEM_USER_DETECTION = 1,
+  SYSTEM_REMOTE_ACCESS = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
new file mode 100644
index 0000000..cc12490
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleApPowerStateConfigFlag {
+  ENABLE_DEEP_SLEEP_FLAG = 0x1,
+  CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 0x2,
+  ENABLE_HIBERNATION_FLAG = 0x4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
new file mode 100644
index 0000000..e4f7e54
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleApPowerStateReport {
+  WAIT_FOR_VHAL = 0x1,
+  DEEP_SLEEP_ENTRY = 0x2,
+  DEEP_SLEEP_EXIT = 0x3,
+  SHUTDOWN_POSTPONE = 0x4,
+  SHUTDOWN_START = 0x5,
+  ON = 0x6,
+  SHUTDOWN_PREPARE = 0x7,
+  SHUTDOWN_CANCELLED = 0x8,
+  HIBERNATION_ENTRY = 0x9,
+  HIBERNATION_EXIT = 0xA,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl
new file mode 100644
index 0000000..db867f4
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleArea {
+  GLOBAL = 0x01000000,
+  WINDOW = 0x03000000,
+  MIRROR = 0x04000000,
+  SEAT = 0x05000000,
+  DOOR = 0x06000000,
+  WHEEL = 0x07000000,
+  MASK = 0x0f000000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
new file mode 100644
index 0000000..04976d6
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaDoor {
+  ROW_1_LEFT = 0x00000001,
+  ROW_1_RIGHT = 0x00000004,
+  ROW_2_LEFT = 0x00000010,
+  ROW_2_RIGHT = 0x00000040,
+  ROW_3_LEFT = 0x00000100,
+  ROW_3_RIGHT = 0x00000400,
+  HOOD = 0x10000000,
+  REAR = 0x20000000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
new file mode 100644
index 0000000..2d1c048
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaMirror {
+  DRIVER_LEFT = 0x00000001,
+  DRIVER_RIGHT = 0x00000002,
+  DRIVER_CENTER = 0x00000004,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
new file mode 100644
index 0000000..44c9d54
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaSeat {
+  ROW_1_LEFT = 0x0001,
+  ROW_1_CENTER = 0x0002,
+  ROW_1_RIGHT = 0x0004,
+  ROW_2_LEFT = 0x0010,
+  ROW_2_CENTER = 0x0020,
+  ROW_2_RIGHT = 0x0040,
+  ROW_3_LEFT = 0x0100,
+  ROW_3_CENTER = 0x0200,
+  ROW_3_RIGHT = 0x0400,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
new file mode 100644
index 0000000..d1b314e
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaWheel {
+  UNKNOWN = 0x0,
+  LEFT_FRONT = 0x1,
+  RIGHT_FRONT = 0x2,
+  LEFT_REAR = 0x4,
+  RIGHT_REAR = 0x8,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
new file mode 100644
index 0000000..2afcca3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaWindow {
+  FRONT_WINDSHIELD = 0x00000001,
+  REAR_WINDSHIELD = 0x00000002,
+  ROW_1_LEFT = 0x00000010,
+  ROW_1_RIGHT = 0x00000040,
+  ROW_2_LEFT = 0x00000100,
+  ROW_2_RIGHT = 0x00000400,
+  ROW_3_LEFT = 0x00001000,
+  ROW_3_RIGHT = 0x00004000,
+  ROOF_TOP_1 = 0x00010000,
+  ROOF_TOP_2 = 0x00020000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl
new file mode 100644
index 0000000..be335ec
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleDisplay {
+  MAIN = 0,
+  INSTRUMENT_CLUSTER = 1,
+  HUD = 2,
+  INPUT = 3,
+  AUXILIARY = 4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleGear.aidl
new file mode 100644
index 0000000..b8a299c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleGear.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleGear {
+  GEAR_UNKNOWN = 0x0000,
+  GEAR_NEUTRAL = 0x0001,
+  GEAR_REVERSE = 0x0002,
+  GEAR_PARK = 0x0004,
+  GEAR_DRIVE = 0x0008,
+  GEAR_1 = 0x0010,
+  GEAR_2 = 0x0020,
+  GEAR_3 = 0x0040,
+  GEAR_4 = 0x0080,
+  GEAR_5 = 0x0100,
+  GEAR_6 = 0x0200,
+  GEAR_7 = 0x0400,
+  GEAR_8 = 0x0800,
+  GEAR_9 = 0x1000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
new file mode 100644
index 0000000..4f9870a
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHvacFanDirection {
+  UNKNOWN = 0x0,
+  FACE = 0x1,
+  FLOOR = 0x2,
+  FACE_AND_FLOOR = 0x3,
+  DEFROST = 0x4,
+  DEFROST_AND_FLOOR = 0x06,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
new file mode 100644
index 0000000..29c5ed6
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionButtonStateFlag {
+  BUTTON_PRIMARY = 0x0001,
+  BUTTON_SECONDARY = 0x0002,
+  BUTTON_TERTIARY = 0x0004,
+  BUTTON_BACK = 0x0008,
+  BUTTON_FORWARD = 0x0010,
+  BUTTON_STYLUS_PRIMARY = 0x0020,
+  BUTTON_STYLUS_SECONDARY = 0x0040,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
new file mode 100644
index 0000000..db4b41e
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionInputAction {
+  ACTION_DOWN = 0,
+  ACTION_UP = 1,
+  ACTION_MOVE = 2,
+  ACTION_CANCEL = 3,
+  ACTION_OUTSIDE = 4,
+  ACTION_POINTER_DOWN = 5,
+  ACTION_POINTER_UP = 6,
+  ACTION_HOVER_MOVE = 7,
+  ACTION_SCROLL = 8,
+  ACTION_HOVER_ENTER = 9,
+  ACTION_HOVER_EXIT = 10,
+  ACTION_BUTTON_PRESS = 11,
+  ACTION_BUTTON_RELEASE = 12,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
new file mode 100644
index 0000000..88c7873
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionInputSource {
+  SOURCE_UNKNOWN = 0,
+  SOURCE_KEYBOARD = 1,
+  SOURCE_DPAD = 2,
+  SOURCE_GAMEPAD = 3,
+  SOURCE_TOUCHSCREEN = 4,
+  SOURCE_MOUSE = 5,
+  SOURCE_STYLUS = 6,
+  SOURCE_BLUETOOTH_STYLUS = 7,
+  SOURCE_TRACKBALL = 8,
+  SOURCE_MOUSE_RELATIVE = 9,
+  SOURCE_TOUCHPAD = 10,
+  SOURCE_TOUCH_NAVIGATION = 11,
+  SOURCE_ROTARY_ENCODER = 12,
+  SOURCE_JOYSTICK = 13,
+  SOURCE_HDMI = 14,
+  SOURCE_SENSOR = 15,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl
new file mode 100644
index 0000000..2b3bc7f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionToolType {
+  TOOL_TYPE_UNKNOWN = 0,
+  TOOL_TYPE_FINGER = 1,
+  TOOL_TYPE_STYLUS = 2,
+  TOOL_TYPE_MOUSE = 3,
+  TOOL_TYPE_ERASER = 4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
new file mode 100644
index 0000000..f572a12
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleIgnitionState {
+  UNDEFINED = 0,
+  LOCK = 1,
+  OFF,
+  ACC,
+  ON,
+  START,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
new file mode 100644
index 0000000..f244884
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleLightSwitch {
+  OFF = 0,
+  ON = 1,
+  DAYTIME_RUNNING = 2,
+  AUTOMATIC = 0x100,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
new file mode 100644
index 0000000..ba75e7b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -0,0 +1,273 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleProperty {
+  INVALID = 0x00000000,
+  INFO_VIN = (((0x0100 + 0x10000000) + 0x01000000) + 0x00100000) /* 286261504 */,
+  INFO_MAKE = (((0x0101 + 0x10000000) + 0x01000000) + 0x00100000) /* 286261505 */,
+  INFO_MODEL = (((0x0102 + 0x10000000) + 0x01000000) + 0x00100000) /* 286261506 */,
+  INFO_MODEL_YEAR = (((0x0103 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407235 */,
+  INFO_FUEL_CAPACITY = (((0x0104 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504388 */,
+  INFO_FUEL_TYPE = (((0x0105 + 0x10000000) + 0x01000000) + 0x00410000) /* 289472773 */,
+  INFO_EV_BATTERY_CAPACITY = (((0x0106 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504390 */,
+  INFO_EV_CONNECTOR_TYPE = (((0x0107 + 0x10000000) + 0x01000000) + 0x00410000) /* 289472775 */,
+  INFO_FUEL_DOOR_LOCATION = (((0x0108 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407240 */,
+  INFO_EV_PORT_LOCATION = (((0x0109 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407241 */,
+  INFO_DRIVER_SEAT = (((0x010A + 0x10000000) + 0x05000000) + 0x00400000) /* 356516106 */,
+  INFO_EXTERIOR_DIMENSIONS = (((0x010B + 0x10000000) + 0x01000000) + 0x00410000) /* 289472779 */,
+  INFO_MULTI_EV_PORT_LOCATIONS = (((0x010C + 0x10000000) + 0x01000000) + 0x00410000) /* 289472780 */,
+  PERF_ODOMETER = (((0x0204 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504644 */,
+  PERF_VEHICLE_SPEED = (((0x0207 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504647 */,
+  PERF_VEHICLE_SPEED_DISPLAY = (((0x0208 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504648 */,
+  PERF_STEERING_ANGLE = (((0x0209 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504649 */,
+  PERF_REAR_STEERING_ANGLE = (((0x0210 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504656 */,
+  ENGINE_COOLANT_TEMP = (((0x0301 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504897 */,
+  ENGINE_OIL_LEVEL = (((0x0303 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407747 */,
+  ENGINE_OIL_TEMP = (((0x0304 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504900 */,
+  ENGINE_RPM = (((0x0305 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504901 */,
+  WHEEL_TICK = (((0x0306 + 0x10000000) + 0x01000000) + 0x00510000) /* 290521862 */,
+  FUEL_LEVEL = (((0x0307 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504903 */,
+  FUEL_DOOR_OPEN = (((0x0308 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310600 */,
+  EV_BATTERY_LEVEL = (((0x0309 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504905 */,
+  EV_CURRENT_BATTERY_CAPACITY = (((0x030D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504909 */,
+  EV_CHARGE_PORT_OPEN = (((0x030A + 0x10000000) + 0x01000000) + 0x00200000) /* 287310602 */,
+  EV_CHARGE_PORT_CONNECTED = (((0x030B + 0x10000000) + 0x01000000) + 0x00200000) /* 287310603 */,
+  EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = (((0x030C + 0x10000000) + 0x01000000) + 0x00600000) /* 291504908 */,
+  RANGE_REMAINING = (((0x0308 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504904 */,
+  TIRE_PRESSURE = (((0x0309 + 0x10000000) + 0x07000000) + 0x00600000) /* 392168201 */,
+  CRITICALLY_LOW_TIRE_PRESSURE = (((0x030A + 0x10000000) + 0x07000000) + 0x00600000) /* 392168202 */,
+  ENGINE_IDLE_AUTO_STOP_ENABLED = (((0x0320 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310624 */,
+  GEAR_SELECTION = (((0x0400 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408000 */,
+  CURRENT_GEAR = (((0x0401 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408001 */,
+  PARKING_BRAKE_ON = (((0x0402 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310850 */,
+  PARKING_BRAKE_AUTO_APPLY = (((0x0403 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310851 */,
+  EV_BRAKE_REGENERATION_LEVEL = (((0x040C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408012 */,
+  FUEL_LEVEL_LOW = (((0x0405 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310853 */,
+  NIGHT_MODE = (((0x0407 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310855 */,
+  TURN_SIGNAL_STATE = (((0x0408 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408008 */,
+  IGNITION_STATE = (((0x0409 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408009 */,
+  ABS_ACTIVE = (((0x040A + 0x10000000) + 0x01000000) + 0x00200000) /* 287310858 */,
+  TRACTION_CONTROL_ACTIVE = (((0x040B + 0x10000000) + 0x01000000) + 0x00200000) /* 287310859 */,
+  EV_STOPPING_MODE = (((0x040D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408013 */,
+  HVAC_FAN_SPEED = (((0x0500 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517120 */,
+  HVAC_FAN_DIRECTION = (((0x0501 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517121 */,
+  HVAC_TEMPERATURE_CURRENT = (((0x0502 + 0x10000000) + 0x05000000) + 0x00600000) /* 358614274 */,
+  HVAC_TEMPERATURE_SET = (((0x0503 + 0x10000000) + 0x05000000) + 0x00600000) /* 358614275 */,
+  HVAC_DEFROSTER = (((0x0504 + 0x10000000) + 0x03000000) + 0x00200000) /* 320865540 */,
+  HVAC_AC_ON = (((0x0505 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419973 */,
+  HVAC_MAX_AC_ON = (((0x0506 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419974 */,
+  HVAC_MAX_DEFROST_ON = (((0x0507 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419975 */,
+  HVAC_RECIRC_ON = (((0x0508 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419976 */,
+  HVAC_DUAL_ON = (((0x0509 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419977 */,
+  HVAC_AUTO_ON = (((0x050A + 0x10000000) + 0x05000000) + 0x00200000) /* 354419978 */,
+  HVAC_SEAT_TEMPERATURE = (((0x050B + 0x10000000) + 0x05000000) + 0x00400000) /* 356517131 */,
+  HVAC_SIDE_MIRROR_HEAT = (((0x050C + 0x10000000) + 0x04000000) + 0x00400000) /* 339739916 */,
+  HVAC_STEERING_WHEEL_HEAT = (((0x050D + 0x10000000) + 0x01000000) + 0x00400000) /* 289408269 */,
+  HVAC_TEMPERATURE_DISPLAY_UNITS = (((0x050E + 0x10000000) + 0x01000000) + 0x00400000) /* 289408270 */,
+  HVAC_ACTUAL_FAN_SPEED_RPM = (((0x050F + 0x10000000) + 0x05000000) + 0x00400000) /* 356517135 */,
+  HVAC_POWER_ON = (((0x0510 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419984 */,
+  HVAC_FAN_DIRECTION_AVAILABLE = (((0x0511 + 0x10000000) + 0x05000000) + 0x00410000) /* 356582673 */,
+  HVAC_AUTO_RECIRC_ON = (((0x0512 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419986 */,
+  HVAC_SEAT_VENTILATION = (((0x0513 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517139 */,
+  HVAC_ELECTRIC_DEFROSTER_ON = (((0x0514 + 0x10000000) + 0x03000000) + 0x00200000) /* 320865556 */,
+  HVAC_TEMPERATURE_VALUE_SUGGESTION = (((0x0515 + 0x10000000) + 0x01000000) + 0x00610000) /* 291570965 */,
+  DISTANCE_DISPLAY_UNITS = (((0x0600 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408512 */,
+  FUEL_VOLUME_DISPLAY_UNITS = (((0x0601 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408513 */,
+  TIRE_PRESSURE_DISPLAY_UNITS = (((0x0602 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408514 */,
+  EV_BATTERY_DISPLAY_UNITS = (((0x0603 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408515 */,
+  FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = (((0x0604 + 0x10000000) + 0x01000000) + 0x00200000) /* 287311364 */,
+  VEHICLE_SPEED_DISPLAY_UNITS = (((0x0605 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408517 */,
+  EXTERNAL_CAR_TIME = (((0x0608 + 0x10000000) + 0x01000000) + 0x00500000) /* 290457096 */,
+  ANDROID_EPOCH_TIME = (((0x0606 + 0x10000000) + 0x01000000) + 0x00500000) /* 290457094 */,
+  STORAGE_ENCRYPTION_BINDING_SEED = (((0x0607 + 0x10000000) + 0x01000000) + 0x00700000) /* 292554247 */,
+  ENV_OUTSIDE_TEMPERATURE = (((0x0703 + 0x10000000) + 0x01000000) + 0x00600000) /* 291505923 */,
+  AP_POWER_STATE_REQ = (((0x0A00 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475072 */,
+  AP_POWER_STATE_REPORT = (((0x0A01 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475073 */,
+  AP_POWER_BOOTUP_REASON = (((0x0A02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409538 */,
+  DISPLAY_BRIGHTNESS = (((0x0A03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409539 */,
+  PER_DISPLAY_BRIGHTNESS = (((0x0A04 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475076 */,
+  HW_KEY_INPUT = (((0x0A10 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475088 */,
+  HW_KEY_INPUT_V2 = (((0x0A11 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004177 */,
+  HW_MOTION_INPUT = (((0x0A12 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004178 */,
+  HW_ROTARY_INPUT = (((0x0A20 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475104 */,
+  HW_CUSTOM_INPUT = (((0X0A30 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475120 */,
+  DOOR_POS = (((0x0B00 + 0x10000000) + 0x06000000) + 0x00400000) /* 373295872 */,
+  DOOR_MOVE = (((0x0B01 + 0x10000000) + 0x06000000) + 0x00400000) /* 373295873 */,
+  DOOR_LOCK = (((0x0B02 + 0x10000000) + 0x06000000) + 0x00200000) /* 371198722 */,
+  DOOR_CHILD_LOCK_ENABLED = (((0x0B03 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.DOOR) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 371198723 */,
+  MIRROR_Z_POS = (((0x0B40 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741504 */,
+  MIRROR_Z_MOVE = (((0x0B41 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741505 */,
+  MIRROR_Y_POS = (((0x0B42 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741506 */,
+  MIRROR_Y_MOVE = (((0x0B43 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741507 */,
+  MIRROR_LOCK = (((0x0B44 + 0x10000000) + 0x01000000) + 0x00200000) /* 287312708 */,
+  MIRROR_FOLD = (((0x0B45 + 0x10000000) + 0x01000000) + 0x00200000) /* 287312709 */,
+  MIRROR_AUTO_FOLD_ENABLED = (((0x0B46 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.MIRROR) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 337644358 */,
+  MIRROR_AUTO_TILT_ENABLED = (((0x0B47 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.MIRROR) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 337644359 */,
+  SEAT_MEMORY_SELECT = (((0x0B80 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518784 */,
+  SEAT_MEMORY_SET = (((0x0B81 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518785 */,
+  SEAT_BELT_BUCKLED = (((0x0B82 + 0x10000000) + 0x05000000) + 0x00200000) /* 354421634 */,
+  SEAT_BELT_HEIGHT_POS = (((0x0B83 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518787 */,
+  SEAT_BELT_HEIGHT_MOVE = (((0x0B84 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518788 */,
+  SEAT_FORE_AFT_POS = (((0x0B85 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518789 */,
+  SEAT_FORE_AFT_MOVE = (((0x0B86 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518790 */,
+  SEAT_BACKREST_ANGLE_1_POS = (((0x0B87 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518791 */,
+  SEAT_BACKREST_ANGLE_1_MOVE = (((0x0B88 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518792 */,
+  SEAT_BACKREST_ANGLE_2_POS = (((0x0B89 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518793 */,
+  SEAT_BACKREST_ANGLE_2_MOVE = (((0x0B8A + 0x10000000) + 0x05000000) + 0x00400000) /* 356518794 */,
+  SEAT_HEIGHT_POS = (((0x0B8B + 0x10000000) + 0x05000000) + 0x00400000) /* 356518795 */,
+  SEAT_HEIGHT_MOVE = (((0x0B8C + 0x10000000) + 0x05000000) + 0x00400000) /* 356518796 */,
+  SEAT_DEPTH_POS = (((0x0B8D + 0x10000000) + 0x05000000) + 0x00400000) /* 356518797 */,
+  SEAT_DEPTH_MOVE = (((0x0B8E + 0x10000000) + 0x05000000) + 0x00400000) /* 356518798 */,
+  SEAT_TILT_POS = (((0x0B8F + 0x10000000) + 0x05000000) + 0x00400000) /* 356518799 */,
+  SEAT_TILT_MOVE = (((0x0B90 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518800 */,
+  SEAT_LUMBAR_FORE_AFT_POS = (((0x0B91 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518801 */,
+  SEAT_LUMBAR_FORE_AFT_MOVE = (((0x0B92 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518802 */,
+  SEAT_LUMBAR_SIDE_SUPPORT_POS = (((0x0B93 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518803 */,
+  SEAT_LUMBAR_SIDE_SUPPORT_MOVE = (((0x0B94 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518804 */,
+  SEAT_HEADREST_HEIGHT_POS = (((0x0B95 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409941 */,
+  SEAT_HEADREST_HEIGHT_POS_V2 = (((0x0BA4 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518820 */,
+  SEAT_HEADREST_HEIGHT_MOVE = (((0x0B96 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518806 */,
+  SEAT_HEADREST_ANGLE_POS = (((0x0B97 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518807 */,
+  SEAT_HEADREST_ANGLE_MOVE = (((0x0B98 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518808 */,
+  SEAT_HEADREST_FORE_AFT_POS = (((0x0B99 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518809 */,
+  SEAT_HEADREST_FORE_AFT_MOVE = (((0x0B9A + 0x10000000) + 0x05000000) + 0x00400000) /* 356518810 */,
+  SEAT_FOOTWELL_LIGHTS_STATE = (((0x0B9B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518811 */,
+  SEAT_FOOTWELL_LIGHTS_SWITCH = (((0x0B9C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518812 */,
+  SEAT_EASY_ACCESS_ENABLED = (((0x0B9D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421661 */,
+  SEAT_AIRBAG_ENABLED = (((0x0B9E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421662 */,
+  SEAT_CUSHION_SIDE_SUPPORT_POS = (((0x0B9F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518815 */,
+  SEAT_CUSHION_SIDE_SUPPORT_MOVE = (((0x0BA0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518816 */,
+  SEAT_LUMBAR_VERTICAL_POS = (((0x0BA1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518817 */,
+  SEAT_LUMBAR_VERTICAL_MOVE = (((0x0BA2 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518818 */,
+  SEAT_WALK_IN_POS = (((0x0BA3 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518819 */,
+  SEAT_OCCUPANCY = (((0x0BB0 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518832 */,
+  WINDOW_POS = (((0x0BC0 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964416 */,
+  WINDOW_MOVE = (((0x0BC1 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964417 */,
+  WINDOW_LOCK = (((0x0BC4 + 0x10000000) + 0x03000000) + 0x00200000) /* 320867268 */,
+  WINDSHIELD_WIPERS_PERIOD = (((0x0BC5 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WINDOW) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 322964421 */,
+  WINDSHIELD_WIPERS_STATE = (((0x0BC6 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WINDOW) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 322964422 */,
+  WINDSHIELD_WIPERS_SWITCH = (((0x0BC7 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WINDOW) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 322964423 */,
+  STEERING_WHEEL_DEPTH_POS = (((0x0BE0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410016 */,
+  STEERING_WHEEL_DEPTH_MOVE = (((0x0BE1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410017 */,
+  STEERING_WHEEL_HEIGHT_POS = (((0x0BE2 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410018 */,
+  STEERING_WHEEL_HEIGHT_MOVE = (((0x0BE3 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410019 */,
+  STEERING_WHEEL_THEFT_LOCK_ENABLED = (((0x0BE4 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312868 */,
+  STEERING_WHEEL_LOCKED = (((0x0BE5 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312869 */,
+  STEERING_WHEEL_EASY_ACCESS_ENABLED = (((0x0BE6 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312870 */,
+  GLOVE_BOX_DOOR_POS = (((0x0BF0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518896 */,
+  GLOVE_BOX_LOCKED = (((0x0BF1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421745 */,
+  VEHICLE_MAP_SERVICE = (((0x0C00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299895808 */,
+  LOCATION_CHARACTERIZATION = (((0x0C10 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410064 */,
+  OBD2_LIVE_FRAME = (((0x0D00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896064 */,
+  OBD2_FREEZE_FRAME = (((0x0D01 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896065 */,
+  OBD2_FREEZE_FRAME_INFO = (((0x0D02 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896066 */,
+  OBD2_FREEZE_FRAME_CLEAR = (((0x0D03 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896067 */,
+  HEADLIGHTS_STATE = (((0x0E00 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410560 */,
+  HIGH_BEAM_LIGHTS_STATE = (((0x0E01 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410561 */,
+  FOG_LIGHTS_STATE = (((0x0E02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410562 */,
+  HAZARD_LIGHTS_STATE = (((0x0E03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410563 */,
+  HEADLIGHTS_SWITCH = (((0x0E10 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410576 */,
+  HIGH_BEAM_LIGHTS_SWITCH = (((0x0E11 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410577 */,
+  FOG_LIGHTS_SWITCH = (((0x0E12 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410578 */,
+  HAZARD_LIGHTS_SWITCH = (((0x0E13 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410579 */,
+  CABIN_LIGHTS_STATE = (((0x0F01 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410817 */,
+  CABIN_LIGHTS_SWITCH = (((0x0F02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410818 */,
+  READING_LIGHTS_STATE = (((0x0F03 + 0x10000000) + 0x05000000) + 0x00400000) /* 356519683 */,
+  READING_LIGHTS_SWITCH = (((0x0F04 + 0x10000000) + 0x05000000) + 0x00400000) /* 356519684 */,
+  STEERING_WHEEL_LIGHTS_STATE = (((0x0F0C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410828 */,
+  STEERING_WHEEL_LIGHTS_SWITCH = (((0x0F0D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410829 */,
+  SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = (((0x0F05 + 0x10000000) + 0x01000000) + 0x00200000) /* 287313669 */,
+  DISABLED_OPTIONAL_FEATURES = (((0x0F06 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265094 */,
+  INITIAL_USER_INFO = (((0x0F07 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896583 */,
+  SWITCH_USER = (((0x0F08 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896584 */,
+  CREATE_USER = (((0x0F09 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896585 */,
+  REMOVE_USER = (((0x0F0A + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896586 */,
+  USER_IDENTIFICATION_ASSOCIATION = (((0x0F0B + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896587 */,
+  EVS_SERVICE_REQUEST = (((0x0F10 + 0x10000000) + 0x01000000) + 0x00410000) /* 289476368 */,
+  POWER_POLICY_REQ = (((0x0F21 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265121 */,
+  POWER_POLICY_GROUP_REQ = (((0x0F22 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265122 */,
+  CURRENT_POWER_POLICY = (((0x0F23 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265123 */,
+  WATCHDOG_ALIVE = (((0xF31 + 0x10000000) + 0x01000000) + 0x00500000) /* 290459441 */,
+  WATCHDOG_TERMINATED_PROCESS = (((0x0F32 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896626 */,
+  VHAL_HEARTBEAT = (((0x0F33 + 0x10000000) + 0x01000000) + 0x00500000) /* 290459443 */,
+  CLUSTER_SWITCH_UI = (((0x0F34 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410868 */,
+  CLUSTER_DISPLAY_STATE = (((0x0F35 + 0x10000000) + 0x01000000) + 0x00410000) /* 289476405 */,
+  CLUSTER_REPORT_STATE = (((0x0F36 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896630 */,
+  CLUSTER_REQUEST_DISPLAY = (((0x0F37 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410871 */,
+  CLUSTER_NAVIGATION_STATE = (((0x0F38 + 0x10000000) + 0x01000000) + 0x00700000) /* 292556600 */,
+  ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = (((0x0F39 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410873 */,
+  ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = (((0x0F3A + 0x10000000) + 0x01000000) + 0x00400000) /* 289410874 */,
+  FRONT_FOG_LIGHTS_STATE = (((0x0F3B + 0x10000000) + 0x01000000) + 0x00400000) /* 289410875 */,
+  FRONT_FOG_LIGHTS_SWITCH = (((0x0F3C + 0x10000000) + 0x01000000) + 0x00400000) /* 289410876 */,
+  REAR_FOG_LIGHTS_STATE = (((0x0F3D + 0x10000000) + 0x01000000) + 0x00400000) /* 289410877 */,
+  REAR_FOG_LIGHTS_SWITCH = (((0x0F3E + 0x10000000) + 0x01000000) + 0x00400000) /* 289410878 */,
+  EV_CHARGE_CURRENT_DRAW_LIMIT = (((0x0F3F + 0x10000000) + 0x01000000) + 0x00600000) /* 291508031 */,
+  EV_CHARGE_PERCENT_LIMIT = (((0x0F40 + 0x10000000) + 0x01000000) + 0x00600000) /* 291508032 */,
+  EV_CHARGE_STATE = (((0x0F41 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410881 */,
+  EV_CHARGE_SWITCH = (((0x0F42 + 0x10000000) + 0x01000000) + 0x00200000) /* 287313730 */,
+  EV_CHARGE_TIME_REMAINING = (((0x0F43 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410883 */,
+  EV_REGENERATIVE_BRAKING_STATE = (((0x0F44 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410884 */,
+  TRAILER_PRESENT = (((0x0F45 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410885 */,
+  VEHICLE_CURB_WEIGHT = (((0x0F46 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410886 */,
+  GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = (((0x0F47 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410887 */,
+  SUPPORTED_PROPERTY_IDS = (((0x0F48 + 0x10000000) + 0x01000000) + 0x00410000) /* 289476424 */,
+  SHUTDOWN_REQUEST = (((0x0F49 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410889 */,
+  VEHICLE_IN_USE = (((0x0F4A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313738 */,
+  AUTOMATIC_EMERGENCY_BRAKING_ENABLED = (((0x1000 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313920 */,
+  AUTOMATIC_EMERGENCY_BRAKING_STATE = (((0x1001 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411073 */,
+  FORWARD_COLLISION_WARNING_ENABLED = (((0x1002 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313922 */,
+  FORWARD_COLLISION_WARNING_STATE = (((0x1003 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411075 */,
+  BLIND_SPOT_WARNING_ENABLED = (((0x1004 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313924 */,
+  BLIND_SPOT_WARNING_STATE = (((0x1005 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.MIRROR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 339742725 */,
+  LANE_DEPARTURE_WARNING_ENABLED = (((0x1006 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313926 */,
+  LANE_DEPARTURE_WARNING_STATE = (((0x1007 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411079 */,
+  LANE_KEEP_ASSIST_ENABLED = (((0x1008 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313928 */,
+  LANE_KEEP_ASSIST_STATE = (((0x1009 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411081 */,
+  LANE_CENTERING_ASSIST_ENABLED = (((0x100A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313930 */,
+  LANE_CENTERING_ASSIST_COMMAND = (((0x100B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411083 */,
+  LANE_CENTERING_ASSIST_STATE = (((0x100C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411084 */,
+  EMERGENCY_LANE_KEEP_ASSIST_ENABLED = (((0x100D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313933 */,
+  EMERGENCY_LANE_KEEP_ASSIST_STATE = (((0x100E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411086 */,
+  CRUISE_CONTROL_ENABLED = (((0x100F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313935 */,
+  CRUISE_CONTROL_TYPE = (((0x1010 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411088 */,
+  CRUISE_CONTROL_STATE = (((0x1011 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411089 */,
+  CRUISE_CONTROL_COMMAND = (((0x1012 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411090 */,
+  CRUISE_CONTROL_TARGET_SPEED = (((0x1013 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291508243 */,
+  ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP = (((0x1014 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411092 */,
+  ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE = (((0x1015 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411093 */,
+  HANDS_ON_DETECTION_ENABLED = (((0x1016 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313942 */,
+  HANDS_ON_DETECTION_DRIVER_STATE = (((0x1017 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411095 */,
+  HANDS_ON_DETECTION_WARNING = (((0x1018 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411096 */,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
new file mode 100644
index 0000000..714d514
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehiclePropertyGroup {
+  SYSTEM = 0x10000000,
+  VENDOR = 0x20000000,
+  MASK = 0xf0000000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
new file mode 100644
index 0000000..7525cbb
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehiclePropertyType {
+  STRING = 0x00100000,
+  BOOLEAN = 0x00200000,
+  INT32 = 0x00400000,
+  INT32_VEC = 0x00410000,
+  INT64 = 0x00500000,
+  INT64_VEC = 0x00510000,
+  FLOAT = 0x00600000,
+  FLOAT_VEC = 0x00610000,
+  BYTES = 0x00700000,
+  MIXED = 0x00e00000,
+  MASK = 0x00ff0000,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
new file mode 100644
index 0000000..0431b45
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleTurnSignal {
+  NONE = 0x00,
+  RIGHT = 0x01,
+  LEFT = 0x02,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleUnit.aidl
new file mode 100644
index 0000000..9aca98b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleUnit.aidl
@@ -0,0 +1,71 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleUnit {
+  SHOULD_NOT_USE = 0x000,
+  METER_PER_SEC = 0x01,
+  RPM = 0x02,
+  HERTZ = 0x03,
+  PERCENTILE = 0x10,
+  MILLIMETER = 0x20,
+  METER = 0x21,
+  KILOMETER = 0x23,
+  MILE = 0x24,
+  CELSIUS = 0x30,
+  FAHRENHEIT = 0x31,
+  KELVIN = 0x32,
+  MILLILITER = 0x40,
+  LITER = 0x41,
+  GALLON = 0x42,
+  US_GALLON = 0x42,
+  IMPERIAL_GALLON = 0x43,
+  NANO_SECS = 0x50,
+  MILLI_SECS = 0x51,
+  SECS = 0x53,
+  YEAR = 0x59,
+  WATT_HOUR = 0x60,
+  MILLIAMPERE = 0x61,
+  MILLIVOLT = 0x62,
+  MILLIWATTS = 0x63,
+  AMPERE_HOURS = 0x64,
+  KILOWATT_HOUR = 0x65,
+  AMPERE = 0x66,
+  KILOPASCAL = 0x70,
+  PSI = 0x71,
+  BAR = 0x72,
+  DEGREES = 0x80,
+  MILES_PER_HOUR = 0x90,
+  KILOMETERS_PER_HOUR = 0x91,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
new file mode 100644
index 0000000..3aa326c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
@@ -0,0 +1,75 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleVendorPermission {
+  PERMISSION_DEFAULT = 0x00000000,
+  PERMISSION_SET_VENDOR_CATEGORY_WINDOW = 0X00000001,
+  PERMISSION_GET_VENDOR_CATEGORY_WINDOW = 0x00000002,
+  PERMISSION_SET_VENDOR_CATEGORY_DOOR = 0x00000003,
+  PERMISSION_GET_VENDOR_CATEGORY_DOOR = 0x00000004,
+  PERMISSION_SET_VENDOR_CATEGORY_SEAT = 0x00000005,
+  PERMISSION_GET_VENDOR_CATEGORY_SEAT = 0x00000006,
+  PERMISSION_SET_VENDOR_CATEGORY_MIRROR = 0x00000007,
+  PERMISSION_GET_VENDOR_CATEGORY_MIRROR = 0x00000008,
+  PERMISSION_SET_VENDOR_CATEGORY_INFO = 0x00000009,
+  PERMISSION_GET_VENDOR_CATEGORY_INFO = 0x0000000A,
+  PERMISSION_SET_VENDOR_CATEGORY_ENGINE = 0x0000000B,
+  PERMISSION_GET_VENDOR_CATEGORY_ENGINE = 0x0000000C,
+  PERMISSION_SET_VENDOR_CATEGORY_HVAC = 0x0000000D,
+  PERMISSION_GET_VENDOR_CATEGORY_HVAC = 0x0000000E,
+  PERMISSION_SET_VENDOR_CATEGORY_LIGHT = 0x0000000F,
+  PERMISSION_GET_VENDOR_CATEGORY_LIGHT = 0x00000010,
+  PERMISSION_SET_VENDOR_CATEGORY_1 = 0x00010000,
+  PERMISSION_GET_VENDOR_CATEGORY_1 = 0x00011000,
+  PERMISSION_SET_VENDOR_CATEGORY_2 = 0x00020000,
+  PERMISSION_GET_VENDOR_CATEGORY_2 = 0x00021000,
+  PERMISSION_SET_VENDOR_CATEGORY_3 = 0x00030000,
+  PERMISSION_GET_VENDOR_CATEGORY_3 = 0x00031000,
+  PERMISSION_SET_VENDOR_CATEGORY_4 = 0x00040000,
+  PERMISSION_GET_VENDOR_CATEGORY_4 = 0x00041000,
+  PERMISSION_SET_VENDOR_CATEGORY_5 = 0x00050000,
+  PERMISSION_GET_VENDOR_CATEGORY_5 = 0x00051000,
+  PERMISSION_SET_VENDOR_CATEGORY_6 = 0x00060000,
+  PERMISSION_GET_VENDOR_CATEGORY_6 = 0x00061000,
+  PERMISSION_SET_VENDOR_CATEGORY_7 = 0x00070000,
+  PERMISSION_GET_VENDOR_CATEGORY_7 = 0x00071000,
+  PERMISSION_SET_VENDOR_CATEGORY_8 = 0x00080000,
+  PERMISSION_GET_VENDOR_CATEGORY_8 = 0x00081000,
+  PERMISSION_SET_VENDOR_CATEGORY_9 = 0x00090000,
+  PERMISSION_GET_VENDOR_CATEGORY_9 = 0x00091000,
+  PERMISSION_SET_VENDOR_CATEGORY_10 = 0x000A0000,
+  PERMISSION_GET_VENDOR_CATEGORY_10 = 0x000A1000,
+  PERMISSION_NOT_ACCESSIBLE = 0xF0000000,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
new file mode 100644
index 0000000..d0c1e8d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum WindshieldWipersState {
+  OTHER = 0,
+  OFF = 1,
+  ON = 2,
+  SERVICE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
new file mode 100644
index 0000000..6c170fe
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum WindshieldWipersSwitch {
+  OTHER = 0,
+  OFF = 1,
+  MIST = 2,
+  INTERMITTENT_LEVEL_1 = 3,
+  INTERMITTENT_LEVEL_2 = 4,
+  INTERMITTENT_LEVEL_3 = 5,
+  INTERMITTENT_LEVEL_4 = 6,
+  INTERMITTENT_LEVEL_5 = 7,
+  CONTINUOUS_LEVEL_1 = 8,
+  CONTINUOUS_LEVEL_2 = 9,
+  CONTINUOUS_LEVEL_3 = 10,
+  CONTINUOUS_LEVEL_4 = 11,
+  CONTINUOUS_LEVEL_5 = 12,
+  AUTO = 13,
+  SERVICE = 14,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
new file mode 100644
index 0000000..540c663
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Automatic Emergency Braking (AEB).
+ */
+@VintfStability
+@Backing(type="int")
+enum AutomaticEmergencyBrakingState {
+
+    /**
+     * This state is used as an alternative to any AutomaticEmergencyBrakingState value that is not
+     * defined in the platform. Ideally, implementations of
+     * VehicleProperty#AUTOMATIC_EMERGENCY_BRAKING_STATE should not use this state. The framework
+     * can use this field to remain backwards compatible if AutomaticEmergencyBrakingState is
+     * extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * AEB is enabled and monitoring safety, but brakes are not activated.
+     */
+    ENABLED = 1,
+    /**
+     * AEB is enabled and currently has the brakes applied for the vehicle.
+     */
+    ACTIVATED = 2,
+    /**
+     * Many AEB implementations allow the driver to override AEB. This means that the car has
+     * determined it should brake, but a user decides to take over and do something else. This is
+     * often done for safety reasons and to ensure that the driver can always take control of the
+     * vehicle. This state should be set when the user is actively overriding the AEB system.
+     */
+    USER_OVERRIDE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
new file mode 100644
index 0000000..3f567c0
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Blind Spot Warning State (BSW).
+ */
+@VintfStability
+@Backing(type="int")
+enum BlindSpotWarningState {
+
+    /**
+     * This state is used as an alternative to any BlindSpotWarningState value that is not
+     * defined in the platform. Ideally, implementations of
+     * VehicleProperty#BLIND_SPOT_WARNING_STATE should not use this state. The framework
+     * can use this field to remain backwards compatible if BlindSpotWarningState is
+     * extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * BSW is enabled and monitoring safety, but no vehicle or object detected in the vehicle's
+     * blind spot.
+     */
+    NO_WARNING = 1,
+    /**
+     * BSW is enabled, detects a vehicle or object in the vehicle's blind spot, and is actively
+     * warning the user.
+     */
+    WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserResponse.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserStatus.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
new file mode 100644
index 0000000..18e1405
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the Cruise Control (CC) commands.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum CruiseControlCommand {
+    /**
+     * Activate cruise control, which means CC takes control of maintaining the vehicle's target
+     * speed without the driver having to keep their foot on the accelerator. The target speed for
+     * CC is generally set to the vehicle's speed at the time of activation.
+     */
+    ACTIVATE = 1,
+    /**
+     * Suspend cruise control, but still keep it enabled. Once CC is activated again, the
+     * target speed should resume to the previous setting.
+     */
+    SUSPEND = 2,
+    /**
+     * Increase the target speed when CC is activated. The increment value should be decided by the
+     * OEM. The updated value can be read from CRUISE_CONTROL_TARGET_SPEED.
+     */
+    INCREASE_TARGET_SPEED = 3,
+    /**
+     * Decrease the target speed when CC is activated. The decrement value should be decided by the
+     * OEM. The updated value can be read from CRUISE_CONTROL_TARGET_SPEED.
+     */
+    DECREASE_TARGET_SPEED = 4,
+    /**
+     * Increase the target time gap or distance from the vehicle ahead when adaptive/predictive CC
+     * is activated. The increment value should be decided by the OEM. The updated value can be read
+     * from ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP. Setting this command on a standard CC vehicle
+     * should return StatusCode.NOT_AVAILABLE.
+     */
+    INCREASE_TARGET_TIME_GAP = 5,
+    /**
+     * Decrease the target time gap or distance from the vehicle ahead when adaptive/predictive CC
+     * is activated. The decrement value should be decided by the 0EM. The updated value can be read
+     * from ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP. Setting this command on a standard CC vehicle
+     * should return StatusCode.NOT_AVAILABLE.
+     */
+    DECREASE_TARGET_TIME_GAP = 6,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl
new file mode 100644
index 0000000..0e55e00
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of Cruise Control (CC).
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum CruiseControlState {
+    /**
+     * This state is used as an alternative for any CruiseControlState value that is not defined in
+     * the platform. Ideally, implementations of VehicleProperty#CRUISE_CONTROL_STATE should not use
+     * this state. The framework can use this field to remain backwards compatible if
+     * CruiseControlState is extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * CC is enabled but the ADAS system is not actively controlling the vehicle's speed.
+     */
+    ENABLED = 1,
+    /**
+     * CC is enabled and activated, so the ADAS system is actively controlling the vehicle's speed.
+     */
+    ACTIVATED = 2,
+    /**
+     * Most CC implementations allow the driver to override CC. This means that the car has
+     * determined it should maintain a certain speed and/or maintain a certain distance from a
+     * leading vehicle, but the driver decides to take over and do something else. This is often
+     * done for safety reasons and to ensure that the driver can always take control of the vehicle.
+     * This state should be set when the user is actively overriding the CC system.
+     */
+    USER_OVERRIDE = 3,
+    /**
+     * Suspended state indicates CC is enabled and was activated, but now is suspended. This could
+     * be caused by the user tapping the brakes while CC is ACTIVATED or the user using the
+     * VehicleProperty#CRUISE_CONTROL_COMMAND to suspend CC. Once CC is suspended, the CC system
+     * gives control of the vehicle back to the driver, but saves the target speed and/or target
+     * time gap settings in case CC is resumed. This state can also be used when adaptive/predictive
+     * CC slows to a stop and needs a user signal to start again.
+     */
+    SUSPENDED = 4,
+    /**
+     * When CC is in the ACTIVATED state but may potentially need to deactivate because of external
+     * conditions (e.g. roads curvature is too extreme, the driver does not have their hands on the
+     * steering wheel for a long period of time, or the driver is not paying attention), then the
+     * ADAS system will notify the driver of a potential need to deactivate and give control back to
+     * the driver.
+     */
+    FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.aidl
new file mode 100644
index 0000000..2367b82
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current type of Cruise Control (CC).
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum CruiseControlType {
+    /**
+     * This state is used as an alternative for any CruiseControlType value that is not defined in
+     * the platform. Ideally, implementations of VehicleProperty#CRUISE_CONTROL_TYPE should not use
+     * this state. The framework can use this field to remain backwards compatible if
+     * CruiseControlType is extended to include additional types.
+     */
+    OTHER = 0,
+    /**
+     * Standard cruise control is when a system in the vehicle automatically maintains a set speed
+     * without the driver having to keep their foot on the accelerator. This version of cruise
+     * control does not include automatic acceleration and deceleration to maintain a set time gap
+     * from a vehicle ahead.
+     */
+    STANDARD = 1,
+    /**
+     * Adaptive cruise control is when a system in the vehicle automatically accelerates and
+     * decelerates to maintain a set speed and/or a set time gap from a vehicle ahead.
+     */
+    ADAPTIVE = 2,
+    /**
+     * Predictive cruise control is a version of adaptive cruise control that also considers road
+     * topography, road curvature, speed limit and traffic signs, etc. to actively adjust braking,
+     * acceleration, gear shifting, etc. for the vehicle. This feature is often used to optimize
+     * fuel consumption.
+     */
+    PREDICTIVE = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CustomInputType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CustomInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/CustomInputType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CustomInputType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
new file mode 100644
index 0000000..302b9af
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by emergency lane keep assist to enumerate state.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum EmergencyLaneKeepAssistState {
+    /**
+     * This state is used as an alternative for any EmergencyLaneKeepAssistState value that is not
+     * defined in the platform. Ideally, implementations of
+     * VehicleProperty#EMERGENCY_LANE_KEEP_ASSIST_STATE should not use this state. The framework can
+     * use this field to remain backwards compatible if EmergencyLaneKeepAssistState is extended to
+     * include additional states.
+     */
+    OTHER = 0,
+    /**
+     * ELKA is enabled and monitoring safety, but no safety event is detected and steering assist is
+     * not activated.
+     */
+    ENABLED = 1,
+    /**
+     * ELKA is enabled and a safety event is detected. Vehicle is sending out a warning to the
+     * driver indicating that there is a dangerous maneuver on the left side of the vehicle.
+     */
+    WARNING_LEFT = 2,
+    /**
+     * ELKA is enabled and a safety event is detected. Vehicle is sending out a warning to the
+     * driver indicating that there is a dangerous maneuver on the right side of the vehicle.
+     */
+    WARNING_RIGHT = 3,
+    /**
+     * ELKA is enabled and currently has steering assist applied to the vehicle. Steering assist
+     * nudges the vehicle towards the left, which generally means the steering wheel turns counter
+     * clockwise. This is usually in response to the driver making an unsafe right lane change.
+     */
+    ACTIVATED_STEER_LEFT = 4,
+    /**
+     * ELKA is enabled and currently has steering assist applied to the vehicle. Steering assist
+     * nudges the vehicle towards the right, which generally means the steering wheel turns
+     * clockwise. This is usually in response to the driver making an unsafe left lane change.
+     */
+    ACTIVATED_STEER_RIGHT = 5,
+    /**
+     * Many safety feature implementations allow the driver to override said feature. This means
+     * that the car has determined it should take some action, but a user decides to take over and
+     * do something else. This is often done for safety reasons and to ensure that the driver can
+     * always take control of the vehicle. This state should be set when the user is currently
+     * overriding ELKA.
+     */
+    USER_OVERRIDE = 6,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl
new file mode 100644
index 0000000..ba44672
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the possible error states. For version 2 of this interface, ErrorState is used
+ * by ADAS STATE properties, but its use may be expanded in future releases.
+ */
+@VintfStability
+@Backing(type="int")
+enum ErrorState {
+
+    /**
+     * This state is used as an alternative to any ErrorState value that is not defined in the
+     * platform. Ideally, implementations of vehicle properties should not use this state. The
+     * framework can use this field to remain backwards compatible if this enum is extended to
+     * include additional states.
+     */
+    OTHER_ERROR_STATE = -1,
+    /**
+     * Vehicle property is not available because the feature is disabled.
+     */
+    NOT_AVAILABLE_DISABLED = -2,
+    /**
+     * Vehicle property is not available because the vehicle speed is too low to use this feature.
+     */
+    NOT_AVAILABLE_SPEED_LOW = -3,
+    /**
+     * Vehicle property is not available because the vehicle speed is too high to use this feature.
+     */
+    NOT_AVAILABLE_SPEED_HIGH = -4,
+    /**
+     * Vehicle property is not available because sensor or camera visibility is insufficient to use
+     * this feature. For example, this can be caused by bird poop blocking the camera, poor weather
+     * conditions such as snow or fog, or by any object obstructing the required sensors.
+     */
+    NOT_AVAILABLE_POOR_VISIBILITY = -5,
+    /**
+     * Vehicle property is not available because there is a safety risk that makes this feature
+     * unavailable to use presently. For example, this can be caused by someone blocking the trunk
+     * door while it is closing, or by the system being in a faulty state.
+     */
+    NOT_AVAILABLE_SAFETY = -6,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvChargeState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvChargeState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvChargeState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvChargeState.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvConnectorType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.aidl
new file mode 100644
index 0000000..8c5ac46
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by EV_STOPPING_MODE to enumerate the current state of the stopping mode.
+ *
+ * This enum may be extended to include more states in the future.
+ */
+@VintfStability
+@Backing(type="int")
+enum EvStoppingMode {
+    /**
+     * Other EV stopping mode. Ideally, this should never be used.
+     */
+    OTHER = 0,
+    /**
+     * Vehicle slowly moves forward when the brake pedal is released.
+     */
+    CREEP = 1,
+    /**
+     * Vehicle rolls freely when the brake pedal is released (similar to neutral gear).
+     */
+    ROLL = 2,
+    /**
+     * Vehicle stops and holds its position when the brake pedal is released.
+     */
+    HOLD = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceState.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceType.aidl
new file mode 100644
index 0000000..20582dc
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceType.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.automotive.vehicle;
+
+/**
+ * Used by EVS_SERVICE_REQUEST to enumerate the service's type.
+ */
+@VintfStability
+@Backing(type="int")
+enum EvsServiceType {
+    REARVIEW = 0,
+    SURROUNDVIEW = 1,
+    FRONTVIEW = 2,
+    LEFTVIEW = 3,
+    RIGHTVIEW = 4,
+    DRIVERVIEW = 5,
+    FRONTPASSENGERSVIEW = 6,
+    REARPASSENGERSVIEW = 7,
+    USER_DEFINED = 1000,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
new file mode 100644
index 0000000..b20cf25
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Forward Collision Warning State (FCW).
+ */
+@VintfStability
+@Backing(type="int")
+enum ForwardCollisionWarningState {
+
+    /**
+     * This state is used as an alternative to any ForwardCollisionWarningState value that is not
+     * defined in the platform. Ideally, implementations of
+     * VehicleProperty#FORWARD_COLLISION_WARNING_STATE should not use this state. The framework
+     * can use this field to remain backwards compatible if ForwardCollisionWarningState is
+     * extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * FCW is enabled and monitoring safety, but no potential collision is detected.
+     */
+    NO_WARNING = 1,
+    /**
+     * FCW is enabled, detects a potential collision, and is actively warning the user.
+     */
+    WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/FuelType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/FuelType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/FuelType.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
new file mode 100644
index 0000000..fb3ca9f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT to indicate what
+ * kind of general safety regulation compliance requirement is enforced.
+ */
+@VintfStability
+@Backing(type="int")
+enum GsrComplianceRequirementType {
+    /**
+     * GSR compliance is not required.
+     */
+    GSR_COMPLIANCE_NOT_REQUIRED = 0,
+
+    /**
+     * GSR compliance is required and the requirement solution version is 1.
+     */
+    GSR_COMPLIANCE_REQUIRED_V1 = 1,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
new file mode 100644
index 0000000..4a36999
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current driver state of Hands On Detection (HOD).
+ */
+@VintfStability
+@Backing(type="int")
+enum HandsOnDetectionDriverState {
+    /**
+     * This state is used as an alternative for any HandsOnDetectionDriverState value that is not
+     * defined in the platform. Ideally, implementations of
+     * VehicleProperty#HANDS_ON_DETECTION_DRIVER_STATE should not use this state. The framework
+     * can use this field to remain backwards compatible if HandsOnDetectionDriverState is
+     * extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * The system detects that the driver has their hands on the steering wheel.
+     */
+    HANDS_ON = 1,
+    /**
+     * The system detects that the driver has their hands off the steering wheel.
+     */
+    HANDS_OFF = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
new file mode 100644
index 0000000..c1a58ce
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current warning state of Hands On Detection (HOD).
+ */
+@VintfStability
+@Backing(type="int")
+enum HandsOnDetectionWarning {
+    /**
+     * This state is used as an alternative for any HandsOnDetectionWarning value that is
+     * defined in the platform. Ideally, implementations of
+     * VehicleProperty#HANDS_ON_DETECTION_WARNING should not use this state. The framework
+     * can use this field to remain backwards compatible if HandsOnDetectionWarning is
+     * extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * HOD is enabled and the driver's current safety does not warrant sending a warning. This
+     * state is independent of whether the driver actually has their hands on or off the wheel.
+     */
+    NO_WARNING = 1,
+    /**
+     * HOD is enabled and the driver's hands have been off the wheel for too long a duration,
+     * and the vehicle is sending a warning to the driver as a consequence of this.
+     */
+    WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
new file mode 100644
index 0000000..d8b0e65
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by Lane Centering Assist (LCA) to enumerate commands.
+ */
+@VintfStability
+@Backing(type="int")
+enum LaneCenteringAssistCommand {
+    /**
+     * When VehicleProperty#LANE_CENTERING_ASSIST_STATE = LaneCenteringAssistState#ENABLED, this
+     * command sends a request to activate steering control that keeps the vehicle centered in its
+     * lane. While waiting for the LCA System to take control of the vehicle,
+     * VehicleProperty#LANE_CENTERING_ASSIST_STATE must be in the
+     * LaneCenteringAssistState#ACTIVATION_REQUESTED state. Once the vehicle takes control of
+     * steering, then VehicleProperty#LANE_CENTERING_ASSIST_STATE must be in the
+     * LaneCenteringAssistState#ACTIVATED state. Otherwise, an error can be communicated through an
+     * ErrorState value.
+     */
+    ACTIVATE = 1,
+    /**
+     * When VehicleProperty#LANE_CENTERING_ASSIST_STATE is set to
+     * LaneCenteringAssistState#ACTIVATION_REQUESTED or LaneCenteringAssistState#ACTIVATED, this
+     * command deactivates steering control and the driver should take full control of the vehicle.
+     * If this command succeeds, VehicleProperty#LANE_CENTERING_ASSIST_STATE must be updated to
+     * LaneCenteringAssistState#ENABLED.
+     */
+    DEACTIVATE = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
new file mode 100644
index 0000000..340a669
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Lane Centering Assist (LCA).
+ */
+@VintfStability
+@Backing(type="int")
+enum LaneCenteringAssistState {
+
+    /**
+     * This state is used as an alternative for any LaneCenteringAssistState value that is not
+     * defined in the platform. Ideally, implementations of
+     * VehicleProperty#LANE_CENTERING_ASSIST_STATE should not use this state. The framework
+     * can use this field to remain backwards compatible if LaneCenteringAssistState is
+     * extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * LCA is enabled but the ADAS system has not received an activation signal from the driver.
+     * Therefore, LCA is not steering the car and waits for the driver to send a
+     * LaneCenteringAssistCommand#ACTIVATE command.
+     */
+    ENABLED = 1,
+    /**
+     * LCA is enabled and the driver has sent an activation command to the LCA system, but the
+     * system has not started actively steering the vehicle. This may happen when LCA needs time to
+     * detect valid lane lines. The activation command can be sent through the
+     * VehicleProperty#LANE_CENTERING_ASSIST_COMMAND vehicle property or through a system external
+     * to Android. Once LCA is actively steering the vehicle, the state must be updated to
+     * ACTIVATED. If the feature is not able to activate, then the cause can be communicated through
+     * the ErrorState values and then return to the ENABLED state.
+     */
+    ACTIVATION_REQUESTED = 2,
+    /**
+     * LCA is enabled and actively steering the car to keep it centered in its lane.
+     */
+    ACTIVATED = 3,
+    /**
+     * Many LCA implementations allow the driver to override LCA. This means that the car has
+     * determined it should go a certain direction to keep the car centered in the lane, but a user
+     * decides to take over and do something else. This is often done for safety reasons and to
+     * ensure that the driver can always take control of the vehicle. This state should be set when
+     * the user is actively overriding the LCA system.
+     */
+    USER_OVERRIDE = 4,
+    /**
+     * When LCA is in the ACTIVATED state but it will potentially need to deactivate because of
+     * external conditions (e.g. roads curvature is too extreme, the driver does not have their
+     * hands on the steering wheel for a long period of time, or the driver is not paying
+     * attention), then the ADAS system will notify the driver of a potential need to deactivate and
+     * give control back to the driver.
+     */
+    FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
new file mode 100644
index 0000000..c12c5765
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Lane Departure Warning (LDW).
+ */
+@VintfStability
+@Backing(type="int")
+enum LaneDepartureWarningState {
+
+    /**
+     * This state is used as an alternative for any LaneDepartureWarningState value that is not
+     * defined in the platform. Ideally, implementations of
+     * VehicleProperty#LANE_DEPARTURE_WARNING_STATE should not use this state. The framework
+     * can use this field to remain backwards compatible if LaneDepartureWarningState is
+     * extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * LDW is enabled and monitoring, but the vehicle is centered in the lane.
+     */
+    NO_WARNING = 1,
+    /**
+     * LDW is enabled, detects the vehicle is approaching or crossing lane lines on the left side
+     * of the vehicle, and is currently warning the user.
+     */
+    WARNING_LEFT = 2,
+    /**
+     * LDW is enabled, detects the vehicle is approaching or crossing lane lines on the right side
+     * of the vehicle, and is currently warning the user.
+     */
+    WARNING_RIGHT = 3,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
new file mode 100644
index 0000000..c1c15a0
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Lane Keep Assist (LKA).
+ */
+@VintfStability
+@Backing(type="int")
+enum LaneKeepAssistState {
+
+    /**
+     * This state is used as an alternative for any LaneKeepAssistState value that is not defined in
+     * the platform. Ideally, implementations of VehicleProperty#LANE_KEEP_ASSIST_STATE should not
+     * use this state. The framework can use this field to remain backwards compatible if
+     * LaneKeepAssistState is extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * LKA is enabled and monitoring, but steering assist is not activated.
+     */
+    ENABLED = 1,
+    /**
+     * LKA is enabled and currently has steering assist applied for the vehicle. Steering assist is
+     * steering toward the left direction, which generally means the steering wheel turns counter
+     * clockwise. This is usually in response to the vehicle drifting to the right. Once steering
+     * assist is completed, LKA must return to the ENABLED state.
+     */
+    ACTIVATED_STEER_LEFT = 2,
+    /**
+     * LKA is enabled and currently has steering assist applied for the vehicle. Steering assist is
+     * steering toward the right direction, which generally means the steering wheel turns
+     * clockwise. This is usually in response to the vehicle drifting to the left. Once steering
+     * assist is completed, LKA must return to the ENABLED state.
+     */
+    ACTIVATED_STEER_RIGHT = 3,
+    /**
+     * Many LKA implementations allow the driver to override LKA. This means that the car has
+     * determined it should take some action, but a user decides to take over and do something else.
+     * This is often done for safety reasons and to ensure that the driver can always take control
+     * of the vehicle. This state should be set when the user is actively overriding the LKA system.
+     */
+    USER_OVERRIDE = 4,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LocationCharacterization.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LocationCharacterization.aidl
new file mode 100644
index 0000000..e06df40
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LocationCharacterization.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by LOCATION_CHARACTERIZATION to enumerate the supported bit flags.
+ *
+ * These flags are used to indicate to what transformations are performed on the
+ * GNSS data before the location data is sent, so that location processing
+ * algorithms can take into account prior fusion.
+ *
+ * This enum can be extended in future releases to include additional bit flags.
+ */
+@VintfStability
+@Backing(type="int")
+enum LocationCharacterization {
+    /**
+     * Prior location samples have been used to refine the raw GNSS data (e.g. a
+     * Kalman Filter).
+     */
+    PRIOR_LOCATIONS = 0x1,
+    /**
+     * Gyroscope data has been used to refine the raw GNSS data.
+     */
+    GYROSCOPE_FUSION = 0x2,
+    /**
+     * Accelerometer data has been used to refine the raw GNSS data.
+     */
+    ACCELEROMETER_FUSION = 0x4,
+    /**
+     * Compass data has been used to refine the raw GNSS data.
+     */
+    COMPASS_FUSION = 0x8,
+    /**
+     * Wheel speed has been used to refine the raw GNSS data.
+     */
+    WHEEL_SPEED_FUSION = 0x10,
+    /**
+     * Steering angle has been used to refine the raw GNSS data.
+     */
+    STEERING_ANGLE_FUSION = 0x20,
+    /**
+     * Car speed has been used to refine the raw GNSS data.
+     */
+    CAR_SPEED_FUSION = 0x40,
+    /**
+     * Some effort is made to dead-reckon location. In particular, this means that
+     * relative changes in location have meaning when no GNSS satellite is
+     * available.
+     */
+    DEAD_RECKONED = 0x80,
+    /**
+     * Location is based on GNSS satellite signals without sufficient fusion of
+     * other sensors for complete dead reckoning. This flag should be set when
+     * relative changes to location cannot be relied on when no GNSS satellite is
+     * available.
+     */
+    RAW_GNSS_ONLY = 0x100,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2FuelType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/PortLocationType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/PortLocationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/PortLocationType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/PortLocationType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RotaryInputType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/RotaryInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/RotaryInputType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/RotaryInputType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.aidl
new file mode 100644
index 0000000..ef65374
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of VehicleProperty#TRAILER_PRESENT.
+ */
+@VintfStability
+@Backing(type="int")
+enum TrailerState {
+    /**
+     * This state is used as an alternative for any TrailerState value that is not defined in the
+     * platform. Ideally, implementations of VehicleProperty#TRAILER_PRESENT should not use this
+     * state. The framework can use this field to remain backwards compatible if TrailerState is
+     * extended to include additional states.
+     */
+    UNKNOWN = 0,
+    /**
+     * A trailer is not attached to the vehicle.
+     */
+    NOT_PRESENT = 1,
+    /**
+     * A trailer is attached to the vehicle.
+     */
+    PRESENT = 2,
+    /**
+     * The state of the trailer is not available due to an error.
+     */
+    ERROR = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserInfo.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UsersInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UsersInfo.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
new file mode 100644
index 0000000..e325b38
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Vehicle AP power bootup reason.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleApPowerBootupReason {
+    /**
+     * Power on due to user's pressing of power key or rotating of ignition
+     * switch.
+     */
+    USER_POWER_ON = 0,
+    /**
+     * Automatic power on triggered by door unlock or any other kind of automatic
+     * user detection.
+     */
+    SYSTEM_USER_DETECTION = 1,
+    /**
+     * Automatic power on to execute a remote task. This is triggered by
+     * receiving a wakeup message from TCU wakeup client.
+     */
+    SYSTEM_REMOTE_ACCESS = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
new file mode 100644
index 0000000..6f7f783
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.automotive.vehicle;
+
+/**
+ * List of different supported area types for vehicle properties.
+ * Used to construct property IDs in the VehicleProperty enum.
+ *
+ * Some properties may be associated with particular areas in the vehicle. For example,
+ * VehicleProperty#DOOR_LOCK property must be associated with a particular door, thus this property
+ * must be of the VehicleArea#DOOR area type.
+ *
+ * Other properties may not be associated with a particular area in the vehicle. These kinds of
+ * properties must be of the VehicleArea#GLOBAL area type.
+ *
+ * Note: This is not the same as areaId used in VehicleAreaConfig. E.g. for a global property, the
+ * property ID is of the VehicleArea#GLOBAL area type, however, the area ID must be 0.
+ */
+@VintfStability
+@Backing(type="int")
+// A better name would be VehicleAreaType
+enum VehicleArea {
+    /**
+     * A global property is a property that applies to the entire vehicle and is not associated with
+     * a specific area. For example, FUEL_LEVEL, HVAC_STEERING_WHEEL_HEAT are global properties.
+     */
+    GLOBAL = 0x01000000,
+    /** WINDOW maps to enum VehicleAreaWindow */
+    WINDOW = 0x03000000,
+    /** MIRROR maps to enum VehicleAreaMirror */
+    MIRROR = 0x04000000,
+    /** SEAT maps to enum VehicleAreaSeat */
+    SEAT = 0x05000000,
+    /** DOOR maps to enum VehicleAreaDoor */
+    DOOR = 0x06000000,
+    /** WHEEL maps to enum VehicleAreaWheel */
+    WHEEL = 0x07000000,
+
+    MASK = 0x0f000000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleDisplay.aidl
new file mode 100644
index 0000000..6642eee
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleDisplay.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+
+@VintfStability
+@Backing(type="int")
+enum VehicleDisplay {
+    /**
+     * The primary Android display (for example, center console)
+     */
+    MAIN = 0,
+    /**
+     * Instrument cluster display. This may exist only for driver
+     */
+    INSTRUMENT_CLUSTER = 1,
+
+    /**
+     * Head Up Display. This may exist only for driver
+     */
+    HUD = 2,
+    /**
+     * Dedicated display for showing IME for {@code MAIN}
+     */
+    INPUT = 3,
+    /**
+     * Auxiliary display which can provide additional screen for {@code MAIN} display
+     */
+    AUXILIARY = 4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleGear.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleGear.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleGear.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
new file mode 100644
index 0000000..f5b77de
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.automotive.vehicle;
+
+/**
+ * Bit flags for fan direction
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHvacFanDirection {
+    UNKNOWN = 0x0,
+    FACE = 0x1,
+    FLOOR = 0x2,
+    /**
+     * FACE_AND_FLOOR = FACE | FLOOR
+     */
+    FACE_AND_FLOOR = 0x3,
+    /**
+     * DEFROST may also be described as the windshield fan direction.
+     */
+    DEFROST = 0x4,
+    /**
+     * DEFROST_AND_FLOOR = DEFROST | FLOOR
+     */
+    DEFROST_AND_FLOOR = 0x06,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
new file mode 100644
index 0000000..5313a55
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * See {@code android.view.MotionEvent#getButtonState()} for more details.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHwMotionButtonStateFlag {
+    /**
+     * Button state primary
+     */
+    BUTTON_PRIMARY = 0x0001,
+    /**
+     * Button state secondary
+     */
+    BUTTON_SECONDARY = 0x0002,
+    /**
+     * Button state tertiary
+     */
+    BUTTON_TERTIARY = 0x0004,
+    /**
+     * Button state back
+     */
+    BUTTON_BACK = 0x0008,
+    /**
+     * Button state forward
+     */
+    BUTTON_FORWARD = 0x0010,
+    /**
+     * Button state stylus primary
+     */
+    BUTTON_STYLUS_PRIMARY = 0x0020,
+    /**
+     * Button state stylus secondary
+     */
+    BUTTON_STYLUS_SECONDARY = 0x0040,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
new file mode 100644
index 0000000..d80119a
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * See {@code android.view.MotionEvent#ACTION_*} fields for more details.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHwMotionInputAction {
+    /**
+     * Motion down
+     */
+    ACTION_DOWN = 0,
+    /**
+     * Motion up
+     */
+    ACTION_UP = 1,
+    /**
+     * Motion move
+     */
+    ACTION_MOVE = 2,
+    /**
+     * Motion cancel
+     */
+    ACTION_CANCEL = 3,
+    /**
+     * Motion outside
+     */
+    ACTION_OUTSIDE = 4,
+    /**
+     * Motion pointer down
+     */
+    ACTION_POINTER_DOWN = 5,
+    /**
+     * Motion pointer up
+     */
+    ACTION_POINTER_UP = 6,
+    /**
+     * Motion hover move
+     */
+    ACTION_HOVER_MOVE = 7,
+    /**
+     * Motion scroll
+     */
+    ACTION_SCROLL = 8,
+    /**
+     * Motion hover enter
+     */
+    ACTION_HOVER_ENTER = 9,
+    /**
+     * Motion hover exit
+     */
+    ACTION_HOVER_EXIT = 10,
+    /**
+     * Motion button press
+     */
+    ACTION_BUTTON_PRESS = 11,
+    /**
+     * Motion button release
+     */
+    ACTION_BUTTON_RELEASE = 12,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
new file mode 100644
index 0000000..fb79983
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * See {@code android.view.InputDevice#SOURCE_*} for more details.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHwMotionInputSource {
+    /**
+     * Unknown source
+     */
+    SOURCE_UNKNOWN = 0,
+    /**
+     * Source keyboard
+     */
+    SOURCE_KEYBOARD = 1,
+    /**
+     * Source dpad
+     */
+    SOURCE_DPAD = 2,
+    /**
+     * Source game pad
+     */
+    SOURCE_GAMEPAD = 3,
+    /**
+     * Source touch screen
+     */
+    SOURCE_TOUCHSCREEN = 4,
+    /**
+     * Source mouse
+     */
+    SOURCE_MOUSE = 5,
+    /**
+     * Source stylus
+     */
+    SOURCE_STYLUS = 6,
+    /**
+     * Source bluetooth stylus
+     */
+    SOURCE_BLUETOOTH_STYLUS = 7,
+    /**
+     * Source trackball
+     */
+    SOURCE_TRACKBALL = 8,
+    /**
+     * Source mouse relative
+     */
+    SOURCE_MOUSE_RELATIVE = 9,
+    /**
+     * Source touchpad
+     */
+    SOURCE_TOUCHPAD = 10,
+    /**
+     * Source touch navigation
+     */
+    SOURCE_TOUCH_NAVIGATION = 11,
+    /**
+     * Source rotary encoder
+     */
+    SOURCE_ROTARY_ENCODER = 12,
+    /**
+     * Source joystick
+     */
+    SOURCE_JOYSTICK = 13,
+    /**
+     * Source hdmi
+     */
+    SOURCE_HDMI = 14,
+    /**
+     * Source sensor
+     */
+    SOURCE_SENSOR = 15,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl
new file mode 100644
index 0000000..08c9aed
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.automotive.vehicle;
+
+/**
+ * See {@code android.view.MotionEvent#TOOL_TYPE_*} for more details.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHwMotionToolType {
+    /**
+     * Unknown type such as for a trackballl or other non-pointing device
+     */
+    TOOL_TYPE_UNKNOWN = 0,
+    /**
+     * Finger type
+     */
+    TOOL_TYPE_FINGER = 1,
+    /**
+     * Stylus type
+     */
+    TOOL_TYPE_STYLUS = 2,
+    /**
+     * Mouse type
+     */
+    TOOL_TYPE_MOUSE = 3,
+    /**
+     * Eraser type
+     */
+    TOOL_TYPE_ERASER = 4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightState.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
new file mode 100644
index 0000000..3c722ba
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.automotive.vehicle;
+
+/**
+ * Used to enumerate the current level of VehicleProperty#ENGINE_OIL_LEVEL.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleOilLevel {
+    /**
+     * The oil level of the engine is critically low, so the vehicle may be unsafe to drive.
+     */
+    CRITICALLY_LOW = 0,
+    /**
+     * The oil level of the engine is low and needs to be replaced.
+     */
+    LOW = 1,
+    /**
+     * The oil level of the engine is normal for the vehicle.
+     */
+    NORMAL = 2,
+    /**
+     * The oil level of the engine is high, so the vehicle may be unsafe to drive.
+     */
+    HIGH = 3,
+    /**
+     * This value represents an error when retrieving the oil level of the engine.
+     */
+    ERROR = 4,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
new file mode 100644
index 0000000..d9c6de7
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -0,0 +1,4962 @@
+/*
+ * 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.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VehicleArea;
+import android.hardware.automotive.vehicle.VehiclePropertyGroup;
+import android.hardware.automotive.vehicle.VehiclePropertyType;
+/**
+ * Declares all vehicle properties. VehicleProperty has a bitwise structure.
+ * Each property must have:
+ *  - a unique id from range 0x0100 - 0xffff
+ *  - associated data type using VehiclePropertyType
+ *  - property group (VehiclePropertyGroup)
+ *  - vehicle area (VehicleArea)
+ *
+ * Vendors are allowed to extend this enum with their own properties. In this
+ * case they must use VehiclePropertyGroup:VENDOR flag when the property is
+ * declared.
+ *
+ * When a property's status field is not set to AVAILABLE:
+ *  - IVehicle#set may return StatusCode::NOT_AVAILABLE.
+ *  - IVehicle#get is not guaranteed to work.
+ *
+ * Properties set to values out of range must be ignored and no action taken
+ * in response to such ill formed requests.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleProperty {
+    /**
+     * Undefined property.
+     *
+     * This property must never be used/supported.
+     */
+    INVALID = 0x00000000,
+    /**
+     * VIN of vehicle
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     */
+    INFO_VIN = 0x0100 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Manufacturer of vehicle
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     */
+    INFO_MAKE = 0x0101 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Model of vehicle
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     */
+    INFO_MODEL = 0x0102 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Model year of vehicle.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:YEAR
+     */
+    INFO_MODEL_YEAR = 0x0103 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fuel capacity of the vehicle in milliliters
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:MILLILITER
+     */
+    INFO_FUEL_CAPACITY = 0x0104 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * List of fuels the vehicle may use.
+     *
+     * FuelType::FUEL_TYPE_ELECTRIC must only be included if the vehicle is plug in rechargeable.
+     * For example:
+     *   An FHEV (Fully Hybrid Electric Vehicle) must not include FuelType::FUEL_TYPE_ELECTRIC in
+     *   INFO_FUEL_TYPE's INT32_VEC value. So INFO_FUEL_TYPE can be populated as such:
+     *     int32Values = { FuelType::FUEL_TYPE_UNLEADED }
+     *   On the other hand, a PHEV (Partially Hybrid Electric Vehicle) is plug in rechargeable, and
+     *   hence should include FuelType::FUEL_TYPE_ELECTRIC in INFO_FUEL_TYPE's INT32_VEC value. So
+     *   INFO_FUEL_TYPE can be populated as such:
+     *     int32Values = { FuelType::FUEL_TYPE_UNLEADED, FuelType::FUEL_TYPE_ELECTRIC }
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @data_enum FuelType
+     */
+    INFO_FUEL_TYPE = 0x0105 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Nominal battery capacity for EV or hybrid vehicle
+     *
+     * Returns the nominal battery capacity, if EV or hybrid. This is the battery capacity when the
+     * vehicle is new. This value might be different from EV_CURRENT_BATTERY_CAPACITY because
+     * EV_CURRENT_BATTERY_CAPACITY returns the real-time battery capacity taking into account
+     * factors such as battery aging and temperature dependency.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:WH
+     */
+    INFO_EV_BATTERY_CAPACITY = 0x0106 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * List of connectors this EV may use
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @data_enum EvConnectorType
+     * @access VehiclePropertyAccess.READ
+     */
+    INFO_EV_CONNECTOR_TYPE = 0x0107 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Fuel door location
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @data_enum PortLocationType
+     * @access VehiclePropertyAccess.READ
+     */
+    INFO_FUEL_DOOR_LOCATION = 0x0108 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * EV port location
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @data_enum PortLocationType
+     */
+    INFO_EV_PORT_LOCATION = 0x0109 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Driver's seat location
+     * VHAL implementations must ignore the areaId. Use VehicleArea:GLOBAL.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @data_enum VehicleAreaSeat
+     * @access VehiclePropertyAccess.READ
+     */
+    INFO_DRIVER_SEAT = 0x010A + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Exterior dimensions of vehicle.
+     *
+     *  int32Values[0] = height
+     *  int32Values[1] = length
+     *  int32Values[2] = width
+     *  int32Values[3] = width including mirrors
+     *  int32Values[4] = wheel base
+     *  int32Values[5] = track width front
+     *  int32Values[6] = track width rear
+     *  int32Values[7] = curb to curb turning radius
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:MILLIMETER
+     */
+    INFO_EXTERIOR_DIMENSIONS = 0x010B + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Multiple EV port locations
+     *
+     * Implement this property if the vehicle has multiple EV ports.
+     * Port locations are defined in PortLocationType.
+     * For example, a car has one port in front left and one port in rear left:
+     *   int32Values[0] = PortLocationType::FRONT_LEFT
+     *   int32Values[0] = PortLocationType::REAR_LEFT
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @data_enum PortLocationType
+     */
+    INFO_MULTI_EV_PORT_LOCATIONS = 0x010C + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Current odometer value of the vehicle
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:KILOMETER
+     */
+    PERF_ODOMETER = 0x0204 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Speed of the vehicle
+     *
+     * The value must be positive when the vehicle is moving forward and negative when
+     * the vehicle is moving backward. This value is independent of gear value
+     * (CURRENT_GEAR or GEAR_SELECTION), for example, if GEAR_SELECTION is GEAR_NEUTRAL,
+     * PERF_VEHICLE_SPEED is positive when the vehicle is moving forward, negative when moving
+     * backward, and zero when not moving.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:METER_PER_SEC
+     */
+    PERF_VEHICLE_SPEED = 0x0207 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Speed of the vehicle for displays
+     *
+     * Some cars display a slightly slower speed than the actual speed.  This is
+     * usually displayed on the speedometer.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:METER_PER_SEC
+     */
+    PERF_VEHICLE_SPEED_DISPLAY = 0x0208 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Front bicycle model steering angle for vehicle
+     *
+     * Angle is in degrees.  Left is negative.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:DEGREES
+     */
+    PERF_STEERING_ANGLE = 0x0209 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Rear bicycle model steering angle for vehicle
+     *
+     * Angle is in degrees.  Left is negative.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:DEGREES
+     */
+    PERF_REAR_STEERING_ANGLE = 0x0210 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Temperature of engine coolant
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:CELSIUS
+     */
+    ENGINE_COOLANT_TEMP = 0x0301 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Engine oil level
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleOilLevel
+     */
+    ENGINE_OIL_LEVEL = 0x0303 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Temperature of engine oil
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:CELSIUS
+     */
+    ENGINE_OIL_TEMP = 0x0304 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Engine rpm
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:RPM
+     */
+    ENGINE_RPM = 0x0305 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Reports wheel ticks
+     *
+     * The first element in the vector is a reset count.  A reset indicates
+     * previous tick counts are not comparable with this and future ones.  Some
+     * sort of discontinuity in tick counting has occurred.
+     *
+     * The next four elements represent ticks for individual wheels in the
+     * following order: front left, front right, rear right, rear left.  All
+     * tick counts are cumulative.  Tick counts increment when the vehicle
+     * moves forward, and decrement when vehicles moves in reverse.  The ticks
+     * should be reset to 0 when the vehicle is started by the user.
+     *
+     *  int64Values[0] = reset count
+     *  int64Values[1] = front left ticks
+     *  int64Values[2] = front right ticks
+     *  int64Values[3] = rear right ticks
+     *  int64Values[4] = rear left ticks
+     *
+     * configArray is used to indicate the micrometers-per-wheel-tick value and
+     * which wheels are supported.  configArray is set as follows:
+     *
+     *  configArray[0], bits [0:3] = supported wheels. Uses enum Wheel. For example, if all wheels
+     *    are supported, then configArray[0] = VehicleAreaWheel::LEFT_FRONT
+     *    | VehicleAreaWheel::RIGHT_FRONT | VehicleAreaWheel::LEFT_REAR
+     *    | VehicleAreaWheel::RIGHT_REAR
+     *  configArray[1] = micrometers per front left wheel tick
+     *  configArray[2] = micrometers per front right wheel tick
+     *  configArray[3] = micrometers per rear right wheel tick
+     *  configArray[4] = micrometers per rear left wheel tick
+     *
+     * NOTE:  If a wheel is not supported, its value shall always be set to 0.
+     *
+     * VehiclePropValue.timestamp must be correctly filled in.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     */
+    WHEEL_TICK = 0x0306 + 0x10000000 + 0x01000000
+            + 0x00510000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64_VEC
+    /**
+     * Fuel remaining in the vehicle, in milliliters
+     *
+     * Value may not exceed INFO_FUEL_CAPACITY
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:MILLILITER
+     */
+    FUEL_LEVEL = 0x0307 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Fuel door open
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    FUEL_DOOR_OPEN = 0x0308 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Battery level for EV or hybrid vehicle
+     *
+     * Returns the current battery level, if EV or hybrid. This value will not exceed
+     * EV_CURRENT_BATTERY_CAPACITY. To calculate the battery percentage, use:
+     * (EV_BATTERY_LEVEL/EV_CURRENT_BATTERY_CAPACITY)*100.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:WH
+     */
+    EV_BATTERY_LEVEL = 0x0309 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Current battery capacity for EV or hybrid vehicle
+     *
+     * Returns the actual value of battery capacity, if EV or hybrid. This property captures the
+     * real-time battery capacity taking into account factors such as battery aging and temperature
+     * dependency. Therefore, this value might be different from INFO_EV_BATTERY_CAPACITY because
+     * INFO_EV_BATTERY_CAPACITY returns the nominal battery capacity from when the vehicle was new.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:WH
+     */
+    EV_CURRENT_BATTERY_CAPACITY =
+            0x030D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+    /**
+     * EV charge port open
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    EV_CHARGE_PORT_OPEN = 0x030A + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * EV charge port connected
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    EV_CHARGE_PORT_CONNECTED = 0x030B + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * EV instantaneous charge rate in milliwatts
+     *
+     * Positive value indicates battery is being charged.
+     * Negative value indicates battery being discharged.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:MW
+     */
+    EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = 0x030C + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Range remaining
+     *
+     * Meters remaining of fuel and charge.  Range remaining shall account for
+     * all energy sources in a vehicle.  For example, a hybrid car's range will
+     * be the sum of the ranges based on fuel and battery.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE because a navigation app could
+     * update the range if it has a more accurate estimate based on the upcoming route. However,
+     * this property can be implemented as VehiclePropertyAccess.READ only at the OEM's discretion.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @unit VehicleUnit:METER
+     */
+    RANGE_REMAINING = 0x0308 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Tire pressure
+     *
+     * Each tires is identified by its areaConfig.areaId config and their
+     * minFloatValue/maxFloatValue are used to store OEM recommended pressure
+     * range. The minFloatValue and maxFloatValue in VehicleAreaConfig must be defined.
+     * The minFloatValue in the areaConfig data represents the lower bound of
+     * the recommended tire pressure.
+     * The maxFloatValue in the areaConfig data represents the upper bound of
+     * the recommended tire pressure.
+     * For example:
+     * The following areaConfig indicates the recommended tire pressure
+     * of left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL.
+     * .areaConfigs = {
+     *      VehicleAreaConfig {
+     *          .areaId = VehicleAreaWheel::LEFT_FRONT,
+     *          .minFloatValue = 200.0,
+     *          .maxFloatValue = 240.0,
+     *      }
+     * },
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:KILOPASCAL
+     */
+    TIRE_PRESSURE = 0x0309 + 0x10000000 + 0x07000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
+    /**
+     * Critically low tire pressure
+     *
+     * This property indicates the critically low pressure threshold for each tire.
+     * It indicates when it is time for tires to be replaced or fixed. The value
+     * must be less than or equal to minFloatValue in TIRE_PRESSURE.
+     * Minimum and maximum property values (that is, minFloatValue, maxFloatValue)
+     * are not applicable to this property.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:KILOPASCAL
+     */
+    CRITICALLY_LOW_TIRE_PRESSURE = 0x030A + 0x10000000 + 0x07000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
+    /**
+     * Represents feature for engine idle automatic stop.
+     *
+     * If true, the vehicle may automatically shut off the engine when it is not needed and then
+     * automatically restart it when needed.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    ENGINE_IDLE_AUTO_STOP_ENABLED =
+            0x0320 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+    /**
+     * Currently selected gear
+     *
+     * This is the gear selected by the user.
+     *
+     * Values in the config data must represent the list of supported gears for this vehicle. For
+     * example, config data for an automatic transmission must contain {GEAR_NEUTRAL, GEAR_REVERSE,
+     * GEAR_PARK, GEAR_DRIVE, GEAR_1, GEAR_2,...} and for manual transmission the list must be
+     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}
+     *
+     * In the case of an automatic transmission vehicle that allows the driver to select specific
+     * gears on demand (i.e. "manual mode"), GEAR_SELECTION's value must be set to the specific gear
+     * selected by the driver instead of simply GEAR_DRIVE.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleGear
+     */
+    GEAR_SELECTION = 0x0400 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Current gear. In non-manual case, selected gear may not
+     * match the current gear. For example, if the selected gear is GEAR_DRIVE,
+     * the current gear will be one of GEAR_1, GEAR_2 etc, which reflects
+     * the actual gear the transmission is currently running in.
+     *
+     * Values in the config data must represent the list of supported gears
+     * for this vehicle.  For example, config data for an automatic transmission
+     * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...}
+     * and for manual transmission the list must be
+     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the
+     * same as that of the supported gears reported in GEAR_SELECTION.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleGear
+     */
+    CURRENT_GEAR = 0x0401 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Parking brake state.
+     *
+     * This property is true indicates that the car's parking brake is currently engaged. False
+     * implies that the car's parking brake is currently disengaged.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    PARKING_BRAKE_ON = 0x0402 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Auto-apply parking brake.
+     *
+     * This property is true indicates that the car's automatic parking brake feature is currently
+     * enabled. False indicates that the car's automatic parking brake feature is currently
+     * disabled.
+     *
+     * This property is often confused with PARKING_BRAKE_ON. The difference is that
+     * PARKING_BRAKE_ON describes whether the actual parking brake is currently on/off, whereas
+     * PARKING_BRAKE_AUTO_APPLY describes whether the feature of automatic parking brake is enabled/
+     * disabled, and does not describe the current state of the actual parking brake.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    PARKING_BRAKE_AUTO_APPLY = 0x0403 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Regenerative braking level of a electronic vehicle
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+     * minInt32Value and maxInt32Value must be supported. The minInt32Value must be 0.
+     *
+     * The maxInt32Value indicates the maximum amount of energy regenerated from braking. The
+     * minInt32Value indicates no regenerative braking.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    EV_BRAKE_REGENERATION_LEVEL =
+            0x040C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * Warning for fuel low level.
+     *
+     * This property corresponds to the low fuel warning on the dashboard.
+     * Once FUEL_LEVEL_LOW is set, it should not be cleared until more fuel is
+     * added to the vehicle.  This property may take into account all fuel
+     * sources for a vehicle - for example:
+     *
+     *   For a gas powered vehicle, this property is based soley on gas level.
+     *   For a battery powered vehicle, this property is based solely on battery level.
+     *   For a hybrid vehicle, this property may be based on the combination of gas and battery
+     *      levels, at the OEM's discretion.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    FUEL_LEVEL_LOW = 0x0405 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Night mode
+     *
+     * True indicates that the night mode sensor has detected that the car cabin environment has
+     * low light. The platform could use this, for example, to enable appropriate UI for
+     * better viewing in dark or low light environments.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    NIGHT_MODE = 0x0407 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * State of the vehicles turn signals
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleTurnSignal
+     */
+    TURN_SIGNAL_STATE = 0x0408 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Represents ignition state
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleIgnitionState
+     */
+    IGNITION_STATE = 0x0409 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * ABS is active
+     *
+     * Set to true when ABS is active.  Reset to false when ABS is off.  This
+     * property may be intermittently set (pulsing) based on the real-time
+     * state of the ABS system.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    ABS_ACTIVE = 0x040A + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Traction Control is active
+     *
+     * Set to true when traction control (TC) is active.  Reset to false when
+     * TC is off.  This property may be intermittently set (pulsing) based on
+     * the real-time state of the TC system.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    TRACTION_CONTROL_ACTIVE = 0x040B + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Represents property for the current stopping mode of the vehicle.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of EvStoppingMode are supported.
+     *
+     * The EvStoppingMode enum may be extended to include more states in the future.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum EvStoppingMode
+     */
+    EV_STOPPING_MODE =
+            0x040D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * HVAC Properties
+     *
+     * Additional rules for mapping non-GLOBAL VehicleArea type HVAC properties
+     * to AreaIDs:
+     *  - Every “area” for a specific VehicleArea type that is affected by the
+     *    property, must be included in an area ID for that property.
+     *
+     * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
+     *  temperature control units -- driver side and passenger side.
+     *   - A valid mapping set of AreaIDs for HVAC_TEMPERATURE_SET would be a
+     *     two element array:
+     *      - ROW_1_LEFT  | ROW_2_LEFT
+     *      - ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT
+     *   - An alternative mapping for the same hardware configuration would be:
+     *      - ROW_1_LEFT  | ROW_2_CENTER | ROW_2_LEFT
+     *      - ROW_1_RIGHT | ROW_2_RIGHT
+     *  The temperature controllers are assigned to the seats which they
+     *  "most influence", but every seat must be included exactly once. The
+     *  assignment of the center rear seat to the left or right AreaID may seem
+     *  arbitrary, but the inclusion of every seat in exactly one AreaID ensures
+     *  that the seats in the car are all expressed and that a "reasonable" way
+     *  to affect each seat is available.
+     *
+     * Example 2: A car has three seat rows with two seats in the front row (ROW_1_LEFT,
+     *  ROW_1_RIGHT) and three seats in the second (ROW_2_LEFT, ROW_2_CENTER,
+     *  ROW_2_RIGHT) and third rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). There
+     *  are three temperature control units -- driver side, passenger side, and rear.
+     *   - A reasonable way to map HVAC_TEMPERATURE_SET to AreaIDs is a three
+     *     element array:
+     *     - ROW_1_LEFT
+     *     - ROW_1_RIGHT
+     *     - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
+     *
+     * Example 3: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). Suppose the car
+     *  supports HVAC_AUTO_ON for just the two front seats.
+     *   - A valid mapping set of AreaIDs for HVAC_AUTO_ON would be:
+     *      - ROW_1_LEFT | ROW_1_RIGHT
+     *   - If HVAC_AUTO_ON had two separate control units for the driver side
+     *     and passenger side, an alternative mapping would be:
+     *      - ROW_1_LEFT
+     *      - ROW_1_RIGHT
+     *
+     *
+     * Fan speed setting
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the lowest fan speed.
+     * The maxInt32Value indicates the highest fan speed.
+     *
+     * This property is not in any particular unit but in a specified range of relative speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_FAN_SPEED = 0x0500 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Fan direction setting
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleHvacFanDirection
+     */
+    HVAC_FAN_DIRECTION = 0x0501 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * HVAC current temperature.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:CELSIUS
+     */
+    HVAC_TEMPERATURE_CURRENT = 0x0502 + 0x10000000 + 0x05000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
+    /**
+     * HVAC, target temperature set.
+     *
+     * The configArray is used to indicate the valid values for HVAC in Fahrenheit and Celsius.
+     * Android might use it in the HVAC app UI.
+     * The configArray is set as follows:
+     *      configArray[0] = [the lower bound of the supported temperature in Celsius] * 10.
+     *      configArray[1] = [the upper bound of the supported temperature in Celsius] * 10.
+     *      configArray[2] = [the increment in Celsius] * 10.
+     *      configArray[3] = [the lower bound of the supported temperature in Fahrenheit] * 10.
+     *      configArray[4] = [the upper bound of the supported temperature in Fahrenheit] * 10.
+     *      configArray[5] = [the increment in Fahrenheit] * 10.
+     * For example, if the vehicle supports temperature values as:
+     *      [16.0, 16.5, 17.0 ,..., 28.0] in Celsius
+     *      [60.5, 61.5, 62.5 ,..., 85.5] in Fahrenheit.
+     * The configArray should be configArray = {160, 280, 5, 605, 825, 10}.
+     *
+     * If the vehicle supports HVAC_TEMPERATURE_VALUE_SUGGESTION, the application can use
+     * that property to get the suggested value before setting HVAC_TEMPERATURE_SET. Otherwise,
+     * the application may choose the value in HVAC_TEMPERATURE_SET configArray by itself.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @unit VehicleUnit:CELSIUS
+     */
+    HVAC_TEMPERATURE_SET = 0x0503 + 0x10000000 + 0x05000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
+    /**
+     * Fan-based defrost for designated window.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_DEFROSTER = 0x0504 + 0x10000000 + 0x03000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
+    /**
+     * On/off AC for designated areaId
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @config_flags Supported areaIds
+     */
+    HVAC_AC_ON = 0x0505 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * On/off max AC
+     *
+     * When MAX AC is on, the ECU may adjust the vent position, fan speed,
+     * temperature, etc as necessary to cool the vehicle as quickly as possible.
+     * Any parameters modified as a side effect of turning on/off the MAX AC
+     * parameter shall generate onPropertyEvent() callbacks to the VHAL.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_MAX_AC_ON = 0x0506 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * On/off max defrost
+     *
+     * When MAX DEFROST is on, the ECU may adjust the vent position, fan speed,
+     * temperature, etc as necessary to defrost the windows as quickly as
+     * possible.  Any parameters modified as a side effect of turning on/off
+     * the MAX DEFROST parameter shall generate onPropertyEvent() callbacks to
+     * the VHAL.
+     * The AreaIDs for HVAC_MAX_DEFROST_ON indicate MAX DEFROST can be controlled
+     * in the area.
+     * For example:
+     * areaConfig.areaId = {ROW_1_LEFT | ROW_1_RIGHT} indicates HVAC_MAX_DEFROST_ON
+     * only can be controlled for the front rows.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_MAX_DEFROST_ON = 0x0507 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Recirculation on/off
+     *
+     * Controls the supply of exterior air to the cabin.  Recirc “on” means the
+     * majority of the airflow into the cabin is originating in the cabin.
+     * Recirc “off” means the majority of the airflow into the cabin is coming
+     * from outside the car.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_RECIRC_ON = 0x0508 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Enable temperature coupling between areas.
+     *
+     * The AreaIDs for HVAC_DUAL_ON property shall contain a combination of
+     * HVAC_TEMPERATURE_SET AreaIDs that can be coupled together. If
+     * HVAC_TEMPERATURE_SET is mapped to AreaIDs [a_1, a_2, ..., a_n], and if
+     * HVAC_DUAL_ON can be enabled to couple a_i and a_j, then HVAC_DUAL_ON
+     * property must be mapped to [a_i | a_j]. Further, if a_k and a_l can also
+     * be coupled together separately then HVAC_DUAL_ON must be mapped to
+     * [a_i | a_j, a_k | a_l].
+     *
+     * Example: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+     *  back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
+     *  temperature control units -- driver side and passenger side -- which can
+     *  be optionally synchronized. This may be expressed in the AreaIDs this way:
+     *  - HVAC_TEMPERATURE_SET->[ROW_1_LEFT | ROW_2_LEFT, ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
+     *  - HVAC_DUAL_ON->[ROW_1_LEFT | ROW_2_LEFT | ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
+     *
+     * When the property is enabled, the ECU must synchronize the temperature
+     * for the affected areas. Any parameters modified as a side effect
+     * of turning on/off the DUAL_ON parameter shall generate
+     * onPropertyEvent() callbacks to the VHAL. In addition, if setting
+     * a temperature (i.e. driver's temperature) changes another temperature
+     * (i.e. front passenger's temperature), then the appropriate
+     * onPropertyEvent() callbacks must be generated.  If a user changes a
+     * temperature that breaks the coupling (e.g. setting the passenger
+     * temperature independently) then the VHAL must send the appropriate
+     * onPropertyEvent() callbacks (i.e. HVAC_DUAL_ON = false,
+     * HVAC_TEMPERATURE_SET[AreaID] = xxx, etc).
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_DUAL_ON = 0x0509 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * On/off automatic climate control.
+     *
+     * If true, automatic climate control is on. If false, automatic climate control is off.
+     *
+     * If the vehicle does not support directly turning off automatic climate control, then OEMs
+     * should add logic in their VHAL implementation so that setting HVAC_AUTO_ON to false would
+     * change the necessary HVAC settings to indirectly turn off HVAC_AUTO_ON. Ideally, this should
+     * not be disruptive to the user, so OEMs should change back to the previous state any settings
+     * that were modified once automatic climate control is off. That way the only outcome should be
+     * that HVAC_AUTO_ON is off. If restoring the HVAC settings to its previous settings is not
+     * possible, then the OEM should choose the least disruptive change and implement that.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_AUTO_ON = 0x050A + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Seat heating/cooling
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the maximum seat temperature heating setting.
+     * The minInt32Value must be 0, unless the vehicle supports seat cooling as well. In this case,
+     * minInt32Value indicates the maximum seat temperature cooling setting.
+     *
+     * This property is not in any particular unit, but in a specified range of relative temperature
+     * settings.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_SEAT_TEMPERATURE = 0x050B + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Side Mirror Heat
+     *
+     * Increasing values denote higher heating levels for side mirrors.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value in the config data represents the maximum heating level.
+     * The minInt32Value in the config data MUST be zero and indicates no heating.
+     *
+     * This property is not in any particular unit but in a specified range of relative heating
+     * settings.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_SIDE_MIRROR_HEAT = 0x050C + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Steering Wheel Heating/Cooling
+     *
+     * Sets the amount of heating/cooling for the steering wheel.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the maximum steering wheel heating setting.
+     * The minInt32Value should be 0, unless the vehicle supports steering wheel cooling as well. In
+     * such a case, the minInt32Value indicates the maximum steering wheel cooling setting.
+     *
+     * This property is not in any particular unit but in a specified range of heating settings.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_STEERING_WHEEL_HEAT = 0x050D + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Temperature units for display
+     *
+     * Indicates whether the vehicle is displaying temperature to the user as
+     * Celsius or Fahrenheit.
+     * VehiclePropConfig.configArray is used to indicate the supported temperature display units.
+     * For example: configArray[0] = CELSIUS
+     *              configArray[1] = FAHRENHEIT
+     *
+     * This parameter MAY be used for displaying any HVAC temperature in the system.
+     * Values must be one of VehicleUnit::CELSIUS or VehicleUnit::FAHRENHEIT
+     * Note that internally, all temperatures are represented in floating point Celsius.
+     *
+     * If updating HVAC_TEMPERATURE_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS
+     * properties, then their values must be updated and communicated to the AAOS framework as well.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    HVAC_TEMPERATURE_DISPLAY_UNITS = 0x050E + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Actual fan speed
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    HVAC_ACTUAL_FAN_SPEED_RPM = 0x050F + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Represents global power state for HVAC. Setting this property to false
+     * MAY mark some properties that control individual HVAC features/subsystems
+     * to UNAVAILABLE state. Setting this property to true MAY mark some
+     * properties that control individual HVAC features/subsystems to AVAILABLE
+     * state (unless any/all of them are UNAVAILABLE on their own individual
+     * merits).
+     *
+     * [Definition] HvacPower_DependentProperties: Properties that need HVAC to be
+     *   powered on in order to enable their functionality. For example, in some cars,
+     *   in order to turn on the AC, HVAC must be powered on first.
+     *
+     * HvacPower_DependentProperties list must be set in the
+     * VehiclePropConfig.configArray. HvacPower_DependentProperties must only contain
+     * properties that are associated with VehicleArea:SEAT. Properties that are not
+     * associated with VehicleArea:SEAT, for example, HVAC_DEFROSTER, must never
+     * depend on HVAC_POWER_ON property and must never be part of
+     * HvacPower_DependentProperties list.
+     *
+     * AreaID mapping for HVAC_POWER_ON property must contain all AreaIDs that
+     * HvacPower_DependentProperties are mapped to.
+     *
+     * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three back
+     *  seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). If the HVAC features (AC,
+     *  Temperature etc.) throughout the car are dependent on a single HVAC power
+     *  controller then HVAC_POWER_ON must be mapped to
+     *  [ROW_1_LEFT | ROW_1_RIGHT | ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT].
+     *
+     * Example 2: A car has two seats in the front row (ROW_1_LEFT, ROW_1_RIGHT) and
+     *   three seats in the second (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT) and third
+     *   rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). If the car has temperature
+     *   controllers in the front row which can operate entirely independently of
+     *   temperature controllers in the back of the vehicle, then HVAC_POWER_ON
+     *   must be mapped to a two element array:
+     *   - ROW_1_LEFT | ROW_1_RIGHT
+     *   - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_POWER_ON = 0x0510 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Fan Positions Available
+     *
+     * This is a bit mask of fan positions available for the zone.  Each
+     * available fan direction is denoted by a separate entry in the vector.  A
+     * fan direction may have multiple bits from vehicle_hvac_fan_direction set.
+     * For instance, a typical car may have the following fan positions:
+     *   - FAN_DIRECTION_FACE (0x1)
+     *   - FAN_DIRECTION_FLOOR (0x2)
+     *   - FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR (0x3)
+     *   - FAN_DIRECTION_DEFROST (0x4)
+     *   - FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST (0x6)
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleHvacFanDirection
+     */
+    HVAC_FAN_DIRECTION_AVAILABLE = 0x0511 + 0x10000000 + 0x05000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32_VEC
+    /**
+     * Automatic recirculation on/off
+     *
+     * When automatic recirculation is ON, the HVAC system may automatically
+     * switch to recirculation mode if the vehicle detects poor incoming air
+     * quality.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_AUTO_RECIRC_ON = 0x0512 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Seat ventilation
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value must be 0.
+     * The maxInt32Value indicates the maximum ventilation setting available for the seat.
+     *
+     * This property is not in any particular unit but in the specified range of ventilation
+     * settings.
+     *
+     * Used by HVAC apps and Assistant to enable, change, or read state of seat
+     * ventilation.  This is different than seating cooling. It can be on at the
+     * same time as cooling, or not.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_SEAT_VENTILATION = 0x0513 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Electric defrosters' status
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_ELECTRIC_DEFROSTER_ON = 0x0514 + 0x10000000 + 0x03000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
+    /**
+     * Suggested values for setting HVAC temperature.
+     *
+     * Implement the property to help applications understand the closest supported temperature
+     * value in Celsius or Fahrenheit.
+     *
+     *      floatValues[0] = the requested value that an application wants to set a temperature to.
+     *      floatValues[1] = the unit for floatValues[0]. It should be one of
+     *                       {VehicleUnit:CELSIUS, VehicleUnit:FAHRENHEIT}.
+     *      floatValues[2] = the value OEMs suggested in CELSIUS. This value is not included
+     *                       in the request.
+     *      floatValues[3] = the value OEMs suggested in FAHRENHEIT. This value is not included
+     *                       in the request.
+     *
+     * An application calls set(VehiclePropValue propValue) with the requested value and unit for
+     * the value. OEMs need to return the suggested values in floatValues[2] and floatValues[3] by
+     * onPropertyEvent() callbacks.
+     *
+     * For example, when a user uses the voice assistant to set HVAC temperature to 66.2 in
+     * Fahrenheit.
+     * First, an application will set this property with the value
+     * [66.2, (float)VehicleUnit:FAHRENHEIT,0,0].
+     * If OEMs suggest to set 19.0 in Celsius or 66.5 in Fahrenheit for user's request, then VHAL
+     * must generate a callback with property value
+     * [66.2, (float)VehicleUnit:FAHRENHEIT, 19.0, 66.5]. After the voice assistant gets the
+     * callback, it will inform the user and set HVAC temperature to the suggested value.
+     *
+     * Another example, an application receives 21 Celsius as the current temperature value by
+     * querying HVC_TEMPERATURE_SET. But the application wants to know what value is displayed on
+     * the car's UI in Fahrenheit.
+     * For this, the application sets the property to [21, (float)VehicleUnit:CELSIUS, 0, 0]. If
+     * the suggested value by the OEM for 21 Celsius is 70 Fahrenheit, then VHAL must generate a
+     * callback with property value [21, (float)VehicleUnit:CELSIUS, 21.0, 70.0].
+     * In this case, the application can know that the value is 70.0 Fahrenheit in the car’s UI.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HVAC_TEMPERATURE_VALUE_SUGGESTION = 0x0515 + 0x10000000 + 0x01000000
+            + 0x00610000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT_VEC
+    /**
+     * Distance units for display
+     *
+     * Indicates which units the car is using to display distances to the user. Eg. Mile, Meter
+     * Kilometer.
+     *
+     * Distance units are defined in VehicleUnit.
+     * VehiclePropConfig.configArray is used to indicate the supported distance display units.
+     * For example: configArray[0] = METER
+     *              configArray[1] = KILOMETER
+     *              configArray[2] = MILE
+     *
+     * If updating DISTANCE_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties,
+     * then their values must be updated and communicated to the AAOS framework as well.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    DISTANCE_DISPLAY_UNITS = 0x0600 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fuel volume units for display
+     *
+     * Indicates which units the car is using to display fuel volume to the user. Eg. Liter or
+     * Gallon.
+     *
+     * VehiclePropConfig.configArray is used to indicate the supported fuel volume display units.
+     * Volume units are defined in VehicleUnit.
+     * For example: configArray[0] = LITER
+     *              configArray[1] = GALLON
+     *
+     * If updating FUEL_VOLUME_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties,
+     * then their values must be updated and communicated to the AAOS framework as well.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    FUEL_VOLUME_DISPLAY_UNITS = 0x0601 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Tire pressure units for display
+     *
+     * Indicates which units the car is using to display tire pressure to the user. Eg. PSI, Bar or
+     * Kilopascal.
+     *
+     * VehiclePropConfig.configArray is used to indicate the supported pressure display units.
+     * Pressure units are defined in VehicleUnit.
+     * For example: configArray[0] = KILOPASCAL
+     *              configArray[1] = PSI
+     *              configArray[2] = BAR
+     *
+     * If updating TIRE_PRESSURE_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS
+     * properties, then their values must be updated and communicated to the AAOS framework as well.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    TIRE_PRESSURE_DISPLAY_UNITS = 0x0602 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * EV battery units for display
+     *
+     * Indicates which units the car is using to display EV battery information to the user. Eg.
+     * watt-hours(Wh), kilowatt-hours(kWh) or ampere-hours(Ah).
+     *
+     * VehiclePropConfig.configArray is used to indicate the supported electrical energy units.
+     * Electrical energy units are defined in VehicleUnit.
+     * For example: configArray[0] = WATT_HOUR
+     *              configArray[1] = AMPERE_HOURS
+     *              configArray[2] = KILOWATT_HOUR
+     *
+     * If updating EV_BATTERY_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties,
+     * then their values must be updated and communicated to the AAOS framework as well.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleUnit
+     */
+    EV_BATTERY_DISPLAY_UNITS = 0x0603 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fuel consumption units for display
+     *
+     * Indicates type of units the car is using to display fuel consumption information to user
+     * True indicates units are distance over volume such as MPG.
+     * False indicates units are volume over distance such as L/100KM.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 0x0604 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Speed units for display
+     *
+     * Indicates type of units the car is using to display speed to user. Eg. m/s, km/h, or mph.
+     *
+     * VehiclePropConfig.configArray is used to indicate the supported speed display units.
+     * Pressure units are defined in VehicleUnit.
+     * For example: configArray[0] = METER_PER_SEC
+     *              configArray[1] = MILES_PER_HOUR
+     *              configArray[2] = KILOMETERS_PER_HOUR
+     *
+     * If updating VEHICLE_SPEED_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS
+     * properties, then their values must be updated and communicated to the AAOS framework as well.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Current date and time suggestion for the Car, encoded as Epoch time
+     * (in milliseconds). This value denotes the number of milliseconds seconds
+     * that have elapsed since 1/1/1970 UTC.
+     *
+     * This property signals a change in CarTime to Android. If the property is supported, VHAL
+     * must report the most accurate current CarTime when this property is read, and publish a
+     * change to this property when the CarTime value has changed. An on-change event for this
+     * property must be published when CarTime changes for any reason other than the natural elapse
+     * of time (time delta smaller than 500ms should not trigger an on change event). Android will
+     * read and subscribe to this property to fetch time from VHAL. This can be useful to
+     * synchronize Android's time with other vehicle systems (dash clock etc).
+     *     int64Values[0] = provided Epoch time (in milliseconds)
+     *
+     * Whenever a new Value for the property is received, AAOS will create
+     * and send an "ExternalTimeSuggestion" to the "TimeDetectorService".
+     * If other sources do not have a higher priority, Android will use this
+     * to set the system time. For information on how to adjust time source
+     * priorities and how time suggestions are handled (including how Android
+     * handles gitter, drift, and minimum resolution) see Time Detector Service
+     * documentation.
+     *
+     * Note that the property may take >0 ms to get propagated through the stack
+     * and, having a timestamped property helps reduce any time drift. So,
+     * for all reads to the property, the timestamp can be used to negate this
+     * drift:
+     *     drift = elapsedTime - PropValue.timestamp
+     *     effectiveTime = PropValue.value.int64Values[0] + drift
+     *
+     * It is strongly recommended that this property must not be used to retrieve
+     * time from ECUs using protocols (GNSS, NTP, Telephony etc). Since these
+     * protocols are already supported by Android, it is recommended to use
+     * Android’s own systems for them instead of wiring those through the VHAL
+     * using this property.
+     *
+     * WARNING: The value available through this property should not be dependent
+     * on value written by Android to ANDROID_EPOCH_TIME property in any way.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:MILLI_SECS
+     */
+    EXTERNAL_CAR_TIME = 0x0608 + 0x10000000 // VehiclePropertyGroup:SYSTEM
+            + 0x01000000 // VehicleArea:GLOBAL
+            + 0x00500000, // VehiclePropertyType:INT64
+    /**
+     * Current date and time, encoded as Epoch time (in milliseconds).
+     * This value denotes the number of milliseconds seconds that have
+     * elapsed since 1/1/1970 UTC.
+     *
+     * CarServices will write to this value to give VHAL the Android system's
+     * time, if the VHAL supports this property. This can be useful to
+     * synchronize other vehicle systems (dash clock etc) with Android's time.
+     *
+     * AAOS writes to this property once during boot, and
+     * will thereafter write only when some time-source changes are propagated.
+     * AAOS will fill in VehiclePropValue.timestamp correctly.
+     * Note that AAOS will not send updates for natural elapse of time.
+     *     int64Values[0] = provided Unix time (in milliseconds)
+     *
+     * Note that the property may take >0 ms to get propagated through the stack
+     * and, having a timestamped property helps reduce any time drift. So,
+     * for all writes to the property, the timestamp can be used to negate this
+     * drift:
+     *     drift = elapsedTime - PropValue.timestamp
+     *     effectiveTime = PropValue.value.int64Values[0] + drift
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     * @unit VehicleUnit:MILLI_SECS
+     */
+    ANDROID_EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000
+            + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
+    /**
+     * External encryption binding seed.
+     *
+     * This value is mixed with the local key storage encryption key.
+     * This property holds 16 bytes, and is expected to be persisted on an ECU separate from
+     * the IVI. The property is initially set by AAOS, who generates it using a CSRNG.
+     * AAOS will then read the property on subsequent boots. The binding seed is expected to be
+     * reliably persisted. Any loss of the seed results in a factory reset of the IVI.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    STORAGE_ENCRYPTION_BINDING_SEED = 0x0607 + 0x10000000 + 0x01000000
+            + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
+    /**
+     * Outside temperature
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:CELSIUS
+     */
+    ENV_OUTSIDE_TEMPERATURE = 0x0703 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+    /**
+     * Property to control power state of application processor
+     *
+     * It is assumed that AP's power state is controlled by a separate power
+     * controller.
+     *
+     * For configuration information, VehiclePropConfig.configArray must have bit flag combining
+     * values in VehicleApPowerStateConfigFlag.
+     *
+     *   int32Values[0] : VehicleApPowerStateReq enum value
+     *   int32Values[1] : additional parameter relevant for each state,
+     *                    0 if not used.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    AP_POWER_STATE_REQ = 0x0A00 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Property to report power state of application processor
+     *
+     * It is assumed that AP's power state is controller by separate power
+     * controller.
+     *
+     *   int32Values[0] : VehicleApPowerStateReport enum value
+     *   int32Values[1] : Time in ms to wake up, if necessary.  Otherwise 0.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    AP_POWER_STATE_REPORT = 0x0A01 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Property to report bootup reason for the current power on. This is a
+     * static property that will not change for the whole duration until power
+     * off. For example, even if user presses power on button after automatic
+     * power on with door unlock, bootup reason must stay with
+     * VehicleApPowerBootupReason#USER_UNLOCK.
+     *
+     * int32Values[0] must be VehicleApPowerBootupReason.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     */
+    AP_POWER_BOOTUP_REASON = 0x0A02 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Property to represent brightness of the display.
+     *
+     * Some cars have single control for the brightness of all displays and this
+     * property is to share change in that control. In cars which have displays
+     * whose brightness is controlled separately, they must use
+     * PER_DISPLAY_BRIGHTNESS.
+     *
+     * Only one of DISPLAY_BRIGHTNESS and PER_DISPLAY_BRIGHTNESS should be
+     * implemented. If both are available, PER_DISPLAY_BRIGHTNESS is used by
+     * AAOS.
+     *
+     * If this is writable, android side can set this value when user changes
+     * display brightness from Settings. If this is read only, user may still
+     * change display brightness from Settings, but that must not be reflected
+     * to other displays.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    DISPLAY_BRIGHTNESS = 0x0A03 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Property to represent brightness of the displays which are controlled separately.
+     *
+     * Some cars have one or more displays whose brightness is controlled
+     * separately and this property is to inform the brightness of each
+     * passenger display. In cars where all displays' brightness is controlled
+     * together, they must use DISPLAY_BRIGHTNESS.
+     *
+     * Only one of DISPLAY_BRIGHTNESS and PER_DISPLAY_BRIGHTNESS should be
+     * implemented. If both are available, PER_DISPLAY_BRIGHTNESS is used by
+     * AAOS.
+     *
+     * The display port uniquely identifies a physical connector on the device
+     * for display output, ranging from 0 to 255.
+     *
+     * int32Values[0] : display port
+     * int32Values[1] : brightness
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    PER_DISPLAY_BRIGHTNESS = 0x0A04 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Property to feed H/W input events to android
+     *
+     * int32Values[0] : action defined by VehicleHwKeyInputAction
+     * int32Values[1] : key code, must use standard android key code
+     * int32Values[2] : target display defined in VehicleDisplay. Events not
+     *                  tied to specific display must be sent to
+     *                  VehicleDisplay#MAIN.
+     * int32Values[3] : [optional] Number of ticks. The value must be equal or
+     *                  greater than 1. When omitted, Android will default to 1.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @config_flags
+     */
+    HW_KEY_INPUT = 0x0A10 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Property to feed H/W input events to android
+     *
+     * int32array[0]: target display defined by VehicleDisplay like VehicleDisplay::MAIN,
+     *                VehicleDisplay::INSTRUMENT_CLUSTER, VehicleDisplay::AUX
+     * int32array[1]: key code, must use standard android key code like KEYCODE_HOME, KEYCODE_BACK
+     * int32array[2]: action defined in VehicleHwKeyInputAction like
+     *                VehicleHwKeyInputAction::ACTION_UP, VehicleHwKeyInputAction::ACTION_UP
+     * int32array[3]: repeat count of the event. For key down events, this is the repeat count
+     *                with the first down starting at 0 and counting up from there. For key up
+     *                events, this is always equal to 0
+     *
+     * int64array[0]: down time, elapsed nanoseconds since boot. Denotes the time of the most
+     *                recent key down event. For the down event, it will be the event time of the
+     *                down event itself
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @config_flags
+     */
+    HW_KEY_INPUT_V2 =
+            0x0A11 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.MIXED,
+    /**
+     * Property to feed H/W input events to android
+     *
+     * int32array[0]: target display defined by VehicleDisplay like VehicleDisplay::MAIN,
+     *                VehicleDisplay::INSTRUMENT_CLUSTER, VehicleDisplay::AUX
+     * int32array[1]: input type defined in VehicleHwMotionInputSource like
+     *                VehicleHwMotionInputSource::SOURCE_KEYBOARD,
+     *                VehicleHwMotionInputSource::SOURCE_DPAD
+     * int32array[2]: action code defined in VehicleHwMotionInputAction like
+     *                VehicleHwMotionInputAction::ACTION_UP, VehicleHwMotionInputAction::ACTION_DOWN
+     * int32array[3]: button state flag defined in VehicleHwMotionButtonStateFlag like
+     *                VehicleHwMotionButtonStateFlag::BUTTON_PRIMARY,
+     *                VehicleHwMotionButtonStateFlag::BUTTON_SECONDARY
+     * int32array[4]: pointer events count, N. N must be a positive integer
+     * int32array[5:5+N-1]: pointer id, length N
+     * int32array[5+N:5+2*N-1] : tool type, length N. As defined in VehicleHwMotionToolType like
+     *                           VehicleHwMotionToolType::TOOL_TYPE_FINGER,
+     *                           VehicleHwMotionToolType::TOOL_TYPE_STYLUS
+     *
+     * floatArray[0:N-1] : x data, length N
+     * floatArray[N:2*N-1] : y data, length N
+     * floatArray[2*N:3*N-1] : pressure data, length N
+     * floatArray[3*N:4*N-1] : size data, length N
+     *
+     * int64array[0]: down time, elapsed nanoseconds since boot. Denotes the time when the user
+     *                originally pressed down to start a stream of position events. For the down
+     *                event, it will be the event time of the down event itself
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @config_flags
+     */
+    HW_MOTION_INPUT =
+            0x0A12 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.MIXED,
+    /**
+     * Property to feed H/W rotary events to android
+     *
+     * int32Values[0] : RotaryInputType identifying which rotary knob rotated
+     * int32Values[1] : number of detents (clicks), positive for clockwise,
+     *                  negative for counterclockwise
+     * int32Values[2] : target display defined in VehicleDisplay. Events not
+     *                  tied to specific display must be sent to
+     *                  VehicleDisplay#MAIN.
+     * int32values[3 .. 3 + abs(number of detents) - 2]:
+     *                  nanosecond deltas between pairs of consecutive detents,
+     *                  if the number of detents is > 1 or < -1
+     *
+     * VehiclePropValue.timestamp: when the rotation occurred. If the number of
+     *                             detents is > 1 or < -1, this is when the
+     *                             first detent of rotation occurred.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @data_enum RotaryInputType
+     * @access VehiclePropertyAccess.READ
+     */
+    HW_ROTARY_INPUT = 0x0A20 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Defines a custom OEM partner input event.
+     *
+     * This input event must be used by OEM partners who wish to propagate events not supported
+     * by Android. It is composed by an array of int32 values only.
+     *
+     * The Android properties are:
+     *
+     * int32Values[0] : Input code identifying the function representing this event. Valid event
+     *                  types are defined by CustomInputType.CUSTOM_EVENT_F1 up to
+     *                  CustomInputType.CUSTOM_EVENT_F10. They represent the custom event to be
+     *                  defined by OEM partners.
+     * int32Values[1] : target display type defined in VehicleDisplay. Events not tied to specific
+     *                  display must be sent to VehicleDisplay#MAIN.
+     * int32Values[2] : repeat counter, if 0 then event is not repeated. Values 1 or above means
+     *                  how many times this event repeated.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @data_enum CustomInputType
+     * @access VehiclePropertyAccess.READ
+     */
+    HW_CUSTOM_INPUT = 0X0A30 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /***************************************************************************
+     * Most Car Cabin properties have both a POSition and MOVE parameter.  These
+     * are used to control the various movements for seats, doors, and windows
+     * in a vehicle.
+     *
+     * A POS parameter allows the user to set the absolution position.  For
+     * instance, for a door, 0 indicates fully closed and max value indicates
+     * fully open.  Thus, a value halfway between min and max must indicate
+     * the door is halfway open.
+     *
+     * A MOVE parameter moves the device in a particular direction.  The sign
+     * indicates direction, and the magnitude indicates speed (if multiple
+     * speeds are available).  For a door, a move of -1 will close the door, and
+     * a move of +1 will open it.  Once a door reaches the limit of open/close,
+     * the door should automatically stop moving.  The user must NOT need to
+     * send a MOVE(0) command to stop the door at the end of its range.
+     **************************************************************************/
+
+    /**
+     * Door position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the door is closed. The minInt32Value must be 0.
+     * The maxInt32Value indicates the door is fully open.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * closed and fully open positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * Some vehicles (minivans) can open the door electronically. Hence, the
+     * ability to write this property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    DOOR_POS = 0x0B00 + 0x10000000 + 0x06000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
+    /**
+     * Door move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the door while opening.
+     * The minInt32Value represents the maximum movement speed of the door while closing.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the door reaches the positional limit, the value must reset to 0. If DOOR_MOVE's value is
+     * currently 0, then that means there is no movement currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    DOOR_MOVE = 0x0B01 + 0x10000000 + 0x06000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
+    /**
+     * Door lock
+     *
+     * 'true' indicates door is locked
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    DOOR_LOCK = 0x0B02 + 0x10000000 + 0x06000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:BOOLEAN
+    /**
+     * Door child lock feature enabled
+     *
+     * Returns true if the door child lock feature is enabled and false if it is disabled.
+     *
+     * If enabled, the door is unable to be opened from the inside.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    DOOR_CHILD_LOCK_ENABLED =
+            0x0B03 + VehiclePropertyGroup.SYSTEM + VehicleArea.DOOR + VehiclePropertyType.BOOLEAN,
+    /**
+     * Mirror Z Position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the mirror is tilted completely downwards. This must be a
+     * non-positive value.
+     * The maxInt32Value indicates the mirror is tilted completely upwards. This must be a
+     * non-negative value.
+     * 0 indicates the mirror is not tilted in either direction.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * fully downward and fully upwards positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    MIRROR_Z_POS = 0x0B40 + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Mirror Z Move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the mirror while tilting upwards.
+     * The minInt32Value represents the maximum movement speed of the mirror while tilting
+     * downwards.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the mirror reaches the positional limit, the value must reset to 0. If MIRROR_Z_MOVE's value
+     * is currently 0, then that means there is no movement currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    MIRROR_Z_MOVE = 0x0B41 + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Mirror Y Position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the mirror is tilted completely to the left. This must be a
+     * non-positive value.
+     * The maxInt32Value indicates the mirror is tilted completely to the right. This must be a
+     * non-negative value.
+     * 0 indicates the mirror is not tilted in either direction.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * left extreme and right extreme positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    MIRROR_Y_POS = 0x0B42 + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Mirror Y Move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the mirror while tilting right.
+     * The minInt32Value represents the maximum movement speed of the mirror while tilting left.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the mirror reaches the positional limit, the value must reset to 0. If MIRROR_Y_MOVE's value
+     * is currently 0, then that means there is no movement currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    MIRROR_Y_MOVE = 0x0B43 + 0x10000000 + 0x04000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+    /**
+     * Mirror Lock
+     *
+     * True indicates mirror positions are locked and not changeable
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    MIRROR_LOCK = 0x0B44 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Mirror Fold
+     *
+     * True indicates mirrors are folded
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    MIRROR_FOLD = 0x0B45 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+
+    /**
+     * Represents property for Mirror Auto Fold feature.
+     *
+     * This property is true when the feature for automatically folding the vehicle's side mirrors
+     * (for example, when the mirrors fold inward automatically when one exits and locks the
+     * vehicle) is enabled.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+
+    MIRROR_AUTO_FOLD_ENABLED =
+            0x0B46 + VehiclePropertyGroup.SYSTEM + VehicleArea.MIRROR + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Represents property for Mirror Auto Tilt feature.
+     *
+     * This property is true when the feature for automatically tilting the vehicle's side mirrors
+     * (for example, when the mirrors tilt downward automatically when one reverses the vehicle) is
+     * enabled.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+
+    MIRROR_AUTO_TILT_ENABLED =
+            0x0B47 + VehiclePropertyGroup.SYSTEM + VehicleArea.MIRROR + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Seat memory select
+     *
+     * This parameter selects the memory preset to use to select the seat position. The
+     * maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between
+     * minInt32Value and maxInt32Value must be supported. The minInt32Value is always 0, and the
+     * maxInt32Value determines the number of seat preset memory slots available (i.e.
+     * numSeatPresets - 1).
+     *
+     * For instance, if the driver's seat has 3 memory presets, the maxInt32Value will be 2. When
+     * the user wants to select a preset, the desired preset number (0, 1, or 2) is set.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     */
+    SEAT_MEMORY_SELECT = 0x0B80 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat memory set
+     *
+     * This setting allows the user to save the current seat position settings into the selected
+     * preset slot. The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. The
+     * minInt32Value must be 0, and the maxInt32Value for each seat position must match the
+     * maxInt32Value for SEAT_MEMORY_SELECT.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     */
+    SEAT_MEMORY_SET = 0x0B81 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seatbelt buckled
+     *
+     * True indicates belt is buckled.
+     *
+     * Write access indicates automatic seat buckling capabilities.  There are
+     * no known cars at this time, but you never know...
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_BELT_BUCKLED = 0x0B82 + 0x10000000 + 0x05000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+    /**
+     * Seatbelt height position
+     *
+     * Adjusts the shoulder belt anchor point.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the seat belt's shoulder anchor is at its lowest position.
+     * The maxInt32Value indicates the seat belt's shoulder anchor is at its highest position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * lowest and highest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_BELT_HEIGHT_POS = 0x0B83 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seatbelt height move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat belt's shoulder anchor
+     * while moving upwards.
+     * The minInt32Value represents the maximum movement speed of the seat belt's shoulder anchor
+     * while moving downwards.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat belt reaches the positional limit, the value must reset to 0. If
+     * SEAT_BELT_HEIGHT_MOVE's value is currently 0, then that means there is no movement currently
+     * occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_BELT_HEIGHT_MOVE = 0x0B84 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat fore/aft position
+     *
+     * Sets the seat position forward and backwards.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the seat is at its rearward-most linear position.
+     * The maxInt32Value indicates the seat is at its forward-most linear position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * closest and farthest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_FORE_AFT_POS = 0x0B85 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat fore/aft move
+     *
+     * This property moves the entire seat forward/backward in the direction that it is facing.
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat while moving forward.
+     * The minInt32Value represents the maximum movement speed of the seat while moving backward.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat reaches the positional limit, the value must reset to 0. If SEAT_FORE_AFT_MOVE's
+     * value is currently 0, then that means there is no movement currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_FORE_AFT_MOVE = 0x0B86 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat backrest angle 1 position
+     *
+     * Backrest angle 1 is the actuator closest to the bottom of the seat.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the seat backrest's full recline position w.r.t the
+     * actuator at the bottom of the seat.
+     * The maxInt32Value indicates the seat backrest's most upright/forward position w.r.t the
+     * actuator at the bottom of the seat.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * full recline and upright/forward positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_BACKREST_ANGLE_1_POS = 0x0B87 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat backrest angle 1 move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat backrest while angling
+     * forward.
+     * The minInt32Value represents the maximum movement speed of the seat backrest while reclining.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat backrest reaches the positional limit, the value must reset to 0. If
+     * SEAT_BACKREST_ANGLE_1_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_BACKREST_ANGLE_1_MOVE = 0x0B88 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat backrest angle 2 position
+     *
+     * Backrest angle 2 is the next actuator up from the bottom of the seat.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the seat backrest's full recline position w.r.t the next
+     * actuator in the backrest from the one at the bottom of the seat (see
+     * SEAT_BACKREST_ANGLE_1_POS for additional details).
+     * The maxInt32Value indicates the seat backrest's most upright/forward position w.r.t the
+     * next actuator in the backrest from the one at the bottom of the seat(see
+     * SEAT_BACKREST_ANGLE_1_POS for additional details).
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * full recline and upright/forward positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_BACKREST_ANGLE_2_POS = 0x0B89 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat backrest angle 2 move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat backrest while angling
+     * forward.
+     * The minInt32Value represents the maximum movement speed of the seat backrest while reclining.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat backrest reaches the positional limit, the value must reset to 0. If
+     * SEAT_BACKREST_ANGLE_2_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_BACKREST_ANGLE_2_MOVE = 0x0B8A + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat height position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the seat is in its lowest position.
+     * The maxInt32Value indicates the seat is in its highest position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * lowest and highest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEIGHT_POS = 0x0B8B + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat height move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat while moving upward.
+     * The minInt32Value represents the maximum movement speed of the seat while moving downward.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat reaches the positional limit, the value must reset to 0. If SEAT_HEIGHT_MOVE's value
+     * is currently 0, then that means there is no movement currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEIGHT_MOVE = 0x0B8C + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat depth position
+     *
+     * Sets the seat depth, distance from back rest to front edge of seat.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the seat is in its shallowest position (i.e. the position with
+     * the smallest distance between the front edge of the seat cushion and the rear end of the
+     * seat).
+     * The maxInt32Value indicates the seat is in its deepest position (i.e. the position with the
+     * largest distance between the front edge of the seat cushion and the rear end of the seat).
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * shallowest and deepest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_DEPTH_POS = 0x0B8D + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat depth move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat while getting deeper
+     * The minInt32Value represents the maximum movement speed of the seat while getting shallower.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat backrest reaches the positional limit, the value must reset to 0. If
+     * SEAT_DEPTH_MOVE's value is currently 0, then that means there is no movement currently
+     * occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_DEPTH_MOVE = 0x0B8E + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat tilt position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the seat bottom is angled at its lowest angular position. This
+     * corresponds to the seat's front edge at its lowest possible position relative to the rear
+     * end of the seat.
+     * The maxInt32Value indicates the seat bottom is angled at its highest angular position. This
+     * corresponds to the seat's front edge at its highest possible position relative to the rear
+     * end of the seat.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * lowest and highest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_TILT_POS = 0x0B8F + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Seat tilt move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the front edge of the seat while
+     * moving upward.
+     * The minInt32Value represents the maximum movement speed of the front edge of the seat while
+     * moving downward.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat bottom reaches the positional limit, the value must reset to 0. If SEAT_TILT_MOVE's
+     * value is currently 0, then that means there is no movement currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_TILT_MOVE = 0x0B90 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Lumber fore/aft position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the lumbar support is in its rearward most position (i.e. least
+     * supportive position).
+     * The maxInt32Value indicates the lumbar support is in its forward most position (i.e. most
+     * supportive position).
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * forward and rearward positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_LUMBAR_FORE_AFT_POS = 0x0B91 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Lumbar fore/aft move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat's lumbar support while
+     * moving forward.
+     * The minInt32Value represents the maximum movement speed of the seat's lumbar support while
+     * moving backward.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat's lumbar support reaches the positional limit, the value must reset to 0. If
+     * SEAT_LUMBAR_FORE_AFT_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_LUMBAR_FORE_AFT_MOVE = 0x0B92 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Lumbar side support position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the lumbar side support is in its thinnest position (i.e.
+     * most support).
+     * The maxInt32Value indicates the lumbar side support is in its widest position (i.e.
+     * least support).
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * thinnest and widest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_LUMBAR_SIDE_SUPPORT_POS = 0x0B93 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Lumbar side support move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat's lumbar side support
+     * while getting wider.
+     * The minInt32Value represents the maximum movement speed of the seat's lumbar side support
+     * while getting thinner.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat's lumbar side support reaches the positional limit, the value must reset to 0. If
+     * SEAT_LUMBAR_SIDE_SUPPORT_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 0x0B94 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * (Deprecated) Headrest height position
+     *
+     * This property is deprecated because it is defined as type VehicleArea:GLOBAL, which means all
+     * seats use the same value. Use SEAT_HEADREST_HEIGHT_POS_V2 instead which fixes this issue by
+     * being defined as type VehicleArea:SEAT.
+     *
+     * Sets the headrest height.
+     * Max value indicates tallest setting.
+     * Min value indicates shortest setting.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEADREST_HEIGHT_POS = 0x0B95 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Headrest height position
+     *
+     * Sets the headrest height for supported seats. VehiclePropConfig.areaConfigs specifies which
+     * seats are supported.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the headrest is in its lowest position.
+     * The maxInt32Value indicates the headrest is in its highest position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * lowest and highest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEADREST_HEIGHT_POS_V2 =
+            0x0BA4 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+
+    /**
+     * Headrest height move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat's headrest while moving
+     * up.
+     * The minInt32Value represents the maximum movement speed of the seat's headrest while moving
+     * down.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat's headrest reaches the positional limit, the value must reset to 0. If
+     * SEAT_HEADREST_HEIGHT_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEADREST_HEIGHT_MOVE = 0x0B96 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Headrest angle position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the headrest is in its full recline position.
+     * The maxInt32Value indicates the headrest is in its most upright/forward position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * full recline and most upright/forward positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEADREST_ANGLE_POS = 0x0B97 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Headrest angle move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat's headrest while moving
+     * into an upright/forward position.
+     * The minInt32Value represents the maximum movement speed of the seat's headrest while moving
+     * into a shallow position.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat's headrest reaches the positional limit, the value must reset to 0. If
+     * SEAT_HEADREST_ANGLE_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEADREST_ANGLE_MOVE = 0x0B98 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Headrest fore/aft position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the headrest is in its rearward-most linear position.
+     * The maxInt32Value indicates the headrest is in its forward-most linear position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * forward and rearward positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEADREST_FORE_AFT_POS = 0x0B99 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Headrest fore/aft move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat's headrest while moving
+     * forward.
+     * The minInt32Value represents the maximum movement speed of the seat's headrest while moving
+     * backward.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat's headrest reaches the positional limit, the value must reset to 0. If
+     * SEAT_HEADREST_FORE_AFT_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_HEADREST_FORE_AFT_MOVE = 0x0B9A + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Represents property for the seat footwell lights state.
+     *
+     * SEAT_FOOTWELL_LIGHTS_STATE reflects the current state of the lights at any point in time.
+     * This is different from the function of SEAT_FOOTWELL_LIGHTS_SWITCH which represents the
+     * position of the switch controlling the lights. Therefore, SEAT_FOOTWELL_LIGHTS_STATE may not
+     * match the value of SEAT_FOOTWELL_LIGHTS_SWITCH (e.g. SEAT_FOOTWELL_LIGHTS_SWITCH=AUTOMATIC
+     * and SEAT_FOOTWELL_LIGHTS_STATE=ON).
+     *
+     * This property should only be implemented if SEAT_FOOTWELL_LIGHTS_STATE's value may be
+     * different from that of CABIN_LIGHTS_STATE.
+     *
+     * For each supported area ID, the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of VehicleLightState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    SEAT_FOOTWELL_LIGHTS_STATE =
+            0x0B9B + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+    /**
+     * Represents property for the seat footwell lights switch.
+     *
+     * SEAT_FOOTWELL_LIGHTS_SWITCH represents the position of the switch controlling the lights.
+     * This is different from the function of SEAT_FOOTWELL_LIGHTS_STATE which reflects the current
+     * state of the lights at any point in time. Therefore, SEAT_FOOTWELL_LIGHTS_SWITCH may not
+     * match the value of SEAT_FOOTWELL_LIGHTS_STATE (e.g. SEAT_FOOTWELL_LIGHTS_SWITCH=AUTOMATIC and
+     * SEAT_FOOTWELL_LIGHTS_STATE=ON).
+     *
+     * This property should only be implemented if SEAT_FOOTWELL_LIGHTS_SWITCH's value may be
+     * different from that of CABIN_LIGHTS_SWITCH.
+     *
+     * For each supported area ID, the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of VehicleLightSwitch are supported.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    SEAT_FOOTWELL_LIGHTS_SWITCH =
+            0x0B9C + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+    /**
+     * Represents property for Seat easy access feature.
+     *
+     * If true, the seat will automatically adjust to make it easier for the occupant to enter and
+     * exit the vehicle. Each area ID must map to the seat that the user is trying to enter/exit
+     * with the help of the easy access feature.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_EASY_ACCESS_ENABLED =
+            0x0B9D + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+    /**
+     * Represents feature to enable/disable a seat's ability to deploy airbag(s) when triggered
+     * (e.g. by a crash).
+     *
+     * If true, it means the seat's airbags are enabled, and if triggered (e.g. by a crash), they
+     * will deploy. If false, it means the seat's airbags are disabled, and they will not deploy
+     * under any circumstance. This property does not indicate if the airbags are deployed or not.
+     *
+     * This property can be set to VehiclePropertyAccess.READ read only for the sake of regulation
+     * or safety concerns.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_AIRBAG_ENABLED =
+            0x0B9E + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+    /**
+     * Represents property for seat’s hipside (bottom cushion’s side) support position.
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the seat cushion side support is in its widest position (i.e.
+     * least support).
+     * The minInt32Value indicates the seat cushion side support is in its thinnest position (i.e.
+     * most support).
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * thinnest and widest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_CUSHION_SIDE_SUPPORT_POS =
+            0x0B9F + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+    /**
+     * Represents property for movement direction and speed of seat cushion side support.
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value represents the maximum movement speed of the seat cushion side support when
+     * growing wider (i.e. support is decreasing).
+     * The minInt32Value represents the maximum movement speed of the seat cushion side support when
+     * growing thinner (i.e. support is increasing).
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat cushion side support reaches the positional limit, the value must reset to 0. If
+     * SEAT_CUSHION_SIDE_SUPPORT_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_CUSHION_SIDE_SUPPORT_MOVE =
+            0x0BA0 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+    /**
+     * Represents property for seat’s lumbar support vertical position.
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the lumbar support's highest position.
+     * The minInt32Value indicates the lumbar support's lowest position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * lowest and highest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_LUMBAR_VERTICAL_POS =
+            0x0BA1 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+    /**
+     * Represents property for vertical movement direction and speed of seat lumbar support.
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the lumbar support is moving at the fastest upward speed.
+     * The minInt32Value indicates the lumbar support is moving at the fastest downward speed.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the seat cushion side support reaches the positional limit, the value must reset to 0. If
+     * SEAT_LUMBAR_VERTICAL_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_LUMBAR_VERTICAL_MOVE =
+            0x0BA2 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+    /**
+     * Represents property that indicates the current walk-in position of the seat.
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the normal seat position. The minInt32Value must be 0.
+     * The maxInt32Value indicates the seat is in the full walk-in position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * normal and walk-in positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * The area ID must match the seat that actually moves when the walk-in feature activates, not
+     * the intended seat the passengers will sit in.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SEAT_WALK_IN_POS =
+            0x0BA3 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+    /**
+     * Seat Occupancy
+     *
+     * Indicates whether a particular seat is occupied or not, to the best of the car's ability
+     * to determine. Valid values are from the VehicleSeatOccupancyState enum.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleSeatOccupancyState
+     */
+    SEAT_OCCUPANCY = 0x0BB0 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Window Position
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the window is closed/fully open out of plane. If the window
+     * cannot open out of plane, then minInt32Value is the position of the window when fully closed
+     * and must be 0. If the window can open out of plane, the minInt32Value indicates the window
+     * is fully open in its position out of plane and will be a negative value. See the example
+     * below for a more detailed explanation.
+     * The maxInt32Value indicates the window is fully open.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * closed/fully open out-of-plane and fully open positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * For example, this is how the property should work for a window that can move out of plane:
+     *  For a window that may open out of plane (i.e. vent mode of sunroof) this
+     *  parameter will work with negative values as follows:
+     *    Max = sunroof completely open
+     *    0 = sunroof closed.
+     *    Min = sunroof vent completely open
+     *
+     *    Note that in this mode, 0 indicates the window is closed.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    WINDOW_POS = 0x0BC0 + 0x10000000 + 0x03000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
+    /**
+     * Window Move
+     *
+     * The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
+     * between minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the window is opening in plane/closing in the out of plane
+     * direction at the fastest speed.
+     * The minInt32Value indicates the window is closing in plane/opening in the out of plane
+     * direction at the fastest speed.
+     *
+     * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+     * the window reaches the positional limit, the value must reset to 0. If WINDOW_MOVE's value is
+     * currently 0, then that means there is no movement currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * For a window that may open out of plane (i.e. vent mode of sunroof) this
+     * parameter will work as follows:
+     *
+     * If sunroof is open:
+     *   Max = open the sunroof further, automatically stop when fully open.
+     *   Min = close the sunroof, automatically stop when sunroof is closed.
+     *
+     * If vent is open:
+     *   Max = close the vent, automatically stop when vent is closed.
+     *   Min = open the vent further, automatically stop when vent is fully open.
+     *
+     * If sunroof is in the closed position:
+     *   Max = open the sunroof, automatically stop when sunroof is fully open.
+     *   Min = open the vent, automatically stop when vent is fully open.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    WINDOW_MOVE = 0x0BC1 + 0x10000000 + 0x03000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
+    /**
+     * Window Lock
+     *
+     * True indicates windows are locked and can't be moved.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    WINDOW_LOCK = 0x0BC4 + 0x10000000 + 0x03000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
+    /**
+     * Windshield wipers period (milliseconds).
+     *
+     * Returns the instantaneous time period for 1 full cycle of the windshield wipers in
+     * milliseconds. A full cycle is defined as a wiper moving from and returning to its rest
+     * position.
+     *
+     * When an intermittent wiper setting is selected, this property value must be set to 0 during
+     * the "pause" period of the intermittent wiping.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. The maxInt32Value
+     * for each area ID must specify the longest wiper period. The minInt32Value must be set to 0
+     * for each area ID.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:MILLI_SECS
+     */
+    WINDSHIELD_WIPERS_PERIOD =
+            0x0BC5 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
+
+    /**
+     * Windshield wipers state.
+     *
+     * Returns the current state of the windshield wipers. The value of WINDSHIELD_WIPERS_STATE may
+     * not match the value of WINDSHIELD_WIPERS_SWITCH. (e.g. WINDSHIELD_WIPERS_STATE = ON and
+     * WINDSHIELD_WIPERS_SWITCH = WindshieldWipersSwitch#AUTO).
+     *
+     * If WINDSHIELD_WIPERS_STATE = ON and WINDSHIELD_WIPERS_PERIOD is implemented, then
+     * WINDSHIELD_WIPERS_PERIOD must reflect the time period of 1 full cycle of the wipers.
+     *
+     * For each supported area ID, the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states in WindshieldWipersState are supported (including OTHER, which is not
+     * recommended).
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum WindshieldWipersState
+     */
+    WINDSHIELD_WIPERS_STATE =
+            0x0BC6 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
+
+    /**
+     * Windshield wipers switch.
+     *
+     * Represents the position of the switch controlling the windshield wipers. The value of
+     * WINDSHIELD_WIPERS_SWITCH may not match the value of WINDSHIELD_WIPERS_STATE (e.g.
+     * WINDSHIELD_WIPERS_SWITCH = AUTO and WINDSHIELD_WIPERS_STATE = WindshieldWipersState#ON).
+     *
+     * For each supported area ID, the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states in WindshieldWipersSwitch are supported (including OTHER, which is not
+     * recommended).
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * If this property is implemented as VehiclePropertyAccess.READ_WRITE and the OTHER state is
+     * listed in the VehicleAreaConfig#supportedEnumValues array, then OTHER is not a supported
+     * value for writing. It is only a supported value for reading.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum WindshieldWipersSwitch
+     */
+    WINDSHIELD_WIPERS_SWITCH =
+            0x0BC7 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
+
+    /**
+     * Steering wheel depth position
+     *
+     * All steering wheel properties' unique ids start from 0x0BE0.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+     * minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the steering wheel position furthest from the driver.
+     * The minInt32Value indicates the steering wheel position closest to the driver.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * closest and furthest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    STEERING_WHEEL_DEPTH_POS =
+            0x0BE0 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * Steering wheel depth movement
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+     * minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the steering wheel moving away from the driver.
+     * The minInt32Value indicates the steering wheel moving towards the driver.
+     *
+     * Larger integers, either positive or negative, indicate a faster movement speed. Once the
+     * steering wheel reaches the positional limit, the value must reset to 0. If
+     * STEERING_WHEEL_DEPTH_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    STEERING_WHEEL_DEPTH_MOVE =
+            0x0BE1 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * Steering wheel height position
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+     * minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the steering wheel being in the highest position.
+     * The minInt32Value indicates the steering wheel being in the lowest position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * lowest and highest positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    STEERING_WHEEL_HEIGHT_POS =
+            0x0BE2 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * Steering wheel height movement
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+     * minInt32Value and maxInt32Value must be supported.
+     *
+     * The maxInt32Value indicates the steering wheel moving upwards.
+     * The minInt32Value indicates the steering wheel moving downwards.
+     *
+     * Larger integers, either positive or negative, indicate a faster movement speed. Once the
+     * steering wheel reaches the positional limit, the value must reset to 0. If
+     * STEERING_WHEEL_HEIGHT_MOVE's value is currently 0, then that means there is no movement
+     * currently occurring.
+     *
+     * This property is not in any particular unit but in a specified range of relative movement
+     * speeds.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    STEERING_WHEEL_HEIGHT_MOVE =
+            0x0BE3 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * Steering wheel theft lock feature enabled
+     *
+     * If true, the steering wheel will lock automatically to prevent theft in certain
+     * situations.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    STEERING_WHEEL_THEFT_LOCK_ENABLED =
+            0x0BE4 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+    /**
+     * Steering wheel locked
+     *
+     * If true, the steering wheel's position is locked and not changeable.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    STEERING_WHEEL_LOCKED =
+            0x0BE5 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+    /**
+     * Steering wheel easy access feature enabled
+     *
+     * If true, the driver’s steering wheel will automatically adjust to make it easier for the
+     * driver to enter and exit the vehicle.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    STEERING_WHEEL_EASY_ACCESS_ENABLED =
+            0x0BE6 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+    /**
+     * Property that represents the current position of the glove box door.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * All integers between minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates that the glove box door is closed. The minInt32Value must be 0.
+     * The maxInt32Value indicates that the glove box door is in the fully open position.
+     *
+     * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+     * closed and fully open positions.
+     *
+     * This property is not in any particular unit but in a specified range of relative positions.
+     *
+     * The area ID must match the seat by which the glove box is intended to be used  (e.g. if the
+     * front right dashboard has a glove box embedded in it, then the area ID should be
+     * SEAT_1_RIGHT).
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    GLOVE_BOX_DOOR_POS =
+            0x0BF0 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+
+    /**
+     * Lock or unlock the glove box.
+     *
+     * If true, the glove box is locked. If false, the glove box is unlocked.
+     *
+     * The area ID must match the seat by which the glove box is intended to be used (e.g. if the
+     * front right dashboard has a glove box embedded in it, then the area ID should be
+     * VehicleAreaSeat#ROW_1_RIGHT).
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    GLOVE_BOX_LOCKED =
+            0x0BF1 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Vehicle Maps Service (VMS) message
+     *
+     * This property uses MIXED data to communicate vms messages.
+     *
+     * Its contents are to be interpreted as follows:
+     * the indices defined in VmsMessageIntegerValuesIndex are to be used to
+     * read from int32Values;
+     * bytes is a serialized VMS message as defined in the vms protocol
+     * which is opaque to the framework;
+     *
+     * IVehicle#get must always return StatusCode::NOT_AVAILABLE.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    VEHICLE_MAP_SERVICE = 0x0C00 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Characterization of inputs used for computing location.
+     *
+     * This property must indicate what (if any) data and sensor inputs are considered by the system
+     * when computing the vehicle's location that is shared with Android through the GNSS HAL.
+     *
+     * The value must return a collection of bit flags. The bit flags are defined in
+     * LocationCharacterization. The value must also include exactly one of DEAD_RECKONED or
+     * RAW_GNSS_ONLY among its collection of bit flags.
+     *
+     * When this property is not supported, it is assumed that no additional sensor inputs are fused
+     * into the GNSS updates provided through the GNSS HAL. That is unless otherwise specified
+     * through the GNSS HAL interfaces.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     */
+    LOCATION_CHARACTERIZATION =
+            0x0C10 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * OBD2 Live Sensor Data
+     *
+     * Reports a snapshot of the current (live) values of the OBD2 sensors available.
+     *
+     * The configArray is set as follows:
+     *   configArray[0] = number of vendor-specific integer-valued sensors
+     *   configArray[1] = number of vendor-specific float-valued sensors
+     *
+     * The values of this property are to be interpreted as in the following example.
+     * Considering a configArray = {2,3}
+     * int32Values must be a vector containing Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 2
+     * elements (that is, 33 elements);
+     * floatValues must be a vector containing Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 3
+     * elements (that is, 73 elements);
+     *
+     * It is possible for each frame to contain a different subset of sensor values, both system
+     * provided sensors, and vendor-specific ones. In order to support that, the bytes element
+     * of the property value is used as a bitmask,.
+     *
+     * bytes must have a sufficient number of bytes to represent the total number of possible
+     * sensors (in this case, 14 bytes to represent 106 possible values); it is to be read as
+     * a contiguous bitmask such that each bit indicates the presence or absence of a sensor
+     * from the frame, starting with as many bits as the size of int32Values, immediately
+     * followed by as many bits as the size of floatValues.
+     *
+     * For example, should bytes[0] = 0x4C (0b01001100) it would mean that:
+     *   int32Values[0 and 1] are not valid sensor values
+     *   int32Values[2 and 3] are valid sensor values
+     *   int32Values[4 and 5] are not valid sensor values
+     *   int32Values[6] is a valid sensor value
+     *   int32Values[7] is not a valid sensor value
+     * Should bytes[5] = 0x61 (0b01100001) it would mean that:
+     *   int32Values[32] is a valid sensor value
+     *   floatValues[0 thru 3] are not valid sensor values
+     *   floatValues[4 and 5] are valid sensor values
+     *   floatValues[6] is not a valid sensor value
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    OBD2_LIVE_FRAME = 0x0D00 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * OBD2 Freeze Frame Sensor Data
+     *
+     * Reports a snapshot of the value of the OBD2 sensors available at the time that a fault
+     * occurred and was detected.
+     *
+     * A configArray must be provided with the same meaning as defined for OBD2_LIVE_FRAME.
+     *
+     * The values of this property are to be interpreted in a similar fashion as those for
+     * OBD2_LIVE_FRAME, with the exception that the stringValue field may contain a non-empty
+     * diagnostic troubleshooting code (DTC).
+     *
+     * A IVehicle#get request of this property must provide a value for int64Values[0].
+     * This will be interpreted as the timestamp of the freeze frame to retrieve. A list of
+     * timestamps can be obtained by a IVehicle#get of OBD2_FREEZE_FRAME_INFO.
+     *
+     * Should no freeze frame be available at the given timestamp, a response of NOT_AVAILABLE
+     * must be returned by the implementation. Because vehicles may have limited storage for
+     * freeze frames, it is possible for a frame request to respond with NOT_AVAILABLE even if
+     * the associated timestamp has been recently obtained via OBD2_FREEZE_FRAME_INFO.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    OBD2_FREEZE_FRAME = 0x0D01 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * OBD2 Freeze Frame Information
+     *
+     * This property describes the current freeze frames stored in vehicle
+     * memory and available for retrieval via OBD2_FREEZE_FRAME.
+     *
+     * The values are to be interpreted as follows:
+     * each element of int64Values must be the timestamp at which a a fault code
+     * has been detected and the corresponding freeze frame stored, and each
+     * such element can be used as the key to OBD2_FREEZE_FRAME to retrieve
+     * the corresponding freeze frame.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    OBD2_FREEZE_FRAME_INFO = 0x0D02 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * OBD2 Freeze Frame Clear
+     *
+     * This property allows deletion of any of the freeze frames stored in
+     * vehicle memory, as described by OBD2_FREEZE_FRAME_INFO.
+     *
+     * The configArray is set as follows:
+     *  configArray[0] = 1 if the implementation is able to clear individual freeze frames
+     *                   by timestamp, 0 otherwise
+     *
+     * IVehicle#set of this property is to be interpreted as follows:
+     *   if int64Values contains no elements, then all frames stored must be cleared;
+     *   if int64Values contains one or more elements, then frames at the timestamps
+     *   stored in int64Values must be cleared, and the others not cleared. Should the
+     *   vehicle not support selective clearing of freeze frames, this latter mode must
+     *   return NOT_AVAILABLE.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     */
+    OBD2_FREEZE_FRAME_CLEAR = 0x0D03 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Headlights State
+     *
+     * Return the current state of headlights.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    HEADLIGHTS_STATE = 0x0E00 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * High beam lights state
+     *
+     * Return the current state of high beam lights.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    HIGH_BEAM_LIGHTS_STATE = 0x0E01 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fog light state
+     *
+     * Return the current state of fog lights.
+     *
+     * If the car has both front and rear fog lights:
+     *   If front and rear fog lights can only be controlled together: FOG_LIGHTS_STATE must be
+     *   implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must not be implemented.
+     *
+     *   If the front and rear fog lights can only be controlled independently: FOG_LIGHTS_STATE
+     *   must not be implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must be
+     *   implemented.
+     *
+     * If the car has only front fog lights:
+     * Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented and not both.
+     * REAR_FOG_LIGHTS_STATE must not be implemented.
+     *
+     * If the car has only rear fog lights:
+     * Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented and not both.
+     * FRONT_FOG_LIGHTS_STATE must not be implemented.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    FOG_LIGHTS_STATE = 0x0E02 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Hazard light status
+     *
+     * Return the current status of hazard lights.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    HAZARD_LIGHTS_STATE = 0x0E03 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Headlight switch
+     *
+     * The setting that the user wants.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    HEADLIGHTS_SWITCH = 0x0E10 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * High beam light switch
+     *
+     * The setting that the user wants.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    HIGH_BEAM_LIGHTS_SWITCH = 0x0E11 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Fog light switch
+     *
+     * The setting that the user wants.
+     *
+     * If the car has both front and rear fog lights:
+     *   If front and rear fog lights can only be controlled together: FOG_LIGHTS_SWITCH must be
+     *   implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must not be implemented.
+     *
+     *   If the front and rear fog lights can only be controlled independently: FOG_LIGHTS_SWITCH
+     *   must not be implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must be
+     *   implemented.
+     *
+     * If the car has only front fog lights:
+     * Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented and not both.
+     * REAR_FOG_LIGHTS_SWITCH must not be implemented.
+     *
+     * If the car has only rear fog lights:
+     * Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented and not both.
+     * FRONT_FOG_LIGHTS_SWITCH must not be implemented.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    FOG_LIGHTS_SWITCH = 0x0E12 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Hazard light switch
+     *
+     * The setting that the user wants.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    HAZARD_LIGHTS_SWITCH = 0x0E13 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Cabin lights
+     *
+     * Return current status of cabin lights.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    CABIN_LIGHTS_STATE = 0x0F01 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Cabin lights switch
+     *
+     * The position of the physical switch which controls the cabin lights.
+     * This might be different than the CABIN_LIGHTS_STATE if the lights are on because a door
+     * is open or because of a voice command.
+     * For example, while the switch is in the "off" or "automatic" position.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    CABIN_LIGHTS_SWITCH = 0x0F02 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Reading lights
+     *
+     * Return current status of reading lights.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    READING_LIGHTS_STATE = 0x0F03 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Reading lights switch
+     *
+     * The position of the physical switch which controls the reading lights.
+     * This might be different than the READING_LIGHTS_STATE if the lights are on because a door
+     * is open or because of a voice command.
+     * For example, while the switch is in the "off" or "automatic" position.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    READING_LIGHTS_SWITCH = 0x0F04 + 0x10000000 + 0x05000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+    /**
+     * Steering wheel lights state
+     *
+     * Represents the current state of the steering wheel lights. This is different from
+     * STEERING_WHEEL_LIGHTS_SWITCH which represents the position of the switch controlling
+     * the lights. Therefore, STEERING_WHEEL_LIGHTS_STATE may not match the value of
+     * STEERING_WHEEL_LIGHTS_SWITCH (e.g. STEERING_WHEEL_LIGHTS_SWITCH=AUTOMATIC and
+     * STEERING_WHEEL_LIGHTS_STATE=ON).
+     *
+     * This property should only be implemented if STEERING_WHEEL_LIGHTS_STATE's value may be
+     * different from that of CABIN_LIGHTS_STATE.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of VehicleLightState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    STEERING_WHEEL_LIGHTS_STATE =
+            0x0F0C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * Steering wheel lights switch
+     *
+     * Represents the position of the switch controlling the steering wheel lights. This is
+     * different from STEERING_WHEEL_LIGHTS_STATE which represents the current state of the steering
+     * wheel lights. Therefore, STEERING_WHEEL_LIGHTS_SWITCH may not match the value of
+     * STEERING_WHEEL_LIGHTS_STATE (e.g. STEERING_WHEEL_LIGHTS_SWITCH=AUTOMATIC and
+     * STEERING_WHEEL_LIGHTS_STATE=ON).
+     *
+     * This property should only be implemented if STEERING_WHEEL_LIGHTS_SWITCH's value may be
+     * different from that of CABIN_LIGHTS_SWITCH.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of VehicleLightSwitch are supported.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    STEERING_WHEEL_LIGHTS_SWITCH =
+            0x0F0D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * Support customize permissions for vendor properties
+     *
+     * Implement this property if vehicle hal support customize vendor permissions feature.
+     * VehiclePropConfig.configArray is used to indicate vendor properties and permissions
+     * which selected for this vendor property. The permission must be one of enum in
+     * VehicleVendorPermission.
+     * The configArray is set as follows:
+     *      configArray[n] = propId : property ID for the vendor property
+     *      configArray[n+1] = one of enums in VehicleVendorPermission. It indicates the permission
+     *      for reading value of the property.
+     *      configArray[n+2] = one of enums in VehicleVendorPermission. It indicates the permission
+     *      for writing value of the property.
+     *
+     * For example:
+     * configArray = {
+     *      vendor_prop_1, PERMISSION_VENDOR_SEAT_READ, PERMISSION_VENDOR_SEAT_WRITE,
+     *      vendor_prop_2, PERMISSION_VENDOR_INFO, PERMISSION_NOT_ACCESSIBLE,
+     * }
+     * If vendor properties are not in this array, they will have the default vendor permission.
+     * If vendor chose PERMISSION_NOT_ACCESSIBLE, android will not have access to the property. In
+     * the example, Android can not write value for vendor_prop_2.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     */
+    SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 0x0F05 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+    /**
+     * Allow disabling optional featurs from vhal.
+     *
+     * This property reports optional features that should be disabled.
+     * All allowed optional features for the system is declared in Car service overlay,
+     * config_allowed_optional_car_features.
+     * This property allows disabling features defined in the overlay. Without this property,
+     * all the features declared in the overlay will be enabled.
+     *
+     * Value read should include all features disabled with ',' separation.
+     * ex) "com.android.car.user.CarUserNoticeService,storage_monitoring"
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     */
+    DISABLED_OPTIONAL_FEATURES = 0x0F06 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Defines the initial Android user to be used during initialization.
+     *
+     * This property is called by the Android system when it initializes and it lets the HAL
+     * define which Android user should be started.
+     *
+     * This request is made by setting a VehiclePropValue (defined by InitialUserInfoRequest),
+     * and the HAL must respond with a property change event (defined by InitialUserInfoResponse).
+     * If the HAL doesn't respond after some time (defined by the Android system), the Android
+     * system will proceed as if HAL returned a response of action
+     * InitialUserInfoResponseAction:DEFAULT.
+     *
+     * For example, on first boot, the request could be:
+     *
+     * int32[0]: 42  // request id (arbitrary number set by Android system)
+     * int32[1]: 1   // InitialUserInfoRequestType::FIRST_BOOT
+     * int32[2]: 0   // id of current user (usersInfo.currentUser.userId)
+     * int32[3]: 1   // flag of current user (usersInfo.currentUser.flags = SYSTEM)
+     * int32[4]: 1   // number of existing users (usersInfo.numberUsers);
+     * int32[5]: 0   // user #0  (usersInfo.existingUsers[0].userId)
+     * int32[6]: 1   // flags of user #0  (usersInfo.existingUsers[0].flags)
+     *
+     * And if the HAL want to respond with the creation of an admin user called "Owner", the
+     * response would be:
+     *
+     * int32[0]: 42      // must match the request id from the request
+     * int32[1]:  2      // action = InitialUserInfoResponseAction::CREATE
+     * int32[2]: -10000  // userToSwitchOrCreate.userId (not used as user will be created)
+     * int32[3]:  8      // userToSwitchOrCreate.flags = ADMIN
+     * string: "||Owner" // userLocales + separator + userNameToCreate
+     *
+     * Notice the string value represents multiple values, separated by ||. The first value is the
+     * (optional) system locales for the user to be created (in this case, it's empty, meaning it
+     * will use Android's default value), while the second value is the (also optional) name of the
+     * to user to be created (when the type of response is InitialUserInfoResponseAction:CREATE).
+     * For example, to create the same "Owner" user with "en-US" and "pt-BR" locales, the string
+     * value of the response would be "en-US,pt-BR||Owner". As such, neither the locale nor the
+     * name can have || on it, although a single | is fine.
+     *
+     * NOTE: if the HAL doesn't support user management, then it should not define this property,
+     * which in turn would disable the other user-related properties (for example, the Android
+     * system would never issue them and user-related requests from the HAL layer would be ignored
+     * by the Android System). But if it supports user management, then it must support all core
+     * user-related properties (INITIAL_USER_INFO, SWITCH_USER, CREATE_USER, and REMOVE_USER).
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    INITIAL_USER_INFO = 0x0F07 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Defines a request to switch the foreground Android user.
+     *
+     * This property is used primarily by the Android System to inform the HAL that the
+     * current foreground Android user is switching, but it could also be used by the HAL to request
+     * the Android system to switch users - the
+     *
+     * When the request is made by Android, it sets a VehiclePropValue and the HAL must responde
+     * with a property change event; when the HAL is making the request, it must also do it through
+     * a property change event (the main difference is that the request id will be positive in the
+     * former case, and negative in the latter; the SwitchUserMessageType will also be different).
+     *
+     * The format of both request is defined by SwitchUserRequest and the format of the response
+     * (when needed) is defined by SwitchUserResponse. How the HAL (or Android System) should
+     * proceed depends on the message type (which is defined by the SwitchUserMessageType
+     * parameter), as defined below.
+     *
+     * 1.LEGACY_ANDROID_SWITCH
+     * -----------------------
+     *
+     * Called by the Android System to indicate the Android user is about to change, when the change
+     * request was made in a way that is not integrated with the HAL (for example, through
+     * adb shell am switch-user).
+     *
+     * The HAL can switch its internal user once it receives this request, but it doesn't need to
+     * reply back to the Android System. If its internal user cannot be changed for some reason,
+     * then it must wait for the SWITCH_USER(type=ANDROID_POST_SWITCH) call to recover
+     * (for example, it could issue a SWITCH_USER(type=VEHICLE_REQUEST) to switch back to
+     * the previous user), but ideally it should never fail (as switching back could result in a
+     * confusing experience for the end user).
+     *
+     * For example, if the system have users (0, 10, 11) and it's switching from 0 to 11 (where none
+     * of them have any special flag), the request would be:
+     *
+     * int32[0]:  42  // request id
+     * int32[1]:  1   // SwitchUserMessageType::LEGACY_ANDROID_SWITCH
+     * int32[2]:  11  // target user id
+     * int32[3]:  0   // target user flags (none)
+     * int32[4]:  10  // current user
+     * int32[5]:  0   // current user flags (none)
+     * int32[6]:  3   // number of users
+     * int32[7]:  0   // user #0 (Android user id 0)
+     * int32[8]:  0   // flags of user #0 (none)
+     * int32[9]:  10  // user #1 (Android user id 10)
+     * int32[10]: 0   // flags of user #1 (none)
+     * int32[11]: 11  // user #2 (Android user id 11)
+     * int32[12]: 0   // flags of user #2 (none)
+     *
+     * 2.ANDROID_SWITCH
+     * ----------------
+     * Called by the Android System to indicate the Android user is about to change, but Android
+     * will wait for the HAL's response (up to some time) before proceeding.
+     *
+     * The HAL must switch its internal user once it receives this request, then respond back to
+     * Android with a SWITCH_USER(type=VEHICLE_RESPONSE) indicating whether its internal
+     * user was switched or not (through the SwitchUserStatus enum).
+     *
+     * For example, if Android has users (0, 10, 11) and it's switching from 10 to 11 (where
+     * none of them have any special flag), the request would be:
+     *
+     * int32[0]:  42  // request id
+     * int32[1]:  2   // SwitchUserMessageType::ANDROID_SWITCH
+     * int32[2]:  11  // target user id
+     * int32[3]:  0   // target user flags (none)
+     * int32[4]:  10  // current user
+     * int32[5]:  0   // current user flags (none)
+     * int32[6]:  3   // number of users
+     * int32[7]:  0   // 1st user (user 0)
+     * int32[8]:  1   // 1st user flags (SYSTEM)
+     * int32[9]:  10  // 2nd user (user 10)
+     * int32[10]: 0   // 2nd user flags (none)
+     * int32[11]: 11  // 3rd user (user 11)
+     * int32[12]: 0   // 3rd user flags (none)
+     *
+     * If the request succeeded, the HAL must update the property with:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 3   // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
+     * int32[2]: 1   // status = SwitchUserStatus::SUCCESS
+     *
+     * But if it failed, the response would be something like:
+     *
+     * int32[0]: 42   // request id
+     * int32[1]: 3    // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
+     * int32[2]: 2    // status = SwitchUserStatus::FAILURE
+     * string: "108-D'OH!" // OEM-specific error message
+     *
+     * 3.VEHICLE_RESPONSE
+     * ------------------
+     * Called by the HAL to indicate whether a request of type ANDROID_SWITCH should proceed or
+     * abort - see the ANDROID_SWITCH section above for more info.
+     *
+     * 4.VEHICLE_REQUEST
+     * ------------------
+     * Called by the HAL to request that the current foreground Android user is switched.
+     *
+     * This is useful in situations where Android started as one user, but the vehicle identified
+     * the driver as another user. For example, user A unlocked the car using the key fob of user B;
+     * the INITIAL_USER_INFO request returned user B, but then a face recognition subsubsystem
+     * identified the user as A.
+     *
+     * The HAL makes this request by a property change event (passing a negative request id), and
+     * the Android system will response by issue an ANDROID_POST_SWITCH call which the same
+     * request id.
+     *
+     * For example, if the current foreground Android user is 10 and the HAL asked it to switch to
+     * 11, the request would be:
+     *
+     * int32[0]: -108  // request id
+     * int32[1]: 4     // messageType = SwitchUserMessageType::VEHICLE_REQUEST
+     * int32[2]: 11    // Android user id
+     *
+     * If the request succeeded and Android has 3 users (0, 10, 11), the response would be:
+     *
+     * int32[0]: -108 // request id
+     * int32[1]:  5   // messageType = SwitchUserMessageType::ANDROID_POST_SWITCH
+     * int32[2]:  11  // target user id
+     * int32[3]:  0   // target user id flags (none)
+     * int32[4]:  11  // current user
+     * int32[5]:  0   // current user flags (none)
+     * int32[6]:  3   // number of users
+     * int32[7]:  0   // 1st user (user 0)
+     * int32[8]:  0   // 1st user flags (none)
+     * int32[9]:  10  // 2nd user (user 10)
+     * int32[10]: 4   // 2nd user flags (none)
+     * int32[11]: 11  // 3rd user (user 11)
+     * int32[12]: 3   // 3rd user flags (none)
+     *
+     * Notice that both the current and target user ids are the same - if the request failed, then
+     * they would be different (i.e, target user would be 11, but current user would still be 10).
+     *
+     * 5.ANDROID_POST_SWITCH
+     * ---------------------
+     * Called by the Android System after a request to switch a user was made.
+     *
+     * This property is called after switch requests of any type (i.e., LEGACY_ANDROID_SWITCH,
+     * ANDROID_SWITCH, or VEHICLE_REQUEST) and can be used to determine if the request succeeded or
+     * failed:
+     *
+     * 1. When it succeeded, it's called when the Android user is in the unlocked state and the
+     *    value of the current and target users ids in the response are the same. This would be
+     *    equivalent to receiving an Intent.ACTION_USER_UNLOCKED in an Android app.
+     * 2. When it failed it's called right away and the value of the current and target users ids
+     *    in the response are different (as the current user didn't change to the target).
+     * 3. If a new switch request is made before the HAL responded to the previous one or before
+     *    the user was unlocked, then the ANDROID_POST_SWITCH request is not made. For example,
+     *    the driver could accidentally switch to the wrong user which has lock credentials, then
+     *    switch to the right one before entering the credentials.
+     *
+     * The HAL can update its internal state once it receives this request, but it doesn't need to
+     * reply back to the Android System.
+     *
+     * Request: the first N values as defined by INITIAL_USER_INFO (where the request-specific
+     * value at index 1 is SwitchUserMessageType::ANDROID_POST_SWITCH), then 2 more values for the
+     * target user id (i.e., the Android user id that was requested to be switched to) and its flags
+     * (as defined by  UserFlags).
+     *
+     * Response: none.
+     *
+     * Example: see VEHICLE_REQUEST section above.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    SWITCH_USER = 0x0F08 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Called by the Android System after an Android user was created.
+     *
+     * The HAL can use this property to create its equivalent user.
+     *
+     * This is an async request: Android makes the request by setting a VehiclePropValue, and HAL
+     * must respond with a property change indicating whether the request succeeded or failed. If
+     * it failed, the Android system will remove the user.
+     *
+     * The format of the request is defined by CreateUserRequest and the format of the response by
+     * CreateUserResponse.
+     *
+     * For example, if system had 2 users (0 and 10) and a 3rd one (which is an ephemeral guest) was
+     * created, the request would be:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 11  // Android id of the created user
+     * int32[2]: 6   // Android flags (ephemeral guest) of the created user
+     * int32[3]: 10  // current user
+     * int32[4]: 0   // current user flags (none)
+     * int32[5]: 3   // number of users
+     * int32[6]: 0   // 1st user (user 0)
+     * int32[7]: 0   // 1st user flags (none)
+     * int32[8]: 10  // 2nd user (user 10)
+     * int32[9]: 0   // 2nd user flags (none)
+     * int32[19]: 11 // 3rd user (user 11)
+     * int32[11]: 6  // 3rd user flags (ephemeral guest)
+     * string: "ElGuesto" // name of the new user
+     *
+     * Then if the request succeeded, the HAL would return:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 1   // CreateUserStatus::SUCCESS
+     *
+     * But if it failed:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 2   // CreateUserStatus::FAILURE
+     * string: "D'OH!" // The meaning is a blackbox - it's passed to the caller (like Settings UI),
+     *                 // which in turn can take the proper action.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    CREATE_USER = 0x0F09 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Called by the Android System after an Android user was removed.
+     *
+     * The HAL can use this property to remove its equivalent user.
+     *
+     * This is write-only call - the Android System is not expecting a reply from the HAL. Hence,
+     * this request should not fail - if the equivalent HAL user cannot be removed, then HAL should
+     * mark it as inactive or recover in some other way.
+     *
+     * The request is made by setting the VehiclePropValue with the contents defined by
+     * RemoveUserRequest.
+     *
+     * For example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request
+     * would be:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 11  // (Android user id of the removed user)
+     * int32[2]: 0   // (Android user flags of the removed user)
+     * int32[3]: 10  // current user
+     * int32[4]: 0   // current user flags (none)
+     * int32[5]: 2   // number of users
+     * int32[6]: 0   // 1st user (user 0)
+     * int32[7]: 0   // 1st user flags (none)
+     * int32[8]: 10  // 2nd user (user 10)
+     * int32[9]: 0   // 2nd user flags (none)
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.WRITE
+     */
+    REMOVE_USER = 0x0F0A + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Property used to associate (or query the association) the current user with vehicle-specific
+     * identification mechanisms (such as key FOB).
+     *
+     * This is an optional user management property - the OEM could still support user management
+     * without defining it. In fact, this property could be used without supporting the core
+     * user-related functions described on INITIAL_USER_INFO.
+     *
+     * To query the association, the Android system gets the property, passing a VehiclePropValue
+     * containing the types of associations are being queried, as defined by
+     * UserIdentificationGetRequest. The HAL must return right away, returning a VehiclePropValue
+     * with a UserIdentificationResponse. Notice that user identification should have already
+     * happened while system is booting up and the VHAL implementation should only return the
+     * already identified association (like the key FOB used to unlock the car), instead of starting
+     * a new association from the get call.
+     *
+     * To associate types, the Android system sets the property, passing a VehiclePropValue
+     * containing the types and values of associations being set, as defined by the
+     * UserIdentificationSetRequest. The HAL will then use a property change event (whose
+     * VehiclePropValue is defined by UserIdentificationResponse) indicating the current status of
+     * the types after the request.
+     *
+     * For example, to query if the current user (10) is associated with the FOB that unlocked the
+     * car and a custom mechanism provided by the OEM, the request would be:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 10  (Android user id)
+     * int32[2]: 0   (Android user flags)
+     * int32[3]: 2   (number of types queried)
+     * int32[4]: 1   (1st type queried, UserIdentificationAssociationType::KEY_FOB)
+     * int32[5]: 101 (2nd type queried, UserIdentificationAssociationType::CUSTOM_1)
+     *
+     * If the user is associated with the FOB but not with the custom mechanism, the response would
+     * be:
+     *
+     * int32[0]: 42  // request id
+     * int32[1]: 2   (number of associations in the response)
+     * int32[2]: 1   (1st type: UserIdentificationAssociationType::KEY_FOB)
+     * int32[3]: 2   (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
+     * int32[4]: 101 (2st type: UserIdentificationAssociationType::CUSTOM_1)
+     * int32[5]: 4   (2nd value: UserIdentificationAssociationValue::NOT_ASSOCIATED_ANY_USER)
+     *
+     * Then to associate the user with the custom mechanism, a set request would be made:
+     *
+     * int32[0]: 43  // request id
+     * int32[1]: 10  (Android user id)
+     * int32[2]: 0   (Android user flags)
+     * int32[3]: 1   (number of associations being set)
+     * int32[4]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
+     * int32[5]: 1   (1st value: UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER)
+     *
+     * If the request succeeded, the response would be simply:
+     *
+     * int32[0]: 43  // request id
+     * int32[1]: 1   (number of associations in the response)
+     * int32[2]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
+     * int32[3]: 1   (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
+     *
+     * Notice that the set request adds associations, but doesn't remove the existing ones. In the
+     * example above, the end state would be 2 associations (FOB and CUSTOM_1). If we wanted to
+     * associate the user with just CUSTOM_1 but not FOB, then the request should have been:
+     *
+     * int32[0]: 43  // request id
+     * int32[1]: 10  (Android user id)
+     * int32[2]: 2   (number of types set)
+     * int32[3]: 1   (1st type: UserIdentificationAssociationType::KEY_FOB)
+     * int32[4]: 2   (1st value: UserIdentificationAssociationValue::DISASSOCIATE_CURRENT_USER)
+     * int32[5]: 101 (2nd type: UserIdentificationAssociationType::CUSTOM_1)
+     * int32[6]: 1   (2nd value: UserIdentificationAssociationValue::ASSOCIATE_CURRENT_USER)
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    USER_IDENTIFICATION_ASSOCIATION = 0x0F0B + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Enable/request an EVS service.
+     *
+     * The property provides a generalized way to trigger EVS services.  VHAL
+     * should use this property to request Android to start or stop EVS service.
+     *
+     *  int32Values[0] = a type of the EVS service. The value must be one of enums in
+     *                   EvsServiceType.
+     *  int32Values[1] = the state of the EVS service. The value must be one of enums in
+     *                   EvsServiceState.
+     *
+     * For example, to enable rear view EVS service, android side can set the property value as
+     * [EvsServiceType::REAR_VIEW, EvsServiceState::ON].
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    EVS_SERVICE_REQUEST = 0x0F10 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Defines a request to apply power policy.
+     *
+     * VHAL sets this property to change car power policy. Car power policy service subscribes to
+     * this property and actually changes the power policy.
+     * The request is made by setting the VehiclePropValue with the ID of a power policy which is
+     * defined at /vendor/etc/automotive/power_policy.xml.
+     * If the given ID is not defined, car power policy service ignores the request
+     * and the current power policy is maintained.
+     *
+     *   string: "sample_policy_id" // power policy ID
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    POWER_POLICY_REQ = 0x0F21 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Defines a request to set the power polic group used to decide a default power policy per
+     * power status transition.
+     *
+     * VHAL sets this property with the ID of a power policy group in order to set the default power
+     * policy applied at power status transition. Power policy groups are defined at
+     * /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy service
+     * ignores the request.
+     * Car power policy service subscribes to this property and sets the power policy group.
+     * The actual application of power policy takes place when the system power status changes and
+     * there is a valid mapped power policy for the new power status.
+     *
+     *   string: "sample_policy_group_id" // power policy group ID
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    POWER_POLICY_GROUP_REQ = 0x0F22 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Notifies the current power policy to VHAL layer.
+     *
+     * Car power policy service sets this property when the current power policy is changed.
+     *
+     *   string: "sample_policy_id" // power policy ID
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    CURRENT_POWER_POLICY = 0x0F23 + 0x10000000 + 0x01000000
+            + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+    /**
+     * Defines an event that car watchdog updates to tell it's alive.
+     *
+     * Car watchdog sets this property to system uptime in milliseconds at every 3 second.
+     * During the boot, the update may take longer time.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     */
+    WATCHDOG_ALIVE = 0xF31 + 0x10000000 + 0x01000000
+            + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
+    /**
+     * Defines a process terminated by car watchdog and the reason of termination.
+     *
+     *   int32Values[0]: 1         // ProcessTerminationReason showing why a process is terminated.
+     *   string: "/system/bin/log" // Process execution command.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     */
+    WATCHDOG_TERMINATED_PROCESS = 0x0F32 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Defines an event that VHAL signals to car watchdog as a heartbeat.
+     *
+     * If VHAL supports this property, VHAL should write system uptime to this property at every 3
+     * second. Car watchdog subscribes to this property and checks if the property is updated at
+     * every 3 second. With the buffer time of 3 second, car watchdog waits for a heart beat to be
+     * signaled up to 6 seconds from the last heart beat. If it isn’t, car watchdog considers
+     * VHAL unhealthy and terminates it.
+     * If this property is not supported by VHAL, car watchdog doesn't check VHAL health status.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    VHAL_HEARTBEAT = 0x0F33 + 0x10000000 + 0x01000000
+            + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
+    /**
+     * Starts the ClusterUI in cluster display.
+     *
+     * int32: the type of ClusterUI to show
+     *    0 indicates ClusterHome, that is a home screen of cluster display, and provides
+     *        the default UI and a kind of launcher functionality for cluster display.
+     *    the other values are followed by OEM's definition.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    CLUSTER_SWITCH_UI = 0x0F34 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Changes the state of the cluster display.
+     *
+     * Bounds: the area to render the cluster Activity.
+     * Inset: the area which Activity should avoid from placing any important
+     *     information.
+     *
+     * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care
+     * int32[1]: Bounds - left: positive number - left position in pixels
+                                -1 - don't care (should set all Bounds fields)
+     * int32[2]: Bounds - top:    same format with 'left'
+     * int32[3]: Bounds - right:  same format with 'left'
+     * int32[4]: Bounds - bottom: same format with 'left'
+     * int32[5]: Inset - left: positive number - actual left inset value in pixels
+                               -1 - don't care (should set "don't care" all Inset fields)
+     * int32[6]: Inset - top:    same format with 'left'
+     * int32[7]: Inset - right:  same format with 'left'
+     * int32[8]: Inset - bottom: same format with 'left'
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     */
+    CLUSTER_DISPLAY_STATE = 0x0F35 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    /**
+     * Reports the current display state and ClusterUI state.
+     *
+     * ClusterHome will send this message when it handles CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE.
+     *
+     * In addition, ClusterHome should send this message when it starts for the first time.
+     * When ClusterOS receives this message and if the internal expectation is different with the
+     * received message, then it should send CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE again to
+     * match the state.
+     *
+     * int32[0]: on/off: 0 - off, 1 - on
+     * int32[1]: Bounds - left
+     * int32[2]: Bounds - top
+     * int32[3]: Bounds - right
+     * int32[4]: Bounds - bottom
+     * int32[5]: Inset - left
+     * int32[6]: Inset - top
+     * int32[7]: Inset - right
+     * int32[8]: Inset - bottom
+     * int32[9]: the type of ClusterUI in the fullscreen or main screen.
+     *    0 indicates ClusterHome.
+     *    the other values are followed by OEM's definition.
+     * int32[10]: the type of ClusterUI in sub screen if the currently two UIs are shown.
+     *    -1 indicates the area isn't used any more.
+     * bytes: the array to represent the availability of ClusterUI.
+     *     0 indicates non-available and 1 indicates available.
+     *     For example, let's assume a car supports 3 OEM defined ClusterUI like HOME, MAPS, CALL,
+     *     and it only supports CALL UI only when the cellular network is available. Then, if the
+     *     nework is avaibale, it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     */
+    CLUSTER_REPORT_STATE = 0x0F36 + 0x10000000 + 0x01000000
+            + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+    /**
+     * Requests to change the cluster display state to show some ClusterUI.
+     *
+     * When the current display state is off and ClusterHome sends this message to ClusterOS to
+     * request to turn the display on to show some specific ClusterUI.
+     * ClusterOS should response this with CLUSTER_DISPLAY_STATE.
+     *
+     * int32: the type of ClusterUI to show
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     */
+    CLUSTER_REQUEST_DISPLAY = 0x0F37 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Informs the current navigation state.
+     *
+     * bytes: the serialized message of NavigationStateProto.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     */
+    CLUSTER_NAVIGATION_STATE = 0x0F38 + 0x10000000 + 0x01000000
+            + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
+    /**
+     * Electronic Toll Collection card type.
+     *
+     * This property indicates the type of ETC card in this vehicle.
+     * If the head unit is aware of an ETC card attached to the vehicle, this property should
+     * return the type of card attached; otherwise, this property should be UNAVAILABLE.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum ElectronicTollCollectionCardType
+     */
+    ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = 0x0F39 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Electronic Toll Collection card status.
+     *
+     * This property indicates the status of ETC card in this vehicle.
+     * If the head unit is aware of an ETC card attached to the vehicle,
+     * ELECTRONIC_TOLL_COLLECTION_CARD_TYPE gives that status of the card; otherwise,
+     * this property should be UNAVAILABLE.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum ElectronicTollCollectionCardStatus
+     */
+    ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = 0x0F3A + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+    /**
+     * Front fog lights state
+     *
+     * Return the current state of the front fog lights.
+     * Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented. Please refer to
+     * the documentation on FOG_LIGHTS_STATE for more information.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    FRONT_FOG_LIGHTS_STATE = 0x0F3B + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Front fog lights switch
+     *
+     * The setting that the user wants.
+     * Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented. Please refer to
+     * the documentation on FOG_LIGHTS_SWITCH for more information.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    FRONT_FOG_LIGHTS_SWITCH = 0x0F3C + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Rear fog lights state
+     *
+     * Return the current state of the rear fog lights.
+     * Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented. Please refer to
+     * the documentation on FOG_LIGHTS_STATE for more information.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleLightState
+     */
+    REAR_FOG_LIGHTS_STATE = 0x0F3D + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Rear fog lights switch
+     *
+     * The setting that the user wants.
+     * Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented. Please refer to
+     * the documentation on FOG_LIGHTS_SWITCH for more information.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum VehicleLightSwitch
+     */
+    REAR_FOG_LIGHTS_SWITCH = 0x0F3E + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Indicates the maximum current draw threshold for charging set by the user
+     *
+     * configArray[0] is used to specify the max current draw allowed by
+     * the vehicle in Amperes.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @unit VehicleUnit:AMPERE
+     */
+    EV_CHARGE_CURRENT_DRAW_LIMIT = 0x0F3F + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+
+    /**
+     * Indicates the maximum charge percent threshold set by the user
+     *
+     * Returns a float value from 0 to 100.
+     *
+     * configArray is used to specify the valid values.
+     *   For example, if the vehicle supports the following charge percent limit values:
+     *     [20, 40, 60, 80, 100]
+     *   then the configArray should be {20, 40, 60, 80, 100}
+     * If the configArray is empty then all values from 0 to 100 must be valid.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    EV_CHARGE_PERCENT_LIMIT = 0x0F40 + 0x10000000 + 0x01000000
+            + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+
+    /**
+     * Charging state of the car
+     *
+     * Returns the current charging state of the car.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum EvChargeState
+     */
+    EV_CHARGE_STATE = 0x0F41 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Start or stop charging the EV battery
+     *
+     * The setting that the user wants. Setting this property to true starts the battery charging
+     * and setting to false stops charging.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    EV_CHARGE_SWITCH = 0x0F42 + 0x10000000 + 0x01000000
+            + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+
+    /**
+     * Estimated charge time remaining in seconds
+     *
+     * Returns 0 if the vehicle is not charging.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:SECS
+     */
+    EV_CHARGE_TIME_REMAINING = 0x0F43 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Regenerative braking or one-pedal drive state of the car
+     *
+     * Returns the current state associated with the regenerative braking
+     * setting in the car
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum EvRegenerativeBrakingState
+     */
+    EV_REGENERATIVE_BRAKING_STATE = 0x0F44 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Indicates if there is a trailer present or not.
+     *
+     * Returns the trailer state of the car.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum TrailerState
+     */
+    TRAILER_PRESENT = 0x0F45 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * Vehicle’s curb weight
+     *
+     * Returns the vehicle's curb weight in kilograms. Curb weight is
+     * the total weight of the vehicle with standard equipment and all
+     * necessary operating consumables such as motor oil,transmission oil,
+     * brake fluid, coolant, air conditioning refrigerant, and weight of
+     * fuel at nominal tank capacity, while not loaded with either passengers
+     * or cargo.
+     *
+     * configArray[0] is used to specify the vehicle’s gross weight in kilograms.
+     * The vehicle’s gross weight is the maximum operating weight of the vehicle
+     * as specified by the manufacturer including the vehicle's chassis, body, engine,
+     * engine fluids, fuel, accessories, driver, passengers and cargo but excluding
+     * that of any trailers.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:KILOGRAM
+     */
+
+    VEHICLE_CURB_WEIGHT = 0x0F46 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * EU's General security regulation compliance requirement.
+     *
+     * Returns whether general security regulation compliance is required, if
+     * so, what type of requirement.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @data_enum GsrComplianceRequirementType
+     */
+    GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = 0x0F47 + 0x10000000 + 0x01000000
+            + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+    /**
+     * (Deprecated) List of all supported property IDs.
+     *
+     * A list of all supported property IDs (including this property). This property is required for
+     * HIDL VHAL to work with large amount of vehicle prop configs where the getAllPropConfigs
+     * payload exceeds the binder limitation. This issue is fixed in AIDL version using
+     * LargeParcelable in getAllPropConfigs, so this property is deprecated.
+     *
+     * In HIDL VHAL implementation, if the amount of data returned in getAllPropConfigs exceeds the
+     * binder limitation, vendor must support this property and return all the supported property
+     * IDs. Car service will divide this list into smaller sub lists and use getPropConfigs([ids])
+     * to query the sub lists. The results will be merged together in Car Service.
+     *
+     * The config array for this property must contain one int element which is the number of
+     * configs per getPropConfigs request by Car Service. This number must be small enough so that
+     * each getPropConfigs payload will not exceed binder limitation, however, a smaller number will
+     * cause more requests, which increase overhead to fetch all the configs.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     */
+    SUPPORTED_PROPERTY_IDS = 0x0F48 + 0x10000000 + 0x01000000
+            + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+
+    /**
+     * Request the head unit to be shutdown.
+     *
+     * <p>This usually involves telling a separate system outside the head unit (e.g. a power
+     * controller) to prepare shutting down the head unit.
+     *
+     * <p>This does not mean the head unit will shutdown immediately.
+     *
+     * <p>This means that another system will start sending a shutdown signal to the head unit,
+     * which will cause VHAL to send SHUTDOWN_PREPARE message to Android. Android will then start
+     * the shut down process by handling the message.
+     *
+     * <p>This property is only for issuing a request and only supports writing. Every time this
+     * property value is set, the request to shutdown will be issued no matter what the current
+     * property value is. The current property value is meaningless.
+     *
+     * <p>Since this property is write-only, subscribing is not allowed and no property change
+     * event will be generated.
+     *
+     * <p>The value to set indicates the shutdown option, it must be one of
+     * {@code VehicleApPowerStateShutdownParam}, e.g.,
+     * VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY. This shutdown option might not be honored
+     * if the system doesn't support such option. In such case, an error will not be returned.
+     *
+     * <p>For configuration information, VehiclePropConfig.configArray must have bit flag combining
+     * values in {@code VehicleApPowerStateConfigFlag} to indicate which shutdown options are
+     * supported.
+     *
+     * <p>Returns error if failed to send the shutdown request to the other system.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     * @data_enum VehicleApPowerStateShutdownParam
+     */
+    SHUTDOWN_REQUEST =
+            0x0F49 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Whether the vehicle is currently in use.
+     *
+     * <p>In-use means a human user is present and is intended to use the vehicle. This doesn't
+     * necessarily means the human user is in the vehicle. For example, if the human user unlocks
+     * the vehicle remotely, the vehicle is considered in use.
+     *
+     * <p>If this property is supported:
+     *
+     * <p>Each time user powers on the vehicle or the system detects the user is present,
+     * VEHICLE_IN_USE must be set to true. Each time user powers off the vehicle or the system
+     * detects the user is not present, VEHICLE_IN_USE must be set to false.
+     *
+     * <p>This property is different than AP_POWER_BOOTUP_REASON in the sense that
+     * AP_POWER_BOOTUP_REASON is only set once during the system bootup. However, this property
+     * might change multiple times during a system bootup cycle.
+     *
+     * <p>For example, a device is currently not in use. The system bootup to execute a remote task.
+     * VEHICLE_IN_USE is false. While the remote task is executing, the user enters the vehicle and
+     * powers on the vehicle. VEHICLE_IN_USE is set to true. After a driving session, user powers
+     * off the vehicle, VEHICLE_IN_USE is set to false.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    VEHICLE_IN_USE =
+            0x0F4A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /***********************************************************************************************
+     * Start of ADAS Properties
+     *
+     * Allocate IDs in range of 0x1000 (inclusive) to 0x1100 (exclusive) for ADAS properties
+     **********************************************************************************************/
+
+    /**
+     * Enable or disable Automatic Emergency Braking (AEB).
+     *
+     * Set true to enable AEB and false to disable AEB. When AEB is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring to avoid potential collisions.
+     *
+     * In general, AUTOMATIC_EMERGENCY_BRAKING_ENABLED should always return true or false. If the
+     * feature is not available due to some temporary state, such as the vehicle speed being too
+     * low, that information must be conveyed through the ErrorState values in the
+     * AUTOMATIC_EMERGENCY_BRAKING_STATE property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    AUTOMATIC_EMERGENCY_BRAKING_ENABLED =
+            0x1000 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Automatic Emergency Braking (AEB) state.
+     *
+     * Returns the current state of AEB. This property must always return a valid state defined in
+     * AutomaticEmergencyBrakingState or ErrorState. It must not surface errors through StatusCode
+     * and must use the supported error states instead.
+     *
+     * If AEB includes forward collision warnings before activating the brakes, those warnings must
+     * be surfaced through the Forward Collision Warning (FCW) properties.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of both AutomaticEmergencyBrakingState (including OTHER, which is not
+     * recommended) and ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum AutomaticEmergencyBrakingState
+     * @data_enum ErrorState
+     */
+    AUTOMATIC_EMERGENCY_BRAKING_STATE =
+            0x1001 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Enable or disable Forward Collision Warning (FCW).
+     *
+     * Set true to enable FCW and false to disable FCW. When FCW is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring for potential collisions.
+     *
+     * In general, FORWARD_COLLISION_WARNING_ENABLED should always return true or false. If the
+     * feature is not available due to some temporary state, such as the vehicle speed being too
+     * low, that information must be conveyed through the ErrorState values in the
+     * FORWARD_COLLISION_WARNING_STATE property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    FORWARD_COLLISION_WARNING_ENABLED =
+            0x1002 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Forward Collision Warning (FCW) state.
+     *
+     * Returns the current state of FCW. This property must always return a valid state defined in
+     * ForwardCollisionWarningState or ErrorState. It must not surface errors through StatusCode
+     * and must use the supported error states instead.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of both ForwardCollisionWarningState (including OTHER, which is not
+     * recommended) and ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum ForwardCollisionWarningState
+     * @data_enum ErrorState
+     */
+    FORWARD_COLLISION_WARNING_STATE =
+            0x1003 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Enable and disable Blind Spot Warning (BSW).
+     *
+     * Set true to enable BSW and false to disable BSW. When BSW is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring for objects in the vehicle’s blind spots.
+     *
+     * In general, BLIND_SPOT_WARNING_ENABLED should always return true or false. If the feature is
+     * not available due to some temporary state, such as the vehicle speed being too low, that
+     * information must be conveyed through the ErrorState values in the BLIND_SPOT_WARNING_STATE
+     * property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    BLIND_SPOT_WARNING_ENABLED =
+            0x1004 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Blind Spot Warning (BSW) state.
+     *
+     * Returns the current state of BSW. This property must always return a valid state defined in
+     * BlindSpotWarningState or ErrorState. It must not surface errors through StatusCode
+     * and must use the supported error states instead.
+     *
+     * For each supported area ID, the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of both BlindSpotWarningState (including OTHER, which is not
+     * recommended) and ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum BlindSpotWarningState
+     * @data_enum ErrorState
+     */
+    BLIND_SPOT_WARNING_STATE =
+            0x1005 + VehiclePropertyGroup.SYSTEM + VehicleArea.MIRROR + VehiclePropertyType.INT32,
+
+    /**
+     * Enable or disable Lane Departure Warning (LDW).
+     *
+     * Set true to enable LDW and false to disable LDW. When LDW is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring if the vehicle is approaching or crossing lane
+     * lines, in which case a warning will be given.
+     *
+     * In general, LANE_DEPARTURE_WARNING_ENABLED should always return true or false. If the feature
+     * is not available due to some temporary state, such as the vehicle speed being too low or too
+     * high, that information must be conveyed through the ErrorState values in the
+     * LANE_DEPARTURE_WARNING_STATE property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    LANE_DEPARTURE_WARNING_ENABLED =
+            0x1006 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Lane Departure Warning (LDW) state.
+     *
+     * Returns the current state of LDW. This property must always return a valid state defined in
+     * LaneDepartureWarningState or ErrorState. It must not surface errors through StatusCode
+     * and must use the supported error states instead.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of both LaneDepartureWarningState (including OTHER, which is not
+     * recommended) and ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum LaneDepartureWarningState
+     * @data_enum ErrorState
+     */
+    LANE_DEPARTURE_WARNING_STATE =
+            0x1007 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Enable or disable Lane Keep Assist (LKA).
+     *
+     * Set true to enable LKA and false to disable LKA. When LKA is enabled, the ADAS system in the
+     * vehicle should be turned on and monitoring if the driver unintentionally drifts toward or
+     * over the lane marking. If an unintentional lane departure is detected, the system applies
+     * steering control to return the vehicle into the current lane.
+     *
+     * This is different from Lane Centering Assist (LCA) which, when activated, applies continuous
+     * steering control to keep the vehicle centered in the current lane.
+     *
+     * In general, LANE_KEEP_ASSIST_ENABLED should always return true or false. If the feature is
+     * not available due to some temporary state, such as the vehicle speed being too low or too
+     * high, that information must be conveyed through the ErrorState values in the
+     * LANE_KEEP_ASSIST_STATE property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    LANE_KEEP_ASSIST_ENABLED =
+            0x1008 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Lane Keep Assist (LKA) state.
+     *
+     * Returns the current state of LKA. This property must always return a valid state defined in
+     * LaneKeepAssistState or ErrorState. It must not surface errors through StatusCode
+     * and must use the supported error states instead.
+     *
+     * If LKA includes lane departure warnings before applying steering corrections, those warnings
+     * must be surfaced through the Lane Departure Warning (LDW) properties.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of both LaneKeepAssistState (including OTHER, which is not
+     * recommended) and ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum LaneKeepAssistState
+     * @data_enum ErrorState
+     */
+    LANE_KEEP_ASSIST_STATE =
+            0x1009 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Enable or disable Lane Centering Assist (LCA).
+     *
+     * Set true to enable LCA and false to disable LCA. When LCA is enabled, the ADAS system in the
+     * vehicle should be turned on and waiting for an activation signal from the driver. Once the
+     * feature is activated, the ADAS system should be steering the vehicle to keep it centered in
+     * its current lane.
+     *
+     * This is different from Lane Keep Assist (LKA) which monitors if the driver unintentionally
+     * drifts toward or over the lane marking. If an unintentional lane departure is detected, the
+     * system applies steering control to return the vehicle into the current lane.
+     *
+     * In general, LANE_CENTERING_ASSIST_ENABLED should always return true or false. If the feature
+     * is not available due to some temporary state, such as the vehicle speed being too low or too
+     * high, that information must be conveyed through the ErrorState values in the
+     * LANE_CENTERING_ASSIST_STATE property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    LANE_CENTERING_ASSIST_ENABLED =
+            0x100A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Lane Centering Assist (LCA) commands.
+     *
+     * Commands to activate and suspend LCA.
+     *
+     * When the command ACTIVATE from LaneCenteringAssistCommmand is sent,
+     * LANE_CENTERING_ASSIST_STATE must be set to LaneCenteringAssistState#ACTIVATION_REQUESTED.
+     * When the ACTIVATE command succeeds, LANE_CENTERING_ASSIST_STATE must be set to
+     * LaneCenteringAssistState#ACTIVATED. When the command DEACTIVATE from
+     * LaneCenteringAssistCommmand succeeds, LANE_CENTERING_ASSIST_STATE must be set to
+     * LaneCenteringAssistState#ENABLED.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+     * all enum values of LaneCenteringAssistCommand are supported.
+     *
+     * When this property is not available because LCA is disabled (i.e.
+     * LANE_CENTERING_ASSIST_ENABLED is false), this property must return
+     * StatusCode#NOT_AVAILABLE_DISABLED. If LANE_CENTERING_ASSIST_STATE is implemented and the
+     * state is set to an ErrorState value, then this property must return a StatusCode that aligns
+     * with the ErrorState value. For example, if LANE_CENTERING_ASSIST_STATE is set to
+     * ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     * @data_enum LaneCenteringAssistCommmand
+     */
+    LANE_CENTERING_ASSIST_COMMAND =
+            0x100B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Lane Centering Assist (LCA) state.
+     *
+     * Returns the current state of LCA. This property must always return a valid state defined in
+     * LaneCenteringAssistState or ErrorState. It must not surface errors through StatusCode
+     * and must use the supported error states instead.
+     *
+     * If LCA includes lane departure warnings, those warnings must be surfaced through the Lane
+     * Departure Warning (LDW) properties.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of both LaneCenteringAssistState (including OTHER, which is not
+     * recommended) and ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum LaneCenteringAssistState
+     * @data_enum ErrorState
+     */
+    LANE_CENTERING_ASSIST_STATE =
+            0x100C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /*
+     * Enable or disable Emergency Lane Keep Assist (ELKA).
+     *
+     * Set true to enable ELKA and false to disable ELKA. When ELKA is enabled, the ADAS system in
+     * the vehicle should be on and monitoring for unsafe lane changes by the driver. When an unsafe
+     * maneuver is detected, ELKA alerts the driver and applies steering corrections to keep the
+     * vehicle in its original lane.
+     *
+     * In general, EMERGENCY_LANE_KEEP_ASSIST_ENABLED should always return true or false. If the
+     * feature is not available due to some temporary state, such as the vehicle speed being too
+     * low, that information must be conveyed through the ErrorState values in the
+     * EMERGENCY_LANE_KEEP_ASSIST_STATE property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    EMERGENCY_LANE_KEEP_ASSIST_ENABLED =
+            0x100D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Emergency Lane Keep Assist (ELKA) state.
+     *
+     * Returns the current state of ELKA. Generally, this property should return a valid state
+     * defined in the EmergencyLaneKeepAssistState or ErrorState. For example, if the feature is not
+     * available due to some temporary state, that information should be conveyed through
+     * ErrorState.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of EmergencyLaneKeepAssistState (including OTHER, which is not recommended)
+     * and ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum EmergencyLaneKeepAssistState
+     * @data_enum ErrorState
+     */
+    EMERGENCY_LANE_KEEP_ASSIST_STATE =
+            0x100E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Enable or disable cruise control (CC).
+     *
+     * Set true to enable CC and false to disable CC. This property is shared by all forms of
+     * CruiseControlType(s).
+     *
+     * When CC is enabled, the ADAS system in the vehicle should be turned on and responding to
+     * commands.
+     *
+     * In general, CRUISE_CONTROL_ENABLED should always return true or false. If the feature is not
+     * available due to some temporary state, such as the vehicle speed being too low, that
+     * information must be conveyed through the ErrorState values in the CRUISE_CONTROL_STATE
+     * property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    CRUISE_CONTROL_ENABLED =
+            0x100F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Current type of Cruise Control (CC).
+     *
+     * When CRUISE_CONTROL_ENABLED is true, this property returns the type of CC that is currently
+     * enabled (for example, standard CC, adaptive CC, predictive CC, etc.). Generally, this
+     * property should return a valid state defined in the CruiseControlType or ErrorState. For
+     * example, if the feature is not available due to some temporary state, that information should
+     * be conveyed through ErrorState.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of CruiseControlType (including OTHER, which is not recommended) and
+     * ErrorState are supported.
+     *
+     * Trying to write CruiseControlType#OTHER or an ErrorState to this property will throw an
+     * IllegalArgumentException.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @data_enum CruiseControlType
+     * @data_enum ErrorState
+     */
+    CRUISE_CONTROL_TYPE =
+            0x1010 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Current state of Cruise Control (CC).
+     *
+     * This property returns the current state of CC. Generally, this property should return a valid
+     * state defined in the CruiseControlState or ErrorState. For example, if the feature is not
+     * available due to some temporary state, that information should be conveyed through
+     * ErrorState.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of CruiseControlState (including OTHER, which is not recommended) and
+     * ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum CruiseControlState
+     * @data_enum ErrorState
+     */
+    CRUISE_CONTROL_STATE =
+            0x1011 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Write Cruise Control (CC) commands.
+     *
+     * See CruiseControlCommand for the details about each supported command.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of CruiseControlState are supported. Any unsupported commands sent through
+     * this property must return StatusCode#INVALID_ARG.
+     *
+     * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
+     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE
+     * is implemented and the state is set to an ErrorState value, then this property must return a
+     * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set
+     * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.WRITE
+     * @data_enum CruiseControlCommand
+     */
+    CRUISE_CONTROL_COMMAND =
+            0x1012 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Current target speed for Cruise Control (CC).
+     *
+     * OEMs should set the minFloatValue and maxFloatValue values for this property to define the
+     * min and max target speed values. These values must be non-negative.
+     *
+     * The maxFloatValue represents the upper bound of the target speed.
+     * The minFloatValue represents the lower bound of the target speed.
+     *
+     * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
+     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE
+     * is implemented and the state is set to an ErrorState value, then this property must return a
+     * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set
+     * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:METER_PER_SEC
+     */
+    CRUISE_CONTROL_TARGET_SPEED =
+            0x1013 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+
+    /**
+     * Current target time gap for Adaptive Cruise Control (ACC) or Predictive Cruise Control in
+     * milliseconds.
+     *
+     * This property should specify the target time gap to a leading vehicle. This gap is defined as
+     * the time to travel the distance between the leading vehicle's rear-most point to the ACC
+     * vehicle's front-most point. The actual time gap from a leading vehicle can be above or below
+     * this value.
+     *
+     * The possible values to set for the target time gap should be specified in configArray in
+     * ascending order. All values must be positive. If the property is writable, all values must be
+     * writable.
+     *
+     * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
+     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE
+     * is implemented and the state is set to an ErrorState value, then this property must return a
+     * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set
+     * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @unit VehicleUnit:MILLI_SECS
+     */
+    ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP =
+            0x1014 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Measured distance from leading vehicle when using Adaptive Cruise Control (ACC) or
+     * Predictive Cruise Control.
+     *
+     * Returns the measured distance in millimeters between the rear-most point of the leading
+     * vehicle and the front-most point of the ACC vehicle.
+     *
+     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+     * The minInt32Value should be 0.
+     * The maxInt32Value should be populated with the maximum range the distance sensor can support.
+     * This value should be non-negative.
+     *
+     * When no lead vehicle is detected (that is, when there is no leading vehicle or the leading
+     * vehicle is too far away for the sensor to detect), this property should return
+     * StatusCode.NOT_AVAILABLE.
+     *
+     * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
+     * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE
+     * is implemented and the state is set to an ErrorState value, then this property must return a
+     * StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set
+     * to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return
+     * StatusCode#NOT_AVAILABLE_SPEED_LOW.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @unit VehicleUnit:MILLIMETER
+     */
+    ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE =
+            0x1015 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Enable or disable Hands On Detection (HOD).
+     *
+     * Set true to enable HOD and false to disable HOD. When HOD is enabled, a system inside the
+     * vehicle should be monitoring the presence of the driver's hands on the steering wheel and
+     * send a warning if it detects that the driver's hands are no longer on the steering wheel.
+     *
+     * In general, HANDS_ON_DETECTION_ENABLED should always return true or false. If the feature is
+     * not available due to some temporary state, that information must be conveyed through the
+     * ErrorState values in the HANDS_ON_DETECTION_STATE property.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     */
+    HANDS_ON_DETECTION_ENABLED =
+            0x1016 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+    /**
+     * Hands On Detection (HOD) driver state.
+     *
+     * Returns whether the driver's hands are on the steering wheel. Generally, this property should
+     * return a valid state defined in the HandsOnDetectionDriverState or ErrorState. For example,
+     * if the feature is not available due to some temporary state, that information should be
+     * conveyed through ErrorState.
+     *
+     * If the vehicle wants to send a warning to the user because the driver's hands have been off
+     * the steering wheel for too long, the warning should be surfaced through
+     * HANDS_ON_DETECTION_WARNING.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of both HandsOnDetectionDriverState (including OTHER, which is not
+     * recommended) and ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum HandsOnDetectionDriverState
+     * @data_enum ErrorState
+     */
+    HANDS_ON_DETECTION_DRIVER_STATE =
+            0x1017 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /**
+     * Hands On Detection (HOD) warning.
+     *
+     * Returns whether a warning is being sent to the driver for having their hands off the wheel
+     * for too long a duration.
+     *
+     * Generally, this property should return a valid state defined in HandsOnDetectionWarning or
+     * ErrorState. For example, if the feature is not available due to some temporary state, that
+     * information should be conveyed through an ErrorState.
+     *
+     * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+     * unless all states of both HandsOnDetectionWarning (including OTHER, which is not recommended)
+     * and ErrorState are supported.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum HandsOnDetectionWarning
+     * @data_enum ErrorState
+     */
+    HANDS_ON_DETECTION_WARNING =
+            0x1018 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+    /***************************************************************************
+     * End of ADAS Properties
+     **************************************************************************/
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
new file mode 100644
index 0000000..7a68b4a
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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.automotive.vehicle;
+
+/**
+ * Enumerates supported data type for VehicleProperty.
+ *
+ * Used to create property ID in VehicleProperty enum.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehiclePropertyType {
+    STRING = 0x00100000,
+    /**
+     * Boolean values should be specified through the int32Values in RawPropValues.
+     * int32Value = {0} represents false and int32Value = {1} represents true.
+     */
+    BOOLEAN = 0x00200000,
+    INT32 = 0x00400000,
+    INT32_VEC = 0x00410000,
+    INT64 = 0x00500000,
+    INT64_VEC = 0x00510000,
+    FLOAT = 0x00600000,
+    FLOAT_VEC = 0x00610000,
+    BYTES = 0x00700000,
+
+    /**
+     * Any combination of scalar or vector types. The exact format must be
+     * provided in the description of the property.
+     *
+     * For vendor MIXED type properties, configArray needs to be formatted in this
+     * structure.
+     * configArray[0], 1 indicates the property has a String value
+     * configArray[1], 1 indicates the property has a Boolean value .
+     * configArray[2], 1 indicates the property has an Integer value.
+     * configArray[3], the number indicates the size of Integer[] in the property.
+     * configArray[4], 1 indicates the property has a Long value.
+     * configArray[5], the number indicates the size of Long[] in the property.
+     * configArray[6], 1 indicates the property has a Float value.
+     * configArray[7], the number indicates the size of Float[] in the property.
+     * configArray[8], the number indicates the size of byte[] in the property.
+     * For example:
+     * {@code configArray = {1, 1, 1, 3, 0, 0, 0, 0, 0}} indicates the property has
+     * a String value, a Boolean value, an Integer value and an array with 3 integers.
+     */
+    MIXED = 0x00e00000,
+
+    MASK = 0x00ff0000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleUnit.aidl
new file mode 100644
index 0000000..d4f9086
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleUnit.aidl
@@ -0,0 +1,62 @@
+/*
+ * 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.automotive.vehicle;
+
+/**
+ * Units used for int or float type with no attached enum types.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleUnit {
+    SHOULD_NOT_USE = 0x000,
+    METER_PER_SEC = 0x01,
+    RPM = 0x02,
+    HERTZ = 0x03,
+    PERCENTILE = 0x10,
+    MILLIMETER = 0x20,
+    METER = 0x21,
+    KILOMETER = 0x23,
+    MILE = 0x24,
+    CELSIUS = 0x30,
+    FAHRENHEIT = 0x31,
+    KELVIN = 0x32,
+    MILLILITER = 0x40,
+    LITER = 0x41,
+    /**
+     * deprecated. Use US_GALLON instead.
+     */
+    GALLON = 0x42,
+    US_GALLON = 0x42,
+    IMPERIAL_GALLON = 0x43,
+    NANO_SECS = 0x50,
+    MILLI_SECS = 0x51,
+    SECS = 0x53,
+    YEAR = 0x59,
+    WATT_HOUR = 0x60,
+    MILLIAMPERE = 0x61,
+    MILLIVOLT = 0x62,
+    MILLIWATTS = 0x63,
+    AMPERE_HOURS = 0x64,
+    KILOWATT_HOUR = 0x65,
+    AMPERE = 0x66,
+    KILOPASCAL = 0x70,
+    PSI = 0x71,
+    BAR = 0x72,
+    DEGREES = 0x80,
+    MILES_PER_HOUR = 0x90,
+    KILOMETERS_PER_HOUR = 0x91,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
new file mode 100644
index 0000000..820fcc8
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of VehicleProperty#WINDSHIELD_WIPERS_STATE.
+ */
+@VintfStability
+@Backing(type="int")
+enum WindshieldWipersState {
+
+    /**
+     * This state is used as an alternative for any WindshieldWipersState value that is not defined
+     * in the platform. Ideally, implementations of VehicleProperty#WINDSHIELD_WIPERS_STATE should
+     * not use this state. The framework can use this field to remain backwards compatible if
+     * WindshieldWipersState is extended to include additional states.
+     */
+    OTHER = 0,
+    /**
+     * This state indicates the windshield wipers are currently off. If
+     * VehicleProperty#WINDSHIELD_WIPERS_SWITCH is implemented, then it may be set to any of the
+     * following modes: OFF or AUTO.
+     */
+    OFF = 1,
+    /**
+     * This state indicates the windshield wipers are currently on. If
+     * VehicleProperty#WINDSHIELD_WIPERS_SWITCH is implemented, then it may be set to any of the
+     * following modes: MIST, INTERMITTENT_LEVEL_*, CONTINUOUS_LEVEL_*, or AUTO.
+     */
+    ON = 2,
+    /**
+     * Windshield wipers are in the service mode.
+     */
+    SERVICE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
new file mode 100644
index 0000000..911d7eb
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current position of VehicleProperty#WINDSHIELD_WIPERS_SWITCH.
+ */
+@VintfStability
+@Backing(type="int")
+enum WindshieldWipersSwitch {
+
+    /**
+     * This value is used as an alternative for any WindshieldWipersSwitch value that is not defined
+     * in the platform. Ideally, implementations of VehicleProperty#WINDSHIELD_WIPERS_SWITCH should
+     * not use this value. The framework can use this field to remain backwards compatible if
+     * WindshieldWipersSwitch is extended to include additional values.
+     */
+    OTHER = 0,
+    /**
+     * The windshield wipers switch is set to the off position.
+     */
+    OFF = 1,
+    /**
+     * MIST mode performs a single wipe, and then returns to the OFF position.
+     */
+    MIST = 2,
+    /**
+     * INTERMITTENT_LEVEL_* modes performs intermittent wiping. As the level increases, the
+     * intermittent time period decreases.
+     */
+    INTERMITTENT_LEVEL_1 = 3,
+    INTERMITTENT_LEVEL_2 = 4,
+    INTERMITTENT_LEVEL_3 = 5,
+    INTERMITTENT_LEVEL_4 = 6,
+    INTERMITTENT_LEVEL_5 = 7,
+    /**
+     * CONTINUOUS_LEVEL_* modes performs continuous wiping. As the level increases the speed of the
+     * wiping increases as well.
+     */
+    CONTINUOUS_LEVEL_1 = 8,
+    CONTINUOUS_LEVEL_2 = 9,
+    CONTINUOUS_LEVEL_3 = 10,
+    CONTINUOUS_LEVEL_4 = 11,
+    CONTINUOUS_LEVEL_5 = 12,
+    /**
+     * AUTO allows the vehicle to decide the required wiping level based on the exterior weather
+     * conditions.
+     */
+    AUTO = 13,
+    /**
+     * Windshield wipers are set to the service mode.
+     */
+    SERVICE = 14,
+}
diff --git a/automotive/vehicle/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
new file mode 100644
index 0000000..c36cbb0
--- /dev/null
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -0,0 +1,245 @@
+#!/usr/bin/python
+
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""A script to generate Java files and CPP header files based on annotations in VehicleProperty.aidl
+
+   Need ANDROID_BUILD_TOP environmental variable to be set. This script will update
+   ChangeModeForVehicleProperty.h and AccessForVehicleProperty.h under generated_lib/cpp and
+   ChangeModeForVehicleProperty.java and AccessForVehicleProperty.java under generated_lib/java.
+
+   Usage:
+   $ python generate_annotation_enums.py
+"""
+import os
+import re
+import sys
+
+PROP_AIDL_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl_property/android/hardware/" +
+    "automotive/vehicle/VehicleProperty.aidl")
+CHANGE_MODE_CPP_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/" +
+    "ChangeModeForVehicleProperty.h")
+ACCESS_CPP_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/" +
+    "AccessForVehicleProperty.h")
+CHANGE_MODE_JAVA_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/" +
+    "ChangeModeForVehicleProperty.java")
+ACCESS_JAVA_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/" +
+    "AccessForVehicleProperty.java")
+
+TAB = "    "
+RE_ENUM_START = re.compile("\s*enum VehicleProperty \{")
+RE_ENUM_END = re.compile("\s*\}\;")
+RE_COMMENT_BEGIN = re.compile("\s*\/\*\*?")
+RE_COMMENT_END = re.compile("\s*\*\/")
+RE_CHANGE_MODE = re.compile("\s*\* @change_mode (\S+)\s*")
+RE_ACCESS = re.compile("\s*\* @access (\S+)\s*")
+RE_VALUE = re.compile("\s*(\w+)\s*=(.*)")
+
+LICENSE = """/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+"""
+
+CHANGE_MODE_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehicleProperty = {
+"""
+
+CHANGE_MODE_CPP_FOOTER = """
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+}  // aidl
+
+#endif  // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+"""
+
+ACCESS_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehicleProperty = {
+"""
+
+ACCESS_CPP_FOOTER = """
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+}  // aidl
+
+#endif  // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+"""
+
+CHANGE_MODE_JAVA_HEADER = """package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class ChangeModeForVehicleProperty {
+
+    public static final Map<Integer, Integer> values = Map.ofEntries(
+"""
+
+CHANGE_MODE_JAVA_FOOTER = """
+    );
+
+}
+"""
+
+ACCESS_JAVA_HEADER = """package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class AccessForVehicleProperty {
+
+    public static final Map<Integer, Integer> values = Map.ofEntries(
+"""
+
+ACCESS_JAVA_FOOTER = """
+    );
+
+}
+"""
+
+
+class Converter:
+
+    def __init__(self, name, annotation_re):
+        self.name = name
+        self.annotation_re = annotation_re
+
+    def convert(self, input, output, header, footer, cpp):
+        processing = False
+        in_comment = False
+        content = LICENSE + header
+        annotation = None
+        id = 0
+        with open(input, 'r') as f:
+            for line in f.readlines():
+                if RE_ENUM_START.match(line):
+                    processing = True
+                    annotation = None
+                elif RE_ENUM_END.match(line):
+                    processing = False
+                if not processing:
+                    continue
+                if RE_COMMENT_BEGIN.match(line):
+                    in_comment = True
+                if RE_COMMENT_END.match(line):
+                    in_comment = False
+                if in_comment:
+                    match = self.annotation_re.match(line)
+                    if match:
+                        annotation = match.group(1)
+                else:
+                    match = RE_VALUE.match(line)
+                    if match:
+                        prop_name = match.group(1)
+                        if prop_name == "INVALID":
+                            continue
+                        if not annotation:
+                            print("No @" + self.name + " annotation for property: " + prop_name)
+                            sys.exit(1)
+                        if id != 0:
+                            content += "\n"
+                        if cpp:
+                            annotation = annotation.replace(".", "::")
+                            content += (TAB + TAB + "{VehicleProperty::" + prop_name + ", " +
+                                        annotation + "},")
+                        else:
+                            content += (TAB + TAB + "Map.entry(VehicleProperty." + prop_name + ", " +
+                                        annotation + "),")
+                        id += 1
+
+        # Remove the additional "," at the end for the Java file.
+        if not cpp:
+            content = content[:-1]
+
+        content += footer
+
+        with open(output, 'w') as f:
+            f.write(content)
+
+
+def main():
+    android_top = os.environ['ANDROID_BUILD_TOP']
+    if not android_top:
+        print("ANDROID_BUILD_TOP is not in envorinmental variable, please run source and lunch " +
+            "at the android root")
+
+    aidl_file = os.path.join(android_top, PROP_AIDL_FILE_PATH)
+    change_mode_cpp_output = os.path.join(android_top, CHANGE_MODE_CPP_FILE_PATH);
+    access_cpp_output = os.path.join(android_top, ACCESS_CPP_FILE_PATH);
+    change_mode_java_output = os.path.join(android_top, CHANGE_MODE_JAVA_FILE_PATH);
+    access_java_output = os.path.join(android_top, ACCESS_JAVA_FILE_PATH);
+
+    c = Converter("change_mode", RE_CHANGE_MODE);
+    c.convert(aidl_file, change_mode_cpp_output, CHANGE_MODE_CPP_HEADER, CHANGE_MODE_CPP_FOOTER, True)
+    c.convert(aidl_file, change_mode_java_output, CHANGE_MODE_JAVA_HEADER, CHANGE_MODE_JAVA_FOOTER, False)
+    c = Converter("access", RE_ACCESS)
+    c.convert(aidl_file, access_cpp_output, ACCESS_CPP_HEADER, ACCESS_CPP_FOOTER, True)
+    c.convert(aidl_file, access_java_output, ACCESS_JAVA_HEADER, ACCESS_JAVA_FOOTER, False)
+
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/automotive/vehicle/vhal_static_cpp_lib.mk b/automotive/vehicle/vhal_static_cpp_lib.mk
new file mode 100644
index 0000000..995589c
--- /dev/null
+++ b/automotive/vehicle/vhal_static_cpp_lib.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This make file contains the latest version of static cpp libraries for VHAL
+# interface and VHAL properties.
+
+LOCAL_STATIC_LIBRARIES += \
+    android.hardware.automotive.vehicle-V2-ndk \
+    android.hardware.automotive.vehicle.property-V2-ndk
diff --git a/automotive/vehicle/vts/Android.bp b/automotive/vehicle/vts/Android.bp
index b78e0ff..736787b 100644
--- a/automotive/vehicle/vts/Android.bp
+++ b/automotive/vehicle/vts/Android.bp
@@ -44,6 +44,8 @@
     test_suites: [
         "general-tests",
         "vts",
+        "automotive-tests",
+        "automotive-general-tests",
     ],
     require_root: true,
 }
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index f8ef8cb..3c5cda2 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -45,10 +45,13 @@
 using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
 using ::android::getAidlHalInstanceNames;
 using ::android::base::ScopedLockAssertion;
 using ::android::base::StringPrintf;
+using ::android::frameworks::automotive::vhal::ErrorCode;
 using ::android::frameworks::automotive::vhal::HalPropError;
 using ::android::frameworks::automotive::vhal::IHalPropConfig;
 using ::android::frameworks::automotive::vhal::IHalPropValue;
@@ -113,22 +116,25 @@
 };
 
 class VtsHalAutomotiveVehicleTargetTest : public testing::TestWithParam<ServiceDescriptor> {
-protected:
-  bool checkIsSupported(int32_t propertyId);
+  protected:
+    bool checkIsSupported(int32_t propertyId);
 
-public:
-  virtual void SetUp() override {
-      auto descriptor = GetParam();
-      if (descriptor.isAidlService) {
-          mVhalClient = IVhalClient::tryCreateAidlClient(descriptor.name.c_str());
-      } else {
-          mVhalClient = IVhalClient::tryCreateHidlClient(descriptor.name.c_str());
-      }
+  public:
+    void verifyProperty(VehicleProperty propId, VehiclePropertyAccess access,
+                        VehiclePropertyChangeMode changeMode, VehiclePropertyGroup group,
+                        VehicleArea area, VehiclePropertyType propertyType);
+    virtual void SetUp() override {
+        auto descriptor = GetParam();
+        if (descriptor.isAidlService) {
+            mVhalClient = IVhalClient::tryCreateAidlClient(descriptor.name.c_str());
+        } else {
+            mVhalClient = IVhalClient::tryCreateHidlClient(descriptor.name.c_str());
+        }
 
-      ASSERT_NE(mVhalClient, nullptr) << "Failed to connect to VHAL";
+        ASSERT_NE(mVhalClient, nullptr) << "Failed to connect to VHAL";
 
-      mCallback = std::make_shared<VtsVehicleCallback>();
-  }
+        mCallback = std::make_shared<VtsVehicleCallback>();
+    }
 
     static bool isBooleanGlobalProp(int32_t property) {
         return (property & toInt(VehiclePropertyType::MASK)) ==
@@ -304,7 +310,31 @@
     auto setValueResult = mVhalClient->setValueSync(*getValueResult.value());
 
     ASSERT_FALSE(setValueResult.ok()) << "Expect set a read-only value to fail";
-    ASSERT_EQ(setValueResult.error().code(), StatusCode::ACCESS_DENIED);
+    ASSERT_EQ(setValueResult.error().code(), ErrorCode::ACCESS_DENIED_FROM_VHAL);
+}
+
+// Test get(), set() and getAllPropConfigs() on VehicleProperty::INVALID.
+TEST_P(VtsHalAutomotiveVehicleTargetTest, getSetPropertyIdInvalid) {
+    ALOGD("VtsHalAutomotiveVehicleTargetTest::getSetPropertyIdInvalid");
+
+    int32_t propId = toInt(VehicleProperty::INVALID);
+    auto getValueResult = mVhalClient->getValueSync(*mVhalClient->createHalPropValue(propId));
+    ASSERT_FALSE(getValueResult.ok()) << "Expect get on VehicleProperty::INVALID to fail";
+    ASSERT_EQ(getValueResult.error().code(), ErrorCode::INVALID_ARG);
+
+    auto propToSet = mVhalClient->createHalPropValue(propId);
+    propToSet->setInt32Values({0});
+    auto setValueResult = mVhalClient->setValueSync(*propToSet);
+    ASSERT_FALSE(setValueResult.ok()) << "Expect set on VehicleProperty::INVALID to fail";
+    ASSERT_EQ(setValueResult.error().code(), ErrorCode::INVALID_ARG);
+
+    auto result = mVhalClient->getAllPropConfigs();
+    ASSERT_TRUE(result.ok());
+    for (const auto& cfgPtr : result.value()) {
+        const IHalPropConfig& cfg = *cfgPtr;
+        ASSERT_FALSE(cfg.getPropId() == propId) << "Expect VehicleProperty::INVALID to not be "
+                                                   "included in propConfigs";
+    }
 }
 
 // Test subscribe() and unsubscribe().
@@ -442,6 +472,422 @@
     }
 }
 
+// Helper function to compare actual vs expected property config
+void VtsHalAutomotiveVehicleTargetTest::verifyProperty(VehicleProperty propId,
+                                                       VehiclePropertyAccess access,
+                                                       VehiclePropertyChangeMode changeMode,
+                                                       VehiclePropertyGroup group, VehicleArea area,
+                                                       VehiclePropertyType propertyType) {
+    int expectedPropId = toInt(propId);
+    int expectedAccess = toInt(access);
+    int expectedChangeMode = toInt(changeMode);
+    int expectedGroup = toInt(group);
+    int expectedArea = toInt(area);
+    int expectedPropertyType = toInt(propertyType);
+
+    auto result = mVhalClient->getAllPropConfigs();
+    ASSERT_TRUE(result.ok()) << "Failed to get all property configs, error: "
+                             << result.error().message();
+
+    // Check if property is implemented by getting all configs and looking to see if the expected
+    // property id is in that list.
+    bool isExpectedPropIdImplemented = false;
+    for (const auto& cfgPtr : result.value()) {
+        const IHalPropConfig& cfg = *cfgPtr;
+        if (expectedPropId == cfg.getPropId()) {
+            isExpectedPropIdImplemented = true;
+            break;
+        }
+    }
+
+    if (!isExpectedPropIdImplemented) {
+        GTEST_SKIP() << StringPrintf("Property %" PRId32 " has not been implemented",
+                                     expectedPropId);
+    }
+
+    result = mVhalClient->getPropConfigs({expectedPropId});
+    ASSERT_TRUE(result.ok()) << "Failed to get required property config, error: "
+                             << result.error().message();
+
+    ASSERT_EQ(result.value().size(), 1u)
+            << StringPrintf("Expect to get exactly 1 config, got %zu", result.value().size());
+
+    const auto& config = result.value().at(0);
+    int actualPropId = config->getPropId();
+    int actualAccess = config->getAccess();
+    int actualChangeMode = config->getChangeMode();
+    int actualGroup = actualPropId & toInt(VehiclePropertyGroup::MASK);
+    int actualArea = actualPropId & toInt(VehicleArea::MASK);
+    int actualPropertyType = actualPropId & toInt(VehiclePropertyType::MASK);
+
+    ASSERT_EQ(actualPropId, expectedPropId)
+            << StringPrintf("Expect to get property ID: %i, got %i", expectedPropId, actualPropId);
+
+    if (expectedAccess == toInt(VehiclePropertyAccess::READ_WRITE)) {
+        ASSERT_TRUE(actualAccess == expectedAccess ||
+                    actualAccess == toInt(VehiclePropertyAccess::READ))
+                << StringPrintf("Expect to get VehiclePropertyAccess: %i or %i, got %i",
+                                expectedAccess, toInt(VehiclePropertyAccess::READ), actualAccess);
+    } else {
+        ASSERT_EQ(actualAccess, expectedAccess) << StringPrintf(
+                "Expect to get VehiclePropertyAccess: %i, got %i", expectedAccess, actualAccess);
+    }
+
+    ASSERT_EQ(actualChangeMode, expectedChangeMode)
+            << StringPrintf("Expect to get VehiclePropertyChangeMode: %i, got %i",
+                            expectedChangeMode, actualChangeMode);
+    ASSERT_EQ(actualGroup, expectedGroup) << StringPrintf(
+            "Expect to get VehiclePropertyGroup: %i, got %i", expectedGroup, actualGroup);
+    ASSERT_EQ(actualArea, expectedArea)
+            << StringPrintf("Expect to get VehicleArea: %i, got %i", expectedArea, actualArea);
+    ASSERT_EQ(actualPropertyType, expectedPropertyType)
+            << StringPrintf("Expect to get VehiclePropertyType: %i, got %i", expectedPropertyType,
+                            actualPropertyType);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLocationCharacterizationConfig) {
+    verifyProperty(VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEmergencyLaneKeepAssistEnabledConfig) {
+    verifyProperty(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEmergencyLaneKeepAssistStateConfig) {
+    verifyProperty(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlEnabledConfig) {
+    verifyProperty(VehicleProperty::CRUISE_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlTypeConfig) {
+    verifyProperty(VehicleProperty::CRUISE_CONTROL_TYPE, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlStateConfig) {
+    verifyProperty(VehicleProperty::CRUISE_CONTROL_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlCommandConfig) {
+    verifyProperty(VehicleProperty::CRUISE_CONTROL_COMMAND, VehiclePropertyAccess::WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlTargetSpeedConfig) {
+    verifyProperty(VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyAdaptiveCruiseControlTargetTimeGapConfig) {
+    verifyProperty(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest,
+       verifyAdaptiveCruiseControlLeadVehicleMeasuredDistanceConfig) {
+    verifyProperty(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE,
+                   VehiclePropertyAccess::READ, VehiclePropertyChangeMode::CONTINUOUS,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyHandsOnDetectionEnabledConfig) {
+    verifyProperty(VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyHandsOnDetectionDriverStateConfig) {
+    verifyProperty(VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyHandsOnDetectionWarningConfig) {
+    verifyProperty(VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvBrakeRegenerationLevelConfig) {
+    verifyProperty(VehicleProperty::EV_BRAKE_REGENERATION_LEVEL,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvStoppingModeConfig) {
+    verifyProperty(VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvCurrentBatteryCapacityConfig) {
+    verifyProperty(VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEngineIdleAutoStopEnabledConfig) {
+    verifyProperty(VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDoorChildLockEnabledConfig) {
+    verifyProperty(VehicleProperty::DOOR_CHILD_LOCK_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::DOOR, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyWindshieldWipersPeriodConfig) {
+    verifyProperty(VehicleProperty::WINDSHIELD_WIPERS_PERIOD, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::WINDOW, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyWindshieldWipersStateConfig) {
+    verifyProperty(VehicleProperty::WINDSHIELD_WIPERS_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::WINDOW, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyWindshieldWipersSwitchConfig) {
+    verifyProperty(VehicleProperty::WINDSHIELD_WIPERS_SWITCH, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::WINDOW, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelDepthPosConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_DEPTH_POS, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelDepthMoveConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelHeightPosConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelHeightMoveConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelTheftLockEnabledConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelLockedConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelEasyAccessEnabledConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelLightsStateConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelLightsSwitchConfig) {
+    verifyProperty(VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyGloveBoxDoorPosConfig) {
+    verifyProperty(VehicleProperty::GLOVE_BOX_DOOR_POS, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyGloveBoxLockedConfig) {
+    verifyProperty(VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyMirrorAutoFoldEnabledConfig) {
+    verifyProperty(VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::MIRROR, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyMirrorAutoTiltEnabledConfig) {
+    verifyProperty(VehicleProperty::MIRROR_AUTO_TILT_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::MIRROR, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatHeadrestHeightPosV2Config) {
+    verifyProperty(VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatWalkInPosConfig) {
+    verifyProperty(VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatFootwellLightsStateConfig) {
+    verifyProperty(VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatFootwellLightsSwitchConfig) {
+    verifyProperty(VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatEasyAccessEnabledConfig) {
+    verifyProperty(VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatAirbagEnabledConfig) {
+    verifyProperty(VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatCushionSideSupportPosConfig) {
+    verifyProperty(VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatCushionSideSupportMoveConfig) {
+    verifyProperty(VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatLumbarVerticalPosConfig) {
+    verifyProperty(VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatLumbarVerticalMoveConfig) {
+    verifyProperty(VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyAutomaticEmergencyBrakingEnabledConfig) {
+    verifyProperty(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyAutomaticEmergencyBrakingStateConfig) {
+    verifyProperty(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyForwardCollisionWarningEnabledConfig) {
+    verifyProperty(VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyForwardCollisionWarningStateConfig) {
+    verifyProperty(VehicleProperty::FORWARD_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyBlindSpotWarningEnabledConfig) {
+    verifyProperty(VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyBlindSpotWarningStateConfig) {
+    verifyProperty(VehicleProperty::BLIND_SPOT_WARNING_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::MIRROR, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneDepartureWarningEnabledConfig) {
+    verifyProperty(VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneDepartureWarningStateConfig) {
+    verifyProperty(VehicleProperty::LANE_DEPARTURE_WARNING_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneKeepAssistEnabledConfig) {
+    verifyProperty(VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneKeepAssistStateConfig) {
+    verifyProperty(VehicleProperty::LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneCenteringAssistEnabledConfig) {
+    verifyProperty(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED,
+                   VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneCenteringAssistCommandConfig) {
+    verifyProperty(VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyAccess::WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneCenteringAssistStateConfig) {
+    verifyProperty(VehicleProperty::LANE_CENTERING_ASSIST_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
 bool VtsHalAutomotiveVehicleTargetTest::checkIsSupported(int32_t propertyId) {
   auto result = mVhalClient->getPropConfigs({propertyId});
   return result.ok();
diff --git a/biometrics/OWNERS b/biometrics/OWNERS
new file mode 100644
index 0000000..58998c1
--- /dev/null
+++ b/biometrics/OWNERS
@@ -0,0 +1,8 @@
+ilyamaty@google.com
+jeffpu@google.com
+jbolinger@google.com
+joshmccloskey@google.com
+diyab@google.com
+austindelgado@google.com
+spdonghao@google.com
+wenhuiy@google.com
diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp
index 167e0c7..b41a937 100644
--- a/biometrics/common/aidl/Android.bp
+++ b/biometrics/common/aidl/Android.bp
@@ -13,6 +13,7 @@
     srcs: [
         "android/hardware/biometrics/common/*.aidl",
     ],
+    frozen: true,
     stability: "vintf",
     backend: {
         java: {
@@ -31,7 +32,10 @@
             version: "2",
             imports: [],
         },
+        {
+            version: "3",
+            imports: [],
+        },
 
     ],
-
 }
diff --git a/biometrics/common/aidl/OWNERS b/biometrics/common/aidl/OWNERS
deleted file mode 100644
index 36d7261..0000000
--- a/biometrics/common/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-ilyamaty@google.com
-kchyn@google.com
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/.hash b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/.hash
new file mode 100644
index 0000000..15b5032
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/.hash
@@ -0,0 +1 @@
+a9ebb97f5abea1dc6800b69d821ef61944e80e65
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/AuthenticateReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/AuthenticateReason.aidl
new file mode 100644
index 0000000..f639ead
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/AuthenticateReason.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.common;
+/* @hide */
+@VintfStability
+union AuthenticateReason {
+  android.hardware.biometrics.common.AuthenticateReason.Vendor vendorAuthenticateReason;
+  android.hardware.biometrics.common.AuthenticateReason.Face faceAuthenticateReason;
+  android.hardware.biometrics.common.AuthenticateReason.Fingerprint fingerprintAuthenticateReason;
+  @VintfStability
+  parcelable Vendor {
+    ParcelableHolder extension;
+  }
+  @Backing(type="int") @VintfStability
+  enum Fingerprint {
+    UNKNOWN,
+  }
+  @Backing(type="int") @VintfStability
+  enum Face {
+    UNKNOWN,
+    STARTED_WAKING_UP,
+    PRIMARY_BOUNCER_SHOWN,
+    ASSISTANT_VISIBLE,
+    ALTERNATE_BIOMETRIC_BOUNCER_SHOWN,
+    NOTIFICATION_PANEL_CLICKED,
+    OCCLUDING_APP_REQUESTED,
+    PICK_UP_GESTURE_TRIGGERED,
+    QS_EXPANDED,
+    SWIPE_UP_ON_BOUNCER,
+    UDFPS_POINTER_DOWN,
+  }
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/CommonProps.aidl
new file mode 100644
index 0000000..1eb8541
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/CommonProps.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.biometrics.common;
+/* @hide */
+@VintfStability
+parcelable CommonProps {
+  int sensorId;
+  android.hardware.biometrics.common.SensorStrength sensorStrength = android.hardware.biometrics.common.SensorStrength.CONVENIENCE;
+  int maxEnrollmentsPerUser;
+  android.hardware.biometrics.common.ComponentInfo[] componentInfo;
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/ComponentInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/ComponentInfo.aidl
new file mode 100644
index 0000000..471ed2b
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/ComponentInfo.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.biometrics.common;
+/* @hide */
+@VintfStability
+parcelable ComponentInfo {
+  String componentId;
+  String hardwareVersion;
+  String firmwareVersion;
+  String serialNumber;
+  String softwareVersion;
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/DisplayState.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/DisplayState.aidl
new file mode 100644
index 0000000..176e8d6
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/DisplayState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DisplayState {
+  UNKNOWN,
+  LOCKSCREEN,
+  NO_UI,
+  SCREENSAVER,
+  AOD,
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/ICancellationSignal.aidl
new file mode 100644
index 0000000..670114f
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/ICancellationSignal.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.biometrics.common;
+/* @hide */
+@VintfStability
+interface ICancellationSignal {
+  oneway void cancel();
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/OperationContext.aidl
new file mode 100644
index 0000000..378017e
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/OperationContext.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.biometrics.common;
+/* @hide */
+@VintfStability
+parcelable OperationContext {
+  int id = 0;
+  android.hardware.biometrics.common.OperationReason reason = android.hardware.biometrics.common.OperationReason.UNKNOWN;
+  /**
+   * @deprecated use displayState instead.
+   */
+  boolean isAod = false;
+  boolean isCrypto = false;
+  android.hardware.biometrics.common.WakeReason wakeReason = android.hardware.biometrics.common.WakeReason.UNKNOWN;
+  android.hardware.biometrics.common.DisplayState displayState = android.hardware.biometrics.common.DisplayState.UNKNOWN;
+  @nullable android.hardware.biometrics.common.AuthenticateReason authenticateReason;
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/OperationReason.aidl
new file mode 100644
index 0000000..188054a
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/OperationReason.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.common;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum OperationReason {
+  UNKNOWN,
+  BIOMETRIC_PROMPT,
+  KEYGUARD,
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/SensorStrength.aidl
new file mode 100644
index 0000000..c931781
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/SensorStrength.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.biometrics.common;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum SensorStrength {
+  CONVENIENCE,
+  WEAK,
+  STRONG,
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/WakeReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/WakeReason.aidl
new file mode 100644
index 0000000..6a08776
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/3/android/hardware/biometrics/common/WakeReason.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum WakeReason {
+  UNKNOWN,
+  POWER_BUTTON,
+  GESTURE,
+  WAKE_KEY,
+  WAKE_MOTION,
+  LID,
+  DISPLAY_GROUP_ADDED,
+  TAP,
+  LIFT,
+  BIOMETRIC,
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/AuthenticateReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/AuthenticateReason.aidl
new file mode 100644
index 0000000..f639ead
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/AuthenticateReason.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.common;
+/* @hide */
+@VintfStability
+union AuthenticateReason {
+  android.hardware.biometrics.common.AuthenticateReason.Vendor vendorAuthenticateReason;
+  android.hardware.biometrics.common.AuthenticateReason.Face faceAuthenticateReason;
+  android.hardware.biometrics.common.AuthenticateReason.Fingerprint fingerprintAuthenticateReason;
+  @VintfStability
+  parcelable Vendor {
+    ParcelableHolder extension;
+  }
+  @Backing(type="int") @VintfStability
+  enum Fingerprint {
+    UNKNOWN,
+  }
+  @Backing(type="int") @VintfStability
+  enum Face {
+    UNKNOWN,
+    STARTED_WAKING_UP,
+    PRIMARY_BOUNCER_SHOWN,
+    ASSISTANT_VISIBLE,
+    ALTERNATE_BIOMETRIC_BOUNCER_SHOWN,
+    NOTIFICATION_PANEL_CLICKED,
+    OCCLUDING_APP_REQUESTED,
+    PICK_UP_GESTURE_TRIGGERED,
+    QS_EXPANDED,
+    SWIPE_UP_ON_BOUNCER,
+    UDFPS_POINTER_DOWN,
+  }
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
index d4433c5..1eb8541 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
@@ -32,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.common;
+/* @hide */
 @VintfStability
 parcelable CommonProps {
   int sensorId;
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl
index ad11dda..471ed2b 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl
@@ -32,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.common;
+/* @hide */
 @VintfStability
 parcelable ComponentInfo {
   String componentId;
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/DisplayState.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/DisplayState.aidl
new file mode 100644
index 0000000..176e8d6
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/DisplayState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DisplayState {
+  UNKNOWN,
+  LOCKSCREEN,
+  NO_UI,
+  SCREENSAVER,
+  AOD,
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
index 2bc6a6d..670114f 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
@@ -32,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.common;
+/* @hide */
 @VintfStability
 interface ICancellationSignal {
   oneway void cancel();
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
index 9d1cb8f..378017e 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
@@ -32,10 +32,17 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.common;
+/* @hide */
 @VintfStability
 parcelable OperationContext {
   int id = 0;
   android.hardware.biometrics.common.OperationReason reason = android.hardware.biometrics.common.OperationReason.UNKNOWN;
+  /**
+   * @deprecated use displayState instead.
+   */
   boolean isAod = false;
   boolean isCrypto = false;
+  android.hardware.biometrics.common.WakeReason wakeReason = android.hardware.biometrics.common.WakeReason.UNKNOWN;
+  android.hardware.biometrics.common.DisplayState displayState = android.hardware.biometrics.common.DisplayState.UNKNOWN;
+  @nullable android.hardware.biometrics.common.AuthenticateReason authenticateReason;
 }
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
index 3da3a6a..188054a 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
@@ -32,9 +32,10 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.common;
+/* @hide */
 @Backing(type="byte") @VintfStability
 enum OperationReason {
-  UNKNOWN = 0,
-  BIOMETRIC_PROMPT = 1,
-  KEYGUARD = 2,
+  UNKNOWN,
+  BIOMETRIC_PROMPT,
+  KEYGUARD,
 }
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
index 6675d09..c931781 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
@@ -32,9 +32,10 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.common;
+/* @hide */
 @Backing(type="byte") @VintfStability
 enum SensorStrength {
-  CONVENIENCE = 0,
-  WEAK = 1,
-  STRONG = 2,
+  CONVENIENCE,
+  WEAK,
+  STRONG,
 }
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/WakeReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/WakeReason.aidl
new file mode 100644
index 0000000..6a08776
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/WakeReason.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum WakeReason {
+  UNKNOWN,
+  POWER_BUTTON,
+  GESTURE,
+  WAKE_KEY,
+  WAKE_MOTION,
+  LID,
+  DISPLAY_GROUP_ADDED,
+  TAP,
+  LIFT,
+  BIOMETRIC,
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/AuthenticateReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/AuthenticateReason.aidl
new file mode 100644
index 0000000..fcf5294
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/AuthenticateReason.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.common;
+
+/**
+ * Reason for an authenticate operation.
+ *
+ * @hide
+ */
+@VintfStability
+union AuthenticateReason {
+    /** Vendor reason for invoking an authenticate operation. */
+    @VintfStability
+    parcelable Vendor {
+        ParcelableHolder extension;
+    }
+
+    /** Reason for invoking fingerprint authentication. */
+    @VintfStability
+    @Backing(type="int")
+    enum Fingerprint {
+        UNKNOWN,
+    }
+
+    /** Reason for invoking face authentication. */
+    @VintfStability
+    @Backing(type="int")
+    enum Face {
+        UNKNOWN,
+        STARTED_WAKING_UP,
+        PRIMARY_BOUNCER_SHOWN,
+        ASSISTANT_VISIBLE,
+        ALTERNATE_BIOMETRIC_BOUNCER_SHOWN,
+        NOTIFICATION_PANEL_CLICKED,
+        OCCLUDING_APP_REQUESTED,
+        PICK_UP_GESTURE_TRIGGERED,
+        QS_EXPANDED,
+        SWIPE_UP_ON_BOUNCER,
+        UDFPS_POINTER_DOWN,
+    }
+
+    AuthenticateReason.Vendor vendorAuthenticateReason;
+    AuthenticateReason.Face faceAuthenticateReason;
+    AuthenticateReason.Fingerprint fingerprintAuthenticateReason;
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
index 2f5af5d..cdedf4f 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
@@ -18,7 +18,9 @@
 
 import android.hardware.biometrics.common.ComponentInfo;
 import android.hardware.biometrics.common.SensorStrength;
-
+/**
+ * @hide
+ */
 @VintfStability
 parcelable CommonProps {
     /**
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl
index b268eef..1da9cf6 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl
@@ -15,7 +15,9 @@
  */
 
 package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
 @VintfStability
 parcelable ComponentInfo {
     /**
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/DisplayState.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/DisplayState.aidl
new file mode 100644
index 0000000..d01eac8
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/DisplayState.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.common;
+
+/**
+ * Display state during an operation.
+ *
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DisplayState {
+    /** The display state is unknown. */
+    UNKNOWN,
+
+    /** The display is on and showing the lockscreen (or an occluding app). */
+    LOCKSCREEN,
+
+    /** The display is off or dozing. */
+    NO_UI,
+
+    /** The display is showing a screensaver (dreaming). */
+    SCREENSAVER,
+
+    /** The display is dreaming with always on display. */
+    AOD,
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl
index 1010256..b9b1f39 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl
@@ -15,9 +15,10 @@
  */
 
 package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
 @VintfStability
 oneway interface ICancellationSignal {
     void cancel();
 }
-
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
index 72fe660..f4191d7 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
@@ -16,10 +16,14 @@
 
 package android.hardware.biometrics.common;
 
+import android.hardware.biometrics.common.AuthenticateReason;
+import android.hardware.biometrics.common.DisplayState;
 import android.hardware.biometrics.common.OperationReason;
+import android.hardware.biometrics.common.WakeReason;
 
 /**
  * Additional context associated with an operation.
+ * @hide
  */
 @VintfStability
 parcelable OperationContext {
@@ -41,9 +45,30 @@
      */
     OperationReason reason = OperationReason.UNKNOWN;
 
-    /* Flag indicating that the display is in AOD mode. */
+    /** @deprecated use displayState instead. */
     boolean isAod = false;
 
     /** Flag indicating that crypto was requested. */
     boolean isCrypto = false;
+
+    /**
+     * An associated wake reason for this operation or WakeReason.UNKNOWN if this
+     * operation was not associated with a device wake up event.
+     *
+     * This should be interpreted as a hint to enable optimizations or tracing. The
+     * framework may choose to use WakeReason.UNKNOWN at any time based on the device's
+     * policy.
+     */
+    WakeReason wakeReason = WakeReason.UNKNOWN;
+
+    /** The current display state. */
+    DisplayState displayState = DisplayState.UNKNOWN;
+
+    /**
+     * An associated reason for an authenticate operation.
+     *
+     * This should be interpreted as a hint to enable optimizations or tracing. The
+     * framework may choose to omit the reason at any time based on the device's policy.
+     */
+    @nullable AuthenticateReason authenticateReason;
 }
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
index abc25ed..1775c43 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
@@ -16,6 +16,10 @@
 
 package android.hardware.biometrics.common;
 
+/**
+ * The reason for invoking an operation.
+ * @hide
+ */
 @VintfStability
 @Backing(type="byte")
 enum OperationReason {
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl
index 790691c..b5c0999 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl
@@ -15,7 +15,9 @@
  */
 
 package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
 @VintfStability
 @Backing(type="byte")
 enum SensorStrength {
@@ -40,4 +42,4 @@
      * HardwareAuthToken(s).
      */
     STRONG,
-}
\ No newline at end of file
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/WakeReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/WakeReason.aidl
new file mode 100644
index 0000000..2f36b00
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/WakeReason.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.common;
+
+/**
+ * The wake event associated with an operation, if applicable.
+ *
+ * The events largely shadow constants defined in PowerManager but they may deviate over time.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum WakeReason {
+    /**
+     * A normal operation without an explicit reason.
+     */
+    UNKNOWN,
+
+    /**
+     * Waking up due to power button press.
+     */
+    POWER_BUTTON,
+
+    /**
+     * Waking up due to a user performed gesture. This includes user
+     * interactions with UI on the screen such as the notification shade. This does not include
+     * WakeReason.TAP or WakeReason.LIFT.
+     */
+    GESTURE,
+
+    /**
+     * Waking up because a wake key other than power was pressed.
+     */
+    WAKE_KEY,
+
+    /**
+     * Waking up because a wake motion was performed.
+     */
+    WAKE_MOTION,
+
+    /**
+     * Waking due to the lid being opened.
+     */
+    LID,
+
+    /**
+     * Waking due to display group being added.
+     */
+    DISPLAY_GROUP_ADDED,
+
+    /**
+     * Waking up due to the user single or double tapping on the screen. This
+     * wake reason is used when the user is not tapping on a specific UI element; rather, the device
+     * wakes up due to a generic tap on the screen.
+     */
+    TAP,
+
+    /**
+     * Waking up due to a user performed lift gesture.
+     */
+    LIFT,
+
+    /**
+     * Waking up due to a user interacting with a biometric.
+     */
+    BIOMETRIC,
+}
diff --git a/biometrics/common/thread/Android.bp b/biometrics/common/thread/Android.bp
new file mode 100644
index 0000000..a497d01
--- /dev/null
+++ b/biometrics/common/thread/Android.bp
@@ -0,0 +1,26 @@
+cc_library {
+    // 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
+    name: "android.hardware.biometrics.common.thread",
+    export_include_dirs: ["include"],
+    vendor: true,
+    srcs: [
+        "WorkerThread.cpp",
+    ],
+}
+
+cc_test_host {
+    name: "android.hardware.biometrics.common.WorkerThreadTest",
+    local_include_dirs: ["include"],
+    srcs: [
+        "tests/WorkerThreadTest.cpp",
+        "WorkerThread.cpp",
+    ],
+    shared_libs: [
+        "libcutils",
+    ],
+    test_suites: ["general-tests"],
+}
diff --git a/biometrics/common/thread/WorkerThread.cpp b/biometrics/common/thread/WorkerThread.cpp
new file mode 100644
index 0000000..61d1a13
--- /dev/null
+++ b/biometrics/common/thread/WorkerThread.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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 "thread/WorkerThread.h"
+
+namespace aidl::android::hardware::biometrics {
+
+// It's important that mThread is initialized after everything else because it runs a member
+// function that may use any member of this class.
+WorkerThread::WorkerThread(size_t maxQueueSize)
+    : mMaxSize(maxQueueSize),
+      mIsDestructing(false),
+      mQueue(),
+      mQueueMutex(),
+      mQueueCond(),
+      mThread(&WorkerThread::threadFunc, this) {}
+
+WorkerThread::~WorkerThread() {
+    // This is a signal for threadFunc to terminate as soon as possible, and a hint for schedule
+    // that it doesn't need to do any work.
+    {
+        std::unique_lock<std::mutex> lock(mQueueMutex);
+        mIsDestructing = true;
+    }
+    mQueueCond.notify_all();
+    mThread.join();
+}
+
+bool WorkerThread::schedule(std::unique_ptr<Callable> task) {
+    if (mIsDestructing) {
+        return false;
+    }
+
+    std::unique_lock<std::mutex> lock(mQueueMutex);
+    if (mQueue.size() >= mMaxSize) {
+        return false;
+    }
+    mQueue.push_back(std::move(task));
+    lock.unlock();
+    mQueueCond.notify_one();
+    return true;
+}
+
+void WorkerThread::threadFunc() {
+    while (!mIsDestructing) {
+        std::unique_lock<std::mutex> lock(mQueueMutex);
+        mQueueCond.wait(lock, [this] { return !mQueue.empty() || mIsDestructing; });
+        if (mIsDestructing) {
+            return;
+        }
+        std::unique_ptr<Callable> task = std::move(mQueue.front());
+        mQueue.pop_front();
+        lock.unlock();
+        (*task)();
+    }
+}
+
+}  // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/common/thread/include/thread/Callable.h b/biometrics/common/thread/include/thread/Callable.h
new file mode 100644
index 0000000..6eeff76
--- /dev/null
+++ b/biometrics/common/thread/include/thread/Callable.h
@@ -0,0 +1,54 @@
+/*
+ * 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
+
+namespace aidl::android::hardware::biometrics {
+
+// Interface for representing parameterless functions. Unlike std::function<void()>, this can also
+// represent move-only lambdas.
+class Callable {
+  public:
+    virtual void operator()() = 0;
+    virtual ~Callable() = default;
+
+    // Creates a heap-allocated Callable instance from any function object.
+    template <typename T>
+    static std::unique_ptr<Callable> from(T func);
+
+  private:
+    template <typename T>
+    class AnyFuncWrapper;
+};
+
+// Private helper class for wrapping any function object into a Callable.
+template <typename T>
+class Callable::AnyFuncWrapper : public Callable {
+  public:
+    explicit AnyFuncWrapper(T func) : mFunc(std::move(func)) {}
+
+    void operator()() override { mFunc(); }
+
+  private:
+    T mFunc;
+};
+
+template <typename T>
+std::unique_ptr<Callable> Callable::from(T func) {
+    return std::make_unique<AnyFuncWrapper<T>>(std::move(func));
+}
+
+}  // namespace aidl::android::hardware::biometrics
\ No newline at end of file
diff --git a/biometrics/common/thread/include/thread/WorkerThread.h b/biometrics/common/thread/include/thread/WorkerThread.h
new file mode 100644
index 0000000..5f89a7f
--- /dev/null
+++ b/biometrics/common/thread/include/thread/WorkerThread.h
@@ -0,0 +1,79 @@
+/*
+ * 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 <mutex>
+#include <optional>
+#include <queue>
+#include <thread>
+
+#include "Callable.h"
+
+namespace aidl::android::hardware::biometrics {
+
+// A class that encapsulates a worker thread and a task queue, and provides a convenient interface
+// for a Session to schedule its tasks for asynchronous execution.
+class WorkerThread final {
+  public:
+    // Internally creates a queue that cannot exceed maxQueueSize elements and a new thread that
+    // polls the queue for tasks until this instance is destructed.
+    explicit WorkerThread(size_t maxQueueSize);
+
+    // Unblocks the internal queue and calls join on the internal thread allowing it to gracefully
+    // exit.
+    ~WorkerThread();
+
+    // Disallow copying this class.
+    WorkerThread(const WorkerThread&) = delete;
+    WorkerThread& operator=(const WorkerThread&) = delete;
+
+    // Also disable moving this class to simplify implementation.
+    WorkerThread(WorkerThread&&) = delete;
+    WorkerThread& operator=(WorkerThread&&) = delete;
+
+    // If the internal queue is not full, pushes a task at the end of the queue and returns true.
+    // Otherwise, returns false. If the queue is busy, blocks until it becomes available.
+    // This method expects heap-allocated tasks because it's the simplest way to represent function
+    // objects of any type. Stack-allocated std::function could be used instead, but it cannot
+    // represent functions with move-only captures because std::function is inherently copyable.
+    // Not being able to pass move-only lambdas is a major limitation for the HAL implementation,
+    // so heap-allocated tasks that share a common interface (Callable) were chosen instead.
+    bool schedule(std::unique_ptr<Callable> task);
+
+  private:
+    // The function that runs on the internal thread. Sequentially runs the available tasks from
+    // the queue. If the queue is empty, waits until a new task is added. If the worker is being
+    // destructed, finishes its current task and gracefully exits.
+    void threadFunc();
+
+    // The maximum size that the queue is allowed to expand to.
+    size_t mMaxSize;
+
+    // Whether the destructor was called. If true, tells threadFunc to exit as soon as possible, and
+    // tells schedule to avoid doing any work.
+    std::atomic<bool> mIsDestructing;
+
+    // Queue that's guarded by mQueueMutex and mQueueCond.
+    std::deque<std::unique_ptr<Callable>> mQueue;
+    std::mutex mQueueMutex;
+    std::condition_variable mQueueCond;
+
+    // The internal thread that works on the tasks from the queue.
+    std::thread mThread;
+};
+
+}  // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/common/thread/tests/WorkerThreadTest.cpp b/biometrics/common/thread/tests/WorkerThreadTest.cpp
new file mode 100644
index 0000000..5bb9e7e
--- /dev/null
+++ b/biometrics/common/thread/tests/WorkerThreadTest.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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 <algorithm>
+#include <chrono>
+#include <future>
+#include <thread>
+
+#include <gtest/gtest.h>
+
+#include "thread/WorkerThread.h"
+
+namespace {
+
+using namespace aidl::android::hardware::biometrics;
+using namespace std::chrono_literals;
+
+TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) {
+    WorkerThread worker(1 /*maxQueueSize*/);
+    for (int i = 0; i < 100; ++i) {
+        std::promise<void> promise;
+        auto future = promise.get_future();
+
+        ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
+            // Notify that the task has started.
+            promise.set_value();
+        })));
+
+        future.wait();
+    }
+}
+
+TEST(WorkerThreadTest, ScheduleReturnsFalseWhenQueueIsFull) {
+    WorkerThread worker(2 /*maxQueueSize*/);
+
+    std::promise<void> promise;
+    auto future = promise.get_future();
+
+    // Schedule a long-running task.
+    ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
+        // Notify that the task has started.
+        promise.set_value();
+        // Block for a "very long" time.
+        std::this_thread::sleep_for(1s);
+    })));
+
+    // Make sure the long-running task began executing.
+    future.wait();
+
+    // The first task is already being worked on, which means the queue must be empty.
+    // Fill the worker's queue to the maximum.
+    ASSERT_TRUE(worker.schedule(Callable::from([] {})));
+    ASSERT_TRUE(worker.schedule(Callable::from([] {})));
+
+    EXPECT_FALSE(worker.schedule(Callable::from([] {})));
+}
+
+TEST(WorkerThreadTest, TasksExecuteInOrder) {
+    constexpr int NUM_TASKS = 10000;
+    WorkerThread worker(NUM_TASKS + 1);
+
+    std::mutex mut;
+    std::condition_variable cv;
+    bool finished = false;
+    std::vector<int> results;
+
+    for (int i = 0; i < NUM_TASKS; ++i) {
+        worker.schedule(Callable::from([&mut, &results, i] {
+            // Delay tasks differently to provoke races.
+            std::this_thread::sleep_for(std::chrono::nanoseconds(100 - i % 100));
+            auto lock = std::lock_guard(mut);
+            results.push_back(i);
+        }));
+    }
+
+    // Schedule a special task to signal when all of the tasks are finished.
+    worker.schedule(Callable::from([&mut, &cv, &finished] {
+        auto lock = std::lock_guard(mut);
+        finished = true;
+        cv.notify_one();
+    }));
+
+    auto lock = std::unique_lock(mut);
+    cv.wait(lock, [&finished] { return finished; });
+    ASSERT_EQ(results.size(), NUM_TASKS);
+    EXPECT_TRUE(std::is_sorted(results.begin(), results.end()));
+}
+
+TEST(WorkerThreadTest, ExecutionStopsAfterWorkerIsDestroyed) {
+    std::promise<void> promise1;
+    std::promise<void> promise2;
+    auto future1 = promise1.get_future();
+    auto future2 = promise2.get_future();
+    std::atomic<bool> value;
+
+    // Local scope for the worker to test its destructor when it goes out of scope.
+    {
+        WorkerThread worker(2 /*maxQueueSize*/);
+
+        ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise1)]() mutable {
+            promise.set_value();
+            std::this_thread::sleep_for(200ms);
+        })));
+
+        // The first task should start executing.
+        future1.wait();
+
+        // The second task should schedule successfully.
+        ASSERT_TRUE(
+                worker.schedule(Callable::from([promise = std::move(promise2), &value]() mutable {
+                    // The worker should destruct before it gets a chance to execute this.
+                    value = true;
+                    promise.set_value();
+                })));
+    }
+
+    // The second task should never execute.
+    future2.wait();
+    // The future is expected to be ready but contain an exception.
+    // Cannot use ASSERT_THROW because exceptions are disabled in this codebase.
+    // ASSERT_THROW(future2.get(), std::future_error);
+    EXPECT_FALSE(value);
+}
+
+}  // namespace
diff --git a/biometrics/common/util/Android.bp b/biometrics/common/util/Android.bp
new file mode 100644
index 0000000..b990812
--- /dev/null
+++ b/biometrics/common/util/Android.bp
@@ -0,0 +1,18 @@
+cc_library {
+    // 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
+    name: "android.hardware.biometrics.common.util",
+    export_include_dirs: ["include"],
+    vendor: true,
+    srcs: [
+        "CancellationSignal.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+    ],
+}
diff --git a/biometrics/common/util/CancellationSignal.cpp b/biometrics/common/util/CancellationSignal.cpp
new file mode 100644
index 0000000..7888838
--- /dev/null
+++ b/biometrics/common/util/CancellationSignal.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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 "util/CancellationSignal.h"
+
+#include <android-base/logging.h>
+#include <chrono>
+
+namespace aidl::android::hardware::biometrics {
+
+CancellationSignal::CancellationSignal(std::promise<void>&& cancellationPromise)
+    : mCancellationPromise(std::move(cancellationPromise)) {}
+
+ndk::ScopedAStatus CancellationSignal::cancel() {
+    mCancellationPromise.set_value();
+    return ndk::ScopedAStatus::ok();
+}
+
+bool shouldCancel(const std::future<void>& f) {
+    CHECK(f.valid());
+    return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
+}
+
+}  // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/common/util/include/util/CancellationSignal.h b/biometrics/common/util/include/util/CancellationSignal.h
new file mode 100644
index 0000000..be77e29
--- /dev/null
+++ b/biometrics/common/util/include/util/CancellationSignal.h
@@ -0,0 +1,39 @@
+/*
+ * 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/biometrics/common/BnCancellationSignal.h>
+#include <functional>
+#include <future>
+
+namespace aidl::android::hardware::biometrics {
+
+class CancellationSignal : public common::BnCancellationSignal {
+  public:
+    explicit CancellationSignal(std::promise<void>&& cancellationPromise);
+
+    ndk::ScopedAStatus cancel() override;
+
+  private:
+    std::promise<void> mCancellationPromise;
+};
+
+// Returns whether the given cancellation future is ready, i.e. whether the operation corresponding
+// to this future should be cancelled.
+bool shouldCancel(const std::future<void>& cancellationFuture);
+
+}  // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/common/util/include/util/Util.h b/biometrics/common/util/include/util/Util.h
new file mode 100644
index 0000000..da19dc6
--- /dev/null
+++ b/biometrics/common/util/include/util/Util.h
@@ -0,0 +1,69 @@
+/*
+ * 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-base/logging.h>
+
+#include <chrono>
+#include <regex>
+#include <thread>
+#include <vector>
+
+namespace aidl::android::hardware::biometrics {
+
+#define SLEEP_MS(x) \
+    if (x > 0) std::this_thread::sleep_for(std::chrono::milliseconds(x))
+#define BEGIN_OP(x)            \
+    do {                       \
+        LOG(INFO) << __func__; \
+        SLEEP_MS(x);           \
+    } while (0)
+#define IS_TRUE(x) ((x == "1") || (x == "true"))
+
+// This is for non-test situations, such as casual cuttlefish users, that don't
+// set an explicit value.
+// Some operations (i.e. enroll, authenticate) will be executed in tight loops
+// by parts of the UI or fail if there is no latency. For example, the
+// Face settings page constantly runs auth and the enrollment UI uses a
+// cancel/restart cycle that requires some latency while the activities change.
+#define DEFAULT_LATENCY 400
+
+class Util {
+  public:
+    static int64_t getSystemNanoTime() {
+        timespec now;
+        clock_gettime(CLOCK_MONOTONIC, &now);
+        return now.tv_sec * 1000000000LL + now.tv_nsec;
+    }
+
+    static bool hasElapsed(int64_t start, int64_t durationMillis) {
+        auto now = getSystemNanoTime();
+        if (now < start) return true;
+        if (durationMillis <= 0) return true;
+        return ((now - start) / 1000000LL) > durationMillis;
+    }
+
+    static std::vector<std::string> split(const std::string& str, const std::string& sep) {
+        std::regex regex(sep);
+        std::vector<std::string> parts(
+                std::sregex_token_iterator(str.begin(), str.end(), regex, -1),
+                std::sregex_token_iterator());
+        return parts;
+    }
+};
+
+}  // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/face/1.0/vts/functional/OWNERS b/biometrics/face/1.0/vts/functional/OWNERS
deleted file mode 100644
index 7651b69..0000000
--- a/biometrics/face/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 432605
-ilyamaty@google.com
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
index 0bec0c5..79df9c6 100644
--- a/biometrics/face/aidl/Android.bp
+++ b/biometrics/face/aidl/Android.bp
@@ -14,9 +14,9 @@
         "android/hardware/biometrics/face/**/*.aidl",
     ],
     imports: [
-        "android.hardware.biometrics.common",
+        "android.hardware.biometrics.common-V3",
         "android.hardware.common-V2",
-        "android.hardware.keymaster-V3",
+        "android.hardware.keymaster-V4",
     ],
     stability: "vintf",
     backend: {
@@ -44,7 +44,16 @@
                 "android.hardware.keymaster-V3",
             ],
         },
+        {
+            version: "3",
+            imports: [
+                "android.hardware.biometrics.common-V3",
+                "android.hardware.common-V2",
+                "android.hardware.keymaster-V4",
+            ],
+        },
 
     ],
+    frozen: true,
 
 }
diff --git a/biometrics/face/aidl/OWNERS b/biometrics/face/aidl/OWNERS
deleted file mode 100644
index 36d7261..0000000
--- a/biometrics/face/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-ilyamaty@google.com
-kchyn@google.com
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/.hash b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/.hash
new file mode 100644
index 0000000..3b42823
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/.hash
@@ -0,0 +1 @@
+fca1ab84dda6c013b251270d848eb6d964a6d765
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/AcquiredInfo.aidl
new file mode 100644
index 0000000..5312ca1
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -0,0 +1,64 @@
+/*
+ * 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.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum AcquiredInfo {
+  UNKNOWN,
+  GOOD,
+  INSUFFICIENT,
+  TOO_BRIGHT,
+  TOO_DARK,
+  TOO_CLOSE,
+  TOO_FAR,
+  FACE_TOO_HIGH,
+  FACE_TOO_LOW,
+  FACE_TOO_RIGHT,
+  FACE_TOO_LEFT,
+  POOR_GAZE,
+  NOT_DETECTED,
+  TOO_MUCH_MOTION,
+  RECALIBRATE,
+  TOO_DIFFERENT,
+  TOO_SIMILAR,
+  PAN_TOO_EXTREME,
+  TILT_TOO_EXTREME,
+  ROLL_TOO_EXTREME,
+  FACE_OBSCURED,
+  START,
+  SENSOR_DIRTY,
+  VENDOR,
+  FIRST_FRAME_RECEIVED,
+  DARK_GLASSES_DETECTED,
+  MOUTH_COVERING_DETECTED,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/AuthenticationFrame.aidl
new file mode 100644
index 0000000..20bc767
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.biometrics.face;
+@VintfStability
+parcelable AuthenticationFrame {
+  android.hardware.biometrics.face.BaseFrame data;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/BaseFrame.aidl
new file mode 100644
index 0000000..67b5cf4
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/BaseFrame.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.biometrics.face;
+@VintfStability
+parcelable BaseFrame {
+  android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.UNKNOWN;
+  int vendorCode;
+  float pan;
+  float tilt;
+  float distance;
+  boolean isCancellable;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/Cell.aidl
new file mode 100644
index 0000000..6be8c8e
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/Cell.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.biometrics.face;
+@VintfStability
+parcelable Cell {
+  int x;
+  int y;
+  int z;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentFrame.aidl
new file mode 100644
index 0000000..0ea10d6
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.biometrics.face;
+@VintfStability
+parcelable EnrollmentFrame {
+  @nullable android.hardware.biometrics.face.Cell cell;
+  android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
+  android.hardware.biometrics.face.BaseFrame data;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentStage.aidl
new file mode 100644
index 0000000..a203dbe
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum EnrollmentStage {
+  UNKNOWN,
+  FIRST_FRAME_RECEIVED,
+  WAITING_FOR_CENTERING,
+  HOLD_STILL_IN_CENTER,
+  ENROLLING_MOVEMENT_1,
+  ENROLLING_MOVEMENT_2,
+  ENROLLMENT_FINISHED,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
new file mode 100644
index 0000000..48db2cf
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.biometrics.face;
+@VintfStability
+parcelable EnrollmentStageConfig {
+  android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
+  List<android.hardware.biometrics.face.Cell> cells;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentType.aidl
new file mode 100644
index 0000000..da1e8a3
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum EnrollmentType {
+  DEFAULT,
+  ACCESSIBILITY,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/Error.aidl
new file mode 100644
index 0000000..28eb420
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/Error.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum Error {
+  UNKNOWN,
+  HW_UNAVAILABLE,
+  UNABLE_TO_PROCESS,
+  TIMEOUT,
+  NO_SPACE,
+  CANCELED,
+  UNABLE_TO_REMOVE,
+  VENDOR,
+  REENROLL_REQUIRED,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/FaceSensorType.aidl
new file mode 100644
index 0000000..bf1677c
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum FaceSensorType {
+  UNKNOWN,
+  RGB,
+  IR,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/Feature.aidl
new file mode 100644
index 0000000..924e6af
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/Feature.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum Feature {
+  REQUIRE_ATTENTION,
+  REQUIRE_DIVERSE_POSES,
+  DEBUG,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/IFace.aidl
new file mode 100644
index 0000000..fc4a4d0
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/IFace.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.biometrics.face;
+@VintfStability
+interface IFace {
+  android.hardware.biometrics.face.SensorProps[] getSensorProps();
+  android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb);
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/ISession.aidl
new file mode 100644
index 0000000..3665534
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/ISession.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.biometrics.face;
+@VintfStability
+interface ISession {
+  void generateChallenge();
+  void revokeChallenge(in long challenge);
+  android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType);
+  android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface);
+  android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId);
+  android.hardware.biometrics.common.ICancellationSignal detectInteraction();
+  void enumerateEnrollments();
+  void removeEnrollments(in int[] enrollmentIds);
+  void getFeatures();
+  void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.Feature feature, boolean enabled);
+  void getAuthenticatorId();
+  void invalidateAuthenticatorId();
+  void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat);
+  void close();
+  android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context);
+  android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface, in android.hardware.biometrics.common.OperationContext context);
+  android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context);
+  void onContextChanged(in android.hardware.biometrics.common.OperationContext context);
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/ISessionCallback.aidl
new file mode 100644
index 0000000..bbace29
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.biometrics.face;
+@VintfStability
+interface ISessionCallback {
+  void onChallengeGenerated(in long challenge);
+  void onChallengeRevoked(in long challenge);
+  void onAuthenticationFrame(in android.hardware.biometrics.face.AuthenticationFrame frame);
+  void onEnrollmentFrame(in android.hardware.biometrics.face.EnrollmentFrame frame);
+  void onError(in android.hardware.biometrics.face.Error error, in int vendorCode);
+  void onEnrollmentProgress(in int enrollmentId, int remaining);
+  void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
+  void onAuthenticationFailed();
+  void onLockoutTimed(in long durationMillis);
+  void onLockoutPermanent();
+  void onLockoutCleared();
+  void onInteractionDetected();
+  void onEnrollmentsEnumerated(in int[] enrollmentIds);
+  void onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features);
+  void onFeatureSet(android.hardware.biometrics.face.Feature feature);
+  void onEnrollmentsRemoved(in int[] enrollmentIds);
+  void onAuthenticatorIdRetrieved(in long authenticatorId);
+  void onAuthenticatorIdInvalidated(in long newAuthenticatorId);
+  void onSessionClosed();
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/SensorProps.aidl
new file mode 100644
index 0000000..8b3c51b
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/3/android/hardware/biometrics/face/SensorProps.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.biometrics.face;
+@VintfStability
+parcelable SensorProps {
+  android.hardware.biometrics.common.CommonProps commonProps;
+  android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.UNKNOWN;
+  boolean halControlsPreview;
+  int previewDisplayId;
+  int enrollPreviewWidth;
+  int enrollPreviewHeight;
+  float enrollTranslationX;
+  float enrollTranslationY;
+  float enrollPreviewScale;
+  boolean supportsDetectInteraction;
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index a92b366..2be76cb 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -178,6 +178,8 @@
      *   2) A face is rejected, and ISessionCallback#onAuthenticationFailed is invoked.
      *   3) Any non-recoverable error occurs (such as lockout). See the full list of
      *      authentication-specific errors in the Error enum.
+     *   4) ISessionCallback#onLockoutPermanent is invoked.
+     *   5) ISessionCallback#onLockoutTimed is invoked.
      *
      * Note that upon successful authentication, the lockout counter for this (sensorId, userId)
      * pair must be cleared.
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
index b3c348d..9eb575c 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -119,6 +119,8 @@
      * lockout, and authentication can be restarted after a period of time. See
      * ISession#resetLockout.
      *
+     * This ends the authentication lifecycle.
+     *
      * @param sensorId Sensor for which the user is locked out.
      * @param userId User for which the sensor is locked out.
      * @param durationMillis Remaining duration of the lockout.
@@ -131,6 +133,8 @@
      * Authentication is disabled until the user unlocks with their device credential
      * (PIN/Pattern/Password). See ISession#resetLockout.
      *
+     * This ends the authentication lifecycle.
+     *
      * @param sensorId Sensor for which the user is locked out.
      * @param userId User for which the sensor is locked out.
      */
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index 7f66eca..876a91f 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -16,12 +16,45 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.biometrics.face-V2-ndk",
-        "android.hardware.biometrics.common-V2-ndk",
+        "android.hardware.biometrics.face-V3-ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+        "android.hardware.biometrics.common.thread",
+        "android.hardware.biometrics.common.util",
     ],
     srcs: [
         "main.cpp",
         "Face.cpp",
+        "FakeFaceEngine.cpp",
         "Session.cpp",
     ],
+    static_libs: ["libandroid.hardware.biometrics.face.VirtualProps"],
+}
+
+sysprop_library {
+    name: "android.hardware.biometrics.face.VirtualProps",
+    srcs: ["face.sysprop"],
+    property_owner: "Vendor",
+    vendor: true,
+}
+
+cc_test {
+    name: "android.hardware.biometrics.face.FakeFaceEngineTest",
+    srcs: [
+        "tests/FakeFaceEngineTest.cpp",
+        "FakeFaceEngine.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "libandroid.hardware.biometrics.face.VirtualProps",
+        "android.hardware.biometrics.face-V3-ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+        "android.hardware.keymaster-V4-ndk",
+        "android.hardware.biometrics.common.util",
+    ],
+    vendor: true,
+    test_suites: ["general-tests"],
+    require_root: true,
 }
diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp
index aca3e13..652a7e1 100644
--- a/biometrics/face/aidl/default/Face.cpp
+++ b/biometrics/face/aidl/default/Face.cpp
@@ -17,12 +17,14 @@
 #include "Face.h"
 #include "Session.h"
 
+#include "FakeFaceEngine.h"
+
 namespace aidl::android::hardware::biometrics::face {
 
 const int kSensorId = 4;
-const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG;
+const common::SensorStrength kSensorStrength = FakeFaceEngine::GetSensorStrength();
 const int kMaxEnrollmentsPerUser = 5;
-const FaceSensorType kSensorType = FaceSensorType::RGB;
+const FaceSensorType kSensorType = FakeFaceEngine::GetSensorType();
 const bool kHalControlsPreview = true;
 const std::string kHwComponentId = "faceSensor";
 const std::string kHardwareVersion = "vendor/model/revision";
@@ -69,7 +71,7 @@
 ndk::ScopedAStatus Face::createSession(int32_t /*sensorId*/, int32_t /*userId*/,
                                        const std::shared_ptr<ISessionCallback>& cb,
                                        std::shared_ptr<ISession>* return_val) {
-    *return_val = SharedRefBase::make<Session>(cb);
+    *return_val = SharedRefBase::make<Session>(std::make_unique<FakeFaceEngine>(), cb);
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/biometrics/face/aidl/default/FakeFaceEngine.cpp b/biometrics/face/aidl/default/FakeFaceEngine.cpp
new file mode 100644
index 0000000..0f088f4
--- /dev/null
+++ b/biometrics/face/aidl/default/FakeFaceEngine.cpp
@@ -0,0 +1,318 @@
+#include "FakeFaceEngine.h"
+
+#include <android-base/logging.h>
+
+#include <face.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+using namespace ::android::face::virt;
+
+namespace aidl::android::hardware::biometrics::face {
+
+FaceSensorType FakeFaceEngine::GetSensorType() {
+    std::string type = FaceHalProperties::type().value_or("");
+    if (type == "IR") {
+        return FaceSensorType::IR;
+    } else {
+        FaceHalProperties::type("RGB");
+        return FaceSensorType::RGB;
+    }
+}
+
+common::SensorStrength FakeFaceEngine::GetSensorStrength() {
+    std::string strength = FaceHalProperties::strength().value_or("");
+    if (strength == "convenience") {
+        return common::SensorStrength::CONVENIENCE;
+    } else if (strength == "weak") {
+        return common::SensorStrength::WEAK;
+    } else {
+        FaceHalProperties::strength("strong");
+        return common::SensorStrength::STRONG;
+    }
+}
+
+void FakeFaceEngine::generateChallengeImpl(ISessionCallback* cb) {
+    BEGIN_OP(0);
+    std::uniform_int_distribution<int64_t> dist;
+    auto challenge = dist(mRandom);
+    FaceHalProperties::challenge(challenge);
+    cb->onChallengeGenerated(challenge);
+}
+
+void FakeFaceEngine::revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
+    BEGIN_OP(0);
+    FaceHalProperties::challenge({});
+    cb->onChallengeRevoked(challenge);
+}
+void FakeFaceEngine::getEnrollmentConfigImpl(ISessionCallback* /*cb*/,
+                                             std::vector<EnrollmentStageConfig>* /*return_val*/) {}
+void FakeFaceEngine::enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+                                EnrollmentType /*enrollmentType*/,
+                                const std::vector<Feature>& /*features*/,
+                                const std::future<void>& cancel) {
+    BEGIN_OP(FaceHalProperties::operation_start_enroll_latency().value_or(0));
+    // format is "<id>,<bucket_id>:<delay>:<succeeds>,<bucket_id>:<delay>:<succeeds>...
+    auto nextEnroll = FaceHalProperties::next_enrollment().value_or("");
+    // Erase the next enrollment
+    FaceHalProperties::next_enrollment({});
+
+    AuthenticationFrame frame;
+    frame.data.acquiredInfo = AcquiredInfo::START;
+    frame.data.vendorCode = 0;
+    cb->onAuthenticationFrame(frame);
+
+    // Do proper HAT verification in the real implementation.
+    if (hat.mac.empty()) {
+        LOG(ERROR) << "Fail: hat";
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+
+    if (FaceHalProperties::operation_enroll_fails().value_or(false)) {
+        LOG(ERROR) << "Fail: operation_enroll_fails";
+        cb->onError(Error::VENDOR, 0 /* vendorError */);
+        return;
+    }
+
+    auto parts = Util::split(nextEnroll, ",");
+    if (parts.size() < 2) {
+        LOG(ERROR) << "Fail: invalid next_enrollment for : " << nextEnroll;
+        cb->onError(Error::VENDOR, 0 /* vendorError */);
+        return;
+    }
+
+    auto enrollmentId = std::stoi(parts[0]);
+    const int numBuckets = parts.size() - 1;
+    for (size_t i = 1; i < parts.size(); i++) {
+        auto enrollHit = Util::split(parts[i], ":");
+        if (enrollHit.size() != 3) {
+            LOG(ERROR) << "Error when unpacking enrollment hit: " << parts[i];
+            cb->onError(Error::VENDOR, 0 /* vendorError */);
+        }
+        std::string bucket = enrollHit[0];
+        std::string delay = enrollHit[1];
+        std::string succeeds = enrollHit[2];
+
+        SLEEP_MS(std::stoi(delay));
+
+        if (shouldCancel(cancel)) {
+            LOG(ERROR) << "Fail: cancel";
+            cb->onError(Error::CANCELED, 0 /* vendorCode */);
+            return;
+        }
+
+        if (!IS_TRUE(succeeds)) {  // end and failed
+            LOG(ERROR) << "Fail: requested by caller: " << parts[i];
+            cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
+            return;
+        }
+
+        EnrollmentFrame frame;
+
+        frame.data.acquiredInfo = AcquiredInfo::GOOD;
+        frame.data.vendorCode = 0;
+        cb->onEnrollmentFrame(frame);
+
+        frame.data.acquiredInfo = AcquiredInfo::VENDOR;
+        frame.data.vendorCode = std::stoi(bucket);
+        cb->onEnrollmentFrame(frame);
+
+        int remainingBuckets = numBuckets - i;
+        if (remainingBuckets > 0) {
+            cb->onEnrollmentProgress(enrollmentId, remainingBuckets);
+        }
+    }
+
+    auto enrollments = FaceHalProperties::enrollments();
+    enrollments.push_back(enrollmentId);
+    FaceHalProperties::enrollments(enrollments);
+    LOG(INFO) << "enrolled : " << enrollmentId;
+    cb->onEnrollmentProgress(enrollmentId, 0);
+}
+
+void FakeFaceEngine::authenticateImpl(ISessionCallback* cb, int64_t /*operationId*/,
+                                      const std::future<void>& cancel) {
+    BEGIN_OP(FaceHalProperties::operation_authenticate_latency().value_or(0));
+
+    // Signal to the framework that we have begun authenticating.
+    AuthenticationFrame frame;
+    frame.data.acquiredInfo = AcquiredInfo::START;
+    frame.data.vendorCode = 0;
+    cb->onAuthenticationFrame(frame);
+
+    // Also signal that we have opened the camera.
+    frame = {};
+    frame.data.acquiredInfo = AcquiredInfo::FIRST_FRAME_RECEIVED;
+    frame.data.vendorCode = 0;
+    cb->onAuthenticationFrame(frame);
+
+    auto now = Util::getSystemNanoTime();
+    int64_t duration = FaceHalProperties::operation_authenticate_duration().value_or(0);
+    if (duration > 0) {
+        do {
+            SLEEP_MS(5);
+        } while (!Util::hasElapsed(now, duration));
+    }
+
+    if (FaceHalProperties::operation_authenticate_fails().value_or(false)) {
+        LOG(ERROR) << "Fail: operation_authenticate_fails";
+        cb->onError(Error::VENDOR, 0 /* vendorError */);
+        return;
+    }
+
+    if (FaceHalProperties::lockout().value_or(false)) {
+        LOG(ERROR) << "Fail: lockout";
+        cb->onLockoutPermanent();
+        cb->onError(Error::HW_UNAVAILABLE, 0 /* vendorError */);
+        return;
+    }
+
+    if (shouldCancel(cancel)) {
+        LOG(ERROR) << "Fail: cancel";
+        cb->onError(Error::CANCELED, 0 /* vendorCode */);
+        return;
+    }
+
+    auto id = FaceHalProperties::enrollment_hit().value_or(0);
+    auto enrolls = FaceHalProperties::enrollments();
+    auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+    if (id < 0 || !isEnrolled) {
+        LOG(ERROR) << (isEnrolled ? "invalid enrollment hit" : "Fail: not enrolled");
+        cb->onAuthenticationFailed();
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+
+    cb->onAuthenticationSucceeded(id, {} /* hat */);
+}
+
+void FakeFaceEngine::detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel) {
+    BEGIN_OP(FaceHalProperties::operation_detect_interaction_latency().value_or(0));
+
+    if (FaceHalProperties::operation_detect_interaction_fails().value_or(false)) {
+        LOG(ERROR) << "Fail: operation_detect_interaction_fails";
+        cb->onError(Error::VENDOR, 0 /* vendorError */);
+        return;
+    }
+
+    if (shouldCancel(cancel)) {
+        LOG(ERROR) << "Fail: cancel";
+        cb->onError(Error::CANCELED, 0 /* vendorCode */);
+        return;
+    }
+
+    auto id = FaceHalProperties::enrollment_hit().value_or(0);
+    auto enrolls = FaceHalProperties::enrollments();
+    auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+    if (id <= 0 || !isEnrolled) {
+        LOG(ERROR) << "Fail: not enrolled";
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+
+    cb->onInteractionDetected();
+}
+
+void FakeFaceEngine::enumerateEnrollmentsImpl(ISessionCallback* cb) {
+    BEGIN_OP(0);
+    std::vector<int32_t> enrollments;
+    for (const auto& enrollmentId : FaceHalProperties::enrollments()) {
+        if (enrollmentId) {
+            enrollments.push_back(*enrollmentId);
+        }
+    }
+    cb->onEnrollmentsEnumerated(enrollments);
+}
+
+void FakeFaceEngine::removeEnrollmentsImpl(ISessionCallback* cb,
+                                           const std::vector<int32_t>& enrollmentIds) {
+    BEGIN_OP(0);
+
+    std::vector<std::optional<int32_t>> newEnrollments;
+    for (const auto& enrollment : FaceHalProperties::enrollments()) {
+        auto id = enrollment.value_or(0);
+        if (std::find(enrollmentIds.begin(), enrollmentIds.end(), id) == enrollmentIds.end()) {
+            newEnrollments.emplace_back(id);
+        }
+    }
+    FaceHalProperties::enrollments(newEnrollments);
+    cb->onEnrollmentsRemoved(enrollmentIds);
+}
+
+void FakeFaceEngine::getFeaturesImpl(ISessionCallback* cb) {
+    BEGIN_OP(0);
+
+    if (FaceHalProperties::enrollments().empty()) {
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
+        return;
+    }
+
+    std::vector<Feature> featuresToReturn = {};
+    for (const auto& feature : FaceHalProperties::features()) {
+        if (feature) {
+            featuresToReturn.push_back((Feature)(*feature));
+        }
+    }
+    cb->onFeaturesRetrieved(featuresToReturn);
+}
+
+void FakeFaceEngine::setFeatureImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+                                    Feature feature, bool enabled) {
+    BEGIN_OP(0);
+
+    if (FaceHalProperties::enrollments().empty()) {
+        LOG(ERROR) << "Unable to set feature, enrollments are empty";
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
+        return;
+    }
+
+    if (hat.mac.empty()) {
+        LOG(ERROR) << "Unable to set feature, invalid hat";
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
+        return;
+    }
+
+    auto features = FaceHalProperties::features();
+
+    auto itr = std::find_if(features.begin(), features.end(), [feature](const auto& theFeature) {
+        return *theFeature == (int)feature;
+    });
+
+    if (!enabled && (itr != features.end())) {
+        features.erase(itr);
+    } else if (enabled && (itr == features.end())) {
+        features.push_back((int)feature);
+    }
+
+    FaceHalProperties::features(features);
+    cb->onFeatureSet(feature);
+}
+
+void FakeFaceEngine::getAuthenticatorIdImpl(ISessionCallback* cb) {
+    BEGIN_OP(0);
+    // If this is a weak HAL return 0 per the spec.
+    if (GetSensorStrength() != common::SensorStrength::STRONG) {
+        cb->onAuthenticatorIdRetrieved(0);
+    } else {
+        cb->onAuthenticatorIdRetrieved(FaceHalProperties::authenticator_id().value_or(0));
+    }
+}
+
+void FakeFaceEngine::invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
+    BEGIN_OP(0);
+    int64_t authenticatorId = FaceHalProperties::authenticator_id().value_or(0);
+    int64_t newId = authenticatorId + 1;
+    FaceHalProperties::authenticator_id(newId);
+    cb->onAuthenticatorIdInvalidated(newId);
+}
+
+void FakeFaceEngine::resetLockoutImpl(ISessionCallback* cb,
+                                      const keymaster::HardwareAuthToken& /*hat*/) {
+    BEGIN_OP(0);
+    FaceHalProperties::lockout(false);
+    cb->onLockoutCleared();
+}
+
+}  // namespace aidl::android::hardware::biometrics::face
\ No newline at end of file
diff --git a/biometrics/face/aidl/default/FakeFaceEngine.h b/biometrics/face/aidl/default/FakeFaceEngine.h
new file mode 100644
index 0000000..edb54ce
--- /dev/null
+++ b/biometrics/face/aidl/default/FakeFaceEngine.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/biometrics/common/SensorStrength.h>
+#include <aidl/android/hardware/biometrics/face/BnSession.h>
+#include <aidl/android/hardware/biometrics/face/FaceSensorType.h>
+#include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
+
+#include <random>
+
+#include <future>
+#include <vector>
+
+namespace aidl::android::hardware::biometrics::face {
+
+namespace face = aidl::android::hardware::biometrics::face;
+namespace common = aidl::android::hardware::biometrics::common;
+namespace keymaster = aidl::android::hardware::keymaster;
+
+using aidl::android::hardware::common::NativeHandle;
+// A fake engine that is backed by system properties instead of hardware.
+class FakeFaceEngine {
+  public:
+    FakeFaceEngine() : mRandom(std::mt19937::default_seed) {}
+
+    static face::FaceSensorType GetSensorType();
+    static common::SensorStrength GetSensorStrength();
+    void generateChallengeImpl(ISessionCallback* cb);
+    void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge);
+    void getEnrollmentConfigImpl(ISessionCallback* cb,
+                                 std::vector<EnrollmentStageConfig>* return_val);
+    void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+                    EnrollmentType enrollmentType, const std::vector<Feature>& features,
+                    const std::future<void>& cancel);
+    void authenticateImpl(ISessionCallback* cb, int64_t operationId,
+                          const std::future<void>& cancel);
+    void detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel);
+    void enumerateEnrollmentsImpl(ISessionCallback* cb);
+    void removeEnrollmentsImpl(ISessionCallback* cb, const std::vector<int32_t>& enrollmentIds);
+    void getFeaturesImpl(ISessionCallback* cb);
+    void setFeatureImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+                        Feature feature, bool enabled);
+    void getAuthenticatorIdImpl(ISessionCallback* cb);
+    void invalidateAuthenticatorIdImpl(ISessionCallback* cb);
+    void resetLockoutImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/);
+
+    std::mt19937 mRandom;
+};
+
+}  // namespace aidl::android::hardware::biometrics::face
\ No newline at end of file
diff --git a/biometrics/face/aidl/default/README.md b/biometrics/face/aidl/default/README.md
new file mode 100644
index 0000000..1655973
--- /dev/null
+++ b/biometrics/face/aidl/default/README.md
@@ -0,0 +1,77 @@
+# Virtual Face HAL
+
+This is a virtual HAL implementation that is backed by system properties
+instead of actual hardware. It's intended for testing and UI development
+on debuggable builds to allow devices to masquerade as alternative device
+types and for emulators.
+
+## Device Selection
+
+You can either run the FakeFaceEngine on a [real device](#actual-device) or a [virtual device/cuttlefish](#getting-started-on-a-virtual-device-cuttlefish). This document should
+help you to get started on either one.
+
+After setting up a device, go ahead and try out [enrolling](#enrolling) & [authenticating](#authenticating)
+
+### Getting started on a Virtual Device (cuttlefish)
+
+
+Note, I'm running this via a cloudtop virtual device.
+
+1. Setup cuttlefish on cloudtop, See [this](https://g3doc.corp.google.com/company/teams/android/teampages/acloud/getting_started.md?cl=head) for more details.
+2. acloud create --local-image
+3. Enter in the shell command to disable hidl
+
+```shell
+$ adb root
+$ adb shell settings put secure com.android.server.biometrics.AuthService.hidlDisabled 1
+$ adb reboot
+```
+4. You should now be able to do fake enrollments and authentications (as seen down below)
+
+### Actual Device
+
+1. Modify your real devices make file (I.E. vendor/google/products/{YOUR_DEVICE}.mk)
+2. Ensure that there is no other face HAL that is being included by the device
+3. Add the following
+```
+PRODUCT_COPY_FILES += \
+    frameworks/native/data/etc/android.hardware.biometrics.face.xml:$(TARGET_COPY_OUT_PRODUCT)/etc/permissions/android.hardware.biometrics.face.xml
+
+PRODUCT_PACKAGES += \
+    android.hardware.biometrics.face-service.example \
+
+```
+4. Now build and flash m -j120 && flash
+5. Run the following commands
+
+```shell
+# This is a temporary workaround
+$ adb root
+$ adb shell setprop persist.vendor.face.virtual.type RGB
+$ adb shell setprop persist.vendor.face.virtual.strength strong
+$ adb shell locksettings set-pin 0000
+$ adb reboot
+```
+
+## Enrolling
+
+```shell
+# authenticar_id,bucket_id:duration:(true|false)....
+$ adb shell setprop vendor.face.virtual.next_enrollment 1,0:500:true,5:250:true,10:150:true,15:500:true
+$ adb shell am start -n com.android.settings/.biometrics.face.FaceEnrollIntroduction
+# If you would like to get rid of the enrollment, run the follwoing command
+$ adb shell setprop persist.vendor.face.virtual.enrollments \"\"
+```
+
+## Authenticating
+
+```shell
+# If enrollment hasn't been setup
+$ adb shell setprop persist.vendor.face.virtual.enrollments 1
+$ adb shell cmd face sync
+# After enrollment has been setup
+$ adb shell setprop vendor.face.virtual.operation_authenticate_duration 800
+$ adb shell setprop vendor.face.virtual.enrollment_hit 1
+# Power button press to simulate auth
+$ adb shell input keyevent 26
+```
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index 984a1a9..1188459 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -14,139 +14,135 @@
  * limitations under the License.
  */
 
-#include <aidl/android/hardware/biometrics/common/BnCancellationSignal.h>
 #include <android-base/logging.h>
 
 #include "Session.h"
 
 namespace aidl::android::hardware::biometrics::face {
 
-class CancellationSignal : public common::BnCancellationSignal {
-  private:
-    std::shared_ptr<ISessionCallback> cb_;
+constexpr size_t MAX_WORKER_QUEUE_SIZE = 5;
 
-  public:
-    explicit CancellationSignal(std::shared_ptr<ISessionCallback> cb) : cb_(std::move(cb)) {}
-
-    ndk::ScopedAStatus cancel() override {
-        cb_->onError(Error::CANCELED, 0 /* vendorCode */);
-        return ndk::ScopedAStatus::ok();
-    }
-};
-
-Session::Session(std::shared_ptr<ISessionCallback> cb)
-    : cb_(std::move(cb)), mRandom(std::mt19937::default_seed) {}
+Session::Session(std::unique_ptr<FakeFaceEngine> engine, std::shared_ptr<ISessionCallback> cb)
+    : mEngine(std::move(engine)), mCb(std::move(cb)), mRandom(std::mt19937::default_seed) {
+    mThread = std::make_unique<WorkerThread>(MAX_WORKER_QUEUE_SIZE);
+}
 
 ndk::ScopedAStatus Session::generateChallenge() {
     LOG(INFO) << "generateChallenge";
-    if (cb_) {
-        std::uniform_int_distribution<int64_t> dist;
-        auto challenge = dist(mRandom);
-        cb_->onChallengeGenerated(challenge);
-    }
+    mThread->schedule(Callable::from([this] { mEngine->generateChallengeImpl(mCb.get()); }));
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) {
     LOG(INFO) << "revokeChallenge";
-    if (cb_) {
-        cb_->onChallengeRevoked(challenge);
-    }
+    mThread->schedule(Callable::from(
+            [this, challenge] { mEngine->revokeChallengeImpl(mCb.get(), challenge); }));
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Session::getEnrollmentConfig(EnrollmentType /*enrollmentType*/,
-                                                std::vector<EnrollmentStageConfig>* return_val) {
-    *return_val = {};
+ndk::ScopedAStatus Session::getEnrollmentConfig(
+        EnrollmentType /*enrollmentType*/, std::vector<EnrollmentStageConfig>* cancellationSignal) {
+    *cancellationSignal = {};
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::enroll(
-        const keymaster::HardwareAuthToken& /*hat*/, EnrollmentType /*enrollmentType*/,
-        const std::vector<Feature>& /*features*/,
-        const std::optional<NativeHandle>& /*previewSurface*/,
-        std::shared_ptr<biometrics::common::ICancellationSignal>* /*return_val*/) {
+        const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType,
+        const std::vector<Feature>& features, const std::optional<NativeHandle>& /*previewSurface*/,
+        std::shared_ptr<biometrics::common::ICancellationSignal>* cancellationSignal) {
     LOG(INFO) << "enroll";
-    if (cb_) {
-        cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
-    }
+    std::promise<void> cancellationPromise;
+    auto cancFuture = cancellationPromise.get_future();
+
+    mThread->schedule(Callable::from(
+            [this, hat, enrollmentType, features, cancFuture = std::move(cancFuture)] {
+                mEngine->enrollImpl(mCb.get(), hat, enrollmentType, features, cancFuture);
+            }));
+
+    *cancellationSignal = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Session::authenticate(int64_t /*keystoreOperationId*/,
-                                         std::shared_ptr<common::ICancellationSignal>* return_val) {
+ndk::ScopedAStatus Session::authenticate(
+        int64_t keystoreOperationId,
+        std::shared_ptr<common::ICancellationSignal>* cancellationSignal) {
     LOG(INFO) << "authenticate";
-    if (cb_) {
-        cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
-    }
-    *return_val = SharedRefBase::make<CancellationSignal>(cb_);
+    std::promise<void> cancellationPromise;
+    auto cancFuture = cancellationPromise.get_future();
+
+    mThread->schedule(
+            Callable::from([this, keystoreOperationId, cancFuture = std::move(cancFuture)] {
+                mEngine->authenticateImpl(mCb.get(), keystoreOperationId, cancFuture);
+            }));
+
+    *cancellationSignal = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::detectInteraction(
-        std::shared_ptr<common::ICancellationSignal>* /*return_val*/) {
+        std::shared_ptr<common::ICancellationSignal>* cancellationSignal) {
     LOG(INFO) << "detectInteraction";
+    std::promise<void> cancellationPromise;
+    auto cancFuture = cancellationPromise.get_future();
+
+    mThread->schedule(Callable::from([this, cancFuture = std::move(cancFuture)] {
+        mEngine->detectInteractionImpl(mCb.get(), cancFuture);
+    }));
+
+    *cancellationSignal = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::enumerateEnrollments() {
     LOG(INFO) << "enumerateEnrollments";
-    if (cb_) {
-        cb_->onEnrollmentsEnumerated(std::vector<int32_t>());
-    }
+    mThread->schedule(Callable::from([this] { mEngine->enumerateEnrollmentsImpl(mCb.get()); }));
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& /*enrollmentIds*/) {
+ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& enrollmentIds) {
     LOG(INFO) << "removeEnrollments";
-    if (cb_) {
-        cb_->onEnrollmentsRemoved(std::vector<int32_t>());
-    }
+    mThread->schedule(Callable::from(
+            [this, enrollmentIds] { mEngine->removeEnrollmentsImpl(mCb.get(), enrollmentIds); }));
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::getFeatures() {
     LOG(INFO) << "getFeatures";
-    if (cb_) {
-        // Must error out with UNABLE_TO_PROCESS when no faces are enrolled.
-        cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
-    }
+    mThread->schedule(Callable::from([this] { mEngine->getFeaturesImpl(mCb.get()); }));
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Session::setFeature(const keymaster::HardwareAuthToken& /*hat*/,
-                                       Feature /*feature*/, bool /*enabled*/) {
+ndk::ScopedAStatus Session::setFeature(const keymaster::HardwareAuthToken& hat, Feature feature,
+                                       bool enabled) {
     LOG(INFO) << "setFeature";
+    mThread->schedule(Callable::from([this, hat, feature, enabled] {
+        mEngine->setFeatureImpl(mCb.get(), hat, feature, enabled);
+    }));
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::getAuthenticatorId() {
     LOG(INFO) << "getAuthenticatorId";
-    if (cb_) {
-        cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */);
-    }
+    mThread->schedule(Callable::from([this] { mEngine->getAuthenticatorIdImpl(mCb.get()); }));
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::invalidateAuthenticatorId() {
     LOG(INFO) << "invalidateAuthenticatorId";
-    if (cb_) {
-        cb_->onAuthenticatorIdInvalidated(0);
-    }
+    mThread->schedule(
+            Callable::from([this] { mEngine->invalidateAuthenticatorIdImpl(mCb.get()); }));
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& /*hat*/) {
+ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& hat) {
     LOG(INFO) << "resetLockout";
-    if (cb_) {
-        cb_->onLockoutCleared();
-    }
+    mThread->schedule(Callable::from([this, hat] { mEngine->resetLockoutImpl(mCb.get(), hat); }));
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::close() {
-    if (cb_) {
-        cb_->onSessionClosed();
+    if (mCb) {
+        mCb->onSessionClosed();
     }
     return ndk::ScopedAStatus::ok();
 }
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index 9db17d2..7ca6a1f 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -21,6 +21,10 @@
 #include <aidl/android/hardware/biometrics/face/BnSession.h>
 #include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
 
+#include "FakeFaceEngine.h"
+#include "thread/WorkerThread.h"
+#include "util/CancellationSignal.h"
+
 namespace aidl::android::hardware::biometrics::face {
 
 namespace common = aidl::android::hardware::biometrics::common;
@@ -30,7 +34,7 @@
 
 class Session : public BnSession {
   public:
-    explicit Session(std::shared_ptr<ISessionCallback> cb);
+    explicit Session(std::unique_ptr<FakeFaceEngine> engine, std::shared_ptr<ISessionCallback> cb);
 
     ndk::ScopedAStatus generateChallenge() override;
 
@@ -85,8 +89,11 @@
     ndk::ScopedAStatus onContextChanged(const common::OperationContext& context) override;
 
   private:
-    std::shared_ptr<ISessionCallback> cb_;
+    std::unique_ptr<FakeFaceEngine> mEngine;
+    std::shared_ptr<ISessionCallback> mCb;
     std::mt19937 mRandom;
+    std::unique_ptr<WorkerThread> mThread;
+    std::shared_ptr<CancellationSignal> mCancellationSignal;
 };
 
 }  // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt b/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt
new file mode 100644
index 0000000..9548920
--- /dev/null
+++ b/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt
@@ -0,0 +1,98 @@
+props {
+  owner: Vendor
+  module: "android.face.virt.FaceHalProperties"
+  prop {
+    api_name: "authenticator_id"
+    type: Long
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.authenticator_id"
+  }
+  prop {
+    api_name: "challenge"
+    type: Long
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.challenge"
+  }
+  prop {
+    api_name: "enrollment_hit"
+    type: Integer
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.enrollment_hit"
+  }
+  prop {
+    api_name: "enrollments"
+    type: IntegerList
+    access: ReadWrite
+    prop_name: "persist.vendor.face.virtual.enrollments"
+  }
+  prop {
+    api_name: "features"
+    type: IntegerList
+    access: ReadWrite
+    prop_name: "persist.vendor.face.virtual.features"
+  }
+  prop {
+    api_name: "lockout"
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.lockout"
+  }
+  prop {
+    api_name: "next_enrollment"
+    type: String
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.next_enrollment"
+  }
+  prop {
+    api_name: "operation_authenticate_duration"
+    type: Integer
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.operation_authenticate_duration"
+  }
+  prop {
+    api_name: "operation_authenticate_fails"
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.operation_authenticate_fails"
+  }
+  prop {
+    api_name: "operation_authenticate_latency"
+    type: Integer
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.operation_authenticate_latency"
+  }
+  prop {
+    api_name: "operation_detect_interaction_fails"
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.operation_detect_interaction_fails"
+  }
+  prop {
+    api_name: "operation_detect_interaction_latency"
+    type: Integer
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.operation_detect_interaction_latency"
+  }
+  prop {
+    api_name: "operation_enroll_fails"
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.operation_enroll_fails"
+  }
+  prop {
+    api_name: "operation_start_enroll_latency"
+    type: Integer
+    access: ReadWrite
+    prop_name: "vendor.face.virtual.operation_start_enroll_latency"
+  }
+  prop {
+    api_name: "strength"
+    type: String
+    access: ReadWrite
+    prop_name: "persist.vendor.face.virtual.strength"
+    enum_values: "convenience|weak|strong"
+  }
+  prop {
+    api_name: "type"
+    type: String
+    access: ReadWrite
+    prop_name: "persist.vendor.face.virtual.type"
+    enum_values: "IR|RGB"
+  }
+}
diff --git a/biometrics/face/aidl/default/face-default.xml b/biometrics/face/aidl/default/face-default.xml
index e6ef842..8f2fbb8 100644
--- a/biometrics/face/aidl/default/face-default.xml
+++ b/biometrics/face/aidl/default/face-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.biometrics.face</name>
-        <version>2</version>
+        <version>3</version>
         <fqname>IFace/default</fqname>
     </hal>
 </manifest>
diff --git a/biometrics/face/aidl/default/face.sysprop b/biometrics/face/aidl/default/face.sysprop
new file mode 100644
index 0000000..6b0f37f
--- /dev/null
+++ b/biometrics/face/aidl/default/face.sysprop
@@ -0,0 +1,159 @@
+# face.sysprop
+# module becomes static class (Java) / namespace (C++) for serving API
+module: "android.face.virt.FaceHalProperties"
+owner: Vendor
+
+# type of face sensor
+prop {
+    prop_name: "persist.vendor.face.virtual.type"
+    type: String
+    scope: Public
+    access: ReadWrite
+    enum_values: "IR|RGB"
+    api_name: "type"
+}
+
+# the strength of the sensor
+prop {
+    prop_name: "persist.vendor.face.virtual.strength"
+    type: String
+    scope: Public
+    access: ReadWrite
+    enum_values: "convenience|weak|strong"
+    api_name: "strength"
+}
+
+# ids of current enrollments
+prop {
+    prop_name: "persist.vendor.face.virtual.enrollments"
+    type: IntegerList
+    scope: Public
+    access: ReadWrite
+    api_name: "enrollments"
+}
+
+# List of features
+prop {
+    prop_name: "persist.vendor.face.virtual.features"
+    type: IntegerList
+    scope: Public
+    access: ReadWrite
+    api_name: "features"
+}
+
+# authenticate and detectInteraction will succeed with this
+# enrollment id, when present, otherwise they will error
+prop {
+    prop_name: "vendor.face.virtual.enrollment_hit"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "enrollment_hit"
+}
+
+# The initial latency for enrollment
+prop {
+    prop_name: "vendor.face.virtual.operation_start_enroll_latency"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_start_enroll_latency"
+}
+
+# the next enrollment in the format:
+# "<id>,<bucket_id>:<delay>:<succeeds>,<bucket_id>..."
+# for example: "0:1,0:100:1,1:200:1" indicating that bucket 0 took
+# 50 milliseconds, bucket 1 took 100 milliseconds, bucket 2 took 200 milliseconds.
+# Note that it is up to the configuration to determine how many buckets are required
+# to complete an enrollment
+prop {
+    prop_name: "vendor.face.virtual.next_enrollment"
+    type: String
+    scope: Public
+    access: ReadWrite
+    api_name: "next_enrollment"
+}
+
+# value for getAuthenticatorId or 0
+prop {
+    prop_name: "vendor.face.virtual.authenticator_id"
+    type: Long
+    scope: Public
+    access: ReadWrite
+    api_name: "authenticator_id"
+}
+
+# value for generateChallenge
+prop {
+    prop_name: "vendor.face.virtual.challenge"
+    type: Long
+    scope: Public
+    access: ReadWrite
+    api_name: "challenge"
+}
+
+# if locked out
+prop {
+    prop_name: "vendor.face.virtual.lockout"
+    type: Boolean
+    scope: Public
+    access: ReadWrite
+    api_name: "lockout"
+}
+
+# force all authenticate operations to fail
+prop {
+    prop_name: "vendor.face.virtual.operation_authenticate_fails"
+    type: Boolean
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_authenticate_fails"
+}
+
+# force all detectInteraction operations to fail
+prop {
+    prop_name: "vendor.face.virtual.operation_detect_interaction_fails"
+    type: Boolean
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_detect_interaction_fails"
+}
+
+# force all enroll operations to fail
+prop {
+    prop_name: "vendor.face.virtual.operation_enroll_fails"
+    type: Boolean
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_enroll_fails"
+}
+
+# add a latency to authentication operations
+# Note that this latency is the initial authentication latency that occurs before
+# the HAL will send AcquiredInfo::START and AcquiredInfo::FIRST_FRAME_RECEIVED
+prop {
+    prop_name: "vendor.face.virtual.operation_authenticate_latency"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_authenticate_latency"
+}
+
+# add a latency to detectInteraction operations
+prop {
+    prop_name: "vendor.face.virtual.operation_detect_interaction_latency"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_detect_interaction_latency"
+}
+
+# millisecond duration for authenticate operations
+# (waits for changes to enrollment_hit)
+prop {
+    prop_name: "vendor.face.virtual.operation_authenticate_duration"
+    type: Integer
+    scope: Public
+    access: ReadWrite
+    api_name: "operation_authenticate_duration"
+}
diff --git a/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp b/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
new file mode 100644
index 0000000..c8ad6b7
--- /dev/null
+++ b/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_process.h>
+#include <face.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <aidl/android/hardware/biometrics/face/BnSessionCallback.h>
+#include <android-base/logging.h>
+
+#include "FakeFaceEngine.h"
+
+using namespace ::android::face::virt;
+using namespace ::aidl::android::hardware::biometrics::face;
+using namespace ::aidl::android::hardware::keymaster;
+
+namespace aidl::android::hardware::biometrics::face {
+
+class TestSessionCallback : public BnSessionCallback {
+  public:
+    ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override {
+        mLastChallenge = challenge;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override {
+        mLastChallengeRevoked = challenge;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onError(Error error, int32_t) override {
+        mError = error;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
+        if (remaining == 0) mLastEnrolled = enrollmentId;
+        return ndk::ScopedAStatus::ok();
+    };
+
+    ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t enrollmentId,
+                                                   const HardwareAuthToken&) override {
+        mLastAuthenticated = enrollmentId;
+        mAuthenticateFailed = false;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticationFailed() override {
+        mLastAuthenticated = 0;
+        mAuthenticateFailed = true;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onInteractionDetected() override {
+        mInteractionDetectedCount++;
+        return ndk::ScopedAStatus::ok();
+    };
+
+    ::ndk::ScopedAStatus onEnrollmentFrame(const EnrollmentFrame& frame) override {
+        mEnrollmentFrames.push_back(frame.data.vendorCode);
+        return ndk::ScopedAStatus::ok();
+    }
+
+    ::ndk::ScopedAStatus onEnrollmentsEnumerated(
+            const std::vector<int32_t>& enrollmentIds) override {
+        mLastEnrollmentsEnumerated = enrollmentIds;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onEnrollmentsRemoved(const std::vector<int32_t>& enrollmentIds) override {
+        mLastEnrollmentRemoved = enrollmentIds;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t authenticatorId) override {
+        mLastAuthenticatorId = authenticatorId;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t authenticatorId) override {
+        mLastAuthenticatorId = authenticatorId;
+        mAuthenticatorIdInvalidated = true;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticationFrame(const AuthenticationFrame& /*authFrame*/) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onLockoutPermanent() override {
+        mLockoutPermanent = true;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onLockoutCleared() override {
+        mLockoutPermanent = false;
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
+
+    ::ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>& features) override {
+        mFeatures = features;
+        return ndk::ScopedAStatus::ok();
+    }
+
+    ::ndk::ScopedAStatus onFeatureSet(Feature feature) override {
+        mLastFeatureSet = feature;
+        return ndk::ScopedAStatus::ok();
+    }
+
+    Error mError = Error::UNKNOWN;
+    int64_t mLastChallenge = -1;
+    int64_t mLastChallengeRevoked = -1;
+    int32_t mLastEnrolled = -1;
+    int32_t mLastAuthenticated = -1;
+    int64_t mLastAuthenticatorId = -1;
+    std::vector<int32_t> mLastEnrollmentsEnumerated;
+    std::vector<int32_t> mLastEnrollmentRemoved;
+    std::vector<Feature> mFeatures;
+    Feature mLastFeatureSet;
+    std::vector<int32_t> mEnrollmentFrames;
+    bool mAuthenticateFailed = false;
+    bool mAuthenticatorIdInvalidated = false;
+    bool mLockoutPermanent = false;
+    int mInteractionDetectedCount = 0;
+};
+
+class FakeFaceEngineTest : public ::testing::Test {
+  protected:
+    void SetUp() override {
+        LOG(ERROR) << "JRM SETUP";
+        mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
+        FaceHalProperties::enrollments({});
+        FaceHalProperties::challenge({});
+        FaceHalProperties::features({});
+        FaceHalProperties::authenticator_id({});
+        FaceHalProperties::strength("");
+    }
+
+    FakeFaceEngine mEngine;
+    std::shared_ptr<TestSessionCallback> mCallback;
+    std::promise<void> mCancel;
+};
+
+TEST_F(FakeFaceEngineTest, one_eq_one) {
+    ASSERT_EQ(1, 1);
+}
+
+TEST_F(FakeFaceEngineTest, GenerateChallenge) {
+    mEngine.generateChallengeImpl(mCallback.get());
+    ASSERT_EQ(FaceHalProperties::challenge().value(), mCallback->mLastChallenge);
+}
+
+TEST_F(FakeFaceEngineTest, RevokeChallenge) {
+    auto challenge = FaceHalProperties::challenge().value_or(10);
+    mEngine.revokeChallengeImpl(mCallback.get(), challenge);
+    ASSERT_FALSE(FaceHalProperties::challenge().has_value());
+    ASSERT_EQ(challenge, mCallback->mLastChallengeRevoked);
+}
+
+TEST_F(FakeFaceEngineTest, ResetLockout) {
+    FaceHalProperties::lockout(true);
+    mEngine.resetLockoutImpl(mCallback.get(), {});
+    ASSERT_FALSE(mCallback->mLockoutPermanent);
+    ASSERT_FALSE(FaceHalProperties::lockout().value_or(true));
+}
+
+TEST_F(FakeFaceEngineTest, AuthenticatorId) {
+    FaceHalProperties::authenticator_id(50);
+    mEngine.getAuthenticatorIdImpl(mCallback.get());
+    ASSERT_EQ(50, mCallback->mLastAuthenticatorId);
+    ASSERT_FALSE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFaceEngineTest, GetAuthenticatorIdWeakReturnsZero) {
+    FaceHalProperties::strength("weak");
+    FaceHalProperties::authenticator_id(500);
+    mEngine.getAuthenticatorIdImpl(mCallback.get());
+    ASSERT_EQ(0, mCallback->mLastAuthenticatorId);
+    ASSERT_FALSE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFaceEngineTest, AuthenticatorIdInvalidate) {
+    FaceHalProperties::authenticator_id(500);
+    mEngine.invalidateAuthenticatorIdImpl(mCallback.get());
+    ASSERT_NE(500, FaceHalProperties::authenticator_id().value());
+    ASSERT_TRUE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFaceEngineTest, Enroll) {
+    FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:true");
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
+                       mCancel.get_future());
+    ASSERT_FALSE(FaceHalProperties::next_enrollment().has_value());
+    ASSERT_EQ(1, FaceHalProperties::enrollments().size());
+    ASSERT_EQ(1, FaceHalProperties::enrollments()[0].value());
+    ASSERT_EQ(1, mCallback->mLastEnrolled);
+}
+
+TEST_F(FakeFaceEngineTest, EnrollFails) {
+    FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:false");
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
+                       mCancel.get_future());
+    ASSERT_FALSE(FaceHalProperties::next_enrollment().has_value());
+    ASSERT_EQ(0, FaceHalProperties::enrollments().size());
+}
+
+TEST_F(FakeFaceEngineTest, EnrollCancel) {
+    FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:false");
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mCancel.set_value();
+    mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
+                       mCancel.get_future());
+    ASSERT_EQ(Error::CANCELED, mCallback->mError);
+    ASSERT_EQ(-1, mCallback->mLastEnrolled);
+    ASSERT_EQ(0, FaceHalProperties::enrollments().size());
+    ASSERT_FALSE(FaceHalProperties::next_enrollment().has_value());
+}
+
+TEST_F(FakeFaceEngineTest, Authenticate) {
+    FaceHalProperties::enrollments({100});
+    FaceHalProperties::enrollment_hit(100);
+    mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, mCancel.get_future());
+
+    ASSERT_EQ(100, mCallback->mLastAuthenticated);
+    ASSERT_FALSE(mCallback->mAuthenticateFailed);
+}
+
+TEST_F(FakeFaceEngineTest, AuthenticateCancel) {
+    FaceHalProperties::enrollments({100});
+    FaceHalProperties::enrollment_hit(100);
+    mCancel.set_value();
+    mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, mCancel.get_future());
+    ASSERT_EQ(Error::CANCELED, mCallback->mError);
+}
+
+TEST_F(FakeFaceEngineTest, AuthenticateFailedForUnEnrolled) {
+    FaceHalProperties::enrollments({3});
+    FaceHalProperties::enrollment_hit(100);
+    mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, mCancel.get_future());
+    ASSERT_EQ(Error::UNABLE_TO_PROCESS, mCallback->mError);
+    ASSERT_TRUE(mCallback->mAuthenticateFailed);
+}
+
+TEST_F(FakeFaceEngineTest, DetectInteraction) {
+    FaceHalProperties::enrollments({100});
+    FaceHalProperties::enrollment_hit(100);
+    ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+}
+
+TEST_F(FakeFaceEngineTest, DetectInteractionCancel) {
+    FaceHalProperties::enrollments({100});
+    FaceHalProperties::enrollment_hit(100);
+    mCancel.set_value();
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(Error::CANCELED, mCallback->mError);
+}
+
+TEST_F(FakeFaceEngineTest, GetFeatureEmpty) {
+    mEngine.getFeaturesImpl(mCallback.get());
+    ASSERT_TRUE(mCallback->mFeatures.empty());
+}
+
+TEST_F(FakeFaceEngineTest, SetFeature) {
+    FaceHalProperties::enrollments({1});
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, true);
+    auto features = mCallback->mFeatures;
+    ASSERT_TRUE(features.empty());
+    ASSERT_EQ(Feature::REQUIRE_ATTENTION, mCallback->mLastFeatureSet);
+
+    mEngine.getFeaturesImpl(mCallback.get());
+    features = mCallback->mFeatures;
+    ASSERT_FALSE(features.empty());
+    ASSERT_NE(features.end(),
+              std::find(features.begin(), features.end(), Feature::REQUIRE_ATTENTION));
+}
+
+TEST_F(FakeFaceEngineTest, ToggleFeature) {
+    FaceHalProperties::enrollments({1});
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, true);
+    mEngine.getFeaturesImpl(mCallback.get());
+    auto features = mCallback->mFeatures;
+    ASSERT_FALSE(features.empty());
+    ASSERT_NE(features.end(),
+              std::find(features.begin(), features.end(), Feature::REQUIRE_ATTENTION));
+
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, false);
+    mEngine.getFeaturesImpl(mCallback.get());
+    features = mCallback->mFeatures;
+    ASSERT_TRUE(features.empty());
+}
+
+TEST_F(FakeFaceEngineTest, TurningOffNonExistentFeatureDoesNothing) {
+    FaceHalProperties::enrollments({1});
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, false);
+    mEngine.getFeaturesImpl(mCallback.get());
+    auto features = mCallback->mFeatures;
+    ASSERT_TRUE(features.empty());
+}
+
+TEST_F(FakeFaceEngineTest, SetMultipleFeatures) {
+    FaceHalProperties::enrollments({1});
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, true);
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_DIVERSE_POSES, true);
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::DEBUG, true);
+    mEngine.getFeaturesImpl(mCallback.get());
+    auto features = mCallback->mFeatures;
+    ASSERT_EQ(3, features.size());
+    ASSERT_NE(features.end(),
+              std::find(features.begin(), features.end(), Feature::REQUIRE_ATTENTION));
+    ASSERT_NE(features.end(),
+              std::find(features.begin(), features.end(), Feature::REQUIRE_DIVERSE_POSES));
+    ASSERT_NE(features.end(), std::find(features.begin(), features.end(), Feature::DEBUG));
+}
+
+TEST_F(FakeFaceEngineTest, SetMultipleFeaturesAndTurnOffSome) {
+    FaceHalProperties::enrollments({1});
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, true);
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_DIVERSE_POSES, true);
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::DEBUG, true);
+    mEngine.setFeatureImpl(mCallback.get(), hat, Feature::DEBUG, false);
+    mEngine.getFeaturesImpl(mCallback.get());
+    auto features = mCallback->mFeatures;
+    ASSERT_EQ(2, features.size());
+    ASSERT_NE(features.end(),
+              std::find(features.begin(), features.end(), Feature::REQUIRE_ATTENTION));
+    ASSERT_NE(features.end(),
+              std::find(features.begin(), features.end(), Feature::REQUIRE_DIVERSE_POSES));
+    ASSERT_EQ(features.end(), std::find(features.begin(), features.end(), Feature::DEBUG));
+}
+
+TEST_F(FakeFaceEngineTest, Enumerate) {
+    FaceHalProperties::enrollments({120, 3});
+    mEngine.enumerateEnrollmentsImpl(mCallback.get());
+    auto enrolls = mCallback->mLastEnrollmentsEnumerated;
+    ASSERT_FALSE(enrolls.empty());
+    ASSERT_NE(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 120));
+    ASSERT_NE(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 3));
+}
+
+TEST_F(FakeFaceEngineTest, RemoveEnrollments) {
+    FaceHalProperties::enrollments({120, 3, 100});
+    mEngine.removeEnrollmentsImpl(mCallback.get(), {120, 100});
+    mEngine.enumerateEnrollmentsImpl(mCallback.get());
+    auto enrolls = mCallback->mLastEnrollmentsEnumerated;
+    ASSERT_FALSE(enrolls.empty());
+    ASSERT_EQ(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 120));
+    ASSERT_NE(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 3));
+    ASSERT_EQ(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 100));
+}
+
+TEST_F(FakeFaceEngineTest, ResetLockoutWithAuth) {
+    FaceHalProperties::lockout(true);
+    FaceHalProperties::enrollments({33});
+    FaceHalProperties::enrollment_hit(33);
+    auto cancelFuture = mCancel.get_future();
+    mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, cancelFuture);
+
+    ASSERT_TRUE(mCallback->mLockoutPermanent);
+
+    mEngine.resetLockoutImpl(mCallback.get(), {} /* hat */);
+    ASSERT_FALSE(mCallback->mLockoutPermanent);
+    FaceHalProperties::enrollment_hit(33);
+    mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, cancelFuture);
+    ASSERT_EQ(33, mCallback->mLastAuthenticated);
+    ASSERT_FALSE(mCallback->mAuthenticateFailed);
+}
+
+}  // namespace aidl::android::hardware::biometrics::face
\ No newline at end of file
diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp
index 4171ac3..f62c4e4 100644
--- a/biometrics/face/aidl/vts/Android.bp
+++ b/biometrics/face/aidl/vts/Android.bp
@@ -15,10 +15,10 @@
     ],
     srcs: ["VtsHalBiometricsFaceTargetTest.cpp"],
     static_libs: [
-        "android.hardware.biometrics.common-V2-ndk",
-        "android.hardware.biometrics.face-V2-ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+        "android.hardware.biometrics.face-V3-ndk",
         "android.hardware.common-V2-ndk",
-        "android.hardware.keymaster-V3-ndk",
+        "android.hardware.keymaster-V4-ndk",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/biometrics/fingerprint/2.1/vts/functional/OWNERS b/biometrics/fingerprint/2.1/vts/functional/OWNERS
deleted file mode 100644
index 0014ce9..0000000
--- a/biometrics/fingerprint/2.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 114777
-ilyamaty@google.com
diff --git a/biometrics/fingerprint/2.2/vts/functional/OWNERS b/biometrics/fingerprint/2.2/vts/functional/OWNERS
deleted file mode 100644
index 0014ce9..0000000
--- a/biometrics/fingerprint/2.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 114777
-ilyamaty@google.com
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index 0bd6422..c543a93 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -14,8 +14,8 @@
         "android/hardware/biometrics/fingerprint/**/*.aidl",
     ],
     imports: [
-        "android.hardware.biometrics.common",
-        "android.hardware.keymaster-V3",
+        "android.hardware.biometrics.common-V3",
+        "android.hardware.keymaster-V4",
     ],
     stability: "vintf",
     backend: {
@@ -41,7 +41,14 @@
                 "android.hardware.keymaster-V3",
             ],
         },
+        {
+            version: "3",
+            imports: [
+                "android.hardware.biometrics.common-V3",
+                "android.hardware.keymaster-V4",
+            ],
+        },
 
     ],
-
+    frozen: true,
 }
diff --git a/biometrics/fingerprint/aidl/OWNERS b/biometrics/fingerprint/aidl/OWNERS
deleted file mode 100644
index 36d7261..0000000
--- a/biometrics/fingerprint/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-ilyamaty@google.com
-kchyn@google.com
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/.hash b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/.hash
new file mode 100644
index 0000000..34b605d
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/.hash
@@ -0,0 +1 @@
+637371b53fb7faf9bd43aa51b72c23852d6e6d96
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
new file mode 100644
index 0000000..7075f71
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.biometrics.fingerprint;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum AcquiredInfo {
+  UNKNOWN,
+  GOOD,
+  PARTIAL,
+  INSUFFICIENT,
+  SENSOR_DIRTY,
+  TOO_SLOW,
+  TOO_FAST,
+  VENDOR,
+  START,
+  TOO_DARK,
+  TOO_BRIGHT,
+  IMMOBILE,
+  RETRYING_CAPTURE,
+  LIFT_TOO_SOON,
+  POWER_PRESS,
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/Error.aidl
new file mode 100644
index 0000000..9eeaac5
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/Error.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.biometrics.fingerprint;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum Error {
+  UNKNOWN,
+  HW_UNAVAILABLE,
+  UNABLE_TO_PROCESS,
+  TIMEOUT,
+  NO_SPACE,
+  CANCELED,
+  UNABLE_TO_REMOVE,
+  VENDOR,
+  BAD_CALIBRATION,
+  POWER_PRESS,
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
new file mode 100644
index 0000000..381aaf7
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.fingerprint;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FingerprintSensorType {
+  UNKNOWN,
+  REAR,
+  UNDER_DISPLAY_ULTRASONIC,
+  UNDER_DISPLAY_OPTICAL,
+  POWER_BUTTON,
+  HOME_BUTTON,
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/IFingerprint.aidl
new file mode 100644
index 0000000..0b6f300
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+interface IFingerprint {
+  android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
+  android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb);
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/ISession.aidl
new file mode 100644
index 0000000..4fdcefc
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -0,0 +1,66 @@
+/*
+ * 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.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+interface ISession {
+  void generateChallenge();
+  void revokeChallenge(in long challenge);
+  android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat);
+  android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId);
+  android.hardware.biometrics.common.ICancellationSignal detectInteraction();
+  void enumerateEnrollments();
+  void removeEnrollments(in int[] enrollmentIds);
+  void getAuthenticatorId();
+  void invalidateAuthenticatorId();
+  void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat);
+  void close();
+  /**
+   * @deprecated use onPointerDownWithContext instead.
+   */
+  void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major);
+  /**
+   * @deprecated use onPointerUpWithContext instead.
+   */
+  void onPointerUp(in int pointerId);
+  void onUiReady();
+  android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context);
+  android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.common.OperationContext context);
+  android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context);
+  void onPointerDownWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
+  void onPointerUpWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
+  void onContextChanged(in android.hardware.biometrics.common.OperationContext context);
+  void onPointerCancelWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
+  void setIgnoreDisplayTouches(in boolean shouldIgnore);
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
new file mode 100644
index 0000000..be18ffe
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+interface ISessionCallback {
+  void onChallengeGenerated(in long challenge);
+  void onChallengeRevoked(in long challenge);
+  void onAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfo info, in int vendorCode);
+  void onError(in android.hardware.biometrics.fingerprint.Error error, in int vendorCode);
+  void onEnrollmentProgress(in int enrollmentId, int remaining);
+  void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
+  void onAuthenticationFailed();
+  void onLockoutTimed(in long durationMillis);
+  void onLockoutPermanent();
+  void onLockoutCleared();
+  void onInteractionDetected();
+  void onEnrollmentsEnumerated(in int[] enrollmentIds);
+  void onEnrollmentsRemoved(in int[] enrollmentIds);
+  void onAuthenticatorIdRetrieved(in long authenticatorId);
+  void onAuthenticatorIdInvalidated(in long newAuthenticatorId);
+  void onSessionClosed();
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/PointerContext.aidl
new file mode 100644
index 0000000..d9bf085
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/PointerContext.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.biometrics.fingerprint;
+/* @hide */
+@JavaDerive(equals=true) @VintfStability
+parcelable PointerContext {
+  int pointerId = (-1) /* -1 */;
+  float x = 0f;
+  float y = 0f;
+  float minor = 0f;
+  float major = 0f;
+  float orientation = 0f;
+  boolean isAod = false;
+  long time = 0;
+  long gestureStart = 0;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/SensorLocation.aidl
new file mode 100644
index 0000000..965576e
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/SensorLocation.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+parcelable SensorLocation {
+  /**
+   * @deprecated use the display field instead. This field was never used.
+   */
+  int displayId;
+  int sensorLocationX;
+  int sensorLocationY;
+  int sensorRadius;
+  String display = "";
+  android.hardware.biometrics.fingerprint.SensorShape sensorShape = android.hardware.biometrics.fingerprint.SensorShape.CIRCLE;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/SensorProps.aidl
new file mode 100644
index 0000000..a97d819
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+parcelable SensorProps {
+  android.hardware.biometrics.common.CommonProps commonProps;
+  android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType = android.hardware.biometrics.fingerprint.FingerprintSensorType.UNKNOWN;
+  android.hardware.biometrics.fingerprint.SensorLocation[] sensorLocations;
+  boolean supportsNavigationGestures;
+  boolean supportsDetectInteraction;
+  boolean halHandlesDisplayTouches;
+  boolean halControlsIllumination;
+  @nullable android.hardware.biometrics.fingerprint.TouchDetectionParameters touchDetectionParameters;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/SensorShape.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/SensorShape.aidl
new file mode 100644
index 0000000..f673b1c
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/SensorShape.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.fingerprint;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum SensorShape {
+  SQUARE,
+  CIRCLE,
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl
new file mode 100644
index 0000000..2e3ec4f
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/3/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+parcelable TouchDetectionParameters {
+  float targetSize = 1.0f;
+  float minOverlap = 0.0f;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index c51aa03..7075f71 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -32,19 +32,22 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.fingerprint;
+/* @hide */
 @Backing(type="byte") @VintfStability
 enum AcquiredInfo {
-  UNKNOWN = 0,
-  GOOD = 1,
-  PARTIAL = 2,
-  INSUFFICIENT = 3,
-  SENSOR_DIRTY = 4,
-  TOO_SLOW = 5,
-  TOO_FAST = 6,
-  VENDOR = 7,
-  START = 8,
-  TOO_DARK = 9,
-  TOO_BRIGHT = 10,
-  IMMOBILE = 11,
-  RETRYING_CAPTURE = 12,
+  UNKNOWN,
+  GOOD,
+  PARTIAL,
+  INSUFFICIENT,
+  SENSOR_DIRTY,
+  TOO_SLOW,
+  TOO_FAST,
+  VENDOR,
+  START,
+  TOO_DARK,
+  TOO_BRIGHT,
+  IMMOBILE,
+  RETRYING_CAPTURE,
+  LIFT_TOO_SOON,
+  POWER_PRESS,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
index af7bc3c..9eeaac5 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
@@ -32,15 +32,17 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.fingerprint;
+/* @hide */
 @Backing(type="byte") @VintfStability
 enum Error {
-  UNKNOWN = 0,
-  HW_UNAVAILABLE = 1,
-  UNABLE_TO_PROCESS = 2,
-  TIMEOUT = 3,
-  NO_SPACE = 4,
-  CANCELED = 5,
-  UNABLE_TO_REMOVE = 6,
-  VENDOR = 7,
-  BAD_CALIBRATION = 8,
+  UNKNOWN,
+  HW_UNAVAILABLE,
+  UNABLE_TO_PROCESS,
+  TIMEOUT,
+  NO_SPACE,
+  CANCELED,
+  UNABLE_TO_REMOVE,
+  VENDOR,
+  BAD_CALIBRATION,
+  POWER_PRESS,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
index 9c208c4..381aaf7 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
@@ -32,12 +32,13 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.fingerprint;
+/* @hide */
 @Backing(type="byte") @VintfStability
 enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+  UNKNOWN,
+  REAR,
+  UNDER_DISPLAY_ULTRASONIC,
+  UNDER_DISPLAY_OPTICAL,
+  POWER_BUTTON,
+  HOME_BUTTON,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 5d3df6f..0b6f300 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -32,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.fingerprint;
+/* @hide */
 @VintfStability
 interface IFingerprint {
   android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
index 30f299d..4fdcefc 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -32,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.fingerprint;
+/* @hide */
 @VintfStability
 interface ISession {
   void generateChallenge();
@@ -45,7 +46,13 @@
   void invalidateAuthenticatorId();
   void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat);
   void close();
+  /**
+   * @deprecated use onPointerDownWithContext instead.
+   */
   void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major);
+  /**
+   * @deprecated use onPointerUpWithContext instead.
+   */
   void onPointerUp(in int pointerId);
   void onUiReady();
   android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context);
@@ -54,4 +61,6 @@
   void onPointerDownWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
   void onPointerUpWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
   void onContextChanged(in android.hardware.biometrics.common.OperationContext context);
+  void onPointerCancelWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
+  void setIgnoreDisplayTouches(in boolean shouldIgnore);
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index 3c40ad6..be18ffe 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -32,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.fingerprint;
+/* @hide */
 @VintfStability
 interface ISessionCallback {
   void onChallengeGenerated(in long challenge);
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
index 43db6cf..d9bf085 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
@@ -32,14 +32,15 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.fingerprint;
-@VintfStability
+/* @hide */
+@JavaDerive(equals=true) @VintfStability
 parcelable PointerContext {
-  int pointerId = -1;
-  float x = 0.000000f;
-  float y = 0.000000f;
-  float minor = 0.000000f;
-  float major = 0.000000f;
-  float orientation = 0.000000f;
+  int pointerId = (-1) /* -1 */;
+  float x = 0f;
+  float y = 0f;
+  float minor = 0f;
+  float major = 0f;
+  float orientation = 0f;
   boolean isAod = false;
   long time = 0;
   long gestureStart = 0;
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
index 295fde9..965576e 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
@@ -32,11 +32,16 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.fingerprint;
+/* @hide */
 @VintfStability
 parcelable SensorLocation {
+  /**
+   * @deprecated use the display field instead. This field was never used.
+   */
   int displayId;
   int sensorLocationX;
   int sensorLocationY;
   int sensorRadius;
   String display = "";
+  android.hardware.biometrics.fingerprint.SensorShape sensorShape = android.hardware.biometrics.fingerprint.SensorShape.CIRCLE;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
index 782d289..a97d819 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -32,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.biometrics.fingerprint;
+/* @hide */
 @VintfStability
 parcelable SensorProps {
   android.hardware.biometrics.common.CommonProps commonProps;
@@ -41,4 +42,5 @@
   boolean supportsDetectInteraction;
   boolean halHandlesDisplayTouches;
   boolean halControlsIllumination;
+  @nullable android.hardware.biometrics.fingerprint.TouchDetectionParameters touchDetectionParameters;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorShape.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorShape.aidl
new file mode 100644
index 0000000..f673b1c
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorShape.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.fingerprint;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum SensorShape {
+  SQUARE,
+  CIRCLE,
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl
new file mode 100644
index 0000000..2e3ec4f
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+parcelable TouchDetectionParameters {
+  float targetSize = 1.0f;
+  float minOverlap = 0.0f;
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 8ec8574..41b7c5e 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -15,7 +15,9 @@
  */
 
 package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
 @VintfStability
 @Backing(type="byte")
 enum AcquiredInfo {
@@ -96,4 +98,15 @@
      * However, RETRYING_CAPTURE must not be sent after ACQUIRED_GOOD is sent.
      */
     RETRYING_CAPTURE,
+
+    /**
+     * Fingerprint was lifted before the capture completed.
+     */
+    LIFT_TOO_SOON,
+
+    /**
+     * Indicates a power press event has occurred. This is typically sent by fingerprint
+     * sensors that have the sensor co-located with the power button.
+     */
+    POWER_PRESS,
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
index e69859a..39a5676 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
@@ -15,7 +15,9 @@
  */
 
 package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
 @VintfStability
 @Backing(type="byte")
 enum Error {
@@ -68,4 +70,10 @@
      * There's a problem with the sensor's calibration.
      */
     BAD_CALIBRATION,
+
+    /**
+     * Indicates a power press event has occurred. This is typically sent by fingerprint
+     * sensors that have the sensor co-located with the power button.
+     */
+    POWER_PRESS,
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
index dbe7137..7caa154 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
@@ -15,7 +15,9 @@
  */
 
 package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
 @VintfStability
 @Backing(type="byte")
 enum FingerprintSensorType {
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 75f90a1..f4febad 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -19,7 +19,9 @@
 import android.hardware.biometrics.fingerprint.ISession;
 import android.hardware.biometrics.fingerprint.ISessionCallback;
 import android.hardware.biometrics.fingerprint.SensorProps;
-
+/**
+ * @hide
+ */
 @VintfStability
 interface IFingerprint {
     /**
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index db01145..83e7bbc 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -45,6 +45,7 @@
  * ISession only supports execution of one non-interrupting operation at a time, regardless of
  * whether it's cancellable. The framework must wait for a callback indicating the end of the
  * current non-interrupting operation before a new non-interrupting operation can be started.
+ * @hide
  */
 @VintfStability
 interface ISession {
@@ -419,6 +420,8 @@
      * @param y The distance in pixels from the top edge of the display.
      * @param minor See android.view.MotionEvent#getTouchMinor
      * @param major See android.view.MotionEvent#getTouchMajor
+     *
+     * @deprecated use onPointerDownWithContext instead.
      */
     void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major);
 
@@ -433,6 +436,8 @@
      * ISession#enroll, ISession#detectInteraction.
      *
      * @param pointerId See android.view.MotionEvent#getPointerId
+     *
+     * @deprecated use onPointerUpWithContext instead.
      */
     void onPointerUp(in int pointerId);
 
@@ -468,15 +473,77 @@
     /** See ISession#detectInteraction() */
     ICancellationSignal detectInteractionWithContext(in OperationContext context);
 
-    /** See ISession#onPointerDown(int, int, int, float, float) */
+    /**
+     * onPointerDownWithContext:
+     *
+     * This operation only applies to sensors that are configured as
+     * FingerprintSensorType::UNDER_DISPLAY_*. If invoked erroneously by the framework for sensors
+     * of other types, the HAL must treat this as a no-op and return immediately.
+     *
+     * Notifies the HAL that a finger entered the sensor area. This operation can be invoked
+     * regardless of the current state of the HAL.
+     *
+     * Note that for sensors which require illumination, for example
+     * FingerprintSensorType::UNDER_DISPLAY_OPTICAL, this is a good time to start illuminating.
+     *
+     * @param context See PointerContext
+     */
     void onPointerDownWithContext(in PointerContext context);
 
-    /** See ISession#onPointerUp(int) */
+    /**
+     * onPointerUpWithContext:
+     *
+     * This operation only applies to sensors that are configured as
+     * FingerprintSensorType::UNDER_DISPLAY_*. If invoked for sensors of other types, the HAL must
+     * treat this as a no-op and return immediately.
+     *
+     * Notifies the HAL that a finger left the sensor area. This operation can be invoked regardless
+     * of the current state of the HAL.
+     *
+     * @param context See PointerContext
+     */
     void onPointerUpWithContext(in PointerContext context);
 
     /**
+     * onContextChanged:
+     *
      * This may be called while an authenticate, detect interaction, or enrollment operation is
      * running when the context changes.
      */
     void onContextChanged(in OperationContext context);
+
+    /**
+     * onPointerCancelWithContext:
+     *
+     * This operation only applies to sensors that are configured as
+     * FingerprintSensorType::UNDER_DISPLAY_*. If invoked for sensors of other types, the HAL must
+     * treat this as a no-op and return immediately.
+     *
+     * Notifies the HAL that if there were fingers within the sensor area, they are no longer being
+     * tracked. The fingers may or may not still be on the sensor. This operation can be invoked
+     * regardless of the current state of the HAL.
+     *
+     * @param context See PointerContext
+     */
+    void onPointerCancelWithContext(in PointerContext context);
+
+    /**
+     * setIgnoreDisplayTouches:
+     *
+     * This operation only applies to sensors that have SensorProps#halHandlesDisplayTouches
+     * set to true. For all other sensors this is a no-op.
+     *
+     * Instructs the HAL whether to ignore display touches. This can be useful to avoid unintended
+     * fingerprint captures during certain UI interactions. For example, when entering a lockscreen
+     * PIN, some of the touches might overlap with the fingerprint sensor. Those touches should be
+     * ignored to avoid unintended authentication attempts.
+     *
+     * This flag must default to false when the HAL starts.
+     *
+     * The framework is responsible for both setting the flag to true and resetting it to false
+     * whenever it's appropriate.
+     *
+     * @param shouldIgnore whether the display touches should be ignored.
+     */
+    void setIgnoreDisplayTouches(in boolean shouldIgnore);
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index f699966..24b169e 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -19,7 +19,9 @@
 import android.hardware.biometrics.fingerprint.AcquiredInfo;
 import android.hardware.biometrics.fingerprint.Error;
 import android.hardware.keymaster.HardwareAuthToken;
-
+/**
+ * @hide
+ */
 @VintfStability
 interface ISessionCallback {
     /**
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
index e025d34..582e6cf 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
@@ -18,7 +18,9 @@
 
 /**
  * Additional context associated with a pointer event.
+ * @hide
  */
+@JavaDerive(equals=true)
 @VintfStability
 parcelable PointerContext {
     /**
@@ -64,7 +66,7 @@
     boolean isAod = false;
 
     /**
-     * The time of the user interaction that produced this event, in milliseconds.
+     * The time when this event was created, in milliseconds.
      *
      * This is obtained from MotionEvent#getEventTime, which uses SystemClock.uptimeMillis() as
      * the clock.
@@ -74,10 +76,10 @@
     long time = 0;
 
     /**
-     * The time of the first user interaction in this gesture, in milliseconds.
+     * This event is part of some gesture. This is the time when MotionEvent#ACTION_DOWN was
+     * created for that gesture, in milliseconds.
      *
-     * If this event is MotionEvent#ACTION_DOWN, it means it's the first event in this gesture,
-     * and `gestureStart` will be equal to `time`.
+     * If this event is MotionEvent#ACTION_DOWN, then this value is equal to `time`.
      *
      * This is obtained from MotionEvent#getDownTime, which uses SystemClock.uptimeMillis() as
      * the clock.
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
index d12605c..fd8c7fc 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
@@ -16,10 +16,15 @@
 
 package android.hardware.biometrics.fingerprint;
 
+import android.hardware.biometrics.fingerprint.SensorShape;
+
+/**
+ * @hide
+ */
 @VintfStability
 parcelable SensorLocation {
     /**
-     * Deprecated use the display field instead. This field was never used.
+     * @deprecated use the display field instead. This field was never used.
      */
     int displayId;
 
@@ -57,4 +62,10 @@
      *      for each display from which the sensor is accessible from.
      */
     String display = "";
+
+    /**
+     * The shape of the sensor if applicable. Most useful for the sensor of type
+     * SensorType::UNDER_DISPLAY_*.
+     */
+    SensorShape sensorShape = SensorShape.CIRCLE;
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
index fb516da..853aae4 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -19,7 +19,11 @@
 import android.hardware.biometrics.common.CommonProps;
 import android.hardware.biometrics.fingerprint.FingerprintSensorType;
 import android.hardware.biometrics.fingerprint.SensorLocation;
+import android.hardware.biometrics.fingerprint.TouchDetectionParameters;
 
+/**
+ * @hide
+ */
 @VintfStability
 parcelable SensorProps {
     /**
@@ -70,4 +74,9 @@
      * This value must be ignored for sensors that aren't optical UDFPS.
      */
     boolean halControlsIllumination;
+
+    /**
+     * Parameters used for fingerprint touch detection.
+     */
+    @nullable TouchDetectionParameters touchDetectionParameters;
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorShape.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorShape.aidl
new file mode 100644
index 0000000..1279332
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorShape.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.fingerprint;
+/**
+ * This is most useful for sensors configured as FingerprintSensorType::UNDER_DISPLAY_OPTICAL,
+ * as it's used to compute the on-screen sensor boundaries for the touch detection algorithm.
+ *
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum SensorShape {
+    SQUARE,
+    CIRCLE,
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl
new file mode 100644
index 0000000..bf117a3
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.fingerprint;
+
+/**
+ * @hide
+ */
+@VintfStability
+parcelable TouchDetectionParameters {
+    /**
+     * The percentage of the sensor that is considered the target. Value is required to be within
+     * [0.0, 1.0]. The target area expands outwards from center matching the sensorShape. Some
+     * portion of the touch must be within the target to be considered a valid touch.
+     */
+    float targetSize = 1.0f;
+
+    /**
+     * The minimum percentage overlap needed on the sensor to be considered a valid touch. Value is
+     * required to be within [0.0, 1.0].
+     */
+    float minOverlap = 0.0f;
+}
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index 430bf3c..16302eb 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -11,33 +11,134 @@
     name: "android.hardware.biometrics.fingerprint-service.example",
     vendor: true,
     relative_install_path: "hw",
-    init_rc: ["fingerprint-default.rc"],
-    vintf_fragments: ["fingerprint-default.xml"],
+    init_rc: ["fingerprint-example.rc"],
+    vintf_fragments: ["fingerprint-example.xml"],
     local_include_dirs: ["include"],
     srcs: [
-        "CancellationSignal.cpp",
+        "FakeLockoutTracker.cpp",
+        "FakeFingerprintEngine.cpp",
+        "FakeFingerprintEngineRear.cpp",
+        "FakeFingerprintEngineUdfps.cpp",
+        "FakeFingerprintEngineSide.cpp",
         "Fingerprint.cpp",
         "Session.cpp",
-        "WorkerThread.cpp",
         "main.cpp",
     ],
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.biometrics.fingerprint-V2-ndk",
-        "android.hardware.biometrics.common-V2-ndk",
+        "android.hardware.biometrics.fingerprint-V3-ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+        "android.hardware.biometrics.common.thread",
+        "android.hardware.biometrics.common.util",
     ],
+    static_libs: ["libandroid.hardware.biometrics.fingerprint.VirtualProps"],
 }
 
-cc_test_host {
-    name: "android.hardware.biometrics.fingerprint.WorkerThreadTest",
+cc_test {
+    name: "android.hardware.biometrics.fingerprint.FakeFingerprintEngineTest",
     local_include_dirs: ["include"],
     srcs: [
-        "tests/WorkerThreadTest.cpp",
-        "WorkerThread.cpp",
+        "tests/FakeFingerprintEngineTest.cpp",
+        "FakeFingerprintEngine.cpp",
+        "FakeLockoutTracker.cpp",
     ],
     shared_libs: [
-        "libcutils",
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.biometrics.common.thread",
     ],
+    static_libs: [
+        "libandroid.hardware.biometrics.fingerprint.VirtualProps",
+        "android.hardware.biometrics.fingerprint-V3-ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+        "android.hardware.keymaster-V4-ndk",
+        "android.hardware.biometrics.common.util",
+    ],
+    vendor: true,
     test_suites: ["general-tests"],
+    require_root: true,
+}
+
+cc_test {
+    name: "android.hardware.biometrics.fingerprint.FakeFingerprintEngineUdfpsTest",
+    local_include_dirs: ["include"],
+    srcs: [
+        "tests/FakeFingerprintEngineUdfpsTest.cpp",
+        "FakeFingerprintEngineUdfps.cpp",
+        "FakeFingerprintEngine.cpp",
+        "FakeLockoutTracker.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.biometrics.common.thread",
+    ],
+    static_libs: [
+        "libandroid.hardware.biometrics.fingerprint.VirtualProps",
+        "android.hardware.biometrics.fingerprint-V3-ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+        "android.hardware.keymaster-V4-ndk",
+        "android.hardware.biometrics.common.util",
+    ],
+    vendor: true,
+    test_suites: ["general-tests"],
+    require_root: true,
+}
+
+cc_test {
+    name: "android.hardware.biometrics.fingerprint.FakeLockoutTrackerTest",
+    local_include_dirs: ["include"],
+    srcs: [
+        "tests/FakeLockoutTrackerTest.cpp",
+        "FakeLockoutTracker.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.biometrics.common.thread",
+    ],
+    static_libs: [
+        "libandroid.hardware.biometrics.fingerprint.VirtualProps",
+        "android.hardware.biometrics.fingerprint-V3-ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+        "android.hardware.keymaster-V4-ndk",
+        "android.hardware.biometrics.common.util",
+    ],
+    vendor: true,
+    test_suites: ["general-tests"],
+    require_root: true,
+}
+
+cc_test {
+    name: "android.hardware.biometrics.fingerprint.SessionTest",
+    local_include_dirs: ["include"],
+    srcs: [
+        "tests/SessionTest.cpp",
+        "Session.cpp",
+        "FakeFingerprintEngine.cpp",
+        "FakeLockoutTracker.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.biometrics.common.thread",
+    ],
+    static_libs: [
+        "libandroid.hardware.biometrics.fingerprint.VirtualProps",
+        "android.hardware.biometrics.fingerprint-V3-ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+        "android.hardware.keymaster-V4-ndk",
+        "android.hardware.biometrics.common.util",
+    ],
+    vendor: true,
+    test_suites: ["general-tests"],
+    require_root: true,
+}
+
+sysprop_library {
+    name: "android.hardware.biometrics.fingerprint.VirtualProps",
+    srcs: ["fingerprint.sysprop"],
+    property_owner: "Vendor",
+    vendor: true,
 }
diff --git a/biometrics/fingerprint/aidl/default/CancellationSignal.cpp b/biometrics/fingerprint/aidl/default/CancellationSignal.cpp
deleted file mode 100644
index 6598316..0000000
--- a/biometrics/fingerprint/aidl/default/CancellationSignal.cpp
+++ /dev/null
@@ -1,37 +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 "CancellationSignal.h"
-
-#include <android-base/logging.h>
-#include <chrono>
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-CancellationSignal::CancellationSignal(std::promise<void>&& cancellationPromise)
-    : mCancellationPromise(std::move(cancellationPromise)) {}
-
-ndk::ScopedAStatus CancellationSignal::cancel() {
-    mCancellationPromise.set_value();
-    return ndk::ScopedAStatus::ok();
-}
-
-bool shouldCancel(const std::future<void>& f) {
-    CHECK(f.valid());
-    return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
-}
-
-}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
new file mode 100644
index 0000000..90ec8f2
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeFingerprintEngine.h"
+#include <regex>
+#include "Fingerprint.h"
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+
+#include <fingerprint.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+using ::android::base::ParseInt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+void FakeFingerprintEngine::generateChallengeImpl(ISessionCallback* cb) {
+    BEGIN_OP(0);
+    std::uniform_int_distribution<int64_t> dist;
+    auto challenge = dist(mRandom);
+    FingerprintHalProperties::challenge(challenge);
+    cb->onChallengeGenerated(challenge);
+}
+
+void FakeFingerprintEngine::revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
+    BEGIN_OP(0);
+    FingerprintHalProperties::challenge({});
+    cb->onChallengeRevoked(challenge);
+}
+
+void FakeFingerprintEngine::enrollImpl(ISessionCallback* cb,
+                                       const keymaster::HardwareAuthToken& hat,
+                                       const std::future<void>& cancel) {
+    BEGIN_OP(getLatency(FingerprintHalProperties::operation_enroll_latency()));
+
+    // Do proper HAT verification in the real implementation.
+    if (hat.mac.empty()) {
+        LOG(ERROR) << "Fail: hat";
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+
+    // Force error-out
+    auto err = FingerprintHalProperties::operation_enroll_error().value_or(0);
+    if (err != 0) {
+        LOG(ERROR) << "Fail: operation_enroll_error";
+        auto ec = convertError(err);
+        cb->onError(ec.first, ec.second);
+        return;
+    }
+
+    // Format is "<id>:<progress_ms-[acquiredInfo..]>,...:<result>
+    auto nextEnroll = FingerprintHalProperties::next_enrollment().value_or("");
+    auto parts = Util::split(nextEnroll, ":");
+    if (parts.size() != 3) {
+        LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
+        cb->onError(Error::VENDOR, 0 /* vendorError */);
+        return;
+    }
+    auto enrollmentId = std::stoi(parts[0]);
+    auto progress = parseEnrollmentCapture(parts[1]);
+    for (size_t i = 0; i < progress.size(); i += 2) {
+        auto left = (progress.size() - i) / 2 - 1;
+        auto duration = progress[i][0];
+        auto acquired = progress[i + 1];
+        auto N = acquired.size();
+
+        for (int j = 0; j < N; j++) {
+            SLEEP_MS(duration / N);
+
+            if (shouldCancel(cancel)) {
+                LOG(ERROR) << "Fail: cancel";
+                cb->onError(Error::CANCELED, 0 /* vendorCode */);
+                return;
+            }
+            auto ac = convertAcquiredInfo(acquired[j]);
+            cb->onAcquired(ac.first, ac.second);
+        }
+
+        if (left == 0 && !IS_TRUE(parts[2])) {  // end and failed
+            LOG(ERROR) << "Fail: requested by caller: " << nextEnroll;
+            FingerprintHalProperties::next_enrollment({});
+            cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
+        } else {  // progress and update props if last time
+            LOG(INFO) << "onEnroll: " << enrollmentId << " left: " << left;
+            if (left == 0) {
+                auto enrollments = FingerprintHalProperties::enrollments();
+                enrollments.emplace_back(enrollmentId);
+                FingerprintHalProperties::enrollments(enrollments);
+                FingerprintHalProperties::next_enrollment({});
+                // change authenticatorId after new enrollment
+                auto id = FingerprintHalProperties::authenticator_id().value_or(0);
+                auto newId = id + 1;
+                FingerprintHalProperties::authenticator_id(newId);
+                LOG(INFO) << "Enrolled: " << enrollmentId;
+            }
+            cb->onEnrollmentProgress(enrollmentId, left);
+        }
+    }
+}
+
+void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t /* operationId */,
+                                             const std::future<void>& cancel) {
+    BEGIN_OP(getLatency(FingerprintHalProperties::operation_authenticate_latency()));
+
+    int64_t now = Util::getSystemNanoTime();
+    int64_t duration = FingerprintHalProperties::operation_authenticate_duration().value_or(10);
+    auto acquired = FingerprintHalProperties::operation_authenticate_acquired().value_or("1");
+    auto acquiredInfos = parseIntSequence(acquired);
+    int N = acquiredInfos.size();
+
+    if (N == 0) {
+        LOG(ERROR) << "Fail to parse authentiate acquired info: " + acquired;
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+
+    // got lockout?
+    FakeLockoutTracker::LockoutMode lockoutMode = mLockoutTracker.getMode();
+    if (lockoutMode == FakeLockoutTracker::LockoutMode::kPermanent) {
+        LOG(ERROR) << "Fail: lockout permanent";
+        cb->onLockoutPermanent();
+        return;
+    } else if (lockoutMode == FakeLockoutTracker::LockoutMode::kTimed) {
+        int64_t timeLeft = mLockoutTracker.getLockoutTimeLeft();
+        LOG(ERROR) << "Fail: lockout timed " << timeLeft;
+        cb->onLockoutTimed(timeLeft);
+    }
+
+    int i = 0;
+    do {
+        if (FingerprintHalProperties::operation_authenticate_fails().value_or(false)) {
+            LOG(ERROR) << "Fail: operation_authenticate_fails";
+            mLockoutTracker.addFailedAttempt();
+            cb->onAuthenticationFailed();
+            return;
+        }
+
+        auto err = FingerprintHalProperties::operation_authenticate_error().value_or(0);
+        if (err != 0) {
+            LOG(ERROR) << "Fail: operation_authenticate_error";
+            auto ec = convertError(err);
+            cb->onError(ec.first, ec.second);
+            return;
+        }
+
+        if (FingerprintHalProperties::lockout().value_or(false)) {
+            LOG(ERROR) << "Fail: lockout";
+            cb->onLockoutPermanent();
+            cb->onError(Error::HW_UNAVAILABLE, 0 /* vendorError */);
+            return;
+        }
+
+        if (shouldCancel(cancel)) {
+            LOG(ERROR) << "Fail: cancel";
+            cb->onError(Error::CANCELED, 0 /* vendorCode */);
+            return;
+        }
+
+        if (i < N) {
+            auto ac = convertAcquiredInfo(acquiredInfos[i]);
+            cb->onAcquired(ac.first, ac.second);
+            i++;
+        }
+
+        SLEEP_MS(duration / N);
+    } while (!Util::hasElapsed(now, duration));
+
+    auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
+    auto enrolls = FingerprintHalProperties::enrollments();
+    auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+    if (id > 0 && isEnrolled) {
+        cb->onAuthenticationSucceeded(id, {} /* hat */);
+        mLockoutTracker.reset();
+        return;
+    } else {
+        LOG(ERROR) << "Fail: fingerprint not enrolled";
+        cb->onAuthenticationFailed();
+        mLockoutTracker.addFailedAttempt();
+    }
+}
+
+void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
+                                                  const std::future<void>& cancel) {
+    BEGIN_OP(getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
+
+    int64_t duration =
+            FingerprintHalProperties::operation_detect_interaction_duration().value_or(10);
+
+    auto detectInteractionSupported =
+            FingerprintHalProperties::detect_interaction().value_or(false);
+    if (!detectInteractionSupported) {
+        LOG(ERROR) << "Detect interaction is not supported";
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+
+    auto acquired = FingerprintHalProperties::operation_detect_interaction_acquired().value_or("1");
+    auto acquiredInfos = parseIntSequence(acquired);
+    int N = acquiredInfos.size();
+    int64_t now = Util::getSystemNanoTime();
+
+    if (N == 0) {
+        LOG(ERROR) << "Fail to parse detect interaction acquired info: " + acquired;
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+
+    int i = 0;
+    do {
+        auto err = FingerprintHalProperties::operation_detect_interaction_error().value_or(0);
+        if (err != 0) {
+            LOG(ERROR) << "Fail: operation_detect_interaction_error";
+            auto ec = convertError(err);
+            cb->onError(ec.first, ec.second);
+            return;
+        }
+
+        if (shouldCancel(cancel)) {
+            LOG(ERROR) << "Fail: cancel";
+            cb->onError(Error::CANCELED, 0 /* vendorCode */);
+            return;
+        }
+
+        if (i < N) {
+            auto ac = convertAcquiredInfo(acquiredInfos[i]);
+            cb->onAcquired(ac.first, ac.second);
+            i++;
+        }
+        SLEEP_MS(duration / N);
+    } while (!Util::hasElapsed(now, duration));
+
+    auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
+    auto enrolls = FingerprintHalProperties::enrollments();
+    auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+    if (id <= 0 || !isEnrolled) {
+        LOG(ERROR) << "Fail: not enrolled";
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+
+    cb->onInteractionDetected();
+}
+
+void FakeFingerprintEngine::enumerateEnrollmentsImpl(ISessionCallback* cb) {
+    BEGIN_OP(0);
+
+    std::vector<int32_t> ids;
+    // There are some enrollment sync issue with framework, which results in
+    //  a single template removal during the very firt sync command after reboot.
+    //  This is a workaround for now. TODO(b/243129174)
+    ids.push_back(-1);
+
+    for (auto& enrollment : FingerprintHalProperties::enrollments()) {
+        auto id = enrollment.value_or(0);
+        if (id > 0) {
+            ids.push_back(id);
+        }
+    }
+
+    cb->onEnrollmentsEnumerated(ids);
+}
+
+void FakeFingerprintEngine::removeEnrollmentsImpl(ISessionCallback* cb,
+                                                  const std::vector<int32_t>& enrollmentIds) {
+    BEGIN_OP(0);
+
+    std::vector<std::optional<int32_t>> newEnrollments;
+    std::vector<int32_t> removed;
+    for (auto& enrollment : FingerprintHalProperties::enrollments()) {
+        auto id = enrollment.value_or(0);
+        if (std::find(enrollmentIds.begin(), enrollmentIds.end(), id) != enrollmentIds.end()) {
+            removed.push_back(id);
+        } else if (id > 0) {
+            newEnrollments.emplace_back(id);
+        }
+    }
+    FingerprintHalProperties::enrollments(newEnrollments);
+
+    cb->onEnrollmentsRemoved(enrollmentIds);
+}
+
+void FakeFingerprintEngine::getAuthenticatorIdImpl(ISessionCallback* cb) {
+    BEGIN_OP(0);
+    int64_t authenticatorId;
+    if (FingerprintHalProperties::enrollments().size() == 0) {
+        authenticatorId = 0;
+    } else {
+        authenticatorId = FingerprintHalProperties::authenticator_id().value_or(0);
+        if (authenticatorId == 0) authenticatorId = 1;
+    }
+    cb->onAuthenticatorIdRetrieved(authenticatorId);
+}
+
+void FakeFingerprintEngine::invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
+    BEGIN_OP(0);
+    int64_t newId;
+    if (FingerprintHalProperties::enrollments().size() == 0) {
+        newId = 0;
+    } else {
+        auto id = FingerprintHalProperties::authenticator_id().value_or(0);
+        newId = id + 1;
+    }
+    FingerprintHalProperties::authenticator_id(newId);
+    cb->onAuthenticatorIdInvalidated(newId);
+}
+
+void FakeFingerprintEngine::resetLockoutImpl(ISessionCallback* cb,
+                                             const keymaster::HardwareAuthToken& hat) {
+    BEGIN_OP(0);
+    if (hat.mac.empty()) {
+        LOG(ERROR) << "Fail: hat in resetLockout()";
+        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+        return;
+    }
+    FingerprintHalProperties::lockout(false);
+    cb->onLockoutCleared();
+    mLockoutTracker.reset();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngine::onPointerDownImpl(int32_t /*pointerId*/, int32_t /*x*/,
+                                                            int32_t /*y*/, float /*minor*/,
+                                                            float /*major*/) {
+    BEGIN_OP(0);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngine::onPointerUpImpl(int32_t /*pointerId*/) {
+    BEGIN_OP(0);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngine::onUiReadyImpl() {
+    BEGIN_OP(0);
+    return ndk::ScopedAStatus::ok();
+}
+
+bool FakeFingerprintEngine::getSensorLocationConfig(SensorLocation& out) {
+    auto loc = FingerprintHalProperties::sensor_location().value_or("");
+    auto isValidStr = false;
+    auto dim = Util::split(loc, ":");
+
+    if (dim.size() < 3 or dim.size() > 4) {
+        if (!loc.empty()) LOG(WARNING) << "Invalid sensor location input (x:y:radius):" + loc;
+        return false;
+    } else {
+        int32_t x, y, r;
+        std::string d = "";
+        if (dim.size() >= 3) {
+            isValidStr = ParseInt(dim[0], &x) && ParseInt(dim[1], &y) && ParseInt(dim[2], &r);
+        }
+        if (dim.size() >= 4) {
+            d = dim[3];
+        }
+        if (isValidStr) out = {0, x, y, r, d};
+
+        return isValidStr;
+    }
+}
+SensorLocation FakeFingerprintEngine::getSensorLocation() {
+    SensorLocation location;
+
+    if (getSensorLocationConfig(location)) {
+        return location;
+    } else {
+        return defaultSensorLocation();
+    }
+}
+
+SensorLocation FakeFingerprintEngine::defaultSensorLocation() {
+    return {0 /* displayId (not used) */, 0 /* sensorLocationX */, 0 /* sensorLocationY */,
+            0 /* sensorRadius */, "" /* display */};
+}
+
+std::vector<int32_t> FakeFingerprintEngine::parseIntSequence(const std::string& str,
+                                                             const std::string& sep) {
+    std::vector<std::string> seqs = Util::split(str, sep);
+    std::vector<int32_t> res;
+
+    for (const auto& seq : seqs) {
+        int32_t val;
+        if (ParseInt(seq, &val)) {
+            res.push_back(val);
+        } else {
+            LOG(WARNING) << "Invalid int sequence:" + str;
+            res.clear();
+            break;
+        }
+    }
+
+    return res;
+}
+
+bool FakeFingerprintEngine::parseEnrollmentCaptureSingle(const std::string& str,
+                                                         std::vector<std::vector<int32_t>>& res) {
+    std::vector<int32_t> defaultAcquiredInfo = {(int32_t)AcquiredInfo::GOOD};
+    bool aborted = true;
+
+    do {
+        std::smatch sms;
+        // Parses strings like "1000-[5,1]" or "500"
+        std::regex ex("((\\d+)(-\\[([\\d|,]+)\\])?)");
+        if (!regex_match(str.cbegin(), str.cend(), sms, ex)) break;
+        int32_t duration;
+        if (!ParseInt(sms.str(2), &duration)) break;
+        res.push_back({duration});
+        if (!sms.str(4).empty()) {
+            auto acqv = parseIntSequence(sms.str(4));
+            if (acqv.empty()) break;
+            res.push_back(acqv);
+        } else
+            res.push_back(defaultAcquiredInfo);
+        aborted = false;
+    } while (0);
+
+    return !aborted;
+}
+
+std::vector<std::vector<int32_t>> FakeFingerprintEngine::parseEnrollmentCapture(
+        const std::string& str) {
+    std::vector<std::vector<int32_t>> res;
+
+    std::string s(str);
+    s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end());
+    bool aborted = false;
+    std::smatch sms;
+    // Parses strings like "1000-[5,1],500,800-[6,5,1]"
+    //                      ---------- --- -----------
+    //  into parts:             A       B       C
+    while (regex_search(s, sms, std::regex("^(,)?(\\d+(-\\[[\\d|,]+\\])?)"))) {
+        if (!parseEnrollmentCaptureSingle(sms.str(2), res)) {
+            aborted = true;
+            break;
+        }
+        s = sms.suffix();
+    }
+    if (aborted || s.length() != 0) {
+        res.clear();
+        LOG(ERROR) << "Failed to parse enrollment captures:" + str;
+    }
+
+    return res;
+}
+
+std::pair<AcquiredInfo, int32_t> FakeFingerprintEngine::convertAcquiredInfo(int32_t code) {
+    std::pair<AcquiredInfo, int32_t> res;
+    if (code > FINGERPRINT_ACQUIRED_VENDOR_BASE) {
+        res.first = AcquiredInfo::VENDOR;
+        res.second = code - FINGERPRINT_ACQUIRED_VENDOR_BASE;
+    } else {
+        res.first = (AcquiredInfo)code;
+        res.second = 0;
+    }
+    return res;
+}
+
+std::pair<Error, int32_t> FakeFingerprintEngine::convertError(int32_t code) {
+    std::pair<Error, int32_t> res;
+    if (code > FINGERPRINT_ERROR_VENDOR_BASE) {
+        res.first = Error::VENDOR;
+        res.second = code - FINGERPRINT_ERROR_VENDOR_BASE;
+    } else {
+        res.first = (Error)code;
+        res.second = 0;
+    }
+    return res;
+}
+
+int32_t FakeFingerprintEngine::getLatency(
+        const std::vector<std::optional<std::int32_t>>& latencyIn) {
+    int32_t res = DEFAULT_LATENCY;
+
+    std::vector<int32_t> latency;
+    for (auto x : latencyIn)
+        if (x.has_value()) latency.push_back(*x);
+
+    switch (latency.size()) {
+        case 0:
+            break;
+        case 1:
+            res = latency[0];
+            break;
+        case 2:
+            res = getRandomInRange(latency[0], latency[1]);
+            break;
+        default:
+            LOG(ERROR) << "ERROR: unexpected input of size " << latency.size();
+            break;
+    }
+
+    return res;
+}
+
+int32_t FakeFingerprintEngine::getRandomInRange(int32_t bound1, int32_t bound2) {
+    std::uniform_int_distribution<int32_t> dist(std::min(bound1, bound2), std::max(bound1, bound2));
+    return dist(mRandom);
+}
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineRear.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineRear.cpp
new file mode 100644
index 0000000..eea80d5
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineRear.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeFingerprintEngineRear.h"
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+
+#include <fingerprint.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {}
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp
new file mode 100644
index 0000000..9f736e7
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeFingerprintEngineSide.h"
+
+#include <android-base/logging.h>
+
+#include <fingerprint.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+SensorLocation FakeFingerprintEngineSide::defaultSensorLocation() {
+    SensorLocation location;
+
+    return {0 /* displayId (not used) */, defaultSensorLocationX /* sensorLocationX */,
+            defaultSensorLocationY /* sensorLocationY */, defaultSensorRadius /* sensorRadius */,
+            "" /* display */};
+}
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp
new file mode 100644
index 0000000..3cdfc70
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeFingerprintEngineUdfps.h"
+
+#include <android-base/logging.h>
+
+#include <fingerprint.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+#undef LOG_TAG
+#define LOG_TAG "FingerprintVirtualHalUdfps"
+
+using namespace ::android::fingerprint::virt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+FakeFingerprintEngineUdfps::FakeFingerprintEngineUdfps()
+    : FakeFingerprintEngine(), mWorkMode(WorkMode::kIdle), mPointerDownTime(0), mUiReadyTime(0) {}
+
+SensorLocation FakeFingerprintEngineUdfps::defaultSensorLocation() {
+    return {0 /* displayId (not used) */, defaultSensorLocationX /* sensorLocationX */,
+            defaultSensorLocationY /* sensorLocationY */, defaultSensorRadius /* sensorRadius */,
+            "" /* display */};
+}
+
+ndk::ScopedAStatus FakeFingerprintEngineUdfps::onPointerDownImpl(int32_t /*pointerId*/,
+                                                                 int32_t /*x*/, int32_t /*y*/,
+                                                                 float /*minor*/, float /*major*/) {
+    BEGIN_OP(0);
+    // verify whetehr touch coordinates/area matching sensor location ?
+    mPointerDownTime = Util::getSystemNanoTime();
+    if (FingerprintHalProperties::control_illumination().value_or(false)) {
+        fingerDownAction();
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngineUdfps::onPointerUpImpl(int32_t /*pointerId*/) {
+    BEGIN_OP(0);
+    mUiReadyTime = 0;
+    mPointerDownTime = 0;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngineUdfps::onUiReadyImpl() {
+    BEGIN_OP(0);
+
+    if (Util::hasElapsed(mPointerDownTime, uiReadyTimeoutInMs * 100)) {
+        LOG(ERROR) << "onUiReady() arrives too late after onPointerDown()";
+    } else {
+        fingerDownAction();
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+void FakeFingerprintEngineUdfps::fingerDownAction() {
+    switch (mWorkMode) {
+        case WorkMode::kAuthenticate:
+            onAuthenticateFingerDown();
+            break;
+        case WorkMode::kEnroll:
+            onEnrollFingerDown();
+            break;
+        case WorkMode::kDetectInteract:
+            onDetectInteractFingerDown();
+            break;
+        default:
+            LOG(WARNING) << "unexpected call: onUiReady()";
+            break;
+    }
+
+    mUiReadyTime = 0;
+    mPointerDownTime = 0;
+}
+
+void FakeFingerprintEngineUdfps::onAuthenticateFingerDown() {
+    FakeFingerprintEngine::authenticateImpl(mCb, mOperationId, mCancelVec[0]);
+}
+
+void FakeFingerprintEngineUdfps::onEnrollFingerDown() {
+    // Any use case to emulate display touch for each capture during enrollment?
+    FakeFingerprintEngine::enrollImpl(mCb, mHat, mCancelVec[0]);
+}
+
+void FakeFingerprintEngineUdfps::onDetectInteractFingerDown() {
+    FakeFingerprintEngine::detectInteractionImpl(mCb, mCancelVec[0]);
+}
+
+void FakeFingerprintEngineUdfps::enrollImpl(ISessionCallback* cb,
+                                            const keymaster::HardwareAuthToken& hat,
+                                            const std::future<void>& cancel) {
+    updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
+}
+
+void FakeFingerprintEngineUdfps::authenticateImpl(ISessionCallback* cb, int64_t operationId,
+                                                  const std::future<void>& cancel) {
+    updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
+                  keymaster::HardwareAuthToken());
+}
+
+void FakeFingerprintEngineUdfps::detectInteractionImpl(ISessionCallback* cb,
+                                                       const std::future<void>& cancel) {
+    updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
+                  keymaster::HardwareAuthToken());
+}
+
+void FakeFingerprintEngineUdfps::updateContext(WorkMode mode, ISessionCallback* cb,
+                                               std::future<void>& cancel, int64_t operationId,
+                                               const keymaster::HardwareAuthToken& hat) {
+    mPointerDownTime = 0;
+    mUiReadyTime = 0;
+    mCancelVec.clear();
+
+    mCancelVec.push_back(std::move(cancel));
+    mWorkMode = mode;
+    mCb = cb;
+    mOperationId = operationId;
+    mHat = hat;
+}
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
new file mode 100644
index 0000000..5996406
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeLockoutTracker.h"
+#include <fingerprint.sysprop.h>
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+void FakeLockoutTracker::reset() {
+    mFailedCount = 0;
+    mLockoutTimedStart = 0;
+    mCurrentMode = LockoutMode::kNone;
+}
+
+void FakeLockoutTracker::addFailedAttempt() {
+    bool enabled = FingerprintHalProperties::lockout_enable().value_or(false);
+    if (enabled) {
+        mFailedCount++;
+        int32_t lockoutTimedThreshold =
+                FingerprintHalProperties::lockout_timed_threshold().value_or(5);
+        int32_t lockoutPermanetThreshold =
+                FingerprintHalProperties::lockout_permanent_threshold().value_or(20);
+        if (mFailedCount >= lockoutPermanetThreshold) {
+            mCurrentMode = LockoutMode::kPermanent;
+            FingerprintHalProperties::lockout(true);
+        } else if (mFailedCount >= lockoutTimedThreshold) {
+            if (mCurrentMode == LockoutMode::kNone) {
+                mCurrentMode = LockoutMode::kTimed;
+                mLockoutTimedStart = Util::getSystemNanoTime();
+            }
+        }
+    } else {
+        reset();
+    }
+}
+
+FakeLockoutTracker::LockoutMode FakeLockoutTracker::getMode() {
+    if (mCurrentMode == LockoutMode::kTimed) {
+        int32_t lockoutTimedDuration =
+                FingerprintHalProperties::lockout_timed_duration().value_or(10 * 100);
+        if (Util::hasElapsed(mLockoutTimedStart, lockoutTimedDuration)) {
+            mCurrentMode = LockoutMode::kNone;
+            mLockoutTimedStart = 0;
+        }
+    }
+
+    return mCurrentMode;
+}
+
+int64_t FakeLockoutTracker::getLockoutTimeLeft() {
+    int64_t res = 0;
+
+    if (mLockoutTimedStart > 0) {
+        auto now = Util::getSystemNanoTime();
+        auto left = now - mLockoutTimedStart;
+        res = (left > 0) ? (left / 1000000LL) : 0;
+    }
+
+    return res;
+}
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index 1f14de6..f00a49d 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -15,16 +15,22 @@
  */
 
 #include "Fingerprint.h"
-
 #include "Session.h"
 
+#include <fingerprint.sysprop.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+using namespace ::android::fingerprint::virt;
+
 namespace aidl::android::hardware::biometrics::fingerprint {
 namespace {
 constexpr size_t MAX_WORKER_QUEUE_SIZE = 5;
-constexpr int SENSOR_ID = 1;
+constexpr int SENSOR_ID = 5;
 constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::STRONG;
 constexpr int MAX_ENROLLMENTS_PER_USER = 5;
-constexpr FingerprintSensorType SENSOR_TYPE = FingerprintSensorType::REAR;
 constexpr bool SUPPORTS_NAVIGATION_GESTURES = true;
 constexpr char HW_COMPONENT_ID[] = "fingerprintSensor";
 constexpr char HW_VERSION[] = "vendor/model/revision";
@@ -35,27 +41,57 @@
 
 }  // namespace
 
-Fingerprint::Fingerprint()
-    : mEngine(std::make_unique<FakeFingerprintEngine>()), mWorker(MAX_WORKER_QUEUE_SIZE) {}
+Fingerprint::Fingerprint() : mWorker(MAX_WORKER_QUEUE_SIZE) {
+    std::string sensorTypeProp = FingerprintHalProperties::type().value_or("");
+    if (sensorTypeProp == "" || sensorTypeProp == "default" || sensorTypeProp == "rear") {
+        mSensorType = FingerprintSensorType::REAR;
+        mEngine = std::make_unique<FakeFingerprintEngineRear>();
+    } else if (sensorTypeProp == "udfps") {
+        mSensorType = FingerprintSensorType::UNDER_DISPLAY_OPTICAL;
+        mEngine = std::make_unique<FakeFingerprintEngineUdfps>();
+    } else if (sensorTypeProp == "side") {
+        mSensorType = FingerprintSensorType::POWER_BUTTON;
+        mEngine = std::make_unique<FakeFingerprintEngineSide>();
+    } else {
+        mSensorType = FingerprintSensorType::UNKNOWN;
+        mEngine = std::make_unique<FakeFingerprintEngineRear>();
+        UNIMPLEMENTED(FATAL) << "unrecognized or unimplemented fingerprint behavior: "
+                             << sensorTypeProp;
+    }
+    LOG(INFO) << "sensorTypeProp:" << sensorTypeProp;
+}
 
 ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector<SensorProps>* out) {
     std::vector<common::ComponentInfo> componentInfo = {
             {HW_COMPONENT_ID, HW_VERSION, FW_VERSION, SERIAL_NUMBER, "" /* softwareVersion */},
             {SW_COMPONENT_ID, "" /* hardwareVersion */, "" /* firmwareVersion */,
              "" /* serialNumber */, SW_VERSION}};
+    auto sensorId = FingerprintHalProperties::sensor_id().value_or(SENSOR_ID);
+    auto sensorStrength =
+            FingerprintHalProperties::sensor_strength().value_or((int)SENSOR_STRENGTH);
+    auto maxEnrollments =
+            FingerprintHalProperties::max_enrollments().value_or(MAX_ENROLLMENTS_PER_USER);
+    auto navigationGuesture = FingerprintHalProperties::navigation_guesture().value_or(false);
+    auto detectInteraction = FingerprintHalProperties::detect_interaction().value_or(false);
+    auto displayTouch = FingerprintHalProperties::display_touch().value_or(true);
+    auto controlIllumination = FingerprintHalProperties::control_illumination().value_or(false);
 
-    common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH, MAX_ENROLLMENTS_PER_USER,
-                                       componentInfo};
+    common::CommonProps commonProps = {sensorId, (common::SensorStrength)sensorStrength,
+                                       maxEnrollments, componentInfo};
 
-    SensorLocation sensorLocation = {0 /* displayId (not used) */, 0 /* sensorLocationX */,
-                                     0 /* sensorLocationY */, 0 /* sensorRadius */,
-                                     "" /* display */};
+    SensorLocation sensorLocation = mEngine->getSensorLocation();
+
+    LOG(INFO) << "sensor type:" << ::android::internal::ToString(mSensorType)
+              << " location:" << sensorLocation.toString();
 
     *out = {{commonProps,
-             SENSOR_TYPE,
+             mSensorType,
              {sensorLocation},
-             SUPPORTS_NAVIGATION_GESTURES,
-             false /* supportsDetectInteraction */}};
+             navigationGuesture,
+             detectInteraction,
+             displayTouch,
+             controlIllumination,
+             std::nullopt}};
     return ndk::ScopedAStatus::ok();
 }
 
@@ -66,7 +102,103 @@
 
     mSession = SharedRefBase::make<Session>(sensorId, userId, cb, mEngine.get(), &mWorker);
     *out = mSession;
+
+    mSession->linkToDeath(cb->asBinder().get());
+
+    LOG(INFO) << "createSession: sensorId:" << sensorId << " userId:" << userId;
     return ndk::ScopedAStatus::ok();
 }
 
+binder_status_t Fingerprint::dump(int fd, const char** /*args*/, uint32_t numArgs) {
+    if (fd < 0) {
+        LOG(ERROR) << "Fingerprint::dump fd invalid: " << fd;
+        return STATUS_BAD_VALUE;
+    } else {
+        LOG(INFO) << "Fingerprint::dump fd:" << fd << "numArgs:" << numArgs;
+    }
+
+    dprintf(fd, "----- FingerprintVirtualHal::dump -----\n");
+    std::vector<SensorProps> sps(1);
+    getSensorProps(&sps);
+    for (auto& sp : sps) {
+        ::android::base::WriteStringToFd(sp.toString(), fd);
+    }
+    ::android::base::WriteStringToFd(mEngine->toString(), fd);
+
+    fsync(fd);
+    return STATUS_OK;
+}
+
+binder_status_t Fingerprint::handleShellCommand(int in, int out, int err, const char** args,
+                                                uint32_t numArgs) {
+    LOG(INFO) << "Fingerprint::handleShellCommand in:" << in << " out:" << out << " err:" << err
+              << " numArgs:" << numArgs;
+
+    if (numArgs == 0) {
+        LOG(INFO) << "Fingerprint::handleShellCommand: available commands";
+        onHelp(out);
+        return STATUS_OK;
+    }
+
+    for (auto&& str : std::vector<std::string_view>(args, args + numArgs)) {
+        std::string option = str.data();
+        if (option.find("clearconfig") != std::string::npos ||
+            option.find("resetconfig") != std::string::npos) {
+            resetConfigToDefault();
+        }
+        if (option.find("help") != std::string::npos) {
+            onHelp(out);
+        }
+    }
+
+    return STATUS_OK;
+}
+
+void Fingerprint::onHelp(int fd) {
+    dprintf(fd, "Virtual HAL commands:\n");
+    dprintf(fd, "         help: print this help\n");
+    dprintf(fd, "  resetconfig: reset all configuration to default\n");
+    dprintf(fd, "\n");
+    fsync(fd);
+}
+
+void Fingerprint::resetConfigToDefault() {
+    LOG(INFO) << "reset virtual HAL configuration to default";
+#define RESET_CONFIG_O(__NAME__) \
+    if (FingerprintHalProperties::__NAME__()) FingerprintHalProperties::__NAME__(std::nullopt)
+#define RESET_CONFIG_V(__NAME__)                       \
+    if (!FingerprintHalProperties::__NAME__().empty()) \
+    FingerprintHalProperties::__NAME__({std::nullopt})
+
+    RESET_CONFIG_O(type);
+    RESET_CONFIG_V(enrollments);
+    RESET_CONFIG_O(enrollment_hit);
+    RESET_CONFIG_O(authenticator_id);
+    RESET_CONFIG_O(challenge);
+    RESET_CONFIG_O(lockout);
+    RESET_CONFIG_O(operation_authenticate_fails);
+    RESET_CONFIG_O(operation_detect_interaction_error);
+    RESET_CONFIG_O(operation_enroll_error);
+    RESET_CONFIG_V(operation_authenticate_latency);
+    RESET_CONFIG_V(operation_detect_interaction_latency);
+    RESET_CONFIG_V(operation_enroll_latency);
+    RESET_CONFIG_O(operation_authenticate_duration);
+    RESET_CONFIG_O(operation_authenticate_error);
+    RESET_CONFIG_O(sensor_location);
+    RESET_CONFIG_O(operation_authenticate_acquired);
+    RESET_CONFIG_O(operation_detect_interaction_duration);
+    RESET_CONFIG_O(operation_detect_interaction_acquired);
+    RESET_CONFIG_O(sensor_id);
+    RESET_CONFIG_O(sensor_strength);
+    RESET_CONFIG_O(max_enrollments);
+    RESET_CONFIG_O(navigation_guesture);
+    RESET_CONFIG_O(detect_interaction);
+    RESET_CONFIG_O(display_touch);
+    RESET_CONFIG_O(control_illumination);
+    RESET_CONFIG_O(lockout_enable);
+    RESET_CONFIG_O(lockout_timed_threshold);
+    RESET_CONFIG_O(lockout_timed_duration);
+    RESET_CONFIG_O(lockout_permanent_threshold);
+}
+
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/README.md b/biometrics/fingerprint/aidl/default/README.md
new file mode 100644
index 0000000..49b6c9d
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/README.md
@@ -0,0 +1,165 @@
+# Virtual Fingerprint HAL
+
+This is a virtual HAL implementation that is backed by system properties instead
+of actual hardware. It's intended for testing and UI development on debuggable
+builds to allow devices to masquerade as alternative device types and for
+emulators.
+
+## Supported Devices
+
+This HAL can be used on emulators, like cuttlefish, or on real devices. Add the
+following to your device's `.mk` file to include it:
+
+```
+PRODUCT_PACKAGES_DEBUG += android.hardware.biometrics.fingerprint-service.example
+```
+
+The virtual HAL will be ignored if a real HAL is also installed on the target
+device. Set the `biometric_virtual_enabled` settings and reboot the device to
+switch to the virtual HAL. Unset it and reboot again to switch back.
+
+## Getting Started
+
+First, set the type of sensor the device should use, enable the virtual
+extensions in the framework, and reboot.
+
+```shell
+$ adb root
+$ adb shell settings put secure biometric_virtual_enabled 1
+$ adb shell setprop persist.vendor.fingerprint.virtual.type rear
+$ adb reboot
+```
+
+### Enrollments
+
+Next, setup enrollments on the device. This can either be done through the UI,
+or via adb directly.
+
+#### Direct Enrollment
+
+To set enrollment directly without the UI:
+
+```shell
+$ adb root
+$ adb shell locksettings set-pin 0000
+$ adb shell setprop persist.vendor.fingerprint.virtual.enrollments 1
+$ adb shell cmd fingerprint sync
+```
+
+#### UI Enrollment
+
+1. Set pin
+      ```shell
+      $ adb shell locksettings set-pin 0000
+      ```
+2. Tee up the results of the enrollment before starting the process:
+
+      ```shell
+      $ adb shell setprop vendor.fingerprint.virtual.next_enrollment 1:100,100,100:true
+      ```
+
+3. Navigate to `Settings -> Security -> Fingerprint Unlock` and follow the
+   prompts.
+4. Verify the enrollments in the UI:
+
+      ```shell
+      $ adb shell getprop persist.vendor.fingerprint.virtual.enrollments
+      ```
+
+## Authenticate
+
+To authenticate successfully set the enrolled id that should succeed. Unset it
+or change the value to make authenticate operations fail:
+
+````shell
+$ adb shell setprop vendor.fingerprint.virtual.enrollment_hit 1
+````
+
+## Acquired Info Insertion
+
+Fingerprint image acquisition states at HAL are reported to framework via onAcquired() callback. The valid acquired state info for AIDL HAL include
+
+{UNKNOWN(0), GOOD(1), PARTIAL(2), INSUFFICIENT(3), SENSOR_DIRTY(4), TOO_SLOW(5), TOO_FAST(6), VENDOR(7), START(8), TOO_DARK(9), TOO_BRIGHT(10), IMMOBILE(11), RETRYING_CAPTURE(12)}
+
+Refer to [AcquiredInfo.aidl](../android/hardware/biometrics/fingerprint/AcquiredInfo.aidl) for details
+
+
+The states can be specified in sequence for the HAL operations involving fingerprint image captures, namely authenticate, enrollment and detectInteraction
+
+```shell
+$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_acquired 6,9,1
+$ adb shell setprop vendor.fingerprint.virtual.operation_detect_interaction_acquired 6,1
+$ adb shell setprop vendor.fingerprint.virtual.next_enrollment 2:1000-[5,1],500:true
+
+#next_enrollment format example:
+.---------------------- enrollment id (2)
+|   .------------------ the image capture 1 duration (1000ms)
+|   |   .--------------   acquired info first (TOO_SLOW)
+|   |   | .------------   acquired info second (GOOD)
+|   |   | |   .-------- the image capture 2 duration (500ms)
+|   |   | |   |   .---- enrollment end status (success)
+|   |   | |   |   |
+|   |   | |   |   |
+|   |   | |   |   |
+2:1000-[5,1],500:true
+```
+For vendor specific acquired info, acquiredInfo = 1000 + vendorAcquiredInfo
+
+## Error Insertion
+The valid error codes for AIDL HAL include
+
+{UNKNOWN(0), HW_UNAVAILABLE(1), UNABLE_TO_PROCESS(2), TIMEOUT(3), NO_SPACE(4), CANCELED(5), UNABLE_TO_REMOVE(6), VENDOR(7), BAD_CALIBRATION(8)}
+
+Refer to [Error.aidl](../android/hardware/biometrics/fingerprint/Error.aidl) for details
+
+
+There are many HAL operations which can result in errors, refer to [here](fingerprint.sysprop) file for details.
+
+```shell
+$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_error 8
+```
+For vendor specific error, errorCode = 1000 + vendorErrorCode
+
+## Latency Insertion
+Three HAL operations (authenticate, enrollment and detect interaction) latency can be optionally specified in multiple ways
+1. default latency is fixed at 400 ms if not specified via sysprop
+2. specify authenticate operation latency to 900 ms
+      ```shell adb shell setprop vendor.fingerprint.virtual.operation_authenticate_latency 900```
+3. specify authenticate operation latency between 600 to 1200 ms in unifrom distribution
+      ```shelladb shell setprop vendor.fingerprint.virtual.operation_authenticate_latency 600,1200```
+
+## Lockout
+To force the device into lockout state
+```shell
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout true
+```
+To test permanent lockout based on the failed authentication attempts (e.g. 7)
+```shell
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_permanent_threshold 7
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_enable true
+```
+To test timed lockout based on the failed authentication attempts (e.g. 8 seconds on 5 attempts)
+```shell
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_timed_duration 8000
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_timed_threshold 5
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_enable true
+```
+
+## Reset all configurations to default
+The following command will reset virtual configurations (related system properties) to default value.
+```shell
+$ adb shell cmd android.hardware.biometrics.fingerprint.IFingerprint/virtual resetconfig
+$ adb reboot
+```
+
+## View HAL State
+
+To view all the properties of the HAL (see `fingerprint.sysprop` file for the API):
+
+```shell
+$ adb shell getprop | grep vendor.fingerprint.virtual
+```
+To dump virtual HAL internal data
+```shell
+adb shell dumpsys android.hardware.biometrics.fingerprint.IFingerprint/virtual
+```
diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp
index 452ed12..c06c931 100644
--- a/biometrics/fingerprint/aidl/default/Session.cpp
+++ b/biometrics/fingerprint/aidl/default/Session.cpp
@@ -18,10 +18,21 @@
 
 #include <android-base/logging.h>
 
-#include "CancellationSignal.h"
+#include "util/CancellationSignal.h"
+
+#undef LOG_TAG
+#define LOG_TAG "FingerprintVirtualHalSession"
 
 namespace aidl::android::hardware::biometrics::fingerprint {
 
+void onClientDeath(void* cookie) {
+    LOG(INFO) << "FingerprintService has died";
+    Session* session = static_cast<Session*>(cookie);
+    if (session && !session->isClosed()) {
+        session->close();
+    }
+}
+
 Session::Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb,
                  FakeFingerprintEngine* engine, WorkerThread* worker)
     : mSensorId(sensorId),
@@ -36,6 +47,12 @@
     CHECK(mEngine);
     CHECK(mWorker);
     CHECK(mCb);
+
+    mDeathRecipient = AIBinder_DeathRecipient_new(onClientDeath);
+}
+
+binder_status_t Session::linkToDeath(AIBinder* binder) {
+    return AIBinder_linkToDeath(binder, mDeathRecipient, this);
 }
 
 void Session::scheduleStateOrCrash(SessionState state) {
@@ -101,7 +118,7 @@
         if (shouldCancel(cancFuture)) {
             mCb->onError(Error::CANCELED, 0 /* vendorCode */);
         } else {
-            mEngine->enrollImpl(mCb.get(), hat);
+            mEngine->enrollImpl(mCb.get(), hat, cancFuture);
         }
         enterIdling();
     }));
@@ -123,7 +140,7 @@
         if (shouldCancel(cancFuture)) {
             mCb->onError(Error::CANCELED, 0 /* vendorCode */);
         } else {
-            mEngine->authenticateImpl(mCb.get(), operationId);
+            mEngine->authenticateImpl(mCb.get(), operationId, cancFuture);
         }
         enterIdling();
     }));
@@ -144,7 +161,7 @@
         if (shouldCancel(cancFuture)) {
             mCb->onError(Error::CANCELED, 0 /* vendorCode */);
         } else {
-            mEngine->detectInteractionImpl(mCb.get());
+            mEngine->detectInteractionImpl(mCb.get(), cancFuture);
         }
         enterIdling();
     }));
@@ -167,7 +184,7 @@
 }
 
 ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& enrollmentIds) {
-    LOG(INFO) << "removeEnrollments";
+    LOG(INFO) << "removeEnrollments, size:" << enrollmentIds.size();
     scheduleStateOrCrash(SessionState::REMOVING_ENROLLMENTS);
 
     mWorker->schedule(Callable::from([this, enrollmentIds] {
@@ -225,22 +242,35 @@
     // Crashing.";
     mCurrentState = SessionState::CLOSED;
     mCb->onSessionClosed();
+    AIBinder_DeathRecipient_delete(mDeathRecipient);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Session::onPointerDown(int32_t /*pointerId*/, int32_t /*x*/, int32_t /*y*/,
-                                          float /*minor*/, float /*major*/) {
+ndk::ScopedAStatus Session::onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor,
+                                          float major) {
     LOG(INFO) << "onPointerDown";
+    mWorker->schedule(Callable::from([this, pointerId, x, y, minor, major] {
+        mEngine->onPointerDownImpl(pointerId, x, y, minor, major);
+        enterIdling();
+    }));
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Session::onPointerUp(int32_t /*pointerId*/) {
+ndk::ScopedAStatus Session::onPointerUp(int32_t pointerId) {
     LOG(INFO) << "onPointerUp";
+    mWorker->schedule(Callable::from([this, pointerId] {
+        mEngine->onPointerUpImpl(pointerId);
+        enterIdling();
+    }));
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::onUiReady() {
     LOG(INFO) << "onUiReady";
+    mWorker->schedule(Callable::from([this] {
+        mEngine->onUiReadyImpl();
+        enterIdling();
+    }));
     return ndk::ScopedAStatus::ok();
 }
 
@@ -274,4 +304,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Session::onPointerCancelWithContext(const PointerContext& /*context*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::setIgnoreDisplayTouches(bool /*shouldIgnore*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/WorkerThread.cpp b/biometrics/fingerprint/aidl/default/WorkerThread.cpp
deleted file mode 100644
index d1a63d0..0000000
--- a/biometrics/fingerprint/aidl/default/WorkerThread.cpp
+++ /dev/null
@@ -1,68 +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 "WorkerThread.h"
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-// It's important that mThread is initialized after everything else because it runs a member
-// function that may use any member of this class.
-WorkerThread::WorkerThread(size_t maxQueueSize)
-    : mMaxSize(maxQueueSize),
-      mIsDestructing(false),
-      mQueue(),
-      mQueueMutex(),
-      mQueueCond(),
-      mThread(&WorkerThread::threadFunc, this) {}
-
-WorkerThread::~WorkerThread() {
-    // This is a signal for threadFunc to terminate as soon as possible, and a hint for schedule
-    // that it doesn't need to do any work.
-    mIsDestructing = true;
-    mQueueCond.notify_all();
-    mThread.join();
-}
-
-bool WorkerThread::schedule(std::unique_ptr<Callable> task) {
-    if (mIsDestructing) {
-        return false;
-    }
-
-    std::unique_lock<std::mutex> lock(mQueueMutex);
-    if (mQueue.size() >= mMaxSize) {
-        return false;
-    }
-    mQueue.push_back(std::move(task));
-    lock.unlock();
-    mQueueCond.notify_one();
-    return true;
-}
-
-void WorkerThread::threadFunc() {
-    while (!mIsDestructing) {
-        std::unique_lock<std::mutex> lock(mQueueMutex);
-        mQueueCond.wait(lock, [this] { return !mQueue.empty() || mIsDestructing; });
-        if (mIsDestructing) {
-            return;
-        }
-        std::unique_ptr<Callable> task = std::move(mQueue.front());
-        mQueue.pop_front();
-        lock.unlock();
-        (*task)();
-    }
-}
-
-}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-default.rc b/biometrics/fingerprint/aidl/default/fingerprint-default.rc
deleted file mode 100644
index eb62c56..0000000
--- a/biometrics/fingerprint/aidl/default/fingerprint-default.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.fingerprint-default /vendor/bin/hw/android.hardware.biometrics.fingerprint-service.example
-    class hal
-    user nobody
-    group nobody
-
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-default.xml b/biometrics/fingerprint/aidl/default/fingerprint-default.xml
deleted file mode 100644
index d322eb6..0000000
--- a/biometrics/fingerprint/aidl/default/fingerprint-default.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<manifest version="1.0" type="device">
-    <hal format="aidl">
-        <name>android.hardware.biometrics.fingerprint</name>
-        <version>2</version>
-        <fqname>IFingerprint/default</fqname>
-    </hal>
-</manifest>
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.rc b/biometrics/fingerprint/aidl/default/fingerprint-example.rc
new file mode 100644
index 0000000..ee4713c
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/fingerprint-example.rc
@@ -0,0 +1,7 @@
+service vendor.fingerprint-example /vendor/bin/hw/android.hardware.biometrics.fingerprint-service.example
+    class hal
+    user nobody
+    group nobody
+    interface aidl android.hardware.biometrics.fingerprint.IFingerprint/virtual
+    oneshot
+    disabled
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.xml b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
new file mode 100644
index 0000000..e977b98
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <version>3</version>
+        <fqname>IFingerprint/virtual</fqname>
+    </hal>
+</manifest>
diff --git a/biometrics/fingerprint/aidl/default/fingerprint.sysprop b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
new file mode 100644
index 0000000..6a6c297
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
@@ -0,0 +1,300 @@
+# fingerprint.sysprop
+# module becomes static class (Java) / namespace (C++) for serving API
+module: "android.fingerprint.virt.FingerprintHalProperties"
+owner: Vendor
+
+# type of fingerprint sensor
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.type"
+    type: String
+    scope: Internal
+    access: ReadWrite
+    enum_values: "default|rear|udfps|side"
+    api_name: "type"
+}
+
+# ids of call current enrollments
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.enrollments"
+    type: IntegerList
+    scope: Internal
+    access: ReadWrite
+    api_name: "enrollments"
+}
+
+# authenticate and detectInteraction will succeed with this
+# enrollment id, when present, otherwise they will error
+prop {
+    prop_name: "vendor.fingerprint.virtual.enrollment_hit"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "enrollment_hit"
+}
+
+# the next enrollment in the format of:
+# "<id>:<delay>,<delay>,...:<result>"
+# <delay> = <duration-[acquiredInfos]>
+# [acquiredInfos] = [acquiredInfo1, acquiredInfo2, ...]
+# (refer to README.md file for acquiredInfo values)
+# e.g. "2:100,20:true", "2:100-[5,1],20:true"
+# this property is reset after enroll completes
+prop {
+    prop_name: "vendor.fingerprint.virtual.next_enrollment"
+    type: String
+    scope: Internal
+    access: ReadWrite
+    api_name: "next_enrollment"
+}
+
+# value for getAuthenticatorId or 0
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
+    type: Long
+    scope: Internal
+    access: ReadWrite
+    api_name: "authenticator_id"
+}
+
+# value for generateChallenge
+prop {
+    prop_name: "vendor.fingerprint.virtual.challenge"
+    type: Long
+    scope: Internal
+    access: ReadWrite
+    api_name: "challenge"
+}
+
+# force all authenticate operations to fail
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_authenticate_fails"
+    type: Boolean
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_authenticate_fails"
+}
+
+# force all detectInteraction operations to error out
+# error consists of errorCode and vendorErrorCode
+# valid errorCodes are listed in README.md file
+# vendorErrorCode = (error>1000) ? error-1000 : 0
+# e.g. error(1002) --> errorCode(7) and vendorErrorCode(2)
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_detect_interaction_error"
+}
+
+# force all enroll operations to result in error
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_enroll_error"
+}
+
+# add a latency to authentication operations
+#   default to 400ms
+#   [x] = x ms
+#   [x,y] = randomly between x and y ms
+#   others = invalid
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_authenticate_latency"
+    type: IntegerList
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_authenticate_latency"
+}
+
+# add a latency to detectInteraction operations
+#   refer to `operation_authenticate_latency` above for usage
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_latency"
+    type: IntegerList
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_detect_interaction_latency"
+}
+
+# add a latency to enroll operations
+#   refer to `operation_authenticate_latency` above for usage
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_enroll_latency"
+    type: IntegerList
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_enroll_latency"
+}
+
+# millisecond duration for authenticate operations
+# (waits for changes to enrollment_hit)
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_authenticate_duration"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_authenticate_duration"
+}
+
+# insert error for authenticate operations
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_authenticate_error"
+}
+
+# sensor location
+#    <x>:<y>:<radius> in pixel
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.sensor_location"
+    type: String
+    scope: Internal
+    access: ReadWrite
+    api_name: "sensor_location"
+}
+
+# acquired info during authentication in format of sequence
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
+    type: String
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_authenticate_acquired"
+}
+
+# millisecond duration for detect interaction operations
+# (waits for changes to enrollment_hit)
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_detect_interaction_duration"
+}
+
+# acquired info during detect interaction operation in format of sequence
+# e.g. 5,6,1  (TOO_SLOW, TOO_FAST, GOOD)
+# onAcquired() callback will be invoked in sequence
+# vendorAcquiredCode = (acquired>1000) ? acquired-1000 : 0
+prop {
+    prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
+    type: String
+    scope: Internal
+    access: ReadWrite
+    api_name: "operation_detect_interaction_acquired"
+}
+
+# sensor id (default: 5)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "sensor_id"
+}
+
+# sensor strength (default: 2)
+# [0=CONVENECE, 1=WEAK, 2=STRONG]
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "sensor_strength"
+}
+
+# max enrollments per user (default: 5)
+#
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "max_enrollments"
+}
+
+# whether support navigation guestures (default: false)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
+    type: Boolean
+    scope: Internal
+    access: ReadWrite
+    api_name: "navigation_guesture"
+}
+
+# whether support detect interaction (default: false)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
+    type: Boolean
+    scope: Internal
+    access: ReadWrite
+    api_name: "detect_interaction"
+}
+
+# whether support display touch by hal (default: true)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
+    type: Boolean
+    scope: Internal
+    access: ReadWrite
+    api_name: "display_touch"
+}
+
+# whether support illumination control  by hal (default: false)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
+    type: Boolean
+    scope: Internal
+    access: ReadWrite
+    api_name: "control_illumination"
+}
+
+# force to be locked out (default: false)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.lockout"
+    type: Boolean
+    scope: Internal
+    access: ReadWrite
+    api_name: "lockout"
+}
+
+# whether support lockout based on the failed auth attempts (default: false)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.lockout_enable"
+    type: Boolean
+    scope: Internal
+    access: ReadWrite
+    api_name: "lockout_enable"
+}
+
+# temporarily lockout threshold in number of consecutive failed auth attempts (default: 5)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.lockout_timed_threshold"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "lockout_timed_threshold"
+}
+
+# temporary lockout duration in ms (default: 10000ms)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.lockout_timed_duration"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "lockout_timed_duration"
+}
+
+# permanently lockout threshold  in number of consecutive failed auth attempts (default: 20)
+prop {
+    prop_name: "persist.vendor.fingerprint.virtual.lockout_permanent_threshold"
+    type: Integer
+    scope: Internal
+    access: ReadWrite
+    api_name: "lockout_permanent_threshold"
+}
diff --git a/biometrics/fingerprint/aidl/default/include/Callable.h b/biometrics/fingerprint/aidl/default/include/Callable.h
deleted file mode 100644
index c629511..0000000
--- a/biometrics/fingerprint/aidl/default/include/Callable.h
+++ /dev/null
@@ -1,54 +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.
- */
-
-#pragma once
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-// Interface for representing parameterless functions. Unlike std::function<void()>, this can also
-// represent move-only lambdas.
-class Callable {
-  public:
-    virtual void operator()() = 0;
-    virtual ~Callable() = default;
-
-    // Creates a heap-allocated Callable instance from any function object.
-    template <typename T>
-    static std::unique_ptr<Callable> from(T func);
-
-  private:
-    template <typename T>
-    class AnyFuncWrapper;
-};
-
-// Private helper class for wrapping any function object into a Callable.
-template <typename T>
-class Callable::AnyFuncWrapper : public Callable {
-  public:
-    explicit AnyFuncWrapper(T func) : mFunc(std::move(func)) {}
-
-    void operator()() override { mFunc(); }
-
-  private:
-    T mFunc;
-};
-
-template <typename T>
-std::unique_ptr<Callable> Callable::from(T func) {
-    return std::make_unique<AnyFuncWrapper<T>>(std::move(func));
-}
-
-}  // namespace aidl::android::hardware::biometrics::fingerprint
\ No newline at end of file
diff --git a/biometrics/fingerprint/aidl/default/include/CancellationSignal.h b/biometrics/fingerprint/aidl/default/include/CancellationSignal.h
deleted file mode 100644
index 99f2fba..0000000
--- a/biometrics/fingerprint/aidl/default/include/CancellationSignal.h
+++ /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.
- */
-
-#pragma once
-
-#include <aidl/android/hardware/biometrics/common/BnCancellationSignal.h>
-#include <aidl/android/hardware/biometrics/fingerprint/ISessionCallback.h>
-#include <functional>
-#include <future>
-
-#include "WorkerThread.h"
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-class CancellationSignal : public common::BnCancellationSignal {
-  public:
-    explicit CancellationSignal(std::promise<void>&& cancellationPromise);
-
-    ndk::ScopedAStatus cancel() override;
-
-  private:
-    std::promise<void> mCancellationPromise;
-};
-
-// Returns whether the given cancellation future is ready, i.e. whether the operation corresponding
-// to this future should be cancelled.
-bool shouldCancel(const std::future<void>& cancellationFuture);
-
-}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index b927770..1279cd9 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,73 +16,83 @@
 
 #pragma once
 
-#include <android-base/logging.h>
+#define LOG_TAG "FingerprintVirtualHal"
+
+#include <aidl/android/hardware/biometrics/common/SensorStrength.h>
+#include <aidl/android/hardware/biometrics/fingerprint/ISessionCallback.h>
+#include <android/binder_to_string.h>
+#include <string>
+
 #include <random>
 
+#include <aidl/android/hardware/biometrics/fingerprint/SensorLocation.h>
+#include <future>
+#include <vector>
+
+#include "FakeLockoutTracker.h"
+
+using namespace ::aidl::android::hardware::biometrics::common;
+
 namespace aidl::android::hardware::biometrics::fingerprint {
 
+// A fake engine that is backed by system properties instead of hardware.
 class FakeFingerprintEngine {
   public:
     FakeFingerprintEngine() : mRandom(std::mt19937::default_seed) {}
+    virtual ~FakeFingerprintEngine() {}
 
-    void generateChallengeImpl(ISessionCallback* cb) {
-        LOG(INFO) << "generateChallengeImpl";
-        std::uniform_int_distribution<int64_t> dist;
-        auto challenge = dist(mRandom);
-        cb->onChallengeGenerated(challenge);
-    }
+    void generateChallengeImpl(ISessionCallback* cb);
+    void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge);
+    virtual void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+                            const std::future<void>& cancel);
+    virtual void authenticateImpl(ISessionCallback* cb, int64_t operationId,
+                                  const std::future<void>& cancel);
+    virtual void detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel);
+    void enumerateEnrollmentsImpl(ISessionCallback* cb);
+    void removeEnrollmentsImpl(ISessionCallback* cb, const std::vector<int32_t>& enrollmentIds);
+    void getAuthenticatorIdImpl(ISessionCallback* cb);
+    void invalidateAuthenticatorIdImpl(ISessionCallback* cb);
+    void resetLockoutImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/);
+    bool getSensorLocationConfig(SensorLocation& out);
 
-    void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
-        LOG(INFO) << "revokeChallengeImpl";
-        cb->onChallengeRevoked(challenge);
-    }
+    virtual ndk::ScopedAStatus onPointerDownImpl(int32_t pointerId, int32_t x, int32_t y,
+                                                 float minor, float major);
 
-    void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat) {
-        LOG(INFO) << "enrollImpl";
-        // Do proper HAT verification in the real implementation.
-        if (hat.mac.empty()) {
-            cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
-            return;
-        }
-        cb->onEnrollmentProgress(0 /* enrollmentId */, 0 /* remaining */);
-    }
+    virtual ndk::ScopedAStatus onPointerUpImpl(int32_t pointerId);
 
-    void authenticateImpl(ISessionCallback* cb, int64_t /* operationId */) {
-        LOG(INFO) << "authenticateImpl";
-        cb->onAuthenticationSucceeded(0 /* enrollmentId */, {} /* hat */);
-    }
+    virtual ndk::ScopedAStatus onUiReadyImpl();
 
-    void detectInteractionImpl(ISessionCallback* cb) {
-        LOG(INFO) << "detectInteractionImpl";
-        cb->onInteractionDetected();
-    }
+    virtual SensorLocation getSensorLocation();
 
-    void enumerateEnrollmentsImpl(ISessionCallback* cb) {
-        LOG(INFO) << "enumerateEnrollmentsImpl";
-        cb->onEnrollmentsEnumerated({} /* enrollmentIds */);
-    }
+    virtual SensorLocation defaultSensorLocation();
 
-    void removeEnrollmentsImpl(ISessionCallback* cb, const std::vector<int32_t>& enrollmentIds) {
-        LOG(INFO) << "removeEnrollmentsImpl";
-        cb->onEnrollmentsRemoved(enrollmentIds);
-    }
+    std::vector<int32_t> parseIntSequence(const std::string& str, const std::string& sep = ",");
 
-    void getAuthenticatorIdImpl(ISessionCallback* cb) {
-        LOG(INFO) << "getAuthenticatorIdImpl";
-        cb->onAuthenticatorIdRetrieved(0 /* authenticatorId */);
-    }
+    std::vector<std::vector<int32_t>> parseEnrollmentCapture(const std::string& str);
 
-    void invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
-        LOG(INFO) << "invalidateAuthenticatorIdImpl";
-        cb->onAuthenticatorIdInvalidated(0 /* newAuthenticatorId */);
-    }
-
-    void resetLockoutImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/) {
-        LOG(INFO) << "resetLockoutImpl";
-        cb->onLockoutCleared();
-    }
+    int32_t getLatency(const std::vector<std::optional<std::int32_t>>& latencyVec);
 
     std::mt19937 mRandom;
+
+    virtual std::string toString() const {
+        std::ostringstream os;
+        os << "----- FakeFingerprintEngine:: -----" << std::endl;
+        os << "acquiredVendorInfoBase:" << FINGERPRINT_ACQUIRED_VENDOR_BASE;
+        os << ", errorVendorBase:" << FINGERPRINT_ERROR_VENDOR_BASE << std::endl;
+        os << mLockoutTracker.toString();
+        return os.str();
+    }
+
+  private:
+    static constexpr int32_t FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
+    static constexpr int32_t FINGERPRINT_ERROR_VENDOR_BASE = 1000;
+    std::pair<AcquiredInfo, int32_t> convertAcquiredInfo(int32_t code);
+    std::pair<Error, int32_t> convertError(int32_t code);
+    bool parseEnrollmentCaptureSingle(const std::string& str,
+                                      std::vector<std::vector<int32_t>>& res);
+    int32_t getRandomInRange(int32_t bound1, int32_t bound2);
+
+    FakeLockoutTracker mLockoutTracker;
 };
 
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineRear.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineRear.h
new file mode 100644
index 0000000..14d5399
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineRear.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include "FakeFingerprintEngine.h"
+
+using namespace ::aidl::android::hardware::biometrics::common;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+// A fake engine that is backed by system properties instead of hardware.
+class FakeFingerprintEngineRear : public FakeFingerprintEngine {
+  public:
+    FakeFingerprintEngineRear() : FakeFingerprintEngine() {}
+    ~FakeFingerprintEngineRear() {}
+};
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h
new file mode 100644
index 0000000..c2fc005
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include "FakeFingerprintEngine.h"
+
+using namespace ::aidl::android::hardware::biometrics::common;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+// A fake engine that is backed by system properties instead of hardware.
+class FakeFingerprintEngineSide : public FakeFingerprintEngine {
+  public:
+    static constexpr int32_t defaultSensorLocationX = 0;
+    static constexpr int32_t defaultSensorLocationY = 600;
+    static constexpr int32_t defaultSensorRadius = 150;
+
+    FakeFingerprintEngineSide() : FakeFingerprintEngine() {}
+    ~FakeFingerprintEngineSide() {}
+
+    virtual SensorLocation defaultSensorLocation() override;
+};
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h
new file mode 100644
index 0000000..c5e93e7
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h
@@ -0,0 +1,82 @@
+/*
+ * 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 "FakeFingerprintEngine.h"
+
+using namespace ::aidl::android::hardware::biometrics::common;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+// A fake engine that is backed by system properties instead of hardware.
+class FakeFingerprintEngineUdfps : public FakeFingerprintEngine {
+  public:
+    static constexpr int32_t defaultSensorLocationX = 400;
+    static constexpr int32_t defaultSensorLocationY = 1600;
+    static constexpr int32_t defaultSensorRadius = 150;
+
+    static constexpr int32_t uiReadyTimeoutInMs = 5000;
+
+    FakeFingerprintEngineUdfps();
+    ~FakeFingerprintEngineUdfps() {}
+
+    ndk::ScopedAStatus onPointerDownImpl(int32_t pointerId, int32_t x, int32_t y, float minor,
+                                         float major) override;
+
+    ndk::ScopedAStatus onPointerUpImpl(int32_t pointerId) override;
+
+    ndk::ScopedAStatus onUiReadyImpl() override;
+
+    SensorLocation defaultSensorLocation() override;
+
+    void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+                    const std::future<void>& cancel);
+    void authenticateImpl(ISessionCallback* cb, int64_t operationId,
+                          const std::future<void>& cancel);
+    void detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel);
+
+    enum class WorkMode : int8_t { kIdle = 0, kAuthenticate, kEnroll, kDetectInteract };
+
+    WorkMode getWorkMode() { return mWorkMode; }
+
+    std::string toString() const {
+        std::ostringstream os;
+        os << FakeFingerprintEngine::toString();
+        os << "----- FakeFingerprintEngineUdfps -----" << std::endl;
+        os << "mWorkMode:" << (int)mWorkMode;
+        os << ", mUiReadyTime:" << mUiReadyTime;
+        os << ", mPointerDownTime:" << mPointerDownTime << std::endl;
+        return os.str();
+    }
+
+  private:
+    void onAuthenticateFingerDown();
+    void onEnrollFingerDown();
+    void onDetectInteractFingerDown();
+    void fingerDownAction();
+    void updateContext(WorkMode mode, ISessionCallback* cb, std::future<void>& cancel,
+                       int64_t operationId, const keymaster::HardwareAuthToken& hat);
+
+    WorkMode mWorkMode;
+    ISessionCallback* mCb;
+    keymaster::HardwareAuthToken mHat;
+    std::vector<std::future<void>> mCancelVec;
+    int64_t mOperationId;
+    int64_t mPointerDownTime;
+    int64_t mUiReadyTime;
+};
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h b/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
new file mode 100644
index 0000000..a1b6128
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_to_string.h>
+#include <stdint.h>
+#include <string>
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class FakeLockoutTracker {
+  public:
+    FakeLockoutTracker() : mFailedCount(0) {}
+    ~FakeLockoutTracker() {}
+
+    enum class LockoutMode : int8_t { kNone = 0, kTimed, kPermanent };
+
+    void reset();
+    LockoutMode getMode();
+    void addFailedAttempt();
+    int64_t getLockoutTimeLeft();
+    inline std::string toString() const {
+        std::ostringstream os;
+        os << "----- FakeLockoutTracker:: -----" << std::endl;
+        os << "FakeLockoutTracker::mFailedCount:" << mFailedCount;
+        os << ", FakeLockoutTracker::mCurrentMode:" << (int)mCurrentMode;
+        os << std::endl;
+        return os.str();
+    }
+
+  private:
+    int32_t mFailedCount;
+    int64_t mLockoutTimedStart;
+    LockoutMode mCurrentMode;
+};
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
index 7bd3d6d..fc4fb8d 100644
--- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
@@ -19,8 +19,12 @@
 #include <aidl/android/hardware/biometrics/fingerprint/BnFingerprint.h>
 
 #include "FakeFingerprintEngine.h"
+#include "FakeFingerprintEngineRear.h"
+#include "FakeFingerprintEngineSide.h"
+#include "FakeFingerprintEngineUdfps.h"
+
 #include "Session.h"
-#include "WorkerThread.h"
+#include "thread/WorkerThread.h"
 
 namespace aidl::android::hardware::biometrics::fingerprint {
 
@@ -33,11 +37,17 @@
     ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
                                      const std::shared_ptr<ISessionCallback>& cb,
                                      std::shared_ptr<ISession>* out) override;
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs);
+    binder_status_t handleShellCommand(int in, int out, int err, const char** argv, uint32_t argc);
 
   private:
+    void resetConfigToDefault();
+    void onHelp(int);
+
     std::unique_ptr<FakeFingerprintEngine> mEngine;
     WorkerThread mWorker;
     std::shared_ptr<Session> mSession;
+    FingerprintSensorType mSensorType;
 };
 
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h
index acd5def..526d579 100644
--- a/biometrics/fingerprint/aidl/default/include/Session.h
+++ b/biometrics/fingerprint/aidl/default/include/Session.h
@@ -20,7 +20,7 @@
 #include <aidl/android/hardware/biometrics/fingerprint/ISessionCallback.h>
 
 #include "FakeFingerprintEngine.h"
-#include "WorkerThread.h"
+#include "thread/WorkerThread.h"
 
 namespace aidl::android::hardware::biometrics::fingerprint {
 
@@ -42,6 +42,8 @@
     RESETTING_LOCKOUT,
 };
 
+void onClientDeath(void* cookie);
+
 class Session : public BnSession {
   public:
     Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb,
@@ -97,6 +99,12 @@
 
     ndk::ScopedAStatus onContextChanged(const common::OperationContext& context) override;
 
+    ndk::ScopedAStatus onPointerCancelWithContext(const PointerContext& context) override;
+
+    ndk::ScopedAStatus setIgnoreDisplayTouches(bool shouldIgnore) override;
+
+    binder_status_t linkToDeath(AIBinder* binder);
+
     bool isClosed();
 
   private:
@@ -135,6 +143,9 @@
     // modified from both the main and the worker threads.
     std::atomic<SessionState> mScheduledState;
     std::atomic<SessionState> mCurrentState;
+
+    // Binder death handler.
+    AIBinder_DeathRecipient* mDeathRecipient;
 };
 
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/WorkerThread.h b/biometrics/fingerprint/aidl/default/include/WorkerThread.h
deleted file mode 100644
index 6fff4f2..0000000
--- a/biometrics/fingerprint/aidl/default/include/WorkerThread.h
+++ /dev/null
@@ -1,79 +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.
- */
-
-#pragma once
-
-#include <mutex>
-#include <optional>
-#include <queue>
-#include <thread>
-
-#include "Callable.h"
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-// A class that encapsulates a worker thread and a task queue, and provides a convenient interface
-// for a Session to schedule its tasks for asynchronous execution.
-class WorkerThread final {
-  public:
-    // Internally creates a queue that cannot exceed maxQueueSize elements and a new thread that
-    // polls the queue for tasks until this instance is destructed.
-    explicit WorkerThread(size_t maxQueueSize);
-
-    // Unblocks the internal queue and calls join on the internal thread allowing it to gracefully
-    // exit.
-    ~WorkerThread();
-
-    // Disallow copying this class.
-    WorkerThread(const WorkerThread&) = delete;
-    WorkerThread& operator=(const WorkerThread&) = delete;
-
-    // Also disable moving this class to simplify implementation.
-    WorkerThread(WorkerThread&&) = delete;
-    WorkerThread& operator=(WorkerThread&&) = delete;
-
-    // If the internal queue is not full, pushes a task at the end of the queue and returns true.
-    // Otherwise, returns false. If the queue is busy, blocks until it becomes available.
-    // This method expects heap-allocated tasks because it's the simplest way to represent function
-    // objects of any type. Stack-allocated std::function could be used instead, but it cannot
-    // represent functions with move-only captures because std::function is inherently copyable.
-    // Not being able to pass move-only lambdas is a major limitation for the HAL implementation,
-    // so heap-allocated tasks that share a common interface (Callable) were chosen instead.
-    bool schedule(std::unique_ptr<Callable> task);
-
-  private:
-    // The function that runs on the internal thread. Sequentially runs the available tasks from
-    // the queue. If the queue is empty, waits until a new task is added. If the worker is being
-    // destructed, finishes its current task and gracefully exits.
-    void threadFunc();
-
-    // The maximum size that the queue is allowed to expand to.
-    size_t mMaxSize;
-
-    // Whether the destructor was called. If true, tells threadFunc to exit as soon as possible, and
-    // tells schedule to avoid doing any work.
-    std::atomic<bool> mIsDestructing;
-
-    // Queue that's guarded by mQueueMutex and mQueueCond.
-    std::deque<std::unique_ptr<Callable>> mQueue;
-    std::mutex mQueueMutex;
-    std::condition_variable mQueueCond;
-
-    // The internal thread that works on the tasks from the queue.
-    std::thread mThread;
-};
-
-}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/main.cpp b/biometrics/fingerprint/aidl/default/main.cpp
index c985201..7df015b 100644
--- a/biometrics/fingerprint/aidl/default/main.cpp
+++ b/biometrics/fingerprint/aidl/default/main.cpp
@@ -27,9 +27,11 @@
     ABinderProcess_setThreadPoolMaxThreadCount(0);
     std::shared_ptr<Fingerprint> hal = ndk::SharedRefBase::make<Fingerprint>();
 
-    const std::string instance = std::string(Fingerprint::descriptor) + "/default";
-    binder_status_t status = AServiceManager_addService(hal->asBinder().get(), instance.c_str());
+    const std::string instance = std::string(Fingerprint::descriptor) + "/virtual";
+    binder_status_t status =
+            AServiceManager_registerLazyService(hal->asBinder().get(), instance.c_str());
     CHECK_EQ(status, STATUS_OK);
+    AServiceManager_forceLazyServicesPersist(true);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
new file mode 100644
index 0000000..a200b39
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_process.h>
+#include <fingerprint.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h>
+
+#include "FakeFingerprintEngine.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+using namespace ::aidl::android::hardware::biometrics::fingerprint;
+using namespace ::aidl::android::hardware::keymaster;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class TestSessionCallback : public BnSessionCallback {
+  public:
+    ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override {
+        mLastChallenge = challenge;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override {
+        mLastChallengeRevoked = challenge;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onError(fingerprint::Error error, int32_t vendorCode) override {
+        mError = error;
+        mErrorVendorCode = vendorCode;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
+        if (remaining == 0) mLastEnrolled = enrollmentId;
+        return ndk::ScopedAStatus::ok();
+    };
+
+    ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t enrollmentId,
+                                                   const keymaster::HardwareAuthToken&) override {
+        mLastAuthenticated = enrollmentId;
+        mAuthenticateFailed = false;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticationFailed() override {
+        mLastAuthenticated = 0;
+        mAuthenticateFailed = true;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onInteractionDetected() override {
+        mInteractionDetectedCount++;
+        return ndk::ScopedAStatus::ok();
+    };
+    ndk::ScopedAStatus onAcquired(AcquiredInfo info, int32_t vendorCode) override {
+        mLastAcquiredInfo = (int32_t)info;
+        mLastAcquiredVendorCode = vendorCode;
+        mLastAcquiredCount++;
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onEnrollmentsEnumerated(
+            const std::vector<int32_t>& enrollmentIds) override {
+        mLastEnrollmentEnumerated = enrollmentIds;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onEnrollmentsRemoved(const std::vector<int32_t>& enrollmentIds) override {
+        mLastEnrollmentRemoved = enrollmentIds;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t authenticatorId) override {
+        mLastAuthenticatorId = authenticatorId;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t authenticatorId) override {
+        mLastAuthenticatorId = authenticatorId;
+        mAuthenticatorIdInvalidated = true;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onLockoutPermanent() override {
+        mLockoutPermanent = true;
+        return ndk::ScopedAStatus::ok();
+    };
+    ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); }
+    ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
+
+    Error mError = Error::UNKNOWN;
+    int32_t mErrorVendorCode = 0;
+    int64_t mLastChallenge = -1;
+    int64_t mLastChallengeRevoked = -1;
+    int32_t mLastEnrolled = -1;
+    int32_t mLastAuthenticated = -1;
+    int64_t mLastAuthenticatorId = -1;
+    std::vector<int32_t> mLastEnrollmentEnumerated;
+    std::vector<int32_t> mLastEnrollmentRemoved;
+    bool mAuthenticateFailed = false;
+    bool mAuthenticatorIdInvalidated = false;
+    bool mLockoutPermanent = false;
+    int mInteractionDetectedCount = 0;
+    int32_t mLastAcquiredInfo = -1;
+    int32_t mLastAcquiredVendorCode = -1;
+    int32_t mLastAcquiredCount = 0;
+};
+
+class FakeFingerprintEngineTest : public ::testing::Test {
+  protected:
+    void SetUp() override {
+        FingerprintHalProperties::operation_enroll_latency({0});
+        FingerprintHalProperties::operation_authenticate_latency({0});
+        FingerprintHalProperties::operation_detect_interaction_latency({0});
+        mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
+    }
+
+    void TearDown() override {
+        FingerprintHalProperties::operation_authenticate_error(0);
+        FingerprintHalProperties::operation_detect_interaction_error(0);
+        FingerprintHalProperties::operation_authenticate_acquired("");
+        FingerprintHalProperties::operation_enroll_latency({});
+        FingerprintHalProperties::operation_authenticate_latency({});
+        FingerprintHalProperties::operation_detect_interaction_latency({});
+    }
+
+    FakeFingerprintEngine mEngine;
+    std::shared_ptr<TestSessionCallback> mCallback;
+    std::promise<void> mCancel;
+};
+
+TEST_F(FakeFingerprintEngineTest, GenerateChallenge) {
+    mEngine.generateChallengeImpl(mCallback.get());
+    ASSERT_EQ(FingerprintHalProperties::challenge().value(), mCallback->mLastChallenge);
+}
+
+TEST_F(FakeFingerprintEngineTest, RevokeChallenge) {
+    auto challenge = FingerprintHalProperties::challenge().value_or(10);
+    mEngine.revokeChallengeImpl(mCallback.get(), challenge);
+    ASSERT_FALSE(FingerprintHalProperties::challenge().has_value());
+    ASSERT_EQ(challenge, mCallback->mLastChallengeRevoked);
+}
+
+TEST_F(FakeFingerprintEngineTest, ResetLockout) {
+    FingerprintHalProperties::lockout(true);
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.resetLockoutImpl(mCallback.get(), hat);
+    ASSERT_FALSE(FingerprintHalProperties::lockout().value_or(true));
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticatorId) {
+    FingerprintHalProperties::enrollments({1});
+    FingerprintHalProperties::authenticator_id(50);
+    mEngine.getAuthenticatorIdImpl(mCallback.get());
+    ASSERT_EQ(50, mCallback->mLastAuthenticatorId);
+    ASSERT_FALSE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticatorIdInvalidate) {
+    FingerprintHalProperties::authenticator_id(500);
+    mEngine.invalidateAuthenticatorIdImpl(mCallback.get());
+    ASSERT_NE(500, FingerprintHalProperties::authenticator_id().value());
+    ASSERT_TRUE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFingerprintEngineTest, Enroll) {
+    FingerprintHalProperties::enrollments({});
+    FingerprintHalProperties::next_enrollment("4:0,0:true");
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+    ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
+    ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
+    ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
+    ASSERT_EQ(4, mCallback->mLastEnrolled);
+    ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+}
+
+TEST_F(FakeFingerprintEngineTest, EnrollCancel) {
+    FingerprintHalProperties::enrollments({});
+    auto next = "4:0,0:true";
+    FingerprintHalProperties::next_enrollment(next);
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mCancel.set_value();
+    mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+    ASSERT_EQ(Error::CANCELED, mCallback->mError);
+    ASSERT_EQ(-1, mCallback->mLastEnrolled);
+    ASSERT_EQ(0, FingerprintHalProperties::enrollments().size());
+    ASSERT_EQ(next, FingerprintHalProperties::next_enrollment().value_or(""));
+}
+
+TEST_F(FakeFingerprintEngineTest, EnrollFail) {
+    FingerprintHalProperties::enrollments({});
+    auto next = "2:0,0:false";
+    FingerprintHalProperties::next_enrollment(next);
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+    ASSERT_EQ(Error::UNABLE_TO_PROCESS, mCallback->mError);
+    ASSERT_EQ(-1, mCallback->mLastEnrolled);
+    ASSERT_EQ(0, FingerprintHalProperties::enrollments().size());
+    ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
+}
+
+TEST_F(FakeFingerprintEngineTest, EnrollAcquired) {
+    FingerprintHalProperties::enrollments({});
+    FingerprintHalProperties::next_enrollment("4:0,5-[12,1013]:true");
+    keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+    int32_t prevCnt = mCallback->mLastAcquiredCount;
+    mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+    ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
+    ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
+    ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
+    ASSERT_EQ(4, mCallback->mLastEnrolled);
+    ASSERT_EQ(prevCnt + 3, mCallback->mLastAcquiredCount);
+    ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+    ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
+}
+
+TEST_F(FakeFingerprintEngineTest, Authenticate) {
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(2);
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_FALSE(mCallback->mAuthenticateFailed);
+    ASSERT_EQ(2, mCallback->mLastAuthenticated);
+    ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateCancel) {
+    FingerprintHalProperties::enrollments({2});
+    FingerprintHalProperties::enrollment_hit(2);
+    mCancel.set_value();
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_EQ(Error::CANCELED, mCallback->mError);
+    ASSERT_EQ(-1, mCallback->mLastAuthenticated);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateNotSet) {
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit({});
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_TRUE(mCallback->mAuthenticateFailed);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateNotEnrolled) {
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(3);
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_TRUE(mCallback->mAuthenticateFailed);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateLockout) {
+    FingerprintHalProperties::enrollments({22, 2});
+    FingerprintHalProperties::enrollment_hit(2);
+    FingerprintHalProperties::lockout(true);
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_TRUE(mCallback->mLockoutPermanent);
+    ASSERT_NE(mCallback->mError, Error::UNKNOWN);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateError8) {
+    FingerprintHalProperties::operation_authenticate_error(8);
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_EQ(mCallback->mError, (Error)8);
+    ASSERT_EQ(mCallback->mErrorVendorCode, 0);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateError9) {
+    FingerprintHalProperties::operation_authenticate_error(1009);
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_EQ(mCallback->mError, (Error)7);
+    ASSERT_EQ(mCallback->mErrorVendorCode, 9);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateAcquired) {
+    FingerprintHalProperties::lockout(false);
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(2);
+    FingerprintHalProperties::operation_authenticate_acquired("4,1009");
+    int32_t prevCount = mCallback->mLastAcquiredCount;
+    mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+    ASSERT_FALSE(mCallback->mAuthenticateFailed);
+    ASSERT_EQ(2, mCallback->mLastAuthenticated);
+    ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
+    ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+    ASSERT_EQ(9, mCallback->mLastAcquiredVendorCode);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetect) {
+    FingerprintHalProperties::detect_interaction(true);
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(2);
+    FingerprintHalProperties::operation_detect_interaction_acquired("");
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+    ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectCancel) {
+    FingerprintHalProperties::detect_interaction(true);
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(2);
+    mCancel.set_value();
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(Error::CANCELED, mCallback->mError);
+    ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectNotSet) {
+    FingerprintHalProperties::detect_interaction(true);
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit({});
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectNotEnrolled) {
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(25);
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectError) {
+    FingerprintHalProperties::detect_interaction(true);
+    FingerprintHalProperties::operation_detect_interaction_error(8);
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+    ASSERT_EQ(mCallback->mError, (Error)8);
+    ASSERT_EQ(mCallback->mErrorVendorCode, 0);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectAcquired) {
+    FingerprintHalProperties::detect_interaction(true);
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(2);
+    FingerprintHalProperties::operation_detect_interaction_acquired("4,1013");
+    int32_t prevCount = mCallback->mLastAcquiredCount;
+    mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+    ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+    ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
+    ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+    ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
+}
+
+TEST_F(FakeFingerprintEngineTest, EnumerateEnrolled) {
+    FingerprintHalProperties::enrollments({2, 4, 8});
+    mEngine.enumerateEnrollmentsImpl(mCallback.get());
+    ASSERT_EQ(
+            4,
+            mCallback->mLastEnrollmentEnumerated.size());  // Due to workaround. TODO (b/243129174)
+    for (auto id : FingerprintHalProperties::enrollments()) {
+        ASSERT_TRUE(std::find(mCallback->mLastEnrollmentEnumerated.begin(),
+                              mCallback->mLastEnrollmentEnumerated.end(),
+                              id) != mCallback->mLastEnrollmentEnumerated.end());
+    }
+}
+
+TEST_F(FakeFingerprintEngineTest, RemoveEnrolled) {
+    FingerprintHalProperties::enrollments({2, 4, 8, 1});
+    mEngine.removeEnrollmentsImpl(mCallback.get(), {2, 8});
+    auto enrolls = FingerprintHalProperties::enrollments();
+    ASSERT_EQ(2, mCallback->mLastEnrollmentRemoved.size());
+    for (auto id : {2, 8}) {
+        ASSERT_TRUE(std::find(mCallback->mLastEnrollmentRemoved.begin(),
+                              mCallback->mLastEnrollmentRemoved.end(),
+                              id) != mCallback->mLastEnrollmentRemoved.end());
+    }
+    ASSERT_EQ(2, enrolls.size());
+    for (auto id : {1, 4}) {
+        ASSERT_TRUE(std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end());
+    }
+}
+
+TEST_F(FakeFingerprintEngineTest, parseIntSequence) {
+    std::vector<int32_t> seqV;
+    seqV = mEngine.parseIntSequence("");
+    ASSERT_EQ(0, seqV.size());
+    seqV = mEngine.parseIntSequence("2");
+    ASSERT_EQ(1, seqV.size());
+    ASSERT_EQ(2, seqV[0]);
+    seqV = mEngine.parseIntSequence("2,3,4");
+    std::vector<int32_t> expV{2, 3, 4};
+    ASSERT_EQ(expV, seqV);
+    seqV = mEngine.parseIntSequence("2,3,a");
+    ASSERT_EQ(0, seqV.size());
+    seqV = mEngine.parseIntSequence("2, 3, 4");
+    ASSERT_EQ(expV, seqV);
+    seqV = mEngine.parseIntSequence("123,456");
+    ASSERT_EQ(2, seqV.size());
+    std::vector<int32_t> expV1{123, 456};
+    ASSERT_EQ(expV1, seqV);
+    seqV = mEngine.parseIntSequence("12f3,456");
+    ASSERT_EQ(0, seqV.size());
+}
+
+TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureOk) {
+    std::vector<std::vector<int32_t>> ecV;
+    ecV = mEngine.parseEnrollmentCapture("100,200,300");
+    ASSERT_EQ(6, ecV.size());
+    std::vector<std::vector<int32_t>> expE{{100}, {200}, {300}};
+    std::vector<int32_t> defC{1};
+    for (int i = 0; i < ecV.size(); i += 2) {
+        ASSERT_EQ(expE[i / 2], ecV[i]);
+        ASSERT_EQ(defC, ecV[i + 1]);
+    }
+    ecV = mEngine.parseEnrollmentCapture("100");
+    ASSERT_EQ(2, ecV.size());
+    ASSERT_EQ(expE[0], ecV[0]);
+    ASSERT_EQ(defC, ecV[1]);
+
+    ecV = mEngine.parseEnrollmentCapture("100-[5,6,7]");
+    std::vector<int32_t> expC{5, 6, 7};
+    ASSERT_EQ(2, ecV.size());
+    for (int i = 0; i < ecV.size(); i += 2) {
+        ASSERT_EQ(expE[i / 2], ecV[i]);
+        ASSERT_EQ(expC, ecV[i + 1]);
+    }
+    ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200, 300-[9,10]");
+    std::vector<std::vector<int32_t>> expC1{{5, 6, 7}, {1}, {9, 10}};
+    ASSERT_EQ(6, ecV.size());
+    for (int i = 0; i < ecV.size(); i += 2) {
+        ASSERT_EQ(expE[i / 2], ecV[i]);
+        ASSERT_EQ(expC1[i / 2], ecV[i + 1]);
+    }
+    ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200-[2,1], 300-[9]");
+    std::vector<std::vector<int32_t>> expC2{{5, 6, 7}, {2, 1}, {9}};
+    ASSERT_EQ(ecV.size(), 6);
+    for (int i = 0; i < ecV.size(); i += 2) {
+        ASSERT_EQ(expE[i / 2], ecV[i]);
+        ASSERT_EQ(expC2[i / 2], ecV[i + 1]);
+    }
+}
+
+TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureFail) {
+    std::vector<std::string> badStr{"10c",         "100-5",   "100-[5,6,7", "100-5,6,7]",
+                                    "100,2x0,300", "200-[f]", "a,b"};
+    std::vector<std::vector<int32_t>> ecV;
+    for (const auto& s : badStr) {
+        ecV = mEngine.parseEnrollmentCapture(s);
+        ASSERT_EQ(ecV.size(), 0);
+    }
+}
+
+TEST_F(FakeFingerprintEngineTest, randomLatency) {
+    FingerprintHalProperties::operation_detect_interaction_latency({});
+    ASSERT_EQ(DEFAULT_LATENCY,
+              mEngine.getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
+    FingerprintHalProperties::operation_detect_interaction_latency({10});
+    ASSERT_EQ(10,
+              mEngine.getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
+    FingerprintHalProperties::operation_detect_interaction_latency({1, 1000});
+    std::set<int32_t> latencySet;
+    for (int i = 0; i < 100; i++) {
+        latencySet.insert(mEngine.getLatency(
+                FingerprintHalProperties::operation_detect_interaction_latency()));
+    }
+    ASSERT_TRUE(latencySet.size() > 95);
+    FingerprintHalProperties::operation_detect_interaction_latency({});
+}
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
new file mode 100644
index 0000000..f551899
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h>
+#include <android/binder_process.h>
+#include <fingerprint.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+#include "FakeFingerprintEngine.h"
+#include "FakeFingerprintEngineUdfps.h"
+
+using namespace ::android::fingerprint::virt;
+using namespace ::aidl::android::hardware::biometrics::fingerprint;
+using namespace ::aidl::android::hardware::keymaster;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class TestSessionCallback : public BnSessionCallback {
+  public:
+    ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onError(fingerprint::Error /*error*/, int32_t /*vendorCode*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
+                                              int32_t /*remaining*/) override {
+        mEnrollmentProgress++;
+        return ndk::ScopedAStatus::ok();
+    };
+
+    ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
+                                                   const keymaster::HardwareAuthToken&) override {
+        mAuthenticationSuccess++;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticationFailed() override {
+        mAuthenticationFailure++;
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onInteractionDetected() override {
+        mDetectInteraction++;
+        return ndk::ScopedAStatus::ok();
+    };
+    ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onEnrollmentsEnumerated(
+            const std::vector<int32_t>& /*enrollmentIds*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onEnrollmentsRemoved(
+            const std::vector<int32_t>& /*enrollmentIds*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*authenticatorId*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); };
+    ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); }
+    ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
+
+    int32_t getAuthenticationCount() { return mAuthenticationSuccess + mAuthenticationFailure; }
+    int32_t getDetectInteractionCount() { return mDetectInteraction; }
+
+    int32_t mAuthenticationSuccess = 0;
+    int32_t mAuthenticationFailure = 0;
+    int32_t mEnrollmentProgress = 0;
+    int32_t mDetectInteraction = 0;
+};
+
+class FakeFingerprintEngineUdfpsTest : public ::testing::Test {
+  protected:
+    void SetUp() override {}
+
+    void TearDown() override {
+        // reset to default
+        FingerprintHalProperties::sensor_location("");
+    }
+
+    FakeFingerprintEngineUdfps mEngine;
+};
+
+bool isDefaultLocation(SensorLocation& sc) {
+    return (sc.sensorLocationX == FakeFingerprintEngineUdfps::defaultSensorLocationX &&
+            sc.sensorLocationY == FakeFingerprintEngineUdfps::defaultSensorLocationY &&
+            sc.sensorRadius == FakeFingerprintEngineUdfps::defaultSensorRadius && sc.display == "");
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationOk) {
+    auto loc = "100:200:30";
+    FingerprintHalProperties::sensor_location(loc);
+    SensorLocation sc = mEngine.getSensorLocation();
+    ASSERT_TRUE(sc.sensorLocationX == 100);
+    ASSERT_TRUE(sc.sensorLocationY == 200);
+    ASSERT_TRUE(sc.sensorRadius == 30);
+
+    loc = "100:200:30:screen1";
+    FingerprintHalProperties::sensor_location(loc);
+    sc = mEngine.getSensorLocation();
+    ASSERT_TRUE(sc.sensorLocationX == 100);
+    ASSERT_TRUE(sc.sensorLocationY == 200);
+    ASSERT_TRUE(sc.sensorRadius == 30);
+    ASSERT_TRUE(sc.display == "screen1");
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationBad) {
+    const std::vector<std::string> badStr{"", "100", "10:20", "10,20,5", "a:b:c"};
+    SensorLocation sc;
+    for (const auto& s : badStr) {
+        FingerprintHalProperties::sensor_location(s);
+        sc = mEngine.getSensorLocation();
+        ASSERT_TRUE(isDefaultLocation(sc));
+    }
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, initialization) {
+    ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kIdle);
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, authenticate) {
+    std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
+    std::promise<void> cancel;
+    mEngine.authenticateImpl(cb.get(), 1, cancel.get_future());
+    ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kAuthenticate);
+    mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
+    ASSERT_EQ(cb->getAuthenticationCount(), 0);
+    mEngine.onUiReadyImpl();
+    ASSERT_EQ(cb->getAuthenticationCount(), 1);
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, enroll) {
+    std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
+    std::promise<void> cancel;
+    keymaster::HardwareAuthToken hat{.mac = {5, 6}};
+    FingerprintHalProperties::next_enrollment("5:0,0:true");
+    mEngine.enrollImpl(cb.get(), hat, cancel.get_future());
+    ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kEnroll);
+    mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
+    ASSERT_EQ(cb->mEnrollmentProgress, 0);
+    mEngine.onUiReadyImpl();
+    ASSERT_TRUE(cb->mEnrollmentProgress > 0);
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, detectInteraction) {
+    FingerprintHalProperties::detect_interaction(true);
+    FingerprintHalProperties::enrollments({1, 2});
+    FingerprintHalProperties::enrollment_hit(2);
+    FingerprintHalProperties::operation_detect_interaction_acquired("");
+    std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
+    std::promise<void> cancel;
+    mEngine.detectInteractionImpl(cb.get(), cancel.get_future());
+    ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kDetectInteract);
+    mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
+    ASSERT_EQ(cb->getDetectInteractionCount(), 0);
+    mEngine.onUiReadyImpl();
+    ASSERT_EQ(cb->getDetectInteractionCount(), 1);
+}
+// More
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
new file mode 100644
index 0000000..1b071ee
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_process.h>
+#include <fingerprint.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+#include "FakeLockoutTracker.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+using namespace ::aidl::android::hardware::biometrics::fingerprint;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class FakeLockoutTrackerTest : public ::testing::Test {
+  protected:
+    static constexpr int32_t LOCKOUT_TIMED_THRESHOLD = 3;
+    static constexpr int32_t LOCKOUT_PERMANENT_THRESHOLD = 5;
+    static constexpr int32_t LOCKOUT_TIMED_DURATION = 100;
+
+    void SetUp() override {
+        FingerprintHalProperties::lockout_timed_threshold(LOCKOUT_TIMED_THRESHOLD);
+        FingerprintHalProperties::lockout_timed_duration(LOCKOUT_TIMED_DURATION);
+        FingerprintHalProperties::lockout_permanent_threshold(LOCKOUT_PERMANENT_THRESHOLD);
+    }
+
+    void TearDown() override {
+        // reset to default
+        FingerprintHalProperties::lockout_timed_threshold(5);
+        FingerprintHalProperties::lockout_timed_duration(20);
+        FingerprintHalProperties::lockout_permanent_threshold(10000);
+        FingerprintHalProperties::lockout_enable(false);
+        FingerprintHalProperties::lockout(false);
+    }
+
+    FakeLockoutTracker mLockoutTracker;
+};
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptDisable) {
+    FingerprintHalProperties::lockout_enable(false);
+    for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD + 1; i++) mLockoutTracker.addFailedAttempt();
+    ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+    mLockoutTracker.reset();
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimed) {
+    FingerprintHalProperties::lockout_enable(true);
+    for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++) mLockoutTracker.addFailedAttempt();
+    ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
+    // time left
+    int N = 5;
+    int64_t prevTimeLeft = INT_MIN;
+    for (int i = 0; i < N; i++) {
+        SLEEP_MS(LOCKOUT_TIMED_DURATION / N + 1);
+        int64_t currTimeLeft = mLockoutTracker.getLockoutTimeLeft();
+        ASSERT_TRUE(currTimeLeft > prevTimeLeft);
+        prevTimeLeft = currTimeLeft;
+    }
+    ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+    mLockoutTracker.reset();
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptPermanent) {
+    FingerprintHalProperties::lockout_enable(true);
+    for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD - 1; i++) mLockoutTracker.addFailedAttempt();
+    ASSERT_NE(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+    mLockoutTracker.addFailedAttempt();
+    ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+    ASSERT_TRUE(FingerprintHalProperties::lockout());
+    mLockoutTracker.reset();
+}
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/biometrics/fingerprint/aidl/default/tests/SessionTest.cpp b/biometrics/fingerprint/aidl/default/tests/SessionTest.cpp
new file mode 100644
index 0000000..3b96d7f
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/tests/SessionTest.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_process.h>
+#include <fingerprint.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+#include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h>
+
+#include "Session.h"
+#include "thread/WorkerThread.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+using namespace ::aidl::android::hardware::biometrics::fingerprint;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class TestSessionCallback : public BnSessionCallback {
+  public:
+    ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onError(fingerprint::Error /*error*/, int32_t /*vendorCode*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
+                                              int32_t /*remaining*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+
+    ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
+                                                   const keymaster::HardwareAuthToken&) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); };
+    ::ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); };
+    ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onEnrollmentsEnumerated(
+            const std::vector<int32_t>& /*enrollmentIds*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onEnrollmentsRemoved(
+            const std::vector<int32_t>& /*enrollmentIds*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*authenticatorId*/) override {
+        return ndk::ScopedAStatus::ok();
+    };
+    ::ndk::ScopedAStatus onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); };
+    ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); }
+    ndk::ScopedAStatus onSessionClosed() override {
+        mIsClosed = true;
+        return ndk::ScopedAStatus::ok();
+    }
+
+    bool mIsClosed = false;
+};
+
+class SessionTest : public ::testing::Test {
+  public:
+    SessionTest() : mWorker(2) {}
+
+  protected:
+    void SetUp() override {
+        mCb = ndk::SharedRefBase::make<TestSessionCallback>();
+        mSession = ndk::SharedRefBase::make<Session>(1, 2, mCb, &mFakeFingerprintEngine, &mWorker);
+        ASSERT_TRUE(mSession != nullptr);
+        mSession->linkToDeath(mCb->asBinder().get());
+    }
+
+    void TearDown() override {}
+
+    std::shared_ptr<Session> mSession;
+    std::shared_ptr<TestSessionCallback> mCb;
+
+  private:
+    FakeFingerprintEngine mFakeFingerprintEngine;
+    WorkerThread mWorker;
+};
+
+TEST_F(SessionTest, close) {
+    ASSERT_TRUE(!mSession->isClosed());
+    ASSERT_TRUE(!mCb->mIsClosed);
+    onClientDeath(nullptr);
+    ASSERT_TRUE(!mSession->isClosed());
+    ASSERT_TRUE(!mCb->mIsClosed);
+    onClientDeath(static_cast<void*>(mSession.get()));
+    ASSERT_TRUE(mSession->isClosed());
+    ASSERT_TRUE(mCb->mIsClosed);
+}
+
+}  //  namespace aidl::android::hardware::biometrics::fingerprint
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
deleted file mode 100644
index 902fb40..0000000
--- a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
+++ /dev/null
@@ -1,139 +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 <algorithm>
-#include <chrono>
-#include <future>
-#include <thread>
-
-#include <gtest/gtest.h>
-
-#include "WorkerThread.h"
-
-namespace {
-
-using aidl::android::hardware::biometrics::fingerprint::Callable;
-using aidl::android::hardware::biometrics::fingerprint::WorkerThread;
-using namespace std::chrono_literals;
-
-TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) {
-    WorkerThread worker(1 /*maxQueueSize*/);
-    for (int i = 0; i < 100; ++i) {
-        std::promise<void> promise;
-        auto future = promise.get_future();
-
-        ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
-            // Notify that the task has started.
-            promise.set_value();
-        })));
-
-        future.wait();
-    }
-}
-
-TEST(WorkerThreadTest, ScheduleReturnsFalseWhenQueueIsFull) {
-    WorkerThread worker(2 /*maxQueueSize*/);
-
-    std::promise<void> promise;
-    auto future = promise.get_future();
-
-    // Schedule a long-running task.
-    ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
-        // Notify that the task has started.
-        promise.set_value();
-        // Block for a "very long" time.
-        std::this_thread::sleep_for(1s);
-    })));
-
-    // Make sure the long-running task began executing.
-    future.wait();
-
-    // The first task is already being worked on, which means the queue must be empty.
-    // Fill the worker's queue to the maximum.
-    ASSERT_TRUE(worker.schedule(Callable::from([] {})));
-    ASSERT_TRUE(worker.schedule(Callable::from([] {})));
-
-    EXPECT_FALSE(worker.schedule(Callable::from([] {})));
-}
-
-TEST(WorkerThreadTest, TasksExecuteInOrder) {
-    constexpr int NUM_TASKS = 10000;
-    WorkerThread worker(NUM_TASKS + 1);
-
-    std::mutex mut;
-    std::condition_variable cv;
-    bool finished = false;
-    std::vector<int> results;
-
-    for (int i = 0; i < NUM_TASKS; ++i) {
-        worker.schedule(Callable::from([&mut, &results, i] {
-            // Delay tasks differently to provoke races.
-            std::this_thread::sleep_for(std::chrono::nanoseconds(100 - i % 100));
-            auto lock = std::lock_guard(mut);
-            results.push_back(i);
-        }));
-    }
-
-    // Schedule a special task to signal when all of the tasks are finished.
-    worker.schedule(Callable::from([&mut, &cv, &finished] {
-        auto lock = std::lock_guard(mut);
-        finished = true;
-        cv.notify_one();
-    }));
-
-    auto lock = std::unique_lock(mut);
-    cv.wait(lock, [&finished] { return finished; });
-    ASSERT_EQ(results.size(), NUM_TASKS);
-    EXPECT_TRUE(std::is_sorted(results.begin(), results.end()));
-}
-
-TEST(WorkerThreadTest, ExecutionStopsAfterWorkerIsDestroyed) {
-    std::promise<void> promise1;
-    std::promise<void> promise2;
-    auto future1 = promise1.get_future();
-    auto future2 = promise2.get_future();
-    std::atomic<bool> value;
-
-    // Local scope for the worker to test its destructor when it goes out of scope.
-    {
-        WorkerThread worker(2 /*maxQueueSize*/);
-
-        ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise1)]() mutable {
-            promise.set_value();
-            std::this_thread::sleep_for(200ms);
-        })));
-
-        // The first task should start executing.
-        future1.wait();
-
-        // The second task should schedule successfully.
-        ASSERT_TRUE(
-                worker.schedule(Callable::from([promise = std::move(promise2), &value]() mutable {
-                    // The worker should destruct before it gets a chance to execute this.
-                    value = true;
-                    promise.set_value();
-                })));
-    }
-
-    // The second task should never execute.
-    future2.wait();
-    // The future is expected to be ready but contain an exception.
-    // Cannot use ASSERT_THROW because exceptions are disabled in this codebase.
-    // ASSERT_THROW(future2.get(), std::future_error);
-    EXPECT_FALSE(value);
-}
-
-}  // namespace
diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp
index 30d5624..1652905 100644
--- a/biometrics/fingerprint/aidl/vts/Android.bp
+++ b/biometrics/fingerprint/aidl/vts/Android.bp
@@ -15,9 +15,9 @@
     ],
     srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"],
     static_libs: [
-        "android.hardware.biometrics.common-V1-ndk",
-        "android.hardware.biometrics.fingerprint-V1-ndk",
-        "android.hardware.keymaster-V3-ndk",
+        "android.hardware.biometrics.common-V3-ndk",
+        "android.hardware.biometrics.fingerprint-V3-ndk",
+        "android.hardware.keymaster-V4-ndk",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/bluetooth/1.0/Android.bp b/bluetooth/1.0/Android.bp
index 20775dd..bd1ca69 100644
--- a/bluetooth/1.0/Android.bp
+++ b/bluetooth/1.0/Android.bp
@@ -23,6 +23,6 @@
     gen_java: true,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
     ],
 }
diff --git a/bluetooth/1.0/default/OWNERS b/bluetooth/1.0/default/OWNERS
deleted file mode 100644
index 5df5bfe..0000000
--- a/bluetooth/1.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-eisenbach@google.com
-mylesgw@google.com
-pavlin@google.com
diff --git a/bluetooth/1.0/default/bluetooth_hci.cc b/bluetooth/1.0/default/bluetooth_hci.cc
index a2211f4..869c723 100644
--- a/bluetooth/1.0/default/bluetooth_hci.cc
+++ b/bluetooth/1.0/default/bluetooth_hci.cc
@@ -33,7 +33,8 @@
 
 class BluetoothDeathRecipient : public hidl_death_recipient {
  public:
-  BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
+  BluetoothDeathRecipient(const sp<IBluetoothHci> hci)
+    : mHci(hci), has_died_(false) {}
 
   virtual void serviceDied(
       uint64_t /*cookie*/,
@@ -51,7 +52,7 @@
 };
 
 BluetoothHci::BluetoothHci()
-    : death_recipient_(new BluetoothDeathRecipient(this)) {}
+    : death_recipient_(new BluetoothDeathRecipient(this)) {bt_enabled = 0;}
 
 Return<void> BluetoothHci::initialize(
     const ::android::sp<IBluetoothHciCallbacks>& cb) {
@@ -61,8 +62,19 @@
     return Void();
   }
 
+  if (bt_enabled == 1) {
+    ALOGE("initialize was called!");
+    return Void();
+  }
+  bt_enabled = 1;
   death_recipient_->setHasDied(false);
   cb->linkToDeath(death_recipient_, 0);
+  unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
+    if (death_recipient->getHasDied())
+      ALOGI("Skipping unlink call, service died.");
+    else
+      cb->unlinkToDeath(death_recipient);
+  };
 
   bool rc = VendorInterface::Initialize(
       [cb](bool status) {
@@ -112,6 +124,12 @@
 
 Return<void> BluetoothHci::close() {
   ALOGI("BluetoothHci::close()");
+
+  if (bt_enabled != 1) {
+    ALOGE("should initialize first!");
+    return Void();
+  }
+  bt_enabled = 0;
   unlink_cb_(death_recipient_);
   VendorInterface::Shutdown();
   return Void();
@@ -134,6 +152,11 @@
 
 void BluetoothHci::sendDataToController(const uint8_t type,
                                         const hidl_vec<uint8_t>& data) {
+  if (bt_enabled != 1) {
+    ALOGE("should initialize first!");
+    return;
+  }
+
   VendorInterface::get()->Send(type, data.data(), data.size());
 }
 
diff --git a/bluetooth/1.0/default/bluetooth_hci.h b/bluetooth/1.0/default/bluetooth_hci.h
index c966990..5130c87 100644
--- a/bluetooth/1.0/default/bluetooth_hci.h
+++ b/bluetooth/1.0/default/bluetooth_hci.h
@@ -48,6 +48,7 @@
   void sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data);
   ::android::sp<BluetoothDeathRecipient> death_recipient_;
   std::function<void(sp<BluetoothDeathRecipient>&)> unlink_cb_;
+  int bt_enabled;
 };
 
 extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
diff --git a/bluetooth/1.0/default/test/fuzzer/Android.bp b/bluetooth/1.0/default/test/fuzzer/Android.bp
index 691136f..de2b46d 100644
--- a/bluetooth/1.0/default/test/fuzzer/Android.bp
+++ b/bluetooth/1.0/default/test/fuzzer/Android.bp
@@ -60,5 +60,13 @@
             "android-media-fuzzing-reports@google.com",
         ],
         componentid: 533764,
+        hotlists: [
+            "4593311",
+        ],
+        description: "The fuzzer targets the APIs of android.hardware.bluetooth@1.0-impl library",
+        vector: "local_no_privileges_required",
+        service_privilege: "privileged",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
     },
 }
diff --git a/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp b/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp
index 90cdc66..fb8df99 100644
--- a/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp
+++ b/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp
@@ -88,11 +88,18 @@
     }
     mBtHci->close();
     mBtHci.clear();
+    for (size_t i = 0; i < mFdCount; ++i) {
+      if (mFdList[i]) {
+        close(mFdList[i]);
+      }
+    }
   }
   bool init(const uint8_t* data, size_t size);
   void process();
 
  private:
+  size_t mFdCount = 1;
+  int32_t mFdList[CH_MAX] = {0};
   sp<BluetoothHci> mBtHci = nullptr;
   FuzzedDataProvider* mFdp = nullptr;
 };
@@ -143,17 +150,15 @@
   bool shouldSetH4Protocol = mFdp->ConsumeBool();
   BtVendor* btVendor = BtVendor::getInstance();
 
-  size_t fdcount = 1;
-  int32_t fdList[CH_MAX] = {0};
   if (!shouldSetH4Protocol) {
-    fdcount = mFdp->ConsumeIntegralInRange<size_t>(kMinFdcount, CH_MAX - 1);
+    mFdCount = mFdp->ConsumeIntegralInRange<size_t>(kMinFdcount, CH_MAX - 1);
   }
 
-  for (size_t i = 0; i < fdcount; ++i) {
-    fdList[i] = open("/dev/null", O_RDWR | O_CREAT);
+  for (size_t i = 0; i < mFdCount; ++i) {
+    mFdList[i] = open("/dev/null", O_RDWR | O_CREAT);
   }
 
-  btVendor->populateFdList(fdList, fdcount);
+  btVendor->populateFdList(mFdList, mFdCount);
   mBtHci->initialize(bluetoothCallback);
 
   if (!bluetoothCallback->isInitialized) {
@@ -181,12 +186,6 @@
   }
 
   btVendor->callRemainingCbacks();
-
-  for (size_t i = 0; i < fdcount; ++i) {
-    if (fdList[i]) {
-      close(fdList[i]);
-    }
-  }
 }
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index 1d15dd6..c23d667 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -36,6 +36,8 @@
     "BLUETOOTH_VENDOR_LIB_INTERFACE";
 
 static const int INVALID_FD = -1;
+std::mutex vendor_mutex_;
+std::mutex initcb_mutex_;
 
 namespace {
 
@@ -47,13 +49,25 @@
   uint16_t opcode;
 } internal_command;
 
+enum {
+  VENDOR_STATE_INIT = 1,
+  VENDOR_STATE_OPENING,	/* during opening */
+  VENDOR_STATE_OPENED,	/* open in fops_open */
+  VENDOR_STATE_CLOSING,	/* during closing */
+  VENDOR_STATE_CLOSED,	/* closed */
+
+  VENDOR_STATE_MSG_NUM
+} ;
+
+uint8_t vstate = VENDOR_STATE_INIT;
+
 // True when LPM is not enabled yet or wake is not asserted.
 bool lpm_wake_deasserted;
 uint32_t lpm_timeout_ms;
 bool recent_activity_flag;
 
 VendorInterface* g_vendor_interface = nullptr;
-std::mutex wakeup_mutex_;
+static VendorInterface vendor_interface;
 
 HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
   size_t packet_size = data.size() + sizeof(HC_BT_HDR);
@@ -167,11 +181,8 @@
     InitializeCompleteCallback initialize_complete_cb,
     PacketReadCallback event_cb, PacketReadCallback acl_cb,
     PacketReadCallback sco_cb, PacketReadCallback iso_cb) {
-  if (g_vendor_interface) {
-    ALOGE("%s: No previous Shutdown()?", __func__);
-    return false;
-  }
-  g_vendor_interface = new VendorInterface();
+  ALOGI("%s: VendorInterface::Initialize", __func__);
+  g_vendor_interface = &vendor_interface;
   return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb,
                                   sco_cb, iso_cb);
 }
@@ -179,9 +190,8 @@
 void VendorInterface::Shutdown() {
   LOG_ALWAYS_FATAL_IF(!g_vendor_interface, "%s: No Vendor interface!",
                       __func__);
+  ALOGI("%s: VendorInterface::Shutdown", __func__);
   g_vendor_interface->Close();
-  delete g_vendor_interface;
-  g_vendor_interface = nullptr;
 }
 
 VendorInterface* VendorInterface::get() { return g_vendor_interface; }
@@ -191,144 +201,189 @@
                            PacketReadCallback acl_cb,
                            PacketReadCallback sco_cb,
                            PacketReadCallback iso_cb) {
-  initialize_complete_cb_ = initialize_complete_cb;
+  {
+    std::unique_lock<std::mutex> guard(vendor_mutex_);
+    if (vstate == VENDOR_STATE_OPENED) {
+      ALOGW("VendorInterface opened!");
+      return true;
+    }
 
-  // Initialize vendor interface
+    if ((vstate == VENDOR_STATE_CLOSING) ||
+        (vstate == VENDOR_STATE_OPENING)) {
+      ALOGW("VendorInterface open/close is on-going !");
+      return true;
+    }
 
-  lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
-  if (!lib_handle_) {
-    ALOGE("%s unable to open %s (%s)", __func__, VENDOR_LIBRARY_NAME,
-          dlerror());
-    return false;
-  }
+    vstate = VENDOR_STATE_OPENING;
+    ALOGI("%s: VendorInterface::Open", __func__);
 
-  lib_interface_ = reinterpret_cast<bt_vendor_interface_t*>(
-      dlsym(lib_handle_, VENDOR_LIBRARY_SYMBOL_NAME));
-  if (!lib_interface_) {
-    ALOGE("%s unable to find symbol %s in %s (%s)", __func__,
-          VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
-    return false;
-  }
+    initialize_complete_cb_ = initialize_complete_cb;
+    // Initialize vendor interface
+
+    lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
+    if (!lib_handle_) {
+      ALOGE("%s unable to open %s (%s)", __func__, VENDOR_LIBRARY_NAME,
+            dlerror());
+      return false;
+    }
+
+    lib_interface_ = reinterpret_cast<bt_vendor_interface_t*>(
+        dlsym(lib_handle_, VENDOR_LIBRARY_SYMBOL_NAME));
+    if (!lib_interface_) {
+      ALOGE("%s unable to find symbol %s in %s (%s)", __func__,
+            VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
+      return false;
+    }
 
   // Get the local BD address
 
-  uint8_t local_bda[BluetoothAddress::kBytes];
-  if (!BluetoothAddress::get_local_address(local_bda)) {
-    LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__);
-  }
-  int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
-  if (status) {
-    ALOGE("%s unable to initialize vendor library: %d", __func__, status);
-    return false;
-  }
+    uint8_t local_bda[BluetoothAddress::kBytes] = {0, 0, 0, 0, 0, 0};
+    if (!BluetoothAddress::get_local_address(local_bda)) {
+      // BT driver will get BD address from NVRAM for MTK solution
+      ALOGW("%s: No pre-set Bluetooth Address!", __func__);
+    }
+    int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
+    if (status) {
+      ALOGE("%s unable to initialize vendor library: %d", __func__, status);
+      return false;
+    }
 
-  ALOGD("%s vendor library loaded", __func__);
+    ALOGD("%s vendor library loaded", __func__);
 
   // Power on the controller
 
-  int power_state = BT_VND_PWR_ON;
-  lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
+    int power_state = BT_VND_PWR_ON;
+    lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
 
   // Get the UART socket(s)
 
-  int fd_list[CH_MAX] = {0};
-  int fd_count = lib_interface_->op(BT_VND_OP_USERIAL_OPEN, &fd_list);
+    int fd_list[CH_MAX] = {0};
+    int fd_count = lib_interface_->op(BT_VND_OP_USERIAL_OPEN, &fd_list);
 
-  if (fd_count < 1 || fd_count > CH_MAX - 1) {
-    ALOGE("%s: fd_count %d is invalid!", __func__, fd_count);
-    return false;
-  }
-
-  for (int i = 0; i < fd_count; i++) {
-    if (fd_list[i] == INVALID_FD) {
-      ALOGE("%s: fd %d is invalid!", __func__, fd_list[i]);
+    if (fd_count < 1 || fd_count > CH_MAX - 1) {
+      ALOGE("%s: fd_count %d is invalid!", __func__, fd_count);
       return false;
     }
-  }
 
-  event_cb_ = event_cb;
-  PacketReadCallback intercept_events = [this](const hidl_vec<uint8_t>& event) {
-    HandleIncomingEvent(event);
-  };
+    for (int i = 0; i < fd_count; i++) {
+      if (fd_list[i] == INVALID_FD) {
+        ALOGE("%s: fd %d is invalid!", __func__, fd_list[i]);
+        return false;
+      }
+    }
 
-  if (fd_count == 1) {
-    hci::H4Protocol* h4_hci =
-        new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb, iso_cb);
-    fd_watcher_.WatchFdForNonBlockingReads(
-        fd_list[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
-    hci_ = h4_hci;
-  } else {
-    hci::MctProtocol* mct_hci =
-        new hci::MctProtocol(fd_list, intercept_events, acl_cb);
-    fd_watcher_.WatchFdForNonBlockingReads(
-        fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
-    fd_watcher_.WatchFdForNonBlockingReads(
-        fd_list[CH_ACL_IN], [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
-    hci_ = mct_hci;
-  }
+    event_cb_ = event_cb;
+    PacketReadCallback intercept_events = [this](const hidl_vec<uint8_t>& event) {
+      HandleIncomingEvent(event);
+    };
+
+    if (fd_count == 1) {
+      hci::H4Protocol* h4_hci =
+          new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb, iso_cb);
+      fd_watcher_.WatchFdForNonBlockingReads(
+          fd_list[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
+      hci_ = h4_hci;
+    } else {
+      hci::MctProtocol* mct_hci =
+          new hci::MctProtocol(fd_list, intercept_events, acl_cb);
+      fd_watcher_.WatchFdForNonBlockingReads(
+          fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
+      fd_watcher_.WatchFdForNonBlockingReads(
+          fd_list[CH_ACL_IN],
+          [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
+      hci_ = mct_hci;
+    }
 
   // Initially, the power management is off.
-  lpm_wake_deasserted = true;
+    lpm_wake_deasserted = true;
 
   // Start configuring the firmware
-  firmware_startup_timer_ = new FirmwareStartupTimer();
-  lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
+    firmware_startup_timer_ = new FirmwareStartupTimer();
+    lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
 
+    vstate = VENDOR_STATE_OPENED;
+    ALOGI("%s: VendorInterface::Open done!!!", __func__);
+  }  // vendor_mutex_ done
   return true;
 }
 
 void VendorInterface::Close() {
   // These callbacks may send HCI events (vendor-dependent), so make sure to
   // StopWatching the file descriptor after this.
+
+  if (vstate != VENDOR_STATE_OPENED) {
+    ALOGW("VendorInterface is not allow close(%d)", vstate);
+    return;
+  }
+  vstate = VENDOR_STATE_CLOSING;
+  ALOGI("%s: VendorInterface::Close", __func__);
+
   if (lib_interface_ != nullptr) {
+    lib_interface_->cleanup();
     bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
     lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
   }
 
-  fd_watcher_.StopWatchingFileDescriptors();
+  {
+    std::unique_lock<std::mutex> guard(vendor_mutex_);
 
-  if (hci_ != nullptr) {
-    delete hci_;
-    hci_ = nullptr;
-  }
+    fd_watcher_.StopWatchingFileDescriptors();
+    if (hci_ != nullptr) {
+      delete hci_;
+      hci_ = nullptr;
+    }
 
-  if (lib_interface_ != nullptr) {
-    lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
+    if (lib_interface_ != nullptr) {
+      lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
 
-    int power_state = BT_VND_PWR_OFF;
-    lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
+      int power_state = BT_VND_PWR_OFF;
+      lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
 
-    lib_interface_->cleanup();
-    lib_interface_ = nullptr;
-  }
+      lib_interface_ = nullptr;
+    }
 
-  if (lib_handle_ != nullptr) {
-    dlclose(lib_handle_);
-    lib_handle_ = nullptr;
-  }
+    if (lib_handle_ != nullptr) {
+      dlclose(lib_handle_);
+      lib_handle_ = nullptr;
+    }
 
-  if (firmware_startup_timer_ != nullptr) {
-    delete firmware_startup_timer_;
-    firmware_startup_timer_ = nullptr;
-  }
+    if (firmware_startup_timer_ != nullptr) {
+      delete firmware_startup_timer_;
+      firmware_startup_timer_ = nullptr;
+    }
+    vstate = VENDOR_STATE_CLOSED;
+  }  // vendor_mutex_ done
+  ALOGI("%s: VendorInterface::Close done!!!", __func__);
 }
 
 size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
-  std::unique_lock<std::mutex> lock(wakeup_mutex_);
-  recent_activity_flag = true;
+  {
+    std::unique_lock<std::mutex> guard(vendor_mutex_);
 
-  if (lpm_wake_deasserted == true) {
-    // Restart the timer.
-    fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
+    if (vstate != VENDOR_STATE_OPENED) {
+      ALOGW("VendorInterface is not open yet(%d)!", vstate);
+      return 0;
+    }
+    ALOGI("%s: VendorInterface::Send", __func__);
+
+    if (lib_interface_ == nullptr) {
+      ALOGE("lib_interface_ is null");
+      return 0;
+    }
+    recent_activity_flag = true;
+    if (lpm_wake_deasserted == true) {
+      // Restart the timer.
+      fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
                                  [this]() { OnTimeout(); });
-    // Assert wake.
-    lpm_wake_deasserted = false;
-    bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
-    lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
-    ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
-  }
+      // Assert wake.
+      lpm_wake_deasserted = false;
+      bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
+      lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
+      ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
+    }
 
-  return hci_->Send(type, data, length);
+    return hci_ ? hci_->Send(type, data, length) : 0;
+  }  // vendor_mutex_ done
 }
 
 void VendorInterface::OnFirmwareConfigured(uint8_t result) {
@@ -339,25 +394,36 @@
     firmware_startup_timer_ = nullptr;
   }
 
-  if (initialize_complete_cb_ != nullptr) {
-    initialize_complete_cb_(result == 0);
-    initialize_complete_cb_ = nullptr;
+  {
+    std::unique_lock<std::mutex> guard(initcb_mutex_);
+    ALOGD("%s OnFirmwareConfigured get lock", __func__);
+    if (initialize_complete_cb_ != nullptr) {
+      LOG_ALWAYS_FATAL_IF((result != 0),
+          "%s: Failed to init firmware!", __func__);
+      initialize_complete_cb_(result == 0);
+    }
+  }  // initcb_mutex_ done
+
+  if (lib_interface_ != nullptr) {
+    lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
+    ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);
+
+    bt_vendor_lpm_mode_t mode = BT_VND_LPM_ENABLE;
+    lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
+
+    ALOGD("%s Calling StartLowPowerWatchdog()", __func__);
+    fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
+                                 [this]() { OnTimeout(); });
+  }
+  else {
+    ALOGE("lib_interface_ is null");
   }
 
-  lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
-  ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);
-
-  bt_vendor_lpm_mode_t mode = BT_VND_LPM_ENABLE;
-  lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
-
-  ALOGD("%s Calling StartLowPowerWatchdog()", __func__);
-  fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
-                               [this]() { OnTimeout(); });
+  initialize_complete_cb_ = nullptr;
 }
 
 void VendorInterface::OnTimeout() {
   ALOGV("%s", __func__);
-  std::unique_lock<std::mutex> lock(wakeup_mutex_);
   if (recent_activity_flag == false) {
     lpm_wake_deasserted = true;
     bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT;
diff --git a/bluetooth/1.0/default/vendor_interface.h b/bluetooth/1.0/default/vendor_interface.h
index 040f31a..2df3946 100644
--- a/bluetooth/1.0/default/vendor_interface.h
+++ b/bluetooth/1.0/default/vendor_interface.h
@@ -22,6 +22,8 @@
 #include "bt_vendor_lib.h"
 #include "hci_protocol.h"
 
+extern std::mutex initcb_mutex_;
+
 namespace android {
 namespace hardware {
 namespace bluetooth {
@@ -45,10 +47,9 @@
   size_t Send(uint8_t type, const uint8_t* data, size_t length);
 
   void OnFirmwareConfigured(uint8_t result);
-
- private:
   virtual ~VendorInterface() = default;
 
+ private:
   bool Open(InitializeCompleteCallback initialize_complete_cb,
             PacketReadCallback event_cb, PacketReadCallback acl_cb,
             PacketReadCallback sco_cb, PacketReadCallback iso_cb);
diff --git a/bluetooth/1.0/vts/OWNERS b/bluetooth/1.0/vts/OWNERS
deleted file mode 100644
index 58d3a66..0000000
--- a/bluetooth/1.0/vts/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-zachoverflow@google.com
-siyuanh@google.com
-mylesgw@google.com
-jpawlowski@google.com
-apanicke@google.com
-stng@google.com
-hsz@google.com
-
diff --git a/bluetooth/1.0/vts/functional/OWNERS b/bluetooth/1.0/vts/functional/OWNERS
deleted file mode 100644
index 7f02612..0000000
--- a/bluetooth/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 27441
-bluetooth-reviews@google.com
diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index 8ea1ddd..9451087 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -516,12 +516,15 @@
 // Return the number of completed packets reported by the controller.
 int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
   int packets_processed = 0;
-  wait_for_event(false);
-  if (event_queue.size() == 0) {
-    ALOGW("%s: WaitForCallback timed out.", __func__);
-    return packets_processed;
-  }
-  while (event_queue.size() > 0) {
+  while (true) {
+    // There should be at least one event.
+    wait_for_event(packets_processed == 0);
+    if (event_queue.empty()) {
+      if (packets_processed == 0) {
+        ALOGW("%s: WaitForCallback timed out.", __func__);
+      }
+      return packets_processed;
+    }
     hidl_vec<uint8_t> event = event_queue.front();
     event_queue.pop();
 
diff --git a/bluetooth/1.1/Android.bp b/bluetooth/1.1/Android.bp
index 4ac2009..f8a05f1 100644
--- a/bluetooth/1.1/Android.bp
+++ b/bluetooth/1.1/Android.bp
@@ -23,6 +23,6 @@
     gen_java: true,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
     ],
 }
diff --git a/bluetooth/1.1/default/OWNERS b/bluetooth/1.1/default/OWNERS
deleted file mode 100644
index 0c01df6..0000000
--- a/bluetooth/1.1/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-zachoverflow@google.com
-mylesgw@google.com
-jpawlowski@google.com
diff --git a/bluetooth/1.1/vts/OWNERS b/bluetooth/1.1/vts/OWNERS
deleted file mode 100644
index ff6fd93..0000000
--- a/bluetooth/1.1/vts/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-zachoverflow@google.com
-siyuanh@google.com
-mylesgw@google.com
-jpawlowski@google.com
-hsz@google.com
-
diff --git a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
index 9ae3837..28ac603 100644
--- a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
+++ b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.cpp
@@ -539,12 +539,15 @@
 // Return the number of completed packets reported by the controller.
 int BluetoothHidlTest::wait_for_completed_packets_event(uint16_t handle) {
   int packets_processed = 0;
-  wait_for_event(false);
-  if (event_queue.size() == 0) {
-    ALOGW("%s: WaitForCallback timed out.", __func__);
-    return packets_processed;
-  }
-  while (event_queue.size() > 0) {
+  while (true) {
+    // There should be at least one event.
+    wait_for_event(packets_processed == 0);
+    if (event_queue.empty()) {
+      if (packets_processed == 0) {
+        ALOGW("%s: WaitForCallback timed out.", __func__);
+      }
+      return packets_processed;
+    }
     hidl_vec<uint8_t> event = event_queue.front();
     event_queue.pop();
 
diff --git a/bluetooth/OWNERS b/bluetooth/OWNERS
new file mode 100644
index 0000000..f401b8c
--- /dev/null
+++ b/bluetooth/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 27441
+
+henrichataing@google.com
+mylesgw@google.com
+siyuanh@google.com
diff --git a/bluetooth/a2dp/1.0/Android.bp b/bluetooth/a2dp/1.0/Android.bp
index 20776dc..6ffbefa 100644
--- a/bluetooth/a2dp/1.0/Android.bp
+++ b/bluetooth/a2dp/1.0/Android.bp
@@ -23,6 +23,6 @@
     gen_java: false,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
     ],
 }
diff --git a/bluetooth/aidl/Android.bp b/bluetooth/aidl/Android.bp
new file mode 100644
index 0000000..c6a592f
--- /dev/null
+++ b/bluetooth/aidl/Android.bp
@@ -0,0 +1,45 @@
+// This is the expected build file, but it may not be right in all cases
+
+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"],
+}
+
+aidl_interface {
+    name: "android.hardware.bluetooth",
+    vendor_available: true,
+    host_supported: true,
+    srcs: ["android/hardware/bluetooth/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            // FIXME should this be disabled?
+            // prefer NDK backend which can be used anywhere
+            // If you disable this, you also need to delete the C++
+            // translate code.
+            enabled: true,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+        ndk: {
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.btservices",
+            ],
+            min_sdk_version: "33",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/bluetooth/aidl/TEST_MAPPING b/bluetooth/aidl/TEST_MAPPING
new file mode 100644
index 0000000..41a508e
--- /dev/null
+++ b/bluetooth/aidl/TEST_MAPPING
@@ -0,0 +1,24 @@
+{
+  "presubmit" : [
+    {
+      "name" : "VtsHalBluetoothTargetTest",
+      "options": [
+        {
+          // TODO(b/275847929)
+          "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Vsr_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default"
+        }
+      ]
+    }
+  ],
+  "hwasan-presubmit" : [
+    {
+      "name" : "VtsHalBluetoothTargetTest",
+      "options": [
+        {
+          // TODO(b/275847929)
+          "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Vsr_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default"
+        }
+      ]
+    }
+  ]
+}
diff --git a/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/.hash b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/.hash
new file mode 100644
index 0000000..e5ef0bf
--- /dev/null
+++ b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/.hash
@@ -0,0 +1 @@
+f0eb2eb6d3b970cef8fb1b6e22c4ec39a4da5119
diff --git a/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/android/hardware/bluetooth/IBluetoothHci.aidl b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/android/hardware/bluetooth/IBluetoothHci.aidl
new file mode 100644
index 0000000..8b1cad2
--- /dev/null
+++ b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/android/hardware/bluetooth/IBluetoothHci.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth;
+@VintfStability
+interface IBluetoothHci {
+  void close();
+  void initialize(in android.hardware.bluetooth.IBluetoothHciCallbacks callback);
+  void sendAclData(in byte[] data);
+  void sendHciCommand(in byte[] command);
+  void sendIsoData(in byte[] data);
+  void sendScoData(in byte[] data);
+}
diff --git a/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl
new file mode 100644
index 0000000..aecff7f
--- /dev/null
+++ b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth;
+@VintfStability
+interface IBluetoothHciCallbacks {
+  void aclDataReceived(in byte[] data);
+  void hciEventReceived(in byte[] event);
+  void initializationComplete(in android.hardware.bluetooth.Status status);
+  void isoDataReceived(in byte[] data);
+  void scoDataReceived(in byte[] data);
+}
diff --git a/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/android/hardware/bluetooth/Status.aidl b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/android/hardware/bluetooth/Status.aidl
new file mode 100644
index 0000000..227224c
--- /dev/null
+++ b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/1/android/hardware/bluetooth/Status.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth;
+@Backing(type="int") @VintfStability
+enum Status {
+  SUCCESS,
+  ALREADY_INITIALIZED,
+  UNABLE_TO_OPEN_INTERFACE,
+  HARDWARE_INITIALIZATION_ERROR,
+  UNKNOWN,
+}
diff --git a/bluetooth/aidl/aidl_api/android.hardware.bluetooth/current/android/hardware/bluetooth/IBluetoothHci.aidl b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/current/android/hardware/bluetooth/IBluetoothHci.aidl
new file mode 100644
index 0000000..8b1cad2
--- /dev/null
+++ b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/current/android/hardware/bluetooth/IBluetoothHci.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth;
+@VintfStability
+interface IBluetoothHci {
+  void close();
+  void initialize(in android.hardware.bluetooth.IBluetoothHciCallbacks callback);
+  void sendAclData(in byte[] data);
+  void sendHciCommand(in byte[] command);
+  void sendIsoData(in byte[] data);
+  void sendScoData(in byte[] data);
+}
diff --git a/bluetooth/aidl/aidl_api/android.hardware.bluetooth/current/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/current/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl
new file mode 100644
index 0000000..aecff7f
--- /dev/null
+++ b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/current/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth;
+@VintfStability
+interface IBluetoothHciCallbacks {
+  void aclDataReceived(in byte[] data);
+  void hciEventReceived(in byte[] event);
+  void initializationComplete(in android.hardware.bluetooth.Status status);
+  void isoDataReceived(in byte[] data);
+  void scoDataReceived(in byte[] data);
+}
diff --git a/bluetooth/aidl/aidl_api/android.hardware.bluetooth/current/android/hardware/bluetooth/Status.aidl b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/current/android/hardware/bluetooth/Status.aidl
new file mode 100644
index 0000000..da429b8
--- /dev/null
+++ b/bluetooth/aidl/aidl_api/android.hardware.bluetooth/current/android/hardware/bluetooth/Status.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth;
+@Backing(type="int") @VintfStability
+enum Status {
+  SUCCESS = 0,
+  ALREADY_INITIALIZED = 1,
+  UNABLE_TO_OPEN_INTERFACE = 2,
+  HARDWARE_INITIALIZATION_ERROR = 3,
+  UNKNOWN = 4,
+}
diff --git a/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHci.aidl b/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHci.aidl
new file mode 100644
index 0000000..ff1f735
--- /dev/null
+++ b/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHci.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth;
+
+import android.hardware.bluetooth.IBluetoothHciCallbacks;
+
+/**
+ * The Host Controller Interface (HCI) is the layer defined by the Bluetooth
+ * specification between the software that runs on the host and the Bluetooth
+ * controller chip. This boundary is the natural choice for a Hardware
+ * Abstraction Layer (HAL). Dealing only in HCI packets and events simplifies
+ * the stack and abstracts away power management, initialization, and other
+ * implementation-specific details related to the hardware.
+ */
+@VintfStability
+interface IBluetoothHci {
+    /**
+     * Close the HCI interface
+     */
+    void close();
+
+    /**
+     * Initialize the Bluetooth interface and set the callbacks.
+     * Only one client can initialize the interface at a time.  When a
+     * call to initialize fails, the Status parameter of the callback
+     * will indicate the reason for the failure.
+     */
+    void initialize(in IBluetoothHciCallbacks callback);
+
+    /**
+     * Send an HCI ACL data packet (as specified in the Bluetooth Specification
+     * V4.2, Vol 2, Part 5, Section 5.4.2) to the Bluetooth controller.
+     * Packets must be processed in order.
+     * @param data HCI data packet to be sent
+     */
+    void sendAclData(in byte[] data);
+
+    /**
+     * Send an HCI command (as specified in the Bluetooth Specification
+     * V4.2, Vol 2, Part 5, Section 5.4.1) to the Bluetooth controller.
+     * Commands must be executed in order.
+     *
+     * @param command is the HCI command to be sent
+     */
+    void sendHciCommand(in byte[] command);
+
+    /**
+     * Send an ISO data packet (as specified in the Bluetooth Core
+     * Specification v5.2) to the Bluetooth controller.
+     * Packets must be processed in order.
+     * @param data HCI data packet to be sent
+     */
+    void sendIsoData(in byte[] data);
+
+    /**
+     * Send an SCO data packet (as specified in the Bluetooth Specification
+     * V4.2, Vol 2, Part 5, Section 5.4.3) to the Bluetooth controller.
+     * Packets must be processed in order.
+     * @param data HCI data packet to be sent
+     */
+    void sendScoData(in byte[] data);
+}
diff --git a/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl b/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl
new file mode 100644
index 0000000..0148c6f
--- /dev/null
+++ b/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth;
+
+import android.hardware.bluetooth.Status;
+
+/**
+ * The interface from the Bluetooth Controller to the stack.
+ */
+@VintfStability
+interface IBluetoothHciCallbacks {
+    /**
+     * Send an ACL data packet from the controller to the host.
+     * @param data the ACL HCI packet to be passed to the host stack
+     */
+    void aclDataReceived(in byte[] data);
+
+    /**
+     * This function is invoked when an HCI event is received from the
+     * Bluetooth controller to be forwarded to the Bluetooth stack.
+     * @param event is the HCI event to be sent to the Bluetooth stack.
+     */
+    void hciEventReceived(in byte[] event);
+
+    /**
+     * Invoked when the Bluetooth controller initialization has been
+     * completed.
+     * @param status contains a return code indicating success, or the
+     *               reason the initialization failed.
+     */
+    void initializationComplete(in Status status);
+
+    /**
+     * Send a ISO data packet from the controller to the host.
+     * @param data the ISO HCI packet to be passed to the host stack
+     */
+    void isoDataReceived(in byte[] data);
+
+    /**
+     * Send a SCO data packet from the controller to the host.
+     * @param data the SCO HCI packet to be passed to the host stack
+     */
+    void scoDataReceived(in byte[] data);
+}
diff --git a/bluetooth/aidl/android/hardware/bluetooth/Status.aidl b/bluetooth/aidl/android/hardware/bluetooth/Status.aidl
new file mode 100644
index 0000000..4ec251a
--- /dev/null
+++ b/bluetooth/aidl/android/hardware/bluetooth/Status.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth;
+
+@VintfStability
+@Backing(type="int")
+enum Status {
+    SUCCESS,
+    ALREADY_INITIALIZED,
+    UNABLE_TO_OPEN_INTERFACE,
+    HARDWARE_INITIALIZATION_ERROR,
+    UNKNOWN,
+}
diff --git a/bluetooth/aidl/default/Android.bp b/bluetooth/aidl/default/Android.bp
new file mode 100644
index 0000000..32d1a13
--- /dev/null
+++ b/bluetooth/aidl/default/Android.bp
@@ -0,0 +1,92 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+    name: "android.hardware.bluetooth-service-build-defaults",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+    ],
+    shared_libs: [
+        "android.hardware.bluetooth-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.bluetooth.async",
+        "android.hardware.bluetooth.hci",
+    ],
+}
+
+cc_library_static {
+    name: "libbluetoothhcihalimpl",
+    vendor_available: true,
+    host_supported: true,
+    defaults: ["android.hardware.bluetooth-service-build-defaults"],
+    srcs: [
+        "BluetoothHci.cpp",
+        ":BluetoothPacketSources",
+        "net_bluetooth_mgmt.cpp",
+    ],
+    generated_headers: [
+        "BluetoothGeneratedPackets_h",
+    ],
+    include_dirs: [
+        "packages/modules/Bluetooth/system/gd",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.bluetooth-service.default",
+    relative_install_path: "hw",
+    init_rc: ["bluetooth-service-default.rc"],
+    vintf_fragments: [":manifest_android.hardware.bluetooth-service.default.xml"],
+    vendor: true,
+    defaults: ["android.hardware.bluetooth-service-build-defaults"],
+    srcs: [
+        "service.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.bluetooth-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "libhidlbase",
+        "libutils",
+        "liblog",
+    ],
+    static_libs: [
+        "libbluetoothhcihalimpl",
+    ],
+}
+
+cc_fuzz {
+    name: "android.hardware.bluetooth-service.default_fuzzer",
+    host_supported: true,
+    defaults: ["service_fuzzer_defaults"],
+    srcs: [
+        "test/fuzzer.cpp",
+    ],
+    static_libs: [
+        "android.hardware.bluetooth.async",
+        "android.hardware.bluetooth.hci",
+        "android.hardware.bluetooth-V1-ndk",
+        "libbluetoothhcihalimpl",
+        "liblog",
+    ],
+    fuzz_config: {
+        componentid: 27441,
+        cc: [
+            "mylesgw@google.com",
+        ],
+    },
+}
+
+filegroup {
+    name: "manifest_android.hardware.bluetooth-service.default.xml",
+    srcs: ["bluetooth-service-default.xml"],
+}
diff --git a/bluetooth/aidl/default/BluetoothHci.cpp b/bluetooth/aidl/default/BluetoothHci.cpp
new file mode 100644
index 0000000..ac2eabc
--- /dev/null
+++ b/bluetooth/aidl/default/BluetoothHci.cpp
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.bluetooth.service.default"
+
+#include "BluetoothHci.h"
+
+#include <cutils/properties.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <poll.h>
+#include <string.h>
+#include <sys/uio.h>
+#include <termios.h>
+
+#include "log/log.h"
+
+// TODO: Remove custom logging defines from PDL packets.
+#undef LOG_INFO
+#undef LOG_DEBUG
+#include "hci/hci_packets.h"
+
+namespace {
+int SetTerminalRaw(int fd) {
+  termios terminal_settings;
+  int rval = tcgetattr(fd, &terminal_settings);
+  if (rval < 0) {
+    return rval;
+  }
+  cfmakeraw(&terminal_settings);
+  rval = tcsetattr(fd, TCSANOW, &terminal_settings);
+  return rval;
+}
+}  // namespace
+
+using namespace ::android::hardware::bluetooth::hci;
+using namespace ::android::hardware::bluetooth::async;
+using aidl::android::hardware::bluetooth::Status;
+
+namespace aidl::android::hardware::bluetooth::impl {
+
+void OnDeath(void* cookie);
+
+class BluetoothDeathRecipient {
+ public:
+  BluetoothDeathRecipient(BluetoothHci* hci) : mHci(hci) {}
+
+  void LinkToDeath(const std::shared_ptr<IBluetoothHciCallbacks>& cb) {
+    mCb = cb;
+    clientDeathRecipient_ = AIBinder_DeathRecipient_new(OnDeath);
+    auto linkToDeathReturnStatus = AIBinder_linkToDeath(
+        mCb->asBinder().get(), clientDeathRecipient_, this /* cookie */);
+    LOG_ALWAYS_FATAL_IF(linkToDeathReturnStatus != STATUS_OK,
+                        "Unable to link to death recipient");
+  }
+
+  void UnlinkToDeath(const std::shared_ptr<IBluetoothHciCallbacks>& cb) {
+    LOG_ALWAYS_FATAL_IF(cb != mCb, "Unable to unlink mismatched pointers");
+  }
+
+  void serviceDied() {
+    if (mCb != nullptr && !AIBinder_isAlive(mCb->asBinder().get())) {
+      ALOGE("Bluetooth remote service has died");
+    } else {
+      ALOGE("BluetoothDeathRecipient::serviceDied called but service not dead");
+      return;
+    }
+    {
+      std::lock_guard<std::mutex> guard(mHasDiedMutex);
+      has_died_ = true;
+    }
+    mHci->close();
+  }
+  BluetoothHci* mHci;
+  std::shared_ptr<IBluetoothHciCallbacks> mCb;
+  AIBinder_DeathRecipient* clientDeathRecipient_;
+  bool getHasDied() {
+    std::lock_guard<std::mutex> guard(mHasDiedMutex);
+    return has_died_;
+  }
+
+ private:
+  std::mutex mHasDiedMutex;
+  bool has_died_{false};
+};
+
+void OnDeath(void* cookie) {
+  auto* death_recipient = static_cast<BluetoothDeathRecipient*>(cookie);
+  death_recipient->serviceDied();
+}
+
+BluetoothHci::BluetoothHci(const std::string& dev_path) {
+  char property_bytes[PROPERTY_VALUE_MAX];
+  property_get("vendor.ser.bt-uart", property_bytes, dev_path.c_str());
+  mDevPath = std::string(property_bytes);
+  mDeathRecipient = std::make_shared<BluetoothDeathRecipient>(this);
+}
+
+int BluetoothHci::getFdFromDevPath() {
+  int fd = open(mDevPath.c_str(), O_RDWR);
+  if (fd < 0) {
+    ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(),
+          strerror(errno));
+    return fd;
+  }
+  if (int ret = SetTerminalRaw(fd) < 0) {
+    ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
+          strerror(errno));
+  }
+  return fd;
+}
+
+void BluetoothHci::reset() {
+  // Send a reset command and wait until the command complete comes back.
+
+  std::vector<uint8_t> reset;
+  ::bluetooth::packet::BitInserter bi{reset};
+  ::bluetooth::hci::ResetBuilder::Create()->Serialize(bi);
+
+  auto resetPromise = std::make_shared<std::promise<void>>();
+  auto resetFuture = resetPromise->get_future();
+
+  mH4 = std::make_shared<H4Protocol>(
+      mFd,
+      [](const std::vector<uint8_t>& raw_command) {
+        ALOGI("Discarding %d bytes with command type",
+              static_cast<int>(raw_command.size()));
+      },
+      [](const std::vector<uint8_t>& raw_acl) {
+        ALOGI("Discarding %d bytes with acl type",
+              static_cast<int>(raw_acl.size()));
+      },
+      [](const std::vector<uint8_t>& raw_sco) {
+        ALOGI("Discarding %d bytes with sco type",
+              static_cast<int>(raw_sco.size()));
+      },
+      [resetPromise](const std::vector<uint8_t>& raw_event) {
+        bool valid = ::bluetooth::hci::ResetCompleteView::Create(
+                         ::bluetooth::hci::CommandCompleteView::Create(
+                             ::bluetooth::hci::EventView::Create(
+                                 ::bluetooth::hci::PacketView<true>(
+                                     std::make_shared<std::vector<uint8_t>>(
+                                         raw_event)))))
+                         .IsValid();
+        if (valid) {
+          resetPromise->set_value();
+        } else {
+          ALOGI("Discarding %d bytes with event type",
+                static_cast<int>(raw_event.size()));
+        }
+      },
+      [](const std::vector<uint8_t>& raw_iso) {
+        ALOGI("Discarding %d bytes with iso type",
+              static_cast<int>(raw_iso.size()));
+      },
+      [this]() {
+        ALOGI("HCI socket device disconnected while waiting for reset");
+        mFdWatcher.StopWatchingFileDescriptors();
+      });
+  mFdWatcher.WatchFdForNonBlockingReads(mFd,
+                                        [this](int) { mH4->OnDataReady(); });
+
+  send(PacketType::COMMAND, reset);
+  auto status = resetFuture.wait_for(std::chrono::seconds(1));
+  mFdWatcher.StopWatchingFileDescriptors();
+  if (status == std::future_status::ready) {
+    ALOGI("HCI Reset successful");
+  } else {
+    ALOGE("HCI Reset Response not received in one second");
+  }
+
+  resetPromise.reset();
+}
+
+ndk::ScopedAStatus BluetoothHci::initialize(
+    const std::shared_ptr<IBluetoothHciCallbacks>& cb) {
+  ALOGI(__func__);
+
+  if (cb == nullptr) {
+    ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
+    return ndk::ScopedAStatus::fromServiceSpecificError(STATUS_BAD_VALUE);
+  }
+
+  HalState old_state = HalState::READY;
+  {
+    std::lock_guard<std::mutex> guard(mStateMutex);
+    if (mState != HalState::READY) {
+      old_state = mState;
+    } else {
+      mState = HalState::INITIALIZING;
+    }
+  }
+
+  if (old_state != HalState::READY) {
+    ALOGE("initialize: Unexpected State %d", static_cast<int>(old_state));
+    close();
+    cb->initializationComplete(Status::ALREADY_INITIALIZED);
+    return ndk::ScopedAStatus::ok();
+  }
+
+  mCb = cb;
+  management_.reset(new NetBluetoothMgmt);
+  mFd = management_->openHci();
+  if (mFd < 0) {
+    management_.reset();
+
+    ALOGI("Unable to open Linux interface, trying default path.");
+    mFd = getFdFromDevPath();
+    if (mFd < 0) {
+      cb->initializationComplete(Status::UNABLE_TO_OPEN_INTERFACE);
+      return ndk::ScopedAStatus::ok();
+    }
+  }
+
+  mDeathRecipient->LinkToDeath(mCb);
+
+  // TODO: This should not be necessary when the device implements rfkill.
+  reset();
+
+  mH4 = std::make_shared<H4Protocol>(
+      mFd,
+      [](const std::vector<uint8_t>& /* raw_command */) {
+        LOG_ALWAYS_FATAL("Unexpected command!");
+      },
+      [this](const std::vector<uint8_t>& raw_acl) {
+        mCb->aclDataReceived(raw_acl);
+      },
+      [this](const std::vector<uint8_t>& raw_sco) {
+        mCb->scoDataReceived(raw_sco);
+      },
+      [this](const std::vector<uint8_t>& raw_event) {
+        mCb->hciEventReceived(raw_event);
+      },
+      [this](const std::vector<uint8_t>& raw_iso) {
+        mCb->isoDataReceived(raw_iso);
+      },
+      [this]() {
+        ALOGI("HCI socket device disconnected");
+        mFdWatcher.StopWatchingFileDescriptors();
+      });
+  mFdWatcher.WatchFdForNonBlockingReads(mFd,
+                                        [this](int) { mH4->OnDataReady(); });
+
+  {
+    std::lock_guard<std::mutex> guard(mStateMutex);
+    mState = HalState::ONE_CLIENT;
+  }
+  ALOGI("initialization complete");
+  auto status = mCb->initializationComplete(Status::SUCCESS);
+  if (!status.isOk()) {
+    if (!mDeathRecipient->getHasDied()) {
+      ALOGE("Error sending init callback, but no death notification");
+    }
+    close();
+    return ndk::ScopedAStatus::fromServiceSpecificError(
+        STATUS_FAILED_TRANSACTION);
+  }
+
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothHci::close() {
+  ALOGI(__func__);
+  {
+    std::lock_guard<std::mutex> guard(mStateMutex);
+    if (mState != HalState::ONE_CLIENT) {
+      ALOGI("Already closed");
+      return ndk::ScopedAStatus::ok();
+    }
+    mState = HalState::CLOSING;
+  }
+
+  mFdWatcher.StopWatchingFileDescriptors();
+
+  if (management_) {
+    management_->closeHci();
+  } else {
+    ::close(mFd);
+  }
+
+  {
+    std::lock_guard<std::mutex> guard(mStateMutex);
+    mState = HalState::READY;
+  }
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothHci::sendHciCommand(
+    const std::vector<uint8_t>& packet) {
+  send(PacketType::COMMAND, packet);
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothHci::sendAclData(
+    const std::vector<uint8_t>& packet) {
+  send(PacketType::ACL_DATA, packet);
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothHci::sendScoData(
+    const std::vector<uint8_t>& packet) {
+  send(PacketType::SCO_DATA, packet);
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothHci::sendIsoData(
+    const std::vector<uint8_t>& packet) {
+  send(PacketType::ISO_DATA, packet);
+  return ndk::ScopedAStatus::ok();
+}
+
+void BluetoothHci::send(PacketType type, const std::vector<uint8_t>& v) {
+  mH4->Send(type, v);
+}
+
+}  // namespace aidl::android::hardware::bluetooth::impl
diff --git a/bluetooth/aidl/default/BluetoothHci.h b/bluetooth/aidl/default/BluetoothHci.h
new file mode 100644
index 0000000..85aafc8
--- /dev/null
+++ b/bluetooth/aidl/default/BluetoothHci.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/bluetooth/BnBluetoothHci.h>
+#include <aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.h>
+
+#include <future>
+#include <string>
+
+#include "async_fd_watcher.h"
+#include "h4_protocol.h"
+#include "net_bluetooth_mgmt.h"
+
+namespace aidl::android::hardware::bluetooth::impl {
+
+class BluetoothDeathRecipient;
+
+// This Bluetooth HAL implementation connects with a serial port at dev_path_.
+class BluetoothHci : public BnBluetoothHci {
+ public:
+  BluetoothHci(const std::string& dev_path = "/dev/hvc5");
+
+  ndk::ScopedAStatus initialize(
+      const std::shared_ptr<IBluetoothHciCallbacks>& cb) override;
+
+  ndk::ScopedAStatus sendHciCommand(
+      const std::vector<uint8_t>& packet) override;
+
+  ndk::ScopedAStatus sendAclData(const std::vector<uint8_t>& packet) override;
+
+  ndk::ScopedAStatus sendScoData(const std::vector<uint8_t>& packet) override;
+
+  ndk::ScopedAStatus sendIsoData(const std::vector<uint8_t>& packet) override;
+
+  ndk::ScopedAStatus close() override;
+
+  static void OnPacketReady();
+
+  static BluetoothHci* get();
+
+ private:
+  int mFd{-1};
+  std::shared_ptr<IBluetoothHciCallbacks> mCb = nullptr;
+
+  std::shared_ptr<::android::hardware::bluetooth::hci::H4Protocol> mH4;
+
+  std::shared_ptr<BluetoothDeathRecipient> mDeathRecipient;
+
+  std::string mDevPath;
+
+  ::android::hardware::bluetooth::async::AsyncFdWatcher mFdWatcher;
+
+  int getFdFromDevPath();
+  void send(::android::hardware::bluetooth::hci::PacketType type,
+            const std::vector<uint8_t>& packet);
+  std::unique_ptr<NetBluetoothMgmt> management_{};
+
+  // Send a reset command and discard all packets until a reset is received.
+  void reset();
+
+  // Don't close twice or open before close is complete
+  std::mutex mStateMutex;
+  enum class HalState {
+    READY,
+    INITIALIZING,
+    ONE_CLIENT,
+    CLOSING,
+  } mState{HalState::READY};
+};
+
+}  // namespace aidl::android::hardware::bluetooth::impl
diff --git a/bluetooth/aidl/default/bluetooth-service-default.rc b/bluetooth/aidl/default/bluetooth-service-default.rc
new file mode 100644
index 0000000..dc78698
--- /dev/null
+++ b/bluetooth/aidl/default/bluetooth-service-default.rc
@@ -0,0 +1,6 @@
+service vendor.bluetooth-default /vendor/bin/hw/android.hardware.bluetooth-service.default
+    class hal
+    capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
+    user bluetooth
+    group bluetooth
+    task_profiles HighPerformance
diff --git a/bluetooth/aidl/default/bluetooth-service-default.xml b/bluetooth/aidl/default/bluetooth-service-default.xml
new file mode 100644
index 0000000..bb05995
--- /dev/null
+++ b/bluetooth/aidl/default/bluetooth-service-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.bluetooth</name>
+        <fqname>IBluetoothHci/default</fqname>
+    </hal>
+</manifest>
diff --git a/bluetooth/aidl/default/net_bluetooth_mgmt.cpp b/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
new file mode 100644
index 0000000..937cd57
--- /dev/null
+++ b/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.bluetooth.service.default"
+
+#include "net_bluetooth_mgmt.h"
+
+#include <fcntl.h>
+#include <log/log.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <cerrno>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+
+// Definitions imported from <linux/net/bluetooth/bluetooth.h>
+#define BTPROTO_HCI 1
+
+// Definitions imported from <linux/net/bluetooth/hci_sock.h>
+#define HCI_CHANNEL_USER 1
+#define HCI_CHANNEL_CONTROL 3
+#define HCI_DEV_NONE 0xffff
+
+struct sockaddr_hci {
+  sa_family_t hci_family;
+  unsigned short hci_dev;
+  unsigned short hci_channel;
+};
+
+// Definitions imported from <linux/net/bluetooth/mgmt.h>
+#define MGMT_OP_READ_INDEX_LIST 0x0003
+#define MGMT_EV_INDEX_ADDED 0x0004
+#define MGMT_EV_CMD_COMPLETE 0x0001
+#define MGMT_PKT_SIZE_MAX 1024
+#define MGMT_INDEX_NONE 0xFFFF
+
+struct mgmt_pkt {
+  uint16_t opcode;
+  uint16_t index;
+  uint16_t len;
+  uint8_t data[MGMT_PKT_SIZE_MAX];
+} __attribute__((packed));
+
+struct mgmt_ev_read_index_list {
+  uint16_t opcode;
+  uint8_t status;
+  uint16_t num_controllers;
+  uint16_t index[];
+} __attribute__((packed));
+
+// Definitions imported from <linux/rfkill.h>
+#define RFKILL_STATE_SOFT_BLOCKED 0
+#define RFKILL_STATE_UNBLOCKED 1
+#define RFKILL_STATE_HARD_BLOCKED 2
+
+#define RFKILL_TYPE_BLUETOOTH 2
+
+#define RFKILL_OP_ADD 0
+#define RFKILL_OP_CHANGE 2
+
+struct rfkill_event {
+  uint32_t idx;
+  uint8_t type;
+  uint8_t op;
+  uint8_t soft;
+  uint8_t hard;
+} __attribute__((packed));
+
+namespace aidl::android::hardware::bluetooth::impl {
+
+// Wait indefinitely for the selected HCI interface to be enabled in the
+// bluetooth driver.
+int NetBluetoothMgmt::waitHciDev(int hci_interface) {
+  ALOGI("waiting for hci interface %d", hci_interface);
+
+  int ret = -1;
+  struct mgmt_pkt cmd;
+  struct pollfd pollfd;
+  struct sockaddr_hci hci_addr = {
+      .hci_family = AF_BLUETOOTH,
+      .hci_dev = HCI_DEV_NONE,
+      .hci_channel = HCI_CHANNEL_CONTROL,
+  };
+
+  // Open and bind a socket to the bluetooth control interface in the
+  // kernel driver, used to send control commands and receive control
+  // events.
+  int fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+  if (fd < 0) {
+    ALOGE("unable to open raw bluetooth socket: %s", strerror(errno));
+    return -1;
+  }
+
+  if (bind(fd, (struct sockaddr*)&hci_addr, sizeof(hci_addr)) < 0) {
+    ALOGE("unable to bind bluetooth control channel: %s", strerror(errno));
+    goto end;
+  }
+
+  // Send the control command [Read Index List].
+  cmd = {
+      .opcode = MGMT_OP_READ_INDEX_LIST,
+      .index = MGMT_INDEX_NONE,
+      .len = 0,
+  };
+
+  if (write(fd, &cmd, 6) != 6) {
+    ALOGE("error writing mgmt command: %s", strerror(errno));
+    goto end;
+  }
+
+  // Poll the control socket waiting for the command response,
+  // and subsequent [Index Added] events. The loops continue without
+  // timeout until the selected hci interface is detected.
+  pollfd = {.fd = fd, .events = POLLIN};
+
+  for (;;) {
+    ret = poll(&pollfd, 1, -1);
+
+    // Poll interrupted, try again.
+    if (ret == -1 && (errno == EINTR || errno == EAGAIN)) {
+      continue;
+    }
+
+    // Poll failure, abandon.
+    if (ret == -1) {
+      ALOGE("poll error: %s", strerror(errno));
+      break;
+    }
+
+    // Spurious wakeup, try again.
+    if (ret == 0 || (pollfd.revents & POLLIN) == 0) {
+      continue;
+    }
+
+    // Read the next control event.
+    struct mgmt_pkt ev {};
+    ret = read(fd, &ev, sizeof(ev));
+    if (ret < 0) {
+      ALOGE("error reading mgmt event: %s", strerror(errno));
+      goto end;
+    }
+
+    // Received [Read Index List] command response.
+    if (ev.opcode == MGMT_EV_CMD_COMPLETE) {
+      struct mgmt_ev_read_index_list* data =
+          (struct mgmt_ev_read_index_list*)ev.data;
+
+      for (int i = 0; i < data->num_controllers; i++) {
+        if (data->index[i] == hci_interface) {
+          ALOGI("hci interface %d found", hci_interface);
+          ret = 0;
+          goto end;
+        }
+      }
+    }
+
+    // Received [Index Added] event.
+    if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
+      ALOGI("hci interface %d added", hci_interface);
+      ret = 0;
+      goto end;
+    }
+  }
+
+end:
+  ::close(fd);
+  return ret;
+}
+
+int NetBluetoothMgmt::openRfkill() {
+  int fd = open("/dev/rfkill", O_RDWR);
+  if (fd < 0) {
+    ALOGE("unable to open /dev/rfkill: %s", strerror(errno));
+    return -1;
+  }
+
+  if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+    ALOGE("unable to set rfkill control device to non-blocking: %s",
+          strerror(errno));
+    ::close(fd);
+    return -1;
+  }
+
+  for (;;) {
+    struct rfkill_event event {};
+    ssize_t res = read(fd, &event, sizeof(event));
+    if (res < 0) {
+      ALOGE("error reading rfkill events: %s", strerror(errno));
+      break;
+    }
+
+    ALOGI("index:%d type:%d op:%d", event.idx, event.type, event.op);
+
+    if (event.op == RFKILL_OP_ADD && event.type == RFKILL_TYPE_BLUETOOTH) {
+      rfkill_bt_index_ = event.idx;
+      rfkill_fd_ = fd;
+      return 0;
+    }
+  }
+
+  ::close(fd);
+  return -1;
+}
+
+// Block or unblock Bluetooth.
+int NetBluetoothMgmt::rfkill(int block) {
+  if (rfkill_fd_ == -1) {
+    openRfkill();
+  }
+
+  if (rfkill_fd_ == -1) {
+    ALOGE("rfkill unavailable");
+    return -1;
+  }
+
+  struct rfkill_event event = {
+      .idx = static_cast<uint32_t>(rfkill_bt_index_),
+      .type = RFKILL_TYPE_BLUETOOTH,
+      .op = RFKILL_OP_CHANGE,
+      .soft = static_cast<uint8_t>(block),
+      .hard = 0,
+  };
+
+  int res = write(rfkill_fd_, &event, sizeof(event));
+  if (res < 0) {
+    ALOGE("error writing rfkill command: %s", strerror(errno));
+    return -1;
+  }
+
+  return 0;
+}
+
+int NetBluetoothMgmt::openHci(int hci_interface) {
+  ALOGI("opening hci interface %d", hci_interface);
+
+  // Block Bluetooth.
+  rfkill(1);
+
+  // Wait for the HCI interface to complete initialization or to come online.
+  if (waitHciDev(hci_interface)) {
+    ALOGE("hci interface %d not found", hci_interface);
+    return -1;
+  }
+
+  // Open the raw HCI socket.
+  int fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+  if (fd < 0) {
+    ALOGE("unable to open raw bluetooth socket: %s", strerror(errno));
+    return -1;
+  }
+
+  struct sockaddr_hci hci_addr = {
+      .hci_family = AF_BLUETOOTH,
+      .hci_dev = static_cast<uint16_t>(hci_interface),
+      .hci_channel = HCI_CHANNEL_USER,
+  };
+
+  // Bind the socket to the selected interface.
+  if (bind(fd, (struct sockaddr*)&hci_addr, sizeof(hci_addr)) < 0) {
+    ALOGE("unable to bind bluetooth user channel: %s", strerror(errno));
+    ::close(fd);
+    return -1;
+  }
+
+  ALOGI("hci interface %d ready", hci_interface);
+  bt_fd_ = fd;
+  return fd;
+}
+
+void NetBluetoothMgmt::closeHci() {
+  if (bt_fd_ != -1) {
+    ::close(bt_fd_);
+    bt_fd_ = -1;
+  }
+
+  // Unblock Bluetooth.
+  rfkill(0);
+}
+
+}  // namespace aidl::android::hardware::bluetooth::impl
diff --git a/bluetooth/aidl/default/net_bluetooth_mgmt.h b/bluetooth/aidl/default/net_bluetooth_mgmt.h
new file mode 100644
index 0000000..5c473f2
--- /dev/null
+++ b/bluetooth/aidl/default/net_bluetooth_mgmt.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <unistd.h>
+
+namespace aidl::android::hardware::bluetooth::impl {
+
+class NetBluetoothMgmt {
+ public:
+  NetBluetoothMgmt() {}
+  ~NetBluetoothMgmt() {
+    ::close(rfkill_fd_);
+    ::close(bt_fd_);
+  }
+
+  int openHci(int hci_interface = 0);
+  void closeHci();
+
+ private:
+  int waitHciDev(int hci_interface);
+  int openRfkill();
+  int rfkill(int block);
+
+  // Index of the first rfkill device of type bluetooth.
+  int rfkill_bt_index_{-1};
+  // File descriptor opened to /dev/rfkill.
+  int rfkill_fd_{-1};
+  // File descriptor opened to the bluetooth user channel.
+  int bt_fd_{-1};
+};
+
+}  // namespace aidl::android::hardware::bluetooth::impl
diff --git a/bluetooth/aidl/default/service.cpp b/bluetooth/aidl/default/service.cpp
new file mode 100644
index 0000000..ef4b884
--- /dev/null
+++ b/bluetooth/aidl/default/service.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "aidl.android.hardware.bluetooth.service.default"
+
+#include <aidl/android/hardware/bluetooth/IBluetoothHci.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "BluetoothHci.h"
+
+using ::aidl::android::hardware::bluetooth::impl::BluetoothHci;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+
+int main(int /* argc */, char** /* argv */) {
+  ALOGI("Bluetooth HAL starting");
+  if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+    ALOGI("failed to set thread pool max thread count");
+    return 1;
+  }
+
+  std::shared_ptr<BluetoothHci> service =
+      ndk::SharedRefBase::make<BluetoothHci>();
+  std::string instance = std::string() + BluetoothHci::descriptor + "/default";
+  auto result =
+      AServiceManager_addService(service->asBinder().get(), instance.c_str());
+  if (result == STATUS_OK) {
+    ABinderProcess_joinThreadPool();
+  } else {
+    ALOGE("Could not register as a service!");
+  }
+  return 0;
+}
diff --git a/bluetooth/aidl/default/test/fuzzer.cpp b/bluetooth/aidl/default/test/fuzzer.cpp
new file mode 100644
index 0000000..e7a1eef
--- /dev/null
+++ b/bluetooth/aidl/default/test/fuzzer.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "BluetoothHci.h"
+
+using aidl::android::hardware::bluetooth::impl::BluetoothHci;
+using android::fuzzService;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  auto service = SharedRefBase::make<BluetoothHci>();
+
+  fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+
+  return 0;
+}
diff --git a/bluetooth/aidl/vts/Android.bp b/bluetooth/aidl/vts/Android.bp
new file mode 100644
index 0000000..5fc0b2e
--- /dev/null
+++ b/bluetooth/aidl/vts/Android.bp
@@ -0,0 +1,62 @@
+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_test {
+    name: "VtsHalBluetoothTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "VtsHalBluetoothTargetTest.cpp",
+        ":BluetoothPacketSources",
+        ":BluetoothHciPacketSources",
+    ],
+    generated_headers: [
+        "BluetoothGeneratedPackets_h",
+    ],
+    include_dirs: [
+        "packages/modules/Bluetooth/system/gd",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+    ],
+    static_libs: [
+        "android.hardware.bluetooth-V1-ndk",
+        "libbluetooth-types",
+    ],
+    test_config: "VtsHalBluetoothTargetTest.xml",
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    tidy: true,
+    tidy_checks: [
+        "-*",
+        "readability-inconsistent-declaration-parameter-name",
+        "readability-*",
+        "-readability-function-size",
+        "-readability-identifier-length",
+        "-readability-implicit-bool-conversion",
+        "-readability-magic-numbers",
+        "-readability-use-anyofallof",
+    ],
+    tidy_checks_as_errors: [
+        "readability-*",
+    ],
+    tidy_flags: [
+        "--header-filter=^.*tools\\/rootcanal\\/(model|include|net|desktop)\\/(.(?!\\.pb\\.h))*$",
+    ],
+    tidy_disabled_srcs: [
+        ":BluetoothPacketSources",
+        ":BluetoothHciPacketSources",
+    ],
+}
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
new file mode 100644
index 0000000..24eb4d0
--- /dev/null
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
@@ -0,0 +1,1054 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/BnBluetoothHciCallbacks.h>
+#include <aidl/android/hardware/bluetooth/IBluetoothHci.h>
+#include <aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.h>
+#include <aidl/android/hardware/bluetooth/Status.h>
+#include <android-base/properties.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+
+#include <atomic>
+#include <chrono>
+#include <condition_variable>
+#include <future>
+#include <queue>
+#include <thread>
+#include <utility>
+#include <vector>
+
+// TODO: Remove custom logging defines from PDL packets.
+#undef LOG_INFO
+#undef LOG_DEBUG
+#undef LOG_TAG
+#define LOG_TAG "VtsHalBluetooth"
+#include "hci/hci_packets.h"
+#include "packet/raw_builder.h"
+
+using aidl::android::hardware::bluetooth::IBluetoothHci;
+using aidl::android::hardware::bluetooth::IBluetoothHciCallbacks;
+using aidl::android::hardware::bluetooth::Status;
+using ndk::ScopedAStatus;
+using ndk::SpAIBinder;
+
+using ::bluetooth::hci::CommandBuilder;
+using ::bluetooth::hci::CommandCompleteView;
+using ::bluetooth::hci::CommandView;
+using ::bluetooth::hci::ErrorCode;
+using ::bluetooth::hci::EventView;
+using ::bluetooth::hci::LeReadLocalSupportedFeaturesBuilder;
+using ::bluetooth::hci::LeReadLocalSupportedFeaturesCompleteView;
+using ::bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsBuilder;
+using ::bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsCompleteView;
+using ::bluetooth::hci::LeReadResolvingListSizeBuilder;
+using ::bluetooth::hci::LeReadResolvingListSizeCompleteView;
+using ::bluetooth::hci::LLFeaturesBits;
+using ::bluetooth::hci::OpCode;
+using ::bluetooth::hci::OpCodeText;
+using ::bluetooth::hci::PacketView;
+using ::bluetooth::hci::ReadLocalVersionInformationBuilder;
+using ::bluetooth::hci::ReadLocalVersionInformationCompleteView;
+
+static constexpr uint8_t kMinLeAdvSetForBt5 = 16;
+static constexpr uint8_t kMinLeAdvSetForBt5FoTv = 10;
+static constexpr uint8_t kMinLeResolvingListForBt5 = 8;
+
+static constexpr size_t kNumHciCommandsBandwidth = 100;
+static constexpr size_t kNumScoPacketsBandwidth = 100;
+static constexpr size_t kNumAclPacketsBandwidth = 100;
+static constexpr std::chrono::milliseconds kWaitForInitTimeout(2000);
+static constexpr std::chrono::milliseconds kWaitForHciEventTimeout(2000);
+static constexpr std::chrono::milliseconds kWaitForScoDataTimeout(1000);
+static constexpr std::chrono::milliseconds kWaitForAclDataTimeout(1000);
+static constexpr std::chrono::milliseconds kInterfaceCloseDelayMs(200);
+
+// To discard Qualcomm ACL debugging
+static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc;
+
+static int get_vsr_api_level() {
+  int vendor_api_level =
+      ::android::base::GetIntProperty("ro.vendor.api_level", -1);
+  if (vendor_api_level != -1) {
+    return vendor_api_level;
+  }
+
+  // Android S and older devices do not define ro.vendor.api_level
+  vendor_api_level = ::android::base::GetIntProperty("ro.board.api_level", -1);
+  if (vendor_api_level == -1) {
+    vendor_api_level =
+        ::android::base::GetIntProperty("ro.board.first_api_level", -1);
+  }
+
+  int product_api_level =
+      ::android::base::GetIntProperty("ro.product.first_api_level", -1);
+  if (product_api_level == -1) {
+    product_api_level =
+        ::android::base::GetIntProperty("ro.build.version.sdk", -1);
+    EXPECT_NE(product_api_level, -1) << "Could not find ro.build.version.sdk";
+  }
+
+  // VSR API level is the minimum of vendor_api_level and product_api_level.
+  if (vendor_api_level == -1 || vendor_api_level > product_api_level) {
+    return product_api_level;
+  }
+  return vendor_api_level;
+}
+
+static bool isTv() {
+  return testing::deviceSupportsFeature("android.software.leanback") ||
+         testing::deviceSupportsFeature("android.hardware.type.television");
+}
+
+class ThroughputLogger {
+ public:
+  explicit ThroughputLogger(std::string task)
+      : total_bytes_(0),
+        task_(std::move(task)),
+        start_time_(std::chrono::steady_clock::now()) {}
+
+  ~ThroughputLogger() {
+    if (total_bytes_ == 0) {
+      return;
+    }
+    std::chrono::duration<double> duration =
+        std::chrono::steady_clock::now() - start_time_;
+    double s = duration.count();
+    if (s == 0) {
+      return;
+    }
+    double rate_kb = (static_cast<double>(total_bytes_) / s) / 1024;
+    ALOGD("%s %.1f KB/s (%zu bytes in %.3fs)", task_.c_str(), rate_kb,
+          total_bytes_, s);
+  }
+
+  void setTotalBytes(size_t total_bytes) { total_bytes_ = total_bytes; }
+
+ private:
+  size_t total_bytes_;
+  std::string task_;
+  std::chrono::steady_clock::time_point start_time_;
+};
+
+// The main test class for Bluetooth HAL.
+class BluetoothAidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+  void SetUp() override {
+    // currently test passthrough mode only
+    hci = IBluetoothHci::fromBinder(
+        SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(hci, nullptr);
+    ALOGI("%s: getService() for bluetooth hci is %s", __func__,
+          hci->isRemote() ? "remote" : "local");
+
+    // Lambda function
+    auto on_binder_death = [](void* /*cookie*/) { FAIL(); };
+
+    bluetooth_hci_death_recipient =
+        AIBinder_DeathRecipient_new(on_binder_death);
+    ASSERT_NE(bluetooth_hci_death_recipient, nullptr);
+    ASSERT_EQ(STATUS_OK,
+              AIBinder_linkToDeath(hci->asBinder().get(),
+                                   bluetooth_hci_death_recipient, nullptr));
+
+    hci_cb = ndk::SharedRefBase::make<BluetoothHciCallbacks>(*this);
+    ASSERT_NE(hci_cb, nullptr);
+
+    max_acl_data_packet_length = 0;
+    max_sco_data_packet_length = 0;
+    max_acl_data_packets = 0;
+    max_sco_data_packets = 0;
+
+    event_cb_count = 0;
+    acl_cb_count = 0;
+    sco_cb_count = 0;
+
+    ASSERT_TRUE(hci->initialize(hci_cb).isOk());
+    auto future = initialized_promise.get_future();
+    auto timeout_status = future.wait_for(kWaitForInitTimeout);
+    ASSERT_EQ(timeout_status, std::future_status::ready);
+    ASSERT_TRUE(future.get());
+  }
+
+  void TearDown() override {
+    ALOGI("TearDown");
+    // Should not be checked in production code
+    ASSERT_TRUE(hci->close().isOk());
+    std::this_thread::sleep_for(kInterfaceCloseDelayMs);
+    handle_no_ops();
+    discard_qca_debugging();
+    EXPECT_EQ(static_cast<size_t>(0), event_queue.size());
+    EXPECT_EQ(static_cast<size_t>(0), sco_queue.size());
+    EXPECT_EQ(static_cast<size_t>(0), acl_queue.size());
+    EXPECT_EQ(static_cast<size_t>(0), iso_queue.size());
+  }
+
+  void setBufferSizes();
+  void setSynchronousFlowControlEnable();
+
+  // Functions called from within tests in loopback mode
+  void sendAndCheckHci(int num_packets);
+  void sendAndCheckSco(int num_packets, size_t size, uint16_t handle);
+  void sendAndCheckAcl(int num_packets, size_t size, uint16_t handle);
+
+  // Helper functions to try to get a handle on verbosity
+  void enterLoopbackMode();
+  void handle_no_ops();
+  void discard_qca_debugging();
+  void wait_for_event(bool timeout_is_error);
+  void wait_for_command_complete_event(OpCode opCode,
+                                       std::vector<uint8_t>& complete_event);
+  // Wait until a command complete is received.
+  // Command complete will be consumed after this method
+  void wait_and_validate_command_complete_event(OpCode opCode);
+  int wait_for_completed_packets_event(uint16_t handle);
+  void send_and_wait_for_cmd_complete(std::unique_ptr<CommandBuilder> cmd,
+                                      std::vector<uint8_t>& cmd_complete);
+  void reassemble_sco_loopback_pkt(std::vector<uint8_t>& scoPackets,
+    size_t size);
+
+  // A simple test implementation of BluetoothHciCallbacks.
+  class BluetoothHciCallbacks
+      : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
+    BluetoothAidlTest& parent_;
+
+   public:
+    explicit BluetoothHciCallbacks(BluetoothAidlTest& parent)
+        : parent_(parent){};
+
+    ~BluetoothHciCallbacks() override = default;
+
+    ndk::ScopedAStatus initializationComplete(Status status) override {
+      parent_.initialized_promise.set_value(status == Status::SUCCESS);
+      ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
+      return ScopedAStatus::ok();
+    };
+
+    ndk::ScopedAStatus hciEventReceived(
+        const std::vector<uint8_t>& event) override {
+      parent_.event_cb_count++;
+      parent_.event_queue.push(event);
+      ALOGI("Event received (length = %d)", static_cast<int>(event.size()));
+      return ScopedAStatus::ok();
+    };
+
+    ndk::ScopedAStatus aclDataReceived(
+        const std::vector<uint8_t>& data) override {
+      parent_.acl_cb_count++;
+      parent_.acl_queue.push(data);
+      return ScopedAStatus::ok();
+    };
+
+    ndk::ScopedAStatus scoDataReceived(
+        const std::vector<uint8_t>& data) override {
+      parent_.sco_cb_count++;
+      parent_.sco_queue.push(data);
+      return ScopedAStatus::ok();
+    };
+
+    ndk::ScopedAStatus isoDataReceived(
+        const std::vector<uint8_t>& data) override {
+      parent_.iso_cb_count++;
+      parent_.iso_queue.push(data);
+      return ScopedAStatus::ok();
+    };
+  };
+
+  template <class T>
+  class WaitQueue {
+   public:
+    WaitQueue() = default;
+    ;
+
+    virtual ~WaitQueue() = default;
+
+    bool empty() const {
+      std::lock_guard<std::mutex> lock(m_);
+      return q_.empty();
+    };
+
+    size_t size() const {
+      std::lock_guard<std::mutex> lock(m_);
+      return q_.size();
+    };
+
+    void push(const T& v) {
+      std::lock_guard<std::mutex> lock(m_);
+      q_.push(v);
+      ready_.notify_one();
+    };
+
+    bool pop(T& v) {
+      std::lock_guard<std::mutex> lock(m_);
+      if (q_.empty()) {
+        return false;
+      }
+      v = std::move(q_.front());
+      q_.pop();
+      return true;
+    };
+
+    void pop() {
+      std::lock_guard<std::mutex> lock(m_);
+      if (q_.empty()) {
+        return;
+      }
+      q_.pop();
+    };
+
+    bool front(T& v) {
+      std::lock_guard<std::mutex> lock(m_);
+      if (q_.empty()) {
+        return false;
+      }
+      v = q_.front();
+      return true;
+    };
+
+    void wait() {
+      std::unique_lock<std::mutex> lock(m_);
+      while (q_.empty()) {
+        ready_.wait(lock);
+      }
+    };
+
+    bool waitWithTimeout(std::chrono::milliseconds timeout) {
+      std::unique_lock<std::mutex> lock(m_);
+      while (q_.empty()) {
+        if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
+          return false;
+        }
+      }
+      return true;
+    };
+
+    bool tryPopWithTimeout(T& v, std::chrono::milliseconds timeout) {
+      std::unique_lock<std::mutex> lock(m_);
+      while (q_.empty()) {
+        if (ready_.wait_for(lock, timeout) == std::cv_status::timeout) {
+          return false;
+        }
+      }
+      v = std::move(q_.front());
+      q_.pop();
+      return true;
+    };
+
+   private:
+    mutable std::mutex m_;
+    std::queue<T> q_;
+    std::condition_variable_any ready_;
+  };
+
+  std::shared_ptr<IBluetoothHci> hci;
+  std::shared_ptr<BluetoothHciCallbacks> hci_cb;
+  AIBinder_DeathRecipient* bluetooth_hci_death_recipient{};
+  WaitQueue<std::vector<uint8_t>> event_queue;
+  WaitQueue<std::vector<uint8_t>> acl_queue;
+  WaitQueue<std::vector<uint8_t>> sco_queue;
+  WaitQueue<std::vector<uint8_t>> iso_queue;
+
+  std::promise<bool> initialized_promise;
+  int event_cb_count{};
+  int sco_cb_count{};
+  int acl_cb_count{};
+  int iso_cb_count{};
+
+  int max_acl_data_packet_length{};
+  int max_sco_data_packet_length{};
+  int max_acl_data_packets{};
+  int max_sco_data_packets{};
+
+  std::vector<uint16_t> sco_connection_handles;
+  std::vector<uint16_t> acl_connection_handles;
+};
+
+// Discard NO-OPs from the event queue.
+void BluetoothAidlTest::handle_no_ops() {
+  while (!event_queue.empty()) {
+    std::vector<uint8_t> event;
+    event_queue.front(event);
+    auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event))));
+    auto status_view = ::bluetooth::hci::CommandCompleteView::Create(
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event))));
+    bool is_complete_no_op =
+        complete_view.IsValid() &&
+        complete_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
+    bool is_status_no_op =
+        status_view.IsValid() &&
+        status_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
+    if (is_complete_no_op || is_status_no_op) {
+      event_queue.pop();
+    } else {
+      break;
+    }
+  }
+}
+
+// Discard Qualcomm ACL debugging
+void BluetoothAidlTest::discard_qca_debugging() {
+  while (!acl_queue.empty()) {
+    std::vector<uint8_t> acl_packet;
+    acl_queue.front(acl_packet);
+    auto acl_view =
+        ::bluetooth::hci::AclView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(acl_packet)));
+    EXPECT_TRUE(acl_view.IsValid());
+    if (acl_view.GetHandle() == kAclHandleQcaDebugMessage) {
+      acl_queue.pop();
+    } else {
+      break;
+    }
+  }
+}
+
+// Receive an event, discarding NO-OPs.
+void BluetoothAidlTest::wait_for_event(bool timeout_is_error = true) {
+  // Wait until we get something that's not a no-op.
+  while (true) {
+    bool event_ready = event_queue.waitWithTimeout(kWaitForHciEventTimeout);
+    ASSERT_TRUE(event_ready || !timeout_is_error);
+    if (event_queue.empty()) {
+      // waitWithTimeout timed out
+      return;
+    }
+    handle_no_ops();
+    if (!event_queue.empty()) {
+      // There's an event in the queue that's not a no-op.
+      return;
+    }
+  }
+}
+
+void BluetoothAidlTest::wait_for_command_complete_event(
+    OpCode opCode, std::vector<uint8_t>& complete_event) {
+  ASSERT_NO_FATAL_FAILURE(wait_for_event());
+  ASSERT_FALSE(event_queue.empty());
+  ASSERT_TRUE(event_queue.pop(complete_event));
+  auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
+      ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(complete_event))));
+  ASSERT_TRUE(complete_view.IsValid());
+  ASSERT_EQ(complete_view.GetCommandOpCode(), opCode);
+  ASSERT_EQ(complete_view.GetPayload()[0],
+            static_cast<uint8_t>(::bluetooth::hci::ErrorCode::SUCCESS));
+}
+
+void BluetoothAidlTest::wait_and_validate_command_complete_event(
+    ::bluetooth::hci::OpCode opCode) {
+  std::vector<uint8_t> complete_event;
+  ASSERT_NO_FATAL_FAILURE(
+      wait_for_command_complete_event(opCode, complete_event));
+}
+
+// Send the command to read the controller's buffer sizes.
+void BluetoothAidlTest::setBufferSizes() {
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::ReadBufferSizeBuilder::Create()->Serialize(bi);
+  hci->sendHciCommand(cmd);
+
+  ASSERT_NO_FATAL_FAILURE(wait_for_event());
+  std::vector<uint8_t> event;
+  ASSERT_TRUE(event_queue.pop(event));
+  auto complete_view = ::bluetooth::hci::ReadBufferSizeCompleteView::Create(
+      ::bluetooth::hci::CommandCompleteView::Create(
+          ::bluetooth::hci::EventView::Create(
+              ::bluetooth::hci::PacketView<true>(
+                  std::make_shared<std::vector<uint8_t>>(event)))));
+
+  ASSERT_TRUE(complete_view.IsValid());
+  ASSERT_EQ(complete_view.GetStatus(), ::bluetooth::hci::ErrorCode::SUCCESS);
+  max_acl_data_packet_length = complete_view.GetAclDataPacketLength();
+  max_sco_data_packet_length = complete_view.GetSynchronousDataPacketLength();
+  max_acl_data_packets = complete_view.GetTotalNumAclDataPackets();
+  max_sco_data_packets = complete_view.GetTotalNumSynchronousDataPackets();
+
+  ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__,
+        static_cast<int>(max_acl_data_packet_length),
+        static_cast<int>(max_acl_data_packets),
+        static_cast<int>(max_sco_data_packet_length),
+        static_cast<int>(max_sco_data_packets));
+}
+
+// Enable flow control packets for SCO
+void BluetoothAidlTest::setSynchronousFlowControlEnable() {
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::WriteSynchronousFlowControlEnableBuilder::Create(
+      ::bluetooth::hci::Enable::ENABLED)
+      ->Serialize(bi);
+  hci->sendHciCommand(cmd);
+
+  wait_and_validate_command_complete_event(
+      ::bluetooth::hci::OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE);
+}
+
+// Send an HCI command (in Loopback mode) and check the response.
+void BluetoothAidlTest::sendAndCheckHci(int num_packets) {
+  ThroughputLogger logger{__func__};
+  size_t command_size = 0;
+  char new_name[] = "John Jacob Jingleheimer Schmidt ___________________";
+  size_t new_name_length = strlen(new_name);
+  for (int n = 0; n < num_packets; n++) {
+    // The name to set is new_name
+    std::array<uint8_t, 248> name_array{};
+    for (size_t i = 0; i < new_name_length; i++) {
+      name_array[i] = new_name[i];
+    }
+    // And the packet number
+    char number[11] = "0000000000";
+    snprintf(number, sizeof(number), "%010d", static_cast<int>(n));
+    for (size_t i = new_name_length; i < new_name_length + sizeof(number) - 1;
+         i++) {
+      name_array[new_name_length + i] = number[i];
+    }
+    std::vector<uint8_t> write_name;
+    ::bluetooth::packet::BitInserter bi{write_name};
+    ::bluetooth::hci::WriteLocalNameBuilder::Create(name_array)->Serialize(bi);
+    hci->sendHciCommand(write_name);
+
+    // Check the loopback of the HCI packet
+    ASSERT_NO_FATAL_FAILURE(wait_for_event());
+
+    std::vector<uint8_t> event;
+    ASSERT_TRUE(event_queue.pop(event));
+    auto event_view = ::bluetooth::hci::LoopbackCommandView::Create(
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event))));
+    ASSERT_TRUE(event_view.IsValid());
+    std::vector<uint8_t> looped_back_command{event_view.GetPayload().begin(),
+                                             event_view.GetPayload().end()};
+    ASSERT_EQ(looped_back_command, write_name);
+
+    if (n == num_packets - 1) {
+      command_size = write_name.size();
+    }
+  }
+  logger.setTotalBytes(command_size * num_packets * 2);
+}
+
+// Send a SCO data packet (in Loopback mode) and check the response.
+void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size,
+                                        uint16_t handle) {
+  ThroughputLogger logger{__func__};
+  for (int n = 0; n < num_packets; n++) {
+    // Send a SCO packet
+    std::vector<uint8_t> sco_packet;
+    std::vector<uint8_t> payload;
+    for (size_t i = 0; i < size; i++) {
+      payload.push_back(static_cast<uint8_t>(i + n));
+    }
+    ::bluetooth::packet::BitInserter bi{sco_packet};
+    ::bluetooth::hci::ScoBuilder::Create(
+        handle, ::bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED, payload)
+        ->Serialize(bi);
+    hci->sendScoData(sco_packet);
+
+    // Check the loopback of the SCO packet
+    std::vector<uint8_t> sco_loopback;
+    ASSERT_TRUE(
+        sco_queue.tryPopWithTimeout(sco_loopback, kWaitForScoDataTimeout));
+
+    if (sco_loopback.size() < size) {
+      // The packets may have been split for USB. Reassemble before checking.
+      reassemble_sco_loopback_pkt(sco_loopback, size);
+    }
+
+    ASSERT_EQ(sco_packet, sco_loopback);
+  }
+  logger.setTotalBytes(num_packets * size * 2);
+}
+
+// Send an ACL data packet (in Loopback mode) and check the response.
+void BluetoothAidlTest::sendAndCheckAcl(int num_packets, size_t size,
+                                        uint16_t handle) {
+  ThroughputLogger logger{__func__};
+  for (int n = 0; n < num_packets; n++) {
+    // Send an ACL packet with counting data
+    auto payload = std::make_unique<::bluetooth::packet::RawBuilder>();
+    for (size_t i = 0; i < size; i++) {
+      payload->AddOctets1(static_cast<uint8_t>(i + n));
+    }
+    std::vector<uint8_t> acl_packet;
+    ::bluetooth::packet::BitInserter bi{acl_packet};
+    ::bluetooth::hci::AclBuilder::Create(
+        handle,
+        ::bluetooth::hci::PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE,
+        ::bluetooth::hci::BroadcastFlag::POINT_TO_POINT, std::move(payload))
+        ->Serialize(bi);
+    hci->sendAclData(acl_packet);
+
+    std::vector<uint8_t> acl_loopback;
+    // Check the loopback of the ACL packet
+    ASSERT_TRUE(
+        acl_queue.tryPopWithTimeout(acl_loopback, kWaitForAclDataTimeout));
+
+    ASSERT_EQ(acl_packet, acl_loopback);
+  }
+  logger.setTotalBytes(num_packets * size * 2);
+}
+
+// Return the number of completed packets reported by the controller.
+int BluetoothAidlTest::wait_for_completed_packets_event(uint16_t handle) {
+  int packets_processed = 0;
+  while (true) {
+    // There should be at least one event.
+    wait_for_event(packets_processed == 0);
+    if (event_queue.empty()) {
+      if (packets_processed == 0) {
+        ALOGW("%s: waitForBluetoothCallback timed out.", __func__);
+      }
+      return packets_processed;
+    }
+    std::vector<uint8_t> event;
+    EXPECT_TRUE(event_queue.pop(event));
+    auto event_view = ::bluetooth::hci::NumberOfCompletedPacketsView::Create(
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event))));
+    if (!event_view.IsValid()) {
+      ADD_FAILURE();
+      return packets_processed;
+    }
+    auto completed_packets = event_view.GetCompletedPackets();
+    for (const auto& entry : completed_packets) {
+      EXPECT_EQ(handle, entry.connection_handle_);
+      packets_processed += entry.host_num_of_completed_packets_;
+    }
+  }
+  return packets_processed;
+}
+
+// Send local loopback command and initialize SCO and ACL handles.
+void BluetoothAidlTest::enterLoopbackMode() {
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::WriteLoopbackModeBuilder::Create(
+      bluetooth::hci::LoopbackMode::ENABLE_LOCAL)
+      ->Serialize(bi);
+  hci->sendHciCommand(cmd);
+
+  // Receive connection complete events with data channels
+  int connection_event_count = 0;
+  bool command_complete_received = false;
+  while (true) {
+    wait_for_event(false);
+    if (event_queue.empty()) {
+      // Fail if there was no event received or no connections completed.
+      ASSERT_TRUE(command_complete_received);
+      ASSERT_LT(0, connection_event_count);
+      return;
+    }
+    std::vector<uint8_t> event;
+    ASSERT_TRUE(event_queue.pop(event));
+    auto event_view =
+        ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+            std::make_shared<std::vector<uint8_t>>(event)));
+    ASSERT_TRUE(event_view.IsValid());
+
+    if (event_view.GetEventCode() ==
+        ::bluetooth::hci::EventCode::CONNECTION_COMPLETE) {
+      auto complete_view =
+          ::bluetooth::hci::ConnectionCompleteView::Create(event_view);
+      ASSERT_TRUE(complete_view.IsValid());
+      switch (complete_view.GetLinkType()) {
+        case ::bluetooth::hci::LinkType::ACL:
+          acl_connection_handles.push_back(complete_view.GetConnectionHandle());
+          break;
+        case ::bluetooth::hci::LinkType::SCO:
+          sco_connection_handles.push_back(complete_view.GetConnectionHandle());
+          break;
+        default:
+          ASSERT_EQ(complete_view.GetLinkType(),
+                    ::bluetooth::hci::LinkType::ACL);
+      }
+      connection_event_count++;
+    } else {
+      auto command_complete_view =
+          ::bluetooth::hci::WriteLoopbackModeCompleteView::Create(
+              ::bluetooth::hci::CommandCompleteView::Create(event_view));
+      ASSERT_TRUE(command_complete_view.IsValid());
+      ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS,
+                command_complete_view.GetStatus());
+      command_complete_received = true;
+    }
+  }
+}
+
+void BluetoothAidlTest::send_and_wait_for_cmd_complete(
+    std::unique_ptr<CommandBuilder> cmd, std::vector<uint8_t>& cmd_complete) {
+  std::vector<uint8_t> cmd_bytes = cmd->SerializeToBytes();
+  hci->sendHciCommand(cmd_bytes);
+
+  auto view = CommandView::Create(
+      PacketView<true>(std::make_shared<std::vector<uint8_t>>(cmd_bytes)));
+  ASSERT_TRUE(view.IsValid());
+  ALOGI("Waiting for %s[0x%x]", OpCodeText(view.GetOpCode()).c_str(),
+        static_cast<int>(view.GetOpCode()));
+  ASSERT_NO_FATAL_FAILURE(
+      wait_for_command_complete_event(view.GetOpCode(), cmd_complete));
+}
+
+// Handle the loopback packet.
+void BluetoothAidlTest::reassemble_sco_loopback_pkt(std::vector<uint8_t>& scoPackets,
+        size_t size) {
+    std::vector<uint8_t> sco_packet_whole;
+    sco_packet_whole.assign(scoPackets.begin(), scoPackets.end());
+    while (size + 3 > sco_packet_whole.size()) {
+      std::vector<uint8_t> sco_packets;
+      ASSERT_TRUE(
+      sco_queue.tryPopWithTimeout(sco_packets, kWaitForScoDataTimeout));
+      sco_packet_whole.insert(sco_packet_whole.end(), sco_packets.begin() + 3,
+          sco_packets.end());
+    }
+    scoPackets.assign(sco_packet_whole.begin(), sco_packet_whole.end());
+    scoPackets[2] = size;
+}
+
+// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
+TEST_P(BluetoothAidlTest, InitializeAndClose) {}
+
+// Send an HCI Reset with sendHciCommand and wait for a command complete event.
+TEST_P(BluetoothAidlTest, HciReset) {
+  std::vector<uint8_t> reset;
+  ::bluetooth::packet::BitInserter bi{reset};
+  ::bluetooth::hci::ResetBuilder::Create()->Serialize(bi);
+  hci->sendHciCommand(reset);
+
+  wait_and_validate_command_complete_event(::bluetooth::hci::OpCode::RESET);
+}
+
+// Read and check the HCI version of the controller.
+TEST_P(BluetoothAidlTest, HciVersionTest) {
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::ReadLocalVersionInformationBuilder::Create()->Serialize(bi);
+  hci->sendHciCommand(cmd);
+
+  ASSERT_NO_FATAL_FAILURE(wait_for_event());
+
+  std::vector<uint8_t> event;
+  ASSERT_TRUE(event_queue.pop(event));
+  auto complete_view =
+      ::bluetooth::hci::ReadLocalVersionInformationCompleteView::Create(
+          ::bluetooth::hci::CommandCompleteView::Create(
+              ::bluetooth::hci::EventView::Create(
+                  ::bluetooth::hci::PacketView<true>(
+                      std::make_shared<std::vector<uint8_t>>(event)))));
+  ASSERT_TRUE(complete_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, complete_view.GetStatus());
+  auto version = complete_view.GetLocalVersionInformation();
+  ASSERT_LE(::bluetooth::hci::HciVersion::V_3_0, version.hci_version_);
+  ASSERT_LE(::bluetooth::hci::LmpVersion::V_3_0, version.lmp_version_);
+}
+
+// Send an unknown HCI command and wait for the error message.
+TEST_P(BluetoothAidlTest, HciUnknownCommand) {
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  ::bluetooth::hci::CommandBuilder::Create(
+      static_cast<::bluetooth::hci::OpCode>(0x3cff),
+      std::make_unique<::bluetooth::packet::RawBuilder>())
+      ->Serialize(bi);
+  hci->sendHciCommand(cmd);
+
+  ASSERT_NO_FATAL_FAILURE(wait_for_event());
+
+  std::vector<uint8_t> event;
+  ASSERT_TRUE(event_queue.pop(event));
+  auto event_view =
+      ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(event)));
+  ASSERT_TRUE(event_view.IsValid());
+
+  switch (event_view.GetEventCode()) {
+    case ::bluetooth::hci::EventCode::COMMAND_COMPLETE: {
+      auto command_complete =
+          ::bluetooth::hci::CommandCompleteView::Create(event_view);
+      ASSERT_TRUE(command_complete.IsValid());
+      ASSERT_EQ(command_complete.GetPayload()[0],
+                static_cast<uint8_t>(
+                    ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND));
+    } break;
+    case ::bluetooth::hci::EventCode::COMMAND_STATUS: {
+      auto command_status =
+          ::bluetooth::hci::CommandStatusView::Create(event_view);
+      ASSERT_TRUE(command_status.IsValid());
+      ASSERT_EQ(command_status.GetStatus(),
+                ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
+    } break;
+    default:
+      ADD_FAILURE();
+  }
+}
+
+// Enter loopback mode, but don't send any packets.
+TEST_P(BluetoothAidlTest, WriteLoopbackMode) { enterLoopbackMode(); }
+
+// Enter loopback mode and send a single command.
+TEST_P(BluetoothAidlTest, LoopbackModeSingleCommand) {
+  setBufferSizes();
+
+  enterLoopbackMode();
+
+  sendAndCheckHci(1);
+}
+
+// Enter loopback mode and send a single SCO packet.
+TEST_P(BluetoothAidlTest, LoopbackModeSingleSco) {
+  setBufferSizes();
+  setSynchronousFlowControlEnable();
+
+  enterLoopbackMode();
+
+  if (!sco_connection_handles.empty()) {
+    ASSERT_LT(0, max_sco_data_packet_length);
+    sendAndCheckSco(1, max_sco_data_packet_length, sco_connection_handles[0]);
+    int sco_packets_sent = 1;
+    int completed_packets =
+        wait_for_completed_packets_event(sco_connection_handles[0]);
+    if (sco_packets_sent != completed_packets) {
+      ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+            sco_packets_sent, completed_packets);
+    }
+  }
+}
+
+// Enter loopback mode and send a single ACL packet.
+TEST_P(BluetoothAidlTest, LoopbackModeSingleAcl) {
+  setBufferSizes();
+
+  enterLoopbackMode();
+
+  if (!acl_connection_handles.empty()) {
+    ASSERT_LT(0, max_acl_data_packet_length);
+    sendAndCheckAcl(1, max_acl_data_packet_length - 1,
+                    acl_connection_handles[0]);
+    int acl_packets_sent = 1;
+    int completed_packets =
+        wait_for_completed_packets_event(acl_connection_handles[0]);
+    if (acl_packets_sent != completed_packets) {
+      ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+            acl_packets_sent, completed_packets);
+    }
+  }
+  ASSERT_GE(acl_cb_count, 1);
+}
+
+// Enter loopback mode and send command packets for bandwidth measurements.
+TEST_P(BluetoothAidlTest, LoopbackModeCommandBandwidth) {
+  setBufferSizes();
+
+  enterLoopbackMode();
+
+  sendAndCheckHci(kNumHciCommandsBandwidth);
+}
+
+// Enter loopback mode and send SCO packets for bandwidth measurements.
+TEST_P(BluetoothAidlTest, LoopbackModeScoBandwidth) {
+  setBufferSizes();
+  setSynchronousFlowControlEnable();
+
+  enterLoopbackMode();
+
+  if (!sco_connection_handles.empty()) {
+    ASSERT_LT(0, max_sco_data_packet_length);
+    sendAndCheckSco(kNumScoPacketsBandwidth, max_sco_data_packet_length,
+                    sco_connection_handles[0]);
+    int sco_packets_sent = kNumScoPacketsBandwidth;
+    int completed_packets =
+        wait_for_completed_packets_event(sco_connection_handles[0]);
+    if (sco_packets_sent != completed_packets) {
+      ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+            sco_packets_sent, completed_packets);
+    }
+  }
+}
+
+// Enter loopback mode and send packets for ACL bandwidth measurements.
+TEST_P(BluetoothAidlTest, LoopbackModeAclBandwidth) {
+  setBufferSizes();
+
+  enterLoopbackMode();
+
+  if (!acl_connection_handles.empty()) {
+    ASSERT_LT(0, max_acl_data_packet_length);
+    sendAndCheckAcl(kNumAclPacketsBandwidth, max_acl_data_packet_length - 1,
+                    acl_connection_handles[0]);
+    int acl_packets_sent = kNumAclPacketsBandwidth;
+    int completed_packets =
+        wait_for_completed_packets_event(acl_connection_handles[0]);
+    if (acl_packets_sent != completed_packets) {
+      ALOGW("%s: packets_sent (%d) != completed_packets (%d)", __func__,
+            acl_packets_sent, completed_packets);
+    }
+  }
+}
+
+// Set all bits in the event mask
+TEST_P(BluetoothAidlTest, SetEventMask) {
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  uint64_t full_mask = UINT64_MAX;
+  ::bluetooth::hci::SetEventMaskBuilder::Create(full_mask)->Serialize(bi);
+  hci->sendHciCommand(cmd);
+  wait_and_validate_command_complete_event(
+      ::bluetooth::hci::OpCode::SET_EVENT_MASK);
+}
+
+// Set all bits in the LE event mask
+TEST_P(BluetoothAidlTest, SetLeEventMask) {
+  std::vector<uint8_t> cmd;
+  ::bluetooth::packet::BitInserter bi{cmd};
+  uint64_t full_mask = UINT64_MAX;
+  ::bluetooth::hci::LeSetEventMaskBuilder::Create(full_mask)->Serialize(bi);
+  hci->sendHciCommand(cmd);
+  wait_and_validate_command_complete_event(
+      ::bluetooth::hci::OpCode::LE_SET_EVENT_MASK);
+}
+
+// Call initialize twice, second one should fail.
+TEST_P(BluetoothAidlTest, CallInitializeTwice) {
+  class SecondCb
+      : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
+   public:
+    ndk::ScopedAStatus initializationComplete(Status status) override {
+      EXPECT_EQ(status, Status::ALREADY_INITIALIZED);
+      init_promise.set_value();
+      return ScopedAStatus::ok();
+    };
+
+    ndk::ScopedAStatus hciEventReceived(
+        const std::vector<uint8_t>& /*event*/) override {
+      ADD_FAILURE();
+      return ScopedAStatus::ok();
+    };
+
+    ndk::ScopedAStatus aclDataReceived(
+        const std::vector<uint8_t>& /*data*/) override {
+      ADD_FAILURE();
+      return ScopedAStatus::ok();
+    };
+
+    ndk::ScopedAStatus scoDataReceived(
+        const std::vector<uint8_t>& /*data*/) override {
+      ADD_FAILURE();
+      return ScopedAStatus::ok();
+    };
+
+    ndk::ScopedAStatus isoDataReceived(
+        const std::vector<uint8_t>& /*data*/) override {
+      ADD_FAILURE();
+      return ScopedAStatus::ok();
+    };
+    std::promise<void> init_promise;
+  };
+
+  std::shared_ptr<SecondCb> second_cb = ndk::SharedRefBase::make<SecondCb>();
+  ASSERT_NE(second_cb, nullptr);
+
+  auto future = second_cb->init_promise.get_future();
+  ASSERT_TRUE(hci->initialize(second_cb).isOk());
+  auto status = future.wait_for(std::chrono::seconds(1));
+  ASSERT_EQ(status, std::future_status::ready);
+}
+
+TEST_P(BluetoothAidlTest, Vsr_Bluetooth5Requirements) {
+  std::vector<uint8_t> version_event;
+  send_and_wait_for_cmd_complete(ReadLocalVersionInformationBuilder::Create(),
+                                 version_event);
+  auto version_view = ReadLocalVersionInformationCompleteView::Create(
+      CommandCompleteView::Create(EventView::Create(PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(version_event)))));
+  ASSERT_TRUE(version_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, version_view.GetStatus());
+  auto version = version_view.GetLocalVersionInformation();
+  if (version.hci_version_ < ::bluetooth::hci::HciVersion::V_5_0) {
+    // This test does not apply to controllers below 5.0
+    return;
+  };
+  // When HCI version is 5.0, LMP version must also be at least 5.0
+  ASSERT_GE(static_cast<int>(version.lmp_version_),
+            static_cast<int>(version.hci_version_));
+
+  std::vector<uint8_t> le_features_event;
+  send_and_wait_for_cmd_complete(LeReadLocalSupportedFeaturesBuilder::Create(),
+                                 le_features_event);
+  auto le_features_view = LeReadLocalSupportedFeaturesCompleteView::Create(
+      CommandCompleteView::Create(EventView::Create(PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(le_features_event)))));
+  ASSERT_TRUE(le_features_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, le_features_view.GetStatus());
+  auto le_features = le_features_view.GetLeFeatures();
+  ASSERT_TRUE(le_features & static_cast<uint64_t>(LLFeaturesBits::LL_PRIVACY));
+  ASSERT_TRUE(le_features & static_cast<uint64_t>(LLFeaturesBits::LE_2M_PHY));
+  ASSERT_TRUE(le_features &
+              static_cast<uint64_t>(LLFeaturesBits::LE_CODED_PHY));
+  ASSERT_TRUE(le_features &
+              static_cast<uint64_t>(LLFeaturesBits::LE_EXTENDED_ADVERTISING));
+
+  std::vector<uint8_t> num_adv_set_event;
+  send_and_wait_for_cmd_complete(
+      LeReadNumberOfSupportedAdvertisingSetsBuilder::Create(),
+      num_adv_set_event);
+  auto num_adv_set_view =
+      LeReadNumberOfSupportedAdvertisingSetsCompleteView::Create(
+          CommandCompleteView::Create(EventView::Create(PacketView<true>(
+              std::make_shared<std::vector<uint8_t>>(num_adv_set_event)))));
+  ASSERT_TRUE(num_adv_set_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, num_adv_set_view.GetStatus());
+  auto num_adv_set = num_adv_set_view.GetNumberSupportedAdvertisingSets();
+
+  if (isTv() && get_vsr_api_level() == __ANDROID_API_U__) {
+    ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5FoTv);
+  } else {
+    ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5);
+  }
+
+  std::vector<uint8_t> num_resolving_list_event;
+  send_and_wait_for_cmd_complete(LeReadResolvingListSizeBuilder::Create(),
+                                 num_resolving_list_event);
+  auto num_resolving_list_view = LeReadResolvingListSizeCompleteView::Create(
+      CommandCompleteView::Create(EventView::Create(PacketView<true>(
+          std::make_shared<std::vector<uint8_t>>(num_resolving_list_event)))));
+  ASSERT_TRUE(num_resolving_list_view.IsValid());
+  ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS,
+            num_resolving_list_view.GetStatus());
+  auto num_resolving_list = num_resolving_list_view.GetResolvingListSize();
+  ASSERT_GE(num_resolving_list, kMinLeResolvingListForBt5);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothHci::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+  ABinderProcess_startThreadPool();
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  ALOGI("Test result = %d", status);
+  return status;
+}
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.xml b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.xml
new file mode 100644
index 0000000..3a42ae6
--- /dev/null
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs VtsHalBluetoothTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="settings put global ble_scan_always_enabled 0" />
+        <option name="run-command" value="cmd bluetooth_manager disable" />
+        <option name="run-command" value="cmd bluetooth_manager wait-for-state:STATE_OFF" />
+        <option name="teardown-command" value="cmd bluetooth_manager enable" />
+        <option name="teardown-command" value="cmd bluetooth_manager wait-for-state:STATE_ON" />
+        <option name="teardown-command" value="settings put global ble_scan_always_enabled 1" />
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalBluetoothTargetTest->/data/local/tmp/VtsHalBluetoothTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalBluetoothTargetTest" />
+    </test>
+</configuration>
diff --git a/bluetooth/async/Android.bp b/bluetooth/async/Android.bp
new file mode 100644
index 0000000..bd7d7b8
--- /dev/null
+++ b/bluetooth/async/Android.bp
@@ -0,0 +1,41 @@
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_static {
+    name: "android.hardware.bluetooth.async",
+    vendor_available: true,
+    host_supported: true,
+    srcs: [
+        "async_fd_watcher.cc",
+    ],
+    export_include_dirs: ["."],
+    shared_libs: [
+        "liblog",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
+
+cc_test {
+    name: "bluetooth-vendor-interface-async-test",
+    host_supported: true,
+    srcs: [
+        "test/async_fd_watcher_unittest.cc",
+    ],
+    shared_libs: [
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.bluetooth.async",
+        "libgmock",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    test_suites: ["general-tests"],
+}
diff --git a/bluetooth/async/async_fd_watcher.cc b/bluetooth/async/async_fd_watcher.cc
new file mode 100644
index 0000000..fb634ff
--- /dev/null
+++ b/bluetooth/async/async_fd_watcher.cc
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "async_fd_watcher.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <atomic>
+#include <condition_variable>
+#include <map>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#include "fcntl.h"
+#include "log/log.h"
+#include "sys/select.h"
+#include "unistd.h"
+
+static const int INVALID_FD = -1;
+
+namespace android::hardware::bluetooth::async {
+
+int AsyncFdWatcher::WatchFdForNonBlockingReads(
+    int file_descriptor, const ReadCallback& on_read_fd_ready_callback) {
+  // Add file descriptor and callback
+  {
+    std::unique_lock<std::mutex> guard(internal_mutex_);
+    watched_fds_[file_descriptor] = on_read_fd_ready_callback;
+  }
+
+  // Start the thread if not started yet
+  return tryStartThread();
+}
+
+int AsyncFdWatcher::ConfigureTimeout(
+    const std::chrono::milliseconds timeout,
+    const TimeoutCallback& on_timeout_callback) {
+  // Add timeout and callback
+  {
+    std::unique_lock<std::mutex> guard(timeout_mutex_);
+    timeout_cb_ = on_timeout_callback;
+    timeout_ms_ = timeout;
+  }
+
+  notifyThread();
+  return 0;
+}
+
+void AsyncFdWatcher::StopWatchingFileDescriptors() { stopThread(); }
+
+AsyncFdWatcher::~AsyncFdWatcher() {}
+
+// Make sure to call this with at least one file descriptor ready to be
+// watched upon or the thread routine will return immediately
+int AsyncFdWatcher::tryStartThread() {
+  if (std::atomic_exchange(&running_, true)) return 0;
+
+  // Set up the communication channel
+  int pipe_fds[2];
+  if (pipe2(pipe_fds, O_NONBLOCK)) return -1;
+
+  notification_listen_fd_ = pipe_fds[0];
+  notification_write_fd_ = pipe_fds[1];
+
+  thread_ = std::thread([this]() { ThreadRoutine(); });
+  if (!thread_.joinable()) return -1;
+
+  return 0;
+}
+
+int AsyncFdWatcher::stopThread() {
+  if (!std::atomic_exchange(&running_, false)) return 0;
+
+  notifyThread();
+  if (std::this_thread::get_id() != thread_.get_id()) {
+    thread_.join();
+  }
+
+  {
+    std::unique_lock<std::mutex> guard(internal_mutex_);
+    watched_fds_.clear();
+  }
+
+  {
+    std::unique_lock<std::mutex> guard(timeout_mutex_);
+    timeout_cb_ = nullptr;
+  }
+
+  close(notification_listen_fd_);
+  close(notification_write_fd_);
+
+  return 0;
+}
+
+int AsyncFdWatcher::notifyThread() {
+  uint8_t buffer[] = {0};
+  if (TEMP_FAILURE_RETRY(write(notification_write_fd_, &buffer, 1)) < 0) {
+    return -1;
+  }
+  return 0;
+}
+
+void AsyncFdWatcher::ThreadRoutine() {
+  while (running_) {
+    fd_set read_fds;
+    FD_ZERO(&read_fds);
+    FD_SET(notification_listen_fd_, &read_fds);
+    int max_read_fd = INVALID_FD;
+    for (auto& it : watched_fds_) {
+      FD_SET(it.first, &read_fds);
+      max_read_fd = std::max(max_read_fd, it.first);
+    }
+
+    struct timeval timeout;
+    struct timeval* timeout_ptr = NULL;
+    if (timeout_ms_ > std::chrono::milliseconds(0)) {
+      timeout.tv_sec = timeout_ms_.count() / 1000;
+      timeout.tv_usec = (timeout_ms_.count() % 1000) * 1000;
+      timeout_ptr = &timeout;
+    }
+
+    // Wait until there is data available to read on some FD.
+    int nfds = std::max(notification_listen_fd_, max_read_fd);
+    int retval = select(nfds + 1, &read_fds, NULL, NULL, timeout_ptr);
+
+    // There was some error.
+    if (retval < 0) continue;
+
+    // Timeout.
+    if (retval == 0) {
+      // Allow the timeout callback to modify the timeout.
+      TimeoutCallback saved_cb;
+      {
+        std::unique_lock<std::mutex> guard(timeout_mutex_);
+        if (timeout_ms_ > std::chrono::milliseconds(0)) saved_cb = timeout_cb_;
+      }
+      if (saved_cb != nullptr) saved_cb();
+      continue;
+    }
+
+    // Read data from the notification FD.
+    if (FD_ISSET(notification_listen_fd_, &read_fds)) {
+      char buffer[] = {0};
+      TEMP_FAILURE_RETRY(read(notification_listen_fd_, buffer, 1));
+      continue;
+    }
+
+    // Invoke the data ready callbacks if appropriate.
+    {
+      // Hold the mutex to make sure that the callbacks are still valid.
+      std::unique_lock<std::mutex> guard(internal_mutex_);
+      for (auto& it : watched_fds_) {
+        if (FD_ISSET(it.first, &read_fds)) {
+          it.second(it.first);
+        }
+      }
+    }
+  }
+}
+
+}  // namespace android::hardware::bluetooth::async
diff --git a/bluetooth/async/async_fd_watcher.h b/bluetooth/async/async_fd_watcher.h
new file mode 100644
index 0000000..b50a7a0
--- /dev/null
+++ b/bluetooth/async/async_fd_watcher.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <map>
+#include <mutex>
+#include <thread>
+
+namespace android::hardware::bluetooth::async {
+
+using ReadCallback = std::function<void(int)>;
+using TimeoutCallback = std::function<void(void)>;
+
+class AsyncFdWatcher {
+ public:
+  AsyncFdWatcher() = default;
+  ~AsyncFdWatcher();
+
+  int WatchFdForNonBlockingReads(int file_descriptor,
+                                 const ReadCallback& on_read_fd_ready_callback);
+  int ConfigureTimeout(const std::chrono::milliseconds timeout,
+                       const TimeoutCallback& on_timeout_callback);
+  void StopWatchingFileDescriptors();
+
+ private:
+  AsyncFdWatcher(const AsyncFdWatcher&) = delete;
+  AsyncFdWatcher& operator=(const AsyncFdWatcher&) = delete;
+
+  int tryStartThread();
+  int stopThread();
+  int notifyThread();
+  void ThreadRoutine();
+
+  std::atomic_bool running_{false};
+  std::thread thread_;
+  std::mutex internal_mutex_;
+  std::mutex timeout_mutex_;
+
+  std::map<int, ReadCallback> watched_fds_;
+  int notification_listen_fd_;
+  int notification_write_fd_;
+  TimeoutCallback timeout_cb_;
+  std::chrono::milliseconds timeout_ms_;
+};
+
+}  // namespace android::hardware::bluetooth::async
diff --git a/bluetooth/async/test/async_fd_watcher_unittest.cc b/bluetooth/async/test/async_fd_watcher_unittest.cc
new file mode 100644
index 0000000..6d75f10
--- /dev/null
+++ b/bluetooth/async/test/async_fd_watcher_unittest.cc
@@ -0,0 +1,377 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "async_fd_watcher_unittest"
+
+#include "async_fd_watcher.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+namespace android::hardware::bluetooth::async_test {
+
+using android::hardware::bluetooth::async::AsyncFdWatcher;
+
+class AsyncFdWatcherSocketTest : public ::testing::Test {
+ public:
+  static const uint16_t kPort = 6111;
+  static const size_t kBufferSize = 16;
+
+  bool CheckBufferEquals() {
+    return strcmp(server_buffer_, client_buffer_) == 0;
+  }
+
+ protected:
+  int StartServer() {
+    ALOGD("%s", __func__);
+    struct sockaddr_in serv_addr;
+    int fd = socket(AF_INET, SOCK_STREAM, 0);
+    EXPECT_FALSE(fd < 0);
+
+    memset(&serv_addr, 0, sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    serv_addr.sin_port = htons(kPort);
+    int reuse_flag = 1;
+    EXPECT_FALSE(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag,
+                            sizeof(reuse_flag)) < 0);
+    EXPECT_FALSE(bind(fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0);
+
+    ALOGD("%s before listen", __func__);
+    listen(fd, 1);
+    return fd;
+  }
+
+  int AcceptConnection(int fd) {
+    ALOGD("%s", __func__);
+    struct sockaddr_in cli_addr;
+    memset(&cli_addr, 0, sizeof(cli_addr));
+    socklen_t clilen = sizeof(cli_addr);
+
+    int connection_fd = accept(fd, (struct sockaddr*)&cli_addr, &clilen);
+    EXPECT_FALSE(connection_fd < 0);
+
+    return connection_fd;
+  }
+
+  void ReadIncomingMessage(int fd) {
+    ALOGD("%s", __func__);
+    int n = TEMP_FAILURE_RETRY(read(fd, server_buffer_, kBufferSize - 1));
+    EXPECT_FALSE(n < 0);
+
+    if (n == 0) {  // got EOF
+      ALOGD("%s: EOF", __func__);
+    } else {
+      ALOGD("%s: Got something", __func__);
+      n = write(fd, "1", 1);
+    }
+  }
+
+  void SetUp() override {
+    ALOGD("%s", __func__);
+    memset(server_buffer_, 0, kBufferSize);
+    memset(client_buffer_, 0, kBufferSize);
+  }
+
+  void ConfigureServer() {
+    socket_fd_ = StartServer();
+
+    conn_watcher_.WatchFdForNonBlockingReads(socket_fd_, [this](int fd) {
+      int connection_fd = AcceptConnection(fd);
+      ALOGD("%s: Conn_watcher fd = %d", __func__, fd);
+
+      conn_watcher_.ConfigureTimeout(std::chrono::seconds(0), []() {
+        bool connection_timeout_cleared = false;
+        ASSERT_TRUE(connection_timeout_cleared);
+      });
+
+      ALOGD("%s: 3", __func__);
+      async_fd_watcher_.WatchFdForNonBlockingReads(
+          connection_fd, [this](int fd) { ReadIncomingMessage(fd); });
+
+      // Time out if it takes longer than a second.
+      SetTimeout(std::chrono::seconds(1));
+    });
+    conn_watcher_.ConfigureTimeout(std::chrono::seconds(1), []() {
+      bool connection_timeout = true;
+      ASSERT_FALSE(connection_timeout);
+    });
+  }
+
+  void CleanUpServer() {
+    async_fd_watcher_.StopWatchingFileDescriptors();
+    conn_watcher_.StopWatchingFileDescriptors();
+    close(socket_fd_);
+  }
+
+  void TearDown() override {
+    ALOGD("%s 3", __func__);
+    EXPECT_TRUE(CheckBufferEquals());
+  }
+
+  void OnTimeout() {
+    ALOGD("%s", __func__);
+    timed_out_ = true;
+  }
+
+  void ClearTimeout() {
+    ALOGD("%s", __func__);
+    timed_out_ = false;
+  }
+
+  bool TimedOut() {
+    ALOGD("%s %d", __func__, timed_out_ ? 1 : 0);
+    return timed_out_;
+  }
+
+  void SetTimeout(std::chrono::milliseconds timeout_ms) {
+    ALOGD("%s", __func__);
+    async_fd_watcher_.ConfigureTimeout(timeout_ms, [this]() { OnTimeout(); });
+    ClearTimeout();
+  }
+
+  int ConnectClient() {
+    ALOGD("%s", __func__);
+    int socket_cli_fd = socket(AF_INET, SOCK_STREAM, 0);
+    EXPECT_FALSE(socket_cli_fd < 0);
+
+    struct sockaddr_in serv_addr;
+    memset((void*)&serv_addr, 0, sizeof(serv_addr));
+    serv_addr.sin_family = AF_INET;
+    serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    serv_addr.sin_port = htons(kPort);
+
+    int result =
+        connect(socket_cli_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+    EXPECT_FALSE(result < 0);
+
+    return socket_cli_fd;
+  }
+
+  void WriteFromClient(int socket_cli_fd) {
+    ALOGD("%s", __func__);
+    strcpy(client_buffer_, "1");
+    int n = write(socket_cli_fd, client_buffer_, strlen(client_buffer_));
+    EXPECT_TRUE(n > 0);
+  }
+
+  void AwaitServerResponse(int socket_cli_fd) {
+    ALOGD("%s", __func__);
+    int n = read(socket_cli_fd, client_buffer_, 1);
+    ALOGD("%s done", __func__);
+    EXPECT_TRUE(n > 0);
+  }
+
+ private:
+  AsyncFdWatcher async_fd_watcher_;
+  AsyncFdWatcher conn_watcher_;
+  int socket_fd_;
+  char server_buffer_[kBufferSize];
+  char client_buffer_[kBufferSize];
+  bool timed_out_;
+};
+
+// Use a single AsyncFdWatcher to signal a connection to the server socket.
+TEST_F(AsyncFdWatcherSocketTest, Connect) {
+  int socket_fd = StartServer();
+
+  AsyncFdWatcher conn_watcher;
+  conn_watcher.WatchFdForNonBlockingReads(socket_fd, [this](int fd) {
+    int connection_fd = AcceptConnection(fd);
+    close(connection_fd);
+  });
+
+  // Fail if the client doesn't connect within 1 second.
+  conn_watcher.ConfigureTimeout(std::chrono::seconds(1), []() {
+    bool connection_timeout = true;
+    ASSERT_FALSE(connection_timeout);
+  });
+
+  int socket_cli_fd = ConnectClient();
+  conn_watcher.StopWatchingFileDescriptors();
+  close(socket_fd);
+  close(socket_cli_fd);
+}
+
+// Use a single AsyncFdWatcher to signal a connection to the server socket.
+TEST_F(AsyncFdWatcherSocketTest, TimedOutConnect) {
+  int socket_fd = StartServer();
+  bool timed_out = false;
+  bool* timeout_ptr = &timed_out;
+
+  AsyncFdWatcher conn_watcher;
+  conn_watcher.WatchFdForNonBlockingReads(socket_fd, [this](int fd) {
+    int connection_fd = AcceptConnection(fd);
+    close(connection_fd);
+  });
+
+  // Set the timeout flag after 100ms.
+  conn_watcher.ConfigureTimeout(std::chrono::milliseconds(100),
+                                [timeout_ptr]() { *timeout_ptr = true; });
+  EXPECT_FALSE(timed_out);
+  sleep(1);
+  EXPECT_TRUE(timed_out);
+  conn_watcher.StopWatchingFileDescriptors();
+  close(socket_fd);
+}
+
+// Modify the timeout in a timeout callback.
+TEST_F(AsyncFdWatcherSocketTest, TimedOutSchedulesTimeout) {
+  int socket_fd = StartServer();
+  bool timed_out = false;
+  bool timed_out2 = false;
+
+  AsyncFdWatcher conn_watcher;
+  conn_watcher.WatchFdForNonBlockingReads(socket_fd, [this](int fd) {
+    int connection_fd = AcceptConnection(fd);
+    close(connection_fd);
+  });
+
+  // Set a timeout flag in each callback.
+  conn_watcher.ConfigureTimeout(std::chrono::milliseconds(500),
+                                [&conn_watcher, &timed_out, &timed_out2]() {
+                                  timed_out = true;
+                                  conn_watcher.ConfigureTimeout(
+                                      std::chrono::seconds(1),
+                                      [&timed_out2]() { timed_out2 = true; });
+                                });
+  EXPECT_FALSE(timed_out);
+  EXPECT_FALSE(timed_out2);
+  sleep(1);
+  EXPECT_TRUE(timed_out);
+  EXPECT_FALSE(timed_out2);
+  sleep(1);
+  EXPECT_TRUE(timed_out);
+  EXPECT_TRUE(timed_out2);
+  conn_watcher.StopWatchingFileDescriptors();
+  close(socket_fd);
+}
+
+MATCHER_P(ReadAndMatchSingleChar, byte,
+          "Reads a byte from the file descriptor and matches the value against "
+          "byte") {
+  char inbuf[1] = {0};
+
+  int n = TEMP_FAILURE_RETRY(read(arg, inbuf, 1));
+
+  TEMP_FAILURE_RETRY(write(arg, inbuf, 1));
+  if (n != 1) {
+    return false;
+  }
+  return inbuf[0] == byte;
+};
+
+// Use a single AsyncFdWatcher to watch two file descriptors.
+TEST_F(AsyncFdWatcherSocketTest, WatchTwoFileDescriptors) {
+  int sockfd1[2];
+  int sockfd2[2];
+  socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd1);
+  socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd2);
+
+  testing::MockFunction<void(int)> cb1;
+  testing::MockFunction<void(int)> cb2;
+
+  AsyncFdWatcher watcher;
+  watcher.WatchFdForNonBlockingReads(sockfd1[0], cb1.AsStdFunction());
+
+  watcher.WatchFdForNonBlockingReads(sockfd2[0], cb2.AsStdFunction());
+
+  EXPECT_CALL(cb1, Call(ReadAndMatchSingleChar('1')));
+  char one_buf[1] = {'1'};
+  TEMP_FAILURE_RETRY(write(sockfd1[1], one_buf, sizeof(one_buf)));
+
+  EXPECT_CALL(cb2, Call(ReadAndMatchSingleChar('2')));
+  char two_buf[1] = {'2'};
+  TEMP_FAILURE_RETRY(write(sockfd2[1], two_buf, sizeof(two_buf)));
+
+  // Blocking read instead of a flush.
+  TEMP_FAILURE_RETRY(read(sockfd1[1], one_buf, sizeof(one_buf)));
+  TEMP_FAILURE_RETRY(read(sockfd2[1], two_buf, sizeof(two_buf)));
+
+  watcher.StopWatchingFileDescriptors();
+}
+
+// Use two AsyncFdWatchers to set up a server socket.
+TEST_F(AsyncFdWatcherSocketTest, ClientServer) {
+  ConfigureServer();
+  int socket_cli_fd = ConnectClient();
+
+  WriteFromClient(socket_cli_fd);
+
+  AwaitServerResponse(socket_cli_fd);
+
+  close(socket_cli_fd);
+  CleanUpServer();
+}
+
+// Use two AsyncFdWatchers to set up a server socket, which times out.
+TEST_F(AsyncFdWatcherSocketTest, TimeOutTest) {
+  ConfigureServer();
+  int socket_cli_fd = ConnectClient();
+
+  while (!TimedOut()) sleep(1);
+
+  close(socket_cli_fd);
+  CleanUpServer();
+}
+
+// Use two AsyncFdWatchers to set up a server socket, which times out.
+TEST_F(AsyncFdWatcherSocketTest, RepeatedTimeOutTest) {
+  ConfigureServer();
+  int socket_cli_fd = ConnectClient();
+  ClearTimeout();
+
+  // Time out when there are no writes.
+  EXPECT_FALSE(TimedOut());
+  sleep(2);
+  EXPECT_TRUE(TimedOut());
+  ClearTimeout();
+
+  // Don't time out when there is a write.
+  WriteFromClient(socket_cli_fd);
+  AwaitServerResponse(socket_cli_fd);
+  EXPECT_FALSE(TimedOut());
+  ClearTimeout();
+
+  // Time out when the write is late.
+  sleep(2);
+  WriteFromClient(socket_cli_fd);
+  AwaitServerResponse(socket_cli_fd);
+  EXPECT_TRUE(TimedOut());
+  ClearTimeout();
+
+  // Time out when there is a pause after a write.
+  WriteFromClient(socket_cli_fd);
+  sleep(2);
+  AwaitServerResponse(socket_cli_fd);
+  EXPECT_TRUE(TimedOut());
+  ClearTimeout();
+
+  close(socket_cli_fd);
+  CleanUpServer();
+}
+
+}  // namespace android::hardware::bluetooth::async_test
diff --git a/bluetooth/audio/2.0/Android.bp b/bluetooth/audio/2.0/Android.bp
index e4d48c1..725ec11 100644
--- a/bluetooth/audio/2.0/Android.bp
+++ b/bluetooth/audio/2.0/Android.bp
@@ -26,6 +26,6 @@
     gen_java: false,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
     ],
 }
diff --git a/bluetooth/audio/2.1/Android.bp b/bluetooth/audio/2.1/Android.bp
index 1175fb3..4ca0bef 100644
--- a/bluetooth/audio/2.1/Android.bp
+++ b/bluetooth/audio/2.1/Android.bp
@@ -25,7 +25,7 @@
     ],
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
     ],
     gen_java: false,
 }
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
index c581702..32f8cca 100644
--- a/bluetooth/audio/aidl/Android.bp
+++ b/bluetooth/audio/aidl/Android.bp
@@ -29,7 +29,7 @@
     imports: [
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
-        "android.hardware.audio.common",
+        "android.hardware.audio.common-V1",
     ],
     backend: {
         cpp: {
@@ -40,12 +40,9 @@
             enabled: false,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apex_available: [
                 "//apex_available:platform",
-                "com.android.bluetooth",
+                "com.android.btservices",
             ],
             min_sdk_version: "31",
         },
@@ -67,7 +64,16 @@
                 "android.hardware.audio.common-V1",
             ],
         },
+        {
+            version: "3",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.common.fmq-V1",
+                "android.hardware.audio.common-V1",
+            ],
+        },
 
     ],
+    frozen: true,
 
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/.hash b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/.hash
new file mode 100644
index 0000000..36a90ad
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/.hash
@@ -0,0 +1 @@
+fead4df60244a5440283617064f184690414a685
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AacCapabilities.aidl
new file mode 100644
index 0000000..e548cd3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AacCapabilities {
+  android.hardware.bluetooth.audio.AacObjectType[] objectType;
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+  boolean variableBitRateSupported;
+  byte[] bitsPerSample;
+  boolean adaptiveBitRateSupported;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AacConfiguration.aidl
new file mode 100644
index 0000000..29ab8ce
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AacConfiguration {
+  android.hardware.bluetooth.audio.AacObjectType objectType;
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  boolean variableBitRateEnabled;
+  byte bitsPerSample;
+  boolean adaptiveBitRateSupported;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AacObjectType.aidl
new file mode 100644
index 0000000..418dd7a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum AacObjectType {
+  MPEG2_LC,
+  MPEG4_LC,
+  MPEG4_LTP,
+  MPEG4_SCALABLE,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveCapabilities.aidl
new file mode 100644
index 0000000..4e5dfe6
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveCapabilities.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.AptxAdaptiveChannelMode[] channelMode;
+  byte[] bitsPerSample;
+  android.hardware.bluetooth.audio.AptxMode[] aptxMode;
+  android.hardware.bluetooth.audio.AptxSinkBuffering sinkBufferingMs;
+  android.hardware.bluetooth.audio.AptxAdaptiveTimeToPlay ttp;
+  android.hardware.bluetooth.audio.AptxAdaptiveInputMode inputMode;
+  int inputFadeDurationMs;
+  byte[] aptxAdaptiveConfigStream;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
new file mode 100644
index 0000000..675f9f2
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum AptxAdaptiveChannelMode {
+  JOINT_STEREO = 0,
+  MONO = 1,
+  DUAL_MONO = 2,
+  TWS_STEREO = 4,
+  UNKNOWN = 0xFF,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveConfiguration.aidl
new file mode 100644
index 0000000..aab0521
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveConfiguration.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.AptxAdaptiveChannelMode channelMode;
+  byte bitsPerSample;
+  android.hardware.bluetooth.audio.AptxMode aptxMode;
+  android.hardware.bluetooth.audio.AptxSinkBuffering sinkBufferingMs;
+  android.hardware.bluetooth.audio.AptxAdaptiveTimeToPlay ttp;
+  android.hardware.bluetooth.audio.AptxAdaptiveInputMode inputMode;
+  int inputFadeDurationMs;
+  byte[] aptxAdaptiveConfigStream;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
new file mode 100644
index 0000000..a18303e
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum AptxAdaptiveInputMode {
+  STEREO = 0x00,
+  DUAL_MONO = 0x01,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
new file mode 100644
index 0000000..c9d3cde
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveLeCapabilities {
+  byte[] pcmBitDepth;
+  int[] samplingFrequencyHz;
+  int[] frameDurationUs;
+  int[] octetsPerFrame;
+  byte[] blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
new file mode 100644
index 0000000..76df4ed
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveLeConfiguration {
+  byte pcmBitDepth;
+  int samplingFrequencyHz;
+  int frameDurationUs;
+  int octetsPerFrame;
+  byte blocksPerSdu;
+  int codecMode;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveTimeToPlay.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveTimeToPlay.aidl
new file mode 100644
index 0000000..3560666
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxAdaptiveTimeToPlay.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveTimeToPlay {
+  byte lowLowLatency;
+  byte highLowLatency;
+  byte lowHighQuality;
+  byte highHighQuality;
+  byte lowTws;
+  byte highTws;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxCapabilities.aidl
new file mode 100644
index 0000000..08a38e2
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+  byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxConfiguration.aidl
new file mode 100644
index 0000000..91e88b3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxConfiguration.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxMode.aidl
new file mode 100644
index 0000000..dd8cf08
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum AptxMode {
+  UNKNOWN = 0x00,
+  HIGH_QUALITY = 0x1000,
+  LOW_LATENCY = 0x2000,
+  ULTRA_LOW_LATENCY = 0x4000,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxSinkBuffering.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxSinkBuffering.aidl
new file mode 100644
index 0000000..527418e
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AptxSinkBuffering.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxSinkBuffering {
+  byte minLowLatency;
+  byte maxLowLatency;
+  byte minHighQuality;
+  byte maxHighQuality;
+  byte minTws;
+  byte maxTws;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AudioCapabilities.aidl
new file mode 100644
index 0000000..8ae716f
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AudioCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+union AudioCapabilities {
+  android.hardware.bluetooth.audio.PcmCapabilities pcmCapabilities;
+  android.hardware.bluetooth.audio.CodecCapabilities a2dpCapabilities;
+  android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting leAudioCapabilities;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AudioConfiguration.aidl
new file mode 100644
index 0000000..3abfb31
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+union AudioConfiguration {
+  android.hardware.bluetooth.audio.PcmConfiguration pcmConfig;
+  android.hardware.bluetooth.audio.CodecConfiguration a2dpConfig;
+  android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig;
+  android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration leAudioBroadcastConfig;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AudioLocation.aidl
new file mode 100644
index 0000000..941344c
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum AudioLocation {
+  UNKNOWN = 1,
+  FRONT_LEFT = (1 << 1) /* 2 */,
+  FRONT_RIGHT = (1 << 2) /* 4 */,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
new file mode 100644
index 0000000..c20c057
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum BluetoothAudioStatus {
+  UNKNOWN = 0,
+  SUCCESS = 1,
+  UNSUPPORTED_CODEC_CONFIGURATION = 2,
+  FAILURE = 3,
+  RECONFIGURATION = 4,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/BroadcastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/BroadcastCapability.aidl
new file mode 100644
index 0000000..58710ef
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/BroadcastCapability.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable BroadcastCapability {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.AudioLocation supportedChannel;
+  int channelCountPerStream;
+  android.hardware.bluetooth.audio.BroadcastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities;
+  @VintfStability
+  parcelable VendorCapabilities {
+    ParcelableHolder extension;
+  }
+  @VintfStability
+  union LeAudioCodecCapabilities {
+    @nullable android.hardware.bluetooth.audio.Lc3Capabilities[] lc3Capabilities;
+    @nullable android.hardware.bluetooth.audio.BroadcastCapability.VendorCapabilities[] vendorCapabillities;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/ChannelMode.aidl
new file mode 100644
index 0000000..2bb5cd8
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum ChannelMode {
+  UNKNOWN,
+  MONO,
+  STEREO,
+  DUALMONO,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/CodecCapabilities.aidl
new file mode 100644
index 0000000..b00649a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/CodecCapabilities.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable CodecCapabilities {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.CodecCapabilities.Capabilities capabilities;
+  @VintfStability
+  parcelable VendorCapabilities {
+    ParcelableHolder extension;
+  }
+  @VintfStability
+  union Capabilities {
+    android.hardware.bluetooth.audio.SbcCapabilities sbcCapabilities;
+    android.hardware.bluetooth.audio.AacCapabilities aacCapabilities;
+    android.hardware.bluetooth.audio.LdacCapabilities ldacCapabilities;
+    android.hardware.bluetooth.audio.AptxCapabilities aptxCapabilities;
+    android.hardware.bluetooth.audio.AptxAdaptiveCapabilities aptxAdaptiveCapabilities;
+    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
+    android.hardware.bluetooth.audio.CodecCapabilities.VendorCapabilities vendorCapabilities;
+    @nullable android.hardware.bluetooth.audio.OpusCapabilities opusCapabilities;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/CodecConfiguration.aidl
new file mode 100644
index 0000000..7f5ea48
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/CodecConfiguration.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable CodecConfiguration {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  int encodedAudioBitrate;
+  int peerMtu;
+  boolean isScmstEnabled;
+  android.hardware.bluetooth.audio.CodecConfiguration.CodecSpecific config;
+  @VintfStability
+  parcelable VendorConfiguration {
+    int vendorId;
+    char codecId;
+    ParcelableHolder codecConfig;
+  }
+  @VintfStability
+  union CodecSpecific {
+    android.hardware.bluetooth.audio.SbcConfiguration sbcConfig;
+    android.hardware.bluetooth.audio.AacConfiguration aacConfig;
+    android.hardware.bluetooth.audio.LdacConfiguration ldacConfig;
+    android.hardware.bluetooth.audio.AptxConfiguration aptxConfig;
+    android.hardware.bluetooth.audio.AptxAdaptiveConfiguration aptxAdaptiveConfig;
+    android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
+    android.hardware.bluetooth.audio.CodecConfiguration.VendorConfiguration vendorConfig;
+    @nullable android.hardware.bluetooth.audio.OpusConfiguration opusConfig;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/CodecType.aidl
new file mode 100644
index 0000000..d4f205e
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/CodecType.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum CodecType {
+  UNKNOWN,
+  SBC,
+  AAC,
+  APTX,
+  APTX_HD,
+  LDAC,
+  LC3,
+  VENDOR,
+  APTX_ADAPTIVE,
+  OPUS,
+  APTX_ADAPTIVE_LE,
+  APTX_ADAPTIVE_LEX,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
new file mode 100644
index 0000000..d364371
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+interface IBluetoothAudioPort {
+  android.hardware.bluetooth.audio.PresentationPosition getPresentationPosition();
+  void startStream(boolean isLowLatency);
+  void stopStream();
+  void suspendStream();
+  void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+  void updateSinkMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
+  void setLatencyMode(in android.hardware.bluetooth.audio.LatencyMode latencyMode);
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
new file mode 100644
index 0000000..267af0f
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+interface IBluetoothAudioProvider {
+  void endSession();
+  android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig, in android.hardware.bluetooth.audio.LatencyMode[] supportedLatencyModes);
+  void streamStarted(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
+  void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
+  void updateAudioConfiguration(in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
+  void setLowLatencyModeAllowed(in boolean allowed);
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
new file mode 100644
index 0000000..5e33deb
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+interface IBluetoothAudioProviderFactory {
+  android.hardware.bluetooth.audio.AudioCapabilities[] getProviderCapabilities(in android.hardware.bluetooth.audio.SessionType sessionType);
+  android.hardware.bluetooth.audio.IBluetoothAudioProvider openProvider(in android.hardware.bluetooth.audio.SessionType sessionType);
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LatencyMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LatencyMode.aidl
new file mode 100644
index 0000000..1140f9e
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum LatencyMode {
+  UNKNOWN,
+  LOW_LATENCY,
+  FREE,
+  DYNAMIC_SPATIAL_AUDIO_SOFTWARE,
+  DYNAMIC_SPATIAL_AUDIO_HARDWARE,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
new file mode 100644
index 0000000..cc4449a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable Lc3Capabilities {
+  byte[] pcmBitDepth;
+  int[] samplingFrequencyHz;
+  int[] frameDurationUs;
+  int[] octetsPerFrame;
+  byte[] blocksPerSdu;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/Lc3Configuration.aidl
new file mode 100644
index 0000000..7e8dccf
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/Lc3Configuration.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable Lc3Configuration {
+  byte pcmBitDepth;
+  int samplingFrequencyHz;
+  int frameDurationUs;
+  int octetsPerFrame;
+  byte blocksPerSdu;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacCapabilities.aidl
new file mode 100644
index 0000000..aa4e4c8
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable LdacCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.LdacChannelMode[] channelMode;
+  android.hardware.bluetooth.audio.LdacQualityIndex[] qualityIndex;
+  byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacChannelMode.aidl
new file mode 100644
index 0000000..3d80c4b
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LdacChannelMode {
+  UNKNOWN,
+  STEREO,
+  DUAL,
+  MONO,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacConfiguration.aidl
new file mode 100644
index 0000000..8a37638
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable LdacConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.LdacChannelMode channelMode;
+  android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex;
+  byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
new file mode 100644
index 0000000..a332dc5
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LdacQualityIndex {
+  HIGH,
+  MID,
+  LOW,
+  ABR,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
new file mode 100644
index 0000000..2945710
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable LeAudioBroadcastConfiguration {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration.BroadcastStreamMap[] streamMap;
+  @VintfStability
+  parcelable BroadcastStreamMap {
+    char streamHandle;
+    int audioChannelAllocation;
+    android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+    char pcmStreamId;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
new file mode 100644
index 0000000..9818d54
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable LeAudioCodecCapabilitiesSetting {
+  android.hardware.bluetooth.audio.UnicastCapability unicastEncodeCapability;
+  android.hardware.bluetooth.audio.UnicastCapability unicastDecodeCapability;
+  android.hardware.bluetooth.audio.BroadcastCapability broadcastCapability;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
new file mode 100644
index 0000000..031ee67
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+union LeAudioCodecConfiguration {
+  android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
+  android.hardware.bluetooth.audio.LeAudioCodecConfiguration.VendorConfiguration vendorConfig;
+  android.hardware.bluetooth.audio.AptxAdaptiveLeConfiguration aptxAdaptiveLeConfig;
+  @VintfStability
+  parcelable VendorConfiguration {
+    ParcelableHolder extension;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
new file mode 100644
index 0000000..2d9ebae
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable LeAudioConfiguration {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap;
+  int peerDelayUs;
+  android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+  @nullable byte[] vendorSpecificMetadata;
+  @VintfStability
+  parcelable StreamMap {
+    char streamHandle;
+    int audioChannelAllocation;
+    boolean isStreamActive;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/OpusCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/OpusCapabilities.aidl
new file mode 100644
index 0000000..2c04b0f
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/OpusCapabilities.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable OpusCapabilities {
+  byte[] pcmBitDepth;
+  int[] samplingFrequencyHz;
+  int[] frameDurationUs;
+  int[] octetsPerFrame;
+  byte[] blocksPerSdu;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/OpusConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/OpusConfiguration.aidl
new file mode 100644
index 0000000..811d32a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/OpusConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable OpusConfiguration {
+  byte pcmBitDepth;
+  int samplingFrequencyHz;
+  int frameDurationUs;
+  int octetsPerFrame;
+  byte blocksPerSdu;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/PcmCapabilities.aidl
new file mode 100644
index 0000000..0c2f87d
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/PcmCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable PcmCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+  byte[] bitsPerSample;
+  int[] dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/PcmConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/PcmConfiguration.aidl
new file mode 100644
index 0000000..93d7805
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/PcmConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable PcmConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  byte bitsPerSample;
+  int dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/PresentationPosition.aidl
new file mode 100644
index 0000000..7e997e8
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/PresentationPosition.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable PresentationPosition {
+  long remoteDeviceAudioDelayNanos;
+  long transmittedOctets;
+  android.hardware.bluetooth.audio.PresentationPosition.TimeSpec transmittedOctetsTimestamp;
+  @VintfStability
+  parcelable TimeSpec {
+    long tvSec;
+    long tvNSec;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
new file mode 100644
index 0000000..9cf65d5
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcAllocMethod.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SbcAllocMethod {
+  ALLOC_MD_S,
+  ALLOC_MD_L,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcCapabilities.aidl
new file mode 100644
index 0000000..c8d7e7e
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcCapabilities.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable SbcCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.SbcChannelMode[] channelMode;
+  byte[] blockLength;
+  byte[] numSubbands;
+  android.hardware.bluetooth.audio.SbcAllocMethod[] allocMethod;
+  byte[] bitsPerSample;
+  int minBitpool;
+  int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcChannelMode.aidl
new file mode 100644
index 0000000..7779aa0
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SbcChannelMode {
+  UNKNOWN,
+  JOINT_STEREO,
+  STEREO,
+  DUAL,
+  MONO,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcConfiguration.aidl
new file mode 100644
index 0000000..8eab9c3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SbcConfiguration.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable SbcConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.SbcChannelMode channelMode;
+  byte blockLength;
+  byte numSubbands;
+  android.hardware.bluetooth.audio.SbcAllocMethod allocMethod;
+  byte bitsPerSample;
+  int minBitpool;
+  int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SessionType.aidl
new file mode 100644
index 0000000..4b2c10f
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/SessionType.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SessionType {
+  UNKNOWN,
+  A2DP_SOFTWARE_ENCODING_DATAPATH,
+  A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+  HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+  LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+  LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+  LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+  LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+  LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+  LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+  A2DP_SOFTWARE_DECODING_DATAPATH,
+  A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/UnicastCapability.aidl
new file mode 100644
index 0000000..894a2f3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/3/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable UnicastCapability {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.AudioLocation supportedChannel;
+  int deviceCount;
+  int channelCountPerDevice;
+  android.hardware.bluetooth.audio.UnicastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities;
+  @VintfStability
+  parcelable VendorCapabilities {
+    ParcelableHolder extension;
+  }
+  @VintfStability
+  union LeAudioCodecCapabilities {
+    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
+    android.hardware.bluetooth.audio.UnicastCapability.VendorCapabilities vendorCapabillities;
+    android.hardware.bluetooth.audio.AptxAdaptiveLeCapabilities aptxAdaptiveLeCapabilities;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
index 899b8ca..e548cd3 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -39,4 +39,5 @@
   android.hardware.bluetooth.audio.ChannelMode[] channelMode;
   boolean variableBitRateSupported;
   byte[] bitsPerSample;
+  boolean adaptiveBitRateSupported;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
index 6adef6d..29ab8ce 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -39,4 +39,5 @@
   android.hardware.bluetooth.audio.ChannelMode channelMode;
   boolean variableBitRateEnabled;
   byte bitsPerSample;
+  boolean adaptiveBitRateSupported;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
new file mode 100644
index 0000000..c9d3cde
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveLeCapabilities {
+  byte[] pcmBitDepth;
+  int[] samplingFrequencyHz;
+  int[] frameDurationUs;
+  int[] octetsPerFrame;
+  byte[] blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
new file mode 100644
index 0000000..76df4ed
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveLeConfiguration {
+  byte pcmBitDepth;
+  int samplingFrequencyHz;
+  int frameDurationUs;
+  int octetsPerFrame;
+  byte blocksPerSdu;
+  int codecMode;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
index d1723e6..3e204f9 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
@@ -44,4 +44,6 @@
   VENDOR = 7,
   APTX_ADAPTIVE = 8,
   OPUS = 9,
+  APTX_ADAPTIVE_LE = 10,
+  APTX_ADAPTIVE_LEX = 11,
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
index 5583679..1140f9e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -34,7 +34,9 @@
 package android.hardware.bluetooth.audio;
 @Backing(type="int") @VintfStability
 enum LatencyMode {
-  UNKNOWN = 0,
-  LOW_LATENCY = 1,
-  FREE = 2,
+  UNKNOWN,
+  LOW_LATENCY,
+  FREE,
+  DYNAMIC_SPATIAL_AUDIO_SOFTWARE,
+  DYNAMIC_SPATIAL_AUDIO_HARDWARE,
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index 7d53b0c..2945710 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -41,5 +41,6 @@
     char streamHandle;
     int audioChannelAllocation;
     android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+    char pcmStreamId;
   }
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
index bb3d7e4..031ee67 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -36,6 +36,7 @@
 union LeAudioCodecConfiguration {
   android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
   android.hardware.bluetooth.audio.LeAudioCodecConfiguration.VendorConfiguration vendorConfig;
+  android.hardware.bluetooth.audio.AptxAdaptiveLeConfiguration aptxAdaptiveLeConfig;
   @VintfStability
   parcelable VendorConfiguration {
     ParcelableHolder extension;
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index edb6795..2d9ebae 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -38,9 +38,11 @@
   android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap;
   int peerDelayUs;
   android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+  @nullable byte[] vendorSpecificMetadata;
   @VintfStability
   parcelable StreamMap {
     char streamHandle;
     int audioChannelAllocation;
+    boolean isStreamActive;
   }
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl
index 2781893..2c04b0f 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl
index 067690e..811d32a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
index 130fef9..894a2f3 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -47,5 +47,6 @@
   union LeAudioCodecCapabilities {
     android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
     android.hardware.bluetooth.audio.UnicastCapability.VendorCapabilities vendorCapabillities;
+    android.hardware.bluetooth.audio.AptxAdaptiveLeCapabilities aptxAdaptiveLeCapabilities;
   }
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
index c4153e9..d7d67de 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -29,4 +29,5 @@
     ChannelMode[] channelMode;
     boolean variableBitRateSupported;
     byte[] bitsPerSample;
+    boolean adaptiveBitRateSupported;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
index 30338e7..34998cd 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -29,4 +29,5 @@
     ChannelMode channelMode;
     boolean variableBitRateEnabled;
     byte bitsPerSample;
+    boolean adaptiveBitRateSupported;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
new file mode 100644
index 0000000..b3fe71c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding Aptx Adaptive LE codec capabilities.
+ */
+@VintfStability
+parcelable AptxAdaptiveLeCapabilities {
+    /*
+     * PCM is Input for encoder, Output for decoder
+     */
+    byte[] pcmBitDepth;
+    /*
+     * codec-specific parameters
+     */
+    int[] samplingFrequencyHz;
+    /*
+     * FrameDuration based on microseconds.
+     */
+    int[] frameDurationUs;
+    /*
+     * length in octets of a codec frame
+     */
+    int[] octetsPerFrame;
+    /*
+     * Number of blocks of codec frames per single SDU (Service Data Unit)
+     */
+    byte[] blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
new file mode 100644
index 0000000..060d5d5
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding Aptx Adaptive LE/LEX codec configuration.
+ */
+@VintfStability
+parcelable AptxAdaptiveLeConfiguration {
+    /*
+     * PCM is Input for encoder, Output for decoder
+     */
+    byte pcmBitDepth;
+    /*
+     * codec-specific parameters
+     */
+    int samplingFrequencyHz;
+    /*
+     * FrameDuration based on microseconds.
+     */
+    int frameDurationUs;
+    /*
+     * length in octets of a codec frame
+     */
+    int octetsPerFrame;
+    /*
+     * Number of blocks of codec frames per single SDU (Service Data Unit)
+     */
+    byte blocksPerSdu;
+    /*
+     * Currently being used for Aptx Adaptive LEX,
+     * RFU for Aptx Adaptive LE
+     * Based on this value, the codec will determine the quality of stream
+     * during initialization for Music/Game
+     */
+    int codecMode;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
index 3499155..1d8acdf 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
@@ -29,4 +29,6 @@
     VENDOR,
     APTX_ADAPTIVE,
     OPUS,
+    APTX_ADAPTIVE_LE,
+    APTX_ADAPTIVE_LEX,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
index 0c354f7..ec181c1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -22,4 +22,6 @@
     UNKNOWN,
     LOW_LATENCY,
     FREE,
+    DYNAMIC_SPATIAL_AUDIO_SOFTWARE,
+    DYNAMIC_SPATIAL_AUDIO_HARDWARE
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index e9a1a0c..16503fb 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -35,6 +35,10 @@
          */
         int audioChannelAllocation;
         LeAudioCodecConfiguration leAudioCodecConfig;
+        /*
+         * Pcm stream id to identify the source for given streamHandle.
+         */
+        char pcmStreamId;
     }
     CodecType codecType;
     BroadcastStreamMap[] streamMap;
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
index 421eeb2..7ce6ff3 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -17,6 +17,7 @@
 package android.hardware.bluetooth.audio;
 
 import android.hardware.bluetooth.audio.Lc3Configuration;
+import android.hardware.bluetooth.audio.AptxAdaptiveLeConfiguration;
 
 @VintfStability
 union LeAudioCodecConfiguration {
@@ -26,4 +27,5 @@
     }
     Lc3Configuration lc3Config;
     VendorConfiguration vendorConfig;
+    AptxAdaptiveLeConfiguration aptxAdaptiveLeConfig;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index 0d1e3de..7302aea 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -35,9 +35,25 @@
          * Audio Location assigned number.
          */
         int audioChannelAllocation;
+        /*
+         * The stream handle status
+         */
+        boolean isStreamActive;
     }
     CodecType codecType;
     StreamMap[] streamMap;
     int peerDelayUs;
     LeAudioCodecConfiguration leAudioCodecConfig;
+
+    /*
+     * Bluetooth LTV format for vendor metadata is defined in the
+     * Section 6.12.6.9 Vendor_Specific of Bluetooth Assigned Numbers
+     *
+     * Octet 0 = Length
+     * Octet 1 = Type (Vendor specific - 0xFF)
+     * Octet 2-3 = Company_ID
+     * Company ID values are defined in Bluetooth Assigned Numbers.
+     * Octet 4 onwards = Vendor specific Metadata
+     */
+    @nullable byte[] vendorSpecificMetadata;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
index f8a924a..07688a7 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -19,6 +19,7 @@
 import android.hardware.bluetooth.audio.AudioLocation;
 import android.hardware.bluetooth.audio.CodecType;
 import android.hardware.bluetooth.audio.Lc3Capabilities;
+import android.hardware.bluetooth.audio.AptxAdaptiveLeCapabilities;
 
 /**
  * Used to specify the le audio unicast codec capabilities for hardware offload.
@@ -33,6 +34,7 @@
     union LeAudioCodecCapabilities {
         Lc3Capabilities lc3Capabilities;
         VendorCapabilities vendorCapabillities;
+        AptxAdaptiveLeCapabilities aptxAdaptiveLeCapabilities;
     }
     CodecType codecType;
     AudioLocation supportedChannel;
diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp
index cbf23dc..e4c2844 100644
--- a/bluetooth/audio/aidl/default/Android.bp
+++ b/bluetooth/audio/aidl/default/Android.bp
@@ -29,7 +29,7 @@
         "libcutils",
         "libfmq",
         "liblog",
-        "android.hardware.bluetooth.audio-V2-ndk",
+        "android.hardware.bluetooth.audio-V3-ndk",
         "libbluetooth_audio_session_aidl",
     ],
 }
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index 0e22e44..7f610ef 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -55,21 +55,20 @@
     const std::shared_ptr<IBluetoothAudioPort>& host_if,
     const AudioConfiguration& audio_config,
     const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
-  if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+  if (session_type_ ==
+      SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+    if (audio_config.getTag() != AudioConfiguration::leAudioBroadcastConfig) {
+      LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+                   << audio_config.toString();
+      *_aidl_return = DataMQDesc();
+      return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+  } else if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
     LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
                  << audio_config.toString();
     *_aidl_return = DataMQDesc();
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
   }
-  const auto& le_audio_config =
-      audio_config.get<AudioConfiguration::leAudioConfig>();
-  if (!BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid(
-          session_type_, le_audio_config)) {
-    LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration="
-                 << le_audio_config.toString();
-    *_aidl_return = DataMQDesc();
-    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
-  }
 
   return BluetoothAudioProvider::startSession(
       host_if, audio_config, latency_modes, _aidl_return);
diff --git a/bluetooth/audio/aidl/default/bluetooth_audio.xml b/bluetooth/audio/aidl/default/bluetooth_audio.xml
index c4b1872..c0bc55e 100644
--- a/bluetooth/audio/aidl/default/bluetooth_audio.xml
+++ b/bluetooth/audio/aidl/default/bluetooth_audio.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.bluetooth.audio</name>
-        <version>2</version>
+        <version>3</version>
         <fqname>IBluetoothAudioProviderFactory/default</fqname>
     </hal>
 </manifest>
diff --git a/bluetooth/audio/aidl/vts/Android.bp b/bluetooth/audio/aidl/vts/Android.bp
index 1d90d21..3e6953f 100644
--- a/bluetooth/audio/aidl/vts/Android.bp
+++ b/bluetooth/audio/aidl/vts/Android.bp
@@ -17,10 +17,10 @@
     srcs: ["VtsHalBluetoothAudioTargetTest.cpp"],
     static_libs: [
         "android.hardware.audio.common-V1-ndk",
-        "android.hardware.bluetooth.audio-V2-ndk",
+        "android.hardware.bluetooth.audio-V3-ndk",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
-        "android.media.audio.common.types-V1-ndk",
+        "android.media.audio.common.types-V2-ndk",
     ],
     shared_libs: [
         "libbase",
@@ -28,6 +28,7 @@
         "libcutils",
         "libfmq",
     ],
+    test_config: "VtsHalBluetoothAudioTargetTest.xml",
     test_suites: [
         "general-tests",
         "vts",
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index e9b74b7..858fa38 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -35,6 +35,8 @@
 using aidl::android::hardware::audio::common::SourceMetadata;
 using aidl::android::hardware::bluetooth::audio::AacCapabilities;
 using aidl::android::hardware::bluetooth::audio::AacConfiguration;
+using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeCapabilities;
+using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeConfiguration;
 using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
 using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
 using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
@@ -87,10 +89,6 @@
 static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
 static constexpr ChannelMode a2dp_channel_modes[] = {
     ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
-static constexpr CodecType a2dp_codec_types[] = {
-    CodecType::UNKNOWN, CodecType::SBC,          CodecType::AAC,
-    CodecType::APTX,    CodecType::APTX_HD,      CodecType::LDAC,
-    CodecType::LC3,     CodecType::APTX_ADAPTIVE};
 static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
 // Helpers
 
@@ -238,6 +236,8 @@
                         CodecCapabilities::Capabilities::opusCapabilities);
               break;
             case CodecType::APTX_ADAPTIVE:
+            case CodecType::APTX_ADAPTIVE_LE:
+            case CodecType::APTX_ADAPTIVE_LEX:
             case CodecType::LC3:
             case CodecType::VENDOR:
             case CodecType::UNKNOWN:
@@ -387,6 +387,11 @@
       variable_bit_rate_enableds.push_back(true);
     }
 
+    std::vector<bool> adaptive_bit_rate_supporteds = {false};
+    if (aac_capability.adaptiveBitRateSupported) {
+      adaptive_bit_rate_supporteds.push_back(true);
+    }
+
     // combine those parameters into one list of
     // CodecConfiguration::CodecSpecific
     for (auto object_type : aac_capability.objectType) {
@@ -394,14 +399,18 @@
         for (auto channel_mode : aac_capability.channelMode) {
           for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
             for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
-              AacConfiguration aac_data{
-                  .objectType = object_type,
-                  .sampleRateHz = sample_rate,
-                  .channelMode = channel_mode,
-                  .variableBitRateEnabled = variable_bit_rate_enabled,
-                  .bitsPerSample = bits_per_sample};
-              aac_codec_specifics.push_back(
-                  CodecConfiguration::CodecSpecific(aac_data));
+              for (auto adaptive_bit_rate_supported :
+                   adaptive_bit_rate_supporteds) {
+                AacConfiguration aac_data{
+                    .objectType = object_type,
+                    .sampleRateHz = sample_rate,
+                    .channelMode = channel_mode,
+                    .variableBitRateEnabled = variable_bit_rate_enabled,
+                    .bitsPerSample = bits_per_sample,
+                    .adaptiveBitRateSupported = adaptive_bit_rate_supported};
+                aac_codec_specifics.push_back(
+                    CodecConfiguration::CodecSpecific(aac_data));
+              }
             }
           }
         }
@@ -845,7 +854,7 @@
   ASSERT_NE(audio_provider_, nullptr);
 
   std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
-  for (auto codec_type : a2dp_codec_types) {
+  for (auto codec_type : ndk::enum_range<CodecType>()) {
     switch (codec_type) {
       case CodecType::SBC:
         codec_specifics = GetSbcCodecSpecificSupportedList(false);
@@ -866,6 +875,8 @@
         codec_specifics = GetOpusCodecSpecificSupportedList(false);
         continue;
       case CodecType::APTX_ADAPTIVE:
+      case CodecType::APTX_ADAPTIVE_LE:
+      case CodecType::APTX_ADAPTIVE_LEX:
       case CodecType::LC3:
       case CodecType::VENDOR:
       case CodecType::UNKNOWN:
@@ -1192,6 +1203,73 @@
     return le_audio_codec_configs;
   }
 
+  static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
+
+  std::vector<AptxAdaptiveLeConfiguration>
+  GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
+                                        bool is_le_extended) {
+    std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
+    if (!supported) {
+      AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
+          .pcmBitDepth = 0, .samplingFrequencyHz = 0};
+      le_audio_codec_configs.push_back(aptx_adaptive_le_config);
+      return le_audio_codec_configs;
+    }
+
+    // There might be more than one LeAudioCodecCapabilitiesSetting
+    std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
+    for (auto& capability : temp_provider_capabilities_) {
+      if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+        continue;
+      }
+      auto& le_audio_capability =
+          capability.get<AudioCapabilities::leAudioCapabilities>();
+      auto& unicast_capability =
+          decoding ? le_audio_capability.unicastDecodeCapability
+                   : le_audio_capability.unicastEncodeCapability;
+      if ((!is_le_extended &&
+           unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
+          (is_le_extended &&
+           unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
+        continue;
+      }
+
+      auto& aptx_adaptive_le_capability =
+          unicast_capability.leAudioCodecCapabilities
+              .get<UnicastCapability::LeAudioCodecCapabilities::
+                       aptxAdaptiveLeCapabilities>();
+
+      aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
+    }
+
+    for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
+      for (int32_t samplingFrequencyHz :
+           aptx_adaptive_le_capability.samplingFrequencyHz) {
+        for (int32_t frameDurationUs :
+             aptx_adaptive_le_capability.frameDurationUs) {
+          for (int32_t octetsPerFrame :
+               aptx_adaptive_le_capability.octetsPerFrame) {
+            for (int8_t blocksPerSdu :
+                 aptx_adaptive_le_capability.blocksPerSdu) {
+              for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
+                AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
+                    .samplingFrequencyHz = samplingFrequencyHz,
+                    .frameDurationUs = frameDurationUs,
+                    .octetsPerFrame = octetsPerFrame,
+                    .blocksPerSdu = blocksPerSdu,
+                    .codecMode = codecMode,
+                };
+                le_audio_codec_configs.push_back(aptx_adaptive_le_config);
+              }
+            }
+          }
+        }
+      }
+    }
+
+    return le_audio_codec_configs;
+  }
+
   LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
 };
 
@@ -1268,6 +1346,87 @@
   }
 }
 
+static std::vector<uint8_t> vendorMetadata = {0x0B,  // Length
+                                              0xFF,  // Type: Vendor-specific
+                                              0x0A, 0x00,  // Company_ID
+                                              0x01, 0x02, 0x03, 0x04,  // Data
+                                              0x05, 0x06, 0x07, 0x08};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
+  if (!IsOffloadOutputSupported()) {
+    return;
+  }
+  for (auto codec_type :
+       {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
+    bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
+    auto aptx_adaptive_le_codec_configs =
+        GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
+    LeAudioConfiguration le_audio_config = {
+        .codecType = codec_type,
+        .peerDelayUs = 0,
+        .vendorSpecificMetadata = vendorMetadata,
+    };
+
+    for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
+      le_audio_config.leAudioCodecConfig
+          .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
+              aptx_adaptive_le_config);
+      DataMQDesc mq_desc;
+      auto aidl_retval = audio_provider_->startSession(
+          audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+          &mq_desc);
+
+      ASSERT_TRUE(aidl_retval.isOk());
+      EXPECT_TRUE(audio_provider_->endSession().isOk());
+    }
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(
+    BluetoothAudioProviderLeAudioOutputHardwareAidl,
+    BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
+  if (!IsOffloadOutputSupported()) {
+    return;
+  }
+
+  for (auto codec_type :
+       {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
+    bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
+    auto aptx_adaptive_le_codec_configs =
+        GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
+    LeAudioConfiguration le_audio_config = {
+        .codecType = codec_type,
+        .peerDelayUs = 0,
+        .vendorSpecificMetadata = vendorMetadata,
+    };
+
+    for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
+      le_audio_config.leAudioCodecConfig
+          .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
+              aptx_adaptive_le_config);
+      DataMQDesc mq_desc;
+      auto aidl_retval = audio_provider_->startSession(
+          audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+          &mq_desc);
+
+      // AIDL call should fail on invalid codec
+      ASSERT_FALSE(aidl_retval.isOk());
+      EXPECT_TRUE(audio_provider_->endSession().isOk());
+    }
+  }
+}
+
 /**
  * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
  */
@@ -1566,9 +1725,14 @@
   };
 
   for (auto& lc3_config : lc3_codec_configs) {
+    le_audio_broadcast_config.streamMap.resize(1);
     le_audio_broadcast_config.streamMap[0]
         .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
             lc3_config);
+    le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
+    le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
+    le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
+
     DataMQDesc mq_desc;
     auto aidl_retval = audio_provider_->startSession(
         audio_port_, AudioConfiguration(le_audio_broadcast_config),
@@ -1872,7 +2036,7 @@
   ASSERT_NE(audio_provider_, nullptr);
 
   std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
-  for (auto codec_type : a2dp_codec_types) {
+  for (auto codec_type : ndk::enum_range<CodecType>()) {
     switch (codec_type) {
       case CodecType::SBC:
         codec_specifics = GetSbcCodecSpecificSupportedList(false);
@@ -1893,6 +2057,8 @@
         codec_specifics = GetOpusCodecSpecificSupportedList(false);
         continue;
       case CodecType::APTX_ADAPTIVE:
+      case CodecType::APTX_ADAPTIVE_LE:
+      case CodecType::APTX_ADAPTIVE_LEX:
       case CodecType::LC3:
       case CodecType::VENDOR:
       case CodecType::UNKNOWN:
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index d08cb0a..914d2b2 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -40,9 +40,13 @@
         "aidl_session/BluetoothAudioCodecs.cpp",
         "aidl_session/BluetoothAudioSession.cpp",
         "aidl_session/HidlToAidlMiddleware.cpp",
+        "aidl_session/BluetoothLeAudioCodecsProvider.cpp",
     ],
     export_include_dirs: ["aidl_session/"],
-    header_libs: ["libhardware_headers"],
+    header_libs: [
+        "libhardware_headers",
+        "libxsdc-utils",
+    ],
     shared_libs: [
         "android.hardware.bluetooth.audio@2.0",
         "android.hardware.bluetooth.audio@2.1",
@@ -51,7 +55,42 @@
         "libbinder_ndk",
         "libfmq",
         "liblog",
-        "android.hardware.bluetooth.audio-V2-ndk",
+        "android.hardware.bluetooth.audio-V3-ndk",
         "libhidlbase",
+        "libxml2",
     ],
+    generated_sources: ["le_audio_codec_capabilities"],
+    generated_headers: ["le_audio_codec_capabilities"],
+}
+
+cc_test {
+    name: "BluetoothLeAudioCodecsProviderTest",
+    srcs: [
+        "aidl_session/BluetoothLeAudioCodecsProvider.cpp",
+        "aidl_session/BluetoothLeAudioCodecsProviderTest.cpp",
+    ],
+    header_libs: [
+        "libxsdc-utils",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.bluetooth.audio-V3-ndk",
+        "libxml2",
+    ],
+    test_suites: [
+        "general-tests",
+    ],
+    test_options: {
+        unit_test: false,
+    },
+    generated_sources: ["le_audio_codec_capabilities"],
+    generated_headers: ["le_audio_codec_capabilities"],
+}
+
+xsd_config {
+    name: "le_audio_codec_capabilities",
+    srcs: ["le_audio_codec_capabilities/le_audio_codec_capabilities.xsd"],
+    package_name: "aidl.android.hardware.bluetooth.audio.setting",
+    api_dir: "le_audio_codec_capabilities/schema",
 }
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index b858f50..3ed9e07 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -20,6 +20,8 @@
 
 #include <aidl/android/hardware/bluetooth/audio/AacCapabilities.h>
 #include <aidl/android/hardware/bluetooth/audio/AacObjectType.h>
+#include <aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.h>
+#include <aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.h>
 #include <aidl/android/hardware/bluetooth/audio/AptxCapabilities.h>
 #include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
 #include <aidl/android/hardware/bluetooth/audio/LdacCapabilities.h>
@@ -32,6 +34,8 @@
 #include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
 #include <android-base/logging.h>
 
+#include "BluetoothLeAudioCodecsProvider.h"
+
 namespace aidl {
 namespace android {
 namespace hardware {
@@ -99,63 +103,51 @@
 static const UnicastCapability kInvalidUnicastCapability = {
     .codecType = CodecType::UNKNOWN};
 
+static const AptxAdaptiveLeCapabilities
+    kDefaultOffloadAptxAdaptiveLeCapability_48k = {
+        .samplingFrequencyHz = {48000},
+        .frameDurationUs = {10000},
+        .octetsPerFrame = {816}};
+
+static const AptxAdaptiveLeCapabilities
+    kDefaultOffloadAptxAdaptiveLeCapability_96k = {
+        .samplingFrequencyHz = {96000},
+        .frameDurationUs = {10000},
+        .octetsPerFrame = {816}};
+
+static const AptxAdaptiveLeCapabilities
+    kDefaultOffloadAptxAdaptiveLeXCapability_48k = {
+        .samplingFrequencyHz = {48000},
+        .frameDurationUs = {10000},
+        .octetsPerFrame = {816}};
+
+static const AptxAdaptiveLeCapabilities
+    kDefaultOffloadAptxAdaptiveLeXCapability_96k = {
+        .samplingFrequencyHz = {96000},
+        .frameDurationUs = {10000},
+        .octetsPerFrame = {816}};
+
 static const BroadcastCapability kInvalidBroadcastCapability = {
     .codecType = CodecType::UNKNOWN};
 
-// Default Supported Codecs
-// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30
-static const Lc3Capabilities kLc3Capability_16_1 = {
-    .samplingFrequencyHz = {16000},
-    .frameDurationUs = {7500},
-    .octetsPerFrame = {30}};
-
-// Default Supported Codecs
-// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40
-static const Lc3Capabilities kLc3Capability_16_2 = {
-    .samplingFrequencyHz = {16000},
-    .frameDurationUs = {10000},
-    .octetsPerFrame = {40}};
-
-// Default Supported Codecs
-// LC3 24_2: sample rate: 24 kHz, frame duration: 10 ms, octets per frame: 60
-static const Lc3Capabilities kLc3Capability_24_2 = {
-    .samplingFrequencyHz = {24000},
-    .frameDurationUs = {10000},
-    .octetsPerFrame = {60}};
-
-// Default Supported Codecs
-// LC3 32_2: sample rate: 32 kHz, frame duration: 10 ms, octets per frame: 80
-static const Lc3Capabilities kLc3Capability_32_2 = {
-    .samplingFrequencyHz = {32000},
-    .frameDurationUs = {10000},
-    .octetsPerFrame = {80}};
-
-// Default Supported Codecs
-// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
-static const Lc3Capabilities kLc3Capability_48_4 = {
-    .samplingFrequencyHz = {48000},
-    .frameDurationUs = {10000},
-    .octetsPerFrame = {120}};
-
-static const std::vector<Lc3Capabilities> supportedLc3CapabilityList = {
-    kLc3Capability_48_4, kLc3Capability_32_2, kLc3Capability_24_2,
-    kLc3Capability_16_2, kLc3Capability_16_1};
-
 static AudioLocation stereoAudio = static_cast<AudioLocation>(
     static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
     static_cast<uint8_t>(AudioLocation::FRONT_RIGHT));
-static AudioLocation monoAudio = AudioLocation::UNKNOWN;
+
+static const std::vector<AptxAdaptiveLeCapabilities>
+    supportedAptxAdaptiveLeCapabilityList = {
+        kDefaultOffloadAptxAdaptiveLeCapability_48k,
+        kDefaultOffloadAptxAdaptiveLeCapability_96k,
+        kDefaultOffloadAptxAdaptiveLeXCapability_48k,
+        kDefaultOffloadAptxAdaptiveLeXCapability_96k};
 
 // Stores the supported setting of audio location, connected device, and the
 // channel count for each device
 std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
     supportedDeviceSetting = {
-        // Stereo, two connected device, one for L one for R
-        std::make_tuple(stereoAudio, 2, 1),
         // Stereo, one connected device for both L and R
         std::make_tuple(stereoAudio, 1, 2),
-        // Mono
-        std::make_tuple(monoAudio, 1, 1)};
+};
 
 template <class T>
 bool BluetoothAudioCodecs::ContainedInVector(
@@ -321,19 +313,6 @@
   return false;
 }
 
-bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid(
-    const SessionType& session_type, const LeAudioConfiguration&) {
-  if (session_type !=
-          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
-      session_type !=
-          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
-      session_type !=
-          SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
-    return false;
-  }
-  return true;
-}
-
 std::vector<PcmCapabilities>
 BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
   return {kDefaultSoftwarePcmCapabilities};
@@ -384,6 +363,8 @@
       case CodecType::VENDOR:
       case CodecType::LC3:
       case CodecType::APTX_ADAPTIVE:
+      case CodecType::APTX_ADAPTIVE_LE:
+      case CodecType::APTX_ADAPTIVE_LEX:
         break;
     }
   }
@@ -449,6 +430,8 @@
       }
       break;
     case CodecType::APTX_ADAPTIVE:
+    case CodecType::APTX_ADAPTIVE_LE:
+    case CodecType::APTX_ADAPTIVE_LEX:
     case CodecType::LC3:
     case CodecType::UNKNOWN:
     case CodecType::VENDOR:
@@ -457,19 +440,6 @@
   return false;
 }
 
-UnicastCapability composeUnicastLc3Capability(
-    AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount,
-    const Lc3Capabilities& capability) {
-  return {
-      .codecType = CodecType::LC3,
-      .supportedChannel = audioLocation,
-      .deviceCount = deviceCnt,
-      .channelCountPerDevice = channelCount,
-      .leAudioCodecCapabilities =
-          UnicastCapability::LeAudioCodecCapabilities(capability),
-  };
-}
-
 std::vector<LeAudioCodecCapabilitiesSetting>
 BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
     const SessionType& session_type) {
@@ -483,36 +453,38 @@
   }
 
   if (kDefaultOffloadLeAudioCapabilities.empty()) {
+    auto le_audio_offload_setting =
+        BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
+    kDefaultOffloadLeAudioCapabilities =
+        BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
+            le_audio_offload_setting);
+
     for (auto [audioLocation, deviceCnt, channelCount] :
          supportedDeviceSetting) {
-      for (auto capability : supportedLc3CapabilityList) {
-        UnicastCapability lc3Capability = composeUnicastLc3Capability(
-            audioLocation, deviceCnt, channelCount, capability);
-        UnicastCapability lc3MonoDecodeCapability =
-            composeUnicastLc3Capability(monoAudio, 1, 1, capability);
+      for (auto capability : supportedAptxAdaptiveLeCapabilityList) {
+        for (auto codec_type :
+             {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
+          if (session_type ==
+              SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+            UnicastCapability aptx_adaptive_le_cap = {
+                .codecType = codec_type,
+                .supportedChannel = audioLocation,
+                .deviceCount = deviceCnt,
+                .channelCountPerDevice = channelCount,
+                .leAudioCodecCapabilities =
+                    UnicastCapability::LeAudioCodecCapabilities(capability),
+            };
 
-        // Adds the capability for encode only
-        kDefaultOffloadLeAudioCapabilities.push_back(
-            {.unicastEncodeCapability = lc3Capability,
-             .unicastDecodeCapability = kInvalidUnicastCapability,
-             .broadcastCapability = kInvalidBroadcastCapability});
-
-        // Adds the capability for decode only
-        kDefaultOffloadLeAudioCapabilities.push_back(
-            {.unicastEncodeCapability = kInvalidUnicastCapability,
-             .unicastDecodeCapability = lc3Capability,
-             .broadcastCapability = kInvalidBroadcastCapability});
-
-        // Adds the capability for the case that encode and decode exist at the
-        // same time
-        kDefaultOffloadLeAudioCapabilities.push_back(
-            {.unicastEncodeCapability = lc3Capability,
-             .unicastDecodeCapability = lc3MonoDecodeCapability,
-             .broadcastCapability = kInvalidBroadcastCapability});
+            // Adds the capability for encode only
+            kDefaultOffloadLeAudioCapabilities.push_back(
+                {.unicastEncodeCapability = aptx_adaptive_le_cap,
+                 .unicastDecodeCapability = kInvalidUnicastCapability,
+                 .broadcastCapability = kInvalidBroadcastCapability});
+          }
+        }
       }
     }
   }
-
   return kDefaultOffloadLeAudioCapabilities;
 }
 
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
index ed0598b..e3d657b 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
@@ -44,9 +44,6 @@
   static bool IsOffloadCodecConfigurationValid(
       const SessionType& session_type, const CodecConfiguration& codec_config);
 
-  static bool IsOffloadLeAudioConfigurationValid(
-      const SessionType& session_type, const LeAudioConfiguration&);
-
   static std::vector<LeAudioCodecCapabilitiesSetting>
   GetLeAudioOffloadCodecCapabilities(const SessionType& session_type);
 
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index 3214bf2..ee5527e 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -114,8 +114,16 @@
           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
     return;
   }
+
   std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+    LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+               << toString(session_type_);
+    return;
+  }
+
   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
+
   if (observers_.empty()) {
     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
                  << " has NO port state observer";
@@ -274,11 +282,14 @@
   bool is_offload_a2dp_session =
       (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
        session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
-  bool is_offload_le_audio_session =
+  bool is_offload_le_audio_unicast_session =
       (session_type_ ==
            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
        session_type_ ==
            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+  bool is_offload_le_audio_broadcast_session =
+      (session_type_ ==
+       SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
   auto audio_config_tag = audio_config.getTag();
   bool is_software_audio_config =
       (is_software_session &&
@@ -286,11 +297,15 @@
   bool is_a2dp_offload_audio_config =
       (is_offload_a2dp_session &&
        audio_config_tag == AudioConfiguration::a2dpConfig);
-  bool is_le_audio_offload_audio_config =
-      (is_offload_le_audio_session &&
+  bool is_le_audio_offload_unicast_audio_config =
+      (is_offload_le_audio_unicast_session &&
        audio_config_tag == AudioConfiguration::leAudioConfig);
+  bool is_le_audio_offload_broadcast_audio_config =
+      (is_offload_le_audio_broadcast_session &&
+       audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
   if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
-      !is_le_audio_offload_audio_config) {
+      !is_le_audio_offload_unicast_audio_config &&
+      !is_le_audio_offload_broadcast_audio_config) {
     return false;
   }
   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
new file mode 100644
index 0000000..0a804bb
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioCodecsProviderAidl"
+
+#include "BluetoothLeAudioCodecsProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+static const char* kLeAudioCodecCapabilitiesFile =
+    "/vendor/etc/le_audio_codec_capabilities.xml";
+
+static const AudioLocation kStereoAudio = static_cast<AudioLocation>(
+    static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
+    static_cast<uint8_t>(AudioLocation::FRONT_RIGHT));
+static const AudioLocation kMonoAudio = AudioLocation::UNKNOWN;
+
+static std::vector<LeAudioCodecCapabilitiesSetting> leAudioCodecCapabilities;
+
+static bool isInvalidFileContent = false;
+
+std::optional<setting::LeAudioOffloadSetting>
+BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile() {
+  if (!leAudioCodecCapabilities.empty() || isInvalidFileContent) {
+    return std::nullopt;
+  }
+  auto le_audio_offload_setting =
+      setting::readLeAudioOffloadSetting(kLeAudioCodecCapabilitiesFile);
+  if (!le_audio_offload_setting.has_value()) {
+    LOG(ERROR) << __func__ << ": Failed to read "
+               << kLeAudioCodecCapabilitiesFile;
+  }
+  return le_audio_offload_setting;
+}
+
+std::vector<LeAudioCodecCapabilitiesSetting>
+BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
+    const std::optional<setting::LeAudioOffloadSetting>&
+        le_audio_offload_setting) {
+  if (!leAudioCodecCapabilities.empty()) {
+    return leAudioCodecCapabilities;
+  }
+
+  if (!le_audio_offload_setting.has_value()) {
+    LOG(ERROR)
+        << __func__
+        << ": input le_audio_offload_setting content need to be non empty";
+    return {};
+  }
+
+  ClearLeAudioCodecCapabilities();
+  isInvalidFileContent = true;
+
+  std::vector<setting::Scenario> supported_scenarios =
+      GetScenarios(le_audio_offload_setting);
+  if (supported_scenarios.empty()) {
+    LOG(ERROR) << __func__ << ": No scenarios in "
+               << kLeAudioCodecCapabilitiesFile;
+    return {};
+  }
+
+  UpdateConfigurationsToMap(le_audio_offload_setting);
+  if (configuration_map_.empty()) {
+    LOG(ERROR) << __func__ << ": No configurations in "
+               << kLeAudioCodecCapabilitiesFile;
+    return {};
+  }
+
+  UpdateCodecConfigurationsToMap(le_audio_offload_setting);
+  if (codec_configuration_map_.empty()) {
+    LOG(ERROR) << __func__ << ": No codec configurations in "
+               << kLeAudioCodecCapabilitiesFile;
+    return {};
+  }
+
+  UpdateStrategyConfigurationsToMap(le_audio_offload_setting);
+  if (strategy_configuration_map_.empty()) {
+    LOG(ERROR) << __func__ << ": No strategy configurations in "
+               << kLeAudioCodecCapabilitiesFile;
+    return {};
+  }
+
+  leAudioCodecCapabilities =
+      ComposeLeAudioCodecCapabilities(supported_scenarios);
+  isInvalidFileContent = leAudioCodecCapabilities.empty();
+
+  return leAudioCodecCapabilities;
+}
+
+void BluetoothLeAudioCodecsProvider::ClearLeAudioCodecCapabilities() {
+  leAudioCodecCapabilities.clear();
+  configuration_map_.clear();
+  codec_configuration_map_.clear();
+  strategy_configuration_map_.clear();
+}
+
+std::vector<setting::Scenario> BluetoothLeAudioCodecsProvider::GetScenarios(
+    const std::optional<setting::LeAudioOffloadSetting>&
+        le_audio_offload_setting) {
+  std::vector<setting::Scenario> supported_scenarios;
+  if (le_audio_offload_setting->hasScenarioList()) {
+    for (const auto& scenario_list :
+         le_audio_offload_setting->getScenarioList()) {
+      if (!scenario_list.hasScenario()) {
+        continue;
+      }
+      for (const auto& scenario : scenario_list.getScenario()) {
+        if (scenario.hasEncode() && scenario.hasDecode()) {
+          supported_scenarios.push_back(scenario);
+        }
+      }
+    }
+  }
+  return supported_scenarios;
+}
+
+void BluetoothLeAudioCodecsProvider::UpdateConfigurationsToMap(
+    const std::optional<setting::LeAudioOffloadSetting>&
+        le_audio_offload_setting) {
+  if (le_audio_offload_setting->hasConfigurationList()) {
+    for (const auto& configuration_list :
+         le_audio_offload_setting->getConfigurationList()) {
+      if (!configuration_list.hasConfiguration()) {
+        continue;
+      }
+      for (const auto& configuration : configuration_list.getConfiguration()) {
+        if (configuration.hasName() && configuration.hasCodecConfiguration() &&
+            configuration.hasStrategyConfiguration()) {
+          configuration_map_.insert(
+              make_pair(configuration.getName(), configuration));
+        }
+      }
+    }
+  }
+}
+
+void BluetoothLeAudioCodecsProvider::UpdateCodecConfigurationsToMap(
+    const std::optional<setting::LeAudioOffloadSetting>&
+        le_audio_offload_setting) {
+  if (le_audio_offload_setting->hasCodecConfigurationList()) {
+    for (const auto& codec_configuration_list :
+         le_audio_offload_setting->getCodecConfigurationList()) {
+      if (!codec_configuration_list.hasCodecConfiguration()) {
+        continue;
+      }
+      for (const auto& codec_configuration :
+           codec_configuration_list.getCodecConfiguration()) {
+        if (IsValidCodecConfiguration(codec_configuration)) {
+          codec_configuration_map_.insert(
+              make_pair(codec_configuration.getName(), codec_configuration));
+        }
+      }
+    }
+  }
+}
+
+void BluetoothLeAudioCodecsProvider::UpdateStrategyConfigurationsToMap(
+    const std::optional<setting::LeAudioOffloadSetting>&
+        le_audio_offload_setting) {
+  if (le_audio_offload_setting->hasStrategyConfigurationList()) {
+    for (const auto& strategy_configuration_list :
+         le_audio_offload_setting->getStrategyConfigurationList()) {
+      if (!strategy_configuration_list.hasStrategyConfiguration()) {
+        continue;
+      }
+      for (const auto& strategy_configuration :
+           strategy_configuration_list.getStrategyConfiguration()) {
+        if (IsValidStrategyConfiguration(strategy_configuration)) {
+          strategy_configuration_map_.insert(make_pair(
+              strategy_configuration.getName(), strategy_configuration));
+        }
+      }
+    }
+  }
+}
+
+std::vector<LeAudioCodecCapabilitiesSetting>
+BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities(
+    const std::vector<setting::Scenario>& supported_scenarios) {
+  std::vector<LeAudioCodecCapabilitiesSetting> le_audio_codec_capabilities;
+  for (const auto& scenario : supported_scenarios) {
+    UnicastCapability unicast_encode_capability =
+        GetUnicastCapability(scenario.getEncode());
+    UnicastCapability unicast_decode_capability =
+        GetUnicastCapability(scenario.getDecode());
+    BroadcastCapability broadcast_capability = {.codecType =
+                                                    CodecType::UNKNOWN};
+
+    if (scenario.hasBroadcast()) {
+      broadcast_capability = GetBroadcastCapability(scenario.getBroadcast());
+    }
+
+    // At least one capability should be valid
+    if (unicast_encode_capability.codecType == CodecType::UNKNOWN &&
+        unicast_decode_capability.codecType == CodecType::UNKNOWN &&
+        broadcast_capability.codecType == CodecType::UNKNOWN) {
+      LOG(ERROR) << __func__ << ": None of the capability is valid.";
+      continue;
+    }
+
+    le_audio_codec_capabilities.push_back(
+        {.unicastEncodeCapability = unicast_encode_capability,
+         .unicastDecodeCapability = unicast_decode_capability,
+         .broadcastCapability = broadcast_capability});
+  }
+  return le_audio_codec_capabilities;
+}
+
+UnicastCapability BluetoothLeAudioCodecsProvider::GetUnicastCapability(
+    const std::string& coding_direction) {
+  if (coding_direction == "invalid") {
+    return {.codecType = CodecType::UNKNOWN};
+  }
+
+  auto configuration_iter = configuration_map_.find(coding_direction);
+  if (configuration_iter == configuration_map_.end()) {
+    return {.codecType = CodecType::UNKNOWN};
+  }
+
+  auto codec_configuration_iter = codec_configuration_map_.find(
+      configuration_iter->second.getCodecConfiguration());
+  if (codec_configuration_iter == codec_configuration_map_.end()) {
+    return {.codecType = CodecType::UNKNOWN};
+  }
+
+  auto strategy_configuration_iter = strategy_configuration_map_.find(
+      configuration_iter->second.getStrategyConfiguration());
+  if (strategy_configuration_iter == strategy_configuration_map_.end()) {
+    return {.codecType = CodecType::UNKNOWN};
+  }
+
+  CodecType codec_type =
+      GetCodecType(codec_configuration_iter->second.getCodec());
+  if (codec_type == CodecType::LC3) {
+    return ComposeUnicastCapability(
+        codec_type,
+        GetAudioLocation(
+            strategy_configuration_iter->second.getAudioLocation()),
+        strategy_configuration_iter->second.getConnectedDevice(),
+        strategy_configuration_iter->second.getChannelCount(),
+        ComposeLc3Capability(codec_configuration_iter->second));
+  }
+  return {.codecType = CodecType::UNKNOWN};
+}
+
+BroadcastCapability BluetoothLeAudioCodecsProvider::GetBroadcastCapability(
+    const std::string& coding_direction) {
+  if (coding_direction == "invalid") {
+    return {.codecType = CodecType::UNKNOWN};
+  }
+
+  auto configuration_iter = configuration_map_.find(coding_direction);
+  if (configuration_iter == configuration_map_.end()) {
+    return {.codecType = CodecType::UNKNOWN};
+  }
+
+  auto codec_configuration_iter = codec_configuration_map_.find(
+      configuration_iter->second.getCodecConfiguration());
+  if (codec_configuration_iter == codec_configuration_map_.end()) {
+    return {.codecType = CodecType::UNKNOWN};
+  }
+
+  auto strategy_configuration_iter = strategy_configuration_map_.find(
+      configuration_iter->second.getStrategyConfiguration());
+  if (strategy_configuration_iter == strategy_configuration_map_.end()) {
+    return {.codecType = CodecType::UNKNOWN};
+  }
+
+  CodecType codec_type =
+      GetCodecType(codec_configuration_iter->second.getCodec());
+  std::vector<std::optional<Lc3Capabilities>> bcastLc3Cap(
+      1, std::optional(ComposeLc3Capability(codec_configuration_iter->second)));
+
+  if (codec_type == CodecType::LC3) {
+    return ComposeBroadcastCapability(
+        codec_type,
+        GetAudioLocation(
+            strategy_configuration_iter->second.getAudioLocation()),
+        strategy_configuration_iter->second.getChannelCount(), bcastLc3Cap);
+  }
+  return {.codecType = CodecType::UNKNOWN};
+}
+
+template <class T>
+BroadcastCapability BluetoothLeAudioCodecsProvider::ComposeBroadcastCapability(
+    const CodecType& codec_type, const AudioLocation& audio_location,
+    const uint8_t& channel_count, const std::vector<T>& capability) {
+  return {.codecType = codec_type,
+          .supportedChannel = audio_location,
+          .channelCountPerStream = channel_count,
+          .leAudioCodecCapabilities = std::optional(capability)};
+}
+
+template <class T>
+UnicastCapability BluetoothLeAudioCodecsProvider::ComposeUnicastCapability(
+    const CodecType& codec_type, const AudioLocation& audio_location,
+    const uint8_t& device_cnt, const uint8_t& channel_count,
+    const T& capability) {
+  return {
+      .codecType = codec_type,
+      .supportedChannel = audio_location,
+      .deviceCount = device_cnt,
+      .channelCountPerDevice = channel_count,
+      .leAudioCodecCapabilities =
+          UnicastCapability::LeAudioCodecCapabilities(capability),
+  };
+}
+
+Lc3Capabilities BluetoothLeAudioCodecsProvider::ComposeLc3Capability(
+    const setting::CodecConfiguration& codec_configuration) {
+  return {.samplingFrequencyHz = {codec_configuration.getSamplingFrequency()},
+          .frameDurationUs = {codec_configuration.getFrameDurationUs()},
+          .octetsPerFrame = {codec_configuration.getOctetsPerCodecFrame()}};
+}
+
+AudioLocation BluetoothLeAudioCodecsProvider::GetAudioLocation(
+    const setting::AudioLocation& audio_location) {
+  switch (audio_location) {
+    case setting::AudioLocation::MONO:
+      return kMonoAudio;
+    case setting::AudioLocation::STEREO:
+      return kStereoAudio;
+    default:
+      return AudioLocation::UNKNOWN;
+  }
+}
+
+CodecType BluetoothLeAudioCodecsProvider::GetCodecType(
+    const setting::CodecType& codec_type) {
+  switch (codec_type) {
+    case setting::CodecType::LC3:
+      return CodecType::LC3;
+    default:
+      return CodecType::UNKNOWN;
+  }
+}
+
+bool BluetoothLeAudioCodecsProvider::IsValidCodecConfiguration(
+    const setting::CodecConfiguration& codec_configuration) {
+  return codec_configuration.hasName() && codec_configuration.hasCodec() &&
+         codec_configuration.hasSamplingFrequency() &&
+         codec_configuration.hasFrameDurationUs() &&
+         codec_configuration.hasOctetsPerCodecFrame();
+}
+
+bool BluetoothLeAudioCodecsProvider::IsValidStrategyConfiguration(
+    const setting::StrategyConfiguration& strategy_configuration) {
+  if (!strategy_configuration.hasName() ||
+      !strategy_configuration.hasAudioLocation() ||
+      !strategy_configuration.hasConnectedDevice() ||
+      !strategy_configuration.hasChannelCount()) {
+    return false;
+  }
+  if (strategy_configuration.getAudioLocation() ==
+      setting::AudioLocation::STEREO) {
+    if ((strategy_configuration.getConnectedDevice() == 2 &&
+         strategy_configuration.getChannelCount() == 1) ||
+        (strategy_configuration.getConnectedDevice() == 1 &&
+         strategy_configuration.getChannelCount() == 2)) {
+      // Stereo
+      // 1. two connected device, one for L one for R
+      // 2. one connected device for both L and R
+      return true;
+    } else if (strategy_configuration.getConnectedDevice() == 0 &&
+               strategy_configuration.getChannelCount() == 2) {
+      // Broadcast
+      return true;
+    }
+  } else if (strategy_configuration.getAudioLocation() ==
+             setting::AudioLocation::MONO) {
+    if (strategy_configuration.getConnectedDevice() == 1 &&
+        strategy_configuration.getChannelCount() == 1) {
+      // Mono
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
new file mode 100644
index 0000000..06e4595
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.h>
+#include <android-base/logging.h>
+
+#include <unordered_map>
+#include <vector>
+
+#include "aidl_android_hardware_bluetooth_audio_setting.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothLeAudioCodecsProvider {
+ public:
+  static std::optional<setting::LeAudioOffloadSetting>
+  ParseFromLeAudioOffloadSettingFile();
+  static std::vector<LeAudioCodecCapabilitiesSetting>
+  GetLeAudioCodecCapabilities(
+      const std::optional<setting::LeAudioOffloadSetting>&
+          le_audio_offload_setting);
+  static void ClearLeAudioCodecCapabilities();
+
+ private:
+  static inline std::unordered_map<std::string, setting::Configuration>
+      configuration_map_;
+  static inline std::unordered_map<std::string, setting::CodecConfiguration>
+      codec_configuration_map_;
+  static inline std::unordered_map<std::string, setting::StrategyConfiguration>
+      strategy_configuration_map_;
+
+  static std::vector<setting::Scenario> GetScenarios(
+      const std::optional<setting::LeAudioOffloadSetting>&
+          le_audio_offload_setting);
+  static void UpdateConfigurationsToMap(
+      const std::optional<setting::LeAudioOffloadSetting>&
+          le_audio_offload_setting);
+  static void UpdateCodecConfigurationsToMap(
+      const std::optional<setting::LeAudioOffloadSetting>&
+          le_audio_offload_setting);
+  static void UpdateStrategyConfigurationsToMap(
+      const std::optional<setting::LeAudioOffloadSetting>&
+          le_audio_offload_setting);
+
+  static std::vector<LeAudioCodecCapabilitiesSetting>
+  ComposeLeAudioCodecCapabilities(
+      const std::vector<setting::Scenario>& supported_scenarios);
+
+  static UnicastCapability GetUnicastCapability(
+      const std::string& coding_direction);
+  static BroadcastCapability GetBroadcastCapability(
+      const std::string& coding_direction);
+
+  template <class T>
+  static inline UnicastCapability ComposeUnicastCapability(
+      const CodecType& codec_type, const AudioLocation& audio_location,
+      const uint8_t& device_cnt, const uint8_t& channel_count,
+      const T& capability);
+
+  template <class T>
+  static inline BroadcastCapability ComposeBroadcastCapability(
+      const CodecType& codec_type, const AudioLocation& audio_location,
+      const uint8_t& channel_count, const std::vector<T>& capability);
+
+  static inline Lc3Capabilities ComposeLc3Capability(
+      const setting::CodecConfiguration& codec_configuration);
+
+  static inline AudioLocation GetAudioLocation(
+      const setting::AudioLocation& audio_location);
+  static inline CodecType GetCodecType(const setting::CodecType& codec_type);
+
+  static inline bool IsValidCodecConfiguration(
+      const setting::CodecConfiguration& codec_configuration);
+  static inline bool IsValidStrategyConfiguration(
+      const setting::StrategyConfiguration& strategy_configuration);
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp
new file mode 100644
index 0000000..dba2749
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <optional>
+#include <tuple>
+
+#include "BluetoothLeAudioCodecsProvider.h"
+
+using aidl::android::hardware::bluetooth::audio::BluetoothLeAudioCodecsProvider;
+using aidl::android::hardware::bluetooth::audio::
+    LeAudioCodecCapabilitiesSetting;
+using aidl::android::hardware::bluetooth::audio::setting::AudioLocation;
+using aidl::android::hardware::bluetooth::audio::setting::CodecConfiguration;
+using aidl::android::hardware::bluetooth::audio::setting::
+    CodecConfigurationList;
+using aidl::android::hardware::bluetooth::audio::setting::CodecType;
+using aidl::android::hardware::bluetooth::audio::setting::Configuration;
+using aidl::android::hardware::bluetooth::audio::setting::ConfigurationList;
+using aidl::android::hardware::bluetooth::audio::setting::LeAudioOffloadSetting;
+using aidl::android::hardware::bluetooth::audio::setting::Scenario;
+using aidl::android::hardware::bluetooth::audio::setting::ScenarioList;
+using aidl::android::hardware::bluetooth::audio::setting::StrategyConfiguration;
+using aidl::android::hardware::bluetooth::audio::setting::
+    StrategyConfigurationList;
+
+typedef std::tuple<std::vector<ScenarioList>, std::vector<ConfigurationList>,
+                   std::vector<CodecConfigurationList>,
+                   std::vector<StrategyConfigurationList>>
+    OffloadSetting;
+
+// Define valid components for each list
+// Scenario
+static const Scenario kValidScenario(std::make_optional("OneChanStereo_16_1"),
+                                     std::make_optional("OneChanStereo_16_1"),
+                                     std::nullopt);
+static const Scenario kValidBroadcastScenario(
+    std::nullopt, std::nullopt, std::make_optional("BcastStereo_16_2"));
+
+// Configuration
+static const Configuration kValidConfigOneChanStereo_16_1(
+    std::make_optional("OneChanStereo_16_1"), std::make_optional("LC3_16k_1"),
+    std::make_optional("STEREO_ONE_CIS_PER_DEVICE"));
+// CodecConfiguration
+static const CodecConfiguration kValidCodecLC3_16k_1(
+    std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
+    std::nullopt, std::make_optional(16000), std::make_optional(7500),
+    std::make_optional(30), std::nullopt);
+// StrategyConfiguration
+static const StrategyConfiguration kValidStrategyStereoOneCis(
+    std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
+    std::make_optional(AudioLocation::STEREO), std::make_optional(2),
+    std::make_optional(1));
+static const StrategyConfiguration kValidStrategyStereoTwoCis(
+    std::make_optional("STEREO_TWO_CISES_PER_DEVICE"),
+    std::make_optional(AudioLocation::STEREO), std::make_optional(1),
+    std::make_optional(2));
+static const StrategyConfiguration kValidStrategyMonoOneCis(
+    std::make_optional("MONO_ONE_CIS_PER_DEVICE"),
+    std::make_optional(AudioLocation::MONO), std::make_optional(1),
+    std::make_optional(1));
+static const StrategyConfiguration kValidStrategyBroadcastStereo(
+    std::make_optional("BROADCAST_STEREO"),
+    std::make_optional(AudioLocation::STEREO), std::make_optional(0),
+    std::make_optional(2));
+
+// Define valid test list built from above valid components
+// Scenario, Configuration, CodecConfiguration, StrategyConfiguration
+static const std::vector<ScenarioList> kValidScenarioList = {ScenarioList(
+    std::vector<Scenario>{kValidScenario, kValidBroadcastScenario})};
+static const std::vector<ConfigurationList> kValidConfigurationList = {
+    ConfigurationList(
+        std::vector<Configuration>{kValidConfigOneChanStereo_16_1})};
+static const std::vector<CodecConfigurationList> kValidCodecConfigurationList =
+    {CodecConfigurationList(
+        std::vector<CodecConfiguration>{kValidCodecLC3_16k_1})};
+static const std::vector<StrategyConfigurationList>
+    kValidStrategyConfigurationList = {
+        StrategyConfigurationList(std::vector<StrategyConfiguration>{
+            kValidStrategyStereoOneCis, kValidStrategyStereoTwoCis,
+            kValidStrategyMonoOneCis, kValidStrategyBroadcastStereo})};
+
+class BluetoothLeAudioCodecsProviderTest
+    : public ::testing::TestWithParam<OffloadSetting> {
+ public:
+  static std::vector<OffloadSetting> CreateTestCases(
+      const std::vector<ScenarioList>& scenario_lists,
+      const std::vector<ConfigurationList>& configuration_lists,
+      const std::vector<CodecConfigurationList>& codec_configuration_lists,
+      const std::vector<StrategyConfigurationList>&
+          strategy_configuration_lists) {
+    // make each vector in output test_cases has only one element
+    // to match the input of test params
+    // normally only one vector in input has multiple elements
+    // we just split elements in this vector to several vector
+    std::vector<OffloadSetting> test_cases;
+    for (const auto& scenario_list : scenario_lists) {
+      for (const auto& configuration_list : configuration_lists) {
+        for (const auto& codec_configuration_list : codec_configuration_lists) {
+          for (const auto& strategy_configuration_list :
+               strategy_configuration_lists) {
+            test_cases.push_back(CreateTestCase(
+                scenario_list, configuration_list, codec_configuration_list,
+                strategy_configuration_list));
+          }
+        }
+      }
+    }
+    return test_cases;
+  }
+
+ protected:
+  void Initialize() {
+    BluetoothLeAudioCodecsProvider::ClearLeAudioCodecCapabilities();
+  }
+
+  std::vector<LeAudioCodecCapabilitiesSetting> RunTestCase() {
+    auto& [scenario_lists, configuration_lists, codec_configuration_lists,
+           strategy_configuration_lists] = GetParam();
+    LeAudioOffloadSetting le_audio_offload_setting(
+        scenario_lists, configuration_lists, codec_configuration_lists,
+        strategy_configuration_lists);
+    auto le_audio_codec_capabilities =
+        BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
+            std::make_optional(le_audio_offload_setting));
+    return le_audio_codec_capabilities;
+  }
+
+ private:
+  static inline OffloadSetting CreateTestCase(
+      const ScenarioList& scenario_list,
+      const ConfigurationList& configuration_list,
+      const CodecConfigurationList& codec_configuration_list,
+      const StrategyConfigurationList& strategy_configuration_list) {
+    return std::make_tuple(
+        std::vector<ScenarioList>{scenario_list},
+        std::vector<ConfigurationList>{configuration_list},
+        std::vector<CodecConfigurationList>{codec_configuration_list},
+        std::vector<StrategyConfigurationList>{strategy_configuration_list});
+  }
+};
+
+class GetScenariosTest : public BluetoothLeAudioCodecsProviderTest {
+ public:
+  static std::vector<ScenarioList> CreateInvalidScenarios() {
+    std::vector<ScenarioList> invalid_scenario_test_cases;
+    invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
+        Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"),
+                 std::nullopt)}));
+
+    invalid_scenario_test_cases.push_back(ScenarioList(
+        std::vector<Scenario>{Scenario(std::make_optional("OneChanStereo_16_1"),
+                                       std::nullopt, std::nullopt)}));
+
+    invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
+        Scenario(std::nullopt, std::nullopt, std::nullopt)}));
+
+    invalid_scenario_test_cases.push_back(
+        ScenarioList(std::vector<Scenario>{}));
+
+    return invalid_scenario_test_cases;
+  }
+};
+
+TEST_P(GetScenariosTest, InvalidScenarios) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(le_audio_codec_capabilities.empty());
+}
+
+class UpdateConfigurationsToMapTest
+    : public BluetoothLeAudioCodecsProviderTest {
+ public:
+  static std::vector<ConfigurationList> CreateInvalidConfigurations() {
+    std::vector<ConfigurationList> invalid_configuration_test_cases;
+    invalid_configuration_test_cases.push_back(
+        ConfigurationList(std::vector<Configuration>{
+            Configuration(std::nullopt, std::make_optional("LC3_16k_1"),
+                          std::make_optional("STEREO_ONE_CIS_PER_DEVICE"))}));
+
+    invalid_configuration_test_cases.push_back(
+        ConfigurationList(std::vector<Configuration>{Configuration(
+            std::make_optional("OneChanStereo_16_1"), std::nullopt,
+            std::make_optional("STEREO_ONE_CIS_PER_DEVICE"))}));
+
+    invalid_configuration_test_cases.push_back(
+        ConfigurationList(std::vector<Configuration>{
+            Configuration(std::make_optional("OneChanStereo_16_1"),
+                          std::make_optional("LC3_16k_1"), std::nullopt)}));
+
+    invalid_configuration_test_cases.push_back(
+        ConfigurationList(std::vector<Configuration>{}));
+
+    return invalid_configuration_test_cases;
+  }
+};
+
+TEST_P(UpdateConfigurationsToMapTest, InvalidConfigurations) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(le_audio_codec_capabilities.empty());
+}
+
+class UpdateCodecConfigurationsToMapTest
+    : public BluetoothLeAudioCodecsProviderTest {
+ public:
+  static std::vector<CodecConfigurationList>
+  CreateInvalidCodecConfigurations() {
+    std::vector<CodecConfigurationList> invalid_codec_configuration_test_cases;
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::nullopt, std::make_optional(CodecType::LC3), std::nullopt,
+            std::make_optional(16000), std::make_optional(7500),
+            std::make_optional(30), std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::make_optional("LC3_16k_1"), std::nullopt, std::nullopt,
+            std::make_optional(16000), std::make_optional(7500),
+            std::make_optional(30), std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
+            std::nullopt, std::nullopt, std::make_optional(7500),
+            std::make_optional(30), std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
+            std::nullopt, std::make_optional(16000), std::nullopt,
+            std::make_optional(30), std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
+            std::nullopt, std::make_optional(16000), std::make_optional(7500),
+            std::nullopt, std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(
+        CodecConfigurationList(std::vector<CodecConfiguration>{}));
+
+    return invalid_codec_configuration_test_cases;
+  }
+};
+
+TEST_P(UpdateCodecConfigurationsToMapTest, InvalidCodecConfigurations) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(le_audio_codec_capabilities.empty());
+}
+
+class UpdateStrategyConfigurationsToMapTest
+    : public BluetoothLeAudioCodecsProviderTest {
+ public:
+  static std::vector<StrategyConfigurationList>
+  CreateInvalidStrategyConfigurations() {
+    std::vector<StrategyConfigurationList>
+        invalid_strategy_configuration_test_cases;
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
+                std::make_optional(AudioLocation::STEREO),
+                std::make_optional(2), std::make_optional(2))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("MONO_ONE_CIS_PER_DEVICE"),
+                std::make_optional(AudioLocation::STEREO),
+                std::make_optional(2), std::make_optional(2))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::nullopt, std::make_optional(AudioLocation::STEREO),
+                std::make_optional(2), std::make_optional(1))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("STEREO_ONE_CIS_PER_DEVICE"), std::nullopt,
+                std::make_optional(2), std::make_optional(1))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
+                std::make_optional(AudioLocation::STEREO), std::nullopt,
+                std::make_optional(1))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
+                std::make_optional(AudioLocation::STEREO),
+                std::make_optional(2), std::nullopt)}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(std::vector<StrategyConfiguration>{}));
+
+    return invalid_strategy_configuration_test_cases;
+  }
+};
+
+TEST_P(UpdateStrategyConfigurationsToMapTest, InvalidStrategyConfigurations) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(le_audio_codec_capabilities.empty());
+}
+
+class ComposeLeAudioCodecCapabilitiesTest
+    : public BluetoothLeAudioCodecsProviderTest {
+ public:
+};
+
+TEST_P(ComposeLeAudioCodecCapabilitiesTest, CodecCapabilitiesNotEmpty) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(!le_audio_codec_capabilities.empty());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetScenariosTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, GetScenariosTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        GetScenariosTest::CreateInvalidScenarios(), kValidConfigurationList,
+        kValidCodecConfigurationList, kValidStrategyConfigurationList)));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UpdateConfigurationsToMapTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, UpdateConfigurationsToMapTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        kValidScenarioList,
+        UpdateConfigurationsToMapTest::CreateInvalidConfigurations(),
+        kValidCodecConfigurationList, kValidStrategyConfigurationList)));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    UpdateCodecConfigurationsToMapTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, UpdateCodecConfigurationsToMapTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        kValidScenarioList, kValidConfigurationList,
+        UpdateCodecConfigurationsToMapTest::CreateInvalidCodecConfigurations(),
+        kValidStrategyConfigurationList)));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    UpdateStrategyConfigurationsToMapTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, UpdateStrategyConfigurationsToMapTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        kValidScenarioList, kValidConfigurationList,
+        kValidCodecConfigurationList,
+        UpdateStrategyConfigurationsToMapTest::
+            CreateInvalidStrategyConfigurations())));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    ComposeLeAudioCodecCapabilitiesTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, ComposeLeAudioCodecCapabilitiesTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        kValidScenarioList, kValidConfigurationList,
+        kValidCodecConfigurationList, kValidStrategyConfigurationList)));
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml
new file mode 100644
index 0000000..c8d1af0
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!---
+  This is an example to configure LE Audio hardware offload supported capability settings
+  In the follow list, there would be only one list in this file. Add element into each list as needed.
+
+  codecConfigurationList:
+    Supported codec capability along with its parameter setting
+
+  strategyConfigurationList:
+     ASE Configuration strategies
+
+  configurationList:
+    For each configuration , there are two attributes
+      - codecConfiguration
+      - strategyConfiguration
+
+  scenarioList:
+    There would be only one `scenarios` group
+    For each scenario, the are two attributes
+      - encode
+      - decode
+    If a scenario is unidirectional, mark another direction as `invalid`
+    The configuration should be chosen from `configurationList`
+-->
+<leAudioOffloadSetting>
+  <scenarioList>
+    <!-- encode only -->
+    <scenario encode="OneChanMono_16_1" decode="invalid"/>
+    <scenario encode="TwoChanStereo_16_1" decode="invalid"/>
+    <scenario encode="OneChanStereo_16_1" decode="invalid"/>
+    <scenario encode="OneChanMono_16_2" decode="invalid"/>
+    <scenario encode="TwoChanStereo_16_2" decode="invalid"/>
+    <scenario encode="OneChanStereo_16_2" decode="invalid"/>
+    <!-- encode and decode -->
+    <scenario encode="OneChanStereo_16_1" decode="OneChanStereo_16_1"/>
+    <scenario encode="OneChanStereo_16_1" decode="OneChanMono_16_1"/>
+    <scenario encode="TwoChanStereo_16_1" decode="OneChanMono_16_1"/>
+    <scenario encode="OneChanMono_16_1" decode="OneChanMono_16_1"/>
+    <scenario encode="OneChanStereo_16_2" decode="OneChanStereo_16_2"/>
+    <scenario encode="OneChanStereo_16_2" decode="OneChanMono_16_2"/>
+    <scenario encode="TwoChanStereo_16_2" decode="OneChanMono_16_2"/>
+    <scenario encode="OneChanMono_16_2" decode="OneChanMono_16_2"/>
+    <!-- broadcast -->
+    <scenario encode="invalid" decode="invalid" broadcast="BcastStereo_16_2"/>
+  </scenarioList>
+  <configurationList>
+    <configuration name="OneChanMono_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
+    <configuration name="TwoChanStereo_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
+    <configuration name="OneChanStereo_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
+    <configuration name="OneChanMono_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
+    <configuration name="TwoChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
+    <configuration name="OneChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
+    <configuration name="BcastStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="BROADCAST_STEREO"/>
+  </configurationList>
+  <codecConfigurationList>
+    <codecConfiguration name="LC3_16k_1" codec="LC3" samplingFrequency="16000" frameDurationUs="7500" octetsPerCodecFrame="30"/>
+    <codecConfiguration name="LC3_16k_2" codec="LC3" samplingFrequency="16000" frameDurationUs="10000" octetsPerCodecFrame="40"/>
+  </codecConfigurationList>
+  <strategyConfigurationList>
+    <strategyConfiguration name="STEREO_ONE_CIS_PER_DEVICE" audioLocation="STEREO" connectedDevice="2" channelCount="1"/>
+    <strategyConfiguration name="STEREO_TWO_CISES_PER_DEVICE" audioLocation="STEREO" connectedDevice="1" channelCount="2"/>
+    <strategyConfiguration name="MONO_ONE_CIS_PER_DEVICE" audioLocation="MONO" connectedDevice="1" channelCount="1"/>
+    <strategyConfiguration name="BROADCAST_STEREO" audioLocation="STEREO" connectedDevice="0" channelCount="2"/>
+  </strategyConfigurationList>
+</leAudioOffloadSetting>
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd
new file mode 100644
index 0000000..8c2d6a1
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd
@@ -0,0 +1,75 @@
+<!-- LE Audio Offload Codec Capability Schema -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xs:element name="leAudioOffloadSetting">
+    <xs:complexType>
+      <xs:element ref="scenarioList" minOccurs="1" maxOccurs="1"/>
+      <xs:element ref="configurationList" minOccurs="1" maxOccurs="1"/>
+      <xs:element ref="codecConfigurationList" minOccurs="1" maxOccurs="1"/>
+      <xs:element ref="strategyConfigurationList" minOccurs="1" maxOccurs="1"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="scenarioList">
+    <xs:complexType>
+      <xs:element ref="scenario" minOccurs="1" maxOccurs="unbounded"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="configurationList">
+    <xs:complexType>
+      <xs:element ref="configuration" minOccurs="1" maxOccurs="unbounded"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="codecConfigurationList">
+    <xs:complexType>
+      <xs:element ref="codecConfiguration" minOccurs="1" maxOccurs="unbounded"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="strategyConfigurationList">
+    <xs:complexType>
+      <xs:element ref="strategyConfiguration" minOccurs="1" maxOccurs="unbounded"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="scenario">
+    <xs:complexType>
+      <xs:attribute name="encode" type="xs:string"/>
+      <xs:attribute name="decode" type="xs:string"/>
+      <xs:attribute name="broadcast" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="configuration">
+    <xs:complexType>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="codecConfiguration" type="xs:string"/>
+      <xs:attribute name="strategyConfiguration" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="codecConfiguration">
+    <xs:complexType>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="codec" type="codecType"/>
+      <xs:attribute name="pcmBitDepth" type="xs:unsignedByte"/>
+      <xs:attribute name="samplingFrequency" type="xs:int"/>
+      <xs:attribute name="frameDurationUs" type="xs:int"/>
+      <xs:attribute name="octetsPerCodecFrame" type="xs:int"/>
+      <xs:attribute name="codecFrameBlocksPerSdu" type="xs:unsignedByte"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="strategyConfiguration">
+    <xs:complexType>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="audioLocation" type="audioLocation"/>
+      <xs:attribute name="connectedDevice" type="xs:unsignedByte"/>
+      <xs:attribute name="channelCount" type="xs:unsignedByte"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:simpleType name="audioLocation">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="MONO"/>
+      <xs:enumeration value="STEREO"/>
+    </xs:restriction>
+  </xs:simpleType>
+  <xs:simpleType name="codecType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="LC3"/>
+    </xs:restriction>
+  </xs:simpleType>
+</xs:schema>
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt
new file mode 100644
index 0000000..886350e
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt
@@ -0,0 +1,113 @@
+// Signature format: 2.0
+package aidl.android.hardware.bluetooth.audio.setting {
+
+  public enum AudioLocation {
+    method public String getRawName();
+    enum_constant public static final aidl.android.hardware.bluetooth.audio.setting.AudioLocation MONO;
+    enum_constant public static final aidl.android.hardware.bluetooth.audio.setting.AudioLocation STEREO;
+  }
+
+  public class CodecConfiguration {
+    ctor public CodecConfiguration();
+    method public aidl.android.hardware.bluetooth.audio.setting.CodecType getCodec();
+    method public short getCodecFrameBlocksPerSdu();
+    method public int getFrameDurationUs();
+    method public String getName();
+    method public int getOctetsPerCodecFrame();
+    method public short getPcmBitDepth();
+    method public int getSamplingFrequency();
+    method public void setCodec(aidl.android.hardware.bluetooth.audio.setting.CodecType);
+    method public void setCodecFrameBlocksPerSdu(short);
+    method public void setFrameDurationUs(int);
+    method public void setName(String);
+    method public void setOctetsPerCodecFrame(int);
+    method public void setPcmBitDepth(short);
+    method public void setSamplingFrequency(int);
+  }
+
+  public class CodecConfigurationList {
+    ctor public CodecConfigurationList();
+    method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.CodecConfiguration> getCodecConfiguration();
+  }
+
+  public enum CodecType {
+    method public String getRawName();
+    enum_constant public static final aidl.android.hardware.bluetooth.audio.setting.CodecType LC3;
+  }
+
+  public class Configuration {
+    ctor public Configuration();
+    method public String getCodecConfiguration();
+    method public String getName();
+    method public String getStrategyConfiguration();
+    method public void setCodecConfiguration(String);
+    method public void setName(String);
+    method public void setStrategyConfiguration(String);
+  }
+
+  public class ConfigurationList {
+    ctor public ConfigurationList();
+    method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.Configuration> getConfiguration();
+  }
+
+  public class LeAudioOffloadSetting {
+    ctor public LeAudioOffloadSetting();
+    method public aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList getCodecConfigurationList();
+    method public aidl.android.hardware.bluetooth.audio.setting.ConfigurationList getConfigurationList();
+    method public aidl.android.hardware.bluetooth.audio.setting.ScenarioList getScenarioList();
+    method public aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList getStrategyConfigurationList();
+    method public void setCodecConfigurationList(aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList);
+    method public void setConfigurationList(aidl.android.hardware.bluetooth.audio.setting.ConfigurationList);
+    method public void setScenarioList(aidl.android.hardware.bluetooth.audio.setting.ScenarioList);
+    method public void setStrategyConfigurationList(aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList);
+  }
+
+  public class Scenario {
+    ctor public Scenario();
+    method public String getBroadcast();
+    method public String getDecode();
+    method public String getEncode();
+    method public void setBroadcast(String);
+    method public void setDecode(String);
+    method public void setEncode(String);
+  }
+
+  public class ScenarioList {
+    ctor public ScenarioList();
+    method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.Scenario> getScenario();
+  }
+
+  public class StrategyConfiguration {
+    ctor public StrategyConfiguration();
+    method public aidl.android.hardware.bluetooth.audio.setting.AudioLocation getAudioLocation();
+    method public short getChannelCount();
+    method public short getConnectedDevice();
+    method public String getName();
+    method public void setAudioLocation(aidl.android.hardware.bluetooth.audio.setting.AudioLocation);
+    method public void setChannelCount(short);
+    method public void setConnectedDevice(short);
+    method public void setName(String);
+  }
+
+  public class StrategyConfigurationList {
+    ctor public StrategyConfigurationList();
+    method public java.util.List<aidl.android.hardware.bluetooth.audio.setting.StrategyConfiguration> getStrategyConfiguration();
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method public static aidl.android.hardware.bluetooth.audio.setting.CodecConfiguration readCodecConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static aidl.android.hardware.bluetooth.audio.setting.CodecConfigurationList readCodecConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static aidl.android.hardware.bluetooth.audio.setting.Configuration readConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static aidl.android.hardware.bluetooth.audio.setting.ConfigurationList readConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static aidl.android.hardware.bluetooth.audio.setting.LeAudioOffloadSetting readLeAudioOffloadSetting(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static aidl.android.hardware.bluetooth.audio.setting.Scenario readScenario(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static aidl.android.hardware.bluetooth.audio.setting.ScenarioList readScenarioList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static aidl.android.hardware.bluetooth.audio.setting.StrategyConfiguration readStrategyConfiguration(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static aidl.android.hardware.bluetooth.audio.setting.StrategyConfigurationList readStrategyConfigurationList(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_current.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_current.txt
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_removed.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/last_removed.txt
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/removed.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/bluetooth/hci/Android.bp b/bluetooth/hci/Android.bp
new file mode 100644
index 0000000..f0f6e8f
--- /dev/null
+++ b/bluetooth/hci/Android.bp
@@ -0,0 +1,46 @@
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_static {
+    name: "android.hardware.bluetooth.hci",
+    vendor_available: true,
+    host_supported: true,
+    defaults: ["hidl_defaults"],
+    srcs: [
+        "hci_packetizer.cc",
+        "h4_protocol.cc",
+    ],
+    export_include_dirs: ["."],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+}
+
+cc_test {
+    name: "bluetooth-vendor-interface-hci-test",
+    host_supported: true,
+    defaults: ["hidl_defaults"],
+    srcs: [
+        "test/h4_protocol_unittest.cc",
+    ],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.bluetooth.async",
+        "android.hardware.bluetooth.hci",
+        "libgmock",
+    ],
+    sanitize: {
+        address: true,
+        cfi: true,
+    },
+    test_suites: ["general-tests"],
+}
diff --git a/bluetooth/hci/h4_protocol.cc b/bluetooth/hci/h4_protocol.cc
new file mode 100644
index 0000000..51a624f
--- /dev/null
+++ b/bluetooth/hci/h4_protocol.cc
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "h4_protocol.h"
+
+#define LOG_TAG "android.hardware.bluetooth.hci-h4"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/uio.h>
+
+#include "log/log.h"
+
+namespace android::hardware::bluetooth::hci {
+
+H4Protocol::H4Protocol(int fd, PacketReadCallback cmd_cb,
+                       PacketReadCallback acl_cb, PacketReadCallback sco_cb,
+                       PacketReadCallback event_cb, PacketReadCallback iso_cb,
+                       DisconnectCallback disconnect_cb)
+    : uart_fd_(fd),
+      cmd_cb_(std::move(cmd_cb)),
+      acl_cb_(std::move(acl_cb)),
+      sco_cb_(std::move(sco_cb)),
+      event_cb_(std::move(event_cb)),
+      iso_cb_(std::move(iso_cb)),
+      disconnect_cb_(std::move(disconnect_cb)) {}
+
+size_t H4Protocol::Send(PacketType type, const std::vector<uint8_t>& vector) {
+  return Send(type, vector.data(), vector.size());
+}
+
+size_t H4Protocol::Send(PacketType type, const uint8_t* data, size_t length) {
+  /* For HCI communication over USB dongle, multiple write results in
+   * response timeout as driver expect type + data at once to process
+   * the command, so using "writev"(for atomicity) here.
+   */
+  struct iovec iov[2];
+  ssize_t ret = 0;
+  iov[0].iov_base = &type;
+  iov[0].iov_len = sizeof(type);
+  iov[1].iov_base = (void*)data;
+  iov[1].iov_len = length;
+  while (1) {
+    ret = TEMP_FAILURE_RETRY(writev(uart_fd_, iov, 2));
+    if (ret == -1) {
+      LOG_ALWAYS_FATAL("%s error writing to UART (%s)", __func__,
+                       strerror(errno));
+    } else if (ret == 0) {
+      // Nothing written :(
+      ALOGE("%s zero bytes written - something went wrong...", __func__);
+      break;
+    }
+    break;
+  }
+  return ret;
+}
+
+size_t H4Protocol::OnPacketReady(const std::vector<uint8_t>& packet) {
+  switch (hci_packet_type_) {
+    case PacketType::COMMAND:
+      cmd_cb_(packet);
+      break;
+    case PacketType::ACL_DATA:
+      acl_cb_(packet);
+      break;
+    case PacketType::SCO_DATA:
+      sco_cb_(packet);
+      break;
+    case PacketType::EVENT:
+      event_cb_(packet);
+      break;
+    case PacketType::ISO_DATA:
+      iso_cb_(packet);
+      break;
+    default: {
+      LOG_ALWAYS_FATAL("Bad packet type 0x%x",
+                       static_cast<int>(hci_packet_type_));
+    }
+  }
+  return packet.size();
+}
+
+void H4Protocol::SendDataToPacketizer(uint8_t* buffer, size_t length) {
+  std::vector<uint8_t> input_buffer{buffer, buffer + length};
+  size_t buffer_offset = 0;
+  while (buffer_offset < input_buffer.size()) {
+    if (hci_packet_type_ == PacketType::UNKNOWN) {
+      hci_packet_type_ =
+          static_cast<PacketType>(input_buffer.data()[buffer_offset]);
+      buffer_offset += 1;
+    } else {
+      bool packet_ready = hci_packetizer_.OnDataReady(
+          hci_packet_type_, input_buffer, buffer_offset);
+      if (packet_ready) {
+        // Call packet callback and move offset.
+        buffer_offset += OnPacketReady(hci_packetizer_.GetPacket());
+        // Get ready for the next type byte.
+        hci_packet_type_ = PacketType::UNKNOWN;
+      } else {
+        // The data was consumed, but there wasn't a packet.
+        buffer_offset = input_buffer.size();
+      }
+    }
+  }
+}
+
+void H4Protocol::OnDataReady() {
+  if (disconnected_) {
+    return;
+  }
+  uint8_t buffer[kMaxPacketLength];
+  ssize_t bytes_read =
+      TEMP_FAILURE_RETRY(read(uart_fd_, buffer, kMaxPacketLength));
+  if (bytes_read == 0) {
+    ALOGI("No bytes read, calling the disconnect callback");
+    disconnected_ = true;
+    disconnect_cb_();
+    return;
+  }
+  if (bytes_read < 0) {
+    ALOGW("error reading from UART (%s)", strerror(errno));
+    return;
+  }
+  SendDataToPacketizer(buffer, bytes_read);
+}
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/h4_protocol.h b/bluetooth/hci/h4_protocol.h
new file mode 100644
index 0000000..5daee83
--- /dev/null
+++ b/bluetooth/hci/h4_protocol.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <vector>
+
+#include "hci_internals.h"
+#include "hci_packetizer.h"
+
+namespace android::hardware::bluetooth::hci {
+
+using PacketReadCallback = std::function<void(const std::vector<uint8_t>&)>;
+using DisconnectCallback = std::function<void(void)>;
+
+class H4Protocol {
+ public:
+  H4Protocol(int fd, PacketReadCallback cmd_cb, PacketReadCallback acl_cb,
+             PacketReadCallback sco_cb, PacketReadCallback event_cb,
+             PacketReadCallback iso_cb, DisconnectCallback disconnect_cb);
+
+  size_t Send(PacketType type, const uint8_t* data, size_t length);
+  size_t Send(PacketType type, const std::vector<uint8_t>& data);
+
+  void OnDataReady();
+
+ protected:
+  size_t OnPacketReady(const std::vector<uint8_t>& packet);
+  void SendDataToPacketizer(uint8_t* buffer, size_t length);
+
+ private:
+  int uart_fd_;
+  bool disconnected_{false};
+
+  PacketReadCallback cmd_cb_;
+  PacketReadCallback acl_cb_;
+  PacketReadCallback sco_cb_;
+  PacketReadCallback event_cb_;
+  PacketReadCallback iso_cb_;
+  DisconnectCallback disconnect_cb_;
+
+  PacketType hci_packet_type_{PacketType::UNKNOWN};
+  HciPacketizer hci_packetizer_;
+
+  /**
+   * Question : Why read in single chunk rather than multiple reads?
+   * Answer: Using multiple reads does not work with some BT USB dongles.
+   * Reading in single shot gives expected response.
+   * ACL max length is 2 bytes, so using 64K as the buffer length.
+   */
+  static constexpr size_t kMaxPacketLength = 64 * 1024;
+};
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/hci_internals.h b/bluetooth/hci/hci_internals.h
new file mode 100644
index 0000000..71b6191
--- /dev/null
+++ b/bluetooth/hci/hci_internals.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdlib>
+
+namespace android::hardware::bluetooth::hci {
+
+// HCI UART transport packet types (Volume 4, Part A, 2)
+enum class PacketType : uint8_t {
+  UNKNOWN = 0,
+  COMMAND = 1,
+  ACL_DATA = 2,
+  SCO_DATA = 3,
+  EVENT = 4,
+  ISO_DATA = 5,
+};
+
+// 2 bytes for opcode, 1 byte for parameter length (Volume 4, Part E, 5.4.1)
+static constexpr size_t kCommandHeaderSize = 3;
+static constexpr size_t kCommandLengthOffset = 2;
+
+// 2 bytes for handle, 2 bytes for data length (Volume 4, Part E, 5.4.2)
+static constexpr size_t kAclHeaderSize = 4;
+static constexpr size_t kAclLengthOffset = 2;
+
+// 2 bytes for handle, 1 byte for data length (Volume 4, Part E, 5.4.3)
+static constexpr size_t kScoHeaderSize = 3;
+static constexpr size_t kScoLengthOffset = 2;
+
+// 1 byte for event code, 1 byte for parameter length (Volume 4, Part E, 5.4.4)
+static constexpr size_t kEventHeaderSize = 2;
+static constexpr size_t kEventLengthOffset = 1;
+
+// 2 bytes for handle, 2 bytes for data length (Volume 4, Part E, 5.4.5)
+static constexpr size_t kIsoHeaderSize = 4;
+static constexpr size_t kIsoLengthOffset = 2;
+
+static constexpr size_t kMaxHeaderSize = kAclHeaderSize;
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/hci_packetizer.cc b/bluetooth/hci/hci_packetizer.cc
new file mode 100644
index 0000000..5b6c443
--- /dev/null
+++ b/bluetooth/hci/hci_packetizer.cc
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hci_packetizer.h"
+
+#define LOG_TAG "android.hardware.bluetooth.hci-packetizer"
+#include "log/log.h"
+
+namespace android::hardware::bluetooth::hci {
+
+namespace {
+
+const size_t header_size_for_type[] = {0,
+                                       kCommandHeaderSize,
+                                       kAclHeaderSize,
+                                       kScoHeaderSize,
+                                       kEventHeaderSize,
+                                       kIsoHeaderSize};
+const size_t packet_length_offset_for_type[] = {0,
+                                                kCommandLengthOffset,
+                                                kAclLengthOffset,
+                                                kScoLengthOffset,
+                                                kEventLengthOffset,
+                                                kIsoLengthOffset};
+
+size_t HciGetPacketLengthForType(PacketType type,
+                                 const std::vector<uint8_t>& header) {
+  size_t offset = packet_length_offset_for_type[static_cast<uint8_t>(type)];
+  if (type != PacketType::ACL_DATA && type != PacketType::ISO_DATA) {
+    return header[offset];
+  }
+  return (((header[offset + 1]) << 8) | header[offset]);
+}
+
+}  // namespace
+
+const std::vector<uint8_t>& HciPacketizer::GetPacket() const { return packet_; }
+
+bool HciPacketizer::OnDataReady(PacketType packet_type,
+                                const std::vector<uint8_t>& buffer,
+                                size_t offset) {
+  bool packet_completed = false;
+  size_t bytes_available = buffer.size() - offset;
+  switch (state_) {
+    case HCI_HEADER: {
+      size_t header_size =
+          header_size_for_type[static_cast<size_t>(packet_type)];
+      if (bytes_remaining_ == 0) {
+        bytes_remaining_ = header_size;
+        packet_.clear();
+      }
+      size_t bytes_to_copy = std::min(bytes_remaining_, bytes_available);
+      packet_.insert(packet_.end(), buffer.begin() + offset,
+                     buffer.begin() + offset + bytes_to_copy);
+      bytes_remaining_ -= bytes_to_copy;
+      bytes_available -= bytes_to_copy;
+      if (bytes_remaining_ == 0) {
+        bytes_remaining_ = HciGetPacketLengthForType(packet_type, packet_);
+        if (bytes_remaining_ > 0) {
+          state_ = HCI_PAYLOAD;
+          if (bytes_available > 0) {
+            packet_completed =
+                OnDataReady(packet_type, buffer, offset + bytes_to_copy);
+          }
+        } else {
+          packet_completed = true;
+        }
+      }
+      break;
+    }
+
+    case HCI_PAYLOAD: {
+      size_t bytes_to_copy = std::min(bytes_remaining_, bytes_available);
+      packet_.insert(packet_.end(), buffer.begin() + offset,
+                     buffer.begin() + offset + bytes_to_copy);
+      bytes_remaining_ -= bytes_to_copy;
+      if (bytes_remaining_ == 0) {
+        state_ = HCI_HEADER;
+        packet_completed = true;
+      }
+      break;
+    }
+  }
+  return packet_completed;
+}
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/hci_packetizer.h b/bluetooth/hci/hci_packetizer.h
new file mode 100644
index 0000000..ba3e841
--- /dev/null
+++ b/bluetooth/hci/hci_packetizer.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include "hci_internals.h"
+
+namespace android::hardware::bluetooth::hci {
+
+class HciPacketizer {
+ public:
+  HciPacketizer() = default;
+  bool OnDataReady(PacketType packet_type, const std::vector<uint8_t>& data,
+                   size_t offset);
+  const std::vector<uint8_t>& GetPacket() const;
+
+ protected:
+  enum State { HCI_HEADER, HCI_PAYLOAD };
+  State state_{HCI_HEADER};
+  std::vector<uint8_t> packet_;
+  size_t bytes_remaining_{0};
+};
+
+}  // namespace android::hardware::bluetooth::hci
diff --git a/bluetooth/hci/test/h4_protocol_unittest.cc b/bluetooth/hci/test/h4_protocol_unittest.cc
new file mode 100644
index 0000000..d3fab61
--- /dev/null
+++ b/bluetooth/hci/test/h4_protocol_unittest.cc
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "bt_h4_unittest"
+
+#include "h4_protocol.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cstdint>
+#include <cstring>
+#include <future>
+#include <vector>
+
+#include "async_fd_watcher.h"
+#include "log/log.h"
+
+using android::hardware::bluetooth::async::AsyncFdWatcher;
+using namespace android::hardware::bluetooth::hci;
+using ::testing::Eq;
+
+static char sample_data1[100] = "A point is that which has no part.";
+static char sample_data2[100] = "A line is breadthless length.";
+static char sample_data3[100] = "The ends of a line are points.";
+static char sample_data4[100] =
+    "A plane surface is a surface which lies evenly with the straight ...";
+static char acl_data[100] =
+    "A straight line is a line which lies evenly with the points on itself.";
+static char sco_data[100] =
+    "A surface is that which has length and breadth only.";
+static char event_data[100] = "The edges of a surface are lines.";
+static char iso_data[100] =
+    "A plane angle is the inclination to one another of two lines in a ...";
+
+// 5 seconds.  Just don't hang.
+static constexpr size_t kTimeoutMs = 5000;
+
+MATCHER_P3(PacketMatches, header_, header_length, payload,
+           "Match header_length bytes of header and then the payload") {
+  size_t payload_length = strlen(payload);
+  if (header_length + payload_length != arg.size()) {
+    return false;
+  }
+
+  if (memcmp(header_, arg.data(), header_length) != 0) {
+    return false;
+  }
+
+  return memcmp(payload, arg.data() + header_length, payload_length) == 0;
+};
+
+ACTION_P(Notify, barrier) {
+  ALOGD("%s", __func__);
+  barrier->set_value();
+}
+
+class H4ProtocolTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    ALOGD("%s", __func__);
+
+    int sockfd[2];
+    socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
+    chip_uart_fd_ = sockfd[1];
+    stack_uart_fd_ = sockfd[0];
+    h4_hci_ = std::make_shared<H4Protocol>(
+        stack_uart_fd_, cmd_cb_.AsStdFunction(), acl_cb_.AsStdFunction(),
+        sco_cb_.AsStdFunction(), event_cb_.AsStdFunction(),
+        iso_cb_.AsStdFunction(), disconnect_cb_.AsStdFunction());
+  }
+
+  void TearDown() override {
+    close(stack_uart_fd_);
+    close(chip_uart_fd_);
+  }
+
+  virtual void CallDataReady() { h4_hci_->OnDataReady(); }
+
+  void SendAndReadUartOutbound(PacketType type, char* data) {
+    ALOGD("%s sending", __func__);
+    int data_length = strlen(data);
+    h4_hci_->Send(type, (uint8_t*)data, data_length);
+
+    int uart_length = data_length + 1;  // + 1 for data type code
+    int i;
+
+    ALOGD("%s reading", __func__);
+    for (i = 0; i < uart_length; i++) {
+      fd_set read_fds;
+      FD_ZERO(&read_fds);
+      FD_SET(chip_uart_fd_, &read_fds);
+      TEMP_FAILURE_RETRY(
+          select(chip_uart_fd_ + 1, &read_fds, nullptr, nullptr, nullptr));
+
+      char byte;
+      TEMP_FAILURE_RETRY(read(chip_uart_fd_, &byte, 1));
+
+      EXPECT_EQ(i == 0 ? static_cast<uint8_t>(type) : data[i - 1], byte);
+    }
+
+    EXPECT_EQ(i, uart_length);
+  }
+
+  void ExpectInboundAclData(char* payload, std::promise<void>* promise) {
+    // h4 type[1] + handle[2] + size[2]
+    header_[0] = static_cast<uint8_t>(PacketType::ACL_DATA);
+    header_[1] = 19;
+    header_[2] = 92;
+    int length = strlen(payload);
+    header_[3] = length & 0xFF;
+    header_[4] = (length >> 8) & 0xFF;
+    ALOGD("(%d bytes) %s", length, payload);
+
+    EXPECT_CALL(acl_cb_,
+                Call(PacketMatches(header_ + 1, kAclHeaderSize, payload)))
+        .WillOnce(Notify(promise));
+  }
+
+  void WaitForTimeout(std::promise<void>* promise) {
+    auto future = promise->get_future();
+    auto status = future.wait_for(std::chrono::milliseconds(kTimeoutMs));
+    EXPECT_EQ(status, std::future_status::ready);
+  }
+
+  void WriteInboundAclData(char* payload) {
+    // Use the header_ computed in ExpectInboundAclData
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kAclHeaderSize + 1));
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+  }
+
+  void ExpectInboundScoData(char* payload, std::promise<void>* promise) {
+    // h4 type[1] + handle[2] + size[1]
+    header_[0] = static_cast<uint8_t>(PacketType::SCO_DATA);
+    header_[1] = 20;
+    header_[2] = 17;
+    header_[3] = strlen(payload) & 0xFF;
+    EXPECT_CALL(sco_cb_,
+                Call(PacketMatches(header_ + 1, kScoHeaderSize, payload)))
+        .WillOnce(Notify(promise));
+  }
+
+  void WriteInboundScoData(char* payload) {
+    // Use the header_ computed in ExpectInboundScoData
+    ALOGD("%s writing", __func__);
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kScoHeaderSize + 1));
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+  }
+
+  void ExpectInboundEvent(char* payload, std::promise<void>* promise) {
+    // h4 type[1] + event_code[1] + size[1]
+    header_[0] = static_cast<uint8_t>(PacketType::EVENT);
+    header_[1] = 9;
+    header_[2] = strlen(payload) & 0xFF;
+    EXPECT_CALL(event_cb_,
+                Call(PacketMatches(header_ + 1, kEventHeaderSize, payload)))
+        .WillOnce(Notify(promise));
+  }
+
+  void WriteInboundEvent(char* payload) {
+    // Use the header_ computed in ExpectInboundEvent
+    char preamble[3] = {static_cast<uint8_t>(PacketType::EVENT), 9, 0};
+    preamble[2] = strlen(payload) & 0xFF;
+    ALOGD("%s writing", __func__);
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kEventHeaderSize + 1));
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+  }
+
+  void ExpectInboundIsoData(char* payload, std::promise<void>* promise) {
+    // h4 type[1] + handle[2] + size[1]
+    header_[0] = static_cast<uint8_t>(PacketType::ISO_DATA);
+    header_[1] = 19;
+    header_[2] = 92;
+    int length = strlen(payload);
+    header_[3] = length & 0xFF;
+    header_[4] = (length >> 8) & 0x3F;
+
+    EXPECT_CALL(iso_cb_,
+                Call(PacketMatches(header_ + 1, kIsoHeaderSize, payload)))
+        .WillOnce(Notify(promise));
+  }
+
+  void WriteInboundIsoData(char* payload) {
+    // Use the header_ computed in ExpectInboundIsoData
+    ALOGD("%s writing", __func__);
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kIsoHeaderSize + 1));
+    TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+  }
+
+  void WriteAndExpectManyInboundAclDataPackets(char* payload) {
+    size_t kNumPackets = 20;
+    // h4 type[1] + handle[2] + size[2]
+    char preamble[5] = {static_cast<uint8_t>(PacketType::ACL_DATA), 19, 92, 0,
+                        0};
+    int length = strlen(payload);
+    preamble[3] = length & 0xFF;
+    preamble[4] = (length >> 8) & 0xFF;
+
+    EXPECT_CALL(acl_cb_, Call(PacketMatches(preamble + 1, sizeof(preamble) - 1,
+                                            payload)))
+        .Times(kNumPackets);
+
+    for (size_t i = 0; i < kNumPackets; i++) {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, preamble, sizeof(preamble)));
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+    }
+
+    CallDataReady();
+  }
+
+  testing::MockFunction<void(const std::vector<uint8_t>&)> cmd_cb_;
+  testing::MockFunction<void(const std::vector<uint8_t>&)> event_cb_;
+  testing::MockFunction<void(const std::vector<uint8_t>&)> acl_cb_;
+  testing::MockFunction<void(const std::vector<uint8_t>&)> sco_cb_;
+  testing::MockFunction<void(const std::vector<uint8_t>&)> iso_cb_;
+  testing::MockFunction<void(void)> disconnect_cb_;
+  std::shared_ptr<H4Protocol> h4_hci_;
+  int chip_uart_fd_;
+  int stack_uart_fd_;
+
+  char header_[5];
+};
+
+// Test sending data sends correct data onto the UART
+TEST_F(H4ProtocolTest, TestSends) {
+  SendAndReadUartOutbound(PacketType::COMMAND, sample_data1);
+  SendAndReadUartOutbound(PacketType::ACL_DATA, sample_data2);
+  SendAndReadUartOutbound(PacketType::SCO_DATA, sample_data3);
+  SendAndReadUartOutbound(PacketType::ISO_DATA, sample_data4);
+}
+
+// Ensure we properly parse data coming from the UART
+TEST_F(H4ProtocolTest, TestReads) {
+  std::promise<void> acl_promise;
+  std::promise<void> sco_promise;
+  std::promise<void> event_promise;
+  std::promise<void> iso_promise;
+
+  ExpectInboundAclData(acl_data, &acl_promise);
+  WriteInboundAclData(acl_data);
+  CallDataReady();
+  ExpectInboundScoData(sco_data, &sco_promise);
+  WriteInboundScoData(sco_data);
+  CallDataReady();
+  ExpectInboundEvent(event_data, &event_promise);
+  WriteInboundEvent(event_data);
+  CallDataReady();
+  ExpectInboundIsoData(iso_data, &iso_promise);
+  WriteInboundIsoData(iso_data);
+  CallDataReady();
+
+  WaitForTimeout(&acl_promise);
+  WaitForTimeout(&sco_promise);
+  WaitForTimeout(&event_promise);
+  WaitForTimeout(&iso_promise);
+}
+
+TEST_F(H4ProtocolTest, TestMultiplePackets) {
+  WriteAndExpectManyInboundAclDataPackets(sco_data);
+}
+
+TEST_F(H4ProtocolTest, TestDisconnect) {
+  EXPECT_CALL(disconnect_cb_, Call());
+  close(chip_uart_fd_);
+  CallDataReady();
+}
+
+TEST_F(H4ProtocolTest, TestPartialWrites) {
+  size_t payload_len = strlen(acl_data);
+  const size_t kNumIntervals = payload_len + 1;
+  // h4 type[1] + handle[2] + size[2]
+  header_[0] = static_cast<uint8_t>(PacketType::ACL_DATA);
+  header_[1] = 19;
+  header_[2] = 92;
+  header_[3] = payload_len & 0xFF;
+  header_[4] = (payload_len >> 8) & 0xFF;
+
+  EXPECT_CALL(acl_cb_,
+              Call(PacketMatches(header_ + 1, sizeof(header_) - 1, acl_data)))
+      .Times(kNumIntervals);
+
+  for (size_t interval = 1; interval < kNumIntervals + 1; interval++) {
+    // Use the header_ data that expect already set up.
+    if (interval < kAclHeaderSize) {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, interval));
+      CallDataReady();
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_ + interval,
+                               kAclHeaderSize + 1 - interval));
+      CallDataReady();
+    } else {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, header_, kAclHeaderSize + 1));
+      CallDataReady();
+    }
+
+    for (size_t bytes = 0; bytes + interval <= payload_len; bytes += interval) {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, acl_data + bytes, interval));
+      CallDataReady();
+    }
+    size_t extra_bytes = payload_len % interval;
+    if (extra_bytes) {
+      TEMP_FAILURE_RETRY(write(
+          chip_uart_fd_, acl_data + payload_len - extra_bytes, extra_bytes));
+      CallDataReady();
+    }
+  }
+}
+
+class H4ProtocolAsyncTest : public H4ProtocolTest {
+ protected:
+  void SetUp() override {
+    H4ProtocolTest::SetUp();
+    fd_watcher_.WatchFdForNonBlockingReads(
+        stack_uart_fd_, [this](int) { h4_hci_->OnDataReady(); });
+  }
+
+  void TearDown() override { fd_watcher_.StopWatchingFileDescriptors(); }
+
+  void CallDataReady() override {
+    // The Async test can't call data ready.
+    FAIL();
+  }
+
+  void SendAndReadUartOutbound(PacketType type, char* data) {
+    ALOGD("%s sending", __func__);
+    int data_length = strlen(data);
+    h4_hci_->Send(type, (uint8_t*)data, data_length);
+
+    int uart_length = data_length + 1;  // + 1 for data type code
+    int i;
+
+    ALOGD("%s reading", __func__);
+    for (i = 0; i < uart_length; i++) {
+      fd_set read_fds;
+      FD_ZERO(&read_fds);
+      FD_SET(chip_uart_fd_, &read_fds);
+      TEMP_FAILURE_RETRY(
+          select(chip_uart_fd_ + 1, &read_fds, nullptr, nullptr, nullptr));
+
+      char byte;
+      TEMP_FAILURE_RETRY(read(chip_uart_fd_, &byte, 1));
+
+      EXPECT_EQ(i == 0 ? static_cast<uint8_t>(type) : data[i - 1], byte);
+    }
+
+    EXPECT_EQ(i, uart_length);
+  }
+
+  void WriteAndExpectInboundAclData(char* payload) {
+    std::promise<void> promise;
+    ExpectInboundAclData(payload, &promise);
+    WriteInboundAclData(payload);
+    WaitForTimeout(&promise);
+  }
+
+  void WriteAndExpectInboundScoData(char* payload) {
+    std::promise<void> promise;
+    ExpectInboundScoData(payload, &promise);
+    WriteInboundScoData(payload);
+    WaitForTimeout(&promise);
+  }
+
+  void WriteAndExpectInboundEvent(char* payload) {
+    std::promise<void> promise;
+    ExpectInboundEvent(payload, &promise);
+    WriteInboundEvent(payload);
+    WaitForTimeout(&promise);
+  }
+
+  void WriteAndExpectInboundIsoData(char* payload) {
+    std::promise<void> promise;
+    ExpectInboundIsoData(payload, &promise);
+    WriteInboundIsoData(payload);
+    WaitForTimeout(&promise);
+  }
+
+  void WriteAndExpectManyInboundAclDataPackets(char* payload) {
+    const size_t kNumPackets = 20;
+    // h4 type[1] + handle[2] + size[2]
+    char preamble[5] = {static_cast<uint8_t>(PacketType::ACL_DATA), 19, 92, 0,
+                        0};
+    int length = strlen(payload);
+    preamble[3] = length & 0xFF;
+    preamble[4] = (length >> 8) & 0xFF;
+
+    EXPECT_CALL(acl_cb_, Call(PacketMatches(preamble + 1, sizeof(preamble) - 1,
+                                            payload)))
+        .Times(kNumPackets);
+
+    for (size_t i = 0; i < kNumPackets; i++) {
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, preamble, sizeof(preamble)));
+      TEMP_FAILURE_RETRY(write(chip_uart_fd_, payload, strlen(payload)));
+    }
+
+    WriteAndExpectInboundEvent(event_data);
+  }
+
+  AsyncFdWatcher fd_watcher_;
+};
+
+// Test sending data sends correct data onto the UART
+TEST_F(H4ProtocolAsyncTest, TestSends) {
+  SendAndReadUartOutbound(PacketType::COMMAND, sample_data1);
+  SendAndReadUartOutbound(PacketType::ACL_DATA, sample_data2);
+  SendAndReadUartOutbound(PacketType::SCO_DATA, sample_data3);
+  SendAndReadUartOutbound(PacketType::ISO_DATA, sample_data4);
+}
+
+// Ensure we properly parse data coming from the UART
+TEST_F(H4ProtocolAsyncTest, TestReads) {
+  WriteAndExpectInboundAclData(acl_data);
+  WriteAndExpectInboundScoData(sco_data);
+  WriteAndExpectInboundEvent(event_data);
+  WriteAndExpectInboundIsoData(iso_data);
+}
+
+TEST_F(H4ProtocolAsyncTest, TestMultiplePackets) {
+  WriteAndExpectManyInboundAclDataPackets(sco_data);
+}
+
+TEST_F(H4ProtocolAsyncTest, TestDisconnect) {
+  std::promise<void> promise;
+  EXPECT_CALL(disconnect_cb_, Call()).WillOnce(Notify(&promise));
+  close(chip_uart_fd_);
+
+  WaitForTimeout(&promise);
+}
diff --git a/boot/1.1/default/boot_control/Android.bp b/boot/1.1/default/boot_control/Android.bp
index ad71700..6aa30c2 100644
--- a/boot/1.1/default/boot_control/Android.bp
+++ b/boot/1.1/default/boot_control/Android.bp
@@ -25,8 +25,6 @@
 
 cc_defaults {
     name: "libboot_control_defaults",
-    vendor: true,
-    recovery_available: true,
     relative_install_path: "hw",
 
     cflags: [
@@ -42,7 +40,7 @@
         "liblog",
     ],
     static_libs: [
-        "libbootloader_message_vendor",
+        "libbootloader_message",
         "libfstab",
     ],
 }
@@ -51,6 +49,8 @@
     name: "libboot_control",
     defaults: ["libboot_control_defaults"],
     export_include_dirs: ["include"],
+    recovery_available: true,
+    vendor_available: true,
 
     srcs: ["libboot_control.cpp"],
 }
@@ -58,6 +58,8 @@
 cc_library_shared {
     name: "bootctrl.default",
     defaults: ["libboot_control_defaults"],
+    recovery_available: true,
+    vendor_available: true,
 
     srcs: ["legacy_boot_control.cpp"],
 
diff --git a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
index ac17d6d..572a8b6 100644
--- a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
+++ b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
@@ -25,9 +25,8 @@
 
 // Helper library to implement the IBootControl HAL using the misc partition.
 class BootControl {
-  using MergeStatus = ::android::hardware::boot::V1_1::MergeStatus;
-
  public:
+  using MergeStatus = ::android::hardware::boot::V1_1::MergeStatus;
   bool Init();
   unsigned int GetNumberSlots();
   unsigned int GetCurrentSlot();
diff --git a/boot/1.1/default/boot_control/include/private/boot_control_definition.h b/boot/1.1/default/boot_control/include/private/boot_control_definition.h
index 8f02111..57c2f73 100644
--- a/boot/1.1/default/boot_control/include/private/boot_control_definition.h
+++ b/boot/1.1/default/boot_control/include/private/boot_control_definition.h
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#include <stdint.h>
+
+#include <bootloader_message/bootloader_message.h>
 
 /**
  * The A/B-specific bootloader message structure (4-KiB).
diff --git a/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp b/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp
index c38f257..05f136e 100644
--- a/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp
+++ b/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp
@@ -1,4 +1,5 @@
 /*
+
  * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,6 +20,7 @@
 #include <vector>
 
 #include <android-base/logging.h>
+#include <android-base/properties.h>
 #include <android/hardware/boot/1.1/IBootControl.h>
 #include <android/hardware/boot/1.1/types.h>
 #include <gmock/gmock.h>
@@ -37,9 +39,21 @@
 using ::android::hardware::boot::V1_1::MergeStatus;
 using ::testing::Contains;
 
+bool IsVirtualAbEnabled();
+
+#define SKIP_IF_NON_VIRTUAL_AB()                                                        \
+    do {                                                                                \
+        if (!IsVirtualAbEnabled()) GTEST_SKIP() << "Test for Virtual A/B devices only"; \
+    } while (0)
+
+bool IsVirtualAbEnabled() {
+    return android::base::GetBoolProperty("ro.virtual_ab.enabled", false);
+}
+
 class BootHidlTest : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
+        SKIP_IF_NON_VIRTUAL_AB();
         boot = IBootControl::getService(GetParam());
         ASSERT_NE(boot, nullptr);
 
diff --git a/boot/aidl/Android.bp b/boot/aidl/Android.bp
new file mode 100644
index 0000000..c2ba1b6
--- /dev/null
+++ b/boot/aidl/Android.bp
@@ -0,0 +1,48 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.boot",
+    vendor_available: true,
+    srcs: ["android/hardware/boot/*.aidl"],
+    stability: "vintf",
+    recovery_available: true,
+    backend: {
+        java: {
+            sdk_version: "module_current",
+        },
+        cpp: {
+            enabled: false,
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/boot/aidl/aidl_api/android.hardware.boot/1/.hash b/boot/aidl/aidl_api/android.hardware.boot/1/.hash
new file mode 100644
index 0000000..b6f1cb2
--- /dev/null
+++ b/boot/aidl/aidl_api/android.hardware.boot/1/.hash
@@ -0,0 +1 @@
+2400346954240a5de495a1debc81429dd012d7b7
diff --git a/boot/aidl/aidl_api/android.hardware.boot/1/android/hardware/boot/IBootControl.aidl b/boot/aidl/aidl_api/android.hardware.boot/1/android/hardware/boot/IBootControl.aidl
new file mode 100644
index 0000000..0c083f6
--- /dev/null
+++ b/boot/aidl/aidl_api/android.hardware.boot/1/android/hardware/boot/IBootControl.aidl
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.boot;
+@VintfStability
+interface IBootControl {
+  int getActiveBootSlot();
+  int getCurrentSlot();
+  int getNumberSlots();
+  android.hardware.boot.MergeStatus getSnapshotMergeStatus();
+  String getSuffix(in int slot);
+  boolean isSlotBootable(in int slot);
+  boolean isSlotMarkedSuccessful(in int slot);
+  void markBootSuccessful();
+  void setActiveBootSlot(in int slot);
+  void setSlotAsUnbootable(in int slot);
+  void setSnapshotMergeStatus(in android.hardware.boot.MergeStatus status);
+  const int INVALID_SLOT = (-1) /* -1 */;
+  const int COMMAND_FAILED = (-2) /* -2 */;
+}
diff --git a/boot/aidl/aidl_api/android.hardware.boot/1/android/hardware/boot/MergeStatus.aidl b/boot/aidl/aidl_api/android.hardware.boot/1/android/hardware/boot/MergeStatus.aidl
new file mode 100644
index 0000000..cdf3f34
--- /dev/null
+++ b/boot/aidl/aidl_api/android.hardware.boot/1/android/hardware/boot/MergeStatus.aidl
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.boot;
+@Backing(type="int") @VintfStability
+enum MergeStatus {
+  NONE = 0,
+  UNKNOWN,
+  SNAPSHOTTED,
+  MERGING,
+  CANCELLED,
+}
diff --git a/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/IBootControl.aidl b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/IBootControl.aidl
new file mode 100644
index 0000000..c8ab51e
--- /dev/null
+++ b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/IBootControl.aidl
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.boot;
+@VintfStability
+interface IBootControl {
+  int getActiveBootSlot();
+  int getCurrentSlot();
+  int getNumberSlots();
+  android.hardware.boot.MergeStatus getSnapshotMergeStatus();
+  String getSuffix(in int slot);
+  boolean isSlotBootable(in int slot);
+  boolean isSlotMarkedSuccessful(in int slot);
+  void markBootSuccessful();
+  void setActiveBootSlot(in int slot);
+  void setSlotAsUnbootable(in int slot);
+  void setSnapshotMergeStatus(in android.hardware.boot.MergeStatus status);
+  const int INVALID_SLOT = -1;
+  const int COMMAND_FAILED = -2;
+}
diff --git a/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/MergeStatus.aidl b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/MergeStatus.aidl
new file mode 100644
index 0000000..53c6204
--- /dev/null
+++ b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/MergeStatus.aidl
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.boot;
+@Backing(type="int") @VintfStability
+enum MergeStatus {
+  NONE = 0,
+  UNKNOWN = 1,
+  SNAPSHOTTED = 2,
+  MERGING = 3,
+  CANCELLED = 4,
+}
diff --git a/boot/aidl/android/hardware/boot/IBootControl.aidl b/boot/aidl/android/hardware/boot/IBootControl.aidl
new file mode 100644
index 0000000..6c9e8ce
--- /dev/null
+++ b/boot/aidl/android/hardware/boot/IBootControl.aidl
@@ -0,0 +1,158 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package android.hardware.boot;
+
+import android.hardware.boot.MergeStatus;
+
+@VintfStability
+interface IBootControl {
+    const int INVALID_SLOT = -1;
+    const int COMMAND_FAILED = -2;
+    /**
+     * Returns the active slot to boot into on the next boot. If
+     * setActiveBootSlot() has been called, the getter function should return the
+     * same slot as the one provided in the last setActiveBootSlot() call.
+     * The returned value is always guaranteed to be strictly less than the
+     * value returned by getNumberSlots. Slots start at 0 and finish at
+     * getNumberSlots() - 1. For instance, a system with A/B must return 0 or 1.
+     * @return the active slot to boot into on the next boot.
+     */
+    int getActiveBootSlot();
+
+    /**
+     * getCurrentSlot() returns the slot number of that the current boot is booted
+     * from, for example slot number 0 (Slot A). It is assumed that if the current
+     * slot is A, then the block devices underlying B can be accessed directly
+     * without any risk of corruption.
+     * The returned value is always guaranteed to be strictly less than the
+     * value returned by getNumberSlots. Slots start at 0 and finish at
+     * getNumberSlots() - 1. The value returned here must match the suffix passed
+     * from the bootloader, regardless of which slot is active or successful.
+     * @return the slot number of that the current boot is booted
+     */
+    int getCurrentSlot();
+
+    /**
+     * getNumberSlots() returns the number of available slots.
+     * For instance, a system with a single set of partitions must return
+     * 1, a system with A/B must return 2, A/B/C -> 3 and so on. A system with
+     * less than two slots doesn't support background updates, for example if
+     * running from a virtual machine with only one copy of each partition for the
+     * purpose of testing.
+     * @return number of available slots
+     */
+    int getNumberSlots();
+
+    /**
+     * Returns whether a snapshot-merge of any dynamic partition is in progress.
+     *
+     * This function must return the merge status set by the last setSnapshotMergeStatus call and
+     * recorded by the bootloader with one exception. If the partitions are being flashed from the
+     * bootloader such that the pending merge must be canceled (for example, if the super partition
+     * is being flashed), this function must return CANCELLED.
+     *
+     * @param out success True if the merge status is read successfully, false otherwise.
+     * @return Merge status.
+     */
+    MergeStatus getSnapshotMergeStatus();
+
+    /**
+     * getSuffix() returns the string suffix used by partitions that correspond to
+     * the slot number passed in as a parameter. The bootloader must pass the
+     * suffix of the currently active slot either through a kernel command line
+     * property at androidboot.slot_suffix, or the device tree at
+     * /firmware/android/slot_suffix.
+     * @return suffix for the input slot, or the empty string "" if slot
+     * does not match an existing slot.
+     */
+    String getSuffix(in int slot);
+
+    /**
+     * isSlotBootable() returns if the slot passed in parameter is bootable. Note
+     * that slots can be made unbootable by both the bootloader and by the OS
+     * using setSlotAsUnbootable.
+     * @return true if the slot is bootable, false if it's not.
+     * @throws service specific error INVALID_SLOT if slot is invalid.
+     */
+    boolean isSlotBootable(in int slot);
+
+    /**
+     * isSlotMarkedSuccessful() returns if the slot passed in parameter has been
+     * marked as successful using markBootSuccessful. Note that only the current
+     * slot can be marked as successful but any slot can be queried.
+     * @return true if the slot has been marked as successful, false if it has
+     * not.
+     * @throws service specific error INVALID_SLOT if slot is invalid.
+     */
+    boolean isSlotMarkedSuccessful(in int slot);
+
+    /**
+     * markBootSuccessful() marks the current slot as having booted successfully.
+     *
+     * @throws Service specific error COMMAND_FAILED if command failed.
+     */
+    void markBootSuccessful();
+
+    /**
+     * setActiveBootSlot() marks the slot passed in parameter as the active boot
+     * slot (see getCurrentSlot for an explanation of the "slot" parameter). This
+     * overrides any previous call to setSlotAsUnbootable.
+     * @throws Service specific error INVALID_SLOT if slot is invalid, or COMMAND_FAILED if
+     * operation failed.
+     */
+    void setActiveBootSlot(in int slot);
+
+    /**
+     * setSlotAsUnbootable() marks the slot passed in parameter as
+     * an unbootable. This can be used while updating the contents of the slot's
+     * partitions, so that the system must not attempt to boot a known bad set up.
+     * @throws Service specific error INVALID_SLOT if slot is invalid, or COMMAND_FAILED if
+     * operation failed.
+     */
+    void setSlotAsUnbootable(in int slot);
+
+    /**
+     * Sets whether a snapshot-merge of any dynamic partition is in progress.
+     *
+     * After the merge status is set to a given value, subsequent calls to
+     * getSnapshotMergeStatus must return the set value.
+     *
+     * The merge status must be persistent across reboots. That is, getSnapshotMergeStatus
+     * must return the same value after a reboot if the merge status is not altered in any way
+     * (e.g. set by setSnapshotMergeStatus or set to CANCELLED by bootloader).
+     *
+     * Read/write access to the merge status must be atomic. When the HAL is processing a
+     * setSnapshotMergeStatus call, all subsequent calls to getSnapshotMergeStatus must block until
+     * setSnapshotMergeStatus has returned.
+     *
+     * A MERGING state indicates that dynamic partitions are partially comprised by blocks in the
+     * userdata partition.
+     *
+     * When the merge status is set to MERGING, the following operations must be prohibited from the
+     * bootloader:
+     *  - Flashing or erasing "userdata" or "metadata".
+     *
+     * The following operations may be prohibited when the status is set to MERGING. If not
+     * prohibited, it is recommended that the user receive a warning.
+     *  - Changing the active slot (e.g. via "fastboot set_active")
+     *
+     * @param status Merge status.
+     *
+     * @throws service specific error COMMAND_FAILED if operation failed.
+     */
+    void setSnapshotMergeStatus(in MergeStatus status);
+}
diff --git a/boot/aidl/android/hardware/boot/MergeStatus.aidl b/boot/aidl/android/hardware/boot/MergeStatus.aidl
new file mode 100644
index 0000000..16ac85f
--- /dev/null
+++ b/boot/aidl/android/hardware/boot/MergeStatus.aidl
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package android.hardware.boot;
+
+@VintfStability
+@Backing(type="int")
+enum MergeStatus {
+    /**
+     * No snapshot or merge is in progress.
+     */
+    NONE = 0,
+    /**
+     * The merge status could not be determined.
+     */
+    UNKNOWN,
+    /**
+     * Partitions are being snapshotted, but no merge has been started.
+     */
+    SNAPSHOTTED,
+    /**
+     * At least one partition has merge is in progress.
+     */
+    MERGING,
+    /**
+     * A merge was in progress, but it was canceled by the bootloader.
+     */
+    CANCELLED,
+}
diff --git a/boot/aidl/client/Android.bp b/boot/aidl/client/Android.bp
new file mode 100644
index 0000000..db4a7ea
--- /dev/null
+++ b/boot/aidl/client/Android.bp
@@ -0,0 +1,31 @@
+
+
+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 {
+    name: "libboot_control_client",
+    srcs: [
+        "BootControlClient.cpp"
+    ],
+    export_include_dirs: ["include"],
+    export_shared_lib_headers: ["android.hardware.boot-V1-ndk"],
+    recovery_available: true,
+    shared_libs: [
+        "android.hardware.boot-V1-ndk",
+        "android.hardware.boot@1.0",
+        "android.hardware.boot@1.1",
+        "android.hardware.boot@1.2",
+        "libhidlbase",
+        "libbinder_ndk",
+        "libbase",
+        "libcutils",
+        "libutils",
+    ],
+}
diff --git a/boot/aidl/client/BootControlClient.cpp b/boot/aidl/client/BootControlClient.cpp
new file mode 100644
index 0000000..89258d2
--- /dev/null
+++ b/boot/aidl/client/BootControlClient.cpp
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <BootControlClient.h>
+
+#include <aidl/android/hardware/boot/IBootControl.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/hardware/boot/1.0/IBootControl.h>
+#include <android/hardware/boot/1.1/IBootControl.h>
+#include <android/hardware/boot/1.2/IBootControl.h>
+#include "utils/StrongPointer.h"
+
+#define CONCAT(x, y) x##y
+
+#define LOG_NDK_STATUS(x)                                                                   \
+    do {                                                                                    \
+        const auto CONCAT(status, __COUNTER__) = x;                                         \
+        if (!CONCAT(status, __COUNTER__).isOk()) {                                          \
+            LOG(ERROR) << #x << " failed " << CONCAT(status, __COUNTER__).getDescription(); \
+        }                                                                                   \
+    } while (0)
+
+using aidl::android::hardware::boot::MergeStatus;
+
+std::ostream& operator<<(std::ostream& os, MergeStatus status) {
+    switch (status) {
+        case MergeStatus::NONE:
+            os << "MergeStatus::NONE";
+            break;
+        case MergeStatus::UNKNOWN:
+            os << "MergeStatus::UNKNOWN";
+            break;
+        case MergeStatus::SNAPSHOTTED:
+            os << "MergeStatus::SNAPSHOTTED";
+            break;
+        case MergeStatus::MERGING:
+            os << "MergeStatus::MERGING";
+            break;
+        case MergeStatus::CANCELLED:
+            os << "MergeStatus::CANCELLED";
+            break;
+        default:
+            os << static_cast<int>(status);
+            break;
+    }
+    return os;
+}
+
+namespace android::hal {
+class BootControlClientAidl final : public BootControlClient {
+    using IBootControl = ::aidl::android::hardware::boot::IBootControl;
+
+  public:
+    BootControlClientAidl(std::shared_ptr<IBootControl> module) : module_(module) {}
+
+    BootControlVersion GetVersion() const override { return BootControlVersion::BOOTCTL_AIDL; }
+
+    ~BootControlClientAidl() = default;
+    virtual int32_t GetNumSlots() const {
+        int32_t ret = -1;
+        LOG_NDK_STATUS(module_->getNumberSlots(&ret));
+        return ret;
+    }
+
+    int32_t GetCurrentSlot() const {
+        int32_t ret = -1;
+        LOG_NDK_STATUS(module_->getCurrentSlot(&ret));
+        return ret;
+    }
+    MergeStatus getSnapshotMergeStatus() const {
+        MergeStatus status = MergeStatus::UNKNOWN;
+        LOG_NDK_STATUS(module_->getSnapshotMergeStatus(&status));
+        return status;
+    }
+    std::string GetSuffix(int32_t slot) const {
+        std::string ret;
+        const auto status = module_->getSuffix(slot, &ret);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+            return {};
+        }
+        return ret;
+    }
+
+    std::optional<bool> IsSlotBootable(int32_t slot) const {
+        bool ret = false;
+        const auto status = module_->isSlotBootable(slot, &ret);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+            return {};
+        }
+        return ret;
+    }
+
+    CommandResult MarkSlotUnbootable(int32_t slot) {
+        const auto status = module_->setSlotAsUnbootable(slot);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+        }
+        return {.success = status.isOk(), .errMsg = status.getDescription()};
+    }
+
+    CommandResult SetActiveBootSlot(int slot) {
+        const auto status = module_->setActiveBootSlot(slot);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+        }
+        return {.success = status.isOk(), .errMsg = status.getDescription()};
+    }
+    int GetActiveBootSlot() const {
+        int ret = -1;
+        LOG_NDK_STATUS(module_->getActiveBootSlot(&ret));
+        return ret;
+    }
+
+    // Check if |slot| is marked boot successfully.
+    std::optional<bool> IsSlotMarkedSuccessful(int slot) const {
+        bool ret = false;
+        const auto status = module_->isSlotMarkedSuccessful(slot, &ret);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+            return {};
+        }
+        return ret;
+    }
+
+    CommandResult MarkBootSuccessful() {
+        const auto status = module_->markBootSuccessful();
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << status.getDescription();
+        }
+        return {.success = status.isOk(), .errMsg = status.getDescription()};
+    }
+
+    CommandResult SetSnapshotMergeStatus(aidl::android::hardware::boot::MergeStatus merge_status) {
+        const auto status = module_->setSnapshotMergeStatus(merge_status);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")"
+                       << " failed " << status.getDescription();
+        }
+        return {.success = status.isOk(), .errMsg = status.getDescription()};
+    }
+
+  private:
+    const std::shared_ptr<IBootControl> module_;
+};
+
+using namespace android::hardware::boot;
+
+class BootControlClientHIDL final : public BootControlClient {
+  public:
+    BootControlClientHIDL(android::sp<V1_0::IBootControl> module_v1,
+                          android::sp<V1_1::IBootControl> module_v1_1,
+                          android::sp<V1_2::IBootControl> module_v1_2)
+        : module_v1_(module_v1), module_v1_1_(module_v1_1), module_v1_2_(module_v1_2) {
+        CHECK(module_v1_ != nullptr);
+    }
+    BootControlVersion GetVersion() const override {
+        if (module_v1_2_ != nullptr) {
+            return BootControlVersion::BOOTCTL_V1_2;
+        } else if (module_v1_1_ != nullptr) {
+            return BootControlVersion::BOOTCTL_V1_1;
+        } else {
+            return BootControlVersion::BOOTCTL_V1_0;
+        }
+    }
+    int32_t GetNumSlots() const {
+        const auto ret = module_v1_->getNumberSlots();
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return ret.withDefault(-1);
+    }
+
+    int32_t GetCurrentSlot() const {
+        const auto ret = module_v1_->getCurrentSlot();
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return ret.withDefault(-1);
+    }
+
+    std::string GetSuffix(int32_t slot) const {
+        std::string suffix;
+        const auto ret = module_v1_->getSuffix(
+                slot,
+                [&](const ::android::hardware::hidl_string& slotSuffix) { suffix = slotSuffix; });
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+        }
+        return suffix;
+    }
+
+    std::optional<bool> IsSlotBootable(int32_t slot) const {
+        const auto ret = module_v1_->isSlotBootable(slot);
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+            return {};
+        }
+        const auto bool_result = ret.withDefault(V1_0::BoolResult::INVALID_SLOT);
+        if (bool_result == V1_0::BoolResult::INVALID_SLOT) {
+            return {};
+        }
+        return bool_result == V1_0::BoolResult::TRUE;
+    }
+
+    CommandResult MarkSlotUnbootable(int32_t slot) {
+        CommandResult result;
+        const auto ret =
+                module_v1_->setSlotAsUnbootable(slot, [&](const V1_0::CommandResult& error) {
+                    result.success = error.success;
+                    result.errMsg = error.errMsg;
+                });
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+        }
+        return result;
+    }
+
+    CommandResult SetActiveBootSlot(int32_t slot) {
+        CommandResult result;
+        const auto ret = module_v1_->setActiveBootSlot(slot, [&](const V1_0::CommandResult& error) {
+            result.success = error.success;
+            result.errMsg = error.errMsg;
+        });
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+        }
+        return result;
+    }
+
+    CommandResult MarkBootSuccessful() {
+        CommandResult result;
+        const auto ret = module_v1_->markBootSuccessful([&](const V1_0::CommandResult& error) {
+            result.success = error.success;
+            result.errMsg = error.errMsg;
+        });
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return result;
+    }
+
+    std::optional<bool> IsSlotMarkedSuccessful(int32_t slot) const {
+        const auto ret = module_v1_->isSlotMarkedSuccessful(slot);
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+            return {};
+        }
+        const auto bool_result = ret.withDefault(V1_0::BoolResult::INVALID_SLOT);
+        if (bool_result == V1_0::BoolResult::INVALID_SLOT) {
+            return {};
+        }
+        return bool_result == V1_0::BoolResult::TRUE;
+    }
+
+    MergeStatus getSnapshotMergeStatus() const {
+        if (module_v1_1_ == nullptr) {
+            LOG(ERROR) << __FUNCTION__ << " is unsupported, requires at least boot v1.1";
+            return MergeStatus::UNKNOWN;
+        }
+        const auto ret = module_v1_1_->getSnapshotMergeStatus();
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return static_cast<MergeStatus>(
+                ret.withDefault(static_cast<V1_1::MergeStatus>(MergeStatus::UNKNOWN)));
+    }
+
+    CommandResult SetSnapshotMergeStatus(MergeStatus merge_status) {
+        if (module_v1_1_ == nullptr) {
+            return {.success = false,
+                    .errMsg = "setSnapshotMergeStatus is unsupported, requires at least boot v1.1"};
+        }
+        const auto ret =
+                module_v1_1_->setSnapshotMergeStatus(static_cast<V1_1::MergeStatus>(merge_status));
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")"
+                       << " failed " << ret.description();
+        }
+        return {.success = ret.isOk(), .errMsg = ret.description()};
+    }
+
+    int32_t GetActiveBootSlot() const {
+        if (module_v1_2_ == nullptr) {
+            LOG(ERROR) << __FUNCTION__ << " is unsupported, requires at least boot v1.2";
+            return -1;
+        }
+        const auto ret = module_v1_2_->getActiveBootSlot();
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return ret.withDefault(-1);
+    }
+
+  private:
+    android::sp<V1_0::IBootControl> module_v1_;
+    android::sp<V1_1::IBootControl> module_v1_1_;
+    android::sp<V1_2::IBootControl> module_v1_2_;
+};
+
+std::unique_ptr<BootControlClient> BootControlClient::WaitForService() {
+    const auto instance_name =
+            std::string(::aidl::android::hardware::boot::IBootControl::descriptor) + "/default";
+
+    if (AServiceManager_isDeclared(instance_name.c_str())) {
+        auto module = ::aidl::android::hardware::boot::IBootControl::fromBinder(
+                ndk::SpAIBinder(AServiceManager_waitForService(instance_name.c_str())));
+        if (module == nullptr) {
+            LOG(ERROR) << "AIDL " << instance_name
+                       << " is declared but waitForService returned nullptr.";
+            return nullptr;
+        }
+        LOG(INFO) << "Using AIDL version of IBootControl";
+        return std::make_unique<BootControlClientAidl>(module);
+    }
+    LOG(INFO) << "AIDL IBootControl not available, falling back to HIDL.";
+
+    android::sp<V1_0::IBootControl> v1_0_module;
+    android::sp<V1_1::IBootControl> v1_1_module;
+    android::sp<V1_2::IBootControl> v1_2_module;
+    v1_0_module = V1_0::IBootControl::getService();
+    if (v1_0_module == nullptr) {
+        LOG(ERROR) << "Error getting bootctrl v1.0 module.";
+        return nullptr;
+    }
+    v1_1_module = V1_1::IBootControl::castFrom(v1_0_module);
+    v1_2_module = V1_2::IBootControl::castFrom(v1_0_module);
+    if (v1_2_module != nullptr) {
+        LOG(INFO) << "Using HIDL version 1.2 of IBootControl";
+    } else if (v1_1_module != nullptr) {
+        LOG(INFO) << "Using HIDL version 1.1 of IBootControl";
+    } else {
+        LOG(INFO) << "Using HIDL version 1.0 of IBootControl";
+    }
+
+    return std::make_unique<BootControlClientHIDL>(v1_0_module, v1_1_module, v1_2_module);
+}
+
+}  // namespace android::hal
diff --git a/boot/aidl/client/include/BootControlClient.h b/boot/aidl/client/include/BootControlClient.h
new file mode 100644
index 0000000..472e82e
--- /dev/null
+++ b/boot/aidl/client/include/BootControlClient.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BOOT_CONTROL_CLIENT_H_
+#define __BOOT_CONTROL_CLIENT_H_
+
+#include <aidl/android/hardware/boot/MergeStatus.h>
+
+#include <stdint.h>
+
+#include <memory>
+#include <optional>
+
+namespace android::hal {
+
+struct CommandResult {
+    bool success;
+    std::string errMsg;
+    constexpr bool IsOk() const { return success; }
+};
+
+enum class BootControlVersion { BOOTCTL_V1_0, BOOTCTL_V1_1, BOOTCTL_V1_2, BOOTCTL_AIDL };
+
+class BootControlClient {
+  public:
+    using MergeStatus = aidl::android::hardware::boot::MergeStatus;
+    virtual ~BootControlClient() = default;
+    virtual BootControlVersion GetVersion() const = 0;
+    // Return the number of update slots in the system. A system will normally
+    // have two slots, named "A" and "B" in the documentation, but sometimes
+    // images running from other media can have only one slot, like some USB
+    // image. Systems with only one slot won't be able to update.
+    [[nodiscard]] virtual int32_t GetNumSlots() const = 0;
+
+    // Return the slot where we are running the system from. On success, the
+    // result is a number between 0 and GetNumSlots() - 1. Otherwise, log an error
+    // and return kInvalidSlot.
+    [[nodiscard]] virtual int32_t GetCurrentSlot() const = 0;
+
+    // Return string suffix for input slot. Usually, for slot 0 the suffix is _a, and for slot 1 the
+    // suffix is _b.
+    [[nodiscard]] virtual std::string GetSuffix(int32_t slot) const = 0;
+
+    // Returns whether the passed |slot| is marked as bootable. Returns false if
+    // the slot is invalid.
+    [[nodiscard]] virtual std::optional<bool> IsSlotBootable(int32_t slot) const = 0;
+
+    // Mark the specified slot unbootable. No other slot flags are modified.
+    // Returns true on success.
+    [[nodiscard]] virtual CommandResult MarkSlotUnbootable(int32_t slot) = 0;
+
+    // Set the passed |slot| as the preferred boot slot. Returns whether it
+    // succeeded setting the active slot. If succeeded, on next boot the
+    // bootloader will attempt to load the |slot| marked as active. Note that this
+    // method doesn't change the value of GetCurrentSlot() on the current boot.
+    // Return true if operation succeeded.
+    [[nodiscard]] virtual CommandResult SetActiveBootSlot(int32_t slot) = 0;
+
+    // Check if |slot| is marked boot successfully. Return empty optional if the RPC call failed.
+    [[nodiscard]] virtual std::optional<bool> IsSlotMarkedSuccessful(int32_t slot) const = 0;
+
+    // Mark boot as successful. Return an error message if operation failed.
+    [[nodiscard]] virtual CommandResult MarkBootSuccessful() = 0;
+
+    // Added in IBootControl v1.1
+    // Return the current merge status.
+    [[nodiscard]] virtual MergeStatus getSnapshotMergeStatus() const = 0;
+
+    // Set snapshot merge status, return true if succeeded.
+    [[nodiscard]] virtual CommandResult SetSnapshotMergeStatus(MergeStatus status) = 0;
+
+    // Added in IBootControl v1.2
+    // Get the active slot. In other words, the slot which will be used on
+    // next system reboot. This should match the |slot| parameter of last
+    // successful call to |SetActiveBootSlot|.
+    // Return 0xFFFFFFFF if underlying HAL doesn't support this operation.
+    [[nodiscard]] virtual int32_t GetActiveBootSlot() const = 0;
+
+    [[nodiscard]] static std::unique_ptr<BootControlClient> WaitForService();
+};
+
+}  // namespace android::hal
+
+#endif
diff --git a/boot/aidl/default/Android.bp b/boot/aidl/default/Android.bp
new file mode 100644
index 0000000..dcb40db
--- /dev/null
+++ b/boot/aidl/default/Android.bp
@@ -0,0 +1,55 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+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_defaults {
+    name: "android.hardware.boot-service_common",
+    relative_install_path: "hw",
+    defaults: ["libboot_control_defaults"],
+    vintf_fragments: ["android.hardware.boot-service.default.xml"],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.boot@1.1",
+        "android.hardware.boot-V1-ndk",
+    ],
+    static_libs: [
+        "libboot_control",
+    ],
+    srcs: ["main.cpp", "BootControl.cpp"],
+}
+
+cc_binary {
+    name: "android.hardware.boot-service.default",
+    defaults: ["android.hardware.boot-service_common"],
+    init_rc: ["android.hardware.boot-service.default.rc"],
+    vendor: true,
+}
+
+cc_binary {
+    name: "android.hardware.boot-service.default_recovery",
+    defaults: ["android.hardware.boot-service_common"],
+    init_rc: ["android.hardware.boot-service.default_recovery.rc"],
+    recovery: true,
+}
diff --git a/boot/aidl/default/BootControl.cpp b/boot/aidl/default/BootControl.cpp
new file mode 100644
index 0000000..b73c94d
--- /dev/null
+++ b/boot/aidl/default/BootControl.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BootControl.h"
+#include <cstdint>
+
+#include <android-base/logging.h>
+
+using HIDLMergeStatus = ::android::bootable::BootControl::MergeStatus;
+using ndk::ScopedAStatus;
+
+namespace aidl::android::hardware::boot {
+
+BootControl::BootControl() {
+    CHECK(impl_.Init());
+}
+
+ScopedAStatus BootControl::getActiveBootSlot(int32_t* _aidl_return) {
+    *_aidl_return = impl_.GetActiveBootSlot();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::getCurrentSlot(int32_t* _aidl_return) {
+    *_aidl_return = impl_.GetCurrentSlot();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::getNumberSlots(int32_t* _aidl_return) {
+    *_aidl_return = impl_.GetNumberSlots();
+    return ScopedAStatus::ok();
+}
+
+namespace {
+
+static constexpr MergeStatus ToAIDLMergeStatus(HIDLMergeStatus status) {
+    switch (status) {
+        case HIDLMergeStatus::NONE:
+            return MergeStatus::NONE;
+        case HIDLMergeStatus::UNKNOWN:
+            return MergeStatus::UNKNOWN;
+        case HIDLMergeStatus::SNAPSHOTTED:
+            return MergeStatus::SNAPSHOTTED;
+        case HIDLMergeStatus::MERGING:
+            return MergeStatus::MERGING;
+        case HIDLMergeStatus::CANCELLED:
+            return MergeStatus::CANCELLED;
+    }
+}
+
+static constexpr HIDLMergeStatus ToHIDLMergeStatus(MergeStatus status) {
+    switch (status) {
+        case MergeStatus::NONE:
+            return HIDLMergeStatus::NONE;
+        case MergeStatus::UNKNOWN:
+            return HIDLMergeStatus::UNKNOWN;
+        case MergeStatus::SNAPSHOTTED:
+            return HIDLMergeStatus::SNAPSHOTTED;
+        case MergeStatus::MERGING:
+            return HIDLMergeStatus::MERGING;
+        case MergeStatus::CANCELLED:
+            return HIDLMergeStatus::CANCELLED;
+    }
+}
+
+}
+
+ScopedAStatus BootControl::getSnapshotMergeStatus(MergeStatus* _aidl_return) {
+    *_aidl_return = ToAIDLMergeStatus(impl_.GetSnapshotMergeStatus());
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::getSuffix(int32_t in_slot, std::string* _aidl_return) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        // Old HIDL hal returns empty string for invalid slots. We should maintain this behavior in
+        // AIDL for compatibility.
+        _aidl_return->clear();
+    } else {
+        *_aidl_return = impl_.GetSuffix(in_slot);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::isSlotBootable(int32_t in_slot, bool* _aidl_return) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
+    }
+    *_aidl_return = impl_.IsSlotBootable(in_slot);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
+    }
+    *_aidl_return = impl_.IsSlotMarkedSuccessful(in_slot);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::markBootSuccessful() {
+    if (!impl_.MarkBootSuccessful()) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
+                                                                  "Operation failed");
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::setActiveBootSlot(int32_t in_slot) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
+    }
+    if (!impl_.SetActiveBootSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
+                                                                  "Operation failed");
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::setSlotAsUnbootable(int32_t in_slot) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
+    }
+    if (!impl_.SetSlotAsUnbootable(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
+                                                                  "Operation failed");
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::setSnapshotMergeStatus(MergeStatus in_status) {
+    if (!impl_.SetSnapshotMergeStatus(ToHIDLMergeStatus(in_status))) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
+                                                                  "Operation failed");
+    }
+    return ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::boot
diff --git a/boot/aidl/default/BootControl.h b/boot/aidl/default/BootControl.h
new file mode 100644
index 0000000..54cd32d
--- /dev/null
+++ b/boot/aidl/default/BootControl.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/boot/BnBootControl.h>
+#include <libboot_control/libboot_control.h>
+
+namespace aidl::android::hardware::boot {
+
+class BootControl final : public BnBootControl {
+  public:
+    BootControl();
+    ::ndk::ScopedAStatus getActiveBootSlot(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getCurrentSlot(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getNumberSlots(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getSnapshotMergeStatus(
+            ::aidl::android::hardware::boot::MergeStatus* _aidl_return) override;
+    ::ndk::ScopedAStatus getSuffix(int32_t in_slot, std::string* _aidl_return) override;
+    ::ndk::ScopedAStatus isSlotBootable(int32_t in_slot, bool* _aidl_return) override;
+    ::ndk::ScopedAStatus isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) override;
+    ::ndk::ScopedAStatus markBootSuccessful() override;
+    ::ndk::ScopedAStatus setActiveBootSlot(int32_t in_slot) override;
+    ::ndk::ScopedAStatus setSlotAsUnbootable(int32_t in_slot) override;
+    ::ndk::ScopedAStatus setSnapshotMergeStatus(
+            ::aidl::android::hardware::boot::MergeStatus in_status) override;
+
+  private:
+    ::android::bootable::BootControl impl_;
+};
+
+}  // namespace aidl::android::hardware::boot
diff --git a/boot/aidl/default/android.hardware.boot-service.default.rc b/boot/aidl/default/android.hardware.boot-service.default.rc
new file mode 100644
index 0000000..589f803
--- /dev/null
+++ b/boot/aidl/default/android.hardware.boot-service.default.rc
@@ -0,0 +1,5 @@
+service vendor.boot-default /vendor/bin/hw/android.hardware.boot-service.default
+    class early_hal
+    user root
+    group root
+
diff --git a/boot/aidl/default/android.hardware.boot-service.default.xml b/boot/aidl/default/android.hardware.boot-service.default.xml
new file mode 100644
index 0000000..23ccc4e
--- /dev/null
+++ b/boot/aidl/default/android.hardware.boot-service.default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.boot</name>
+        <fqname>IBootControl/default</fqname>
+    </hal>
+</manifest>
diff --git a/boot/aidl/default/android.hardware.boot-service.default_recovery.rc b/boot/aidl/default/android.hardware.boot-service.default_recovery.rc
new file mode 100644
index 0000000..cb08a39
--- /dev/null
+++ b/boot/aidl/default/android.hardware.boot-service.default_recovery.rc
@@ -0,0 +1,7 @@
+service vendor.boot-default /system/bin/hw/android.hardware.boot-service.default_recovery
+    class early_hal
+    user root
+    group root
+    seclabel u:r:hal_bootctl_default:s0
+    interface aidl android.hardware.boot.IBootControl/default
+
diff --git a/boot/aidl/default/main.cpp b/boot/aidl/default/main.cpp
new file mode 100644
index 0000000..70b284e
--- /dev/null
+++ b/boot/aidl/default/main.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BootControl.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::boot::BootControl;
+using aidl::android::hardware::boot::IBootControl;
+
+int main(int, char* argv[]) {
+    android::base::InitLogging(argv, android::base::KernelLogger);
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<IBootControl> service = ndk::SharedRefBase::make<BootControl>();
+
+    const std::string instance = std::string(BootControl::descriptor) + "/default";
+    auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status;
+    LOG(INFO) << "IBootControl AIDL service running...";
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/boot/aidl/vts/functional/Android.bp b/boot/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..e46cbef
--- /dev/null
+++ b/boot/aidl/vts/functional/Android.bp
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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_test {
+    name: "VtsHalBootAidlTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static"
+    ],
+    srcs: ["VtsHalBootAidlTargetTest.cpp"],
+    static_libs: [
+        "android.hardware.boot-V1-ndk",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libvintf",
+    ],
+    test_suites: ["general-tests", "vts"],
+}
diff --git a/boot/aidl/vts/functional/OWNERS b/boot/aidl/vts/functional/OWNERS
new file mode 100644
index 0000000..bc813d8
--- /dev/null
+++ b/boot/aidl/vts/functional/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 30545
+zhangkelvin@google.com
diff --git a/boot/aidl/vts/functional/VtsHalBootAidlTargetTest.cpp b/boot/aidl/vts/functional/VtsHalBootAidlTargetTest.cpp
new file mode 100644
index 0000000..93c8376
--- /dev/null
+++ b/boot/aidl/vts/functional/VtsHalBootAidlTargetTest.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <cutils/properties.h>
+
+#include <aidl/android/hardware/boot/IBootControl.h>
+
+#include <aidl/Vintf.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include <unordered_set>
+
+using aidl::android::hardware::boot::IBootControl;
+using std::string;
+using std::unordered_set;
+
+// The main test class for the Boot HIDL HAL.
+class BootAidlTest : public ::testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        const auto instance_name = GetParam();
+        ASSERT_TRUE(AServiceManager_isDeclared(instance_name.c_str()))
+                << " instance " << instance_name << " not declared.";
+        boot = ::aidl::android::hardware::boot::IBootControl::fromBinder(
+                ndk::SpAIBinder(AServiceManager_waitForService(instance_name.c_str())));
+        ASSERT_NE(boot, nullptr);
+    }
+
+    std::shared_ptr<IBootControl> boot;
+};
+
+// validity check Boot::getNumberSlots().
+TEST_P(BootAidlTest, GetNumberSlots) {
+    int32_t slots{};
+    boot->getNumberSlots(&slots);
+    ASSERT_LE(2, slots);
+}
+
+// validity check Boot::getCurrentSlot().
+TEST_P(BootAidlTest, GetCurrentSlot) {
+    int curSlot = -1;
+    boot->getCurrentSlot(&curSlot);
+    int slots = 0;
+    boot->getNumberSlots(&slots);
+    ASSERT_LT(curSlot, slots);
+}
+
+// validity check Boot::markBootSuccessful().
+TEST_P(BootAidlTest, MarkBootSuccessful) {
+    const auto result = boot->markBootSuccessful();
+    ASSERT_TRUE(result.isOk());
+    int curSlot = 0;
+    boot->getCurrentSlot(&curSlot);
+    bool ret = false;
+    boot->isSlotMarkedSuccessful(curSlot, &ret);
+    ASSERT_TRUE(ret);
+}
+
+TEST_P(BootAidlTest, SetActiveBootSlot) {
+    int curSlot = -1;
+    boot->getCurrentSlot(&curSlot);
+    ASSERT_GE(curSlot, 0);
+    int otherSlot = curSlot ? 0 : 1;
+    bool otherBootable = true;
+    boot->isSlotBootable(otherSlot, &otherBootable);
+
+    for (int s = 0; s < 2; s++) {
+        const auto result = boot->setActiveBootSlot(s);
+        ASSERT_TRUE(result.isOk());
+    }
+    {
+        // Restore original flags to avoid problems on reboot
+        auto result = boot->setActiveBootSlot(curSlot);
+        ASSERT_TRUE(result.isOk());
+
+        if (!otherBootable) {
+            const auto result = boot->setSlotAsUnbootable(otherSlot);
+            ASSERT_TRUE(result.isOk());
+        }
+
+        result = boot->markBootSuccessful();
+        ASSERT_TRUE(result.isOk());
+    }
+    {
+        int slots = 0;
+        boot->getNumberSlots(&slots);
+        const auto result = boot->setActiveBootSlot(slots);
+        ASSERT_FALSE(result.isOk()) << "setActiveBootSlot on invalid slot should fail";
+    }
+}
+
+TEST_P(BootAidlTest, SetSlotAsUnbootable) {
+    int curSlot = -1;
+    boot->getCurrentSlot(&curSlot);
+    ASSERT_GE(curSlot, 0);
+    int otherSlot = curSlot ? 0 : 1;
+    bool otherBootable = false;
+    boot->isSlotBootable(otherSlot, &otherBootable);
+    {
+        auto result = boot->setSlotAsUnbootable(otherSlot);
+        ASSERT_TRUE(result.isOk());
+        boot->isSlotBootable(otherSlot, &otherBootable);
+        ASSERT_FALSE(otherBootable);
+
+        // Restore original flags to avoid problems on reboot
+        if (otherBootable) {
+            result = boot->setActiveBootSlot(otherSlot);
+            ASSERT_TRUE(result.isOk());
+        }
+        result = boot->setActiveBootSlot(curSlot);
+        ASSERT_TRUE(result.isOk());
+        result = boot->markBootSuccessful();
+        ASSERT_TRUE(result.isOk());
+    }
+    {
+        int32_t slots = 0;
+        boot->getNumberSlots(&slots);
+        const auto result = boot->setSlotAsUnbootable(slots);
+        ASSERT_FALSE(result.isOk());
+    }
+}
+
+// validity check Boot::isSlotBootable() on good and bad inputs.
+TEST_P(BootAidlTest, IsSlotBootable) {
+    for (int s = 0; s < 2; s++) {
+        bool bootable = false;
+        const auto res = boot->isSlotBootable(s, &bootable);
+        ASSERT_TRUE(res.isOk()) << res.getMessage();
+    }
+    int32_t slots = 0;
+    boot->getNumberSlots(&slots);
+    bool bootable = false;
+    const auto res = boot->isSlotBootable(slots, &bootable);
+    ASSERT_FALSE(res.isOk());
+}
+
+// validity check Boot::isSlotMarkedSuccessful() on good and bad inputs.
+TEST_P(BootAidlTest, IsSlotMarkedSuccessful) {
+    for (int32_t s = 0; s < 2; s++) {
+        bool isSuccess = false;
+        const auto res = boot->isSlotMarkedSuccessful(s, &isSuccess);
+    }
+    int32_t slots = 0;
+    boot->getNumberSlots(&slots);
+    bool isSuccess = false;
+    const auto res = boot->isSlotMarkedSuccessful(slots, &isSuccess);
+    ASSERT_FALSE(res.isOk());
+}
+
+// validity check Boot::getSuffix() on good and bad inputs.
+TEST_P(BootAidlTest, GetSuffix) {
+    string suffixStr;
+    unordered_set<string> suffixes;
+    int numSlots = 0;
+    boot->getNumberSlots(&numSlots);
+    for (int32_t i = 0; i < numSlots; i++) {
+        std::string suffix;
+        const auto result = boot->getSuffix(i, &suffixStr);
+        ASSERT_TRUE(result.isOk());
+        ASSERT_EQ('_', suffixStr[0]);
+        ASSERT_LE((unsigned)2, suffixStr.size());
+        suffixes.insert(suffixStr);
+    }
+    // All suffixes should be unique
+    ASSERT_EQ(numSlots, suffixes.size());
+    {
+        const string emptySuffix = "";
+        const auto result = boot->getSuffix(numSlots, &suffixStr);
+        ASSERT_TRUE(result.isOk());
+        ASSERT_EQ(suffixStr, emptySuffix);
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, BootAidlTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IBootControl::descriptor)));
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BootAidlTest);
diff --git a/broadcastradio/1.0/default/OWNERS b/broadcastradio/1.0/default/OWNERS
index 57e6592..302fdd7 100644
--- a/broadcastradio/1.0/default/OWNERS
+++ b/broadcastradio/1.0/default/OWNERS
@@ -1,3 +1,4 @@
-elaurent@google.com
-mnaganov@google.com
-twasilczyk@google.com
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/1.0/vts/functional/OWNERS b/broadcastradio/1.0/vts/functional/OWNERS
index 778c4a2..aa19d6a 100644
--- a/broadcastradio/1.0/vts/functional/OWNERS
+++ b/broadcastradio/1.0/vts/functional/OWNERS
@@ -1,2 +1,5 @@
 # Bug component: 533946
+xuweilin@google.com
 oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/1.1/default/OWNERS b/broadcastradio/1.1/default/OWNERS
index 136b607..259b91e 100644
--- a/broadcastradio/1.1/default/OWNERS
+++ b/broadcastradio/1.1/default/OWNERS
@@ -1,3 +1,5 @@
 # Automotive team
-egranata@google.com
-twasilczyk@google.com
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/1.1/vts/OWNERS b/broadcastradio/1.1/vts/OWNERS
index 2c21c25..aa19d6a 100644
--- a/broadcastradio/1.1/vts/OWNERS
+++ b/broadcastradio/1.1/vts/OWNERS
@@ -1,3 +1,5 @@
 # Bug component: 533946
+xuweilin@google.com
 oscarazu@google.com
+ericjeong@google.com
 keunyoung@google.com
diff --git a/broadcastradio/2.0/default/OWNERS b/broadcastradio/2.0/default/OWNERS
index 136b607..259b91e 100644
--- a/broadcastradio/2.0/default/OWNERS
+++ b/broadcastradio/2.0/default/OWNERS
@@ -1,3 +1,5 @@
 # Automotive team
-egranata@google.com
-twasilczyk@google.com
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/2.0/default/TunerSession.cpp b/broadcastradio/2.0/default/TunerSession.cpp
index 2ba4d02..cc2f1a5 100644
--- a/broadcastradio/2.0/default/TunerSession.cpp
+++ b/broadcastradio/2.0/default/TunerSession.cpp
@@ -241,13 +241,13 @@
     };
     std::copy_if(list.begin(), list.end(), std::back_inserter(filteredList), filterCb);
 
-    auto task = [this, list]() {
+    auto task = [this, filteredList]() {
         lock_guard<mutex> lk(mMut);
 
         ProgramListChunk chunk = {};
         chunk.purge = true;
         chunk.complete = true;
-        chunk.modified = hidl_vec<ProgramInfo>(list.begin(), list.end());
+        chunk.modified = hidl_vec<ProgramInfo>(filteredList.begin(), filteredList.end());
 
         mCallback->onProgramListUpdated(chunk);
     };
diff --git a/broadcastradio/2.0/default/VirtualRadio.cpp b/broadcastradio/2.0/default/VirtualRadio.cpp
index c59fd8f..e6b1017 100644
--- a/broadcastradio/2.0/default/VirtualRadio.cpp
+++ b/broadcastradio/2.0/default/VirtualRadio.cpp
@@ -46,9 +46,9 @@
 VirtualRadio gDabRadio(
     "DAB radio mock",
     {
-        {make_selector_dab(12345, 225648), "BBC Radio 1", "Khalid", "Talk"},  // 12B
-        {make_selector_dab(22345, 222064), "Classic FM", "Jean Sibelius", "Andante Festivo"},  // 11D
-        {make_selector_dab(32345, 222064), "Absolute Radio", "Coldplay", "Clocks"},  // 11D
+        {make_selector_dab(0xA00001u, 0x0001u), "BBC Radio 1", "Khalid", "Talk"},
+        {make_selector_dab(0xB00001u, 0x1001u), "Classic FM", "Jean Sibelius", "Andante Festivo"},
+        {make_selector_dab(0xB00002u, 0x1001u), "Absolute Radio", "Coldplay", "Clocks"},
     });
 // clang-format on
 
diff --git a/broadcastradio/2.0/vts/OWNERS b/broadcastradio/2.0/vts/OWNERS
index eb03052..09690ef 100644
--- a/broadcastradio/2.0/vts/OWNERS
+++ b/broadcastradio/2.0/vts/OWNERS
@@ -1,6 +1,8 @@
 # Automotive team
 xuweilin@google.com
 oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
 
 # VTS team
 dshi@google.com
diff --git a/broadcastradio/2.0/vts/functional/OWNERS b/broadcastradio/2.0/vts/functional/OWNERS
index 2c21c25..aa19d6a 100644
--- a/broadcastradio/2.0/vts/functional/OWNERS
+++ b/broadcastradio/2.0/vts/functional/OWNERS
@@ -1,3 +1,5 @@
 # Bug component: 533946
+xuweilin@google.com
 oscarazu@google.com
+ericjeong@google.com
 keunyoung@google.com
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index 63e3b55..5e8a5cf 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -108,6 +108,7 @@
     bool openSession();
     bool getAmFmRegionConfig(bool full, AmFmRegionConfig* config);
     std::optional<utils::ProgramInfoSet> getProgramList();
+    std::optional<utils::ProgramInfoSet> getProgramList(const ProgramFilter& filter);
 
     sp<IBroadcastRadio> mModule;
     Properties mProperties;
@@ -239,9 +240,15 @@
 }
 
 std::optional<utils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList() {
+    ProgramFilter emptyFilter = {};
+    return getProgramList(emptyFilter);
+}
+
+std::optional<utils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList(
+        const ProgramFilter& filter) {
     EXPECT_TIMEOUT_CALL(*mCallback, onProgramListReady).Times(AnyNumber());
 
-    auto startResult = mSession->startProgramListUpdates({});
+    auto startResult = mSession->startProgramListUpdates(filter);
     if (startResult == Result::NOT_SUPPORTED) {
         printSkipped("Program list not supported");
         return std::nullopt;
@@ -514,48 +521,9 @@
 
     ASSERT_TRUE(openSession());
 
-    auto programList = getProgramList();
-
-    if (!programList) {
-        printSkipped("Empty Station-List, tune cannot be performed");
-        return;
-    }
-
     ProgramSelector sel = {};
-    uint64_t freq = 0;
-    bool dabStnPresent = false;
-
-    for (auto&& programInfo : *programList) {
-        if (utils::hasId(programInfo.selector, IdentifierType::DAB_FREQUENCY)) {
-            for (auto&& config_entry : config) {
-                if (config_entry.frequency == utils::getId(programInfo.selector,
-                    IdentifierType::DAB_FREQUENCY, 0)) {
-                    freq = config_entry.frequency;
-                    break;
-                }
-            }
-            // Do not trigger a tune request if the programList entry does not contain
-            // a valid DAB frequency
-            if (freq == 0) {
-              continue;
-            }
-            uint64_t dabSidExt = utils::getId(programInfo.selector, IdentifierType::DAB_SID_EXT, 0);
-            uint64_t dabEns = utils::getId(programInfo.selector, IdentifierType::DAB_ENSEMBLE, 0);
-            sel.primaryId = make_identifier(IdentifierType::DAB_SID_EXT, dabSidExt);
-            hidl_vec<ProgramIdentifier> secondaryIds = {
-                make_identifier(IdentifierType::DAB_ENSEMBLE, dabEns),
-                make_identifier(IdentifierType::DAB_FREQUENCY, freq)
-            };
-            sel.secondaryIds = secondaryIds;
-            dabStnPresent = true;
-            break;
-        }
-    }
-
-    if (!dabStnPresent) {
-        printSkipped("No DAB stations in the list, tune cannot be performed");
-        return;
-    }
+    uint64_t freq = config[config.size() / 2].frequency;
+    sel.primaryId = make_identifier(IdentifierType::DAB_FREQUENCY,freq);
 
     std::this_thread::sleep_for(gTuneWorkaround);
 
@@ -849,20 +817,98 @@
 }
 
 /**
- * Test getting program list.
+ * Test getting program list using empty program filter.
  *
  * Verifies that:
  * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
  * - the complete list is fetched within timeout::programListScan;
  * - stopProgramListUpdates does not crash.
  */
-TEST_P(BroadcastRadioHalTest, GetProgramList) {
+TEST_P(BroadcastRadioHalTest, GetProgramListFromEmptyFilter) {
     ASSERT_TRUE(openSession());
 
     getProgramList();
 }
 
 /**
+ * Test getting program list using AMFM frequency program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within timeout::programListScan;
+ * - stopProgramListUpdates does not crash;
+ * - result for startProgramListUpdates using a filter with AMFM_FREQUENCY value of the first AMFM
+ *   program matches the expected result.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromAmFmFilter) {
+    ASSERT_TRUE(openSession());
+
+    auto completeList = getProgramList();
+    if (!completeList) return;
+
+    ProgramFilter amfmFilter = {};
+    int expectedResultSize = 0;
+    uint64_t expectedFreq = 0;
+    for (auto&& program : *completeList) {
+        auto amfmIds = utils::getAllIds(program.selector, IdentifierType::AMFM_FREQUENCY);
+        EXPECT_LE(amfmIds.size(), 1u);
+        if (amfmIds.size() == 0) continue;
+
+        if (expectedResultSize == 0) {
+            expectedFreq = amfmIds[0];
+            amfmFilter.identifiers = {
+                    make_identifier(IdentifierType::AMFM_FREQUENCY, expectedFreq)};
+            expectedResultSize = 1;
+        } else if (amfmIds[0] == expectedFreq) {
+            expectedResultSize++;
+        }
+    }
+
+    if (expectedResultSize == 0) return;
+    auto amfmList = getProgramList(amfmFilter);
+    ASSERT_EQ(expectedResultSize, amfmList->size()) << "amfm filter result size is wrong";
+}
+
+/**
+ * Test getting program list using DAB ensemble program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within timeout::programListScan;
+ * - stopProgramListUpdates does not crash;
+ * - result for startProgramListUpdates using a filter with DAB_ENSEMBLE value of the first DAB
+ *   program matches the expected result.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromDabFilter) {
+    ASSERT_TRUE(openSession());
+
+    auto completeList = getProgramList();
+    if (!completeList) return;
+
+    ProgramFilter dabFilter = {};
+    int expectedResultSize = 0;
+    uint64_t expectedEnsemble = 0;
+    for (auto&& program : *completeList) {
+        auto dabEnsembles = utils::getAllIds(program.selector, IdentifierType::DAB_ENSEMBLE);
+        EXPECT_LE(dabEnsembles.size(), 1u);
+        if (dabEnsembles.size() == 0) continue;
+
+        if (expectedResultSize == 0) {
+            expectedEnsemble = dabEnsembles[0];
+            dabFilter.identifiers = {
+                    make_identifier(IdentifierType::DAB_ENSEMBLE, expectedEnsemble)};
+            expectedResultSize = 1;
+        } else if (dabEnsembles[0] == expectedEnsemble) {
+            expectedResultSize++;
+        }
+    }
+
+    if (expectedResultSize == 0) return;
+    auto dabList = getProgramList(dabFilter);
+    ASSERT_EQ(expectedResultSize, dabList->size()) << "dab filter result size is wrong";
+}
+
+/**
  * Test HD_STATION_NAME correctness.
  *
  * Verifies that if a program on the list contains HD_STATION_NAME identifier:
diff --git a/broadcastradio/aidl/Android.bp b/broadcastradio/aidl/Android.bp
new file mode 100644
index 0000000..3f89029
--- /dev/null
+++ b/broadcastradio/aidl/Android.bp
@@ -0,0 +1,48 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.broadcastradio",
+    vendor_available: true,
+    srcs: ["android/hardware/broadcastradio/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+            min_sdk_version: "Tiramisu",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/broadcastradio/aidl/OWNERS b/broadcastradio/aidl/OWNERS
new file mode 100644
index 0000000..302fdd7
--- /dev/null
+++ b/broadcastradio/aidl/OWNERS
@@ -0,0 +1,4 @@
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/.hash b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/.hash
new file mode 100644
index 0000000..41917fe
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/.hash
@@ -0,0 +1 @@
+3c864ddf392d28cfbf95849bedf0b753b81cc013
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/AmFmBandRange.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/AmFmBandRange.aidl
new file mode 100644
index 0000000..ca511aa
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/AmFmBandRange.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AmFmBandRange {
+  int lowerBound;
+  int upperBound;
+  int spacing;
+  int seekSpacing;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/AmFmRegionConfig.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/AmFmRegionConfig.aidl
new file mode 100644
index 0000000..b96def3
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/AmFmRegionConfig.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AmFmRegionConfig {
+  android.hardware.broadcastradio.AmFmBandRange[] ranges;
+  int fmDeemphasis;
+  int fmRds;
+  const int DEEMPHASIS_D50 = (1 << 0) /* 1 */;
+  const int DEEMPHASIS_D75 = (1 << 1) /* 2 */;
+  const int RDS = (1 << 0) /* 1 */;
+  const int RBDS = (1 << 1) /* 2 */;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Announcement.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Announcement.aidl
new file mode 100644
index 0000000..bbdd86f
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Announcement.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Announcement {
+  android.hardware.broadcastradio.ProgramSelector selector;
+  android.hardware.broadcastradio.AnnouncementType type = android.hardware.broadcastradio.AnnouncementType.INVALID;
+  android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/AnnouncementType.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/AnnouncementType.aidl
new file mode 100644
index 0000000..1d187fe
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/AnnouncementType.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="byte") @JavaDerive(equals=true, toString=true) @VintfStability
+enum AnnouncementType {
+  INVALID = 0,
+  EMERGENCY = 1,
+  WARNING,
+  TRAFFIC,
+  WEATHER,
+  NEWS,
+  EVENT,
+  SPORT,
+  MISC,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ConfigFlag.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ConfigFlag.aidl
new file mode 100644
index 0000000..98af437
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ConfigFlag.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum ConfigFlag {
+  FORCE_MONO = 1,
+  FORCE_ANALOG,
+  FORCE_DIGITAL,
+  RDS_AF,
+  RDS_REG,
+  DAB_DAB_LINKING,
+  DAB_FM_LINKING,
+  DAB_DAB_SOFT_LINKING,
+  DAB_FM_SOFT_LINKING,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/DabTableEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/DabTableEntry.aidl
new file mode 100644
index 0000000..162f4abd
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/DabTableEntry.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable DabTableEntry {
+  String label;
+  int frequencyKhz;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/IAnnouncementListener.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/IAnnouncementListener.aidl
new file mode 100644
index 0000000..346af58
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/IAnnouncementListener.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface IAnnouncementListener {
+  oneway void onListUpdated(in android.hardware.broadcastradio.Announcement[] announcements);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/IBroadcastRadio.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/IBroadcastRadio.aidl
new file mode 100644
index 0000000..39eb04c
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/IBroadcastRadio.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface IBroadcastRadio {
+  android.hardware.broadcastradio.Properties getProperties();
+  android.hardware.broadcastradio.AmFmRegionConfig getAmFmRegionConfig(in boolean full);
+  android.hardware.broadcastradio.DabTableEntry[] getDabRegionConfig();
+  void setTunerCallback(in android.hardware.broadcastradio.ITunerCallback callback);
+  void unsetTunerCallback();
+  void tune(in android.hardware.broadcastradio.ProgramSelector program);
+  void seek(in boolean directionUp, in boolean skipSubChannel);
+  void step(in boolean directionUp);
+  void cancel();
+  void startProgramListUpdates(in android.hardware.broadcastradio.ProgramFilter filter);
+  void stopProgramListUpdates();
+  boolean isConfigFlagSet(in android.hardware.broadcastradio.ConfigFlag flag);
+  void setConfigFlag(in android.hardware.broadcastradio.ConfigFlag flag, in boolean value);
+  android.hardware.broadcastradio.VendorKeyValue[] setParameters(in android.hardware.broadcastradio.VendorKeyValue[] parameters);
+  android.hardware.broadcastradio.VendorKeyValue[] getParameters(in String[] keys);
+  byte[] getImage(in int id);
+  android.hardware.broadcastradio.ICloseHandle registerAnnouncementListener(in android.hardware.broadcastradio.IAnnouncementListener listener, in android.hardware.broadcastradio.AnnouncementType[] enabled);
+  const int INVALID_IMAGE = 0;
+  const int ANTENNA_STATE_CHANGE_TIMEOUT_MS = 100;
+  const int LIST_COMPLETE_TIMEOUT_MS = 300000;
+  const int TUNER_TIMEOUT_MS = 30000;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ICloseHandle.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ICloseHandle.aidl
new file mode 100644
index 0000000..75e7f2a
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ICloseHandle.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface ICloseHandle {
+  void close();
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ITunerCallback.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ITunerCallback.aidl
new file mode 100644
index 0000000..f5badad
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ITunerCallback.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface ITunerCallback {
+  oneway void onTuneFailed(in android.hardware.broadcastradio.Result result, in android.hardware.broadcastradio.ProgramSelector selector);
+  oneway void onCurrentProgramInfoChanged(in android.hardware.broadcastradio.ProgramInfo info);
+  oneway void onProgramListUpdated(in android.hardware.broadcastradio.ProgramListChunk chunk);
+  oneway void onAntennaStateChange(in boolean connected);
+  oneway void onConfigFlagUpdated(in android.hardware.broadcastradio.ConfigFlag flag, in boolean value);
+  oneway void onParametersUpdated(in android.hardware.broadcastradio.VendorKeyValue[] parameters);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/IdentifierType.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/IdentifierType.aidl
new file mode 100644
index 0000000..63a0efd
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/IdentifierType.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum IdentifierType {
+  VENDOR_START = 1000,
+  VENDOR_END = 1999,
+  INVALID = 0,
+  AMFM_FREQUENCY_KHZ,
+  RDS_PI,
+  HD_STATION_ID_EXT,
+  HD_STATION_NAME,
+  DAB_SID_EXT,
+  DAB_ENSEMBLE,
+  DAB_SCID,
+  DAB_FREQUENCY_KHZ,
+  DRMO_SERVICE_ID,
+  DRMO_FREQUENCY_KHZ,
+  SXM_SERVICE_ID = (DRMO_FREQUENCY_KHZ + 2) /* 12 */,
+  SXM_CHANNEL,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Metadata.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Metadata.aidl
new file mode 100644
index 0000000..e02b6b1
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Metadata.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+union Metadata {
+  String rdsPs;
+  int rdsPty;
+  int rbdsPty;
+  String rdsRt;
+  String songTitle;
+  String songArtist;
+  String songAlbum;
+  int stationIcon;
+  int albumArt;
+  String programName;
+  String dabEnsembleName;
+  String dabEnsembleNameShort;
+  String dabServiceName;
+  String dabServiceNameShort;
+  String dabComponentName;
+  String dabComponentNameShort;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramFilter.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramFilter.aidl
new file mode 100644
index 0000000..9edeb8d
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramFilter.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramFilter {
+  android.hardware.broadcastradio.IdentifierType[] identifierTypes;
+  android.hardware.broadcastradio.ProgramIdentifier[] identifiers;
+  boolean includeCategories;
+  boolean excludeModifications;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramIdentifier.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramIdentifier.aidl
new file mode 100644
index 0000000..6676350
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramIdentifier.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramIdentifier {
+  android.hardware.broadcastradio.IdentifierType type = android.hardware.broadcastradio.IdentifierType.INVALID;
+  long value;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramInfo.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramInfo.aidl
new file mode 100644
index 0000000..335f060
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramInfo.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramInfo {
+  android.hardware.broadcastradio.ProgramSelector selector;
+  android.hardware.broadcastradio.ProgramIdentifier logicallyTunedTo;
+  android.hardware.broadcastradio.ProgramIdentifier physicallyTunedTo;
+  @nullable android.hardware.broadcastradio.ProgramIdentifier[] relatedContent;
+  int infoFlags;
+  int signalQuality;
+  android.hardware.broadcastradio.Metadata[] metadata;
+  android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+  const int FLAG_LIVE = (1 << 0) /* 1 */;
+  const int FLAG_MUTED = (1 << 1) /* 2 */;
+  const int FLAG_TRAFFIC_PROGRAM = (1 << 2) /* 4 */;
+  const int FLAG_TRAFFIC_ANNOUNCEMENT = (1 << 3) /* 8 */;
+  const int FLAG_TUNABLE = (1 << 4) /* 16 */;
+  const int FLAG_STEREO = (1 << 5) /* 32 */;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramListChunk.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramListChunk.aidl
new file mode 100644
index 0000000..5d53b99
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramListChunk.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramListChunk {
+  boolean purge;
+  boolean complete;
+  android.hardware.broadcastradio.ProgramInfo[] modified;
+  @nullable android.hardware.broadcastradio.ProgramIdentifier[] removed;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramSelector.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramSelector.aidl
new file mode 100644
index 0000000..9af1dc8
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/ProgramSelector.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramSelector {
+  android.hardware.broadcastradio.ProgramIdentifier primaryId;
+  android.hardware.broadcastradio.ProgramIdentifier[] secondaryIds;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Properties.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Properties.aidl
new file mode 100644
index 0000000..643b819
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Properties.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Properties {
+  String maker;
+  String product;
+  String version;
+  String serial;
+  android.hardware.broadcastradio.IdentifierType[] supportedIdentifierTypes;
+  android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Result.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Result.aidl
new file mode 100644
index 0000000..b0fc018
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/Result.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum Result {
+  OK = 0,
+  INTERNAL_ERROR,
+  INVALID_ARGUMENTS,
+  INVALID_STATE,
+  NOT_SUPPORTED,
+  TIMEOUT,
+  CANCELED,
+  UNKNOWN_ERROR,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/VendorKeyValue.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/VendorKeyValue.aidl
new file mode 100644
index 0000000..3c6b194
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/1/android/hardware/broadcastradio/VendorKeyValue.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VendorKeyValue {
+  String key;
+  String value;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmBandRange.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmBandRange.aidl
new file mode 100644
index 0000000..ca511aa
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmBandRange.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AmFmBandRange {
+  int lowerBound;
+  int upperBound;
+  int spacing;
+  int seekSpacing;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmRegionConfig.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmRegionConfig.aidl
new file mode 100644
index 0000000..fe8489c
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmRegionConfig.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AmFmRegionConfig {
+  android.hardware.broadcastradio.AmFmBandRange[] ranges;
+  int fmDeemphasis;
+  int fmRds;
+  const int DEEMPHASIS_D50 = (1 << 0);
+  const int DEEMPHASIS_D75 = (1 << 1);
+  const int RDS = (1 << 0);
+  const int RBDS = (1 << 1);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Announcement.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Announcement.aidl
new file mode 100644
index 0000000..bbdd86f
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Announcement.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Announcement {
+  android.hardware.broadcastradio.ProgramSelector selector;
+  android.hardware.broadcastradio.AnnouncementType type = android.hardware.broadcastradio.AnnouncementType.INVALID;
+  android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AnnouncementType.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AnnouncementType.aidl
new file mode 100644
index 0000000..1d187fe
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AnnouncementType.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="byte") @JavaDerive(equals=true, toString=true) @VintfStability
+enum AnnouncementType {
+  INVALID = 0,
+  EMERGENCY = 1,
+  WARNING,
+  TRAFFIC,
+  WEATHER,
+  NEWS,
+  EVENT,
+  SPORT,
+  MISC,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ConfigFlag.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ConfigFlag.aidl
new file mode 100644
index 0000000..98af437
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ConfigFlag.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum ConfigFlag {
+  FORCE_MONO = 1,
+  FORCE_ANALOG,
+  FORCE_DIGITAL,
+  RDS_AF,
+  RDS_REG,
+  DAB_DAB_LINKING,
+  DAB_FM_LINKING,
+  DAB_DAB_SOFT_LINKING,
+  DAB_FM_SOFT_LINKING,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/DabTableEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/DabTableEntry.aidl
new file mode 100644
index 0000000..162f4abd
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/DabTableEntry.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable DabTableEntry {
+  String label;
+  int frequencyKhz;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IAnnouncementListener.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IAnnouncementListener.aidl
new file mode 100644
index 0000000..346af58
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IAnnouncementListener.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface IAnnouncementListener {
+  oneway void onListUpdated(in android.hardware.broadcastradio.Announcement[] announcements);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IBroadcastRadio.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IBroadcastRadio.aidl
new file mode 100644
index 0000000..39eb04c
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IBroadcastRadio.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface IBroadcastRadio {
+  android.hardware.broadcastradio.Properties getProperties();
+  android.hardware.broadcastradio.AmFmRegionConfig getAmFmRegionConfig(in boolean full);
+  android.hardware.broadcastradio.DabTableEntry[] getDabRegionConfig();
+  void setTunerCallback(in android.hardware.broadcastradio.ITunerCallback callback);
+  void unsetTunerCallback();
+  void tune(in android.hardware.broadcastradio.ProgramSelector program);
+  void seek(in boolean directionUp, in boolean skipSubChannel);
+  void step(in boolean directionUp);
+  void cancel();
+  void startProgramListUpdates(in android.hardware.broadcastradio.ProgramFilter filter);
+  void stopProgramListUpdates();
+  boolean isConfigFlagSet(in android.hardware.broadcastradio.ConfigFlag flag);
+  void setConfigFlag(in android.hardware.broadcastradio.ConfigFlag flag, in boolean value);
+  android.hardware.broadcastradio.VendorKeyValue[] setParameters(in android.hardware.broadcastradio.VendorKeyValue[] parameters);
+  android.hardware.broadcastradio.VendorKeyValue[] getParameters(in String[] keys);
+  byte[] getImage(in int id);
+  android.hardware.broadcastradio.ICloseHandle registerAnnouncementListener(in android.hardware.broadcastradio.IAnnouncementListener listener, in android.hardware.broadcastradio.AnnouncementType[] enabled);
+  const int INVALID_IMAGE = 0;
+  const int ANTENNA_STATE_CHANGE_TIMEOUT_MS = 100;
+  const int LIST_COMPLETE_TIMEOUT_MS = 300000;
+  const int TUNER_TIMEOUT_MS = 30000;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ICloseHandle.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ICloseHandle.aidl
new file mode 100644
index 0000000..75e7f2a
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ICloseHandle.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface ICloseHandle {
+  void close();
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ITunerCallback.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ITunerCallback.aidl
new file mode 100644
index 0000000..f5badad
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ITunerCallback.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface ITunerCallback {
+  oneway void onTuneFailed(in android.hardware.broadcastradio.Result result, in android.hardware.broadcastradio.ProgramSelector selector);
+  oneway void onCurrentProgramInfoChanged(in android.hardware.broadcastradio.ProgramInfo info);
+  oneway void onProgramListUpdated(in android.hardware.broadcastradio.ProgramListChunk chunk);
+  oneway void onAntennaStateChange(in boolean connected);
+  oneway void onConfigFlagUpdated(in android.hardware.broadcastradio.ConfigFlag flag, in boolean value);
+  oneway void onParametersUpdated(in android.hardware.broadcastradio.VendorKeyValue[] parameters);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IdentifierType.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IdentifierType.aidl
new file mode 100644
index 0000000..4df272c
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IdentifierType.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum IdentifierType {
+  VENDOR_START = 1000,
+  VENDOR_END = 1999,
+  INVALID = 0,
+  AMFM_FREQUENCY_KHZ,
+  RDS_PI,
+  HD_STATION_ID_EXT,
+  HD_STATION_NAME,
+  DAB_SID_EXT,
+  DAB_ENSEMBLE,
+  DAB_SCID,
+  DAB_FREQUENCY_KHZ,
+  DRMO_SERVICE_ID,
+  DRMO_FREQUENCY_KHZ,
+  SXM_SERVICE_ID = (DRMO_FREQUENCY_KHZ + 2),
+  SXM_CHANNEL,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Metadata.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Metadata.aidl
new file mode 100644
index 0000000..e02b6b1
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Metadata.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+union Metadata {
+  String rdsPs;
+  int rdsPty;
+  int rbdsPty;
+  String rdsRt;
+  String songTitle;
+  String songArtist;
+  String songAlbum;
+  int stationIcon;
+  int albumArt;
+  String programName;
+  String dabEnsembleName;
+  String dabEnsembleNameShort;
+  String dabServiceName;
+  String dabServiceNameShort;
+  String dabComponentName;
+  String dabComponentNameShort;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramFilter.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramFilter.aidl
new file mode 100644
index 0000000..9edeb8d
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramFilter.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramFilter {
+  android.hardware.broadcastradio.IdentifierType[] identifierTypes;
+  android.hardware.broadcastradio.ProgramIdentifier[] identifiers;
+  boolean includeCategories;
+  boolean excludeModifications;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramIdentifier.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramIdentifier.aidl
new file mode 100644
index 0000000..6676350
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramIdentifier.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramIdentifier {
+  android.hardware.broadcastradio.IdentifierType type = android.hardware.broadcastradio.IdentifierType.INVALID;
+  long value;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl
new file mode 100644
index 0000000..b14023a
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramInfo {
+  android.hardware.broadcastradio.ProgramSelector selector;
+  android.hardware.broadcastradio.ProgramIdentifier logicallyTunedTo;
+  android.hardware.broadcastradio.ProgramIdentifier physicallyTunedTo;
+  @nullable android.hardware.broadcastradio.ProgramIdentifier[] relatedContent;
+  int infoFlags;
+  int signalQuality;
+  android.hardware.broadcastradio.Metadata[] metadata;
+  android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+  const int FLAG_LIVE = (1 << 0);
+  const int FLAG_MUTED = (1 << 1);
+  const int FLAG_TRAFFIC_PROGRAM = (1 << 2);
+  const int FLAG_TRAFFIC_ANNOUNCEMENT = (1 << 3);
+  const int FLAG_TUNABLE = (1 << 4);
+  const int FLAG_STEREO = (1 << 5);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramListChunk.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramListChunk.aidl
new file mode 100644
index 0000000..5d53b99
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramListChunk.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramListChunk {
+  boolean purge;
+  boolean complete;
+  android.hardware.broadcastradio.ProgramInfo[] modified;
+  @nullable android.hardware.broadcastradio.ProgramIdentifier[] removed;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramSelector.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramSelector.aidl
new file mode 100644
index 0000000..9af1dc8
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramSelector.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramSelector {
+  android.hardware.broadcastradio.ProgramIdentifier primaryId;
+  android.hardware.broadcastradio.ProgramIdentifier[] secondaryIds;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Properties.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Properties.aidl
new file mode 100644
index 0000000..643b819
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Properties.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Properties {
+  String maker;
+  String product;
+  String version;
+  String serial;
+  android.hardware.broadcastradio.IdentifierType[] supportedIdentifierTypes;
+  android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl
new file mode 100644
index 0000000..8af74c7
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum Result {
+  OK,
+  INTERNAL_ERROR,
+  INVALID_ARGUMENTS,
+  INVALID_STATE,
+  NOT_SUPPORTED,
+  TIMEOUT,
+  CANCELED,
+  UNKNOWN_ERROR,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/VendorKeyValue.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/VendorKeyValue.aidl
new file mode 100644
index 0000000..3c6b194
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/VendorKeyValue.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VendorKeyValue {
+  String key;
+  String value;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AmFmBandRange.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmBandRange.aidl
new file mode 100644
index 0000000..562631f
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmBandRange.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Defines the AM/FM band range for configuring different regions.
+ *
+ * <p>Channel grid is defined as: each possible channel is set at
+ * lowerBound + channelNumber * spacing, up to upperBound.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable AmFmBandRange {
+    /**
+     * The frequency (in kHz) of the first channel within the range.
+     *
+     * Lower bound must be a tunable frequency.
+     */
+    int lowerBound;
+
+    /**
+     * The frequency (in kHz) of the last channel within the range.
+     */
+    int upperBound;
+
+    /**
+     * Channel grid resolution (in kHz), telling how far the channels are apart.
+     */
+    int spacing;
+
+    /**
+     * Channel spacing (in kHz) used to speed up seeking to the next station
+     * via the {@link IBroadcastRadio#seek} operation.
+     *
+     * It must be a multiple of channel grid resolution.
+     *
+     * Tuner may first quickly check every n-th channel and if it detects echo
+     * from a station, it fine-tunes to find the exact frequency.
+     *
+     * It's ignored for capabilities check (with full=true when calling
+     * getAmFmRegionConfig).
+     */
+    int seekSpacing;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl
new file mode 100644
index 0000000..f4c6fd3
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.AmFmBandRange;
+
+/**
+ * Regional configuration for AM/FM.
+ *
+ * <p>For hardware capabilities check (with full=true when calling
+ * {@link IBroadcastRadio#getAmFmRegionConfig}), HAL implementation fills
+ * entire supported range of frequencies and features.
+ *
+ * When checking current configuration, at most one bit in each bitset
+ * can be set.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable AmFmRegionConfig {
+    /**
+     * Noth D50 and D75 are FM de-emphasis filter supported or configured.
+     *
+     * Both might be set for hardware capabilities check (with full={@code true}
+     * when calling getAmFmRegionConfig), but exactly one for specific region
+     * settings.
+     */
+    const int DEEMPHASIS_D50 = 1 << 0;
+
+    const int DEEMPHASIS_D75 = 1 << 1;
+
+    /**
+     * Both RDS and RBDS are supported or configured RDS variants.
+     *
+     * Both might be set for hardware capabilities check (with full={@code true}
+     * when calling getAmFmRegionConfig), but only one (or none) for specific
+     * region settings.
+     *
+     * RDS is Standard variant, used everywhere except North America.
+     */
+    const int RDS = 1 << 0;
+
+    /**
+     * Variant used in North America (see RDS).
+     */
+    const int RBDS = 1 << 1;
+
+    /**
+     * All supported or configured AM/FM bands.
+     *
+     * AM/FM bands are identified by frequency value
+     * (see {@link IdentifierType#AMFM_FREQUENCY_KHZ}).
+     *
+     * With typical configuration, it's expected to have two frequency ranges
+     * for capabilities check (AM and FM) and four ranges for specific region
+     * configuration (AM LW, AM MW, AM SW, FM).
+     */
+    AmFmBandRange[] ranges;
+
+    /**
+     * De-emphasis filter supported/configured.
+     *
+     * It can be a combination of de-emphasis values ({@link #DEEMPHASIS_D50} and
+     * {@link #DEEMPHASIS_D75}).
+     */
+    int fmDeemphasis;
+
+    /**
+     * RDS/RBDS variant supported/configured.
+     *
+     * It can be a combination of RDS values ({@link #RDS} and {@link #RBDS}).
+     */
+    int fmRds;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Announcement.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Announcement.aidl
new file mode 100644
index 0000000..a972d4d
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Announcement.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.AnnouncementType;
+import android.hardware.broadcastradio.ProgramSelector;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+/**
+ * Station broadcasting active announcement.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable Announcement {
+    /**
+     * Program selector to tune to the announcement.
+     */
+    ProgramSelector selector;
+
+    /**
+     * Announcement type.
+     */
+    AnnouncementType type = AnnouncementType.INVALID;
+
+    /**
+     * Vendor-specific information.
+     *
+     * It may be used for extra features, not supported by the platform,
+     * for example: com.me.hdradio.urgency=100; com.me.hdradio.certainity=50.
+     */
+    VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AnnouncementType.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AnnouncementType.aidl
new file mode 100644
index 0000000..8df8025
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AnnouncementType.aidl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Type of an announcement.
+ *
+ * <p>It maps to different announcement types for each radio technology.
+ */
+@VintfStability
+@Backing(type="byte")
+@JavaDerive(equals=true, toString=true)
+enum AnnouncementType {
+    /**
+     * Undefined announcement type
+     */
+    INVALID = 0,
+
+    /**
+     * DAB alarm, RDS emergency program type (PTY 31).
+     */
+    EMERGENCY = 1,
+
+    /**
+     * DAB warning.
+     */
+    WARNING,
+
+    /**
+     * DAB road traffic, RDS TA, HD Radio transportation.
+     */
+    TRAFFIC,
+
+    /**
+     * Weather.
+     */
+    WEATHER,
+
+    /**
+     * News.
+     */
+    NEWS,
+
+    /**
+     * DAB event, special event.
+     */
+    EVENT,
+
+    /**
+     * DAB sport report, RDS sports.
+     */
+    SPORT,
+
+    /**
+     * All others.
+     */
+    MISC,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ConfigFlag.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ConfigFlag.aidl
new file mode 100644
index 0000000..11da39c
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ConfigFlag.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Configuration flags to be used with isConfigFlagSet and setConfigFlag methods
+ * of IBroadcastRadio.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum ConfigFlag {
+    /**
+     * Forces mono audio stream reception.
+     *
+     * Analog broadcasts can recover poor reception conditions by jointing
+     * stereo channels into one. Mainly for, but not limited to AM/FM.
+     */
+    FORCE_MONO = 1,
+
+    /**
+     * Forces the analog playback for the supporting radio technology.
+     *
+     * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
+     * this option. This is purely user choice, ie. does not reflect digital-
+     * analog handover state managed from the HAL implementation side.
+     *
+     * Some radio technologies may not support this, ie. DAB.
+     */
+    FORCE_ANALOG,
+
+    /**
+     * Forces the digital playback for the supporting radio technology.
+     *
+     * User may disable digital-analog handover that happens with poor
+     * reception conditions. With digital forced, the radio will remain silent
+     * instead of switching to analog channel if it's available. This is purely
+     * user choice, it does not reflect the actual state of handover.
+     */
+    FORCE_DIGITAL,
+
+    /**
+     * RDS Alternative Frequencies.
+     *
+     * If set and the currently tuned RDS station broadcasts on multiple
+     * channels, radio tuner automatically switches to the best available
+     * alternative.
+     */
+    RDS_AF,
+
+    /**
+     * RDS region-specific program lock-down.
+     *
+     * Allows user to lock to the current region as they move into the
+     * other region.
+     */
+    RDS_REG,
+
+    /**
+     * Enables DAB-DAB hard- and implicit-linking (the same content).
+     */
+    DAB_DAB_LINKING,
+
+    /**
+     * Enables DAB-FM hard- and implicit-linking (the same content).
+     */
+    DAB_FM_LINKING,
+
+    /**
+     * Enables DAB-DAB soft-linking (related content).
+     */
+    DAB_DAB_SOFT_LINKING,
+
+    /**
+     * Enables DAB-FM soft-linking (related content).
+     */
+    DAB_FM_SOFT_LINKING,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/DabTableEntry.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/DabTableEntry.aidl
new file mode 100644
index 0000000..13c20b0
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/DabTableEntry.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * An entry in regional configuration for DAB.
+ *
+ * <p>This defines a frequency table row for ensembles.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable DabTableEntry {
+    /**
+     * Channel name, i.e. 5A, 7B.
+     *
+     * It must match the following regular expression:
+     * /^[A-Z0-9][A-Z0-9 ]{0,5}[A-Z0-9]$/ (2-7 uppercase alphanumeric characters
+     * without spaces allowed at the beginning nor end).
+     */
+    String label;
+
+    /**
+     * Frequency, in kHz.
+     */
+    int frequencyKhz;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/IAnnouncementListener.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/IAnnouncementListener.aidl
new file mode 100644
index 0000000..f6021c1
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/IAnnouncementListener.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.Announcement;
+
+/**
+ * Callback interface for announcement listener.
+ *
+ * For typical configuration, the listener is a broadcast radio service.
+ */
+@VintfStability
+interface IAnnouncementListener {
+    /**
+     * Called whenever announcement list has changed.
+     *
+     * @param announcements The complete list of currently active announcements.
+     */
+    oneway void onListUpdated(in Announcement[] announcements);
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/IBroadcastRadio.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/IBroadcastRadio.aidl
new file mode 100644
index 0000000..0f88fc0
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/IBroadcastRadio.aidl
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.AmFmRegionConfig;
+import android.hardware.broadcastradio.AnnouncementType;
+import android.hardware.broadcastradio.ConfigFlag;
+import android.hardware.broadcastradio.DabTableEntry;
+import android.hardware.broadcastradio.IAnnouncementListener;
+import android.hardware.broadcastradio.ICloseHandle;
+import android.hardware.broadcastradio.ITunerCallback;
+import android.hardware.broadcastradio.ProgramFilter;
+import android.hardware.broadcastradio.ProgramSelector;
+import android.hardware.broadcastradio.Properties;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+/**
+ * Represents a hardware broadcast radio module. A single module may contain
+ * multiple hardware tuners (i.e. with an additional background tuner), but the
+ * layers above the HAL see them as a single logical unit.
+ */
+@VintfStability
+interface IBroadcastRadio {
+    /**
+     * Invalid identifier for {@link IBroadcastRadio#getImage}.
+     */
+    const int INVALID_IMAGE = 0;
+
+    /**
+     * If the antenna is disconnected from the beginning, the
+     * {@link ITunerCallback#onAntennaStateChange} callback must be
+     * called within this time.
+     */
+    const int ANTENNA_STATE_CHANGE_TIMEOUT_MS = 100;
+
+    /**
+     * All chunks of a signal program list update must be transmitted
+     * within this time.
+     */
+    const int LIST_COMPLETE_TIMEOUT_MS = 300000;
+
+    /**
+     * All tune, seek and step operations must be completed within
+     * this time.
+     */
+    const int TUNER_TIMEOUT_MS = 30000;
+
+    /**
+     * Returns module properties: a description of a module and its
+     * capabilities. This method must not fail.
+     *
+     * @return Module description.
+     */
+    Properties getProperties();
+
+    /**
+     * Fetches current or possible AM/FM region configuration.
+     *
+     * If the tuner doesn't support AM/FM, a service-specific error
+     * {@link Result#NOT_SUPPORTED} will be returned.
+     *
+     * @param full If {@code true}, returns full hardware capabilities.
+     *             If {@code false}, returns current regional configuration.
+     * @return config Hardware capabilities (full={@code true}) or current configuration
+     *                (full={@code false}).
+     */
+    AmFmRegionConfig getAmFmRegionConfig(in boolean full);
+
+    /**
+     * Fetches current DAB region configuration.
+     *
+     * If tuner doesn't support DAB, a service-specific error
+     * {@link Result#NOT_SUPPORTED} wiil be returned.
+     *
+     * @return config Current configuration.
+     */
+    DabTableEntry[] getDabRegionConfig();
+
+    /**
+     * Sets callback interface.
+     *
+     * It is expected that there will only ever be a single callback set.
+     * If called when a callback is already set, the existing one should be
+     * replaced with the new callback.
+     *
+     * If the callback to be set is null, a service-specific error
+     * {@link Result#INVALID_ARGUMENTS} will be returned; if the callback
+     * is not set successfully, a service-specific error
+     * {@link Result#NOT_SUPPORTED} should be returned.
+     *
+     * @param callback The callback interface used for BroadcastRadio HAL.
+     */
+    void setTunerCallback(in ITunerCallback callback);
+
+    /**
+     * Unsets callback interface.
+     *
+     * The existing callback is set to null.
+     */
+    void unsetTunerCallback();
+
+    /**
+     * Tunes to a specified program.
+     *
+     * Automatically cancels pending tune(), seek() or step().
+     * The method should first check whether tune can be processed by the status
+     * of tuner and inputs, schedule tune task, and then return status
+     * immediately. If a non-null callback is not set, a service-specific
+     * error {@link Result#INVALID_STATE} will be returned; if the program
+     * selector doesn't contain any supported identifier, a service-specific error
+     * {@link Result#NOT_SUPPORTED} will be returned; if the program selector
+     * contains identifiers in invalid format (i.e. out of range), a
+     * service-specific error {@link Result#INVALID_ARGUMENTS} will be returned;
+     * otherwise, OK will be returned as status. Tune task should be processed
+     * asynchronously after the method returns status. If the method returns OK,
+     * {@link ITunerCallback#tuneFailed} or
+     * {@link ITunerCallback#currentProgramInfoChanged} callback must be called
+     * after the tune task completes.
+     *
+     * @param program Program to tune to.
+     */
+    void tune(in ProgramSelector program);
+
+    /**
+     * Seeks the next valid program on the "air".
+     *
+     * Advance to the next detected program and stay there.
+     *
+     * Automatically cancels pending tune(), seek() or step().
+     * The method should first check whether seek can be processed by the status
+     * of tuner and inputs, schedule seek task, and then return status
+     * immediately. If a non-null callback is not set, a service-specific
+     * error {@link Result#INVALID_STATE} will be returned; otherwise, OK will
+     * be returned as status. Seek task should be processed asynchronously
+     * after the method returns status. If the method returns OK,
+     * {@link ITunerCallback#tuneFailed} or
+     * {@link ITunerCallback#currentProgramInfoChanged} callback must be called
+     * after the seek task completes.
+     *
+     * The skipSubChannel parameter is used to skip digital radio subchannels:
+     *  - HD Radio SPS;
+     *  - DAB secondary service.
+     *
+     * As an implementation detail, the HAL has the option to perform an actual
+     * seek or select the next program from the list retrieved in the
+     * background.
+     *
+     * @param directionUp {@code true} to change towards higher numeric values
+     *                    (frequency, channel number), {@code false} towards
+     *                    lower.
+     * @param skipSubChannel Don't tune to subchannels.
+     */
+    void seek(in boolean directionUp, in boolean skipSubChannel);
+
+    /**
+     * Steps to the adjacent channel, which may not be occupied by any program.
+     *
+     * Automatically cancels pending tune(), seek() or step().
+     * The method should first check whether step can be processed by the status
+     * of tuner and inputs, schedule step task, and then return status
+     * immediately. If a non-null callback is not set, service-specific
+     * error {@link Result#INVALID_STATE} will be returned; if tuning to an
+     * unoccupied channel is not supported (i.e. for satellite radio), a
+     * service-specific error {@link Result#NOT_SUPPORTED} will be returned;
+     * otherwise, OK should be returned as status. Step task should be
+     * processed asynchronously after the method returns status. If the
+     * method returns OK, {@link ITunerCallback#tuneFailed} or
+     * {@link currentProgramInfoChanged} callback must be called after the
+     * step task completes.
+     *
+     * @param directionUp {@code true} to change towards higher numeric values
+     *                    (frequency, channel number), {@code false} towards lower.
+     */
+    void step(in boolean directionUp);
+
+    /**
+     * Cancels pending tune(), seek() or step().
+     *
+     * If there is no such operation running, the call can be ignored.
+     * If cancel is called after the HAL completes an operation (tune, seek, and step)
+     * and before the callback completions, the cancel can be ignored and the callback
+     * should complete.
+     */
+    void cancel();
+
+    /**
+     * Applies a filter to the program list and starts sending program list
+     * update over {@link ITunerCallback#onProgramListUpdated} callback.
+     *
+     * There may be only one updates stream active at the moment. Calling this
+     * method again must result in cancelling the pending update request.
+     *
+     * This call clears the program list on the client side, the HAL must send
+     * the whole list again.
+     *
+     * If the program list scanning hardware (i.e. background tuner) is
+     * unavailable at the moment, the call must succeed and start updates
+     * when it becomes available.
+     *
+     * If the program list scanning is not supported by the hardware, a
+     * service-specific error {@link Result#NOT_SUPPORTED} will be returned.
+     *
+     * @param filter Filter to apply on the fetched program list.
+     */
+    void startProgramListUpdates(in ProgramFilter filter);
+
+    /**
+     * Stops sending program list updates.
+     *
+     * If stopProgramListUpdates is called after the HAL completes a program list update
+     * and before the onCurrentProgramInfoChanged callback completions,
+     * stopProgramListUpdates can be ignored and the callback should complete.
+     */
+    void stopProgramListUpdates();
+
+    /**
+     * Fetches the current setting of a given config flag.
+     *
+     * The success/failure result must be consistent with setConfigFlag.
+     *
+     * If the flag is not applicable, a service-specific error
+     * {@link Result#INVALID_STATE} will be returned. If the flag is not
+     * supported at all, a service-specific error {@link Result#NOT_SUPPORTED}
+     * will be returned.
+     *
+     * @return the current value of the flag, if succeed.
+     */
+    boolean isConfigFlagSet(in ConfigFlag flag);
+
+    /**
+     * Sets the config flag.
+     *
+     * The success/failure result must be consistent with isConfigFlagSet.
+     *
+     * If the flag is not applicable, a service-specific error
+     * {@link Result#INVALID_STATE} will be returned. If the flag is not
+     * supported at all, a service-specific error {@link Result#NOT_SUPPORTED}
+     * will be returned.
+     *
+     * @param flag Flag to set.
+     * @param value The new value of a given flag.
+     */
+    void setConfigFlag(in ConfigFlag flag, in boolean value);
+
+    /**
+     * Generic method for setting vendor-specific parameter values.
+     * The framework does not interpret the parameters, they are passed
+     * in an opaque manner between a vendor application and HAL.
+     *
+     * Framework does not make any assumptions on the keys or values, other than
+     * ones stated in VendorKeyValue documentation (a requirement of key
+     * prefixes).
+     *
+     * For each pair in the result array, the key must be one of the keys
+     * contained in the input (possibly with wildcards expanded), and the value
+     * must be a vendor-specific result status (i.e. the string "OK" or an error
+     * code). The implementation may choose to return an empty array, or only
+     * return a status for a subset of the provided inputs, at its discretion.
+     *
+     * Application and HAL must not use keys with unknown prefix. In particular,
+     * it must not place a key-value pair in results array for unknown key from
+     * parameters array - instead, an unknown key should simply be ignored.
+     * In other words, results array may contain a subset of parameter keys
+     * (however, the framework doesn't enforce a strict subset - the only
+     * formal requirement is vendor domain prefix for keys).
+     *
+     * @param parameters Vendor-specific key-value pairs.
+     * @return Operation completion status for parameters being set.
+     */
+    VendorKeyValue[] setParameters(in VendorKeyValue[] parameters);
+
+    /**
+     * Generic method for retrieving vendor-specific parameter values.
+     * The framework does not interpret the parameters, they are passed
+     * in an opaque manner between a vendor application and HAL.
+     *
+     * Framework does not cache set/get requests, so it's allowed for
+     * getParameter to return a different value than previous setParameter call.
+     *
+     * The syntax and semantics of keys are up to the vendor (as long as prefix
+     * rules are obeyed). For instance, vendors may include some form of
+     * wildcard support. In such case, result array may be of different size
+     * than requested keys array. However, wildcards are not recognized by
+     * framework and they are passed as-is to the HAL implementation.
+     *
+     * Unknown keys must be ignored and not placed into results array.
+     *
+     * @param keys Parameter keys to fetch.
+     * @return Vendor-specific key-value pairs.
+     */
+    VendorKeyValue[] getParameters(in String[] keys);
+
+    /**
+     * Fetches image from radio module cache.
+     *
+     * This is out-of-band transport mechanism for images carried with metadata.
+     * The metadata array only passes the identifier, so the client may cache
+     * images or even not fetch them.
+     *
+     * The identifier may be any arbitrary number (i.e. sha256 prefix) selected
+     * by the vendor. It must be stable so the application may cache it.
+     *
+     * The data must be a valid PNG, JPEG, GIF or BMP file, and must be less
+     * than 1MB, due to hard limit on binder transaction buffer.
+     *
+     * Image data with an invalid format must be handled gracefully in the same
+     * way as a missing image.
+     *
+     * The image identifier may become invalid after some time from passing it
+     * with metadata struct (due to resource cleanup at the HAL implementation).
+     * However, it must remain valid for a currently tuned program at least
+     * until onCurrentProgramInfoChanged is called.
+     *
+     * @param id Identifier of an image (value of {@link IBroadcastRadio#INVALID_IMAGE}
+     *           is reserved and must be treated as invalid image).
+     * @return A binary blob with image data
+     *         or a zero-length array if identifier doesn't exist.
+     */
+    byte[] getImage(in int id);
+
+    /**
+     * Registers announcement listener.
+     *
+     * If there is at least one observer registered, HAL implementation must
+     * notify about announcements.
+     *
+     * If the observer dies, the HAL implementation must unregister observer
+     * automatically.
+     *
+     * If the tuner doesn't support announcements, a service-specific error
+     * {@link Result#NOT_SUPPORTED} will be returned.
+     *
+     * @param listener The listener interface.
+     * @param enabled The list of announcement types to watch for.
+     * @return a handle to unregister observer.
+     */
+    ICloseHandle registerAnnouncementListener(
+            in IAnnouncementListener listener, in AnnouncementType[] enabled);
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ICloseHandle.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ICloseHandle.aidl
new file mode 100644
index 0000000..4a3240b
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ICloseHandle.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Represents a generic close handle to remove a callback that doesn't need
+ * active interface.
+ */
+@VintfStability
+interface ICloseHandle {
+    /**
+     * Closes the handle.
+     *
+     * The call must not fail and must only be issued once.
+     *
+     * After the close call is executed, no other calls to this interface
+     * are allowed. If the call is issued second time, a service-specific
+     * error {@link Result#INVALID_STATE} will be returned.
+     */
+    void close();
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl
new file mode 100644
index 0000000..8de12c8
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.ConfigFlag;
+import android.hardware.broadcastradio.ProgramInfo;
+import android.hardware.broadcastradio.ProgramListChunk;
+import android.hardware.broadcastradio.ProgramSelector;
+import android.hardware.broadcastradio.Result;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+@VintfStability
+oneway interface ITunerCallback {
+    /**
+     * Method called by the HAL when a tuning operation fails asynchronously
+     * following {@link IBroadcastRadio#tune}, {@link IBroadcastRadio#seek}
+     * or {@link IBroadcastRadio#step}.
+     *
+     * This callback is only called when the tune(), seek() or step() command
+     * succeeds without returning any error at first.
+     *
+     * @param result {@link Result#TIMEOUT} in case that tune(), seek() or
+     *               step() is not completed within
+     *               @link IBroadcastRadio#TUNER_TIMEOUT_MS}
+     *               or {@link Result#CANCELED} if the command was canceled.
+     * @param selector A ProgramSelector structure passed from tune() call;
+     *                 empty for step() and seek().
+     */
+    void onTuneFailed(in Result result, in ProgramSelector selector);
+
+    /**
+     * Method called by the HAL when current program information (including
+     * metadata) is updated. It must be called when {@link IBroadcastRadio#tune}
+     * {@link IBroadcastRadio#seek} or {@link IBroadcastRadio#step} command
+     * succeeds.
+     *
+     * This is also called when the radio tuned to the static (not a valid
+     * station), see {@link ProgramInfo#FLAG_TUNABLE} flag.
+     *
+     * @param info Current program information.
+     */
+    void onCurrentProgramInfoChanged(in ProgramInfo info);
+
+    /**
+     * A delta update of the program list, called whenever there's a change in
+     * the list.
+     *
+     * If there are frequent changes, HAL implementation must throttle the rate
+     * of the updates.
+     *
+     * There is a hard limit on binder transaction buffer, and the list must
+     * not exceed it. For large lists, HAL implementation must split them to
+     * multiple chunks, no larger than 500kiB each, and call this program list
+     * update callback method separately.
+     *
+     * @param chunk A chunk of the program list update.
+     */
+    void onProgramListUpdated(in ProgramListChunk chunk);
+
+    /**
+     * Method called by the HAL when the antenna gets connected or disconnected.
+     *
+     * For broadcast radio service, client must assume the antenna is connected.
+     * If it's not, then antennaStateChange must be called within
+     * {@link IBroadcastRadio#ANTENNA_STATE_CHANGE_TIMEOUT_MS} to indicate that.
+     *
+     * @param connected {@code true} if the antenna is now connected, {@code false}
+     * otherwise.
+     */
+    void onAntennaStateChange(in boolean connected);
+
+    /**
+     * Generic callback for passing updates to config flags.
+     *
+     * It's up to the HAL implementation if and how to implement this callback,
+     * as long as it obeys the prefix rule. However, setConfigFlag must not
+     * trigger this callback, while an internal event can change config flag
+     * asynchronously at the HAL layer.
+     *
+     * @param flag Flag that has changed.
+     * @param value The new value of the given flag.
+     */
+    void onConfigFlagUpdated(in ConfigFlag flag, in boolean value);
+
+    /**
+     * Generic callback for passing updates to vendor-specific parameter values.
+     * The framework does not interpret the parameters, they are passed
+     * in an opaque manner between a vendor application and HAL.
+     *
+     * It's up to the HAL implementation if and how to implement this callback,
+     * as long as it obeys the prefix rule. In particular, only selected keys
+     * may be notified this way. However, setParameters must not trigger
+     * this callback, while an internal event can change parameters
+     * asynchronously at the HAL layer.
+     *
+     * @param parameters Vendor-specific key-value pairs,
+     *                   opaque to Android framework.
+     */
+    void onParametersUpdated(in VendorKeyValue[] parameters);
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
new file mode 100644
index 0000000..646c502
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Type of program identifier component.
+ *
+ * Each identifier type corresponds to exactly one radio technology,
+ * i.e. DAB_ENSEMBLE is specifically for DAB.
+ *
+ * VENDOR identifier types must be opaque to the framework.
+ *
+ * The value format for each (but VENDOR_*) identifier is strictly defined
+ * to maintain interoperability between devices made by different vendors.
+ *
+ * All other values are reserved for future use.
+ * Values not matching any enumerated constant must be ignored.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum IdentifierType {
+    /**
+     * Primary/secondary identifier for vendor-specific radio technology.
+     * The value format is determined by a vendor.
+     *
+     * The vendor identifiers have limited serialization capabilities - see
+     * ProgramSelector description.
+     */
+    VENDOR_START = 1000,
+
+    /**
+     * See VENDOR_START
+     */
+    VENDOR_END = 1999,
+
+    /**
+     * Undefined identifier type.
+     */
+    INVALID = 0,
+
+    /**
+     * Primary identifier for analogue (without RDS) AM/FM stations:
+     * frequency in kHz.
+     *
+     * This identifier also contains band information:
+     *  - <500kHz: AM LW;
+     *  - 500kHz - 1705kHz: AM MW;
+     *  - 1.71MHz - 30MHz: AM SW;
+     *  - >60MHz: FM.
+     */
+    AMFM_FREQUENCY_KHZ,
+
+    /**
+     * 16bit primary identifier for FM RDS station.
+     */
+    RDS_PI,
+
+    /**
+     * 64bit compound primary identifier for HD Radio.
+     *
+     * Consists of (from the LSB):
+     * - 32bit: Station ID number;
+     * - 4bit: HD Radio subchannel;
+     * - 18bit: AMFM_FREQUENCY_KHZ.
+     *
+     * While station ID number should be unique globally, it sometimes get
+     * abused by broadcasters (i.e. not being set at all). To ensure local
+     * uniqueness, AMFM_FREQUENCY_KHZ was added here. Global uniqueness is
+     * a best-effort - see HD_STATION_NAME.
+     *
+     * HD Radio subchannel is a value in range 0-7.
+     * This index is 0-based (where 0 is MPS and 1..7 are SPS),
+     * as opposed to HD Radio standard (where it's 1-based).
+     *
+     * The remaining bits should be set to zeros when writing on the chip side
+     * and ignored when read.
+     */
+
+    HD_STATION_ID_EXT,
+
+    /**
+     * 64bit additional identifier for HD Radio.
+     *
+     * Due to Station ID abuse, some HD_STATION_ID_EXT identifiers may be not
+     * globally unique. To provide a best-effort solution, a short version of
+     * station name may be carried as additional identifier and may be used
+     * by the tuner hardware to double-check tuning.
+     *
+     * The name is limited to the first 8 A-Z0-9 characters (lowercase letters
+     * must be converted to uppercase). Encoded in little-endian ASCII:
+     * the first character of the name is the LSB.
+     *
+     * For example: "Abc" is encoded as 0x434241.
+     */
+    HD_STATION_NAME,
+
+    /**
+     * 44bit compound primary identifier for Digital Audio Broadcasting and
+     * Digital Multimeida Broadcasting.
+     *
+     * Consists of (from the LSB):
+     * - 32bit: SId;
+     * - 8bit: ECC code;
+     * - 4bit: SCIdS.
+     *
+     * SCIdS (Service Component Identifier within the Service) value
+     * of 0 represents the main service, while 1 and above represents
+     * secondary services.
+     *
+     * The remaining bits should be set to zeros when writing on the chip side
+     * and ignored when read.
+     */
+    DAB_SID_EXT,
+
+    /**
+     * 16bit
+     */
+    DAB_ENSEMBLE,
+
+    /**
+     * 12bit
+     */
+    DAB_SCID,
+
+    /**
+     * kHz (see AMFM_FREQUENCY_KHZ)
+     */
+    DAB_FREQUENCY_KHZ,
+
+    /**
+     * 24bit primary identifier for Digital Radio Mondiale.
+     */
+    DRMO_SERVICE_ID,
+
+    /**
+     * kHz (see AMFM_FREQUENCY_KHZ)
+     */
+    DRMO_FREQUENCY_KHZ,
+
+    /**
+     * 32bit primary identifier for SiriusXM Satellite Radio.
+     */
+    SXM_SERVICE_ID = DRMO_FREQUENCY_KHZ + 2,
+
+    /**
+     * 0-999 range
+     */
+    SXM_CHANNEL,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
new file mode 100644
index 0000000..3298cac
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * An element of metadata array.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+union Metadata {
+    /**
+     * RDS PS (string)
+     */
+    String rdsPs;
+
+    /**
+     * RDS PTY (uint8_t)
+     */
+    int rdsPty;
+
+    /**
+     * RBDS PTY (uint8_t)
+     */
+    int rbdsPty;
+
+    /**
+     * RDS RT (string)
+     */
+    String rdsRt;
+
+    /**
+     * Song title (string)
+     */
+    String songTitle;
+
+    /**
+     * Artist name (string)
+     */
+    String songArtist;
+
+    /**
+     * Album name (string)
+     */
+    String songAlbum;
+
+    /**
+     * Station icon (uint32_t, see {@link IBroadcastRadio#getImage})
+     */
+    int stationIcon;
+
+    /**
+     * Album art (uint32_t, see {@link IBroadcastRadio#getImage})
+     */
+    int albumArt;
+
+    /**
+     * Station name.
+     *
+     * This is a generic field to cover any radio technology.
+     *
+     * If the PROGRAM_NAME has the same content as DAB_*_NAME or RDS_PS,
+     * it may not be present, to preserve space - framework must repopulate
+     * it on the client side.
+     */
+    String programName;
+
+    /**
+     * DAB ensemble name (string)
+     */
+    String dabEnsembleName;
+
+    /**
+     * DAB ensemble name abbreviated (string).
+     *
+     * The string must be up to 8 characters long.
+     *
+     * If the short variant is present, the long (DAB_ENSEMBLE_NAME) one must be
+     * present as well.
+     */
+    String dabEnsembleNameShort;
+
+    /**
+     * DAB service name (string)
+     */
+    String dabServiceName;
+
+    /**
+     * DAB service name abbreviated (see DAB_ENSEMBLE_NAME_SHORT) (string)
+     */
+    String dabServiceNameShort;
+
+    /**
+     * DAB component name (string)
+     */
+    String dabComponentName;
+
+    /**
+     * DAB component name abbreviated (see DAB_ENSEMBLE_NAME_SHORT) (string)
+     */
+    String dabComponentNameShort;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramFilter.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramFilter.aidl
new file mode 100644
index 0000000..3dd10eb
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramFilter.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.IdentifierType;
+import android.hardware.broadcastradio.ProgramIdentifier;
+
+/**
+ * Large-grain filter to the program list.
+ *
+ * This is meant to reduce binder transaction bandwidth, not for fine-grained
+ * filtering user might expect.
+ *
+ * The filter is designed as conjunctive normal form: the entry that passes the
+ * filter must satisfy all the clauses (members of this struct). Vector clauses
+ * are disjunctions of literals. In other words, there is AND between each
+ * high-level group and OR inside it.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramFilter {
+    /**
+     * List of identifier types that are filtered by the filter.
+     *
+     * If the program list entry contains at least one identifier of the type
+     * listed, it satisfies this condition.
+     *
+     * Empty list means no filtering on identifier type.
+     */
+    IdentifierType[] identifierTypes;
+
+    /**
+     * List of identifiers that are filtered by the filter.
+     *
+     * If the program list entry contains at least one listed identifier,
+     * it satisfies this condition.
+     *
+     * Empty list means no filtering on identifier.
+     */
+    ProgramIdentifier[] identifiers;
+
+    /**
+     * Includes non-tunable entries that define tree structure on the
+     * program list (i.e. DAB ensembles).
+     */
+    boolean includeCategories;
+
+    /**
+     * Disables updates on entry modifications.
+     *
+     * If {@code true}, 'modified' vector of {@link ProgramListChunk} must contain
+     * list additions only. Once the program is added to the list, it's not
+     * updated anymore.
+     */
+    boolean excludeModifications;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl
new file mode 100644
index 0000000..2057d97
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.IdentifierType;
+
+/**
+ * A single program identifier component, i.e. frequency or channel ID.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramIdentifier {
+    /**
+     * Maps to IdentifierType enum.
+     */
+    IdentifierType type = IdentifierType.INVALID;
+
+    /**
+     * The uint64_t value field holds the value in format described in comments
+     * for IdentifierType enum.
+     */
+    long value;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
new file mode 100644
index 0000000..7632c81
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.Metadata;
+import android.hardware.broadcastradio.ProgramIdentifier;
+import android.hardware.broadcastradio.ProgramSelector;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+/**
+ * Program (channel, station) information.
+ *
+ * Carries both user-visible information (like station name) and technical
+ * details (tuning selector).
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramInfo {
+    /**
+     * Set when the program is currently playing live stream.
+     * This may result in a slightly altered reception parameters,
+     * usually targeted at reduced latency.
+     */
+    const int FLAG_LIVE = 1 << 0;
+
+    /**
+     * Radio stream is not playing, ie. due to bad reception conditions or
+     * buffering. In this state volume knob MAY be disabled to prevent user
+     * increasing volume too much.
+     */
+    const int FLAG_MUTED = 1 << 1;
+
+    /**
+     * Station broadcasts traffic information regularly,
+     * but not necessarily right now.
+     */
+    const int FLAG_TRAFFIC_PROGRAM = 1 << 2;
+
+    /**
+     * Station is broadcasting traffic information at the very moment.
+     */
+    const int FLAG_TRAFFIC_ANNOUNCEMENT = 1 << 3;
+
+    /**
+     * Station can be tuned to (not playing static).
+     *
+     * It's the same condition that would stop a seek operation
+     * (i.e. {@link IBroadcastRadio#seek}).
+     *
+     * By definition, this flag must be set for all items on the program list.
+     */
+    const int FLAG_TUNABLE = 1 << 4;
+
+    /**
+     * Audio stream is MONO if this bit is not set.
+     */
+    const int FLAG_STEREO = 1 << 5;
+
+    /**
+     * An identifier used to point at the program (primarily to tune to it).
+     *
+     * This field is required - its type field must not be set to
+     * {@link IdentifierType#INVALID}.
+     */
+    ProgramSelector selector;
+
+    /**
+     * Identifier currently used for program selection.
+     *
+     * It allows to determine which technology is currently used for reception.
+     *
+     * Some program selectors contain tuning information for different radio
+     * technologies (i.e. FM RDS and DAB). For example, user may tune using
+     * a ProgramSelector with RDS_PI primary identifier, but the tuner hardware
+     * may choose to use DAB technology to make actual tuning. This identifier
+     * must reflect that.
+     *
+     * This field is required for currently tuned program only.
+     * For all other items on the program list, its type field must be
+     * initialized to {@link IdentifierType#INVALID}.
+     *
+     * Only primary identifiers for a given radio technology are valid:
+     *  - AMFM_FREQUENCY_KHZ for analog AM/FM;
+     *  - RDS_PI for FM RDS;
+     *  - HD_STATION_ID_EXT;
+     *  - DAB_SID_EXT;
+     *  - DRMO_SERVICE_ID;
+     *  - SXM_SERVICE_ID;
+     *  - VENDOR_*;
+     *  - more might come in next minor versions of this HAL.
+     */
+    ProgramIdentifier logicallyTunedTo;
+
+    /**
+     * Identifier currently used by hardware to physically tune to a channel.
+     *
+     * Some radio technologies broadcast the same program on multiple channels,
+     * i.e. with RDS AF the same program may be broadcasted on multiple
+     * alternative frequencies; the same DAB program may be broadcast on
+     * multiple ensembles. This identifier points to the channel to which the
+     * radio hardware is physically tuned to.
+     *
+     * This field is required for currently tuned program only.
+     * For all other items on the program list, its type field must be
+     * initialized to {@link IdentifierType#INVALID}.
+     *
+     * Only physical identifiers are valid:
+     *  - AMFM_FREQUENCY_KHZ;
+     *  - DAB_FREQUENCY_KHZ;
+     *  - DRMO_FREQUENCY_KHZ;
+     *  - SXM_CHANNEL;
+     *  - VENDOR_*;
+     *  - more might come in next minor versions of this HAL.
+     */
+    ProgramIdentifier physicallyTunedTo;
+
+    /**
+     * Primary identifiers of related contents.
+     *
+     * Some radio technologies provide pointers to other programs that carry
+     * related content (i.e. DAB soft-links). This field is a list of pointers
+     * to other programs on the program list.
+     *
+     * This is not a list of programs that carry the same content (i.e.
+     * DAB hard-links, RDS AF). Switching to programs from this list usually
+     * require user action.
+     *
+     * Please note, that these identifiers do not have to exist on the program
+     * list - i.e. DAB tuner may provide information on FM RDS alternatives
+     * despite not supporting FM RDS. If the system has multiple tuners, another
+     * one may have it on its list.
+     *
+     * This field is optional.
+     */
+    @nullable ProgramIdentifier[] relatedContent;
+
+    /**
+     * Program flags.
+     *
+     * It can be a combination of {@link #FLAG_LIVE}, {@link #FLAG_MUTED},
+     * {@link #FLAG_TRAFFIC_PROGRAM}, {@link #FLAG_TRAFFIC_ANNOUNCEMENT},
+     * {@link #FLAG_TUNABLE}, and {@link #FLAG_STEREO}.
+     */
+    int infoFlags;
+
+    /**
+     * Signal quality measured in 0% to 100% range to be shown in the UI.
+     */
+    int signalQuality;
+
+    /**
+     * Program metadata (station name, PTY, song title).
+     */
+    Metadata[] metadata;
+
+    /**
+     * Vendor-specific information.
+     *
+     * It may be used for extra features, not supported by the platform,
+     * for example: paid-service=true; bitrate=320kbps.
+     */
+    VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramListChunk.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramListChunk.aidl
new file mode 100644
index 0000000..a62d461
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramListChunk.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.ProgramIdentifier;
+import android.hardware.broadcastradio.ProgramInfo;
+
+/**
+ * An update packet of the program list.
+ *
+ * The order of entries in the arrays is unspecified.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramListChunk {
+    /**
+     * Treats all previously added entries as removed.
+     *
+     * This is meant to save binder transaction bandwidth on 'removed' array
+     * and provide a clear empty state.
+     *
+     * If set, 'removed' array must be null.
+     *
+     * The client may wait with taking action on this until it received the
+     * chunk with complete flag set (to avoid part of stations temporarily
+     * disappearing from the list).
+     */
+    boolean purge;
+
+    /**
+     * If false, it means there are still programs not transmitted,
+     * due for transmission in following updates.
+     *
+     * Used by UIs that wait for complete list instead of displaying
+     * programs while scanning.
+     *
+     * After the whole channel range was scanned and all discovered programs
+     * were transmitted, the last chunk must have set this flag to {@code true}.
+     * This must happen within {@link IBroadcastRadio#LIST_COMPLETE_TIMEOUT_MS}
+     * from the startProgramListUpdates call. If it doesn't, client may assume
+     * the tuner came into a bad state and display error message.
+     */
+    boolean complete;
+
+    /**
+     * Added or modified program list entries.
+     *
+     * Two entries with the same primaryId (ProgramSelector member)
+     * are considered the same.
+     */
+    ProgramInfo[] modified;
+
+    /**
+     * Removed program list entries.
+     *
+     * Contains primaryId (ProgramSelector member) of a program to remove.
+     */
+    @nullable ProgramIdentifier[] removed;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
new file mode 100644
index 0000000..71b824b
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.ProgramIdentifier;
+
+/**
+ * A set of identifiers necessary to tune to a given station.
+ *
+ * This can hold a combination of various identifiers, like:
+ * - AM/FM frequency,
+ * - HD Radio subchannel,
+ * - DAB service ID.
+ *
+ * The type of radio technology is determined by the primary identifier - if the
+ * primary identifier is for DAB, the program is DAB. However, a program of a
+ * specific radio technology may have additional secondary identifiers for other
+ * technologies, i.e. a satellite program may have FM fallback frequency,
+ * if a station broadcasts both via satellite and FM.
+ *
+ * The identifiers from VENDOR_START..VENDOR_END range have limited
+ * serialization capabilities: they are serialized locally, but ignored by the
+ * cloud services. If a program has primary id from vendor range, it's not
+ * synchronized with other devices at all.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramSelector {
+    /**
+     * Primary program identifier.
+     *
+     * This identifier uniquely identifies a station and can be used for
+     * equality check.
+     *
+     * It can hold only a subset of identifier types, one per each
+     * radio technology:
+     *  - analogue AM/FM: AMFM_FREQUENCY_KHZ;
+     *  - FM RDS: RDS_PI;
+     *  - HD Radio: HD_STATION_ID_EXT;
+     *  - DAB/DMB: DAB_SID_EXT;
+     *  - Digital Radio Mondiale: DRMO_SERVICE_ID;
+     *  - SiriusXM: SXM_SERVICE_ID;
+     *  - vendor-specific: VENDOR_START..VENDOR_END.
+     */
+    ProgramIdentifier primaryId;
+
+    /**
+     * Secondary program identifiers.
+     *
+     * These identifiers are supplementary and can speed up tuning process,
+     * but the primary ID should be sufficient (i.e. RDS PI is enough to select
+     * a station from the list after a full band scan).
+     *
+     * Two selectors with different secondary IDs, but the same primary ID are
+     * considered equal. In particular, secondary IDs array may get updated for
+     * an entry on the program list (ie. when a better frequency for a given
+     * station is found).
+     *
+     * If DAB_SID_EXT is used as primaryId, using DAB_ENSEMBLE or DAB_FREQUENCY_KHZ
+     * as secondray identifiers can uniquely identify the DAB station.
+     */
+    ProgramIdentifier[] secondaryIds;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Properties.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Properties.aidl
new file mode 100644
index 0000000..36cbaff
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Properties.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.IdentifierType;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+/**
+ * Properties of a given broadcast radio module.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable Properties {
+    /**
+     * A company name who made the radio module. Must be a valid, registered
+     * name of the company itself.
+     *
+     * It must be opaque to the Android framework.
+     */
+    String maker;
+
+    /**
+     * A product name. Must be unique within the company.
+     *
+     * It must be opaque to the Android framework.
+     */
+    String product;
+
+    /**
+     * Version of the hardware module.
+     *
+     * It must be opaque to the Android framework.
+     */
+    String version;
+
+    /**
+     * Hardware serial number (for subscription services).
+     *
+     * It must be opaque to the Android framework.
+     */
+    String serial;
+
+    /**
+     * A list of supported {@link IdentifierType} values.
+     *
+     * If an identifier is supported by radio module, it means it can use it for
+     * tuning to ProgramSelector with either primary or secondary Identifier of
+     * a given type.
+     *
+     * Support for VENDOR identifier type does not guarantee compatibility, as
+     * other module properties (implementor, product, version) must be checked.
+     */
+    IdentifierType[] supportedIdentifierTypes;
+
+    /**
+     * Vendor-specific information.
+     *
+     * It may be used for extra features, not supported by the platform,
+     * for example: com.me.preset-slots=6; com.me.ultra-hd-capable={@code false}.
+     */
+    VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl
new file mode 100644
index 0000000..f775bd0
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Result for methods of BroadcastRadio AIDL HAL interfaces.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum Result {
+    /**
+     * Methods run without error.
+     */
+    OK = 0,
+
+    /**
+     * Internal error in HAL.
+     */
+    INTERNAL_ERROR,
+
+    /**
+     * Error used when the input argument for the method is invalid.
+     */
+    INVALID_ARGUMENTS,
+
+    /**
+     * Error used when the service is on invalid state (i.e. callback
+     * is not registered for IBroadcastRadio).
+     */
+    INVALID_STATE,
+
+    /**
+     * Error used when an operation is not supported.
+     */
+    NOT_SUPPORTED,
+
+    /**
+     * Error used when a tune, seek, or step operation is not completed
+     * within {@link IBroadcastRadio#TUNER_TIMEOUT_MS}.
+     */
+    TIMEOUT,
+
+    /**
+     * Error used when a tune, seek, or step operation is canceled before
+     * being processed.
+     */
+    CANCELED,
+
+    /**
+     * Error that does not follow into the error categories above.
+     */
+    UNKNOWN_ERROR,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/VendorKeyValue.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/VendorKeyValue.aidl
new file mode 100644
index 0000000..c923e92
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/VendorKeyValue.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * A key-value pair for vendor-specific information to be passed as-is through
+ * Android framework to the front-end application.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable VendorKeyValue {
+    /**
+     * Key must start with unique vendor Java-style namespace,
+     * eg. 'com.somecompany.parameter1'.
+     */
+    String key;
+
+    /**
+     * Value must be passed through the framework without any changes.
+     * Format of this string can vary across vendors.
+     */
+    String value;
+}
diff --git a/broadcastradio/aidl/default/Android.bp b/broadcastradio/aidl/default/Android.bp
new file mode 100644
index 0000000..720aa8a
--- /dev/null
+++ b/broadcastradio/aidl/default/Android.bp
@@ -0,0 +1,54 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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_binary {
+    name: "android.hardware.broadcastradio-service.default",
+    relative_install_path: "hw",
+    init_rc: ["broadcastradio-default.rc"],
+    vintf_fragments: ["broadcastradio-default.xml"],
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    srcs: [
+        "BroadcastRadio.cpp",
+        "main.cpp",
+        "VirtualProgram.cpp",
+        "VirtualRadio.cpp",
+    ],
+    static_libs: [
+        "android.hardware.broadcastradio@common-utils-aidl-lib",
+        "android.hardware.broadcastradio@common-utils-lib",
+    ],
+    shared_libs: [
+        "android.hardware.broadcastradio-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "liblog",
+        "libcutils",
+    ],
+}
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
new file mode 100644
index 0000000..c0c475a
--- /dev/null
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -0,0 +1,802 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BroadcastRadio.h"
+#include <broadcastradio-utils-aidl/Utils.h>
+#include "resources.h"
+
+#include <aidl/android/hardware/broadcastradio/IdentifierType.h>
+#include <aidl/android/hardware/broadcastradio/Result.h>
+
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+
+#include <private/android_filesystem_config.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+using ::aidl::android::hardware::broadcastradio::utils::resultToInt;
+using ::aidl::android::hardware::broadcastradio::utils::tunesTo;
+using ::android::base::EqualsIgnoreCase;
+using ::ndk::ScopedAStatus;
+using ::std::literals::chrono_literals::operator""ms;
+using ::std::literals::chrono_literals::operator""s;
+using ::std::lock_guard;
+using ::std::mutex;
+using ::std::string;
+using ::std::vector;
+
+namespace {
+
+inline constexpr std::chrono::milliseconds kSeekDelayTimeMs = 200ms;
+inline constexpr std::chrono::milliseconds kStepDelayTimeMs = 100ms;
+inline constexpr std::chrono::milliseconds kTuneDelayTimeMs = 150ms;
+inline constexpr std::chrono::seconds kListDelayTimeS = 1s;
+
+// clang-format off
+const AmFmRegionConfig kDefaultAmFmConfig = {
+        {
+                {87500, 108000, 100, 100},  // FM
+                {153, 282, 3, 9},           // AM LW
+                {531, 1620, 9, 9},          // AM MW
+                {1600, 30000, 1, 5},        // AM SW
+        },
+        AmFmRegionConfig::DEEMPHASIS_D50,
+        AmFmRegionConfig::RDS};
+// clang-format on
+
+Properties initProperties(const VirtualRadio& virtualRadio) {
+    Properties prop = {};
+
+    prop.maker = "Android";
+    prop.product = virtualRadio.getName();
+    prop.supportedIdentifierTypes = vector<IdentifierType>({
+            IdentifierType::AMFM_FREQUENCY_KHZ,
+            IdentifierType::RDS_PI,
+            IdentifierType::HD_STATION_ID_EXT,
+            IdentifierType::DAB_SID_EXT,
+    });
+    prop.vendorInfo = vector<VendorKeyValue>({
+            {"com.android.sample", "sample"},
+    });
+
+    return prop;
+}
+
+// Makes ProgramInfo that does not point to any particular program
+ProgramInfo makeSampleProgramInfo(const ProgramSelector& selector) {
+    ProgramInfo info = {};
+    info.selector = selector;
+    info.logicallyTunedTo =
+            utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
+                                  utils::getId(selector, IdentifierType::AMFM_FREQUENCY_KHZ));
+    info.physicallyTunedTo = info.logicallyTunedTo;
+    return info;
+}
+
+static bool checkDumpCallerHasWritePermissions(int fd) {
+    uid_t uid = AIBinder_getCallingUid();
+    if (uid == AID_ROOT || uid == AID_SHELL || uid == AID_SYSTEM) {
+        return true;
+    }
+    dprintf(fd, "BroadcastRadio HAL dump must be root, shell or system\n");
+    return false;
+}
+
+}  // namespace
+
+BroadcastRadio::BroadcastRadio(const VirtualRadio& virtualRadio)
+    : mVirtualRadio(virtualRadio),
+      mAmFmConfig(kDefaultAmFmConfig),
+      mProperties(initProperties(virtualRadio)) {
+    const auto& ranges = kDefaultAmFmConfig.ranges;
+    if (ranges.size() > 0) {
+        ProgramSelector sel = utils::makeSelectorAmfm(ranges[0].lowerBound);
+        VirtualProgram virtualProgram = {};
+        if (mVirtualRadio.getProgram(sel, &virtualProgram)) {
+            mCurrentProgram = virtualProgram.selector;
+        } else {
+            mCurrentProgram = sel;
+        }
+    }
+}
+
+BroadcastRadio::~BroadcastRadio() {
+    mThread.reset();
+}
+
+ScopedAStatus BroadcastRadio::getAmFmRegionConfig(bool full, AmFmRegionConfig* returnConfigs) {
+    if (full) {
+        *returnConfigs = {};
+        returnConfigs->ranges = vector<AmFmBandRange>({
+                {65000, 108000, 10, 0},  // FM
+                {150, 30000, 1, 0},      // AM
+        });
+        returnConfigs->fmDeemphasis =
+                AmFmRegionConfig::DEEMPHASIS_D50 | AmFmRegionConfig::DEEMPHASIS_D75;
+        returnConfigs->fmRds = AmFmRegionConfig::RDS | AmFmRegionConfig::RBDS;
+        return ScopedAStatus::ok();
+    }
+    lock_guard<mutex> lk(mMutex);
+    *returnConfigs = mAmFmConfig;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::getDabRegionConfig(vector<DabTableEntry>* returnConfigs) {
+    *returnConfigs = {
+            {"5A", 174928},  {"7D", 194064},  {"8A", 195936},  {"8B", 197648},  {"9A", 202928},
+            {"9B", 204640},  {"9C", 206352},  {"10B", 211648}, {"10C", 213360}, {"10D", 215072},
+            {"11A", 216928}, {"11B", 218640}, {"11C", 220352}, {"11D", 222064}, {"12A", 223936},
+            {"12B", 225648}, {"12C", 227360}, {"12D", 229072},
+    };
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::getImage(int32_t id, vector<uint8_t>* returnImage) {
+    LOG(DEBUG) << __func__ << ": fetching image " << std::hex << id;
+
+    if (id == resources::kDemoPngId) {
+        *returnImage = vector<uint8_t>(resources::kDemoPng, std::end(resources::kDemoPng));
+        return ScopedAStatus::ok();
+    }
+
+    LOG(WARNING) << __func__ << ": image of id " << std::hex << id << " doesn't exist";
+    *returnImage = {};
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::getProperties(Properties* returnProperties) {
+    lock_guard<mutex> lk(mMutex);
+    *returnProperties = mProperties;
+    return ScopedAStatus::ok();
+}
+
+ProgramInfo BroadcastRadio::tuneInternalLocked(const ProgramSelector& sel) {
+    LOG(DEBUG) << __func__ << ": tune (internal) to " << sel.toString();
+
+    VirtualProgram virtualProgram = {};
+    ProgramInfo programInfo;
+    if (mVirtualRadio.getProgram(sel, &virtualProgram)) {
+        mCurrentProgram = virtualProgram.selector;
+        programInfo = virtualProgram;
+    } else {
+        mCurrentProgram = sel;
+        programInfo = makeSampleProgramInfo(sel);
+    }
+    mIsTuneCompleted = true;
+
+    return programInfo;
+}
+
+ScopedAStatus BroadcastRadio::setTunerCallback(const std::shared_ptr<ITunerCallback>& callback) {
+    LOG(DEBUG) << __func__ << ": setTunerCallback";
+
+    if (callback == nullptr) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                resultToInt(Result::INVALID_ARGUMENTS), "cannot set tuner callback to null");
+    }
+
+    lock_guard<mutex> lk(mMutex);
+    mCallback = callback;
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::unsetTunerCallback() {
+    LOG(DEBUG) << __func__ << ": unsetTunerCallback";
+
+    lock_guard<mutex> lk(mMutex);
+    mCallback = nullptr;
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::tune(const ProgramSelector& program) {
+    LOG(DEBUG) << __func__ << ": tune to " << program.toString() << "...";
+
+    lock_guard<mutex> lk(mMutex);
+    if (mCallback == nullptr) {
+        LOG(ERROR) << __func__ << ": callback is not registered.";
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                resultToInt(Result::INVALID_STATE), "callback is not registered");
+    }
+
+    if (!utils::isSupported(mProperties, program)) {
+        LOG(WARNING) << __func__ << ": selector not supported: " << program.toString();
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                resultToInt(Result::NOT_SUPPORTED), "selector is not supported");
+    }
+
+    if (!utils::isValid(program)) {
+        LOG(ERROR) << __func__ << ": selector is not valid: " << program.toString();
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                resultToInt(Result::INVALID_ARGUMENTS), "selector is not valid");
+    }
+
+    cancelLocked();
+
+    mIsTuneCompleted = false;
+    std::shared_ptr<ITunerCallback> callback = mCallback;
+    auto task = [this, program, callback]() {
+        ProgramInfo programInfo = {};
+        {
+            lock_guard<mutex> lk(mMutex);
+            programInfo = tuneInternalLocked(program);
+        }
+        callback->onCurrentProgramInfoChanged(programInfo);
+    };
+    auto cancelTask = [program, callback]() { callback->onTuneFailed(Result::CANCELED, program); };
+    mThread->schedule(task, cancelTask, kTuneDelayTimeMs);
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::seek(bool directionUp, bool skipSubChannel) {
+    LOG(DEBUG) << __func__ << ": seek " << (directionUp ? "up" : "down") << " with skipSubChannel? "
+               << (skipSubChannel ? "yes" : "no") << "...";
+
+    lock_guard<mutex> lk(mMutex);
+    if (mCallback == nullptr) {
+        LOG(ERROR) << __func__ << ": callback is not registered.";
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                resultToInt(Result::INVALID_STATE), "callback is not registered");
+    }
+
+    cancelLocked();
+
+    const auto& list = mVirtualRadio.getProgramList();
+    std::shared_ptr<ITunerCallback> callback = mCallback;
+    auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
+    if (list.empty()) {
+        mIsTuneCompleted = false;
+        auto task = [callback]() {
+            LOG(DEBUG) << "seek: program list is empty, seek couldn't stop";
+
+            callback->onTuneFailed(Result::TIMEOUT, {});
+        };
+        mThread->schedule(task, cancelTask, kSeekDelayTimeMs);
+
+        return ScopedAStatus::ok();
+    }
+
+    // The list is not sorted here since it has already stored in VirtualRadio.
+    // If the list is not sorted in advance, it should be sorted here.
+    const auto& current = mCurrentProgram;
+    auto found = std::lower_bound(list.begin(), list.end(), VirtualProgram({current}));
+    if (directionUp) {
+        if (found < list.end() - 1) {
+            if (tunesTo(current, found->selector)) found++;
+        } else {
+            found = list.begin();
+        }
+    } else {
+        if (found > list.begin() && found != list.end()) {
+            found--;
+        } else {
+            found = list.end() - 1;
+        }
+    }
+    const ProgramSelector tuneTo = found->selector;
+
+    mIsTuneCompleted = false;
+    auto task = [this, tuneTo, callback]() {
+        ProgramInfo programInfo = {};
+        {
+            lock_guard<mutex> lk(mMutex);
+            programInfo = tuneInternalLocked(tuneTo);
+        }
+        callback->onCurrentProgramInfoChanged(programInfo);
+    };
+    mThread->schedule(task, cancelTask, kSeekDelayTimeMs);
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::step(bool directionUp) {
+    LOG(DEBUG) << __func__ << ": step " << (directionUp ? "up" : "down") << "...";
+
+    lock_guard<mutex> lk(mMutex);
+    if (mCallback == nullptr) {
+        LOG(ERROR) << __func__ << ": callback is not registered.";
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                resultToInt(Result::INVALID_STATE), "callback is not registered");
+    }
+
+    cancelLocked();
+
+    if (!utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+        LOG(WARNING) << __func__ << ": can't step in anything else than AM/FM";
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                resultToInt(Result::NOT_SUPPORTED), "cannot step in anything else than AM/FM");
+    }
+
+    int64_t stepTo = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ);
+    std::optional<AmFmBandRange> range = getAmFmRangeLocked();
+    if (!range) {
+        LOG(ERROR) << __func__ << ": can't find current band or tune operation is in process";
+        ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                resultToInt(Result::INTERNAL_ERROR),
+                "can't find current band or tune operation is in process");
+    }
+
+    if (directionUp) {
+        stepTo += range->spacing;
+    } else {
+        stepTo -= range->spacing;
+    }
+    if (stepTo > range->upperBound) {
+        stepTo = range->lowerBound;
+    }
+    if (stepTo < range->lowerBound) {
+        stepTo = range->upperBound;
+    }
+
+    mIsTuneCompleted = false;
+    std::shared_ptr<ITunerCallback> callback = mCallback;
+    auto task = [this, stepTo, callback]() {
+        ProgramInfo programInfo;
+        {
+            lock_guard<mutex> lk(mMutex);
+            programInfo = tuneInternalLocked(utils::makeSelectorAmfm(stepTo));
+        }
+        callback->onCurrentProgramInfoChanged(programInfo);
+    };
+    auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
+    mThread->schedule(task, cancelTask, kStepDelayTimeMs);
+
+    return ScopedAStatus::ok();
+}
+
+void BroadcastRadio::cancelLocked() {
+    LOG(DEBUG) << __func__ << ": cancelling current operations...";
+
+    mThread->cancelAll();
+    if (mCurrentProgram.primaryId.type != IdentifierType::INVALID) {
+        mIsTuneCompleted = true;
+    }
+}
+
+ScopedAStatus BroadcastRadio::cancel() {
+    LOG(DEBUG) << __func__ << ": cancel pending tune, seek and step...";
+
+    lock_guard<mutex> lk(mMutex);
+    cancelLocked();
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::startProgramListUpdates(const ProgramFilter& filter) {
+    LOG(DEBUG) << __func__ << ": requested program list updates, filter = " << filter.toString()
+               << "...";
+
+    auto filterCb = [&filter](const VirtualProgram& program) {
+        return utils::satisfies(filter, program.selector);
+    };
+
+    lock_guard<mutex> lk(mMutex);
+
+    const auto& list = mVirtualRadio.getProgramList();
+    vector<VirtualProgram> filteredList;
+    std::copy_if(list.begin(), list.end(), std::back_inserter(filteredList), filterCb);
+
+    auto task = [this, filteredList]() {
+        std::shared_ptr<ITunerCallback> callback;
+        {
+            lock_guard<mutex> lk(mMutex);
+            if (mCallback == nullptr) {
+                LOG(WARNING) << "Callback is null when updating program List";
+                return;
+            }
+            callback = mCallback;
+        }
+
+        ProgramListChunk chunk = {};
+        chunk.purge = true;
+        chunk.complete = true;
+        chunk.modified = vector<ProgramInfo>(filteredList.begin(), filteredList.end());
+
+        callback->onProgramListUpdated(chunk);
+    };
+    mThread->schedule(task, kListDelayTimeS);
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::stopProgramListUpdates() {
+    LOG(DEBUG) << __func__ << ": requested program list updates to stop...";
+    // TODO(b/243681584) Implement stop program list updates method
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::isConfigFlagSet(ConfigFlag flag, [[maybe_unused]] bool* returnIsSet) {
+    LOG(DEBUG) << __func__ << ": flag = " << toString(flag);
+
+    LOG(INFO) << __func__ << ": getting ConfigFlag is not supported";
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            resultToInt(Result::NOT_SUPPORTED), "getting ConfigFlag is not supported");
+}
+
+ScopedAStatus BroadcastRadio::setConfigFlag(ConfigFlag flag, bool value) {
+    LOG(DEBUG) << __func__ << ": flag = " << toString(flag) << ", value = " << value;
+
+    LOG(INFO) << __func__ << ": setting ConfigFlag is not supported";
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            resultToInt(Result::NOT_SUPPORTED), "setting ConfigFlag is not supported");
+}
+
+ScopedAStatus BroadcastRadio::setParameters(
+        [[maybe_unused]] const vector<VendorKeyValue>& parameters,
+        vector<VendorKeyValue>* returnParameters) {
+    // TODO(b/243682330) Support vendor parameter functionality
+    *returnParameters = {};
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::getParameters([[maybe_unused]] const vector<string>& keys,
+                                            vector<VendorKeyValue>* returnParameters) {
+    // TODO(b/243682330) Support vendor parameter functionality
+    *returnParameters = {};
+    return ScopedAStatus::ok();
+}
+
+std::optional<AmFmBandRange> BroadcastRadio::getAmFmRangeLocked() const {
+    if (!mIsTuneCompleted) {
+        LOG(WARNING) << __func__ << ": tune operation is in process";
+        return {};
+    }
+    if (!utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+        LOG(WARNING) << __func__ << ": current program does not has AMFM_FREQUENCY_KHZ identifier";
+        return {};
+    }
+
+    int64_t freq = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ);
+    for (const auto& range : mAmFmConfig.ranges) {
+        if (range.lowerBound <= freq && range.upperBound >= freq) {
+            return range;
+        }
+    }
+
+    return {};
+}
+
+ScopedAStatus BroadcastRadio::registerAnnouncementListener(
+        [[maybe_unused]] const std::shared_ptr<IAnnouncementListener>& listener,
+        const vector<AnnouncementType>& enabled, std::shared_ptr<ICloseHandle>* returnCloseHandle) {
+    LOG(DEBUG) << __func__ << ": registering announcement listener for "
+               << utils::vectorToString(enabled);
+
+    // TODO(b/243683842) Support announcement listener
+    *returnCloseHandle = nullptr;
+    LOG(INFO) << __func__ << ": registering announcementListener is not supported";
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            resultToInt(Result::NOT_SUPPORTED),
+            "registering announcementListener is not supported");
+}
+
+binder_status_t BroadcastRadio::dump(int fd, const char** args, uint32_t numArgs) {
+    if (numArgs == 0) {
+        return dumpsys(fd);
+    }
+
+    string option = string(args[0]);
+    if (EqualsIgnoreCase(option, "--help")) {
+        return cmdHelp(fd);
+    } else if (EqualsIgnoreCase(option, "--tune")) {
+        return cmdTune(fd, args, numArgs);
+    } else if (EqualsIgnoreCase(option, "--seek")) {
+        return cmdSeek(fd, args, numArgs);
+    } else if (EqualsIgnoreCase(option, "--step")) {
+        return cmdStep(fd, args, numArgs);
+    } else if (EqualsIgnoreCase(option, "--cancel")) {
+        return cmdCancel(fd, numArgs);
+    } else if (EqualsIgnoreCase(option, "--startProgramListUpdates")) {
+        return cmdStartProgramListUpdates(fd, args, numArgs);
+    } else if (EqualsIgnoreCase(option, "--stopProgramListUpdates")) {
+        return cmdStopProgramListUpdates(fd, numArgs);
+    }
+    dprintf(fd, "Invalid option: %s\n", option.c_str());
+    return STATUS_BAD_VALUE;
+}
+
+binder_status_t BroadcastRadio::dumpsys(int fd) {
+    if (!checkDumpCallerHasWritePermissions(fd)) {
+        return STATUS_PERMISSION_DENIED;
+    }
+    lock_guard<mutex> lk(mMutex);
+    dprintf(fd, "AmFmRegionConfig: %s\n", mAmFmConfig.toString().c_str());
+    dprintf(fd, "Properties: %s \n", mProperties.toString().c_str());
+    if (mIsTuneCompleted) {
+        dprintf(fd, "Tune completed\n");
+    } else {
+        dprintf(fd, "Tune not completed\n");
+    }
+    if (mCallback == nullptr) {
+        dprintf(fd, "No ITunerCallback registered\n");
+    } else {
+        dprintf(fd, "ITunerCallback registered\n");
+    }
+    dprintf(fd, "CurrentProgram: %s \n", mCurrentProgram.toString().c_str());
+    return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdHelp(int fd) const {
+    dprintf(fd, "Usage: \n\n");
+    dprintf(fd, "[no args]: dumps focus listener / gain callback registered status\n");
+    dprintf(fd, "--help: shows this help\n");
+    dprintf(fd,
+            "--tune amfm <FREQUENCY>: tunes amfm radio to frequency (in Hz) specified: "
+            "frequency (int) \n"
+            "--tune dab <SID> <ENSEMBLE>: tunes dab radio to sid and ensemble specified: "
+            "sidExt (int), ensemble (int) \n");
+    dprintf(fd,
+            "--seek [up|down] <SKIP_SUB_CHANNEL>: seek with direction (up or down) and "
+            "option whether skipping sub channel: "
+            "skipSubChannel (string, should be either \"true\" or \"false\")\n");
+    dprintf(fd, "--step [up|down]: step in direction (up or down) specified\n");
+    dprintf(fd, "--cancel: cancel current pending tune, step, and seek\n");
+    dprintf(fd,
+            "--startProgramListUpdates <IDENTIFIER_TYPES> <IDENTIFIERS> <INCLUDE_CATEGORIES> "
+            "<EXCLUDE_MODIFICATIONS>: start update program list with the filter specified: "
+            "identifier types (string, in format <TYPE>,<TYPE>,...,<TYPE> or \"null\" (if empty), "
+            "where TYPE is int), "
+            "program identifiers (string, in format "
+            "<TYPE>:<VALUE>,<TYPE>:<VALUE>,...,<TYPE>:<VALUE> or \"null\" (if empty), "
+            "where TYPE is int and VALUE is long), "
+            "includeCategories (string, should be either \"true\" or \"false\"), "
+            "excludeModifications (string, should be either \"true\" or \"false\")\n");
+    dprintf(fd, "--stopProgramListUpdates: stop current pending program list updates\n");
+    dprintf(fd,
+            "Note on <TYPE> for --startProgramList command: it is int for identifier type. "
+            "Please see broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl "
+            "for its definition.\n");
+    dprintf(fd,
+            "Note on <VALUE> for --startProgramList command: it is long type for identifier value. "
+            "Please see broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl "
+            "for its value.\n");
+
+    return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdTune(int fd, const char** args, uint32_t numArgs) {
+    if (!checkDumpCallerHasWritePermissions(fd)) {
+        return STATUS_PERMISSION_DENIED;
+    }
+    if (numArgs != 3 && numArgs != 4) {
+        dprintf(fd,
+                "Invalid number of arguments: please provide --tune amfm <FREQUENCY> "
+                "or --tune dab <SID> <ENSEMBLE>\n");
+        return STATUS_BAD_VALUE;
+    }
+    bool isDab = false;
+    if (EqualsIgnoreCase(string(args[1]), "dab")) {
+        isDab = true;
+    } else if (!EqualsIgnoreCase(string(args[1]), "amfm")) {
+        dprintf(fd, "Unknown radio type provided with tune: %s\n", args[1]);
+        return STATUS_BAD_VALUE;
+    }
+    ProgramSelector sel = {};
+    if (isDab) {
+        if (numArgs != 5 && numArgs != 3) {
+            dprintf(fd,
+                    "Invalid number of arguments: please provide "
+                    "--tune dab <SID> <ENSEMBLE> <FREQUENCY> or "
+                    "--tune dab <SID>\n");
+            return STATUS_BAD_VALUE;
+        }
+        int sid;
+        if (!utils::parseArgInt(string(args[2]), &sid)) {
+            dprintf(fd, "Non-integer sid provided with tune: %s\n", args[2]);
+            return STATUS_BAD_VALUE;
+        }
+        if (numArgs == 3) {
+            sel = utils::makeSelectorDab(sid);
+        } else {
+            int ensemble;
+            if (!utils::parseArgInt(string(args[3]), &ensemble)) {
+                dprintf(fd, "Non-integer ensemble provided with tune: %s\n", args[3]);
+                return STATUS_BAD_VALUE;
+            }
+            int freq;
+            if (!utils::parseArgInt(string(args[4]), &freq)) {
+                dprintf(fd, "Non-integer frequency provided with tune: %s\n", args[4]);
+                return STATUS_BAD_VALUE;
+            }
+            sel = utils::makeSelectorDab(sid, ensemble, freq);
+        }
+    } else {
+        if (numArgs != 3) {
+            dprintf(fd, "Invalid number of arguments: please provide --tune amfm <FREQUENCY>\n");
+            return STATUS_BAD_VALUE;
+        }
+        int freq;
+        if (!utils::parseArgInt(string(args[2]), &freq)) {
+            dprintf(fd, "Non-integer frequency provided with tune: %s\n", args[2]);
+            return STATUS_BAD_VALUE;
+        }
+        sel = utils::makeSelectorAmfm(freq);
+    }
+
+    auto tuneResult = tune(sel);
+    if (!tuneResult.isOk()) {
+        dprintf(fd, "Unable to tune %s radio to %s\n", args[1], sel.toString().c_str());
+        return STATUS_BAD_VALUE;
+    }
+    dprintf(fd, "Tune %s radio to %s \n", args[1], sel.toString().c_str());
+    return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdSeek(int fd, const char** args, uint32_t numArgs) {
+    if (!checkDumpCallerHasWritePermissions(fd)) {
+        return STATUS_PERMISSION_DENIED;
+    }
+    if (numArgs != 3) {
+        dprintf(fd,
+                "Invalid number of arguments: please provide --seek <DIRECTION> "
+                "<SKIP_SUB_CHANNEL>\n");
+        return STATUS_BAD_VALUE;
+    }
+    string seekDirectionIn = string(args[1]);
+    bool seekDirectionUp;
+    if (!utils::parseArgDirection(seekDirectionIn, &seekDirectionUp)) {
+        dprintf(fd, "Invalid direction (\"up\" or \"down\") provided with seek: %s\n",
+                seekDirectionIn.c_str());
+        return STATUS_BAD_VALUE;
+    }
+    string skipSubChannelIn = string(args[2]);
+    bool skipSubChannel;
+    if (!utils::parseArgBool(skipSubChannelIn, &skipSubChannel)) {
+        dprintf(fd, "Invalid skipSubChannel (\"true\" or \"false\") provided with seek: %s\n",
+                skipSubChannelIn.c_str());
+        return STATUS_BAD_VALUE;
+    }
+
+    auto seekResult = seek(seekDirectionUp, skipSubChannel);
+    if (!seekResult.isOk()) {
+        dprintf(fd, "Unable to seek in %s direction\n", seekDirectionIn.c_str());
+        return STATUS_BAD_VALUE;
+    }
+    dprintf(fd, "Seek in %s direction\n", seekDirectionIn.c_str());
+    return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdStep(int fd, const char** args, uint32_t numArgs) {
+    if (!checkDumpCallerHasWritePermissions(fd)) {
+        return STATUS_PERMISSION_DENIED;
+    }
+    if (numArgs != 2) {
+        dprintf(fd, "Invalid number of arguments: please provide --step <DIRECTION>\n");
+        return STATUS_BAD_VALUE;
+    }
+    string stepDirectionIn = string(args[1]);
+    bool stepDirectionUp;
+    if (!utils::parseArgDirection(stepDirectionIn, &stepDirectionUp)) {
+        dprintf(fd, "Invalid direction (\"up\" or \"down\") provided with step: %s\n",
+                stepDirectionIn.c_str());
+        return STATUS_BAD_VALUE;
+    }
+
+    auto stepResult = step(stepDirectionUp);
+    if (!stepResult.isOk()) {
+        dprintf(fd, "Unable to step in %s direction\n", stepDirectionIn.c_str());
+        return STATUS_BAD_VALUE;
+    }
+    dprintf(fd, "Step in %s direction\n", stepDirectionIn.c_str());
+    return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdCancel(int fd, uint32_t numArgs) {
+    if (!checkDumpCallerHasWritePermissions(fd)) {
+        return STATUS_PERMISSION_DENIED;
+    }
+    if (numArgs != 1) {
+        dprintf(fd,
+                "Invalid number of arguments: please provide --cancel "
+                "only and no more arguments\n");
+        return STATUS_BAD_VALUE;
+    }
+
+    auto cancelResult = cancel();
+    if (!cancelResult.isOk()) {
+        dprintf(fd, "Unable to cancel pending tune, seek, and step\n");
+        return STATUS_BAD_VALUE;
+    }
+    dprintf(fd, "Canceled pending tune, seek, and step\n");
+    return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdStartProgramListUpdates(int fd, const char** args,
+                                                           uint32_t numArgs) {
+    if (!checkDumpCallerHasWritePermissions(fd)) {
+        return STATUS_PERMISSION_DENIED;
+    }
+    if (numArgs != 5) {
+        dprintf(fd,
+                "Invalid number of arguments: please provide --startProgramListUpdates "
+                "<IDENTIFIER_TYPES> <IDENTIFIERS> <INCLUDE_CATEGORIES> "
+                "<EXCLUDE_MODIFICATIONS>\n");
+        return STATUS_BAD_VALUE;
+    }
+    string filterTypesStr = string(args[1]);
+    std::vector<IdentifierType> filterTypeList;
+    if (!EqualsIgnoreCase(filterTypesStr, "null") &&
+        !utils::parseArgIdentifierTypeArray(filterTypesStr, &filterTypeList)) {
+        dprintf(fd,
+                "Invalid identifier types provided with startProgramListUpdates: %s, "
+                "should be: <TYPE>,<TYPE>,...,<TYPE>\n",
+                filterTypesStr.c_str());
+        return STATUS_BAD_VALUE;
+    }
+    string filtersStr = string(args[2]);
+    std::vector<ProgramIdentifier> filterList;
+    if (!EqualsIgnoreCase(filtersStr, "null") &&
+        !utils::parseProgramIdentifierList(filtersStr, &filterList)) {
+        dprintf(fd,
+                "Invalid program identifiers provided with startProgramListUpdates: %s, "
+                "should be: <TYPE>:<VALUE>,<TYPE>:<VALUE>,...,<TYPE>:<VALUE>\n",
+                filtersStr.c_str());
+        return STATUS_BAD_VALUE;
+    }
+    string includeCategoriesStr = string(args[3]);
+    bool includeCategories;
+    if (!utils::parseArgBool(includeCategoriesStr, &includeCategories)) {
+        dprintf(fd,
+                "Invalid includeCategories (\"true\" or \"false\") "
+                "provided with startProgramListUpdates : %s\n",
+                includeCategoriesStr.c_str());
+        return STATUS_BAD_VALUE;
+    }
+    string excludeModificationsStr = string(args[4]);
+    bool excludeModifications;
+    if (!utils::parseArgBool(excludeModificationsStr, &excludeModifications)) {
+        dprintf(fd,
+                "Invalid excludeModifications(\"true\" or \"false\") "
+                "provided with startProgramListUpdates : %s\n",
+                excludeModificationsStr.c_str());
+        return STATUS_BAD_VALUE;
+    }
+    ProgramFilter filter = {filterTypeList, filterList, includeCategories, excludeModifications};
+
+    auto updateResult = startProgramListUpdates(filter);
+    if (!updateResult.isOk()) {
+        dprintf(fd, "Unable to start program list update for filter %s \n",
+                filter.toString().c_str());
+        return STATUS_BAD_VALUE;
+    }
+    dprintf(fd, "Start program list update for filter %s\n", filter.toString().c_str());
+    return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdStopProgramListUpdates(int fd, uint32_t numArgs) {
+    if (!checkDumpCallerHasWritePermissions(fd)) {
+        return STATUS_PERMISSION_DENIED;
+    }
+    if (numArgs != 1) {
+        dprintf(fd,
+                "Invalid number of arguments: please provide --stopProgramListUpdates "
+                "only and no more arguments\n");
+        return STATUS_BAD_VALUE;
+    }
+
+    auto stopResult = stopProgramListUpdates();
+    if (!stopResult.isOk()) {
+        dprintf(fd, "Unable to stop pending program list update\n");
+        return STATUS_BAD_VALUE;
+    }
+    dprintf(fd, "Stop pending program list update\n");
+    return STATUS_OK;
+}
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/BroadcastRadio.h b/broadcastradio/aidl/default/BroadcastRadio.h
new file mode 100644
index 0000000..1c85ddc
--- /dev/null
+++ b/broadcastradio/aidl/default/BroadcastRadio.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "VirtualRadio.h"
+
+#include <aidl/android/hardware/broadcastradio/AmFmBandRange.h>
+#include <aidl/android/hardware/broadcastradio/AmFmRegionConfig.h>
+#include <aidl/android/hardware/broadcastradio/AnnouncementType.h>
+#include <aidl/android/hardware/broadcastradio/BnBroadcastRadio.h>
+#include <aidl/android/hardware/broadcastradio/DabTableEntry.h>
+#include <aidl/android/hardware/broadcastradio/IAnnouncementListener.h>
+#include <aidl/android/hardware/broadcastradio/ICloseHandle.h>
+#include <aidl/android/hardware/broadcastradio/ITunerCallback.h>
+#include <aidl/android/hardware/broadcastradio/Properties.h>
+#include <broadcastradio-utils/WorkerThread.h>
+
+#include <android-base/thread_annotations.h>
+
+#include <optional>
+
+namespace aidl::android::hardware::broadcastradio {
+
+class BroadcastRadio final : public BnBroadcastRadio {
+  public:
+    explicit BroadcastRadio(const VirtualRadio& virtualRadio);
+    ~BroadcastRadio();
+    ndk::ScopedAStatus getAmFmRegionConfig(bool full, AmFmRegionConfig* returnConfigs) override;
+    ndk::ScopedAStatus getDabRegionConfig(std::vector<DabTableEntry>* returnConfigs) override;
+    ndk::ScopedAStatus getImage(int32_t id, std::vector<uint8_t>* returnImage) override;
+    ndk::ScopedAStatus getProperties(Properties* returnProperties) override;
+
+    ndk::ScopedAStatus setTunerCallback(const std::shared_ptr<ITunerCallback>& callback) override;
+    ndk::ScopedAStatus unsetTunerCallback() override;
+    ndk::ScopedAStatus tune(const ProgramSelector& program) override;
+    ndk::ScopedAStatus seek(bool directionUp, bool skipSubChannel) override;
+    ndk::ScopedAStatus step(bool directionUp) override;
+    ndk::ScopedAStatus cancel() override;
+    ndk::ScopedAStatus startProgramListUpdates(const ProgramFilter& filter) override;
+    ndk::ScopedAStatus stopProgramListUpdates() override;
+    ndk::ScopedAStatus isConfigFlagSet(ConfigFlag flag, bool* returnIsSet) override;
+    ndk::ScopedAStatus setConfigFlag(ConfigFlag flag, bool in_value) override;
+    ndk::ScopedAStatus setParameters(const std::vector<VendorKeyValue>& parameters,
+                                     std::vector<VendorKeyValue>* returnParameters) override;
+    ndk::ScopedAStatus getParameters(const std::vector<std::string>& keys,
+                                     std::vector<VendorKeyValue>* returnParameters) override;
+    ndk::ScopedAStatus registerAnnouncementListener(
+            const std::shared_ptr<IAnnouncementListener>& listener,
+            const std::vector<AnnouncementType>& enabled,
+            std::shared_ptr<ICloseHandle>* returnCloseHandle) override;
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+  private:
+    const VirtualRadio& mVirtualRadio;
+    std::mutex mMutex;
+    AmFmRegionConfig mAmFmConfig GUARDED_BY(mMutex);
+    std::unique_ptr<::android::WorkerThread> mThread GUARDED_BY(mMutex) =
+            std::unique_ptr<::android::WorkerThread>(new ::android::WorkerThread());
+    bool mIsTuneCompleted GUARDED_BY(mMutex) = true;
+    Properties mProperties GUARDED_BY(mMutex);
+    ProgramSelector mCurrentProgram GUARDED_BY(mMutex) = {};
+    std::shared_ptr<ITunerCallback> mCallback GUARDED_BY(mMutex);
+
+    std::optional<AmFmBandRange> getAmFmRangeLocked() const;
+    void cancelLocked();
+    ProgramInfo tuneInternalLocked(const ProgramSelector& sel);
+
+    binder_status_t cmdHelp(int fd) const;
+    binder_status_t cmdTune(int fd, const char** args, uint32_t numArgs);
+    binder_status_t cmdSeek(int fd, const char** args, uint32_t numArgs);
+    binder_status_t cmdStep(int fd, const char** args, uint32_t numArgs);
+    binder_status_t cmdCancel(int fd, uint32_t numArgs);
+    binder_status_t cmdStartProgramListUpdates(int fd, const char** args, uint32_t numArgs);
+    binder_status_t cmdStopProgramListUpdates(int fd, uint32_t numArgs);
+
+    binder_status_t dumpsys(int fd);
+};
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualProgram.cpp b/broadcastradio/aidl/default/VirtualProgram.cpp
new file mode 100644
index 0000000..4fe6567
--- /dev/null
+++ b/broadcastradio/aidl/default/VirtualProgram.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VirtualProgram.h"
+
+#include <broadcastradio-utils-aidl/Utils.h>
+#include "resources.h"
+
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+using ::std::vector;
+
+VirtualProgram::operator ProgramInfo() const {
+    ProgramInfo info = {};
+
+    info.selector = selector;
+
+    IdentifierType programType = selector.primaryId.type;
+    bool isDigital = (programType != IdentifierType::AMFM_FREQUENCY_KHZ &&
+                      programType != IdentifierType::RDS_PI);
+
+    auto selectId = [&info](const IdentifierType& type) {
+        return utils::makeIdentifier(type, utils::getId(info.selector, type));
+    };
+
+    switch (programType) {
+        case IdentifierType::AMFM_FREQUENCY_KHZ:
+            info.logicallyTunedTo = info.physicallyTunedTo =
+                    selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
+            break;
+        case IdentifierType::RDS_PI:
+            info.logicallyTunedTo = selectId(IdentifierType::RDS_PI);
+            info.physicallyTunedTo = selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
+            break;
+        case IdentifierType::HD_STATION_ID_EXT:
+            info.logicallyTunedTo = selectId(IdentifierType::HD_STATION_ID_EXT);
+            info.physicallyTunedTo = selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
+            break;
+        case IdentifierType::DAB_SID_EXT:
+            info.logicallyTunedTo = selectId(IdentifierType::DAB_SID_EXT);
+            info.physicallyTunedTo = selectId(IdentifierType::DAB_FREQUENCY_KHZ);
+            break;
+        case IdentifierType::DRMO_SERVICE_ID:
+            info.logicallyTunedTo = selectId(IdentifierType::DRMO_SERVICE_ID);
+            info.physicallyTunedTo = selectId(IdentifierType::DRMO_FREQUENCY_KHZ);
+            break;
+        case IdentifierType::SXM_SERVICE_ID:
+            info.logicallyTunedTo = selectId(IdentifierType::SXM_SERVICE_ID);
+            info.physicallyTunedTo = selectId(IdentifierType::SXM_CHANNEL);
+            break;
+        default:
+            LOG(FATAL) << "unsupported program type: " << toString(programType);
+            return {};
+    }
+
+    info.infoFlags |= (ProgramInfo::FLAG_TUNABLE | ProgramInfo::FLAG_STEREO);
+    info.signalQuality = isDigital ? kSignalQualityDigital : kSignalQualityNonDigital;
+
+    info.metadata = vector<Metadata>({
+            Metadata::make<Metadata::rdsPs>(programName),
+            Metadata::make<Metadata::songTitle>(songTitle),
+            Metadata::make<Metadata::songArtist>(songArtist),
+            Metadata::make<Metadata::stationIcon>(resources::kDemoPngId),
+            Metadata::make<Metadata::albumArt>(resources::kDemoPngId),
+    });
+
+    info.vendorInfo = vector<VendorKeyValue>({
+            {"com.android.sample", "sample"},
+            {"com.android.sample.VirtualProgram", "VirtualProgram"},
+    });
+
+    return info;
+}
+
+bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs) {
+    auto& l = lhs.selector;
+    auto& r = rhs.selector;
+
+    // Two programs with the same primaryId are considered the same.
+    if (l.primaryId.type != r.primaryId.type) return l.primaryId.type < r.primaryId.type;
+
+    return l.primaryId.value < r.primaryId.value;
+}
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualProgram.h b/broadcastradio/aidl/default/VirtualProgram.h
new file mode 100644
index 0000000..0c20721
--- /dev/null
+++ b/broadcastradio/aidl/default/VirtualProgram.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/broadcastradio/IdentifierType.h>
+#include <aidl/android/hardware/broadcastradio/ProgramInfo.h>
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+constexpr int kSignalQualityDigital = 100;
+constexpr int kSignalQualityNonDigital = 80;
+/**
+ * A radio program mock.
+ *
+ * This represents broadcast waves flying over the air,
+ * not an entry for a captured station in the radio tuner memory.
+ */
+struct VirtualProgram {
+    ProgramSelector selector;
+
+    std::string programName = "";
+    std::string songArtist = "";
+    std::string songTitle = "";
+
+    operator ProgramInfo() const;
+
+    /**
+     * Defines order in which virtual programs appear on the "air" with
+     * ITunerSession::scan().
+     *
+     * It's for default implementation purposes, may not be complete or correct.
+     */
+    friend bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs);
+};
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualRadio.cpp b/broadcastradio/aidl/default/VirtualRadio.cpp
new file mode 100644
index 0000000..126bcff
--- /dev/null
+++ b/broadcastradio/aidl/default/VirtualRadio.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VirtualRadio.h"
+#include <broadcastradio-utils-aidl/Utils.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorAmfm;
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorDab;
+using ::std::string;
+using ::std::vector;
+
+VirtualRadio::VirtualRadio(const string& name, const vector<VirtualProgram>& initialList)
+    : mName(name), mPrograms(initialList) {
+    sort(mPrograms.begin(), mPrograms.end());
+}
+
+string VirtualRadio::getName() const {
+    return mName;
+}
+
+const vector<VirtualProgram>& VirtualRadio::getProgramList() const {
+    return mPrograms;
+}
+
+bool VirtualRadio::getProgram(const ProgramSelector& selector, VirtualProgram* programOut) const {
+    for (const auto& program : mPrograms) {
+        if (utils::tunesTo(selector, program.selector)) {
+            *programOut = program;
+            return true;
+        }
+    }
+    return false;
+}
+
+// get singleton of AMFM Virtual Radio
+const VirtualRadio& VirtualRadio::getAmFmRadio() {
+    // clang-format off
+    static VirtualRadio amFmRadioMock(
+        "AM/FM radio mock",
+        {
+            {makeSelectorAmfm(/* frequency= */ 94900), "Wild 94.9", "Drake ft. Rihanna",
+                "Too Good"},
+            {makeSelectorAmfm(/* frequency= */ 96500), "KOIT", "Celine Dion", "All By Myself"},
+            {makeSelectorAmfm(/* frequency= */ 97300), "Alice@97.3", "Drops of Jupiter", "Train"},
+            {makeSelectorAmfm(/* frequency= */ 99700), "99.7 Now!", "The Chainsmokers", "Closer"},
+            {makeSelectorAmfm(/* frequency= */ 101300), "101-3 KISS-FM", "Justin Timberlake",
+                "Rock Your Body"},
+            {makeSelectorAmfm(/* frequency= */ 103700), "iHeart80s @ 103.7", "Michael Jackson",
+                "Billie Jean"},
+            {makeSelectorAmfm(/* frequency= */ 106100), "106 KMEL", "Drake", "Marvins Room"},
+            {makeSelectorAmfm(/* frequency= */ 700), "700 AM", "Artist700", "Title700"},
+            {makeSelectorAmfm(/* frequency= */ 1700), "1700 AM", "Artist1700", "Title1700"},
+        });
+    // clang-format on
+    return amFmRadioMock;
+}
+
+// get singleton of DAB Virtual Radio
+const VirtualRadio& VirtualRadio::getDabRadio() {
+    // clang-format off
+    static VirtualRadio dabRadioMock(
+        "DAB radio mock",
+        {
+            {makeSelectorDab(/* sidExt= */ 0xA000000001u, /* ensemble= */ 0x0001u,
+                /* freq= */ 225648), "BBC Radio 1", "Khalid", "Talk"},
+            {makeSelectorDab(/* sidExt= */ 0xB000000001u, /* ensemble= */ 0x1001u,
+                /* freq= */ 222064), "Classic FM", "Jean Sibelius", "Andante Festivo"},
+            {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
+                /* freq= */ 227360), "Absolute Radio", "Coldplay", "Clocks"},
+            {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
+                /* freq= */ 222064), "Absolute Radio", "Coldplay", "Clocks"},
+        });
+    // clang-format on
+    return dabRadioMock;
+}
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualRadio.h b/broadcastradio/aidl/default/VirtualRadio.h
new file mode 100644
index 0000000..ae039c4
--- /dev/null
+++ b/broadcastradio/aidl/default/VirtualRadio.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "VirtualProgram.h"
+
+#include <vector>
+
+namespace aidl::android::hardware::broadcastradio {
+
+/**
+ * A radio frequency space mock.
+ *
+ * This represents all broadcast waves in the air for a given radio technology,
+ * not a captured station list in the radio tuner memory.
+ *
+ * It's meant to abstract out radio content from default tuner implementation.
+ */
+class VirtualRadio final {
+  public:
+    VirtualRadio(const std::string& name, const std::vector<VirtualProgram>& initialList);
+    std::string getName() const;
+    const std::vector<VirtualProgram>& getProgramList() const;
+    bool getProgram(const ProgramSelector& selector, VirtualProgram* program) const;
+
+    static const VirtualRadio& getAmFmRadio();
+    static const VirtualRadio& getDabRadio();
+
+  private:
+    const std::string mName;
+    std::vector<VirtualProgram> mPrograms;
+};
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/broadcastradio-default.rc b/broadcastradio/aidl/default/broadcastradio-default.rc
new file mode 100644
index 0000000..49389e6
--- /dev/null
+++ b/broadcastradio/aidl/default/broadcastradio-default.rc
@@ -0,0 +1,6 @@
+service vendor.broadcastradio-default /vendor/bin/hw/android.hardware.broadcastradio-service.default
+    interface aidl android.hardware.broadcastradio.IBroadcastRadio/amfm
+    interface aidl android.hardware.broadcastradio.IBroadcastRadio/dab
+    class hal
+    user audioserver
+    group audio
diff --git a/broadcastradio/aidl/default/broadcastradio-default.xml b/broadcastradio/aidl/default/broadcastradio-default.xml
new file mode 100644
index 0000000..1555822
--- /dev/null
+++ b/broadcastradio/aidl/default/broadcastradio-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.broadcastradio</name>
+        <fqname>IBroadcastRadio/amfm</fqname>
+        <fqname>IBroadcastRadio/dab</fqname>
+    </hal>
+</manifest>
diff --git a/broadcastradio/aidl/default/main.cpp b/broadcastradio/aidl/default/main.cpp
new file mode 100644
index 0000000..6bf20d5
--- /dev/null
+++ b/broadcastradio/aidl/default/main.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BroadcastRadio.h"
+#include "VirtualRadio.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using ::aidl::android::hardware::broadcastradio::BroadcastRadio;
+using ::aidl::android::hardware::broadcastradio::VirtualRadio;
+
+int main() {
+    android::base::SetDefaultTag("BcRadioAidlDef");
+    ABinderProcess_setThreadPoolMaxThreadCount(4);
+    ABinderProcess_startThreadPool();
+
+    const VirtualRadio& amFmRadioMock = VirtualRadio::getAmFmRadio();
+    std::shared_ptr<BroadcastRadio> broadcastRadio =
+            ::ndk::SharedRefBase::make<BroadcastRadio>(amFmRadioMock);
+    const std::string instanceAmFm = std::string() + BroadcastRadio::descriptor + "/amfm";
+    binder_status_t statusAmFm =
+            AServiceManager_addService(broadcastRadio->asBinder().get(), instanceAmFm.c_str());
+    CHECK_EQ(statusAmFm, STATUS_OK)
+            << "Failed to register Broadcast Radio AM/FM HAL implementation";
+
+    const VirtualRadio& dabRadioMock = VirtualRadio::getDabRadio();
+    std::shared_ptr<BroadcastRadio> dabRadio =
+            ::ndk::SharedRefBase::make<BroadcastRadio>(dabRadioMock);
+    const std::string instanceDab = std::string() + BroadcastRadio::descriptor + "/dab";
+    binder_status_t statusDab =
+            AServiceManager_addService(dabRadio->asBinder().get(), instanceDab.c_str());
+    CHECK_EQ(statusDab, STATUS_OK) << "Failed to register Broadcast Radio DAB HAL implementation";
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/broadcastradio/aidl/default/resources.h b/broadcastradio/aidl/default/resources.h
new file mode 100644
index 0000000..beffc76
--- /dev/null
+++ b/broadcastradio/aidl/default/resources.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+
+namespace aidl::android::hardware::broadcastradio::resources {
+
+constexpr int32_t kDemoPngId = 123456;
+constexpr uint8_t kDemoPng[] = {
+        0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44,
+        0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25,
+        0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x5d, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xed, 0xd9,
+        0xc1, 0x09, 0x00, 0x30, 0x08, 0x04, 0xc1, 0x33, 0xfd, 0xf7, 0x6c, 0x6a, 0xc8, 0x23, 0x04,
+        0xc9, 0x6c, 0x01, 0xc2, 0x20, 0xbe, 0x4c, 0x86, 0x57, 0x49, 0xba, 0xfb, 0xd6, 0xf4, 0xba,
+        0x3e, 0x7f, 0x4d, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x8f, 0x00, 0xbd, 0xce, 0x7f,
+        0xc0, 0x11, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xb8, 0x0d, 0x32, 0xd4, 0x0c, 0x77, 0xbd,
+        0xfb, 0xc1, 0xce, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82};
+
+}  // namespace aidl::android::hardware::broadcastradio::resources
diff --git a/broadcastradio/aidl/vts/Android.bp b/broadcastradio/aidl/vts/Android.bp
new file mode 100644
index 0000000..b60387e
--- /dev/null
+++ b/broadcastradio/aidl/vts/Android.bp
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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_test {
+    name: "VtsHalBroadcastradioAidlTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    tidy_timeout_srcs: ["src/*.cpp"],
+    srcs: ["src/*.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+        "libbase",
+        "libxml2",
+    ],
+    static_libs: [
+        "android.hardware.broadcastradio-V1-ndk",
+        "android.hardware.broadcastradio@common-utils-aidl-lib",
+        "android.hardware.broadcastradio@vts-utils-lib",
+        "libgmock",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/broadcastradio/aidl/vts/OWNERS b/broadcastradio/aidl/vts/OWNERS
new file mode 100644
index 0000000..302fdd7
--- /dev/null
+++ b/broadcastradio/aidl/vts/OWNERS
@@ -0,0 +1,4 @@
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
new file mode 100644
index 0000000..790d60b
--- /dev/null
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -0,0 +1,1233 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define EGMOCK_VERBOSE 1
+
+#include <aidl/android/hardware/broadcastradio/BnAnnouncementListener.h>
+#include <aidl/android/hardware/broadcastradio/BnTunerCallback.h>
+#include <aidl/android/hardware/broadcastradio/ConfigFlag.h>
+#include <aidl/android/hardware/broadcastradio/IBroadcastRadio.h>
+#include <aidl/android/hardware/broadcastradio/ProgramListChunk.h>
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+#include <aidl/android/hardware/broadcastradio/VendorKeyValue.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <android-base/thread_annotations.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <broadcastradio-utils-aidl/Utils.h>
+#include <cutils/bitops.h>
+#include <gmock/gmock.h>
+
+#include <chrono>
+#include <condition_variable>
+#include <optional>
+#include <regex>
+
+namespace aidl::android::hardware::broadcastradio::vts {
+
+namespace {
+
+using ::aidl::android::hardware::broadcastradio::utils::makeIdentifier;
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorAmfm;
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorDab;
+using ::aidl::android::hardware::broadcastradio::utils::resultToInt;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+using ::std::string;
+using ::std::vector;
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::ByMove;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::SaveArg;
+
+namespace bcutils = ::aidl::android::hardware::broadcastradio::utils;
+
+const ConfigFlag kConfigFlagValues[] = {
+        ConfigFlag::FORCE_MONO,
+        ConfigFlag::FORCE_ANALOG,
+        ConfigFlag::FORCE_DIGITAL,
+        ConfigFlag::RDS_AF,
+        ConfigFlag::RDS_REG,
+        ConfigFlag::DAB_DAB_LINKING,
+        ConfigFlag::DAB_FM_LINKING,
+        ConfigFlag::DAB_DAB_SOFT_LINKING,
+        ConfigFlag::DAB_FM_SOFT_LINKING,
+};
+
+void printSkipped(const string& msg) {
+    const auto testInfo = testing::UnitTest::GetInstance()->current_test_info();
+    LOG(INFO) << "[  SKIPPED ] " << testInfo->test_case_name() << "." << testInfo->name()
+              << " with message: " << msg;
+}
+
+bool isValidAmFmFreq(int64_t freq) {
+    ProgramIdentifier id = bcutils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, freq);
+    return bcutils::isValid(id);
+}
+
+void validateRange(const AmFmBandRange& range) {
+    EXPECT_TRUE(isValidAmFmFreq(range.lowerBound));
+    EXPECT_TRUE(isValidAmFmFreq(range.upperBound));
+    EXPECT_LT(range.lowerBound, range.upperBound);
+    EXPECT_GT(range.spacing, 0u);
+    EXPECT_EQ((range.upperBound - range.lowerBound) % range.spacing, 0u);
+}
+
+bool supportsFM(const AmFmRegionConfig& config) {
+    for (const auto& range : config.ranges) {
+        if (bcutils::getBand(range.lowerBound) == bcutils::FrequencyBand::FM) {
+            return true;
+        }
+    }
+    return false;
+}
+
+}  // namespace
+
+class CallbackFlag final {
+  public:
+    CallbackFlag(int timeoutMs) { mTimeoutMs = timeoutMs; }
+    /**
+     * Notify that the callback is called.
+     */
+    void notify() {
+        std::unique_lock<std::mutex> lock(mMutex);
+        mCalled = true;
+        lock.unlock();
+        mCv.notify_all();
+    };
+
+    /**
+     * Wait for the timeout passed into the constructor.
+     */
+    bool wait() {
+        std::unique_lock<std::mutex> lock(mMutex);
+        return mCv.wait_for(lock, std::chrono::milliseconds(mTimeoutMs),
+                            [this] { return mCalled; });
+    };
+
+    /**
+     * Reset the callback to not called.
+     */
+    void reset() {
+        std::unique_lock<std::mutex> lock(mMutex);
+        mCalled = false;
+    }
+
+  private:
+    std::mutex mMutex;
+    bool mCalled GUARDED_BY(mMutex) = false;
+    std::condition_variable mCv;
+    int mTimeoutMs;
+};
+
+class TunerCallbackImpl final : public BnTunerCallback {
+  public:
+    TunerCallbackImpl();
+    ScopedAStatus onTuneFailed(Result result, const ProgramSelector& selector) override;
+    ScopedAStatus onCurrentProgramInfoChanged(const ProgramInfo& info) override;
+    ScopedAStatus onProgramListUpdated(const ProgramListChunk& chunk) override;
+    ScopedAStatus onParametersUpdated(const vector<VendorKeyValue>& parameters) override;
+    ScopedAStatus onAntennaStateChange(bool connected) override;
+    ScopedAStatus onConfigFlagUpdated(ConfigFlag in_flag, bool in_value) override;
+
+    bool waitOnCurrentProgramInfoChangedCallback();
+    bool waitProgramReady();
+    void reset();
+
+    bool getAntennaConnectionState();
+    ProgramInfo getCurrentProgramInfo();
+    bcutils::ProgramInfoSet getProgramList();
+
+  private:
+    std::mutex mLock;
+    bool mAntennaConnectionState GUARDED_BY(mLock);
+    ProgramInfo mCurrentProgramInfo GUARDED_BY(mLock);
+    bcutils::ProgramInfoSet mProgramList GUARDED_BY(mLock);
+    CallbackFlag mOnCurrentProgramInfoChangedFlag = CallbackFlag(IBroadcastRadio::TUNER_TIMEOUT_MS);
+    CallbackFlag mOnProgramListReadyFlag = CallbackFlag(IBroadcastRadio::LIST_COMPLETE_TIMEOUT_MS);
+};
+
+struct AnnouncementListenerMock : public BnAnnouncementListener {
+    MOCK_METHOD1(onListUpdated, ScopedAStatus(const vector<Announcement>&));
+};
+
+class BroadcastRadioHalTest : public testing::TestWithParam<string> {
+  protected:
+    void SetUp() override;
+    void TearDown() override;
+
+    bool getAmFmRegionConfig(bool full, AmFmRegionConfig* config);
+    std::optional<bcutils::ProgramInfoSet> getProgramList();
+    std::optional<bcutils::ProgramInfoSet> getProgramList(const ProgramFilter& filter);
+
+    std::shared_ptr<IBroadcastRadio> mModule;
+    Properties mProperties;
+    std::shared_ptr<TunerCallbackImpl> mCallback;
+};
+
+MATCHER_P(InfoHasId, id, string(negation ? "does not contain" : "contains") + " " + id.toString()) {
+    vector<int> ids = bcutils::getAllIds(arg.selector, id.type);
+    return ids.end() != find(ids.begin(), ids.end(), id.value);
+}
+
+TunerCallbackImpl::TunerCallbackImpl() {
+    mAntennaConnectionState = true;
+}
+
+ScopedAStatus TunerCallbackImpl::onTuneFailed(Result result, const ProgramSelector& selector) {
+    LOG(DEBUG) << "Tune failed for selector" << selector.toString();
+    EXPECT_TRUE(result == Result::CANCELED);
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus TunerCallbackImpl::onCurrentProgramInfoChanged(const ProgramInfo& info) {
+    LOG(DEBUG) << "onCurrentProgramInfoChanged called";
+    for (const auto& id : info.selector) {
+        EXPECT_NE(id.type, IdentifierType::INVALID);
+    }
+
+    IdentifierType logically = info.logicallyTunedTo.type;
+    // This field is required for currently tuned program and should be INVALID
+    // for entries from the program list.
+    EXPECT_TRUE(logically == IdentifierType::AMFM_FREQUENCY_KHZ ||
+                logically == IdentifierType::RDS_PI ||
+                logically == IdentifierType::HD_STATION_ID_EXT ||
+                logically == IdentifierType::DAB_SID_EXT ||
+                logically == IdentifierType::DRMO_SERVICE_ID ||
+                logically == IdentifierType::SXM_SERVICE_ID ||
+                (logically >= IdentifierType::VENDOR_START &&
+                 logically <= IdentifierType::VENDOR_END) ||
+                logically > IdentifierType::SXM_CHANNEL);
+
+    IdentifierType physically = info.physicallyTunedTo.type;
+    // ditto (see "logically" above)
+    EXPECT_TRUE(physically == IdentifierType::AMFM_FREQUENCY_KHZ ||
+                physically == IdentifierType::DAB_FREQUENCY_KHZ ||
+                physically == IdentifierType::DRMO_FREQUENCY_KHZ ||
+                physically == IdentifierType::SXM_CHANNEL ||
+                (physically >= IdentifierType::VENDOR_START &&
+                 physically <= IdentifierType::VENDOR_END) ||
+                physically > IdentifierType::SXM_CHANNEL);
+
+    if (logically == IdentifierType::AMFM_FREQUENCY_KHZ) {
+        std::optional<string> ps = bcutils::getMetadataString(info, Metadata::rdsPs);
+        if (ps.has_value()) {
+            EXPECT_NE(::android::base::Trim(*ps), "")
+                    << "Don't use empty RDS_PS as an indicator of missing RSD PS data.";
+        }
+    }
+
+    {
+        std::lock_guard<std::mutex> lk(mLock);
+        mCurrentProgramInfo = info;
+    }
+
+    mOnCurrentProgramInfoChangedFlag.notify();
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus TunerCallbackImpl::onProgramListUpdated(const ProgramListChunk& chunk) {
+    LOG(DEBUG) << "onProgramListUpdated called";
+    {
+        std::lock_guard<std::mutex> lk(mLock);
+        updateProgramList(chunk, &mProgramList);
+    }
+
+    if (chunk.complete) {
+        mOnProgramListReadyFlag.notify();
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus TunerCallbackImpl::onParametersUpdated(
+        [[maybe_unused]] const vector<VendorKeyValue>& parameters) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus TunerCallbackImpl::onAntennaStateChange(bool connected) {
+    if (!connected) {
+        std::lock_guard<std::mutex> lk(mLock);
+        mAntennaConnectionState = false;
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus TunerCallbackImpl::onConfigFlagUpdated([[maybe_unused]] ConfigFlag in_flag,
+                                                     [[maybe_unused]] bool in_value) {
+    return ndk::ScopedAStatus::ok();
+}
+
+bool TunerCallbackImpl::waitOnCurrentProgramInfoChangedCallback() {
+    return mOnCurrentProgramInfoChangedFlag.wait();
+}
+
+bool TunerCallbackImpl::waitProgramReady() {
+    return mOnProgramListReadyFlag.wait();
+}
+
+void TunerCallbackImpl::reset() {
+    mOnCurrentProgramInfoChangedFlag.reset();
+    mOnProgramListReadyFlag.reset();
+}
+
+bool TunerCallbackImpl::getAntennaConnectionState() {
+    std::lock_guard<std::mutex> lk(mLock);
+    return mAntennaConnectionState;
+}
+
+ProgramInfo TunerCallbackImpl::getCurrentProgramInfo() {
+    std::lock_guard<std::mutex> lk(mLock);
+    return mCurrentProgramInfo;
+}
+
+bcutils::ProgramInfoSet TunerCallbackImpl::getProgramList() {
+    std::lock_guard<std::mutex> lk(mLock);
+    return mProgramList;
+}
+
+void BroadcastRadioHalTest::SetUp() {
+    EXPECT_EQ(mModule.get(), nullptr) << "Module is already open";
+
+    // lookup AIDL service (radio module)
+    AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+    ASSERT_NE(binder, nullptr);
+    mModule = IBroadcastRadio::fromBinder(ndk::SpAIBinder(binder));
+    ASSERT_NE(mModule, nullptr) << "Couldn't find broadcast radio HAL implementation";
+
+    // get module properties
+    auto propResult = mModule->getProperties(&mProperties);
+
+    ASSERT_TRUE(propResult.isOk());
+    EXPECT_FALSE(mProperties.maker.empty());
+    EXPECT_FALSE(mProperties.product.empty());
+    EXPECT_GT(mProperties.supportedIdentifierTypes.size(), 0u);
+
+    mCallback = SharedRefBase::make<TunerCallbackImpl>();
+
+    // set callback
+    EXPECT_TRUE(mModule->setTunerCallback(mCallback).isOk());
+}
+
+void BroadcastRadioHalTest::TearDown() {
+    if (mModule) {
+        ASSERT_TRUE(mModule->unsetTunerCallback().isOk());
+    }
+    if (mCallback) {
+        // we expect the antenna is connected through the whole test
+        EXPECT_TRUE(mCallback->getAntennaConnectionState());
+        mCallback = nullptr;
+    }
+}
+
+bool BroadcastRadioHalTest::getAmFmRegionConfig(bool full, AmFmRegionConfig* config) {
+    auto halResult = mModule->getAmFmRegionConfig(full, config);
+
+    if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+        return false;
+    }
+
+    EXPECT_TRUE(halResult.isOk());
+    return halResult.isOk();
+}
+
+std::optional<bcutils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList() {
+    ProgramFilter emptyFilter = {};
+    return getProgramList(emptyFilter);
+}
+
+std::optional<bcutils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList(
+        const ProgramFilter& filter) {
+    mCallback->reset();
+
+    auto startResult = mModule->startProgramListUpdates(filter);
+
+    if (startResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+        printSkipped("Program list not supported");
+        return std::nullopt;
+    }
+    EXPECT_TRUE(startResult.isOk());
+    if (!startResult.isOk()) {
+        return std::nullopt;
+    }
+    EXPECT_TRUE(mCallback->waitProgramReady());
+
+    auto stopResult = mModule->stopProgramListUpdates();
+
+    EXPECT_TRUE(stopResult.isOk());
+
+    return mCallback->getProgramList();
+}
+
+/**
+ * Test setting tuner callback to null.
+ *
+ * Verifies that:
+ *  - Setting to a null tuner callback results with INVALID_ARGUMENTS.
+ */
+TEST_P(BroadcastRadioHalTest, TunerCallbackFailsWithNull) {
+    LOG(DEBUG) << "TunerCallbackFailsWithNull Test";
+
+    auto halResult = mModule->setTunerCallback(nullptr);
+
+    EXPECT_EQ(halResult.getServiceSpecificError(), resultToInt(Result::INVALID_ARGUMENTS));
+}
+
+/**
+ * Test fetching AM/FM regional configuration.
+ *
+ * Verifies that:
+ *  - AM/FM regional configuration is either set at startup or not supported at all by the hardware;
+ *  - FM Deemphasis and RDS are correctly configured for FM-capable radio;
+ */
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfig) {
+    LOG(DEBUG) << "GetAmFmRegionConfig Test";
+
+    AmFmRegionConfig config;
+
+    bool supported = getAmFmRegionConfig(/* full= */ false, &config);
+
+    if (!supported) {
+        printSkipped("AM/FM not supported");
+        return;
+    }
+
+    EXPECT_LE(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
+    EXPECT_LE(popcountll(static_cast<unsigned long long>(config.fmRds)), 1);
+
+    if (supportsFM(config)) {
+        EXPECT_EQ(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
+    }
+}
+
+/**
+ * Test fetching ranges of AM/FM regional configuration.
+ *
+ * Verifies that:
+ *  - AM/FM regional configuration is either set at startup or not supported at all by the hardware;
+ *  - there is at least one AM/FM band configured;
+ *  - all channel grids (frequency ranges and spacings) are valid;
+ *  - seek spacing is a multiple of the manual spacing value.
+ */
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfigRanges) {
+    LOG(DEBUG) << "GetAmFmRegionConfigRanges Test";
+
+    AmFmRegionConfig config;
+
+    bool supported = getAmFmRegionConfig(/* full= */ false, &config);
+
+    if (!supported) {
+        printSkipped("AM/FM not supported");
+        return;
+    }
+
+    EXPECT_GT(config.ranges.size(), 0u);
+    for (const auto& range : config.ranges) {
+        validateRange(range);
+        EXPECT_EQ(range.seekSpacing % range.spacing, 0u);
+        EXPECT_GE(range.seekSpacing, range.spacing);
+    }
+}
+
+/**
+ * Test fetching FM regional capabilities.
+ *
+ * Verifies that:
+ *  - AM/FM regional capabilities are either available or not supported at all by the hardware;
+ *  - there is at least one de-emphasis filter mode supported for FM-capable radio;
+ */
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfigCapabilitiesForFM) {
+    LOG(DEBUG) << "GetAmFmRegionConfigCapabilitiesForFM Test";
+
+    AmFmRegionConfig config;
+
+    bool supported = getAmFmRegionConfig(/* full= */ true, &config);
+
+    if (supported && supportsFM(config)) {
+        EXPECT_GE(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
+    } else {
+        printSkipped("FM not supported");
+    }
+}
+
+/**
+ * Test fetching the ranges of AM/FM regional capabilities.
+ *
+ * Verifies that:
+ *  - AM/FM regional capabilities are either available or not supported at all by the hardware;
+ *  - there is at least one AM/FM range supported;
+ *  - all channel grids (frequency ranges and spacings) are valid;
+ *  - seek spacing is not set.
+ */
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfigCapabilitiesRanges) {
+    LOG(DEBUG) << "GetAmFmRegionConfigCapabilitiesRanges Test";
+
+    AmFmRegionConfig config;
+
+    bool supported = getAmFmRegionConfig(/* full= */ true, &config);
+
+    if (!supported) {
+        printSkipped("AM/FM not supported");
+        return;
+    }
+
+    EXPECT_GT(config.ranges.size(), 0u);
+
+    for (const auto& range : config.ranges) {
+        validateRange(range);
+        EXPECT_EQ(range.seekSpacing, 0u);
+    }
+}
+
+/**
+ * Test fetching DAB regional configuration.
+ *
+ * Verifies that:
+ *  - DAB regional configuration is either set at startup or not supported at all by the hardware;
+ *  - all channel labels match correct format;
+ *  - all channel frequencies are in correct range.
+ */
+TEST_P(BroadcastRadioHalTest, GetDabRegionConfig) {
+    LOG(DEBUG) << "GetDabRegionConfig Test";
+    vector<DabTableEntry> config;
+
+    auto halResult = mModule->getDabRegionConfig(&config);
+
+    if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+        printSkipped("DAB not supported");
+        return;
+    }
+    ASSERT_TRUE(halResult.isOk());
+
+    std::regex re("^[A-Z0-9][A-Z0-9 ]{0,5}[A-Z0-9]$");
+
+    for (const auto& entry : config) {
+        EXPECT_TRUE(std::regex_match(string(entry.label), re));
+
+        ProgramIdentifier id =
+                bcutils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, entry.frequencyKhz);
+        EXPECT_TRUE(bcutils::isValid(id));
+    }
+}
+
+/**
+ * Test tuning without tuner callback set.
+ *
+ * Verifies that:
+ *  - No tuner callback set results in INVALID_STATE, regardless of whether the selector is
+ * supported.
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsWithoutTunerCallback) {
+    LOG(DEBUG) << "TuneFailsWithoutTunerCallback Test";
+
+    mModule->unsetTunerCallback();
+    int64_t freq = 90900;  // 90.9 FM
+    ProgramSelector sel = makeSelectorAmfm(freq);
+
+    auto result = mModule->tune(sel);
+
+    EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+}
+
+/**
+ * Test tuning with selectors that can be not supported.
+ *
+ * Verifies that:
+ *  - if the selector is not supported, an invalid value results with NOT_SUPPORTED, regardless of
+ *    whether it is valid;
+ *  - if it is supported, the test is ignored;
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsWithNotSupported) {
+    LOG(DEBUG) << "TuneFailsWithNotSupported Test";
+
+    vector<ProgramIdentifier> supportTestId = {
+            makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 0),           // invalid
+            makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 94900),       // valid
+            makeIdentifier(IdentifierType::RDS_PI, 0x10000),                 // invalid
+            makeIdentifier(IdentifierType::RDS_PI, 0x1001),                  // valid
+            makeIdentifier(IdentifierType::HD_STATION_ID_EXT, 0x100000000),  // invalid
+            makeIdentifier(IdentifierType::HD_STATION_ID_EXT, 0x10000001),   // valid
+            makeIdentifier(IdentifierType::DAB_SID_EXT, 0),                  // invalid
+            makeIdentifier(IdentifierType::DAB_SID_EXT, 0xA00001),           // valid
+            makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x100000000),    // invalid
+            makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x10000001),     // valid
+            makeIdentifier(IdentifierType::SXM_SERVICE_ID, 0x100000000),     // invalid
+            makeIdentifier(IdentifierType::SXM_SERVICE_ID, 0x10000001),      // valid
+    };
+
+    auto notSupportedError = resultToInt(Result::NOT_SUPPORTED);
+    for (const auto& id : supportTestId) {
+        ProgramSelector sel{id, {}};
+
+        if (!bcutils::isSupported(mProperties, sel)) {
+            auto result = mModule->tune(sel);
+
+            EXPECT_EQ(result.getServiceSpecificError(), notSupportedError);
+        }
+    }
+}
+
+/**
+ * Test tuning with invalid selectors.
+ *
+ * Verifies that:
+ *  - if the selector is not supported, it's ignored;
+ *  - if it is supported, an invalid value results with INVALID_ARGUMENTS;
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsWithInvalid) {
+    LOG(DEBUG) << "TuneFailsWithInvalid Test";
+
+    vector<ProgramIdentifier> invalidId = {
+            makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 0),
+            makeIdentifier(IdentifierType::RDS_PI, 0x10000),
+            makeIdentifier(IdentifierType::HD_STATION_ID_EXT, 0x100000000),
+            makeIdentifier(IdentifierType::DAB_SID_EXT, 0),
+            makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x100000000),
+            makeIdentifier(IdentifierType::SXM_SERVICE_ID, 0x100000000),
+    };
+
+    auto invalidArgumentsError = resultToInt(Result::INVALID_ARGUMENTS);
+    for (const auto& id : invalidId) {
+        ProgramSelector sel{id, {}};
+
+        if (bcutils::isSupported(mProperties, sel)) {
+            auto result = mModule->tune(sel);
+
+            EXPECT_EQ(result.getServiceSpecificError(), invalidArgumentsError);
+        }
+    }
+}
+
+/**
+ * Test tuning with empty program selector.
+ *
+ * Verifies that:
+ *  - tune fails with NOT_SUPPORTED when program selector is not initialized.
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsWithEmpty) {
+    LOG(DEBUG) << "TuneFailsWithEmpty Test";
+
+    // Program type is 1-based, so 0 will always be invalid.
+    ProgramSelector sel = {};
+
+    auto result = mModule->tune(sel);
+
+    ASSERT_EQ(result.getServiceSpecificError(), resultToInt(Result::NOT_SUPPORTED));
+}
+
+/**
+ * Test tuning with FM selector.
+ *
+ * Verifies that:
+ *  - if AM/FM selector is not supported, the method returns NOT_SUPPORTED;
+ *  - if it is supported, the method succeeds;
+ *  - after a successful tune call, onCurrentProgramInfoChanged callback is
+ *    invoked carrying a proper selector;
+ *  - program changes exactly to what was requested.
+ */
+TEST_P(BroadcastRadioHalTest, FmTune) {
+    LOG(DEBUG) << "FmTune Test";
+
+    int64_t freq = 90900;  // 90.9 FM
+    ProgramSelector sel = makeSelectorAmfm(freq);
+    // try tuning
+    mCallback->reset();
+    auto result = mModule->tune(sel);
+
+    // expect a failure if it's not supported
+    if (!bcutils::isSupported(mProperties, sel)) {
+        EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::NOT_SUPPORTED));
+        return;
+    }
+
+    // expect a callback if it succeeds
+    EXPECT_TRUE(result.isOk());
+    EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+    ProgramInfo infoCb = mCallback->getCurrentProgramInfo();
+
+    LOG(DEBUG) << "Current program info: " << infoCb.toString();
+
+    // it should tune exactly to what was requested
+    vector<int> freqs = bcutils::getAllIds(infoCb.selector, IdentifierType::AMFM_FREQUENCY_KHZ);
+    EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq))
+            << "FM freq " << freq << " kHz is not sent back by callback.";
+}
+
+/**
+ * Test tuning with DAB selector.
+ *
+ * Verifies that:
+ *  - if DAB selector is not supported, the method returns NOT_SUPPORTED;
+ *  - if it is supported, the method succeeds;
+ *  - after a successful tune call, onCurrentProgramInfoChanged callback is
+ *    invoked carrying a proper selector;
+ *  - program changes exactly to what was requested.
+ */
+TEST_P(BroadcastRadioHalTest, DabTune) {
+    LOG(DEBUG) << "DabTune Test";
+    vector<DabTableEntry> config;
+
+    auto halResult = mModule->getDabRegionConfig(&config);
+
+    if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+        printSkipped("DAB not supported");
+        return;
+    }
+    ASSERT_TRUE(halResult.isOk());
+    ASSERT_NE(config.size(), 0U);
+
+    auto programList = getProgramList();
+
+    if (!programList) {
+        printSkipped("Empty DAB station list, tune cannot be performed");
+        return;
+    }
+
+    ProgramSelector sel = {};
+    uint64_t freq = 0;
+    bool dabStationPresent = false;
+    for (auto&& programInfo : *programList) {
+        if (!utils::hasId(programInfo.selector, IdentifierType::DAB_FREQUENCY_KHZ)) {
+            continue;
+        }
+        for (auto&& config_entry : config) {
+            if (config_entry.frequencyKhz ==
+                utils::getId(programInfo.selector, IdentifierType::DAB_FREQUENCY_KHZ, 0)) {
+                freq = config_entry.frequencyKhz;
+                break;
+            }
+        }
+        // Do not trigger a tune request if the programList entry does not contain
+        // a valid DAB frequency.
+        if (freq == 0) {
+            continue;
+        }
+        int64_t dabSidExt = utils::getId(programInfo.selector, IdentifierType::DAB_SID_EXT, 0);
+        int64_t dabEns = utils::getId(programInfo.selector, IdentifierType::DAB_ENSEMBLE, 0);
+        sel = makeSelectorDab(dabSidExt, (int32_t)dabEns, freq);
+        dabStationPresent = true;
+        break;
+    }
+
+    if (!dabStationPresent) {
+        printSkipped("No DAB stations in the list, tune cannot be performed");
+        return;
+    }
+
+    // try tuning
+
+    auto result = mModule->tune(sel);
+
+    // expect a failure if it's not supported
+    if (!bcutils::isSupported(mProperties, sel)) {
+        EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::NOT_SUPPORTED));
+        return;
+    }
+
+    // expect a callback if it succeeds
+    EXPECT_TRUE(result.isOk());
+    EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+    ProgramInfo infoCb = mCallback->getCurrentProgramInfo();
+
+    LOG(DEBUG) << "Current program info: " << infoCb.toString();
+
+    // it should tune exactly to what was requested
+    vector<int> freqs = bcutils::getAllIds(infoCb.selector, IdentifierType::DAB_FREQUENCY_KHZ);
+    EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq))
+            << "DAB freq " << freq << " kHz is not sent back by callback.";
+}
+
+/**
+ * Test seeking to next/prev station via IBroadcastRadio::seek().
+ *
+ * Verifies that:
+ *  - the method succeeds;
+ *  - the program info is changed within kTuneTimeoutMs;
+ *  - works both directions and with or without skipping sub-channel.
+ */
+TEST_P(BroadcastRadioHalTest, Seek) {
+    LOG(DEBUG) << "Seek Test";
+
+    mCallback->reset();
+
+    auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
+
+    if (result.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+        printSkipped("Seek not supported");
+        return;
+    }
+
+    EXPECT_TRUE(result.isOk());
+    EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+
+    mCallback->reset();
+
+    result = mModule->seek(/* in_directionUp= */ false, /* in_skipSubChannel= */ false);
+
+    EXPECT_TRUE(result.isOk());
+    EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+}
+
+/**
+ * Test seeking without tuner callback set.
+ *
+ * Verifies that:
+ *  - No tuner callback set results in INVALID_STATE.
+ */
+TEST_P(BroadcastRadioHalTest, SeekFailsWithoutTunerCallback) {
+    LOG(DEBUG) << "SeekFailsWithoutTunerCallback Test";
+
+    mModule->unsetTunerCallback();
+
+    auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
+
+    EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+
+    result = mModule->seek(/* in_directionUp= */ false, /* in_skipSubChannel= */ false);
+
+    EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+}
+
+/**
+ * Test step operation.
+ *
+ * Verifies that:
+ *  - the method succeeds or returns NOT_SUPPORTED;
+ *  - the program info is changed within kTuneTimeoutMs if the method succeeded;
+ *  - works both directions.
+ */
+TEST_P(BroadcastRadioHalTest, Step) {
+    LOG(DEBUG) << "Step Test";
+
+    mCallback->reset();
+
+    auto result = mModule->step(/* in_directionUp= */ true);
+
+    if (result.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+        printSkipped("Step not supported");
+        return;
+    }
+    EXPECT_TRUE(result.isOk());
+    EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+
+    mCallback->reset();
+
+    result = mModule->step(/* in_directionUp= */ false);
+
+    EXPECT_TRUE(result.isOk());
+    EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+}
+
+/**
+ * Test step operation without tuner callback set.
+ *
+ * Verifies that:
+ *  - No tuner callback set results in INVALID_STATE.
+ */
+TEST_P(BroadcastRadioHalTest, StepFailsWithoutTunerCallback) {
+    LOG(DEBUG) << "StepFailsWithoutTunerCallback Test";
+
+    mModule->unsetTunerCallback();
+
+    auto result = mModule->step(/* in_directionUp= */ true);
+
+    EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+
+    result = mModule->step(/* in_directionUp= */ false);
+
+    EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+}
+
+/**
+ * Test tune cancellation.
+ *
+ * Verifies that:
+ *  - the method does not crash after being invoked multiple times.
+ *
+ * Since cancel() might be called after the HAL completes an operation (tune, seek, and step)
+ * and before the callback completions, the operation might not be actually canceled and the
+ * effect of cancel() is not deterministic to be tested here.
+ */
+TEST_P(BroadcastRadioHalTest, Cancel) {
+    LOG(DEBUG) << "Cancel Test";
+
+    auto notSupportedError = resultToInt(Result::NOT_SUPPORTED);
+    for (int i = 0; i < 10; i++) {
+        auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
+
+        if (result.getServiceSpecificError() == notSupportedError) {
+            printSkipped("Cancel is skipped because of seek not supported");
+            return;
+        }
+        EXPECT_TRUE(result.isOk());
+
+        auto cancelResult = mModule->cancel();
+
+        ASSERT_TRUE(cancelResult.isOk());
+    }
+}
+
+/**
+ * Test IBroadcastRadio::get|setParameters() methods called with no parameters.
+ *
+ * Verifies that:
+ *  - callback is called for empty parameters set.
+ */
+TEST_P(BroadcastRadioHalTest, NoParameters) {
+    LOG(DEBUG) << "NoParameters Test";
+
+    vector<VendorKeyValue> parametersResults = {};
+
+    auto halResult = mModule->setParameters({}, &parametersResults);
+
+    ASSERT_TRUE(halResult.isOk());
+    ASSERT_EQ(parametersResults.size(), 0u);
+
+    parametersResults.clear();
+
+    halResult = mModule->getParameters({}, &parametersResults);
+
+    ASSERT_TRUE(halResult.isOk());
+    ASSERT_EQ(parametersResults.size(), 0u);
+}
+
+/**
+ * Test IBroadcastRadio::get|setParameters() methods called with unknown parameters.
+ *
+ * Verifies that:
+ *  - unknown parameters are ignored;
+ *  - callback is called also for empty results set.
+ */
+TEST_P(BroadcastRadioHalTest, UnknownParameters) {
+    LOG(DEBUG) << "UnknownParameters Test";
+
+    vector<VendorKeyValue> parametersResults = {};
+
+    auto halResult =
+            mModule->setParameters({{"com.android.unknown", "sample"}}, &parametersResults);
+
+    ASSERT_TRUE(halResult.isOk());
+    ASSERT_EQ(parametersResults.size(), 0u);
+
+    parametersResults.clear();
+
+    halResult = mModule->getParameters({"com.android.unknown*", "sample"}, &parametersResults);
+
+    ASSERT_TRUE(halResult.isOk());
+    ASSERT_EQ(parametersResults.size(), 0u);
+}
+
+/**
+ * Test geting image of invalid ID.
+ *
+ * Verifies that:
+ * - getImage call handles argument 0 gracefully.
+ */
+TEST_P(BroadcastRadioHalTest, GetNoImage) {
+    LOG(DEBUG) << "GetNoImage Test";
+    vector<uint8_t> rawImage;
+
+    auto result = mModule->getImage(IBroadcastRadio::INVALID_IMAGE, &rawImage);
+
+    ASSERT_TRUE(result.isOk());
+    ASSERT_EQ(rawImage.size(), 0u);
+}
+
+/**
+ * Test getting config flags.
+ *
+ * Verifies that:
+ * - isConfigFlagSet either succeeds or ends with NOT_SUPPORTED or INVALID_STATE;
+ * - call success or failure is consistent with setConfigFlag.
+ */
+TEST_P(BroadcastRadioHalTest, FetchConfigFlags) {
+    LOG(DEBUG) << "FetchConfigFlags Test";
+
+    for (const auto& flag : kConfigFlagValues) {
+        bool gotValue = false;
+
+        auto halResult = mModule->isConfigFlagSet(flag, &gotValue);
+
+        if (halResult.getServiceSpecificError() != resultToInt(Result::NOT_SUPPORTED) &&
+            halResult.getServiceSpecificError() != resultToInt(Result::INVALID_STATE)) {
+            ASSERT_TRUE(halResult.isOk());
+        }
+
+        // set must fail or succeed the same way as get
+        auto setResult = mModule->setConfigFlag(flag, /* value= */ false);
+
+        EXPECT_TRUE((halResult.isOk() && setResult.isOk()) ||
+                    (halResult.getServiceSpecificError()) == setResult.getServiceSpecificError());
+
+        setResult = mModule->setConfigFlag(flag, /* value= */ true);
+
+        EXPECT_TRUE((halResult.isOk() && setResult.isOk()) ||
+                    (halResult.getServiceSpecificError()) == setResult.getServiceSpecificError());
+    }
+}
+
+/**
+ * Test setting config flags.
+ *
+ * Verifies that:
+ * - setConfigFlag either succeeds or ends with NOT_SUPPORTED or INVALID_STATE;
+ * - isConfigFlagSet reflects the state requested immediately after the set call.
+ */
+TEST_P(BroadcastRadioHalTest, SetConfigFlags) {
+    LOG(DEBUG) << "SetConfigFlags Test";
+
+    auto get = [&](ConfigFlag flag) -> bool {
+        bool gotValue;
+
+        auto halResult = mModule->isConfigFlagSet(flag, &gotValue);
+
+        EXPECT_TRUE(halResult.isOk());
+        return gotValue;
+    };
+
+    auto notSupportedError = resultToInt(Result::NOT_SUPPORTED);
+    auto invalidStateError = resultToInt(Result::INVALID_STATE);
+    for (const auto& flag : kConfigFlagValues) {
+        auto result = mModule->setConfigFlag(flag, /* value= */ false);
+
+        if (result.getServiceSpecificError() == notSupportedError ||
+            result.getServiceSpecificError() == invalidStateError) {
+            // setting to true must result in the same error as false
+            auto secondResult = mModule->setConfigFlag(flag, /* value= */ true);
+
+            EXPECT_TRUE((result.isOk() && secondResult.isOk()) ||
+                        result.getServiceSpecificError() == secondResult.getServiceSpecificError());
+            continue;
+        } else {
+            ASSERT_TRUE(result.isOk());
+        }
+
+        // verify false is set
+        bool value = get(flag);
+        EXPECT_FALSE(value);
+
+        // try setting true this time
+        result = mModule->setConfigFlag(flag, /* value= */ true);
+
+        ASSERT_TRUE(result.isOk());
+        value = get(flag);
+        EXPECT_TRUE(value);
+
+        // false again
+        result = mModule->setConfigFlag(flag, /* value= */ false);
+
+        ASSERT_TRUE(result.isOk());
+        value = get(flag);
+        EXPECT_FALSE(value);
+    }
+}
+
+/**
+ * Test getting program list using empty program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within kProgramListScanTimeoutMs;
+ * - stopProgramListUpdates does not crash.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromEmptyFilter) {
+    LOG(DEBUG) << "GetProgramListFromEmptyFilter Test";
+
+    getProgramList();
+}
+
+/**
+ * Test getting program list using AMFM frequency program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within kProgramListScanTimeoutMs;
+ * - stopProgramListUpdates does not crash;
+ * - result for startProgramListUpdates using a filter with AMFM_FREQUENCY_KHZ value of the first
+ *   AMFM program matches the expected result.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromAmFmFilter) {
+    LOG(DEBUG) << "GetProgramListFromAmFmFilter Test";
+
+    std::optional<bcutils::ProgramInfoSet> completeList = getProgramList();
+    if (!completeList) {
+        printSkipped("No program list available");
+        return;
+    }
+
+    ProgramFilter amfmFilter = {};
+    int expectedResultSize = 0;
+    uint64_t expectedFreq = 0;
+    for (const auto& program : *completeList) {
+        vector<int> amfmIds =
+                bcutils::getAllIds(program.selector, IdentifierType::AMFM_FREQUENCY_KHZ);
+        EXPECT_LE(amfmIds.size(), 1u);
+        if (amfmIds.size() == 0) {
+            continue;
+        }
+
+        if (expectedResultSize == 0) {
+            expectedFreq = amfmIds[0];
+            amfmFilter.identifiers = {
+                    makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, expectedFreq)};
+            expectedResultSize = 1;
+        } else if (amfmIds[0] == expectedFreq) {
+            expectedResultSize++;
+        }
+    }
+
+    if (expectedResultSize == 0) {
+        printSkipped("No Am/FM programs available");
+        return;
+    }
+    std::optional<bcutils::ProgramInfoSet> amfmList = getProgramList(amfmFilter);
+    ASSERT_EQ(amfmList->size(), expectedResultSize) << "amfm filter result size is wrong";
+}
+
+/**
+ * Test getting program list using DAB ensemble program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within kProgramListScanTimeoutMs;
+ * - stopProgramListUpdates does not crash;
+ * - result for startProgramListUpdates using a filter with DAB_ENSEMBLE value of the first DAB
+ *   program matches the expected result.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromDabFilter) {
+    LOG(DEBUG) << "GetProgramListFromDabFilter Test";
+
+    std::optional<bcutils::ProgramInfoSet> completeList = getProgramList();
+    if (!completeList) {
+        printSkipped("No program list available");
+        return;
+    }
+
+    ProgramFilter dabFilter = {};
+    int expectedResultSize = 0;
+    uint64_t expectedEnsemble = 0;
+    for (const auto& program : *completeList) {
+        auto dabEnsembles = bcutils::getAllIds(program.selector, IdentifierType::DAB_ENSEMBLE);
+        EXPECT_LE(dabEnsembles.size(), 1u);
+        if (dabEnsembles.size() == 0) {
+            continue;
+        }
+
+        if (expectedResultSize == 0) {
+            expectedEnsemble = dabEnsembles[0];
+            dabFilter.identifiers = {
+                    makeIdentifier(IdentifierType::DAB_ENSEMBLE, expectedEnsemble)};
+            expectedResultSize = 1;
+        } else if (dabEnsembles[0] == expectedEnsemble) {
+            expectedResultSize++;
+        }
+    }
+
+    if (expectedResultSize == 0) {
+        printSkipped("No DAB programs available");
+        return;
+    }
+    std::optional<bcutils::ProgramInfoSet> dabList = getProgramList(dabFilter);
+    ASSERT_EQ(dabList->size(), expectedResultSize) << "dab filter result size is wrong";
+}
+
+/**
+ * Test HD_STATION_NAME correctness.
+ *
+ * Verifies that if a program on the list contains HD_STATION_NAME identifier:
+ *  - the program provides station name in its metadata;
+ *  - the identifier matches the name;
+ *  - there is only one identifier of that type.
+ */
+TEST_P(BroadcastRadioHalTest, HdRadioStationNameId) {
+    LOG(DEBUG) << "HdRadioStationNameId Test";
+
+    std::optional<bcutils::ProgramInfoSet> list = getProgramList();
+    if (!list) {
+        printSkipped("No program list");
+        return;
+    }
+
+    for (const auto& program : *list) {
+        vector<int> nameIds = bcutils::getAllIds(program.selector, IdentifierType::HD_STATION_NAME);
+        EXPECT_LE(nameIds.size(), 1u);
+        if (nameIds.size() == 0) {
+            continue;
+        }
+
+        std::optional<string> name = bcutils::getMetadataString(program, Metadata::programName);
+        if (!name) {
+            name = bcutils::getMetadataString(program, Metadata::rdsPs);
+        }
+        ASSERT_TRUE(name.has_value());
+
+        ProgramIdentifier expectedId = bcutils::makeHdRadioStationName(*name);
+        EXPECT_EQ(nameIds[0], expectedId.value);
+    }
+}
+
+/**
+ * Test announcement listener registration.
+ *
+ * Verifies that:
+ *  - registerAnnouncementListener either succeeds or returns NOT_SUPPORTED;
+ *  - if it succeeds, it returns a valid close handle (which is a nullptr otherwise);
+ *  - closing handle does not crash.
+ */
+TEST_P(BroadcastRadioHalTest, AnnouncementListenerRegistration) {
+    LOG(DEBUG) << "AnnouncementListenerRegistration Test";
+    std::shared_ptr<AnnouncementListenerMock> listener =
+            SharedRefBase::make<AnnouncementListenerMock>();
+    std::shared_ptr<ICloseHandle> closeHandle = nullptr;
+
+    auto halResult = mModule->registerAnnouncementListener(listener, {AnnouncementType::EMERGENCY},
+                                                           &closeHandle);
+
+    if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+        ASSERT_EQ(closeHandle.get(), nullptr);
+        printSkipped("Announcements not supported");
+        return;
+    }
+
+    ASSERT_TRUE(halResult.isOk());
+    ASSERT_NE(closeHandle.get(), nullptr);
+
+    closeHandle->close();
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BroadcastRadioHalTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, BroadcastRadioHalTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IBroadcastRadio::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+}  // namespace aidl::android::hardware::broadcastradio::vts
+
+int main(int argc, char** argv) {
+    android::base::SetDefaultTag("BcRadio.vts");
+    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(4);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/broadcastradio/common/OWNERS b/broadcastradio/common/OWNERS
index 136b607..259b91e 100644
--- a/broadcastradio/common/OWNERS
+++ b/broadcastradio/common/OWNERS
@@ -1,3 +1,5 @@
 # Automotive team
-egranata@google.com
-twasilczyk@google.com
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/common/utils/WorkerThread.cpp b/broadcastradio/common/utils/WorkerThread.cpp
index 31f4d3f..43fd04a 100644
--- a/broadcastradio/common/utils/WorkerThread.cpp
+++ b/broadcastradio/common/utils/WorkerThread.cpp
@@ -18,20 +18,23 @@
 
 namespace android {
 
-using std::chrono::milliseconds;
-using std::chrono::steady_clock;
 using std::function;
 using std::lock_guard;
 using std::mutex;
-using std::priority_queue;
-using std::this_thread::sleep_for;
 using std::unique_lock;
+using std::chrono::milliseconds;
+using std::chrono::steady_clock;
+using std::this_thread::sleep_for;
 
 bool operator<(const WorkerThread::Task& lhs, const WorkerThread::Task& rhs) {
     return lhs.when > rhs.when;
 }
 
-WorkerThread::WorkerThread() : mIsTerminating(false), mThread(&WorkerThread::threadLoop, this) {}
+WorkerThread::WorkerThread() : mIsTerminating(false) {
+    // putting mThread in constructor instead of initializer list
+    // to ensure all class members are init before mThread starts
+    mThread = std::thread(&WorkerThread::threadLoop, this);
+}
 
 WorkerThread::~WorkerThread() {
     {
@@ -43,16 +46,26 @@
 }
 
 void WorkerThread::schedule(function<void()> task, milliseconds delay) {
+    auto cancelTask = []() {};
+    schedule(std::move(task), cancelTask, delay);
+}
+
+void WorkerThread::schedule(function<void()> task, function<void()> cancelTask,
+                            milliseconds delay) {
     auto when = steady_clock::now() + delay;
 
     lock_guard<mutex> lk(mMut);
-    mTasks.push(Task({when, task}));
+    mTasks.push(Task({when, std::move(task), std::move(cancelTask)}));
     mCond.notify_one();
 }
 
 void WorkerThread::cancelAll() {
     lock_guard<mutex> lk(mMut);
-    priority_queue<Task>().swap(mTasks);  // empty queue
+    while (!mTasks.empty()) {
+        auto task = mTasks.top();
+        task.onCanceled();
+        mTasks.pop();
+    }
 }
 
 void WorkerThread::threadLoop() {
diff --git a/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h b/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
index 62bede6..457b57e 100644
--- a/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
+++ b/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
@@ -28,12 +28,15 @@
     virtual ~WorkerThread();
 
     void schedule(std::function<void()> task, std::chrono::milliseconds delay);
+    void schedule(std::function<void()> task, std::function<void()> cancelTask,
+                  std::chrono::milliseconds delay);
     void cancelAll();
 
    private:
     struct Task {
         std::chrono::time_point<std::chrono::steady_clock> when;
         std::function<void()> what;
+        std::function<void()> onCanceled;
     };
     friend bool operator<(const Task& lhs, const Task& rhs);
 
diff --git a/broadcastradio/common/utilsaidl/Android.bp b/broadcastradio/common/utilsaidl/Android.bp
new file mode 100644
index 0000000..fa6de19
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/Android.bp
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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_static {
+    name: "android.hardware.broadcastradio@common-utils-aidl-lib",
+    vendor_available: true,
+    relative_install_path: "hw",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wno-error=implicit-fallthrough",
+    ],
+    cppflags: [
+        "-std=c++1z",
+    ],
+    srcs: [
+        "Utils.cpp",
+    ],
+    export_include_dirs: ["include"],
+    shared_libs: [
+        "android.hardware.broadcastradio-V1-ndk",
+        "libbase",
+    ],
+    static_libs: [
+        "libmath",
+    ],
+}
diff --git a/broadcastradio/common/utilsaidl/Utils.cpp b/broadcastradio/common/utilsaidl/Utils.cpp
new file mode 100644
index 0000000..0551bad
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/Utils.cpp
@@ -0,0 +1,558 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BcRadioAidlDef.utils"
+
+#include "broadcastradio-utils-aidl/Utils.h"
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+
+#include <math/HashCombine.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace utils {
+
+namespace {
+
+using ::android::base::EqualsIgnoreCase;
+using ::std::string;
+using ::std::vector;
+
+const int64_t kValueForNotFoundIdentifier = 0;
+
+bool bothHaveId(const ProgramSelector& a, const ProgramSelector& b, const IdentifierType& type) {
+    return hasId(a, type) && hasId(b, type);
+}
+
+bool haveEqualIds(const ProgramSelector& a, const ProgramSelector& b, const IdentifierType& type) {
+    if (!bothHaveId(a, b, type)) {
+        return false;
+    }
+    /* We should check all Ids of a given type (ie. other AF),
+     * but it doesn't matter for default implementation.
+     */
+    return getId(a, type) == getId(b, type);
+}
+
+int getHdSubchannel(const ProgramSelector& sel) {
+    int64_t hdSidExt = getId(sel, IdentifierType::HD_STATION_ID_EXT, /* defaultValue */ 0);
+    hdSidExt >>= 32;        // Station ID number
+    return hdSidExt & 0xF;  // HD Radio subchannel
+}
+
+bool maybeGetId(const ProgramSelector& sel, const IdentifierType& type, int64_t* val) {
+    // iterate through primaryId and secondaryIds
+    for (auto it = begin(sel); it != end(sel); it++) {
+        if (it->type == type) {
+            if (val != nullptr) {
+                *val = it->value;
+            }
+            return true;
+        }
+    }
+
+    return false;
+}
+
+}  // namespace
+
+IdentifierIterator::IdentifierIterator(const ProgramSelector& sel) : IdentifierIterator(sel, 0) {}
+
+IdentifierIterator::IdentifierIterator(const ProgramSelector& sel, size_t pos)
+    : mSel(sel), mPos(pos) {}
+
+const IdentifierIterator IdentifierIterator::operator++(int) {
+    IdentifierIterator i = *this;
+    mPos++;
+    return i;
+}
+
+IdentifierIterator& IdentifierIterator::operator++() {
+    ++mPos;
+    return *this;
+}
+
+IdentifierIterator::refType IdentifierIterator::operator*() const {
+    if (mPos == 0) {
+        return getSelector().primaryId;
+    }
+
+    // mPos is 1-based for secondary identifiers
+    DCHECK(mPos <= getSelector().secondaryIds.size());
+    return getSelector().secondaryIds[mPos - 1];
+}
+
+bool IdentifierIterator::operator==(const IdentifierIterator& rhs) const {
+    // Check, if both iterators points at the same selector.
+    if (reinterpret_cast<intptr_t>(&getSelector()) !=
+        reinterpret_cast<intptr_t>(&rhs.getSelector())) {
+        return false;
+    }
+
+    return mPos == rhs.mPos;
+}
+
+int32_t resultToInt(Result result) {
+    return static_cast<int32_t>(result);
+}
+
+FrequencyBand getBand(int64_t freq) {
+    // keep in sync with
+    // frameworks/base/services/core/java/com/android/server/broadcastradio/aidl/Utils.java
+    if (freq < 30) return FrequencyBand::UNKNOWN;
+    if (freq < 500) return FrequencyBand::AM_LW;
+    if (freq < 1705) return FrequencyBand::AM_MW;
+    if (freq < 30000) return FrequencyBand::AM_SW;
+    if (freq < 60000) return FrequencyBand::UNKNOWN;
+    if (freq < 110000) return FrequencyBand::FM;
+    return FrequencyBand::UNKNOWN;
+}
+
+bool tunesTo(const ProgramSelector& a, const ProgramSelector& b) {
+    IdentifierType type = b.primaryId.type;
+
+    switch (type) {
+        case IdentifierType::HD_STATION_ID_EXT:
+        case IdentifierType::RDS_PI:
+        case IdentifierType::AMFM_FREQUENCY_KHZ:
+            if (haveEqualIds(a, b, IdentifierType::HD_STATION_ID_EXT)) return true;
+            if (haveEqualIds(a, b, IdentifierType::RDS_PI)) return true;
+            return getHdSubchannel(b) == 0 &&
+                   haveEqualIds(a, b, IdentifierType::AMFM_FREQUENCY_KHZ);
+        case IdentifierType::DAB_SID_EXT:
+            if (!haveEqualIds(a, b, IdentifierType::DAB_SID_EXT)) {
+                return false;
+            }
+            if (hasId(a, IdentifierType::DAB_ENSEMBLE) &&
+                !haveEqualIds(a, b, IdentifierType::DAB_ENSEMBLE)) {
+                return false;
+            }
+            if (hasId(a, IdentifierType::DAB_FREQUENCY_KHZ) &&
+                !haveEqualIds(a, b, IdentifierType::DAB_FREQUENCY_KHZ)) {
+                return false;
+            }
+            return true;
+        case IdentifierType::DRMO_SERVICE_ID:
+            return haveEqualIds(a, b, IdentifierType::DRMO_SERVICE_ID);
+        case IdentifierType::SXM_SERVICE_ID:
+            return haveEqualIds(a, b, IdentifierType::SXM_SERVICE_ID);
+        default:  // includes all vendor types
+            LOG(WARNING) << "unsupported program type: " << toString(type);
+            return false;
+    }
+}
+
+bool hasId(const ProgramSelector& sel, const IdentifierType& type) {
+    return maybeGetId(sel, type, /* val */ nullptr);
+}
+
+int64_t getId(const ProgramSelector& sel, const IdentifierType& type) {
+    int64_t val;
+
+    if (maybeGetId(sel, type, &val)) {
+        return val;
+    }
+
+    LOG(WARNING) << "identifier not found: " << toString(type);
+    return kValueForNotFoundIdentifier;
+}
+
+int64_t getId(const ProgramSelector& sel, const IdentifierType& type, int64_t defaultValue) {
+    if (!hasId(sel, type)) {
+        return defaultValue;
+    }
+    return getId(sel, type);
+}
+
+vector<int> getAllIds(const ProgramSelector& sel, const IdentifierType& type) {
+    vector<int> ret;
+
+    // iterate through primaryId and secondaryIds
+    for (auto it = begin(sel); it != end(sel); it++) {
+        if (it->type == type) {
+            ret.push_back(it->value);
+        }
+    }
+
+    return ret;
+}
+
+bool isSupported(const Properties& prop, const ProgramSelector& sel) {
+    for (auto it = prop.supportedIdentifierTypes.begin(); it != prop.supportedIdentifierTypes.end();
+         it++) {
+        if (hasId(sel, *it)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool isValid(const ProgramIdentifier& id) {
+    int64_t val = id.value;
+    bool valid = true;
+
+    auto expect = [&valid](bool condition, const string& message) {
+        if (!condition) {
+            valid = false;
+            LOG(ERROR) << "identifier not valid, expected " << message;
+        }
+    };
+
+    switch (id.type) {
+        case IdentifierType::INVALID:
+            expect(false, "IdentifierType::INVALID");
+            break;
+        case IdentifierType::DAB_FREQUENCY_KHZ:
+            expect(val > 100000u, "f > 100MHz");
+            [[fallthrough]];
+        case IdentifierType::AMFM_FREQUENCY_KHZ:
+        case IdentifierType::DRMO_FREQUENCY_KHZ:
+            expect(val > 100u, "f > 100kHz");
+            expect(val < 10000000u, "f < 10GHz");
+            break;
+        case IdentifierType::RDS_PI:
+            expect(val != 0u, "RDS PI != 0");
+            expect(val <= 0xFFFFu, "16bit id");
+            break;
+        case IdentifierType::HD_STATION_ID_EXT: {
+            int64_t stationId = val & 0xFFFFFFFF;  // 32bit
+            val >>= 32;
+            int64_t subchannel = val & 0xF;  // 4bit
+            val >>= 4;
+            int64_t freq = val & 0x3FFFF;  // 18bit
+            expect(stationId != 0u, "HD station id != 0");
+            expect(subchannel < 8u, "HD subch < 8");
+            expect(freq > 100u, "f > 100kHz");
+            expect(freq < 10000000u, "f < 10GHz");
+            break;
+        }
+        case IdentifierType::HD_STATION_NAME: {
+            while (val > 0) {
+                char ch = static_cast<char>(val & 0xFF);
+                val >>= 8;
+                expect((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'),
+                       "HD_STATION_NAME does not match [A-Z0-9]+");
+            }
+            break;
+        }
+        case IdentifierType::DAB_SID_EXT: {
+            int64_t sid = val & 0xFFFFFFFF;  // 32bit
+            val >>= 32;
+            int64_t ecc = val & 0xFF;  // 8bit
+            expect(sid != 0u, "DAB SId != 0");
+            expect(ecc >= 0xA0u && ecc <= 0xF6u, "Invalid ECC, see ETSI TS 101 756 V2.1.1");
+            break;
+        }
+        case IdentifierType::DAB_ENSEMBLE:
+            expect(val != 0u, "DAB ensemble != 0");
+            expect(val <= 0xFFFFu, "16bit id");
+            break;
+        case IdentifierType::DAB_SCID:
+            expect(val > 0xFu, "12bit SCId (not 4bit SCIdS)");
+            expect(val <= 0xFFFu, "12bit id");
+            break;
+        case IdentifierType::DRMO_SERVICE_ID:
+            expect(val != 0u, "DRM SId != 0");
+            expect(val <= 0xFFFFFFu, "24bit id");
+            break;
+        case IdentifierType::SXM_SERVICE_ID:
+            expect(val != 0u, "SXM SId != 0");
+            expect(val <= 0xFFFFFFFFu, "32bit id");
+            break;
+        case IdentifierType::SXM_CHANNEL:
+            expect(val < 1000u, "SXM channel < 1000");
+            break;
+        case IdentifierType::VENDOR_START:
+        case IdentifierType::VENDOR_END:
+            // skip
+            break;
+    }
+
+    return valid;
+}
+
+bool isValid(const ProgramSelector& sel) {
+    if (sel.primaryId.type != IdentifierType::AMFM_FREQUENCY_KHZ &&
+        sel.primaryId.type != IdentifierType::RDS_PI &&
+        sel.primaryId.type != IdentifierType::HD_STATION_ID_EXT &&
+        sel.primaryId.type != IdentifierType::DAB_SID_EXT &&
+        sel.primaryId.type != IdentifierType::DRMO_SERVICE_ID &&
+        sel.primaryId.type != IdentifierType::SXM_SERVICE_ID &&
+        (sel.primaryId.type < IdentifierType::VENDOR_START ||
+         sel.primaryId.type > IdentifierType::VENDOR_END)) {
+        return false;
+    }
+    return isValid(sel.primaryId);
+}
+
+ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value) {
+    return {type, value};
+}
+
+ProgramSelector makeSelectorAmfm(int32_t frequency) {
+    ProgramSelector sel = {};
+    sel.primaryId = makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, frequency);
+    return sel;
+}
+
+ProgramSelector makeSelectorDab(int64_t sidExt) {
+    ProgramSelector sel = {};
+    sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
+    return sel;
+}
+
+ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq) {
+    ProgramSelector sel = {};
+    sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
+    vector<ProgramIdentifier> secondaryIds = {
+            makeIdentifier(IdentifierType::DAB_ENSEMBLE, ensemble),
+            makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, freq)};
+    sel.secondaryIds = std::move(secondaryIds);
+    return sel;
+}
+
+bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel) {
+    if (filter.identifierTypes.size() > 0) {
+        auto typeEquals = [](const ProgramIdentifier& id, IdentifierType type) {
+            return id.type == type;
+        };
+        auto it = std::find_first_of(begin(sel), end(sel), filter.identifierTypes.begin(),
+                                     filter.identifierTypes.end(), typeEquals);
+        if (it == end(sel)) {
+            return false;
+        }
+    }
+
+    if (filter.identifiers.size() > 0) {
+        auto it = std::find_first_of(begin(sel), end(sel), filter.identifiers.begin(),
+                                     filter.identifiers.end());
+        if (it == end(sel)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+size_t ProgramInfoHasher::operator()(const ProgramInfo& info) const {
+    const ProgramIdentifier& id = info.selector.primaryId;
+
+    // This is not the best hash implementation, but good enough for default HAL
+    // implementation and tests.
+    size_t h = 0;
+    ::android::hashCombineSingle(h, id.type);
+    ::android::hashCombineSingle(h, id.value);
+    return h;
+}
+
+bool ProgramInfoKeyEqual::operator()(const ProgramInfo& info1, const ProgramInfo& info2) const {
+    const ProgramIdentifier& id1 = info1.selector.primaryId;
+    const ProgramIdentifier& id2 = info2.selector.primaryId;
+    return id1.type == id2.type && id1.value == id2.value;
+}
+
+void updateProgramList(const ProgramListChunk& chunk, ProgramInfoSet* list) {
+    if (chunk.purge) {
+        list->clear();
+    }
+
+    list->insert(chunk.modified.begin(), chunk.modified.end());
+
+    if (!chunk.removed.has_value()) {
+        return;
+    }
+
+    for (auto& id : chunk.removed.value()) {
+        if (id.has_value()) {
+            ProgramInfo info = {};
+            info.selector.primaryId = id.value();
+            list->erase(info);
+        }
+    }
+}
+
+std::optional<std::string> getMetadataString(const ProgramInfo& info, const Metadata::Tag& tag) {
+    auto isRdsPs = [tag](const Metadata& item) { return item.getTag() == tag; };
+
+    auto it = std::find_if(info.metadata.begin(), info.metadata.end(), isRdsPs);
+    if (it == info.metadata.end()) {
+        return std::nullopt;
+    }
+
+    std::string metadataString;
+    switch (it->getTag()) {
+        case Metadata::rdsPs:
+            metadataString = it->get<Metadata::rdsPs>();
+            break;
+        case Metadata::rdsPty:
+            metadataString = std::to_string(it->get<Metadata::rdsPty>());
+            break;
+        case Metadata::rbdsPty:
+            metadataString = std::to_string(it->get<Metadata::rbdsPty>());
+            break;
+        case Metadata::rdsRt:
+            metadataString = it->get<Metadata::rdsRt>();
+            break;
+        case Metadata::songTitle:
+            metadataString = it->get<Metadata::songTitle>();
+            break;
+        case Metadata::songArtist:
+            metadataString = it->get<Metadata::songArtist>();
+            break;
+        case Metadata::songAlbum:
+            metadataString = it->get<Metadata::songAlbum>();
+            break;
+        case Metadata::stationIcon:
+            metadataString = std::to_string(it->get<Metadata::stationIcon>());
+            break;
+        case Metadata::albumArt:
+            metadataString = std::to_string(it->get<Metadata::albumArt>());
+            break;
+        case Metadata::programName:
+            metadataString = it->get<Metadata::programName>();
+            break;
+        case Metadata::dabEnsembleName:
+            metadataString = it->get<Metadata::dabEnsembleName>();
+            break;
+        case Metadata::dabEnsembleNameShort:
+            metadataString = it->get<Metadata::dabEnsembleNameShort>();
+            break;
+        case Metadata::dabServiceName:
+            metadataString = it->get<Metadata::dabServiceName>();
+            break;
+        case Metadata::dabServiceNameShort:
+            metadataString = it->get<Metadata::dabServiceNameShort>();
+            break;
+        case Metadata::dabComponentName:
+            metadataString = it->get<Metadata::dabComponentName>();
+            break;
+        case Metadata::dabComponentNameShort:
+            metadataString = it->get<Metadata::dabComponentNameShort>();
+            break;
+        default:
+            LOG(ERROR) << "Metadata " << it->toString() << " is not converted.";
+            return std::nullopt;
+    }
+    return metadataString;
+}
+
+ProgramIdentifier makeHdRadioStationName(const string& name) {
+    constexpr size_t maxlen = 8;
+
+    string shortName;
+    shortName.reserve(maxlen);
+
+    const auto& loc = std::locale::classic();
+    for (const char& ch : name) {
+        if (!std::isalnum(ch, loc)) {
+            continue;
+        }
+        shortName.push_back(std::toupper(ch, loc));
+        if (shortName.length() >= maxlen) {
+            break;
+        }
+    }
+
+    // Short name is converted to HD_STATION_NAME by encoding each char into its ASCII value in
+    // in little-endian order. For example, "Abc" is converted to 0x434241.
+    int64_t val = 0;
+    for (auto rit = shortName.rbegin(); rit != shortName.rend(); ++rit) {
+        val <<= 8;
+        val |= static_cast<char>(*rit);
+    }
+
+    return makeIdentifier(IdentifierType::HD_STATION_NAME, val);
+}
+
+IdentifierType getType(int typeAsInt) {
+    return static_cast<IdentifierType>(typeAsInt);
+}
+
+bool parseArgInt(const string& s, int* out) {
+    return ::android::base::ParseInt(s, out);
+}
+
+bool parseArgLong(const std::string& s, long* out) {
+    return ::android::base::ParseInt(s, out);
+}
+
+bool parseArgBool(const string& s, bool* out) {
+    if (EqualsIgnoreCase(s, "true")) {
+        *out = true;
+    } else if (EqualsIgnoreCase(s, "false")) {
+        *out = false;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+bool parseArgDirection(const string& s, bool* out) {
+    if (EqualsIgnoreCase(s, "up")) {
+        *out = true;
+    } else if (EqualsIgnoreCase(s, "down")) {
+        *out = false;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+bool parseArgIdentifierTypeArray(const string& s, vector<IdentifierType>* out) {
+    for (const string& val : ::android::base::Split(s, ",")) {
+        int outInt;
+        if (!parseArgInt(val, &outInt)) {
+            return false;
+        }
+        out->push_back(getType(outInt));
+    }
+    return true;
+}
+
+bool parseProgramIdentifierList(const std::string& s, vector<ProgramIdentifier>* out) {
+    for (const string& idStr : ::android::base::Split(s, ",")) {
+        const vector<string> idStrPair = ::android::base::Split(idStr, ":");
+        if (idStrPair.size() != 2) {
+            return false;
+        }
+        int idType;
+        if (!parseArgInt(idStrPair[0], &idType)) {
+            return false;
+        }
+        long idVal;
+        if (!parseArgLong(idStrPair[1], &idVal)) {
+            return false;
+        }
+        ProgramIdentifier id = {getType(idType), idVal};
+        out->push_back(id);
+    }
+    return true;
+}
+
+}  // namespace utils
+
+utils::IdentifierIterator begin(const ProgramSelector& sel) {
+    return utils::IdentifierIterator(sel);
+}
+
+utils::IdentifierIterator end(const ProgramSelector& sel) {
+    return utils::IdentifierIterator(sel) + 1 /* primary id */ + sel.secondaryIds.size();
+}
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
new file mode 100644
index 0000000..ad075f2
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/broadcastradio/IdentifierType.h>
+#include <aidl/android/hardware/broadcastradio/Metadata.h>
+#include <aidl/android/hardware/broadcastradio/ProgramFilter.h>
+#include <aidl/android/hardware/broadcastradio/ProgramIdentifier.h>
+#include <aidl/android/hardware/broadcastradio/ProgramInfo.h>
+#include <aidl/android/hardware/broadcastradio/ProgramListChunk.h>
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+#include <aidl/android/hardware/broadcastradio/Properties.h>
+#include <aidl/android/hardware/broadcastradio/Result.h>
+
+#include <numeric>
+#include <optional>
+#include <thread>
+#include <unordered_set>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace utils {
+
+enum class FrequencyBand {
+    UNKNOWN,
+    FM,
+    AM_LW,
+    AM_MW,
+    AM_SW,
+};
+
+class IdentifierIterator final
+    : public std::iterator<std::random_access_iterator_tag, ProgramIdentifier, ssize_t,
+                           const ProgramIdentifier*, const ProgramIdentifier&> {
+    using ptrType = typename std::iterator_traits<IdentifierIterator>::pointer;
+    using refType = typename std::iterator_traits<IdentifierIterator>::reference;
+    using diffType = typename std::iterator_traits<IdentifierIterator>::difference_type;
+
+  public:
+    explicit IdentifierIterator(const ProgramSelector& sel);
+
+    const IdentifierIterator operator++(int);
+    IdentifierIterator& operator++();
+    refType operator*() const;
+    inline ptrType operator->() const { return &operator*(); }
+    IdentifierIterator operator+(diffType v) const { return IdentifierIterator(mSel, mPos + v); }
+    bool operator==(const IdentifierIterator& rhs) const;
+    inline bool operator!=(const IdentifierIterator& rhs) const { return !operator==(rhs); };
+
+  private:
+    explicit IdentifierIterator(const ProgramSelector& sel, size_t pos);
+
+    std::reference_wrapper<const ProgramSelector> mSel;
+
+    const ProgramSelector& getSelector() const { return mSel.get(); }
+
+    /** 0 is the primary identifier, 1-n are secondary identifiers. */
+    size_t mPos = 0;
+};
+
+/**
+ * Convert Result to int
+ */
+int32_t resultToInt(Result result);
+
+/**
+ * Guesses band from the frequency value.
+ *
+ * The band bounds are not exact to cover multiple regions.
+ * The function is biased towards success, i.e. it never returns
+ * FrequencyBand::UNKNOWN for correct frequency, but a result for
+ * incorrect one is undefined (it doesn't have to return UNKNOWN).
+ */
+FrequencyBand getBand(int64_t frequency);
+
+/**
+ * Checks, if {@code pointer} tunes to {@channel}.
+ *
+ * For example, having a channel {AMFM_FREQUENCY_KHZ = 103.3}:
+ * - selector {AMFM_FREQUENCY_KHZ = 103.3, HD_SUBCHANNEL = 0} can tune to this channel;
+ * - selector {AMFM_FREQUENCY_KHZ = 103.3, HD_SUBCHANNEL = 1} can't.
+ *
+ * @param pointer selector we're trying to match against channel.
+ * @param channel existing channel.
+ */
+bool tunesTo(const ProgramSelector& pointer, const ProgramSelector& channel);
+
+/**
+ * Checks whether a given program selector has the given ID (either primary or secondary).
+ */
+bool hasId(const ProgramSelector& sel, const IdentifierType& type);
+
+/**
+ * Returns ID (either primary or secondary) for a given program selector.
+ *
+ * If the selector does not contain given type, returns kValueForNotFoundIdentifier
+ * and emits a warning.
+ */
+int64_t getId(const ProgramSelector& sel, const IdentifierType& type);
+
+/**
+ * Returns ID (either primary or secondary) for a given program selector.
+ *
+ * If the selector does not contain given type, returns default value.
+ */
+int64_t getId(const ProgramSelector& sel, const IdentifierType& type, int64_t defaultValue);
+
+/**
+ * Returns all IDs of a given type.
+ */
+std::vector<int> getAllIds(const ProgramSelector& sel, const IdentifierType& type);
+
+/**
+ * Checks, if a given selector is supported by the radio module.
+ *
+ * @param prop Module description.
+ * @param sel The selector to check.
+ * @return True, if the selector is supported, false otherwise.
+ */
+bool isSupported(const Properties& prop, const ProgramSelector& sel);
+
+bool isValid(const ProgramIdentifier& id);
+bool isValid(const ProgramSelector& sel);
+
+ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value);
+ProgramSelector makeSelectorAmfm(int32_t frequency);
+ProgramSelector makeSelectorDab(int64_t sidExt);
+ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq);
+
+bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);
+
+struct ProgramInfoHasher {
+    size_t operator()(const ProgramInfo& info) const;
+};
+
+struct ProgramInfoKeyEqual {
+    bool operator()(const ProgramInfo& info1, const ProgramInfo& info2) const;
+};
+
+typedef std::unordered_set<ProgramInfo, ProgramInfoHasher, ProgramInfoKeyEqual> ProgramInfoSet;
+
+void updateProgramList(const ProgramListChunk& chunk, ProgramInfoSet* list);
+
+std::optional<std::string> getMetadataString(const ProgramInfo& info, const Metadata::Tag& tag);
+
+ProgramIdentifier makeHdRadioStationName(const std::string& name);
+
+template <typename aidl_type>
+inline std::string vectorToString(const std::vector<aidl_type>& in_values) {
+    return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
+                           [](const std::string& ls, const aidl_type& rs) {
+                               return ls + (ls.empty() ? "" : ",") + toString(rs);
+                           });
+}
+
+IdentifierType getType(int typeAsInt);
+
+bool parseArgInt(const std::string& s, int* out);
+
+bool parseArgLong(const std::string& s, long* out);
+
+bool parseArgBool(const std::string& s, bool* out);
+
+bool parseArgDirection(const std::string& s, bool* out);
+
+bool parseArgIdentifierTypeArray(const std::string& s, std::vector<IdentifierType>* out);
+
+bool parseProgramIdentifierList(const std::string& s, std::vector<ProgramIdentifier>* out);
+
+}  // namespace utils
+
+utils::IdentifierIterator begin(const ProgramSelector& sel);
+utils::IdentifierIterator end(const ProgramSelector& sel);
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/camera/OWNERS b/camera/OWNERS
new file mode 100644
index 0000000..b946264
--- /dev/null
+++ b/camera/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 41727
+
+include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/README.md b/camera/README.md
index 8ce3352..25badfd 100644
--- a/camera/README.md
+++ b/camera/README.md
@@ -10,3 +10,8 @@
 
 More complete information about the Android camera HAL and subsystem can be found at
 [source.android.com](http://source.android.com/devices/camera/index.html).
+
+### AIDL Camera HAL Interfaces
+
+The AIDL Camera HAL interfaces can be found in the respective <interface>/aidl
+directories.
diff --git a/camera/common/1.0/default/Android.bp b/camera/common/1.0/default/Android.bp
deleted file mode 100644
index 4a5ca83..0000000
--- a/camera/common/1.0/default/Android.bp
+++ /dev/null
@@ -1,39 +0,0 @@
-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_static {
-    name: "android.hardware.camera.common@1.0-helper",
-    vendor_available: true,
-    defaults: ["hidl_defaults"],
-    srcs: [
-        "CameraModule.cpp",
-        "CameraMetadata.cpp",
-        "CameraParameters.cpp",
-        "VendorTagDescriptor.cpp",
-        "HandleImporter.cpp",
-        "Exif.cpp",
-    ],
-    cflags: [
-        "-Werror",
-        "-Wextra",
-        "-Wall",
-    ],
-    shared_libs: [
-        "liblog",
-        "libgralloctypes",
-        "libhardware",
-        "libcamera_metadata",
-        "android.hardware.graphics.mapper@2.0",
-        "android.hardware.graphics.mapper@3.0",
-        "android.hardware.graphics.mapper@4.0",
-        "libexif",
-    ],
-    include_dirs: ["system/media/private/camera/include"],
-    export_include_dirs: ["include"],
-}
diff --git a/camera/common/1.0/default/CameraMetadata.cpp b/camera/common/1.0/default/CameraMetadata.cpp
deleted file mode 100644
index eb1bd1c..0000000
--- a/camera/common/1.0/default/CameraMetadata.cpp
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (C) 2016 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_NDEBUG 0
-
-#define LOG_TAG "CamComm1.0-MD"
-#include <log/log.h>
-#include <utils/Errors.h>
-
-#include "CameraMetadata.h"
-#include "VendorTagDescriptor.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-#define ALIGN_TO(val, alignment) \
-    (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
-
-CameraMetadata::CameraMetadata() :
-        mBuffer(NULL), mLocked(false) {
-}
-
-CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
-        mLocked(false)
-{
-    mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
-}
-
-CameraMetadata::CameraMetadata(const CameraMetadata &other) :
-        mLocked(false) {
-    mBuffer = clone_camera_metadata(other.mBuffer);
-}
-
-CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
-        mBuffer(NULL), mLocked(false) {
-    acquire(buffer);
-}
-
-CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
-    return operator=(other.mBuffer);
-}
-
-CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
-    if (mLocked) {
-        ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
-        return *this;
-    }
-
-    if (CC_LIKELY(buffer != mBuffer)) {
-        camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
-        clear();
-        mBuffer = newBuffer;
-    }
-    return *this;
-}
-
-CameraMetadata::~CameraMetadata() {
-    mLocked = false;
-    clear();
-}
-
-const camera_metadata_t* CameraMetadata::getAndLock() const {
-    mLocked = true;
-    return mBuffer;
-}
-
-status_t CameraMetadata::unlock(const camera_metadata_t *buffer) const {
-    if (!mLocked) {
-        ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    if (buffer != mBuffer) {
-        ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!",
-                __FUNCTION__);
-        return BAD_VALUE;
-    }
-    mLocked = false;
-    return OK;
-}
-
-camera_metadata_t* CameraMetadata::release() {
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return NULL;
-    }
-    camera_metadata_t *released = mBuffer;
-    mBuffer = NULL;
-    return released;
-}
-
-void CameraMetadata::clear() {
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return;
-    }
-    if (mBuffer) {
-        free_camera_metadata(mBuffer);
-        mBuffer = NULL;
-    }
-}
-
-void CameraMetadata::acquire(camera_metadata_t *buffer) {
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return;
-    }
-    clear();
-    mBuffer = buffer;
-
-    ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK,
-             "%s: Failed to validate metadata structure %p",
-             __FUNCTION__, buffer);
-}
-
-void CameraMetadata::acquire(CameraMetadata &other) {
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return;
-    }
-    acquire(other.release());
-}
-
-status_t CameraMetadata::append(const CameraMetadata &other) {
-    return append(other.mBuffer);
-}
-
-status_t CameraMetadata::append(const camera_metadata_t* other) {
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    size_t extraEntries = get_camera_metadata_entry_count(other);
-    size_t extraData = get_camera_metadata_data_count(other);
-    resizeIfNeeded(extraEntries, extraData);
-
-    return append_camera_metadata(mBuffer, other);
-}
-
-size_t CameraMetadata::entryCount() const {
-    return (mBuffer == NULL) ? 0 :
-            get_camera_metadata_entry_count(mBuffer);
-}
-
-bool CameraMetadata::isEmpty() const {
-    return entryCount() == 0;
-}
-
-status_t CameraMetadata::sort() {
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    return sort_camera_metadata(mBuffer);
-}
-
-status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
-    int tagType = get_local_camera_metadata_tag_type(tag, mBuffer);
-    if ( CC_UNLIKELY(tagType == -1)) {
-        ALOGE("Update metadata entry: Unknown tag %d", tag);
-        return INVALID_OPERATION;
-    }
-    if ( CC_UNLIKELY(tagType != expectedType) ) {
-        ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
-              "got type %s data instead ",
-              get_local_camera_metadata_tag_name(tag, mBuffer), tag,
-              camera_metadata_type_names[tagType], camera_metadata_type_names[expectedType]);
-        return INVALID_OPERATION;
-    }
-    return OK;
-}
-
-status_t CameraMetadata::update(uint32_t tag,
-        const int32_t *data, size_t data_count) {
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    if ( (res = checkType(tag, TYPE_INT32)) != OK) {
-        return res;
-    }
-    return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
-        const uint8_t *data, size_t data_count) {
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
-        return res;
-    }
-    return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
-        const float *data, size_t data_count) {
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
-        return res;
-    }
-    return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
-        const int64_t *data, size_t data_count) {
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    if ( (res = checkType(tag, TYPE_INT64)) != OK) {
-        return res;
-    }
-    return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
-        const double *data, size_t data_count) {
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
-        return res;
-    }
-    return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
-        const camera_metadata_rational_t *data, size_t data_count) {
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
-        return res;
-    }
-    return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
-        const String8 &string) {
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
-        return res;
-    }
-    // string.size() doesn't count the null termination character.
-    return updateImpl(tag, (const void*)string.string(), string.size() + 1);
-}
-
-status_t CameraMetadata::update(const camera_metadata_ro_entry &entry) {
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    if ( (res = checkType(entry.tag, entry.type)) != OK) {
-        return res;
-    }
-    return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
-}
-
-status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
-        size_t data_count) {
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    int type = get_local_camera_metadata_tag_type(tag, mBuffer);
-    if (type == -1) {
-        ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
-        return BAD_VALUE;
-    }
-    // Safety check - ensure that data isn't pointing to this metadata, since
-    // that would get invalidated if a resize is needed
-    size_t bufferSize = get_camera_metadata_size(mBuffer);
-    uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
-    uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
-    if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
-        ALOGE("%s: Update attempted with data from the same metadata buffer!",
-                __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-
-    size_t data_size = calculate_camera_metadata_entry_data_size(type,
-            data_count);
-
-    res = resizeIfNeeded(1, data_size);
-
-    if (res == OK) {
-        camera_metadata_entry_t entry;
-        res = find_camera_metadata_entry(mBuffer, tag, &entry);
-        if (res == NAME_NOT_FOUND) {
-            res = add_camera_metadata_entry(mBuffer,
-                    tag, data, data_count);
-        } else if (res == OK) {
-            res = update_camera_metadata_entry(mBuffer,
-                    entry.index, data, data_count, NULL);
-        }
-    }
-
-    if (res != OK) {
-        ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", __FUNCTION__,
-              get_local_camera_metadata_section_name(tag, mBuffer),
-              get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
-    }
-
-    IF_ALOGV() {
-        ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
-                 OK,
-
-                 "%s: Failed to validate metadata structure after update %p",
-                 __FUNCTION__, mBuffer);
-    }
-
-    return res;
-}
-
-bool CameraMetadata::exists(uint32_t tag) const {
-    camera_metadata_ro_entry entry;
-    return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
-}
-
-camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
-    status_t res;
-    camera_metadata_entry entry;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        entry.count = 0;
-        return entry;
-    }
-    res = find_camera_metadata_entry(mBuffer, tag, &entry);
-    if (CC_UNLIKELY( res != OK )) {
-        entry.count = 0;
-        entry.data.u8 = NULL;
-    }
-    return entry;
-}
-
-camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
-    status_t res;
-    camera_metadata_ro_entry entry;
-    res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
-    if (CC_UNLIKELY( res != OK )) {
-        entry.count = 0;
-        entry.data.u8 = NULL;
-    }
-    return entry;
-}
-
-status_t CameraMetadata::erase(uint32_t tag) {
-    camera_metadata_entry_t entry;
-    status_t res;
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return INVALID_OPERATION;
-    }
-    res = find_camera_metadata_entry(mBuffer, tag, &entry);
-    if (res == NAME_NOT_FOUND) {
-        return OK;
-    } else if (res != OK) {
-        ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", __FUNCTION__,
-              get_local_camera_metadata_section_name(tag, mBuffer),
-              get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
-        return res;
-    }
-    res = delete_camera_metadata_entry(mBuffer, entry.index);
-    if (res != OK) {
-        ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", __FUNCTION__,
-              get_local_camera_metadata_section_name(tag, mBuffer),
-              get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
-    }
-    return res;
-}
-
-void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
-    dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
-}
-
-status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
-    if (mBuffer == NULL) {
-        mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
-        if (mBuffer == NULL) {
-            ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
-            return NO_MEMORY;
-        }
-    } else {
-        size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
-        size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
-        size_t newEntryCount = currentEntryCount +
-                extraEntries;
-        newEntryCount = (newEntryCount > currentEntryCap) ?
-                newEntryCount * 2 : currentEntryCap;
-
-        size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
-        size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
-        size_t newDataCount = currentDataCount +
-                extraData;
-        newDataCount = (newDataCount > currentDataCap) ?
-                newDataCount * 2 : currentDataCap;
-
-        if (newEntryCount > currentEntryCap ||
-                newDataCount > currentDataCap) {
-            camera_metadata_t *oldBuffer = mBuffer;
-            mBuffer = allocate_camera_metadata(newEntryCount,
-                    newDataCount);
-            if (mBuffer == NULL) {
-                ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
-                return NO_MEMORY;
-            }
-            append_camera_metadata(mBuffer, oldBuffer);
-            free_camera_metadata(oldBuffer);
-        }
-    }
-    return OK;
-}
-
-void CameraMetadata::swap(CameraMetadata& other) {
-    if (mLocked) {
-        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
-        return;
-    } else if (other.mLocked) {
-        ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
-        return;
-    }
-
-    camera_metadata* thisBuf = mBuffer;
-    camera_metadata* otherBuf = other.mBuffer;
-
-    other.mBuffer = thisBuf;
-    mBuffer = otherBuf;
-}
-
-status_t CameraMetadata::getTagFromName(const char *name,
-        const VendorTagDescriptor* vTags, uint32_t *tag) {
-
-    if (name == nullptr || tag == nullptr) return BAD_VALUE;
-
-    size_t nameLength = strlen(name);
-
-    const SortedVector<String8> *vendorSections;
-    size_t vendorSectionCount = 0;
-
-    if (vTags != NULL) {
-        vendorSections = vTags->getAllSectionNames();
-        vendorSectionCount = vendorSections->size();
-    }
-
-    // First, find the section by the longest string match
-    const char *section = NULL;
-    size_t sectionIndex = 0;
-    size_t sectionLength = 0;
-    size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
-    for (size_t i = 0; i < totalSectionCount; ++i) {
-
-        const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
-                (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
-
-        ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
-
-        if (strstr(name, str) == name) { // name begins with the section name
-            size_t strLength = strlen(str);
-
-            ALOGV("%s: Name begins with section name", __FUNCTION__);
-
-            // section name is the longest we've found so far
-            if (section == NULL || sectionLength < strLength) {
-                section = str;
-                sectionIndex = i;
-                sectionLength = strLength;
-
-                ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
-            }
-        }
-    }
-
-    if (section == NULL) {
-        return NAME_NOT_FOUND;
-    } else {
-        ALOGV("%s: Found matched section '%s' (%zu)",
-              __FUNCTION__, section, sectionIndex);
-    }
-
-    // Get the tag name component of the name
-    const char *nameTagName = name + sectionLength + 1; // x.y.z -> z
-    if (sectionLength + 1 >= nameLength) {
-        return BAD_VALUE;
-    }
-
-    // Match rest of name against the tag names in that section only
-    uint32_t candidateTag = 0;
-    if (sectionIndex < ANDROID_SECTION_COUNT) {
-        // Match built-in tags (typically android.*)
-        uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
-        tagBegin = camera_metadata_section_bounds[sectionIndex][0];
-        tagEnd = camera_metadata_section_bounds[sectionIndex][1];
-
-        for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
-            const char *tagName = get_camera_metadata_tag_name(candidateTag);
-
-            if (strcmp(nameTagName, tagName) == 0) {
-                ALOGV("%s: Found matched tag '%s' (%d)",
-                      __FUNCTION__, tagName, candidateTag);
-                break;
-            }
-        }
-
-        if (candidateTag == tagEnd) {
-            return NAME_NOT_FOUND;
-        }
-    } else if (vTags != NULL) {
-        // Match vendor tags (typically com.*)
-        const String8 sectionName(section);
-        const String8 tagName(nameTagName);
-
-        status_t res = OK;
-        if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
-            return NAME_NOT_FOUND;
-        }
-    }
-
-    *tag = candidateTag;
-    return OK;
-}
-
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
deleted file mode 100644
index 16fb85c..0000000
--- a/camera/common/1.0/default/CameraModule.cpp
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * Copyright (C) 2016 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 "CamComm1.0-CamModule"
-#define ATRACE_TAG ATRACE_TAG_CAMERA
-//#define LOG_NDEBUG 0
-
-#include <utils/Trace.h>
-
-#include "CameraModule.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-void CameraModule::deriveCameraCharacteristicsKeys(
-        uint32_t deviceVersion, CameraMetadata &chars) {
-    ATRACE_CALL();
-
-    Vector<int32_t> derivedCharKeys;
-    Vector<int32_t> derivedRequestKeys;
-    Vector<int32_t> derivedResultKeys;
-    // Keys added in HAL3.3
-    if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) {
-        Vector<uint8_t> controlModes;
-        uint8_t data = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
-        chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/1);
-        data = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE;
-        chars.update(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &data, /*count*/1);
-        controlModes.push(ANDROID_CONTROL_MODE_AUTO);
-        camera_metadata_entry entry = chars.find(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
-        if (entry.count > 1 || entry.data.u8[0] != ANDROID_CONTROL_SCENE_MODE_DISABLED) {
-            controlModes.push(ANDROID_CONTROL_MODE_USE_SCENE_MODE);
-        }
-
-        // Only advertise CONTROL_OFF mode if 3A manual controls are supported.
-        bool isManualAeSupported = false;
-        bool isManualAfSupported = false;
-        bool isManualAwbSupported = false;
-        entry = chars.find(ANDROID_CONTROL_AE_AVAILABLE_MODES);
-        if (entry.count > 0) {
-            for (size_t i = 0; i < entry.count; i++) {
-                if (entry.data.u8[i] == ANDROID_CONTROL_AE_MODE_OFF) {
-                    isManualAeSupported = true;
-                    break;
-                }
-            }
-        }
-        entry = chars.find(ANDROID_CONTROL_AF_AVAILABLE_MODES);
-        if (entry.count > 0) {
-            for (size_t i = 0; i < entry.count; i++) {
-                if (entry.data.u8[i] == ANDROID_CONTROL_AF_MODE_OFF) {
-                    isManualAfSupported = true;
-                    break;
-                }
-            }
-        }
-        entry = chars.find(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
-        if (entry.count > 0) {
-            for (size_t i = 0; i < entry.count; i++) {
-                if (entry.data.u8[i] == ANDROID_CONTROL_AWB_MODE_OFF) {
-                    isManualAwbSupported = true;
-                    break;
-                }
-            }
-        }
-        if (isManualAeSupported && isManualAfSupported && isManualAwbSupported) {
-            controlModes.push(ANDROID_CONTROL_MODE_OFF);
-        }
-
-        chars.update(ANDROID_CONTROL_AVAILABLE_MODES, controlModes);
-
-        entry = chars.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
-        // HAL3.2 devices passing existing CTS test should all support all LSC modes and LSC map
-        bool lensShadingModeSupported = false;
-        if (entry.count > 0) {
-            for (size_t i = 0; i < entry.count; i++) {
-                if (entry.data.i32[i] == ANDROID_SHADING_MODE) {
-                    lensShadingModeSupported = true;
-                    break;
-                }
-            }
-        }
-        Vector<uint8_t> lscModes;
-        Vector<uint8_t> lscMapModes;
-        lscModes.push(ANDROID_SHADING_MODE_FAST);
-        lscModes.push(ANDROID_SHADING_MODE_HIGH_QUALITY);
-        lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
-        if (lensShadingModeSupported) {
-            lscModes.push(ANDROID_SHADING_MODE_OFF);
-            lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON);
-        }
-        chars.update(ANDROID_SHADING_AVAILABLE_MODES, lscModes);
-        chars.update(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, lscMapModes);
-
-        derivedCharKeys.push(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
-        derivedCharKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE);
-        derivedCharKeys.push(ANDROID_CONTROL_AVAILABLE_MODES);
-        derivedCharKeys.push(ANDROID_SHADING_AVAILABLE_MODES);
-        derivedCharKeys.push(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES);
-
-        // Need update android.control.availableHighSpeedVideoConfigurations since HAL3.3
-        // adds batch size to this array.
-        entry = chars.find(ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);
-        if (entry.count > 0) {
-            Vector<int32_t> highSpeedConfig;
-            for (size_t i = 0; i < entry.count; i += 4) {
-                highSpeedConfig.add(entry.data.i32[i]); // width
-                highSpeedConfig.add(entry.data.i32[i + 1]); // height
-                highSpeedConfig.add(entry.data.i32[i + 2]); // fps_min
-                highSpeedConfig.add(entry.data.i32[i + 3]); // fps_max
-                highSpeedConfig.add(1); // batchSize_max. default to 1 for HAL3.2
-            }
-            chars.update(ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
-                    highSpeedConfig);
-        }
-    }
-
-    // Keys added in HAL3.4
-    if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
-        // Check if HAL supports RAW_OPAQUE output
-        camera_metadata_entry entry = chars.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
-        bool supportRawOpaque = false;
-        bool supportAnyRaw = false;
-        const int STREAM_CONFIGURATION_SIZE = 4;
-        const int STREAM_FORMAT_OFFSET = 0;
-        const int STREAM_WIDTH_OFFSET = 1;
-        const int STREAM_HEIGHT_OFFSET = 2;
-        const int STREAM_IS_INPUT_OFFSET = 3;
-        Vector<int32_t> rawOpaqueSizes;
-
-        for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
-            int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
-            int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
-            int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
-            int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
-            if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
-                    format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
-                supportRawOpaque = true;
-                rawOpaqueSizes.push(width);
-                rawOpaqueSizes.push(height);
-                // 2 bytes per pixel. This rough estimation is only used when
-                // HAL does not fill in the opaque raw size
-                rawOpaqueSizes.push(width * height *2);
-            }
-            if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
-                    (format == HAL_PIXEL_FORMAT_RAW16 ||
-                     format == HAL_PIXEL_FORMAT_RAW10 ||
-                     format == HAL_PIXEL_FORMAT_RAW12 ||
-                     format == HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
-                supportAnyRaw = true;
-            }
-        }
-
-        if (supportRawOpaque) {
-            entry = chars.find(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
-            if (entry.count == 0) {
-                // Fill in estimated value if HAL does not list it
-                chars.update(ANDROID_SENSOR_OPAQUE_RAW_SIZE, rawOpaqueSizes);
-                derivedCharKeys.push(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
-            }
-        }
-
-        // Check if HAL supports any RAW output, if so, fill in postRawSensitivityBoost range
-        if (supportAnyRaw) {
-            int32_t defaultRange[2] = {100, 100};
-            entry = chars.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE);
-            if (entry.count == 0) {
-                // Fill in default value (100, 100)
-                chars.update(
-                        ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
-                        defaultRange, 2);
-                derivedCharKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE);
-                // Actual request/results will be derived by camera device.
-                derivedRequestKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
-                derivedResultKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
-            }
-        }
-    }
-
-    // Add those newly added keys to AVAILABLE_CHARACTERISTICS_KEYS
-    // This has to be done at this end of this function.
-    if (derivedCharKeys.size() > 0) {
-        appendAvailableKeys(
-                chars, ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, derivedCharKeys);
-    }
-    if (derivedRequestKeys.size() > 0) {
-        appendAvailableKeys(
-                chars, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, derivedRequestKeys);
-    }
-    if (derivedResultKeys.size() > 0) {
-        appendAvailableKeys(
-                chars, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, derivedResultKeys);
-    }
-    return;
-}
-
-void CameraModule::appendAvailableKeys(CameraMetadata &chars,
-        int32_t keyTag, const Vector<int32_t>& appendKeys) {
-    camera_metadata_entry entry = chars.find(keyTag);
-    Vector<int32_t> availableKeys;
-    availableKeys.setCapacity(entry.count + appendKeys.size());
-    for (size_t i = 0; i < entry.count; i++) {
-        availableKeys.push(entry.data.i32[i]);
-    }
-    for (size_t i = 0; i < appendKeys.size(); i++) {
-        availableKeys.push(appendKeys[i]);
-    }
-    chars.update(keyTag, availableKeys);
-}
-
-CameraModule::CameraModule(camera_module_t *module) : mNumberOfCameras(0) {
-    if (module == NULL) {
-        ALOGE("%s: camera hardware module must not be null", __FUNCTION__);
-        assert(0);
-    }
-    mModule = module;
-}
-
-CameraModule::~CameraModule()
-{
-    while (mCameraInfoMap.size() > 0) {
-        camera_info cameraInfo = mCameraInfoMap.editValueAt(0);
-        if (cameraInfo.static_camera_characteristics != NULL) {
-            free_camera_metadata(
-                    const_cast<camera_metadata_t*>(cameraInfo.static_camera_characteristics));
-        }
-        mCameraInfoMap.removeItemsAt(0);
-    }
-
-    while (mPhysicalCameraInfoMap.size() > 0) {
-        camera_metadata_t* metadata = mPhysicalCameraInfoMap.editValueAt(0);
-        if (metadata != NULL) {
-            free_camera_metadata(metadata);
-        }
-        mPhysicalCameraInfoMap.removeItemsAt(0);
-    }
-}
-
-int CameraModule::init() {
-    ATRACE_CALL();
-    int res = OK;
-    if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 &&
-            mModule->init != NULL) {
-        ATRACE_BEGIN("camera_module->init");
-        res = mModule->init();
-        ATRACE_END();
-    }
-    mNumberOfCameras = getNumberOfCameras();
-    mCameraInfoMap.setCapacity(mNumberOfCameras);
-    return res;
-}
-
-int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) {
-    ATRACE_CALL();
-    Mutex::Autolock lock(mCameraInfoLock);
-    if (cameraId < 0) {
-        ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
-        return -EINVAL;
-    }
-
-    // Only override static_camera_characteristics for API2 devices
-    int apiVersion = mModule->common.module_api_version;
-    if (apiVersion < CAMERA_MODULE_API_VERSION_2_0) {
-        int ret;
-        ATRACE_BEGIN("camera_module->get_camera_info");
-        ret = mModule->get_camera_info(cameraId, info);
-        // Fill in this so CameraService won't be confused by
-        // possibly 0 device_version
-        info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
-        ATRACE_END();
-        return ret;
-    }
-
-    ssize_t index = mCameraInfoMap.indexOfKey(cameraId);
-    if (index == NAME_NOT_FOUND) {
-        // Get camera info from raw module and cache it
-        camera_info rawInfo, cameraInfo;
-        ATRACE_BEGIN("camera_module->get_camera_info");
-        int ret = mModule->get_camera_info(cameraId, &rawInfo);
-        ATRACE_END();
-        if (ret != 0) {
-            return ret;
-        }
-        int deviceVersion = rawInfo.device_version;
-        if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_0) {
-            // static_camera_characteristics is invalid
-            *info = rawInfo;
-            return ret;
-        }
-        CameraMetadata m;
-        m.append(rawInfo.static_camera_characteristics);
-        deriveCameraCharacteristicsKeys(rawInfo.device_version, m);
-        cameraInfo = rawInfo;
-        cameraInfo.static_camera_characteristics = m.release();
-        index = mCameraInfoMap.add(cameraId, cameraInfo);
-    }
-
-    assert(index != NAME_NOT_FOUND);
-    // return the cached camera info
-    *info = mCameraInfoMap[index];
-    return OK;
-}
-
-int CameraModule::getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t **physicalInfo) {
-    ATRACE_CALL();
-    Mutex::Autolock lock(mCameraInfoLock);
-    if (physicalCameraId < mNumberOfCameras) {
-        ALOGE("%s: Invalid physical camera ID %d", __FUNCTION__, physicalCameraId);
-        return -EINVAL;
-    }
-
-    // Only query physical camera info for 2.5 version for newer
-    int apiVersion = mModule->common.module_api_version;
-    if (apiVersion < CAMERA_MODULE_API_VERSION_2_5) {
-        ALOGE("%s: Module version must be at least 2.5 to handle getPhysicalCameraInfo",
-                __FUNCTION__);
-        return -ENODEV;
-    }
-    if (mModule->get_physical_camera_info == nullptr) {
-        ALOGE("%s: get_physical_camera is NULL for module version 2.5", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    ssize_t index = mPhysicalCameraInfoMap.indexOfKey(physicalCameraId);
-    if (index == NAME_NOT_FOUND) {
-        // Get physical camera characteristics, and cache it
-        camera_metadata_t *info = nullptr;
-        ATRACE_BEGIN("camera_module->get_physical_camera_info");
-        int ret = mModule->get_physical_camera_info(physicalCameraId, &info);
-        ATRACE_END();
-        if (ret != 0) {
-            return ret;
-        }
-
-        // The camera_metadata_t returned by get_physical_camera_info could be using
-        // more memory than necessary due to unused reserved space. Reduce the
-        // size by appending it to a new CameraMetadata object, which internally
-        // calls resizeIfNeeded.
-        CameraMetadata m;
-        m.append(info);
-        camera_metadata_t* derivedMetadata = m.release();
-        index = mPhysicalCameraInfoMap.add(physicalCameraId, derivedMetadata);
-    }
-
-    assert(index != NAME_NOT_FOUND);
-    *physicalInfo = mPhysicalCameraInfoMap[index];
-    return OK;
-}
-
-int CameraModule::getDeviceVersion(int cameraId) {
-    ssize_t index = mDeviceVersionMap.indexOfKey(cameraId);
-    if (index == NAME_NOT_FOUND) {
-        int deviceVersion;
-        if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
-            struct camera_info info;
-            getCameraInfo(cameraId, &info);
-            deviceVersion = info.device_version;
-        } else {
-            deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
-        }
-        index = mDeviceVersionMap.add(cameraId, deviceVersion);
-    }
-    assert(index != NAME_NOT_FOUND);
-    return mDeviceVersionMap[index];
-}
-
-int CameraModule::open(const char* id, struct hw_device_t** device) {
-    int res;
-    ATRACE_BEGIN("camera_module->open");
-    res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
-    ATRACE_END();
-    return res;
-}
-
-bool CameraModule::isOpenLegacyDefined() const {
-    if (getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_3) {
-        return false;
-    }
-    return mModule->open_legacy != NULL;
-}
-
-int CameraModule::openLegacy(
-        const char* id, uint32_t halVersion, struct hw_device_t** device) {
-    int res;
-    ATRACE_BEGIN("camera_module->open_legacy");
-    res = mModule->open_legacy(&mModule->common, id, halVersion, device);
-    ATRACE_END();
-    return res;
-}
-
-int CameraModule::getNumberOfCameras() {
-    int numCameras;
-    ATRACE_BEGIN("camera_module->get_number_of_cameras");
-    numCameras = mModule->get_number_of_cameras();
-    ATRACE_END();
-    return numCameras;
-}
-
-int CameraModule::setCallbacks(const camera_module_callbacks_t *callbacks) {
-    int res = OK;
-    ATRACE_BEGIN("camera_module->set_callbacks");
-    if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
-        res = mModule->set_callbacks(callbacks);
-    }
-    ATRACE_END();
-    return res;
-}
-
-bool CameraModule::isVendorTagDefined() const {
-    return mModule->get_vendor_tag_ops != NULL;
-}
-
-void CameraModule::getVendorTagOps(vendor_tag_ops_t* ops) {
-    if (mModule->get_vendor_tag_ops) {
-        ATRACE_BEGIN("camera_module->get_vendor_tag_ops");
-        mModule->get_vendor_tag_ops(ops);
-        ATRACE_END();
-    }
-}
-
-bool CameraModule::isSetTorchModeSupported() const {
-    if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
-        if (mModule->set_torch_mode == NULL) {
-            ALOGE("%s: Module 2.4 device must support set torch API!",
-                    __FUNCTION__);
-            return false;
-        }
-        return true;
-    }
-    return false;
-}
-
-int CameraModule::setTorchMode(const char* camera_id, bool enable) {
-    int res = INVALID_OPERATION;
-    if (mModule->set_torch_mode != NULL) {
-        ATRACE_BEGIN("camera_module->set_torch_mode");
-        res = mModule->set_torch_mode(camera_id, enable);
-        ATRACE_END();
-    }
-    return res;
-}
-
-int CameraModule::isStreamCombinationSupported(int cameraId, camera_stream_combination_t *streams) {
-    int res = INVALID_OPERATION;
-    if (mModule->is_stream_combination_supported != NULL) {
-        ATRACE_BEGIN("camera_module->is_stream_combination_supported");
-        res = mModule->is_stream_combination_supported(cameraId, streams);
-        ATRACE_END();
-    }
-    return res;
-}
-
-void CameraModule::notifyDeviceStateChange(uint64_t deviceState) {
-   if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_5 &&
-           mModule->notify_device_state_change != NULL) {
-       ATRACE_BEGIN("camera_module->notify_device_state_change");
-       ALOGI("%s: calling notify_device_state_change with state %" PRId64, __FUNCTION__,
-               deviceState);
-       mModule->notify_device_state_change(deviceState);
-       ATRACE_END();
-   }
-}
-
-bool CameraModule::isLogicalMultiCamera(
-        const common::V1_0::helper::CameraMetadata& metadata,
-        std::unordered_set<std::string>* physicalCameraIds) {
-    if (physicalCameraIds == nullptr) {
-        ALOGE("%s: physicalCameraIds must not be null", __FUNCTION__);
-        return false;
-    }
-
-    bool isLogicalMultiCamera = false;
-    camera_metadata_ro_entry_t capabilities =
-            metadata.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
-    for (size_t i = 0; i < capabilities.count; i++) {
-        if (capabilities.data.u8[i] ==
-                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
-            isLogicalMultiCamera = true;
-            break;
-        }
-    }
-
-    if (isLogicalMultiCamera) {
-        camera_metadata_ro_entry_t entry =
-                metadata.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
-        const uint8_t* ids = entry.data.u8;
-        size_t start = 0;
-        for (size_t i = 0; i < entry.count; ++i) {
-            if (ids[i] == '\0') {
-                if (start != i) {
-                    const char* physicalId = reinterpret_cast<const char*>(ids+start);
-                    physicalCameraIds->emplace(physicalId);
-                }
-                start = i + 1;
-            }
-        }
-    }
-    return isLogicalMultiCamera;
-}
-
-status_t CameraModule::filterOpenErrorCode(status_t err) {
-    switch(err) {
-        case NO_ERROR:
-        case -EBUSY:
-        case -EINVAL:
-        case -EUSERS:
-            return err;
-        default:
-            break;
-    }
-    return -ENODEV;
-}
-
-void CameraModule::removeCamera(int cameraId) {
-    // Skip HAL1 devices which isn't cached in mCameraInfoMap and don't advertise
-    // static_camera_characteristics
-    if (getDeviceVersion(cameraId) >= CAMERA_DEVICE_API_VERSION_3_0) {
-        std::unordered_set<std::string> physicalIds;
-        camera_metadata_t *metadata = const_cast<camera_metadata_t*>(
-                mCameraInfoMap.valueFor(cameraId).static_camera_characteristics);
-        common::V1_0::helper::CameraMetadata hidlMetadata(metadata);
-
-        if (isLogicalMultiCamera(hidlMetadata, &physicalIds)) {
-            for (const auto& id : physicalIds) {
-                int idInt = std::stoi(id);
-                if (mPhysicalCameraInfoMap.indexOfKey(idInt) >= 0) {
-                    free_camera_metadata(mPhysicalCameraInfoMap[idInt]);
-                    mPhysicalCameraInfoMap.removeItem(idInt);
-                } else {
-                    ALOGE("%s: Cannot find corresponding static metadata for physical id %s",
-                            __FUNCTION__, id.c_str());
-                }
-            }
-        }
-    }
-
-    mCameraInfoMap.removeItem(cameraId);
-    mDeviceVersionMap.removeItem(cameraId);
-}
-
-uint16_t CameraModule::getModuleApiVersion() const {
-    return mModule->common.module_api_version;
-}
-
-const char* CameraModule::getModuleName() const {
-    return mModule->common.name;
-}
-
-uint16_t CameraModule::getHalApiVersion() const {
-    return mModule->common.hal_api_version;
-}
-
-const char* CameraModule::getModuleAuthor() const {
-    return mModule->common.author;
-}
-
-void* CameraModule::getDso() {
-    return mModule->common.dso;
-}
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/CameraParameters.cpp b/camera/common/1.0/default/CameraParameters.cpp
deleted file mode 100644
index e707b08..0000000
--- a/camera/common/1.0/default/CameraParameters.cpp
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
-**
-** Copyright 2008, 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 "CameraParams"
-#include <log/log.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "CameraParameters.h"
-#include <system/graphics.h>
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-// Parameter keys to communicate between camera application and driver.
-const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
-const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values";
-const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values";
-const char CameraParameters::KEY_PREVIEW_FPS_RANGE[] = "preview-fps-range";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE[] = "preview-fps-range-values";
-const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size";
-const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values";
-const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format";
-const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values";
-const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width";
-const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height";
-const char CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values";
-const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality";
-const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality";
-const char CameraParameters::KEY_ROTATION[] = "rotation";
-const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude";
-const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude";
-const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude";
-const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp";
-const char CameraParameters::KEY_GPS_PROCESSING_METHOD[] = "gps-processing-method";
-const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance";
-const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values";
-const char CameraParameters::KEY_EFFECT[] = "effect";
-const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values";
-const char CameraParameters::KEY_ANTIBANDING[] = "antibanding";
-const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values";
-const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode";
-const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values";
-const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode";
-const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
-const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
-const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
-const char CameraParameters::KEY_MAX_NUM_FOCUS_AREAS[] = "max-num-focus-areas";
-const char CameraParameters::KEY_FOCUS_AREAS[] = "focus-areas";
-const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length";
-const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
-const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
-const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation";
-const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
-const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
-const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
-const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK[] = "auto-exposure-lock";
-const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[] = "auto-exposure-lock-supported";
-const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK[] = "auto-whitebalance-lock";
-const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[] = "auto-whitebalance-lock-supported";
-const char CameraParameters::KEY_MAX_NUM_METERING_AREAS[] = "max-num-metering-areas";
-const char CameraParameters::KEY_METERING_AREAS[] = "metering-areas";
-const char CameraParameters::KEY_ZOOM[] = "zoom";
-const char CameraParameters::KEY_MAX_ZOOM[] = "max-zoom";
-const char CameraParameters::KEY_ZOOM_RATIOS[] = "zoom-ratios";
-const char CameraParameters::KEY_ZOOM_SUPPORTED[] = "zoom-supported";
-const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported";
-const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances";
-const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format";
-const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size";
-const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
-const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
-const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
-const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
-const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
-const char CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED[] = "video-snapshot-supported";
-const char CameraParameters::KEY_VIDEO_STABILIZATION[] = "video-stabilization";
-const char CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED[] = "video-stabilization-supported";
-const char CameraParameters::KEY_LIGHTFX[] = "light-fx";
-
-const char CameraParameters::TRUE[] = "true";
-const char CameraParameters::FALSE[] = "false";
-const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
-
-// Values for white balance settings.
-const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
-const char CameraParameters::WHITE_BALANCE_INCANDESCENT[] = "incandescent";
-const char CameraParameters::WHITE_BALANCE_FLUORESCENT[] = "fluorescent";
-const char CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT[] = "warm-fluorescent";
-const char CameraParameters::WHITE_BALANCE_DAYLIGHT[] = "daylight";
-const char CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT[] = "cloudy-daylight";
-const char CameraParameters::WHITE_BALANCE_TWILIGHT[] = "twilight";
-const char CameraParameters::WHITE_BALANCE_SHADE[] = "shade";
-
-// Values for effect settings.
-const char CameraParameters::EFFECT_NONE[] = "none";
-const char CameraParameters::EFFECT_MONO[] = "mono";
-const char CameraParameters::EFFECT_NEGATIVE[] = "negative";
-const char CameraParameters::EFFECT_SOLARIZE[] = "solarize";
-const char CameraParameters::EFFECT_SEPIA[] = "sepia";
-const char CameraParameters::EFFECT_POSTERIZE[] = "posterize";
-const char CameraParameters::EFFECT_WHITEBOARD[] = "whiteboard";
-const char CameraParameters::EFFECT_BLACKBOARD[] = "blackboard";
-const char CameraParameters::EFFECT_AQUA[] = "aqua";
-
-// Values for antibanding settings.
-const char CameraParameters::ANTIBANDING_AUTO[] = "auto";
-const char CameraParameters::ANTIBANDING_50HZ[] = "50hz";
-const char CameraParameters::ANTIBANDING_60HZ[] = "60hz";
-const char CameraParameters::ANTIBANDING_OFF[] = "off";
-
-// Values for flash mode settings.
-const char CameraParameters::FLASH_MODE_OFF[] = "off";
-const char CameraParameters::FLASH_MODE_AUTO[] = "auto";
-const char CameraParameters::FLASH_MODE_ON[] = "on";
-const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye";
-const char CameraParameters::FLASH_MODE_TORCH[] = "torch";
-
-// Values for scene mode settings.
-const char CameraParameters::SCENE_MODE_AUTO[] = "auto";
-const char CameraParameters::SCENE_MODE_ACTION[] = "action";
-const char CameraParameters::SCENE_MODE_PORTRAIT[] = "portrait";
-const char CameraParameters::SCENE_MODE_LANDSCAPE[] = "landscape";
-const char CameraParameters::SCENE_MODE_NIGHT[] = "night";
-const char CameraParameters::SCENE_MODE_NIGHT_PORTRAIT[] = "night-portrait";
-const char CameraParameters::SCENE_MODE_THEATRE[] = "theatre";
-const char CameraParameters::SCENE_MODE_BEACH[] = "beach";
-const char CameraParameters::SCENE_MODE_SNOW[] = "snow";
-const char CameraParameters::SCENE_MODE_SUNSET[] = "sunset";
-const char CameraParameters::SCENE_MODE_STEADYPHOTO[] = "steadyphoto";
-const char CameraParameters::SCENE_MODE_FIREWORKS[] = "fireworks";
-const char CameraParameters::SCENE_MODE_SPORTS[] = "sports";
-const char CameraParameters::SCENE_MODE_PARTY[] = "party";
-const char CameraParameters::SCENE_MODE_CANDLELIGHT[] = "candlelight";
-const char CameraParameters::SCENE_MODE_BARCODE[] = "barcode";
-const char CameraParameters::SCENE_MODE_HDR[] = "hdr";
-
-const char CameraParameters::PIXEL_FORMAT_YUV422SP[] = "yuv422sp";
-const char CameraParameters::PIXEL_FORMAT_YUV420SP[] = "yuv420sp";
-const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv";
-const char CameraParameters::PIXEL_FORMAT_YUV420P[]  = "yuv420p";
-const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
-const char CameraParameters::PIXEL_FORMAT_RGBA8888[] = "rgba8888";
-const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
-const char CameraParameters::PIXEL_FORMAT_BAYER_RGGB[] = "bayer-rggb";
-const char CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE[] = "android-opaque";
-
-// Values for focus mode settings.
-const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
-const char CameraParameters::FOCUS_MODE_INFINITY[] = "infinity";
-const char CameraParameters::FOCUS_MODE_MACRO[] = "macro";
-const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed";
-const char CameraParameters::FOCUS_MODE_EDOF[] = "edof";
-const char CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO[] = "continuous-video";
-const char CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE[] = "continuous-picture";
-
-// Values for light fx settings
-const char CameraParameters::LIGHTFX_LOWLIGHT[] = "low-light";
-const char CameraParameters::LIGHTFX_HDR[] = "high-dynamic-range";
-
-CameraParameters::CameraParameters()
-                : mMap()
-{
-}
-
-CameraParameters::~CameraParameters()
-{
-}
-
-String8 CameraParameters::flatten() const
-{
-    String8 flattened("");
-    size_t size = mMap.size();
-
-    for (size_t i = 0; i < size; i++) {
-        String8 k, v;
-        k = mMap.keyAt(i);
-        v = mMap.valueAt(i);
-
-        flattened += k;
-        flattened += "=";
-        flattened += v;
-        if (i != size-1)
-            flattened += ";";
-    }
-
-    return flattened;
-}
-
-void CameraParameters::unflatten(const String8 &params)
-{
-    const char *a = params.string();
-    const char *b;
-
-    mMap.clear();
-
-    for (;;) {
-        // Find the bounds of the key name.
-        b = strchr(a, '=');
-        if (b == 0)
-            break;
-
-        // Create the key string.
-        String8 k(a, (size_t)(b-a));
-
-        // Find the value.
-        a = b+1;
-        b = strchr(a, ';');
-        if (b == 0) {
-            // If there's no semicolon, this is the last item.
-            String8 v(a);
-            mMap.add(k, v);
-            break;
-        }
-
-        String8 v(a, (size_t)(b-a));
-        mMap.add(k, v);
-        a = b+1;
-    }
-}
-
-
-void CameraParameters::set(const char *key, const char *value)
-{
-    // i think i can do this with strspn()
-    if (strchr(key, '=') || strchr(key, ';')) {
-        // ALOGE("Key \"%s\"contains invalid character (= or ;)", key);
-        return;
-    }
-
-    if (strchr(value, '=') || strchr(value, ';')) {
-        // ALOGE("Value \"%s\"contains invalid character (= or ;)", value);
-        return;
-    }
-
-    mMap.replaceValueFor(String8(key), String8(value));
-}
-
-void CameraParameters::set(const char *key, int value)
-{
-    char str[16];
-    sprintf(str, "%d", value);
-    set(key, str);
-}
-
-void CameraParameters::setFloat(const char *key, float value)
-{
-    char str[16];  // 14 should be enough. We overestimate to be safe.
-    snprintf(str, sizeof(str), "%g", value);
-    set(key, str);
-}
-
-const char *CameraParameters::get(const char *key) const
-{
-    String8 v = mMap.valueFor(String8(key));
-    if (v.length() == 0)
-        return 0;
-    return v.string();
-}
-
-int CameraParameters::getInt(const char *key) const
-{
-    const char *v = get(key);
-    if (v == 0)
-        return -1;
-    return strtol(v, 0, 0);
-}
-
-float CameraParameters::getFloat(const char *key) const
-{
-    const char *v = get(key);
-    if (v == 0) return -1;
-    return strtof(v, 0);
-}
-
-void CameraParameters::remove(const char *key)
-{
-    mMap.removeItem(String8(key));
-}
-
-// Parse string like "640x480" or "10000,20000"
-static int parse_pair(const char *str, int *first, int *second, char delim,
-                      char **endptr = NULL)
-{
-    // Find the first integer.
-    char *end;
-    int w = (int)strtol(str, &end, 10);
-    // If a delimeter does not immediately follow, give up.
-    if (*end != delim) {
-        ALOGE("Cannot find delimeter (%c) in str=%s", delim, str);
-        return -1;
-    }
-
-    // Find the second integer, immediately after the delimeter.
-    int h = (int)strtol(end+1, &end, 10);
-
-    *first = w;
-    *second = h;
-
-    if (endptr) {
-        *endptr = end;
-    }
-
-    return 0;
-}
-
-static void parseSizesList(const char *sizesStr, Vector<Size> &sizes)
-{
-    if (sizesStr == 0) {
-        return;
-    }
-
-    char *sizeStartPtr = (char *)sizesStr;
-
-    while (true) {
-        int width, height;
-        int success = parse_pair(sizeStartPtr, &width, &height, 'x',
-                                 &sizeStartPtr);
-        if (success == -1 || (*sizeStartPtr != ',' && *sizeStartPtr != '\0')) {
-            ALOGE("Picture sizes string \"%s\" contains invalid character.", sizesStr);
-            return;
-        }
-        sizes.push(Size(width, height));
-
-        if (*sizeStartPtr == '\0') {
-            return;
-        }
-        sizeStartPtr++;
-    }
-}
-
-void CameraParameters::setPreviewSize(int width, int height)
-{
-    char str[32];
-    sprintf(str, "%dx%d", width, height);
-    set(KEY_PREVIEW_SIZE, str);
-}
-
-void CameraParameters::getPreviewSize(int *width, int *height) const
-{
-    *width = *height = -1;
-    // Get the current string, if it doesn't exist, leave the -1x-1
-    const char *p = get(KEY_PREVIEW_SIZE);
-    if (p == 0)  return;
-    parse_pair(p, width, height, 'x');
-}
-
-void CameraParameters::getPreferredPreviewSizeForVideo(int *width, int *height) const
-{
-    *width = *height = -1;
-    const char *p = get(KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO);
-    if (p == 0)  return;
-    parse_pair(p, width, height, 'x');
-}
-
-void CameraParameters::getSupportedPreviewSizes(Vector<Size> &sizes) const
-{
-    const char *previewSizesStr = get(KEY_SUPPORTED_PREVIEW_SIZES);
-    parseSizesList(previewSizesStr, sizes);
-}
-
-void CameraParameters::setVideoSize(int width, int height)
-{
-    char str[32];
-    sprintf(str, "%dx%d", width, height);
-    set(KEY_VIDEO_SIZE, str);
-}
-
-void CameraParameters::getVideoSize(int *width, int *height) const
-{
-    *width = *height = -1;
-    const char *p = get(KEY_VIDEO_SIZE);
-    if (p == 0) return;
-    parse_pair(p, width, height, 'x');
-}
-
-void CameraParameters::getSupportedVideoSizes(Vector<Size> &sizes) const
-{
-    const char *videoSizesStr = get(KEY_SUPPORTED_VIDEO_SIZES);
-    parseSizesList(videoSizesStr, sizes);
-}
-
-void CameraParameters::setPreviewFrameRate(int fps)
-{
-    set(KEY_PREVIEW_FRAME_RATE, fps);
-}
-
-int CameraParameters::getPreviewFrameRate() const
-{
-    return getInt(KEY_PREVIEW_FRAME_RATE);
-}
-
-void CameraParameters::getPreviewFpsRange(int *min_fps, int *max_fps) const
-{
-    *min_fps = *max_fps = -1;
-    const char *p = get(KEY_PREVIEW_FPS_RANGE);
-    if (p == 0) return;
-    parse_pair(p, min_fps, max_fps, ',');
-}
-
-void CameraParameters::setPreviewFormat(const char *format)
-{
-    set(KEY_PREVIEW_FORMAT, format);
-}
-
-const char *CameraParameters::getPreviewFormat() const
-{
-    return get(KEY_PREVIEW_FORMAT);
-}
-
-void CameraParameters::setPictureSize(int width, int height)
-{
-    char str[32];
-    sprintf(str, "%dx%d", width, height);
-    set(KEY_PICTURE_SIZE, str);
-}
-
-void CameraParameters::getPictureSize(int *width, int *height) const
-{
-    *width = *height = -1;
-    // Get the current string, if it doesn't exist, leave the -1x-1
-    const char *p = get(KEY_PICTURE_SIZE);
-    if (p == 0) return;
-    parse_pair(p, width, height, 'x');
-}
-
-void CameraParameters::getSupportedPictureSizes(Vector<Size> &sizes) const
-{
-    const char *pictureSizesStr = get(KEY_SUPPORTED_PICTURE_SIZES);
-    parseSizesList(pictureSizesStr, sizes);
-}
-
-void CameraParameters::setPictureFormat(const char *format)
-{
-    set(KEY_PICTURE_FORMAT, format);
-}
-
-const char *CameraParameters::getPictureFormat() const
-{
-    return get(KEY_PICTURE_FORMAT);
-}
-
-void CameraParameters::dump() const
-{
-    ALOGD("dump: mMap.size = %zu", mMap.size());
-    for (size_t i = 0; i < mMap.size(); i++) {
-        String8 k, v;
-        k = mMap.keyAt(i);
-        v = mMap.valueAt(i);
-        ALOGD("%s: %s\n", k.string(), v.string());
-    }
-}
-
-status_t CameraParameters::dump(int fd, const Vector<String16>& /*args*/) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %zu\n", mMap.size());
-    result.append(buffer);
-    for (size_t i = 0; i < mMap.size(); i++) {
-        String8 k, v;
-        k = mMap.keyAt(i);
-        v = mMap.valueAt(i);
-        snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
-        result.append(buffer);
-    }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-void CameraParameters::getSupportedPreviewFormats(Vector<int>& formats) const {
-    const char* supportedPreviewFormats =
-          get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
-
-    if (supportedPreviewFormats == NULL) {
-        ALOGW("%s: No supported preview formats.", __FUNCTION__);
-        return;
-    }
-
-    String8 fmtStr(supportedPreviewFormats);
-    char* prevFmts = fmtStr.lockBuffer(fmtStr.size());
-
-    char* savePtr;
-    char* fmt = strtok_r(prevFmts, ",", &savePtr);
-    while (fmt) {
-        int actual = previewFormatToEnum(fmt);
-        if (actual != -1) {
-            formats.add(actual);
-        }
-        fmt = strtok_r(NULL, ",", &savePtr);
-    }
-    fmtStr.unlockBuffer(fmtStr.size());
-}
-
-
-int CameraParameters::previewFormatToEnum(const char* format) {
-    return
-        !format ?
-            HAL_PIXEL_FORMAT_YCrCb_420_SP :
-        !strcmp(format, PIXEL_FORMAT_YUV422SP) ?
-            HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
-        !strcmp(format, PIXEL_FORMAT_YUV420SP) ?
-            HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
-        !strcmp(format, PIXEL_FORMAT_YUV422I) ?
-            HAL_PIXEL_FORMAT_YCbCr_422_I :  // YUY2
-        !strcmp(format, PIXEL_FORMAT_YUV420P) ?
-            HAL_PIXEL_FORMAT_YV12 :         // YV12
-        !strcmp(format, PIXEL_FORMAT_RGB565) ?
-            HAL_PIXEL_FORMAT_RGB_565 :      // RGB565
-        !strcmp(format, PIXEL_FORMAT_RGBA8888) ?
-            HAL_PIXEL_FORMAT_RGBA_8888 :    // RGB8888
-        !strcmp(format, PIXEL_FORMAT_BAYER_RGGB) ?
-            HAL_PIXEL_FORMAT_RAW16 :   // Raw sensor data
-        -1;
-}
-
-bool CameraParameters::isEmpty() const {
-    return mMap.isEmpty();
-}
-
-};
-};
-};
-};
-};
-}; // namespace android
diff --git a/camera/common/1.0/default/Exif.cpp b/camera/common/1.0/default/Exif.cpp
deleted file mode 100644
index 413b6bb..0000000
--- a/camera/common/1.0/default/Exif.cpp
+++ /dev/null
@@ -1,1115 +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.
- */
-
-#define LOG_TAG "CamComm1.0-Exif"
-#define ATRACE_TAG ATRACE_TAG_CAMERA
-//#define LOG_NDEBUG 0
-
-#include <android/log.h>
-
-#include <inttypes.h>
-#include <math.h>
-#include <stdint.h>
-#include <string>
-#include <vector>
-
-#include "Exif.h"
-
-extern "C" {
-#include <libexif/exif-data.h>
-}
-
-namespace std {
-
-template <>
-struct default_delete<ExifEntry> {
-    inline void operator()(ExifEntry* entry) const { exif_entry_unref(entry); }
-};
-
-}  // namespace std
-
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-
-class ExifUtilsImpl : public ExifUtils {
-  public:
-    ExifUtilsImpl();
-
-    virtual ~ExifUtilsImpl();
-
-    // Initialize() can be called multiple times. The setting of Exif tags will be
-    // cleared.
-    virtual bool initialize();
-
-    // set all known fields from a metadata structure
-    virtual bool setFromMetadata(const CameraMetadata& metadata,
-                                 const size_t imageWidth,
-                                 const size_t imageHeight);
-
-    // sets the len aperture.
-    // Returns false if memory allocation fails.
-    virtual bool setAperture(uint32_t numerator, uint32_t denominator);
-
-    // sets the value of brightness.
-    // Returns false if memory allocation fails.
-    virtual bool setBrightness(int32_t numerator, int32_t denominator);
-
-    // sets the color space.
-    // Returns false if memory allocation fails.
-    virtual bool setColorSpace(uint16_t color_space);
-
-    // sets the information to compressed data.
-    // Returns false if memory allocation fails.
-    virtual bool setComponentsConfiguration(const std::string& components_configuration);
-
-    // sets the compression scheme used for the image data.
-    // Returns false if memory allocation fails.
-    virtual bool setCompression(uint16_t compression);
-
-    // sets image contrast.
-    // Returns false if memory allocation fails.
-    virtual bool setContrast(uint16_t contrast);
-
-    // sets the date and time of image last modified. It takes local time. The
-    // name of the tag is DateTime in IFD0.
-    // Returns false if memory allocation fails.
-    virtual bool setDateTime(const struct tm& t);
-
-    // sets the image description.
-    // Returns false if memory allocation fails.
-    virtual bool setDescription(const std::string& description);
-
-    // sets the digital zoom ratio. If the numerator is 0, it means digital zoom
-    // was not used.
-    // Returns false if memory allocation fails.
-    virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator);
-
-    // sets the exposure bias.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureBias(int32_t numerator, int32_t denominator);
-
-    // sets the exposure mode set when the image was shot.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureMode(uint16_t exposure_mode);
-
-    // sets the program used by the camera to set exposure when the picture is
-    // taken.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureProgram(uint16_t exposure_program);
-
-    // sets the exposure time, given in seconds.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureTime(uint32_t numerator, uint32_t denominator);
-
-    // sets the status of flash.
-    // Returns false if memory allocation fails.
-    virtual bool setFlash(uint16_t flash);
-
-    // sets the F number.
-    // Returns false if memory allocation fails.
-    virtual bool setFNumber(uint32_t numerator, uint32_t denominator);
-
-    // sets the focal length of lens used to take the image in millimeters.
-    // Returns false if memory allocation fails.
-    virtual bool setFocalLength(uint32_t numerator, uint32_t denominator);
-
-    // sets the degree of overall image gain adjustment.
-    // Returns false if memory allocation fails.
-    virtual bool setGainControl(uint16_t gain_control);
-
-    // sets the altitude in meters.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsAltitude(double altitude);
-
-    // sets the latitude with degrees minutes seconds format.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsLatitude(double latitude);
-
-    // sets the longitude with degrees minutes seconds format.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsLongitude(double longitude);
-
-    // sets GPS processing method.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsProcessingMethod(const std::string& method);
-
-    // sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsTimestamp(const struct tm& t);
-
-    // sets the length (number of rows) of main image.
-    // Returns false if memory allocation fails.
-    virtual bool setImageHeight(uint32_t length);
-
-    // sets the width (number of columes) of main image.
-    // Returns false if memory allocation fails.
-    virtual bool setImageWidth(uint32_t width);
-
-    // sets the ISO speed.
-    // Returns false if memory allocation fails.
-    virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
-
-    // sets the kind of light source.
-    // Returns false if memory allocation fails.
-    virtual bool setLightSource(uint16_t light_source);
-
-    // sets the smallest F number of the lens.
-    // Returns false if memory allocation fails.
-    virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator);
-
-    // sets the metering mode.
-    // Returns false if memory allocation fails.
-    virtual bool setMeteringMode(uint16_t metering_mode);
-
-    // sets image orientation.
-    // Returns false if memory allocation fails.
-    virtual bool setOrientation(uint16_t orientation);
-
-    // sets the unit for measuring XResolution and YResolution.
-    // Returns false if memory allocation fails.
-    virtual bool setResolutionUnit(uint16_t resolution_unit);
-
-    // sets image saturation.
-    // Returns false if memory allocation fails.
-    virtual bool setSaturation(uint16_t saturation);
-
-    // sets the type of scene that was shot.
-    // Returns false if memory allocation fails.
-    virtual bool setSceneCaptureType(uint16_t type);
-
-    // sets image sharpness.
-    // Returns false if memory allocation fails.
-    virtual bool setSharpness(uint16_t sharpness);
-
-    // sets the shutter speed.
-    // Returns false if memory allocation fails.
-    virtual bool setShutterSpeed(int32_t numerator, int32_t denominator);
-
-    // sets the distance to the subject, given in meters.
-    // Returns false if memory allocation fails.
-    virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator);
-
-    // sets the fractions of seconds for the <DateTime> tag.
-    // Returns false if memory allocation fails.
-    virtual bool setSubsecTime(const std::string& subsec_time);
-
-    // sets the white balance mode set when the image was shot.
-    // Returns false if memory allocation fails.
-    virtual bool setWhiteBalance(uint16_t white_balance);
-
-    // sets the number of pixels per resolution unit in the image width.
-    // Returns false if memory allocation fails.
-    virtual bool setXResolution(uint32_t numerator, uint32_t denominator);
-
-    // sets the position of chrominance components in relation to the luminance
-    // component.
-    // Returns false if memory allocation fails.
-    virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning);
-
-    // sets the number of pixels per resolution unit in the image length.
-    // Returns false if memory allocation fails.
-    virtual bool setYResolution(uint32_t numerator, uint32_t denominator);
-
-    // sets the manufacturer of camera.
-    // Returns false if memory allocation fails.
-    virtual bool setMake(const std::string& make);
-
-    // sets the model number of camera.
-    // Returns false if memory allocation fails.
-    virtual bool setModel(const std::string& model);
-
-    // Generates APP1 segment.
-    // Returns false if generating APP1 segment fails.
-    virtual bool generateApp1(const void* thumbnail_buffer, uint32_t size);
-
-    // Gets buffer of APP1 segment. This method must be called only after calling
-    // GenerateAPP1().
-    virtual const uint8_t* getApp1Buffer();
-
-    // Gets length of APP1 segment. This method must be called only after calling
-    // GenerateAPP1().
-    virtual unsigned int getApp1Length();
-
-  protected:
-    // sets the version of this standard supported.
-    // Returns false if memory allocation fails.
-    virtual bool setExifVersion(const std::string& exif_version);
-
-
-    // Resets the pointers and memories.
-    virtual void reset();
-
-    // Adds a variable length tag to |exif_data_|. It will remove the original one
-    // if the tag exists.
-    // Returns the entry of the tag. The reference count of returned ExifEntry is
-    // two.
-    virtual std::unique_ptr<ExifEntry> addVariableLengthEntry(ExifIfd ifd,
-                                                              ExifTag tag,
-                                                              ExifFormat format,
-                                                              uint64_t components,
-                                                              unsigned int size);
-
-    // Adds a entry of |tag| in |exif_data_|. It won't remove the original one if
-    // the tag exists.
-    // Returns the entry of the tag. It adds one reference count to returned
-    // ExifEntry.
-    virtual std::unique_ptr<ExifEntry> addEntry(ExifIfd ifd, ExifTag tag);
-
-    // Helpe functions to add exif data with different types.
-    virtual bool setShort(ExifIfd ifd,
-                          ExifTag tag,
-                          uint16_t value,
-                          const std::string& msg);
-
-    virtual bool setLong(ExifIfd ifd,
-                         ExifTag tag,
-                         uint32_t value,
-                         const std::string& msg);
-
-    virtual bool setRational(ExifIfd ifd,
-                             ExifTag tag,
-                             uint32_t numerator,
-                             uint32_t denominator,
-                             const std::string& msg);
-
-    virtual bool setSRational(ExifIfd ifd,
-                              ExifTag tag,
-                              int32_t numerator,
-                              int32_t denominator,
-                              const std::string& msg);
-
-    virtual bool setString(ExifIfd ifd,
-                           ExifTag tag,
-                           ExifFormat format,
-                           const std::string& buffer,
-                           const std::string& msg);
-
-    // Destroys the buffer of APP1 segment if exists.
-    virtual void destroyApp1();
-
-    // The Exif data (APP1). Owned by this class.
-    ExifData* exif_data_;
-    // The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but
-    // owned by this class.
-    uint8_t* app1_buffer_;
-    // The length of |app1_buffer_|.
-    unsigned int app1_length_;
-
-};
-
-#define SET_SHORT(ifd, tag, value)                      \
-    do {                                                \
-        if (setShort(ifd, tag, value, #tag) == false)   \
-            return false;                               \
-    } while (0);
-
-#define SET_LONG(ifd, tag, value)                       \
-    do {                                                \
-        if (setLong(ifd, tag, value, #tag) == false)    \
-            return false;                               \
-    } while (0);
-
-#define SET_RATIONAL(ifd, tag, numerator, denominator)                      \
-    do {                                                                    \
-        if (setRational(ifd, tag, numerator, denominator, #tag) == false)   \
-            return false;                                                   \
-    } while (0);
-
-#define SET_SRATIONAL(ifd, tag, numerator, denominator)                       \
-    do {                                                                      \
-        if (setSRational(ifd, tag, numerator, denominator, #tag) == false)    \
-            return false;                                                     \
-    } while (0);
-
-#define SET_STRING(ifd, tag, format, buffer)                                  \
-    do {                                                                      \
-        if (setString(ifd, tag, format, buffer, #tag) == false)               \
-            return false;                                                     \
-    } while (0);
-
-// This comes from the Exif Version 2.2 standard table 6.
-const char gExifAsciiPrefix[] = {0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0};
-
-static void setLatitudeOrLongitudeData(unsigned char* data, double num) {
-    // Take the integer part of |num|.
-    ExifLong degrees = static_cast<ExifLong>(num);
-    ExifLong minutes = static_cast<ExifLong>(60 * (num - degrees));
-    ExifLong microseconds =
-            static_cast<ExifLong>(3600000000u * (num - degrees - minutes / 60.0));
-    exif_set_rational(data, EXIF_BYTE_ORDER_INTEL, {degrees, 1});
-    exif_set_rational(data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
-                                        {minutes, 1});
-    exif_set_rational(data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
-                                        {microseconds, 1000000});
-}
-
-ExifUtils *ExifUtils::create() {
-    return new ExifUtilsImpl();
-}
-
-ExifUtils::~ExifUtils() {
-}
-
-ExifUtilsImpl::ExifUtilsImpl()
-        : exif_data_(nullptr), app1_buffer_(nullptr), app1_length_(0) {}
-
-ExifUtilsImpl::~ExifUtilsImpl() {
-    reset();
-}
-
-
-bool ExifUtilsImpl::initialize() {
-    reset();
-    exif_data_ = exif_data_new();
-    if (exif_data_ == nullptr) {
-        ALOGE("%s: allocate memory for exif_data_ failed", __FUNCTION__);
-        return false;
-    }
-    // set the image options.
-    exif_data_set_option(exif_data_, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
-    exif_data_set_data_type(exif_data_, EXIF_DATA_TYPE_COMPRESSED);
-    exif_data_set_byte_order(exif_data_, EXIF_BYTE_ORDER_INTEL);
-
-    // set exif version to 2.2.
-    if (!setExifVersion("0220")) {
-        return false;
-    }
-
-    return true;
-}
-
-bool ExifUtilsImpl::setAperture(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setBrightness(int32_t numerator, int32_t denominator) {
-    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_BRIGHTNESS_VALUE, numerator,
-                                denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setColorSpace(uint16_t color_space) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE, color_space);
-    return true;
-}
-
-bool ExifUtilsImpl::setComponentsConfiguration(
-        const std::string& components_configuration) {
-    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_COMPONENTS_CONFIGURATION,
-                          EXIF_FORMAT_UNDEFINED, components_configuration);
-    return true;
-}
-
-bool ExifUtilsImpl::setCompression(uint16_t compression) {
-    SET_SHORT(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);
-    return true;
-}
-
-bool ExifUtilsImpl::setContrast(uint16_t contrast) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_CONTRAST, contrast);
-    return true;
-}
-
-bool ExifUtilsImpl::setDateTime(const struct tm& t) {
-    // The length is 20 bytes including NULL for termination in Exif standard.
-    char str[20];
-    int result = snprintf(str, sizeof(str), "%04i:%02i:%02i %02i:%02i:%02i",
-                                                t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour,
-                                                t.tm_min, t.tm_sec);
-    if (result != sizeof(str) - 1) {
-        ALOGW("%s: Input time is invalid", __FUNCTION__);
-        return false;
-    }
-    std::string buffer(str);
-    SET_STRING(EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, buffer);
-    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_FORMAT_ASCII,
-                          buffer);
-    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_FORMAT_ASCII,
-                          buffer);
-    return true;
-}
-
-bool ExifUtilsImpl::setDescription(const std::string& description) {
-    SET_STRING(EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_FORMAT_ASCII,
-                          description);
-    return true;
-}
-
-bool ExifUtilsImpl::setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, numerator,
-                              denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setExposureBias(int32_t numerator, int32_t denominator) {
-    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, numerator,
-                                denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setExposureMode(uint16_t exposure_mode) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposure_mode);
-    return true;
-}
-
-bool ExifUtilsImpl::setExposureProgram(uint16_t exposure_program) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, exposure_program);
-    return true;
-}
-
-bool ExifUtilsImpl::setExposureTime(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setFlash(uint16_t flash) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
-    return true;
-}
-
-bool ExifUtilsImpl::setFNumber(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setFocalLength(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setGainControl(uint16_t gain_control) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_GAIN_CONTROL, gain_control);
-    return true;
-}
-
-bool ExifUtilsImpl::setGpsAltitude(double altitude) {
-    ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF);
-    std::unique_ptr<ExifEntry> refEntry =
-            addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_BYTE, 1, 1);
-    if (!refEntry) {
-        ALOGE("%s: Adding GPSAltitudeRef exif entry failed", __FUNCTION__);
-        return false;
-    }
-    if (altitude >= 0) {
-        *refEntry->data = 0;
-    } else {
-        *refEntry->data = 1;
-        altitude *= -1;
-    }
-
-    ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE);
-    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
-            EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 1, sizeof(ExifRational));
-    if (!entry) {
-        exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
-        ALOGE("%s: Adding GPSAltitude exif entry failed", __FUNCTION__);
-        return false;
-    }
-    exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
-                                        {static_cast<ExifLong>(altitude * 1000), 1000});
-
-    return true;
-}
-
-bool ExifUtilsImpl::setGpsLatitude(double latitude) {
-    const ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF);
-    std::unique_ptr<ExifEntry> refEntry =
-            addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
-    if (!refEntry) {
-        ALOGE("%s: Adding GPSLatitudeRef exif entry failed", __FUNCTION__);
-        return false;
-    }
-    if (latitude >= 0) {
-        memcpy(refEntry->data, "N", sizeof("N"));
-    } else {
-        memcpy(refEntry->data, "S", sizeof("S"));
-        latitude *= -1;
-    }
-
-    const ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE);
-    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
-            EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
-    if (!entry) {
-        exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
-        ALOGE("%s: Adding GPSLatitude exif entry failed", __FUNCTION__);
-        return false;
-    }
-    setLatitudeOrLongitudeData(entry->data, latitude);
-
-    return true;
-}
-
-bool ExifUtilsImpl::setGpsLongitude(double longitude) {
-    ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF);
-    std::unique_ptr<ExifEntry> refEntry =
-            addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
-    if (!refEntry) {
-        ALOGE("%s: Adding GPSLongitudeRef exif entry failed", __FUNCTION__);
-        return false;
-    }
-    if (longitude >= 0) {
-        memcpy(refEntry->data, "E", sizeof("E"));
-    } else {
-        memcpy(refEntry->data, "W", sizeof("W"));
-        longitude *= -1;
-    }
-
-    ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE);
-    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
-            EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
-    if (!entry) {
-        exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
-        ALOGE("%s: Adding GPSLongitude exif entry failed", __FUNCTION__);
-        return false;
-    }
-    setLatitudeOrLongitudeData(entry->data, longitude);
-
-    return true;
-}
-
-bool ExifUtilsImpl::setGpsProcessingMethod(const std::string& method) {
-    std::string buffer =
-            std::string(gExifAsciiPrefix, sizeof(gExifAsciiPrefix)) + method;
-    SET_STRING(EXIF_IFD_GPS, static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD),
-                          EXIF_FORMAT_UNDEFINED, buffer);
-    return true;
-}
-
-bool ExifUtilsImpl::setGpsTimestamp(const struct tm& t) {
-    const ExifTag dateTag = static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP);
-    const size_t kGpsDateStampSize = 11;
-    std::unique_ptr<ExifEntry> entry =
-            addVariableLengthEntry(EXIF_IFD_GPS, dateTag, EXIF_FORMAT_ASCII,
-                                                          kGpsDateStampSize, kGpsDateStampSize);
-    if (!entry) {
-        ALOGE("%s: Adding GPSDateStamp exif entry failed", __FUNCTION__);
-        return false;
-    }
-    int result =
-            snprintf(reinterpret_cast<char*>(entry->data), kGpsDateStampSize,
-                              "%04i:%02i:%02i", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
-    if (result != kGpsDateStampSize - 1) {
-        ALOGW("%s: Input time is invalid", __FUNCTION__);
-        return false;
-    }
-
-    const ExifTag timeTag = static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP);
-    entry = addVariableLengthEntry(EXIF_IFD_GPS, timeTag, EXIF_FORMAT_RATIONAL, 3,
-                                                                  3 * sizeof(ExifRational));
-    if (!entry) {
-        ALOGE("%s: Adding GPSTimeStamp exif entry failed", __FUNCTION__);
-        return false;
-    }
-    exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
-                                        {static_cast<ExifLong>(t.tm_hour), 1});
-    exif_set_rational(entry->data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
-                                        {static_cast<ExifLong>(t.tm_min), 1});
-    exif_set_rational(entry->data + 2 * sizeof(ExifRational),
-                                        EXIF_BYTE_ORDER_INTEL,
-                                        {static_cast<ExifLong>(t.tm_sec), 1});
-
-    return true;
-}
-
-bool ExifUtilsImpl::setImageHeight(uint32_t length) {
-    SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length);
-    SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION, length);
-    return true;
-}
-
-bool ExifUtilsImpl::setImageWidth(uint32_t width) {
-    SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width);
-    SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION, width);
-    return true;
-}
-
-bool ExifUtilsImpl::setIsoSpeedRating(uint16_t iso_speed_ratings) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, iso_speed_ratings);
-    return true;
-}
-
-bool ExifUtilsImpl::setLightSource(uint16_t light_source) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_LIGHT_SOURCE, light_source);
-    return true;
-}
-
-bool ExifUtilsImpl::setMaxAperture(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE, numerator,
-                              denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setMeteringMode(uint16_t metering_mode) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_METERING_MODE, metering_mode);
-    return true;
-}
-
-bool ExifUtilsImpl::setOrientation(uint16_t orientation) {
-    /*
-     * Orientation value:
-     *  1      2      3      4      5          6          7          8
-     *
-     *  888888 888888     88 88     8888888888 88                 88 8888888888
-     *  88         88     88 88     88  88     88  88         88  88     88  88
-     *  8888     8888   8888 8888   88         8888888888 8888888888         88
-     *  88         88     88 88
-     *  88         88 888888 888888
-     */
-    int value = 1;
-    switch (orientation) {
-        case 90:
-            value = 6;
-            break;
-        case 180:
-            value = 3;
-            break;
-        case 270:
-            value = 8;
-            break;
-        default:
-            break;
-    }
-    SET_SHORT(EXIF_IFD_0, EXIF_TAG_ORIENTATION, value);
-    return true;
-}
-
-bool ExifUtilsImpl::setResolutionUnit(uint16_t resolution_unit) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_RESOLUTION_UNIT, resolution_unit);
-    return true;
-}
-
-bool ExifUtilsImpl::setSaturation(uint16_t saturation) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SATURATION, saturation);
-    return true;
-}
-
-bool ExifUtilsImpl::setSceneCaptureType(uint16_t type) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, type);
-    return true;
-}
-
-bool ExifUtilsImpl::setSharpness(uint16_t sharpness) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SHARPNESS, sharpness);
-    return true;
-}
-
-bool ExifUtilsImpl::setShutterSpeed(int32_t numerator, int32_t denominator) {
-    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, numerator,
-                                denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setSubjectDistance(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator,
-                              denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setSubsecTime(const std::string& subsec_time) {
-    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME, EXIF_FORMAT_ASCII,
-                          subsec_time);
-    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_ORIGINAL, EXIF_FORMAT_ASCII,
-                          subsec_time);
-    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_DIGITIZED, EXIF_FORMAT_ASCII,
-                          subsec_time);
-    return true;
-}
-
-bool ExifUtilsImpl::setWhiteBalance(uint16_t white_balance) {
-    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, white_balance);
-    return true;
-}
-
-bool ExifUtilsImpl::setXResolution(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_X_RESOLUTION, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::setYCbCrPositioning(uint16_t ycbcr_positioning) {
-    SET_SHORT(EXIF_IFD_0, EXIF_TAG_YCBCR_POSITIONING, ycbcr_positioning);
-    return true;
-}
-
-bool ExifUtilsImpl::setYResolution(uint32_t numerator, uint32_t denominator) {
-    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_Y_RESOLUTION, numerator, denominator);
-    return true;
-}
-
-bool ExifUtilsImpl::generateApp1(const void* thumbnail_buffer, uint32_t size) {
-    destroyApp1();
-    exif_data_->data = const_cast<uint8_t*>(static_cast<const uint8_t*>(thumbnail_buffer));
-    exif_data_->size = size;
-    // Save the result into |app1_buffer_|.
-    exif_data_save_data(exif_data_, &app1_buffer_, &app1_length_);
-    if (!app1_length_) {
-        ALOGE("%s: Allocate memory for app1_buffer_ failed", __FUNCTION__);
-        return false;
-    }
-    /*
-     * The JPEG segment size is 16 bits in spec. The size of APP1 segment should
-     * be smaller than 65533 because there are two bytes for segment size field.
-     */
-    if (app1_length_ > 65533) {
-        destroyApp1();
-        ALOGE("%s: The size of APP1 segment is too large", __FUNCTION__);
-        return false;
-    }
-    return true;
-}
-
-const uint8_t* ExifUtilsImpl::getApp1Buffer() {
-    return app1_buffer_;
-}
-
-unsigned int ExifUtilsImpl::getApp1Length() {
-    return app1_length_;
-}
-
-bool ExifUtilsImpl::setExifVersion(const std::string& exif_version) {
-    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_EXIF_VERSION, EXIF_FORMAT_UNDEFINED, exif_version);
-    return true;
-}
-
-bool ExifUtilsImpl::setMake(const std::string& make) {
-    SET_STRING(EXIF_IFD_0, EXIF_TAG_MAKE, EXIF_FORMAT_ASCII, make);
-    return true;
-}
-
-bool ExifUtilsImpl::setModel(const std::string& model) {
-    SET_STRING(EXIF_IFD_0, EXIF_TAG_MODEL, EXIF_FORMAT_ASCII, model);
-    return true;
-}
-
-void ExifUtilsImpl::reset() {
-    destroyApp1();
-    if (exif_data_) {
-        /*
-         * Since we decided to ignore the original APP1, we are sure that there is
-         * no thumbnail allocated by libexif. |exif_data_->data| is actually
-         * allocated by JpegCompressor. sets |exif_data_->data| to nullptr to
-         * prevent exif_data_unref() destroy it incorrectly.
-         */
-        exif_data_->data = nullptr;
-        exif_data_->size = 0;
-        exif_data_unref(exif_data_);
-        exif_data_ = nullptr;
-    }
-}
-
-std::unique_ptr<ExifEntry> ExifUtilsImpl::addVariableLengthEntry(ExifIfd ifd,
-                                                                 ExifTag tag,
-                                                                 ExifFormat format,
-                                                                 uint64_t components,
-                                                                 unsigned int size) {
-    // Remove old entry if exists.
-    exif_content_remove_entry(exif_data_->ifd[ifd],
-                              exif_content_get_entry(exif_data_->ifd[ifd], tag));
-    ExifMem* mem = exif_mem_new_default();
-    if (!mem) {
-        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
-        return nullptr;
-    }
-    std::unique_ptr<ExifEntry> entry(exif_entry_new_mem(mem));
-    if (!entry) {
-        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
-        exif_mem_unref(mem);
-        return nullptr;
-    }
-    void* tmpBuffer = exif_mem_alloc(mem, size);
-    if (!tmpBuffer) {
-        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
-        exif_mem_unref(mem);
-        return nullptr;
-    }
-
-    entry->data = static_cast<unsigned char*>(tmpBuffer);
-    entry->tag = tag;
-    entry->format = format;
-    entry->components = components;
-    entry->size = size;
-
-    exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
-    exif_mem_unref(mem);
-
-    return entry;
-}
-
-std::unique_ptr<ExifEntry> ExifUtilsImpl::addEntry(ExifIfd ifd, ExifTag tag) {
-    std::unique_ptr<ExifEntry> entry(exif_content_get_entry(exif_data_->ifd[ifd], tag));
-    if (entry) {
-        // exif_content_get_entry() won't ref the entry, so we ref here.
-        exif_entry_ref(entry.get());
-        return entry;
-    }
-    entry.reset(exif_entry_new());
-    if (!entry) {
-        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
-        return nullptr;
-    }
-    entry->tag = tag;
-    exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
-    exif_entry_initialize(entry.get(), tag);
-    return entry;
-}
-
-bool ExifUtilsImpl::setShort(ExifIfd ifd,
-                             ExifTag tag,
-                             uint16_t value,
-                             const std::string& msg) {
-    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
-    if (!entry) {
-        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
-        return false;
-    }
-    exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, value);
-    return true;
-}
-
-bool ExifUtilsImpl::setLong(ExifIfd ifd,
-                            ExifTag tag,
-                            uint32_t value,
-                            const std::string& msg) {
-    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
-    if (!entry) {
-        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
-        return false;
-    }
-    exif_set_long(entry->data, EXIF_BYTE_ORDER_INTEL, value);
-    return true;
-}
-
-bool ExifUtilsImpl::setRational(ExifIfd ifd,
-                                ExifTag tag,
-                                uint32_t numerator,
-                                uint32_t denominator,
-                                const std::string& msg) {
-    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
-    if (!entry) {
-        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
-        return false;
-    }
-    exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
-                                        {numerator, denominator});
-    return true;
-}
-
-bool ExifUtilsImpl::setSRational(ExifIfd ifd,
-                                 ExifTag tag,
-                                 int32_t numerator,
-                                 int32_t denominator,
-                                 const std::string& msg) {
-    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
-    if (!entry) {
-        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
-        return false;
-    }
-    exif_set_srational(entry->data, EXIF_BYTE_ORDER_INTEL,
-                                          {numerator, denominator});
-    return true;
-}
-
-bool ExifUtilsImpl::setString(ExifIfd ifd,
-                              ExifTag tag,
-                              ExifFormat format,
-                              const std::string& buffer,
-                              const std::string& msg) {
-    size_t entry_size = buffer.length();
-    // Since the exif format is undefined, NULL termination is not necessary.
-    if (format == EXIF_FORMAT_ASCII) {
-        entry_size++;
-    }
-    std::unique_ptr<ExifEntry> entry =
-            addVariableLengthEntry(ifd, tag, format, entry_size, entry_size);
-    if (!entry) {
-        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
-        return false;
-    }
-    memcpy(entry->data, buffer.c_str(), entry_size);
-    return true;
-}
-
-void ExifUtilsImpl::destroyApp1() {
-    /*
-     * Since there is no API to access ExifMem in ExifData->priv, we use free
-     * here, which is the default free function in libexif. See
-     * exif_data_save_data() for detail.
-     */
-    free(app1_buffer_);
-    app1_buffer_ = nullptr;
-    app1_length_ = 0;
-}
-
-bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
-                                    const size_t imageWidth,
-                                    const size_t imageHeight) {
-    // How precise the float-to-rational conversion for EXIF tags would be.
-    constexpr int kRationalPrecision = 10000;
-    if (!setImageWidth(imageWidth) ||
-            !setImageHeight(imageHeight)) {
-        ALOGE("%s: setting image resolution failed.", __FUNCTION__);
-        return false;
-    }
-
-    struct timespec tp;
-    struct tm time_info;
-    bool time_available = clock_gettime(CLOCK_REALTIME, &tp) != -1;
-    localtime_r(&tp.tv_sec, &time_info);
-    if (!setDateTime(time_info)) {
-        ALOGE("%s: setting data time failed.", __FUNCTION__);
-        return false;
-    }
-
-    float focal_length;
-    camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH);
-    if (entry.count) {
-        focal_length = entry.data.f[0];
-
-        if (!setFocalLength(
-                        static_cast<uint32_t>(focal_length * kRationalPrecision),
-                        kRationalPrecision)) {
-            ALOGE("%s: setting focal length failed.", __FUNCTION__);
-            return false;
-        }
-    } else {
-        ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
-    }
-
-    if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
-        entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
-        if (entry.count < 3) {
-            ALOGE("%s: Gps coordinates in metadata is not complete.", __FUNCTION__);
-            return false;
-        }
-        if (!setGpsLatitude(entry.data.d[0])) {
-            ALOGE("%s: setting gps latitude failed.", __FUNCTION__);
-            return false;
-        }
-        if (!setGpsLongitude(entry.data.d[1])) {
-            ALOGE("%s: setting gps longitude failed.", __FUNCTION__);
-            return false;
-        }
-        if (!setGpsAltitude(entry.data.d[2])) {
-            ALOGE("%s: setting gps altitude failed.", __FUNCTION__);
-            return false;
-        }
-    }
-
-    if (metadata.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
-        entry = metadata.find(ANDROID_JPEG_GPS_PROCESSING_METHOD);
-        std::string method_str(reinterpret_cast<const char*>(entry.data.u8));
-        if (!setGpsProcessingMethod(method_str)) {
-            ALOGE("%s: setting gps processing method failed.", __FUNCTION__);
-            return false;
-        }
-    }
-
-    if (time_available && metadata.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
-        entry = metadata.find(ANDROID_JPEG_GPS_TIMESTAMP);
-        time_t timestamp = static_cast<time_t>(entry.data.i64[0]);
-        if (gmtime_r(&timestamp, &time_info)) {
-            if (!setGpsTimestamp(time_info)) {
-                ALOGE("%s: setting gps timestamp failed.", __FUNCTION__);
-                return false;
-            }
-        } else {
-            ALOGE("%s: Time tranformation failed.", __FUNCTION__);
-            return false;
-        }
-    }
-
-    if (metadata.exists(ANDROID_JPEG_ORIENTATION)) {
-        entry = metadata.find(ANDROID_JPEG_ORIENTATION);
-        if (!setOrientation(entry.data.i32[0])) {
-            ALOGE("%s: setting orientation failed.", __FUNCTION__);
-            return false;
-        }
-    }
-
-    if (metadata.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
-        entry = metadata.find(ANDROID_SENSOR_EXPOSURE_TIME);
-        // int64_t of nanoseconds
-        if (!setExposureTime(entry.data.i64[0],1000000000u)) {
-            ALOGE("%s: setting exposure time failed.", __FUNCTION__);
-            return false;
-        }
-    }
-
-    if (metadata.exists(ANDROID_LENS_APERTURE)) {
-        const int kAperturePrecision = 10000;
-        entry = metadata.find(ANDROID_LENS_APERTURE);
-        if (!setFNumber(entry.data.f[0] * kAperturePrecision,
-                                                      kAperturePrecision)) {
-            ALOGE("%s: setting F number failed.", __FUNCTION__);
-            return false;
-        }
-    }
-
-    if (metadata.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
-        entry = metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
-        if (entry.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_FALSE) {
-            const uint32_t kNoFlashFunction = 0x20;
-            if (!setFlash(kNoFlashFunction)) {
-                ALOGE("%s: setting flash failed.", __FUNCTION__);
-                return false;
-            }
-        } else {
-            ALOGE("%s: Unsupported flash info: %d",__FUNCTION__, entry.data.u8[0]);
-            return false;
-        }
-    }
-
-    if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
-        entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
-        if (entry.data.u8[0] == ANDROID_CONTROL_AWB_MODE_AUTO) {
-            const uint16_t kAutoWhiteBalance = 0;
-            if (!setWhiteBalance(kAutoWhiteBalance)) {
-                ALOGE("%s: setting white balance failed.", __FUNCTION__);
-                return false;
-            }
-        } else {
-            ALOGE("%s: Unsupported awb mode: %d", __FUNCTION__, entry.data.u8[0]);
-            return false;
-        }
-    }
-
-    if (time_available) {
-        char str[4];
-        if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {
-            ALOGE("%s: Subsec is invalid: %ld", __FUNCTION__, tp.tv_nsec);
-            return false;
-        }
-        if (!setSubsecTime(std::string(str))) {
-            ALOGE("%s: setting subsec time failed.", __FUNCTION__);
-            return false;
-        }
-    }
-
-    return true;
-}
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
deleted file mode 100644
index d2fdf02..0000000
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Copyright (C) 2017 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 "HandleImporter"
-#include "HandleImporter.h"
-
-#include <gralloctypes/Gralloc4.h>
-#include "aidl/android/hardware/graphics/common/Smpte2086.h"
-#include <log/log.h>
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-using aidl::android::hardware::graphics::common::PlaneLayout;
-using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
-using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
-using aidl::android::hardware::graphics::common::Smpte2086;
-using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
-using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
-using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
-using MapperErrorV4 = android::hardware::graphics::mapper::V4_0::Error;
-using IMapperV3 = android::hardware::graphics::mapper::V3_0::IMapper;
-using IMapperV4 = android::hardware::graphics::mapper::V4_0::IMapper;
-
-HandleImporter::HandleImporter() : mInitialized(false) {}
-
-void HandleImporter::initializeLocked() {
-    if (mInitialized) {
-        return;
-    }
-
-    mMapperV4 = IMapperV4::getService();
-    if (mMapperV4 != nullptr) {
-        mInitialized = true;
-        return;
-    }
-
-    mMapperV3 = IMapperV3::getService();
-    if (mMapperV3 != nullptr) {
-        mInitialized = true;
-        return;
-    }
-
-    mMapperV2 = IMapper::getService();
-    if (mMapperV2 == nullptr) {
-        ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
-        return;
-    }
-
-    mInitialized = true;
-    return;
-}
-
-void HandleImporter::cleanup() {
-    mMapperV4.clear();
-    mMapperV3.clear();
-    mMapperV2.clear();
-    mInitialized = false;
-}
-
-template<class M, class E>
-bool HandleImporter::importBufferInternal(const sp<M> mapper, buffer_handle_t& handle) {
-    E error;
-    buffer_handle_t importedHandle;
-    auto ret = mapper->importBuffer(
-        hidl_handle(handle),
-        [&](const auto& tmpError, const auto& tmpBufferHandle) {
-            error = tmpError;
-            importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
-        });
-
-    if (!ret.isOk()) {
-        ALOGE("%s: mapper importBuffer failed: %s",
-                __FUNCTION__, ret.description().c_str());
-        return false;
-    }
-
-    if (error != E::NONE) {
-        return false;
-    }
-
-    handle = importedHandle;
-    return true;
-}
-
-template<class M, class E>
-YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf,
-        uint64_t cpuUsage, const IMapper::Rect& accessRegion) {
-    hidl_handle acquireFenceHandle;
-    auto buffer = const_cast<native_handle_t*>(buf);
-    YCbCrLayout layout = {};
-
-    typename M::Rect accessRegionCopy = {accessRegion.left, accessRegion.top,
-            accessRegion.width, accessRegion.height};
-    mapper->lockYCbCr(buffer, cpuUsage, accessRegionCopy, acquireFenceHandle,
-            [&](const auto& tmpError, const auto& tmpLayout) {
-                if (tmpError == E::NONE) {
-                    // Member by member copy from different versions of YCbCrLayout.
-                    layout.y = tmpLayout.y;
-                    layout.cb = tmpLayout.cb;
-                    layout.cr = tmpLayout.cr;
-                    layout.yStride = tmpLayout.yStride;
-                    layout.cStride = tmpLayout.cStride;
-                    layout.chromaStep = tmpLayout.chromaStep;
-                } else {
-                    ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
-                }
-           });
-    return layout;
-}
-
-bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf,
-        MetadataType metadataType) {
-    auto buffer = const_cast<native_handle_t*>(buf);
-    bool ret = false;
-    hidl_vec<uint8_t> vec;
-    mapper->get(buffer, metadataType, [&] (const auto& tmpError,
-                const auto& tmpMetadata) {
-                    if (tmpError == MapperErrorV4::NONE) {
-                        vec = tmpMetadata;
-                    } else {
-                        ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError);
-                    }});
-
-    if (vec.size() > 0) {
-            if (metadataType == gralloc4::MetadataType_Smpte2086){
-                std::optional<Smpte2086> realSmpte2086;
-                gralloc4::decodeSmpte2086(vec, &realSmpte2086);
-                ret = realSmpte2086.has_value();
-            } else if (metadataType == gralloc4::MetadataType_Smpte2094_10) {
-                std::optional<std::vector<uint8_t>> realSmpte2094_10;
-                gralloc4::decodeSmpte2094_10(vec, &realSmpte2094_10);
-                ret = realSmpte2094_10.has_value();
-            } else if (metadataType == gralloc4::MetadataType_Smpte2094_40) {
-                std::optional<std::vector<uint8_t>> realSmpte2094_40;
-                gralloc4::decodeSmpte2094_40(vec, &realSmpte2094_40);
-                ret = realSmpte2094_40.has_value();
-            } else {
-                ALOGE("%s: Unknown metadata type!", __FUNCTION__);
-            }
-    }
-
-    return ret;
-}
-
-std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) {
-    auto buffer = const_cast<native_handle_t*>(buf);
-    std::vector<PlaneLayout> planeLayouts;
-    hidl_vec<uint8_t> encodedPlaneLayouts;
-    mapper->get(buffer, gralloc4::MetadataType_PlaneLayouts,
-                [&](const auto& tmpError, const auto& tmpEncodedPlaneLayouts) {
-                    if (tmpError == MapperErrorV4::NONE) {
-                        encodedPlaneLayouts = tmpEncodedPlaneLayouts;
-                    } else {
-                        ALOGE("%s: failed to get plane layouts %d!", __FUNCTION__, tmpError);
-                    }
-                });
-
-    gralloc4::decodePlaneLayouts(encodedPlaneLayouts, &planeLayouts);
-
-    return planeLayouts;
-}
-
-template <>
-YCbCrLayout HandleImporter::lockYCbCrInternal<IMapperV4, MapperErrorV4>(
-        const sp<IMapperV4> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
-        const IMapper::Rect& accessRegion) {
-    hidl_handle acquireFenceHandle;
-    auto buffer = const_cast<native_handle_t*>(buf);
-    YCbCrLayout layout = {};
-    void* mapped = nullptr;
-
-    typename IMapperV4::Rect accessRegionV4 = {accessRegion.left, accessRegion.top,
-                                               accessRegion.width, accessRegion.height};
-    mapper->lock(buffer, cpuUsage, accessRegionV4, acquireFenceHandle,
-                 [&](const auto& tmpError, const auto& tmpPtr) {
-                     if (tmpError == MapperErrorV4::NONE) {
-                         mapped = tmpPtr;
-                     } else {
-                         ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
-                     }
-                 });
-
-    if (mapped == nullptr) {
-        return layout;
-    }
-
-    std::vector<PlaneLayout> planeLayouts = getPlaneLayouts(mapper, buf);
-    for (const auto& planeLayout : planeLayouts) {
-        for (const auto& planeLayoutComponent : planeLayout.components) {
-            const auto& type = planeLayoutComponent.type;
-
-            if (!gralloc4::isStandardPlaneLayoutComponentType(type)) {
-                continue;
-            }
-
-            uint8_t* data = reinterpret_cast<uint8_t*>(mapped);
-            data += planeLayout.offsetInBytes;
-            data += planeLayoutComponent.offsetInBits / 8;
-
-            switch (static_cast<PlaneLayoutComponentType>(type.value)) {
-                case PlaneLayoutComponentType::Y:
-                    layout.y = data;
-                    layout.yStride = planeLayout.strideInBytes;
-                    break;
-                case PlaneLayoutComponentType::CB:
-                    layout.cb = data;
-                    layout.cStride = planeLayout.strideInBytes;
-                    layout.chromaStep = planeLayout.sampleIncrementInBits / 8;
-                    break;
-                case PlaneLayoutComponentType::CR:
-                    layout.cr = data;
-                    layout.cStride = planeLayout.strideInBytes;
-                    layout.chromaStep = planeLayout.sampleIncrementInBits / 8;
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-    return layout;
-}
-
-template<class M, class E>
-int HandleImporter::unlockInternal(const sp<M> mapper, buffer_handle_t& buf) {
-    int releaseFence = -1;
-    auto buffer = const_cast<native_handle_t*>(buf);
-
-    mapper->unlock(
-        buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
-            if (tmpError == E::NONE) {
-                auto fenceHandle = tmpReleaseFence.getNativeHandle();
-                if (fenceHandle) {
-                    if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
-                        ALOGE("%s: bad release fence numInts %d numFds %d",
-                                __FUNCTION__, fenceHandle->numInts, fenceHandle->numFds);
-                        return;
-                    }
-                    releaseFence = dup(fenceHandle->data[0]);
-                    if (releaseFence < 0) {
-                        ALOGE("%s: bad release fence FD %d",
-                                __FUNCTION__, releaseFence);
-                    }
-                }
-            } else {
-                ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
-            }
-        });
-    return releaseFence;
-}
-
-// In IComposer, any buffer_handle_t is owned by the caller and we need to
-// make a clone for hwcomposer2.  We also need to translate empty handle
-// to nullptr.  This function does that, in-place.
-bool HandleImporter::importBuffer(buffer_handle_t& handle) {
-    if (!handle->numFds && !handle->numInts) {
-        handle = nullptr;
-        return true;
-    }
-
-    Mutex::Autolock lock(mLock);
-    if (!mInitialized) {
-        initializeLocked();
-    }
-
-    if (mMapperV4 != nullptr) {
-        return importBufferInternal<IMapperV4, MapperErrorV4>(mMapperV4, handle);
-    }
-
-    if (mMapperV3 != nullptr) {
-        return importBufferInternal<IMapperV3, MapperErrorV3>(mMapperV3, handle);
-    }
-
-    if (mMapperV2 != nullptr) {
-        return importBufferInternal<IMapper, MapperErrorV2>(mMapperV2, handle);
-    }
-
-    ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
-    return false;
-}
-
-void HandleImporter::freeBuffer(buffer_handle_t handle) {
-    if (!handle) {
-        return;
-    }
-
-    Mutex::Autolock lock(mLock);
-    if (!mInitialized) {
-        initializeLocked();
-    }
-
-    if (mMapperV4 != nullptr) {
-        auto ret = mMapperV4->freeBuffer(const_cast<native_handle_t*>(handle));
-        if (!ret.isOk()) {
-            ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
-        }
-    } else if (mMapperV3 != nullptr) {
-        auto ret = mMapperV3->freeBuffer(const_cast<native_handle_t*>(handle));
-        if (!ret.isOk()) {
-            ALOGE("%s: mapper freeBuffer failed: %s",
-                    __FUNCTION__, ret.description().c_str());
-        }
-    } else {
-        auto ret = mMapperV2->freeBuffer(const_cast<native_handle_t*>(handle));
-        if (!ret.isOk()) {
-            ALOGE("%s: mapper freeBuffer failed: %s",
-                    __FUNCTION__, ret.description().c_str());
-        }
-    }
-}
-
-bool HandleImporter::importFence(const native_handle_t* handle, int& fd) const {
-    if (handle == nullptr || handle->numFds == 0) {
-        fd = -1;
-    } else if (handle->numFds == 1) {
-        fd = dup(handle->data[0]);
-        if (fd < 0) {
-            ALOGE("failed to dup fence fd %d", handle->data[0]);
-            return false;
-        }
-    } else {
-        ALOGE("invalid fence handle with %d file descriptors",
-                handle->numFds);
-        return false;
-    }
-
-    return true;
-}
-
-void HandleImporter::closeFence(int fd) const {
-    if (fd >= 0) {
-        close(fd);
-    }
-}
-
-void* HandleImporter::lock(
-        buffer_handle_t& buf, uint64_t cpuUsage, size_t size) {
-    IMapper::Rect accessRegion{0, 0, static_cast<int>(size), 1};
-    return lock(buf, cpuUsage, accessRegion);
-}
-
-void* HandleImporter::lock(buffer_handle_t& buf, uint64_t cpuUsage,
-                           const IMapper::Rect& accessRegion) {
-    Mutex::Autolock lock(mLock);
-
-    if (!mInitialized) {
-        initializeLocked();
-    }
-
-    void* ret = nullptr;
-
-    if (mMapperV4 == nullptr && mMapperV3 == nullptr && mMapperV2 == nullptr) {
-        ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
-        return ret;
-    }
-
-    hidl_handle acquireFenceHandle;
-    auto buffer = const_cast<native_handle_t*>(buf);
-    if (mMapperV4 != nullptr) {
-        IMapperV4::Rect accessRegionV4{accessRegion.left, accessRegion.top, accessRegion.width,
-                                       accessRegion.height};
-
-        mMapperV4->lock(buffer, cpuUsage, accessRegionV4, acquireFenceHandle,
-                        [&](const auto& tmpError, const auto& tmpPtr) {
-                            if (tmpError == MapperErrorV4::NONE) {
-                                ret = tmpPtr;
-                            } else {
-                                ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
-                            }
-                        });
-    } else if (mMapperV3 != nullptr) {
-        IMapperV3::Rect accessRegionV3{accessRegion.left, accessRegion.top, accessRegion.width,
-                                       accessRegion.height};
-
-        mMapperV3->lock(buffer, cpuUsage, accessRegionV3, acquireFenceHandle,
-                        [&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
-                            const auto& /*bytesPerStride*/) {
-                            if (tmpError == MapperErrorV3::NONE) {
-                                ret = tmpPtr;
-                            } else {
-                                ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
-                            }
-                        });
-    } else {
-        mMapperV2->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
-                [&](const auto& tmpError, const auto& tmpPtr) {
-                    if (tmpError == MapperErrorV2::NONE) {
-                        ret = tmpPtr;
-                    } else {
-                        ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
-                    }
-               });
-    }
-
-    ALOGV("%s: ptr %p accessRegion.top: %d accessRegion.left: %d accessRegion.width: %d "
-          "accessRegion.height: %d",
-          __FUNCTION__, ret, accessRegion.top, accessRegion.left, accessRegion.width,
-          accessRegion.height);
-    return ret;
-}
-
-YCbCrLayout HandleImporter::lockYCbCr(
-        buffer_handle_t& buf, uint64_t cpuUsage,
-        const IMapper::Rect& accessRegion) {
-    Mutex::Autolock lock(mLock);
-
-    if (!mInitialized) {
-        initializeLocked();
-    }
-
-    if (mMapperV4 != nullptr) {
-        return lockYCbCrInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf, cpuUsage, accessRegion);
-    }
-
-    if (mMapperV3 != nullptr) {
-        return lockYCbCrInternal<IMapperV3, MapperErrorV3>(
-                mMapperV3, buf, cpuUsage, accessRegion);
-    }
-
-    if (mMapperV2 != nullptr) {
-        return lockYCbCrInternal<IMapper, MapperErrorV2>(
-                mMapperV2, buf, cpuUsage, accessRegion);
-    }
-
-    ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
-    return {};
-}
-
-status_t HandleImporter::getMonoPlanarStrideBytes(buffer_handle_t &buf, uint32_t *stride /*out*/) {
-    if (stride == nullptr) {
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock lock(mLock);
-
-    if (!mInitialized) {
-        initializeLocked();
-    }
-
-    if (mMapperV4 != nullptr) {
-        std::vector<PlaneLayout> planeLayouts = getPlaneLayouts(mMapperV4, buf);
-        if (planeLayouts.size() != 1) {
-            ALOGE("%s: Unexpected number of planes %zu!",  __FUNCTION__, planeLayouts.size());
-            return BAD_VALUE;
-        }
-
-        *stride = planeLayouts[0].strideInBytes;
-    } else {
-        ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
-        return NO_INIT;
-    }
-
-    return OK;
-}
-
-int HandleImporter::unlock(buffer_handle_t& buf) {
-    if (mMapperV4 != nullptr) {
-        return unlockInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf);
-    }
-    if (mMapperV3 != nullptr) {
-        return unlockInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf);
-    }
-    if (mMapperV2 != nullptr) {
-        return unlockInternal<IMapper, MapperErrorV2>(mMapperV2, buf);
-    }
-
-    ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
-    return -1;
-}
-
-bool HandleImporter::isSmpte2086Present(const buffer_handle_t& buf) {
-    Mutex::Autolock lock(mLock);
-
-    if (!mInitialized) {
-        initializeLocked();
-    }
-
-    if (mMapperV4 != nullptr) {
-        return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2086);
-    } else {
-        ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
-    }
-
-    return false;
-}
-
-bool HandleImporter::isSmpte2094_10Present(const buffer_handle_t& buf) {
-    Mutex::Autolock lock(mLock);
-
-    if (!mInitialized) {
-        initializeLocked();
-    }
-
-    if (mMapperV4 != nullptr) {
-        return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_10);
-    } else {
-        ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
-    }
-
-    return false;
-}
-
-bool HandleImporter::isSmpte2094_40Present(const buffer_handle_t& buf) {
-    Mutex::Autolock lock(mLock);
-
-    if (!mInitialized) {
-        initializeLocked();
-    }
-
-    if (mMapperV4 != nullptr) {
-        return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_40);
-    } else {
-        ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
-    }
-
-    return false;
-}
-
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/OWNERS b/camera/common/1.0/default/OWNERS
deleted file mode 100644
index f48a95c..0000000
--- a/camera/common/1.0/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/common/1.0/default/VendorTagDescriptor.cpp b/camera/common/1.0/default/VendorTagDescriptor.cpp
deleted file mode 100644
index d2bee85..0000000
--- a/camera/common/1.0/default/VendorTagDescriptor.cpp
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (C) 2016 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 "CamComm1.0-VTDesc"
-
-#include <log/log.h>
-#include <system/camera_metadata.h>
-#include <camera_metadata_hidden.h>
-#include <utils/Errors.h>
-#include <utils/Mutex.h>
-#include <utils/SortedVector.h>
-#include <utils/Vector.h>
-
-#include "VendorTagDescriptor.h"
-
-#include <stdio.h>
-#include <string.h>
-
-namespace android {
-namespace hardware {
-namespace camera2 {
-namespace params {
-
-VendorTagDescriptor::~VendorTagDescriptor() {
-    size_t len = mReverseMapping.size();
-    for (size_t i = 0; i < len; ++i)  {
-        delete mReverseMapping[i];
-    }
-}
-
-VendorTagDescriptor::VendorTagDescriptor() :
-        mTagCount(0),
-        mVendorOps() {
-}
-
-VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
-    copyFrom(src);
-}
-
-VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
-    copyFrom(rhs);
-    return *this;
-}
-
-void VendorTagDescriptor::copyFrom(const VendorTagDescriptor& src) {
-    if (this == &src) return;
-
-    size_t len = mReverseMapping.size();
-    for (size_t i = 0; i < len; ++i) {
-        delete mReverseMapping[i];
-    }
-    mReverseMapping.clear();
-
-    len = src.mReverseMapping.size();
-    // Have to copy KeyedVectors inside mReverseMapping
-    for (size_t i = 0; i < len; ++i) {
-        KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
-        *nameMapper = *(src.mReverseMapping.valueAt(i));
-        mReverseMapping.add(src.mReverseMapping.keyAt(i), nameMapper);
-    }
-    // Everything else is simple
-    mTagToNameMap = src.mTagToNameMap;
-    mTagToSectionMap = src.mTagToSectionMap;
-    mTagToTypeMap = src.mTagToTypeMap;
-    mSections = src.mSections;
-    mTagCount = src.mTagCount;
-    mVendorOps = src.mVendorOps;
-}
-
-int VendorTagDescriptor::getTagCount() const {
-    size_t size = mTagToNameMap.size();
-    if (size == 0) {
-        return VENDOR_TAG_COUNT_ERR;
-    }
-    return size;
-}
-
-void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
-    size_t size = mTagToNameMap.size();
-    for (size_t i = 0; i < size; ++i) {
-        tagArray[i] = mTagToNameMap.keyAt(i);
-    }
-}
-
-const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
-    ssize_t index = mTagToSectionMap.indexOfKey(tag);
-    if (index < 0) {
-        return VENDOR_SECTION_NAME_ERR;
-    }
-    return mSections[mTagToSectionMap.valueAt(index)].string();
-}
-
-ssize_t VendorTagDescriptor::getSectionIndex(uint32_t tag) const {
-    return mTagToSectionMap.valueFor(tag);
-}
-
-const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
-    ssize_t index = mTagToNameMap.indexOfKey(tag);
-    if (index < 0) {
-        return VENDOR_TAG_NAME_ERR;
-    }
-    return mTagToNameMap.valueAt(index).string();
-}
-
-int VendorTagDescriptor::getTagType(uint32_t tag) const {
-    auto iter = mTagToTypeMap.find(tag);
-    if (iter == mTagToTypeMap.end()) {
-        return VENDOR_TAG_TYPE_ERR;
-    }
-    return iter->second;
-}
-
-const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const {
-    return &mSections;
-}
-
-status_t VendorTagDescriptor::lookupTag(const String8& name, const String8& section, /*out*/uint32_t* tag) const {
-    ssize_t index = mReverseMapping.indexOfKey(section);
-    if (index < 0) {
-        ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string());
-        return BAD_VALUE;
-    }
-
-    ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
-    if (nameIndex < 0) {
-        ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string());
-        return BAD_VALUE;
-    }
-
-    if (tag != NULL) {
-        *tag = mReverseMapping[index]->valueAt(nameIndex);
-    }
-    return OK;
-}
-
-void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
-
-    size_t size = mTagToNameMap.size();
-    if (size == 0) {
-        dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
-                indentation, "");
-        return;
-    }
-
-    dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
-            indentation, "", size);
-    for (size_t i = 0; i < size; ++i) {
-        uint32_t tag =  mTagToNameMap.keyAt(i);
-
-        if (verbosity < 1) {
-            dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
-            continue;
-        }
-        String8 name = mTagToNameMap.valueAt(i);
-        uint32_t sectionId = mTagToSectionMap.valueFor(tag);
-        String8 sectionName = mSections[sectionId];
-        int type = mTagToTypeMap.at(tag);
-        const char* typeName = (type >= 0 && type < NUM_TYPES) ?
-                camera_metadata_type_names[type] : "UNKNOWN";
-        dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
-            "", tag, name.string(), type, typeName, sectionName.string());
-    }
-
-}
-
-int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
-    int ret = 0;
-    auto desc = mVendorMap.find(id);
-    if (desc != mVendorMap.end()) {
-        ret = desc->second->getTagCount();
-    } else {
-        ALOGE("%s: Vendor descriptor id is missing!", __func__);
-    }
-
-    return ret;
-}
-
-void VendorTagDescriptorCache::getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const {
-    auto desc = mVendorMap.find(id);
-    if (desc != mVendorMap.end()) {
-        desc->second->getTagArray(tagArray);
-    } else {
-        ALOGE("%s: Vendor descriptor id is missing!", __func__);
-    }
-}
-
-const char* VendorTagDescriptorCache::getSectionName(uint32_t tag, metadata_vendor_id_t id) const {
-    const char* ret = nullptr;
-    auto desc = mVendorMap.find(id);
-    if (desc != mVendorMap.end()) {
-        ret = desc->second->getSectionName(tag);
-    } else {
-        ALOGE("%s: Vendor descriptor id is missing!", __func__);
-    }
-
-    return ret;
-}
-
-const char* VendorTagDescriptorCache::getTagName(uint32_t tag, metadata_vendor_id_t id) const {
-    const char* ret = nullptr;
-    auto desc = mVendorMap.find(id);
-    if (desc != mVendorMap.end()) {
-        ret = desc->second->getTagName(tag);
-    } else {
-        ALOGE("%s: Vendor descriptor id is missing!", __func__);
-    }
-
-    return ret;
-}
-
-int VendorTagDescriptorCache::getTagType(uint32_t tag, metadata_vendor_id_t id) const {
-    int ret = 0;
-    auto desc = mVendorMap.find(id);
-    if (desc != mVendorMap.end()) {
-        ret = desc->second->getTagType(tag);
-    } else {
-        ALOGE("%s: Vendor descriptor id is missing!", __func__);
-    }
-
-    return ret;
-}
-
-void VendorTagDescriptorCache::dump(int fd, int verbosity, int indentation) const {
-    for (const auto& desc : mVendorMap) {
-        desc.second->dump(fd, verbosity, indentation);
-    }
-}
-
-int32_t VendorTagDescriptorCache::addVendorDescriptor(
-    metadata_vendor_id_t id, sp<hardware::camera::common::V1_0::helper::VendorTagDescriptor> desc) {
-    auto entry = mVendorMap.find(id);
-    if (entry != mVendorMap.end()) {
-        ALOGE("%s: Vendor descriptor with same id already present!", __func__);
-        return BAD_VALUE;
-    }
-
-    mVendorMap.emplace(id, desc);
-    return NO_ERROR;
-}
-
-int32_t VendorTagDescriptorCache::getVendorTagDescriptor(
-    metadata_vendor_id_t id,
-    sp<hardware::camera::common::V1_0::helper::VendorTagDescriptor>* desc /*out*/) {
-    auto entry = mVendorMap.find(id);
-    if (entry == mVendorMap.end()) {
-        return NAME_NOT_FOUND;
-    }
-
-    *desc = entry->second;
-
-    return NO_ERROR;
-}
-} // namespace params
-} // namespace camera2
-
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-extern "C" {
-
-static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
-static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
-static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
-static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
-static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
-
-static int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id);
-static void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id);
-static const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
-                                                                metadata_vendor_id_t id);
-static const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id);
-static int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id);
-} /* extern "C" */
-
-static Mutex sLock;
-static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
-static sp<VendorTagDescriptorCache> sGlobalVendorTagDescriptorCache;
-
-status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
-            /*out*/
-            sp<VendorTagDescriptor>& descriptor) {
-    if (vOps == NULL) {
-        ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    int tagCount = vOps->get_tag_count(vOps);
-    if (tagCount < 0 || tagCount > INT32_MAX) {
-        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
-        return BAD_VALUE;
-    }
-
-    Vector<uint32_t> tagArray;
-    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
-            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
-
-    vOps->get_all_tags(vOps, /*out*/tagArray.editArray());
-
-    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
-    desc->mTagCount = tagCount;
-
-    SortedVector<String8> sections;
-    KeyedVector<uint32_t, String8> tagToSectionMap;
-
-    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
-        uint32_t tag = tagArray[i];
-        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
-            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
-            return BAD_VALUE;
-        }
-        const char *tagName = vOps->get_tag_name(vOps, tag);
-        if (tagName == NULL) {
-            ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
-            return BAD_VALUE;
-        }
-        desc->mTagToNameMap.add(tag, String8(tagName));
-        const char *sectionName = vOps->get_section_name(vOps, tag);
-        if (sectionName == NULL) {
-            ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
-            return BAD_VALUE;
-        }
-
-        String8 sectionString(sectionName);
-
-        sections.add(sectionString);
-        tagToSectionMap.add(tag, sectionString);
-
-        int tagType = vOps->get_tag_type(vOps, tag);
-        if (tagType < 0 || tagType >= NUM_TYPES) {
-            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
-            return BAD_VALUE;
-        }
-        desc->mTagToTypeMap.insert(std::make_pair(tag, tagType));
-    }
-
-    desc->mSections = sections;
-
-    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
-        uint32_t tag = tagArray[i];
-        const String8& sectionString = tagToSectionMap.valueFor(tag);
-
-        // Set up tag to section index map
-        ssize_t index = sections.indexOf(sectionString);
-        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
-        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
-
-        // Set up reverse mapping
-        ssize_t reverseIndex = -1;
-        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
-            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
-            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
-        }
-        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
-    }
-
-    descriptor = desc;
-    return OK;
-}
-
-status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
-    status_t res = OK;
-    Mutex::Autolock al(sLock);
-    sGlobalVendorTagDescriptor = desc;
-
-    vendor_tag_ops_t* opsPtr = NULL;
-    if (desc != NULL) {
-        opsPtr = &(desc->mVendorOps);
-        opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
-        opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
-        opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
-        opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
-        opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
-    }
-    if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
-        ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)."
-                , __FUNCTION__, strerror(-res), res);
-    }
-    return res;
-}
-
-void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
-    Mutex::Autolock al(sLock);
-    set_camera_metadata_vendor_ops(NULL);
-    sGlobalVendorTagDescriptor.clear();
-}
-
-sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
-    Mutex::Autolock al(sLock);
-    return sGlobalVendorTagDescriptor;
-}
-
-status_t VendorTagDescriptorCache::setAsGlobalVendorTagCache(
-    const sp<VendorTagDescriptorCache>& cache) {
-    status_t res = OK;
-    Mutex::Autolock al(sLock);
-    sGlobalVendorTagDescriptorCache = cache;
-
-    struct vendor_tag_cache_ops* opsPtr = NULL;
-    if (cache != NULL) {
-        opsPtr = &(cache->mVendorCacheOps);
-        opsPtr->get_tag_count = vendor_tag_descriptor_cache_get_tag_count;
-        opsPtr->get_all_tags = vendor_tag_descriptor_cache_get_all_tags;
-        opsPtr->get_section_name = vendor_tag_descriptor_cache_get_section_name;
-        opsPtr->get_tag_name = vendor_tag_descriptor_cache_get_tag_name;
-        opsPtr->get_tag_type = vendor_tag_descriptor_cache_get_tag_type;
-    }
-    if ((res = set_camera_metadata_vendor_cache_ops(opsPtr)) != OK) {
-        ALOGE("%s: Could not set vendor tag cache, received error %s (%d).", __FUNCTION__,
-              strerror(-res), res);
-    }
-    return res;
-}
-
-void VendorTagDescriptorCache::clearGlobalVendorTagCache() {
-    Mutex::Autolock al(sLock);
-    set_camera_metadata_vendor_cache_ops(NULL);
-    sGlobalVendorTagDescriptorCache.clear();
-}
-
-sp<VendorTagDescriptorCache> VendorTagDescriptorCache::getGlobalVendorTagCache() {
-    Mutex::Autolock al(sLock);
-    return sGlobalVendorTagDescriptorCache;
-}
-
-extern "C" {
-
-int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptor == NULL) {
-        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
-        return VENDOR_TAG_COUNT_ERR;
-    }
-    return sGlobalVendorTagDescriptor->getTagCount();
-}
-
-void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptor == NULL) {
-        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
-        return;
-    }
-    sGlobalVendorTagDescriptor->getTagArray(tagArray);
-}
-
-const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptor == NULL) {
-        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
-        return VENDOR_SECTION_NAME_ERR;
-    }
-    return sGlobalVendorTagDescriptor->getSectionName(tag);
-}
-
-const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptor == NULL) {
-        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
-        return VENDOR_TAG_NAME_ERR;
-    }
-    return sGlobalVendorTagDescriptor->getTagName(tag);
-}
-
-int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptor == NULL) {
-        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
-        return VENDOR_TAG_TYPE_ERR;
-    }
-    return sGlobalVendorTagDescriptor->getTagType(tag);
-}
-
-int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptorCache == NULL) {
-        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
-        return VENDOR_TAG_COUNT_ERR;
-    }
-    return sGlobalVendorTagDescriptorCache->getTagCount(id);
-}
-
-void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptorCache == NULL) {
-        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
-    }
-    sGlobalVendorTagDescriptorCache->getTagArray(tagArray, id);
-}
-
-const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag, metadata_vendor_id_t id) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptorCache == NULL) {
-        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
-        return VENDOR_SECTION_NAME_ERR;
-    }
-    return sGlobalVendorTagDescriptorCache->getSectionName(tag, id);
-}
-
-const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptorCache == NULL) {
-        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
-        return VENDOR_TAG_NAME_ERR;
-    }
-    return sGlobalVendorTagDescriptorCache->getTagName(tag, id);
-}
-
-int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id) {
-    Mutex::Autolock al(sLock);
-    if (sGlobalVendorTagDescriptorCache == NULL) {
-        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
-        return VENDOR_TAG_NAME_ERR;
-    }
-    return sGlobalVendorTagDescriptorCache->getTagType(tag, id);
-}
-
-} /* extern "C" */
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/include/CameraMetadata.h b/camera/common/1.0/default/include/CameraMetadata.h
deleted file mode 100644
index d5e4d56..0000000
--- a/camera/common/1.0/default/include/CameraMetadata.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2016 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 CAMERA_COMMON_1_0_CAMERAMETADATA_H
-#define CAMERA_COMMON_1_0_CAMERAMETADATA_H
-
-#include "system/camera_metadata.h"
-
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-class VendorTagDescriptor;
-
-/**
- * A convenience wrapper around the C-based camera_metadata_t library.
- */
-class CameraMetadata {
-  public:
-    /** Creates an empty object; best used when expecting to acquire contents
-     * from elsewhere */
-    CameraMetadata();
-    /** Creates an object with space for entryCapacity entries, with
-     * dataCapacity extra storage */
-    CameraMetadata(size_t entryCapacity, size_t dataCapacity = 10);
-
-    ~CameraMetadata();
-
-    /** Takes ownership of passed-in buffer */
-    CameraMetadata(camera_metadata_t *buffer);
-    /** Clones the metadata */
-    CameraMetadata(const CameraMetadata &other);
-
-    /**
-     * Assignment clones metadata buffer.
-     */
-    CameraMetadata &operator=(const CameraMetadata &other);
-    CameraMetadata &operator=(const camera_metadata_t *buffer);
-
-    /**
-     * Get reference to the underlying metadata buffer. Ownership remains with
-     * the CameraMetadata object, but non-const CameraMetadata methods will not
-     * work until unlock() is called. Note that the lock has nothing to do with
-     * thread-safety, it simply prevents the camera_metadata_t pointer returned
-     * here from being accidentally invalidated by CameraMetadata operations.
-     */
-    const camera_metadata_t* getAndLock() const;
-
-    /**
-     * Unlock the CameraMetadata for use again. After this unlock, the pointer
-     * given from getAndLock() may no longer be used. The pointer passed out
-     * from getAndLock must be provided to guarantee that the right object is
-     * being unlocked.
-     */
-    status_t unlock(const camera_metadata_t *buffer) const;
-
-    /**
-     * Release a raw metadata buffer to the caller. After this call,
-     * CameraMetadata no longer references the buffer, and the caller takes
-     * responsibility for freeing the raw metadata buffer (using
-     * free_camera_metadata()), or for handing it to another CameraMetadata
-     * instance.
-     */
-    camera_metadata_t* release();
-
-    /**
-     * Clear the metadata buffer and free all storage used by it
-     */
-    void clear();
-
-    /**
-     * Acquire a raw metadata buffer from the caller. After this call,
-     * the caller no longer owns the raw buffer, and must not free or manipulate it.
-     * If CameraMetadata already contains metadata, it is freed.
-     */
-    void acquire(camera_metadata_t* buffer);
-
-    /**
-     * Acquires raw buffer from other CameraMetadata object. After the call, the argument
-     * object no longer has any metadata.
-     */
-    void acquire(CameraMetadata &other);
-
-    /**
-     * Append metadata from another CameraMetadata object.
-     */
-    status_t append(const CameraMetadata &other);
-
-    /**
-     * Append metadata from a raw camera_metadata buffer
-     */
-    status_t append(const camera_metadata* other);
-
-    /**
-     * Number of metadata entries.
-     */
-    size_t entryCount() const;
-
-    /**
-     * Is the buffer empty (no entires)
-     */
-    bool isEmpty() const;
-
-    /**
-     * Sort metadata buffer for faster find
-     */
-    status_t sort();
-
-    /**
-     * Update metadata entry. Will create entry if it doesn't exist already, and
-     * will reallocate the buffer if insufficient space exists. Overloaded for
-     * the various types of valid data.
-     */
-    status_t update(uint32_t tag,
-            const uint8_t *data, size_t data_count);
-    status_t update(uint32_t tag,
-            const int32_t *data, size_t data_count);
-    status_t update(uint32_t tag,
-            const float *data, size_t data_count);
-    status_t update(uint32_t tag,
-            const int64_t *data, size_t data_count);
-    status_t update(uint32_t tag,
-            const double *data, size_t data_count);
-    status_t update(uint32_t tag,
-            const camera_metadata_rational_t *data, size_t data_count);
-    status_t update(uint32_t tag,
-            const String8 &string);
-    status_t update(const camera_metadata_ro_entry &entry);
-
-
-    template<typename T>
-    status_t update(uint32_t tag, Vector<T> data) {
-        return update(tag, data.array(), data.size());
-    }
-
-    /**
-     * Check if a metadata entry exists for a given tag id
-     *
-     */
-    bool exists(uint32_t tag) const;
-
-    /**
-     * Get metadata entry by tag id
-     */
-    camera_metadata_entry find(uint32_t tag);
-
-    /**
-     * Get metadata entry by tag id, with no editing
-     */
-    camera_metadata_ro_entry find(uint32_t tag) const;
-
-    /**
-     * Delete metadata entry by tag
-     */
-    status_t erase(uint32_t tag);
-
-    /**
-     * Swap the underlying camera metadata between this and the other
-     * metadata object.
-     */
-    void swap(CameraMetadata &other);
-
-    /**
-     * Dump contents into FD for debugging. The verbosity levels are
-     * 0: Tag entry information only, no data values
-     * 1: Level 0 plus at most 16 data values per entry
-     * 2: All information
-     *
-     * The indentation parameter sets the number of spaces to add to the start
-     * each line of output.
-     */
-    void dump(int fd, int verbosity = 1, int indentation = 0) const;
-
-    /**
-     * Find tag id for a given tag name, also checking vendor tags if available.
-     * On success, returns OK and writes the tag id into tag.
-     *
-     * This is a slow method.
-     */
-    static status_t getTagFromName(const char *name,
-            const VendorTagDescriptor* vTags, uint32_t *tag);
-
-  private:
-    camera_metadata_t *mBuffer;
-    mutable bool       mLocked;
-
-    /**
-     * Check if tag has a given type
-     */
-    status_t checkType(uint32_t tag, uint8_t expectedType);
-
-    /**
-     * Base update entry method
-     */
-    status_t updateImpl(uint32_t tag, const void *data, size_t data_count);
-
-    /**
-     * Resize metadata buffer if needed by reallocating it and copying it over.
-     */
-    status_t resizeIfNeeded(size_t extraEntries, size_t extraData);
-
-};
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-#endif
diff --git a/camera/common/1.0/default/include/CameraModule.h b/camera/common/1.0/default/include/CameraModule.h
deleted file mode 100644
index c89e934..0000000
--- a/camera/common/1.0/default/include/CameraModule.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2016 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 CAMERA_COMMON_1_0_CAMERAMODULE_H
-#define CAMERA_COMMON_1_0_CAMERAMODULE_H
-
-#include <string>
-#include <unordered_set>
-
-#include <hardware/camera.h>
-#include <utils/Mutex.h>
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-
-#include "CameraMetadata.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-/**
- * A wrapper class for HAL camera module.
- *
- * This class wraps camera_module_t returned from HAL to provide a wrapped
- * get_camera_info implementation which CameraService generates some
- * camera characteristics keys defined in newer HAL version on an older HAL.
- */
-class CameraModule : public RefBase {
-public:
-    explicit CameraModule(camera_module_t *module);
-    virtual ~CameraModule();
-
-    // Must be called after construction
-    // Returns OK on success, NO_INIT on failure
-    int init();
-
-    int getCameraInfo(int cameraId, struct camera_info *info);
-    int getDeviceVersion(int cameraId);
-    int getNumberOfCameras(void);
-    int open(const char* id, struct hw_device_t** device);
-    bool isOpenLegacyDefined() const;
-    int openLegacy(const char* id, uint32_t halVersion, struct hw_device_t** device);
-    int setCallbacks(const camera_module_callbacks_t *callbacks);
-    bool isVendorTagDefined() const;
-    void getVendorTagOps(vendor_tag_ops_t* ops);
-    bool isSetTorchModeSupported() const;
-    int setTorchMode(const char* camera_id, bool enable);
-    uint16_t getModuleApiVersion() const;
-    const char* getModuleName() const;
-    uint16_t getHalApiVersion() const;
-    const char* getModuleAuthor() const;
-    // Only used by CameraModuleFixture native test. Do NOT use elsewhere.
-    void *getDso();
-    // Only used by CameraProvider
-    void removeCamera(int cameraId);
-    int getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t **physicalInfo);
-    int isStreamCombinationSupported(int cameraId, camera_stream_combination_t *streams);
-    void notifyDeviceStateChange(uint64_t deviceState);
-
-    static bool isLogicalMultiCamera(
-            const common::V1_0::helper::CameraMetadata& metadata,
-            std::unordered_set<std::string>* physicalCameraIds);
-
-private:
-    // Derive camera characteristics keys defined after HAL device version
-    static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);
-    // Helper function to append available[request|result|chars]Keys
-    static void appendAvailableKeys(CameraMetadata &chars,
-            int32_t keyTag, const Vector<int32_t>& appendKeys);
-    status_t filterOpenErrorCode(status_t err);
-    camera_module_t *mModule;
-    int mNumberOfCameras;
-    KeyedVector<int, camera_info> mCameraInfoMap;
-    KeyedVector<int, int> mDeviceVersionMap;
-    KeyedVector<int, camera_metadata_t*> mPhysicalCameraInfoMap;
-    Mutex mCameraInfoLock;
-};
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-#endif
diff --git a/camera/common/1.0/default/include/CameraParameters.h b/camera/common/1.0/default/include/CameraParameters.h
deleted file mode 100644
index e4ff6f2..0000000
--- a/camera/common/1.0/default/include/CameraParameters.h
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * Copyright (C) 2008 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_HARDWARE_CAMERA_PARAMETERS_H
-#define ANDROID_HARDWARE_CAMERA_PARAMETERS_H
-
-#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-struct Size {
-    int width;
-    int height;
-
-    Size() {
-        width = 0;
-        height = 0;
-    }
-
-    Size(int w, int h) {
-        width = w;
-        height = h;
-    }
-};
-
-class CameraParameters
-{
-public:
-    CameraParameters();
-    CameraParameters(const String8 &params) { unflatten(params); }
-    ~CameraParameters();
-
-    String8 flatten() const;
-    void unflatten(const String8 &params);
-
-    void set(const char *key, const char *value);
-    void set(const char *key, int value);
-    void setFloat(const char *key, float value);
-    const char *get(const char *key) const;
-    int getInt(const char *key) const;
-    float getFloat(const char *key) const;
-
-    void remove(const char *key);
-
-    void setPreviewSize(int width, int height);
-    void getPreviewSize(int *width, int *height) const;
-    void getSupportedPreviewSizes(Vector<Size> &sizes) const;
-
-    // Set the dimensions in pixels to the given width and height
-    // for video frames. The given width and height must be one
-    // of the supported dimensions returned from
-    // getSupportedVideoSizes(). Must not be called if
-    // getSupportedVideoSizes() returns an empty Vector of Size.
-    void setVideoSize(int width, int height);
-    // Retrieve the current dimensions (width and height)
-    // in pixels for video frames, which must be one of the
-    // supported dimensions returned from getSupportedVideoSizes().
-    // Must not be called if getSupportedVideoSizes() returns an
-    // empty Vector of Size.
-    void getVideoSize(int *width, int *height) const;
-    // Retrieve a Vector of supported dimensions (width and height)
-    // in pixels for video frames. If sizes returned from the method
-    // is empty, the camera does not support calls to setVideoSize()
-    // or getVideoSize(). In adddition, it also indicates that
-    // the camera only has a single output, and does not have
-    // separate output for video frames and preview frame.
-    void getSupportedVideoSizes(Vector<Size> &sizes) const;
-    // Retrieve the preferred preview size (width and height) in pixels
-    // for video recording. The given width and height must be one of
-    // supported preview sizes returned from getSupportedPreviewSizes().
-    // Must not be called if getSupportedVideoSizes() returns an empty
-    // Vector of Size. If getSupportedVideoSizes() returns an empty
-    // Vector of Size, the width and height returned from this method
-    // is invalid, and is "-1x-1".
-    void getPreferredPreviewSizeForVideo(int *width, int *height) const;
-
-    void setPreviewFrameRate(int fps);
-    int getPreviewFrameRate() const;
-    void getPreviewFpsRange(int *min_fps, int *max_fps) const;
-    void setPreviewFormat(const char *format);
-    const char *getPreviewFormat() const;
-    void setPictureSize(int width, int height);
-    void getPictureSize(int *width, int *height) const;
-    void getSupportedPictureSizes(Vector<Size> &sizes) const;
-    void setPictureFormat(const char *format);
-    const char *getPictureFormat() const;
-
-    void dump() const;
-    status_t dump(int fd, const Vector<String16>& args) const;
-
-    /**
-     * Returns a Vector containing the supported preview formats
-     * as enums given in graphics.h.
-     */
-    void getSupportedPreviewFormats(Vector<int>& formats) const;
-
-    // Returns true if no keys are present
-    bool isEmpty() const;
-
-    // Parameter keys to communicate between camera application and driver.
-    // The access (read/write, read only, or write only) is viewed from the
-    // perspective of applications, not driver.
-
-    // Preview frame size in pixels (width x height).
-    // Example value: "480x320". Read/Write.
-    static const char KEY_PREVIEW_SIZE[];
-    // Supported preview frame sizes in pixels.
-    // Example value: "800x600,480x320". Read only.
-    static const char KEY_SUPPORTED_PREVIEW_SIZES[];
-    // The current minimum and maximum preview fps. This controls the rate of
-    // preview frames received (CAMERA_MSG_PREVIEW_FRAME). The minimum and
-    // maximum fps must be one of the elements from
-    // KEY_SUPPORTED_PREVIEW_FPS_RANGE parameter.
-    // Example value: "10500,26623"
-    static const char KEY_PREVIEW_FPS_RANGE[];
-    // The supported preview fps (frame-per-second) ranges. Each range contains
-    // a minimum fps and maximum fps. If minimum fps equals to maximum fps, the
-    // camera outputs frames in fixed frame rate. If not, the camera outputs
-    // frames in auto frame rate. The actual frame rate fluctuates between the
-    // minimum and the maximum. The list has at least one element. The list is
-    // sorted from small to large (first by maximum fps and then minimum fps).
-    // Example value: "(10500,26623),(15000,26623),(30000,30000)"
-    static const char KEY_SUPPORTED_PREVIEW_FPS_RANGE[];
-    // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in
-    // frameworks/av/include/camera/Camera.h. The default is
-    // PIXEL_FORMAT_YUV420SP. Example value: "yuv420sp" or PIXEL_FORMAT_XXX
-    // constants. Read/write.
-    static const char KEY_PREVIEW_FORMAT[];
-    // Supported image formats for preview frames.
-    // Example value: "yuv420sp,yuv422i-yuyv". Read only.
-    static const char KEY_SUPPORTED_PREVIEW_FORMATS[];
-    // Number of preview frames per second. This is the target frame rate. The
-    // actual frame rate depends on the driver.
-    // Example value: "15". Read/write.
-    static const char KEY_PREVIEW_FRAME_RATE[];
-    // Supported number of preview frames per second.
-    // Example value: "24,15,10". Read.
-    static const char KEY_SUPPORTED_PREVIEW_FRAME_RATES[];
-    // The dimensions for captured pictures in pixels (width x height).
-    // Example value: "1024x768". Read/write.
-    static const char KEY_PICTURE_SIZE[];
-    // Supported dimensions for captured pictures in pixels.
-    // Example value: "2048x1536,1024x768". Read only.
-    static const char KEY_SUPPORTED_PICTURE_SIZES[];
-    // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE
-    // in frameworks/base/include/camera/Camera.h.
-    // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write.
-    static const char KEY_PICTURE_FORMAT[];
-    // Supported image formats for captured pictures.
-    // Example value: "jpeg,rgb565". Read only.
-    static const char KEY_SUPPORTED_PICTURE_FORMATS[];
-    // The width (in pixels) of EXIF thumbnail in Jpeg picture.
-    // Example value: "512". Read/write.
-    static const char KEY_JPEG_THUMBNAIL_WIDTH[];
-    // The height (in pixels) of EXIF thumbnail in Jpeg picture.
-    // Example value: "384". Read/write.
-    static const char KEY_JPEG_THUMBNAIL_HEIGHT[];
-    // Supported EXIF thumbnail sizes (width x height). 0x0 means not thumbnail
-    // in EXIF.
-    // Example value: "512x384,320x240,0x0". Read only.
-    static const char KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[];
-    // The quality of the EXIF thumbnail in Jpeg picture. The range is 1 to 100,
-    // with 100 being the best.
-    // Example value: "90". Read/write.
-    static const char KEY_JPEG_THUMBNAIL_QUALITY[];
-    // Jpeg quality of captured picture. The range is 1 to 100, with 100 being
-    // the best.
-    // Example value: "90". Read/write.
-    static const char KEY_JPEG_QUALITY[];
-    // The rotation angle in degrees relative to the orientation of the camera.
-    // This affects the pictures returned from CAMERA_MSG_COMPRESSED_IMAGE. The
-    // camera driver may set orientation in the EXIF header without rotating the
-    // picture. Or the driver may rotate the picture and the EXIF thumbnail. If
-    // the Jpeg picture is rotated, the orientation in the EXIF header will be
-    // missing or 1 (row #0 is top and column #0 is left side).
-    //
-    // Note that the JPEG pictures of front-facing cameras are not mirrored
-    // as in preview display.
-    //
-    // For example, suppose the natural orientation of the device is portrait.
-    // The device is rotated 270 degrees clockwise, so the device orientation is
-    // 270. Suppose a back-facing camera sensor is mounted in landscape and the
-    // top side of the camera sensor is aligned with the right edge of the
-    // display in natural orientation. So the camera orientation is 90. The
-    // rotation should be set to 0 (270 + 90).
-    //
-    // Example value: "0" or "90" or "180" or "270". Write only.
-    static const char KEY_ROTATION[];
-    // GPS latitude coordinate. GPSLatitude and GPSLatitudeRef will be stored in
-    // JPEG EXIF header.
-    // Example value: "25.032146" or "-33.462809". Write only.
-    static const char KEY_GPS_LATITUDE[];
-    // GPS longitude coordinate. GPSLongitude and GPSLongitudeRef will be stored
-    // in JPEG EXIF header.
-    // Example value: "121.564448" or "-70.660286". Write only.
-    static const char KEY_GPS_LONGITUDE[];
-    // GPS altitude. GPSAltitude and GPSAltitudeRef will be stored in JPEG EXIF
-    // header.
-    // Example value: "21.0" or "-5". Write only.
-    static const char KEY_GPS_ALTITUDE[];
-    // GPS timestamp (UTC in seconds since January 1, 1970). This should be
-    // stored in JPEG EXIF header.
-    // Example value: "1251192757". Write only.
-    static const char KEY_GPS_TIMESTAMP[];
-    // GPS Processing Method
-    // Example value: "GPS" or "NETWORK". Write only.
-    static const char KEY_GPS_PROCESSING_METHOD[];
-    // Current white balance setting.
-    // Example value: "auto" or WHITE_BALANCE_XXX constants. Read/write.
-    static const char KEY_WHITE_BALANCE[];
-    // Supported white balance settings.
-    // Example value: "auto,incandescent,daylight". Read only.
-    static const char KEY_SUPPORTED_WHITE_BALANCE[];
-    // Current color effect setting.
-    // Example value: "none" or EFFECT_XXX constants. Read/write.
-    static const char KEY_EFFECT[];
-    // Supported color effect settings.
-    // Example value: "none,mono,sepia". Read only.
-    static const char KEY_SUPPORTED_EFFECTS[];
-    // Current antibanding setting.
-    // Example value: "auto" or ANTIBANDING_XXX constants. Read/write.
-    static const char KEY_ANTIBANDING[];
-    // Supported antibanding settings.
-    // Example value: "auto,50hz,60hz,off". Read only.
-    static const char KEY_SUPPORTED_ANTIBANDING[];
-    // Current scene mode.
-    // Example value: "auto" or SCENE_MODE_XXX constants. Read/write.
-    static const char KEY_SCENE_MODE[];
-    // Supported scene mode settings.
-    // Example value: "auto,night,fireworks". Read only.
-    static const char KEY_SUPPORTED_SCENE_MODES[];
-    // Current flash mode.
-    // Example value: "auto" or FLASH_MODE_XXX constants. Read/write.
-    static const char KEY_FLASH_MODE[];
-    // Supported flash modes.
-    // Example value: "auto,on,off". Read only.
-    static const char KEY_SUPPORTED_FLASH_MODES[];
-    // Current focus mode. This will not be empty. Applications should call
-    // CameraHardwareInterface.autoFocus to start the focus if focus mode is
-    // FOCUS_MODE_AUTO or FOCUS_MODE_MACRO.
-    // Example value: "auto" or FOCUS_MODE_XXX constants. Read/write.
-    static const char KEY_FOCUS_MODE[];
-    // Supported focus modes.
-    // Example value: "auto,macro,fixed". Read only.
-    static const char KEY_SUPPORTED_FOCUS_MODES[];
-    // The maximum number of focus areas supported. This is the maximum length
-    // of KEY_FOCUS_AREAS.
-    // Example value: "0" or "2". Read only.
-    static const char KEY_MAX_NUM_FOCUS_AREAS[];
-    // Current focus areas.
-    //
-    // Before accessing this parameter, apps should check
-    // KEY_MAX_NUM_FOCUS_AREAS first to know the maximum number of focus areas
-    // first. If the value is 0, focus area is not supported.
-    //
-    // Each focus area is a five-element int array. The first four elements are
-    // the rectangle of the area (left, top, right, bottom). The direction is
-    // relative to the sensor orientation, that is, what the sensor sees. The
-    // direction is not affected by the rotation or mirroring of
-    // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates range from -1000 to 1000.
-    // (-1000,-1000) is the upper left point. (1000, 1000) is the lower right
-    // point. The width and height of focus areas cannot be 0 or negative.
-    //
-    // The fifth element is the weight. Values for weight must range from 1 to
-    // 1000.  The weight should be interpreted as a per-pixel weight - all
-    // pixels in the area have the specified weight. This means a small area
-    // with the same weight as a larger area will have less influence on the
-    // focusing than the larger area. Focus areas can partially overlap and the
-    // driver will add the weights in the overlap region.
-    //
-    // A special case of single focus area (0,0,0,0,0) means driver to decide
-    // the focus area. For example, the driver may use more signals to decide
-    // focus areas and change them dynamically. Apps can set (0,0,0,0,0) if they
-    // want the driver to decide focus areas.
-    //
-    // Focus areas are relative to the current field of view (KEY_ZOOM). No
-    // matter what the zoom level is, (-1000,-1000) represents the top of the
-    // currently visible camera frame. The focus area cannot be set to be
-    // outside the current field of view, even when using zoom.
-    //
-    // Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO,
-    // FOCUS_MODE_MACRO, FOCUS_MODE_CONTINUOUS_VIDEO, or
-    // FOCUS_MODE_CONTINUOUS_PICTURE.
-    // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
-    static const char KEY_FOCUS_AREAS[];
-    // Focal length in millimeter.
-    // Example value: "4.31". Read only.
-    static const char KEY_FOCAL_LENGTH[];
-    // Horizontal angle of view in degrees.
-    // Example value: "54.8". Read only.
-    static const char KEY_HORIZONTAL_VIEW_ANGLE[];
-    // Vertical angle of view in degrees.
-    // Example value: "42.5". Read only.
-    static const char KEY_VERTICAL_VIEW_ANGLE[];
-    // Exposure compensation index. 0 means exposure is not adjusted.
-    // Example value: "-5" or "5". Read/write.
-    static const char KEY_EXPOSURE_COMPENSATION[];
-    // The maximum exposure compensation index (>=0).
-    // Example value: "6". Read only.
-    static const char KEY_MAX_EXPOSURE_COMPENSATION[];
-    // The minimum exposure compensation index (<=0).
-    // Example value: "-6". Read only.
-    static const char KEY_MIN_EXPOSURE_COMPENSATION[];
-    // The exposure compensation step. Exposure compensation index multiply by
-    // step eqals to EV. Ex: if exposure compensation index is -6 and step is
-    // 0.3333, EV is -2.
-    // Example value: "0.333333333" or "0.5". Read only.
-    static const char KEY_EXPOSURE_COMPENSATION_STEP[];
-    // The state of the auto-exposure lock. "true" means that
-    // auto-exposure is locked to its current value and will not
-    // change. "false" means the auto-exposure routine is free to
-    // change exposure values. If auto-exposure is already locked,
-    // setting this to true again has no effect (the driver will not
-    // recalculate exposure values). Changing exposure compensation
-    // settings will still affect the exposure settings while
-    // auto-exposure is locked. Stopping preview or taking a still
-    // image will not change the lock. In conjunction with
-    // exposure compensation, this allows for capturing multi-exposure
-    // brackets with known relative exposure values. Locking
-    // auto-exposure after open but before the first call to
-    // startPreview may result in severely over- or under-exposed
-    // images.  The driver will not change the AE lock after
-    // auto-focus completes.
-    static const char KEY_AUTO_EXPOSURE_LOCK[];
-    // Whether locking the auto-exposure is supported. "true" means it is, and
-    // "false" or this key not existing means it is not supported.
-    static const char KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[];
-    // The state of the auto-white balance lock. "true" means that
-    // auto-white balance is locked to its current value and will not
-    // change. "false" means the auto-white balance routine is free to
-    // change white balance values. If auto-white balance is already
-    // locked, setting this to true again has no effect (the driver
-    // will not recalculate white balance values). Stopping preview or
-    // taking a still image will not change the lock. In conjunction
-    // with exposure compensation, this allows for capturing
-    // multi-exposure brackets with fixed white balance. Locking
-    // auto-white balance after open but before the first call to
-    // startPreview may result in severely incorrect color.  The
-    // driver will not change the AWB lock after auto-focus
-    // completes.
-    static const char KEY_AUTO_WHITEBALANCE_LOCK[];
-    // Whether locking the auto-white balance is supported. "true"
-    // means it is, and "false" or this key not existing means it is
-    // not supported.
-    static const char KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[];
-
-    // The maximum number of metering areas supported. This is the maximum
-    // length of KEY_METERING_AREAS.
-    // Example value: "0" or "2". Read only.
-    static const char KEY_MAX_NUM_METERING_AREAS[];
-    // Current metering areas. Camera driver uses these areas to decide
-    // exposure.
-    //
-    // Before accessing this parameter, apps should check
-    // KEY_MAX_NUM_METERING_AREAS first to know the maximum number of metering
-    // areas first. If the value is 0, metering area is not supported.
-    //
-    // Each metering area is a rectangle with specified weight. The direction is
-    // relative to the sensor orientation, that is, what the sensor sees. The
-    // direction is not affected by the rotation or mirroring of
-    // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates of the rectangle range
-    // from -1000 to 1000. (-1000, -1000) is the upper left point. (1000, 1000)
-    // is the lower right point. The width and height of metering areas cannot
-    // be 0 or negative.
-    //
-    // The fifth element is the weight. Values for weight must range from 1 to
-    // 1000.  The weight should be interpreted as a per-pixel weight - all
-    // pixels in the area have the specified weight. This means a small area
-    // with the same weight as a larger area will have less influence on the
-    // metering than the larger area. Metering areas can partially overlap and
-    // the driver will add the weights in the overlap region.
-    //
-    // A special case of all-zero single metering area means driver to decide
-    // the metering area. For example, the driver may use more signals to decide
-    // metering areas and change them dynamically. Apps can set all-zero if they
-    // want the driver to decide metering areas.
-    //
-    // Metering areas are relative to the current field of view (KEY_ZOOM).
-    // No matter what the zoom level is, (-1000,-1000) represents the top of the
-    // currently visible camera frame. The metering area cannot be set to be
-    // outside the current field of view, even when using zoom.
-    //
-    // No matter what metering areas are, the final exposure are compensated
-    // by KEY_EXPOSURE_COMPENSATION.
-    // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
-    static const char KEY_METERING_AREAS[];
-    // Current zoom value.
-    // Example value: "0" or "6". Read/write.
-    static const char KEY_ZOOM[];
-    // Maximum zoom value.
-    // Example value: "6". Read only.
-    static const char KEY_MAX_ZOOM[];
-    // The zoom ratios of all zoom values. The zoom ratio is in 1/100
-    // increments. Ex: a zoom of 3.2x is returned as 320. The number of list
-    // elements is KEY_MAX_ZOOM + 1. The first element is always 100. The last
-    // element is the zoom ratio of zoom value KEY_MAX_ZOOM.
-    // Example value: "100,150,200,250,300,350,400". Read only.
-    static const char KEY_ZOOM_RATIOS[];
-    // Whether zoom is supported. Zoom is supported if the value is "true". Zoom
-    // is not supported if the value is not "true" or the key does not exist.
-    // Example value: "true". Read only.
-    static const char KEY_ZOOM_SUPPORTED[];
-    // Whether if smooth zoom is supported. Smooth zoom is supported if the
-    // value is "true". It is not supported if the value is not "true" or the
-    // key does not exist.
-    // See CAMERA_CMD_START_SMOOTH_ZOOM, CAMERA_CMD_STOP_SMOOTH_ZOOM, and
-    // CAMERA_MSG_ZOOM in frameworks/base/include/camera/Camera.h.
-    // Example value: "true". Read only.
-    static const char KEY_SMOOTH_ZOOM_SUPPORTED[];
-
-    // The distances (in meters) from the camera to where an object appears to
-    // be in focus. The object is sharpest at the optimal focus distance. The
-    // depth of field is the far focus distance minus near focus distance.
-    //
-    // Focus distances may change after starting auto focus, canceling auto
-    // focus, or starting the preview. Applications can read this anytime to get
-    // the latest focus distances. If the focus mode is FOCUS_MODE_CONTINUOUS,
-    // focus distances may change from time to time.
-    //
-    // This is intended to estimate the distance between the camera and the
-    // subject. After autofocus, the subject distance may be within near and far
-    // focus distance. However, the precision depends on the camera hardware,
-    // autofocus algorithm, the focus area, and the scene. The error can be
-    // large and it should be only used as a reference.
-    //
-    // Far focus distance > optimal focus distance > near focus distance. If
-    // the far focus distance is infinity, the value should be "Infinity" (case
-    // sensitive). The format is three float values separated by commas. The
-    // first is near focus distance. The second is optimal focus distance. The
-    // third is far focus distance.
-    // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only.
-    static const char KEY_FOCUS_DISTANCES[];
-
-    // The current dimensions in pixels (width x height) for video frames.
-    // The width and height must be one of the supported sizes retrieved
-    // via KEY_SUPPORTED_VIDEO_SIZES.
-    // Example value: "1280x720". Read/write.
-    static const char KEY_VIDEO_SIZE[];
-    // A list of the supported dimensions in pixels (width x height)
-    // for video frames. See CAMERA_MSG_VIDEO_FRAME for details in
-    // frameworks/base/include/camera/Camera.h.
-    // Example: "176x144,1280x720". Read only.
-    static const char KEY_SUPPORTED_VIDEO_SIZES[];
-
-    // The maximum number of detected faces supported by hardware face
-    // detection. If the value is 0, hardware face detection is not supported.
-    // Example: "5". Read only
-    static const char KEY_MAX_NUM_DETECTED_FACES_HW[];
-
-    // The maximum number of detected faces supported by software face
-    // detection. If the value is 0, software face detection is not supported.
-    // Example: "5". Read only
-    static const char KEY_MAX_NUM_DETECTED_FACES_SW[];
-
-    // Preferred preview frame size in pixels for video recording.
-    // The width and height must be one of the supported sizes retrieved
-    // via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when
-    // getSupportedVideoSizes() does not return an empty Vector of Size.
-    // Camcorder applications are recommended to set the preview size
-    // to a value that is not larger than the preferred preview size.
-    // In other words, the product of the width and height of the
-    // preview size should not be larger than that of the preferred
-    // preview size. In addition, we recommend to choos a preview size
-    // that has the same aspect ratio as the resolution of video to be
-    // recorded.
-    // Example value: "800x600". Read only.
-    static const char KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[];
-
-    // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in
-    // frameworks/base/include/camera/Camera.h.
-    // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
-    static const char KEY_VIDEO_FRAME_FORMAT[];
-
-    // Sets the hint of the recording mode. If this is true, MediaRecorder.start
-    // may be faster or has less glitches. This should be called before starting
-    // the preview for the best result. But it is allowed to change the hint
-    // while the preview is active. The default value is false.
-    //
-    // The apps can still call Camera.takePicture when the hint is true. The
-    // apps can call MediaRecorder.start when the hint is false. But the
-    // performance may be worse.
-    // Example value: "true" or "false". Read/write.
-    static const char KEY_RECORDING_HINT[];
-
-    // Returns true if video snapshot is supported. That is, applications
-    // can call Camera.takePicture during recording. Applications do not need to
-    // call Camera.startPreview after taking a picture. The preview will be
-    // still active. Other than that, taking a picture during recording is
-    // identical to taking a picture normally. All settings and methods related
-    // to takePicture work identically. Ex: KEY_PICTURE_SIZE,
-    // KEY_SUPPORTED_PICTURE_SIZES, KEY_JPEG_QUALITY, KEY_ROTATION, and etc.
-    // The picture will have an EXIF header. FLASH_MODE_AUTO and FLASH_MODE_ON
-    // also still work, but the video will record the flash.
-    //
-    // Applications can set shutter callback as null to avoid the shutter
-    // sound. It is also recommended to set raw picture and post view callbacks
-    // to null to avoid the interrupt of preview display.
-    //
-    // Field-of-view of the recorded video may be different from that of the
-    // captured pictures.
-    // Example value: "true" or "false". Read only.
-    static const char KEY_VIDEO_SNAPSHOT_SUPPORTED[];
-
-    // The state of the video stabilization. If set to true, both the
-    // preview stream and the recorded video stream are stabilized by
-    // the camera. Only valid to set if KEY_VIDEO_STABILIZATION_SUPPORTED is
-    // set to true.
-    //
-    // The value of this key can be changed any time the camera is
-    // open. If preview or recording is active, it is acceptable for
-    // there to be a slight video glitch when video stabilization is
-    // toggled on and off.
-    //
-    // This only stabilizes video streams (between-frames stabilization), and
-    // has no effect on still image capture.
-    static const char KEY_VIDEO_STABILIZATION[];
-
-    // Returns true if video stabilization is supported. That is, applications
-    // can set KEY_VIDEO_STABILIZATION to true and have a stabilized preview
-    // stream and record stabilized videos.
-    static const char KEY_VIDEO_STABILIZATION_SUPPORTED[];
-
-    // Supported modes for special effects with light.
-    // Example values: "lowlight,hdr".
-    static const char KEY_LIGHTFX[];
-
-    // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
-    static const char TRUE[];
-    static const char FALSE[];
-
-    // Value for KEY_FOCUS_DISTANCES.
-    static const char FOCUS_DISTANCE_INFINITY[];
-
-    // Values for white balance settings.
-    static const char WHITE_BALANCE_AUTO[];
-    static const char WHITE_BALANCE_INCANDESCENT[];
-    static const char WHITE_BALANCE_FLUORESCENT[];
-    static const char WHITE_BALANCE_WARM_FLUORESCENT[];
-    static const char WHITE_BALANCE_DAYLIGHT[];
-    static const char WHITE_BALANCE_CLOUDY_DAYLIGHT[];
-    static const char WHITE_BALANCE_TWILIGHT[];
-    static const char WHITE_BALANCE_SHADE[];
-
-    // Values for effect settings.
-    static const char EFFECT_NONE[];
-    static const char EFFECT_MONO[];
-    static const char EFFECT_NEGATIVE[];
-    static const char EFFECT_SOLARIZE[];
-    static const char EFFECT_SEPIA[];
-    static const char EFFECT_POSTERIZE[];
-    static const char EFFECT_WHITEBOARD[];
-    static const char EFFECT_BLACKBOARD[];
-    static const char EFFECT_AQUA[];
-
-    // Values for antibanding settings.
-    static const char ANTIBANDING_AUTO[];
-    static const char ANTIBANDING_50HZ[];
-    static const char ANTIBANDING_60HZ[];
-    static const char ANTIBANDING_OFF[];
-
-    // Values for flash mode settings.
-    // Flash will not be fired.
-    static const char FLASH_MODE_OFF[];
-    // Flash will be fired automatically when required. The flash may be fired
-    // during preview, auto-focus, or snapshot depending on the driver.
-    static const char FLASH_MODE_AUTO[];
-    // Flash will always be fired during snapshot. The flash may also be
-    // fired during preview or auto-focus depending on the driver.
-    static const char FLASH_MODE_ON[];
-    // Flash will be fired in red-eye reduction mode.
-    static const char FLASH_MODE_RED_EYE[];
-    // Constant emission of light during preview, auto-focus and snapshot.
-    // This can also be used for video recording.
-    static const char FLASH_MODE_TORCH[];
-
-    // Values for scene mode settings.
-    static const char SCENE_MODE_AUTO[];
-    static const char SCENE_MODE_ACTION[];
-    static const char SCENE_MODE_PORTRAIT[];
-    static const char SCENE_MODE_LANDSCAPE[];
-    static const char SCENE_MODE_NIGHT[];
-    static const char SCENE_MODE_NIGHT_PORTRAIT[];
-    static const char SCENE_MODE_THEATRE[];
-    static const char SCENE_MODE_BEACH[];
-    static const char SCENE_MODE_SNOW[];
-    static const char SCENE_MODE_SUNSET[];
-    static const char SCENE_MODE_STEADYPHOTO[];
-    static const char SCENE_MODE_FIREWORKS[];
-    static const char SCENE_MODE_SPORTS[];
-    static const char SCENE_MODE_PARTY[];
-    static const char SCENE_MODE_CANDLELIGHT[];
-    // Applications are looking for a barcode. Camera driver will be optimized
-    // for barcode reading.
-    static const char SCENE_MODE_BARCODE[];
-    // A high-dynamic range mode. In this mode, the HAL module will use a
-    // capture strategy that extends the dynamic range of the captured
-    // image in some fashion. Only the final image is returned.
-    static const char SCENE_MODE_HDR[];
-
-    // Pixel color formats for KEY_PREVIEW_FORMAT, KEY_PICTURE_FORMAT,
-    // and KEY_VIDEO_FRAME_FORMAT
-    static const char PIXEL_FORMAT_YUV422SP[];
-    static const char PIXEL_FORMAT_YUV420SP[]; // NV21
-    static const char PIXEL_FORMAT_YUV422I[]; // YUY2
-    static const char PIXEL_FORMAT_YUV420P[]; // YV12
-    static const char PIXEL_FORMAT_RGB565[];
-    static const char PIXEL_FORMAT_RGBA8888[];
-    static const char PIXEL_FORMAT_JPEG[];
-    // Raw bayer format used for images, which is 10 bit precision samples
-    // stored in 16 bit words. The filter pattern is RGGB.
-    static const char PIXEL_FORMAT_BAYER_RGGB[];
-    // Pixel format is not known to the framework
-    static const char PIXEL_FORMAT_ANDROID_OPAQUE[];
-
-    // Values for focus mode settings.
-    // Auto-focus mode. Applications should call
-    // CameraHardwareInterface.autoFocus to start the focus in this mode.
-    static const char FOCUS_MODE_AUTO[];
-    // Focus is set at infinity. Applications should not call
-    // CameraHardwareInterface.autoFocus in this mode.
-    static const char FOCUS_MODE_INFINITY[];
-    // Macro (close-up) focus mode. Applications should call
-    // CameraHardwareInterface.autoFocus to start the focus in this mode.
-    static const char FOCUS_MODE_MACRO[];
-    // Focus is fixed. The camera is always in this mode if the focus is not
-    // adjustable. If the camera has auto-focus, this mode can fix the
-    // focus, which is usually at hyperfocal distance. Applications should
-    // not call CameraHardwareInterface.autoFocus in this mode.
-    static const char FOCUS_MODE_FIXED[];
-    // Extended depth of field (EDOF). Focusing is done digitally and
-    // continuously. Applications should not call
-    // CameraHardwareInterface.autoFocus in this mode.
-    static const char FOCUS_MODE_EDOF[];
-    // Continuous auto focus mode intended for video recording. The camera
-    // continuously tries to focus. This is the best choice for video
-    // recording because the focus changes smoothly . Applications still can
-    // call CameraHardwareInterface.takePicture in this mode but the subject may
-    // not be in focus. Auto focus starts when the parameter is set.
-    //
-    // Applications can call CameraHardwareInterface.autoFocus in this mode. The
-    // focus callback will immediately return with a boolean that indicates
-    // whether the focus is sharp or not. The focus position is locked after
-    // autoFocus call. If applications want to resume the continuous focus,
-    // cancelAutoFocus must be called. Restarting the preview will not resume
-    // the continuous autofocus. To stop continuous focus, applications should
-    // change the focus mode to other modes.
-    static const char FOCUS_MODE_CONTINUOUS_VIDEO[];
-    // Continuous auto focus mode intended for taking pictures. The camera
-    // continuously tries to focus. The speed of focus change is more aggressive
-    // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is
-    // set.
-    //
-    // Applications can call CameraHardwareInterface.autoFocus in this mode. If
-    // the autofocus is in the middle of scanning, the focus callback will
-    // return when it completes. If the autofocus is not scanning, focus
-    // callback will immediately return with a boolean that indicates whether
-    // the focus is sharp or not. The apps can then decide if they want to take
-    // a picture immediately or to change the focus mode to auto, and run a full
-    // autofocus cycle. The focus position is locked after autoFocus call. If
-    // applications want to resume the continuous focus, cancelAutoFocus must be
-    // called. Restarting the preview will not resume the continuous autofocus.
-    // To stop continuous focus, applications should change the focus mode to
-    // other modes.
-    static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
-
-    // Values for light special effects
-    // Low-light enhancement mode
-    static const char LIGHTFX_LOWLIGHT[];
-    // High-dynamic range mode
-    static const char LIGHTFX_HDR[];
-
-    /**
-     * Returns the the supported preview formats as an enum given in graphics.h
-     * corrsponding to the format given in the input string or -1 if no such
-     * conversion exists.
-     */
-    static int previewFormatToEnum(const char* format);
-
-private:
-    DefaultKeyedVector<String8,String8>    mMap;
-};
-
-};
-};
-};
-};
-};
-}; // namespace
-
-#endif
diff --git a/camera/common/1.0/default/include/Exif.h b/camera/common/1.0/default/include/Exif.h
deleted file mode 100644
index dc31679..0000000
--- a/camera/common/1.0/default/include/Exif.h
+++ /dev/null
@@ -1,256 +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_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
-#define ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
-
-#include "CameraMetadata.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-
-// This is based on the original ChromeOS ARC implementation of a V4L2 HAL
-
-// ExifUtils can generate APP1 segment with tags which caller set. ExifUtils can
-// also add a thumbnail in the APP1 segment if thumbnail size is specified.
-// ExifUtils can be reused with different images by calling initialize().
-//
-// Example of using this class :
-//  std::unique_ptr<ExifUtils> utils(ExifUtils::Create());
-//  utils->initialize();
-//  ...
-//  // Call ExifUtils functions to set Exif tags.
-//  ...
-//  utils->GenerateApp1(thumbnail_buffer, thumbnail_size);
-//  unsigned int app1Length = utils->GetApp1Length();
-//  uint8_t* app1Buffer = new uint8_t[app1Length];
-//  memcpy(app1Buffer, utils->GetApp1Buffer(), app1Length);
-class ExifUtils {
-
- public:
-    virtual ~ExifUtils();
-
-    static ExifUtils* create();
-
-    // Initialize() can be called multiple times. The setting of Exif tags will be
-    // cleared.
-    virtual bool initialize() = 0;
-
-    // Set all known fields from a metadata structure
-    virtual bool setFromMetadata(const CameraMetadata& metadata,
-                                 const size_t imageWidth,
-                                 const size_t imageHeight) = 0;
-
-    // Sets the len aperture.
-    // Returns false if memory allocation fails.
-    virtual bool setAperture(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the value of brightness.
-    // Returns false if memory allocation fails.
-    virtual bool setBrightness(int32_t numerator, int32_t denominator) = 0;
-
-    // Sets the color space.
-    // Returns false if memory allocation fails.
-    virtual bool setColorSpace(uint16_t color_space) = 0;
-
-    // Sets the information to compressed data.
-    // Returns false if memory allocation fails.
-    virtual bool setComponentsConfiguration(const std::string& components_configuration) = 0;
-
-    // Sets the compression scheme used for the image data.
-    // Returns false if memory allocation fails.
-    virtual bool setCompression(uint16_t compression) = 0;
-
-    // Sets image contrast.
-    // Returns false if memory allocation fails.
-    virtual bool setContrast(uint16_t contrast) = 0;
-
-    // Sets the date and time of image last modified. It takes local time. The
-    // name of the tag is DateTime in IFD0.
-    // Returns false if memory allocation fails.
-    virtual bool setDateTime(const struct tm& t) = 0;
-
-    // Sets the image description.
-    // Returns false if memory allocation fails.
-    virtual bool setDescription(const std::string& description) = 0;
-
-    // Sets the digital zoom ratio. If the numerator is 0, it means digital zoom
-    // was not used.
-    // Returns false if memory allocation fails.
-    virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the exposure bias.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureBias(int32_t numerator, int32_t denominator) = 0;
-
-    // Sets the exposure mode set when the image was shot.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureMode(uint16_t exposure_mode) = 0;
-
-    // Sets the program used by the camera to set exposure when the picture is
-    // taken.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureProgram(uint16_t exposure_program) = 0;
-
-    // Sets the exposure time, given in seconds.
-    // Returns false if memory allocation fails.
-    virtual bool setExposureTime(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the status of flash.
-    // Returns false if memory allocation fails.
-    virtual bool setFlash(uint16_t flash) = 0;
-
-    // Sets the F number.
-    // Returns false if memory allocation fails.
-    virtual bool setFNumber(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the focal length of lens used to take the image in millimeters.
-    // Returns false if memory allocation fails.
-    virtual bool setFocalLength(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the degree of overall image gain adjustment.
-    // Returns false if memory allocation fails.
-    virtual bool setGainControl(uint16_t gain_control) = 0;
-
-    // Sets the altitude in meters.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsAltitude(double altitude) = 0;
-
-    // Sets the latitude with degrees minutes seconds format.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsLatitude(double latitude) = 0;
-
-    // Sets the longitude with degrees minutes seconds format.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsLongitude(double longitude) = 0;
-
-    // Sets GPS processing method.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsProcessingMethod(const std::string& method) = 0;
-
-    // Sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
-    // Returns false if memory allocation fails.
-    virtual bool setGpsTimestamp(const struct tm& t) = 0;
-
-    // Sets the height (number of rows) of main image.
-    // Returns false if memory allocation fails.
-    virtual bool setImageHeight(uint32_t length) = 0;
-
-    // Sets the width (number of columns) of main image.
-    // Returns false if memory allocation fails.
-    virtual bool setImageWidth(uint32_t width) = 0;
-
-    // Sets the ISO speed.
-    // Returns false if memory allocation fails.
-    virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings) = 0;
-
-    // Sets the kind of light source.
-    // Returns false if memory allocation fails.
-    virtual bool setLightSource(uint16_t light_source) = 0;
-
-    // Sets the smallest F number of the lens.
-    // Returns false if memory allocation fails.
-    virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the metering mode.
-    // Returns false if memory allocation fails.
-    virtual bool setMeteringMode(uint16_t metering_mode) = 0;
-
-    // Sets image orientation.
-    // Returns false if memory allocation fails.
-    virtual bool setOrientation(uint16_t orientation) = 0;
-
-    // Sets the unit for measuring XResolution and YResolution.
-    // Returns false if memory allocation fails.
-    virtual bool setResolutionUnit(uint16_t resolution_unit) = 0;
-
-    // Sets image saturation.
-    // Returns false if memory allocation fails.
-    virtual bool setSaturation(uint16_t saturation) = 0;
-
-    // Sets the type of scene that was shot.
-    // Returns false if memory allocation fails.
-    virtual bool setSceneCaptureType(uint16_t type) = 0;
-
-    // Sets image sharpness.
-    // Returns false if memory allocation fails.
-    virtual bool setSharpness(uint16_t sharpness) = 0;
-
-    // Sets the shutter speed.
-    // Returns false if memory allocation fails.
-    virtual bool setShutterSpeed(int32_t numerator, int32_t denominator) = 0;
-
-    // Sets the distance to the subject, given in meters.
-    // Returns false if memory allocation fails.
-    virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the fractions of seconds for the <DateTime> tag.
-    // Returns false if memory allocation fails.
-    virtual bool setSubsecTime(const std::string& subsec_time) = 0;
-
-    // Sets the white balance mode set when the image was shot.
-    // Returns false if memory allocation fails.
-    virtual bool setWhiteBalance(uint16_t white_balance) = 0;
-
-    // Sets the number of pixels per resolution unit in the image width.
-    // Returns false if memory allocation fails.
-    virtual bool setXResolution(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the position of chrominance components in relation to the luminance
-    // component.
-    // Returns false if memory allocation fails.
-    virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning) = 0;
-
-    // Sets the number of pixels per resolution unit in the image length.
-    // Returns false if memory allocation fails.
-    virtual bool setYResolution(uint32_t numerator, uint32_t denominator) = 0;
-
-    // Sets the manufacturer of camera.
-    // Returns false if memory allocation fails.
-    virtual bool setMake(const std::string& make) = 0;
-
-    // Sets the model number of camera.
-    // Returns false if memory allocation fails.
-    virtual bool setModel(const std::string& model) = 0;
-
-    // Generates APP1 segment.
-    // Returns false if generating APP1 segment fails.
-    virtual bool generateApp1(const void* thumbnail_buffer, uint32_t size) = 0;
-
-    // Gets buffer of APP1 segment. This method must be called only after calling
-    // GenerateAPP1().
-    virtual const uint8_t* getApp1Buffer() = 0;
-
-    // Gets length of APP1 segment. This method must be called only after calling
-    // GenerateAPP1().
-    virtual unsigned int getApp1Length() = 0;
-};
-
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-
-#endif  // ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
diff --git a/camera/common/1.0/default/include/HandleImporter.h b/camera/common/1.0/default/include/HandleImporter.h
deleted file mode 100644
index 83fa755..0000000
--- a/camera/common/1.0/default/include/HandleImporter.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2017 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 CAMERA_COMMON_1_0_HANDLEIMPORTED_H
-#define CAMERA_COMMON_1_0_HANDLEIMPORTED_H
-
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <android/hardware/graphics/mapper/3.0/IMapper.h>
-#include <android/hardware/graphics/mapper/4.0/IMapper.h>
-#include <cutils/native_handle.h>
-#include <utils/Mutex.h>
-
-using android::hardware::graphics::mapper::V2_0::IMapper;
-using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-// Borrowed from graphics HAL. Use this until gralloc mapper HAL is working
-class HandleImporter {
-public:
-    HandleImporter();
-
-    // In IComposer, any buffer_handle_t is owned by the caller and we need to
-    // make a clone for hwcomposer2.  We also need to translate empty handle
-    // to nullptr.  This function does that, in-place.
-    bool importBuffer(buffer_handle_t& handle);
-    void freeBuffer(buffer_handle_t handle);
-    bool importFence(const native_handle_t* handle, int& fd) const;
-    void closeFence(int fd) const;
-
-    // Locks 1-D buffer. Assumes caller has waited for acquire fences.
-    void* lock(buffer_handle_t& buf, uint64_t cpuUsage, size_t size);
-
-    // Locks 2-D buffer. Assumes caller has waited for acquire fences.
-    void* lock(buffer_handle_t& buf, uint64_t cpuUsage, const IMapper::Rect& accessRegion);
-
-    // Assumes caller has waited for acquire fences.
-    YCbCrLayout lockYCbCr(buffer_handle_t& buf, uint64_t cpuUsage,
-                          const IMapper::Rect& accessRegion);
-
-    // Query the stride of the first plane in bytes.
-    status_t getMonoPlanarStrideBytes(buffer_handle_t& buf, uint32_t* stride /*out*/);
-
-    int unlock(buffer_handle_t& buf); // returns release fence
-
-    // Query Gralloc4 metadata
-    bool isSmpte2086Present(const buffer_handle_t& buf);
-    bool isSmpte2094_10Present(const buffer_handle_t& buf);
-    bool isSmpte2094_40Present(const buffer_handle_t& buf);
-
-private:
-    void initializeLocked();
-    void cleanup();
-
-    template<class M, class E>
-    bool importBufferInternal(const sp<M> mapper, buffer_handle_t& handle);
-    template<class M, class E>
-    YCbCrLayout lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
-            const IMapper::Rect& accessRegion);
-    template<class M, class E>
-    int unlockInternal(const sp<M> mapper, buffer_handle_t& buf);
-
-    Mutex mLock;
-    bool mInitialized;
-    sp<IMapper> mMapperV2;
-    sp<graphics::mapper::V3_0::IMapper> mMapperV3;
-    sp<graphics::mapper::V4_0::IMapper> mMapperV4;
-};
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-#endif // CAMERA_COMMON_1_0_HANDLEIMPORTED_H
diff --git a/camera/common/1.0/default/include/VendorTagDescriptor.h b/camera/common/1.0/default/include/VendorTagDescriptor.h
deleted file mode 100644
index 0f54db5..0000000
--- a/camera/common/1.0/default/include/VendorTagDescriptor.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2016 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 CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H
-#define CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H
-
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-#include <utils/RefBase.h>
-#include <system/camera_vendor_tags.h>
-
-#include <stdint.h>
-#include <unordered_map>
-
-namespace android {
-namespace hardware {
-namespace camera2 {
-namespace params {
-
-/**
- * VendorTagDescriptor objects are containers for the vendor tag
- * definitions provided, and are typically used to pass the vendor tag
- * information enumerated by the HAL to clients of the camera service.
- */
-class VendorTagDescriptor {
-    public:
-        virtual ~VendorTagDescriptor();
-
-        VendorTagDescriptor();
-        VendorTagDescriptor(const VendorTagDescriptor& src);
-        VendorTagDescriptor& operator=(const VendorTagDescriptor& rhs);
-
-        void copyFrom(const VendorTagDescriptor& src);
-
-        /**
-         * The following 'get*' methods implement the corresponding
-         * functions defined in
-         * system/media/camera/include/system/camera_vendor_tags.h
-         */
-
-        // Returns the number of vendor tags defined.
-        int getTagCount() const;
-
-        // Returns an array containing the id's of vendor tags defined.
-        void getTagArray(uint32_t* tagArray) const;
-
-        // Returns the section name string for a given vendor tag id.
-        const char* getSectionName(uint32_t tag) const;
-
-        // Returns the index in section vectors returned in getAllSectionNames()
-        // for a given vendor tag id. -1 if input tag does not exist.
-        ssize_t getSectionIndex(uint32_t tag) const;
-
-        // Returns the tag name string for a given vendor tag id.
-        const char* getTagName(uint32_t tag) const;
-
-        // Returns the tag type for a given vendor tag id.
-        int getTagType(uint32_t tag) const;
-
-        /**
-         * Convenience method to get a vector containing all vendor tag
-         * sections, or an empty vector if none are defined.
-         * The pointer is valid for the lifetime of the VendorTagDescriptor,
-         * or until copyFrom is invoked.
-         */
-        const SortedVector<String8>* getAllSectionNames() const;
-
-        /**
-         * Lookup the tag id for a given tag name and section.
-         *
-         * Returns OK on success, or a negative error code.
-         */
-        status_t lookupTag(const String8& name, const String8& section, /*out*/uint32_t* tag) const;
-
-        /**
-         * Dump the currently configured vendor tags to a file descriptor.
-         */
-        void dump(int fd, int verbosity, int indentation) const;
-
-    protected:
-        KeyedVector<String8, KeyedVector<String8, uint32_t>*> mReverseMapping;
-        KeyedVector<uint32_t, String8> mTagToNameMap;
-        KeyedVector<uint32_t, uint32_t> mTagToSectionMap; // Value is offset in mSections
-
-        std::unordered_map<uint32_t, int32_t> mTagToTypeMap;
-        SortedVector<String8> mSections;
-        // must be int32_t to be compatible with Parcel::writeInt32
-        int32_t mTagCount;
-
-        vendor_tag_ops mVendorOps;
-};
-} /* namespace params */
-} /* namespace camera2 */
-
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-/**
- * This version of VendorTagDescriptor must be stored in Android sp<>, and adds support for using it
- * as a global tag descriptor.
- *
- * It's a child class of the basic hardware::camera2::params::VendorTagDescriptor since basic
- * Parcelable objects cannot require being kept in an sp<> and still work with auto-generated AIDL
- * interface implementations.
- */
-class VendorTagDescriptor :
-            public ::android::hardware::camera2::params::VendorTagDescriptor,
-            public LightRefBase<VendorTagDescriptor> {
-
-  public:
-
-    /**
-     * Create a VendorTagDescriptor object from the given vendor_tag_ops_t
-     * struct.
-     *
-     * Returns OK on success, or a negative error code.
-     */
-    static status_t createDescriptorFromOps(const vendor_tag_ops_t* vOps,
-            /*out*/
-            sp<VendorTagDescriptor>& descriptor);
-
-    /**
-     * Sets the global vendor tag descriptor to use for this process.
-     * Camera metadata operations that access vendor tags will use the
-     * vendor tag definitions set this way.
-     *
-     * Returns OK on success, or a negative error code.
-     */
-    static status_t setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc);
-
-    /**
-     * Returns the global vendor tag descriptor used by this process.
-     * This will contain NULL if no vendor tags are defined.
-     */
-    static sp<VendorTagDescriptor> getGlobalVendorTagDescriptor();
-
-    /**
-     * Clears the global vendor tag descriptor used by this process.
-     */
-    static void clearGlobalVendorTagDescriptor();
-
-};
-
-} /* namespace helper */
-} /* namespace V1_0 */
-} /* namespace common */
-} /* namespace camera */
-
-namespace camera2 {
-namespace params {
-
-class VendorTagDescriptorCache {
-   public:
-    typedef android::hardware::camera::common::V1_0::helper::VendorTagDescriptor
-        VendorTagDescriptor;
-    VendorTagDescriptorCache(){};
-    int32_t addVendorDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor> desc);
-
-    int32_t getVendorTagDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor>* desc /*out*/);
-
-    // Returns the number of vendor tags defined.
-    int getTagCount(metadata_vendor_id_t id) const;
-
-    // Returns an array containing the id's of vendor tags defined.
-    void getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const;
-
-    // Returns the section name string for a given vendor tag id.
-    const char* getSectionName(uint32_t tag, metadata_vendor_id_t id) const;
-
-    // Returns the tag name string for a given vendor tag id.
-    const char* getTagName(uint32_t tag, metadata_vendor_id_t id) const;
-
-    // Returns the tag type for a given vendor tag id.
-    int getTagType(uint32_t tag, metadata_vendor_id_t id) const;
-
-    /**
-     * Dump the currently configured vendor tags to a file descriptor.
-     */
-    void dump(int fd, int verbosity, int indentation) const;
-
-   protected:
-    std::unordered_map<metadata_vendor_id_t, sp<VendorTagDescriptor>> mVendorMap;
-    struct vendor_tag_cache_ops mVendorCacheOps;
-};
-
-} /* namespace params */
-} /* namespace camera2 */
-
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-class VendorTagDescriptorCache
-    : public ::android::hardware::camera2::params::VendorTagDescriptorCache,
-      public LightRefBase<VendorTagDescriptorCache> {
-   public:
-    /**
-     * Sets the global vendor tag descriptor cache to use for this process.
-     * Camera metadata operations that access vendor tags will use the
-     * vendor tag definitions set this way.
-     *
-     * Returns OK on success, or a negative error code.
-     */
-    static status_t setAsGlobalVendorTagCache(const sp<VendorTagDescriptorCache>& cache);
-
-    /**
-     * Returns the global vendor tag cache used by this process.
-     * This will contain NULL if no vendor tags are defined.
-     */
-    static sp<VendorTagDescriptorCache> getGlobalVendorTagCache();
-
-    /**
-     * Clears the global vendor tag cache used by this process.
-     */
-    static void clearGlobalVendorTagCache();
-};
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-#endif /* CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H */
diff --git a/camera/common/aidl/Android.bp b/camera/common/aidl/Android.bp
index 19de22d..4ffcfd9 100644
--- a/camera/common/aidl/Android.bp
+++ b/camera/common/aidl/Android.bp
@@ -11,6 +11,7 @@
     name: "android.hardware.camera.common",
     vendor_available: true,
     srcs: ["android/hardware/camera/common/*.aidl"],
+    frozen: true,
     stability: "vintf",
     backend: {
         cpp: {
@@ -19,11 +20,9 @@
         java: {
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
+        rust: {
+            enabled: true,
+        }
     },
     versions_with_info: [
         {
diff --git a/camera/common/default/Android.bp b/camera/common/default/Android.bp
new file mode 100644
index 0000000..e8c8f9d
--- /dev/null
+++ b/camera/common/default/Android.bp
@@ -0,0 +1,48 @@
+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_static {
+    name: "android.hardware.camera.common-helper",
+    vendor_available: true,
+    defaults: ["hidl_defaults"],
+    srcs: [
+        "CameraModule.cpp",
+        "CameraMetadata.cpp",
+        "CameraParameters.cpp",
+        "VendorTagDescriptor.cpp",
+        "HandleImporter.cpp",
+        "Exif.cpp",
+        "SimpleThread.cpp",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wextra",
+        "-Wall",
+    ],
+    shared_libs: [
+        "liblog",
+        "libgralloctypes",
+        "libhardware",
+        "libcamera_metadata",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.graphics.mapper@4.0",
+        "libexif",
+    ],
+    include_dirs: ["system/media/private/camera/include"],
+    export_include_dirs: ["include"],
+}
+
+// NOTE: Deprecated module kept for compatibility reasons.
+// Depend on "android.hardware.camera.common-helper" instead
+cc_library_static {
+    name: "android.hardware.camera.common@1.0-helper",
+    vendor_available: true,
+    whole_static_libs: ["android.hardware.camera.common-helper"],
+}
diff --git a/camera/common/default/CameraMetadata.cpp b/camera/common/default/CameraMetadata.cpp
new file mode 100644
index 0000000..ed56261
--- /dev/null
+++ b/camera/common/default/CameraMetadata.cpp
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2016 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_NDEBUG 0
+
+#define LOG_TAG "CamComm1.0-MD"
+#include <log/log.h>
+#include <utils/Errors.h>
+
+#include "CameraMetadata.h"
+#include "VendorTagDescriptor.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+#define ALIGN_TO(val, alignment) (((uintptr_t)(val) + ((alignment)-1)) & ~((alignment)-1))
+
+CameraMetadata::CameraMetadata() : mBuffer(NULL), mLocked(false) {}
+
+CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) : mLocked(false) {
+    mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
+}
+
+CameraMetadata::CameraMetadata(const CameraMetadata& other) : mLocked(false) {
+    mBuffer = clone_camera_metadata(other.mBuffer);
+}
+
+CameraMetadata::CameraMetadata(camera_metadata_t* buffer) : mBuffer(NULL), mLocked(false) {
+    acquire(buffer);
+}
+
+CameraMetadata& CameraMetadata::operator=(const CameraMetadata& other) {
+    return operator=(other.mBuffer);
+}
+
+CameraMetadata& CameraMetadata::operator=(const camera_metadata_t* buffer) {
+    if (mLocked) {
+        ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
+        return *this;
+    }
+
+    if (CC_LIKELY(buffer != mBuffer)) {
+        camera_metadata_t* newBuffer = clone_camera_metadata(buffer);
+        clear();
+        mBuffer = newBuffer;
+    }
+    return *this;
+}
+
+CameraMetadata::~CameraMetadata() {
+    mLocked = false;
+    clear();
+}
+
+const camera_metadata_t* CameraMetadata::getAndLock() const {
+    mLocked = true;
+    return mBuffer;
+}
+
+status_t CameraMetadata::unlock(const camera_metadata_t* buffer) const {
+    if (!mLocked) {
+        ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    if (buffer != mBuffer) {
+        ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    mLocked = false;
+    return OK;
+}
+
+camera_metadata_t* CameraMetadata::release() {
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return NULL;
+    }
+    camera_metadata_t* released = mBuffer;
+    mBuffer = NULL;
+    return released;
+}
+
+void CameraMetadata::clear() {
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return;
+    }
+    if (mBuffer) {
+        free_camera_metadata(mBuffer);
+        mBuffer = NULL;
+    }
+}
+
+void CameraMetadata::acquire(camera_metadata_t* buffer) {
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return;
+    }
+    clear();
+    mBuffer = buffer;
+
+    ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/ NULL) != OK,
+             "%s: Failed to validate metadata structure %p", __FUNCTION__, buffer);
+}
+
+void CameraMetadata::acquire(CameraMetadata& other) {
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return;
+    }
+    acquire(other.release());
+}
+
+status_t CameraMetadata::append(const CameraMetadata& other) {
+    return append(other.mBuffer);
+}
+
+status_t CameraMetadata::append(const camera_metadata_t* other) {
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    size_t extraEntries = get_camera_metadata_entry_count(other);
+    size_t extraData = get_camera_metadata_data_count(other);
+    resizeIfNeeded(extraEntries, extraData);
+
+    return append_camera_metadata(mBuffer, other);
+}
+
+size_t CameraMetadata::entryCount() const {
+    return (mBuffer == NULL) ? 0 : get_camera_metadata_entry_count(mBuffer);
+}
+
+bool CameraMetadata::isEmpty() const {
+    return entryCount() == 0;
+}
+
+status_t CameraMetadata::sort() {
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    return sort_camera_metadata(mBuffer);
+}
+
+status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
+    int tagType = get_local_camera_metadata_tag_type(tag, mBuffer);
+    if (CC_UNLIKELY(tagType == -1)) {
+        ALOGE("Update metadata entry: Unknown tag %d", tag);
+        return INVALID_OPERATION;
+    }
+    if (CC_UNLIKELY(tagType != expectedType)) {
+        ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
+              "got type %s data instead ",
+              get_local_camera_metadata_tag_name(tag, mBuffer), tag,
+              camera_metadata_type_names[tagType], camera_metadata_type_names[expectedType]);
+        return INVALID_OPERATION;
+    }
+    return OK;
+}
+
+status_t CameraMetadata::update(uint32_t tag, const int32_t* data, size_t data_count) {
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    if ((res = checkType(tag, TYPE_INT32)) != OK) {
+        return res;
+    }
+    return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const uint8_t* data, size_t data_count) {
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    if ((res = checkType(tag, TYPE_BYTE)) != OK) {
+        return res;
+    }
+    return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const float* data, size_t data_count) {
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    if ((res = checkType(tag, TYPE_FLOAT)) != OK) {
+        return res;
+    }
+    return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const int64_t* data, size_t data_count) {
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    if ((res = checkType(tag, TYPE_INT64)) != OK) {
+        return res;
+    }
+    return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const double* data, size_t data_count) {
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    if ((res = checkType(tag, TYPE_DOUBLE)) != OK) {
+        return res;
+    }
+    return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const camera_metadata_rational_t* data,
+                                size_t data_count) {
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    if ((res = checkType(tag, TYPE_RATIONAL)) != OK) {
+        return res;
+    }
+    return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const String8& string) {
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    if ((res = checkType(tag, TYPE_BYTE)) != OK) {
+        return res;
+    }
+    // string.size() doesn't count the null termination character.
+    return updateImpl(tag, (const void*)string.string(), string.size() + 1);
+}
+
+status_t CameraMetadata::update(const camera_metadata_ro_entry& entry) {
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    if ((res = checkType(entry.tag, entry.type)) != OK) {
+        return res;
+    }
+    return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
+}
+
+status_t CameraMetadata::updateImpl(uint32_t tag, const void* data, size_t data_count) {
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    int type = get_local_camera_metadata_tag_type(tag, mBuffer);
+    if (type == -1) {
+        ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
+        return BAD_VALUE;
+    }
+    // Safety check - ensure that data isn't pointing to this metadata, since
+    // that would get invalidated if a resize is needed
+    size_t bufferSize = get_camera_metadata_size(mBuffer);
+    uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
+    uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
+    if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
+        ALOGE("%s: Update attempted with data from the same metadata buffer!", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+
+    size_t data_size = calculate_camera_metadata_entry_data_size(type, data_count);
+
+    res = resizeIfNeeded(1, data_size);
+
+    if (res == OK) {
+        camera_metadata_entry_t entry;
+        res = find_camera_metadata_entry(mBuffer, tag, &entry);
+        if (res == NAME_NOT_FOUND) {
+            res = add_camera_metadata_entry(mBuffer, tag, data, data_count);
+        } else if (res == OK) {
+            res = update_camera_metadata_entry(mBuffer, entry.index, data, data_count, NULL);
+        }
+    }
+
+    if (res != OK) {
+        ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", __FUNCTION__,
+              get_local_camera_metadata_section_name(tag, mBuffer),
+              get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
+    }
+
+    IF_ALOGV() {
+        ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/ NULL) != OK,
+
+                 "%s: Failed to validate metadata structure after update %p", __FUNCTION__,
+                 mBuffer);
+    }
+
+    return res;
+}
+
+bool CameraMetadata::exists(uint32_t tag) const {
+    camera_metadata_ro_entry entry;
+    return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
+}
+
+camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
+    status_t res;
+    camera_metadata_entry entry;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        entry.count = 0;
+        return entry;
+    }
+    res = find_camera_metadata_entry(mBuffer, tag, &entry);
+    if (CC_UNLIKELY(res != OK)) {
+        entry.count = 0;
+        entry.data.u8 = NULL;
+    }
+    return entry;
+}
+
+camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
+    status_t res;
+    camera_metadata_ro_entry entry;
+    res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
+    if (CC_UNLIKELY(res != OK)) {
+        entry.count = 0;
+        entry.data.u8 = NULL;
+    }
+    return entry;
+}
+
+status_t CameraMetadata::erase(uint32_t tag) {
+    camera_metadata_entry_t entry;
+    status_t res;
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    res = find_camera_metadata_entry(mBuffer, tag, &entry);
+    if (res == NAME_NOT_FOUND) {
+        return OK;
+    } else if (res != OK) {
+        ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", __FUNCTION__,
+              get_local_camera_metadata_section_name(tag, mBuffer),
+              get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
+        return res;
+    }
+    res = delete_camera_metadata_entry(mBuffer, entry.index);
+    if (res != OK) {
+        ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", __FUNCTION__,
+              get_local_camera_metadata_section_name(tag, mBuffer),
+              get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
+    }
+    return res;
+}
+
+void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
+    dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
+}
+
+status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
+    if (mBuffer == NULL) {
+        mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
+        if (mBuffer == NULL) {
+            ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
+            return NO_MEMORY;
+        }
+    } else {
+        size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
+        size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
+        size_t newEntryCount = currentEntryCount + extraEntries;
+        newEntryCount = (newEntryCount > currentEntryCap) ? newEntryCount * 2 : currentEntryCap;
+
+        size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
+        size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
+        size_t newDataCount = currentDataCount + extraData;
+        newDataCount = (newDataCount > currentDataCap) ? newDataCount * 2 : currentDataCap;
+
+        if (newEntryCount > currentEntryCap || newDataCount > currentDataCap) {
+            camera_metadata_t* oldBuffer = mBuffer;
+            mBuffer = allocate_camera_metadata(newEntryCount, newDataCount);
+            if (mBuffer == NULL) {
+                ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
+                return NO_MEMORY;
+            }
+            append_camera_metadata(mBuffer, oldBuffer);
+            free_camera_metadata(oldBuffer);
+        }
+    }
+    return OK;
+}
+
+void CameraMetadata::swap(CameraMetadata& other) {
+    if (mLocked) {
+        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+        return;
+    } else if (other.mLocked) {
+        ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
+        return;
+    }
+
+    camera_metadata* thisBuf = mBuffer;
+    camera_metadata* otherBuf = other.mBuffer;
+
+    other.mBuffer = thisBuf;
+    mBuffer = otherBuf;
+}
+
+status_t CameraMetadata::getTagFromName(const char* name, const VendorTagDescriptor* vTags,
+                                        uint32_t* tag) {
+    if (name == nullptr || tag == nullptr) return BAD_VALUE;
+
+    size_t nameLength = strlen(name);
+
+    const SortedVector<String8>* vendorSections;
+    size_t vendorSectionCount = 0;
+
+    if (vTags != NULL) {
+        vendorSections = vTags->getAllSectionNames();
+        vendorSectionCount = vendorSections->size();
+    }
+
+    // First, find the section by the longest string match
+    const char* section = NULL;
+    size_t sectionIndex = 0;
+    size_t sectionLength = 0;
+    size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
+    for (size_t i = 0; i < totalSectionCount; ++i) {
+        const char* str = (i < ANDROID_SECTION_COUNT)
+                                  ? camera_metadata_section_names[i]
+                                  : (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
+
+        ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
+
+        if (strstr(name, str) == name) {  // name begins with the section name
+            size_t strLength = strlen(str);
+
+            ALOGV("%s: Name begins with section name", __FUNCTION__);
+
+            // section name is the longest we've found so far
+            if (section == NULL || sectionLength < strLength) {
+                section = str;
+                sectionIndex = i;
+                sectionLength = strLength;
+
+                ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
+            }
+        }
+    }
+
+    if (section == NULL) {
+        return NAME_NOT_FOUND;
+    } else {
+        ALOGV("%s: Found matched section '%s' (%zu)", __FUNCTION__, section, sectionIndex);
+    }
+
+    // Get the tag name component of the name
+    const char* nameTagName = name + sectionLength + 1;  // x.y.z -> z
+    if (sectionLength + 1 >= nameLength) {
+        return BAD_VALUE;
+    }
+
+    // Match rest of name against the tag names in that section only
+    uint32_t candidateTag = 0;
+    if (sectionIndex < ANDROID_SECTION_COUNT) {
+        // Match built-in tags (typically android.*)
+        uint32_t tagBegin, tagEnd;  // [tagBegin, tagEnd)
+        tagBegin = camera_metadata_section_bounds[sectionIndex][0];
+        tagEnd = camera_metadata_section_bounds[sectionIndex][1];
+
+        for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
+            const char* tagName = get_camera_metadata_tag_name(candidateTag);
+
+            if (strcmp(nameTagName, tagName) == 0) {
+                ALOGV("%s: Found matched tag '%s' (%d)", __FUNCTION__, tagName, candidateTag);
+                break;
+            }
+        }
+
+        if (candidateTag == tagEnd) {
+            return NAME_NOT_FOUND;
+        }
+    } else if (vTags != NULL) {
+        // Match vendor tags (typically com.*)
+        const String8 sectionName(section);
+        const String8 tagName(nameTagName);
+
+        status_t res = OK;
+        if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
+            return NAME_NOT_FOUND;
+        }
+    }
+
+    *tag = candidateTag;
+    return OK;
+}
+
+}  // namespace helper
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/common/default/CameraModule.cpp b/camera/common/default/CameraModule.cpp
new file mode 100644
index 0000000..9960842
--- /dev/null
+++ b/camera/common/default/CameraModule.cpp
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) 2016 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 "CamComm1.0-CamModule"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+// #define LOG_NDEBUG 0
+
+#include <utils/Trace.h>
+
+#include "CameraModule.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+void CameraModule::deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata& chars) {
+    ATRACE_CALL();
+
+    Vector<int32_t> derivedCharKeys;
+    Vector<int32_t> derivedRequestKeys;
+    Vector<int32_t> derivedResultKeys;
+    // Keys added in HAL3.3
+    if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) {
+        Vector<uint8_t> controlModes;
+        uint8_t data = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
+        chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/ 1);
+        data = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE;
+        chars.update(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &data, /*count*/ 1);
+        controlModes.push(ANDROID_CONTROL_MODE_AUTO);
+        camera_metadata_entry entry = chars.find(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
+        if (entry.count > 1 || entry.data.u8[0] != ANDROID_CONTROL_SCENE_MODE_DISABLED) {
+            controlModes.push(ANDROID_CONTROL_MODE_USE_SCENE_MODE);
+        }
+
+        // Only advertise CONTROL_OFF mode if 3A manual controls are supported.
+        bool isManualAeSupported = false;
+        bool isManualAfSupported = false;
+        bool isManualAwbSupported = false;
+        entry = chars.find(ANDROID_CONTROL_AE_AVAILABLE_MODES);
+        if (entry.count > 0) {
+            for (size_t i = 0; i < entry.count; i++) {
+                if (entry.data.u8[i] == ANDROID_CONTROL_AE_MODE_OFF) {
+                    isManualAeSupported = true;
+                    break;
+                }
+            }
+        }
+        entry = chars.find(ANDROID_CONTROL_AF_AVAILABLE_MODES);
+        if (entry.count > 0) {
+            for (size_t i = 0; i < entry.count; i++) {
+                if (entry.data.u8[i] == ANDROID_CONTROL_AF_MODE_OFF) {
+                    isManualAfSupported = true;
+                    break;
+                }
+            }
+        }
+        entry = chars.find(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
+        if (entry.count > 0) {
+            for (size_t i = 0; i < entry.count; i++) {
+                if (entry.data.u8[i] == ANDROID_CONTROL_AWB_MODE_OFF) {
+                    isManualAwbSupported = true;
+                    break;
+                }
+            }
+        }
+        if (isManualAeSupported && isManualAfSupported && isManualAwbSupported) {
+            controlModes.push(ANDROID_CONTROL_MODE_OFF);
+        }
+
+        chars.update(ANDROID_CONTROL_AVAILABLE_MODES, controlModes);
+
+        entry = chars.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
+        // HAL3.2 devices passing existing CTS test should all support all LSC modes and LSC map
+        bool lensShadingModeSupported = false;
+        if (entry.count > 0) {
+            for (size_t i = 0; i < entry.count; i++) {
+                if (entry.data.i32[i] == ANDROID_SHADING_MODE) {
+                    lensShadingModeSupported = true;
+                    break;
+                }
+            }
+        }
+        Vector<uint8_t> lscModes;
+        Vector<uint8_t> lscMapModes;
+        lscModes.push(ANDROID_SHADING_MODE_FAST);
+        lscModes.push(ANDROID_SHADING_MODE_HIGH_QUALITY);
+        lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
+        if (lensShadingModeSupported) {
+            lscModes.push(ANDROID_SHADING_MODE_OFF);
+            lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON);
+        }
+        chars.update(ANDROID_SHADING_AVAILABLE_MODES, lscModes);
+        chars.update(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, lscMapModes);
+
+        derivedCharKeys.push(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
+        derivedCharKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE);
+        derivedCharKeys.push(ANDROID_CONTROL_AVAILABLE_MODES);
+        derivedCharKeys.push(ANDROID_SHADING_AVAILABLE_MODES);
+        derivedCharKeys.push(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES);
+
+        // Need update android.control.availableHighSpeedVideoConfigurations since HAL3.3
+        // adds batch size to this array.
+        entry = chars.find(ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);
+        if (entry.count > 0) {
+            Vector<int32_t> highSpeedConfig;
+            for (size_t i = 0; i < entry.count; i += 4) {
+                highSpeedConfig.add(entry.data.i32[i]);      // width
+                highSpeedConfig.add(entry.data.i32[i + 1]);  // height
+                highSpeedConfig.add(entry.data.i32[i + 2]);  // fps_min
+                highSpeedConfig.add(entry.data.i32[i + 3]);  // fps_max
+                highSpeedConfig.add(1);  // batchSize_max. default to 1 for HAL3.2
+            }
+            chars.update(ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
+                         highSpeedConfig);
+        }
+    }
+
+    // Keys added in HAL3.4
+    if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
+        // Check if HAL supports RAW_OPAQUE output
+        camera_metadata_entry entry = chars.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
+        bool supportRawOpaque = false;
+        bool supportAnyRaw = false;
+        const int STREAM_CONFIGURATION_SIZE = 4;
+        const int STREAM_FORMAT_OFFSET = 0;
+        const int STREAM_WIDTH_OFFSET = 1;
+        const int STREAM_HEIGHT_OFFSET = 2;
+        const int STREAM_IS_INPUT_OFFSET = 3;
+        Vector<int32_t> rawOpaqueSizes;
+
+        for (size_t i = 0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
+            int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
+            int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
+            int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
+            int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
+            if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
+                format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
+                supportRawOpaque = true;
+                rawOpaqueSizes.push(width);
+                rawOpaqueSizes.push(height);
+                // 2 bytes per pixel. This rough estimation is only used when
+                // HAL does not fill in the opaque raw size
+                rawOpaqueSizes.push(width * height * 2);
+            }
+            if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
+                (format == HAL_PIXEL_FORMAT_RAW16 || format == HAL_PIXEL_FORMAT_RAW10 ||
+                 format == HAL_PIXEL_FORMAT_RAW12 || format == HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
+                supportAnyRaw = true;
+            }
+        }
+
+        if (supportRawOpaque) {
+            entry = chars.find(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
+            if (entry.count == 0) {
+                // Fill in estimated value if HAL does not list it
+                chars.update(ANDROID_SENSOR_OPAQUE_RAW_SIZE, rawOpaqueSizes);
+                derivedCharKeys.push(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
+            }
+        }
+
+        // Check if HAL supports any RAW output, if so, fill in postRawSensitivityBoost range
+        if (supportAnyRaw) {
+            int32_t defaultRange[2] = {100, 100};
+            entry = chars.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE);
+            if (entry.count == 0) {
+                // Fill in default value (100, 100)
+                chars.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE, defaultRange, 2);
+                derivedCharKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE);
+                // Actual request/results will be derived by camera device.
+                derivedRequestKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
+                derivedResultKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
+            }
+        }
+    }
+
+    // Add those newly added keys to AVAILABLE_CHARACTERISTICS_KEYS
+    // This has to be done at this end of this function.
+    if (derivedCharKeys.size() > 0) {
+        appendAvailableKeys(chars, ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, derivedCharKeys);
+    }
+    if (derivedRequestKeys.size() > 0) {
+        appendAvailableKeys(chars, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, derivedRequestKeys);
+    }
+    if (derivedResultKeys.size() > 0) {
+        appendAvailableKeys(chars, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, derivedResultKeys);
+    }
+    return;
+}
+
+void CameraModule::appendAvailableKeys(CameraMetadata& chars, int32_t keyTag,
+                                       const Vector<int32_t>& appendKeys) {
+    camera_metadata_entry entry = chars.find(keyTag);
+    Vector<int32_t> availableKeys;
+    availableKeys.setCapacity(entry.count + appendKeys.size());
+    for (size_t i = 0; i < entry.count; i++) {
+        availableKeys.push(entry.data.i32[i]);
+    }
+    for (size_t i = 0; i < appendKeys.size(); i++) {
+        availableKeys.push(appendKeys[i]);
+    }
+    chars.update(keyTag, availableKeys);
+}
+
+CameraModule::CameraModule(camera_module_t* module) : mNumberOfCameras(0) {
+    if (module == NULL) {
+        ALOGE("%s: camera hardware module must not be null", __FUNCTION__);
+        assert(0);
+    }
+    mModule = module;
+}
+
+CameraModule::~CameraModule() {
+    while (mCameraInfoMap.size() > 0) {
+        camera_info cameraInfo = mCameraInfoMap.editValueAt(0);
+        if (cameraInfo.static_camera_characteristics != NULL) {
+            free_camera_metadata(
+                    const_cast<camera_metadata_t*>(cameraInfo.static_camera_characteristics));
+        }
+        mCameraInfoMap.removeItemsAt(0);
+    }
+
+    while (mPhysicalCameraInfoMap.size() > 0) {
+        camera_metadata_t* metadata = mPhysicalCameraInfoMap.editValueAt(0);
+        if (metadata != NULL) {
+            free_camera_metadata(metadata);
+        }
+        mPhysicalCameraInfoMap.removeItemsAt(0);
+    }
+}
+
+int CameraModule::init() {
+    ATRACE_CALL();
+    int res = OK;
+    if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 && mModule->init != NULL) {
+        ATRACE_BEGIN("camera_module->init");
+        res = mModule->init();
+        ATRACE_END();
+    }
+    mNumberOfCameras = getNumberOfCameras();
+    mCameraInfoMap.setCapacity(mNumberOfCameras);
+    return res;
+}
+
+int CameraModule::getCameraInfo(int cameraId, struct camera_info* info) {
+    ATRACE_CALL();
+    Mutex::Autolock lock(mCameraInfoLock);
+    if (cameraId < 0) {
+        ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
+        return -EINVAL;
+    }
+
+    // Only override static_camera_characteristics for API2 devices
+    int apiVersion = mModule->common.module_api_version;
+    if (apiVersion < CAMERA_MODULE_API_VERSION_2_0) {
+        int ret;
+        ATRACE_BEGIN("camera_module->get_camera_info");
+        ret = mModule->get_camera_info(cameraId, info);
+        // Fill in this so CameraService won't be confused by
+        // possibly 0 device_version
+        info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
+        ATRACE_END();
+        return ret;
+    }
+
+    ssize_t index = mCameraInfoMap.indexOfKey(cameraId);
+    if (index == NAME_NOT_FOUND) {
+        // Get camera info from raw module and cache it
+        camera_info rawInfo, cameraInfo;
+        ATRACE_BEGIN("camera_module->get_camera_info");
+        int ret = mModule->get_camera_info(cameraId, &rawInfo);
+        ATRACE_END();
+        if (ret != 0) {
+            return ret;
+        }
+        int deviceVersion = rawInfo.device_version;
+        if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_0) {
+            // static_camera_characteristics is invalid
+            *info = rawInfo;
+            return ret;
+        }
+        CameraMetadata m;
+        m.append(rawInfo.static_camera_characteristics);
+        deriveCameraCharacteristicsKeys(rawInfo.device_version, m);
+        cameraInfo = rawInfo;
+        cameraInfo.static_camera_characteristics = m.release();
+        index = mCameraInfoMap.add(cameraId, cameraInfo);
+    }
+
+    assert(index != NAME_NOT_FOUND);
+    // return the cached camera info
+    *info = mCameraInfoMap[index];
+    return OK;
+}
+
+int CameraModule::getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t** physicalInfo) {
+    ATRACE_CALL();
+    Mutex::Autolock lock(mCameraInfoLock);
+    if (physicalCameraId < mNumberOfCameras) {
+        ALOGE("%s: Invalid physical camera ID %d", __FUNCTION__, physicalCameraId);
+        return -EINVAL;
+    }
+
+    // Only query physical camera info for 2.5 version for newer
+    int apiVersion = mModule->common.module_api_version;
+    if (apiVersion < CAMERA_MODULE_API_VERSION_2_5) {
+        ALOGE("%s: Module version must be at least 2.5 to handle getPhysicalCameraInfo",
+              __FUNCTION__);
+        return -ENODEV;
+    }
+    if (mModule->get_physical_camera_info == nullptr) {
+        ALOGE("%s: get_physical_camera is NULL for module version 2.5", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    ssize_t index = mPhysicalCameraInfoMap.indexOfKey(physicalCameraId);
+    if (index == NAME_NOT_FOUND) {
+        // Get physical camera characteristics, and cache it
+        camera_metadata_t* info = nullptr;
+        ATRACE_BEGIN("camera_module->get_physical_camera_info");
+        int ret = mModule->get_physical_camera_info(physicalCameraId, &info);
+        ATRACE_END();
+        if (ret != 0) {
+            return ret;
+        }
+
+        // The camera_metadata_t returned by get_physical_camera_info could be using
+        // more memory than necessary due to unused reserved space. Reduce the
+        // size by appending it to a new CameraMetadata object, which internally
+        // calls resizeIfNeeded.
+        CameraMetadata m;
+        m.append(info);
+        camera_metadata_t* derivedMetadata = m.release();
+        index = mPhysicalCameraInfoMap.add(physicalCameraId, derivedMetadata);
+    }
+
+    assert(index != NAME_NOT_FOUND);
+    *physicalInfo = mPhysicalCameraInfoMap[index];
+    return OK;
+}
+
+int CameraModule::getDeviceVersion(int cameraId) {
+    ssize_t index = mDeviceVersionMap.indexOfKey(cameraId);
+    if (index == NAME_NOT_FOUND) {
+        int deviceVersion;
+        if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
+            struct camera_info info;
+            getCameraInfo(cameraId, &info);
+            deviceVersion = info.device_version;
+        } else {
+            deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
+        }
+        index = mDeviceVersionMap.add(cameraId, deviceVersion);
+    }
+    assert(index != NAME_NOT_FOUND);
+    return mDeviceVersionMap[index];
+}
+
+int CameraModule::open(const char* id, struct hw_device_t** device) {
+    int res;
+    ATRACE_BEGIN("camera_module->open");
+    res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
+    ATRACE_END();
+    return res;
+}
+
+bool CameraModule::isOpenLegacyDefined() const {
+    if (getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_3) {
+        return false;
+    }
+    return mModule->open_legacy != NULL;
+}
+
+int CameraModule::openLegacy(const char* id, uint32_t halVersion, struct hw_device_t** device) {
+    int res;
+    ATRACE_BEGIN("camera_module->open_legacy");
+    res = mModule->open_legacy(&mModule->common, id, halVersion, device);
+    ATRACE_END();
+    return res;
+}
+
+int CameraModule::getNumberOfCameras() {
+    int numCameras;
+    ATRACE_BEGIN("camera_module->get_number_of_cameras");
+    numCameras = mModule->get_number_of_cameras();
+    ATRACE_END();
+    return numCameras;
+}
+
+int CameraModule::setCallbacks(const camera_module_callbacks_t* callbacks) {
+    int res = OK;
+    ATRACE_BEGIN("camera_module->set_callbacks");
+    if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
+        res = mModule->set_callbacks(callbacks);
+    }
+    ATRACE_END();
+    return res;
+}
+
+bool CameraModule::isVendorTagDefined() const {
+    return mModule->get_vendor_tag_ops != NULL;
+}
+
+void CameraModule::getVendorTagOps(vendor_tag_ops_t* ops) {
+    if (mModule->get_vendor_tag_ops) {
+        ATRACE_BEGIN("camera_module->get_vendor_tag_ops");
+        mModule->get_vendor_tag_ops(ops);
+        ATRACE_END();
+    }
+}
+
+bool CameraModule::isSetTorchModeSupported() const {
+    if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
+        if (mModule->set_torch_mode == NULL) {
+            ALOGE("%s: Module 2.4 device must support set torch API!", __FUNCTION__);
+            return false;
+        }
+        return true;
+    }
+    return false;
+}
+
+int CameraModule::setTorchMode(const char* camera_id, bool enable) {
+    int res = INVALID_OPERATION;
+    if (mModule->set_torch_mode != NULL) {
+        ATRACE_BEGIN("camera_module->set_torch_mode");
+        res = mModule->set_torch_mode(camera_id, enable);
+        ATRACE_END();
+    }
+    return res;
+}
+
+int CameraModule::isStreamCombinationSupported(int cameraId, camera_stream_combination_t* streams) {
+    int res = INVALID_OPERATION;
+    if (mModule->is_stream_combination_supported != NULL) {
+        ATRACE_BEGIN("camera_module->is_stream_combination_supported");
+        res = mModule->is_stream_combination_supported(cameraId, streams);
+        ATRACE_END();
+    }
+    return res;
+}
+
+void CameraModule::notifyDeviceStateChange(uint64_t deviceState) {
+    if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_5 &&
+        mModule->notify_device_state_change != NULL) {
+        ATRACE_BEGIN("camera_module->notify_device_state_change");
+        ALOGI("%s: calling notify_device_state_change with state %" PRId64, __FUNCTION__,
+              deviceState);
+        mModule->notify_device_state_change(deviceState);
+        ATRACE_END();
+    }
+}
+
+bool CameraModule::isLogicalMultiCamera(const common::helper::CameraMetadata& metadata,
+                                        std::unordered_set<std::string>* physicalCameraIds) {
+    if (physicalCameraIds == nullptr) {
+        ALOGE("%s: physicalCameraIds must not be null", __FUNCTION__);
+        return false;
+    }
+
+    bool isLogicalMultiCamera = false;
+    camera_metadata_ro_entry_t capabilities = metadata.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+    for (size_t i = 0; i < capabilities.count; i++) {
+        if (capabilities.data.u8[i] ==
+            ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
+            isLogicalMultiCamera = true;
+            break;
+        }
+    }
+
+    if (isLogicalMultiCamera) {
+        camera_metadata_ro_entry_t entry = metadata.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
+        const uint8_t* ids = entry.data.u8;
+        size_t start = 0;
+        for (size_t i = 0; i < entry.count; ++i) {
+            if (ids[i] == '\0') {
+                if (start != i) {
+                    const char* physicalId = reinterpret_cast<const char*>(ids + start);
+                    physicalCameraIds->emplace(physicalId);
+                }
+                start = i + 1;
+            }
+        }
+    }
+    return isLogicalMultiCamera;
+}
+
+status_t CameraModule::filterOpenErrorCode(status_t err) {
+    switch (err) {
+        case NO_ERROR:
+        case -EBUSY:
+        case -EINVAL:
+        case -EUSERS:
+            return err;
+        default:
+            break;
+    }
+    return -ENODEV;
+}
+
+void CameraModule::removeCamera(int cameraId) {
+    // Skip HAL1 devices which isn't cached in mCameraInfoMap and don't advertise
+    // static_camera_characteristics
+    if (getDeviceVersion(cameraId) >= CAMERA_DEVICE_API_VERSION_3_0) {
+        std::unordered_set<std::string> physicalIds;
+        camera_metadata_t* metadata = const_cast<camera_metadata_t*>(
+                mCameraInfoMap.valueFor(cameraId).static_camera_characteristics);
+        common::helper::CameraMetadata hidlMetadata(metadata);
+
+        if (isLogicalMultiCamera(hidlMetadata, &physicalIds)) {
+            for (const auto& id : physicalIds) {
+                int idInt = std::stoi(id);
+                if (mPhysicalCameraInfoMap.indexOfKey(idInt) >= 0) {
+                    free_camera_metadata(mPhysicalCameraInfoMap[idInt]);
+                    mPhysicalCameraInfoMap.removeItem(idInt);
+                } else {
+                    ALOGE("%s: Cannot find corresponding static metadata for physical id %s",
+                          __FUNCTION__, id.c_str());
+                }
+            }
+        }
+    }
+
+    mCameraInfoMap.removeItem(cameraId);
+    mDeviceVersionMap.removeItem(cameraId);
+}
+
+uint16_t CameraModule::getModuleApiVersion() const {
+    return mModule->common.module_api_version;
+}
+
+const char* CameraModule::getModuleName() const {
+    return mModule->common.name;
+}
+
+uint16_t CameraModule::getHalApiVersion() const {
+    return mModule->common.hal_api_version;
+}
+
+const char* CameraModule::getModuleAuthor() const {
+    return mModule->common.author;
+}
+
+void* CameraModule::getDso() {
+    return mModule->common.dso;
+}
+
+}  // namespace helper
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/common/default/CameraParameters.cpp b/camera/common/default/CameraParameters.cpp
new file mode 100644
index 0000000..37e28a2
--- /dev/null
+++ b/camera/common/default/CameraParameters.cpp
@@ -0,0 +1,503 @@
+/*
+**
+** Copyright 2008, 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 "CameraParams"
+#include <log/log.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <system/graphics.h>
+#include <unistd.h>
+#include "CameraParameters.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+// Parameter keys to communicate between camera application and driver.
+const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
+const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values";
+const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values";
+const char CameraParameters::KEY_PREVIEW_FPS_RANGE[] = "preview-fps-range";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE[] = "preview-fps-range-values";
+const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size";
+const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values";
+const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format";
+const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height";
+const char CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality";
+const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality";
+const char CameraParameters::KEY_ROTATION[] = "rotation";
+const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude";
+const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude";
+const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude";
+const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp";
+const char CameraParameters::KEY_GPS_PROCESSING_METHOD[] = "gps-processing-method";
+const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance";
+const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values";
+const char CameraParameters::KEY_EFFECT[] = "effect";
+const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values";
+const char CameraParameters::KEY_ANTIBANDING[] = "antibanding";
+const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values";
+const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode";
+const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values";
+const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode";
+const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
+const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
+const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
+const char CameraParameters::KEY_MAX_NUM_FOCUS_AREAS[] = "max-num-focus-areas";
+const char CameraParameters::KEY_FOCUS_AREAS[] = "focus-areas";
+const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length";
+const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
+const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
+const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation";
+const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
+const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
+const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK[] = "auto-exposure-lock";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[] = "auto-exposure-lock-supported";
+const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK[] = "auto-whitebalance-lock";
+const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[] =
+        "auto-whitebalance-lock-supported";
+const char CameraParameters::KEY_MAX_NUM_METERING_AREAS[] = "max-num-metering-areas";
+const char CameraParameters::KEY_METERING_AREAS[] = "metering-areas";
+const char CameraParameters::KEY_ZOOM[] = "zoom";
+const char CameraParameters::KEY_MAX_ZOOM[] = "max-zoom";
+const char CameraParameters::KEY_ZOOM_RATIOS[] = "zoom-ratios";
+const char CameraParameters::KEY_ZOOM_SUPPORTED[] = "zoom-supported";
+const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported";
+const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances";
+const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format";
+const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size";
+const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
+const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] =
+        "preferred-preview-size-for-video";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
+const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
+const char CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED[] = "video-snapshot-supported";
+const char CameraParameters::KEY_VIDEO_STABILIZATION[] = "video-stabilization";
+const char CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED[] = "video-stabilization-supported";
+const char CameraParameters::KEY_LIGHTFX[] = "light-fx";
+
+const char CameraParameters::TRUE[] = "true";
+const char CameraParameters::FALSE[] = "false";
+const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
+
+// Values for white balance settings.
+const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
+const char CameraParameters::WHITE_BALANCE_INCANDESCENT[] = "incandescent";
+const char CameraParameters::WHITE_BALANCE_FLUORESCENT[] = "fluorescent";
+const char CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT[] = "warm-fluorescent";
+const char CameraParameters::WHITE_BALANCE_DAYLIGHT[] = "daylight";
+const char CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT[] = "cloudy-daylight";
+const char CameraParameters::WHITE_BALANCE_TWILIGHT[] = "twilight";
+const char CameraParameters::WHITE_BALANCE_SHADE[] = "shade";
+
+// Values for effect settings.
+const char CameraParameters::EFFECT_NONE[] = "none";
+const char CameraParameters::EFFECT_MONO[] = "mono";
+const char CameraParameters::EFFECT_NEGATIVE[] = "negative";
+const char CameraParameters::EFFECT_SOLARIZE[] = "solarize";
+const char CameraParameters::EFFECT_SEPIA[] = "sepia";
+const char CameraParameters::EFFECT_POSTERIZE[] = "posterize";
+const char CameraParameters::EFFECT_WHITEBOARD[] = "whiteboard";
+const char CameraParameters::EFFECT_BLACKBOARD[] = "blackboard";
+const char CameraParameters::EFFECT_AQUA[] = "aqua";
+
+// Values for antibanding settings.
+const char CameraParameters::ANTIBANDING_AUTO[] = "auto";
+const char CameraParameters::ANTIBANDING_50HZ[] = "50hz";
+const char CameraParameters::ANTIBANDING_60HZ[] = "60hz";
+const char CameraParameters::ANTIBANDING_OFF[] = "off";
+
+// Values for flash mode settings.
+const char CameraParameters::FLASH_MODE_OFF[] = "off";
+const char CameraParameters::FLASH_MODE_AUTO[] = "auto";
+const char CameraParameters::FLASH_MODE_ON[] = "on";
+const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye";
+const char CameraParameters::FLASH_MODE_TORCH[] = "torch";
+
+// Values for scene mode settings.
+const char CameraParameters::SCENE_MODE_AUTO[] = "auto";
+const char CameraParameters::SCENE_MODE_ACTION[] = "action";
+const char CameraParameters::SCENE_MODE_PORTRAIT[] = "portrait";
+const char CameraParameters::SCENE_MODE_LANDSCAPE[] = "landscape";
+const char CameraParameters::SCENE_MODE_NIGHT[] = "night";
+const char CameraParameters::SCENE_MODE_NIGHT_PORTRAIT[] = "night-portrait";
+const char CameraParameters::SCENE_MODE_THEATRE[] = "theatre";
+const char CameraParameters::SCENE_MODE_BEACH[] = "beach";
+const char CameraParameters::SCENE_MODE_SNOW[] = "snow";
+const char CameraParameters::SCENE_MODE_SUNSET[] = "sunset";
+const char CameraParameters::SCENE_MODE_STEADYPHOTO[] = "steadyphoto";
+const char CameraParameters::SCENE_MODE_FIREWORKS[] = "fireworks";
+const char CameraParameters::SCENE_MODE_SPORTS[] = "sports";
+const char CameraParameters::SCENE_MODE_PARTY[] = "party";
+const char CameraParameters::SCENE_MODE_CANDLELIGHT[] = "candlelight";
+const char CameraParameters::SCENE_MODE_BARCODE[] = "barcode";
+const char CameraParameters::SCENE_MODE_HDR[] = "hdr";
+
+const char CameraParameters::PIXEL_FORMAT_YUV422SP[] = "yuv422sp";
+const char CameraParameters::PIXEL_FORMAT_YUV420SP[] = "yuv420sp";
+const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv";
+const char CameraParameters::PIXEL_FORMAT_YUV420P[] = "yuv420p";
+const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
+const char CameraParameters::PIXEL_FORMAT_RGBA8888[] = "rgba8888";
+const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
+const char CameraParameters::PIXEL_FORMAT_BAYER_RGGB[] = "bayer-rggb";
+const char CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE[] = "android-opaque";
+
+// Values for focus mode settings.
+const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
+const char CameraParameters::FOCUS_MODE_INFINITY[] = "infinity";
+const char CameraParameters::FOCUS_MODE_MACRO[] = "macro";
+const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed";
+const char CameraParameters::FOCUS_MODE_EDOF[] = "edof";
+const char CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO[] = "continuous-video";
+const char CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE[] = "continuous-picture";
+
+// Values for light fx settings
+const char CameraParameters::LIGHTFX_LOWLIGHT[] = "low-light";
+const char CameraParameters::LIGHTFX_HDR[] = "high-dynamic-range";
+
+CameraParameters::CameraParameters() : mMap() {}
+
+CameraParameters::~CameraParameters() {}
+
+String8 CameraParameters::flatten() const {
+    String8 flattened("");
+    size_t size = mMap.size();
+
+    for (size_t i = 0; i < size; i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+
+        flattened += k;
+        flattened += "=";
+        flattened += v;
+        if (i != size - 1) flattened += ";";
+    }
+
+    return flattened;
+}
+
+void CameraParameters::unflatten(const String8& params) {
+    const char* a = params.string();
+    const char* b;
+
+    mMap.clear();
+
+    for (;;) {
+        // Find the bounds of the key name.
+        b = strchr(a, '=');
+        if (b == 0) break;
+
+        // Create the key string.
+        String8 k(a, (size_t)(b - a));
+
+        // Find the value.
+        a = b + 1;
+        b = strchr(a, ';');
+        if (b == 0) {
+            // If there's no semicolon, this is the last item.
+            String8 v(a);
+            mMap.add(k, v);
+            break;
+        }
+
+        String8 v(a, (size_t)(b - a));
+        mMap.add(k, v);
+        a = b + 1;
+    }
+}
+
+void CameraParameters::set(const char* key, const char* value) {
+    // i think i can do this with strspn()
+    if (strchr(key, '=') || strchr(key, ';')) {
+        // ALOGE("Key \"%s\"contains invalid character (= or ;)", key);
+        return;
+    }
+
+    if (strchr(value, '=') || strchr(value, ';')) {
+        // ALOGE("Value \"%s\"contains invalid character (= or ;)", value);
+        return;
+    }
+
+    mMap.replaceValueFor(String8(key), String8(value));
+}
+
+void CameraParameters::set(const char* key, int value) {
+    char str[16];
+    sprintf(str, "%d", value);
+    set(key, str);
+}
+
+void CameraParameters::setFloat(const char* key, float value) {
+    char str[16];  // 14 should be enough. We overestimate to be safe.
+    snprintf(str, sizeof(str), "%g", value);
+    set(key, str);
+}
+
+const char* CameraParameters::get(const char* key) const {
+    String8 v = mMap.valueFor(String8(key));
+    if (v.length() == 0) return 0;
+    return v.string();
+}
+
+int CameraParameters::getInt(const char* key) const {
+    const char* v = get(key);
+    if (v == 0) return -1;
+    return strtol(v, 0, 0);
+}
+
+float CameraParameters::getFloat(const char* key) const {
+    const char* v = get(key);
+    if (v == 0) return -1;
+    return strtof(v, 0);
+}
+
+void CameraParameters::remove(const char* key) {
+    mMap.removeItem(String8(key));
+}
+
+// Parse string like "640x480" or "10000,20000"
+static int parse_pair(const char* str, int* first, int* second, char delim, char** endptr = NULL) {
+    // Find the first integer.
+    char* end;
+    int w = (int)strtol(str, &end, 10);
+    // If a delimeter does not immediately follow, give up.
+    if (*end != delim) {
+        ALOGE("Cannot find delimeter (%c) in str=%s", delim, str);
+        return -1;
+    }
+
+    // Find the second integer, immediately after the delimeter.
+    int h = (int)strtol(end + 1, &end, 10);
+
+    *first = w;
+    *second = h;
+
+    if (endptr) {
+        *endptr = end;
+    }
+
+    return 0;
+}
+
+static void parseSizesList(const char* sizesStr, Vector<Size>& sizes) {
+    if (sizesStr == 0) {
+        return;
+    }
+
+    char* sizeStartPtr = (char*)sizesStr;
+
+    while (true) {
+        int width, height;
+        int success = parse_pair(sizeStartPtr, &width, &height, 'x', &sizeStartPtr);
+        if (success == -1 || (*sizeStartPtr != ',' && *sizeStartPtr != '\0')) {
+            ALOGE("Picture sizes string \"%s\" contains invalid character.", sizesStr);
+            return;
+        }
+        sizes.push(Size(width, height));
+
+        if (*sizeStartPtr == '\0') {
+            return;
+        }
+        sizeStartPtr++;
+    }
+}
+
+void CameraParameters::setPreviewSize(int width, int height) {
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set(KEY_PREVIEW_SIZE, str);
+}
+
+void CameraParameters::getPreviewSize(int* width, int* height) const {
+    *width = *height = -1;
+    // Get the current string, if it doesn't exist, leave the -1x-1
+    const char* p = get(KEY_PREVIEW_SIZE);
+    if (p == 0) return;
+    parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getPreferredPreviewSizeForVideo(int* width, int* height) const {
+    *width = *height = -1;
+    const char* p = get(KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO);
+    if (p == 0) return;
+    parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getSupportedPreviewSizes(Vector<Size>& sizes) const {
+    const char* previewSizesStr = get(KEY_SUPPORTED_PREVIEW_SIZES);
+    parseSizesList(previewSizesStr, sizes);
+}
+
+void CameraParameters::setVideoSize(int width, int height) {
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set(KEY_VIDEO_SIZE, str);
+}
+
+void CameraParameters::getVideoSize(int* width, int* height) const {
+    *width = *height = -1;
+    const char* p = get(KEY_VIDEO_SIZE);
+    if (p == 0) return;
+    parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getSupportedVideoSizes(Vector<Size>& sizes) const {
+    const char* videoSizesStr = get(KEY_SUPPORTED_VIDEO_SIZES);
+    parseSizesList(videoSizesStr, sizes);
+}
+
+void CameraParameters::setPreviewFrameRate(int fps) {
+    set(KEY_PREVIEW_FRAME_RATE, fps);
+}
+
+int CameraParameters::getPreviewFrameRate() const {
+    return getInt(KEY_PREVIEW_FRAME_RATE);
+}
+
+void CameraParameters::getPreviewFpsRange(int* min_fps, int* max_fps) const {
+    *min_fps = *max_fps = -1;
+    const char* p = get(KEY_PREVIEW_FPS_RANGE);
+    if (p == 0) return;
+    parse_pair(p, min_fps, max_fps, ',');
+}
+
+void CameraParameters::setPreviewFormat(const char* format) {
+    set(KEY_PREVIEW_FORMAT, format);
+}
+
+const char* CameraParameters::getPreviewFormat() const {
+    return get(KEY_PREVIEW_FORMAT);
+}
+
+void CameraParameters::setPictureSize(int width, int height) {
+    char str[32];
+    sprintf(str, "%dx%d", width, height);
+    set(KEY_PICTURE_SIZE, str);
+}
+
+void CameraParameters::getPictureSize(int* width, int* height) const {
+    *width = *height = -1;
+    // Get the current string, if it doesn't exist, leave the -1x-1
+    const char* p = get(KEY_PICTURE_SIZE);
+    if (p == 0) return;
+    parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getSupportedPictureSizes(Vector<Size>& sizes) const {
+    const char* pictureSizesStr = get(KEY_SUPPORTED_PICTURE_SIZES);
+    parseSizesList(pictureSizesStr, sizes);
+}
+
+void CameraParameters::setPictureFormat(const char* format) {
+    set(KEY_PICTURE_FORMAT, format);
+}
+
+const char* CameraParameters::getPictureFormat() const {
+    return get(KEY_PICTURE_FORMAT);
+}
+
+void CameraParameters::dump() const {
+    ALOGD("dump: mMap.size = %zu", mMap.size());
+    for (size_t i = 0; i < mMap.size(); i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+        ALOGD("%s: %s\n", k.string(), v.string());
+    }
+}
+
+status_t CameraParameters::dump(int fd, const Vector<String16>& /*args*/) const {
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %zu\n", mMap.size());
+    result.append(buffer);
+    for (size_t i = 0; i < mMap.size(); i++) {
+        String8 k, v;
+        k = mMap.keyAt(i);
+        v = mMap.valueAt(i);
+        snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
+        result.append(buffer);
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+void CameraParameters::getSupportedPreviewFormats(Vector<int>& formats) const {
+    const char* supportedPreviewFormats = get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
+
+    if (supportedPreviewFormats == NULL) {
+        ALOGW("%s: No supported preview formats.", __FUNCTION__);
+        return;
+    }
+
+    String8 fmtStr(supportedPreviewFormats);
+    char* prevFmts = fmtStr.lockBuffer(fmtStr.size());
+
+    char* savePtr;
+    char* fmt = strtok_r(prevFmts, ",", &savePtr);
+    while (fmt) {
+        int actual = previewFormatToEnum(fmt);
+        if (actual != -1) {
+            formats.add(actual);
+        }
+        fmt = strtok_r(NULL, ",", &savePtr);
+    }
+    fmtStr.unlockBuffer(fmtStr.size());
+}
+
+int CameraParameters::previewFormatToEnum(const char* format) {
+    return !format                                  ? HAL_PIXEL_FORMAT_YCrCb_420_SP
+           : !strcmp(format, PIXEL_FORMAT_YUV422SP) ? HAL_PIXEL_FORMAT_YCbCr_422_SP
+                                                    :  // NV16
+                   !strcmp(format, PIXEL_FORMAT_YUV420SP) ? HAL_PIXEL_FORMAT_YCrCb_420_SP
+                                                          :  // NV21
+                   !strcmp(format, PIXEL_FORMAT_YUV422I) ? HAL_PIXEL_FORMAT_YCbCr_422_I
+                                                         :  // YUY2
+                   !strcmp(format, PIXEL_FORMAT_YUV420P) ? HAL_PIXEL_FORMAT_YV12
+                                                         :  // YV12
+                   !strcmp(format, PIXEL_FORMAT_RGB565) ? HAL_PIXEL_FORMAT_RGB_565
+                                                        :  // RGB565
+                   !strcmp(format, PIXEL_FORMAT_RGBA8888) ? HAL_PIXEL_FORMAT_RGBA_8888
+                                                          :  // RGB8888
+                   !strcmp(format, PIXEL_FORMAT_BAYER_RGGB) ? HAL_PIXEL_FORMAT_RAW16
+                                                            :  // Raw sensor data
+                   -1;
+}
+
+bool CameraParameters::isEmpty() const {
+    return mMap.isEmpty();
+}
+
+};  // namespace helper
+};  // namespace common
+};  // namespace camera
+};  // namespace hardware
+};  // namespace android
diff --git a/camera/common/default/Exif.cpp b/camera/common/default/Exif.cpp
new file mode 100644
index 0000000..f4b2a31
--- /dev/null
+++ b/camera/common/default/Exif.cpp
@@ -0,0 +1,1041 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "CamComm1.0-Exif"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+// #define LOG_NDEBUG 0
+
+#include <android/log.h>
+
+#include <inttypes.h>
+#include <math.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "Exif.h"
+
+extern "C" {
+#include <libexif/exif-data.h>
+}
+
+namespace std {
+
+template <>
+struct default_delete<ExifEntry> {
+    inline void operator()(ExifEntry* entry) const { exif_entry_unref(entry); }
+};
+
+}  // namespace std
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+class ExifUtilsImpl : public ExifUtils {
+  public:
+    ExifUtilsImpl();
+
+    virtual ~ExifUtilsImpl();
+
+    // Initialize() can be called multiple times. The setting of Exif tags will be
+    // cleared.
+    virtual bool initialize();
+
+    // set all known fields from a metadata structure
+    virtual bool setFromMetadata(const CameraMetadata& metadata, const size_t imageWidth,
+                                 const size_t imageHeight);
+
+    // sets the len aperture.
+    // Returns false if memory allocation fails.
+    virtual bool setAperture(uint32_t numerator, uint32_t denominator);
+
+    // sets the value of brightness.
+    // Returns false if memory allocation fails.
+    virtual bool setBrightness(int32_t numerator, int32_t denominator);
+
+    // sets the color space.
+    // Returns false if memory allocation fails.
+    virtual bool setColorSpace(uint16_t color_space);
+
+    // sets the information to compressed data.
+    // Returns false if memory allocation fails.
+    virtual bool setComponentsConfiguration(const std::string& components_configuration);
+
+    // sets the compression scheme used for the image data.
+    // Returns false if memory allocation fails.
+    virtual bool setCompression(uint16_t compression);
+
+    // sets image contrast.
+    // Returns false if memory allocation fails.
+    virtual bool setContrast(uint16_t contrast);
+
+    // sets the date and time of image last modified. It takes local time. The
+    // name of the tag is DateTime in IFD0.
+    // Returns false if memory allocation fails.
+    virtual bool setDateTime(const struct tm& t);
+
+    // sets the image description.
+    // Returns false if memory allocation fails.
+    virtual bool setDescription(const std::string& description);
+
+    // sets the digital zoom ratio. If the numerator is 0, it means digital zoom
+    // was not used.
+    // Returns false if memory allocation fails.
+    virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator);
+
+    // sets the exposure bias.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureBias(int32_t numerator, int32_t denominator);
+
+    // sets the exposure mode set when the image was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureMode(uint16_t exposure_mode);
+
+    // sets the program used by the camera to set exposure when the picture is
+    // taken.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureProgram(uint16_t exposure_program);
+
+    // sets the exposure time, given in seconds.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureTime(uint32_t numerator, uint32_t denominator);
+
+    // sets the status of flash.
+    // Returns false if memory allocation fails.
+    virtual bool setFlash(uint16_t flash);
+
+    // sets the F number.
+    // Returns false if memory allocation fails.
+    virtual bool setFNumber(uint32_t numerator, uint32_t denominator);
+
+    // sets the focal length of lens used to take the image in millimeters.
+    // Returns false if memory allocation fails.
+    virtual bool setFocalLength(uint32_t numerator, uint32_t denominator);
+
+    // sets the degree of overall image gain adjustment.
+    // Returns false if memory allocation fails.
+    virtual bool setGainControl(uint16_t gain_control);
+
+    // sets the altitude in meters.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsAltitude(double altitude);
+
+    // sets the latitude with degrees minutes seconds format.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsLatitude(double latitude);
+
+    // sets the longitude with degrees minutes seconds format.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsLongitude(double longitude);
+
+    // sets GPS processing method.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsProcessingMethod(const std::string& method);
+
+    // sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsTimestamp(const struct tm& t);
+
+    // sets the length (number of rows) of main image.
+    // Returns false if memory allocation fails.
+    virtual bool setImageHeight(uint32_t length);
+
+    // sets the width (number of columes) of main image.
+    // Returns false if memory allocation fails.
+    virtual bool setImageWidth(uint32_t width);
+
+    // sets the ISO speed.
+    // Returns false if memory allocation fails.
+    virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
+
+    // sets the kind of light source.
+    // Returns false if memory allocation fails.
+    virtual bool setLightSource(uint16_t light_source);
+
+    // sets the smallest F number of the lens.
+    // Returns false if memory allocation fails.
+    virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator);
+
+    // sets the metering mode.
+    // Returns false if memory allocation fails.
+    virtual bool setMeteringMode(uint16_t metering_mode);
+
+    // sets image orientation.
+    // Returns false if memory allocation fails.
+    virtual bool setOrientation(uint16_t orientation);
+
+    // sets the unit for measuring XResolution and YResolution.
+    // Returns false if memory allocation fails.
+    virtual bool setResolutionUnit(uint16_t resolution_unit);
+
+    // sets image saturation.
+    // Returns false if memory allocation fails.
+    virtual bool setSaturation(uint16_t saturation);
+
+    // sets the type of scene that was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setSceneCaptureType(uint16_t type);
+
+    // sets image sharpness.
+    // Returns false if memory allocation fails.
+    virtual bool setSharpness(uint16_t sharpness);
+
+    // sets the shutter speed.
+    // Returns false if memory allocation fails.
+    virtual bool setShutterSpeed(int32_t numerator, int32_t denominator);
+
+    // sets the distance to the subject, given in meters.
+    // Returns false if memory allocation fails.
+    virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator);
+
+    // sets the fractions of seconds for the <DateTime> tag.
+    // Returns false if memory allocation fails.
+    virtual bool setSubsecTime(const std::string& subsec_time);
+
+    // sets the white balance mode set when the image was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setWhiteBalance(uint16_t white_balance);
+
+    // sets the number of pixels per resolution unit in the image width.
+    // Returns false if memory allocation fails.
+    virtual bool setXResolution(uint32_t numerator, uint32_t denominator);
+
+    // sets the position of chrominance components in relation to the luminance
+    // component.
+    // Returns false if memory allocation fails.
+    virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning);
+
+    // sets the number of pixels per resolution unit in the image length.
+    // Returns false if memory allocation fails.
+    virtual bool setYResolution(uint32_t numerator, uint32_t denominator);
+
+    // sets the manufacturer of camera.
+    // Returns false if memory allocation fails.
+    virtual bool setMake(const std::string& make);
+
+    // sets the model number of camera.
+    // Returns false if memory allocation fails.
+    virtual bool setModel(const std::string& model);
+
+    // Generates APP1 segment.
+    // Returns false if generating APP1 segment fails.
+    virtual bool generateApp1(const void* thumbnail_buffer, uint32_t size);
+
+    // Gets buffer of APP1 segment. This method must be called only after calling
+    // GenerateAPP1().
+    virtual const uint8_t* getApp1Buffer();
+
+    // Gets length of APP1 segment. This method must be called only after calling
+    // GenerateAPP1().
+    virtual unsigned int getApp1Length();
+
+  protected:
+    // sets the version of this standard supported.
+    // Returns false if memory allocation fails.
+    virtual bool setExifVersion(const std::string& exif_version);
+
+    // Resets the pointers and memories.
+    virtual void reset();
+
+    // Adds a variable length tag to |exif_data_|. It will remove the original one
+    // if the tag exists.
+    // Returns the entry of the tag. The reference count of returned ExifEntry is
+    // two.
+    virtual std::unique_ptr<ExifEntry> addVariableLengthEntry(ExifIfd ifd, ExifTag tag,
+                                                              ExifFormat format,
+                                                              uint64_t components,
+                                                              unsigned int size);
+
+    // Adds a entry of |tag| in |exif_data_|. It won't remove the original one if
+    // the tag exists.
+    // Returns the entry of the tag. It adds one reference count to returned
+    // ExifEntry.
+    virtual std::unique_ptr<ExifEntry> addEntry(ExifIfd ifd, ExifTag tag);
+
+    // Helpe functions to add exif data with different types.
+    virtual bool setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg);
+
+    virtual bool setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg);
+
+    virtual bool setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator, uint32_t denominator,
+                             const std::string& msg);
+
+    virtual bool setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator, int32_t denominator,
+                              const std::string& msg);
+
+    virtual bool setString(ExifIfd ifd, ExifTag tag, ExifFormat format, const std::string& buffer,
+                           const std::string& msg);
+
+    // Destroys the buffer of APP1 segment if exists.
+    virtual void destroyApp1();
+
+    // The Exif data (APP1). Owned by this class.
+    ExifData* exif_data_;
+    // The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but
+    // owned by this class.
+    uint8_t* app1_buffer_;
+    // The length of |app1_buffer_|.
+    unsigned int app1_length_;
+};
+
+#define SET_SHORT(ifd, tag, value)                                  \
+    do {                                                            \
+        if (setShort(ifd, tag, value, #tag) == false) return false; \
+    } while (0);
+
+#define SET_LONG(ifd, tag, value)                                  \
+    do {                                                           \
+        if (setLong(ifd, tag, value, #tag) == false) return false; \
+    } while (0);
+
+#define SET_RATIONAL(ifd, tag, numerator, denominator)                                  \
+    do {                                                                                \
+        if (setRational(ifd, tag, numerator, denominator, #tag) == false) return false; \
+    } while (0);
+
+#define SET_SRATIONAL(ifd, tag, numerator, denominator)                                  \
+    do {                                                                                 \
+        if (setSRational(ifd, tag, numerator, denominator, #tag) == false) return false; \
+    } while (0);
+
+#define SET_STRING(ifd, tag, format, buffer)                                  \
+    do {                                                                      \
+        if (setString(ifd, tag, format, buffer, #tag) == false) return false; \
+    } while (0);
+
+// This comes from the Exif Version 2.2 standard table 6.
+const char gExifAsciiPrefix[] = {0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0};
+
+static void setLatitudeOrLongitudeData(unsigned char* data, double num) {
+    // Take the integer part of |num|.
+    ExifLong degrees = static_cast<ExifLong>(num);
+    ExifLong minutes = static_cast<ExifLong>(60 * (num - degrees));
+    ExifLong microseconds = static_cast<ExifLong>(3600000000u * (num - degrees - minutes / 60.0));
+    exif_set_rational(data, EXIF_BYTE_ORDER_INTEL, {degrees, 1});
+    exif_set_rational(data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL, {minutes, 1});
+    exif_set_rational(data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
+                      {microseconds, 1000000});
+}
+
+ExifUtils* ExifUtils::create() {
+    return new ExifUtilsImpl();
+}
+
+ExifUtils::~ExifUtils() {}
+
+ExifUtilsImpl::ExifUtilsImpl() : exif_data_(nullptr), app1_buffer_(nullptr), app1_length_(0) {}
+
+ExifUtilsImpl::~ExifUtilsImpl() {
+    reset();
+}
+
+bool ExifUtilsImpl::initialize() {
+    reset();
+    exif_data_ = exif_data_new();
+    if (exif_data_ == nullptr) {
+        ALOGE("%s: allocate memory for exif_data_ failed", __FUNCTION__);
+        return false;
+    }
+    // set the image options.
+    exif_data_set_option(exif_data_, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
+    exif_data_set_data_type(exif_data_, EXIF_DATA_TYPE_COMPRESSED);
+    exif_data_set_byte_order(exif_data_, EXIF_BYTE_ORDER_INTEL);
+
+    // set exif version to 2.2.
+    if (!setExifVersion("0220")) {
+        return false;
+    }
+
+    return true;
+}
+
+bool ExifUtilsImpl::setAperture(uint32_t numerator, uint32_t denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setBrightness(int32_t numerator, int32_t denominator) {
+    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_BRIGHTNESS_VALUE, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setColorSpace(uint16_t color_space) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE, color_space);
+    return true;
+}
+
+bool ExifUtilsImpl::setComponentsConfiguration(const std::string& components_configuration) {
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_COMPONENTS_CONFIGURATION, EXIF_FORMAT_UNDEFINED,
+               components_configuration);
+    return true;
+}
+
+bool ExifUtilsImpl::setCompression(uint16_t compression) {
+    SET_SHORT(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);
+    return true;
+}
+
+bool ExifUtilsImpl::setContrast(uint16_t contrast) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_CONTRAST, contrast);
+    return true;
+}
+
+bool ExifUtilsImpl::setDateTime(const struct tm& t) {
+    // The length is 20 bytes including NULL for termination in Exif standard.
+    char str[20];
+    int result = snprintf(str, sizeof(str), "%04i:%02i:%02i %02i:%02i:%02i", t.tm_year + 1900,
+                          t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
+    if (result != sizeof(str) - 1) {
+        ALOGW("%s: Input time is invalid", __FUNCTION__);
+        return false;
+    }
+    std::string buffer(str);
+    SET_STRING(EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, buffer);
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_FORMAT_ASCII, buffer);
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_FORMAT_ASCII, buffer);
+    return true;
+}
+
+bool ExifUtilsImpl::setDescription(const std::string& description) {
+    SET_STRING(EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_FORMAT_ASCII, description);
+    return true;
+}
+
+bool ExifUtilsImpl::setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setExposureBias(int32_t numerator, int32_t denominator) {
+    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setExposureMode(uint16_t exposure_mode) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposure_mode);
+    return true;
+}
+
+bool ExifUtilsImpl::setExposureProgram(uint16_t exposure_program) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, exposure_program);
+    return true;
+}
+
+bool ExifUtilsImpl::setExposureTime(uint32_t numerator, uint32_t denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setFlash(uint16_t flash) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
+    return true;
+}
+
+bool ExifUtilsImpl::setFNumber(uint32_t numerator, uint32_t denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setFocalLength(uint32_t numerator, uint32_t denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setGainControl(uint16_t gain_control) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_GAIN_CONTROL, gain_control);
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsAltitude(double altitude) {
+    ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF);
+    std::unique_ptr<ExifEntry> refEntry =
+            addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_BYTE, 1, 1);
+    if (!refEntry) {
+        ALOGE("%s: Adding GPSAltitudeRef exif entry failed", __FUNCTION__);
+        return false;
+    }
+    if (altitude >= 0) {
+        *refEntry->data = 0;
+    } else {
+        *refEntry->data = 1;
+        altitude *= -1;
+    }
+
+    ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE);
+    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+            EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 1, sizeof(ExifRational));
+    if (!entry) {
+        exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
+        ALOGE("%s: Adding GPSAltitude exif entry failed", __FUNCTION__);
+        return false;
+    }
+    exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
+                      {static_cast<ExifLong>(altitude * 1000), 1000});
+
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsLatitude(double latitude) {
+    const ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF);
+    std::unique_ptr<ExifEntry> refEntry =
+            addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
+    if (!refEntry) {
+        ALOGE("%s: Adding GPSLatitudeRef exif entry failed", __FUNCTION__);
+        return false;
+    }
+    if (latitude >= 0) {
+        memcpy(refEntry->data, "N", sizeof("N"));
+    } else {
+        memcpy(refEntry->data, "S", sizeof("S"));
+        latitude *= -1;
+    }
+
+    const ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE);
+    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+            EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
+    if (!entry) {
+        exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
+        ALOGE("%s: Adding GPSLatitude exif entry failed", __FUNCTION__);
+        return false;
+    }
+    setLatitudeOrLongitudeData(entry->data, latitude);
+
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsLongitude(double longitude) {
+    ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF);
+    std::unique_ptr<ExifEntry> refEntry =
+            addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
+    if (!refEntry) {
+        ALOGE("%s: Adding GPSLongitudeRef exif entry failed", __FUNCTION__);
+        return false;
+    }
+    if (longitude >= 0) {
+        memcpy(refEntry->data, "E", sizeof("E"));
+    } else {
+        memcpy(refEntry->data, "W", sizeof("W"));
+        longitude *= -1;
+    }
+
+    ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE);
+    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+            EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
+    if (!entry) {
+        exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
+        ALOGE("%s: Adding GPSLongitude exif entry failed", __FUNCTION__);
+        return false;
+    }
+    setLatitudeOrLongitudeData(entry->data, longitude);
+
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsProcessingMethod(const std::string& method) {
+    std::string buffer = std::string(gExifAsciiPrefix, sizeof(gExifAsciiPrefix)) + method;
+    SET_STRING(EXIF_IFD_GPS, static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD),
+               EXIF_FORMAT_UNDEFINED, buffer);
+    return true;
+}
+
+bool ExifUtilsImpl::setGpsTimestamp(const struct tm& t) {
+    const ExifTag dateTag = static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP);
+    const size_t kGpsDateStampSize = 11;
+    std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+            EXIF_IFD_GPS, dateTag, EXIF_FORMAT_ASCII, kGpsDateStampSize, kGpsDateStampSize);
+    if (!entry) {
+        ALOGE("%s: Adding GPSDateStamp exif entry failed", __FUNCTION__);
+        return false;
+    }
+    int result = snprintf(reinterpret_cast<char*>(entry->data), kGpsDateStampSize, "%04i:%02i:%02i",
+                          t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
+    if (result != kGpsDateStampSize - 1) {
+        ALOGW("%s: Input time is invalid", __FUNCTION__);
+        return false;
+    }
+
+    const ExifTag timeTag = static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP);
+    entry = addVariableLengthEntry(EXIF_IFD_GPS, timeTag, EXIF_FORMAT_RATIONAL, 3,
+                                   3 * sizeof(ExifRational));
+    if (!entry) {
+        ALOGE("%s: Adding GPSTimeStamp exif entry failed", __FUNCTION__);
+        return false;
+    }
+    exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, {static_cast<ExifLong>(t.tm_hour), 1});
+    exif_set_rational(entry->data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
+                      {static_cast<ExifLong>(t.tm_min), 1});
+    exif_set_rational(entry->data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
+                      {static_cast<ExifLong>(t.tm_sec), 1});
+
+    return true;
+}
+
+bool ExifUtilsImpl::setImageHeight(uint32_t length) {
+    SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length);
+    SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION, length);
+    return true;
+}
+
+bool ExifUtilsImpl::setImageWidth(uint32_t width) {
+    SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width);
+    SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION, width);
+    return true;
+}
+
+bool ExifUtilsImpl::setIsoSpeedRating(uint16_t iso_speed_ratings) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, iso_speed_ratings);
+    return true;
+}
+
+bool ExifUtilsImpl::setLightSource(uint16_t light_source) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_LIGHT_SOURCE, light_source);
+    return true;
+}
+
+bool ExifUtilsImpl::setMaxAperture(uint32_t numerator, uint32_t denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setMeteringMode(uint16_t metering_mode) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_METERING_MODE, metering_mode);
+    return true;
+}
+
+bool ExifUtilsImpl::setOrientation(uint16_t orientation) {
+    /*
+     * Orientation value:
+     *  1      2      3      4      5          6          7          8
+     *
+     *  888888 888888     88 88     8888888888 88                 88 8888888888
+     *  88         88     88 88     88  88     88  88         88  88     88  88
+     *  8888     8888   8888 8888   88         8888888888 8888888888         88
+     *  88         88     88 88
+     *  88         88 888888 888888
+     */
+    int value = 1;
+    switch (orientation) {
+        case 90:
+            value = 6;
+            break;
+        case 180:
+            value = 3;
+            break;
+        case 270:
+            value = 8;
+            break;
+        default:
+            break;
+    }
+    SET_SHORT(EXIF_IFD_0, EXIF_TAG_ORIENTATION, value);
+    return true;
+}
+
+bool ExifUtilsImpl::setResolutionUnit(uint16_t resolution_unit) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_RESOLUTION_UNIT, resolution_unit);
+    return true;
+}
+
+bool ExifUtilsImpl::setSaturation(uint16_t saturation) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SATURATION, saturation);
+    return true;
+}
+
+bool ExifUtilsImpl::setSceneCaptureType(uint16_t type) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, type);
+    return true;
+}
+
+bool ExifUtilsImpl::setSharpness(uint16_t sharpness) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SHARPNESS, sharpness);
+    return true;
+}
+
+bool ExifUtilsImpl::setShutterSpeed(int32_t numerator, int32_t denominator) {
+    SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setSubjectDistance(uint32_t numerator, uint32_t denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setSubsecTime(const std::string& subsec_time) {
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME, EXIF_FORMAT_ASCII, subsec_time);
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_ORIGINAL, EXIF_FORMAT_ASCII, subsec_time);
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_DIGITIZED, EXIF_FORMAT_ASCII, subsec_time);
+    return true;
+}
+
+bool ExifUtilsImpl::setWhiteBalance(uint16_t white_balance) {
+    SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, white_balance);
+    return true;
+}
+
+bool ExifUtilsImpl::setXResolution(uint32_t numerator, uint32_t denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_X_RESOLUTION, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::setYCbCrPositioning(uint16_t ycbcr_positioning) {
+    SET_SHORT(EXIF_IFD_0, EXIF_TAG_YCBCR_POSITIONING, ycbcr_positioning);
+    return true;
+}
+
+bool ExifUtilsImpl::setYResolution(uint32_t numerator, uint32_t denominator) {
+    SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_Y_RESOLUTION, numerator, denominator);
+    return true;
+}
+
+bool ExifUtilsImpl::generateApp1(const void* thumbnail_buffer, uint32_t size) {
+    destroyApp1();
+    exif_data_->data = const_cast<uint8_t*>(static_cast<const uint8_t*>(thumbnail_buffer));
+    exif_data_->size = size;
+    // Save the result into |app1_buffer_|.
+    exif_data_save_data(exif_data_, &app1_buffer_, &app1_length_);
+    if (!app1_length_) {
+        ALOGE("%s: Allocate memory for app1_buffer_ failed", __FUNCTION__);
+        return false;
+    }
+    /*
+     * The JPEG segment size is 16 bits in spec. The size of APP1 segment should
+     * be smaller than 65533 because there are two bytes for segment size field.
+     */
+    if (app1_length_ > 65533) {
+        destroyApp1();
+        ALOGE("%s: The size of APP1 segment is too large", __FUNCTION__);
+        return false;
+    }
+    return true;
+}
+
+const uint8_t* ExifUtilsImpl::getApp1Buffer() {
+    return app1_buffer_;
+}
+
+unsigned int ExifUtilsImpl::getApp1Length() {
+    return app1_length_;
+}
+
+bool ExifUtilsImpl::setExifVersion(const std::string& exif_version) {
+    SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_EXIF_VERSION, EXIF_FORMAT_UNDEFINED, exif_version);
+    return true;
+}
+
+bool ExifUtilsImpl::setMake(const std::string& make) {
+    SET_STRING(EXIF_IFD_0, EXIF_TAG_MAKE, EXIF_FORMAT_ASCII, make);
+    return true;
+}
+
+bool ExifUtilsImpl::setModel(const std::string& model) {
+    SET_STRING(EXIF_IFD_0, EXIF_TAG_MODEL, EXIF_FORMAT_ASCII, model);
+    return true;
+}
+
+void ExifUtilsImpl::reset() {
+    destroyApp1();
+    if (exif_data_) {
+        /*
+         * Since we decided to ignore the original APP1, we are sure that there is
+         * no thumbnail allocated by libexif. |exif_data_->data| is actually
+         * allocated by JpegCompressor. sets |exif_data_->data| to nullptr to
+         * prevent exif_data_unref() destroy it incorrectly.
+         */
+        exif_data_->data = nullptr;
+        exif_data_->size = 0;
+        exif_data_unref(exif_data_);
+        exif_data_ = nullptr;
+    }
+}
+
+std::unique_ptr<ExifEntry> ExifUtilsImpl::addVariableLengthEntry(ExifIfd ifd, ExifTag tag,
+                                                                 ExifFormat format,
+                                                                 uint64_t components,
+                                                                 unsigned int size) {
+    // Remove old entry if exists.
+    exif_content_remove_entry(exif_data_->ifd[ifd],
+                              exif_content_get_entry(exif_data_->ifd[ifd], tag));
+    ExifMem* mem = exif_mem_new_default();
+    if (!mem) {
+        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+        return nullptr;
+    }
+    std::unique_ptr<ExifEntry> entry(exif_entry_new_mem(mem));
+    if (!entry) {
+        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+        exif_mem_unref(mem);
+        return nullptr;
+    }
+    void* tmpBuffer = exif_mem_alloc(mem, size);
+    if (!tmpBuffer) {
+        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+        exif_mem_unref(mem);
+        return nullptr;
+    }
+
+    entry->data = static_cast<unsigned char*>(tmpBuffer);
+    entry->tag = tag;
+    entry->format = format;
+    entry->components = components;
+    entry->size = size;
+
+    exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
+    exif_mem_unref(mem);
+
+    return entry;
+}
+
+std::unique_ptr<ExifEntry> ExifUtilsImpl::addEntry(ExifIfd ifd, ExifTag tag) {
+    std::unique_ptr<ExifEntry> entry(exif_content_get_entry(exif_data_->ifd[ifd], tag));
+    if (entry) {
+        // exif_content_get_entry() won't ref the entry, so we ref here.
+        exif_entry_ref(entry.get());
+        return entry;
+    }
+    entry.reset(exif_entry_new());
+    if (!entry) {
+        ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+        return nullptr;
+    }
+    entry->tag = tag;
+    exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
+    exif_entry_initialize(entry.get(), tag);
+    return entry;
+}
+
+bool ExifUtilsImpl::setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg) {
+    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, value);
+    return true;
+}
+
+bool ExifUtilsImpl::setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg) {
+    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    exif_set_long(entry->data, EXIF_BYTE_ORDER_INTEL, value);
+    return true;
+}
+
+bool ExifUtilsImpl::setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator, uint32_t denominator,
+                                const std::string& msg) {
+    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
+    return true;
+}
+
+bool ExifUtilsImpl::setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator, int32_t denominator,
+                                 const std::string& msg) {
+    std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    exif_set_srational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
+    return true;
+}
+
+bool ExifUtilsImpl::setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
+                              const std::string& buffer, const std::string& msg) {
+    size_t entry_size = buffer.length();
+    // Since the exif format is undefined, NULL termination is not necessary.
+    if (format == EXIF_FORMAT_ASCII) {
+        entry_size++;
+    }
+    std::unique_ptr<ExifEntry> entry =
+            addVariableLengthEntry(ifd, tag, format, entry_size, entry_size);
+    if (!entry) {
+        ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+        return false;
+    }
+    memcpy(entry->data, buffer.c_str(), entry_size);
+    return true;
+}
+
+void ExifUtilsImpl::destroyApp1() {
+    /*
+     * Since there is no API to access ExifMem in ExifData->priv, we use free
+     * here, which is the default free function in libexif. See
+     * exif_data_save_data() for detail.
+     */
+    free(app1_buffer_);
+    app1_buffer_ = nullptr;
+    app1_length_ = 0;
+}
+
+bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata, const size_t imageWidth,
+                                    const size_t imageHeight) {
+    // How precise the float-to-rational conversion for EXIF tags would be.
+    constexpr int kRationalPrecision = 10000;
+    if (!setImageWidth(imageWidth) || !setImageHeight(imageHeight)) {
+        ALOGE("%s: setting image resolution failed.", __FUNCTION__);
+        return false;
+    }
+
+    struct timespec tp;
+    struct tm time_info;
+    bool time_available = clock_gettime(CLOCK_REALTIME, &tp) != -1;
+    localtime_r(&tp.tv_sec, &time_info);
+    if (!setDateTime(time_info)) {
+        ALOGE("%s: setting data time failed.", __FUNCTION__);
+        return false;
+    }
+
+    float focal_length;
+    camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH);
+    if (entry.count) {
+        focal_length = entry.data.f[0];
+
+        if (!setFocalLength(static_cast<uint32_t>(focal_length * kRationalPrecision),
+                            kRationalPrecision)) {
+            ALOGE("%s: setting focal length failed.", __FUNCTION__);
+            return false;
+        }
+    } else {
+        ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
+    }
+
+    if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
+        entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
+        if (entry.count < 3) {
+            ALOGE("%s: Gps coordinates in metadata is not complete.", __FUNCTION__);
+            return false;
+        }
+        if (!setGpsLatitude(entry.data.d[0])) {
+            ALOGE("%s: setting gps latitude failed.", __FUNCTION__);
+            return false;
+        }
+        if (!setGpsLongitude(entry.data.d[1])) {
+            ALOGE("%s: setting gps longitude failed.", __FUNCTION__);
+            return false;
+        }
+        if (!setGpsAltitude(entry.data.d[2])) {
+            ALOGE("%s: setting gps altitude failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
+        entry = metadata.find(ANDROID_JPEG_GPS_PROCESSING_METHOD);
+        std::string method_str(reinterpret_cast<const char*>(entry.data.u8));
+        if (!setGpsProcessingMethod(method_str)) {
+            ALOGE("%s: setting gps processing method failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (time_available && metadata.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
+        entry = metadata.find(ANDROID_JPEG_GPS_TIMESTAMP);
+        time_t timestamp = static_cast<time_t>(entry.data.i64[0]);
+        if (gmtime_r(&timestamp, &time_info)) {
+            if (!setGpsTimestamp(time_info)) {
+                ALOGE("%s: setting gps timestamp failed.", __FUNCTION__);
+                return false;
+            }
+        } else {
+            ALOGE("%s: Time tranformation failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_JPEG_ORIENTATION)) {
+        entry = metadata.find(ANDROID_JPEG_ORIENTATION);
+        if (!setOrientation(entry.data.i32[0])) {
+            ALOGE("%s: setting orientation failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
+        entry = metadata.find(ANDROID_SENSOR_EXPOSURE_TIME);
+        // int64_t of nanoseconds
+        if (!setExposureTime(entry.data.i64[0], 1000000000u)) {
+            ALOGE("%s: setting exposure time failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_LENS_APERTURE)) {
+        const int kAperturePrecision = 10000;
+        entry = metadata.find(ANDROID_LENS_APERTURE);
+        if (!setFNumber(entry.data.f[0] * kAperturePrecision, kAperturePrecision)) {
+            ALOGE("%s: setting F number failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
+        entry = metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
+        if (entry.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_FALSE) {
+            const uint32_t kNoFlashFunction = 0x20;
+            if (!setFlash(kNoFlashFunction)) {
+                ALOGE("%s: setting flash failed.", __FUNCTION__);
+                return false;
+            }
+        } else {
+            ALOGE("%s: Unsupported flash info: %d", __FUNCTION__, entry.data.u8[0]);
+            return false;
+        }
+    }
+
+    if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
+        entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
+        if (entry.data.u8[0] == ANDROID_CONTROL_AWB_MODE_AUTO) {
+            const uint16_t kAutoWhiteBalance = 0;
+            if (!setWhiteBalance(kAutoWhiteBalance)) {
+                ALOGE("%s: setting white balance failed.", __FUNCTION__);
+                return false;
+            }
+        } else {
+            ALOGE("%s: Unsupported awb mode: %d", __FUNCTION__, entry.data.u8[0]);
+            return false;
+        }
+    }
+
+    if (time_available) {
+        char str[4];
+        if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {
+            ALOGE("%s: Subsec is invalid: %ld", __FUNCTION__, tp.tv_nsec);
+            return false;
+        }
+        if (!setSubsecTime(std::string(str))) {
+            ALOGE("%s: setting subsec time failed.", __FUNCTION__);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+}  // namespace helper
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/common/default/HandleImporter.cpp b/camera/common/default/HandleImporter.cpp
new file mode 100644
index 0000000..1145baa
--- /dev/null
+++ b/camera/common/default/HandleImporter.cpp
@@ -0,0 +1,530 @@
+/*
+ * Copyright (C) 2017 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 "HandleImporter"
+#include "HandleImporter.h"
+
+#include <gralloctypes/Gralloc4.h>
+#include <log/log.h>
+#include "aidl/android/hardware/graphics/common/Smpte2086.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using aidl::android::hardware::graphics::common::Smpte2086;
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
+using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
+using MapperErrorV4 = android::hardware::graphics::mapper::V4_0::Error;
+using IMapperV3 = android::hardware::graphics::mapper::V3_0::IMapper;
+using IMapperV4 = android::hardware::graphics::mapper::V4_0::IMapper;
+
+HandleImporter::HandleImporter() : mInitialized(false) {}
+
+void HandleImporter::initializeLocked() {
+    if (mInitialized) {
+        return;
+    }
+
+    mMapperV4 = IMapperV4::getService();
+    if (mMapperV4 != nullptr) {
+        mInitialized = true;
+        return;
+    }
+
+    mMapperV3 = IMapperV3::getService();
+    if (mMapperV3 != nullptr) {
+        mInitialized = true;
+        return;
+    }
+
+    mMapperV2 = IMapper::getService();
+    if (mMapperV2 == nullptr) {
+        ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
+        return;
+    }
+
+    mInitialized = true;
+    return;
+}
+
+void HandleImporter::cleanup() {
+    mMapperV4.clear();
+    mMapperV3.clear();
+    mMapperV2.clear();
+    mInitialized = false;
+}
+
+template <class M, class E>
+bool HandleImporter::importBufferInternal(const sp<M> mapper, buffer_handle_t& handle) {
+    E error;
+    buffer_handle_t importedHandle;
+    auto ret = mapper->importBuffer(
+            hidl_handle(handle), [&](const auto& tmpError, const auto& tmpBufferHandle) {
+                error = tmpError;
+                importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
+            });
+
+    if (!ret.isOk()) {
+        ALOGE("%s: mapper importBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+        return false;
+    }
+
+    if (error != E::NONE) {
+        return false;
+    }
+
+    handle = importedHandle;
+    return true;
+}
+
+template <class M, class E>
+YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf,
+                                              uint64_t cpuUsage,
+                                              const IMapper::Rect& accessRegion) {
+    hidl_handle acquireFenceHandle;
+    auto buffer = const_cast<native_handle_t*>(buf);
+    YCbCrLayout layout = {};
+
+    typename M::Rect accessRegionCopy = {accessRegion.left, accessRegion.top, accessRegion.width,
+                                         accessRegion.height};
+    mapper->lockYCbCr(buffer, cpuUsage, accessRegionCopy, acquireFenceHandle,
+                      [&](const auto& tmpError, const auto& tmpLayout) {
+                          if (tmpError == E::NONE) {
+                              // Member by member copy from different versions of YCbCrLayout.
+                              layout.y = tmpLayout.y;
+                              layout.cb = tmpLayout.cb;
+                              layout.cr = tmpLayout.cr;
+                              layout.yStride = tmpLayout.yStride;
+                              layout.cStride = tmpLayout.cStride;
+                              layout.chromaStep = tmpLayout.chromaStep;
+                          } else {
+                              ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
+                          }
+                      });
+    return layout;
+}
+
+bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf,
+                      MetadataType metadataType) {
+    auto buffer = const_cast<native_handle_t*>(buf);
+    bool ret = false;
+    hidl_vec<uint8_t> vec;
+    mapper->get(buffer, metadataType, [&](const auto& tmpError, const auto& tmpMetadata) {
+        if (tmpError == MapperErrorV4::NONE) {
+            vec = tmpMetadata;
+        } else {
+            ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError);
+        }
+    });
+
+    if (vec.size() > 0) {
+        if (metadataType == gralloc4::MetadataType_Smpte2086) {
+            std::optional<Smpte2086> realSmpte2086;
+            gralloc4::decodeSmpte2086(vec, &realSmpte2086);
+            ret = realSmpte2086.has_value();
+        } else if (metadataType == gralloc4::MetadataType_Smpte2094_10) {
+            std::optional<std::vector<uint8_t>> realSmpte2094_10;
+            gralloc4::decodeSmpte2094_10(vec, &realSmpte2094_10);
+            ret = realSmpte2094_10.has_value();
+        } else if (metadataType == gralloc4::MetadataType_Smpte2094_40) {
+            std::optional<std::vector<uint8_t>> realSmpte2094_40;
+            gralloc4::decodeSmpte2094_40(vec, &realSmpte2094_40);
+            ret = realSmpte2094_40.has_value();
+        } else {
+            ALOGE("%s: Unknown metadata type!", __FUNCTION__);
+        }
+    }
+
+    return ret;
+}
+
+std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) {
+    auto buffer = const_cast<native_handle_t*>(buf);
+    std::vector<PlaneLayout> planeLayouts;
+    hidl_vec<uint8_t> encodedPlaneLayouts;
+    mapper->get(buffer, gralloc4::MetadataType_PlaneLayouts,
+                [&](const auto& tmpError, const auto& tmpEncodedPlaneLayouts) {
+                    if (tmpError == MapperErrorV4::NONE) {
+                        encodedPlaneLayouts = tmpEncodedPlaneLayouts;
+                    } else {
+                        ALOGE("%s: failed to get plane layouts %d!", __FUNCTION__, tmpError);
+                    }
+                });
+
+    gralloc4::decodePlaneLayouts(encodedPlaneLayouts, &planeLayouts);
+
+    return planeLayouts;
+}
+
+template <>
+YCbCrLayout HandleImporter::lockYCbCrInternal<IMapperV4, MapperErrorV4>(
+        const sp<IMapperV4> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
+        const IMapper::Rect& accessRegion) {
+    hidl_handle acquireFenceHandle;
+    auto buffer = const_cast<native_handle_t*>(buf);
+    YCbCrLayout layout = {};
+    void* mapped = nullptr;
+
+    typename IMapperV4::Rect accessRegionV4 = {accessRegion.left, accessRegion.top,
+                                               accessRegion.width, accessRegion.height};
+    mapper->lock(buffer, cpuUsage, accessRegionV4, acquireFenceHandle,
+                 [&](const auto& tmpError, const auto& tmpPtr) {
+                     if (tmpError == MapperErrorV4::NONE) {
+                         mapped = tmpPtr;
+                     } else {
+                         ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
+                     }
+                 });
+
+    if (mapped == nullptr) {
+        return layout;
+    }
+
+    std::vector<PlaneLayout> planeLayouts = getPlaneLayouts(mapper, buf);
+    for (const auto& planeLayout : planeLayouts) {
+        for (const auto& planeLayoutComponent : planeLayout.components) {
+            const auto& type = planeLayoutComponent.type;
+
+            if (!gralloc4::isStandardPlaneLayoutComponentType(type)) {
+                continue;
+            }
+
+            uint8_t* data = reinterpret_cast<uint8_t*>(mapped);
+            data += planeLayout.offsetInBytes;
+            data += planeLayoutComponent.offsetInBits / 8;
+
+            switch (static_cast<PlaneLayoutComponentType>(type.value)) {
+                case PlaneLayoutComponentType::Y:
+                    layout.y = data;
+                    layout.yStride = planeLayout.strideInBytes;
+                    break;
+                case PlaneLayoutComponentType::CB:
+                    layout.cb = data;
+                    layout.cStride = planeLayout.strideInBytes;
+                    layout.chromaStep = planeLayout.sampleIncrementInBits / 8;
+                    break;
+                case PlaneLayoutComponentType::CR:
+                    layout.cr = data;
+                    layout.cStride = planeLayout.strideInBytes;
+                    layout.chromaStep = planeLayout.sampleIncrementInBits / 8;
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    return layout;
+}
+
+template <class M, class E>
+int HandleImporter::unlockInternal(const sp<M> mapper, buffer_handle_t& buf) {
+    int releaseFence = -1;
+    auto buffer = const_cast<native_handle_t*>(buf);
+
+    mapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+        if (tmpError == E::NONE) {
+            auto fenceHandle = tmpReleaseFence.getNativeHandle();
+            if (fenceHandle) {
+                if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
+                    ALOGE("%s: bad release fence numInts %d numFds %d", __FUNCTION__,
+                          fenceHandle->numInts, fenceHandle->numFds);
+                    return;
+                }
+                releaseFence = dup(fenceHandle->data[0]);
+                if (releaseFence < 0) {
+                    ALOGE("%s: bad release fence FD %d", __FUNCTION__, releaseFence);
+                }
+            }
+        } else {
+            ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
+        }
+    });
+    return releaseFence;
+}
+
+// In IComposer, any buffer_handle_t is owned by the caller and we need to
+// make a clone for hwcomposer2.  We also need to translate empty handle
+// to nullptr.  This function does that, in-place.
+bool HandleImporter::importBuffer(buffer_handle_t& handle) {
+    if (!handle->numFds && !handle->numInts) {
+        handle = nullptr;
+        return true;
+    }
+
+    Mutex::Autolock lock(mLock);
+    if (!mInitialized) {
+        initializeLocked();
+    }
+
+    if (mMapperV4 != nullptr) {
+        return importBufferInternal<IMapperV4, MapperErrorV4>(mMapperV4, handle);
+    }
+
+    if (mMapperV3 != nullptr) {
+        return importBufferInternal<IMapperV3, MapperErrorV3>(mMapperV3, handle);
+    }
+
+    if (mMapperV2 != nullptr) {
+        return importBufferInternal<IMapper, MapperErrorV2>(mMapperV2, handle);
+    }
+
+    ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
+    return false;
+}
+
+void HandleImporter::freeBuffer(buffer_handle_t handle) {
+    if (!handle) {
+        return;
+    }
+
+    Mutex::Autolock lock(mLock);
+    if (!mInitialized) {
+        initializeLocked();
+    }
+
+    if (mMapperV4 != nullptr) {
+        auto ret = mMapperV4->freeBuffer(const_cast<native_handle_t*>(handle));
+        if (!ret.isOk()) {
+            ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+        }
+    } else if (mMapperV3 != nullptr) {
+        auto ret = mMapperV3->freeBuffer(const_cast<native_handle_t*>(handle));
+        if (!ret.isOk()) {
+            ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+        }
+    } else {
+        auto ret = mMapperV2->freeBuffer(const_cast<native_handle_t*>(handle));
+        if (!ret.isOk()) {
+            ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+        }
+    }
+}
+
+bool HandleImporter::importFence(const native_handle_t* handle, int& fd) const {
+    if (handle == nullptr || handle->numFds == 0) {
+        fd = -1;
+    } else if (handle->numFds == 1) {
+        fd = dup(handle->data[0]);
+        if (fd < 0) {
+            ALOGE("failed to dup fence fd %d", handle->data[0]);
+            return false;
+        }
+    } else {
+        ALOGE("invalid fence handle with %d file descriptors", handle->numFds);
+        return false;
+    }
+
+    return true;
+}
+
+void HandleImporter::closeFence(int fd) const {
+    if (fd >= 0) {
+        close(fd);
+    }
+}
+
+void* HandleImporter::lock(buffer_handle_t& buf, uint64_t cpuUsage, size_t size) {
+    IMapper::Rect accessRegion{0, 0, static_cast<int>(size), 1};
+    return lock(buf, cpuUsage, accessRegion);
+}
+
+void* HandleImporter::lock(buffer_handle_t& buf, uint64_t cpuUsage,
+                           const IMapper::Rect& accessRegion) {
+    Mutex::Autolock lock(mLock);
+
+    if (!mInitialized) {
+        initializeLocked();
+    }
+
+    void* ret = nullptr;
+
+    if (mMapperV4 == nullptr && mMapperV3 == nullptr && mMapperV2 == nullptr) {
+        ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
+        return ret;
+    }
+
+    hidl_handle acquireFenceHandle;
+    auto buffer = const_cast<native_handle_t*>(buf);
+    if (mMapperV4 != nullptr) {
+        IMapperV4::Rect accessRegionV4{accessRegion.left, accessRegion.top, accessRegion.width,
+                                       accessRegion.height};
+
+        mMapperV4->lock(buffer, cpuUsage, accessRegionV4, acquireFenceHandle,
+                        [&](const auto& tmpError, const auto& tmpPtr) {
+                            if (tmpError == MapperErrorV4::NONE) {
+                                ret = tmpPtr;
+                            } else {
+                                ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
+                            }
+                        });
+    } else if (mMapperV3 != nullptr) {
+        IMapperV3::Rect accessRegionV3{accessRegion.left, accessRegion.top, accessRegion.width,
+                                       accessRegion.height};
+
+        mMapperV3->lock(buffer, cpuUsage, accessRegionV3, acquireFenceHandle,
+                        [&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
+                            const auto& /*bytesPerStride*/) {
+                            if (tmpError == MapperErrorV3::NONE) {
+                                ret = tmpPtr;
+                            } else {
+                                ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
+                            }
+                        });
+    } else {
+        mMapperV2->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+                        [&](const auto& tmpError, const auto& tmpPtr) {
+                            if (tmpError == MapperErrorV2::NONE) {
+                                ret = tmpPtr;
+                            } else {
+                                ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
+                            }
+                        });
+    }
+
+    ALOGV("%s: ptr %p accessRegion.top: %d accessRegion.left: %d accessRegion.width: %d "
+          "accessRegion.height: %d",
+          __FUNCTION__, ret, accessRegion.top, accessRegion.left, accessRegion.width,
+          accessRegion.height);
+    return ret;
+}
+
+YCbCrLayout HandleImporter::lockYCbCr(buffer_handle_t& buf, uint64_t cpuUsage,
+                                      const IMapper::Rect& accessRegion) {
+    Mutex::Autolock lock(mLock);
+
+    if (!mInitialized) {
+        initializeLocked();
+    }
+
+    if (mMapperV4 != nullptr) {
+        return lockYCbCrInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf, cpuUsage, accessRegion);
+    }
+
+    if (mMapperV3 != nullptr) {
+        return lockYCbCrInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf, cpuUsage, accessRegion);
+    }
+
+    if (mMapperV2 != nullptr) {
+        return lockYCbCrInternal<IMapper, MapperErrorV2>(mMapperV2, buf, cpuUsage, accessRegion);
+    }
+
+    ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
+    return {};
+}
+
+status_t HandleImporter::getMonoPlanarStrideBytes(buffer_handle_t& buf, uint32_t* stride /*out*/) {
+    if (stride == nullptr) {
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mLock);
+
+    if (!mInitialized) {
+        initializeLocked();
+    }
+
+    if (mMapperV4 != nullptr) {
+        std::vector<PlaneLayout> planeLayouts = getPlaneLayouts(mMapperV4, buf);
+        if (planeLayouts.size() != 1) {
+            ALOGE("%s: Unexpected number of planes %zu!", __FUNCTION__, planeLayouts.size());
+            return BAD_VALUE;
+        }
+
+        *stride = planeLayouts[0].strideInBytes;
+    } else {
+        ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+        return NO_INIT;
+    }
+
+    return OK;
+}
+
+int HandleImporter::unlock(buffer_handle_t& buf) {
+    if (mMapperV4 != nullptr) {
+        return unlockInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf);
+    }
+    if (mMapperV3 != nullptr) {
+        return unlockInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf);
+    }
+    if (mMapperV2 != nullptr) {
+        return unlockInternal<IMapper, MapperErrorV2>(mMapperV2, buf);
+    }
+
+    ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
+    return -1;
+}
+
+bool HandleImporter::isSmpte2086Present(const buffer_handle_t& buf) {
+    Mutex::Autolock lock(mLock);
+
+    if (!mInitialized) {
+        initializeLocked();
+    }
+
+    if (mMapperV4 != nullptr) {
+        return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2086);
+    } else {
+        ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+    }
+
+    return false;
+}
+
+bool HandleImporter::isSmpte2094_10Present(const buffer_handle_t& buf) {
+    Mutex::Autolock lock(mLock);
+
+    if (!mInitialized) {
+        initializeLocked();
+    }
+
+    if (mMapperV4 != nullptr) {
+        return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_10);
+    } else {
+        ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+    }
+
+    return false;
+}
+
+bool HandleImporter::isSmpte2094_40Present(const buffer_handle_t& buf) {
+    Mutex::Autolock lock(mLock);
+
+    if (!mInitialized) {
+        initializeLocked();
+    }
+
+    if (mMapperV4 != nullptr) {
+        return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_40);
+    } else {
+        ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+    }
+
+    return false;
+}
+
+}  // namespace helper
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/common/default/SimpleThread.cpp b/camera/common/default/SimpleThread.cpp
new file mode 100644
index 0000000..46e89ba
--- /dev/null
+++ b/camera/common/default/SimpleThread.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SimpleThread.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+SimpleThread::SimpleThread() : mDone(true), mThread() {}
+SimpleThread::~SimpleThread() {
+    // Safe to call requestExitAndWait() from the destructor because requestExitAndWait() ensures
+    // that the thread is joinable before joining on it. This is different from how
+    // android::Thread worked.
+    requestExitAndWait();
+}
+
+void SimpleThread::run() {
+    requestExitAndWait();  // Exit current execution, if any.
+
+    // start thread
+    mDone.store(false, std::memory_order_release);
+    mThread = std::thread(&SimpleThread::runLoop, this);
+}
+
+void SimpleThread::requestExitAndWait() {
+    // Signal thread to stop
+    mDone.store(true, std::memory_order_release);
+
+    // Wait for thread to exit if needed. This should happen in no more than one iteration of
+    // threadLoop
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+    mThread = std::thread();
+}
+
+void SimpleThread::runLoop() {
+    while (!exitPending()) {
+        if (!threadLoop()) {
+            break;
+        }
+    }
+}
+
+}  // namespace helper
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/camera/common/default/VendorTagDescriptor.cpp b/camera/common/default/VendorTagDescriptor.cpp
new file mode 100644
index 0000000..1282bd0
--- /dev/null
+++ b/camera/common/default/VendorTagDescriptor.cpp
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2016 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 "CamComm1.0-VTDesc"
+
+#include <camera_metadata_hidden.h>
+#include <log/log.h>
+#include <system/camera_metadata.h>
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+#include <utils/SortedVector.h>
+#include <utils/Vector.h>
+
+#include "VendorTagDescriptor.h"
+
+#include <stdio.h>
+#include <string.h>
+
+namespace android {
+namespace hardware {
+namespace camera2 {
+namespace params {
+
+VendorTagDescriptor::~VendorTagDescriptor() {
+    size_t len = mReverseMapping.size();
+    for (size_t i = 0; i < len; ++i) {
+        delete mReverseMapping[i];
+    }
+}
+
+VendorTagDescriptor::VendorTagDescriptor() : mTagCount(0), mVendorOps() {}
+
+VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
+    copyFrom(src);
+}
+
+VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
+    copyFrom(rhs);
+    return *this;
+}
+
+void VendorTagDescriptor::copyFrom(const VendorTagDescriptor& src) {
+    if (this == &src) return;
+
+    size_t len = mReverseMapping.size();
+    for (size_t i = 0; i < len; ++i) {
+        delete mReverseMapping[i];
+    }
+    mReverseMapping.clear();
+
+    len = src.mReverseMapping.size();
+    // Have to copy KeyedVectors inside mReverseMapping
+    for (size_t i = 0; i < len; ++i) {
+        KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+        *nameMapper = *(src.mReverseMapping.valueAt(i));
+        mReverseMapping.add(src.mReverseMapping.keyAt(i), nameMapper);
+    }
+    // Everything else is simple
+    mTagToNameMap = src.mTagToNameMap;
+    mTagToSectionMap = src.mTagToSectionMap;
+    mTagToTypeMap = src.mTagToTypeMap;
+    mSections = src.mSections;
+    mTagCount = src.mTagCount;
+    mVendorOps = src.mVendorOps;
+}
+
+int VendorTagDescriptor::getTagCount() const {
+    size_t size = mTagToNameMap.size();
+    if (size == 0) {
+        return VENDOR_TAG_COUNT_ERR;
+    }
+    return size;
+}
+
+void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
+    size_t size = mTagToNameMap.size();
+    for (size_t i = 0; i < size; ++i) {
+        tagArray[i] = mTagToNameMap.keyAt(i);
+    }
+}
+
+const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
+    ssize_t index = mTagToSectionMap.indexOfKey(tag);
+    if (index < 0) {
+        return VENDOR_SECTION_NAME_ERR;
+    }
+    return mSections[mTagToSectionMap.valueAt(index)].string();
+}
+
+ssize_t VendorTagDescriptor::getSectionIndex(uint32_t tag) const {
+    return mTagToSectionMap.valueFor(tag);
+}
+
+const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
+    ssize_t index = mTagToNameMap.indexOfKey(tag);
+    if (index < 0) {
+        return VENDOR_TAG_NAME_ERR;
+    }
+    return mTagToNameMap.valueAt(index).string();
+}
+
+int VendorTagDescriptor::getTagType(uint32_t tag) const {
+    auto iter = mTagToTypeMap.find(tag);
+    if (iter == mTagToTypeMap.end()) {
+        return VENDOR_TAG_TYPE_ERR;
+    }
+    return iter->second;
+}
+
+const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const {
+    return &mSections;
+}
+
+status_t VendorTagDescriptor::lookupTag(const String8& name, const String8& section,
+                                        /*out*/ uint32_t* tag) const {
+    ssize_t index = mReverseMapping.indexOfKey(section);
+    if (index < 0) {
+        ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string());
+        return BAD_VALUE;
+    }
+
+    ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
+    if (nameIndex < 0) {
+        ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string());
+        return BAD_VALUE;
+    }
+
+    if (tag != NULL) {
+        *tag = mReverseMapping[index]->valueAt(nameIndex);
+    }
+    return OK;
+}
+
+void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
+    size_t size = mTagToNameMap.size();
+    if (size == 0) {
+        dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n", indentation, "");
+        return;
+    }
+
+    dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n", indentation, "",
+            size);
+    for (size_t i = 0; i < size; ++i) {
+        uint32_t tag = mTagToNameMap.keyAt(i);
+
+        if (verbosity < 1) {
+            dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
+            continue;
+        }
+        String8 name = mTagToNameMap.valueAt(i);
+        uint32_t sectionId = mTagToSectionMap.valueFor(tag);
+        String8 sectionName = mSections[sectionId];
+        int type = mTagToTypeMap.at(tag);
+        const char* typeName =
+                (type >= 0 && type < NUM_TYPES) ? camera_metadata_type_names[type] : "UNKNOWN";
+        dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2, "",
+                tag, name.string(), type, typeName, sectionName.string());
+    }
+}
+
+int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
+    int ret = 0;
+    auto desc = mVendorMap.find(id);
+    if (desc != mVendorMap.end()) {
+        ret = desc->second->getTagCount();
+    } else {
+        ALOGE("%s: Vendor descriptor id is missing!", __func__);
+    }
+
+    return ret;
+}
+
+void VendorTagDescriptorCache::getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const {
+    auto desc = mVendorMap.find(id);
+    if (desc != mVendorMap.end()) {
+        desc->second->getTagArray(tagArray);
+    } else {
+        ALOGE("%s: Vendor descriptor id is missing!", __func__);
+    }
+}
+
+const char* VendorTagDescriptorCache::getSectionName(uint32_t tag, metadata_vendor_id_t id) const {
+    const char* ret = nullptr;
+    auto desc = mVendorMap.find(id);
+    if (desc != mVendorMap.end()) {
+        ret = desc->second->getSectionName(tag);
+    } else {
+        ALOGE("%s: Vendor descriptor id is missing!", __func__);
+    }
+
+    return ret;
+}
+
+const char* VendorTagDescriptorCache::getTagName(uint32_t tag, metadata_vendor_id_t id) const {
+    const char* ret = nullptr;
+    auto desc = mVendorMap.find(id);
+    if (desc != mVendorMap.end()) {
+        ret = desc->second->getTagName(tag);
+    } else {
+        ALOGE("%s: Vendor descriptor id is missing!", __func__);
+    }
+
+    return ret;
+}
+
+int VendorTagDescriptorCache::getTagType(uint32_t tag, metadata_vendor_id_t id) const {
+    int ret = 0;
+    auto desc = mVendorMap.find(id);
+    if (desc != mVendorMap.end()) {
+        ret = desc->second->getTagType(tag);
+    } else {
+        ALOGE("%s: Vendor descriptor id is missing!", __func__);
+    }
+
+    return ret;
+}
+
+void VendorTagDescriptorCache::dump(int fd, int verbosity, int indentation) const {
+    for (const auto& desc : mVendorMap) {
+        desc.second->dump(fd, verbosity, indentation);
+    }
+}
+
+int32_t VendorTagDescriptorCache::addVendorDescriptor(
+        metadata_vendor_id_t id, sp<hardware::camera::common::helper::VendorTagDescriptor> desc) {
+    auto entry = mVendorMap.find(id);
+    if (entry != mVendorMap.end()) {
+        ALOGE("%s: Vendor descriptor with same id already present!", __func__);
+        return BAD_VALUE;
+    }
+
+    mVendorMap.emplace(id, desc);
+    return NO_ERROR;
+}
+
+int32_t VendorTagDescriptorCache::getVendorTagDescriptor(
+        metadata_vendor_id_t id,
+        sp<hardware::camera::common::helper::VendorTagDescriptor>* desc /*out*/) {
+    auto entry = mVendorMap.find(id);
+    if (entry == mVendorMap.end()) {
+        return NAME_NOT_FOUND;
+    }
+
+    *desc = entry->second;
+
+    return NO_ERROR;
+}
+}  // namespace params
+}  // namespace camera2
+
+namespace camera {
+namespace common {
+namespace helper {
+
+extern "C" {
+
+static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
+static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
+static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
+static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
+static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
+
+static int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id);
+static void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id);
+static const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
+                                                                metadata_vendor_id_t id);
+static const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id);
+static int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id);
+} /* extern "C" */
+
+static Mutex sLock;
+static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
+static sp<VendorTagDescriptorCache> sGlobalVendorTagDescriptorCache;
+
+status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
+                                                      /*out*/
+                                                      sp<VendorTagDescriptor>& descriptor) {
+    if (vOps == NULL) {
+        ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    int tagCount = vOps->get_tag_count(vOps);
+    if (tagCount < 0 || tagCount > INT32_MAX) {
+        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
+        return BAD_VALUE;
+    }
+
+    Vector<uint32_t> tagArray;
+    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
+                        "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
+
+    vOps->get_all_tags(vOps, /*out*/ tagArray.editArray());
+
+    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
+    desc->mTagCount = tagCount;
+
+    SortedVector<String8> sections;
+    KeyedVector<uint32_t, String8> tagToSectionMap;
+
+    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
+        uint32_t tag = tagArray[i];
+        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
+            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
+            return BAD_VALUE;
+        }
+        const char* tagName = vOps->get_tag_name(vOps, tag);
+        if (tagName == NULL) {
+            ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
+            return BAD_VALUE;
+        }
+        desc->mTagToNameMap.add(tag, String8(tagName));
+        const char* sectionName = vOps->get_section_name(vOps, tag);
+        if (sectionName == NULL) {
+            ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
+            return BAD_VALUE;
+        }
+
+        String8 sectionString(sectionName);
+
+        sections.add(sectionString);
+        tagToSectionMap.add(tag, sectionString);
+
+        int tagType = vOps->get_tag_type(vOps, tag);
+        if (tagType < 0 || tagType >= NUM_TYPES) {
+            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
+            return BAD_VALUE;
+        }
+        desc->mTagToTypeMap.insert(std::make_pair(tag, tagType));
+    }
+
+    desc->mSections = sections;
+
+    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
+        uint32_t tag = tagArray[i];
+        const String8& sectionString = tagToSectionMap.valueFor(tag);
+
+        // Set up tag to section index map
+        ssize_t index = sections.indexOf(sectionString);
+        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
+        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
+
+        // Set up reverse mapping
+        ssize_t reverseIndex = -1;
+        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
+            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
+        }
+        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
+    }
+
+    descriptor = desc;
+    return OK;
+}
+
+status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
+    status_t res = OK;
+    Mutex::Autolock al(sLock);
+    sGlobalVendorTagDescriptor = desc;
+
+    vendor_tag_ops_t* opsPtr = NULL;
+    if (desc != NULL) {
+        opsPtr = &(desc->mVendorOps);
+        opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
+        opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
+        opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
+        opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
+        opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
+    }
+    if ((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
+        ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d).", __FUNCTION__,
+              strerror(-res), res);
+    }
+    return res;
+}
+
+void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
+    Mutex::Autolock al(sLock);
+    set_camera_metadata_vendor_ops(NULL);
+    sGlobalVendorTagDescriptor.clear();
+}
+
+sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
+    Mutex::Autolock al(sLock);
+    return sGlobalVendorTagDescriptor;
+}
+
+status_t VendorTagDescriptorCache::setAsGlobalVendorTagCache(
+        const sp<VendorTagDescriptorCache>& cache) {
+    status_t res = OK;
+    Mutex::Autolock al(sLock);
+    sGlobalVendorTagDescriptorCache = cache;
+
+    struct vendor_tag_cache_ops* opsPtr = NULL;
+    if (cache != NULL) {
+        opsPtr = &(cache->mVendorCacheOps);
+        opsPtr->get_tag_count = vendor_tag_descriptor_cache_get_tag_count;
+        opsPtr->get_all_tags = vendor_tag_descriptor_cache_get_all_tags;
+        opsPtr->get_section_name = vendor_tag_descriptor_cache_get_section_name;
+        opsPtr->get_tag_name = vendor_tag_descriptor_cache_get_tag_name;
+        opsPtr->get_tag_type = vendor_tag_descriptor_cache_get_tag_type;
+    }
+    if ((res = set_camera_metadata_vendor_cache_ops(opsPtr)) != OK) {
+        ALOGE("%s: Could not set vendor tag cache, received error %s (%d).", __FUNCTION__,
+              strerror(-res), res);
+    }
+    return res;
+}
+
+void VendorTagDescriptorCache::clearGlobalVendorTagCache() {
+    Mutex::Autolock al(sLock);
+    set_camera_metadata_vendor_cache_ops(NULL);
+    sGlobalVendorTagDescriptorCache.clear();
+}
+
+sp<VendorTagDescriptorCache> VendorTagDescriptorCache::getGlobalVendorTagCache() {
+    Mutex::Autolock al(sLock);
+    return sGlobalVendorTagDescriptorCache;
+}
+
+extern "C" {
+
+int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptor == NULL) {
+        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+        return VENDOR_TAG_COUNT_ERR;
+    }
+    return sGlobalVendorTagDescriptor->getTagCount();
+}
+
+void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptor == NULL) {
+        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+        return;
+    }
+    sGlobalVendorTagDescriptor->getTagArray(tagArray);
+}
+
+const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptor == NULL) {
+        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+        return VENDOR_SECTION_NAME_ERR;
+    }
+    return sGlobalVendorTagDescriptor->getSectionName(tag);
+}
+
+const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptor == NULL) {
+        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+        return VENDOR_TAG_NAME_ERR;
+    }
+    return sGlobalVendorTagDescriptor->getTagName(tag);
+}
+
+int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptor == NULL) {
+        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+        return VENDOR_TAG_TYPE_ERR;
+    }
+    return sGlobalVendorTagDescriptor->getTagType(tag);
+}
+
+int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptorCache == NULL) {
+        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+        return VENDOR_TAG_COUNT_ERR;
+    }
+    return sGlobalVendorTagDescriptorCache->getTagCount(id);
+}
+
+void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptorCache == NULL) {
+        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+    }
+    sGlobalVendorTagDescriptorCache->getTagArray(tagArray, id);
+}
+
+const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag, metadata_vendor_id_t id) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptorCache == NULL) {
+        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+        return VENDOR_SECTION_NAME_ERR;
+    }
+    return sGlobalVendorTagDescriptorCache->getSectionName(tag, id);
+}
+
+const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptorCache == NULL) {
+        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+        return VENDOR_TAG_NAME_ERR;
+    }
+    return sGlobalVendorTagDescriptorCache->getTagName(tag, id);
+}
+
+int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id) {
+    Mutex::Autolock al(sLock);
+    if (sGlobalVendorTagDescriptorCache == NULL) {
+        ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+        return VENDOR_TAG_NAME_ERR;
+    }
+    return sGlobalVendorTagDescriptorCache->getTagType(tag, id);
+}
+
+} /* extern "C" */
+
+}  // namespace helper
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/common/default/include/CameraMetadata.h b/camera/common/default/include/CameraMetadata.h
new file mode 100644
index 0000000..b67914e
--- /dev/null
+++ b/camera/common/default/include/CameraMetadata.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2016 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 CAMERA_COMMON_1_0_CAMERAMETADATA_H
+#define CAMERA_COMMON_1_0_CAMERAMETADATA_H
+
+#include "system/camera_metadata.h"
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+class VendorTagDescriptor;
+
+/**
+ * A convenience wrapper around the C-based camera_metadata_t library.
+ */
+class CameraMetadata {
+  public:
+    /** Creates an empty object; best used when expecting to acquire contents
+     * from elsewhere */
+    CameraMetadata();
+    /** Creates an object with space for entryCapacity entries, with
+     * dataCapacity extra storage */
+    CameraMetadata(size_t entryCapacity, size_t dataCapacity = 10);
+
+    ~CameraMetadata();
+
+    /** Takes ownership of passed-in buffer */
+    CameraMetadata(camera_metadata_t* buffer);
+    /** Clones the metadata */
+    CameraMetadata(const CameraMetadata& other);
+
+    /**
+     * Assignment clones metadata buffer.
+     */
+    CameraMetadata& operator=(const CameraMetadata& other);
+    CameraMetadata& operator=(const camera_metadata_t* buffer);
+
+    /**
+     * Get reference to the underlying metadata buffer. Ownership remains with
+     * the CameraMetadata object, but non-const CameraMetadata methods will not
+     * work until unlock() is called. Note that the lock has nothing to do with
+     * thread-safety, it simply prevents the camera_metadata_t pointer returned
+     * here from being accidentally invalidated by CameraMetadata operations.
+     */
+    const camera_metadata_t* getAndLock() const;
+
+    /**
+     * Unlock the CameraMetadata for use again. After this unlock, the pointer
+     * given from getAndLock() may no longer be used. The pointer passed out
+     * from getAndLock must be provided to guarantee that the right object is
+     * being unlocked.
+     */
+    status_t unlock(const camera_metadata_t* buffer) const;
+
+    /**
+     * Release a raw metadata buffer to the caller. After this call,
+     * CameraMetadata no longer references the buffer, and the caller takes
+     * responsibility for freeing the raw metadata buffer (using
+     * free_camera_metadata()), or for handing it to another CameraMetadata
+     * instance.
+     */
+    camera_metadata_t* release();
+
+    /**
+     * Clear the metadata buffer and free all storage used by it
+     */
+    void clear();
+
+    /**
+     * Acquire a raw metadata buffer from the caller. After this call,
+     * the caller no longer owns the raw buffer, and must not free or manipulate it.
+     * If CameraMetadata already contains metadata, it is freed.
+     */
+    void acquire(camera_metadata_t* buffer);
+
+    /**
+     * Acquires raw buffer from other CameraMetadata object. After the call, the argument
+     * object no longer has any metadata.
+     */
+    void acquire(CameraMetadata& other);
+
+    /**
+     * Append metadata from another CameraMetadata object.
+     */
+    status_t append(const CameraMetadata& other);
+
+    /**
+     * Append metadata from a raw camera_metadata buffer
+     */
+    status_t append(const camera_metadata* other);
+
+    /**
+     * Number of metadata entries.
+     */
+    size_t entryCount() const;
+
+    /**
+     * Is the buffer empty (no entires)
+     */
+    bool isEmpty() const;
+
+    /**
+     * Sort metadata buffer for faster find
+     */
+    status_t sort();
+
+    /**
+     * Update metadata entry. Will create entry if it doesn't exist already, and
+     * will reallocate the buffer if insufficient space exists. Overloaded for
+     * the various types of valid data.
+     */
+    status_t update(uint32_t tag, const uint8_t* data, size_t data_count);
+    status_t update(uint32_t tag, const int32_t* data, size_t data_count);
+    status_t update(uint32_t tag, const float* data, size_t data_count);
+    status_t update(uint32_t tag, const int64_t* data, size_t data_count);
+    status_t update(uint32_t tag, const double* data, size_t data_count);
+    status_t update(uint32_t tag, const camera_metadata_rational_t* data, size_t data_count);
+    status_t update(uint32_t tag, const String8& string);
+    status_t update(const camera_metadata_ro_entry& entry);
+
+    template <typename T>
+    status_t update(uint32_t tag, Vector<T> data) {
+        return update(tag, data.array(), data.size());
+    }
+
+    /**
+     * Check if a metadata entry exists for a given tag id
+     *
+     */
+    bool exists(uint32_t tag) const;
+
+    /**
+     * Get metadata entry by tag id
+     */
+    camera_metadata_entry find(uint32_t tag);
+
+    /**
+     * Get metadata entry by tag id, with no editing
+     */
+    camera_metadata_ro_entry find(uint32_t tag) const;
+
+    /**
+     * Delete metadata entry by tag
+     */
+    status_t erase(uint32_t tag);
+
+    /**
+     * Swap the underlying camera metadata between this and the other
+     * metadata object.
+     */
+    void swap(CameraMetadata& other);
+
+    /**
+     * Dump contents into FD for debugging. The verbosity levels are
+     * 0: Tag entry information only, no data values
+     * 1: Level 0 plus at most 16 data values per entry
+     * 2: All information
+     *
+     * The indentation parameter sets the number of spaces to add to the start
+     * each line of output.
+     */
+    void dump(int fd, int verbosity = 1, int indentation = 0) const;
+
+    /**
+     * Find tag id for a given tag name, also checking vendor tags if available.
+     * On success, returns OK and writes the tag id into tag.
+     *
+     * This is a slow method.
+     */
+    static status_t getTagFromName(const char* name, const VendorTagDescriptor* vTags,
+                                   uint32_t* tag);
+
+  private:
+    camera_metadata_t* mBuffer;
+    mutable bool mLocked;
+
+    /**
+     * Check if tag has a given type
+     */
+    status_t checkType(uint32_t tag, uint8_t expectedType);
+
+    /**
+     * Base update entry method
+     */
+    status_t updateImpl(uint32_t tag, const void* data, size_t data_count);
+
+    /**
+     * Resize metadata buffer if needed by reallocating it and copying it over.
+     */
+    status_t resizeIfNeeded(size_t extraEntries, size_t extraData);
+};
+
+}  // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used.
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::CameraMetadata CameraMetadata;
+}  // namespace V1_0::helper
+
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif
diff --git a/camera/common/default/include/CameraModule.h b/camera/common/default/include/CameraModule.h
new file mode 100644
index 0000000..5c1f8ec
--- /dev/null
+++ b/camera/common/default/include/CameraModule.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2016 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 CAMERA_COMMON_1_0_CAMERAMODULE_H
+#define CAMERA_COMMON_1_0_CAMERAMODULE_H
+
+#include <string>
+#include <unordered_set>
+
+#include <hardware/camera.h>
+#include <utils/KeyedVector.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+
+#include "CameraMetadata.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+/**
+ * A wrapper class for HAL camera module.
+ *
+ * This class wraps camera_module_t returned from HAL to provide a wrapped
+ * get_camera_info implementation which CameraService generates some
+ * camera characteristics keys defined in newer HAL version on an older HAL.
+ */
+class CameraModule : public RefBase {
+  public:
+    explicit CameraModule(camera_module_t* module);
+    virtual ~CameraModule();
+
+    // Must be called after construction
+    // Returns OK on success, NO_INIT on failure
+    int init();
+
+    int getCameraInfo(int cameraId, struct camera_info* info);
+    int getDeviceVersion(int cameraId);
+    int getNumberOfCameras(void);
+    int open(const char* id, struct hw_device_t** device);
+    bool isOpenLegacyDefined() const;
+    int openLegacy(const char* id, uint32_t halVersion, struct hw_device_t** device);
+    int setCallbacks(const camera_module_callbacks_t* callbacks);
+    bool isVendorTagDefined() const;
+    void getVendorTagOps(vendor_tag_ops_t* ops);
+    bool isSetTorchModeSupported() const;
+    int setTorchMode(const char* camera_id, bool enable);
+    uint16_t getModuleApiVersion() const;
+    const char* getModuleName() const;
+    uint16_t getHalApiVersion() const;
+    const char* getModuleAuthor() const;
+    // Only used by CameraModuleFixture native test. Do NOT use elsewhere.
+    void* getDso();
+    // Only used by CameraProvider
+    void removeCamera(int cameraId);
+    int getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t** physicalInfo);
+    int isStreamCombinationSupported(int cameraId, camera_stream_combination_t* streams);
+    void notifyDeviceStateChange(uint64_t deviceState);
+
+    static bool isLogicalMultiCamera(const common::helper::CameraMetadata& metadata,
+                                     std::unordered_set<std::string>* physicalCameraIds);
+
+  private:
+    // Derive camera characteristics keys defined after HAL device version
+    static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata& chars);
+    // Helper function to append available[request|result|chars]Keys
+    static void appendAvailableKeys(CameraMetadata& chars, int32_t keyTag,
+                                    const Vector<int32_t>& appendKeys);
+    status_t filterOpenErrorCode(status_t err);
+    camera_module_t* mModule;
+    int mNumberOfCameras;
+    KeyedVector<int, camera_info> mCameraInfoMap;
+    KeyedVector<int, int> mDeviceVersionMap;
+    KeyedVector<int, camera_metadata_t*> mPhysicalCameraInfoMap;
+    Mutex mCameraInfoLock;
+};
+
+}  // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::CameraModule CameraModule;
+}  // namespace V1_0::helper
+
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif
diff --git a/camera/common/default/include/CameraParameters.h b/camera/common/default/include/CameraParameters.h
new file mode 100644
index 0000000..d2b5075
--- /dev/null
+++ b/camera/common/default/include/CameraParameters.h
@@ -0,0 +1,714 @@
+/*
+ * Copyright (C) 2008 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_HARDWARE_CAMERA_PARAMETERS_H
+#define ANDROID_HARDWARE_CAMERA_PARAMETERS_H
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+struct Size {
+    int width;
+    int height;
+
+    Size() {
+        width = 0;
+        height = 0;
+    }
+
+    Size(int w, int h) {
+        width = w;
+        height = h;
+    }
+};
+
+class CameraParameters {
+  public:
+    CameraParameters();
+    CameraParameters(const String8& params) { unflatten(params); }
+    ~CameraParameters();
+
+    String8 flatten() const;
+    void unflatten(const String8& params);
+
+    void set(const char* key, const char* value);
+    void set(const char* key, int value);
+    void setFloat(const char* key, float value);
+    const char* get(const char* key) const;
+    int getInt(const char* key) const;
+    float getFloat(const char* key) const;
+
+    void remove(const char* key);
+
+    void setPreviewSize(int width, int height);
+    void getPreviewSize(int* width, int* height) const;
+    void getSupportedPreviewSizes(Vector<Size>& sizes) const;
+
+    // Set the dimensions in pixels to the given width and height
+    // for video frames. The given width and height must be one
+    // of the supported dimensions returned from
+    // getSupportedVideoSizes(). Must not be called if
+    // getSupportedVideoSizes() returns an empty Vector of Size.
+    void setVideoSize(int width, int height);
+    // Retrieve the current dimensions (width and height)
+    // in pixels for video frames, which must be one of the
+    // supported dimensions returned from getSupportedVideoSizes().
+    // Must not be called if getSupportedVideoSizes() returns an
+    // empty Vector of Size.
+    void getVideoSize(int* width, int* height) const;
+    // Retrieve a Vector of supported dimensions (width and height)
+    // in pixels for video frames. If sizes returned from the method
+    // is empty, the camera does not support calls to setVideoSize()
+    // or getVideoSize(). In adddition, it also indicates that
+    // the camera only has a single output, and does not have
+    // separate output for video frames and preview frame.
+    void getSupportedVideoSizes(Vector<Size>& sizes) const;
+    // Retrieve the preferred preview size (width and height) in pixels
+    // for video recording. The given width and height must be one of
+    // supported preview sizes returned from getSupportedPreviewSizes().
+    // Must not be called if getSupportedVideoSizes() returns an empty
+    // Vector of Size. If getSupportedVideoSizes() returns an empty
+    // Vector of Size, the width and height returned from this method
+    // is invalid, and is "-1x-1".
+    void getPreferredPreviewSizeForVideo(int* width, int* height) const;
+
+    void setPreviewFrameRate(int fps);
+    int getPreviewFrameRate() const;
+    void getPreviewFpsRange(int* min_fps, int* max_fps) const;
+    void setPreviewFormat(const char* format);
+    const char* getPreviewFormat() const;
+    void setPictureSize(int width, int height);
+    void getPictureSize(int* width, int* height) const;
+    void getSupportedPictureSizes(Vector<Size>& sizes) const;
+    void setPictureFormat(const char* format);
+    const char* getPictureFormat() const;
+
+    void dump() const;
+    status_t dump(int fd, const Vector<String16>& args) const;
+
+    /**
+     * Returns a Vector containing the supported preview formats
+     * as enums given in graphics.h.
+     */
+    void getSupportedPreviewFormats(Vector<int>& formats) const;
+
+    // Returns true if no keys are present
+    bool isEmpty() const;
+
+    // Parameter keys to communicate between camera application and driver.
+    // The access (read/write, read only, or write only) is viewed from the
+    // perspective of applications, not driver.
+
+    // Preview frame size in pixels (width x height).
+    // Example value: "480x320". Read/Write.
+    static const char KEY_PREVIEW_SIZE[];
+    // Supported preview frame sizes in pixels.
+    // Example value: "800x600,480x320". Read only.
+    static const char KEY_SUPPORTED_PREVIEW_SIZES[];
+    // The current minimum and maximum preview fps. This controls the rate of
+    // preview frames received (CAMERA_MSG_PREVIEW_FRAME). The minimum and
+    // maximum fps must be one of the elements from
+    // KEY_SUPPORTED_PREVIEW_FPS_RANGE parameter.
+    // Example value: "10500,26623"
+    static const char KEY_PREVIEW_FPS_RANGE[];
+    // The supported preview fps (frame-per-second) ranges. Each range contains
+    // a minimum fps and maximum fps. If minimum fps equals to maximum fps, the
+    // camera outputs frames in fixed frame rate. If not, the camera outputs
+    // frames in auto frame rate. The actual frame rate fluctuates between the
+    // minimum and the maximum. The list has at least one element. The list is
+    // sorted from small to large (first by maximum fps and then minimum fps).
+    // Example value: "(10500,26623),(15000,26623),(30000,30000)"
+    static const char KEY_SUPPORTED_PREVIEW_FPS_RANGE[];
+    // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in
+    // frameworks/av/include/camera/Camera.h. The default is
+    // PIXEL_FORMAT_YUV420SP. Example value: "yuv420sp" or PIXEL_FORMAT_XXX
+    // constants. Read/write.
+    static const char KEY_PREVIEW_FORMAT[];
+    // Supported image formats for preview frames.
+    // Example value: "yuv420sp,yuv422i-yuyv". Read only.
+    static const char KEY_SUPPORTED_PREVIEW_FORMATS[];
+    // Number of preview frames per second. This is the target frame rate. The
+    // actual frame rate depends on the driver.
+    // Example value: "15". Read/write.
+    static const char KEY_PREVIEW_FRAME_RATE[];
+    // Supported number of preview frames per second.
+    // Example value: "24,15,10". Read.
+    static const char KEY_SUPPORTED_PREVIEW_FRAME_RATES[];
+    // The dimensions for captured pictures in pixels (width x height).
+    // Example value: "1024x768". Read/write.
+    static const char KEY_PICTURE_SIZE[];
+    // Supported dimensions for captured pictures in pixels.
+    // Example value: "2048x1536,1024x768". Read only.
+    static const char KEY_SUPPORTED_PICTURE_SIZES[];
+    // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE
+    // in frameworks/base/include/camera/Camera.h.
+    // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write.
+    static const char KEY_PICTURE_FORMAT[];
+    // Supported image formats for captured pictures.
+    // Example value: "jpeg,rgb565". Read only.
+    static const char KEY_SUPPORTED_PICTURE_FORMATS[];
+    // The width (in pixels) of EXIF thumbnail in Jpeg picture.
+    // Example value: "512". Read/write.
+    static const char KEY_JPEG_THUMBNAIL_WIDTH[];
+    // The height (in pixels) of EXIF thumbnail in Jpeg picture.
+    // Example value: "384". Read/write.
+    static const char KEY_JPEG_THUMBNAIL_HEIGHT[];
+    // Supported EXIF thumbnail sizes (width x height). 0x0 means not thumbnail
+    // in EXIF.
+    // Example value: "512x384,320x240,0x0". Read only.
+    static const char KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[];
+    // The quality of the EXIF thumbnail in Jpeg picture. The range is 1 to 100,
+    // with 100 being the best.
+    // Example value: "90". Read/write.
+    static const char KEY_JPEG_THUMBNAIL_QUALITY[];
+    // Jpeg quality of captured picture. The range is 1 to 100, with 100 being
+    // the best.
+    // Example value: "90". Read/write.
+    static const char KEY_JPEG_QUALITY[];
+    // The rotation angle in degrees relative to the orientation of the camera.
+    // This affects the pictures returned from CAMERA_MSG_COMPRESSED_IMAGE. The
+    // camera driver may set orientation in the EXIF header without rotating the
+    // picture. Or the driver may rotate the picture and the EXIF thumbnail. If
+    // the Jpeg picture is rotated, the orientation in the EXIF header will be
+    // missing or 1 (row #0 is top and column #0 is left side).
+    //
+    // Note that the JPEG pictures of front-facing cameras are not mirrored
+    // as in preview display.
+    //
+    // For example, suppose the natural orientation of the device is portrait.
+    // The device is rotated 270 degrees clockwise, so the device orientation is
+    // 270. Suppose a back-facing camera sensor is mounted in landscape and the
+    // top side of the camera sensor is aligned with the right edge of the
+    // display in natural orientation. So the camera orientation is 90. The
+    // rotation should be set to 0 (270 + 90).
+    //
+    // Example value: "0" or "90" or "180" or "270". Write only.
+    static const char KEY_ROTATION[];
+    // GPS latitude coordinate. GPSLatitude and GPSLatitudeRef will be stored in
+    // JPEG EXIF header.
+    // Example value: "25.032146" or "-33.462809". Write only.
+    static const char KEY_GPS_LATITUDE[];
+    // GPS longitude coordinate. GPSLongitude and GPSLongitudeRef will be stored
+    // in JPEG EXIF header.
+    // Example value: "121.564448" or "-70.660286". Write only.
+    static const char KEY_GPS_LONGITUDE[];
+    // GPS altitude. GPSAltitude and GPSAltitudeRef will be stored in JPEG EXIF
+    // header.
+    // Example value: "21.0" or "-5". Write only.
+    static const char KEY_GPS_ALTITUDE[];
+    // GPS timestamp (UTC in seconds since January 1, 1970). This should be
+    // stored in JPEG EXIF header.
+    // Example value: "1251192757". Write only.
+    static const char KEY_GPS_TIMESTAMP[];
+    // GPS Processing Method
+    // Example value: "GPS" or "NETWORK". Write only.
+    static const char KEY_GPS_PROCESSING_METHOD[];
+    // Current white balance setting.
+    // Example value: "auto" or WHITE_BALANCE_XXX constants. Read/write.
+    static const char KEY_WHITE_BALANCE[];
+    // Supported white balance settings.
+    // Example value: "auto,incandescent,daylight". Read only.
+    static const char KEY_SUPPORTED_WHITE_BALANCE[];
+    // Current color effect setting.
+    // Example value: "none" or EFFECT_XXX constants. Read/write.
+    static const char KEY_EFFECT[];
+    // Supported color effect settings.
+    // Example value: "none,mono,sepia". Read only.
+    static const char KEY_SUPPORTED_EFFECTS[];
+    // Current antibanding setting.
+    // Example value: "auto" or ANTIBANDING_XXX constants. Read/write.
+    static const char KEY_ANTIBANDING[];
+    // Supported antibanding settings.
+    // Example value: "auto,50hz,60hz,off". Read only.
+    static const char KEY_SUPPORTED_ANTIBANDING[];
+    // Current scene mode.
+    // Example value: "auto" or SCENE_MODE_XXX constants. Read/write.
+    static const char KEY_SCENE_MODE[];
+    // Supported scene mode settings.
+    // Example value: "auto,night,fireworks". Read only.
+    static const char KEY_SUPPORTED_SCENE_MODES[];
+    // Current flash mode.
+    // Example value: "auto" or FLASH_MODE_XXX constants. Read/write.
+    static const char KEY_FLASH_MODE[];
+    // Supported flash modes.
+    // Example value: "auto,on,off". Read only.
+    static const char KEY_SUPPORTED_FLASH_MODES[];
+    // Current focus mode. This will not be empty. Applications should call
+    // CameraHardwareInterface.autoFocus to start the focus if focus mode is
+    // FOCUS_MODE_AUTO or FOCUS_MODE_MACRO.
+    // Example value: "auto" or FOCUS_MODE_XXX constants. Read/write.
+    static const char KEY_FOCUS_MODE[];
+    // Supported focus modes.
+    // Example value: "auto,macro,fixed". Read only.
+    static const char KEY_SUPPORTED_FOCUS_MODES[];
+    // The maximum number of focus areas supported. This is the maximum length
+    // of KEY_FOCUS_AREAS.
+    // Example value: "0" or "2". Read only.
+    static const char KEY_MAX_NUM_FOCUS_AREAS[];
+    // Current focus areas.
+    //
+    // Before accessing this parameter, apps should check
+    // KEY_MAX_NUM_FOCUS_AREAS first to know the maximum number of focus areas
+    // first. If the value is 0, focus area is not supported.
+    //
+    // Each focus area is a five-element int array. The first four elements are
+    // the rectangle of the area (left, top, right, bottom). The direction is
+    // relative to the sensor orientation, that is, what the sensor sees. The
+    // direction is not affected by the rotation or mirroring of
+    // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates range from -1000 to 1000.
+    // (-1000,-1000) is the upper left point. (1000, 1000) is the lower right
+    // point. The width and height of focus areas cannot be 0 or negative.
+    //
+    // The fifth element is the weight. Values for weight must range from 1 to
+    // 1000.  The weight should be interpreted as a per-pixel weight - all
+    // pixels in the area have the specified weight. This means a small area
+    // with the same weight as a larger area will have less influence on the
+    // focusing than the larger area. Focus areas can partially overlap and the
+    // driver will add the weights in the overlap region.
+    //
+    // A special case of single focus area (0,0,0,0,0) means driver to decide
+    // the focus area. For example, the driver may use more signals to decide
+    // focus areas and change them dynamically. Apps can set (0,0,0,0,0) if they
+    // want the driver to decide focus areas.
+    //
+    // Focus areas are relative to the current field of view (KEY_ZOOM). No
+    // matter what the zoom level is, (-1000,-1000) represents the top of the
+    // currently visible camera frame. The focus area cannot be set to be
+    // outside the current field of view, even when using zoom.
+    //
+    // Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO,
+    // FOCUS_MODE_MACRO, FOCUS_MODE_CONTINUOUS_VIDEO, or
+    // FOCUS_MODE_CONTINUOUS_PICTURE.
+    // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
+    static const char KEY_FOCUS_AREAS[];
+    // Focal length in millimeter.
+    // Example value: "4.31". Read only.
+    static const char KEY_FOCAL_LENGTH[];
+    // Horizontal angle of view in degrees.
+    // Example value: "54.8". Read only.
+    static const char KEY_HORIZONTAL_VIEW_ANGLE[];
+    // Vertical angle of view in degrees.
+    // Example value: "42.5". Read only.
+    static const char KEY_VERTICAL_VIEW_ANGLE[];
+    // Exposure compensation index. 0 means exposure is not adjusted.
+    // Example value: "-5" or "5". Read/write.
+    static const char KEY_EXPOSURE_COMPENSATION[];
+    // The maximum exposure compensation index (>=0).
+    // Example value: "6". Read only.
+    static const char KEY_MAX_EXPOSURE_COMPENSATION[];
+    // The minimum exposure compensation index (<=0).
+    // Example value: "-6". Read only.
+    static const char KEY_MIN_EXPOSURE_COMPENSATION[];
+    // The exposure compensation step. Exposure compensation index multiply by
+    // step eqals to EV. Ex: if exposure compensation index is -6 and step is
+    // 0.3333, EV is -2.
+    // Example value: "0.333333333" or "0.5". Read only.
+    static const char KEY_EXPOSURE_COMPENSATION_STEP[];
+    // The state of the auto-exposure lock. "true" means that
+    // auto-exposure is locked to its current value and will not
+    // change. "false" means the auto-exposure routine is free to
+    // change exposure values. If auto-exposure is already locked,
+    // setting this to true again has no effect (the driver will not
+    // recalculate exposure values). Changing exposure compensation
+    // settings will still affect the exposure settings while
+    // auto-exposure is locked. Stopping preview or taking a still
+    // image will not change the lock. In conjunction with
+    // exposure compensation, this allows for capturing multi-exposure
+    // brackets with known relative exposure values. Locking
+    // auto-exposure after open but before the first call to
+    // startPreview may result in severely over- or under-exposed
+    // images.  The driver will not change the AE lock after
+    // auto-focus completes.
+    static const char KEY_AUTO_EXPOSURE_LOCK[];
+    // Whether locking the auto-exposure is supported. "true" means it is, and
+    // "false" or this key not existing means it is not supported.
+    static const char KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[];
+    // The state of the auto-white balance lock. "true" means that
+    // auto-white balance is locked to its current value and will not
+    // change. "false" means the auto-white balance routine is free to
+    // change white balance values. If auto-white balance is already
+    // locked, setting this to true again has no effect (the driver
+    // will not recalculate white balance values). Stopping preview or
+    // taking a still image will not change the lock. In conjunction
+    // with exposure compensation, this allows for capturing
+    // multi-exposure brackets with fixed white balance. Locking
+    // auto-white balance after open but before the first call to
+    // startPreview may result in severely incorrect color.  The
+    // driver will not change the AWB lock after auto-focus
+    // completes.
+    static const char KEY_AUTO_WHITEBALANCE_LOCK[];
+    // Whether locking the auto-white balance is supported. "true"
+    // means it is, and "false" or this key not existing means it is
+    // not supported.
+    static const char KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[];
+
+    // The maximum number of metering areas supported. This is the maximum
+    // length of KEY_METERING_AREAS.
+    // Example value: "0" or "2". Read only.
+    static const char KEY_MAX_NUM_METERING_AREAS[];
+    // Current metering areas. Camera driver uses these areas to decide
+    // exposure.
+    //
+    // Before accessing this parameter, apps should check
+    // KEY_MAX_NUM_METERING_AREAS first to know the maximum number of metering
+    // areas first. If the value is 0, metering area is not supported.
+    //
+    // Each metering area is a rectangle with specified weight. The direction is
+    // relative to the sensor orientation, that is, what the sensor sees. The
+    // direction is not affected by the rotation or mirroring of
+    // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates of the rectangle range
+    // from -1000 to 1000. (-1000, -1000) is the upper left point. (1000, 1000)
+    // is the lower right point. The width and height of metering areas cannot
+    // be 0 or negative.
+    //
+    // The fifth element is the weight. Values for weight must range from 1 to
+    // 1000.  The weight should be interpreted as a per-pixel weight - all
+    // pixels in the area have the specified weight. This means a small area
+    // with the same weight as a larger area will have less influence on the
+    // metering than the larger area. Metering areas can partially overlap and
+    // the driver will add the weights in the overlap region.
+    //
+    // A special case of all-zero single metering area means driver to decide
+    // the metering area. For example, the driver may use more signals to decide
+    // metering areas and change them dynamically. Apps can set all-zero if they
+    // want the driver to decide metering areas.
+    //
+    // Metering areas are relative to the current field of view (KEY_ZOOM).
+    // No matter what the zoom level is, (-1000,-1000) represents the top of the
+    // currently visible camera frame. The metering area cannot be set to be
+    // outside the current field of view, even when using zoom.
+    //
+    // No matter what metering areas are, the final exposure are compensated
+    // by KEY_EXPOSURE_COMPENSATION.
+    // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
+    static const char KEY_METERING_AREAS[];
+    // Current zoom value.
+    // Example value: "0" or "6". Read/write.
+    static const char KEY_ZOOM[];
+    // Maximum zoom value.
+    // Example value: "6". Read only.
+    static const char KEY_MAX_ZOOM[];
+    // The zoom ratios of all zoom values. The zoom ratio is in 1/100
+    // increments. Ex: a zoom of 3.2x is returned as 320. The number of list
+    // elements is KEY_MAX_ZOOM + 1. The first element is always 100. The last
+    // element is the zoom ratio of zoom value KEY_MAX_ZOOM.
+    // Example value: "100,150,200,250,300,350,400". Read only.
+    static const char KEY_ZOOM_RATIOS[];
+    // Whether zoom is supported. Zoom is supported if the value is "true". Zoom
+    // is not supported if the value is not "true" or the key does not exist.
+    // Example value: "true". Read only.
+    static const char KEY_ZOOM_SUPPORTED[];
+    // Whether if smooth zoom is supported. Smooth zoom is supported if the
+    // value is "true". It is not supported if the value is not "true" or the
+    // key does not exist.
+    // See CAMERA_CMD_START_SMOOTH_ZOOM, CAMERA_CMD_STOP_SMOOTH_ZOOM, and
+    // CAMERA_MSG_ZOOM in frameworks/base/include/camera/Camera.h.
+    // Example value: "true". Read only.
+    static const char KEY_SMOOTH_ZOOM_SUPPORTED[];
+
+    // The distances (in meters) from the camera to where an object appears to
+    // be in focus. The object is sharpest at the optimal focus distance. The
+    // depth of field is the far focus distance minus near focus distance.
+    //
+    // Focus distances may change after starting auto focus, canceling auto
+    // focus, or starting the preview. Applications can read this anytime to get
+    // the latest focus distances. If the focus mode is FOCUS_MODE_CONTINUOUS,
+    // focus distances may change from time to time.
+    //
+    // This is intended to estimate the distance between the camera and the
+    // subject. After autofocus, the subject distance may be within near and far
+    // focus distance. However, the precision depends on the camera hardware,
+    // autofocus algorithm, the focus area, and the scene. The error can be
+    // large and it should be only used as a reference.
+    //
+    // Far focus distance > optimal focus distance > near focus distance. If
+    // the far focus distance is infinity, the value should be "Infinity" (case
+    // sensitive). The format is three float values separated by commas. The
+    // first is near focus distance. The second is optimal focus distance. The
+    // third is far focus distance.
+    // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only.
+    static const char KEY_FOCUS_DISTANCES[];
+
+    // The current dimensions in pixels (width x height) for video frames.
+    // The width and height must be one of the supported sizes retrieved
+    // via KEY_SUPPORTED_VIDEO_SIZES.
+    // Example value: "1280x720". Read/write.
+    static const char KEY_VIDEO_SIZE[];
+    // A list of the supported dimensions in pixels (width x height)
+    // for video frames. See CAMERA_MSG_VIDEO_FRAME for details in
+    // frameworks/base/include/camera/Camera.h.
+    // Example: "176x144,1280x720". Read only.
+    static const char KEY_SUPPORTED_VIDEO_SIZES[];
+
+    // The maximum number of detected faces supported by hardware face
+    // detection. If the value is 0, hardware face detection is not supported.
+    // Example: "5". Read only
+    static const char KEY_MAX_NUM_DETECTED_FACES_HW[];
+
+    // The maximum number of detected faces supported by software face
+    // detection. If the value is 0, software face detection is not supported.
+    // Example: "5". Read only
+    static const char KEY_MAX_NUM_DETECTED_FACES_SW[];
+
+    // Preferred preview frame size in pixels for video recording.
+    // The width and height must be one of the supported sizes retrieved
+    // via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when
+    // getSupportedVideoSizes() does not return an empty Vector of Size.
+    // Camcorder applications are recommended to set the preview size
+    // to a value that is not larger than the preferred preview size.
+    // In other words, the product of the width and height of the
+    // preview size should not be larger than that of the preferred
+    // preview size. In addition, we recommend to choos a preview size
+    // that has the same aspect ratio as the resolution of video to be
+    // recorded.
+    // Example value: "800x600". Read only.
+    static const char KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[];
+
+    // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in
+    // frameworks/base/include/camera/Camera.h.
+    // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
+    static const char KEY_VIDEO_FRAME_FORMAT[];
+
+    // Sets the hint of the recording mode. If this is true, MediaRecorder.start
+    // may be faster or has less glitches. This should be called before starting
+    // the preview for the best result. But it is allowed to change the hint
+    // while the preview is active. The default value is false.
+    //
+    // The apps can still call Camera.takePicture when the hint is true. The
+    // apps can call MediaRecorder.start when the hint is false. But the
+    // performance may be worse.
+    // Example value: "true" or "false". Read/write.
+    static const char KEY_RECORDING_HINT[];
+
+    // Returns true if video snapshot is supported. That is, applications
+    // can call Camera.takePicture during recording. Applications do not need to
+    // call Camera.startPreview after taking a picture. The preview will be
+    // still active. Other than that, taking a picture during recording is
+    // identical to taking a picture normally. All settings and methods related
+    // to takePicture work identically. Ex: KEY_PICTURE_SIZE,
+    // KEY_SUPPORTED_PICTURE_SIZES, KEY_JPEG_QUALITY, KEY_ROTATION, and etc.
+    // The picture will have an EXIF header. FLASH_MODE_AUTO and FLASH_MODE_ON
+    // also still work, but the video will record the flash.
+    //
+    // Applications can set shutter callback as null to avoid the shutter
+    // sound. It is also recommended to set raw picture and post view callbacks
+    // to null to avoid the interrupt of preview display.
+    //
+    // Field-of-view of the recorded video may be different from that of the
+    // captured pictures.
+    // Example value: "true" or "false". Read only.
+    static const char KEY_VIDEO_SNAPSHOT_SUPPORTED[];
+
+    // The state of the video stabilization. If set to true, both the
+    // preview stream and the recorded video stream are stabilized by
+    // the camera. Only valid to set if KEY_VIDEO_STABILIZATION_SUPPORTED is
+    // set to true.
+    //
+    // The value of this key can be changed any time the camera is
+    // open. If preview or recording is active, it is acceptable for
+    // there to be a slight video glitch when video stabilization is
+    // toggled on and off.
+    //
+    // This only stabilizes video streams (between-frames stabilization), and
+    // has no effect on still image capture.
+    static const char KEY_VIDEO_STABILIZATION[];
+
+    // Returns true if video stabilization is supported. That is, applications
+    // can set KEY_VIDEO_STABILIZATION to true and have a stabilized preview
+    // stream and record stabilized videos.
+    static const char KEY_VIDEO_STABILIZATION_SUPPORTED[];
+
+    // Supported modes for special effects with light.
+    // Example values: "lowlight,hdr".
+    static const char KEY_LIGHTFX[];
+
+    // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
+    static const char TRUE[];
+    static const char FALSE[];
+
+    // Value for KEY_FOCUS_DISTANCES.
+    static const char FOCUS_DISTANCE_INFINITY[];
+
+    // Values for white balance settings.
+    static const char WHITE_BALANCE_AUTO[];
+    static const char WHITE_BALANCE_INCANDESCENT[];
+    static const char WHITE_BALANCE_FLUORESCENT[];
+    static const char WHITE_BALANCE_WARM_FLUORESCENT[];
+    static const char WHITE_BALANCE_DAYLIGHT[];
+    static const char WHITE_BALANCE_CLOUDY_DAYLIGHT[];
+    static const char WHITE_BALANCE_TWILIGHT[];
+    static const char WHITE_BALANCE_SHADE[];
+
+    // Values for effect settings.
+    static const char EFFECT_NONE[];
+    static const char EFFECT_MONO[];
+    static const char EFFECT_NEGATIVE[];
+    static const char EFFECT_SOLARIZE[];
+    static const char EFFECT_SEPIA[];
+    static const char EFFECT_POSTERIZE[];
+    static const char EFFECT_WHITEBOARD[];
+    static const char EFFECT_BLACKBOARD[];
+    static const char EFFECT_AQUA[];
+
+    // Values for antibanding settings.
+    static const char ANTIBANDING_AUTO[];
+    static const char ANTIBANDING_50HZ[];
+    static const char ANTIBANDING_60HZ[];
+    static const char ANTIBANDING_OFF[];
+
+    // Values for flash mode settings.
+    // Flash will not be fired.
+    static const char FLASH_MODE_OFF[];
+    // Flash will be fired automatically when required. The flash may be fired
+    // during preview, auto-focus, or snapshot depending on the driver.
+    static const char FLASH_MODE_AUTO[];
+    // Flash will always be fired during snapshot. The flash may also be
+    // fired during preview or auto-focus depending on the driver.
+    static const char FLASH_MODE_ON[];
+    // Flash will be fired in red-eye reduction mode.
+    static const char FLASH_MODE_RED_EYE[];
+    // Constant emission of light during preview, auto-focus and snapshot.
+    // This can also be used for video recording.
+    static const char FLASH_MODE_TORCH[];
+
+    // Values for scene mode settings.
+    static const char SCENE_MODE_AUTO[];
+    static const char SCENE_MODE_ACTION[];
+    static const char SCENE_MODE_PORTRAIT[];
+    static const char SCENE_MODE_LANDSCAPE[];
+    static const char SCENE_MODE_NIGHT[];
+    static const char SCENE_MODE_NIGHT_PORTRAIT[];
+    static const char SCENE_MODE_THEATRE[];
+    static const char SCENE_MODE_BEACH[];
+    static const char SCENE_MODE_SNOW[];
+    static const char SCENE_MODE_SUNSET[];
+    static const char SCENE_MODE_STEADYPHOTO[];
+    static const char SCENE_MODE_FIREWORKS[];
+    static const char SCENE_MODE_SPORTS[];
+    static const char SCENE_MODE_PARTY[];
+    static const char SCENE_MODE_CANDLELIGHT[];
+    // Applications are looking for a barcode. Camera driver will be optimized
+    // for barcode reading.
+    static const char SCENE_MODE_BARCODE[];
+    // A high-dynamic range mode. In this mode, the HAL module will use a
+    // capture strategy that extends the dynamic range of the captured
+    // image in some fashion. Only the final image is returned.
+    static const char SCENE_MODE_HDR[];
+
+    // Pixel color formats for KEY_PREVIEW_FORMAT, KEY_PICTURE_FORMAT,
+    // and KEY_VIDEO_FRAME_FORMAT
+    static const char PIXEL_FORMAT_YUV422SP[];
+    static const char PIXEL_FORMAT_YUV420SP[];  // NV21
+    static const char PIXEL_FORMAT_YUV422I[];   // YUY2
+    static const char PIXEL_FORMAT_YUV420P[];   // YV12
+    static const char PIXEL_FORMAT_RGB565[];
+    static const char PIXEL_FORMAT_RGBA8888[];
+    static const char PIXEL_FORMAT_JPEG[];
+    // Raw bayer format used for images, which is 10 bit precision samples
+    // stored in 16 bit words. The filter pattern is RGGB.
+    static const char PIXEL_FORMAT_BAYER_RGGB[];
+    // Pixel format is not known to the framework
+    static const char PIXEL_FORMAT_ANDROID_OPAQUE[];
+
+    // Values for focus mode settings.
+    // Auto-focus mode. Applications should call
+    // CameraHardwareInterface.autoFocus to start the focus in this mode.
+    static const char FOCUS_MODE_AUTO[];
+    // Focus is set at infinity. Applications should not call
+    // CameraHardwareInterface.autoFocus in this mode.
+    static const char FOCUS_MODE_INFINITY[];
+    // Macro (close-up) focus mode. Applications should call
+    // CameraHardwareInterface.autoFocus to start the focus in this mode.
+    static const char FOCUS_MODE_MACRO[];
+    // Focus is fixed. The camera is always in this mode if the focus is not
+    // adjustable. If the camera has auto-focus, this mode can fix the
+    // focus, which is usually at hyperfocal distance. Applications should
+    // not call CameraHardwareInterface.autoFocus in this mode.
+    static const char FOCUS_MODE_FIXED[];
+    // Extended depth of field (EDOF). Focusing is done digitally and
+    // continuously. Applications should not call
+    // CameraHardwareInterface.autoFocus in this mode.
+    static const char FOCUS_MODE_EDOF[];
+    // Continuous auto focus mode intended for video recording. The camera
+    // continuously tries to focus. This is the best choice for video
+    // recording because the focus changes smoothly . Applications still can
+    // call CameraHardwareInterface.takePicture in this mode but the subject may
+    // not be in focus. Auto focus starts when the parameter is set.
+    //
+    // Applications can call CameraHardwareInterface.autoFocus in this mode. The
+    // focus callback will immediately return with a boolean that indicates
+    // whether the focus is sharp or not. The focus position is locked after
+    // autoFocus call. If applications want to resume the continuous focus,
+    // cancelAutoFocus must be called. Restarting the preview will not resume
+    // the continuous autofocus. To stop continuous focus, applications should
+    // change the focus mode to other modes.
+    static const char FOCUS_MODE_CONTINUOUS_VIDEO[];
+    // Continuous auto focus mode intended for taking pictures. The camera
+    // continuously tries to focus. The speed of focus change is more aggressive
+    // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is
+    // set.
+    //
+    // Applications can call CameraHardwareInterface.autoFocus in this mode. If
+    // the autofocus is in the middle of scanning, the focus callback will
+    // return when it completes. If the autofocus is not scanning, focus
+    // callback will immediately return with a boolean that indicates whether
+    // the focus is sharp or not. The apps can then decide if they want to take
+    // a picture immediately or to change the focus mode to auto, and run a full
+    // autofocus cycle. The focus position is locked after autoFocus call. If
+    // applications want to resume the continuous focus, cancelAutoFocus must be
+    // called. Restarting the preview will not resume the continuous autofocus.
+    // To stop continuous focus, applications should change the focus mode to
+    // other modes.
+    static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
+
+    // Values for light special effects
+    // Low-light enhancement mode
+    static const char LIGHTFX_LOWLIGHT[];
+    // High-dynamic range mode
+    static const char LIGHTFX_HDR[];
+
+    /**
+     * Returns the the supported preview formats as an enum given in graphics.h
+     * corrsponding to the format given in the input string or -1 if no such
+     * conversion exists.
+     */
+    static int previewFormatToEnum(const char* format);
+
+  private:
+    DefaultKeyedVector<String8, String8> mMap;
+};
+
+};  // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::CameraParameters CameraParameters;
+typedef android::hardware::camera::common::helper::Size Size;
+}  // namespace V1_0::helper
+
+};  // namespace common
+};  // namespace camera
+};  // namespace hardware
+};  // namespace android
+
+#endif
diff --git a/camera/common/default/include/Exif.h b/camera/common/default/include/Exif.h
new file mode 100644
index 0000000..6974b8e
--- /dev/null
+++ b/camera/common/default/include/Exif.h
@@ -0,0 +1,256 @@
+/*
+ * 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_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
+#define ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
+
+#include "CameraMetadata.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+// This is based on the original ChromeOS ARC implementation of a V4L2 HAL
+
+// ExifUtils can generate APP1 segment with tags which caller set. ExifUtils can
+// also add a thumbnail in the APP1 segment if thumbnail size is specified.
+// ExifUtils can be reused with different images by calling initialize().
+//
+// Example of using this class :
+//  std::unique_ptr<ExifUtils> utils(ExifUtils::Create());
+//  utils->initialize();
+//  ...
+//  // Call ExifUtils functions to set Exif tags.
+//  ...
+//  utils->GenerateApp1(thumbnail_buffer, thumbnail_size);
+//  unsigned int app1Length = utils->GetApp1Length();
+//  uint8_t* app1Buffer = new uint8_t[app1Length];
+//  memcpy(app1Buffer, utils->GetApp1Buffer(), app1Length);
+class ExifUtils {
+  public:
+    virtual ~ExifUtils();
+
+    static ExifUtils* create();
+
+    // Initialize() can be called multiple times. The setting of Exif tags will be
+    // cleared.
+    virtual bool initialize() = 0;
+
+    // Set all known fields from a metadata structure
+    virtual bool setFromMetadata(const CameraMetadata& metadata, const size_t imageWidth,
+                                 const size_t imageHeight) = 0;
+
+    // Sets the len aperture.
+    // Returns false if memory allocation fails.
+    virtual bool setAperture(uint32_t numerator, uint32_t denominator) = 0;
+
+    // Sets the value of brightness.
+    // Returns false if memory allocation fails.
+    virtual bool setBrightness(int32_t numerator, int32_t denominator) = 0;
+
+    // Sets the color space.
+    // Returns false if memory allocation fails.
+    virtual bool setColorSpace(uint16_t color_space) = 0;
+
+    // Sets the information to compressed data.
+    // Returns false if memory allocation fails.
+    virtual bool setComponentsConfiguration(const std::string& components_configuration) = 0;
+
+    // Sets the compression scheme used for the image data.
+    // Returns false if memory allocation fails.
+    virtual bool setCompression(uint16_t compression) = 0;
+
+    // Sets image contrast.
+    // Returns false if memory allocation fails.
+    virtual bool setContrast(uint16_t contrast) = 0;
+
+    // Sets the date and time of image last modified. It takes local time. The
+    // name of the tag is DateTime in IFD0.
+    // Returns false if memory allocation fails.
+    virtual bool setDateTime(const struct tm& t) = 0;
+
+    // Sets the image description.
+    // Returns false if memory allocation fails.
+    virtual bool setDescription(const std::string& description) = 0;
+
+    // Sets the digital zoom ratio. If the numerator is 0, it means digital zoom
+    // was not used.
+    // Returns false if memory allocation fails.
+    virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) = 0;
+
+    // Sets the exposure bias.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureBias(int32_t numerator, int32_t denominator) = 0;
+
+    // Sets the exposure mode set when the image was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureMode(uint16_t exposure_mode) = 0;
+
+    // Sets the program used by the camera to set exposure when the picture is
+    // taken.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureProgram(uint16_t exposure_program) = 0;
+
+    // Sets the exposure time, given in seconds.
+    // Returns false if memory allocation fails.
+    virtual bool setExposureTime(uint32_t numerator, uint32_t denominator) = 0;
+
+    // Sets the status of flash.
+    // Returns false if memory allocation fails.
+    virtual bool setFlash(uint16_t flash) = 0;
+
+    // Sets the F number.
+    // Returns false if memory allocation fails.
+    virtual bool setFNumber(uint32_t numerator, uint32_t denominator) = 0;
+
+    // Sets the focal length of lens used to take the image in millimeters.
+    // Returns false if memory allocation fails.
+    virtual bool setFocalLength(uint32_t numerator, uint32_t denominator) = 0;
+
+    // Sets the degree of overall image gain adjustment.
+    // Returns false if memory allocation fails.
+    virtual bool setGainControl(uint16_t gain_control) = 0;
+
+    // Sets the altitude in meters.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsAltitude(double altitude) = 0;
+
+    // Sets the latitude with degrees minutes seconds format.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsLatitude(double latitude) = 0;
+
+    // Sets the longitude with degrees minutes seconds format.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsLongitude(double longitude) = 0;
+
+    // Sets GPS processing method.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsProcessingMethod(const std::string& method) = 0;
+
+    // Sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
+    // Returns false if memory allocation fails.
+    virtual bool setGpsTimestamp(const struct tm& t) = 0;
+
+    // Sets the height (number of rows) of main image.
+    // Returns false if memory allocation fails.
+    virtual bool setImageHeight(uint32_t length) = 0;
+
+    // Sets the width (number of columns) of main image.
+    // Returns false if memory allocation fails.
+    virtual bool setImageWidth(uint32_t width) = 0;
+
+    // Sets the ISO speed.
+    // Returns false if memory allocation fails.
+    virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings) = 0;
+
+    // Sets the kind of light source.
+    // Returns false if memory allocation fails.
+    virtual bool setLightSource(uint16_t light_source) = 0;
+
+    // Sets the smallest F number of the lens.
+    // Returns false if memory allocation fails.
+    virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator) = 0;
+
+    // Sets the metering mode.
+    // Returns false if memory allocation fails.
+    virtual bool setMeteringMode(uint16_t metering_mode) = 0;
+
+    // Sets image orientation.
+    // Returns false if memory allocation fails.
+    virtual bool setOrientation(uint16_t orientation) = 0;
+
+    // Sets the unit for measuring XResolution and YResolution.
+    // Returns false if memory allocation fails.
+    virtual bool setResolutionUnit(uint16_t resolution_unit) = 0;
+
+    // Sets image saturation.
+    // Returns false if memory allocation fails.
+    virtual bool setSaturation(uint16_t saturation) = 0;
+
+    // Sets the type of scene that was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setSceneCaptureType(uint16_t type) = 0;
+
+    // Sets image sharpness.
+    // Returns false if memory allocation fails.
+    virtual bool setSharpness(uint16_t sharpness) = 0;
+
+    // Sets the shutter speed.
+    // Returns false if memory allocation fails.
+    virtual bool setShutterSpeed(int32_t numerator, int32_t denominator) = 0;
+
+    // Sets the distance to the subject, given in meters.
+    // Returns false if memory allocation fails.
+    virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator) = 0;
+
+    // Sets the fractions of seconds for the <DateTime> tag.
+    // Returns false if memory allocation fails.
+    virtual bool setSubsecTime(const std::string& subsec_time) = 0;
+
+    // Sets the white balance mode set when the image was shot.
+    // Returns false if memory allocation fails.
+    virtual bool setWhiteBalance(uint16_t white_balance) = 0;
+
+    // Sets the number of pixels per resolution unit in the image width.
+    // Returns false if memory allocation fails.
+    virtual bool setXResolution(uint32_t numerator, uint32_t denominator) = 0;
+
+    // Sets the position of chrominance components in relation to the luminance
+    // component.
+    // Returns false if memory allocation fails.
+    virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning) = 0;
+
+    // Sets the number of pixels per resolution unit in the image length.
+    // Returns false if memory allocation fails.
+    virtual bool setYResolution(uint32_t numerator, uint32_t denominator) = 0;
+
+    // Sets the manufacturer of camera.
+    // Returns false if memory allocation fails.
+    virtual bool setMake(const std::string& make) = 0;
+
+    // Sets the model number of camera.
+    // Returns false if memory allocation fails.
+    virtual bool setModel(const std::string& model) = 0;
+
+    // Generates APP1 segment.
+    // Returns false if generating APP1 segment fails.
+    virtual bool generateApp1(const void* thumbnail_buffer, uint32_t size) = 0;
+
+    // Gets buffer of APP1 segment. This method must be called only after calling
+    // GenerateAPP1().
+    virtual const uint8_t* getApp1Buffer() = 0;
+
+    // Gets length of APP1 segment. This method must be called only after calling
+    // GenerateAPP1().
+    virtual unsigned int getApp1Length() = 0;
+};
+
+}  // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::ExifUtils ExifUtils;
+}  // namespace V1_0::helper
+
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
diff --git a/camera/common/default/include/HandleImporter.h b/camera/common/default/include/HandleImporter.h
new file mode 100644
index 0000000..5408ba9
--- /dev/null
+++ b/camera/common/default/include/HandleImporter.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 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 CAMERA_COMMON_1_0_HANDLEIMPORTED_H
+#define CAMERA_COMMON_1_0_HANDLEIMPORTED_H
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <cutils/native_handle.h>
+#include <utils/Mutex.h>
+
+using android::hardware::graphics::mapper::V2_0::IMapper;
+using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+// Borrowed from graphics HAL. Use this until gralloc mapper HAL is working
+class HandleImporter {
+  public:
+    HandleImporter();
+
+    // In IComposer, any buffer_handle_t is owned by the caller and we need to
+    // make a clone for hwcomposer2.  We also need to translate empty handle
+    // to nullptr.  This function does that, in-place.
+    bool importBuffer(buffer_handle_t& handle);
+    void freeBuffer(buffer_handle_t handle);
+    bool importFence(const native_handle_t* handle, int& fd) const;
+    void closeFence(int fd) const;
+
+    // Locks 1-D buffer. Assumes caller has waited for acquire fences.
+    void* lock(buffer_handle_t& buf, uint64_t cpuUsage, size_t size);
+
+    // Locks 2-D buffer. Assumes caller has waited for acquire fences.
+    void* lock(buffer_handle_t& buf, uint64_t cpuUsage, const IMapper::Rect& accessRegion);
+
+    // Assumes caller has waited for acquire fences.
+    YCbCrLayout lockYCbCr(buffer_handle_t& buf, uint64_t cpuUsage,
+                          const IMapper::Rect& accessRegion);
+
+    // Query the stride of the first plane in bytes.
+    status_t getMonoPlanarStrideBytes(buffer_handle_t& buf, uint32_t* stride /*out*/);
+
+    int unlock(buffer_handle_t& buf);  // returns release fence
+
+    // Query Gralloc4 metadata
+    bool isSmpte2086Present(const buffer_handle_t& buf);
+    bool isSmpte2094_10Present(const buffer_handle_t& buf);
+    bool isSmpte2094_40Present(const buffer_handle_t& buf);
+
+  private:
+    void initializeLocked();
+    void cleanup();
+
+    template <class M, class E>
+    bool importBufferInternal(const sp<M> mapper, buffer_handle_t& handle);
+    template <class M, class E>
+    YCbCrLayout lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
+                                  const IMapper::Rect& accessRegion);
+    template <class M, class E>
+    int unlockInternal(const sp<M> mapper, buffer_handle_t& buf);
+
+    Mutex mLock;
+    bool mInitialized;
+    sp<IMapper> mMapperV2;
+    sp<graphics::mapper::V3_0::IMapper> mMapperV3;
+    sp<graphics::mapper::V4_0::IMapper> mMapperV4;
+};
+
+}  // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::HandleImporter HandleImporter;
+}  // namespace V1_0::helper
+
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // CAMERA_COMMON_1_0_HANDLEIMPORTED_H
diff --git a/camera/common/default/include/SimpleThread.h b/camera/common/default/include/SimpleThread.h
new file mode 100644
index 0000000..d1becd6
--- /dev/null
+++ b/camera/common/default/include/SimpleThread.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_COMMON_SIMPLETHREAD_H_
+#define HARDWARE_INTERFACES_CAMERA_COMMON_SIMPLETHREAD_H_
+
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+// A simple looper based on std::thread.
+class SimpleThread {
+  public:
+    SimpleThread();
+    virtual ~SimpleThread();
+
+    // Explicit call to start execution of the thread. No thread is created before this function
+    // is called.
+    virtual void run() final;
+    virtual void requestExitAndWait() final;
+
+  protected:
+    // Main logic of the thread. This function is called repeatedly until it returns false.
+    // Thread execution stops if this function returns false.
+    virtual bool threadLoop() = 0;
+
+    // Returns true if the thread execution should stop. Should be used by threadLoop to check if
+    // the thread has been requested to exit.
+    virtual inline bool exitPending() final { return mDone.load(std::memory_order_acquire); }
+
+  private:
+    // Wraps threadLoop in a simple while loop that allows safe exit
+    virtual void runLoop() final;
+
+    // Flag to signal end of thread execution. This flag is checked before every iteration
+    // of threadLoop.
+    std::atomic_bool mDone;
+    std::thread mThread;
+};
+
+}  // namespace helper
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_CAMERA_COMMON_SIMPLETHREAD_H_
diff --git a/camera/common/default/include/VendorTagDescriptor.h b/camera/common/default/include/VendorTagDescriptor.h
new file mode 100644
index 0000000..3133c26
--- /dev/null
+++ b/camera/common/default/include/VendorTagDescriptor.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2016 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 CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H
+#define CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H
+
+#include <system/camera_vendor_tags.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include <stdint.h>
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace camera2 {
+namespace params {
+
+/**
+ * VendorTagDescriptor objects are containers for the vendor tag
+ * definitions provided, and are typically used to pass the vendor tag
+ * information enumerated by the HAL to clients of the camera service.
+ */
+class VendorTagDescriptor {
+  public:
+    virtual ~VendorTagDescriptor();
+
+    VendorTagDescriptor();
+    VendorTagDescriptor(const VendorTagDescriptor& src);
+    VendorTagDescriptor& operator=(const VendorTagDescriptor& rhs);
+
+    void copyFrom(const VendorTagDescriptor& src);
+
+    /**
+     * The following 'get*' methods implement the corresponding
+     * functions defined in
+     * system/media/camera/include/system/camera_vendor_tags.h
+     */
+
+    // Returns the number of vendor tags defined.
+    int getTagCount() const;
+
+    // Returns an array containing the id's of vendor tags defined.
+    void getTagArray(uint32_t* tagArray) const;
+
+    // Returns the section name string for a given vendor tag id.
+    const char* getSectionName(uint32_t tag) const;
+
+    // Returns the index in section vectors returned in getAllSectionNames()
+    // for a given vendor tag id. -1 if input tag does not exist.
+    ssize_t getSectionIndex(uint32_t tag) const;
+
+    // Returns the tag name string for a given vendor tag id.
+    const char* getTagName(uint32_t tag) const;
+
+    // Returns the tag type for a given vendor tag id.
+    int getTagType(uint32_t tag) const;
+
+    /**
+     * Convenience method to get a vector containing all vendor tag
+     * sections, or an empty vector if none are defined.
+     * The pointer is valid for the lifetime of the VendorTagDescriptor,
+     * or until copyFrom is invoked.
+     */
+    const SortedVector<String8>* getAllSectionNames() const;
+
+    /**
+     * Lookup the tag id for a given tag name and section.
+     *
+     * Returns OK on success, or a negative error code.
+     */
+    status_t lookupTag(const String8& name, const String8& section, /*out*/ uint32_t* tag) const;
+
+    /**
+     * Dump the currently configured vendor tags to a file descriptor.
+     */
+    void dump(int fd, int verbosity, int indentation) const;
+
+  protected:
+    KeyedVector<String8, KeyedVector<String8, uint32_t>*> mReverseMapping;
+    KeyedVector<uint32_t, String8> mTagToNameMap;
+    KeyedVector<uint32_t, uint32_t> mTagToSectionMap;  // Value is offset in mSections
+
+    std::unordered_map<uint32_t, int32_t> mTagToTypeMap;
+    SortedVector<String8> mSections;
+    // must be int32_t to be compatible with Parcel::writeInt32
+    int32_t mTagCount;
+
+    vendor_tag_ops mVendorOps;
+};
+} /* namespace params */
+} /* namespace camera2 */
+
+namespace camera {
+namespace common {
+namespace helper {
+
+/**
+ * This version of VendorTagDescriptor must be stored in Android sp<>, and adds support for using it
+ * as a global tag descriptor.
+ *
+ * It's a child class of the basic hardware::camera2::params::VendorTagDescriptor since basic
+ * Parcelable objects cannot require being kept in an sp<> and still work with auto-generated AIDL
+ * interface implementations.
+ */
+class VendorTagDescriptor : public ::android::hardware::camera2::params::VendorTagDescriptor,
+                            public LightRefBase<VendorTagDescriptor> {
+  public:
+    /**
+     * Create a VendorTagDescriptor object from the given vendor_tag_ops_t
+     * struct.
+     *
+     * Returns OK on success, or a negative error code.
+     */
+    static status_t createDescriptorFromOps(const vendor_tag_ops_t* vOps,
+                                            /*out*/
+                                            sp<VendorTagDescriptor>& descriptor);
+
+    /**
+     * Sets the global vendor tag descriptor to use for this process.
+     * Camera metadata operations that access vendor tags will use the
+     * vendor tag definitions set this way.
+     *
+     * Returns OK on success, or a negative error code.
+     */
+    static status_t setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc);
+
+    /**
+     * Returns the global vendor tag descriptor used by this process.
+     * This will contain NULL if no vendor tags are defined.
+     */
+    static sp<VendorTagDescriptor> getGlobalVendorTagDescriptor();
+
+    /**
+     * Clears the global vendor tag descriptor used by this process.
+     */
+    static void clearGlobalVendorTagDescriptor();
+};
+
+} /* namespace helper */
+} /* namespace common */
+} /* namespace camera */
+
+namespace camera2 {
+namespace params {
+
+class VendorTagDescriptorCache {
+  public:
+    typedef android::hardware::camera::common::helper::VendorTagDescriptor VendorTagDescriptor;
+    VendorTagDescriptorCache(){};
+    int32_t addVendorDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor> desc);
+
+    int32_t getVendorTagDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor>* desc /*out*/);
+
+    // Returns the number of vendor tags defined.
+    int getTagCount(metadata_vendor_id_t id) const;
+
+    // Returns an array containing the id's of vendor tags defined.
+    void getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const;
+
+    // Returns the section name string for a given vendor tag id.
+    const char* getSectionName(uint32_t tag, metadata_vendor_id_t id) const;
+
+    // Returns the tag name string for a given vendor tag id.
+    const char* getTagName(uint32_t tag, metadata_vendor_id_t id) const;
+
+    // Returns the tag type for a given vendor tag id.
+    int getTagType(uint32_t tag, metadata_vendor_id_t id) const;
+
+    /**
+     * Dump the currently configured vendor tags to a file descriptor.
+     */
+    void dump(int fd, int verbosity, int indentation) const;
+
+  protected:
+    std::unordered_map<metadata_vendor_id_t, sp<VendorTagDescriptor>> mVendorMap;
+    struct vendor_tag_cache_ops mVendorCacheOps;
+};
+
+} /* namespace params */
+} /* namespace camera2 */
+
+namespace camera {
+namespace common {
+namespace helper {
+
+class VendorTagDescriptorCache
+    : public ::android::hardware::camera2::params::VendorTagDescriptorCache,
+      public LightRefBase<VendorTagDescriptorCache> {
+  public:
+    /**
+     * Sets the global vendor tag descriptor cache to use for this process.
+     * Camera metadata operations that access vendor tags will use the
+     * vendor tag definitions set this way.
+     *
+     * Returns OK on success, or a negative error code.
+     */
+    static status_t setAsGlobalVendorTagCache(const sp<VendorTagDescriptorCache>& cache);
+
+    /**
+     * Returns the global vendor tag cache used by this process.
+     * This will contain NULL if no vendor tags are defined.
+     */
+    static sp<VendorTagDescriptorCache> getGlobalVendorTagCache();
+
+    /**
+     * Clears the global vendor tag cache used by this process.
+     */
+    static void clearGlobalVendorTagCache();
+};
+
+}  // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::VendorTagDescriptor VendorTagDescriptor;
+typedef android::hardware::camera::common::helper::VendorTagDescriptorCache
+        VendorTagDescriptorCache;
+}  // namespace V1_0::helper
+
+}  // namespace common
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif /* CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H */
diff --git a/camera/device/1.0/default/OWNERS b/camera/device/1.0/default/OWNERS
deleted file mode 100644
index f48a95c..0000000
--- a/camera/device/1.0/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.2/default/OWNERS b/camera/device/3.2/default/OWNERS
deleted file mode 100644
index f48a95c..0000000
--- a/camera/device/3.2/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.2/default/convert.cpp b/camera/device/3.2/default/convert.cpp
index 06ad7e9..2075607 100644
--- a/camera/device/3.2/default/convert.cpp
+++ b/camera/device/3.2/default/convert.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "android.hardware.camera.device@3.2-convert-impl"
 #include <log/log.h>
+#include <system/camera_metadata.h>
 
 #include "include/convert.h"
 
@@ -43,6 +44,13 @@
         ALOGE("%s: input CameraMetadata is corrupt!", __FUNCTION__);
         return false;
     }
+
+    if (validate_camera_metadata_structure((camera_metadata_t*)data, /*expected_size=*/NULL) !=
+        OK) {
+        ALOGE("%s: Failed to validate the metadata structure", __FUNCTION__);
+        return false;
+    }
+
     *dst = (camera_metadata_t*) data;
     return true;
 }
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 276e92a..3989161 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -346,15 +346,18 @@
      * An override pixel format for the buffers in this stream.
      *
      * The HAL must respect the requested format in Stream unless it is
-     * IMPLEMENTATION_DEFINED, in which case the override format here must be
-     * used by the client instead, for this stream. This allows cross-platform
-     * HALs to use a standard format since IMPLEMENTATION_DEFINED formats often
-     * require device-specific information. In all other cases, the
+     * IMPLEMENTATION_DEFINED output, in which case the override format
+     * here must be used by the client instead, for this stream. This allows
+     * cross-platform HALs to use a standard format since IMPLEMENTATION_DEFINED
+     * formats often require device-specific information. In all other cases, the
      * overrideFormat must match the requested format.
      *
      * When HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform
      * gralloc module must select a format based on the usage flags provided by
      * the camera device and the other endpoint of the stream.
+     *
+     * For private reprocessing, the HAL must not override the input stream's
+     * IMPLEMENTATION_DEFINED format.
      */
     android.hardware.graphics.common@1.0::PixelFormat overrideFormat;
 
diff --git a/camera/device/3.3/default/OWNERS b/camera/device/3.3/default/OWNERS
deleted file mode 100644
index f48a95c..0000000
--- a/camera/device/3.3/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.4/default/OWNERS b/camera/device/3.4/default/OWNERS
deleted file mode 100644
index f48a95c..0000000
--- a/camera/device/3.4/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.5/default/OWNERS b/camera/device/3.5/default/OWNERS
deleted file mode 100644
index f48a95c..0000000
--- a/camera/device/3.5/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/3.6/default/OWNERS b/camera/device/3.6/default/OWNERS
deleted file mode 100644
index f48a95c..0000000
--- a/camera/device/3.6/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index afc6b8d..43a3934 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -11,13 +11,14 @@
     name: "android.hardware.camera.device",
     vendor_available: true,
     srcs: ["android/hardware/camera/device/*.aidl"],
+    frozen: true,
     stability: "vintf",
     imports: [
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
-        "android.hardware.camera.common",
-        "android.hardware.camera.metadata",
-        "android.hardware.graphics.common",
+        "android.hardware.camera.common-V1",
+        "android.hardware.camera.metadata-V2",
+        "android.hardware.graphics.common-V4",
     ],
     backend: {
         cpp: {
@@ -27,11 +28,6 @@
             sdk_version: "module_current",
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
@@ -41,9 +37,20 @@
                 "android.hardware.common.fmq-V1",
                 "android.hardware.camera.common-V1",
                 "android.hardware.camera.metadata-V1",
-                "android.hardware.graphics.common-V3",
+                "android.hardware.graphics.common-V4",
             ],
         },
+        {
+            version: "2",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.common.fmq-V1",
+                "android.hardware.camera.common-V1",
+                "android.hardware.camera.metadata-V2",
+                "android.hardware.graphics.common-V4",
+            ],
+        },
+
     ],
 
 }
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/.hash b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/.hash
new file mode 100644
index 0000000..7a7bd43
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/.hash
@@ -0,0 +1 @@
+c03791dc9ced356c793cc487d0de3266dcb06ac9
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferCache.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferCache.aidl
new file mode 100644
index 0000000..9439172
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferCache.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable BufferCache {
+  int streamId;
+  long bufferId;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferRequest.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferRequest.aidl
new file mode 100644
index 0000000..c40a24a
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferRequest.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable BufferRequest {
+  int streamId;
+  int numBuffersRequested;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferRequestStatus.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferRequestStatus.aidl
new file mode 100644
index 0000000..72fb61b
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferRequestStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@Backing(type="int") @VintfStability
+enum BufferRequestStatus {
+  OK = 0,
+  FAILED_PARTIAL = 1,
+  FAILED_CONFIGURING = 2,
+  FAILED_ILLEGAL_ARGUMENTS = 3,
+  FAILED_UNKNOWN = 4,
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferStatus.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferStatus.aidl
new file mode 100644
index 0000000..43a2b35
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/BufferStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@Backing(type="int") @VintfStability
+enum BufferStatus {
+  OK = 0,
+  ERROR = 1,
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraBlob.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraBlob.aidl
new file mode 100644
index 0000000..520181c
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraBlob.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable CameraBlob {
+  android.hardware.camera.device.CameraBlobId blobId;
+  int blobSizeBytes;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraBlobId.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraBlobId.aidl
new file mode 100644
index 0000000..24083ad
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraBlobId.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@Backing(type="int") @VintfStability
+enum CameraBlobId {
+  JPEG = 0x00FF,
+  JPEG_APP_SEGMENTS = 0x100,
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraMetadata.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraMetadata.aidl
new file mode 100644
index 0000000..b96d69e
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraMetadata.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable CameraMetadata {
+  byte[] metadata;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraOfflineSessionInfo.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraOfflineSessionInfo.aidl
new file mode 100644
index 0000000..1ad8e11
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CameraOfflineSessionInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable CameraOfflineSessionInfo {
+  android.hardware.camera.device.OfflineStream[] offlineStreams;
+  android.hardware.camera.device.OfflineRequest[] offlineRequests;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CaptureRequest.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CaptureRequest.aidl
new file mode 100644
index 0000000..6b5b256
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CaptureRequest.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable CaptureRequest {
+  int frameNumber;
+  long fmqSettingsSize;
+  android.hardware.camera.device.CameraMetadata settings;
+  android.hardware.camera.device.StreamBuffer inputBuffer;
+  int inputWidth;
+  int inputHeight;
+  android.hardware.camera.device.StreamBuffer[] outputBuffers;
+  android.hardware.camera.device.PhysicalCameraSetting[] physicalCameraSettings;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CaptureResult.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CaptureResult.aidl
new file mode 100644
index 0000000..a820e2c
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/CaptureResult.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable CaptureResult {
+  int frameNumber;
+  long fmqResultSize;
+  android.hardware.camera.device.CameraMetadata result;
+  android.hardware.camera.device.StreamBuffer[] outputBuffers;
+  android.hardware.camera.device.StreamBuffer inputBuffer;
+  int partialResult;
+  android.hardware.camera.device.PhysicalCameraMetadata[] physicalCameraMetadata;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ErrorCode.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ErrorCode.aidl
new file mode 100644
index 0000000..2f9887a
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ErrorCode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@Backing(type="int") @VintfStability
+enum ErrorCode {
+  ERROR_DEVICE = 1,
+  ERROR_REQUEST = 2,
+  ERROR_RESULT = 3,
+  ERROR_BUFFER = 4,
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ErrorMsg.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ErrorMsg.aidl
new file mode 100644
index 0000000..b2e9512
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ErrorMsg.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable ErrorMsg {
+  int frameNumber;
+  int errorStreamId;
+  android.hardware.camera.device.ErrorCode errorCode;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/HalStream.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/HalStream.aidl
new file mode 100644
index 0000000..a5784bc
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/HalStream.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable HalStream {
+  int id;
+  android.hardware.graphics.common.PixelFormat overrideFormat;
+  android.hardware.graphics.common.BufferUsage producerUsage;
+  android.hardware.graphics.common.BufferUsage consumerUsage;
+  int maxBuffers;
+  android.hardware.graphics.common.Dataspace overrideDataSpace;
+  String physicalCameraId;
+  boolean supportOffline;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraDevice.aidl
new file mode 100644
index 0000000..51c6067
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraDevice.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+interface ICameraDevice {
+  android.hardware.camera.device.CameraMetadata getCameraCharacteristics();
+  android.hardware.camera.device.CameraMetadata getPhysicalCameraCharacteristics(in String physicalCameraId);
+  android.hardware.camera.common.CameraResourceCost getResourceCost();
+  boolean isStreamCombinationSupported(in android.hardware.camera.device.StreamConfiguration streams);
+  android.hardware.camera.device.ICameraDeviceSession open(in android.hardware.camera.device.ICameraDeviceCallback callback);
+  android.hardware.camera.device.ICameraInjectionSession openInjectionSession(in android.hardware.camera.device.ICameraDeviceCallback callback);
+  void setTorchMode(boolean on);
+  void turnOnTorchWithStrengthLevel(int torchStrength);
+  int getTorchStrengthLevel();
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraDeviceCallback.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraDeviceCallback.aidl
new file mode 100644
index 0000000..7b79c6c
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraDeviceCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+interface ICameraDeviceCallback {
+  void notify(in android.hardware.camera.device.NotifyMsg[] msgs);
+  void processCaptureResult(in android.hardware.camera.device.CaptureResult[] results);
+  android.hardware.camera.device.BufferRequestStatus requestStreamBuffers(in android.hardware.camera.device.BufferRequest[] bufReqs, out android.hardware.camera.device.StreamBufferRet[] buffers);
+  void returnStreamBuffers(in android.hardware.camera.device.StreamBuffer[] buffers);
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraDeviceSession.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraDeviceSession.aidl
new file mode 100644
index 0000000..2196d37
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraDeviceSession.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+interface ICameraDeviceSession {
+  void close();
+  android.hardware.camera.device.HalStream[] configureStreams(in android.hardware.camera.device.StreamConfiguration requestedConfiguration);
+  android.hardware.camera.device.CameraMetadata constructDefaultRequestSettings(in android.hardware.camera.device.RequestTemplate type);
+  void flush();
+  android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> getCaptureRequestMetadataQueue();
+  android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> getCaptureResultMetadataQueue();
+  boolean isReconfigurationRequired(in android.hardware.camera.device.CameraMetadata oldSessionParams, in android.hardware.camera.device.CameraMetadata newSessionParams);
+  int processCaptureRequest(in android.hardware.camera.device.CaptureRequest[] requests, in android.hardware.camera.device.BufferCache[] cachesToRemove);
+  oneway void signalStreamFlush(in int[] streamIds, in int streamConfigCounter);
+  android.hardware.camera.device.ICameraOfflineSession switchToOffline(in int[] streamsToKeep, out android.hardware.camera.device.CameraOfflineSessionInfo offlineSessionInfo);
+  void repeatingRequestEnd(in int frameNumber, in int[] streamIds);
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraInjectionSession.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraInjectionSession.aidl
new file mode 100644
index 0000000..80f74f3
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraInjectionSession.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+interface ICameraInjectionSession {
+  void configureInjectionStreams(in android.hardware.camera.device.StreamConfiguration requestedConfiguration, in android.hardware.camera.device.CameraMetadata characteristics);
+  android.hardware.camera.device.ICameraDeviceSession getCameraDeviceSession();
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraOfflineSession.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraOfflineSession.aidl
new file mode 100644
index 0000000..727d856
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ICameraOfflineSession.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+interface ICameraOfflineSession {
+  void close();
+  android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> getCaptureResultMetadataQueue();
+  void setCallback(in android.hardware.camera.device.ICameraDeviceCallback cb);
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/NotifyMsg.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/NotifyMsg.aidl
new file mode 100644
index 0000000..3ad7e52
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/NotifyMsg.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+union NotifyMsg {
+  android.hardware.camera.device.ErrorMsg error;
+  android.hardware.camera.device.ShutterMsg shutter;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/OfflineRequest.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/OfflineRequest.aidl
new file mode 100644
index 0000000..6e6f29d
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/OfflineRequest.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable OfflineRequest {
+  int frameNumber;
+  int[] pendingStreams;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/OfflineStream.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/OfflineStream.aidl
new file mode 100644
index 0000000..54cb1fe
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/OfflineStream.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable OfflineStream {
+  int id;
+  int numOutstandingBuffers;
+  long[] circulatingBufferIds;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/PhysicalCameraMetadata.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/PhysicalCameraMetadata.aidl
new file mode 100644
index 0000000..3d66ab8
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/PhysicalCameraMetadata.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable PhysicalCameraMetadata {
+  long fmqMetadataSize;
+  String physicalCameraId;
+  android.hardware.camera.device.CameraMetadata metadata;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/PhysicalCameraSetting.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/PhysicalCameraSetting.aidl
new file mode 100644
index 0000000..a6c241d
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/PhysicalCameraSetting.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable PhysicalCameraSetting {
+  long fmqSettingsSize;
+  String physicalCameraId;
+  android.hardware.camera.device.CameraMetadata settings;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/RequestTemplate.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/RequestTemplate.aidl
new file mode 100644
index 0000000..1f87aa3
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/RequestTemplate.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@Backing(type="int") @VintfStability
+enum RequestTemplate {
+  PREVIEW = 1,
+  STILL_CAPTURE = 2,
+  VIDEO_RECORD = 3,
+  VIDEO_SNAPSHOT = 4,
+  ZERO_SHUTTER_LAG = 5,
+  MANUAL = 6,
+  VENDOR_TEMPLATE_START = 0x40000000,
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ShutterMsg.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ShutterMsg.aidl
new file mode 100644
index 0000000..ce059ac
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/ShutterMsg.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable ShutterMsg {
+  int frameNumber;
+  long timestamp;
+  long readoutTimestamp;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/Stream.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/Stream.aidl
new file mode 100644
index 0000000..5057663
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/Stream.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable Stream {
+  int id;
+  android.hardware.camera.device.StreamType streamType;
+  int width;
+  int height;
+  android.hardware.graphics.common.PixelFormat format;
+  android.hardware.graphics.common.BufferUsage usage;
+  android.hardware.graphics.common.Dataspace dataSpace;
+  android.hardware.camera.device.StreamRotation rotation;
+  String physicalCameraId;
+  int bufferSize;
+  int groupId;
+  android.hardware.camera.metadata.SensorPixelMode[] sensorPixelModesUsed;
+  android.hardware.camera.metadata.RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile;
+  android.hardware.camera.metadata.ScalerAvailableStreamUseCases useCase;
+  int colorSpace;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBuffer.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBuffer.aidl
new file mode 100644
index 0000000..8fabf03
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBuffer.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable StreamBuffer {
+  int streamId;
+  long bufferId;
+  android.hardware.common.NativeHandle buffer;
+  android.hardware.camera.device.BufferStatus status;
+  android.hardware.common.NativeHandle acquireFence;
+  android.hardware.common.NativeHandle releaseFence;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBufferRequestError.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBufferRequestError.aidl
new file mode 100644
index 0000000..f450149
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBufferRequestError.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@Backing(type="int") @VintfStability
+enum StreamBufferRequestError {
+  NO_BUFFER_AVAILABLE = 1,
+  MAX_BUFFER_EXCEEDED = 2,
+  STREAM_DISCONNECTED = 3,
+  UNKNOWN_ERROR = 4,
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBufferRet.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBufferRet.aidl
new file mode 100644
index 0000000..3998cc3
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBufferRet.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable StreamBufferRet {
+  int streamId;
+  android.hardware.camera.device.StreamBuffersVal val;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBuffersVal.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBuffersVal.aidl
new file mode 100644
index 0000000..bebc9fc
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamBuffersVal.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+union StreamBuffersVal {
+  android.hardware.camera.device.StreamBufferRequestError error = android.hardware.camera.device.StreamBufferRequestError.UNKNOWN_ERROR;
+  android.hardware.camera.device.StreamBuffer[] buffers;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamConfiguration.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamConfiguration.aidl
new file mode 100644
index 0000000..97fd067
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@VintfStability
+parcelable StreamConfiguration {
+  android.hardware.camera.device.Stream[] streams;
+  android.hardware.camera.device.StreamConfigurationMode operationMode;
+  android.hardware.camera.device.CameraMetadata sessionParams;
+  int streamConfigCounter;
+  boolean multiResolutionInputImage;
+  long logId = 0;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamConfigurationMode.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamConfigurationMode.aidl
new file mode 100644
index 0000000..ef7ec25
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamConfigurationMode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@Backing(type="int") @VintfStability
+enum StreamConfigurationMode {
+  NORMAL_MODE = 0,
+  CONSTRAINED_HIGH_SPEED_MODE = 1,
+  VENDOR_MODE_0 = 0x8000,
+  VENDOR_MODE_1,
+  VENDOR_MODE_2,
+  VENDOR_MODE_3,
+  VENDOR_MODE_4,
+  VENDOR_MODE_5,
+  VENDOR_MODE_6,
+  VENDOR_MODE_7,
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamRotation.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamRotation.aidl
new file mode 100644
index 0000000..2ef4274
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamRotation.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@Backing(type="int") @VintfStability
+enum StreamRotation {
+  ROTATION_0 = 0,
+  ROTATION_90 = 1,
+  ROTATION_180 = 2,
+  ROTATION_270 = 3,
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamType.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamType.aidl
new file mode 100644
index 0000000..0f13fe8
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/2/android/hardware/camera/device/StreamType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.device;
+@Backing(type="int") @VintfStability
+enum StreamType {
+  OUTPUT = 0,
+  INPUT = 1,
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/CameraBlobId.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/CameraBlobId.aidl
index 632499d..24083ad 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/CameraBlobId.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/CameraBlobId.aidl
@@ -34,6 +34,6 @@
 package android.hardware.camera.device;
 @Backing(type="int") @VintfStability
 enum CameraBlobId {
-  JPEG = 255,
-  JPEG_APP_SEGMENTS = 256,
+  JPEG = 0x00FF,
+  JPEG_APP_SEGMENTS = 0x100,
 }
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/RequestTemplate.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/RequestTemplate.aidl
index b70b899..1f87aa3 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/RequestTemplate.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/RequestTemplate.aidl
@@ -40,5 +40,5 @@
   VIDEO_SNAPSHOT = 4,
   ZERO_SHUTTER_LAG = 5,
   MANUAL = 6,
-  VENDOR_TEMPLATE_START = 1073741824,
+  VENDOR_TEMPLATE_START = 0x40000000,
 }
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/Stream.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/Stream.aidl
index d2f295a..5057663 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/Stream.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/Stream.aidl
@@ -48,4 +48,5 @@
   android.hardware.camera.metadata.SensorPixelMode[] sensorPixelModesUsed;
   android.hardware.camera.metadata.RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile;
   android.hardware.camera.metadata.ScalerAvailableStreamUseCases useCase;
+  int colorSpace;
 }
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfiguration.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfiguration.aidl
index f340578..97fd067 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfiguration.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfiguration.aidl
@@ -39,4 +39,5 @@
   android.hardware.camera.device.CameraMetadata sessionParams;
   int streamConfigCounter;
   boolean multiResolutionInputImage;
+  long logId = 0;
 }
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfigurationMode.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfigurationMode.aidl
index bdef412..ef7ec25 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfigurationMode.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfigurationMode.aidl
@@ -36,12 +36,12 @@
 enum StreamConfigurationMode {
   NORMAL_MODE = 0,
   CONSTRAINED_HIGH_SPEED_MODE = 1,
-  VENDOR_MODE_0 = 32768,
-  VENDOR_MODE_1 = 32769,
-  VENDOR_MODE_2 = 32770,
-  VENDOR_MODE_3 = 32771,
-  VENDOR_MODE_4 = 32772,
-  VENDOR_MODE_5 = 32773,
-  VENDOR_MODE_6 = 32774,
-  VENDOR_MODE_7 = 32775,
+  VENDOR_MODE_0 = 0x8000,
+  VENDOR_MODE_1,
+  VENDOR_MODE_2,
+  VENDOR_MODE_3,
+  VENDOR_MODE_4,
+  VENDOR_MODE_5,
+  VENDOR_MODE_6,
+  VENDOR_MODE_7,
 }
diff --git a/camera/device/aidl/android/hardware/camera/device/HalStream.aidl b/camera/device/aidl/android/hardware/camera/device/HalStream.aidl
index b8ec3de..25a80bc 100644
--- a/camera/device/aidl/android/hardware/camera/device/HalStream.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/HalStream.aidl
@@ -38,7 +38,7 @@
      * An override pixel format for the buffers in this stream.
      *
      * The HAL must respect the requested format in Stream unless it is
-     * IMPLEMENTATION_DEFINED, in which case the override format here must be
+     * IMPLEMENTATION_DEFINED output, in which case the override format here must be
      * used by the client instead, for this stream. This allows cross-platform
      * HALs to use a standard format since IMPLEMENTATION_DEFINED formats often
      * require device-specific information. In all other cases, the
@@ -47,6 +47,9 @@
      * When HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform
      * gralloc module must select a format based on the usage flags provided by
      * the camera device and the other endpoint of the stream.
+     *
+     * For private reprocessing, the HAL must not override the input stream's
+     * IMPLEMENTATION_DEFINED format.
      */
     android.hardware.graphics.common.PixelFormat overrideFormat;
 
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
index 57705bc..f940000 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
@@ -279,8 +279,10 @@
      * with specified torchStrength if the torch is OFF.
      *
      * The torchStrength value must be within the valid range i.e. >=1 and
-     * <= FLASH_INFO_STRENGTH_MAXIMUM_LEVEL. Whenever the torch is turned OFF,
-     * the brightness level will reset to FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
+     * <= FLASH_INFO_STRENGTH_MAXIMUM_LEVEL. The FLASH_INFO_STRENGTH_MAXIMUM_LEVEL must
+     * be set to a level which will not cause any burn out issues. Whenever
+     * the torch is turned OFF, the brightness level will reset to
+     * FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
      * When the client calls setTorchMode(ON) after turnOnTorchWithStrengthLevel(N),
      * the flash unit will have brightness level equal to N. This level does not
      * represent the real brightness units. It is linear in nature i.e. flashlight
diff --git a/camera/device/aidl/android/hardware/camera/device/Stream.aidl b/camera/device/aidl/android/hardware/camera/device/Stream.aidl
index e35e4ff..0a657d7 100644
--- a/camera/device/aidl/android/hardware/camera/device/Stream.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/Stream.aidl
@@ -98,14 +98,19 @@
      *
      * For most formats, dataSpace defines the color space of the image data.
      * In addition, for some formats, dataSpace indicates whether image- or
-     * depth-based data is requested. See
-     * android.hardware.graphics.common@1.0::types for details of formats and
-     * valid dataSpace values for each format.
+     * depth-based data is requested. For others, it merely describes an encoding
+     * scheme. See android.hardware.graphics.common@1.0::types for details of formats
+     * and valid dataSpace values for each format.
      *
      * The HAL must use this dataSpace to configure the stream to the correct
      * colorspace, or to select between color and depth outputs if
      * supported. The dataspace values are set using the V0 dataspace
      * definitions.
+     *
+     * The standard bits of this field will match the requested colorSpace (if set) for
+     * non-BLOB formats. For BLOB formats, if colorSpace is not
+     * ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED, colorSpace takes
+     * over as the authority for the color space of the stream regardless of dataSpace.
      */
     android.hardware.graphics.common.Dataspace dataSpace;
 
@@ -222,4 +227,19 @@
      * DEFAULT.
      */
     android.hardware.camera.metadata.ScalerAvailableStreamUseCases useCase;
+
+    /**
+     * The color space of the stream.
+     *
+     * A client may not specify a color space. In this case, the value will be
+     * ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED, and the color space
+     * implied by dataSpace should be used instead.
+     *
+     * When specified, this field and the standard bits of dataSpace will match for non-BLOB
+     * formats. For BLOB formats, the dataSpace will remain unchanged. In this case, this field is
+     * the ultimate authority over the color space of the stream.
+     *
+     * See ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP for possible values.
+     */
+    int colorSpace;
 }
diff --git a/camera/device/aidl/android/hardware/camera/device/StreamBuffer.aidl b/camera/device/aidl/android/hardware/camera/device/StreamBuffer.aidl
index e487494..29fec68 100644
--- a/camera/device/aidl/android/hardware/camera/device/StreamBuffer.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/StreamBuffer.aidl
@@ -33,8 +33,8 @@
 parcelable StreamBuffer {
     /**
      * The ID of the stream this buffer is associated with. -1 indicates an
-     * invalid (empty) StreamBuffer, in which case buffer must also point to
-     * null and bufferId must be 0.
+     * invalid (empty) StreamBuffer, in which case buffer must be empty
+     * and bufferId must be 0.
      */
     int streamId;
 
@@ -48,7 +48,7 @@
      * corresponding stream is removed from stream configuration or until camera
      * device session is closed. After the first time a buffer is introduced to
      * HAL, in the future camera service must refer to the same buffer using
-     * only bufferId, and keep the buffer handle null.
+     * only bufferId, and keep the buffer handle empty.
      */
     long bufferId;
 
@@ -59,10 +59,10 @@
      * is not seen by the HAL before, this buffer handle is guaranteed to be a
      * valid handle to a graphics buffer, with dimensions and format matching
      * that of the stream. If the bufferId has been sent to the HAL before, this
-     * buffer handle must be null and HAL must look up the actual buffer handle
+     * buffer handle must be empty and HAL must look up the actual buffer handle
      * to use from its own bufferId to buffer handle map.
      *
-     * For StreamBuffers returned in a CaptureResult, this must be null, since
+     * For StreamBuffers returned in a CaptureResult, this must be empty, since
      * the handle to the buffer is already known to the client (since the client
      * sent it in the matching CaptureRequest), and the handle can be identified
      * by the combination of frame number and stream ID.
@@ -81,11 +81,11 @@
      * The acquire sync fence for this buffer. The HAL must wait on this fence
      * fd before attempting to read from or write to this buffer.
      *
-     * In a buffer included in a CaptureRequest, the client may set this to null
+     * In a buffer included in a CaptureRequest, the client may leave this empty
      * to indicate that no waiting is necessary for this buffer.
      *
      * When the HAL returns an input or output buffer to the framework with
-     * processCaptureResult(), the acquireFence must be set to null. If the HAL
+     * processCaptureResult(), the acquireFence must be empty. If the HAL
      * never waits on the acquireFence due to an error in filling or reading a
      * buffer, when calling processCaptureResult() the HAL must set the
      * releaseFence of the buffer to be the acquireFence passed to it by the
@@ -97,17 +97,17 @@
     /**
      * The release sync fence for this buffer. The HAL must set this to a valid
      * fence fd when returning the input buffer or output buffers to the client
-     * in a CaptureResult, or set it to null to indicate that no waiting is
+     * in a CaptureResult, or leave it empty to indicate that no waiting is
      * required for this buffer.
      *
-     * The client must set this to be null for all buffers included in a
+     * The client must leave this empty for all buffers included in a
      * processCaptureRequest call.
      *
      * After signaling the releaseFence for this buffer, the HAL
      * must not make any further attempts to access this buffer as the
      * ownership has been fully transferred back to the client.
      *
-     * If this is null, then the ownership of this buffer is transferred back
+     * If this is empty, then the ownership of the buffer is transferred back
      * immediately upon the call of processCaptureResult.
      */
     NativeHandle releaseFence;
diff --git a/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl b/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
index cacd32c..197d9af 100644
--- a/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
@@ -62,7 +62,7 @@
      */
     CameraMetadata sessionParams;
 
-   /**
+    /**
      * An incrementing counter used for HAL to keep track of the stream
      * configuration and the paired oneway signalStreamFlush call. When the
      * counter in signalStreamFlush call is less than the counter here, that
@@ -83,4 +83,13 @@
      * any one of the supported multi-resolution input stream sizes.
      */
     boolean multiResolutionInputImage;
+
+    /**
+     * Logging identifier to join HAL logs to logs collected by cameraservice. This field has no
+     * functional purpose.
+     *
+     * See documentation of 'mLogId' in frameworks/av/camera/include/camera/CameraSessionStats.h
+     * for specifics of this identifier and how it can be used to join with cameraservice logs.
+     */
+    long logId = 0;
 }
diff --git a/camera/device/default/Android.bp b/camera/device/default/Android.bp
new file mode 100644
index 0000000..b577597
--- /dev/null
+++ b/camera/device/default/Android.bp
@@ -0,0 +1,71 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // 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_shared {
+    name: "camera.device-external-impl",
+    defaults: ["hidl_defaults"],
+    proprietary: true,
+    srcs: [
+        "ExternalCameraDevice.cpp",
+        "ExternalCameraDeviceSession.cpp",
+        "ExternalCameraOfflineSession.cpp",
+        "ExternalCameraUtils.cpp",
+        "convert.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.camera.common-V1-ndk",
+        "android.hardware.camera.device-V1-ndk",
+        "android.hardware.graphics.allocator-V1-ndk",
+        "android.hardware.graphics.common-V4-ndk",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.graphics.mapper@4.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "libbinder_ndk",
+        "libcamera_metadata",
+        "libcutils",
+        "libexif",
+        "libfmq",
+        "libgralloctypes",
+        "libhardware",
+        "libhidlbase",
+        "libhidlmemory",
+        "libjpeg",
+        "liblog",
+        "libsync",
+        "libtinyxml2",
+        "libutils",
+        "libyuv",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+        "libaidlcommonsupport",
+    ],
+    header_libs: [
+        "media_plugin_headers",
+    ],
+    export_include_dirs: ["."],
+}
diff --git a/camera/device/default/ExternalCameraDevice.cpp b/camera/device/default/ExternalCameraDevice.cpp
new file mode 100644
index 0000000..677fb42
--- /dev/null
+++ b/camera/device/default/ExternalCameraDevice.cpp
@@ -0,0 +1,1001 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamDev"
+// #define LOG_NDEBUG 0
+#include <log/log.h>
+
+#include "ExternalCameraDevice.h"
+
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <convert.h>
+#include <linux/videodev2.h>
+#include <regex>
+#include <set>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+
+namespace {
+// Only support MJPEG for now as it seems to be the one supports higher fps
+// Other formats to consider in the future:
+// * V4L2_PIX_FMT_YVU420 (== YV12)
+// * V4L2_PIX_FMT_YVYU (YVYU: can be converted to YV12 or other YUV420_888 formats)
+const std::array<uint32_t, /*size*/ 2> kSupportedFourCCs{
+        {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_Z16}};  // double braces required in C++11
+
+constexpr int MAX_RETRY = 5;                  // Allow retry v4l2 open failures a few times.
+constexpr int OPEN_RETRY_SLEEP_US = 100'000;  // 100ms * MAX_RETRY = 0.5 seconds
+
+const std::regex kDevicePathRE("/dev/video([0-9]+)");
+}  // namespace
+
+std::string ExternalCameraDevice::kDeviceVersion = "1.1";
+
+ExternalCameraDevice::ExternalCameraDevice(const std::string& devicePath,
+                                           const ExternalCameraConfig& config)
+    : mCameraId("-1"), mDevicePath(devicePath), mCfg(config) {
+    std::smatch sm;
+    if (std::regex_match(mDevicePath, sm, kDevicePathRE)) {
+        mCameraId = std::to_string(mCfg.cameraIdOffset + std::stoi(sm[1]));
+    } else {
+        ALOGE("%s: device path match failed for %s", __FUNCTION__, mDevicePath.c_str());
+    }
+}
+
+ExternalCameraDevice::~ExternalCameraDevice() {}
+
+ndk::ScopedAStatus ExternalCameraDevice::getCameraCharacteristics(CameraMetadata* _aidl_return) {
+    Mutex::Autolock _l(mLock);
+    if (_aidl_return == nullptr) {
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+
+    if (isInitFailedLocked()) {
+        return fromStatus(Status::INTERNAL_ERROR);
+    }
+
+    const camera_metadata_t* rawMetadata = mCameraCharacteristics.getAndLock();
+    convertToAidl(rawMetadata, _aidl_return);
+    mCameraCharacteristics.unlock(rawMetadata);
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::getPhysicalCameraCharacteristics(const std::string&,
+                                                                          CameraMetadata*) {
+    ALOGE("%s: Physical camera functions are not supported for external cameras.", __FUNCTION__);
+    return fromStatus(Status::ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::getResourceCost(CameraResourceCost* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+
+    _aidl_return->resourceCost = 100;
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::isStreamCombinationSupported(
+        const StreamConfiguration& in_streams, bool* _aidl_return) {
+    if (isInitFailed()) {
+        ALOGE("%s: camera %s. camera init failed!", __FUNCTION__, mCameraId.c_str());
+        return fromStatus(Status::INTERNAL_ERROR);
+    }
+    Status s = ExternalCameraDeviceSession::isStreamCombinationSupported(in_streams,
+                                                                         mSupportedFormats, mCfg);
+    *_aidl_return = s == Status::OK;
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::open(
+        const std::shared_ptr<ICameraDeviceCallback>& in_callback,
+        std::shared_ptr<ICameraDeviceSession>* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        ALOGE("%s: cannot open camera %s. return session ptr is null!", __FUNCTION__,
+              mCameraId.c_str());
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+
+    Mutex::Autolock _l(mLock);
+    if (isInitFailedLocked()) {
+        ALOGE("%s: cannot open camera %s. camera init failed!", __FUNCTION__, mCameraId.c_str());
+        return fromStatus(Status::INTERNAL_ERROR);
+    }
+
+    std::shared_ptr<ExternalCameraDeviceSession> session;
+    ALOGV("%s: Initializing device for camera %s", __FUNCTION__, mCameraId.c_str());
+    session = mSession.lock();
+
+    if (session != nullptr && !session->isClosed()) {
+        ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
+        return fromStatus(Status::CAMERA_IN_USE);
+    }
+
+    int numAttempt = 0;
+    unique_fd fd(::open(mDevicePath.c_str(), O_RDWR));
+    while (fd.get() < 0 && numAttempt < MAX_RETRY) {
+        // Previous retry attempts failed. Retry opening the device at most MAX_RETRY times
+        ALOGW("%s: v4l2 device %s open failed, wait 33ms and try again", __FUNCTION__,
+              mDevicePath.c_str());
+        usleep(OPEN_RETRY_SLEEP_US);  // sleep and try again
+        fd.reset(::open(mDevicePath.c_str(), O_RDWR));
+        numAttempt++;
+    }
+
+    if (fd.get() < 0) {
+        ALOGE("%s: v4l2 device open %s failed: %s", __FUNCTION__, mDevicePath.c_str(),
+              strerror(errno));
+        return fromStatus(Status::INTERNAL_ERROR);
+    }
+
+    session = createSession(in_callback, mCfg, mSupportedFormats, mCroppingType,
+                            mCameraCharacteristics, mCameraId, std::move(fd));
+    if (session == nullptr) {
+        ALOGE("%s: camera device session allocation failed", __FUNCTION__);
+        return fromStatus(Status::INTERNAL_ERROR);
+    }
+
+    if (session->isInitFailed()) {
+        ALOGE("%s: camera device session init failed", __FUNCTION__);
+        return fromStatus(Status::INTERNAL_ERROR);
+    }
+
+    mSession = session;
+    *_aidl_return = session;
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::openInjectionSession(
+        const std::shared_ptr<ICameraDeviceCallback>&, std::shared_ptr<ICameraInjectionSession>*) {
+    return fromStatus(Status::OPERATION_NOT_SUPPORTED);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::setTorchMode(bool) {
+    return fromStatus(Status::OPERATION_NOT_SUPPORTED);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::turnOnTorchWithStrengthLevel(int32_t) {
+    return fromStatus(Status::OPERATION_NOT_SUPPORTED);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::getTorchStrengthLevel(int32_t*) {
+    return fromStatus(Status::OPERATION_NOT_SUPPORTED);
+}
+
+std::shared_ptr<ExternalCameraDeviceSession> ExternalCameraDevice::createSession(
+        const std::shared_ptr<ICameraDeviceCallback>& cb, const ExternalCameraConfig& cfg,
+        const std::vector<SupportedV4L2Format>& sortedFormats, const CroppingType& croppingType,
+        const common::V1_0::helper::CameraMetadata& chars, const std::string& cameraId,
+        unique_fd v4l2Fd) {
+    return ndk::SharedRefBase::make<ExternalCameraDeviceSession>(
+            cb, cfg, sortedFormats, croppingType, chars, cameraId, std::move(v4l2Fd));
+}
+
+bool ExternalCameraDevice::isInitFailed() {
+    Mutex::Autolock _l(mLock);
+    return isInitFailedLocked();
+}
+
+bool ExternalCameraDevice::isInitFailedLocked() {
+    if (!mInitialized) {
+        status_t ret = initCameraCharacteristics();
+        if (ret != OK) {
+            ALOGE("%s: init camera characteristics failed: errorno %d", __FUNCTION__, ret);
+            mInitFailed = true;
+        }
+        mInitialized = true;
+    }
+    return mInitFailed;
+}
+
+void ExternalCameraDevice::initSupportedFormatsLocked(int fd) {
+    std::vector<SupportedV4L2Format> horizontalFmts =
+            getCandidateSupportedFormatsLocked(fd, HORIZONTAL, mCfg.fpsLimits, mCfg.depthFpsLimits,
+                                               mCfg.minStreamSize, mCfg.depthEnabled);
+    std::vector<SupportedV4L2Format> verticalFmts =
+            getCandidateSupportedFormatsLocked(fd, VERTICAL, mCfg.fpsLimits, mCfg.depthFpsLimits,
+                                               mCfg.minStreamSize, mCfg.depthEnabled);
+
+    size_t horiSize = horizontalFmts.size();
+    size_t vertSize = verticalFmts.size();
+
+    if (horiSize == 0 && vertSize == 0) {
+        ALOGE("%s: cannot find suitable cropping type!", __FUNCTION__);
+        return;
+    }
+
+    if (horiSize == 0) {
+        mSupportedFormats = verticalFmts;
+        mCroppingType = VERTICAL;
+        return;
+    } else if (vertSize == 0) {
+        mSupportedFormats = horizontalFmts;
+        mCroppingType = HORIZONTAL;
+        return;
+    }
+
+    const auto& maxHoriSize = horizontalFmts[horizontalFmts.size() - 1];
+    const auto& maxVertSize = verticalFmts[verticalFmts.size() - 1];
+
+    // Try to keep the largest possible output size
+    // When they are the same or ambiguous, pick the one support more sizes
+    if (maxHoriSize.width == maxVertSize.width && maxHoriSize.height == maxVertSize.height) {
+        if (horiSize > vertSize) {
+            mSupportedFormats = horizontalFmts;
+            mCroppingType = HORIZONTAL;
+        } else {
+            mSupportedFormats = verticalFmts;
+            mCroppingType = VERTICAL;
+        }
+    } else if (maxHoriSize.width >= maxVertSize.width && maxHoriSize.height >= maxVertSize.height) {
+        mSupportedFormats = horizontalFmts;
+        mCroppingType = HORIZONTAL;
+    } else if (maxHoriSize.width <= maxVertSize.width && maxHoriSize.height <= maxVertSize.height) {
+        mSupportedFormats = verticalFmts;
+        mCroppingType = VERTICAL;
+    } else {
+        if (horiSize > vertSize) {
+            mSupportedFormats = horizontalFmts;
+            mCroppingType = HORIZONTAL;
+        } else {
+            mSupportedFormats = verticalFmts;
+            mCroppingType = VERTICAL;
+        }
+    }
+}
+
+status_t ExternalCameraDevice::initCameraCharacteristics() {
+    if (!mCameraCharacteristics.isEmpty()) {
+        // Camera Characteristics previously initialized. Skip.
+        return OK;
+    }
+
+    // init camera characteristics
+    unique_fd fd(::open(mDevicePath.c_str(), O_RDWR));
+    if (fd.get() < 0) {
+        ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mDevicePath.c_str());
+        return DEAD_OBJECT;
+    }
+
+    status_t ret;
+    ret = initDefaultCharsKeys(&mCameraCharacteristics);
+    if (ret != OK) {
+        ALOGE("%s: init default characteristics key failed: errorno %d", __FUNCTION__, ret);
+        mCameraCharacteristics.clear();
+        return ret;
+    }
+
+    ret = initCameraControlsCharsKeys(fd.get(), &mCameraCharacteristics);
+    if (ret != OK) {
+        ALOGE("%s: init camera control characteristics key failed: errorno %d", __FUNCTION__, ret);
+        mCameraCharacteristics.clear();
+        return ret;
+    }
+
+    ret = initOutputCharsKeys(fd.get(), &mCameraCharacteristics);
+    if (ret != OK) {
+        ALOGE("%s: init output characteristics key failed: errorno %d", __FUNCTION__, ret);
+        mCameraCharacteristics.clear();
+        return ret;
+    }
+
+    ret = initAvailableCapabilities(&mCameraCharacteristics);
+    if (ret != OK) {
+        ALOGE("%s: init available capabilities key failed: errorno %d", __FUNCTION__, ret);
+        mCameraCharacteristics.clear();
+        return ret;
+    }
+
+    return OK;
+}
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#define UPDATE(tag, data, size)                        \
+    do {                                               \
+        if (metadata->update((tag), (data), (size))) { \
+            ALOGE("Update " #tag " failed!");          \
+            return -EINVAL;                            \
+        }                                              \
+    } while (0)
+
+status_t ExternalCameraDevice::initAvailableCapabilities(
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+    if (mSupportedFormats.empty()) {
+        ALOGE("%s: Supported formats list is empty", __FUNCTION__);
+        return UNKNOWN_ERROR;
+    }
+
+    bool hasDepth = false;
+    bool hasColor = false;
+    for (const auto& fmt : mSupportedFormats) {
+        switch (fmt.fourcc) {
+            case V4L2_PIX_FMT_Z16:
+                hasDepth = true;
+                break;
+            case V4L2_PIX_FMT_MJPEG:
+                hasColor = true;
+                break;
+            default:
+                ALOGW("%s: Unsupported format found", __FUNCTION__);
+        }
+    }
+
+    std::vector<uint8_t> availableCapabilities;
+    if (hasDepth) {
+        availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT);
+    }
+    if (hasColor) {
+        availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
+    }
+    if (!availableCapabilities.empty()) {
+        UPDATE(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, availableCapabilities.data(),
+               availableCapabilities.size());
+    }
+
+    return OK;
+}
+
+status_t ExternalCameraDevice::initDefaultCharsKeys(
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+    const uint8_t hardware_level = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL;
+    UPDATE(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &hardware_level, 1);
+
+    // android.colorCorrection
+    const uint8_t availableAberrationModes[] = {ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF};
+    UPDATE(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, availableAberrationModes,
+           ARRAY_SIZE(availableAberrationModes));
+
+    // android.control
+    const uint8_t antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
+    UPDATE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, &antibandingMode, 1);
+
+    const int32_t controlMaxRegions[] = {/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0};
+    UPDATE(ANDROID_CONTROL_MAX_REGIONS, controlMaxRegions, ARRAY_SIZE(controlMaxRegions));
+
+    const uint8_t videoStabilizationMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
+    UPDATE(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, &videoStabilizationMode, 1);
+
+    const uint8_t awbAvailableMode = ANDROID_CONTROL_AWB_MODE_AUTO;
+    UPDATE(ANDROID_CONTROL_AWB_AVAILABLE_MODES, &awbAvailableMode, 1);
+
+    const uint8_t aeAvailableMode = ANDROID_CONTROL_AE_MODE_ON;
+    UPDATE(ANDROID_CONTROL_AE_AVAILABLE_MODES, &aeAvailableMode, 1);
+
+    const uint8_t availableFffect = ANDROID_CONTROL_EFFECT_MODE_OFF;
+    UPDATE(ANDROID_CONTROL_AVAILABLE_EFFECTS, &availableFffect, 1);
+
+    const uint8_t controlAvailableModes[] = {ANDROID_CONTROL_MODE_OFF, ANDROID_CONTROL_MODE_AUTO};
+    UPDATE(ANDROID_CONTROL_AVAILABLE_MODES, controlAvailableModes,
+           ARRAY_SIZE(controlAvailableModes));
+
+    // android.edge
+    const uint8_t edgeMode = ANDROID_EDGE_MODE_OFF;
+    UPDATE(ANDROID_EDGE_AVAILABLE_EDGE_MODES, &edgeMode, 1);
+
+    // android.flash
+    const uint8_t flashInfo = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
+    UPDATE(ANDROID_FLASH_INFO_AVAILABLE, &flashInfo, 1);
+
+    // android.hotPixel
+    const uint8_t hotPixelMode = ANDROID_HOT_PIXEL_MODE_OFF;
+    UPDATE(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES, &hotPixelMode, 1);
+
+    // android.jpeg
+    const int32_t jpegAvailableThumbnailSizes[] = {0,   0,   176, 144, 240, 144, 256,
+                                                   144, 240, 160, 256, 154, 240, 180};
+    UPDATE(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegAvailableThumbnailSizes,
+           ARRAY_SIZE(jpegAvailableThumbnailSizes));
+
+    const int32_t jpegMaxSize = mCfg.maxJpegBufSize;
+    UPDATE(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1);
+
+    // android.lens
+    const uint8_t focusDistanceCalibration =
+            ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED;
+    UPDATE(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION, &focusDistanceCalibration, 1);
+
+    const uint8_t opticalStabilizationMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+    UPDATE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, &opticalStabilizationMode, 1);
+
+    const uint8_t facing = ANDROID_LENS_FACING_EXTERNAL;
+    UPDATE(ANDROID_LENS_FACING, &facing, 1);
+
+    // android.noiseReduction
+    const uint8_t noiseReductionMode = ANDROID_NOISE_REDUCTION_MODE_OFF;
+    UPDATE(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, &noiseReductionMode, 1);
+    UPDATE(ANDROID_NOISE_REDUCTION_MODE, &noiseReductionMode, 1);
+
+    const int32_t partialResultCount = 1;
+    UPDATE(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &partialResultCount, 1);
+
+    // This means pipeline latency of X frame intervals. The maximum number is 4.
+    const uint8_t requestPipelineMaxDepth = 4;
+    UPDATE(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &requestPipelineMaxDepth, 1);
+
+    // Three numbers represent the maximum numbers of different types of output
+    // streams simultaneously. The types are raw sensor, processed (but not
+    // stalling), and processed (but stalling). For usb limited mode, raw sensor
+    // is not supported. Stalling stream is JPEG. Non-stalling streams are
+    // YUV_420_888 or YV12.
+    const int32_t requestMaxNumOutputStreams[] = {
+            /*RAW*/ 0,
+            /*Processed*/ ExternalCameraDeviceSession::kMaxProcessedStream,
+            /*Stall*/ ExternalCameraDeviceSession::kMaxStallStream};
+    UPDATE(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, requestMaxNumOutputStreams,
+           ARRAY_SIZE(requestMaxNumOutputStreams));
+
+    // Limited mode doesn't support reprocessing.
+    const int32_t requestMaxNumInputStreams = 0;
+    UPDATE(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, &requestMaxNumInputStreams, 1);
+
+    // android.scaler
+    // TODO: b/72263447 V4L2_CID_ZOOM_*
+    const float scalerAvailableMaxDigitalZoom[] = {1};
+    UPDATE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, scalerAvailableMaxDigitalZoom,
+           ARRAY_SIZE(scalerAvailableMaxDigitalZoom));
+
+    const uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
+    UPDATE(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
+
+    const int32_t testPatternModes[] = {ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
+                                        ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR};
+    UPDATE(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, testPatternModes,
+           ARRAY_SIZE(testPatternModes));
+
+    const uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
+    UPDATE(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, &timestampSource, 1);
+
+    // Orientation is a bit odd for external camera, but consider it as the orientation
+    // between the external camera sensor (which is usually landscape) and the device's
+    // natural display orientation. For devices with natural landscape display (ex: tablet/TV), the
+    // orientation should be 0. For devices with natural portrait display (phone), the orientation
+    // should be 270.
+    const int32_t orientation = mCfg.orientation;
+    UPDATE(ANDROID_SENSOR_ORIENTATION, &orientation, 1);
+
+    // android.shading
+    const uint8_t availableMode = ANDROID_SHADING_MODE_OFF;
+    UPDATE(ANDROID_SHADING_AVAILABLE_MODES, &availableMode, 1);
+
+    // android.statistics
+    const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
+    UPDATE(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, &faceDetectMode, 1);
+
+    const int32_t maxFaceCount = 0;
+    UPDATE(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &maxFaceCount, 1);
+
+    const uint8_t availableHotpixelMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
+    UPDATE(ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES, &availableHotpixelMode, 1);
+
+    const uint8_t lensShadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+    UPDATE(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, &lensShadingMapMode, 1);
+
+    // android.sync
+    const int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
+    UPDATE(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
+
+    /* Other sensor/RAW related keys:
+     * android.sensor.info.colorFilterArrangement -> no need if we don't do RAW
+     * android.sensor.info.physicalSize           -> not available
+     * android.sensor.info.whiteLevel             -> not available/not needed
+     * android.sensor.info.lensShadingApplied     -> not needed
+     * android.sensor.info.preCorrectionActiveArraySize -> not available/not needed
+     * android.sensor.blackLevelPattern           -> not available/not needed
+     */
+
+    const int32_t availableRequestKeys[] = {ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
+                                            ANDROID_CONTROL_AE_ANTIBANDING_MODE,
+                                            ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+                                            ANDROID_CONTROL_AE_LOCK,
+                                            ANDROID_CONTROL_AE_MODE,
+                                            ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+                                            ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
+                                            ANDROID_CONTROL_AF_MODE,
+                                            ANDROID_CONTROL_AF_TRIGGER,
+                                            ANDROID_CONTROL_AWB_LOCK,
+                                            ANDROID_CONTROL_AWB_MODE,
+                                            ANDROID_CONTROL_CAPTURE_INTENT,
+                                            ANDROID_CONTROL_EFFECT_MODE,
+                                            ANDROID_CONTROL_MODE,
+                                            ANDROID_CONTROL_SCENE_MODE,
+                                            ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+                                            ANDROID_FLASH_MODE,
+                                            ANDROID_JPEG_ORIENTATION,
+                                            ANDROID_JPEG_QUALITY,
+                                            ANDROID_JPEG_THUMBNAIL_QUALITY,
+                                            ANDROID_JPEG_THUMBNAIL_SIZE,
+                                            ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+                                            ANDROID_NOISE_REDUCTION_MODE,
+                                            ANDROID_SCALER_CROP_REGION,
+                                            ANDROID_SENSOR_TEST_PATTERN_MODE,
+                                            ANDROID_STATISTICS_FACE_DETECT_MODE,
+                                            ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE};
+    UPDATE(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, availableRequestKeys,
+           ARRAY_SIZE(availableRequestKeys));
+
+    const int32_t availableResultKeys[] = {ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
+                                           ANDROID_CONTROL_AE_ANTIBANDING_MODE,
+                                           ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+                                           ANDROID_CONTROL_AE_LOCK,
+                                           ANDROID_CONTROL_AE_MODE,
+                                           ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+                                           ANDROID_CONTROL_AE_STATE,
+                                           ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
+                                           ANDROID_CONTROL_AF_MODE,
+                                           ANDROID_CONTROL_AF_STATE,
+                                           ANDROID_CONTROL_AF_TRIGGER,
+                                           ANDROID_CONTROL_AWB_LOCK,
+                                           ANDROID_CONTROL_AWB_MODE,
+                                           ANDROID_CONTROL_AWB_STATE,
+                                           ANDROID_CONTROL_CAPTURE_INTENT,
+                                           ANDROID_CONTROL_EFFECT_MODE,
+                                           ANDROID_CONTROL_MODE,
+                                           ANDROID_CONTROL_SCENE_MODE,
+                                           ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+                                           ANDROID_FLASH_MODE,
+                                           ANDROID_FLASH_STATE,
+                                           ANDROID_JPEG_ORIENTATION,
+                                           ANDROID_JPEG_QUALITY,
+                                           ANDROID_JPEG_THUMBNAIL_QUALITY,
+                                           ANDROID_JPEG_THUMBNAIL_SIZE,
+                                           ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+                                           ANDROID_NOISE_REDUCTION_MODE,
+                                           ANDROID_REQUEST_PIPELINE_DEPTH,
+                                           ANDROID_SCALER_CROP_REGION,
+                                           ANDROID_SENSOR_TIMESTAMP,
+                                           ANDROID_STATISTICS_FACE_DETECT_MODE,
+                                           ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
+                                           ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
+                                           ANDROID_STATISTICS_SCENE_FLICKER};
+    UPDATE(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, availableResultKeys,
+           ARRAY_SIZE(availableResultKeys));
+
+    UPDATE(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, AVAILABLE_CHARACTERISTICS_KEYS.data(),
+           AVAILABLE_CHARACTERISTICS_KEYS.size());
+
+    return OK;
+}
+
+status_t ExternalCameraDevice::initCameraControlsCharsKeys(
+        int, ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+    // android.sensor.info.sensitivityRange   -> V4L2_CID_ISO_SENSITIVITY
+    // android.sensor.info.exposureTimeRange  -> V4L2_CID_EXPOSURE_ABSOLUTE
+    // android.sensor.info.maxFrameDuration   -> TBD
+    // android.lens.info.minimumFocusDistance -> V4L2_CID_FOCUS_ABSOLUTE
+    // android.lens.info.hyperfocalDistance
+    // android.lens.info.availableFocalLengths -> not available?
+
+    // android.control
+    // No AE compensation support for now.
+    // TODO: V4L2_CID_EXPOSURE_BIAS
+    const int32_t controlAeCompensationRange[] = {0, 0};
+    UPDATE(ANDROID_CONTROL_AE_COMPENSATION_RANGE, controlAeCompensationRange,
+           ARRAY_SIZE(controlAeCompensationRange));
+    const camera_metadata_rational_t controlAeCompensationStep[] = {{0, 1}};
+    UPDATE(ANDROID_CONTROL_AE_COMPENSATION_STEP, controlAeCompensationStep,
+           ARRAY_SIZE(controlAeCompensationStep));
+
+    // TODO: Check V4L2_CID_AUTO_FOCUS_*.
+    const uint8_t afAvailableModes[] = {ANDROID_CONTROL_AF_MODE_AUTO, ANDROID_CONTROL_AF_MODE_OFF};
+    UPDATE(ANDROID_CONTROL_AF_AVAILABLE_MODES, afAvailableModes, ARRAY_SIZE(afAvailableModes));
+
+    // TODO: V4L2_CID_SCENE_MODE
+    const uint8_t availableSceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED;
+    UPDATE(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, &availableSceneMode, 1);
+
+    // TODO: V4L2_CID_3A_LOCK
+    const uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
+    UPDATE(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &aeLockAvailable, 1);
+    const uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
+    UPDATE(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &awbLockAvailable, 1);
+
+    // TODO: V4L2_CID_ZOOM_*
+    const float scalerAvailableMaxDigitalZoom[] = {1};
+    UPDATE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, scalerAvailableMaxDigitalZoom,
+           ARRAY_SIZE(scalerAvailableMaxDigitalZoom));
+
+    return OK;
+}
+
+status_t ExternalCameraDevice::initOutputCharsKeys(
+        int fd, ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+    initSupportedFormatsLocked(fd);
+    if (mSupportedFormats.empty()) {
+        ALOGE("%s: Init supported format list failed", __FUNCTION__);
+        return UNKNOWN_ERROR;
+    }
+
+    bool hasDepth = false;
+    bool hasColor = false;
+
+    // For V4L2_PIX_FMT_Z16
+    std::array<int, /*size*/ 1> halDepthFormats{{HAL_PIXEL_FORMAT_Y16}};
+    // For V4L2_PIX_FMT_MJPEG
+    std::array<int, /*size*/ 3> halFormats{{HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_YCbCr_420_888,
+                                            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED}};
+
+    for (const auto& supportedFormat : mSupportedFormats) {
+        switch (supportedFormat.fourcc) {
+            case V4L2_PIX_FMT_Z16:
+                hasDepth = true;
+                break;
+            case V4L2_PIX_FMT_MJPEG:
+                hasColor = true;
+                break;
+            default:
+                ALOGW("%s: format %c%c%c%c is not supported!", __FUNCTION__,
+                      supportedFormat.fourcc & 0xFF, (supportedFormat.fourcc >> 8) & 0xFF,
+                      (supportedFormat.fourcc >> 16) & 0xFF, (supportedFormat.fourcc >> 24) & 0xFF);
+        }
+    }
+
+    if (hasDepth) {
+        status_t ret = initOutputCharsKeysByFormat(
+                metadata, V4L2_PIX_FMT_Z16, halDepthFormats,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
+                ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
+        if (ret != OK) {
+            ALOGE("%s: Unable to initialize depth format keys: %s", __FUNCTION__,
+                  statusToString(ret).c_str());
+            return ret;
+        }
+    }
+    if (hasColor) {
+        status_t ret =
+                initOutputCharsKeysByFormat(metadata, V4L2_PIX_FMT_MJPEG, halFormats,
+                                            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+                                            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+                                            ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
+                                            ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
+        if (ret != OK) {
+            ALOGE("%s: Unable to initialize color format keys: %s", __FUNCTION__,
+                  statusToString(ret).c_str());
+            return ret;
+        }
+    }
+
+    status_t ret = calculateMinFps(metadata);
+    if (ret != OK) {
+        ALOGE("%s: Unable to update fps metadata: %s", __FUNCTION__, statusToString(ret).c_str());
+        return ret;
+    }
+
+    SupportedV4L2Format maximumFormat{.width = 0, .height = 0};
+    for (const auto& supportedFormat : mSupportedFormats) {
+        if (supportedFormat.width >= maximumFormat.width &&
+            supportedFormat.height >= maximumFormat.height) {
+            maximumFormat = supportedFormat;
+        }
+    }
+    int32_t activeArraySize[] = {0, 0, static_cast<int32_t>(maximumFormat.width),
+                                 static_cast<int32_t>(maximumFormat.height)};
+    UPDATE(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, activeArraySize,
+           ARRAY_SIZE(activeArraySize));
+    UPDATE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArraySize, ARRAY_SIZE(activeArraySize));
+
+    int32_t pixelArraySize[] = {static_cast<int32_t>(maximumFormat.width),
+                                static_cast<int32_t>(maximumFormat.height)};
+    UPDATE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArraySize, ARRAY_SIZE(pixelArraySize));
+    return OK;
+}
+
+template <size_t SIZE>
+status_t ExternalCameraDevice::initOutputCharsKeysByFormat(
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata,
+        uint32_t fourcc, const std::array<int, SIZE>& halFormats, int streamConfigTag,
+        int streamConfigurationKey, int minFrameDurationKey, int stallDurationKey) {
+    if (mSupportedFormats.empty()) {
+        ALOGE("%s: Init supported format list failed", __FUNCTION__);
+        return UNKNOWN_ERROR;
+    }
+
+    std::vector<int32_t> streamConfigurations;
+    std::vector<int64_t> minFrameDurations;
+    std::vector<int64_t> stallDurations;
+
+    for (const auto& supportedFormat : mSupportedFormats) {
+        if (supportedFormat.fourcc != fourcc) {
+            // Skip 4CCs not meant for the halFormats
+            continue;
+        }
+        for (const auto& format : halFormats) {
+            streamConfigurations.push_back(format);
+            streamConfigurations.push_back(supportedFormat.width);
+            streamConfigurations.push_back(supportedFormat.height);
+            streamConfigurations.push_back(streamConfigTag);
+        }
+
+        int64_t minFrameDuration = std::numeric_limits<int64_t>::max();
+        for (const auto& fr : supportedFormat.frameRates) {
+            // 1000000000LL < (2^32 - 1) and
+            // fr.durationNumerator is uint32_t, so no overflow here
+            int64_t frameDuration = 1000000000LL * fr.durationNumerator / fr.durationDenominator;
+            if (frameDuration < minFrameDuration) {
+                minFrameDuration = frameDuration;
+            }
+        }
+
+        for (const auto& format : halFormats) {
+            minFrameDurations.push_back(format);
+            minFrameDurations.push_back(supportedFormat.width);
+            minFrameDurations.push_back(supportedFormat.height);
+            minFrameDurations.push_back(minFrameDuration);
+        }
+
+        // The stall duration is 0 for non-jpeg formats. For JPEG format, stall
+        // duration can be 0 if JPEG is small. Here we choose 1 sec for JPEG.
+        // TODO: b/72261675. Maybe set this dynamically
+        for (const auto& format : halFormats) {
+            const int64_t NS_TO_SECOND = 1E9;
+            int64_t stall_duration = (format == HAL_PIXEL_FORMAT_BLOB) ? NS_TO_SECOND : 0;
+            stallDurations.push_back(format);
+            stallDurations.push_back(supportedFormat.width);
+            stallDurations.push_back(supportedFormat.height);
+            stallDurations.push_back(stall_duration);
+        }
+    }
+
+    UPDATE(streamConfigurationKey, streamConfigurations.data(), streamConfigurations.size());
+
+    UPDATE(minFrameDurationKey, minFrameDurations.data(), minFrameDurations.size());
+
+    UPDATE(stallDurationKey, stallDurations.data(), stallDurations.size());
+
+    return OK;
+}
+
+status_t ExternalCameraDevice::calculateMinFps(
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+    std::set<int32_t> framerates;
+    int32_t minFps = std::numeric_limits<int32_t>::max();
+
+    for (const auto& supportedFormat : mSupportedFormats) {
+        for (const auto& fr : supportedFormat.frameRates) {
+            int32_t frameRateInt = static_cast<int32_t>(fr.getFramesPerSecond());
+            if (minFps > frameRateInt) {
+                minFps = frameRateInt;
+            }
+            framerates.insert(frameRateInt);
+        }
+    }
+
+    std::vector<int32_t> fpsRanges;
+    // FPS ranges
+    for (const auto& framerate : framerates) {
+        // Empirical: webcams often have close to 2x fps error and cannot support fixed fps range
+        fpsRanges.push_back(framerate / 2);
+        fpsRanges.push_back(framerate);
+    }
+    minFps /= 2;
+    int64_t maxFrameDuration = 1000000000LL / minFps;
+
+    UPDATE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fpsRanges.data(), fpsRanges.size());
+
+    UPDATE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, &maxFrameDuration, 1);
+
+    return OK;
+}
+
+#undef ARRAY_SIZE
+#undef UPDATE
+
+void ExternalCameraDevice::getFrameRateList(int fd, double fpsUpperBound,
+                                            SupportedV4L2Format* format) {
+    format->frameRates.clear();
+
+    v4l2_frmivalenum frameInterval{
+            .index = 0,
+            .pixel_format = format->fourcc,
+            .width = static_cast<__u32>(format->width),
+            .height = static_cast<__u32>(format->height),
+    };
+
+    for (frameInterval.index = 0;
+         TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frameInterval)) == 0;
+         ++frameInterval.index) {
+        if (frameInterval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
+            if (frameInterval.discrete.numerator != 0) {
+                SupportedV4L2Format::FrameRate fr = {frameInterval.discrete.numerator,
+                                                     frameInterval.discrete.denominator};
+                double framerate = fr.getFramesPerSecond();
+                if (framerate > fpsUpperBound) {
+                    continue;
+                }
+                ALOGV("index:%d, format:%c%c%c%c, w %d, h %d, framerate %f", frameInterval.index,
+                      frameInterval.pixel_format & 0xFF, (frameInterval.pixel_format >> 8) & 0xFF,
+                      (frameInterval.pixel_format >> 16) & 0xFF,
+                      (frameInterval.pixel_format >> 24) & 0xFF, frameInterval.width,
+                      frameInterval.height, framerate);
+                format->frameRates.push_back(fr);
+            }
+        }
+    }
+
+    if (format->frameRates.empty()) {
+        ALOGE("%s: failed to get supported frame rates for format:%c%c%c%c w %d h %d", __FUNCTION__,
+              frameInterval.pixel_format & 0xFF, (frameInterval.pixel_format >> 8) & 0xFF,
+              (frameInterval.pixel_format >> 16) & 0xFF, (frameInterval.pixel_format >> 24) & 0xFF,
+              frameInterval.width, frameInterval.height);
+    }
+}
+
+void ExternalCameraDevice::updateFpsBounds(
+        int fd, CroppingType cropType,
+        const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+        SupportedV4L2Format format, std::vector<SupportedV4L2Format>& outFmts) {
+    double fpsUpperBound = -1.0;
+    for (const auto& limit : fpsLimits) {
+        if (cropType == VERTICAL) {
+            if (format.width <= limit.size.width) {
+                fpsUpperBound = limit.fpsUpperBound;
+                break;
+            }
+        } else {  // HORIZONTAL
+            if (format.height <= limit.size.height) {
+                fpsUpperBound = limit.fpsUpperBound;
+                break;
+            }
+        }
+    }
+    if (fpsUpperBound < 0.f) {
+        return;
+    }
+
+    getFrameRateList(fd, fpsUpperBound, &format);
+    if (!format.frameRates.empty()) {
+        outFmts.push_back(format);
+    }
+}
+
+std::vector<SupportedV4L2Format> ExternalCameraDevice::getCandidateSupportedFormatsLocked(
+        int fd, CroppingType cropType,
+        const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+        const std::vector<ExternalCameraConfig::FpsLimitation>& depthFpsLimits,
+        const Size& minStreamSize, bool depthEnabled) {
+    std::vector<SupportedV4L2Format> outFmts;
+    struct v4l2_fmtdesc fmtdesc {
+        .index = 0, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE
+    };
+    int ret = 0;
+    while (ret == 0) {
+        ret = TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc));
+        ALOGV("index:%d,ret:%d, format:%c%c%c%c", fmtdesc.index, ret, fmtdesc.pixelformat & 0xFF,
+              (fmtdesc.pixelformat >> 8) & 0xFF, (fmtdesc.pixelformat >> 16) & 0xFF,
+              (fmtdesc.pixelformat >> 24) & 0xFF);
+
+        if (ret != 0 || (fmtdesc.flags & V4L2_FMT_FLAG_EMULATED)) {
+            // Skip if IOCTL failed, or if the format is emulated
+            fmtdesc.index++;
+            continue;
+        }
+        auto it =
+                std::find(kSupportedFourCCs.begin(), kSupportedFourCCs.end(), fmtdesc.pixelformat);
+        if (it == kSupportedFourCCs.end()) {
+            fmtdesc.index++;
+            continue;
+        }
+
+        // Found supported format
+        v4l2_frmsizeenum frameSize{.index = 0, .pixel_format = fmtdesc.pixelformat};
+        for (; TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frameSize)) == 0;
+             ++frameSize.index) {
+            if (frameSize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
+                ALOGV("index:%d, format:%c%c%c%c, w %d, h %d", frameSize.index,
+                      fmtdesc.pixelformat & 0xFF, (fmtdesc.pixelformat >> 8) & 0xFF,
+                      (fmtdesc.pixelformat >> 16) & 0xFF, (fmtdesc.pixelformat >> 24) & 0xFF,
+                      frameSize.discrete.width, frameSize.discrete.height);
+
+                // Disregard h > w formats so all aspect ratio (h/w) <= 1.0
+                // This will simplify the crop/scaling logic down the road
+                if (frameSize.discrete.height > frameSize.discrete.width) {
+                    continue;
+                }
+
+                // Discard all formats which is smaller than minStreamSize
+                if (frameSize.discrete.width < minStreamSize.width ||
+                    frameSize.discrete.height < minStreamSize.height) {
+                    continue;
+                }
+
+                SupportedV4L2Format format{
+                        .width = static_cast<int32_t>(frameSize.discrete.width),
+                        .height = static_cast<int32_t>(frameSize.discrete.height),
+                        .fourcc = fmtdesc.pixelformat};
+
+                if (format.fourcc == V4L2_PIX_FMT_Z16 && depthEnabled) {
+                    updateFpsBounds(fd, cropType, depthFpsLimits, format, outFmts);
+                } else {
+                    updateFpsBounds(fd, cropType, fpsLimits, format, outFmts);
+                }
+            }
+        }
+        fmtdesc.index++;
+    }
+    trimSupportedFormats(cropType, &outFmts);
+    return outFmts;
+}
+
+void ExternalCameraDevice::trimSupportedFormats(CroppingType cropType,
+                                                std::vector<SupportedV4L2Format>* pFmts) {
+    std::vector<SupportedV4L2Format>& sortedFmts = *pFmts;
+    if (cropType == VERTICAL) {
+        std::sort(sortedFmts.begin(), sortedFmts.end(),
+                  [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
+                      if (a.width == b.width) {
+                          return a.height < b.height;
+                      }
+                      return a.width < b.width;
+                  });
+    } else {
+        std::sort(sortedFmts.begin(), sortedFmts.end(),
+                  [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
+                      if (a.height == b.height) {
+                          return a.width < b.width;
+                      }
+                      return a.height < b.height;
+                  });
+    }
+
+    if (sortedFmts.empty()) {
+        ALOGE("%s: input format list is empty!", __FUNCTION__);
+        return;
+    }
+
+    const auto& maxSize = sortedFmts[sortedFmts.size() - 1];
+    float maxSizeAr = ASPECT_RATIO(maxSize);
+
+    // Remove formats that has aspect ratio not croppable from largest size
+    std::vector<SupportedV4L2Format> out;
+    for (const auto& fmt : sortedFmts) {
+        float ar = ASPECT_RATIO(fmt);
+        if (isAspectRatioClose(ar, maxSizeAr)) {
+            out.push_back(fmt);
+        } else if (cropType == HORIZONTAL && ar < maxSizeAr) {
+            out.push_back(fmt);
+        } else if (cropType == VERTICAL && ar > maxSizeAr) {
+            out.push_back(fmt);
+        } else {
+            ALOGV("%s: size (%d,%d) is removed due to unable to crop %s from (%d,%d)", __FUNCTION__,
+                  fmt.width, fmt.height, cropType == VERTICAL ? "vertically" : "horizontally",
+                  maxSize.width, maxSize.height);
+        }
+    }
+    sortedFmts = out;
+}
+
+binder_status_t ExternalCameraDevice::dump(int fd, const char** args, uint32_t numArgs) {
+    std::shared_ptr<ExternalCameraDeviceSession> session = mSession.lock();
+    if (session == nullptr) {
+        dprintf(fd, "No active camera device session instance\n");
+        return STATUS_OK;
+    }
+
+    return session->dump(fd, args, numArgs);
+}
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/camera/device/default/ExternalCameraDevice.h b/camera/device/default/ExternalCameraDevice.h
new file mode 100644
index 0000000..bcae194
--- /dev/null
+++ b/camera/device/default/ExternalCameraDevice.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICE_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICE_H_
+
+#include <ExternalCameraDeviceSession.h>
+#include <ExternalCameraUtils.h>
+#include <aidl/android/hardware/camera/device/BnCameraDevice.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::CameraResourceCost;
+using ::aidl::android::hardware::camera::device::BnCameraDevice;
+using ::aidl::android::hardware::camera::device::CameraMetadata;
+using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
+using ::aidl::android::hardware::camera::device::ICameraDeviceSession;
+using ::aidl::android::hardware::camera::device::ICameraInjectionSession;
+using ::aidl::android::hardware::camera::device::StreamConfiguration;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+
+class ExternalCameraDevice : public BnCameraDevice {
+  public:
+    // Called by external camera provider HAL.
+    // Provider HAL must ensure the uniqueness of CameraDevice object per cameraId, or there could
+    // be multiple CameraDevice trying to access the same physical camera.  Also, provider will have
+    // to keep track of all CameraDevice objects in order to notify CameraDevice when the underlying
+    // camera is detached.
+    ExternalCameraDevice(const std::string& devicePath, const ExternalCameraConfig& config);
+    ~ExternalCameraDevice() override;
+
+    ndk::ScopedAStatus getCameraCharacteristics(CameraMetadata* _aidl_return) override;
+    ndk::ScopedAStatus getPhysicalCameraCharacteristics(const std::string& in_physicalCameraId,
+                                                        CameraMetadata* _aidl_return) override;
+    ndk::ScopedAStatus getResourceCost(CameraResourceCost* _aidl_return) override;
+    ndk::ScopedAStatus isStreamCombinationSupported(const StreamConfiguration& in_streams,
+                                                    bool* _aidl_return) override;
+    ndk::ScopedAStatus open(const std::shared_ptr<ICameraDeviceCallback>& in_callback,
+                            std::shared_ptr<ICameraDeviceSession>* _aidl_return) override;
+    ndk::ScopedAStatus openInjectionSession(
+            const std::shared_ptr<ICameraDeviceCallback>& in_callback,
+            std::shared_ptr<ICameraInjectionSession>* _aidl_return) override;
+    ndk::ScopedAStatus setTorchMode(bool in_on) override;
+    ndk::ScopedAStatus turnOnTorchWithStrengthLevel(int32_t in_torchStrength) override;
+    ndk::ScopedAStatus getTorchStrengthLevel(int32_t* _aidl_return) override;
+
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+    // Caller must use this method to check if CameraDevice ctor failed
+    bool isInitFailed();
+
+    // Device version to be used by the external camera provider.
+    // Should be of the form <major>.<minor>
+    static std::string kDeviceVersion;
+
+  private:
+    virtual std::shared_ptr<ExternalCameraDeviceSession> createSession(
+            const std::shared_ptr<ICameraDeviceCallback>&, const ExternalCameraConfig& cfg,
+            const std::vector<SupportedV4L2Format>& sortedFormats, const CroppingType& croppingType,
+            const common::V1_0::helper::CameraMetadata& chars, const std::string& cameraId,
+            unique_fd v4l2Fd);
+
+    bool isInitFailedLocked();
+
+    // Init supported w/h/format/fps in mSupportedFormats. Caller still owns fd
+    void initSupportedFormatsLocked(int fd);
+
+    // Calls into virtual member function. Do not use it in constructor
+    status_t initCameraCharacteristics();
+    // Init available capabilities keys
+    virtual status_t initAvailableCapabilities(
+            ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+    // Init non-device dependent keys
+    virtual status_t initDefaultCharsKeys(
+            ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+    // Init camera control chars keys. Caller still owns fd
+    status_t initCameraControlsCharsKeys(
+            int fd, ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+    // Init camera output configuration related keys.  Caller still owns fd
+    status_t initOutputCharsKeys(
+            int fd, ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+
+    // Helper function for initOutputCharskeys
+    template <size_t SIZE>
+    status_t initOutputCharsKeysByFormat(
+            ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata,
+            uint32_t fourcc, const std::array<int, SIZE>& halFormats, int streamConfigTag,
+            int streamConfiguration, int minFrameDuration, int stallDuration);
+
+    status_t calculateMinFps(::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+
+    static void getFrameRateList(int fd, double fpsUpperBound, SupportedV4L2Format* format);
+
+    static void updateFpsBounds(int fd, CroppingType cropType,
+                                const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+                                SupportedV4L2Format format,
+                                std::vector<SupportedV4L2Format>& outFmts);
+
+    // Get candidate supported formats list of input cropping type.
+    static std::vector<SupportedV4L2Format> getCandidateSupportedFormatsLocked(
+            int fd, CroppingType cropType,
+            const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+            const std::vector<ExternalCameraConfig::FpsLimitation>& depthFpsLimits,
+            const Size& minStreamSize, bool depthEnabled);
+    // Trim supported format list by the cropping type. Also sort output formats by width/height
+    static void trimSupportedFormats(CroppingType cropType,
+                                     /*inout*/ std::vector<SupportedV4L2Format>* pFmts);
+
+    Mutex mLock;
+    bool mInitialized = false;
+    bool mInitFailed = false;
+    std::string mCameraId;
+    std::string mDevicePath;
+    const ExternalCameraConfig& mCfg;
+    std::vector<SupportedV4L2Format> mSupportedFormats;
+    CroppingType mCroppingType;
+
+    std::weak_ptr<ExternalCameraDeviceSession> mSession =
+            std::weak_ptr<ExternalCameraDeviceSession>();
+
+    ::android::hardware::camera::common::V1_0::helper::CameraMetadata mCameraCharacteristics;
+
+    const std::vector<int32_t> AVAILABLE_CHARACTERISTICS_KEYS = {
+            ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
+            ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
+            ANDROID_CONTROL_AE_AVAILABLE_MODES,
+            ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
+            ANDROID_CONTROL_AE_COMPENSATION_RANGE,
+            ANDROID_CONTROL_AE_COMPENSATION_STEP,
+            ANDROID_CONTROL_AE_LOCK_AVAILABLE,
+            ANDROID_CONTROL_AF_AVAILABLE_MODES,
+            ANDROID_CONTROL_AVAILABLE_EFFECTS,
+            ANDROID_CONTROL_AVAILABLE_MODES,
+            ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
+            ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
+            ANDROID_CONTROL_AWB_AVAILABLE_MODES,
+            ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+            ANDROID_CONTROL_MAX_REGIONS,
+            ANDROID_FLASH_INFO_AVAILABLE,
+            ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
+            ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
+            ANDROID_LENS_FACING,
+            ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
+            ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
+            ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
+            ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+            ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
+            ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
+            ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
+            ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
+            ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+            ANDROID_SCALER_CROPPING_TYPE,
+            ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+            ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
+            ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
+            ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
+            ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
+            ANDROID_SENSOR_ORIENTATION,
+            ANDROID_SHADING_AVAILABLE_MODES,
+            ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
+            ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
+            ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
+            ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
+            ANDROID_SYNC_MAX_LATENCY};
+};
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICE_H_
diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp
new file mode 100644
index 0000000..c962974
--- /dev/null
+++ b/camera/device/default/ExternalCameraDeviceSession.cpp
@@ -0,0 +1,2945 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamDevSsn"
+// #define LOG_NDEBUG 0
+#include <log/log.h>
+
+#include "ExternalCameraDeviceSession.h"
+
+#include <Exif.h>
+#include <ExternalCameraOfflineSession.h>
+#include <aidl/android/hardware/camera/device/CameraBlob.h>
+#include <aidl/android/hardware/camera/device/CameraBlobId.h>
+#include <aidl/android/hardware/camera/device/ErrorMsg.h>
+#include <aidl/android/hardware/camera/device/ShutterMsg.h>
+#include <aidl/android/hardware/camera/device/StreamBufferRet.h>
+#include <aidl/android/hardware/camera/device/StreamBuffersVal.h>
+#include <aidl/android/hardware/camera/device/StreamConfigurationMode.h>
+#include <aidl/android/hardware/camera/device/StreamRotation.h>
+#include <aidl/android/hardware/camera/device/StreamType.h>
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <convert.h>
+#include <linux/videodev2.h>
+#include <sync/sync.h>
+#include <utils/Trace.h>
+#include <deque>
+
+#define HAVE_JPEG  // required for libyuv.h to export MJPEG decode APIs
+#include <libyuv.h>
+#include <libyuv/convert.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+namespace {
+
+// Size of request/result metadata fast message queue. Change to 0 to always use hwbinder buffer.
+static constexpr size_t kMetadataMsgQueueSize = 1 << 18 /* 256kB */;
+
+const int kBadFramesAfterStreamOn = 1;  // drop x frames after streamOn to get rid of some initial
+                                        // bad frames. TODO: develop a better bad frame detection
+                                        // method
+constexpr int MAX_RETRY = 15;  // Allow retry some ioctl failures a few times to account for some
+                               // webcam showing temporarily ioctl failures.
+constexpr int IOCTL_RETRY_SLEEP_US = 33000;  // 33ms * MAX_RETRY = 0.5 seconds
+
+// Constants for tryLock during dumpstate
+static constexpr int kDumpLockRetries = 50;
+static constexpr int kDumpLockSleep = 60000;
+
+bool tryLock(Mutex& mutex) {
+    bool locked = false;
+    for (int i = 0; i < kDumpLockRetries; ++i) {
+        if (mutex.tryLock() == NO_ERROR) {
+            locked = true;
+            break;
+        }
+        usleep(kDumpLockSleep);
+    }
+    return locked;
+}
+
+bool tryLock(std::mutex& mutex) {
+    bool locked = false;
+    for (int i = 0; i < kDumpLockRetries; ++i) {
+        if (mutex.try_lock()) {
+            locked = true;
+            break;
+        }
+        usleep(kDumpLockSleep);
+    }
+    return locked;
+}
+
+}  // anonymous namespace
+
+using ::aidl::android::hardware::camera::device::BufferRequestStatus;
+using ::aidl::android::hardware::camera::device::CameraBlob;
+using ::aidl::android::hardware::camera::device::CameraBlobId;
+using ::aidl::android::hardware::camera::device::ErrorMsg;
+using ::aidl::android::hardware::camera::device::ShutterMsg;
+using ::aidl::android::hardware::camera::device::StreamBuffer;
+using ::aidl::android::hardware::camera::device::StreamBufferRet;
+using ::aidl::android::hardware::camera::device::StreamBuffersVal;
+using ::aidl::android::hardware::camera::device::StreamConfigurationMode;
+using ::aidl::android::hardware::camera::device::StreamRotation;
+using ::aidl::android::hardware::camera::device::StreamType;
+using ::aidl::android::hardware::graphics::common::Dataspace;
+using ::android::hardware::camera::common::V1_0::helper::ExifUtils;
+
+// Static instances
+const int ExternalCameraDeviceSession::kMaxProcessedStream;
+const int ExternalCameraDeviceSession::kMaxStallStream;
+HandleImporter ExternalCameraDeviceSession::sHandleImporter;
+
+ExternalCameraDeviceSession::ExternalCameraDeviceSession(
+        const std::shared_ptr<ICameraDeviceCallback>& callback, const ExternalCameraConfig& cfg,
+        const std::vector<SupportedV4L2Format>& sortedFormats, const CroppingType& croppingType,
+        const common::V1_0::helper::CameraMetadata& chars, const std::string& cameraId,
+        unique_fd v4l2Fd)
+    : mCallback(callback),
+      mCfg(cfg),
+      mCameraCharacteristics(chars),
+      mSupportedFormats(sortedFormats),
+      mCroppingType(croppingType),
+      mCameraId(cameraId),
+      mV4l2Fd(std::move(v4l2Fd)),
+      mMaxThumbResolution(getMaxThumbResolution()),
+      mMaxJpegResolution(getMaxJpegResolution()) {}
+
+Size ExternalCameraDeviceSession::getMaxThumbResolution() const {
+    return getMaxThumbnailResolution(mCameraCharacteristics);
+}
+
+Size ExternalCameraDeviceSession::getMaxJpegResolution() const {
+    Size ret{0, 0};
+    for (auto& fmt : mSupportedFormats) {
+        if (fmt.width * fmt.height > ret.width * ret.height) {
+            ret = Size{fmt.width, fmt.height};
+        }
+    }
+    return ret;
+}
+
+bool ExternalCameraDeviceSession::initialize() {
+    if (mV4l2Fd.get() < 0) {
+        ALOGE("%s: invalid v4l2 device fd %d!", __FUNCTION__, mV4l2Fd.get());
+        return true;
+    }
+
+    struct v4l2_capability capability;
+    int ret = ioctl(mV4l2Fd.get(), VIDIOC_QUERYCAP, &capability);
+    std::string make, model;
+    if (ret < 0) {
+        ALOGW("%s v4l2 QUERYCAP failed", __FUNCTION__);
+        mExifMake = "Generic UVC webcam";
+        mExifModel = "Generic UVC webcam";
+    } else {
+        // capability.card is UTF-8 encoded
+        char card[32];
+        int j = 0;
+        for (int i = 0; i < 32; i++) {
+            if (capability.card[i] < 128) {
+                card[j++] = capability.card[i];
+            }
+            if (capability.card[i] == '\0') {
+                break;
+            }
+        }
+        if (j == 0 || card[j - 1] != '\0') {
+            mExifMake = "Generic UVC webcam";
+            mExifModel = "Generic UVC webcam";
+        } else {
+            mExifMake = card;
+            mExifModel = card;
+        }
+    }
+
+    initOutputThread();
+    if (mOutputThread == nullptr) {
+        ALOGE("%s: init OutputThread failed!", __FUNCTION__);
+        return true;
+    }
+    mOutputThread->setExifMakeModel(mExifMake, mExifModel);
+
+    status_t status = initDefaultRequests();
+    if (status != OK) {
+        ALOGE("%s: init default requests failed!", __FUNCTION__);
+        return true;
+    }
+
+    mRequestMetadataQueue =
+            std::make_unique<RequestMetadataQueue>(kMetadataMsgQueueSize, false /* non blocking */);
+    if (!mRequestMetadataQueue->isValid()) {
+        ALOGE("%s: invalid request fmq", __FUNCTION__);
+        return true;
+    }
+
+    mResultMetadataQueue =
+            std::make_shared<ResultMetadataQueue>(kMetadataMsgQueueSize, false /* non blocking */);
+    if (!mResultMetadataQueue->isValid()) {
+        ALOGE("%s: invalid result fmq", __FUNCTION__);
+        return true;
+    }
+
+    mOutputThread->run();
+    return false;
+}
+
+bool ExternalCameraDeviceSession::isInitFailed() {
+    Mutex::Autolock _l(mLock);
+    if (!mInitialized) {
+        mInitFail = initialize();
+        mInitialized = true;
+    }
+    return mInitFail;
+}
+
+void ExternalCameraDeviceSession::initOutputThread() {
+    // Grab a shared_ptr to 'this' from ndk::SharedRefBase::ref()
+    std::shared_ptr<ExternalCameraDeviceSession> thiz = ref<ExternalCameraDeviceSession>();
+
+    mBufferRequestThread = std::make_shared<BufferRequestThread>(/*parent=*/thiz, mCallback);
+    mBufferRequestThread->run();
+    mOutputThread = std::make_shared<OutputThread>(/*parent=*/thiz, mCroppingType,
+                                                   mCameraCharacteristics, mBufferRequestThread);
+}
+
+void ExternalCameraDeviceSession::closeOutputThread() {
+    closeOutputThreadImpl();
+}
+
+void ExternalCameraDeviceSession::closeOutputThreadImpl() {
+    if (mOutputThread != nullptr) {
+        mOutputThread->flush();
+        mOutputThread->requestExitAndWait();
+        mOutputThread.reset();
+    }
+}
+
+Status ExternalCameraDeviceSession::initStatus() const {
+    Mutex::Autolock _l(mLock);
+    Status status = Status::OK;
+    if (mInitFail || mClosed) {
+        ALOGI("%s: session initFailed %d closed %d", __FUNCTION__, mInitFail, mClosed);
+        status = Status::INTERNAL_ERROR;
+    }
+    return status;
+}
+
+ExternalCameraDeviceSession::~ExternalCameraDeviceSession() {
+    if (!isClosed()) {
+        ALOGE("ExternalCameraDeviceSession deleted before close!");
+        close(/*callerIsDtor*/ true);
+    }
+}
+
+ScopedAStatus ExternalCameraDeviceSession::constructDefaultRequestSettings(
+        RequestTemplate in_type, CameraMetadata* _aidl_return) {
+    CameraMetadata emptyMetadata;
+    Status status = initStatus();
+    if (status != Status::OK) {
+        return fromStatus(status);
+    }
+    switch (in_type) {
+        case RequestTemplate::PREVIEW:
+        case RequestTemplate::STILL_CAPTURE:
+        case RequestTemplate::VIDEO_RECORD:
+        case RequestTemplate::VIDEO_SNAPSHOT: {
+            *_aidl_return = mDefaultRequests[in_type];
+            break;
+        }
+        case RequestTemplate::MANUAL:
+        case RequestTemplate::ZERO_SHUTTER_LAG:
+            // Don't support MANUAL, ZSL templates
+            status = Status::ILLEGAL_ARGUMENT;
+            break;
+        default:
+            ALOGE("%s: unknown request template type %d", __FUNCTION__, static_cast<int>(in_type));
+            status = Status::ILLEGAL_ARGUMENT;
+            break;
+    }
+    return fromStatus(status);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::configureStreams(
+        const StreamConfiguration& in_requestedConfiguration,
+        std::vector<HalStream>* _aidl_return) {
+    uint32_t blobBufferSize = 0;
+    _aidl_return->clear();
+    Mutex::Autolock _il(mInterfaceLock);
+
+    Status status =
+            isStreamCombinationSupported(in_requestedConfiguration, mSupportedFormats, mCfg);
+    if (status != Status::OK) {
+        return fromStatus(status);
+    }
+
+    status = initStatus();
+    if (status != Status::OK) {
+        return fromStatus(status);
+    }
+
+    {
+        std::lock_guard<std::mutex> lk(mInflightFramesLock);
+        if (!mInflightFrames.empty()) {
+            ALOGE("%s: trying to configureStreams while there are still %zu inflight frames!",
+                  __FUNCTION__, mInflightFrames.size());
+            return fromStatus(Status::INTERNAL_ERROR);
+        }
+    }
+
+    Mutex::Autolock _l(mLock);
+    {
+        Mutex::Autolock _cl(mCbsLock);
+        // Add new streams
+        for (const auto& stream : in_requestedConfiguration.streams) {
+            if (mStreamMap.count(stream.id) == 0) {
+                mStreamMap[stream.id] = stream;
+                mCirculatingBuffers.emplace(stream.id, CirculatingBuffers{});
+            }
+        }
+
+        // Cleanup removed streams
+        for (auto it = mStreamMap.begin(); it != mStreamMap.end();) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : in_requestedConfiguration.streams) {
+                if (id == stream.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                // Unmap all buffers of deleted stream
+                cleanupBuffersLocked(id);
+                it = mStreamMap.erase(it);
+            } else {
+                ++it;
+            }
+        }
+    }
+
+    // Now select a V4L2 format to produce all output streams
+    float desiredAr = (mCroppingType == VERTICAL) ? kMaxAspectRatio : kMinAspectRatio;
+    uint32_t maxDim = 0;
+    for (const auto& stream : in_requestedConfiguration.streams) {
+        float aspectRatio = ASPECT_RATIO(stream);
+        ALOGI("%s: request stream %dx%d", __FUNCTION__, stream.width, stream.height);
+        if ((mCroppingType == VERTICAL && aspectRatio < desiredAr) ||
+            (mCroppingType == HORIZONTAL && aspectRatio > desiredAr)) {
+            desiredAr = aspectRatio;
+        }
+
+        // The dimension that's not cropped
+        uint32_t dim = (mCroppingType == VERTICAL) ? stream.width : stream.height;
+        if (dim > maxDim) {
+            maxDim = dim;
+        }
+    }
+
+    // Find the smallest format that matches the desired aspect ratio and is wide/high enough
+    SupportedV4L2Format v4l2Fmt{.width = 0, .height = 0};
+    for (const auto& fmt : mSupportedFormats) {
+        uint32_t dim = (mCroppingType == VERTICAL) ? fmt.width : fmt.height;
+        if (dim >= maxDim) {
+            float aspectRatio = ASPECT_RATIO(fmt);
+            if (isAspectRatioClose(aspectRatio, desiredAr)) {
+                v4l2Fmt = fmt;
+                // since mSupportedFormats is sorted by width then height, the first matching fmt
+                // will be the smallest one with matching aspect ratio
+                break;
+            }
+        }
+    }
+
+    if (v4l2Fmt.width == 0) {
+        // Cannot find exact good aspect ratio candidate, try to find a close one
+        for (const auto& fmt : mSupportedFormats) {
+            uint32_t dim = (mCroppingType == VERTICAL) ? fmt.width : fmt.height;
+            if (dim >= maxDim) {
+                float aspectRatio = ASPECT_RATIO(fmt);
+                if ((mCroppingType == VERTICAL && aspectRatio < desiredAr) ||
+                    (mCroppingType == HORIZONTAL && aspectRatio > desiredAr)) {
+                    v4l2Fmt = fmt;
+                    break;
+                }
+            }
+        }
+    }
+
+    if (v4l2Fmt.width == 0) {
+        ALOGE("%s: unable to find a resolution matching (%s at least %d, aspect ratio %f)",
+              __FUNCTION__, (mCroppingType == VERTICAL) ? "width" : "height", maxDim, desiredAr);
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+
+    if (configureV4l2StreamLocked(v4l2Fmt) != 0) {
+        ALOGE("V4L configuration failed!, format:%c%c%c%c, w %d, h %d", v4l2Fmt.fourcc & 0xFF,
+              (v4l2Fmt.fourcc >> 8) & 0xFF, (v4l2Fmt.fourcc >> 16) & 0xFF,
+              (v4l2Fmt.fourcc >> 24) & 0xFF, v4l2Fmt.width, v4l2Fmt.height);
+        return fromStatus(Status::INTERNAL_ERROR);
+    }
+
+    Size v4lSize = {v4l2Fmt.width, v4l2Fmt.height};
+    Size thumbSize{0, 0};
+    camera_metadata_ro_entry entry =
+            mCameraCharacteristics.find(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
+    for (uint32_t i = 0; i < entry.count; i += 2) {
+        Size sz{entry.data.i32[i], entry.data.i32[i + 1]};
+        if (sz.width * sz.height > thumbSize.width * thumbSize.height) {
+            thumbSize = sz;
+        }
+    }
+
+    if (thumbSize.width * thumbSize.height == 0) {
+        ALOGE("%s: non-zero thumbnail size not available", __FUNCTION__);
+        return fromStatus(Status::INTERNAL_ERROR);
+    }
+
+    mBlobBufferSize = blobBufferSize;
+    status = mOutputThread->allocateIntermediateBuffers(
+            v4lSize, mMaxThumbResolution, in_requestedConfiguration.streams, blobBufferSize);
+    if (status != Status::OK) {
+        ALOGE("%s: allocating intermediate buffers failed!", __FUNCTION__);
+        return fromStatus(status);
+    }
+
+    std::vector<HalStream>& out = *_aidl_return;
+    out.resize(in_requestedConfiguration.streams.size());
+    for (size_t i = 0; i < in_requestedConfiguration.streams.size(); i++) {
+        out[i].overrideDataSpace = in_requestedConfiguration.streams[i].dataSpace;
+        out[i].id = in_requestedConfiguration.streams[i].id;
+        // TODO: double check should we add those CAMERA flags
+        mStreamMap[in_requestedConfiguration.streams[i].id].usage = out[i].producerUsage =
+                static_cast<BufferUsage>(((int64_t)in_requestedConfiguration.streams[i].usage) |
+                                         ((int64_t)BufferUsage::CPU_WRITE_OFTEN) |
+                                         ((int64_t)BufferUsage::CAMERA_OUTPUT));
+        out[i].consumerUsage = static_cast<BufferUsage>(0);
+        out[i].maxBuffers = static_cast<int32_t>(mV4L2BufferCount);
+
+        switch (in_requestedConfiguration.streams[i].format) {
+            case PixelFormat::BLOB:
+            case PixelFormat::YCBCR_420_888:
+            case PixelFormat::YV12:  // Used by SurfaceTexture
+            case PixelFormat::Y16:
+                // No override
+                out[i].overrideFormat = in_requestedConfiguration.streams[i].format;
+                break;
+            case PixelFormat::IMPLEMENTATION_DEFINED:
+                // Implementation Defined
+                // This should look at the Stream's dataspace flag to determine the format or leave
+                // it as is if the rest of the system knows how to handle a private format. To keep
+                // this HAL generic, this is being overridden to YUV420
+                out[i].overrideFormat = PixelFormat::YCBCR_420_888;
+                // Save overridden format in mStreamMap
+                mStreamMap[in_requestedConfiguration.streams[i].id].format = out[i].overrideFormat;
+                break;
+            default:
+                ALOGE("%s: unsupported format 0x%x", __FUNCTION__,
+                      in_requestedConfiguration.streams[i].format);
+                return fromStatus(Status::ILLEGAL_ARGUMENT);
+        }
+    }
+
+    mFirstRequest = true;
+    mLastStreamConfigCounter = in_requestedConfiguration.streamConfigCounter;
+    return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::flush() {
+    ATRACE_CALL();
+    Mutex::Autolock _il(mInterfaceLock);
+    Status status = initStatus();
+    if (status != Status::OK) {
+        return fromStatus(status);
+    }
+    mOutputThread->flush();
+    return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::getCaptureRequestMetadataQueue(
+        MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
+    Mutex::Autolock _il(mInterfaceLock);
+    *_aidl_return = mRequestMetadataQueue->dupeDesc();
+    return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::getCaptureResultMetadataQueue(
+        MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
+    Mutex::Autolock _il(mInterfaceLock);
+    *_aidl_return = mResultMetadataQueue->dupeDesc();
+    return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::isReconfigurationRequired(
+        const CameraMetadata& in_oldSessionParams, const CameraMetadata& in_newSessionParams,
+        bool* _aidl_return) {
+    // reconfiguration required if there is any change in the session params
+    *_aidl_return = in_oldSessionParams != in_newSessionParams;
+    return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::processCaptureRequest(
+        const std::vector<CaptureRequest>& in_requests,
+        const std::vector<BufferCache>& in_cachesToRemove, int32_t* _aidl_return) {
+    Mutex::Autolock _il(mInterfaceLock);
+    updateBufferCaches(in_cachesToRemove);
+
+    int32_t& numRequestProcessed = *_aidl_return;
+    numRequestProcessed = 0;
+    Status s = Status::OK;
+    for (size_t i = 0; i < in_requests.size(); i++, numRequestProcessed++) {
+        s = processOneCaptureRequest(in_requests[i]);
+        if (s != Status::OK) {
+            break;
+        }
+    }
+
+    return fromStatus(s);
+}
+
+Status ExternalCameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request) {
+    ATRACE_CALL();
+    Status status = initStatus();
+    if (status != Status::OK) {
+        return status;
+    }
+
+    if (request.inputBuffer.streamId != -1) {
+        ALOGE("%s: external camera does not support reprocessing!", __FUNCTION__);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    Mutex::Autolock _l(mLock);
+    if (!mV4l2Streaming) {
+        ALOGE("%s: cannot process request in streamOff state!", __FUNCTION__);
+        return Status::INTERNAL_ERROR;
+    }
+
+    const camera_metadata_t* rawSettings = nullptr;
+    bool converted;
+    CameraMetadata settingsFmq;  // settings from FMQ
+
+    if (request.fmqSettingsSize > 0) {
+        // non-blocking read; client must write metadata before calling
+        // processOneCaptureRequest
+        settingsFmq.metadata.resize(request.fmqSettingsSize);
+        bool read = mRequestMetadataQueue->read(
+                reinterpret_cast<int8_t*>(settingsFmq.metadata.data()), request.fmqSettingsSize);
+        if (read) {
+            converted = convertFromAidl(settingsFmq, &rawSettings);
+        } else {
+            ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
+            converted = false;
+        }
+    } else {
+        converted = convertFromAidl(request.settings, &rawSettings);
+    }
+
+    if (converted && rawSettings != nullptr) {
+        mLatestReqSetting = rawSettings;
+    }
+
+    if (!converted) {
+        ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    if (mFirstRequest && rawSettings == nullptr) {
+        ALOGE("%s: capture request settings must not be null for first request!", __FUNCTION__);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    std::vector<buffer_handle_t*> allBufPtrs;
+    std::vector<int> allFences;
+    size_t numOutputBufs = request.outputBuffers.size();
+
+    if (numOutputBufs == 0) {
+        ALOGE("%s: capture request must have at least one output buffer!", __FUNCTION__);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    camera_metadata_entry fpsRange = mLatestReqSetting.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE);
+    if (fpsRange.count == 2) {
+        double requestFpsMax = fpsRange.data.i32[1];
+        double closestFps = 0.0;
+        double fpsError = 1000.0;
+        bool fpsSupported = false;
+        for (const auto& fr : mV4l2StreamingFmt.frameRates) {
+            double f = fr.getFramesPerSecond();
+            if (std::fabs(requestFpsMax - f) < 1.0) {
+                fpsSupported = true;
+                break;
+            }
+            if (std::fabs(requestFpsMax - f) < fpsError) {
+                fpsError = std::fabs(requestFpsMax - f);
+                closestFps = f;
+            }
+        }
+        if (!fpsSupported) {
+            /* This can happen in a few scenarios:
+             * 1. The application is sending an FPS range not supported by the configured outputs.
+             * 2. The application is sending a valid FPS range for all configured outputs, but
+             *    the selected V4L2 size can only run at slower speed. This should be very rare
+             *    though: for this to happen a sensor needs to support at least 3 different aspect
+             *    ratio outputs, and when (at least) two outputs are both not the main aspect ratio
+             *    of the webcam, a third size that's larger might be picked and runs into this
+             *    issue.
+             */
+            ALOGW("%s: cannot reach fps %d! Will do %f instead", __FUNCTION__, fpsRange.data.i32[1],
+                  closestFps);
+            requestFpsMax = closestFps;
+        }
+
+        if (requestFpsMax != mV4l2StreamingFps) {
+            {
+                std::unique_lock<std::mutex> lk(mV4l2BufferLock);
+                while (mNumDequeuedV4l2Buffers != 0) {
+                    // Wait until pipeline is idle before reconfigure stream
+                    int waitRet = waitForV4L2BufferReturnLocked(lk);
+                    if (waitRet != 0) {
+                        ALOGE("%s: wait for pipeline idle failed!", __FUNCTION__);
+                        return Status::INTERNAL_ERROR;
+                    }
+                }
+            }
+            configureV4l2StreamLocked(mV4l2StreamingFmt, requestFpsMax);
+        }
+    }
+
+    status = importRequestLocked(request, allBufPtrs, allFences);
+    if (status != Status::OK) {
+        return status;
+    }
+
+    nsecs_t shutterTs = 0;
+    std::unique_ptr<V4L2Frame> frameIn = dequeueV4l2FrameLocked(&shutterTs);
+    if (frameIn == nullptr) {
+        ALOGE("%s: V4L2 deque frame failed!", __FUNCTION__);
+        return Status::INTERNAL_ERROR;
+    }
+
+    std::shared_ptr<HalRequest> halReq = std::make_shared<HalRequest>();
+    halReq->frameNumber = request.frameNumber;
+    halReq->setting = mLatestReqSetting;
+    halReq->frameIn = std::move(frameIn);
+    halReq->shutterTs = shutterTs;
+    halReq->buffers.resize(numOutputBufs);
+    for (size_t i = 0; i < numOutputBufs; i++) {
+        HalStreamBuffer& halBuf = halReq->buffers[i];
+        int streamId = halBuf.streamId = request.outputBuffers[i].streamId;
+        halBuf.bufferId = request.outputBuffers[i].bufferId;
+        const Stream& stream = mStreamMap[streamId];
+        halBuf.width = stream.width;
+        halBuf.height = stream.height;
+        halBuf.format = stream.format;
+        halBuf.usage = stream.usage;
+        halBuf.bufPtr = allBufPtrs[i];
+        halBuf.acquireFence = allFences[i];
+        halBuf.fenceTimeout = false;
+    }
+    {
+        std::lock_guard<std::mutex> lk(mInflightFramesLock);
+        mInflightFrames.insert(halReq->frameNumber);
+    }
+    // Send request to OutputThread for the rest of processing
+    mOutputThread->submitRequest(halReq);
+    mFirstRequest = false;
+    return Status::OK;
+}
+
+ScopedAStatus ExternalCameraDeviceSession::signalStreamFlush(
+        const std::vector<int32_t>& /*in_streamIds*/, int32_t in_streamConfigCounter) {
+    {
+        Mutex::Autolock _l(mLock);
+        if (in_streamConfigCounter < mLastStreamConfigCounter) {
+            // stale call. new streams have been configured since this call was issued.
+            // Do nothing.
+            return fromStatus(Status::OK);
+        }
+    }
+
+    // TODO: implement if needed.
+    return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::switchToOffline(
+        const std::vector<int32_t>& in_streamsToKeep,
+        CameraOfflineSessionInfo* out_offlineSessionInfo,
+        std::shared_ptr<ICameraOfflineSession>* _aidl_return) {
+    std::vector<NotifyMsg> msgs;
+    std::vector<CaptureResult> results;
+    CameraOfflineSessionInfo info;
+    std::shared_ptr<ICameraOfflineSession> session;
+    Status st = switchToOffline(in_streamsToKeep, &msgs, &results, &info, &session);
+
+    mCallback->notify(msgs);
+    invokeProcessCaptureResultCallback(results, /* tryWriteFmq= */ true);
+    freeReleaseFences(results);
+
+    // setup return values
+    *out_offlineSessionInfo = info;
+    *_aidl_return = session;
+    return fromStatus(st);
+}
+
+Status ExternalCameraDeviceSession::switchToOffline(
+        const std::vector<int32_t>& offlineStreams, std::vector<NotifyMsg>* msgs,
+        std::vector<CaptureResult>* results, CameraOfflineSessionInfo* info,
+        std::shared_ptr<ICameraOfflineSession>* session) {
+    ATRACE_CALL();
+    if (offlineStreams.size() > 1) {
+        ALOGE("%s: more than one offline stream is not supported", __FUNCTION__);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    if (msgs == nullptr || results == nullptr || info == nullptr || session == nullptr) {
+        ALOGE("%s, output arguments (%p, %p, %p, %p) must not be null", __FUNCTION__, msgs, results,
+              info, session);
+    }
+
+    Mutex::Autolock _il(mInterfaceLock);
+    Status status = initStatus();
+    if (status != Status::OK) {
+        return status;
+    }
+
+    Mutex::Autolock _l(mLock);
+    for (auto streamId : offlineStreams) {
+        if (!supportOfflineLocked(streamId)) {
+            return Status::ILLEGAL_ARGUMENT;
+        }
+    }
+
+    // pause output thread and get all remaining inflight requests
+    auto remainingReqs = mOutputThread->switchToOffline();
+    std::vector<std::shared_ptr<HalRequest>> halReqs;
+
+    // Send out buffer/request error for remaining requests and filter requests
+    // to be handled in offline mode
+    for (auto& halReq : remainingReqs) {
+        bool dropReq = canDropRequest(offlineStreams, halReq);
+        if (dropReq) {
+            // Request is dropped completely. Just send request error and
+            // there is no need to send the request to offline session
+            processCaptureRequestError(halReq, msgs, results);
+            continue;
+        }
+
+        // All requests reach here must have at least one offline stream output
+        NotifyMsg shutter;
+        aidl::android::hardware::camera::device::ShutterMsg shutterMsg = {
+                .frameNumber = static_cast<int32_t>(halReq->frameNumber),
+                .timestamp = halReq->shutterTs};
+        shutter.set<NotifyMsg::Tag::shutter>(shutterMsg);
+        msgs->push_back(shutter);
+
+        std::vector<HalStreamBuffer> offlineBuffers;
+        for (const auto& buffer : halReq->buffers) {
+            bool dropBuffer = true;
+            for (auto offlineStreamId : offlineStreams) {
+                if (buffer.streamId == offlineStreamId) {
+                    dropBuffer = false;
+                    break;
+                }
+            }
+            if (dropBuffer) {
+                aidl::android::hardware::camera::device::ErrorMsg errorMsg = {
+                        .frameNumber = static_cast<int32_t>(halReq->frameNumber),
+                        .errorStreamId = buffer.streamId,
+                        .errorCode = ErrorCode::ERROR_BUFFER};
+
+                NotifyMsg error;
+                error.set<NotifyMsg::Tag::error>(errorMsg);
+                msgs->push_back(error);
+
+                results->push_back({
+                        .frameNumber = static_cast<int32_t>(halReq->frameNumber),
+                        .outputBuffers = {},
+                        .inputBuffer = {.streamId = -1},
+                        .partialResult = 0,  // buffer only result
+                });
+
+                CaptureResult& result = results->back();
+                result.outputBuffers.resize(1);
+                StreamBuffer& outputBuffer = result.outputBuffers[0];
+                outputBuffer.streamId = buffer.streamId;
+                outputBuffer.bufferId = buffer.bufferId;
+                outputBuffer.status = BufferStatus::ERROR;
+                if (buffer.acquireFence >= 0) {
+                    native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                    handle->data[0] = buffer.acquireFence;
+                    outputBuffer.releaseFence = android::makeToAidl(handle);
+                }
+            } else {
+                offlineBuffers.push_back(buffer);
+            }
+        }
+        halReq->buffers = offlineBuffers;
+        halReqs.push_back(halReq);
+    }
+
+    // convert hal requests to offline request
+    std::deque<std::shared_ptr<HalRequest>> offlineReqs(halReqs.size());
+    size_t i = 0;
+    for (auto& v4lReq : halReqs) {
+        offlineReqs[i] = std::make_shared<HalRequest>();
+        offlineReqs[i]->frameNumber = v4lReq->frameNumber;
+        offlineReqs[i]->setting = v4lReq->setting;
+        offlineReqs[i]->shutterTs = v4lReq->shutterTs;
+        offlineReqs[i]->buffers = v4lReq->buffers;
+        std::shared_ptr<V4L2Frame> v4l2Frame(static_cast<V4L2Frame*>(v4lReq->frameIn.get()));
+        offlineReqs[i]->frameIn = std::make_shared<AllocatedV4L2Frame>(v4l2Frame);
+        i++;
+        // enqueue V4L2 frame
+        enqueueV4l2Frame(v4l2Frame);
+    }
+
+    // Collect buffer caches/streams
+    std::vector<Stream> streamInfos(offlineStreams.size());
+    std::map<int, CirculatingBuffers> circulatingBuffers;
+    {
+        Mutex::Autolock _cbsl(mCbsLock);
+        for (auto streamId : offlineStreams) {
+            circulatingBuffers[streamId] = mCirculatingBuffers.at(streamId);
+            mCirculatingBuffers.erase(streamId);
+            streamInfos.push_back(mStreamMap.at(streamId));
+            mStreamMap.erase(streamId);
+        }
+    }
+
+    fillOfflineSessionInfo(offlineStreams, offlineReqs, circulatingBuffers, info);
+    // create the offline session object
+    bool afTrigger;
+    {
+        std::lock_guard<std::mutex> _lk(mAfTriggerLock);
+        afTrigger = mAfTrigger;
+    }
+
+    std::shared_ptr<ExternalCameraOfflineSession> sessionImpl =
+            ndk::SharedRefBase::make<ExternalCameraOfflineSession>(
+                    mCroppingType, mCameraCharacteristics, mCameraId, mExifMake, mExifModel,
+                    mBlobBufferSize, afTrigger, streamInfos, offlineReqs, circulatingBuffers);
+
+    bool initFailed = sessionImpl->initialize();
+    if (initFailed) {
+        ALOGE("%s: offline session initialize failed!", __FUNCTION__);
+        return Status::INTERNAL_ERROR;
+    }
+
+    // cleanup stream and buffer caches
+    {
+        Mutex::Autolock _cbsl(mCbsLock);
+        for (auto pair : mStreamMap) {
+            cleanupBuffersLocked(/*Stream ID*/ pair.first);
+        }
+        mCirculatingBuffers.clear();
+    }
+    mStreamMap.clear();
+
+    // update inflight records
+    {
+        std::lock_guard<std::mutex> _lk(mInflightFramesLock);
+        mInflightFrames.clear();
+    }
+
+    // stop v4l2 streaming
+    if (v4l2StreamOffLocked() != 0) {
+        ALOGE("%s: stop V4L2 streaming failed!", __FUNCTION__);
+        return Status::INTERNAL_ERROR;
+    }
+
+    // No need to return session if there is no offline requests left
+    if (!offlineReqs.empty()) {
+        *session = sessionImpl;
+    } else {
+        *session = nullptr;
+    }
+
+    return Status::OK;
+}
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+#define UPDATE(md, tag, data, size)               \
+    do {                                          \
+        if ((md).update((tag), (data), (size))) { \
+            ALOGE("Update " #tag " failed!");     \
+            return BAD_VALUE;                     \
+        }                                         \
+    } while (0)
+
+status_t ExternalCameraDeviceSession::initDefaultRequests() {
+    common::V1_0::helper::CameraMetadata md;
+
+    const uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
+    UPDATE(md, ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &aberrationMode, 1);
+
+    const int32_t exposureCompensation = 0;
+    UPDATE(md, ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &exposureCompensation, 1);
+
+    const uint8_t videoStabilizationMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
+    UPDATE(md, ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &videoStabilizationMode, 1);
+
+    const uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
+    UPDATE(md, ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
+
+    const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
+    UPDATE(md, ANDROID_CONTROL_AE_MODE, &aeMode, 1);
+
+    const uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
+    UPDATE(md, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aePrecaptureTrigger, 1);
+
+    const uint8_t afMode = ANDROID_CONTROL_AF_MODE_AUTO;
+    UPDATE(md, ANDROID_CONTROL_AF_MODE, &afMode, 1);
+
+    const uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
+    UPDATE(md, ANDROID_CONTROL_AF_TRIGGER, &afTrigger, 1);
+
+    const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED;
+    UPDATE(md, ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
+
+    const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
+    UPDATE(md, ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);
+
+    const uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
+    UPDATE(md, ANDROID_FLASH_MODE, &flashMode, 1);
+
+    const int32_t thumbnailSize[] = {240, 180};
+    UPDATE(md, ANDROID_JPEG_THUMBNAIL_SIZE, thumbnailSize, 2);
+
+    const uint8_t jpegQuality = 90;
+    UPDATE(md, ANDROID_JPEG_QUALITY, &jpegQuality, 1);
+    UPDATE(md, ANDROID_JPEG_THUMBNAIL_QUALITY, &jpegQuality, 1);
+
+    const int32_t jpegOrientation = 0;
+    UPDATE(md, ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1);
+
+    const uint8_t oisMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+    UPDATE(md, ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &oisMode, 1);
+
+    const uint8_t nrMode = ANDROID_NOISE_REDUCTION_MODE_OFF;
+    UPDATE(md, ANDROID_NOISE_REDUCTION_MODE, &nrMode, 1);
+
+    const int32_t testPatternModes = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
+    UPDATE(md, ANDROID_SENSOR_TEST_PATTERN_MODE, &testPatternModes, 1);
+
+    const uint8_t fdMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
+    UPDATE(md, ANDROID_STATISTICS_FACE_DETECT_MODE, &fdMode, 1);
+
+    const uint8_t hotpixelMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
+    UPDATE(md, ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, &hotpixelMode, 1);
+
+    bool support30Fps = false;
+    int32_t maxFps = std::numeric_limits<int32_t>::min();
+    for (const auto& supportedFormat : mSupportedFormats) {
+        for (const auto& fr : supportedFormat.frameRates) {
+            int32_t framerateInt = static_cast<int32_t>(fr.getFramesPerSecond());
+            if (maxFps < framerateInt) {
+                maxFps = framerateInt;
+            }
+            if (framerateInt == 30) {
+                support30Fps = true;
+                break;
+            }
+        }
+        if (support30Fps) {
+            break;
+        }
+    }
+
+    int32_t defaultFramerate = support30Fps ? 30 : maxFps;
+    int32_t defaultFpsRange[] = {defaultFramerate / 2, defaultFramerate};
+    UPDATE(md, ANDROID_CONTROL_AE_TARGET_FPS_RANGE, defaultFpsRange, ARRAY_SIZE(defaultFpsRange));
+
+    uint8_t antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
+    UPDATE(md, ANDROID_CONTROL_AE_ANTIBANDING_MODE, &antibandingMode, 1);
+
+    const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
+    UPDATE(md, ANDROID_CONTROL_MODE, &controlMode, 1);
+
+    for (const auto& type : ndk::enum_range<RequestTemplate>()) {
+        common::V1_0::helper::CameraMetadata mdCopy = md;
+        uint8_t intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
+        switch (type) {
+            case RequestTemplate::PREVIEW:
+                intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
+                break;
+            case RequestTemplate::STILL_CAPTURE:
+                intent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
+                break;
+            case RequestTemplate::VIDEO_RECORD:
+                intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
+                break;
+            case RequestTemplate::VIDEO_SNAPSHOT:
+                intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
+                break;
+            default:
+                ALOGV("%s: unsupported RequestTemplate type %d", __FUNCTION__, type);
+                continue;
+        }
+        UPDATE(mdCopy, ANDROID_CONTROL_CAPTURE_INTENT, &intent, 1);
+        camera_metadata_t* mdPtr = mdCopy.release();
+        uint8_t* rawMd = reinterpret_cast<uint8_t*>(mdPtr);
+        CameraMetadata aidlMd;
+        aidlMd.metadata.assign(rawMd, rawMd + get_camera_metadata_size(mdPtr));
+        mDefaultRequests[type] = aidlMd;
+        free_camera_metadata(mdPtr);
+    }
+    return OK;
+}
+
+status_t ExternalCameraDeviceSession::fillCaptureResult(common::V1_0::helper::CameraMetadata& md,
+                                                        nsecs_t timestamp) {
+    bool afTrigger = false;
+    {
+        std::lock_guard<std::mutex> lk(mAfTriggerLock);
+        afTrigger = mAfTrigger;
+        if (md.exists(ANDROID_CONTROL_AF_TRIGGER)) {
+            camera_metadata_entry entry = md.find(ANDROID_CONTROL_AF_TRIGGER);
+            if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_START) {
+                mAfTrigger = afTrigger = true;
+            } else if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_CANCEL) {
+                mAfTrigger = afTrigger = false;
+            }
+        }
+    }
+
+    // For USB camera, the USB camera handles everything and we don't have control
+    // over AF. We only simply fake the AF metadata based on the request
+    // received here.
+    uint8_t afState;
+    if (afTrigger) {
+        afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+    } else {
+        afState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+    }
+    UPDATE(md, ANDROID_CONTROL_AF_STATE, &afState, 1);
+
+    camera_metadata_ro_entry activeArraySize =
+            mCameraCharacteristics.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+
+    return fillCaptureResultCommon(md, timestamp, activeArraySize);
+}
+
+int ExternalCameraDeviceSession::configureV4l2StreamLocked(const SupportedV4L2Format& v4l2Fmt,
+                                                           double requestFps) {
+    ATRACE_CALL();
+    int ret = v4l2StreamOffLocked();
+    if (ret != OK) {
+        ALOGE("%s: stop v4l2 streaming failed: ret %d", __FUNCTION__, ret);
+        return ret;
+    }
+
+    // VIDIOC_S_FMT w/h/fmt
+    v4l2_format fmt;
+    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    fmt.fmt.pix.width = v4l2Fmt.width;
+    fmt.fmt.pix.height = v4l2Fmt.height;
+    fmt.fmt.pix.pixelformat = v4l2Fmt.fourcc;
+
+    {
+        int numAttempt = 0;
+        do {
+            ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_FMT, &fmt));
+            if (numAttempt == MAX_RETRY) {
+                break;
+            }
+            numAttempt++;
+            if (ret < 0) {
+                ALOGW("%s: VIDIOC_S_FMT failed, wait 33ms and try again", __FUNCTION__);
+                usleep(IOCTL_RETRY_SLEEP_US);  // sleep and try again
+            }
+        } while (ret < 0);
+        if (ret < 0) {
+            ALOGE("%s: S_FMT ioctl failed: %s", __FUNCTION__, strerror(errno));
+            return -errno;
+        }
+    }
+
+    if (v4l2Fmt.width != fmt.fmt.pix.width || v4l2Fmt.height != fmt.fmt.pix.height ||
+        v4l2Fmt.fourcc != fmt.fmt.pix.pixelformat) {
+        ALOGE("%s: S_FMT expect %c%c%c%c %dx%d, got %c%c%c%c %dx%d instead!", __FUNCTION__,
+              v4l2Fmt.fourcc & 0xFF, (v4l2Fmt.fourcc >> 8) & 0xFF, (v4l2Fmt.fourcc >> 16) & 0xFF,
+              (v4l2Fmt.fourcc >> 24) & 0xFF, v4l2Fmt.width, v4l2Fmt.height,
+              fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF,
+              (fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) & 0xFF,
+              fmt.fmt.pix.width, fmt.fmt.pix.height);
+        return -EINVAL;
+    }
+
+    uint32_t bufferSize = fmt.fmt.pix.sizeimage;
+    ALOGI("%s: V4L2 buffer size is %d", __FUNCTION__, bufferSize);
+    uint32_t expectedMaxBufferSize = kMaxBytesPerPixel * fmt.fmt.pix.width * fmt.fmt.pix.height;
+    if ((bufferSize == 0) || (bufferSize > expectedMaxBufferSize)) {
+        ALOGE("%s: V4L2 buffer size: %u looks invalid. Expected maximum size: %u", __FUNCTION__,
+              bufferSize, expectedMaxBufferSize);
+        return -EINVAL;
+    }
+    mMaxV4L2BufferSize = bufferSize;
+
+    const double kDefaultFps = 30.0;
+    double fps = std::numeric_limits<double>::max();
+    if (requestFps != 0.0) {
+        fps = requestFps;
+    } else {
+        double maxFps = -1.0;
+        // Try to pick the slowest fps that is at least 30
+        for (const auto& fr : v4l2Fmt.frameRates) {
+            double f = fr.getFramesPerSecond();
+            if (maxFps < f) {
+                maxFps = f;
+            }
+            if (f >= kDefaultFps && f < fps) {
+                fps = f;
+            }
+        }
+        // No fps > 30 found, use the highest fps available within supported formats.
+        if (fps == std::numeric_limits<double>::max()) {
+            fps = maxFps;
+        }
+    }
+
+    int fpsRet = setV4l2FpsLocked(fps);
+    if (fpsRet != 0 && fpsRet != -EINVAL) {
+        ALOGE("%s: set fps failed: %s", __FUNCTION__, strerror(fpsRet));
+        return fpsRet;
+    }
+
+    uint32_t v4lBufferCount = (fps >= kDefaultFps) ? mCfg.numVideoBuffers : mCfg.numStillBuffers;
+
+    // VIDIOC_REQBUFS: create buffers
+    v4l2_requestbuffers req_buffers{};
+    req_buffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    req_buffers.memory = V4L2_MEMORY_MMAP;
+    req_buffers.count = v4lBufferCount;
+    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_REQBUFS, &req_buffers)) < 0) {
+        ALOGE("%s: VIDIOC_REQBUFS failed: %s", __FUNCTION__, strerror(errno));
+        return -errno;
+    }
+
+    // Driver can indeed return more buffer if it needs more to operate
+    if (req_buffers.count < v4lBufferCount) {
+        ALOGE("%s: VIDIOC_REQBUFS expected %d buffers, got %d instead", __FUNCTION__,
+              v4lBufferCount, req_buffers.count);
+        return NO_MEMORY;
+    }
+
+    // VIDIOC_QUERYBUF:  get buffer offset in the V4L2 fd
+    // VIDIOC_QBUF: send buffer to driver
+    mV4L2BufferCount = req_buffers.count;
+    for (uint32_t i = 0; i < req_buffers.count; i++) {
+        v4l2_buffer buffer = {
+                .index = i, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .memory = V4L2_MEMORY_MMAP};
+
+        if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QUERYBUF, &buffer)) < 0) {
+            ALOGE("%s: QUERYBUF %d failed: %s", __FUNCTION__, i, strerror(errno));
+            return -errno;
+        }
+
+        if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
+            ALOGE("%s: QBUF %d failed: %s", __FUNCTION__, i, strerror(errno));
+            return -errno;
+        }
+    }
+
+    {
+        // VIDIOC_STREAMON: start streaming
+        v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        int numAttempt = 0;
+        do {
+            ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMON, &capture_type));
+            if (numAttempt == MAX_RETRY) {
+                break;
+            }
+            if (ret < 0) {
+                ALOGW("%s: VIDIOC_STREAMON failed, wait 33ms and try again", __FUNCTION__);
+                usleep(IOCTL_RETRY_SLEEP_US);  // sleep 100 ms and try again
+            }
+        } while (ret < 0);
+
+        if (ret < 0) {
+            ALOGE("%s: VIDIOC_STREAMON ioctl failed: %s", __FUNCTION__, strerror(errno));
+            return -errno;
+        }
+    }
+
+    // Swallow first few frames after streamOn to account for bad frames from some devices
+    for (int i = 0; i < kBadFramesAfterStreamOn; i++) {
+        v4l2_buffer buffer{};
+        buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        buffer.memory = V4L2_MEMORY_MMAP;
+        if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_DQBUF, &buffer)) < 0) {
+            ALOGE("%s: DQBUF fails: %s", __FUNCTION__, strerror(errno));
+            return -errno;
+        }
+
+        if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
+            ALOGE("%s: QBUF index %d fails: %s", __FUNCTION__, buffer.index, strerror(errno));
+            return -errno;
+        }
+    }
+
+    ALOGI("%s: start V4L2 streaming %dx%d@%ffps", __FUNCTION__, v4l2Fmt.width, v4l2Fmt.height, fps);
+    mV4l2StreamingFmt = v4l2Fmt;
+    mV4l2Streaming = true;
+    return OK;
+}
+
+std::unique_ptr<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked(nsecs_t* shutterTs) {
+    ATRACE_CALL();
+    std::unique_ptr<V4L2Frame> ret = nullptr;
+    if (shutterTs == nullptr) {
+        ALOGE("%s: shutterTs must not be null!", __FUNCTION__);
+        return ret;
+    }
+
+    {
+        std::unique_lock<std::mutex> lk(mV4l2BufferLock);
+        if (mNumDequeuedV4l2Buffers == mV4L2BufferCount) {
+            int waitRet = waitForV4L2BufferReturnLocked(lk);
+            if (waitRet != 0) {
+                return ret;
+            }
+        }
+    }
+
+    ATRACE_BEGIN("VIDIOC_DQBUF");
+    v4l2_buffer buffer{};
+    buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    buffer.memory = V4L2_MEMORY_MMAP;
+    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_DQBUF, &buffer)) < 0) {
+        ALOGE("%s: DQBUF fails: %s", __FUNCTION__, strerror(errno));
+        return ret;
+    }
+    ATRACE_END();
+
+    if (buffer.index >= mV4L2BufferCount) {
+        ALOGE("%s: Invalid buffer id: %d", __FUNCTION__, buffer.index);
+        return ret;
+    }
+
+    if (buffer.flags & V4L2_BUF_FLAG_ERROR) {
+        ALOGE("%s: v4l2 buf error! buf flag 0x%x", __FUNCTION__, buffer.flags);
+        // TODO: try to dequeue again
+    }
+
+    if (buffer.bytesused > mMaxV4L2BufferSize) {
+        ALOGE("%s: v4l2 buffer bytes used: %u maximum %u", __FUNCTION__, buffer.bytesused,
+              mMaxV4L2BufferSize);
+        return ret;
+    }
+
+    if (buffer.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) {
+        // Ideally we should also check for V4L2_BUF_FLAG_TSTAMP_SRC_SOE, but
+        // even V4L2_BUF_FLAG_TSTAMP_SRC_EOF is better than capture a timestamp now
+        *shutterTs = static_cast<nsecs_t>(buffer.timestamp.tv_sec) * 1000000000LL +
+                     buffer.timestamp.tv_usec * 1000LL;
+    } else {
+        *shutterTs = systemTime(SYSTEM_TIME_MONOTONIC);
+    }
+
+    {
+        std::lock_guard<std::mutex> lk(mV4l2BufferLock);
+        mNumDequeuedV4l2Buffers++;
+    }
+
+    return std::make_unique<V4L2Frame>(mV4l2StreamingFmt.width, mV4l2StreamingFmt.height,
+                                       mV4l2StreamingFmt.fourcc, buffer.index, mV4l2Fd.get(),
+                                       buffer.bytesused, buffer.m.offset);
+}
+
+void ExternalCameraDeviceSession::enqueueV4l2Frame(const std::shared_ptr<V4L2Frame>& frame) {
+    ATRACE_CALL();
+    frame->unmap();
+    ATRACE_BEGIN("VIDIOC_QBUF");
+    v4l2_buffer buffer{};
+    buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    buffer.memory = V4L2_MEMORY_MMAP;
+    buffer.index = frame->mBufferIndex;
+    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
+        ALOGE("%s: QBUF index %d fails: %s", __FUNCTION__, frame->mBufferIndex, strerror(errno));
+        return;
+    }
+    ATRACE_END();
+
+    {
+        std::lock_guard<std::mutex> lk(mV4l2BufferLock);
+        mNumDequeuedV4l2Buffers--;
+    }
+    mV4L2BufferReturned.notify_one();
+}
+
+bool ExternalCameraDeviceSession::isSupported(
+        const Stream& stream, const std::vector<SupportedV4L2Format>& supportedFormats,
+        const ExternalCameraConfig& devCfg) {
+    Dataspace ds = stream.dataSpace;
+    PixelFormat fmt = stream.format;
+    uint32_t width = stream.width;
+    uint32_t height = stream.height;
+    // TODO: check usage flags
+
+    if (stream.streamType != StreamType::OUTPUT) {
+        ALOGE("%s: does not support non-output stream type", __FUNCTION__);
+        return false;
+    }
+
+    if (stream.rotation != StreamRotation::ROTATION_0) {
+        ALOGE("%s: does not support stream rotation", __FUNCTION__);
+        return false;
+    }
+
+    switch (fmt) {
+        case PixelFormat::BLOB:
+            if (ds != Dataspace::JFIF) {
+                ALOGI("%s: BLOB format does not support dataSpace %x", __FUNCTION__, ds);
+                return false;
+            }
+            break;
+        case PixelFormat::IMPLEMENTATION_DEFINED:
+        case PixelFormat::YCBCR_420_888:
+        case PixelFormat::YV12:
+            // TODO: check what dataspace we can support here.
+            // intentional no-ops.
+            break;
+        case PixelFormat::Y16:
+            if (!devCfg.depthEnabled) {
+                ALOGI("%s: Depth is not Enabled", __FUNCTION__);
+                return false;
+            }
+            if (!(static_cast<int32_t>(ds) & static_cast<int32_t>(Dataspace::DEPTH))) {
+                ALOGI("%s: Y16 supports only dataSpace DEPTH", __FUNCTION__);
+                return false;
+            }
+            break;
+        default:
+            ALOGI("%s: does not support format %x", __FUNCTION__, fmt);
+            return false;
+    }
+
+    // Assume we can convert any V4L2 format to any of supported output format for now, i.e.
+    // ignoring v4l2Fmt.fourcc for now. Might need more subtle check if we support more v4l format
+    // in the futrue.
+    for (const auto& v4l2Fmt : supportedFormats) {
+        if (width == v4l2Fmt.width && height == v4l2Fmt.height) {
+            return true;
+        }
+    }
+    ALOGI("%s: resolution %dx%d is not supported", __FUNCTION__, width, height);
+    return false;
+}
+
+Status ExternalCameraDeviceSession::importRequestLocked(const CaptureRequest& request,
+                                                        std::vector<buffer_handle_t*>& allBufPtrs,
+                                                        std::vector<int>& allFences) {
+    return importRequestLockedImpl(request, allBufPtrs, allFences);
+}
+
+Status ExternalCameraDeviceSession::importRequestLockedImpl(
+        const CaptureRequest& request, std::vector<buffer_handle_t*>& allBufPtrs,
+        std::vector<int>& allFences) {
+    size_t numOutputBufs = request.outputBuffers.size();
+    size_t numBufs = numOutputBufs;
+    // Validate all I/O buffers
+    std::vector<buffer_handle_t> allBufs;
+    std::vector<uint64_t> allBufIds;
+    allBufs.resize(numBufs);
+    allBufIds.resize(numBufs);
+    allBufPtrs.resize(numBufs);
+    allFences.resize(numBufs);
+    std::vector<int32_t> streamIds(numBufs);
+
+    for (size_t i = 0; i < numOutputBufs; i++) {
+        allBufs[i] = ::android::makeFromAidl(request.outputBuffers[i].buffer);
+        allBufIds[i] = request.outputBuffers[i].bufferId;
+        allBufPtrs[i] = &allBufs[i];
+        streamIds[i] = request.outputBuffers[i].streamId;
+    }
+
+    {
+        Mutex::Autolock _l(mCbsLock);
+        for (size_t i = 0; i < numBufs; i++) {
+            Status st = importBufferLocked(streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i]);
+            if (st != Status::OK) {
+                // Detailed error logs printed in importBuffer
+                return st;
+            }
+        }
+    }
+
+    // All buffers are imported. Now validate output buffer acquire fences
+    for (size_t i = 0; i < numOutputBufs; i++) {
+        if (!sHandleImporter.importFence(
+                    ::android::makeFromAidl(request.outputBuffers[i].acquireFence), allFences[i])) {
+            ALOGE("%s: output buffer %zu acquire fence is invalid", __FUNCTION__, i);
+            cleanupInflightFences(allFences, i);
+            return Status::INTERNAL_ERROR;
+        }
+    }
+    return Status::OK;
+}
+
+Status ExternalCameraDeviceSession::importBuffer(int32_t streamId, uint64_t bufId,
+                                                 buffer_handle_t buf,
+                                                 /*out*/ buffer_handle_t** outBufPtr) {
+    Mutex::Autolock _l(mCbsLock);
+    return importBufferLocked(streamId, bufId, buf, outBufPtr);
+}
+
+Status ExternalCameraDeviceSession::importBufferLocked(int32_t streamId, uint64_t bufId,
+                                                       buffer_handle_t buf,
+                                                       buffer_handle_t** outBufPtr) {
+    return importBufferImpl(mCirculatingBuffers, sHandleImporter, streamId, bufId, buf, outBufPtr);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::close() {
+    close(false);
+    return fromStatus(Status::OK);
+}
+
+void ExternalCameraDeviceSession::close(bool callerIsDtor) {
+    Mutex::Autolock _il(mInterfaceLock);
+    bool closed = isClosed();
+    if (!closed) {
+        if (callerIsDtor) {
+            closeOutputThreadImpl();
+        } else {
+            closeOutputThread();
+        }
+
+        Mutex::Autolock _l(mLock);
+        // free all buffers
+        {
+            Mutex::Autolock _cbsl(mCbsLock);
+            for (auto pair : mStreamMap) {
+                cleanupBuffersLocked(/*Stream ID*/ pair.first);
+            }
+        }
+        v4l2StreamOffLocked();
+        ALOGV("%s: closing V4L2 camera FD %d", __FUNCTION__, mV4l2Fd.get());
+        mV4l2Fd.reset();
+        mClosed = true;
+    }
+}
+
+bool ExternalCameraDeviceSession::isClosed() {
+    Mutex::Autolock _l(mLock);
+    return mClosed;
+}
+
+ScopedAStatus ExternalCameraDeviceSession::repeatingRequestEnd(
+        int32_t /*in_frameNumber*/, const std::vector<int32_t>& /*in_streamIds*/) {
+    // TODO: Figure this one out.
+    return fromStatus(Status::OK);
+}
+
+int ExternalCameraDeviceSession::v4l2StreamOffLocked() {
+    if (!mV4l2Streaming) {
+        return OK;
+    }
+
+    {
+        std::lock_guard<std::mutex> lk(mV4l2BufferLock);
+        if (mNumDequeuedV4l2Buffers != 0) {
+            ALOGE("%s: there are %zu inflight V4L buffers", __FUNCTION__, mNumDequeuedV4l2Buffers);
+            return -1;
+        }
+    }
+    mV4L2BufferCount = 0;
+
+    // VIDIOC_STREAMOFF
+    v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMOFF, &capture_type)) < 0) {
+        ALOGE("%s: STREAMOFF failed: %s", __FUNCTION__, strerror(errno));
+        return -errno;
+    }
+
+    // VIDIOC_REQBUFS: clear buffers
+    v4l2_requestbuffers req_buffers{};
+    req_buffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    req_buffers.memory = V4L2_MEMORY_MMAP;
+    req_buffers.count = 0;
+    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_REQBUFS, &req_buffers)) < 0) {
+        ALOGE("%s: REQBUFS failed: %s", __FUNCTION__, strerror(errno));
+        return -errno;
+    }
+
+    mV4l2Streaming = false;
+    return OK;
+}
+
+int ExternalCameraDeviceSession::setV4l2FpsLocked(double fps) {
+    // VIDIOC_G_PARM/VIDIOC_S_PARM: set fps
+    v4l2_streamparm streamparm = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
+    // The following line checks that the driver knows about framerate get/set.
+    int ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_G_PARM, &streamparm));
+    if (ret != 0) {
+        if (errno == -EINVAL) {
+            ALOGW("%s: device does not support VIDIOC_G_PARM", __FUNCTION__);
+        }
+        return -errno;
+    }
+    // Now check if the device is able to accept a capture framerate set.
+    if (!(streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) {
+        ALOGW("%s: device does not support V4L2_CAP_TIMEPERFRAME", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    // fps is float, approximate by a fraction.
+    const int kFrameRatePrecision = 10000;
+    streamparm.parm.capture.timeperframe.numerator = kFrameRatePrecision;
+    streamparm.parm.capture.timeperframe.denominator = (fps * kFrameRatePrecision);
+
+    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_PARM, &streamparm)) < 0) {
+        ALOGE("%s: failed to set framerate to %f: %s", __FUNCTION__, fps, strerror(errno));
+        return -1;
+    }
+
+    double retFps = streamparm.parm.capture.timeperframe.denominator /
+                    static_cast<double>(streamparm.parm.capture.timeperframe.numerator);
+    if (std::fabs(fps - retFps) > 1.0) {
+        ALOGE("%s: expect fps %f, got %f instead", __FUNCTION__, fps, retFps);
+        return -1;
+    }
+    mV4l2StreamingFps = fps;
+    return 0;
+}
+
+void ExternalCameraDeviceSession::cleanupInflightFences(std::vector<int>& allFences,
+                                                        size_t numFences) {
+    for (size_t j = 0; j < numFences; j++) {
+        sHandleImporter.closeFence(allFences[j]);
+    }
+}
+
+void ExternalCameraDeviceSession::cleanupBuffersLocked(int id) {
+    for (auto& pair : mCirculatingBuffers.at(id)) {
+        sHandleImporter.freeBuffer(pair.second);
+    }
+    mCirculatingBuffers[id].clear();
+    mCirculatingBuffers.erase(id);
+}
+
+void ExternalCameraDeviceSession::notifyShutter(int32_t frameNumber, nsecs_t shutterTs) {
+    NotifyMsg msg;
+    msg.set<NotifyMsg::Tag::shutter>(ShutterMsg{
+            .frameNumber = frameNumber,
+            .timestamp = shutterTs,
+    });
+    mCallback->notify({msg});
+}
+void ExternalCameraDeviceSession::notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) {
+    NotifyMsg msg;
+    msg.set<NotifyMsg::Tag::error>(ErrorMsg{
+            .frameNumber = frameNumber,
+            .errorStreamId = streamId,
+            .errorCode = ec,
+    });
+    mCallback->notify({msg});
+}
+
+void ExternalCameraDeviceSession::invokeProcessCaptureResultCallback(
+        std::vector<CaptureResult>& results, bool tryWriteFmq) {
+    if (mProcessCaptureResultLock.tryLock() != OK) {
+        const nsecs_t NS_TO_SECOND = 1000000000;
+        ALOGV("%s: previous call is not finished! waiting 1s...", __FUNCTION__);
+        if (mProcessCaptureResultLock.timedLock(/* 1s */ NS_TO_SECOND) != OK) {
+            ALOGE("%s: cannot acquire lock in 1s, cannot proceed", __FUNCTION__);
+            return;
+        }
+    }
+    if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
+        for (CaptureResult& result : results) {
+            CameraMetadata& md = result.result;
+            if (!md.metadata.empty()) {
+                if (mResultMetadataQueue->write(reinterpret_cast<int8_t*>(md.metadata.data()),
+                                                md.metadata.size())) {
+                    result.fmqResultSize = md.metadata.size();
+                    md.metadata.resize(0);
+                } else {
+                    ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
+                    result.fmqResultSize = 0;
+                }
+            } else {
+                result.fmqResultSize = 0;
+            }
+        }
+    }
+    auto status = mCallback->processCaptureResult(results);
+    if (!status.isOk()) {
+        ALOGE("%s: processCaptureResult ERROR : %d:%d", __FUNCTION__, status.getExceptionCode(),
+              status.getServiceSpecificError());
+    }
+
+    mProcessCaptureResultLock.unlock();
+}
+
+int ExternalCameraDeviceSession::waitForV4L2BufferReturnLocked(std::unique_lock<std::mutex>& lk) {
+    ATRACE_CALL();
+    auto timeout = std::chrono::seconds(kBufferWaitTimeoutSec);
+    mLock.unlock();
+    auto st = mV4L2BufferReturned.wait_for(lk, timeout);
+    // Here we introduce an order where mV4l2BufferLock is acquired before mLock, while
+    // the normal lock acquisition order is reversed. This is fine because in most of
+    // cases we are protected by mInterfaceLock. The only thread that can cause deadlock
+    // is the OutputThread, where we do need to make sure we don't acquire mLock then
+    // mV4l2BufferLock
+    mLock.lock();
+    if (st == std::cv_status::timeout) {
+        ALOGE("%s: wait for V4L2 buffer return timeout!", __FUNCTION__);
+        return -1;
+    }
+    return 0;
+}
+
+bool ExternalCameraDeviceSession::supportOfflineLocked(int32_t streamId) {
+    const Stream& stream = mStreamMap[streamId];
+    if (stream.format == PixelFormat::BLOB &&
+        static_cast<int32_t>(stream.dataSpace) == static_cast<int32_t>(Dataspace::JFIF)) {
+        return true;
+    }
+    // TODO: support YUV output stream?
+    return false;
+}
+
+bool ExternalCameraDeviceSession::canDropRequest(const std::vector<int32_t>& offlineStreams,
+                                                 std::shared_ptr<HalRequest> halReq) {
+    for (const auto& buffer : halReq->buffers) {
+        for (auto offlineStreamId : offlineStreams) {
+            if (buffer.streamId == offlineStreamId) {
+                return false;
+            }
+        }
+    }
+    // Only drop a request completely if it has no offline output
+    return true;
+}
+
+void ExternalCameraDeviceSession::fillOfflineSessionInfo(
+        const std::vector<int32_t>& offlineStreams,
+        std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
+        const std::map<int, CirculatingBuffers>& circulatingBuffers,
+        CameraOfflineSessionInfo* info) {
+    if (info == nullptr) {
+        ALOGE("%s: output info must not be null!", __FUNCTION__);
+        return;
+    }
+
+    info->offlineStreams.resize(offlineStreams.size());
+    info->offlineRequests.resize(offlineReqs.size());
+
+    // Fill in offline reqs and count outstanding buffers
+    for (size_t i = 0; i < offlineReqs.size(); i++) {
+        info->offlineRequests[i].frameNumber = offlineReqs[i]->frameNumber;
+        info->offlineRequests[i].pendingStreams.resize(offlineReqs[i]->buffers.size());
+        for (size_t bIdx = 0; bIdx < offlineReqs[i]->buffers.size(); bIdx++) {
+            int32_t streamId = offlineReqs[i]->buffers[bIdx].streamId;
+            info->offlineRequests[i].pendingStreams[bIdx] = streamId;
+        }
+    }
+
+    for (size_t i = 0; i < offlineStreams.size(); i++) {
+        int32_t streamId = offlineStreams[i];
+        info->offlineStreams[i].id = streamId;
+        // outstanding buffers are 0 since we are doing hal buffer management and
+        // offline session will ask for those buffers later
+        info->offlineStreams[i].numOutstandingBuffers = 0;
+        const CirculatingBuffers& bufIdMap = circulatingBuffers.at(streamId);
+        info->offlineStreams[i].circulatingBufferIds.resize(bufIdMap.size());
+        size_t bIdx = 0;
+        for (const auto& pair : bufIdMap) {
+            // Fill in bufferId
+            info->offlineStreams[i].circulatingBufferIds[bIdx++] = pair.first;
+        }
+    }
+}
+
+Status ExternalCameraDeviceSession::isStreamCombinationSupported(
+        const StreamConfiguration& config, const std::vector<SupportedV4L2Format>& supportedFormats,
+        const ExternalCameraConfig& devCfg) {
+    if (config.operationMode != StreamConfigurationMode::NORMAL_MODE) {
+        ALOGE("%s: unsupported operation mode: %d", __FUNCTION__, config.operationMode);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    if (config.streams.size() == 0) {
+        ALOGE("%s: cannot configure zero stream", __FUNCTION__);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    int numProcessedStream = 0;
+    int numStallStream = 0;
+    for (const auto& stream : config.streams) {
+        // Check if the format/width/height combo is supported
+        if (!isSupported(stream, supportedFormats, devCfg)) {
+            return Status::ILLEGAL_ARGUMENT;
+        }
+        if (stream.format == PixelFormat::BLOB) {
+            numStallStream++;
+        } else {
+            numProcessedStream++;
+        }
+    }
+
+    if (numProcessedStream > kMaxProcessedStream) {
+        ALOGE("%s: too many processed streams (expect <= %d, got %d)", __FUNCTION__,
+              kMaxProcessedStream, numProcessedStream);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    if (numStallStream > kMaxStallStream) {
+        ALOGE("%s: too many stall streams (expect <= %d, got %d)", __FUNCTION__, kMaxStallStream,
+              numStallStream);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    return Status::OK;
+}
+void ExternalCameraDeviceSession::updateBufferCaches(
+        const std::vector<BufferCache>& cachesToRemove) {
+    Mutex::Autolock _l(mCbsLock);
+    for (auto& cache : cachesToRemove) {
+        auto cbsIt = mCirculatingBuffers.find(cache.streamId);
+        if (cbsIt == mCirculatingBuffers.end()) {
+            // The stream could have been removed
+            continue;
+        }
+        CirculatingBuffers& cbs = cbsIt->second;
+        auto it = cbs.find(cache.bufferId);
+        if (it != cbs.end()) {
+            sHandleImporter.freeBuffer(it->second);
+            cbs.erase(it);
+        } else {
+            ALOGE("%s: stream %d buffer %" PRIu64 " is not cached", __FUNCTION__, cache.streamId,
+                  cache.bufferId);
+        }
+    }
+}
+
+Status ExternalCameraDeviceSession::processCaptureRequestError(
+        const std::shared_ptr<HalRequest>& req, std::vector<NotifyMsg>* outMsgs,
+        std::vector<CaptureResult>* outResults) {
+    ATRACE_CALL();
+    // Return V4L2 buffer to V4L2 buffer queue
+    std::shared_ptr<V4L2Frame> v4l2Frame = std::static_pointer_cast<V4L2Frame>(req->frameIn);
+    enqueueV4l2Frame(v4l2Frame);
+
+    if (outMsgs == nullptr) {
+        notifyShutter(req->frameNumber, req->shutterTs);
+        notifyError(/*frameNum*/ req->frameNumber, /*stream*/ -1, ErrorCode::ERROR_REQUEST);
+    } else {
+        NotifyMsg shutter;
+        shutter.set<NotifyMsg::Tag::shutter>(
+                ShutterMsg{.frameNumber = req->frameNumber, .timestamp = req->shutterTs});
+
+        NotifyMsg error;
+        error.set<NotifyMsg::Tag::error>(ErrorMsg{.frameNumber = req->frameNumber,
+                                                  .errorStreamId = -1,
+                                                  .errorCode = ErrorCode::ERROR_REQUEST});
+        outMsgs->push_back(shutter);
+        outMsgs->push_back(error);
+    }
+
+    // Fill output buffers
+    CaptureResult result;
+    result.frameNumber = req->frameNumber;
+    result.partialResult = 1;
+    result.inputBuffer.streamId = -1;
+    result.outputBuffers.resize(req->buffers.size());
+    for (size_t i = 0; i < req->buffers.size(); i++) {
+        result.outputBuffers[i].streamId = req->buffers[i].streamId;
+        result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
+        result.outputBuffers[i].status = BufferStatus::ERROR;
+        if (req->buffers[i].acquireFence >= 0) {
+            native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+            handle->data[0] = req->buffers[i].acquireFence;
+            result.outputBuffers[i].releaseFence = ::android::makeToAidl(handle);
+        }
+    }
+
+    // update inflight records
+    {
+        std::lock_guard<std::mutex> lk(mInflightFramesLock);
+        mInflightFrames.erase(req->frameNumber);
+    }
+
+    if (outResults == nullptr) {
+        // Callback into framework
+        std::vector<CaptureResult> results(1);
+        results[0] = std::move(result);
+        invokeProcessCaptureResultCallback(results, /* tryWriteFmq */ true);
+        freeReleaseFences(results);
+    } else {
+        outResults->push_back(std::move(result));
+    }
+    return Status::OK;
+}
+
+Status ExternalCameraDeviceSession::processCaptureResult(std::shared_ptr<HalRequest>& req) {
+    ATRACE_CALL();
+    // Return V4L2 buffer to V4L2 buffer queue
+    std::shared_ptr<V4L2Frame> v4l2Frame = std::static_pointer_cast<V4L2Frame>(req->frameIn);
+    enqueueV4l2Frame(v4l2Frame);
+
+    // NotifyShutter
+    notifyShutter(req->frameNumber, req->shutterTs);
+
+    // Fill output buffers;
+    std::vector<CaptureResult> results(1);
+    CaptureResult& result = results[0];
+    result.frameNumber = req->frameNumber;
+    result.partialResult = 1;
+    result.inputBuffer.streamId = -1;
+    result.outputBuffers.resize(req->buffers.size());
+    for (size_t i = 0; i < req->buffers.size(); i++) {
+        result.outputBuffers[i].streamId = req->buffers[i].streamId;
+        result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
+        if (req->buffers[i].fenceTimeout) {
+            result.outputBuffers[i].status = BufferStatus::ERROR;
+            if (req->buffers[i].acquireFence >= 0) {
+                native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                handle->data[0] = req->buffers[i].acquireFence;
+                result.outputBuffers[i].releaseFence = ::android::makeToAidl(handle);
+            }
+            notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
+        } else {
+            result.outputBuffers[i].status = BufferStatus::OK;
+            // TODO: refactor
+            if (req->buffers[i].acquireFence >= 0) {
+                native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                handle->data[0] = req->buffers[i].acquireFence;
+                result.outputBuffers[i].releaseFence = ::android::makeToAidl(handle);
+            }
+        }
+    }
+
+    // Fill capture result metadata
+    fillCaptureResult(req->setting, req->shutterTs);
+    const camera_metadata_t* rawResult = req->setting.getAndLock();
+    convertToAidl(rawResult, &result.result);
+    req->setting.unlock(rawResult);
+
+    // update inflight records
+    {
+        std::lock_guard<std::mutex> lk(mInflightFramesLock);
+        mInflightFrames.erase(req->frameNumber);
+    }
+
+    // Callback into framework
+    invokeProcessCaptureResultCallback(results, /* tryWriteFmq */ true);
+    freeReleaseFences(results);
+    return Status::OK;
+}
+
+ssize_t ExternalCameraDeviceSession::getJpegBufferSize(int32_t width, int32_t height) const {
+    // Constant from camera3.h
+    const ssize_t kMinJpegBufferSize = 256 * 1024 + sizeof(CameraBlob);
+    // Get max jpeg size (area-wise).
+    if (mMaxJpegResolution.width == 0) {
+        ALOGE("%s: No supported JPEG stream", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    // Get max jpeg buffer size
+    ssize_t maxJpegBufferSize = 0;
+    camera_metadata_ro_entry jpegBufMaxSize = mCameraCharacteristics.find(ANDROID_JPEG_MAX_SIZE);
+    if (jpegBufMaxSize.count == 0) {
+        ALOGE("%s: Can't find maximum JPEG size in static metadata!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
+
+    if (maxJpegBufferSize <= kMinJpegBufferSize) {
+        ALOGE("%s: ANDROID_JPEG_MAX_SIZE (%zd) <= kMinJpegBufferSize (%zd)", __FUNCTION__,
+              maxJpegBufferSize, kMinJpegBufferSize);
+        return BAD_VALUE;
+    }
+
+    // Calculate final jpeg buffer size for the given resolution.
+    float scaleFactor =
+            ((float)(width * height)) / (mMaxJpegResolution.width * mMaxJpegResolution.height);
+    ssize_t jpegBufferSize =
+            scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) + kMinJpegBufferSize;
+    if (jpegBufferSize > maxJpegBufferSize) {
+        jpegBufferSize = maxJpegBufferSize;
+    }
+
+    return jpegBufferSize;
+}
+binder_status_t ExternalCameraDeviceSession::dump(int fd, const char** /*args*/,
+                                                  uint32_t /*numArgs*/) {
+    bool intfLocked = tryLock(mInterfaceLock);
+    if (!intfLocked) {
+        dprintf(fd, "!! ExternalCameraDeviceSession interface may be deadlocked !!\n");
+    }
+
+    if (isClosed()) {
+        dprintf(fd, "External camera %s is closed\n", mCameraId.c_str());
+        return STATUS_OK;
+    }
+
+    bool streaming = false;
+    size_t v4L2BufferCount = 0;
+    SupportedV4L2Format streamingFmt;
+    {
+        bool sessionLocked = tryLock(mLock);
+        if (!sessionLocked) {
+            dprintf(fd, "!! ExternalCameraDeviceSession mLock may be deadlocked !!\n");
+        }
+        streaming = mV4l2Streaming;
+        streamingFmt = mV4l2StreamingFmt;
+        v4L2BufferCount = mV4L2BufferCount;
+
+        if (sessionLocked) {
+            mLock.unlock();
+        }
+    }
+
+    std::unordered_set<uint32_t> inflightFrames;
+    {
+        bool iffLocked = tryLock(mInflightFramesLock);
+        if (!iffLocked) {
+            dprintf(fd,
+                    "!! ExternalCameraDeviceSession mInflightFramesLock may be deadlocked !!\n");
+        }
+        inflightFrames = mInflightFrames;
+        if (iffLocked) {
+            mInflightFramesLock.unlock();
+        }
+    }
+
+    dprintf(fd, "External camera %s V4L2 FD %d, cropping type %s, %s\n", mCameraId.c_str(),
+            mV4l2Fd.get(), (mCroppingType == VERTICAL) ? "vertical" : "horizontal",
+            streaming ? "streaming" : "not streaming");
+
+    if (streaming) {
+        // TODO: dump fps later
+        dprintf(fd, "Current V4L2 format %c%c%c%c %dx%d @ %ffps\n", streamingFmt.fourcc & 0xFF,
+                (streamingFmt.fourcc >> 8) & 0xFF, (streamingFmt.fourcc >> 16) & 0xFF,
+                (streamingFmt.fourcc >> 24) & 0xFF, streamingFmt.width, streamingFmt.height,
+                mV4l2StreamingFps);
+
+        size_t numDequeuedV4l2Buffers = 0;
+        {
+            std::lock_guard<std::mutex> lk(mV4l2BufferLock);
+            numDequeuedV4l2Buffers = mNumDequeuedV4l2Buffers;
+        }
+        dprintf(fd, "V4L2 buffer queue size %zu, dequeued %zu\n", v4L2BufferCount,
+                numDequeuedV4l2Buffers);
+    }
+
+    dprintf(fd, "In-flight frames (not sorted):");
+    for (const auto& frameNumber : inflightFrames) {
+        dprintf(fd, "%d, ", frameNumber);
+    }
+    dprintf(fd, "\n");
+    mOutputThread->dump(fd);
+    dprintf(fd, "\n");
+
+    if (intfLocked) {
+        mInterfaceLock.unlock();
+    }
+
+    return STATUS_OK;
+}
+
+// Start ExternalCameraDeviceSession::BufferRequestThread functions
+ExternalCameraDeviceSession::BufferRequestThread::BufferRequestThread(
+        std::weak_ptr<OutputThreadInterface> parent,
+        std::shared_ptr<ICameraDeviceCallback> callbacks)
+    : mParent(parent), mCallbacks(callbacks) {}
+
+int ExternalCameraDeviceSession::BufferRequestThread::requestBufferStart(
+        const std::vector<HalStreamBuffer>& bufReqs) {
+    if (bufReqs.empty()) {
+        ALOGE("%s: bufReqs is empty!", __FUNCTION__);
+        return -1;
+    }
+
+    {
+        std::lock_guard<std::mutex> lk(mLock);
+        if (mRequestingBuffer) {
+            ALOGE("%s: BufferRequestThread does not support more than one concurrent request!",
+                  __FUNCTION__);
+            return -1;
+        }
+
+        mBufferReqs = bufReqs;
+        mRequestingBuffer = true;
+    }
+    mRequestCond.notify_one();
+    return 0;
+}
+
+int ExternalCameraDeviceSession::BufferRequestThread::waitForBufferRequestDone(
+        std::vector<HalStreamBuffer>* outBufReqs) {
+    std::unique_lock<std::mutex> lk(mLock);
+    if (!mRequestingBuffer) {
+        ALOGE("%s: no pending buffer request!", __FUNCTION__);
+        return -1;
+    }
+
+    if (mPendingReturnBufferReqs.empty()) {
+        std::chrono::milliseconds timeout = std::chrono::milliseconds(kReqProcTimeoutMs);
+        auto st = mRequestDoneCond.wait_for(lk, timeout);
+        if (st == std::cv_status::timeout) {
+            ALOGE("%s: wait for buffer request finish timeout!", __FUNCTION__);
+            return -1;
+        }
+    }
+    mRequestingBuffer = false;
+    *outBufReqs = std::move(mPendingReturnBufferReqs);
+    mPendingReturnBufferReqs.clear();
+    return 0;
+}
+
+void ExternalCameraDeviceSession::BufferRequestThread::waitForNextRequest() {
+    ATRACE_CALL();
+    std::unique_lock<std::mutex> lk(mLock);
+    int waitTimes = 0;
+    while (mBufferReqs.empty()) {
+        if (exitPending()) {
+            return;
+        }
+        auto timeout = std::chrono::milliseconds(kReqWaitTimeoutMs);
+        auto st = mRequestCond.wait_for(lk, timeout);
+        if (st == std::cv_status::timeout) {
+            waitTimes++;
+            if (waitTimes == kReqWaitTimesWarn) {
+                // BufferRequestThread just wait forever for new buffer request
+                // But it will print some periodic warning indicating it's waiting
+                ALOGV("%s: still waiting for new buffer request", __FUNCTION__);
+                waitTimes = 0;
+            }
+        }
+    }
+
+    // Fill in BufferRequest
+    mHalBufferReqs.resize(mBufferReqs.size());
+    for (size_t i = 0; i < mHalBufferReqs.size(); i++) {
+        mHalBufferReqs[i].streamId = mBufferReqs[i].streamId;
+        mHalBufferReqs[i].numBuffersRequested = 1;
+    }
+}
+
+bool ExternalCameraDeviceSession::BufferRequestThread::threadLoop() {
+    waitForNextRequest();
+    if (exitPending()) {
+        return false;
+    }
+
+    ATRACE_BEGIN("AIDL requestStreamBuffers");
+    BufferRequestStatus status;
+    std::vector<StreamBufferRet> bufRets;
+    ScopedAStatus ret = mCallbacks->requestStreamBuffers(mHalBufferReqs, &bufRets, &status);
+    if (!ret.isOk()) {
+        ALOGE("%s: Transaction error: %d:%d", __FUNCTION__, ret.getExceptionCode(),
+              ret.getServiceSpecificError());
+        return false;
+    }
+
+    std::unique_lock<std::mutex> lk(mLock);
+    if (status == BufferRequestStatus::OK || status == BufferRequestStatus::FAILED_PARTIAL) {
+        if (bufRets.size() != mHalBufferReqs.size()) {
+            ALOGE("%s: expect %zu buffer requests returned, only got %zu", __FUNCTION__,
+                  mHalBufferReqs.size(), bufRets.size());
+            return false;
+        }
+
+        auto parent = mParent.lock();
+        if (parent == nullptr) {
+            ALOGE("%s: session has been disconnected!", __FUNCTION__);
+            return false;
+        }
+
+        std::vector<int> importedFences;
+        importedFences.resize(bufRets.size());
+        for (size_t i = 0; i < bufRets.size(); i++) {
+            int streamId = bufRets[i].streamId;
+            switch (bufRets[i].val.getTag()) {
+                case StreamBuffersVal::Tag::error:
+                    continue;
+                case StreamBuffersVal::Tag::buffers: {
+                    const std::vector<StreamBuffer>& hBufs =
+                            bufRets[i].val.get<StreamBuffersVal::Tag::buffers>();
+                    if (hBufs.size() != 1) {
+                        ALOGE("%s: expect 1 buffer returned, got %zu!", __FUNCTION__, hBufs.size());
+                        return false;
+                    }
+                    const StreamBuffer& hBuf = hBufs[0];
+
+                    mBufferReqs[i].bufferId = hBuf.bufferId;
+                    // TODO: create a batch import API so we don't need to lock/unlock mCbsLock
+                    // repeatedly?
+                    lk.unlock();
+                    Status s =
+                            parent->importBuffer(streamId, hBuf.bufferId, makeFromAidl(hBuf.buffer),
+                                                 /*out*/ &mBufferReqs[i].bufPtr);
+                    lk.lock();
+
+                    if (s != Status::OK) {
+                        ALOGE("%s: stream %d import buffer failed!", __FUNCTION__, streamId);
+                        cleanupInflightFences(importedFences, i - 1);
+                        return false;
+                    }
+                    if (!sHandleImporter.importFence(makeFromAidl(hBuf.acquireFence),
+                                                     mBufferReqs[i].acquireFence)) {
+                        ALOGE("%s: stream %d import fence failed!", __FUNCTION__, streamId);
+                        cleanupInflightFences(importedFences, i - 1);
+                        return false;
+                    }
+                    importedFences[i] = mBufferReqs[i].acquireFence;
+                } break;
+                default:
+                    ALOGE("%s: Unknown StreamBuffersVal!", __FUNCTION__);
+                    return false;
+            }
+        }
+    } else {
+        ALOGE("%s: requestStreamBuffers call failed!", __FUNCTION__);
+    }
+
+    mPendingReturnBufferReqs = std::move(mBufferReqs);
+    mBufferReqs.clear();
+
+    lk.unlock();
+    mRequestDoneCond.notify_one();
+    return true;
+}
+
+// End ExternalCameraDeviceSession::BufferRequestThread functions
+
+// Start ExternalCameraDeviceSession::OutputThread functions
+
+ExternalCameraDeviceSession::OutputThread::OutputThread(
+        std::weak_ptr<OutputThreadInterface> parent, CroppingType ct,
+        const common::V1_0::helper::CameraMetadata& chars,
+        std::shared_ptr<BufferRequestThread> bufReqThread)
+    : mParent(parent),
+      mCroppingType(ct),
+      mCameraCharacteristics(chars),
+      mBufferRequestThread(bufReqThread) {}
+
+ExternalCameraDeviceSession::OutputThread::~OutputThread() {}
+
+Status ExternalCameraDeviceSession::OutputThread::allocateIntermediateBuffers(
+        const Size& v4lSize, const Size& thumbSize, const std::vector<Stream>& streams,
+        uint32_t blobBufferSize) {
+    std::lock_guard<std::mutex> lk(mBufferLock);
+    if (!mScaledYu12Frames.empty()) {
+        ALOGE("%s: intermediate buffer pool has %zu inflight buffers! (expect 0)", __FUNCTION__,
+              mScaledYu12Frames.size());
+        return Status::INTERNAL_ERROR;
+    }
+
+    // Allocating intermediate YU12 frame
+    if (mYu12Frame == nullptr || mYu12Frame->mWidth != v4lSize.width ||
+        mYu12Frame->mHeight != v4lSize.height) {
+        mYu12Frame.reset();
+        mYu12Frame = std::make_shared<AllocatedFrame>(v4lSize.width, v4lSize.height);
+        int ret = mYu12Frame->allocate(&mYu12FrameLayout);
+        if (ret != 0) {
+            ALOGE("%s: allocating YU12 frame failed!", __FUNCTION__);
+            return Status::INTERNAL_ERROR;
+        }
+    }
+
+    // Allocating intermediate YU12 thumbnail frame
+    if (mYu12ThumbFrame == nullptr || mYu12ThumbFrame->mWidth != thumbSize.width ||
+        mYu12ThumbFrame->mHeight != thumbSize.height) {
+        mYu12ThumbFrame.reset();
+        mYu12ThumbFrame = std::make_shared<AllocatedFrame>(thumbSize.width, thumbSize.height);
+        int ret = mYu12ThumbFrame->allocate(&mYu12ThumbFrameLayout);
+        if (ret != 0) {
+            ALOGE("%s: allocating YU12 thumb frame failed!", __FUNCTION__);
+            return Status::INTERNAL_ERROR;
+        }
+    }
+
+    // Allocating scaled buffers
+    for (const auto& stream : streams) {
+        Size sz = {stream.width, stream.height};
+        if (sz == v4lSize) {
+            continue;  // Don't need an intermediate buffer same size as v4lBuffer
+        }
+        if (mIntermediateBuffers.count(sz) == 0) {
+            // Create new intermediate buffer
+            std::shared_ptr<AllocatedFrame> buf =
+                    std::make_shared<AllocatedFrame>(stream.width, stream.height);
+            int ret = buf->allocate();
+            if (ret != 0) {
+                ALOGE("%s: allocating intermediate YU12 frame %dx%d failed!", __FUNCTION__,
+                      stream.width, stream.height);
+                return Status::INTERNAL_ERROR;
+            }
+            mIntermediateBuffers[sz] = buf;
+        }
+    }
+
+    // Remove unconfigured buffers
+    auto it = mIntermediateBuffers.begin();
+    while (it != mIntermediateBuffers.end()) {
+        bool configured = false;
+        auto sz = it->first;
+        for (const auto& stream : streams) {
+            if (stream.width == sz.width && stream.height == sz.height) {
+                configured = true;
+                break;
+            }
+        }
+        if (configured) {
+            it++;
+        } else {
+            it = mIntermediateBuffers.erase(it);
+        }
+    }
+
+    // Allocate mute test pattern frame
+    mMuteTestPatternFrame.resize(mYu12Frame->mWidth * mYu12Frame->mHeight * 3);
+
+    mBlobBufferSize = blobBufferSize;
+    return Status::OK;
+}
+
+Status ExternalCameraDeviceSession::OutputThread::submitRequest(
+        const std::shared_ptr<HalRequest>& req) {
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    mRequestList.push_back(req);
+    lk.unlock();
+    mRequestCond.notify_one();
+    return Status::OK;
+}
+
+void ExternalCameraDeviceSession::OutputThread::flush() {
+    ATRACE_CALL();
+    auto parent = mParent.lock();
+    if (parent == nullptr) {
+        ALOGE("%s: session has been disconnected!", __FUNCTION__);
+        return;
+    }
+
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    std::list<std::shared_ptr<HalRequest>> reqs = std::move(mRequestList);
+    mRequestList.clear();
+    if (mProcessingRequest) {
+        auto timeout = std::chrono::seconds(kFlushWaitTimeoutSec);
+        auto st = mRequestDoneCond.wait_for(lk, timeout);
+        if (st == std::cv_status::timeout) {
+            ALOGE("%s: wait for inflight request finish timeout!", __FUNCTION__);
+        }
+    }
+
+    ALOGV("%s: flushing inflight requests", __FUNCTION__);
+    lk.unlock();
+    for (const auto& req : reqs) {
+        parent->processCaptureRequestError(req);
+    }
+}
+
+void ExternalCameraDeviceSession::OutputThread::dump(int fd) {
+    std::lock_guard<std::mutex> lk(mRequestListLock);
+    if (mProcessingRequest) {
+        dprintf(fd, "OutputThread processing frame %d\n", mProcessingFrameNumber);
+    } else {
+        dprintf(fd, "OutputThread not processing any frames\n");
+    }
+    dprintf(fd, "OutputThread request list contains frame: ");
+    for (const auto& req : mRequestList) {
+        dprintf(fd, "%d, ", req->frameNumber);
+    }
+    dprintf(fd, "\n");
+}
+
+void ExternalCameraDeviceSession::OutputThread::setExifMakeModel(const std::string& make,
+                                                                 const std::string& model) {
+    mExifMake = make;
+    mExifModel = model;
+}
+
+std::list<std::shared_ptr<HalRequest>>
+ExternalCameraDeviceSession::OutputThread::switchToOffline() {
+    ATRACE_CALL();
+    auto parent = mParent.lock();
+    if (parent == nullptr) {
+        ALOGE("%s: session has been disconnected!", __FUNCTION__);
+        return {};
+    }
+
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    std::list<std::shared_ptr<HalRequest>> reqs = std::move(mRequestList);
+    mRequestList.clear();
+    if (mProcessingRequest) {
+        auto timeout = std::chrono::seconds(kFlushWaitTimeoutSec);
+        auto st = mRequestDoneCond.wait_for(lk, timeout);
+        if (st == std::cv_status::timeout) {
+            ALOGE("%s: wait for inflight request finish timeout!", __FUNCTION__);
+        }
+    }
+    lk.unlock();
+    clearIntermediateBuffers();
+    ALOGV("%s: returning %zu request for offline processing", __FUNCTION__, reqs.size());
+    return reqs;
+}
+
+int ExternalCameraDeviceSession::OutputThread::requestBufferStart(
+        const std::vector<HalStreamBuffer>& bufs) {
+    if (mBufferRequestThread == nullptr) {
+        return 0;
+    }
+    return mBufferRequestThread->requestBufferStart(bufs);
+}
+
+int ExternalCameraDeviceSession::OutputThread::waitForBufferRequestDone(
+        std::vector<HalStreamBuffer>* outBufs) {
+    if (mBufferRequestThread == nullptr) {
+        return 0;
+    }
+    return mBufferRequestThread->waitForBufferRequestDone(outBufs);
+}
+
+void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(
+        std::shared_ptr<HalRequest>* out) {
+    ATRACE_CALL();
+    if (out == nullptr) {
+        ALOGE("%s: out is null", __FUNCTION__);
+        return;
+    }
+
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    int waitTimes = 0;
+    while (mRequestList.empty()) {
+        if (exitPending()) {
+            return;
+        }
+        auto timeout = std::chrono::milliseconds(kReqWaitTimeoutMs);
+        auto st = mRequestCond.wait_for(lk, timeout);
+        if (st == std::cv_status::timeout) {
+            waitTimes++;
+            if (waitTimes == kReqWaitTimesMax) {
+                // no new request, return
+                return;
+            }
+        }
+    }
+    *out = mRequestList.front();
+    mRequestList.pop_front();
+    mProcessingRequest = true;
+    mProcessingFrameNumber = (*out)->frameNumber;
+}
+
+void ExternalCameraDeviceSession::OutputThread::signalRequestDone() {
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    mProcessingRequest = false;
+    mProcessingFrameNumber = 0;
+    lk.unlock();
+    mRequestDoneCond.notify_one();
+}
+
+int ExternalCameraDeviceSession::OutputThread::cropAndScaleLocked(
+        std::shared_ptr<AllocatedFrame>& in, const Size& outSz, YCbCrLayout* out) {
+    Size inSz = {in->mWidth, in->mHeight};
+
+    int ret;
+    if (inSz == outSz) {
+        ret = in->getLayout(out);
+        if (ret != 0) {
+            ALOGE("%s: failed to get input image layout", __FUNCTION__);
+            return ret;
+        }
+        return ret;
+    }
+
+    // Cropping to output aspect ratio
+    IMapper::Rect inputCrop;
+    ret = getCropRect(mCroppingType, inSz, outSz, &inputCrop);
+    if (ret != 0) {
+        ALOGE("%s: failed to compute crop rect for output size %dx%d", __FUNCTION__, outSz.width,
+              outSz.height);
+        return ret;
+    }
+
+    YCbCrLayout croppedLayout;
+    ret = in->getCroppedLayout(inputCrop, &croppedLayout);
+    if (ret != 0) {
+        ALOGE("%s: failed to crop input image %dx%d to output size %dx%d", __FUNCTION__, inSz.width,
+              inSz.height, outSz.width, outSz.height);
+        return ret;
+    }
+
+    if ((mCroppingType == VERTICAL && inSz.width == outSz.width) ||
+        (mCroppingType == HORIZONTAL && inSz.height == outSz.height)) {
+        // No scale is needed
+        *out = croppedLayout;
+        return 0;
+    }
+
+    auto it = mScaledYu12Frames.find(outSz);
+    std::shared_ptr<AllocatedFrame> scaledYu12Buf;
+    if (it != mScaledYu12Frames.end()) {
+        scaledYu12Buf = it->second;
+    } else {
+        it = mIntermediateBuffers.find(outSz);
+        if (it == mIntermediateBuffers.end()) {
+            ALOGE("%s: failed to find intermediate buffer size %dx%d", __FUNCTION__, outSz.width,
+                  outSz.height);
+            return -1;
+        }
+        scaledYu12Buf = it->second;
+    }
+    // Scale
+    YCbCrLayout outLayout;
+    ret = scaledYu12Buf->getLayout(&outLayout);
+    if (ret != 0) {
+        ALOGE("%s: failed to get output buffer layout", __FUNCTION__);
+        return ret;
+    }
+
+    ret = libyuv::I420Scale(
+            static_cast<uint8_t*>(croppedLayout.y), croppedLayout.yStride,
+            static_cast<uint8_t*>(croppedLayout.cb), croppedLayout.cStride,
+            static_cast<uint8_t*>(croppedLayout.cr), croppedLayout.cStride, inputCrop.width,
+            inputCrop.height, static_cast<uint8_t*>(outLayout.y), outLayout.yStride,
+            static_cast<uint8_t*>(outLayout.cb), outLayout.cStride,
+            static_cast<uint8_t*>(outLayout.cr), outLayout.cStride, outSz.width, outSz.height,
+            // TODO: b/72261744 see if we can use better filter without losing too much perf
+            libyuv::FilterMode::kFilterNone);
+
+    if (ret != 0) {
+        ALOGE("%s: failed to scale buffer from %dx%d to %dx%d. Ret %d", __FUNCTION__,
+              inputCrop.width, inputCrop.height, outSz.width, outSz.height, ret);
+        return ret;
+    }
+
+    *out = outLayout;
+    mScaledYu12Frames.insert({outSz, scaledYu12Buf});
+    return 0;
+}
+
+int ExternalCameraDeviceSession::OutputThread::cropAndScaleThumbLocked(
+        std::shared_ptr<AllocatedFrame>& in, const Size& outSz, YCbCrLayout* out) {
+    Size inSz{in->mWidth, in->mHeight};
+
+    if ((outSz.width * outSz.height) > (mYu12ThumbFrame->mWidth * mYu12ThumbFrame->mHeight)) {
+        ALOGE("%s: Requested thumbnail size too big (%d,%d) > (%d,%d)", __FUNCTION__, outSz.width,
+              outSz.height, mYu12ThumbFrame->mWidth, mYu12ThumbFrame->mHeight);
+        return -1;
+    }
+
+    int ret;
+
+    /* This will crop-and-zoom the input YUV frame to the thumbnail size
+     * Based on the following logic:
+     *  1) Square pixels come in, square pixels come out, therefore single
+     *  scale factor is computed to either make input bigger or smaller
+     *  depending on if we are upscaling or downscaling
+     *  2) That single scale factor would either make height too tall or width
+     *  too wide so we need to crop the input either horizontally or vertically
+     *  but not both
+     */
+
+    /* Convert the input and output dimensions into floats for ease of math */
+    float fWin = static_cast<float>(inSz.width);
+    float fHin = static_cast<float>(inSz.height);
+    float fWout = static_cast<float>(outSz.width);
+    float fHout = static_cast<float>(outSz.height);
+
+    /* Compute the one scale factor from (1) above, it will be the smaller of
+     * the two possibilities. */
+    float scaleFactor = std::min(fHin / fHout, fWin / fWout);
+
+    /* Since we are crop-and-zooming (as opposed to letter/pillar boxing) we can
+     * simply multiply the output by our scaleFactor to get the cropped input
+     * size. Note that at least one of {fWcrop, fHcrop} is going to wind up
+     * being {fWin, fHin} respectively because fHout or fWout cancels out the
+     * scaleFactor calculation above.
+     *
+     * Specifically:
+     *  if ( fHin / fHout ) < ( fWin / fWout ) we crop the sides off
+     * input, in which case
+     *    scaleFactor = fHin / fHout
+     *    fWcrop = fHin / fHout * fWout
+     *    fHcrop = fHin
+     *
+     * Note that fWcrop <= fWin ( because ( fHin / fHout ) * fWout < fWin, which
+     * is just the inequality above with both sides multiplied by fWout
+     *
+     * on the other hand if ( fWin / fWout ) < ( fHin / fHout) we crop the top
+     * and the bottom off of input, and
+     *    scaleFactor = fWin / fWout
+     *    fWcrop = fWin
+     *    fHCrop = fWin / fWout * fHout
+     */
+    float fWcrop = scaleFactor * fWout;
+    float fHcrop = scaleFactor * fHout;
+
+    /* Convert to integer and truncate to an even number */
+    Size cropSz = {.width = 2 * static_cast<int32_t>(fWcrop / 2.0f),
+                   .height = 2 * static_cast<int32_t>(fHcrop / 2.0f)};
+
+    /* Convert to a centered rectange with even top/left */
+    IMapper::Rect inputCrop{.left = 2 * static_cast<int32_t>((inSz.width - cropSz.width) / 4),
+                            .top = 2 * static_cast<int32_t>((inSz.height - cropSz.height) / 4),
+                            .width = static_cast<int32_t>(cropSz.width),
+                            .height = static_cast<int32_t>(cropSz.height)};
+
+    if ((inputCrop.top < 0) || (inputCrop.top >= static_cast<int32_t>(inSz.height)) ||
+        (inputCrop.left < 0) || (inputCrop.left >= static_cast<int32_t>(inSz.width)) ||
+        (inputCrop.width <= 0) ||
+        (inputCrop.width + inputCrop.left > static_cast<int32_t>(inSz.width)) ||
+        (inputCrop.height <= 0) ||
+        (inputCrop.height + inputCrop.top > static_cast<int32_t>(inSz.height))) {
+        ALOGE("%s: came up with really wrong crop rectangle", __FUNCTION__);
+        ALOGE("%s: input layout %dx%d to for output size %dx%d", __FUNCTION__, inSz.width,
+              inSz.height, outSz.width, outSz.height);
+        ALOGE("%s: computed input crop +%d,+%d %dx%d", __FUNCTION__, inputCrop.left, inputCrop.top,
+              inputCrop.width, inputCrop.height);
+        return -1;
+    }
+
+    YCbCrLayout inputLayout;
+    ret = in->getCroppedLayout(inputCrop, &inputLayout);
+    if (ret != 0) {
+        ALOGE("%s: failed to crop input layout %dx%d to for output size %dx%d", __FUNCTION__,
+              inSz.width, inSz.height, outSz.width, outSz.height);
+        ALOGE("%s: computed input crop +%d,+%d %dx%d", __FUNCTION__, inputCrop.left, inputCrop.top,
+              inputCrop.width, inputCrop.height);
+        return ret;
+    }
+    ALOGV("%s: crop input layout %dx%d to for output size %dx%d", __FUNCTION__, inSz.width,
+          inSz.height, outSz.width, outSz.height);
+    ALOGV("%s: computed input crop +%d,+%d %dx%d", __FUNCTION__, inputCrop.left, inputCrop.top,
+          inputCrop.width, inputCrop.height);
+
+    // Scale
+    YCbCrLayout outFullLayout;
+
+    ret = mYu12ThumbFrame->getLayout(&outFullLayout);
+    if (ret != 0) {
+        ALOGE("%s: failed to get output buffer layout", __FUNCTION__);
+        return ret;
+    }
+
+    ret = libyuv::I420Scale(static_cast<uint8_t*>(inputLayout.y), inputLayout.yStride,
+                            static_cast<uint8_t*>(inputLayout.cb), inputLayout.cStride,
+                            static_cast<uint8_t*>(inputLayout.cr), inputLayout.cStride,
+                            inputCrop.width, inputCrop.height,
+                            static_cast<uint8_t*>(outFullLayout.y), outFullLayout.yStride,
+                            static_cast<uint8_t*>(outFullLayout.cb), outFullLayout.cStride,
+                            static_cast<uint8_t*>(outFullLayout.cr), outFullLayout.cStride,
+                            outSz.width, outSz.height, libyuv::FilterMode::kFilterNone);
+
+    if (ret != 0) {
+        ALOGE("%s: failed to scale buffer from %dx%d to %dx%d. Ret %d", __FUNCTION__,
+              inputCrop.width, inputCrop.height, outSz.width, outSz.height, ret);
+        return ret;
+    }
+
+    *out = outFullLayout;
+    return 0;
+}
+
+int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
+        HalStreamBuffer& halBuf, const common::V1_0::helper::CameraMetadata& setting) {
+    ATRACE_CALL();
+    int ret;
+    auto lfail = [&](auto... args) {
+        ALOGE(args...);
+
+        return 1;
+    };
+    auto parent = mParent.lock();
+    if (parent == nullptr) {
+        ALOGE("%s: session has been disconnected!", __FUNCTION__);
+        return 1;
+    }
+
+    ALOGV("%s: HAL buffer sid: %d bid: %" PRIu64 " w: %u h: %u", __FUNCTION__, halBuf.streamId,
+          static_cast<uint64_t>(halBuf.bufferId), halBuf.width, halBuf.height);
+    ALOGV("%s: HAL buffer fmt: %x usage: %" PRIx64 " ptr: %p", __FUNCTION__, halBuf.format,
+          static_cast<uint64_t>(halBuf.usage), halBuf.bufPtr);
+    ALOGV("%s: YV12 buffer %d x %d", __FUNCTION__, mYu12Frame->mWidth, mYu12Frame->mHeight);
+
+    int jpegQuality, thumbQuality;
+    Size thumbSize;
+    bool outputThumbnail = true;
+
+    if (setting.exists(ANDROID_JPEG_QUALITY)) {
+        camera_metadata_ro_entry entry = setting.find(ANDROID_JPEG_QUALITY);
+        jpegQuality = entry.data.u8[0];
+    } else {
+        return lfail("%s: ANDROID_JPEG_QUALITY not set", __FUNCTION__);
+    }
+
+    if (setting.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) {
+        camera_metadata_ro_entry entry = setting.find(ANDROID_JPEG_THUMBNAIL_QUALITY);
+        thumbQuality = entry.data.u8[0];
+    } else {
+        return lfail("%s: ANDROID_JPEG_THUMBNAIL_QUALITY not set", __FUNCTION__);
+    }
+
+    if (setting.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
+        camera_metadata_ro_entry entry = setting.find(ANDROID_JPEG_THUMBNAIL_SIZE);
+        thumbSize = Size{.width = entry.data.i32[0], .height = entry.data.i32[1]};
+        if (thumbSize.width == 0 && thumbSize.height == 0) {
+            outputThumbnail = false;
+        }
+    } else {
+        return lfail("%s: ANDROID_JPEG_THUMBNAIL_SIZE not set", __FUNCTION__);
+    }
+
+    /* Cropped and scaled YU12 buffer for main and thumbnail */
+    YCbCrLayout yu12Main;
+    Size jpegSize{halBuf.width, halBuf.height};
+
+    /* Compute temporary buffer sizes accounting for the following:
+     * thumbnail can't exceed APP1 size of 64K
+     * main image needs to hold APP1, headers, and at most a poorly
+     * compressed image */
+    const ssize_t maxThumbCodeSize = 64 * 1024;
+    const ssize_t maxJpegCodeSize =
+            mBlobBufferSize == 0 ? parent->getJpegBufferSize(jpegSize.width, jpegSize.height)
+                                 : mBlobBufferSize;
+
+    /* Check that getJpegBufferSize did not return an error */
+    if (maxJpegCodeSize < 0) {
+        return lfail("%s: getJpegBufferSize returned %zd", __FUNCTION__, maxJpegCodeSize);
+    }
+
+    /* Hold actual thumbnail and main image code sizes */
+    size_t thumbCodeSize = 0, jpegCodeSize = 0;
+    /* Temporary thumbnail code buffer */
+    std::vector<uint8_t> thumbCode(outputThumbnail ? maxThumbCodeSize : 0);
+
+    YCbCrLayout yu12Thumb;
+    if (outputThumbnail) {
+        ret = cropAndScaleThumbLocked(mYu12Frame, thumbSize, &yu12Thumb);
+
+        if (ret != 0) {
+            return lfail("%s: crop and scale thumbnail failed!", __FUNCTION__);
+        }
+    }
+
+    /* Scale and crop main jpeg */
+    ret = cropAndScaleLocked(mYu12Frame, jpegSize, &yu12Main);
+
+    if (ret != 0) {
+        return lfail("%s: crop and scale main failed!", __FUNCTION__);
+    }
+
+    /* Encode the thumbnail image */
+    if (outputThumbnail) {
+        ret = encodeJpegYU12(thumbSize, yu12Thumb, thumbQuality, 0, 0, &thumbCode[0],
+                             maxThumbCodeSize, thumbCodeSize);
+
+        if (ret != 0) {
+            return lfail("%s: thumbnail encodeJpegYU12 failed with %d", __FUNCTION__, ret);
+        }
+    }
+
+    /* Combine camera characteristics with request settings to form EXIF
+     * metadata */
+    common::V1_0::helper::CameraMetadata meta(mCameraCharacteristics);
+    meta.append(setting);
+
+    /* Generate EXIF object */
+    std::unique_ptr<ExifUtils> utils(ExifUtils::create());
+    /* Make sure it's initialized */
+    utils->initialize();
+
+    utils->setFromMetadata(meta, jpegSize.width, jpegSize.height);
+    utils->setMake(mExifMake);
+    utils->setModel(mExifModel);
+
+    ret = utils->generateApp1(outputThumbnail ? &thumbCode[0] : nullptr, thumbCodeSize);
+
+    if (!ret) {
+        return lfail("%s: generating APP1 failed", __FUNCTION__);
+    }
+
+    /* Get internal buffer */
+    size_t exifDataSize = utils->getApp1Length();
+    const uint8_t* exifData = utils->getApp1Buffer();
+
+    /* Lock the HAL jpeg code buffer */
+    void* bufPtr = sHandleImporter.lock(*(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage),
+                                        maxJpegCodeSize);
+
+    if (!bufPtr) {
+        return lfail("%s: could not lock %zu bytes", __FUNCTION__, maxJpegCodeSize);
+    }
+
+    /* Encode the main jpeg image */
+    ret = encodeJpegYU12(jpegSize, yu12Main, jpegQuality, exifData, exifDataSize, bufPtr,
+                         maxJpegCodeSize, jpegCodeSize);
+
+    /* TODO: Not sure this belongs here, maybe better to pass jpegCodeSize out
+     * and do this when returning buffer to parent */
+    CameraBlob blob{CameraBlobId::JPEG, static_cast<int32_t>(jpegCodeSize)};
+    void* blobDst = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(bufPtr) + maxJpegCodeSize -
+                                            sizeof(CameraBlob));
+    memcpy(blobDst, &blob, sizeof(CameraBlob));
+
+    /* Unlock the HAL jpeg code buffer */
+    int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+    if (relFence >= 0) {
+        halBuf.acquireFence = relFence;
+    }
+
+    /* Check if our JPEG actually succeeded */
+    if (ret != 0) {
+        return lfail("%s: encodeJpegYU12 failed with %d", __FUNCTION__, ret);
+    }
+
+    ALOGV("%s: encoded JPEG (ret:%d) with Q:%d max size: %zu", __FUNCTION__, ret, jpegQuality,
+          maxJpegCodeSize);
+
+    return 0;
+}
+
+void ExternalCameraDeviceSession::OutputThread::clearIntermediateBuffers() {
+    std::lock_guard<std::mutex> lk(mBufferLock);
+    mYu12Frame.reset();
+    mYu12ThumbFrame.reset();
+    mIntermediateBuffers.clear();
+    mMuteTestPatternFrame.clear();
+    mBlobBufferSize = 0;
+}
+
+bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
+    std::shared_ptr<HalRequest> req;
+    auto parent = mParent.lock();
+    if (parent == nullptr) {
+        ALOGE("%s: session has been disconnected!", __FUNCTION__);
+        return false;
+    }
+
+    // TODO: maybe we need to setup a sensor thread to dq/enq v4l frames
+    //       regularly to prevent v4l buffer queue filled with stale buffers
+    //       when app doesn't program a preview request
+    waitForNextRequest(&req);
+    if (req == nullptr) {
+        // No new request, wait again
+        return true;
+    }
+
+    auto onDeviceError = [&](auto... args) {
+        ALOGE(args...);
+        parent->notifyError(req->frameNumber, /*stream*/ -1, ErrorCode::ERROR_DEVICE);
+        signalRequestDone();
+        return false;
+    };
+
+    if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG && req->frameIn->mFourcc != V4L2_PIX_FMT_Z16) {
+        return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
+                             req->frameIn->mFourcc & 0xFF, (req->frameIn->mFourcc >> 8) & 0xFF,
+                             (req->frameIn->mFourcc >> 16) & 0xFF,
+                             (req->frameIn->mFourcc >> 24) & 0xFF);
+    }
+
+    int res = requestBufferStart(req->buffers);
+    if (res != 0) {
+        ALOGE("%s: send BufferRequest failed! res %d", __FUNCTION__, res);
+        return onDeviceError("%s: failed to send buffer request!", __FUNCTION__);
+    }
+
+    std::unique_lock<std::mutex> lk(mBufferLock);
+    // Convert input V4L2 frame to YU12 of the same size
+    // TODO: see if we can save some computation by converting to YV12 here
+    uint8_t* inData;
+    size_t inDataSize;
+    if (req->frameIn->getData(&inData, &inDataSize) != 0) {
+        lk.unlock();
+        return onDeviceError("%s: V4L2 buffer map failed", __FUNCTION__);
+    }
+
+    // Process camera mute state
+    auto testPatternMode = req->setting.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
+    if (testPatternMode.count == 1) {
+        if (mCameraMuted != (testPatternMode.data.u8[0] != ANDROID_SENSOR_TEST_PATTERN_MODE_OFF)) {
+            mCameraMuted = !mCameraMuted;
+            // Get solid color for test pattern, if any was set
+            if (testPatternMode.data.u8[0] == ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR) {
+                auto entry = req->setting.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
+                if (entry.count == 4) {
+                    // Update the mute frame if the pattern color has changed
+                    if (memcmp(entry.data.i32, mTestPatternData, sizeof(mTestPatternData)) != 0) {
+                        memcpy(mTestPatternData, entry.data.i32, sizeof(mTestPatternData));
+                        // Fill the mute frame with the solid color, use only 8 MSB of RGGB as RGB
+                        for (int i = 0; i < mMuteTestPatternFrame.size(); i += 3) {
+                            mMuteTestPatternFrame[i] = entry.data.i32[0] >> 24;
+                            mMuteTestPatternFrame[i + 1] = entry.data.i32[1] >> 24;
+                            mMuteTestPatternFrame[i + 2] = entry.data.i32[3] >> 24;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // TODO: in some special case maybe we can decode jpg directly to gralloc output?
+    if (req->frameIn->mFourcc == V4L2_PIX_FMT_MJPEG) {
+        ATRACE_BEGIN("MJPGtoI420");
+        res = 0;
+        if (mCameraMuted) {
+            res = libyuv::ConvertToI420(
+                    mMuteTestPatternFrame.data(), mMuteTestPatternFrame.size(),
+                    static_cast<uint8_t*>(mYu12FrameLayout.y), mYu12FrameLayout.yStride,
+                    static_cast<uint8_t*>(mYu12FrameLayout.cb), mYu12FrameLayout.cStride,
+                    static_cast<uint8_t*>(mYu12FrameLayout.cr), mYu12FrameLayout.cStride, 0, 0,
+                    mYu12Frame->mWidth, mYu12Frame->mHeight, mYu12Frame->mWidth,
+                    mYu12Frame->mHeight, libyuv::kRotate0, libyuv::FOURCC_RAW);
+        } else {
+            res = libyuv::MJPGToI420(
+                    inData, inDataSize, static_cast<uint8_t*>(mYu12FrameLayout.y),
+                    mYu12FrameLayout.yStride, static_cast<uint8_t*>(mYu12FrameLayout.cb),
+                    mYu12FrameLayout.cStride, static_cast<uint8_t*>(mYu12FrameLayout.cr),
+                    mYu12FrameLayout.cStride, mYu12Frame->mWidth, mYu12Frame->mHeight,
+                    mYu12Frame->mWidth, mYu12Frame->mHeight);
+        }
+        ATRACE_END();
+
+        if (res != 0) {
+            // For some webcam, the first few V4L2 frames might be malformed...
+            ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, res);
+            lk.unlock();
+            Status st = parent->processCaptureRequestError(req);
+            if (st != Status::OK) {
+                return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
+            }
+            signalRequestDone();
+            return true;
+        }
+    }
+
+    ATRACE_BEGIN("Wait for BufferRequest done");
+    res = waitForBufferRequestDone(&req->buffers);
+    ATRACE_END();
+
+    if (res != 0) {
+        ALOGE("%s: wait for BufferRequest done failed! res %d", __FUNCTION__, res);
+        lk.unlock();
+        return onDeviceError("%s: failed to process buffer request error!", __FUNCTION__);
+    }
+
+    ALOGV("%s processing new request", __FUNCTION__);
+    const int kSyncWaitTimeoutMs = 500;
+    for (auto& halBuf : req->buffers) {
+        if (*(halBuf.bufPtr) == nullptr) {
+            ALOGW("%s: buffer for stream %d missing", __FUNCTION__, halBuf.streamId);
+            halBuf.fenceTimeout = true;
+        } else if (halBuf.acquireFence >= 0) {
+            int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs);
+            if (ret) {
+                halBuf.fenceTimeout = true;
+            } else {
+                ::close(halBuf.acquireFence);
+                halBuf.acquireFence = -1;
+            }
+        }
+
+        if (halBuf.fenceTimeout) {
+            continue;
+        }
+
+        // Gralloc lockYCbCr the buffer
+        switch (halBuf.format) {
+            case PixelFormat::BLOB: {
+                int ret = createJpegLocked(halBuf, req->setting);
+
+                if (ret != 0) {
+                    lk.unlock();
+                    return onDeviceError("%s: createJpegLocked failed with %d", __FUNCTION__, ret);
+                }
+            } break;
+            case PixelFormat::Y16: {
+                void* outLayout = sHandleImporter.lock(
+                        *(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage), inDataSize);
+
+                std::memcpy(outLayout, inData, inDataSize);
+
+                int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+                if (relFence >= 0) {
+                    halBuf.acquireFence = relFence;
+                }
+            } break;
+            case PixelFormat::YCBCR_420_888:
+            case PixelFormat::YV12: {
+                IMapper::Rect outRect{0, 0, static_cast<int32_t>(halBuf.width),
+                                      static_cast<int32_t>(halBuf.height)};
+                YCbCrLayout outLayout = sHandleImporter.lockYCbCr(
+                        *(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage), outRect);
+                ALOGV("%s: outLayout y %p cb %p cr %p y_str %d c_str %d c_step %d", __FUNCTION__,
+                      outLayout.y, outLayout.cb, outLayout.cr, outLayout.yStride, outLayout.cStride,
+                      outLayout.chromaStep);
+
+                // Convert to output buffer size/format
+                uint32_t outputFourcc = getFourCcFromLayout(outLayout);
+                ALOGV("%s: converting to format %c%c%c%c", __FUNCTION__, outputFourcc & 0xFF,
+                      (outputFourcc >> 8) & 0xFF, (outputFourcc >> 16) & 0xFF,
+                      (outputFourcc >> 24) & 0xFF);
+
+                YCbCrLayout cropAndScaled;
+                ATRACE_BEGIN("cropAndScaleLocked");
+                int ret = cropAndScaleLocked(mYu12Frame, Size{halBuf.width, halBuf.height},
+                                             &cropAndScaled);
+                ATRACE_END();
+                if (ret != 0) {
+                    lk.unlock();
+                    return onDeviceError("%s: crop and scale failed!", __FUNCTION__);
+                }
+
+                Size sz{halBuf.width, halBuf.height};
+                ATRACE_BEGIN("formatConvert");
+                ret = formatConvert(cropAndScaled, outLayout, sz, outputFourcc);
+                ATRACE_END();
+                if (ret != 0) {
+                    lk.unlock();
+                    return onDeviceError("%s: format conversion failed!", __FUNCTION__);
+                }
+                int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+                if (relFence >= 0) {
+                    halBuf.acquireFence = relFence;
+                }
+            } break;
+            default:
+                lk.unlock();
+                return onDeviceError("%s: unknown output format %x", __FUNCTION__, halBuf.format);
+        }
+    }  // for each buffer
+    mScaledYu12Frames.clear();
+
+    // Don't hold the lock while calling back to parent
+    lk.unlock();
+    Status st = parent->processCaptureResult(req);
+    if (st != Status::OK) {
+        return onDeviceError("%s: failed to process capture result!", __FUNCTION__);
+    }
+    signalRequestDone();
+    return true;
+}
+
+// End ExternalCameraDeviceSession::OutputThread functions
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/device/default/ExternalCameraDeviceSession.h b/camera/device/default/ExternalCameraDeviceSession.h
new file mode 100644
index 0000000..e7eb799
--- /dev/null
+++ b/camera/device/default/ExternalCameraDeviceSession.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICESESSION_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICESESSION_H_
+
+#include <ExternalCameraUtils.h>
+#include <SimpleThread.h>
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/device/BnCameraDeviceSession.h>
+#include <aidl/android/hardware/camera/device/BufferRequest.h>
+#include <aidl/android/hardware/camera/device/Stream.h>
+#include <android-base/unique_fd.h>
+#include <fmq/AidlMessageQueue.h>
+#include <utils/Thread.h>
+#include <deque>
+#include <list>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::aidl::android::hardware::camera::device::BnCameraDeviceSession;
+using ::aidl::android::hardware::camera::device::BufferCache;
+using ::aidl::android::hardware::camera::device::BufferRequest;
+using ::aidl::android::hardware::camera::device::CameraMetadata;
+using ::aidl::android::hardware::camera::device::CameraOfflineSessionInfo;
+using ::aidl::android::hardware::camera::device::CaptureRequest;
+using ::aidl::android::hardware::camera::device::HalStream;
+using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
+using ::aidl::android::hardware::camera::device::ICameraOfflineSession;
+using ::aidl::android::hardware::camera::device::RequestTemplate;
+using ::aidl::android::hardware::camera::device::Stream;
+using ::aidl::android::hardware::camera::device::StreamConfiguration;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::base::unique_fd;
+using ::android::hardware::camera::common::helper::SimpleThread;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+using ::android::hardware::camera::external::common::SizeHasher;
+using ::ndk::ScopedAStatus;
+
+class ExternalCameraDeviceSession : public BnCameraDeviceSession, public OutputThreadInterface {
+  public:
+    ExternalCameraDeviceSession(const std::shared_ptr<ICameraDeviceCallback>&,
+                                const ExternalCameraConfig& cfg,
+                                const std::vector<SupportedV4L2Format>& sortedFormats,
+                                const CroppingType& croppingType,
+                                const common::V1_0::helper::CameraMetadata& chars,
+                                const std::string& cameraId, unique_fd v4l2Fd);
+    ~ExternalCameraDeviceSession() override;
+
+    // Caller must use this method to check if CameraDeviceSession ctor failed
+    bool isInitFailed();
+    bool isClosed();
+
+    ScopedAStatus close() override;
+
+    ScopedAStatus configureStreams(const StreamConfiguration& in_requestedConfiguration,
+                                   std::vector<HalStream>* _aidl_return) override;
+    ScopedAStatus constructDefaultRequestSettings(RequestTemplate in_type,
+                                                  CameraMetadata* _aidl_return) override;
+    ScopedAStatus flush() override;
+    ScopedAStatus getCaptureRequestMetadataQueue(
+            MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
+    ScopedAStatus getCaptureResultMetadataQueue(
+            MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
+    ScopedAStatus isReconfigurationRequired(const CameraMetadata& in_oldSessionParams,
+                                            const CameraMetadata& in_newSessionParams,
+                                            bool* _aidl_return) override;
+    ScopedAStatus processCaptureRequest(const std::vector<CaptureRequest>& in_requests,
+                                        const std::vector<BufferCache>& in_cachesToRemove,
+                                        int32_t* _aidl_return) override;
+    ScopedAStatus signalStreamFlush(const std::vector<int32_t>& in_streamIds,
+                                    int32_t in_streamConfigCounter) override;
+    ScopedAStatus switchToOffline(const std::vector<int32_t>& in_streamsToKeep,
+                                  CameraOfflineSessionInfo* out_offlineSessionInfo,
+                                  std::shared_ptr<ICameraOfflineSession>* _aidl_return) override;
+    ScopedAStatus repeatingRequestEnd(int32_t in_frameNumber,
+                                      const std::vector<int32_t>& in_streamIds) override;
+
+    Status importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
+                        buffer_handle_t** outBufPtr) override;
+
+    void notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) override;
+
+    Status processCaptureRequestError(const std::shared_ptr<HalRequest>& ptr,
+                                      std::vector<NotifyMsg>* msgs,
+                                      std::vector<CaptureResult>* results) override;
+
+    Status processCaptureResult(std::shared_ptr<HalRequest>& ptr) override;
+    ssize_t getJpegBufferSize(int32_t width, int32_t height) const override;
+
+    // Called by CameraDevice to dump active device states
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+    static Status isStreamCombinationSupported(
+            const StreamConfiguration& config,
+            const std::vector<SupportedV4L2Format>& supportedFormats,
+            const ExternalCameraConfig& devCfg);
+
+    static const int kMaxProcessedStream = 2;
+    static const int kMaxStallStream = 1;
+    static const uint32_t kMaxBytesPerPixel = 2;
+
+    class BufferRequestThread : public SimpleThread {
+      public:
+        BufferRequestThread(std::weak_ptr<OutputThreadInterface> parent,
+                            std::shared_ptr<ICameraDeviceCallback> callbacks);
+
+        int requestBufferStart(const std::vector<HalStreamBuffer>&);
+        int waitForBufferRequestDone(
+                /*out*/ std::vector<HalStreamBuffer>*);
+
+        bool threadLoop() override;
+
+      private:
+        void waitForNextRequest();
+
+        const std::weak_ptr<OutputThreadInterface> mParent;
+        const std::shared_ptr<ICameraDeviceCallback> mCallbacks;
+
+        std::mutex mLock;
+        bool mRequestingBuffer = false;
+
+        std::vector<HalStreamBuffer> mBufferReqs;
+        std::vector<HalStreamBuffer> mPendingReturnBufferReqs;
+        // mHalBufferReqs is not under mLock protection during the HIDL transaction
+        std::vector<BufferRequest> mHalBufferReqs;
+
+        // request buffers takes much less time in steady state, but can take much longer
+        // when requesting 1st buffer from a stream.
+        // TODO: consider a separate timeout for new vs. steady state?
+        // TODO: or make sure framework is warming up the pipeline during configure new stream?
+        static const int kReqProcTimeoutMs = 66;
+
+        static const int kReqWaitTimeoutMs = 33;
+        static const int kReqWaitTimesWarn = 90;   // 33ms * 90 ~= 3 sec
+        std::condition_variable mRequestCond;      // signaled when a new buffer request incoming
+        std::condition_variable mRequestDoneCond;  // signaled when a request is done
+    };
+
+    class OutputThread : public SimpleThread {
+      public:
+        OutputThread(std::weak_ptr<OutputThreadInterface> parent, CroppingType,
+                     const common::V1_0::helper::CameraMetadata&,
+                     std::shared_ptr<BufferRequestThread> bufReqThread);
+        ~OutputThread();
+
+        Status allocateIntermediateBuffers(const Size& v4lSize, const Size& thumbSize,
+                                           const std::vector<Stream>& streams,
+                                           uint32_t blobBufferSize);
+        Status submitRequest(const std::shared_ptr<HalRequest>&);
+        void flush();
+        void dump(int fd);
+        bool threadLoop() override;
+
+        void setExifMakeModel(const std::string& make, const std::string& model);
+
+        // The remaining request list is returned for offline processing
+        std::list<std::shared_ptr<HalRequest>> switchToOffline();
+
+      protected:
+        static const int kFlushWaitTimeoutSec = 3;  // 3 sec
+        static const int kReqWaitTimeoutMs = 33;    // 33ms
+        static const int kReqWaitTimesMax = 90;     // 33ms * 90 ~= 3 sec
+
+        // Methods to request output buffer in parallel
+        int requestBufferStart(const std::vector<HalStreamBuffer>&);
+        int waitForBufferRequestDone(
+                /*out*/ std::vector<HalStreamBuffer>*);
+
+        void waitForNextRequest(std::shared_ptr<HalRequest>* out);
+        void signalRequestDone();
+
+        int cropAndScaleLocked(std::shared_ptr<AllocatedFrame>& in, const Size& outSize,
+                               YCbCrLayout* out);
+
+        int cropAndScaleThumbLocked(std::shared_ptr<AllocatedFrame>& in, const Size& outSize,
+                                    YCbCrLayout* out);
+
+        int createJpegLocked(HalStreamBuffer& halBuf,
+                             const common::V1_0::helper::CameraMetadata& settings);
+
+        void clearIntermediateBuffers();
+
+        const std::weak_ptr<OutputThreadInterface> mParent;
+        const CroppingType mCroppingType;
+        const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
+
+        mutable std::mutex mRequestListLock;       // Protect access to mRequestList,
+                                                   // mProcessingRequest and mProcessingFrameNumber
+        std::condition_variable mRequestCond;      // signaled when a new request is submitted
+        std::condition_variable mRequestDoneCond;  // signaled when a request is done processing
+        std::list<std::shared_ptr<HalRequest>> mRequestList;
+        bool mProcessingRequest = false;
+        uint32_t mProcessingFrameNumber = 0;
+
+        // V4L2 frameIn
+        // (MJPG decode)-> mYu12Frame
+        // (Scale)-> mScaledYu12Frames
+        // (Format convert) -> output gralloc frames
+        mutable std::mutex mBufferLock;  // Protect access to intermediate buffers
+        std::shared_ptr<AllocatedFrame> mYu12Frame;
+        std::shared_ptr<AllocatedFrame> mYu12ThumbFrame;
+        std::unordered_map<Size, std::shared_ptr<AllocatedFrame>, SizeHasher> mIntermediateBuffers;
+        std::unordered_map<Size, std::shared_ptr<AllocatedFrame>, SizeHasher> mScaledYu12Frames;
+        YCbCrLayout mYu12FrameLayout;
+        YCbCrLayout mYu12ThumbFrameLayout;
+        std::vector<uint8_t> mMuteTestPatternFrame;
+        uint32_t mTestPatternData[4] = {0, 0, 0, 0};
+        bool mCameraMuted = false;
+        uint32_t mBlobBufferSize = 0;  // 0 -> HAL derive buffer size, else: use given size
+
+        std::string mExifMake;
+        std::string mExifModel;
+
+        const std::shared_ptr<BufferRequestThread> mBufferRequestThread;
+    };
+
+  private:
+    bool initialize();
+    // To init/close different version of output thread
+    void initOutputThread();
+    void closeOutputThread();
+    void closeOutputThreadImpl();
+
+    void close(bool callerIsDtor);
+    Status initStatus() const;
+    status_t initDefaultRequests();
+
+    status_t fillCaptureResult(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp);
+    int configureV4l2StreamLocked(const SupportedV4L2Format& fmt, double fps = 0.0);
+    int v4l2StreamOffLocked();
+
+    int setV4l2FpsLocked(double fps);
+
+    std::unique_ptr<V4L2Frame> dequeueV4l2FrameLocked(
+            /*out*/ nsecs_t* shutterTs);  // Called with mLock held
+
+    void enqueueV4l2Frame(const std::shared_ptr<V4L2Frame>&);
+
+    // Check if input Stream is one of supported stream setting on this device
+    static bool isSupported(const Stream& stream,
+                            const std::vector<SupportedV4L2Format>& supportedFormats,
+                            const ExternalCameraConfig& cfg);
+
+    // Validate and import request's output buffers and acquire fence
+    Status importRequestLocked(const CaptureRequest& request,
+                               std::vector<buffer_handle_t*>& allBufPtrs,
+                               std::vector<int>& allFences);
+
+    Status importRequestLockedImpl(const CaptureRequest& request,
+                                   std::vector<buffer_handle_t*>& allBufPtrs,
+                                   std::vector<int>& allFences);
+
+    Status importBufferLocked(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
+                              /*out*/ buffer_handle_t** outBufPtr);
+    static void cleanupInflightFences(std::vector<int>& allFences, size_t numFences);
+    void cleanupBuffersLocked(int id);
+
+    void updateBufferCaches(const std::vector<BufferCache>& cachesToRemove);
+
+    Status processOneCaptureRequest(const CaptureRequest& request);
+    void notifyShutter(int32_t frameNumber, nsecs_t shutterTs);
+
+    void invokeProcessCaptureResultCallback(std::vector<CaptureResult>& results, bool tryWriteFmq);
+    Size getMaxJpegResolution() const;
+
+    Size getMaxThumbResolution() const;
+
+    int waitForV4L2BufferReturnLocked(std::unique_lock<std::mutex>& lk);
+
+    // Main body of switchToOffline. This method does not invoke any callbacks
+    // but instead returns the necessary callbacks in output arguments so callers
+    // can callback later without holding any locks
+    Status switchToOffline(const std::vector<int32_t>& offlineStreams,
+                           /*out*/ std::vector<NotifyMsg>* msgs,
+                           /*out*/ std::vector<CaptureResult>* results,
+                           /*out*/ CameraOfflineSessionInfo* info,
+                           /*out*/ std::shared_ptr<ICameraOfflineSession>* session);
+
+    bool supportOfflineLocked(int32_t streamId);
+
+    // Whether a request can be completely dropped when switching to offline
+    bool canDropRequest(const std::vector<int32_t>& offlineStreams,
+                        std::shared_ptr<HalRequest> halReq);
+
+    void fillOfflineSessionInfo(const std::vector<int32_t>& offlineStreams,
+                                std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
+                                const std::map<int, CirculatingBuffers>& circulatingBuffers,
+                                /*out*/ CameraOfflineSessionInfo* info);
+
+    // Protect (most of) HIDL interface methods from synchronized-entering
+    mutable Mutex mInterfaceLock;
+
+    mutable Mutex mLock;  // Protect all private members except otherwise noted
+    const std::shared_ptr<ICameraDeviceCallback> mCallback;
+    const ExternalCameraConfig& mCfg;
+    const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
+    const std::vector<SupportedV4L2Format> mSupportedFormats;
+    const CroppingType mCroppingType;
+    const std::string mCameraId;
+
+    // Not protected by mLock, this is almost a const.
+    // Setup in constructor, reset in close() after OutputThread is joined
+    unique_fd mV4l2Fd;
+
+    // device is closed either
+    //    - closed by user
+    //    - init failed
+    //    - camera disconnected
+    bool mClosed = false;
+    bool mInitialized = false;
+    bool mInitFail = false;
+    bool mFirstRequest = false;
+    common::V1_0::helper::CameraMetadata mLatestReqSetting;
+
+    bool mV4l2Streaming = false;
+    SupportedV4L2Format mV4l2StreamingFmt;
+    double mV4l2StreamingFps = 0.0;
+    size_t mV4L2BufferCount = 0;
+
+    static const int kBufferWaitTimeoutSec = 3;  // TODO: handle long exposure (or not allowing)
+    std::mutex mV4l2BufferLock;                  // protect the buffer count and condition below
+    std::condition_variable mV4L2BufferReturned;
+    size_t mNumDequeuedV4l2Buffers = 0;
+    uint32_t mMaxV4L2BufferSize = 0;
+
+    // Not protected by mLock (but might be used when mLock is locked)
+    std::shared_ptr<OutputThread> mOutputThread;
+
+    // Stream ID -> Stream cache
+    std::unordered_map<int, Stream> mStreamMap;
+
+    std::mutex mInflightFramesLock;  // protect mInflightFrames
+    std::unordered_set<uint32_t> mInflightFrames;
+
+    // Stream ID -> circulating buffers map
+    std::map<int, CirculatingBuffers> mCirculatingBuffers;
+    // Protect mCirculatingBuffers, must not lock mLock after acquiring this lock
+    mutable Mutex mCbsLock;
+
+    std::mutex mAfTriggerLock;  // protect mAfTrigger
+    bool mAfTrigger = false;
+
+    uint32_t mBlobBufferSize = 0;
+
+    static HandleImporter sHandleImporter;
+
+    std::shared_ptr<BufferRequestThread> mBufferRequestThread;
+
+    /* Beginning of members not changed after initialize() */
+    using RequestMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+    std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
+    using ResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+    std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
+
+    // Protect against invokeProcessCaptureResultCallback()
+    Mutex mProcessCaptureResultLock;
+
+    // tracks last seen stream config counter
+    int32_t mLastStreamConfigCounter = -1;
+
+    std::unordered_map<RequestTemplate, CameraMetadata> mDefaultRequests;
+
+    const Size mMaxThumbResolution;
+    const Size mMaxJpegResolution;
+
+    std::string mExifMake;
+    std::string mExifModel;
+    /* End of members not changed after initialize() */
+};
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICESESSION_H_
diff --git a/camera/device/default/ExternalCameraOfflineSession.cpp b/camera/device/default/ExternalCameraOfflineSession.cpp
new file mode 100644
index 0000000..4c7f732
--- /dev/null
+++ b/camera/device/default/ExternalCameraOfflineSession.cpp
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamOfflnSsn"
+#include <android/log.h>
+
+#include "ExternalCameraOfflineSession.h"
+
+#include <aidl/android/hardware/camera/device/BufferStatus.h>
+#include <aidl/android/hardware/camera/device/ErrorMsg.h>
+#include <aidl/android/hardware/camera/device/ShutterMsg.h>
+#include <aidl/android/hardware/camera/device/StreamBuffer.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <convert.h>
+#include <linux/videodev2.h>
+#include <sync/sync.h>
+#include <utils/Trace.h>
+
+#define HAVE_JPEG  // required for libyuv.h to export MJPEG decode APIs
+#include <libyuv.h>
+
+namespace {
+
+// Size of request/result metadata fast message queue. Change to 0 to always use hwbinder buffer.
+constexpr size_t kMetadataMsgQueueSize = 1 << 18 /* 256kB */;
+
+}  // anonymous namespace
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::device::BufferStatus;
+using ::aidl::android::hardware::camera::device::ErrorMsg;
+using ::aidl::android::hardware::camera::device::ShutterMsg;
+using ::aidl::android::hardware::camera::device::StreamBuffer;
+
+// Static instance
+HandleImporter ExternalCameraOfflineSession::sHandleImporter;
+
+ExternalCameraOfflineSession::ExternalCameraOfflineSession(
+        const CroppingType& croppingType, const common::V1_0::helper::CameraMetadata& chars,
+        const std::string& cameraId, const std::string& exifMake, const std::string& exifModel,
+        uint32_t blobBufferSize, bool afTrigger, const std::vector<Stream>& offlineStreams,
+        std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
+        const std::map<int, CirculatingBuffers>& circulatingBuffers)
+    : mCroppingType(croppingType),
+      mChars(chars),
+      mCameraId(cameraId),
+      mExifMake(exifMake),
+      mExifModel(exifModel),
+      mBlobBufferSize(blobBufferSize),
+      mAfTrigger(afTrigger),
+      mOfflineStreams(offlineStreams),
+      mOfflineReqs(offlineReqs),
+      mCirculatingBuffers(circulatingBuffers) {}
+
+ExternalCameraOfflineSession::~ExternalCameraOfflineSession() {
+    close();
+}
+
+bool ExternalCameraOfflineSession::initialize() {
+    mResultMetadataQueue =
+            std::make_shared<ResultMetadataQueue>(kMetadataMsgQueueSize, false /* non blocking */);
+    if (!mResultMetadataQueue->isValid()) {
+        ALOGE("%s: invalid result fmq", __FUNCTION__);
+        return true;
+    }
+    return false;
+}
+
+Status ExternalCameraOfflineSession::importBuffer(int32_t streamId, uint64_t bufId,
+                                                  buffer_handle_t buf,
+                                                  buffer_handle_t** outBufPtr) {
+    Mutex::Autolock _l(mCbsLock);
+    return importBufferImpl(mCirculatingBuffers, sHandleImporter, streamId, bufId, buf, outBufPtr);
+}
+
+Status ExternalCameraOfflineSession::processCaptureResult(std::shared_ptr<HalRequest>& req) {
+    ATRACE_CALL();
+    // Fill output buffers
+    std::vector<CaptureResult> results;
+    results.resize(1);
+    CaptureResult& result = results[0];
+    result.frameNumber = req->frameNumber;
+    result.partialResult = 1;
+    result.inputBuffer.streamId = -1;
+    result.outputBuffers.resize(req->buffers.size());
+    for (size_t i = 0; i < req->buffers.size(); i++) {
+        StreamBuffer& outputBuffer = result.outputBuffers[i];
+        outputBuffer.streamId = req->buffers[i].streamId;
+        outputBuffer.bufferId = req->buffers[i].bufferId;
+        if (req->buffers[i].fenceTimeout) {
+            outputBuffer.status = BufferStatus::ERROR;
+            if (req->buffers[i].acquireFence >= 0) {
+                native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                handle->data[0] = req->buffers[i].acquireFence;
+                result.outputBuffers[i].releaseFence = android::makeToAidl(handle);
+            }
+            notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
+        } else {
+            result.outputBuffers[i].status = BufferStatus::OK;
+            // TODO: refactor
+            if (req->buffers[i].acquireFence >= 0) {
+                native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+                handle->data[0] = req->buffers[i].acquireFence;
+                outputBuffer.releaseFence = android::makeToAidl(handle);
+            }
+        }
+    }
+
+    // Fill capture result metadata
+    fillCaptureResult(req->setting, req->shutterTs);
+    const camera_metadata_t* rawResult = req->setting.getAndLock();
+    convertToAidl(rawResult, &result.result);
+    req->setting.unlock(rawResult);
+
+    // Callback into framework
+    invokeProcessCaptureResultCallback(results, /* tryWriteFmq */ true);
+    freeReleaseFences(results);
+    return Status::OK;
+}
+
+#define UPDATE(md, tag, data, size)               \
+    do {                                          \
+        if ((md).update((tag), (data), (size))) { \
+            ALOGE("Update " #tag " failed!");     \
+            return BAD_VALUE;                     \
+        }                                         \
+    } while (0)
+
+status_t ExternalCameraOfflineSession::fillCaptureResult(common::V1_0::helper::CameraMetadata md,
+                                                         nsecs_t timestamp) {
+    bool afTrigger = false;
+    {
+        std::lock_guard<std::mutex> lk(mAfTriggerLock);
+        afTrigger = mAfTrigger;
+        if (md.exists(ANDROID_CONTROL_AF_TRIGGER)) {
+            camera_metadata_entry entry = md.find(ANDROID_CONTROL_AF_TRIGGER);
+            if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_START) {
+                mAfTrigger = afTrigger = true;
+            } else if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_CANCEL) {
+                mAfTrigger = afTrigger = false;
+            }
+        }
+    }
+
+    // For USB camera, the USB camera handles everything and we don't have control
+    // over AF. We only simply fake the AF metadata based on the request
+    // received here.
+    uint8_t afState;
+    if (afTrigger) {
+        afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+    } else {
+        afState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+    }
+    UPDATE(md, ANDROID_CONTROL_AF_STATE, &afState, 1);
+
+    camera_metadata_ro_entry activeArraySize = mChars.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+
+    return fillCaptureResultCommon(md, timestamp, activeArraySize);
+}
+void ExternalCameraOfflineSession::invokeProcessCaptureResultCallback(
+        std::vector<CaptureResult>& results, bool tryWriteFmq) {
+    if (mProcessCaptureResultLock.tryLock() != OK) {
+        const nsecs_t NS_TO_SECOND = 1E9;
+        ALOGV("%s: previous call is not finished! waiting 1s...", __FUNCTION__);
+        if (mProcessCaptureResultLock.timedLock(/* 1s */ NS_TO_SECOND) != OK) {
+            ALOGE("%s: cannot acquire lock in 1s, cannot proceed", __FUNCTION__);
+            return;
+        }
+    }
+    if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
+        for (CaptureResult& result : results) {
+            if (!result.result.metadata.empty()) {
+                if (mResultMetadataQueue->write(
+                            reinterpret_cast<int8_t*>(result.result.metadata.data()),
+                            result.result.metadata.size())) {
+                    result.fmqResultSize = result.result.metadata.size();
+                    result.result.metadata.clear();
+                } else {
+                    ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
+                    result.fmqResultSize = 0;
+                }
+            } else {
+                result.fmqResultSize = 0;
+            }
+        }
+    }
+    auto status = mCallback->processCaptureResult(results);
+    if (!status.isOk()) {
+        ALOGE("%s: processCaptureResult ERROR : %d:%d", __FUNCTION__, status.getExceptionCode(),
+              status.getServiceSpecificError());
+    }
+
+    mProcessCaptureResultLock.unlock();
+}
+
+Status ExternalCameraOfflineSession::processCaptureRequestError(
+        const std::shared_ptr<HalRequest>& req, std::vector<NotifyMsg>* outMsgs,
+        std::vector<CaptureResult>* outResults) {
+    ATRACE_CALL();
+
+    if (outMsgs == nullptr) {
+        notifyError(/*frameNum*/ req->frameNumber, /*stream*/ -1, ErrorCode::ERROR_REQUEST);
+    } else {
+        NotifyMsg shutter;
+        shutter.set<NotifyMsg::Tag::shutter>(ShutterMsg{
+                .frameNumber = req->frameNumber,
+                .timestamp = req->shutterTs,
+        });
+
+        NotifyMsg error;
+        error.set<NotifyMsg::Tag::error>(ErrorMsg{.frameNumber = req->frameNumber,
+                                                  .errorStreamId = -1,
+                                                  .errorCode = ErrorCode::ERROR_REQUEST});
+        outMsgs->push_back(shutter);
+        outMsgs->push_back(error);
+    }
+
+    // Fill output buffers
+    CaptureResult result;
+    result.frameNumber = req->frameNumber;
+    result.partialResult = 1;
+    result.inputBuffer.streamId = -1;
+    result.outputBuffers.resize(req->buffers.size());
+    for (size_t i = 0; i < req->buffers.size(); i++) {
+        StreamBuffer& outputBuffer = result.outputBuffers[i];
+        outputBuffer.streamId = req->buffers[i].streamId;
+        outputBuffer.bufferId = req->buffers[i].bufferId;
+        outputBuffer.status = BufferStatus::ERROR;
+        if (req->buffers[i].acquireFence >= 0) {
+            native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+            handle->data[0] = req->buffers[i].acquireFence;
+            outputBuffer.releaseFence = makeToAidl(handle);
+        }
+    }
+
+    if (outResults == nullptr) {
+        // Callback into framework
+        std::vector<CaptureResult> results(1);
+        results[0] = std::move(result);
+        invokeProcessCaptureResultCallback(results, /* tryWriteFmq */ true);
+        freeReleaseFences(results);
+    } else {
+        outResults->push_back(std::move(result));
+    }
+    return Status::OK;
+}
+
+ssize_t ExternalCameraOfflineSession::getJpegBufferSize(int32_t, int32_t) const {
+    // Empty implementation here as the jpeg buffer size is passed in by ctor
+    return 0;
+}
+
+void ExternalCameraOfflineSession::notifyError(int32_t frameNumber, int32_t streamId,
+                                               ErrorCode ec) {
+    NotifyMsg msg;
+    msg.set<NotifyMsg::Tag::error>(
+            ErrorMsg{.frameNumber = frameNumber, .errorStreamId = streamId, .errorCode = ec});
+    mCallback->notify({msg});
+}
+
+ScopedAStatus ExternalCameraOfflineSession::setCallback(
+        const std::shared_ptr<ICameraDeviceCallback>& in_cb) {
+    Mutex::Autolock _il(mInterfaceLock);
+    if (mCallback != nullptr && in_cb != nullptr) {
+        ALOGE("%s: callback must not be set twice!", __FUNCTION__);
+        return fromStatus(Status::OK);
+    }
+    mCallback = in_cb;
+
+    initOutputThread();
+
+    if (mOutputThread == nullptr) {
+        ALOGE("%s: init OutputThread failed!", __FUNCTION__);
+    }
+    return fromStatus(Status::OK);
+}
+void ExternalCameraOfflineSession::initOutputThread() {
+    if (mOutputThread != nullptr) {
+        ALOGE("%s: OutputThread already exist!", __FUNCTION__);
+        return;
+    }
+
+    // Grab a shared_ptr to 'this' from ndk::SharedRefBase::ref()
+    std::shared_ptr<ExternalCameraOfflineSession> thiz = ref<ExternalCameraOfflineSession>();
+
+    mBufferRequestThread = std::make_shared<ExternalCameraDeviceSession::BufferRequestThread>(
+            /*parent=*/thiz, mCallback);
+    mBufferRequestThread->run();
+
+    mOutputThread = std::make_shared<OutputThread>(/*parent=*/thiz, mCroppingType, mChars,
+                                                   mBufferRequestThread, mOfflineReqs);
+
+    mOutputThread->setExifMakeModel(mExifMake, mExifModel);
+
+    Size inputSize = {mOfflineReqs[0]->frameIn->mWidth, mOfflineReqs[0]->frameIn->mHeight};
+    Size maxThumbSize = getMaxThumbnailResolution(mChars);
+    mOutputThread->allocateIntermediateBuffers(inputSize, maxThumbSize, mOfflineStreams,
+                                               mBlobBufferSize);
+
+    mOutputThread->run();
+}
+
+ScopedAStatus ExternalCameraOfflineSession::getCaptureResultMetadataQueue(
+        MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
+    Mutex::Autolock _il(mInterfaceLock);
+    *_aidl_return = mResultMetadataQueue->dupeDesc();
+    return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraOfflineSession::close() {
+    Mutex::Autolock _il(mInterfaceLock);
+    {
+        Mutex::Autolock _l(mLock);
+        if (mClosed) {
+            ALOGW("%s: offline session already closed!", __FUNCTION__);
+            return fromStatus(Status::OK);
+        }
+    }
+    if (mBufferRequestThread != nullptr) {
+        mBufferRequestThread->requestExitAndWait();
+        mBufferRequestThread.reset();
+    }
+    if (mOutputThread) {
+        mOutputThread->flush();
+        mOutputThread->requestExitAndWait();
+        mOutputThread.reset();
+    }
+
+    Mutex::Autolock _l(mLock);
+    // free all buffers
+    {
+        Mutex::Autolock _cbl(mCbsLock);
+        for (auto& stream : mOfflineStreams) {
+            cleanupBuffersLocked(stream.id);
+        }
+    }
+    mCallback.reset();
+    mClosed = true;
+    return fromStatus(Status::OK);
+}
+void ExternalCameraOfflineSession::cleanupBuffersLocked(int32_t id) {
+    for (auto& pair : mCirculatingBuffers.at(id)) {
+        sHandleImporter.freeBuffer(pair.second);
+    }
+    mCirculatingBuffers[id].clear();
+    mCirculatingBuffers.erase(id);
+}
+
+bool ExternalCameraOfflineSession::OutputThread::threadLoop() {
+    auto parent = mParent.lock();
+    if (parent == nullptr) {
+        ALOGE("%s: session has been disconnected!", __FUNCTION__);
+        return false;
+    }
+
+    if (mOfflineReqs.empty()) {
+        ALOGI("%s: all offline requests are processed. Stopping.", __FUNCTION__);
+        return false;
+    }
+
+    std::shared_ptr<HalRequest> req = mOfflineReqs.front();
+    mOfflineReqs.pop_front();
+
+    auto onDeviceError = [&](auto... args) {
+        ALOGE(args...);
+        parent->notifyError(req->frameNumber, /*stream*/ -1, ErrorCode::ERROR_DEVICE);
+        signalRequestDone();
+        return false;
+    };
+
+    if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG && req->frameIn->mFourcc != V4L2_PIX_FMT_Z16) {
+        return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
+                             req->frameIn->mFourcc & 0xFF, (req->frameIn->mFourcc >> 8) & 0xFF,
+                             (req->frameIn->mFourcc >> 16) & 0xFF,
+                             (req->frameIn->mFourcc >> 24) & 0xFF);
+    }
+
+    int res = requestBufferStart(req->buffers);
+    if (res != 0) {
+        ALOGE("%s: send BufferRequest failed! res %d", __FUNCTION__, res);
+        return onDeviceError("%s: failed to send buffer request!", __FUNCTION__);
+    }
+
+    std::unique_lock<std::mutex> lk(mBufferLock);
+    // Convert input V4L2 frame to YU12 of the same size
+    // TODO: see if we can save some computation by converting to YV12 here
+    uint8_t* inData;
+    size_t inDataSize;
+    if (req->frameIn->getData(&inData, &inDataSize) != 0) {
+        lk.unlock();
+        return onDeviceError("%s: V4L2 buffer map failed", __FUNCTION__);
+    }
+
+    // TODO: in some special case maybe we can decode jpg directly to gralloc output?
+    if (req->frameIn->mFourcc == V4L2_PIX_FMT_MJPEG) {
+        ATRACE_BEGIN("MJPGtoI420");
+        int convRes = libyuv::MJPGToI420(
+                inData, inDataSize, static_cast<uint8_t*>(mYu12FrameLayout.y),
+                mYu12FrameLayout.yStride, static_cast<uint8_t*>(mYu12FrameLayout.cb),
+                mYu12FrameLayout.cStride, static_cast<uint8_t*>(mYu12FrameLayout.cr),
+                mYu12FrameLayout.cStride, mYu12Frame->mWidth, mYu12Frame->mHeight,
+                mYu12Frame->mWidth, mYu12Frame->mHeight);
+        ATRACE_END();
+
+        if (convRes != 0) {
+            // For some webcam, the first few V4L2 frames might be malformed...
+            ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, convRes);
+            lk.unlock();
+            Status st = parent->processCaptureRequestError(req);
+            if (st != Status::OK) {
+                return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
+            }
+            signalRequestDone();
+            return true;
+        }
+    }
+
+    ATRACE_BEGIN("Wait for BufferRequest done");
+    res = waitForBufferRequestDone(&req->buffers);
+    ATRACE_END();
+
+    if (res != 0) {
+        ALOGE("%s: wait for BufferRequest done failed! res %d", __FUNCTION__, res);
+        lk.unlock();
+        return onDeviceError("%s: failed to process buffer request error!", __FUNCTION__);
+    }
+
+    ALOGV("%s processing new request", __FUNCTION__);
+    const int kSyncWaitTimeoutMs = 500;
+    for (auto& halBuf : req->buffers) {
+        if (*(halBuf.bufPtr) == nullptr) {
+            ALOGW("%s: buffer for stream %d missing", __FUNCTION__, halBuf.streamId);
+            halBuf.fenceTimeout = true;
+        } else if (halBuf.acquireFence >= 0) {
+            int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs);
+            if (ret) {
+                halBuf.fenceTimeout = true;
+            } else {
+                ::close(halBuf.acquireFence);
+                halBuf.acquireFence = -1;
+            }
+        }
+
+        if (halBuf.fenceTimeout) {
+            continue;
+        }
+
+        // Gralloc lockYCbCr the buffer
+        switch (halBuf.format) {
+            case PixelFormat::BLOB: {
+                int ret = createJpegLocked(halBuf, req->setting);
+
+                if (ret != 0) {
+                    lk.unlock();
+                    return onDeviceError("%s: createJpegLocked failed with %d", __FUNCTION__, ret);
+                }
+            } break;
+            case PixelFormat::Y16: {
+                void* outLayout = sHandleImporter.lock(
+                        *(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage), inDataSize);
+
+                std::memcpy(outLayout, inData, inDataSize);
+
+                int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+                if (relFence >= 0) {
+                    halBuf.acquireFence = relFence;
+                }
+            } break;
+            case PixelFormat::YCBCR_420_888:
+            case PixelFormat::YV12: {
+                IMapper::Rect outRect{0, 0, static_cast<int32_t>(halBuf.width),
+                                      static_cast<int32_t>(halBuf.height)};
+                YCbCrLayout outLayout = sHandleImporter.lockYCbCr(
+                        *(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage), outRect);
+                ALOGV("%s: outLayout y %p cb %p cr %p y_str %d c_str %d c_step %d", __FUNCTION__,
+                      outLayout.y, outLayout.cb, outLayout.cr, outLayout.yStride, outLayout.cStride,
+                      outLayout.chromaStep);
+
+                // Convert to output buffer size/format
+                uint32_t outputFourcc = getFourCcFromLayout(outLayout);
+                ALOGV("%s: converting to format %c%c%c%c", __FUNCTION__, outputFourcc & 0xFF,
+                      (outputFourcc >> 8) & 0xFF, (outputFourcc >> 16) & 0xFF,
+                      (outputFourcc >> 24) & 0xFF);
+
+                YCbCrLayout cropAndScaled;
+                ATRACE_BEGIN("cropAndScaleLocked");
+                int ret = cropAndScaleLocked(mYu12Frame, Size{halBuf.width, halBuf.height},
+                                             &cropAndScaled);
+                ATRACE_END();
+                if (ret != 0) {
+                    lk.unlock();
+                    return onDeviceError("%s: crop and scale failed!", __FUNCTION__);
+                }
+
+                Size sz{halBuf.width, halBuf.height};
+                ATRACE_BEGIN("formatConvert");
+                ret = formatConvert(cropAndScaled, outLayout, sz, outputFourcc);
+                ATRACE_END();
+                if (ret != 0) {
+                    lk.unlock();
+                    return onDeviceError("%s: format coversion failed!", __FUNCTION__);
+                }
+                int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+                if (relFence >= 0) {
+                    halBuf.acquireFence = relFence;
+                }
+            } break;
+            default:
+                lk.unlock();
+                return onDeviceError("%s: unknown output format %x", __FUNCTION__, halBuf.format);
+        }
+    }  // for each buffer
+    mScaledYu12Frames.clear();
+
+    // Don't hold the lock while calling back to parent
+    lk.unlock();
+    Status st = parent->processCaptureResult(req);
+    if (st != Status::OK) {
+        return onDeviceError("%s: failed to process capture result!", __FUNCTION__);
+    }
+    signalRequestDone();
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/camera/device/default/ExternalCameraOfflineSession.h b/camera/device/default/ExternalCameraOfflineSession.h
new file mode 100644
index 0000000..1d0c057
--- /dev/null
+++ b/camera/device/default/ExternalCameraOfflineSession.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAOFFLINESESSION_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAOFFLINESESSION_H_
+
+#include <ExternalCameraDeviceSession.h>
+#include <ExternalCameraUtils.h>
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/device/BnCameraOfflineSession.h>
+#include <aidl/android/hardware/camera/device/Stream.h>
+#include <fmq/AidlMessageQueue.h>
+#include <utils/RefBase.h>
+#include <deque>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::aidl::android::hardware::camera::device::BnCameraOfflineSession;
+using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
+using ::aidl::android::hardware::camera::device::Stream;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+
+class ExternalCameraOfflineSession final : public BnCameraOfflineSession,
+                                           public virtual RefBase,
+                                           public virtual OutputThreadInterface {
+  public:
+    ExternalCameraOfflineSession(const CroppingType& croppingType,
+                                 const common::V1_0::helper::CameraMetadata& chars,
+                                 const std::string& cameraId, const std::string& exifMake,
+                                 const std::string& exifModel, uint32_t blobBufferSize,
+                                 bool afTrigger, const std::vector<Stream>& offlineStreams,
+                                 std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
+                                 const std::map<int, CirculatingBuffers>& circulatingBuffers);
+
+    ~ExternalCameraOfflineSession() override;
+
+    bool initialize();
+
+    // Methods from OutputThreadInterface
+    Status importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
+                        /*out*/ buffer_handle_t** outBufPtr) override;
+
+    Status processCaptureResult(std::shared_ptr<HalRequest>&) override;
+
+    Status processCaptureRequestError(const std::shared_ptr<HalRequest>&,
+                                      /*out*/ std::vector<NotifyMsg>* msgs,
+                                      /*out*/ std::vector<CaptureResult>* results) override;
+
+    ssize_t getJpegBufferSize(int32_t width, int32_t height) const override;
+
+    void notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) override;
+    // End of OutputThreadInterface methods
+
+    ScopedAStatus setCallback(const std::shared_ptr<ICameraDeviceCallback>& in_cb) override;
+    ScopedAStatus getCaptureResultMetadataQueue(
+            MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
+    ScopedAStatus close() override;
+
+  private:
+    class OutputThread : public ExternalCameraDeviceSession::OutputThread {
+      public:
+        OutputThread(std::weak_ptr<OutputThreadInterface> parent, CroppingType ct,
+                     const common::V1_0::helper::CameraMetadata& chars,
+                     std::shared_ptr<ExternalCameraDeviceSession::BufferRequestThread> bufReqThread,
+                     std::deque<std::shared_ptr<HalRequest>>& offlineReqs)
+            : ExternalCameraDeviceSession::OutputThread(std::move(parent), ct, chars,
+                                                        std::move(bufReqThread)),
+              mOfflineReqs(offlineReqs) {}
+
+        bool threadLoop() override;
+
+      protected:
+        std::deque<std::shared_ptr<HalRequest>> mOfflineReqs;
+    };  // OutputThread
+
+    status_t fillCaptureResult(common::V1_0::helper::CameraMetadata md, nsecs_t timestamp);
+    void invokeProcessCaptureResultCallback(std::vector<CaptureResult>& results, bool tryWriteFmq);
+    void initOutputThread();
+    void cleanupBuffersLocked(int32_t id);
+
+    // Protect (most of) HIDL interface methods from synchronized-entering
+    mutable Mutex mInterfaceLock;
+
+    mutable Mutex mLock;  // Protect all data members except otherwise noted
+
+    bool mClosed = false;
+    const CroppingType mCroppingType;
+    const common::V1_0::helper::CameraMetadata mChars;
+    const std::string mCameraId;
+    const std::string mExifMake;
+    const std::string mExifModel;
+    const uint32_t mBlobBufferSize;
+
+    std::mutex mAfTriggerLock;  // protect mAfTrigger
+    bool mAfTrigger;
+
+    const std::vector<Stream> mOfflineStreams;
+    std::deque<std::shared_ptr<HalRequest>> mOfflineReqs;
+
+    // Protect mCirculatingBuffers, must not lock mLock after acquiring this lock
+    mutable Mutex mCbsLock;
+    std::map<int, CirculatingBuffers> mCirculatingBuffers;
+
+    static HandleImporter sHandleImporter;
+
+    using ResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+    std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
+
+    // Protect against invokeProcessCaptureResultCallback()
+    Mutex mProcessCaptureResultLock;
+
+    std::shared_ptr<ICameraDeviceCallback> mCallback;
+
+    std::shared_ptr<ExternalCameraDeviceSession::BufferRequestThread> mBufferRequestThread;
+    std::shared_ptr<OutputThread> mOutputThread;
+};
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAOFFLINESESSION_H_
diff --git a/camera/device/default/ExternalCameraUtils.cpp b/camera/device/default/ExternalCameraUtils.cpp
new file mode 100644
index 0000000..cfb95f2
--- /dev/null
+++ b/camera/device/default/ExternalCameraUtils.cpp
@@ -0,0 +1,860 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamUtils"
+// #define LOG_NDEBUG 0
+
+#include "ExternalCameraUtils.h"
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <jpeglib.h>
+#include <linux/videodev2.h>
+#include <log/log.h>
+#include <algorithm>
+#include <cinttypes>
+#include <cmath>
+
+#define HAVE_JPEG  // required for libyuv.h to export MJPEG decode APIs
+#include <libyuv.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+
+namespace external {
+namespace common {
+
+namespace {
+const int kDefaultCameraIdOffset = 100;
+const int kDefaultJpegBufSize = 5 << 20;  // 5MB
+const int kDefaultNumVideoBuffer = 4;
+const int kDefaultNumStillBuffer = 2;
+const int kDefaultOrientation = 0;  // suitable for natural landscape displays like tablet/TV
+                                    // For phone devices 270 is better
+}  // anonymous namespace
+
+const char* ExternalCameraConfig::kDefaultCfgPath = "/vendor/etc/external_camera_config.xml";
+
+ExternalCameraConfig ExternalCameraConfig::loadFromCfg(const char* cfgPath) {
+    using namespace tinyxml2;
+    ExternalCameraConfig ret;
+
+    XMLDocument configXml;
+    XMLError err = configXml.LoadFile(cfgPath);
+    if (err != XML_SUCCESS) {
+        ALOGE("%s: Unable to load external camera config file '%s'. Error: %s", __FUNCTION__,
+              cfgPath, XMLDocument::ErrorIDToName(err));
+        return ret;
+    } else {
+        ALOGI("%s: load external camera config succeeded!", __FUNCTION__);
+    }
+
+    XMLElement* extCam = configXml.FirstChildElement("ExternalCamera");
+    if (extCam == nullptr) {
+        ALOGI("%s: no external camera config specified", __FUNCTION__);
+        return ret;
+    }
+
+    XMLElement* providerCfg = extCam->FirstChildElement("Provider");
+    if (providerCfg == nullptr) {
+        ALOGI("%s: no external camera provider config specified", __FUNCTION__);
+        return ret;
+    }
+
+    XMLElement* cameraIdOffset = providerCfg->FirstChildElement("CameraIdOffset");
+    if (cameraIdOffset != nullptr) {
+        ret.cameraIdOffset = std::atoi(cameraIdOffset->GetText());
+    }
+
+    XMLElement* ignore = providerCfg->FirstChildElement("ignore");
+    if (ignore == nullptr) {
+        ALOGI("%s: no internal ignored device specified", __FUNCTION__);
+        return ret;
+    }
+
+    XMLElement* id = ignore->FirstChildElement("id");
+    while (id != nullptr) {
+        const char* text = id->GetText();
+        if (text != nullptr) {
+            ret.mInternalDevices.insert(text);
+            ALOGI("%s: device %s will be ignored by external camera provider", __FUNCTION__, text);
+        }
+        id = id->NextSiblingElement("id");
+    }
+
+    XMLElement* deviceCfg = extCam->FirstChildElement("Device");
+    if (deviceCfg == nullptr) {
+        ALOGI("%s: no external camera device config specified", __FUNCTION__);
+        return ret;
+    }
+
+    XMLElement* jpegBufSz = deviceCfg->FirstChildElement("MaxJpegBufferSize");
+    if (jpegBufSz == nullptr) {
+        ALOGI("%s: no max jpeg buffer size specified", __FUNCTION__);
+    } else {
+        ret.maxJpegBufSize = jpegBufSz->UnsignedAttribute("bytes", /*Default*/ kDefaultJpegBufSize);
+    }
+
+    XMLElement* numVideoBuf = deviceCfg->FirstChildElement("NumVideoBuffers");
+    if (numVideoBuf == nullptr) {
+        ALOGI("%s: no num video buffers specified", __FUNCTION__);
+    } else {
+        ret.numVideoBuffers =
+                numVideoBuf->UnsignedAttribute("count", /*Default*/ kDefaultNumVideoBuffer);
+    }
+
+    XMLElement* numStillBuf = deviceCfg->FirstChildElement("NumStillBuffers");
+    if (numStillBuf == nullptr) {
+        ALOGI("%s: no num still buffers specified", __FUNCTION__);
+    } else {
+        ret.numStillBuffers =
+                numStillBuf->UnsignedAttribute("count", /*Default*/ kDefaultNumStillBuffer);
+    }
+
+    XMLElement* fpsList = deviceCfg->FirstChildElement("FpsList");
+    if (fpsList == nullptr) {
+        ALOGI("%s: no fps list specified", __FUNCTION__);
+    } else {
+        if (!updateFpsList(fpsList, ret.fpsLimits)) {
+            return ret;
+        }
+    }
+
+    XMLElement* depth = deviceCfg->FirstChildElement("Depth16Supported");
+    if (depth == nullptr) {
+        ret.depthEnabled = false;
+        ALOGI("%s: depth output is not enabled", __FUNCTION__);
+    } else {
+        ret.depthEnabled = depth->BoolAttribute("enabled", false);
+    }
+
+    if (ret.depthEnabled) {
+        XMLElement* depthFpsList = deviceCfg->FirstChildElement("DepthFpsList");
+        if (depthFpsList == nullptr) {
+            ALOGW("%s: no depth fps list specified", __FUNCTION__);
+        } else {
+            if (!updateFpsList(depthFpsList, ret.depthFpsLimits)) {
+                return ret;
+            }
+        }
+    }
+
+    XMLElement* minStreamSize = deviceCfg->FirstChildElement("MinimumStreamSize");
+    if (minStreamSize == nullptr) {
+        ALOGI("%s: no minimum stream size specified", __FUNCTION__);
+    } else {
+        ret.minStreamSize = {
+                static_cast<int32_t>(minStreamSize->UnsignedAttribute("width", /*Default*/ 0)),
+                static_cast<int32_t>(minStreamSize->UnsignedAttribute("height", /*Default*/ 0))};
+    }
+
+    XMLElement* orientation = deviceCfg->FirstChildElement("Orientation");
+    if (orientation == nullptr) {
+        ALOGI("%s: no sensor orientation specified", __FUNCTION__);
+    } else {
+        ret.orientation = orientation->IntAttribute("degree", /*Default*/ kDefaultOrientation);
+    }
+
+    ALOGI("%s: external camera cfg loaded: maxJpgBufSize %d,"
+          " num video buffers %d, num still buffers %d, orientation %d",
+          __FUNCTION__, ret.maxJpegBufSize, ret.numVideoBuffers, ret.numStillBuffers,
+          ret.orientation);
+    for (const auto& limit : ret.fpsLimits) {
+        ALOGI("%s: fpsLimitList: %dx%d@%f", __FUNCTION__, limit.size.width, limit.size.height,
+              limit.fpsUpperBound);
+    }
+    for (const auto& limit : ret.depthFpsLimits) {
+        ALOGI("%s: depthFpsLimitList: %dx%d@%f", __FUNCTION__, limit.size.width, limit.size.height,
+              limit.fpsUpperBound);
+    }
+    ALOGI("%s: minStreamSize: %dx%d", __FUNCTION__, ret.minStreamSize.width,
+          ret.minStreamSize.height);
+    return ret;
+}
+
+bool ExternalCameraConfig::updateFpsList(tinyxml2::XMLElement* fpsList,
+                                         std::vector<FpsLimitation>& fpsLimits) {
+    using namespace tinyxml2;
+    std::vector<FpsLimitation> limits;
+    XMLElement* row = fpsList->FirstChildElement("Limit");
+    while (row != nullptr) {
+        FpsLimitation prevLimit{{0, 0}, 1000.0};
+        FpsLimitation limit = {
+                {/* width */ static_cast<int32_t>(row->UnsignedAttribute("width", /*Default*/ 0)),
+                 /* height */ static_cast<int32_t>(
+                         row->UnsignedAttribute("height", /*Default*/ 0))},
+                /* fpsUpperBound */ row->DoubleAttribute("fpsBound", /*Default*/ 1000.0)};
+        if (limit.size.width <= prevLimit.size.width ||
+            limit.size.height <= prevLimit.size.height ||
+            limit.fpsUpperBound >= prevLimit.fpsUpperBound) {
+            ALOGE("%s: FPS limit list must have increasing size and decreasing fps!"
+                  " Prev %dx%d@%f, Current %dx%d@%f",
+                  __FUNCTION__, prevLimit.size.width, prevLimit.size.height,
+                  prevLimit.fpsUpperBound, limit.size.width, limit.size.height,
+                  limit.fpsUpperBound);
+            return false;
+        }
+        limits.push_back(limit);
+        row = row->NextSiblingElement("Limit");
+    }
+    fpsLimits = limits;
+    return true;
+}
+
+ExternalCameraConfig::ExternalCameraConfig()
+    : cameraIdOffset(kDefaultCameraIdOffset),
+      maxJpegBufSize(kDefaultJpegBufSize),
+      numVideoBuffers(kDefaultNumVideoBuffer),
+      numStillBuffers(kDefaultNumStillBuffer),
+      depthEnabled(false),
+      orientation(kDefaultOrientation) {
+    fpsLimits.push_back({/* size */ {/* width */ 640, /* height */ 480}, /* fpsUpperBound */ 30.0});
+    fpsLimits.push_back({/* size */ {/* width */ 1280, /* height */ 720}, /* fpsUpperBound */ 7.5});
+    fpsLimits.push_back(
+            {/* size */ {/* width */ 1920, /* height */ 1080}, /* fpsUpperBound */ 5.0});
+    minStreamSize = {0, 0};
+}
+
+}  // namespace common
+}  // namespace external
+
+namespace device {
+namespace implementation {
+
+double SupportedV4L2Format::FrameRate::getFramesPerSecond() const {
+    return static_cast<double>(durationDenominator) / durationNumerator;
+}
+
+Frame::Frame(uint32_t width, uint32_t height, uint32_t fourcc)
+    : mWidth(width), mHeight(height), mFourcc(fourcc) {}
+Frame::~Frame() {}
+
+V4L2Frame::V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd, uint32_t dataSize,
+                     uint64_t offset)
+    : Frame(w, h, fourcc), mBufferIndex(bufIdx), mFd(fd), mDataSize(dataSize), mOffset(offset) {}
+
+V4L2Frame::~V4L2Frame() {
+    unmap();
+}
+
+int V4L2Frame::getData(uint8_t** outData, size_t* dataSize) {
+    return map(outData, dataSize);
+}
+
+int V4L2Frame::map(uint8_t** data, size_t* dataSize) {
+    if (data == nullptr || dataSize == nullptr) {
+        ALOGI("%s: V4L2 buffer map bad argument: data %p, dataSize %p", __FUNCTION__, data,
+              dataSize);
+        return -EINVAL;
+    }
+
+    std::lock_guard<std::mutex> lk(mLock);
+    if (!mMapped) {
+        void* addr = mmap(nullptr, mDataSize, PROT_READ, MAP_SHARED, mFd, mOffset);
+        if (addr == MAP_FAILED) {
+            ALOGE("%s: V4L2 buffer map failed: %s", __FUNCTION__, strerror(errno));
+            return -EINVAL;
+        }
+        mData = static_cast<uint8_t*>(addr);
+        mMapped = true;
+    }
+    *data = mData;
+    *dataSize = mDataSize;
+    ALOGV("%s: V4L map FD %d, data %p size %zu", __FUNCTION__, mFd, mData, mDataSize);
+    return 0;
+}
+
+int V4L2Frame::unmap() {
+    std::lock_guard<std::mutex> lk(mLock);
+    if (mMapped) {
+        ALOGV("%s: V4L unmap data %p size %zu", __FUNCTION__, mData, mDataSize);
+        if (munmap(mData, mDataSize) != 0) {
+            ALOGE("%s: V4L2 buffer unmap failed: %s", __FUNCTION__, strerror(errno));
+            return -EINVAL;
+        }
+        mMapped = false;
+    }
+    return 0;
+}
+
+AllocatedFrame::AllocatedFrame(uint32_t w, uint32_t h) : Frame(w, h, V4L2_PIX_FMT_YUV420) {}
+AllocatedFrame::~AllocatedFrame() {}
+
+int AllocatedFrame::getData(uint8_t** outData, size_t* dataSize) {
+    YCbCrLayout layout;
+    int ret = allocate(&layout);
+    if (ret != 0) {
+        return ret;
+    }
+    *outData = mData.data();
+    *dataSize = mBufferSize;
+    return 0;
+}
+
+int AllocatedFrame::allocate(YCbCrLayout* out) {
+    std::lock_guard<std::mutex> lk(mLock);
+    if ((mWidth % 2) || (mHeight % 2)) {
+        ALOGE("%s: bad dimension %dx%d (not multiple of 2)", __FUNCTION__, mWidth, mHeight);
+        return -EINVAL;
+    }
+
+    // This frame might be sent to jpeglib to be encoded. Since AllocatedFrame only contains YUV420,
+    // jpeglib expects height and width of Y component to be an integral multiple of 2*DCTSIZE,
+    // and heights and widths of Cb and Cr components to be an integral multiple of DCTSIZE. If the
+    // image size does not meet this requirement, libjpeg expects its input to be padded to meet the
+    // constraints. This padding is removed from the final encoded image so the content in the
+    // padding doesn't matter. What matters is that the memory is accessible to jpeglib at the time
+    // of encoding.
+    // For example, if the image size is 1500x844 and DCTSIZE is 8, jpeglib expects a YUV 420
+    // frame with components of following sizes:
+    //   Y:      1504x848 because 1504 and 848 are the next smallest multiples of 2*8
+    //   Cb/Cr:  752x424 which are the next smallest multiples of 8
+
+    // jpeglib takes an array of row pointers which makes vertical padding trivial when setting up
+    // the pointers. Padding horizontally is a bit more complicated. AllocatedFrame holds the data
+    // in a flattened buffer, which means memory accesses past a row will flow into the next logical
+    // row. For any row of a component, we can consider the first few bytes of the next row as
+    // padding for the current one. This is true for Y and Cb components and all but last row of the
+    // Cr component. Reading past the last row of Cr component will lead to undefined behavior as
+    // libjpeg attempts to read memory past the allocated buffer. To prevent undefined behavior,
+    // the buffer allocated here is padded such that libjpeg never accesses unallocated memory when
+    // reading the last row. Effectively, we only need to ensure that the last row of Cr component
+    // has width that is an integral multiple of DCTSIZE.
+
+    size_t dataSize = mWidth * mHeight * 3 / 2;  // YUV420
+
+    size_t cbWidth = mWidth / 2;
+    size_t requiredCbWidth = DCTSIZE * ((cbWidth + DCTSIZE - 1) / DCTSIZE);
+    size_t padding = requiredCbWidth - cbWidth;
+    size_t finalSize = dataSize + padding;
+
+    if (mData.size() != finalSize) {
+        mData.resize(finalSize);
+        mBufferSize = dataSize;
+    }
+
+    if (out != nullptr) {
+        out->y = mData.data();
+        out->yStride = mWidth;
+        uint8_t* cbStart = mData.data() + mWidth * mHeight;
+        uint8_t* crStart = cbStart + mWidth * mHeight / 4;
+        out->cb = cbStart;
+        out->cr = crStart;
+        out->cStride = mWidth / 2;
+        out->chromaStep = 1;
+    }
+    return 0;
+}
+
+int AllocatedFrame::getLayout(YCbCrLayout* out) {
+    IMapper::Rect noCrop = {0, 0, static_cast<int32_t>(mWidth), static_cast<int32_t>(mHeight)};
+    return getCroppedLayout(noCrop, out);
+}
+
+int AllocatedFrame::getCroppedLayout(const IMapper::Rect& rect, YCbCrLayout* out) {
+    if (out == nullptr) {
+        ALOGE("%s: null out", __FUNCTION__);
+        return -1;
+    }
+
+    std::lock_guard<std::mutex> lk(mLock);
+    if ((rect.left + rect.width) > static_cast<int>(mWidth) ||
+        (rect.top + rect.height) > static_cast<int>(mHeight) || (rect.left % 2) || (rect.top % 2) ||
+        (rect.width % 2) || (rect.height % 2)) {
+        ALOGE("%s: bad rect left %d top %d w %d h %d", __FUNCTION__, rect.left, rect.top,
+              rect.width, rect.height);
+        return -1;
+    }
+
+    out->y = mData.data() + mWidth * rect.top + rect.left;
+    out->yStride = mWidth;
+    uint8_t* cbStart = mData.data() + mWidth * mHeight;
+    uint8_t* crStart = cbStart + mWidth * mHeight / 4;
+    out->cb = cbStart + mWidth * rect.top / 4 + rect.left / 2;
+    out->cr = crStart + mWidth * rect.top / 4 + rect.left / 2;
+    out->cStride = mWidth / 2;
+    out->chromaStep = 1;
+    return 0;
+}
+
+bool isAspectRatioClose(float ar1, float ar2) {
+    constexpr float kAspectRatioMatchThres = 0.025f;  // This threshold is good enough to
+                                                      // distinguish 4:3/16:9/20:9 1.33/1.78/2
+    return std::abs(ar1 - ar2) < kAspectRatioMatchThres;
+}
+
+aidl::android::hardware::camera::common::Status importBufferImpl(
+        /*inout*/ std::map<int, CirculatingBuffers>& circulatingBuffers,
+        /*inout*/ HandleImporter& handleImporter, int32_t streamId, uint64_t bufId,
+        buffer_handle_t buf,
+        /*out*/ buffer_handle_t** outBufPtr) {
+    using ::aidl::android::hardware::camera::common::Status;
+    if (buf == nullptr && bufId == BUFFER_ID_NO_BUFFER) {
+        ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    CirculatingBuffers& cbs = circulatingBuffers[streamId];
+    if (cbs.count(bufId) == 0) {
+        if (buf == nullptr) {
+            ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
+            return Status::ILLEGAL_ARGUMENT;
+        }
+        // Register a newly seen buffer
+        buffer_handle_t importedBuf = buf;
+        handleImporter.importBuffer(importedBuf);
+        if (importedBuf == nullptr) {
+            ALOGE("%s: output buffer for stream %d is invalid!", __FUNCTION__, streamId);
+            return Status::INTERNAL_ERROR;
+        } else {
+            cbs[bufId] = importedBuf;
+        }
+    }
+    *outBufPtr = &cbs[bufId];
+    return Status::OK;
+}
+
+uint32_t getFourCcFromLayout(const YCbCrLayout& layout) {
+    intptr_t cb = reinterpret_cast<intptr_t>(layout.cb);
+    intptr_t cr = reinterpret_cast<intptr_t>(layout.cr);
+    if (std::abs(cb - cr) == 1 && layout.chromaStep == 2) {
+        // Interleaved format
+        if (layout.cb > layout.cr) {
+            return V4L2_PIX_FMT_NV21;
+        } else {
+            return V4L2_PIX_FMT_NV12;
+        }
+    } else if (layout.chromaStep == 1) {
+        // Planar format
+        if (layout.cb > layout.cr) {
+            return V4L2_PIX_FMT_YVU420;  // YV12
+        } else {
+            return V4L2_PIX_FMT_YUV420;  // YU12
+        }
+    } else {
+        return FLEX_YUV_GENERIC;
+    }
+}
+
+int getCropRect(CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out) {
+    if (out == nullptr) {
+        ALOGE("%s: out is null", __FUNCTION__);
+        return -1;
+    }
+
+    uint32_t inW = inSize.width;
+    uint32_t inH = inSize.height;
+    uint32_t outW = outSize.width;
+    uint32_t outH = outSize.height;
+
+    // Handle special case where aspect ratio is close to input but scaled
+    // dimension is slightly larger than input
+    float arIn = ASPECT_RATIO(inSize);
+    float arOut = ASPECT_RATIO(outSize);
+    if (isAspectRatioClose(arIn, arOut)) {
+        out->left = 0;
+        out->top = 0;
+        out->width = static_cast<int32_t>(inW);
+        out->height = static_cast<int32_t>(inH);
+        return 0;
+    }
+
+    if (ct == VERTICAL) {
+        uint64_t scaledOutH = static_cast<uint64_t>(outH) * inW / outW;
+        if (scaledOutH > inH) {
+            ALOGE("%s: Output size %dx%d cannot be vertically cropped from input size %dx%d",
+                  __FUNCTION__, outW, outH, inW, inH);
+            return -1;
+        }
+        scaledOutH = scaledOutH & ~0x1;  // make it multiple of 2
+
+        out->left = 0;
+        out->top = static_cast<int32_t>((inH - scaledOutH) / 2) & ~0x1;
+        out->width = static_cast<int32_t>(inW);
+        out->height = static_cast<int32_t>(scaledOutH);
+        ALOGV("%s: crop %dx%d to %dx%d: top %d, scaledH %d", __FUNCTION__, inW, inH, outW, outH,
+              out->top, static_cast<int32_t>(scaledOutH));
+    } else {
+        uint64_t scaledOutW = static_cast<uint64_t>(outW) * inH / outH;
+        if (scaledOutW > inW) {
+            ALOGE("%s: Output size %dx%d cannot be horizontally cropped from input size %dx%d",
+                  __FUNCTION__, outW, outH, inW, inH);
+            return -1;
+        }
+        scaledOutW = scaledOutW & ~0x1;  // make it multiple of 2
+
+        out->left = static_cast<int32_t>((inW - scaledOutW) / 2) & ~0x1;
+        out->top = 0;
+        out->width = static_cast<int32_t>(scaledOutW);
+        out->height = static_cast<int32_t>(inH);
+        ALOGV("%s: crop %dx%d to %dx%d: top %d, scaledW %d", __FUNCTION__, inW, inH, outW, outH,
+              out->top, static_cast<int32_t>(scaledOutW));
+    }
+
+    return 0;
+}
+
+int formatConvert(const YCbCrLayout& in, const YCbCrLayout& out, Size sz, uint32_t format) {
+    int ret = 0;
+    switch (format) {
+        case V4L2_PIX_FMT_NV21:
+            ret = libyuv::I420ToNV21(
+                    static_cast<uint8_t*>(in.y), static_cast<int32_t>(in.yStride),
+                    static_cast<uint8_t*>(in.cb), static_cast<int32_t>(in.cStride),
+                    static_cast<uint8_t*>(in.cr), static_cast<int32_t>(in.cStride),
+                    static_cast<uint8_t*>(out.y), static_cast<int32_t>(out.yStride),
+                    static_cast<uint8_t*>(out.cr), static_cast<int32_t>(out.cStride),
+                    static_cast<int32_t>(sz.width), static_cast<int32_t>(sz.height));
+            if (ret != 0) {
+                ALOGE("%s: convert to NV21 buffer failed! ret %d", __FUNCTION__, ret);
+                return ret;
+            }
+            break;
+        case V4L2_PIX_FMT_NV12:
+            ret = libyuv::I420ToNV12(
+                    static_cast<uint8_t*>(in.y), static_cast<int32_t>(in.yStride),
+                    static_cast<uint8_t*>(in.cb), static_cast<int32_t>(in.cStride),
+                    static_cast<uint8_t*>(in.cr), static_cast<int32_t>(in.cStride),
+                    static_cast<uint8_t*>(out.y), static_cast<int32_t>(out.yStride),
+                    static_cast<uint8_t*>(out.cb), static_cast<int32_t>(out.cStride),
+                    static_cast<int32_t>(sz.width), static_cast<int32_t>(sz.height));
+            if (ret != 0) {
+                ALOGE("%s: convert to NV12 buffer failed! ret %d", __FUNCTION__, ret);
+                return ret;
+            }
+            break;
+        case V4L2_PIX_FMT_YVU420:  // YV12
+        case V4L2_PIX_FMT_YUV420:  // YU12
+            // TODO: maybe we can speed up here by somehow save this copy?
+            ret = libyuv::I420Copy(static_cast<uint8_t*>(in.y), static_cast<int32_t>(in.yStride),
+                                   static_cast<uint8_t*>(in.cb), static_cast<int32_t>(in.cStride),
+                                   static_cast<uint8_t*>(in.cr), static_cast<int32_t>(in.cStride),
+                                   static_cast<uint8_t*>(out.y), static_cast<int32_t>(out.yStride),
+                                   static_cast<uint8_t*>(out.cb), static_cast<int32_t>(out.cStride),
+                                   static_cast<uint8_t*>(out.cr), static_cast<int32_t>(out.cStride),
+                                   static_cast<int32_t>(sz.width), static_cast<int32_t>(sz.height));
+            if (ret != 0) {
+                ALOGE("%s: copy to YV12 or YU12 buffer failed! ret %d", __FUNCTION__, ret);
+                return ret;
+            }
+            break;
+        case FLEX_YUV_GENERIC:
+            // TODO: b/72261744 write to arbitrary flexible YUV layout. Slow.
+            ALOGE("%s: unsupported flexible yuv layout"
+                  " y %p cb %p cr %p y_str %d c_str %d c_step %d",
+                  __FUNCTION__, out.y, out.cb, out.cr, out.yStride, out.cStride, out.chromaStep);
+            return -1;
+        default:
+            ALOGE("%s: unknown YUV format 0x%x!", __FUNCTION__, format);
+            return -1;
+    }
+    return 0;
+}
+
+int encodeJpegYU12(const Size& inSz, const YCbCrLayout& inLayout, int jpegQuality,
+                   const void* app1Buffer, size_t app1Size, void* out, size_t maxOutSize,
+                   size_t& actualCodeSize) {
+    /* libjpeg is a C library so we use C-style "inheritance" by
+     * putting libjpeg's jpeg_destination_mgr first in our custom
+     * struct. This allows us to cast jpeg_destination_mgr* to
+     * CustomJpegDestMgr* when we get it passed to us in a callback */
+    struct CustomJpegDestMgr {
+        struct jpeg_destination_mgr mgr;
+        JOCTET* mBuffer;
+        size_t mBufferSize;
+        size_t mEncodedSize;
+        bool mSuccess;
+    } dmgr;
+
+    jpeg_compress_struct cinfo = {};
+    jpeg_error_mgr jerr;
+
+    /* Initialize error handling with standard callbacks, but
+     * then override output_message (to print to ALOG) and
+     * error_exit to set a flag and print a message instead
+     * of killing the whole process */
+    cinfo.err = jpeg_std_error(&jerr);
+
+    cinfo.err->output_message = [](j_common_ptr cinfo) {
+        char buffer[JMSG_LENGTH_MAX];
+
+        /* Create the message */
+        (*cinfo->err->format_message)(cinfo, buffer);
+        ALOGE("libjpeg error: %s", buffer);
+    };
+    cinfo.err->error_exit = [](j_common_ptr cinfo) {
+        (*cinfo->err->output_message)(cinfo);
+        if (cinfo->client_data) {
+            auto& dmgr = *reinterpret_cast<CustomJpegDestMgr*>(cinfo->client_data);
+            dmgr.mSuccess = false;
+        }
+    };
+
+    /* Now that we initialized some callbacks, let's create our compressor */
+    jpeg_create_compress(&cinfo);
+
+    /* Initialize our destination manager */
+    dmgr.mBuffer = static_cast<JOCTET*>(out);
+    dmgr.mBufferSize = maxOutSize;
+    dmgr.mEncodedSize = 0;
+    dmgr.mSuccess = true;
+    cinfo.client_data = static_cast<void*>(&dmgr);
+
+    /* These lambdas become C-style function pointers and as per C++11 spec
+     * may not capture anything */
+    dmgr.mgr.init_destination = [](j_compress_ptr cinfo) {
+        auto& dmgr = reinterpret_cast<CustomJpegDestMgr&>(*cinfo->dest);
+        dmgr.mgr.next_output_byte = dmgr.mBuffer;
+        dmgr.mgr.free_in_buffer = dmgr.mBufferSize;
+        ALOGV("%s:%d jpeg start: %p [%zu]", __FUNCTION__, __LINE__, dmgr.mBuffer, dmgr.mBufferSize);
+    };
+
+    dmgr.mgr.empty_output_buffer = [](j_compress_ptr cinfo __unused) {
+        ALOGV("%s:%d Out of buffer", __FUNCTION__, __LINE__);
+        return 0;
+    };
+
+    dmgr.mgr.term_destination = [](j_compress_ptr cinfo) {
+        auto& dmgr = reinterpret_cast<CustomJpegDestMgr&>(*cinfo->dest);
+        dmgr.mEncodedSize = dmgr.mBufferSize - dmgr.mgr.free_in_buffer;
+        ALOGV("%s:%d Done with jpeg: %zu", __FUNCTION__, __LINE__, dmgr.mEncodedSize);
+    };
+    cinfo.dest = reinterpret_cast<struct jpeg_destination_mgr*>(&dmgr);
+
+    /* We are going to be using JPEG in raw data mode, so we are passing
+     * straight subsampled planar YCbCr and it will not touch our pixel
+     * data or do any scaling or anything */
+    cinfo.image_width = inSz.width;
+    cinfo.image_height = inSz.height;
+    cinfo.input_components = 3;
+    cinfo.in_color_space = JCS_YCbCr;
+
+    /* Initialize defaults and then override what we want */
+    jpeg_set_defaults(&cinfo);
+
+    jpeg_set_quality(&cinfo, jpegQuality, 1);
+    jpeg_set_colorspace(&cinfo, JCS_YCbCr);
+    cinfo.raw_data_in = 1;
+    cinfo.dct_method = JDCT_IFAST;
+
+    /* Configure sampling factors. The sampling factor is JPEG subsampling 420
+     * because the source format is YUV420. Note that libjpeg sampling factors
+     * are... a little weird. Sampling of Y=2,U=1,V=1 means there is 1 U and
+     * 1 V value for each 2 Y values */
+    cinfo.comp_info[0].h_samp_factor = 2;
+    cinfo.comp_info[0].v_samp_factor = 2;
+    cinfo.comp_info[1].h_samp_factor = 1;
+    cinfo.comp_info[1].v_samp_factor = 1;
+    cinfo.comp_info[2].h_samp_factor = 1;
+    cinfo.comp_info[2].v_samp_factor = 1;
+
+    /* Start the compressor */
+    jpeg_start_compress(&cinfo, TRUE);
+
+    /* Let's not hardcode YUV420 in 6 places... 5 was enough */
+    int maxVSampFactor = cinfo.max_v_samp_factor;
+    int cVSubSampling = cinfo.comp_info[0].v_samp_factor / cinfo.comp_info[1].v_samp_factor;
+
+    /* Compute our macroblock height, so we can pad our input to be vertically
+     * macroblock aligned. No need to for horizontal alignment since AllocatedFrame already
+     * pads horizontally */
+
+    size_t mcuV = DCTSIZE * maxVSampFactor;
+    size_t paddedHeight = mcuV * ((inSz.height + mcuV - 1) / mcuV);
+
+    /* libjpeg uses arrays of row pointers, which makes it really easy to pad
+     * data vertically (unfortunately doesn't help horizontally) */
+    std::vector<JSAMPROW> yLines(paddedHeight);
+    std::vector<JSAMPROW> cbLines(paddedHeight / cVSubSampling);
+    std::vector<JSAMPROW> crLines(paddedHeight / cVSubSampling);
+
+    uint8_t* py = static_cast<uint8_t*>(inLayout.y);
+    uint8_t* pcb = static_cast<uint8_t*>(inLayout.cb);
+    uint8_t* pcr = static_cast<uint8_t*>(inLayout.cr);
+
+    for (int32_t i = 0; i < paddedHeight; i++) {
+        /* Once we are in the padding territory we still point to the last line
+         * effectively replicating it several times ~ CLAMP_TO_EDGE */
+        int li = std::min(i, inSz.height - 1);
+        yLines[i] = static_cast<JSAMPROW>(py + li * inLayout.yStride);
+        if (i < paddedHeight / cVSubSampling) {
+            li = std::min(i, (inSz.height - 1) / cVSubSampling);
+            cbLines[i] = static_cast<JSAMPROW>(pcb + li * inLayout.cStride);
+            crLines[i] = static_cast<JSAMPROW>(pcr + li * inLayout.cStride);
+        }
+    }
+
+    /* If APP1 data was passed in, use it */
+    if (app1Buffer && app1Size) {
+        jpeg_write_marker(&cinfo, JPEG_APP0 + 1, static_cast<const JOCTET*>(app1Buffer), app1Size);
+    }
+
+    /* While we still have padded height left to go, keep giving it one
+     * macroblock at a time. */
+    while (cinfo.next_scanline < cinfo.image_height) {
+        const uint32_t batchSize = DCTSIZE * maxVSampFactor;
+        const uint32_t nl = cinfo.next_scanline;
+        JSAMPARRAY planes[3]{&yLines[nl], &cbLines[nl / cVSubSampling],
+                             &crLines[nl / cVSubSampling]};
+
+        uint32_t done = jpeg_write_raw_data(&cinfo, planes, batchSize);
+
+        if (done != batchSize) {
+            ALOGE("%s: compressed %u lines, expected %u (total %u/%u)", __FUNCTION__, done,
+                  batchSize, cinfo.next_scanline, cinfo.image_height);
+            return -1;
+        }
+    }
+
+    /* This will flush everything */
+    jpeg_finish_compress(&cinfo);
+
+    /* Grab the actual code size and set it */
+    actualCodeSize = dmgr.mEncodedSize;
+
+    return 0;
+}
+
+Size getMaxThumbnailResolution(const common::V1_0::helper::CameraMetadata& chars) {
+    Size thumbSize{0, 0};
+    camera_metadata_ro_entry entry = chars.find(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
+    for (uint32_t i = 0; i < entry.count; i += 2) {
+        Size sz{.width = entry.data.i32[i], .height = entry.data.i32[i + 1]};
+        if (sz.width * sz.height > thumbSize.width * thumbSize.height) {
+            thumbSize = sz;
+        }
+    }
+
+    if (thumbSize.width * thumbSize.height == 0) {
+        ALOGW("%s: non-zero thumbnail size not available", __FUNCTION__);
+    }
+
+    return thumbSize;
+}
+
+void freeReleaseFences(std::vector<CaptureResult>& results) {
+    for (auto& result : results) {
+        native_handle_t* inputReleaseFence =
+                ::android::makeFromAidl(result.inputBuffer.releaseFence);
+        if (inputReleaseFence != nullptr) {
+            native_handle_close(inputReleaseFence);
+            native_handle_delete(inputReleaseFence);
+        }
+        for (auto& buf : result.outputBuffers) {
+            native_handle_t* outReleaseFence = ::android::makeFromAidl(buf.releaseFence);
+            if (outReleaseFence != nullptr) {
+                native_handle_close(outReleaseFence);
+                native_handle_delete(outReleaseFence);
+            }
+        }
+    }
+}
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#define UPDATE(md, tag, data, size)               \
+    do {                                          \
+        if ((md).update((tag), (data), (size))) { \
+            ALOGE("Update " #tag " failed!");     \
+            return BAD_VALUE;                     \
+        }                                         \
+    } while (0)
+
+status_t fillCaptureResultCommon(CameraMetadata& md, nsecs_t timestamp,
+                                 camera_metadata_ro_entry& activeArraySize) {
+    if (activeArraySize.count < 4) {
+        ALOGE("%s: cannot find active array size!", __FUNCTION__);
+        return -EINVAL;
+    }
+    // android.control
+    // For USB camera, we don't know the AE state. Set the state to converged to
+    // indicate the frame should be good to use. Then apps don't have to wait the
+    // AE state.
+    const uint8_t aeState = ANDROID_CONTROL_AE_STATE_CONVERGED;
+    UPDATE(md, ANDROID_CONTROL_AE_STATE, &aeState, 1);
+
+    const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
+    UPDATE(md, ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
+
+    // Set AWB state to converged to indicate the frame should be good to use.
+    const uint8_t awbState = ANDROID_CONTROL_AWB_STATE_CONVERGED;
+    UPDATE(md, ANDROID_CONTROL_AWB_STATE, &awbState, 1);
+
+    const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
+    UPDATE(md, ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);
+
+    const uint8_t flashState = ANDROID_FLASH_STATE_UNAVAILABLE;
+    UPDATE(md, ANDROID_FLASH_STATE, &flashState, 1);
+
+    // This means pipeline latency of X frame intervals. The maximum number is 4.
+    const uint8_t requestPipelineMaxDepth = 4;
+    UPDATE(md, ANDROID_REQUEST_PIPELINE_DEPTH, &requestPipelineMaxDepth, 1);
+
+    // android.scaler
+    const int32_t crop_region[] = {
+            activeArraySize.data.i32[0],
+            activeArraySize.data.i32[1],
+            activeArraySize.data.i32[2],
+            activeArraySize.data.i32[3],
+    };
+    UPDATE(md, ANDROID_SCALER_CROP_REGION, crop_region, ARRAY_SIZE(crop_region));
+
+    // android.sensor
+    UPDATE(md, ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
+
+    // android.statistics
+    const uint8_t lensShadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+    UPDATE(md, ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &lensShadingMapMode, 1);
+
+    const uint8_t sceneFlicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
+    UPDATE(md, ANDROID_STATISTICS_SCENE_FLICKER, &sceneFlicker, 1);
+
+    return OK;
+}
+
+#undef ARRAY_SIZE
+#undef UPDATE
+
+AllocatedV4L2Frame::AllocatedV4L2Frame(std::shared_ptr<V4L2Frame> frameIn)
+    : Frame(frameIn->mWidth, frameIn->mHeight, frameIn->mFourcc) {
+    uint8_t* dataIn;
+    size_t dataSize;
+    if (frameIn->getData(&dataIn, &dataSize) != 0) {
+        ALOGE("%s: map input V4L2 frame failed!", __FUNCTION__);
+        return;
+    }
+
+    mData.resize(dataSize);
+    std::memcpy(mData.data(), dataIn, dataSize);
+}
+
+AllocatedV4L2Frame::~AllocatedV4L2Frame() {}
+
+int AllocatedV4L2Frame::getData(uint8_t** outData, size_t* dataSize) {
+    if (outData == nullptr || dataSize == nullptr) {
+        ALOGE("%s: outData(%p)/dataSize(%p) must not be null", __FUNCTION__, outData, dataSize);
+        return -1;
+    }
+
+    *outData = mData.data();
+    *dataSize = mData.size();
+    return 0;
+}
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/camera/device/default/ExternalCameraUtils.h b/camera/device/default/ExternalCameraUtils.h
new file mode 100644
index 0000000..b37933c
--- /dev/null
+++ b/camera/device/default/ExternalCameraUtils.h
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAUTILS_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAUTILS_H_
+
+#include <CameraMetadata.h>
+#include <HandleImporter.h>
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/device/CaptureResult.h>
+#include <aidl/android/hardware/camera/device/ErrorCode.h>
+#include <aidl/android/hardware/camera/device/NotifyMsg.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <tinyxml2.h>
+#include <unordered_map>
+#include <unordered_set>
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::aidl::android::hardware::camera::device::CaptureResult;
+using ::aidl::android::hardware::camera::device::ErrorCode;
+using ::aidl::android::hardware::camera::device::NotifyMsg;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+using ::android::hardware::camera::common::V1_0::helper::CameraMetadata;
+using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
+
+namespace android {
+namespace hardware {
+namespace camera {
+
+namespace external {
+namespace common {
+
+struct Size {
+    int32_t width;
+    int32_t height;
+
+    bool operator==(const Size& other) const {
+        return (width == other.width && height == other.height);
+    }
+};
+
+struct SizeHasher {
+    size_t operator()(const Size& sz) const {
+        size_t result = 1;
+        result = 31 * result + sz.width;
+        result = 31 * result + sz.height;
+        return result;
+    }
+};
+
+struct ExternalCameraConfig {
+    static const char* kDefaultCfgPath;
+    static ExternalCameraConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath);
+
+    // CameraId base offset for numerical representation
+    uint32_t cameraIdOffset;
+
+    // List of internal V4L2 video nodes external camera HAL must ignore.
+    std::unordered_set<std::string> mInternalDevices;
+
+    // Maximal size of a JPEG buffer, in bytes
+    int32_t maxJpegBufSize;
+
+    // Maximum Size that can sustain 30fps streaming
+    Size maxVideoSize;
+
+    // Size of v4l2 buffer queue when streaming <= kMaxVideoSize
+    uint32_t numVideoBuffers;
+
+    // Size of v4l2 buffer queue when streaming > kMaxVideoSize
+    uint32_t numStillBuffers;
+
+    // Indication that the device connected supports depth output
+    bool depthEnabled;
+
+    struct FpsLimitation {
+        Size size;
+        double fpsUpperBound;
+    };
+    std::vector<FpsLimitation> fpsLimits;
+    std::vector<FpsLimitation> depthFpsLimits;
+
+    // Minimum output stream size
+    Size minStreamSize;
+
+    // The value of android.sensor.orientation
+    int32_t orientation;
+
+  private:
+    ExternalCameraConfig();
+    static bool updateFpsList(tinyxml2::XMLElement* fpsList, std::vector<FpsLimitation>& fpsLimits);
+};
+
+}  // namespace common
+}  // namespace external
+
+namespace device {
+namespace implementation {
+
+struct SupportedV4L2Format {
+    int32_t width;
+    int32_t height;
+    uint32_t fourcc;
+    // All supported frame rate for this w/h/fourcc combination
+    struct FrameRate {
+        // Duration (in seconds) of a single frame.
+        // Numerator and denominator of the frame duration are stored separately.
+        // For ex. a frame lasting 1/30 of a second will be stored as {1, 30}
+        uint32_t durationNumerator;         // frame duration numerator.   Ex: 1
+        uint32_t durationDenominator;       // frame duration denominator. Ex: 30
+        double getFramesPerSecond() const;  // FPS as double.        Ex: 30.0
+    };
+    std::vector<FrameRate> frameRates;
+};
+
+// A Base class with basic information about a frame
+struct Frame : public std::enable_shared_from_this<Frame> {
+  public:
+    Frame(uint32_t width, uint32_t height, uint32_t fourcc);
+    virtual ~Frame();
+    const int32_t mWidth;
+    const int32_t mHeight;
+    const uint32_t mFourcc;
+
+    // getData might involve map/allocation
+    virtual int getData(uint8_t** outData, size_t* dataSize) = 0;
+};
+
+// A class provide access to a dequeued V4L2 frame buffer (mostly in MJPG format)
+// Also contains necessary information to enqueue the buffer back to V4L2 buffer queue
+class V4L2Frame : public Frame {
+  public:
+    V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd, uint32_t dataSize,
+              uint64_t offset);
+    virtual ~V4L2Frame();
+
+    virtual int getData(uint8_t** outData, size_t* dataSize) override;
+
+    const int mBufferIndex;  // for later enqueue
+    int map(uint8_t** data, size_t* dataSize);
+    int unmap();
+
+  private:
+    std::mutex mLock;
+    const int mFd;  // used for mmap but doesn't claim ownership
+    const size_t mDataSize;
+    const uint64_t mOffset;  // used for mmap
+    uint8_t* mData = nullptr;
+    bool mMapped = false;
+};
+
+// A RAII class representing a CPU allocated YUV frame used as intermediate buffers
+// when generating output images.
+class AllocatedFrame : public Frame {
+  public:
+    AllocatedFrame(uint32_t w, uint32_t h);  // only support V4L2_PIX_FMT_YUV420 for now
+    ~AllocatedFrame() override;
+
+    virtual int getData(uint8_t** outData, size_t* dataSize) override;
+
+    int allocate(YCbCrLayout* out = nullptr);
+    int getLayout(YCbCrLayout* out);
+    int getCroppedLayout(const IMapper::Rect&, YCbCrLayout* out);  // return non-zero for bad input
+  private:
+    std::mutex mLock;
+    std::vector<uint8_t> mData;
+    size_t mBufferSize;  // size of mData before padding. Actual size of mData might be slightly
+                         // bigger to horizontally pad the frame for jpeglib.
+};
+
+enum CroppingType { HORIZONTAL = 0, VERTICAL = 1 };
+
+// Aspect ratio is defined as width/height here and ExternalCameraDevice
+// will guarantee all supported sizes has width >= height (so aspect ratio >= 1.0)
+#define ASPECT_RATIO(sz) (static_cast<float>((sz).width) / (sz).height)
+const float kMaxAspectRatio = std::numeric_limits<float>::max();
+const float kMinAspectRatio = 1.f;
+
+bool isAspectRatioClose(float ar1, float ar2);
+
+struct HalStreamBuffer {
+    int32_t streamId;
+    int64_t bufferId;
+    int32_t width;
+    int32_t height;
+    ::aidl::android::hardware::graphics::common::PixelFormat format;
+    ::aidl::android::hardware::graphics::common::BufferUsage usage;
+    buffer_handle_t* bufPtr;
+    int acquireFence;
+    bool fenceTimeout;
+};
+
+struct HalRequest {
+    int32_t frameNumber;
+    common::V1_0::helper::CameraMetadata setting;
+    std::shared_ptr<Frame> frameIn;
+    nsecs_t shutterTs;
+    std::vector<HalStreamBuffer> buffers;
+};
+
+static const uint64_t BUFFER_ID_NO_BUFFER = 0;
+
+// buffers currently circulating between HAL and camera service
+// key: bufferId sent via HIDL interface
+// value: imported buffer_handle_t
+// Buffer will be imported during processCaptureRequest (or requestStreamBuffer
+// in the case of HAL buffer manager is enabled) and will be freed
+// when the stream is deleted or camera device session is closed
+typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
+
+aidl::android::hardware::camera::common::Status importBufferImpl(
+        /*inout*/ std::map<int, CirculatingBuffers>& circulatingBuffers,
+        /*inout*/ HandleImporter& handleImporter, int32_t streamId, uint64_t bufId,
+        buffer_handle_t buf,
+        /*out*/ buffer_handle_t** outBufPtr);
+
+static const uint32_t FLEX_YUV_GENERIC =
+        static_cast<uint32_t>('F') | static_cast<uint32_t>('L') << 8 |
+        static_cast<uint32_t>('E') << 16 | static_cast<uint32_t>('X') << 24;
+
+// returns FLEX_YUV_GENERIC for formats other than YV12/YU12/NV12/NV21
+uint32_t getFourCcFromLayout(const YCbCrLayout&);
+
+using ::android::hardware::camera::external::common::Size;
+int getCropRect(CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out);
+
+int formatConvert(const YCbCrLayout& in, const YCbCrLayout& out, Size sz, uint32_t format);
+
+int encodeJpegYU12(const Size& inSz, const YCbCrLayout& inLayout, int jpegQuality,
+                   const void* app1Buffer, size_t app1Size, void* out, size_t maxOutSize,
+                   size_t& actualCodeSize);
+
+Size getMaxThumbnailResolution(const common::V1_0::helper::CameraMetadata&);
+
+void freeReleaseFences(std::vector<CaptureResult>&);
+
+status_t fillCaptureResultCommon(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp,
+                                 camera_metadata_ro_entry& activeArraySize);
+
+// Interface for OutputThread calling back to parent
+struct OutputThreadInterface {
+    virtual ~OutputThreadInterface() {}
+    virtual aidl::android::hardware::camera::common::Status importBuffer(
+            int32_t streamId, uint64_t bufId, buffer_handle_t buf,
+            /*out*/ buffer_handle_t** outBufPtr) = 0;
+
+    virtual void notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) = 0;
+
+    // Callbacks are fired within the method if msgs/results are nullptr.
+    // Otherwise the callbacks will be returned and caller is responsible to
+    // fire the callback later
+    virtual aidl::android::hardware::camera::common::Status processCaptureRequestError(
+            const std::shared_ptr<HalRequest>&,
+            /*out*/ std::vector<NotifyMsg>* msgs,
+            /*out*/ std::vector<CaptureResult>* results) = 0;
+
+    virtual aidl::android::hardware::camera::common::Status processCaptureRequestError(
+            const std::shared_ptr<HalRequest>& reqs) final {
+        return processCaptureRequestError(reqs, nullptr, nullptr);
+    }
+
+    virtual aidl::android::hardware::camera::common::Status processCaptureResult(
+            std::shared_ptr<HalRequest>&) = 0;
+
+    virtual ssize_t getJpegBufferSize(int32_t width, int32_t height) const = 0;
+};
+
+// A CPU copy of a mapped V4L2Frame. Will map the input V4L2 frame.
+class AllocatedV4L2Frame : public Frame {
+  public:
+    AllocatedV4L2Frame(std::shared_ptr<V4L2Frame> frameIn);
+    ~AllocatedV4L2Frame() override;
+    virtual int getData(uint8_t** outData, size_t* dataSize) override;
+
+  private:
+    std::vector<uint8_t> mData;
+};
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAUTILS_H_
diff --git a/camera/device/default/convert.cpp b/camera/device/default/convert.cpp
new file mode 100644
index 0000000..8134dd5
--- /dev/null
+++ b/camera/device/default/convert.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.camera.device@3.4-convert-impl"
+#include <log/log.h>
+
+#include "convert.h"
+
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <hardware/camera_common.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::device::ErrorCode;
+using ::aidl::android::hardware::camera::device::ErrorMsg;
+using ::aidl::android::hardware::camera::device::ShutterMsg;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+
+void convertToAidl(const camera_metadata_t* src, CameraMetadata* dest) {
+    if (src == nullptr) {
+        return;
+    }
+
+    size_t size = get_camera_metadata_size(src);
+    auto* src_start = (uint8_t*)src;
+    uint8_t* src_end = src_start + size;
+    dest->metadata.assign(src_start, src_end);
+}
+
+bool convertFromAidl(const CameraMetadata& src, const camera_metadata_t** dst) {
+    const std::vector<uint8_t>& metadata = src.metadata;
+    if (metadata.empty()) {
+        // Special case for null metadata
+        *dst = nullptr;
+        return true;
+    }
+
+    const uint8_t* data = metadata.data();
+    // check that the size of CameraMetadata match underlying camera_metadata_t
+    if (get_camera_metadata_size((camera_metadata_t*)data) != metadata.size()) {
+        ALOGE("%s: input CameraMetadata is corrupt!", __FUNCTION__);
+        return false;
+    }
+    *dst = (camera_metadata_t*)data;
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/device/default/convert.h b/camera/device/default/convert.h
new file mode 100644
index 0000000..5a508fc
--- /dev/null
+++ b/camera/device/default/convert.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_CONVERT_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_CONVERT_H_
+
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/device/BufferStatus.h>
+#include <aidl/android/hardware/camera/device/CameraMetadata.h>
+#include <aidl/android/hardware/camera/device/HalStream.h>
+#include <aidl/android/hardware/camera/device/NotifyMsg.h>
+#include <aidl/android/hardware/camera/device/Stream.h>
+#include <hardware/camera3.h>
+#include <system/camera_metadata.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::aidl::android::hardware::camera::device::BufferStatus;
+using ::aidl::android::hardware::camera::device::CameraMetadata;
+using ::aidl::android::hardware::camera::device::HalStream;
+using ::aidl::android::hardware::camera::device::NotifyMsg;
+using ::aidl::android::hardware::camera::device::Stream;
+
+void convertToAidl(const camera_metadata_t* src, CameraMetadata* dest);
+
+bool convertFromAidl(const CameraMetadata& src, const camera_metadata_t** dst);
+
+inline ndk::ScopedAStatus fromStatus(Status status) {
+    return status == Status::OK
+                   ? ndk::ScopedAStatus::ok()
+                   : ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+}  // namespace implementation
+}  // namespace device
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_CONVERT_H_
diff --git a/camera/metadata/aidl/Android.bp b/camera/metadata/aidl/Android.bp
index 31d4b4d..5872a86 100644
--- a/camera/metadata/aidl/Android.bp
+++ b/camera/metadata/aidl/Android.bp
@@ -11,6 +11,7 @@
     name: "android.hardware.camera.metadata",
     vendor_available: true,
     srcs: ["android/hardware/camera/metadata/*.aidl"],
+    frozen: true,
     stability: "vintf",
     backend: {
         cpp: {
@@ -19,10 +20,8 @@
         java: {
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
+        rust: {
+            enabled: true,
         },
     },
     versions_with_info: [
@@ -30,6 +29,11 @@
             version: "1",
             imports: [],
         },
+        {
+            version: "2",
+            imports: [],
+        },
+
     ],
 
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/.hash b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/.hash
new file mode 100644
index 0000000..c11d411
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/.hash
@@ -0,0 +1 @@
+634042390edccd6163f1ec2fb2ff56ff1befaad4
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/AutomotiveLensFacing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
new file mode 100644
index 0000000..18917f7
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum AutomotiveLensFacing {
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/AutomotiveLocation.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/AutomotiveLocation.aidl
new file mode 100644
index 0000000..ad6003f
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/AutomotiveLocation.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum AutomotiveLocation {
+  ANDROID_AUTOMOTIVE_LOCATION_INTERIOR,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/BlackLevelLock.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/BlackLevelLock.aidl
new file mode 100644
index 0000000..1f3e76f
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/BlackLevelLock.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum BlackLevelLock {
+  ANDROID_BLACK_LEVEL_LOCK_OFF,
+  ANDROID_BLACK_LEVEL_LOCK_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/CameraMetadataSection.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/CameraMetadataSection.aidl
new file mode 100644
index 0000000..138101b
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/CameraMetadataSection.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum CameraMetadataSection {
+  ANDROID_COLOR_CORRECTION,
+  ANDROID_CONTROL,
+  ANDROID_DEMOSAIC,
+  ANDROID_EDGE,
+  ANDROID_FLASH,
+  ANDROID_FLASH_INFO,
+  ANDROID_HOT_PIXEL,
+  ANDROID_JPEG,
+  ANDROID_LENS,
+  ANDROID_LENS_INFO,
+  ANDROID_NOISE_REDUCTION,
+  ANDROID_QUIRKS,
+  ANDROID_REQUEST,
+  ANDROID_SCALER,
+  ANDROID_SENSOR,
+  ANDROID_SENSOR_INFO,
+  ANDROID_SHADING,
+  ANDROID_STATISTICS,
+  ANDROID_STATISTICS_INFO,
+  ANDROID_TONEMAP,
+  ANDROID_LED,
+  ANDROID_INFO,
+  ANDROID_BLACK_LEVEL,
+  ANDROID_SYNC,
+  ANDROID_REPROCESS,
+  ANDROID_DEPTH,
+  ANDROID_LOGICAL_MULTI_CAMERA,
+  ANDROID_DISTORTION_CORRECTION,
+  ANDROID_HEIC,
+  ANDROID_HEIC_INFO,
+  ANDROID_AUTOMOTIVE,
+  ANDROID_AUTOMOTIVE_LENS,
+  ANDROID_EXTENSION,
+  ANDROID_JPEGR,
+  VENDOR_SECTION = 0x8000,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
new file mode 100644
index 0000000..85eee08
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum CameraMetadataSectionStart {
+  ANDROID_COLOR_CORRECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_COLOR_CORRECTION << 16) /* 0 */,
+  ANDROID_CONTROL_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_CONTROL << 16) /* 65536 */,
+  ANDROID_DEMOSAIC_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DEMOSAIC << 16) /* 131072 */,
+  ANDROID_EDGE_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_EDGE << 16) /* 196608 */,
+  ANDROID_FLASH_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_FLASH << 16) /* 262144 */,
+  ANDROID_FLASH_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_FLASH_INFO << 16) /* 327680 */,
+  ANDROID_HOT_PIXEL_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_HOT_PIXEL << 16) /* 393216 */,
+  ANDROID_JPEG_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_JPEG << 16) /* 458752 */,
+  ANDROID_LENS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LENS << 16) /* 524288 */,
+  ANDROID_LENS_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LENS_INFO << 16) /* 589824 */,
+  ANDROID_NOISE_REDUCTION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_NOISE_REDUCTION << 16) /* 655360 */,
+  ANDROID_QUIRKS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_QUIRKS << 16) /* 720896 */,
+  ANDROID_REQUEST_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_REQUEST << 16) /* 786432 */,
+  ANDROID_SCALER_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SCALER << 16) /* 851968 */,
+  ANDROID_SENSOR_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SENSOR << 16) /* 917504 */,
+  ANDROID_SENSOR_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SENSOR_INFO << 16) /* 983040 */,
+  ANDROID_SHADING_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SHADING << 16) /* 1048576 */,
+  ANDROID_STATISTICS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_STATISTICS << 16) /* 1114112 */,
+  ANDROID_STATISTICS_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_STATISTICS_INFO << 16) /* 1179648 */,
+  ANDROID_TONEMAP_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_TONEMAP << 16) /* 1245184 */,
+  ANDROID_LED_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LED << 16) /* 1310720 */,
+  ANDROID_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_INFO << 16) /* 1376256 */,
+  ANDROID_BLACK_LEVEL_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_BLACK_LEVEL << 16) /* 1441792 */,
+  ANDROID_SYNC_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SYNC << 16) /* 1507328 */,
+  ANDROID_REPROCESS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_REPROCESS << 16) /* 1572864 */,
+  ANDROID_DEPTH_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DEPTH << 16) /* 1638400 */,
+  ANDROID_LOGICAL_MULTI_CAMERA_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LOGICAL_MULTI_CAMERA << 16) /* 1703936 */,
+  ANDROID_DISTORTION_CORRECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DISTORTION_CORRECTION << 16) /* 1769472 */,
+  ANDROID_HEIC_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_HEIC << 16) /* 1835008 */,
+  ANDROID_HEIC_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_HEIC_INFO << 16) /* 1900544 */,
+  ANDROID_AUTOMOTIVE_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_AUTOMOTIVE << 16) /* 1966080 */,
+  ANDROID_AUTOMOTIVE_LENS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_AUTOMOTIVE_LENS << 16) /* 2031616 */,
+  ANDROID_EXTENSION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_EXTENSION << 16) /* 2097152 */,
+  ANDROID_JPEGR_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_JPEGR << 16) /* 2162688 */,
+  VENDOR_SECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.VENDOR_SECTION << 16) /* -2147483648 */,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/CameraMetadataTag.aidl
new file mode 100644
index 0000000..71d4e41
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum CameraMetadataTag {
+  ANDROID_COLOR_CORRECTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_COLOR_CORRECTION_START /* 0 */,
+  ANDROID_COLOR_CORRECTION_TRANSFORM,
+  ANDROID_COLOR_CORRECTION_GAINS,
+  ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
+  ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_CONTROL_START /* 65536 */,
+  ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+  ANDROID_CONTROL_AE_LOCK,
+  ANDROID_CONTROL_AE_MODE,
+  ANDROID_CONTROL_AE_REGIONS,
+  ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
+  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+  ANDROID_CONTROL_AF_MODE,
+  ANDROID_CONTROL_AF_REGIONS,
+  ANDROID_CONTROL_AF_TRIGGER,
+  ANDROID_CONTROL_AWB_LOCK,
+  ANDROID_CONTROL_AWB_MODE,
+  ANDROID_CONTROL_AWB_REGIONS,
+  ANDROID_CONTROL_CAPTURE_INTENT,
+  ANDROID_CONTROL_EFFECT_MODE,
+  ANDROID_CONTROL_MODE,
+  ANDROID_CONTROL_SCENE_MODE,
+  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+  ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
+  ANDROID_CONTROL_AE_AVAILABLE_MODES,
+  ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
+  ANDROID_CONTROL_AE_COMPENSATION_RANGE,
+  ANDROID_CONTROL_AE_COMPENSATION_STEP,
+  ANDROID_CONTROL_AF_AVAILABLE_MODES,
+  ANDROID_CONTROL_AVAILABLE_EFFECTS,
+  ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
+  ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
+  ANDROID_CONTROL_AWB_AVAILABLE_MODES,
+  ANDROID_CONTROL_MAX_REGIONS,
+  ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
+  ANDROID_CONTROL_AE_PRECAPTURE_ID,
+  ANDROID_CONTROL_AE_STATE,
+  ANDROID_CONTROL_AF_STATE,
+  ANDROID_CONTROL_AF_TRIGGER_ID,
+  ANDROID_CONTROL_AWB_STATE,
+  ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
+  ANDROID_CONTROL_AE_LOCK_AVAILABLE,
+  ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+  ANDROID_CONTROL_AVAILABLE_MODES,
+  ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
+  ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
+  ANDROID_CONTROL_ENABLE_ZSL,
+  ANDROID_CONTROL_AF_SCENE_CHANGE,
+  ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES,
+  ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES,
+  ANDROID_CONTROL_EXTENDED_SCENE_MODE,
+  ANDROID_CONTROL_ZOOM_RATIO_RANGE,
+  ANDROID_CONTROL_ZOOM_RATIO,
+  ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_CONTROL_SETTINGS_OVERRIDE = 65588,
+  ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
+  ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
+  ANDROID_CONTROL_AUTOFRAMING,
+  ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
+  ANDROID_CONTROL_AUTOFRAMING_STATE,
+  ANDROID_DEMOSAIC_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEMOSAIC_START /* 131072 */,
+  ANDROID_EDGE_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_EDGE_START /* 196608 */,
+  ANDROID_EDGE_STRENGTH,
+  ANDROID_EDGE_AVAILABLE_EDGE_MODES,
+  ANDROID_FLASH_FIRING_POWER = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_FLASH_START /* 262144 */,
+  ANDROID_FLASH_FIRING_TIME,
+  ANDROID_FLASH_MODE,
+  ANDROID_FLASH_COLOR_TEMPERATURE,
+  ANDROID_FLASH_MAX_ENERGY,
+  ANDROID_FLASH_STATE,
+  ANDROID_FLASH_INFO_AVAILABLE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_FLASH_INFO_START /* 327680 */,
+  ANDROID_FLASH_INFO_CHARGE_DURATION,
+  ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL,
+  ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL,
+  ANDROID_HOT_PIXEL_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HOT_PIXEL_START /* 393216 */,
+  ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
+  ANDROID_JPEG_GPS_COORDINATES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_JPEG_START /* 458752 */,
+  ANDROID_JPEG_GPS_PROCESSING_METHOD,
+  ANDROID_JPEG_GPS_TIMESTAMP,
+  ANDROID_JPEG_ORIENTATION,
+  ANDROID_JPEG_QUALITY,
+  ANDROID_JPEG_THUMBNAIL_QUALITY,
+  ANDROID_JPEG_THUMBNAIL_SIZE,
+  ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
+  ANDROID_JPEG_MAX_SIZE,
+  ANDROID_JPEG_SIZE,
+  ANDROID_LENS_APERTURE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LENS_START /* 524288 */,
+  ANDROID_LENS_FILTER_DENSITY,
+  ANDROID_LENS_FOCAL_LENGTH,
+  ANDROID_LENS_FOCUS_DISTANCE,
+  ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+  ANDROID_LENS_FACING,
+  ANDROID_LENS_POSE_ROTATION,
+  ANDROID_LENS_POSE_TRANSLATION,
+  ANDROID_LENS_FOCUS_RANGE,
+  ANDROID_LENS_STATE,
+  ANDROID_LENS_INTRINSIC_CALIBRATION,
+  ANDROID_LENS_RADIAL_DISTORTION,
+  ANDROID_LENS_POSE_REFERENCE,
+  ANDROID_LENS_DISTORTION,
+  ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION,
+  ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION,
+  ANDROID_LENS_INFO_AVAILABLE_APERTURES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LENS_INFO_START /* 589824 */,
+  ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
+  ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
+  ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
+  ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
+  ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
+  ANDROID_LENS_INFO_SHADING_MAP_SIZE,
+  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
+  ANDROID_NOISE_REDUCTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_NOISE_REDUCTION_START /* 655360 */,
+  ANDROID_NOISE_REDUCTION_STRENGTH,
+  ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
+  ANDROID_QUIRKS_METERING_CROP_REGION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_QUIRKS_START /* 720896 */,
+  ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO,
+  ANDROID_QUIRKS_USE_ZSL_FORMAT,
+  ANDROID_QUIRKS_USE_PARTIAL_RESULT,
+  ANDROID_QUIRKS_PARTIAL_RESULT,
+  ANDROID_REQUEST_FRAME_COUNT = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_REQUEST_START /* 786432 */,
+  ANDROID_REQUEST_ID,
+  ANDROID_REQUEST_INPUT_STREAMS,
+  ANDROID_REQUEST_METADATA_MODE,
+  ANDROID_REQUEST_OUTPUT_STREAMS,
+  ANDROID_REQUEST_TYPE,
+  ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
+  ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS,
+  ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
+  ANDROID_REQUEST_PIPELINE_DEPTH,
+  ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
+  ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+  ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
+  ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
+  ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
+  ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
+  ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS,
+  ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP,
+  ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE,
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP,
+  ANDROID_SCALER_CROP_REGION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SCALER_START /* 851968 */,
+  ANDROID_SCALER_AVAILABLE_FORMATS,
+  ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS,
+  ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
+  ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+  ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS,
+  ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
+  ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
+  ANDROID_SCALER_AVAILABLE_RAW_SIZES,
+  ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+  ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
+  ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
+  ANDROID_SCALER_CROPPING_TYPE,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP,
+  ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES,
+  ANDROID_SCALER_ROTATE_AND_CROP,
+  ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE,
+  ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION,
+  ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = 851994,
+  ANDROID_SCALER_RAW_CROP_REGION,
+  ANDROID_SENSOR_EXPOSURE_TIME = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SENSOR_START /* 917504 */,
+  ANDROID_SENSOR_FRAME_DURATION,
+  ANDROID_SENSOR_SENSITIVITY,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
+  ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
+  ANDROID_SENSOR_CALIBRATION_TRANSFORM2,
+  ANDROID_SENSOR_COLOR_TRANSFORM1,
+  ANDROID_SENSOR_COLOR_TRANSFORM2,
+  ANDROID_SENSOR_FORWARD_MATRIX1,
+  ANDROID_SENSOR_FORWARD_MATRIX2,
+  ANDROID_SENSOR_BASE_GAIN_FACTOR,
+  ANDROID_SENSOR_BLACK_LEVEL_PATTERN,
+  ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
+  ANDROID_SENSOR_ORIENTATION,
+  ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS,
+  ANDROID_SENSOR_TIMESTAMP,
+  ANDROID_SENSOR_TEMPERATURE,
+  ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
+  ANDROID_SENSOR_NOISE_PROFILE,
+  ANDROID_SENSOR_PROFILE_HUE_SAT_MAP,
+  ANDROID_SENSOR_PROFILE_TONE_CURVE,
+  ANDROID_SENSOR_GREEN_SPLIT,
+  ANDROID_SENSOR_TEST_PATTERN_DATA,
+  ANDROID_SENSOR_TEST_PATTERN_MODE,
+  ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
+  ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
+  ANDROID_SENSOR_OPTICAL_BLACK_REGIONS,
+  ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL,
+  ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL,
+  ANDROID_SENSOR_OPAQUE_RAW_SIZE,
+  ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION,
+  ANDROID_SENSOR_PIXEL_MODE,
+  ANDROID_SENSOR_RAW_BINNING_FACTOR_USED,
+  ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SENSOR_INFO_START /* 983040 */,
+  ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
+  ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
+  ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
+  ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
+  ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
+  ANDROID_SENSOR_INFO_WHITE_LEVEL,
+  ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
+  ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED,
+  ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
+  ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+  ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+  ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+  ANDROID_SENSOR_INFO_BINNING_FACTOR,
+  ANDROID_SHADING_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SHADING_START /* 1048576 */,
+  ANDROID_SHADING_STRENGTH,
+  ANDROID_SHADING_AVAILABLE_MODES,
+  ANDROID_STATISTICS_FACE_DETECT_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_STATISTICS_START /* 1114112 */,
+  ANDROID_STATISTICS_HISTOGRAM_MODE,
+  ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
+  ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
+  ANDROID_STATISTICS_FACE_IDS,
+  ANDROID_STATISTICS_FACE_LANDMARKS,
+  ANDROID_STATISTICS_FACE_RECTANGLES,
+  ANDROID_STATISTICS_FACE_SCORES,
+  ANDROID_STATISTICS_HISTOGRAM,
+  ANDROID_STATISTICS_SHARPNESS_MAP,
+  ANDROID_STATISTICS_LENS_SHADING_CORRECTION_MAP,
+  ANDROID_STATISTICS_LENS_SHADING_MAP,
+  ANDROID_STATISTICS_PREDICTED_COLOR_GAINS,
+  ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM,
+  ANDROID_STATISTICS_SCENE_FLICKER,
+  ANDROID_STATISTICS_HOT_PIXEL_MAP,
+  ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
+  ANDROID_STATISTICS_OIS_DATA_MODE,
+  ANDROID_STATISTICS_OIS_TIMESTAMPS,
+  ANDROID_STATISTICS_OIS_X_SHIFTS,
+  ANDROID_STATISTICS_OIS_Y_SHIFTS,
+  ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_STATISTICS_INFO_START /* 1179648 */,
+  ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
+  ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
+  ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
+  ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
+  ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
+  ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
+  ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
+  ANDROID_STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES,
+  ANDROID_TONEMAP_CURVE_BLUE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_TONEMAP_START /* 1245184 */,
+  ANDROID_TONEMAP_CURVE_GREEN,
+  ANDROID_TONEMAP_CURVE_RED,
+  ANDROID_TONEMAP_MODE,
+  ANDROID_TONEMAP_MAX_CURVE_POINTS,
+  ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
+  ANDROID_TONEMAP_GAMMA,
+  ANDROID_TONEMAP_PRESET_CURVE,
+  ANDROID_LED_TRANSMIT = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LED_START /* 1310720 */,
+  ANDROID_LED_AVAILABLE_LEDS,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_INFO_START /* 1376256 */,
+  ANDROID_INFO_VERSION,
+  ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
+  ANDROID_INFO_DEVICE_STATE_ORIENTATIONS,
+  ANDROID_BLACK_LEVEL_LOCK = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_BLACK_LEVEL_START /* 1441792 */,
+  ANDROID_SYNC_FRAME_NUMBER = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SYNC_START /* 1507328 */,
+  ANDROID_SYNC_MAX_LATENCY,
+  ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_REPROCESS_START /* 1572864 */,
+  ANDROID_REPROCESS_MAX_CAPTURE_STALL,
+  ANDROID_DEPTH_MAX_DEPTH_SAMPLES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEPTH_START /* 1638400 */,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
+  ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE,
+  ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LOGICAL_MULTI_CAMERA_START /* 1703936 */,
+  ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE,
+  ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID,
+  ANDROID_DISTORTION_CORRECTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DISTORTION_CORRECTION_START /* 1769472 */,
+  ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HEIC_START /* 1835008 */,
+  ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_INFO_SUPPORTED = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HEIC_INFO_START /* 1900544 */,
+  ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
+  ANDROID_AUTOMOTIVE_LOCATION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_START /* 1966080 */,
+  ANDROID_AUTOMOTIVE_LENS_FACING = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START /* 2031616 */,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_JPEGR_START /* 2162688 */,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
new file mode 100644
index 0000000..0b976f3
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ColorCorrectionAberrationMode {
+  ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
+  ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
+  ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ColorCorrectionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ColorCorrectionMode.aidl
new file mode 100644
index 0000000..2381605
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ColorCorrectionMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ColorCorrectionMode {
+  ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX,
+  ANDROID_COLOR_CORRECTION_MODE_FAST,
+  ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
new file mode 100644
index 0000000..0d5aad9
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAeAntibandingMode {
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeLock.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeLock.aidl
new file mode 100644
index 0000000..766b835
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeLock.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAeLock {
+  ANDROID_CONTROL_AE_LOCK_OFF,
+  ANDROID_CONTROL_AE_LOCK_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeLockAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
new file mode 100644
index 0000000..a22c93e
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAeLockAvailable {
+  ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE,
+  ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeMode.aidl
new file mode 100644
index 0000000..5e1b871
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeMode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAeMode {
+  ANDROID_CONTROL_AE_MODE_OFF,
+  ANDROID_CONTROL_AE_MODE_ON,
+  ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH,
+  ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
+  ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
+  ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
new file mode 100644
index 0000000..20382c0
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAePrecaptureTrigger {
+  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE,
+  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START,
+  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeState.aidl
new file mode 100644
index 0000000..e52eafe
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAeState.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAeState {
+  ANDROID_CONTROL_AE_STATE_INACTIVE,
+  ANDROID_CONTROL_AE_STATE_SEARCHING,
+  ANDROID_CONTROL_AE_STATE_CONVERGED,
+  ANDROID_CONTROL_AE_STATE_LOCKED,
+  ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED,
+  ANDROID_CONTROL_AE_STATE_PRECAPTURE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfMode.aidl
new file mode 100644
index 0000000..6cd46c6
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfMode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAfMode {
+  ANDROID_CONTROL_AF_MODE_OFF,
+  ANDROID_CONTROL_AF_MODE_AUTO,
+  ANDROID_CONTROL_AF_MODE_MACRO,
+  ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
+  ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
+  ANDROID_CONTROL_AF_MODE_EDOF,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfSceneChange.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfSceneChange.aidl
new file mode 100644
index 0000000..ba853a1
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfSceneChange.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAfSceneChange {
+  ANDROID_CONTROL_AF_SCENE_CHANGE_NOT_DETECTED,
+  ANDROID_CONTROL_AF_SCENE_CHANGE_DETECTED,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfState.aidl
new file mode 100644
index 0000000..25b6a1c
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfState.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAfState {
+  ANDROID_CONTROL_AF_STATE_INACTIVE,
+  ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN,
+  ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED,
+  ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN,
+  ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED,
+  ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED,
+  ANDROID_CONTROL_AF_STATE_PASSIVE_UNFOCUSED,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfTrigger.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfTrigger.aidl
new file mode 100644
index 0000000..9d61b2d
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAfTrigger.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAfTrigger {
+  ANDROID_CONTROL_AF_TRIGGER_IDLE,
+  ANDROID_CONTROL_AF_TRIGGER_START,
+  ANDROID_CONTROL_AF_TRIGGER_CANCEL,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAutoframing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAutoframing.aidl
new file mode 100644
index 0000000..2daf00b
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAutoframing.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAutoframing {
+  ANDROID_CONTROL_AUTOFRAMING_OFF,
+  ANDROID_CONTROL_AUTOFRAMING_ON,
+  ANDROID_CONTROL_AUTOFRAMING_AUTO,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
new file mode 100644
index 0000000..ab91bb4
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAutoframingAvailable {
+  ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE,
+  ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAutoframingState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAutoframingState.aidl
new file mode 100644
index 0000000..db0d288
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAutoframingState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAutoframingState {
+  ANDROID_CONTROL_AUTOFRAMING_STATE_INACTIVE,
+  ANDROID_CONTROL_AUTOFRAMING_STATE_FRAMING,
+  ANDROID_CONTROL_AUTOFRAMING_STATE_CONVERGED,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbLock.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbLock.aidl
new file mode 100644
index 0000000..949b5e8
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbLock.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAwbLock {
+  ANDROID_CONTROL_AWB_LOCK_OFF,
+  ANDROID_CONTROL_AWB_LOCK_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
new file mode 100644
index 0000000..80c4c31
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAwbLockAvailable {
+  ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE,
+  ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbMode.aidl
new file mode 100644
index 0000000..6ed9ece
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbMode.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAwbMode {
+  ANDROID_CONTROL_AWB_MODE_OFF,
+  ANDROID_CONTROL_AWB_MODE_AUTO,
+  ANDROID_CONTROL_AWB_MODE_INCANDESCENT,
+  ANDROID_CONTROL_AWB_MODE_FLUORESCENT,
+  ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT,
+  ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
+  ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT,
+  ANDROID_CONTROL_AWB_MODE_TWILIGHT,
+  ANDROID_CONTROL_AWB_MODE_SHADE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbState.aidl
new file mode 100644
index 0000000..c5b02d5
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlAwbState.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAwbState {
+  ANDROID_CONTROL_AWB_STATE_INACTIVE,
+  ANDROID_CONTROL_AWB_STATE_SEARCHING,
+  ANDROID_CONTROL_AWB_STATE_CONVERGED,
+  ANDROID_CONTROL_AWB_STATE_LOCKED,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlCaptureIntent.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlCaptureIntent.aidl
new file mode 100644
index 0000000..fa1c0a9
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlCaptureIntent.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlCaptureIntent {
+  ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM,
+  ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW,
+  ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE,
+  ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD,
+  ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT,
+  ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG,
+  ANDROID_CONTROL_CAPTURE_INTENT_MANUAL,
+  ANDROID_CONTROL_CAPTURE_INTENT_MOTION_TRACKING,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlEffectMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlEffectMode.aidl
new file mode 100644
index 0000000..471deed
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlEffectMode.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlEffectMode {
+  ANDROID_CONTROL_EFFECT_MODE_OFF,
+  ANDROID_CONTROL_EFFECT_MODE_MONO,
+  ANDROID_CONTROL_EFFECT_MODE_NEGATIVE,
+  ANDROID_CONTROL_EFFECT_MODE_SOLARIZE,
+  ANDROID_CONTROL_EFFECT_MODE_SEPIA,
+  ANDROID_CONTROL_EFFECT_MODE_POSTERIZE,
+  ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD,
+  ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD,
+  ANDROID_CONTROL_EFFECT_MODE_AQUA,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlEnableZsl.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlEnableZsl.aidl
new file mode 100644
index 0000000..3f2d4a3
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlEnableZsl.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlEnableZsl {
+  ANDROID_CONTROL_ENABLE_ZSL_FALSE,
+  ANDROID_CONTROL_ENABLE_ZSL_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
new file mode 100644
index 0000000..7838288
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlExtendedSceneMode {
+  ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED = 0,
+  ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE,
+  ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS,
+  ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START = 0x40,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlMode.aidl
new file mode 100644
index 0000000..c5a8172
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlMode.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlMode {
+  ANDROID_CONTROL_MODE_OFF,
+  ANDROID_CONTROL_MODE_AUTO,
+  ANDROID_CONTROL_MODE_USE_SCENE_MODE,
+  ANDROID_CONTROL_MODE_OFF_KEEP_STATE,
+  ANDROID_CONTROL_MODE_USE_EXTENDED_SCENE_MODE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlSceneMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlSceneMode.aidl
new file mode 100644
index 0000000..62c67e3
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlSceneMode.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlSceneMode {
+  ANDROID_CONTROL_SCENE_MODE_DISABLED = 0,
+  ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY,
+  ANDROID_CONTROL_SCENE_MODE_ACTION,
+  ANDROID_CONTROL_SCENE_MODE_PORTRAIT,
+  ANDROID_CONTROL_SCENE_MODE_LANDSCAPE,
+  ANDROID_CONTROL_SCENE_MODE_NIGHT,
+  ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT,
+  ANDROID_CONTROL_SCENE_MODE_THEATRE,
+  ANDROID_CONTROL_SCENE_MODE_BEACH,
+  ANDROID_CONTROL_SCENE_MODE_SNOW,
+  ANDROID_CONTROL_SCENE_MODE_SUNSET,
+  ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO,
+  ANDROID_CONTROL_SCENE_MODE_FIREWORKS,
+  ANDROID_CONTROL_SCENE_MODE_SPORTS,
+  ANDROID_CONTROL_SCENE_MODE_PARTY,
+  ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT,
+  ANDROID_CONTROL_SCENE_MODE_BARCODE,
+  ANDROID_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO,
+  ANDROID_CONTROL_SCENE_MODE_HDR,
+  ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT,
+  ANDROID_CONTROL_SCENE_MODE_DEVICE_CUSTOM_START = 100,
+  ANDROID_CONTROL_SCENE_MODE_DEVICE_CUSTOM_END = 127,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlSettingsOverride.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlSettingsOverride.aidl
new file mode 100644
index 0000000..404bbfa
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlSettingsOverride.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlSettingsOverride {
+  ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF,
+  ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM,
+  ANDROID_CONTROL_SETTINGS_OVERRIDE_VENDOR_START = 0x4000,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
new file mode 100644
index 0000000..2b199ef
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlVideoStabilizationMode {
+  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
+  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON,
+  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DemosaicMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DemosaicMode.aidl
new file mode 100644
index 0000000..5770009
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DemosaicMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DemosaicMode {
+  ANDROID_DEMOSAIC_MODE_FAST,
+  ANDROID_DEMOSAIC_MODE_HIGH_QUALITY,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
new file mode 100644
index 0000000..0cce2da
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DepthAvailableDepthStreamConfigurations {
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..9be06db
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DepthAvailableDepthStreamConfigurationsMaximumResolution {
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
new file mode 100644
index 0000000..c6aebaa
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DepthAvailableDynamicDepthStreamConfigurations {
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..4d5161d
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution {
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
new file mode 100644
index 0000000..f7b69cd
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DepthDepthIsExclusive {
+  ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE,
+  ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DistortionCorrectionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
new file mode 100644
index 0000000..6e965f6
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DistortionCorrectionMode {
+  ANDROID_DISTORTION_CORRECTION_MODE_OFF,
+  ANDROID_DISTORTION_CORRECTION_MODE_FAST,
+  ANDROID_DISTORTION_CORRECTION_MODE_HIGH_QUALITY,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/EdgeMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/EdgeMode.aidl
new file mode 100644
index 0000000..fdd32f4
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/EdgeMode.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum EdgeMode {
+  ANDROID_EDGE_MODE_OFF,
+  ANDROID_EDGE_MODE_FAST,
+  ANDROID_EDGE_MODE_HIGH_QUALITY,
+  ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/FlashInfoAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/FlashInfoAvailable.aidl
new file mode 100644
index 0000000..83292fe
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/FlashInfoAvailable.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum FlashInfoAvailable {
+  ANDROID_FLASH_INFO_AVAILABLE_FALSE,
+  ANDROID_FLASH_INFO_AVAILABLE_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/FlashMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/FlashMode.aidl
new file mode 100644
index 0000000..e18ea3c
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/FlashMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum FlashMode {
+  ANDROID_FLASH_MODE_OFF,
+  ANDROID_FLASH_MODE_SINGLE,
+  ANDROID_FLASH_MODE_TORCH,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/FlashState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/FlashState.aidl
new file mode 100644
index 0000000..4343d4f
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/FlashState.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum FlashState {
+  ANDROID_FLASH_STATE_UNAVAILABLE,
+  ANDROID_FLASH_STATE_CHARGING,
+  ANDROID_FLASH_STATE_READY,
+  ANDROID_FLASH_STATE_FIRED,
+  ANDROID_FLASH_STATE_PARTIAL,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
new file mode 100644
index 0000000..3957267
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum HeicAvailableHeicStreamConfigurations {
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..4eda538
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum HeicAvailableHeicStreamConfigurationsMaximumResolution {
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HeicInfoSupported.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HeicInfoSupported.aidl
new file mode 100644
index 0000000..7079bbf
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HeicInfoSupported.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum HeicInfoSupported {
+  ANDROID_HEIC_INFO_SUPPORTED_FALSE,
+  ANDROID_HEIC_INFO_SUPPORTED_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HotPixelMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HotPixelMode.aidl
new file mode 100644
index 0000000..50b3446
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/HotPixelMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum HotPixelMode {
+  ANDROID_HOT_PIXEL_MODE_OFF,
+  ANDROID_HOT_PIXEL_MODE_FAST,
+  ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
new file mode 100644
index 0000000..7303ff5
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum InfoSupportedBufferManagementVersion {
+  ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
new file mode 100644
index 0000000..3b50647
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum InfoSupportedHardwareLevel {
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
new file mode 100644
index 0000000..cf9dbb7
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum JpegrAvailableJpegRStreamConfigurations {
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..0a95e1f
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum JpegrAvailableJpegRStreamConfigurationsMaximumResolution {
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LedAvailableLeds.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LedAvailableLeds.aidl
new file mode 100644
index 0000000..b3beb2d
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LedAvailableLeds.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum LedAvailableLeds {
+  ANDROID_LED_AVAILABLE_LEDS_TRANSMIT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LedTransmit.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LedTransmit.aidl
new file mode 100644
index 0000000..0cbf239
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LedTransmit.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum LedTransmit {
+  ANDROID_LED_TRANSMIT_OFF,
+  ANDROID_LED_TRANSMIT_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensFacing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensFacing.aidl
new file mode 100644
index 0000000..d15674d
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensFacing.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum LensFacing {
+  ANDROID_LENS_FACING_FRONT,
+  ANDROID_LENS_FACING_BACK,
+  ANDROID_LENS_FACING_EXTERNAL,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
new file mode 100644
index 0000000..937347b
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum LensInfoFocusDistanceCalibration {
+  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED,
+  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE,
+  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
new file mode 100644
index 0000000..550d9f3
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum LensOpticalStabilizationMode {
+  ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
+  ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensPoseReference.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensPoseReference.aidl
new file mode 100644
index 0000000..6a3799d
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensPoseReference.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum LensPoseReference {
+  ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA,
+  ANDROID_LENS_POSE_REFERENCE_GYROSCOPE,
+  ANDROID_LENS_POSE_REFERENCE_UNDEFINED,
+  ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensState.aidl
new file mode 100644
index 0000000..4f98956
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LensState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum LensState {
+  ANDROID_LENS_STATE_STATIONARY,
+  ANDROID_LENS_STATE_MOVING,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
new file mode 100644
index 0000000..5eb5759
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum LogicalMultiCameraSensorSyncType {
+  ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE,
+  ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/NoiseReductionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/NoiseReductionMode.aidl
new file mode 100644
index 0000000..8b589ce
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/NoiseReductionMode.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum NoiseReductionMode {
+  ANDROID_NOISE_REDUCTION_MODE_OFF,
+  ANDROID_NOISE_REDUCTION_MODE_FAST,
+  ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY,
+  ANDROID_NOISE_REDUCTION_MODE_MINIMAL,
+  ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/QuirksPartialResult.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/QuirksPartialResult.aidl
new file mode 100644
index 0000000..8ab6a05
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/QuirksPartialResult.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum QuirksPartialResult {
+  ANDROID_QUIRKS_PARTIAL_RESULT_FINAL,
+  ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
new file mode 100644
index 0000000..0564db8
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum RequestAvailableCapabilities {
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
new file mode 100644
index 0000000..74606bf
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="long") @VintfStability
+enum RequestAvailableColorSpaceProfilesMap {
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED = (-1L) /* -1 */,
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB = 0L,
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3 = 7L,
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG = 16L,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
new file mode 100644
index 0000000..45ffb1b
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="long") @VintfStability
+enum RequestAvailableDynamicRangeProfilesMap {
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD = 0x1L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 0x2L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 0x4L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS = 0x8L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF = 0x10L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO = 0x20L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM = 0x40L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO = 0x80L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF = 0x100L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO = 0x200L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM = 0x400L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO = 0x800L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000L,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestMetadataMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestMetadataMode.aidl
new file mode 100644
index 0000000..cede799
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestMetadataMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum RequestMetadataMode {
+  ANDROID_REQUEST_METADATA_MODE_NONE,
+  ANDROID_REQUEST_METADATA_MODE_FULL,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestType.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestType.aidl
new file mode 100644
index 0000000..6b4ae71
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/RequestType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum RequestType {
+  ANDROID_REQUEST_TYPE_CAPTURE,
+  ANDROID_REQUEST_TYPE_REPROCESS,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableFormats.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
new file mode 100644
index 0000000..fdc2f60
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ScalerAvailableFormats {
+  ANDROID_SCALER_AVAILABLE_FORMATS_RAW16 = 0x20,
+  ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE = 0x24,
+  ANDROID_SCALER_AVAILABLE_FORMATS_YV12 = 0x32315659,
+  ANDROID_SCALER_AVAILABLE_FORMATS_YCrCb_420_SP = 0x11,
+  ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED = 0x22,
+  ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 = 0x23,
+  ANDROID_SCALER_AVAILABLE_FORMATS_BLOB = 0x21,
+  ANDROID_SCALER_AVAILABLE_FORMATS_RAW10 = 0x25,
+  ANDROID_SCALER_AVAILABLE_FORMATS_RAW12 = 0x26,
+  ANDROID_SCALER_AVAILABLE_FORMATS_Y8 = 0x20203859,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
new file mode 100644
index 0000000..741a99d
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ScalerAvailableRecommendedStreamConfigurations {
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW = 0x0,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD = 0x1,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT = 0x2,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT = 0x3,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL = 0x4,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW = 0x5,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT = 0x6,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT = 0x8,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START = 0x18,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
new file mode 100644
index 0000000..4e2899d
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ScalerAvailableStreamConfigurations {
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..fb15815
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ScalerAvailableStreamConfigurationsMaximumResolution {
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
new file mode 100644
index 0000000..ff92f9e
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="long") @VintfStability
+enum ScalerAvailableStreamUseCases {
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT = 0x0L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW = 0x1L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE = 0x2L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 0x6L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 0x10000L,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerCroppingType.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerCroppingType.aidl
new file mode 100644
index 0000000..60782e4
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerCroppingType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ScalerCroppingType {
+  ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY,
+  ANDROID_SCALER_CROPPING_TYPE_FREEFORM,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
new file mode 100644
index 0000000..e09d89c
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ScalerMultiResolutionStreamSupported {
+  ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_FALSE,
+  ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
new file mode 100644
index 0000000..64a0220
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ScalerPhysicalCameraMultiResolutionStreamConfigurations {
+  ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
new file mode 100644
index 0000000..bf5380e
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ScalerRotateAndCrop {
+  ANDROID_SCALER_ROTATE_AND_CROP_NONE,
+  ANDROID_SCALER_ROTATE_AND_CROP_90,
+  ANDROID_SCALER_ROTATE_AND_CROP_180,
+  ANDROID_SCALER_ROTATE_AND_CROP_270,
+  ANDROID_SCALER_ROTATE_AND_CROP_AUTO,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
new file mode 100644
index 0000000..c96f3c5
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SensorInfoColorFilterArrangement {
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
new file mode 100644
index 0000000..0153731
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SensorInfoLensShadingApplied {
+  ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_FALSE,
+  ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
new file mode 100644
index 0000000..9a00cf1
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SensorInfoTimestampSource {
+  ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN,
+  ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorPixelMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorPixelMode.aidl
new file mode 100644
index 0000000..5f055d6
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorPixelMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SensorPixelMode {
+  ANDROID_SENSOR_PIXEL_MODE_DEFAULT,
+  ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
new file mode 100644
index 0000000..851dae0
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SensorRawBinningFactorUsed {
+  ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_TRUE,
+  ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_FALSE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorReferenceIlluminant1.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorReferenceIlluminant1.aidl
new file mode 100644
index 0000000..cd22d2e
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorReferenceIlluminant1.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SensorReferenceIlluminant1 {
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT = 1,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT = 2,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN = 3,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FLASH = 4,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER = 9,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER = 10,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_SHADE = 11,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT = 12,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT = 13,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT = 14,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT = 15,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A = 17,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B = 18,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C = 19,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D55 = 20,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D65 = 21,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D75 = 22,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D50 = 23,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN = 24,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorTestPatternMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorTestPatternMode.aidl
new file mode 100644
index 0000000..98f0ebe
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SensorTestPatternMode.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SensorTestPatternMode {
+  ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_PN9,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ShadingMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ShadingMode.aidl
new file mode 100644
index 0000000..ffc6a56
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/ShadingMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ShadingMode {
+  ANDROID_SHADING_MODE_OFF,
+  ANDROID_SHADING_MODE_FAST,
+  ANDROID_SHADING_MODE_HIGH_QUALITY,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
new file mode 100644
index 0000000..48c6797
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum StatisticsFaceDetectMode {
+  ANDROID_STATISTICS_FACE_DETECT_MODE_OFF,
+  ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE,
+  ANDROID_STATISTICS_FACE_DETECT_MODE_FULL,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsHistogramMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
new file mode 100644
index 0000000..354518b
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum StatisticsHistogramMode {
+  ANDROID_STATISTICS_HISTOGRAM_MODE_OFF,
+  ANDROID_STATISTICS_HISTOGRAM_MODE_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
new file mode 100644
index 0000000..b96e4be
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum StatisticsHotPixelMapMode {
+  ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF,
+  ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
new file mode 100644
index 0000000..7d0b082
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum StatisticsLensShadingMapMode {
+  ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF,
+  ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsOisDataMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
new file mode 100644
index 0000000..b80889b
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum StatisticsOisDataMode {
+  ANDROID_STATISTICS_OIS_DATA_MODE_OFF,
+  ANDROID_STATISTICS_OIS_DATA_MODE_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
new file mode 100644
index 0000000..a9268c0
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum StatisticsSceneFlicker {
+  ANDROID_STATISTICS_SCENE_FLICKER_NONE,
+  ANDROID_STATISTICS_SCENE_FLICKER_50HZ,
+  ANDROID_STATISTICS_SCENE_FLICKER_60HZ,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
new file mode 100644
index 0000000..09a2003
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum StatisticsSharpnessMapMode {
+  ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF,
+  ANDROID_STATISTICS_SHARPNESS_MAP_MODE_ON,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SyncFrameNumber.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SyncFrameNumber.aidl
new file mode 100644
index 0000000..230f57e
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SyncFrameNumber.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SyncFrameNumber {
+  ANDROID_SYNC_FRAME_NUMBER_CONVERGING = (-1) /* -1 */,
+  ANDROID_SYNC_FRAME_NUMBER_UNKNOWN = (-2) /* -2 */,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SyncMaxLatency.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SyncMaxLatency.aidl
new file mode 100644
index 0000000..d484f45
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/SyncMaxLatency.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum SyncMaxLatency {
+  ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL = 0,
+  ANDROID_SYNC_MAX_LATENCY_UNKNOWN = (-1) /* -1 */,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/TonemapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/TonemapMode.aidl
new file mode 100644
index 0000000..e729166
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/TonemapMode.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum TonemapMode {
+  ANDROID_TONEMAP_MODE_CONTRAST_CURVE,
+  ANDROID_TONEMAP_MODE_FAST,
+  ANDROID_TONEMAP_MODE_HIGH_QUALITY,
+  ANDROID_TONEMAP_MODE_GAMMA_VALUE,
+  ANDROID_TONEMAP_MODE_PRESET_CURVE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/TonemapPresetCurve.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/TonemapPresetCurve.aidl
new file mode 100644
index 0000000..2e5fbd3
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/2/android/hardware/camera/metadata/TonemapPresetCurve.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum TonemapPresetCurve {
+  ANDROID_TONEMAP_PRESET_CURVE_SRGB,
+  ANDROID_TONEMAP_PRESET_CURVE_REC709,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
index 14ad26e..18917f7 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
@@ -38,19 +38,19 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum AutomotiveLensFacing {
-  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER = 0,
-  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT = 1,
-  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR = 2,
-  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT = 3,
-  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT = 4,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER = 5,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT = 6,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER = 7,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT = 8,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT = 9,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER = 10,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT = 11,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT = 12,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER = 13,
-  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT = 14,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER,
+  ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl
index 5417bdb..ad6003f 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl
@@ -38,15 +38,15 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum AutomotiveLocation {
-  ANDROID_AUTOMOTIVE_LOCATION_INTERIOR = 0,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER = 1,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT = 2,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR = 3,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT = 4,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT = 5,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER = 6,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT = 7,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR = 8,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT = 9,
-  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT = 10,
+  ANDROID_AUTOMOTIVE_LOCATION_INTERIOR,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT,
+  ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/BlackLevelLock.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/BlackLevelLock.aidl
index dcefa2f..1f3e76f 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/BlackLevelLock.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/BlackLevelLock.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum BlackLevelLock {
-  ANDROID_BLACK_LEVEL_LOCK_OFF = 0,
-  ANDROID_BLACK_LEVEL_LOCK_ON = 1,
+  ANDROID_BLACK_LEVEL_LOCK_OFF,
+  ANDROID_BLACK_LEVEL_LOCK_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
index 8bed156..138101b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
@@ -38,37 +38,39 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum CameraMetadataSection {
-  ANDROID_COLOR_CORRECTION = 0,
-  ANDROID_CONTROL = 1,
-  ANDROID_DEMOSAIC = 2,
-  ANDROID_EDGE = 3,
-  ANDROID_FLASH = 4,
-  ANDROID_FLASH_INFO = 5,
-  ANDROID_HOT_PIXEL = 6,
-  ANDROID_JPEG = 7,
-  ANDROID_LENS = 8,
-  ANDROID_LENS_INFO = 9,
-  ANDROID_NOISE_REDUCTION = 10,
-  ANDROID_QUIRKS = 11,
-  ANDROID_REQUEST = 12,
-  ANDROID_SCALER = 13,
-  ANDROID_SENSOR = 14,
-  ANDROID_SENSOR_INFO = 15,
-  ANDROID_SHADING = 16,
-  ANDROID_STATISTICS = 17,
-  ANDROID_STATISTICS_INFO = 18,
-  ANDROID_TONEMAP = 19,
-  ANDROID_LED = 20,
-  ANDROID_INFO = 21,
-  ANDROID_BLACK_LEVEL = 22,
-  ANDROID_SYNC = 23,
-  ANDROID_REPROCESS = 24,
-  ANDROID_DEPTH = 25,
-  ANDROID_LOGICAL_MULTI_CAMERA = 26,
-  ANDROID_DISTORTION_CORRECTION = 27,
-  ANDROID_HEIC = 28,
-  ANDROID_HEIC_INFO = 29,
-  ANDROID_AUTOMOTIVE = 30,
-  ANDROID_AUTOMOTIVE_LENS = 31,
-  VENDOR_SECTION = 32768,
+  ANDROID_COLOR_CORRECTION,
+  ANDROID_CONTROL,
+  ANDROID_DEMOSAIC,
+  ANDROID_EDGE,
+  ANDROID_FLASH,
+  ANDROID_FLASH_INFO,
+  ANDROID_HOT_PIXEL,
+  ANDROID_JPEG,
+  ANDROID_LENS,
+  ANDROID_LENS_INFO,
+  ANDROID_NOISE_REDUCTION,
+  ANDROID_QUIRKS,
+  ANDROID_REQUEST,
+  ANDROID_SCALER,
+  ANDROID_SENSOR,
+  ANDROID_SENSOR_INFO,
+  ANDROID_SHADING,
+  ANDROID_STATISTICS,
+  ANDROID_STATISTICS_INFO,
+  ANDROID_TONEMAP,
+  ANDROID_LED,
+  ANDROID_INFO,
+  ANDROID_BLACK_LEVEL,
+  ANDROID_SYNC,
+  ANDROID_REPROCESS,
+  ANDROID_DEPTH,
+  ANDROID_LOGICAL_MULTI_CAMERA,
+  ANDROID_DISTORTION_CORRECTION,
+  ANDROID_HEIC,
+  ANDROID_HEIC_INFO,
+  ANDROID_AUTOMOTIVE,
+  ANDROID_AUTOMOTIVE_LENS,
+  ANDROID_EXTENSION,
+  ANDROID_JPEGR,
+  VENDOR_SECTION = 0x8000,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
index 1725347..85eee08 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
@@ -38,37 +38,39 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum CameraMetadataSectionStart {
-  ANDROID_COLOR_CORRECTION_START = 0,
-  ANDROID_CONTROL_START = 65536,
-  ANDROID_DEMOSAIC_START = 131072,
-  ANDROID_EDGE_START = 196608,
-  ANDROID_FLASH_START = 262144,
-  ANDROID_FLASH_INFO_START = 327680,
-  ANDROID_HOT_PIXEL_START = 393216,
-  ANDROID_JPEG_START = 458752,
-  ANDROID_LENS_START = 524288,
-  ANDROID_LENS_INFO_START = 589824,
-  ANDROID_NOISE_REDUCTION_START = 655360,
-  ANDROID_QUIRKS_START = 720896,
-  ANDROID_REQUEST_START = 786432,
-  ANDROID_SCALER_START = 851968,
-  ANDROID_SENSOR_START = 917504,
-  ANDROID_SENSOR_INFO_START = 983040,
-  ANDROID_SHADING_START = 1048576,
-  ANDROID_STATISTICS_START = 1114112,
-  ANDROID_STATISTICS_INFO_START = 1179648,
-  ANDROID_TONEMAP_START = 1245184,
-  ANDROID_LED_START = 1310720,
-  ANDROID_INFO_START = 1376256,
-  ANDROID_BLACK_LEVEL_START = 1441792,
-  ANDROID_SYNC_START = 1507328,
-  ANDROID_REPROCESS_START = 1572864,
-  ANDROID_DEPTH_START = 1638400,
-  ANDROID_LOGICAL_MULTI_CAMERA_START = 1703936,
-  ANDROID_DISTORTION_CORRECTION_START = 1769472,
-  ANDROID_HEIC_START = 1835008,
-  ANDROID_HEIC_INFO_START = 1900544,
-  ANDROID_AUTOMOTIVE_START = 1966080,
-  ANDROID_AUTOMOTIVE_LENS_START = 2031616,
-  VENDOR_SECTION_START = -2147483648,
+  ANDROID_COLOR_CORRECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_COLOR_CORRECTION << 16) /* 0 */,
+  ANDROID_CONTROL_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_CONTROL << 16) /* 65536 */,
+  ANDROID_DEMOSAIC_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DEMOSAIC << 16) /* 131072 */,
+  ANDROID_EDGE_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_EDGE << 16) /* 196608 */,
+  ANDROID_FLASH_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_FLASH << 16) /* 262144 */,
+  ANDROID_FLASH_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_FLASH_INFO << 16) /* 327680 */,
+  ANDROID_HOT_PIXEL_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_HOT_PIXEL << 16) /* 393216 */,
+  ANDROID_JPEG_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_JPEG << 16) /* 458752 */,
+  ANDROID_LENS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LENS << 16) /* 524288 */,
+  ANDROID_LENS_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LENS_INFO << 16) /* 589824 */,
+  ANDROID_NOISE_REDUCTION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_NOISE_REDUCTION << 16) /* 655360 */,
+  ANDROID_QUIRKS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_QUIRKS << 16) /* 720896 */,
+  ANDROID_REQUEST_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_REQUEST << 16) /* 786432 */,
+  ANDROID_SCALER_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SCALER << 16) /* 851968 */,
+  ANDROID_SENSOR_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SENSOR << 16) /* 917504 */,
+  ANDROID_SENSOR_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SENSOR_INFO << 16) /* 983040 */,
+  ANDROID_SHADING_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SHADING << 16) /* 1048576 */,
+  ANDROID_STATISTICS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_STATISTICS << 16) /* 1114112 */,
+  ANDROID_STATISTICS_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_STATISTICS_INFO << 16) /* 1179648 */,
+  ANDROID_TONEMAP_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_TONEMAP << 16) /* 1245184 */,
+  ANDROID_LED_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LED << 16) /* 1310720 */,
+  ANDROID_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_INFO << 16) /* 1376256 */,
+  ANDROID_BLACK_LEVEL_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_BLACK_LEVEL << 16) /* 1441792 */,
+  ANDROID_SYNC_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SYNC << 16) /* 1507328 */,
+  ANDROID_REPROCESS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_REPROCESS << 16) /* 1572864 */,
+  ANDROID_DEPTH_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DEPTH << 16) /* 1638400 */,
+  ANDROID_LOGICAL_MULTI_CAMERA_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LOGICAL_MULTI_CAMERA << 16) /* 1703936 */,
+  ANDROID_DISTORTION_CORRECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DISTORTION_CORRECTION << 16) /* 1769472 */,
+  ANDROID_HEIC_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_HEIC << 16) /* 1835008 */,
+  ANDROID_HEIC_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_HEIC_INFO << 16) /* 1900544 */,
+  ANDROID_AUTOMOTIVE_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_AUTOMOTIVE << 16) /* 1966080 */,
+  ANDROID_AUTOMOTIVE_LENS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_AUTOMOTIVE_LENS << 16) /* 2031616 */,
+  ANDROID_EXTENSION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_EXTENSION << 16) /* 2097152 */,
+  ANDROID_JPEGR_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_JPEGR << 16) /* 2162688 */,
+  VENDOR_SECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.VENDOR_SECTION << 16) /* -2147483648 */,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 9bb55d2..71d4e41 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -38,294 +38,308 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum CameraMetadataTag {
-  ANDROID_COLOR_CORRECTION_MODE = 0,
-  ANDROID_COLOR_CORRECTION_TRANSFORM = 1,
-  ANDROID_COLOR_CORRECTION_GAINS = 2,
-  ANDROID_COLOR_CORRECTION_ABERRATION_MODE = 3,
-  ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES = 4,
-  ANDROID_CONTROL_AE_ANTIBANDING_MODE = 65536,
-  ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION = 65537,
-  ANDROID_CONTROL_AE_LOCK = 65538,
-  ANDROID_CONTROL_AE_MODE = 65539,
-  ANDROID_CONTROL_AE_REGIONS = 65540,
-  ANDROID_CONTROL_AE_TARGET_FPS_RANGE = 65541,
-  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER = 65542,
-  ANDROID_CONTROL_AF_MODE = 65543,
-  ANDROID_CONTROL_AF_REGIONS = 65544,
-  ANDROID_CONTROL_AF_TRIGGER = 65545,
-  ANDROID_CONTROL_AWB_LOCK = 65546,
-  ANDROID_CONTROL_AWB_MODE = 65547,
-  ANDROID_CONTROL_AWB_REGIONS = 65548,
-  ANDROID_CONTROL_CAPTURE_INTENT = 65549,
-  ANDROID_CONTROL_EFFECT_MODE = 65550,
-  ANDROID_CONTROL_MODE = 65551,
-  ANDROID_CONTROL_SCENE_MODE = 65552,
-  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE = 65553,
-  ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES = 65554,
-  ANDROID_CONTROL_AE_AVAILABLE_MODES = 65555,
-  ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES = 65556,
-  ANDROID_CONTROL_AE_COMPENSATION_RANGE = 65557,
-  ANDROID_CONTROL_AE_COMPENSATION_STEP = 65558,
-  ANDROID_CONTROL_AF_AVAILABLE_MODES = 65559,
-  ANDROID_CONTROL_AVAILABLE_EFFECTS = 65560,
-  ANDROID_CONTROL_AVAILABLE_SCENE_MODES = 65561,
-  ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES = 65562,
-  ANDROID_CONTROL_AWB_AVAILABLE_MODES = 65563,
-  ANDROID_CONTROL_MAX_REGIONS = 65564,
-  ANDROID_CONTROL_SCENE_MODE_OVERRIDES = 65565,
-  ANDROID_CONTROL_AE_PRECAPTURE_ID = 65566,
-  ANDROID_CONTROL_AE_STATE = 65567,
-  ANDROID_CONTROL_AF_STATE = 65568,
-  ANDROID_CONTROL_AF_TRIGGER_ID = 65569,
-  ANDROID_CONTROL_AWB_STATE = 65570,
-  ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS = 65571,
-  ANDROID_CONTROL_AE_LOCK_AVAILABLE = 65572,
-  ANDROID_CONTROL_AWB_LOCK_AVAILABLE = 65573,
-  ANDROID_CONTROL_AVAILABLE_MODES = 65574,
-  ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE = 65575,
-  ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST = 65576,
-  ANDROID_CONTROL_ENABLE_ZSL = 65577,
-  ANDROID_CONTROL_AF_SCENE_CHANGE = 65578,
-  ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES = 65579,
-  ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES = 65580,
-  ANDROID_CONTROL_EXTENDED_SCENE_MODE = 65581,
-  ANDROID_CONTROL_ZOOM_RATIO_RANGE = 65582,
-  ANDROID_CONTROL_ZOOM_RATIO = 65583,
-  ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION = 65584,
-  ANDROID_DEMOSAIC_MODE = 131072,
-  ANDROID_EDGE_MODE = 196608,
-  ANDROID_EDGE_STRENGTH = 196609,
-  ANDROID_EDGE_AVAILABLE_EDGE_MODES = 196610,
-  ANDROID_FLASH_FIRING_POWER = 262144,
-  ANDROID_FLASH_FIRING_TIME = 262145,
-  ANDROID_FLASH_MODE = 262146,
-  ANDROID_FLASH_COLOR_TEMPERATURE = 262147,
-  ANDROID_FLASH_MAX_ENERGY = 262148,
-  ANDROID_FLASH_STATE = 262149,
-  ANDROID_FLASH_INFO_AVAILABLE = 327680,
-  ANDROID_FLASH_INFO_CHARGE_DURATION = 327681,
-  ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL = 327682,
-  ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL = 327683,
-  ANDROID_HOT_PIXEL_MODE = 393216,
-  ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES = 393217,
-  ANDROID_JPEG_GPS_COORDINATES = 458752,
-  ANDROID_JPEG_GPS_PROCESSING_METHOD = 458753,
-  ANDROID_JPEG_GPS_TIMESTAMP = 458754,
-  ANDROID_JPEG_ORIENTATION = 458755,
-  ANDROID_JPEG_QUALITY = 458756,
-  ANDROID_JPEG_THUMBNAIL_QUALITY = 458757,
-  ANDROID_JPEG_THUMBNAIL_SIZE = 458758,
-  ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES = 458759,
-  ANDROID_JPEG_MAX_SIZE = 458760,
-  ANDROID_JPEG_SIZE = 458761,
-  ANDROID_LENS_APERTURE = 524288,
-  ANDROID_LENS_FILTER_DENSITY = 524289,
-  ANDROID_LENS_FOCAL_LENGTH = 524290,
-  ANDROID_LENS_FOCUS_DISTANCE = 524291,
-  ANDROID_LENS_OPTICAL_STABILIZATION_MODE = 524292,
-  ANDROID_LENS_FACING = 524293,
-  ANDROID_LENS_POSE_ROTATION = 524294,
-  ANDROID_LENS_POSE_TRANSLATION = 524295,
-  ANDROID_LENS_FOCUS_RANGE = 524296,
-  ANDROID_LENS_STATE = 524297,
-  ANDROID_LENS_INTRINSIC_CALIBRATION = 524298,
-  ANDROID_LENS_RADIAL_DISTORTION = 524299,
-  ANDROID_LENS_POSE_REFERENCE = 524300,
-  ANDROID_LENS_DISTORTION = 524301,
-  ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION = 524302,
-  ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION = 524303,
-  ANDROID_LENS_INFO_AVAILABLE_APERTURES = 589824,
-  ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES = 589825,
-  ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS = 589826,
-  ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION = 589827,
-  ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE = 589828,
-  ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE = 589829,
-  ANDROID_LENS_INFO_SHADING_MAP_SIZE = 589830,
-  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION = 589831,
-  ANDROID_NOISE_REDUCTION_MODE = 655360,
-  ANDROID_NOISE_REDUCTION_STRENGTH = 655361,
-  ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES = 655362,
-  ANDROID_QUIRKS_METERING_CROP_REGION = 720896,
-  ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO = 720897,
-  ANDROID_QUIRKS_USE_ZSL_FORMAT = 720898,
-  ANDROID_QUIRKS_USE_PARTIAL_RESULT = 720899,
-  ANDROID_QUIRKS_PARTIAL_RESULT = 720900,
-  ANDROID_REQUEST_FRAME_COUNT = 786432,
-  ANDROID_REQUEST_ID = 786433,
-  ANDROID_REQUEST_INPUT_STREAMS = 786434,
-  ANDROID_REQUEST_METADATA_MODE = 786435,
-  ANDROID_REQUEST_OUTPUT_STREAMS = 786436,
-  ANDROID_REQUEST_TYPE = 786437,
-  ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS = 786438,
-  ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS = 786439,
-  ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS = 786440,
-  ANDROID_REQUEST_PIPELINE_DEPTH = 786441,
-  ANDROID_REQUEST_PIPELINE_MAX_DEPTH = 786442,
-  ANDROID_REQUEST_PARTIAL_RESULT_COUNT = 786443,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES = 786444,
-  ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS = 786445,
-  ANDROID_REQUEST_AVAILABLE_RESULT_KEYS = 786446,
-  ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS = 786447,
-  ANDROID_REQUEST_AVAILABLE_SESSION_KEYS = 786448,
-  ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS = 786449,
-  ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION = 786450,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP = 786451,
-  ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE = 786452,
-  ANDROID_SCALER_CROP_REGION = 851968,
-  ANDROID_SCALER_AVAILABLE_FORMATS = 851969,
-  ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS = 851970,
-  ANDROID_SCALER_AVAILABLE_JPEG_SIZES = 851971,
-  ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM = 851972,
-  ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS = 851973,
-  ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES = 851974,
-  ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS = 851975,
-  ANDROID_SCALER_AVAILABLE_RAW_SIZES = 851976,
-  ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP = 851977,
-  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS = 851978,
-  ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS = 851979,
-  ANDROID_SCALER_AVAILABLE_STALL_DURATIONS = 851980,
-  ANDROID_SCALER_CROPPING_TYPE = 851981,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS = 851982,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP = 851983,
-  ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES = 851984,
-  ANDROID_SCALER_ROTATE_AND_CROP = 851985,
-  ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE = 851986,
-  ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS = 851987,
-  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = 851988,
-  ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION = 851989,
-  ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION = 851990,
-  ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION = 851991,
-  ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED = 851992,
+  ANDROID_COLOR_CORRECTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_COLOR_CORRECTION_START /* 0 */,
+  ANDROID_COLOR_CORRECTION_TRANSFORM,
+  ANDROID_COLOR_CORRECTION_GAINS,
+  ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
+  ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_CONTROL_START /* 65536 */,
+  ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+  ANDROID_CONTROL_AE_LOCK,
+  ANDROID_CONTROL_AE_MODE,
+  ANDROID_CONTROL_AE_REGIONS,
+  ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
+  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+  ANDROID_CONTROL_AF_MODE,
+  ANDROID_CONTROL_AF_REGIONS,
+  ANDROID_CONTROL_AF_TRIGGER,
+  ANDROID_CONTROL_AWB_LOCK,
+  ANDROID_CONTROL_AWB_MODE,
+  ANDROID_CONTROL_AWB_REGIONS,
+  ANDROID_CONTROL_CAPTURE_INTENT,
+  ANDROID_CONTROL_EFFECT_MODE,
+  ANDROID_CONTROL_MODE,
+  ANDROID_CONTROL_SCENE_MODE,
+  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+  ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
+  ANDROID_CONTROL_AE_AVAILABLE_MODES,
+  ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
+  ANDROID_CONTROL_AE_COMPENSATION_RANGE,
+  ANDROID_CONTROL_AE_COMPENSATION_STEP,
+  ANDROID_CONTROL_AF_AVAILABLE_MODES,
+  ANDROID_CONTROL_AVAILABLE_EFFECTS,
+  ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
+  ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
+  ANDROID_CONTROL_AWB_AVAILABLE_MODES,
+  ANDROID_CONTROL_MAX_REGIONS,
+  ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
+  ANDROID_CONTROL_AE_PRECAPTURE_ID,
+  ANDROID_CONTROL_AE_STATE,
+  ANDROID_CONTROL_AF_STATE,
+  ANDROID_CONTROL_AF_TRIGGER_ID,
+  ANDROID_CONTROL_AWB_STATE,
+  ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
+  ANDROID_CONTROL_AE_LOCK_AVAILABLE,
+  ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+  ANDROID_CONTROL_AVAILABLE_MODES,
+  ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
+  ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
+  ANDROID_CONTROL_ENABLE_ZSL,
+  ANDROID_CONTROL_AF_SCENE_CHANGE,
+  ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES,
+  ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES,
+  ANDROID_CONTROL_EXTENDED_SCENE_MODE,
+  ANDROID_CONTROL_ZOOM_RATIO_RANGE,
+  ANDROID_CONTROL_ZOOM_RATIO,
+  ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_CONTROL_SETTINGS_OVERRIDE = 65588,
+  ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
+  ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
+  ANDROID_CONTROL_AUTOFRAMING,
+  ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
+  ANDROID_CONTROL_AUTOFRAMING_STATE,
+  ANDROID_DEMOSAIC_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEMOSAIC_START /* 131072 */,
+  ANDROID_EDGE_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_EDGE_START /* 196608 */,
+  ANDROID_EDGE_STRENGTH,
+  ANDROID_EDGE_AVAILABLE_EDGE_MODES,
+  ANDROID_FLASH_FIRING_POWER = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_FLASH_START /* 262144 */,
+  ANDROID_FLASH_FIRING_TIME,
+  ANDROID_FLASH_MODE,
+  ANDROID_FLASH_COLOR_TEMPERATURE,
+  ANDROID_FLASH_MAX_ENERGY,
+  ANDROID_FLASH_STATE,
+  ANDROID_FLASH_INFO_AVAILABLE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_FLASH_INFO_START /* 327680 */,
+  ANDROID_FLASH_INFO_CHARGE_DURATION,
+  ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL,
+  ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL,
+  ANDROID_HOT_PIXEL_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HOT_PIXEL_START /* 393216 */,
+  ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
+  ANDROID_JPEG_GPS_COORDINATES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_JPEG_START /* 458752 */,
+  ANDROID_JPEG_GPS_PROCESSING_METHOD,
+  ANDROID_JPEG_GPS_TIMESTAMP,
+  ANDROID_JPEG_ORIENTATION,
+  ANDROID_JPEG_QUALITY,
+  ANDROID_JPEG_THUMBNAIL_QUALITY,
+  ANDROID_JPEG_THUMBNAIL_SIZE,
+  ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
+  ANDROID_JPEG_MAX_SIZE,
+  ANDROID_JPEG_SIZE,
+  ANDROID_LENS_APERTURE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LENS_START /* 524288 */,
+  ANDROID_LENS_FILTER_DENSITY,
+  ANDROID_LENS_FOCAL_LENGTH,
+  ANDROID_LENS_FOCUS_DISTANCE,
+  ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+  ANDROID_LENS_FACING,
+  ANDROID_LENS_POSE_ROTATION,
+  ANDROID_LENS_POSE_TRANSLATION,
+  ANDROID_LENS_FOCUS_RANGE,
+  ANDROID_LENS_STATE,
+  ANDROID_LENS_INTRINSIC_CALIBRATION,
+  ANDROID_LENS_RADIAL_DISTORTION,
+  ANDROID_LENS_POSE_REFERENCE,
+  ANDROID_LENS_DISTORTION,
+  ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION,
+  ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION,
+  ANDROID_LENS_INFO_AVAILABLE_APERTURES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LENS_INFO_START /* 589824 */,
+  ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
+  ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
+  ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
+  ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
+  ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
+  ANDROID_LENS_INFO_SHADING_MAP_SIZE,
+  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
+  ANDROID_NOISE_REDUCTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_NOISE_REDUCTION_START /* 655360 */,
+  ANDROID_NOISE_REDUCTION_STRENGTH,
+  ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
+  ANDROID_QUIRKS_METERING_CROP_REGION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_QUIRKS_START /* 720896 */,
+  ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO,
+  ANDROID_QUIRKS_USE_ZSL_FORMAT,
+  ANDROID_QUIRKS_USE_PARTIAL_RESULT,
+  ANDROID_QUIRKS_PARTIAL_RESULT,
+  ANDROID_REQUEST_FRAME_COUNT = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_REQUEST_START /* 786432 */,
+  ANDROID_REQUEST_ID,
+  ANDROID_REQUEST_INPUT_STREAMS,
+  ANDROID_REQUEST_METADATA_MODE,
+  ANDROID_REQUEST_OUTPUT_STREAMS,
+  ANDROID_REQUEST_TYPE,
+  ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
+  ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS,
+  ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
+  ANDROID_REQUEST_PIPELINE_DEPTH,
+  ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
+  ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+  ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
+  ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
+  ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
+  ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
+  ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS,
+  ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP,
+  ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE,
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP,
+  ANDROID_SCALER_CROP_REGION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SCALER_START /* 851968 */,
+  ANDROID_SCALER_AVAILABLE_FORMATS,
+  ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS,
+  ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
+  ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+  ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS,
+  ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
+  ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
+  ANDROID_SCALER_AVAILABLE_RAW_SIZES,
+  ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+  ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
+  ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
+  ANDROID_SCALER_CROPPING_TYPE,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP,
+  ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES,
+  ANDROID_SCALER_ROTATE_AND_CROP,
+  ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE,
+  ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION,
+  ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED,
   ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = 851994,
-  ANDROID_SENSOR_EXPOSURE_TIME = 917504,
-  ANDROID_SENSOR_FRAME_DURATION = 917505,
-  ANDROID_SENSOR_SENSITIVITY = 917506,
-  ANDROID_SENSOR_REFERENCE_ILLUMINANT1 = 917507,
-  ANDROID_SENSOR_REFERENCE_ILLUMINANT2 = 917508,
-  ANDROID_SENSOR_CALIBRATION_TRANSFORM1 = 917509,
-  ANDROID_SENSOR_CALIBRATION_TRANSFORM2 = 917510,
-  ANDROID_SENSOR_COLOR_TRANSFORM1 = 917511,
-  ANDROID_SENSOR_COLOR_TRANSFORM2 = 917512,
-  ANDROID_SENSOR_FORWARD_MATRIX1 = 917513,
-  ANDROID_SENSOR_FORWARD_MATRIX2 = 917514,
-  ANDROID_SENSOR_BASE_GAIN_FACTOR = 917515,
-  ANDROID_SENSOR_BLACK_LEVEL_PATTERN = 917516,
-  ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY = 917517,
-  ANDROID_SENSOR_ORIENTATION = 917518,
-  ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS = 917519,
-  ANDROID_SENSOR_TIMESTAMP = 917520,
-  ANDROID_SENSOR_TEMPERATURE = 917521,
-  ANDROID_SENSOR_NEUTRAL_COLOR_POINT = 917522,
-  ANDROID_SENSOR_NOISE_PROFILE = 917523,
-  ANDROID_SENSOR_PROFILE_HUE_SAT_MAP = 917524,
-  ANDROID_SENSOR_PROFILE_TONE_CURVE = 917525,
-  ANDROID_SENSOR_GREEN_SPLIT = 917526,
-  ANDROID_SENSOR_TEST_PATTERN_DATA = 917527,
-  ANDROID_SENSOR_TEST_PATTERN_MODE = 917528,
-  ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES = 917529,
-  ANDROID_SENSOR_ROLLING_SHUTTER_SKEW = 917530,
-  ANDROID_SENSOR_OPTICAL_BLACK_REGIONS = 917531,
-  ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL = 917532,
-  ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL = 917533,
-  ANDROID_SENSOR_OPAQUE_RAW_SIZE = 917534,
-  ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION = 917535,
-  ANDROID_SENSOR_PIXEL_MODE = 917536,
-  ANDROID_SENSOR_RAW_BINNING_FACTOR_USED = 917537,
-  ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE = 983040,
-  ANDROID_SENSOR_INFO_SENSITIVITY_RANGE = 983041,
-  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT = 983042,
-  ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE = 983043,
-  ANDROID_SENSOR_INFO_MAX_FRAME_DURATION = 983044,
-  ANDROID_SENSOR_INFO_PHYSICAL_SIZE = 983045,
-  ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE = 983046,
-  ANDROID_SENSOR_INFO_WHITE_LEVEL = 983047,
-  ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE = 983048,
-  ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED = 983049,
-  ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE = 983050,
-  ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION = 983051,
-  ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION = 983052,
-  ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION = 983053,
-  ANDROID_SENSOR_INFO_BINNING_FACTOR = 983054,
-  ANDROID_SHADING_MODE = 1048576,
-  ANDROID_SHADING_STRENGTH = 1048577,
-  ANDROID_SHADING_AVAILABLE_MODES = 1048578,
-  ANDROID_STATISTICS_FACE_DETECT_MODE = 1114112,
-  ANDROID_STATISTICS_HISTOGRAM_MODE = 1114113,
-  ANDROID_STATISTICS_SHARPNESS_MAP_MODE = 1114114,
-  ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE = 1114115,
-  ANDROID_STATISTICS_FACE_IDS = 1114116,
-  ANDROID_STATISTICS_FACE_LANDMARKS = 1114117,
-  ANDROID_STATISTICS_FACE_RECTANGLES = 1114118,
-  ANDROID_STATISTICS_FACE_SCORES = 1114119,
-  ANDROID_STATISTICS_HISTOGRAM = 1114120,
-  ANDROID_STATISTICS_SHARPNESS_MAP = 1114121,
-  ANDROID_STATISTICS_LENS_SHADING_CORRECTION_MAP = 1114122,
-  ANDROID_STATISTICS_LENS_SHADING_MAP = 1114123,
-  ANDROID_STATISTICS_PREDICTED_COLOR_GAINS = 1114124,
-  ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM = 1114125,
-  ANDROID_STATISTICS_SCENE_FLICKER = 1114126,
-  ANDROID_STATISTICS_HOT_PIXEL_MAP = 1114127,
-  ANDROID_STATISTICS_LENS_SHADING_MAP_MODE = 1114128,
-  ANDROID_STATISTICS_OIS_DATA_MODE = 1114129,
-  ANDROID_STATISTICS_OIS_TIMESTAMPS = 1114130,
-  ANDROID_STATISTICS_OIS_X_SHIFTS = 1114131,
-  ANDROID_STATISTICS_OIS_Y_SHIFTS = 1114132,
-  ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES = 1179648,
-  ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT = 1179649,
-  ANDROID_STATISTICS_INFO_MAX_FACE_COUNT = 1179650,
-  ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT = 1179651,
-  ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE = 1179652,
-  ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE = 1179653,
-  ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES = 1179654,
-  ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES = 1179655,
-  ANDROID_STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES = 1179656,
-  ANDROID_TONEMAP_CURVE_BLUE = 1245184,
-  ANDROID_TONEMAP_CURVE_GREEN = 1245185,
-  ANDROID_TONEMAP_CURVE_RED = 1245186,
-  ANDROID_TONEMAP_MODE = 1245187,
-  ANDROID_TONEMAP_MAX_CURVE_POINTS = 1245188,
-  ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES = 1245189,
-  ANDROID_TONEMAP_GAMMA = 1245190,
-  ANDROID_TONEMAP_PRESET_CURVE = 1245191,
-  ANDROID_LED_TRANSMIT = 1310720,
-  ANDROID_LED_AVAILABLE_LEDS = 1310721,
-  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL = 1376256,
-  ANDROID_INFO_VERSION = 1376257,
-  ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION = 1376258,
-  ANDROID_INFO_DEVICE_STATE_ORIENTATIONS = 1376259,
-  ANDROID_BLACK_LEVEL_LOCK = 1441792,
-  ANDROID_SYNC_FRAME_NUMBER = 1507328,
-  ANDROID_SYNC_MAX_LATENCY = 1507329,
-  ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR = 1572864,
-  ANDROID_REPROCESS_MAX_CAPTURE_STALL = 1572865,
-  ANDROID_DEPTH_MAX_DEPTH_SAMPLES = 1638400,
-  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS = 1638401,
-  ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS = 1638402,
-  ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS = 1638403,
-  ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE = 1638404,
-  ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS = 1638405,
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS = 1638406,
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS = 1638407,
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS = 1638408,
-  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = 1638409,
-  ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION = 1638410,
-  ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION = 1638411,
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = 1638412,
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION = 1638413,
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION = 1638414,
-  ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS = 1703936,
-  ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE = 1703937,
-  ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID = 1703938,
-  ANDROID_DISTORTION_CORRECTION_MODE = 1769472,
-  ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES = 1769473,
-  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS = 1835008,
-  ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS = 1835009,
-  ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS = 1835010,
-  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = 1835011,
-  ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION = 1835012,
-  ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION = 1835013,
-  ANDROID_HEIC_INFO_SUPPORTED = 1900544,
-  ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT = 1900545,
-  ANDROID_AUTOMOTIVE_LOCATION = 1966080,
-  ANDROID_AUTOMOTIVE_LENS_FACING = 2031616,
+  ANDROID_SCALER_RAW_CROP_REGION,
+  ANDROID_SENSOR_EXPOSURE_TIME = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SENSOR_START /* 917504 */,
+  ANDROID_SENSOR_FRAME_DURATION,
+  ANDROID_SENSOR_SENSITIVITY,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT1,
+  ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
+  ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
+  ANDROID_SENSOR_CALIBRATION_TRANSFORM2,
+  ANDROID_SENSOR_COLOR_TRANSFORM1,
+  ANDROID_SENSOR_COLOR_TRANSFORM2,
+  ANDROID_SENSOR_FORWARD_MATRIX1,
+  ANDROID_SENSOR_FORWARD_MATRIX2,
+  ANDROID_SENSOR_BASE_GAIN_FACTOR,
+  ANDROID_SENSOR_BLACK_LEVEL_PATTERN,
+  ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
+  ANDROID_SENSOR_ORIENTATION,
+  ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS,
+  ANDROID_SENSOR_TIMESTAMP,
+  ANDROID_SENSOR_TEMPERATURE,
+  ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
+  ANDROID_SENSOR_NOISE_PROFILE,
+  ANDROID_SENSOR_PROFILE_HUE_SAT_MAP,
+  ANDROID_SENSOR_PROFILE_TONE_CURVE,
+  ANDROID_SENSOR_GREEN_SPLIT,
+  ANDROID_SENSOR_TEST_PATTERN_DATA,
+  ANDROID_SENSOR_TEST_PATTERN_MODE,
+  ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
+  ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
+  ANDROID_SENSOR_OPTICAL_BLACK_REGIONS,
+  ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL,
+  ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL,
+  ANDROID_SENSOR_OPAQUE_RAW_SIZE,
+  ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION,
+  ANDROID_SENSOR_PIXEL_MODE,
+  ANDROID_SENSOR_RAW_BINNING_FACTOR_USED,
+  ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SENSOR_INFO_START /* 983040 */,
+  ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
+  ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
+  ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
+  ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
+  ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
+  ANDROID_SENSOR_INFO_WHITE_LEVEL,
+  ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
+  ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED,
+  ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
+  ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+  ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+  ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+  ANDROID_SENSOR_INFO_BINNING_FACTOR,
+  ANDROID_SHADING_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SHADING_START /* 1048576 */,
+  ANDROID_SHADING_STRENGTH,
+  ANDROID_SHADING_AVAILABLE_MODES,
+  ANDROID_STATISTICS_FACE_DETECT_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_STATISTICS_START /* 1114112 */,
+  ANDROID_STATISTICS_HISTOGRAM_MODE,
+  ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
+  ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
+  ANDROID_STATISTICS_FACE_IDS,
+  ANDROID_STATISTICS_FACE_LANDMARKS,
+  ANDROID_STATISTICS_FACE_RECTANGLES,
+  ANDROID_STATISTICS_FACE_SCORES,
+  ANDROID_STATISTICS_HISTOGRAM,
+  ANDROID_STATISTICS_SHARPNESS_MAP,
+  ANDROID_STATISTICS_LENS_SHADING_CORRECTION_MAP,
+  ANDROID_STATISTICS_LENS_SHADING_MAP,
+  ANDROID_STATISTICS_PREDICTED_COLOR_GAINS,
+  ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM,
+  ANDROID_STATISTICS_SCENE_FLICKER,
+  ANDROID_STATISTICS_HOT_PIXEL_MAP,
+  ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
+  ANDROID_STATISTICS_OIS_DATA_MODE,
+  ANDROID_STATISTICS_OIS_TIMESTAMPS,
+  ANDROID_STATISTICS_OIS_X_SHIFTS,
+  ANDROID_STATISTICS_OIS_Y_SHIFTS,
+  ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_STATISTICS_INFO_START /* 1179648 */,
+  ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
+  ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
+  ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
+  ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
+  ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
+  ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
+  ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
+  ANDROID_STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES,
+  ANDROID_TONEMAP_CURVE_BLUE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_TONEMAP_START /* 1245184 */,
+  ANDROID_TONEMAP_CURVE_GREEN,
+  ANDROID_TONEMAP_CURVE_RED,
+  ANDROID_TONEMAP_MODE,
+  ANDROID_TONEMAP_MAX_CURVE_POINTS,
+  ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
+  ANDROID_TONEMAP_GAMMA,
+  ANDROID_TONEMAP_PRESET_CURVE,
+  ANDROID_LED_TRANSMIT = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LED_START /* 1310720 */,
+  ANDROID_LED_AVAILABLE_LEDS,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_INFO_START /* 1376256 */,
+  ANDROID_INFO_VERSION,
+  ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
+  ANDROID_INFO_DEVICE_STATE_ORIENTATIONS,
+  ANDROID_BLACK_LEVEL_LOCK = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_BLACK_LEVEL_START /* 1441792 */,
+  ANDROID_SYNC_FRAME_NUMBER = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SYNC_START /* 1507328 */,
+  ANDROID_SYNC_MAX_LATENCY,
+  ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_REPROCESS_START /* 1572864 */,
+  ANDROID_REPROCESS_MAX_CAPTURE_STALL,
+  ANDROID_DEPTH_MAX_DEPTH_SAMPLES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEPTH_START /* 1638400 */,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
+  ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE,
+  ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LOGICAL_MULTI_CAMERA_START /* 1703936 */,
+  ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE,
+  ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID,
+  ANDROID_DISTORTION_CORRECTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DISTORTION_CORRECTION_START /* 1769472 */,
+  ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HEIC_START /* 1835008 */,
+  ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_INFO_SUPPORTED = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HEIC_INFO_START /* 1900544 */,
+  ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
+  ANDROID_AUTOMOTIVE_LOCATION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_START /* 1966080 */,
+  ANDROID_AUTOMOTIVE_LENS_FACING = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START /* 2031616 */,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_JPEGR_START /* 2162688 */,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
index d04ffe3..0b976f3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ColorCorrectionAberrationMode {
-  ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF = 0,
-  ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST = 1,
-  ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY = 2,
+  ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
+  ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
+  ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl
index 219c802..2381605 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ColorCorrectionMode {
-  ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0,
-  ANDROID_COLOR_CORRECTION_MODE_FAST = 1,
-  ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY = 2,
+  ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX,
+  ANDROID_COLOR_CORRECTION_MODE_FAST,
+  ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
index 84fd718..0d5aad9 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
@@ -38,8 +38,8 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAeAntibandingMode {
-  ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF = 0,
-  ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ = 1,
-  ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ = 2,
-  ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO = 3,
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
+  ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLock.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLock.aidl
index f825f11..766b835 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLock.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLock.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAeLock {
-  ANDROID_CONTROL_AE_LOCK_OFF = 0,
-  ANDROID_CONTROL_AE_LOCK_ON = 1,
+  ANDROID_CONTROL_AE_LOCK_OFF,
+  ANDROID_CONTROL_AE_LOCK_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLockAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
index df7924e..a22c93e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAeLockAvailable {
-  ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE = 0,
-  ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE = 1,
+  ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE,
+  ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
index 75a3486..5e1b871 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
@@ -38,10 +38,10 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAeMode {
-  ANDROID_CONTROL_AE_MODE_OFF = 0,
-  ANDROID_CONTROL_AE_MODE_ON = 1,
-  ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH = 2,
-  ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3,
-  ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4,
-  ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH = 5,
+  ANDROID_CONTROL_AE_MODE_OFF,
+  ANDROID_CONTROL_AE_MODE_ON,
+  ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH,
+  ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
+  ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
+  ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
index 4678e01..20382c0 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAePrecaptureTrigger {
-  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0,
-  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START = 1,
-  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL = 2,
+  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE,
+  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START,
+  ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeState.aidl
index 3be64ea..e52eafe 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeState.aidl
@@ -38,10 +38,10 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAeState {
-  ANDROID_CONTROL_AE_STATE_INACTIVE = 0,
-  ANDROID_CONTROL_AE_STATE_SEARCHING = 1,
-  ANDROID_CONTROL_AE_STATE_CONVERGED = 2,
-  ANDROID_CONTROL_AE_STATE_LOCKED = 3,
-  ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED = 4,
-  ANDROID_CONTROL_AE_STATE_PRECAPTURE = 5,
+  ANDROID_CONTROL_AE_STATE_INACTIVE,
+  ANDROID_CONTROL_AE_STATE_SEARCHING,
+  ANDROID_CONTROL_AE_STATE_CONVERGED,
+  ANDROID_CONTROL_AE_STATE_LOCKED,
+  ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED,
+  ANDROID_CONTROL_AE_STATE_PRECAPTURE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfMode.aidl
index 155d3c9..6cd46c6 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfMode.aidl
@@ -38,10 +38,10 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAfMode {
-  ANDROID_CONTROL_AF_MODE_OFF = 0,
-  ANDROID_CONTROL_AF_MODE_AUTO = 1,
-  ANDROID_CONTROL_AF_MODE_MACRO = 2,
-  ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO = 3,
-  ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4,
-  ANDROID_CONTROL_AF_MODE_EDOF = 5,
+  ANDROID_CONTROL_AF_MODE_OFF,
+  ANDROID_CONTROL_AF_MODE_AUTO,
+  ANDROID_CONTROL_AF_MODE_MACRO,
+  ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
+  ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
+  ANDROID_CONTROL_AF_MODE_EDOF,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfSceneChange.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfSceneChange.aidl
index 4b31c84..ba853a1 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfSceneChange.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfSceneChange.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAfSceneChange {
-  ANDROID_CONTROL_AF_SCENE_CHANGE_NOT_DETECTED = 0,
-  ANDROID_CONTROL_AF_SCENE_CHANGE_DETECTED = 1,
+  ANDROID_CONTROL_AF_SCENE_CHANGE_NOT_DETECTED,
+  ANDROID_CONTROL_AF_SCENE_CHANGE_DETECTED,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfState.aidl
index 4aac8c8..25b6a1c 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfState.aidl
@@ -38,11 +38,11 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAfState {
-  ANDROID_CONTROL_AF_STATE_INACTIVE = 0,
-  ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN = 1,
-  ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED = 2,
-  ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN = 3,
-  ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED = 4,
-  ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5,
-  ANDROID_CONTROL_AF_STATE_PASSIVE_UNFOCUSED = 6,
+  ANDROID_CONTROL_AF_STATE_INACTIVE,
+  ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN,
+  ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED,
+  ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN,
+  ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED,
+  ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED,
+  ANDROID_CONTROL_AF_STATE_PASSIVE_UNFOCUSED,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfTrigger.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfTrigger.aidl
index 3fbf94b..9d61b2d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfTrigger.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfTrigger.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAfTrigger {
-  ANDROID_CONTROL_AF_TRIGGER_IDLE = 0,
-  ANDROID_CONTROL_AF_TRIGGER_START = 1,
-  ANDROID_CONTROL_AF_TRIGGER_CANCEL = 2,
+  ANDROID_CONTROL_AF_TRIGGER_IDLE,
+  ANDROID_CONTROL_AF_TRIGGER_START,
+  ANDROID_CONTROL_AF_TRIGGER_CANCEL,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframing.aidl
new file mode 100644
index 0000000..2daf00b
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframing.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAutoframing {
+  ANDROID_CONTROL_AUTOFRAMING_OFF,
+  ANDROID_CONTROL_AUTOFRAMING_ON,
+  ANDROID_CONTROL_AUTOFRAMING_AUTO,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
new file mode 100644
index 0000000..ab91bb4
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAutoframingAvailable {
+  ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE,
+  ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingState.aidl
new file mode 100644
index 0000000..db0d288
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAutoframingState {
+  ANDROID_CONTROL_AUTOFRAMING_STATE_INACTIVE,
+  ANDROID_CONTROL_AUTOFRAMING_STATE_FRAMING,
+  ANDROID_CONTROL_AUTOFRAMING_STATE_CONVERGED,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLock.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLock.aidl
index 0e297a5..949b5e8 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLock.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLock.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAwbLock {
-  ANDROID_CONTROL_AWB_LOCK_OFF = 0,
-  ANDROID_CONTROL_AWB_LOCK_ON = 1,
+  ANDROID_CONTROL_AWB_LOCK_OFF,
+  ANDROID_CONTROL_AWB_LOCK_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
index d471d19..80c4c31 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAwbLockAvailable {
-  ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE = 0,
-  ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE = 1,
+  ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE,
+  ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbMode.aidl
index a3463f8..6ed9ece 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbMode.aidl
@@ -38,13 +38,13 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAwbMode {
-  ANDROID_CONTROL_AWB_MODE_OFF = 0,
-  ANDROID_CONTROL_AWB_MODE_AUTO = 1,
-  ANDROID_CONTROL_AWB_MODE_INCANDESCENT = 2,
-  ANDROID_CONTROL_AWB_MODE_FLUORESCENT = 3,
-  ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT = 4,
-  ANDROID_CONTROL_AWB_MODE_DAYLIGHT = 5,
-  ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6,
-  ANDROID_CONTROL_AWB_MODE_TWILIGHT = 7,
-  ANDROID_CONTROL_AWB_MODE_SHADE = 8,
+  ANDROID_CONTROL_AWB_MODE_OFF,
+  ANDROID_CONTROL_AWB_MODE_AUTO,
+  ANDROID_CONTROL_AWB_MODE_INCANDESCENT,
+  ANDROID_CONTROL_AWB_MODE_FLUORESCENT,
+  ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT,
+  ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
+  ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT,
+  ANDROID_CONTROL_AWB_MODE_TWILIGHT,
+  ANDROID_CONTROL_AWB_MODE_SHADE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbState.aidl
index f1b0e40..c5b02d5 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbState.aidl
@@ -38,8 +38,8 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlAwbState {
-  ANDROID_CONTROL_AWB_STATE_INACTIVE = 0,
-  ANDROID_CONTROL_AWB_STATE_SEARCHING = 1,
-  ANDROID_CONTROL_AWB_STATE_CONVERGED = 2,
-  ANDROID_CONTROL_AWB_STATE_LOCKED = 3,
+  ANDROID_CONTROL_AWB_STATE_INACTIVE,
+  ANDROID_CONTROL_AWB_STATE_SEARCHING,
+  ANDROID_CONTROL_AWB_STATE_CONVERGED,
+  ANDROID_CONTROL_AWB_STATE_LOCKED,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlCaptureIntent.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlCaptureIntent.aidl
index 283bb1b..fa1c0a9 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlCaptureIntent.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlCaptureIntent.aidl
@@ -38,12 +38,12 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlCaptureIntent {
-  ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM = 0,
-  ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW = 1,
-  ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2,
-  ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3,
-  ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4,
-  ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5,
-  ANDROID_CONTROL_CAPTURE_INTENT_MANUAL = 6,
-  ANDROID_CONTROL_CAPTURE_INTENT_MOTION_TRACKING = 7,
+  ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM,
+  ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW,
+  ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE,
+  ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD,
+  ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT,
+  ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG,
+  ANDROID_CONTROL_CAPTURE_INTENT_MANUAL,
+  ANDROID_CONTROL_CAPTURE_INTENT_MOTION_TRACKING,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEffectMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEffectMode.aidl
index 911223d..471deed 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEffectMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEffectMode.aidl
@@ -38,13 +38,13 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlEffectMode {
-  ANDROID_CONTROL_EFFECT_MODE_OFF = 0,
-  ANDROID_CONTROL_EFFECT_MODE_MONO = 1,
-  ANDROID_CONTROL_EFFECT_MODE_NEGATIVE = 2,
-  ANDROID_CONTROL_EFFECT_MODE_SOLARIZE = 3,
-  ANDROID_CONTROL_EFFECT_MODE_SEPIA = 4,
-  ANDROID_CONTROL_EFFECT_MODE_POSTERIZE = 5,
-  ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD = 6,
-  ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD = 7,
-  ANDROID_CONTROL_EFFECT_MODE_AQUA = 8,
+  ANDROID_CONTROL_EFFECT_MODE_OFF,
+  ANDROID_CONTROL_EFFECT_MODE_MONO,
+  ANDROID_CONTROL_EFFECT_MODE_NEGATIVE,
+  ANDROID_CONTROL_EFFECT_MODE_SOLARIZE,
+  ANDROID_CONTROL_EFFECT_MODE_SEPIA,
+  ANDROID_CONTROL_EFFECT_MODE_POSTERIZE,
+  ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD,
+  ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD,
+  ANDROID_CONTROL_EFFECT_MODE_AQUA,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEnableZsl.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEnableZsl.aidl
index 920def7..3f2d4a3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEnableZsl.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEnableZsl.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlEnableZsl {
-  ANDROID_CONTROL_ENABLE_ZSL_FALSE = 0,
-  ANDROID_CONTROL_ENABLE_ZSL_TRUE = 1,
+  ANDROID_CONTROL_ENABLE_ZSL_FALSE,
+  ANDROID_CONTROL_ENABLE_ZSL_TRUE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
index 2655d61..7838288 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
@@ -39,7 +39,7 @@
 @Backing(type="int") @VintfStability
 enum ControlExtendedSceneMode {
   ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED = 0,
-  ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE = 1,
-  ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS = 2,
-  ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START = 64,
+  ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE,
+  ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS,
+  ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START = 0x40,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlMode.aidl
index f58491e..c5a8172 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlMode.aidl
@@ -38,9 +38,9 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlMode {
-  ANDROID_CONTROL_MODE_OFF = 0,
-  ANDROID_CONTROL_MODE_AUTO = 1,
-  ANDROID_CONTROL_MODE_USE_SCENE_MODE = 2,
-  ANDROID_CONTROL_MODE_OFF_KEEP_STATE = 3,
-  ANDROID_CONTROL_MODE_USE_EXTENDED_SCENE_MODE = 4,
+  ANDROID_CONTROL_MODE_OFF,
+  ANDROID_CONTROL_MODE_AUTO,
+  ANDROID_CONTROL_MODE_USE_SCENE_MODE,
+  ANDROID_CONTROL_MODE_OFF_KEEP_STATE,
+  ANDROID_CONTROL_MODE_USE_EXTENDED_SCENE_MODE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSceneMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSceneMode.aidl
index 994bbf3..62c67e3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSceneMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSceneMode.aidl
@@ -39,25 +39,25 @@
 @Backing(type="int") @VintfStability
 enum ControlSceneMode {
   ANDROID_CONTROL_SCENE_MODE_DISABLED = 0,
-  ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY = 1,
-  ANDROID_CONTROL_SCENE_MODE_ACTION = 2,
-  ANDROID_CONTROL_SCENE_MODE_PORTRAIT = 3,
-  ANDROID_CONTROL_SCENE_MODE_LANDSCAPE = 4,
-  ANDROID_CONTROL_SCENE_MODE_NIGHT = 5,
-  ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6,
-  ANDROID_CONTROL_SCENE_MODE_THEATRE = 7,
-  ANDROID_CONTROL_SCENE_MODE_BEACH = 8,
-  ANDROID_CONTROL_SCENE_MODE_SNOW = 9,
-  ANDROID_CONTROL_SCENE_MODE_SUNSET = 10,
-  ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO = 11,
-  ANDROID_CONTROL_SCENE_MODE_FIREWORKS = 12,
-  ANDROID_CONTROL_SCENE_MODE_SPORTS = 13,
-  ANDROID_CONTROL_SCENE_MODE_PARTY = 14,
-  ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT = 15,
-  ANDROID_CONTROL_SCENE_MODE_BARCODE = 16,
-  ANDROID_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17,
-  ANDROID_CONTROL_SCENE_MODE_HDR = 18,
-  ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT = 19,
+  ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY,
+  ANDROID_CONTROL_SCENE_MODE_ACTION,
+  ANDROID_CONTROL_SCENE_MODE_PORTRAIT,
+  ANDROID_CONTROL_SCENE_MODE_LANDSCAPE,
+  ANDROID_CONTROL_SCENE_MODE_NIGHT,
+  ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT,
+  ANDROID_CONTROL_SCENE_MODE_THEATRE,
+  ANDROID_CONTROL_SCENE_MODE_BEACH,
+  ANDROID_CONTROL_SCENE_MODE_SNOW,
+  ANDROID_CONTROL_SCENE_MODE_SUNSET,
+  ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO,
+  ANDROID_CONTROL_SCENE_MODE_FIREWORKS,
+  ANDROID_CONTROL_SCENE_MODE_SPORTS,
+  ANDROID_CONTROL_SCENE_MODE_PARTY,
+  ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT,
+  ANDROID_CONTROL_SCENE_MODE_BARCODE,
+  ANDROID_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO,
+  ANDROID_CONTROL_SCENE_MODE_HDR,
+  ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT,
   ANDROID_CONTROL_SCENE_MODE_DEVICE_CUSTOM_START = 100,
   ANDROID_CONTROL_SCENE_MODE_DEVICE_CUSTOM_END = 127,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSettingsOverride.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSettingsOverride.aidl
new file mode 100644
index 0000000..404bbfa
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSettingsOverride.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlSettingsOverride {
+  ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF,
+  ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM,
+  ANDROID_CONTROL_SETTINGS_OVERRIDE_VENDOR_START = 0x4000,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
index b3b24f7..2b199ef 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ControlVideoStabilizationMode {
-  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF = 0,
-  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON = 1,
-  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION = 2,
+  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
+  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON,
+  ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DemosaicMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DemosaicMode.aidl
index 26874a2..5770009 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DemosaicMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DemosaicMode.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum DemosaicMode {
-  ANDROID_DEMOSAIC_MODE_FAST = 0,
-  ANDROID_DEMOSAIC_MODE_HIGH_QUALITY = 1,
+  ANDROID_DEMOSAIC_MODE_FAST,
+  ANDROID_DEMOSAIC_MODE_HIGH_QUALITY,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
index 6a154ca..0cce2da 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum DepthAvailableDepthStreamConfigurations {
-  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT = 0,
-  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_INPUT = 1,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
index 23d6589..9be06db 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum DepthAvailableDepthStreamConfigurationsMaximumResolution {
-  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT = 0,
-  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT = 1,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
index f3ca039..c6aebaa 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum DepthAvailableDynamicDepthStreamConfigurations {
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT = 0,
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT = 1,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
index 46a4ce6..4d5161d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution {
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT = 0,
-  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT = 1,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
index f5fc218..f7b69cd 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum DepthDepthIsExclusive {
-  ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE = 0,
-  ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_TRUE = 1,
+  ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE,
+  ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_TRUE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DistortionCorrectionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
index 46327e0..6e965f6 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum DistortionCorrectionMode {
-  ANDROID_DISTORTION_CORRECTION_MODE_OFF = 0,
-  ANDROID_DISTORTION_CORRECTION_MODE_FAST = 1,
-  ANDROID_DISTORTION_CORRECTION_MODE_HIGH_QUALITY = 2,
+  ANDROID_DISTORTION_CORRECTION_MODE_OFF,
+  ANDROID_DISTORTION_CORRECTION_MODE_FAST,
+  ANDROID_DISTORTION_CORRECTION_MODE_HIGH_QUALITY,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/EdgeMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/EdgeMode.aidl
index 4b02e19..fdd32f4 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/EdgeMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/EdgeMode.aidl
@@ -38,8 +38,8 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum EdgeMode {
-  ANDROID_EDGE_MODE_OFF = 0,
-  ANDROID_EDGE_MODE_FAST = 1,
-  ANDROID_EDGE_MODE_HIGH_QUALITY = 2,
-  ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG = 3,
+  ANDROID_EDGE_MODE_OFF,
+  ANDROID_EDGE_MODE_FAST,
+  ANDROID_EDGE_MODE_HIGH_QUALITY,
+  ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashInfoAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashInfoAvailable.aidl
index 10d07a5..83292fe 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashInfoAvailable.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashInfoAvailable.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum FlashInfoAvailable {
-  ANDROID_FLASH_INFO_AVAILABLE_FALSE = 0,
-  ANDROID_FLASH_INFO_AVAILABLE_TRUE = 1,
+  ANDROID_FLASH_INFO_AVAILABLE_FALSE,
+  ANDROID_FLASH_INFO_AVAILABLE_TRUE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashMode.aidl
index 1ab0560..e18ea3c 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashMode.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum FlashMode {
-  ANDROID_FLASH_MODE_OFF = 0,
-  ANDROID_FLASH_MODE_SINGLE = 1,
-  ANDROID_FLASH_MODE_TORCH = 2,
+  ANDROID_FLASH_MODE_OFF,
+  ANDROID_FLASH_MODE_SINGLE,
+  ANDROID_FLASH_MODE_TORCH,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashState.aidl
index a571e66..4343d4f 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashState.aidl
@@ -38,9 +38,9 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum FlashState {
-  ANDROID_FLASH_STATE_UNAVAILABLE = 0,
-  ANDROID_FLASH_STATE_CHARGING = 1,
-  ANDROID_FLASH_STATE_READY = 2,
-  ANDROID_FLASH_STATE_FIRED = 3,
-  ANDROID_FLASH_STATE_PARTIAL = 4,
+  ANDROID_FLASH_STATE_UNAVAILABLE,
+  ANDROID_FLASH_STATE_CHARGING,
+  ANDROID_FLASH_STATE_READY,
+  ANDROID_FLASH_STATE_FIRED,
+  ANDROID_FLASH_STATE_PARTIAL,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
index d92c2db..3957267 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum HeicAvailableHeicStreamConfigurations {
-  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT = 0,
-  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT = 1,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
index f02cf58..4eda538 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum HeicAvailableHeicStreamConfigurationsMaximumResolution {
-  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT = 0,
-  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT = 1,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicInfoSupported.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicInfoSupported.aidl
index ae5a8e7..7079bbf 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicInfoSupported.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicInfoSupported.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum HeicInfoSupported {
-  ANDROID_HEIC_INFO_SUPPORTED_FALSE = 0,
-  ANDROID_HEIC_INFO_SUPPORTED_TRUE = 1,
+  ANDROID_HEIC_INFO_SUPPORTED_FALSE,
+  ANDROID_HEIC_INFO_SUPPORTED_TRUE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HotPixelMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HotPixelMode.aidl
index 1248c60..50b3446 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HotPixelMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HotPixelMode.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum HotPixelMode {
-  ANDROID_HOT_PIXEL_MODE_OFF = 0,
-  ANDROID_HOT_PIXEL_MODE_FAST = 1,
-  ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY = 2,
+  ANDROID_HOT_PIXEL_MODE_OFF,
+  ANDROID_HOT_PIXEL_MODE_FAST,
+  ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
index 1272f27..7303ff5 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
@@ -38,5 +38,5 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum InfoSupportedBufferManagementVersion {
-  ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE = 0,
+  ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
index 8ae39b0..3b50647 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
@@ -38,9 +38,9 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum InfoSupportedHardwareLevel {
-  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0,
-  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1,
-  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2,
-  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3,
-  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL = 4,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3,
+  ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
new file mode 100644
index 0000000..cf9dbb7
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum JpegrAvailableJpegRStreamConfigurations {
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..0a95e1f
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum JpegrAvailableJpegRStreamConfigurationsMaximumResolution {
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedAvailableLeds.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedAvailableLeds.aidl
index da558d2..b3beb2d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedAvailableLeds.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedAvailableLeds.aidl
@@ -38,5 +38,5 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum LedAvailableLeds {
-  ANDROID_LED_AVAILABLE_LEDS_TRANSMIT = 0,
+  ANDROID_LED_AVAILABLE_LEDS_TRANSMIT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedTransmit.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedTransmit.aidl
index 658b3cd..0cbf239 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedTransmit.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedTransmit.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum LedTransmit {
-  ANDROID_LED_TRANSMIT_OFF = 0,
-  ANDROID_LED_TRANSMIT_ON = 1,
+  ANDROID_LED_TRANSMIT_OFF,
+  ANDROID_LED_TRANSMIT_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensFacing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensFacing.aidl
index 4db987b..d15674d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensFacing.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensFacing.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum LensFacing {
-  ANDROID_LENS_FACING_FRONT = 0,
-  ANDROID_LENS_FACING_BACK = 1,
-  ANDROID_LENS_FACING_EXTERNAL = 2,
+  ANDROID_LENS_FACING_FRONT,
+  ANDROID_LENS_FACING_BACK,
+  ANDROID_LENS_FACING_EXTERNAL,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
index d83d67f..937347b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum LensInfoFocusDistanceCalibration {
-  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED = 0,
-  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE = 1,
-  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED = 2,
+  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED,
+  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE,
+  ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
index f2f039c..550d9f3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum LensOpticalStabilizationMode {
-  ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF = 0,
-  ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON = 1,
+  ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
+  ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl
index b2d837a..6a3799d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl
@@ -38,8 +38,8 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum LensPoseReference {
-  ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA = 0,
-  ANDROID_LENS_POSE_REFERENCE_GYROSCOPE = 1,
-  ANDROID_LENS_POSE_REFERENCE_UNDEFINED = 2,
-  ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE = 3,
+  ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA,
+  ANDROID_LENS_POSE_REFERENCE_GYROSCOPE,
+  ANDROID_LENS_POSE_REFERENCE_UNDEFINED,
+  ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensState.aidl
index 4b15b0f..4f98956 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensState.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum LensState {
-  ANDROID_LENS_STATE_STATIONARY = 0,
-  ANDROID_LENS_STATE_MOVING = 1,
+  ANDROID_LENS_STATE_STATIONARY,
+  ANDROID_LENS_STATE_MOVING,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
index 224a7fa..5eb5759 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum LogicalMultiCameraSensorSyncType {
-  ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE = 0,
-  ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED = 1,
+  ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE,
+  ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/NoiseReductionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/NoiseReductionMode.aidl
index ed0ebc1..8b589ce 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/NoiseReductionMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/NoiseReductionMode.aidl
@@ -38,9 +38,9 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum NoiseReductionMode {
-  ANDROID_NOISE_REDUCTION_MODE_OFF = 0,
-  ANDROID_NOISE_REDUCTION_MODE_FAST = 1,
-  ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY = 2,
-  ANDROID_NOISE_REDUCTION_MODE_MINIMAL = 3,
-  ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG = 4,
+  ANDROID_NOISE_REDUCTION_MODE_OFF,
+  ANDROID_NOISE_REDUCTION_MODE_FAST,
+  ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY,
+  ANDROID_NOISE_REDUCTION_MODE_MINIMAL,
+  ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/QuirksPartialResult.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/QuirksPartialResult.aidl
index d217fe8..8ab6a05 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/QuirksPartialResult.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/QuirksPartialResult.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum QuirksPartialResult {
-  ANDROID_QUIRKS_PARTIAL_RESULT_FINAL = 0,
-  ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL = 1,
+  ANDROID_QUIRKS_PARTIAL_RESULT_FINAL,
+  ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
index 8dc2aa2..0564db8 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
@@ -38,24 +38,25 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum RequestAvailableCapabilities {
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW = 3,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO = 9,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING = 10,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA = 11,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA = 13,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA = 14,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING = 15,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR = 16,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING = 17,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT = 18,
-  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE = 19,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE,
+  ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
new file mode 100644
index 0000000..74606bf
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="long") @VintfStability
+enum RequestAvailableColorSpaceProfilesMap {
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED = (-1L) /* -1 */,
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB = 0L,
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3 = 7L,
+  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG = 16L,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
index 16e38ba..45ffb1b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
@@ -38,17 +38,17 @@
 package android.hardware.camera.metadata;
 @Backing(type="long") @VintfStability
 enum RequestAvailableDynamicRangeProfilesMap {
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD = 1,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 2,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 4,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS = 8,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF = 16,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO = 32,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM = 64,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO = 128,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF = 256,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO = 512,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM = 1024,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO = 2048,
-  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 4096,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD = 0x1L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 0x2L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 0x4L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS = 0x8L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF = 0x10L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO = 0x20L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM = 0x40L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO = 0x80L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF = 0x100L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO = 0x200L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM = 0x400L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO = 0x800L,
+  ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000L,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestMetadataMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestMetadataMode.aidl
index 90fba00..cede799 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestMetadataMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestMetadataMode.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum RequestMetadataMode {
-  ANDROID_REQUEST_METADATA_MODE_NONE = 0,
-  ANDROID_REQUEST_METADATA_MODE_FULL = 1,
+  ANDROID_REQUEST_METADATA_MODE_NONE,
+  ANDROID_REQUEST_METADATA_MODE_FULL,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestType.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestType.aidl
index 4f38cfb..6b4ae71 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestType.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestType.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum RequestType {
-  ANDROID_REQUEST_TYPE_CAPTURE = 0,
-  ANDROID_REQUEST_TYPE_REPROCESS = 1,
+  ANDROID_REQUEST_TYPE_CAPTURE,
+  ANDROID_REQUEST_TYPE_REPROCESS,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableFormats.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
index 41fd2c2..fdc2f60 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
@@ -38,14 +38,14 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ScalerAvailableFormats {
-  ANDROID_SCALER_AVAILABLE_FORMATS_RAW16 = 32,
-  ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE = 36,
-  ANDROID_SCALER_AVAILABLE_FORMATS_YV12 = 842094169,
-  ANDROID_SCALER_AVAILABLE_FORMATS_YCrCb_420_SP = 17,
-  ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED = 34,
-  ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 = 35,
-  ANDROID_SCALER_AVAILABLE_FORMATS_BLOB = 33,
-  ANDROID_SCALER_AVAILABLE_FORMATS_RAW10 = 37,
-  ANDROID_SCALER_AVAILABLE_FORMATS_RAW12 = 38,
-  ANDROID_SCALER_AVAILABLE_FORMATS_Y8 = 538982489,
+  ANDROID_SCALER_AVAILABLE_FORMATS_RAW16 = 0x20,
+  ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE = 0x24,
+  ANDROID_SCALER_AVAILABLE_FORMATS_YV12 = 0x32315659,
+  ANDROID_SCALER_AVAILABLE_FORMATS_YCrCb_420_SP = 0x11,
+  ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED = 0x22,
+  ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 = 0x23,
+  ANDROID_SCALER_AVAILABLE_FORMATS_BLOB = 0x21,
+  ANDROID_SCALER_AVAILABLE_FORMATS_RAW10 = 0x25,
+  ANDROID_SCALER_AVAILABLE_FORMATS_RAW12 = 0x26,
+  ANDROID_SCALER_AVAILABLE_FORMATS_Y8 = 0x20203859,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
index 85daa85..741a99d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
@@ -38,13 +38,13 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ScalerAvailableRecommendedStreamConfigurations {
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW = 0,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD = 1,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT = 2,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT = 3,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL = 4,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW = 5,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT = 6,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT = 8,
-  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START = 24,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW = 0x0,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD = 0x1,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT = 0x2,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT = 0x3,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL = 0x4,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW = 0x5,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT = 0x6,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT = 0x8,
+  ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START = 0x18,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
index 1515ad5..4e2899d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ScalerAvailableStreamConfigurations {
-  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT = 0,
-  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT = 1,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
index b9c3374..fb15815 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ScalerAvailableStreamConfigurationsMaximumResolution {
-  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT = 0,
-  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT = 1,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
index bfa4f1a..ff92f9e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
@@ -38,11 +38,12 @@
 package android.hardware.camera.metadata;
 @Backing(type="long") @VintfStability
 enum ScalerAvailableStreamUseCases {
-  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT = 0,
-  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW = 1,
-  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE = 2,
-  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 3,
-  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 4,
-  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 5,
-  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 65536,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT = 0x0L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW = 0x1L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE = 0x2L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 0x6L,
+  ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 0x10000L,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerCroppingType.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerCroppingType.aidl
index 0487196..60782e4 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerCroppingType.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerCroppingType.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ScalerCroppingType {
-  ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY = 0,
-  ANDROID_SCALER_CROPPING_TYPE_FREEFORM = 1,
+  ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY,
+  ANDROID_SCALER_CROPPING_TYPE_FREEFORM,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
index 711243f..e09d89c 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ScalerMultiResolutionStreamSupported {
-  ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_FALSE = 0,
-  ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE = 1,
+  ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_FALSE,
+  ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
index 50bc097..64a0220 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ScalerPhysicalCameraMultiResolutionStreamConfigurations {
-  ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT = 0,
-  ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT = 1,
+  ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
index 3b9c5b8..bf5380e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
@@ -38,9 +38,9 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ScalerRotateAndCrop {
-  ANDROID_SCALER_ROTATE_AND_CROP_NONE = 0,
-  ANDROID_SCALER_ROTATE_AND_CROP_90 = 1,
-  ANDROID_SCALER_ROTATE_AND_CROP_180 = 2,
-  ANDROID_SCALER_ROTATE_AND_CROP_270 = 3,
-  ANDROID_SCALER_ROTATE_AND_CROP_AUTO = 4,
+  ANDROID_SCALER_ROTATE_AND_CROP_NONE,
+  ANDROID_SCALER_ROTATE_AND_CROP_90,
+  ANDROID_SCALER_ROTATE_AND_CROP_180,
+  ANDROID_SCALER_ROTATE_AND_CROP_270,
+  ANDROID_SCALER_ROTATE_AND_CROP_AUTO,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
index 3400233..c96f3c5 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
@@ -38,11 +38,11 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum SensorInfoColorFilterArrangement {
-  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB = 0,
-  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG = 1,
-  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG = 2,
-  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3,
-  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4,
-  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO = 5,
-  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR = 6,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO,
+  ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
index c8faaee..0153731 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum SensorInfoLensShadingApplied {
-  ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_FALSE = 0,
-  ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_TRUE = 1,
+  ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_FALSE,
+  ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_TRUE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
index 2a4b3dd..9a00cf1 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum SensorInfoTimestampSource {
-  ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN = 0,
-  ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME = 1,
+  ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN,
+  ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorPixelMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorPixelMode.aidl
index e021434..5f055d6 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorPixelMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorPixelMode.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum SensorPixelMode {
-  ANDROID_SENSOR_PIXEL_MODE_DEFAULT = 0,
-  ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION = 1,
+  ANDROID_SENSOR_PIXEL_MODE_DEFAULT,
+  ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
index a1f0c5f..851dae0 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum SensorRawBinningFactorUsed {
-  ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_TRUE = 0,
-  ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_FALSE = 1,
+  ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_TRUE,
+  ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_FALSE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorTestPatternMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorTestPatternMode.aidl
index 3f49b9a..98f0ebe 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorTestPatternMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorTestPatternMode.aidl
@@ -38,11 +38,11 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum SensorTestPatternMode {
-  ANDROID_SENSOR_TEST_PATTERN_MODE_OFF = 0,
-  ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR = 1,
-  ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS = 2,
-  ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY = 3,
-  ANDROID_SENSOR_TEST_PATTERN_MODE_PN9 = 4,
-  ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK = 5,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_PN9,
+  ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK,
   ANDROID_SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ShadingMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ShadingMode.aidl
index a2d2a32..ffc6a56 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ShadingMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ShadingMode.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum ShadingMode {
-  ANDROID_SHADING_MODE_OFF = 0,
-  ANDROID_SHADING_MODE_FAST = 1,
-  ANDROID_SHADING_MODE_HIGH_QUALITY = 2,
+  ANDROID_SHADING_MODE_OFF,
+  ANDROID_SHADING_MODE_FAST,
+  ANDROID_SHADING_MODE_HIGH_QUALITY,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
index 1c65f99..48c6797 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum StatisticsFaceDetectMode {
-  ANDROID_STATISTICS_FACE_DETECT_MODE_OFF = 0,
-  ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE = 1,
-  ANDROID_STATISTICS_FACE_DETECT_MODE_FULL = 2,
+  ANDROID_STATISTICS_FACE_DETECT_MODE_OFF,
+  ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE,
+  ANDROID_STATISTICS_FACE_DETECT_MODE_FULL,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHistogramMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
index 39a013e..354518b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum StatisticsHistogramMode {
-  ANDROID_STATISTICS_HISTOGRAM_MODE_OFF = 0,
-  ANDROID_STATISTICS_HISTOGRAM_MODE_ON = 1,
+  ANDROID_STATISTICS_HISTOGRAM_MODE_OFF,
+  ANDROID_STATISTICS_HISTOGRAM_MODE_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
index 3a8c6c2..b96e4be 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum StatisticsHotPixelMapMode {
-  ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF = 0,
-  ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_ON = 1,
+  ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF,
+  ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
index cc280ca..7d0b082 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum StatisticsLensShadingMapMode {
-  ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0,
-  ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON = 1,
+  ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF,
+  ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsOisDataMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
index 6607037..b80889b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum StatisticsOisDataMode {
-  ANDROID_STATISTICS_OIS_DATA_MODE_OFF = 0,
-  ANDROID_STATISTICS_OIS_DATA_MODE_ON = 1,
+  ANDROID_STATISTICS_OIS_DATA_MODE_OFF,
+  ANDROID_STATISTICS_OIS_DATA_MODE_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
index bc286c3..a9268c0 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
@@ -38,7 +38,7 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum StatisticsSceneFlicker {
-  ANDROID_STATISTICS_SCENE_FLICKER_NONE = 0,
-  ANDROID_STATISTICS_SCENE_FLICKER_50HZ = 1,
-  ANDROID_STATISTICS_SCENE_FLICKER_60HZ = 2,
+  ANDROID_STATISTICS_SCENE_FLICKER_NONE,
+  ANDROID_STATISTICS_SCENE_FLICKER_50HZ,
+  ANDROID_STATISTICS_SCENE_FLICKER_60HZ,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
index 774a43a..09a2003 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum StatisticsSharpnessMapMode {
-  ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF = 0,
-  ANDROID_STATISTICS_SHARPNESS_MAP_MODE_ON = 1,
+  ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF,
+  ANDROID_STATISTICS_SHARPNESS_MAP_MODE_ON,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncFrameNumber.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncFrameNumber.aidl
index 12ccbb9..230f57e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncFrameNumber.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncFrameNumber.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum SyncFrameNumber {
-  ANDROID_SYNC_FRAME_NUMBER_CONVERGING = -1,
-  ANDROID_SYNC_FRAME_NUMBER_UNKNOWN = -2,
+  ANDROID_SYNC_FRAME_NUMBER_CONVERGING = (-1) /* -1 */,
+  ANDROID_SYNC_FRAME_NUMBER_UNKNOWN = (-2) /* -2 */,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncMaxLatency.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncMaxLatency.aidl
index e0116e7..d484f45 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncMaxLatency.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncMaxLatency.aidl
@@ -39,5 +39,5 @@
 @Backing(type="int") @VintfStability
 enum SyncMaxLatency {
   ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL = 0,
-  ANDROID_SYNC_MAX_LATENCY_UNKNOWN = -1,
+  ANDROID_SYNC_MAX_LATENCY_UNKNOWN = (-1) /* -1 */,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapMode.aidl
index 728b298..e729166 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapMode.aidl
@@ -38,9 +38,9 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum TonemapMode {
-  ANDROID_TONEMAP_MODE_CONTRAST_CURVE = 0,
-  ANDROID_TONEMAP_MODE_FAST = 1,
-  ANDROID_TONEMAP_MODE_HIGH_QUALITY = 2,
-  ANDROID_TONEMAP_MODE_GAMMA_VALUE = 3,
-  ANDROID_TONEMAP_MODE_PRESET_CURVE = 4,
+  ANDROID_TONEMAP_MODE_CONTRAST_CURVE,
+  ANDROID_TONEMAP_MODE_FAST,
+  ANDROID_TONEMAP_MODE_HIGH_QUALITY,
+  ANDROID_TONEMAP_MODE_GAMMA_VALUE,
+  ANDROID_TONEMAP_MODE_PRESET_CURVE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapPresetCurve.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapPresetCurve.aidl
index fc2e39b..2e5fbd3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapPresetCurve.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapPresetCurve.aidl
@@ -38,6 +38,6 @@
 package android.hardware.camera.metadata;
 @Backing(type="int") @VintfStability
 enum TonemapPresetCurve {
-  ANDROID_TONEMAP_PRESET_CURVE_SRGB = 0,
-  ANDROID_TONEMAP_PRESET_CURVE_REC709 = 1,
+  ANDROID_TONEMAP_PRESET_CURVE_SRGB,
+  ANDROID_TONEMAP_PRESET_CURVE_REC709,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
index 99e28b9..73bcc12 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
@@ -61,5 +61,7 @@
     ANDROID_HEIC_INFO,
     ANDROID_AUTOMOTIVE,
     ANDROID_AUTOMOTIVE_LENS,
+    ANDROID_EXTENSION,
+    ANDROID_JPEGR,
     VENDOR_SECTION = 0x8000,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
index 62c71e9..75e7915 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
@@ -63,5 +63,7 @@
     ANDROID_HEIC_INFO_START = CameraMetadataSection.ANDROID_HEIC_INFO << 16,
     ANDROID_AUTOMOTIVE_START = CameraMetadataSection.ANDROID_AUTOMOTIVE << 16,
     ANDROID_AUTOMOTIVE_LENS_START = CameraMetadataSection.ANDROID_AUTOMOTIVE_LENS << 16,
+    ANDROID_EXTENSION_START = CameraMetadataSection.ANDROID_EXTENSION << 16,
+    ANDROID_JPEGR_START = CameraMetadataSection.ANDROID_JPEGR << 16,
     VENDOR_SECTION_START = CameraMetadataSection.VENDOR_SECTION << 16,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 48b1ee4..56aa690 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -450,6 +450,46 @@
      */
     ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION,
     /**
+     * android.control.settingsOverride [dynamic, enum, public]
+     *
+     * <p>The desired CaptureRequest settings override with which certain keys are
+     * applied earlier so that they can take effect sooner.</p>
+     */
+    ANDROID_CONTROL_SETTINGS_OVERRIDE = 65588,
+    /**
+     * android.control.availableSettingsOverrides [static, int32[], public]
+     *
+     * <p>List of available settings overrides supported by the camera device that can
+     * be used to speed up certain controls.</p>
+     */
+    ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
+    /**
+     * android.control.settingsOverridingFrameNumber [dynamic, int32, system]
+     *
+     * <p>The frame number of the newer request overriding this capture.</p>
+     */
+    ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
+    /**
+     * android.control.autoframing [dynamic, enum, public]
+     *
+     * <p>Automatic crop, pan and zoom to keep objects in the center of the frame.</p>
+     */
+    ANDROID_CONTROL_AUTOFRAMING,
+    /**
+     * android.control.autoframingAvailable [static, enum, public]
+     *
+     * <p>Whether the camera device supports ANDROID_CONTROL_AUTOFRAMING.</p>
+     *
+     * @see ANDROID_CONTROL_AUTOFRAMING
+     */
+    ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
+    /**
+     * android.control.autoframingState [dynamic, enum, public]
+     *
+     * <p>Current state of auto-framing.</p>
+     */
+    ANDROID_CONTROL_AUTOFRAMING_STATE,
+    /**
      * android.demosaic.mode [controls, enum, system]
      *
      * <p>Controls the quality of the demosaicing
@@ -1030,6 +1070,12 @@
      */
     ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE,
     /**
+     * android.request.availableColorSpaceProfilesMap [static, enum[], ndk_public]
+     *
+     * <p>A list of all possible color space profiles supported by a camera device.</p>
+     */
+    ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP,
+    /**
      * android.scaler.cropRegion [dynamic, int32[], public]
      *
      * <p>The desired region of the sensor to read out for this capture.</p>
@@ -1238,6 +1284,13 @@
      */
     ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = 851994,
     /**
+     * android.scaler.rawCropRegion [dynamic, int32[], public]
+     *
+     * <p>The region of the sensor that corresponds to the RAW read out for this
+     * capture when the stream use case of a RAW stream is set to CROPPED_RAW.</p>
+     */
+    ANDROID_SCALER_RAW_CROP_REGION,
+    /**
      * android.sensor.exposureTime [dynamic, int64, public]
      *
      * <p>Duration each pixel is exposed to
@@ -2229,8 +2282,8 @@
      *
      * <p>Whether this camera device can support identical set of stream combinations
      * involving HEIC image format, compared to the
-     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html#createCaptureSession">table of combinations</a>
-     * involving JPEG image format required for the device's hardware level and capabilities.</p>
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html#legacy-level-guaranteed-configurations">table of combinations</a> involving JPEG image format required for the device's hardware
+     * level and capabilities.</p>
      */
     ANDROID_HEIC_INFO_SUPPORTED = CameraMetadataSectionStart.ANDROID_HEIC_INFO_START,
     /**
@@ -2252,4 +2305,56 @@
      * passenger seats.</p>
      */
     ANDROID_AUTOMOTIVE_LENS_FACING = CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START,
+    /**
+     * android.jpegr.availableJpegRStreamConfigurations [static, enum[], ndk_public]
+     *
+     * <p>The available Jpeg/R stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     */
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS = CameraMetadataSectionStart.ANDROID_JPEGR_START,
+    /**
+     * android.jpegr.availableJpegRMinFrameDurations [static, int64[], ndk_public]
+     *
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for Jpeg/R output formats.</p>
+     */
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS,
+    /**
+     * android.jpegr.availableJpegRStallDurations [static, int64[], ndk_public]
+     *
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for Jpeg/R streams.</p>
+     */
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS,
+    /**
+     * android.jpegr.availableJpegRStreamConfigurationsMaximumResolution [static, enum[], ndk_public]
+     *
+     * <p>The available Jpeg/R stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     */
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+    /**
+     * android.jpegr.availableJpegRMinFrameDurationsMaximumResolution [static, int64[], ndk_public]
+     *
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for Jpeg/R output formats for CaptureRequests where
+     * ANDROID_SENSOR_PIXEL_MODE is set to
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+     *
+     * @see ANDROID_SENSOR_PIXEL_MODE
+     */
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+    /**
+     * android.jpegr.availableJpegRStallDurationsMaximumResolution [static, int64[], ndk_public]
+     *
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for Jpeg/R streams for CaptureRequests where
+     * ANDROID_SENSOR_PIXEL_MODE is set to
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+     *
+     * @see ANDROID_SENSOR_PIXEL_MODE
+     */
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl
new file mode 100644
index 0000000..0fef373
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.control.autoframing enumeration values
+ * @see ANDROID_CONTROL_AUTOFRAMING
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlAutoframing {
+    ANDROID_CONTROL_AUTOFRAMING_OFF,
+    ANDROID_CONTROL_AUTOFRAMING_ON,
+    ANDROID_CONTROL_AUTOFRAMING_AUTO,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
new file mode 100644
index 0000000..da0d348
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.control.autoframingAvailable enumeration values
+ * @see ANDROID_CONTROL_AUTOFRAMING_AVAILABLE
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlAutoframingAvailable {
+    ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE,
+    ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_TRUE,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl
new file mode 100644
index 0000000..13183a5
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.control.autoframingState enumeration values
+ * @see ANDROID_CONTROL_AUTOFRAMING_STATE
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlAutoframingState {
+    ANDROID_CONTROL_AUTOFRAMING_STATE_INACTIVE,
+    ANDROID_CONTROL_AUTOFRAMING_STATE_FRAMING,
+    ANDROID_CONTROL_AUTOFRAMING_STATE_CONVERGED,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl
new file mode 100644
index 0000000..d97f7c8
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.control.settingsOverride enumeration values
+ * @see ANDROID_CONTROL_SETTINGS_OVERRIDE
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlSettingsOverride {
+    ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF,
+    ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM,
+    ANDROID_CONTROL_SETTINGS_OVERRIDE_VENDOR_START = 0x4000,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
new file mode 100644
index 0000000..911a062
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.jpegr.availableJpegRStreamConfigurations enumeration values
+ * @see ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS
+ */
+@VintfStability
+@Backing(type="int")
+enum JpegrAvailableJpegRStreamConfigurations {
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_OUTPUT,
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..9e78662
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.jpegr.availableJpegRStreamConfigurationsMaximumResolution enumeration values
+ * @see ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION
+ */
+@VintfStability
+@Backing(type="int")
+enum JpegrAvailableJpegRStreamConfigurationsMaximumResolution {
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+    ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
index f5c77eb..ebe0b4c 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
@@ -49,4 +49,5 @@
     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING,
     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT,
     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE,
+    ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
new file mode 100644
index 0000000..b397dea
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.request.availableColorSpaceProfilesMap enumeration values
+ * @see ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP
+ */
+@VintfStability
+@Backing(type="long")
+enum RequestAvailableColorSpaceProfilesMap {
+    ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED = -1L,
+    ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB = 0L,
+    ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3 = 7L,
+    ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG = 16L,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
index daa0fd3..da27a48 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
@@ -35,5 +35,6 @@
     ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3L,
     ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4L,
     ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5L,
+    ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 0x6L,
     ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 0x10000L,
 }
diff --git a/camera/provider/2.4/default/OWNERS b/camera/provider/2.4/default/OWNERS
deleted file mode 100644
index f48a95c..0000000
--- a/camera/provider/2.4/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/provider/2.4/vts/OWNERS b/camera/provider/2.4/vts/OWNERS
deleted file mode 100644
index eb4f0e4..0000000
--- a/camera/provider/2.4/vts/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-# Bug component: 41727
-
-# Camera team
-include platform/frameworks/av:/camera/OWNERS
-
-# VTS team
-yim@google.com
-zhuoyao@google.com
diff --git a/camera/provider/2.4/vts/functional/OWNERS b/camera/provider/2.4/vts/functional/OWNERS
deleted file mode 100644
index 479f465..0000000
--- a/camera/provider/2.4/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 41727
-epeev@google.com
diff --git a/camera/provider/2.5/default/OWNERS b/camera/provider/2.5/default/OWNERS
deleted file mode 100644
index f48a95c..0000000
--- a/camera/provider/2.5/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include platform/frameworks/av:/camera/OWNERS
diff --git a/camera/provider/README.md b/camera/provider/README.md
index 0718fb1..7666a58 100644
--- a/camera/provider/README.md
+++ b/camera/provider/README.md
@@ -35,3 +35,9 @@
 First HIDL version of the camara provider HAL callback interface, closely
 matching the feature set and operation of the pre-HIDL camera HAL module
 callbacks v2.4.
+
+### AIDL Camera HAL Default Implementation ###
+
+The default implementation can be found at
+$ANDROID_BUILD_TOP/hardware/google/camera/common/hal/aidl_service and
+$ANDROID_BUILD_TOP/hardware/google/camera/devices/EmulatedCamera
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index f082bce..35ec976 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -14,9 +14,10 @@
         "android/hardware/camera/provider/*.aidl",
     ],
     imports: [
-        "android.hardware.camera.device",
-        "android.hardware.camera.common",
+        "android.hardware.camera.device-V2",
+        "android.hardware.camera.common-V1",
     ],
+    frozen: true,
     stability: "vintf",
     backend: {
         java: {
@@ -25,11 +26,6 @@
         cpp: {
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
@@ -39,6 +35,14 @@
                 "android.hardware.camera.common-V1",
             ],
         },
+        {
+            version: "2",
+            imports: [
+                "android.hardware.camera.device-V2",
+                "android.hardware.camera.common-V1",
+            ],
+        },
+
     ],
 
 }
diff --git a/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/.hash b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/.hash
new file mode 100644
index 0000000..2770775
--- /dev/null
+++ b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/.hash
@@ -0,0 +1 @@
+5c3de5da344a2cf7f68e1078a9ed9d6770e59136
diff --git a/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/CameraIdAndStreamCombination.aidl b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/CameraIdAndStreamCombination.aidl
new file mode 100644
index 0000000..df77c40
--- /dev/null
+++ b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/CameraIdAndStreamCombination.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.provider;
+@VintfStability
+parcelable CameraIdAndStreamCombination {
+  String cameraId;
+  android.hardware.camera.device.StreamConfiguration streamConfiguration;
+}
diff --git a/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/ConcurrentCameraIdCombination.aidl b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/ConcurrentCameraIdCombination.aidl
new file mode 100644
index 0000000..334fb2c
--- /dev/null
+++ b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/ConcurrentCameraIdCombination.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.provider;
+@VintfStability
+parcelable ConcurrentCameraIdCombination {
+  List<String> combination;
+}
diff --git a/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/ICameraProvider.aidl b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/ICameraProvider.aidl
new file mode 100644
index 0000000..2f0184f
--- /dev/null
+++ b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/ICameraProvider.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.provider;
+@VintfStability
+interface ICameraProvider {
+  void setCallback(android.hardware.camera.provider.ICameraProviderCallback callback);
+  android.hardware.camera.common.VendorTagSection[] getVendorTags();
+  String[] getCameraIdList();
+  android.hardware.camera.device.ICameraDevice getCameraDeviceInterface(String cameraDeviceName);
+  void notifyDeviceStateChange(long deviceState);
+  android.hardware.camera.provider.ConcurrentCameraIdCombination[] getConcurrentCameraIds();
+  boolean isConcurrentStreamCombinationSupported(in android.hardware.camera.provider.CameraIdAndStreamCombination[] configs);
+  const long DEVICE_STATE_NORMAL = 0;
+  const long DEVICE_STATE_BACK_COVERED = (1 << 0) /* 1 */;
+  const long DEVICE_STATE_FRONT_COVERED = (1 << 1) /* 2 */;
+  const long DEVICE_STATE_FOLDED = (1 << 2) /* 4 */;
+}
diff --git a/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/ICameraProviderCallback.aidl b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/ICameraProviderCallback.aidl
new file mode 100644
index 0000000..d3c53f5
--- /dev/null
+++ b/camera/provider/aidl/aidl_api/android.hardware.camera.provider/2/android/hardware/camera/provider/ICameraProviderCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.camera.provider;
+@VintfStability
+interface ICameraProviderCallback {
+  void cameraDeviceStatusChange(String cameraDeviceName, android.hardware.camera.common.CameraDeviceStatus newStatus);
+  void torchModeStatusChange(String cameraDeviceName, android.hardware.camera.common.TorchModeStatus newStatus);
+  void physicalCameraDeviceStatusChange(String cameraDeviceName, String physicalCameraDeviceName, android.hardware.camera.common.CameraDeviceStatus newStatus);
+}
diff --git a/camera/provider/aidl/vts/Android.bp b/camera/provider/aidl/vts/Android.bp
index 727ef03..8429b21 100644
--- a/camera/provider/aidl/vts/Android.bp
+++ b/camera/provider/aidl/vts/Android.bp
@@ -27,6 +27,7 @@
     name: "VtsAidlHalCameraProvider_TargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
+        "android.hardware.graphics.common-ndk_static",
         "use_libaidlvintf_gtest_helper_static",
     ],
     srcs: [
@@ -58,10 +59,9 @@
     static_libs: [
         "android.hardware.camera.common@1.0-helper",
         "android.hardware.camera.common-V1-ndk",
-        "android.hardware.camera.device-V1-ndk",
-        "android.hardware.camera.metadata-V1-ndk",
-        "android.hardware.camera.provider-V1-ndk",
-        "android.hardware.graphics.common-V3-ndk",
+        "android.hardware.camera.device-V2-ndk",
+        "android.hardware.camera.metadata-V2-ndk",
+        "android.hardware.camera.provider-V2-ndk",
         "android.hidl.allocator@1.0",
         "libgrallocusage",
         "libhidlmemory",
diff --git a/camera/provider/aidl/vts/OWNERS b/camera/provider/aidl/vts/OWNERS
deleted file mode 100644
index 27d370b..0000000
--- a/camera/provider/aidl/vts/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Camera team
-include platform/frameworks/av:/camera/OWNERS
-
-# VTS team
-yim@google.com
-zhuoyao@google.com
\ No newline at end of file
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index b764ad6..2845180 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -36,6 +36,7 @@
 using ::aidl::android::hardware::camera::common::TorchModeStatus;
 using ::aidl::android::hardware::camera::common::VendorTagSection;
 using ::aidl::android::hardware::camera::device::ICameraDevice;
+using ::aidl::android::hardware::camera::metadata::RequestAvailableColorSpaceProfilesMap;
 using ::aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
 using ::aidl::android::hardware::camera::metadata::SensorPixelMode;
 using ::aidl::android::hardware::camera::provider::CameraIdAndStreamCombination;
@@ -550,6 +551,11 @@
             stream.rotation = StreamRotation::ROTATION_0;
             stream.dynamicRangeProfile = RequestAvailableDynamicRangeProfilesMap::
                     ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
+            stream.useCase = ScalerAvailableStreamUseCases::
+                    ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
+            stream.colorSpace = static_cast<int>(
+                    RequestAvailableColorSpaceProfilesMap::
+                            ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED);
 
             std::vector<Stream> streams = {stream};
             StreamConfiguration config;
@@ -2025,6 +2031,61 @@
     }
 }
 
+TEST_P(CameraAidlTest, process8BitColorSpaceRequests) {
+    static int profiles[] = {ColorSpaceNamed::DISPLAY_P3, ColorSpaceNamed::SRGB};
+
+    for (int32_t i = 0; i < sizeof(profiles) / sizeof(profiles[0]); i++) {
+        processColorSpaceRequest(static_cast<RequestAvailableColorSpaceProfilesMap>(profiles[i]),
+                static_cast<RequestAvailableDynamicRangeProfilesMap>(
+                ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD));
+    }
+}
+
+TEST_P(CameraAidlTest, process10BitColorSpaceRequests) {
+    static const camera_metadata_enum_android_request_available_dynamic_range_profiles_map
+            dynamicRangeProfiles[] = {
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM,
+        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO
+    };
+
+    // Process all dynamic range profiles with BT2020_HLG
+    for (int32_t i = 0; i < sizeof(dynamicRangeProfiles) / sizeof(dynamicRangeProfiles[0]); i++) {
+        processColorSpaceRequest(
+                static_cast<RequestAvailableColorSpaceProfilesMap>(ColorSpaceNamed::BT2020_HLG),
+                static_cast<RequestAvailableDynamicRangeProfilesMap>(dynamicRangeProfiles[i]));
+    }
+}
+
+TEST_P(CameraAidlTest, processZoomSettingsOverrideRequests) {
+    const int32_t kFrameCount = 5;
+    const int32_t kTestCases = 2;
+    const bool kOverrideSequence[kTestCases][kFrameCount] = {// ZOOM, ZOOM, ZOOM, ZOOM, ZOOM;
+                                                             {true, true, true, true, true},
+                                                             // OFF, ZOOM, ZOOM, ZOOM, OFF;
+                                                             {false, true, true, true, false}};
+    const bool kExpectedOverrideResults[kTestCases][kFrameCount] = {
+            // All resuls should be overridden except the last one. The last result's
+            // zoom doesn't have speed-up.
+            {true, true, true, true, false},
+            // Because we require at least 1 frame speed-up, request #1, #2 and #3
+            // will be overridden.
+            {true, true, true, false, false}};
+
+    for (int i = 0; i < kTestCases; i++) {
+        processZoomSettingsOverrideRequests(kFrameCount, kOverrideSequence[i],
+                kExpectedOverrideResults[i]);
+    }
+}
+
 // Generate and verify a burst containing alternating sensor sensitivity values
 TEST_P(CameraAidlTest, processCaptureRequestBurstISO) {
     std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
@@ -2973,10 +3034,28 @@
     }
 }
 
+TEST_P(CameraAidlTest, configureStreamsUseCasesCroppedRaw) {
+    AvailableStream rawStreamThreshold =
+            {INT_MAX, INT_MAX, static_cast<int32_t>(PixelFormat::RAW16)};
+    configureStreamUseCaseInternal(rawStreamThreshold);
+}
+
 // Verify that  valid stream use cases can be configured successfully, and invalid use cases
 // fail stream configuration.
 TEST_P(CameraAidlTest, configureStreamsUseCases) {
+    AvailableStream previewStreamThreshold =
+            {kMaxPreviewWidth, kMaxPreviewHeight, static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
+    configureStreamUseCaseInternal(previewStreamThreshold);
+}
+
+// Validate the integrity of stream configuration metadata
+TEST_P(CameraAidlTest, validateStreamConfigurations) {
     std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+    std::vector<AvailableStream> outputStreams;
+
+    const int32_t scalerSizesTag = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
+    const int32_t scalerMinFrameDurationsTag = ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
+    const int32_t scalerStallDurationsTag = ANDROID_SCALER_AVAILABLE_STALL_DURATIONS;
 
     for (const auto& name : cameraDeviceNames) {
         CameraMetadata meta;
@@ -2984,97 +3063,31 @@
 
         openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
                                &cameraDevice /*out*/);
-
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
-        // Check if camera support depth only
-        if (isDepthOnly(staticMeta)) {
-            ndk::ScopedAStatus ret = mSession->close();
-            mSession = nullptr;
-            ASSERT_TRUE(ret.isOk());
-            continue;
+
+        if (is10BitDynamicRangeCapable(staticMeta)) {
+            std::vector<std::tuple<size_t, size_t>> supportedP010Sizes, supportedBlobSizes;
+
+            getSupportedSizes(staticMeta, scalerSizesTag, HAL_PIXEL_FORMAT_BLOB,
+                              &supportedBlobSizes);
+            getSupportedSizes(staticMeta, scalerSizesTag, HAL_PIXEL_FORMAT_YCBCR_P010,
+                              &supportedP010Sizes);
+            ASSERT_FALSE(supportedP010Sizes.empty());
+
+            std::vector<int64_t> blobMinDurations, blobStallDurations;
+            getSupportedDurations(staticMeta, scalerMinFrameDurationsTag, HAL_PIXEL_FORMAT_BLOB,
+                                  supportedP010Sizes, &blobMinDurations);
+            getSupportedDurations(staticMeta, scalerStallDurationsTag, HAL_PIXEL_FORMAT_BLOB,
+                                  supportedP010Sizes, &blobStallDurations);
+            ASSERT_FALSE(blobStallDurations.empty());
+            ASSERT_FALSE(blobMinDurations.empty());
+            ASSERT_EQ(supportedP010Sizes.size(), blobMinDurations.size());
+            ASSERT_EQ(blobMinDurations.size(), blobStallDurations.size());
         }
 
-        std::vector<AvailableStream> outputPreviewStreams;
-        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-                                            static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
-        ASSERT_EQ(Status::OK,
-                  getAvailableOutputStreams(staticMeta, outputPreviewStreams, &previewThreshold));
-        ASSERT_NE(0u, outputPreviewStreams.size());
+        // TODO (b/280887191): Validate other aspects of stream configuration metadata...
 
-        // Combine valid and invalid stream use cases
-        std::vector<int64_t> useCases(kMandatoryUseCases);
-        useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL + 1);
-
-        std::vector<int64_t> supportedUseCases;
-        camera_metadata_ro_entry entry;
-        auto retcode = find_camera_metadata_ro_entry(
-                staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry);
-        if ((0 == retcode) && (entry.count > 0)) {
-            supportedUseCases.insert(supportedUseCases.end(), entry.data.i64,
-                                     entry.data.i64 + entry.count);
-        } else {
-            supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
-        }
-
-        std::vector<Stream> streams(1);
-        streams[0] = {0,
-                      StreamType::OUTPUT,
-                      outputPreviewStreams[0].width,
-                      outputPreviewStreams[0].height,
-                      static_cast<PixelFormat>(outputPreviewStreams[0].format),
-                      static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
-                              GRALLOC1_CONSUMER_USAGE_CPU_READ),
-                      Dataspace::UNKNOWN,
-                      StreamRotation::ROTATION_0,
-                      std::string(),
-                      0,
-                      -1,
-                      {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
-                      RequestAvailableDynamicRangeProfilesMap::
-                              ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
-
-        int32_t streamConfigCounter = 0;
-        CameraMetadata req;
-        StreamConfiguration config;
-        RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE;
-        ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &req);
-        ASSERT_TRUE(ret.isOk());
-        config.sessionParams = req;
-
-        for (int64_t useCase : useCases) {
-            bool useCaseSupported = std::find(supportedUseCases.begin(), supportedUseCases.end(),
-                                              useCase) != supportedUseCases.end();
-
-            streams[0].useCase = static_cast<
-                    aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases>(
-                    useCase);
-            config.streams = streams;
-            config.operationMode = StreamConfigurationMode::NORMAL_MODE;
-            config.streamConfigCounter = streamConfigCounter;
-            config.multiResolutionInputImage = false;
-
-            bool combSupported;
-            ret = cameraDevice->isStreamCombinationSupported(config, &combSupported);
-            if (static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED) ==
-                ret.getServiceSpecificError()) {
-                continue;
-            }
-
-            ASSERT_TRUE(ret.isOk());
-            ASSERT_EQ(combSupported, useCaseSupported);
-
-            std::vector<HalStream> halStreams;
-            ret = mSession->configureStreams(config, &halStreams);
-            ALOGI("configureStreams returns status: %d", ret.getServiceSpecificError());
-            if (useCaseSupported) {
-                ASSERT_TRUE(ret.isOk());
-                ASSERT_EQ(1u, halStreams.size());
-            } else {
-                ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
-                          ret.getServiceSpecificError());
-            }
-        }
-        ret = mSession->close();
+        ndk::ScopedAStatus ret = mSession->close();
         mSession = nullptr;
         ASSERT_TRUE(ret.isOk());
     }
@@ -3084,4 +3097,4 @@
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, CameraAidlTest,
         testing::ValuesIn(android::getAidlHalInstanceNames(ICameraProvider::descriptor)),
-        android::hardware::PrintInstanceNameToString);
\ No newline at end of file
+        android::hardware::PrintInstanceNameToString);
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index ef3ce4f..9559a1e 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -22,6 +22,7 @@
 #include <HandleImporter.h>
 #include <aidl/android/hardware/camera/device/ICameraDevice.h>
 #include <aidl/android/hardware/camera/metadata/CameraMetadataTag.h>
+#include <aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.h>
 #include <aidl/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.h>
 #include <aidl/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.h>
 #include <aidl/android/hardware/camera/metadata/SensorPixelMode.h>
@@ -44,7 +45,6 @@
 using ::aidl::android::hardware::camera::device::CameraMetadata;
 using ::aidl::android::hardware::camera::device::ICameraDevice;
 using ::aidl::android::hardware::camera::metadata::CameraMetadataTag;
-using ::aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
 using ::aidl::android::hardware::camera::metadata::SensorInfoColorFilterArrangement;
 using ::aidl::android::hardware::camera::metadata::SensorPixelMode;
 using ::aidl::android::hardware::camera::provider::BnCameraProviderCallback;
@@ -120,7 +120,7 @@
     ABinderProcess_startThreadPool();
 
     SpAIBinder cameraProviderBinder =
-            SpAIBinder(AServiceManager_getService(serviceDescriptor.c_str()));
+            SpAIBinder(AServiceManager_waitForService(serviceDescriptor.c_str()));
     ASSERT_NE(cameraProviderBinder.get(), nullptr);
 
     std::shared_ptr<ICameraProvider> cameraProvider =
@@ -310,21 +310,11 @@
 
 void CameraAidlTest::verifyStreamUseCaseCharacteristics(const camera_metadata_t* metadata) {
     camera_metadata_ro_entry entry;
-    // Check capabilities
-    int retcode =
-            find_camera_metadata_ro_entry(metadata, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
-    bool hasStreamUseCaseCap = false;
-    if ((0 == retcode) && (entry.count > 0)) {
-        if (std::find(entry.data.u8, entry.data.u8 + entry.count,
-                      ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE) !=
-            entry.data.u8 + entry.count) {
-            hasStreamUseCaseCap = true;
-        }
-    }
+    bool hasStreamUseCaseCap = supportsStreamUseCaseCap(metadata);
 
     bool supportMandatoryUseCases = false;
-    retcode = find_camera_metadata_ro_entry(metadata, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
-                                            &entry);
+    int retcode = find_camera_metadata_ro_entry(metadata, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
+                                                &entry);
     if ((0 == retcode) && (entry.count > 0)) {
         supportMandatoryUseCases = true;
         for (size_t i = 0; i < kMandatoryUseCases.size(); i++) {
@@ -339,8 +329,8 @@
             if (entry.data.i64[i] == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
                 supportDefaultUseCase = true;
             }
-            ASSERT_TRUE(entry.data.i64[i] <= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL ||
-                        entry.data.i64[i] >=
+            ASSERT_TRUE(entry.data.i64[i] <= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW
+                        || entry.data.i64[i] >=
                                 ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START);
         }
         ASSERT_TRUE(supportDefaultUseCase);
@@ -349,6 +339,69 @@
     ASSERT_EQ(hasStreamUseCaseCap, supportMandatoryUseCases);
 }
 
+void CameraAidlTest::verifySettingsOverrideCharacteristics(const camera_metadata_t* metadata) {
+    camera_metadata_ro_entry entry;
+    int retcode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES, &entry);
+    bool supportSettingsOverride = false;
+    if (0 == retcode) {
+        supportSettingsOverride = true;
+        bool hasOff = false;
+        for (size_t i = 0; i < entry.count; i++) {
+            if (entry.data.u8[i] == ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF) {
+                hasOff = true;
+            }
+        }
+        ASSERT_TRUE(hasOff);
+    }
+
+    // Check availableRequestKeys
+    retcode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry);
+    bool hasSettingsOverrideRequestKey = false;
+    if ((0 == retcode) && (entry.count > 0)) {
+        hasSettingsOverrideRequestKey =
+                std::find(entry.data.i32, entry.data.i32 + entry.count,
+                        ANDROID_CONTROL_SETTINGS_OVERRIDE) != entry.data.i32 + entry.count;
+    } else {
+        ADD_FAILURE() << "Get camera availableRequestKeys failed!";
+    }
+
+    // Check availableResultKeys
+    retcode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
+    bool hasSettingsOverrideResultKey = false;
+    bool hasOverridingFrameNumberKey = false;
+    if ((0 == retcode) && (entry.count > 0)) {
+        hasSettingsOverrideResultKey =
+                std::find(entry.data.i32, entry.data.i32 + entry.count,
+                        ANDROID_CONTROL_SETTINGS_OVERRIDE) != entry.data.i32 + entry.count;
+        hasOverridingFrameNumberKey =
+                std::find(entry.data.i32, entry.data.i32 + entry.count,
+                        ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER)
+                        != entry.data.i32 + entry.count;
+    } else {
+        ADD_FAILURE() << "Get camera availableResultKeys failed!";
+    }
+
+    // Check availableCharacteristicKeys
+    retcode = find_camera_metadata_ro_entry(metadata,
+            ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry);
+    bool hasSettingsOverrideCharacteristicsKey= false;
+    if ((0 == retcode) && (entry.count > 0)) {
+        hasSettingsOverrideCharacteristicsKey = std::find(entry.data.i32,
+                entry.data.i32 + entry.count, ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES)
+                        != entry.data.i32 + entry.count;
+    } else {
+        ADD_FAILURE() << "Get camera availableCharacteristicsKeys failed!";
+    }
+
+    ASSERT_EQ(supportSettingsOverride, hasSettingsOverrideRequestKey);
+    ASSERT_EQ(supportSettingsOverride, hasSettingsOverrideResultKey);
+    ASSERT_EQ(supportSettingsOverride, hasOverridingFrameNumberKey);
+    ASSERT_EQ(supportSettingsOverride, hasSettingsOverrideCharacteristicsKey);
+}
+
 Status CameraAidlTest::isMonochromeCamera(const camera_metadata_t* staticMeta) {
     Status ret = Status::OPERATION_NOT_SUPPORTED;
     if (nullptr == staticMeta) {
@@ -624,6 +677,7 @@
     verifyExtendedSceneModeCharacteristics(metadata);
     verifyZoomCharacteristics(metadata);
     verifyStreamUseCaseCharacteristics(metadata);
+    verifySettingsOverrideCharacteristics(metadata);
 }
 
 void CameraAidlTest::verifyExtendedSceneModeCharacteristics(const camera_metadata_t* metadata) {
@@ -1537,6 +1591,15 @@
         ASSERT_EQ(zoomRatioEntry.count, 1);
         ASSERT_EQ(zoomRatioEntry.data.f[0], 1.0f);
     }
+
+    // Check settings override
+    camera_metadata_ro_entry settingsOverrideEntry;
+    int foundSettingsOverride = find_camera_metadata_ro_entry(metadata,
+           ANDROID_CONTROL_SETTINGS_OVERRIDE, &settingsOverrideEntry);
+    if (foundSettingsOverride == 0) {
+        ASSERT_EQ(settingsOverrideEntry.count, 1);
+        ASSERT_EQ(settingsOverrideEntry.data.u8[0], ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF);
+    }
 }
 
 void CameraAidlTest::openEmptyDeviceSession(const std::string& name,
@@ -2111,6 +2174,126 @@
     }
 }
 
+void CameraAidlTest::configureStreamUseCaseInternal(const AvailableStream &threshold) {
+    std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+
+    for (const auto& name : cameraDeviceNames) {
+        CameraMetadata meta;
+        std::shared_ptr<ICameraDevice> cameraDevice;
+
+        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
+                               &cameraDevice /*out*/);
+
+        camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
+        // Check if camera support depth only or doesn't support stream use case capability
+        if (isDepthOnly(staticMeta) || !supportsStreamUseCaseCap(staticMeta) ||
+            (threshold.format == static_cast<int32_t>(PixelFormat::RAW16) &&
+             !supportsCroppedRawUseCase(staticMeta))) {
+            ndk::ScopedAStatus ret = mSession->close();
+            mSession = nullptr;
+            ASSERT_TRUE(ret.isOk());
+            continue;
+        }
+
+        std::vector<AvailableStream> outputPreviewStreams;
+
+        ASSERT_EQ(Status::OK,
+                  getAvailableOutputStreams(staticMeta, outputPreviewStreams, &threshold));
+        ASSERT_NE(0u, outputPreviewStreams.size());
+
+        // Combine valid and invalid stream use cases
+        std::vector<int64_t> useCases(kMandatoryUseCases);
+        useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW + 1);
+
+        std::vector<int64_t> supportedUseCases;
+        if (threshold.format == static_cast<int32_t>(PixelFormat::RAW16)) {
+            // If the format is RAW16, supported use case is only CROPPED_RAW.
+            // All others are unsupported for this format.
+            useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW);
+            supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW);
+            supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+        } else {
+            camera_metadata_ro_entry entry;
+            auto retcode = find_camera_metadata_ro_entry(
+                    staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry);
+            if ((0 == retcode) && (entry.count > 0)) {
+                supportedUseCases.insert(supportedUseCases.end(), entry.data.i64,
+                                         entry.data.i64 + entry.count);
+            } else {
+                supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+            }
+        }
+
+        std::vector<Stream> streams(1);
+        streams[0] = {
+                0,
+                StreamType::OUTPUT,
+                outputPreviewStreams[0].width,
+                outputPreviewStreams[0].height,
+                static_cast<PixelFormat>(outputPreviewStreams[0].format),
+                static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
+                        GRALLOC1_CONSUMER_USAGE_CPU_READ),
+                Dataspace::UNKNOWN,
+                StreamRotation::ROTATION_0,
+                std::string(),
+                0,
+                -1,
+                {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+                RequestAvailableDynamicRangeProfilesMap::
+                        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+                ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+                static_cast<int>(
+                        RequestAvailableColorSpaceProfilesMap::
+                                ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED)};
+
+        int32_t streamConfigCounter = 0;
+        CameraMetadata req;
+        StreamConfiguration config;
+        RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE;
+        ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &req);
+        ASSERT_TRUE(ret.isOk());
+        config.sessionParams = req;
+
+        for (int64_t useCase : useCases) {
+            bool useCaseSupported = std::find(supportedUseCases.begin(), supportedUseCases.end(),
+                                              useCase) != supportedUseCases.end();
+
+            streams[0].useCase = static_cast<
+                    aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases>(
+                    useCase);
+            config.streams = streams;
+            config.operationMode = StreamConfigurationMode::NORMAL_MODE;
+            config.streamConfigCounter = streamConfigCounter;
+            config.multiResolutionInputImage = false;
+
+            bool combSupported;
+            ret = cameraDevice->isStreamCombinationSupported(config, &combSupported);
+            if (static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED) ==
+                ret.getServiceSpecificError()) {
+                continue;
+            }
+
+            ASSERT_TRUE(ret.isOk());
+            ASSERT_EQ(combSupported, useCaseSupported);
+
+            std::vector<HalStream> halStreams;
+            ret = mSession->configureStreams(config, &halStreams);
+            ALOGI("configureStreams returns status: %d", ret.getServiceSpecificError());
+            if (useCaseSupported) {
+                ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(1u, halStreams.size());
+            } else {
+                ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
+                          ret.getServiceSpecificError());
+            }
+        }
+        ret = mSession->close();
+        mSession = nullptr;
+        ASSERT_TRUE(ret.isOk());
+    }
+
+}
+
 void CameraAidlTest::configureSingleStream(
         const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
         const AvailableStream* previewThreshold, uint64_t bufferUsage, RequestTemplate reqTemplate,
@@ -2205,7 +2388,11 @@
                   /*groupId*/ -1,
                   {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
                   RequestAvailableDynamicRangeProfilesMap::
-                          ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+                          ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+                  ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+                  static_cast<int>(
+                          RequestAvailableColorSpaceProfilesMap::
+                                  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED)};
 
     StreamConfiguration config;
     config.streams = streams;
@@ -2536,21 +2723,26 @@
     std::vector<Stream> streams(physicalIds.size());
     int32_t streamId = 0;
     for (auto const& physicalId : physicalIds) {
-        streams[streamId] = {streamId,
-                             StreamType::OUTPUT,
-                             outputPreviewStreams[0].width,
-                             outputPreviewStreams[0].height,
-                             static_cast<PixelFormat>(outputPreviewStreams[0].format),
-                             static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
-                                     GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
-                             Dataspace::UNKNOWN,
-                             StreamRotation::ROTATION_0,
-                             physicalId,
-                             0,
-                             -1,
-                             {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
-                             RequestAvailableDynamicRangeProfilesMap::
-                                     ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+        streams[streamId] = {
+                streamId,
+                StreamType::OUTPUT,
+                outputPreviewStreams[0].width,
+                outputPreviewStreams[0].height,
+                static_cast<PixelFormat>(outputPreviewStreams[0].format),
+                static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+                        GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
+                Dataspace::UNKNOWN,
+                StreamRotation::ROTATION_0,
+                physicalId,
+                0,
+                -1,
+                {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+                RequestAvailableDynamicRangeProfilesMap::
+                        ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+                ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+                static_cast<int>(
+                        RequestAvailableColorSpaceProfilesMap::
+                                ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED)};
         streamId++;
     }
 
@@ -2609,7 +2801,8 @@
                                       bool* supportsPartialResults, int32_t* partialResultCount,
                                       bool* useHalBufManager, std::shared_ptr<DeviceCb>* outCb,
                                       uint32_t streamConfigCounter, bool maxResolution,
-                                      RequestAvailableDynamicRangeProfilesMap prof) {
+                                      RequestAvailableDynamicRangeProfilesMap dynamicRangeProf,
+                                      RequestAvailableColorSpaceProfilesMap colorSpaceProf) {
     ASSERT_NE(nullptr, session);
     ASSERT_NE(nullptr, halStreams);
     ASSERT_NE(nullptr, previewStream);
@@ -2691,7 +2884,9 @@
                   -1,
                   {maxResolution ? SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION
                                  : SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
-                  prof};
+                  dynamicRangeProf,
+                  ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+                  static_cast<int>(colorSpaceProf)};
 
     StreamConfiguration config;
     config.streams = streams;
@@ -2812,6 +3007,226 @@
     }
 }
 
+bool CameraAidlTest::reportsColorSpaces(const camera_metadata_t* staticMeta) {
+    camera_metadata_ro_entry capabilityEntry;
+    int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+                                           &capabilityEntry);
+    if (rc == 0) {
+        for (uint32_t i = 0; i < capabilityEntry.count; i++) {
+            if (capabilityEntry.data.u8[i] ==
+                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+void CameraAidlTest::getColorSpaceProfiles(
+        const camera_metadata_t* staticMeta,
+        std::vector<RequestAvailableColorSpaceProfilesMap>* profiles) {
+    ASSERT_NE(nullptr, staticMeta);
+    ASSERT_NE(nullptr, profiles);
+    camera_metadata_ro_entry entry;
+    int rc = find_camera_metadata_ro_entry(
+            staticMeta, ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP, &entry);
+    ASSERT_EQ(rc, 0);
+    ASSERT_TRUE(entry.count > 0);
+    ASSERT_EQ(entry.count % 3, 0);
+
+    for (uint32_t i = 0; i < entry.count; i += 3) {
+        ASSERT_NE(entry.data.i64[i],
+                ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED);
+        if (std::find(profiles->begin(), profiles->end(),
+                static_cast<RequestAvailableColorSpaceProfilesMap>(entry.data.i64[i]))
+                == profiles->end()) {
+            profiles->emplace_back(
+                    static_cast<RequestAvailableColorSpaceProfilesMap>(entry.data.i64[i]));
+        }
+    }
+}
+
+bool CameraAidlTest::isColorSpaceCompatibleWithDynamicRangeAndPixelFormat(
+        const camera_metadata_t* staticMeta,
+        RequestAvailableColorSpaceProfilesMap colorSpace,
+        RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile,
+        aidl::android::hardware::graphics::common::PixelFormat pixelFormat) {
+    camera_metadata_ro_entry entry;
+    int rc = find_camera_metadata_ro_entry(
+            staticMeta, ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP, &entry);
+
+    if (rc == 0) {
+        for (uint32_t i = 0; i < entry.count; i += 3) {
+            RequestAvailableColorSpaceProfilesMap entryColorSpace =
+                    static_cast<RequestAvailableColorSpaceProfilesMap>(entry.data.i64[i]);
+            int64_t dynamicRangeProfileI64 = static_cast<int64_t>(dynamicRangeProfile);
+            int32_t entryImageFormat = static_cast<int32_t>(entry.data.i64[i + 1]);
+            int32_t expectedImageFormat = halFormatToPublicFormat(pixelFormat);
+            if (entryColorSpace == colorSpace
+                    && (entry.data.i64[i + 2] & dynamicRangeProfileI64) != 0
+                    && entryImageFormat == expectedImageFormat) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+const char* CameraAidlTest::getColorSpaceProfileString(
+        RequestAvailableColorSpaceProfilesMap colorSpace) {
+    auto colorSpaceCast = static_cast<int>(colorSpace);
+    switch (colorSpaceCast) {
+        case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED:
+            return "UNSPECIFIED";
+        case ColorSpaceNamed::SRGB:
+            return "SRGB";
+        case ColorSpaceNamed::LINEAR_SRGB:
+            return "LINEAR_SRGB";
+        case ColorSpaceNamed::EXTENDED_SRGB:
+            return "EXTENDED_SRGB";
+        case ColorSpaceNamed::LINEAR_EXTENDED_SRGB:
+            return "LINEAR_EXTENDED_SRGB";
+        case ColorSpaceNamed::BT709:
+            return "BT709";
+        case ColorSpaceNamed::BT2020:
+            return "BT2020";
+        case ColorSpaceNamed::DCI_P3:
+            return "DCI_P3";
+        case ColorSpaceNamed::DISPLAY_P3:
+            return "DISPLAY_P3";
+        case ColorSpaceNamed::NTSC_1953:
+            return "NTSC_1953";
+        case ColorSpaceNamed::SMPTE_C:
+            return "SMPTE_C";
+        case ColorSpaceNamed::ADOBE_RGB:
+            return "ADOBE_RGB";
+        case ColorSpaceNamed::PRO_PHOTO_RGB:
+            return "PRO_PHOTO_RGB";
+        case ColorSpaceNamed::ACES:
+            return "ACES";
+        case ColorSpaceNamed::ACESCG:
+            return "ACESCG";
+        case ColorSpaceNamed::CIE_XYZ:
+            return "CIE_XYZ";
+        case ColorSpaceNamed::CIE_LAB:
+            return "CIE_LAB";
+        case ColorSpaceNamed::BT2020_HLG:
+            return "BT2020_HLG";
+        case ColorSpaceNamed::BT2020_PQ:
+            return "BT2020_PQ";
+        default:
+            return "INVALID";
+    }
+
+    return "INVALID";
+}
+
+const char* CameraAidlTest::getDynamicRangeProfileString(
+        RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile) {
+    auto dynamicRangeProfileCast =
+            static_cast<camera_metadata_enum_android_request_available_dynamic_range_profiles_map>
+            (dynamicRangeProfile);
+    switch (dynamicRangeProfileCast) {
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD:
+            return "STANDARD";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
+            return "HLG10";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
+            return "HDR10";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
+            return "HDR10_PLUS";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
+            return "DOLBY_VISION_10B_HDR_REF";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
+            return "DOLBY_VISION_10B_HDR_REF_P0";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
+            return "DOLBY_VISION_10B_HDR_OEM";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
+            return "DOLBY_VISION_10B_HDR_OEM_P0";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF:
+            return "DOLBY_VISION_8B_HDR_REF";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO:
+            return "DOLBY_VISION_8B_HDR_REF_P0";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM:
+            return "DOLBY_VISION_8B_HDR_OEM";
+        case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO:
+            return "DOLBY_VISION_8B_HDR_OEM_P0";
+        default:
+            return "INVALID";
+    }
+
+    return "INVALID";
+}
+
+int32_t CameraAidlTest::halFormatToPublicFormat(
+        aidl::android::hardware::graphics::common::PixelFormat pixelFormat) {
+    // This is an incomplete mapping of pixel format to image format and assumes dataspaces
+    // (see getDataspace)
+    switch (pixelFormat) {
+    case PixelFormat::BLOB:
+        return 0x100; // ImageFormat.JPEG
+    case PixelFormat::Y16:
+        return 0x44363159; // ImageFormat.DEPTH16
+    default:
+        return static_cast<int32_t>(pixelFormat);
+    }
+}
+
+bool CameraAidlTest::supportZoomSettingsOverride(const camera_metadata_t* staticMeta) {
+    camera_metadata_ro_entry availableOverridesEntry;
+    int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
+                                           &availableOverridesEntry);
+    if (rc == 0) {
+        for (size_t i = 0; i < availableOverridesEntry.count; i++) {
+            if (availableOverridesEntry.data.i32[i] == ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool CameraAidlTest::supportsCroppedRawUseCase(const camera_metadata_t *staticMeta) {
+    camera_metadata_ro_entry availableStreamUseCasesEntry;
+    int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
+                                           &availableStreamUseCasesEntry);
+    if (rc == 0) {
+        for (size_t i = 0; i < availableStreamUseCasesEntry.count; i++) {
+            if (availableStreamUseCasesEntry.data.i64[i] ==
+                    ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool CameraAidlTest::supportsStreamUseCaseCap(const camera_metadata_t* staticMeta) {
+    camera_metadata_ro_entry entry;
+    int retcode = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+                                                &entry);
+    bool hasStreamUseCaseCap = false;
+    if ((0 == retcode) && (entry.count > 0)) {
+        if (std::find(entry.data.u8, entry.data.u8 + entry.count,
+                      ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE) !=
+            entry.data.u8 + entry.count) {
+            hasStreamUseCaseCap = true;
+        }
+    }
+    return hasStreamUseCaseCap;
+}
+
+bool CameraAidlTest::isPerFrameControl(const camera_metadata_t* staticMeta) {
+    camera_metadata_ro_entry syncLatencyEntry;
+    int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SYNC_MAX_LATENCY,
+                                           &syncLatencyEntry);
+    if (rc == 0 && syncLatencyEntry.data.i32[0] == ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL) {
+        return true;
+    }
+    return false;
+}
+
 void CameraAidlTest::configurePreviewStream(
         const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
         const AvailableStream* previewThreshold, std::shared_ptr<ICameraDeviceSession>* session,
@@ -2937,7 +3352,11 @@
                   /*groupId*/ 0,
                   {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
                   RequestAvailableDynamicRangeProfilesMap::
-                          ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+                          ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+                  ScalerAvailableStreamUseCases::ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
+                  static_cast<int>(
+                          RequestAvailableColorSpaceProfilesMap::
+                                  ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED)};
 
     StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE, CameraMetadata()};
 
@@ -2957,4 +3376,422 @@
     for (auto& it : mInflightMap) {
         it.second->resultQueue = resultQueue;
     }
-}
\ No newline at end of file
+}
+
+void CameraAidlTest::processColorSpaceRequest(
+        RequestAvailableColorSpaceProfilesMap colorSpace,
+        RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile) {
+    std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+    CameraMetadata settings;
+
+    for (const auto& name : cameraDeviceNames) {
+        std::string version, deviceId;
+        ASSERT_TRUE(matchDeviceName(name, mProviderType, &version, &deviceId));
+        CameraMetadata meta;
+        std::shared_ptr<ICameraDevice> device;
+        openEmptyDeviceSession(name, mProvider, &mSession, &meta, &device);
+        camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
+
+        // Device does not report color spaces, skip.
+        if (!reportsColorSpaces(staticMeta)) {
+            ndk::ScopedAStatus ret = mSession->close();
+            mSession = nullptr;
+            ASSERT_TRUE(ret.isOk());
+            ALOGV("Camera %s does not report color spaces", name.c_str());
+            continue;
+        }
+        std::vector<RequestAvailableColorSpaceProfilesMap> profileList;
+        getColorSpaceProfiles(staticMeta, &profileList);
+        ASSERT_FALSE(profileList.empty());
+
+        // Device does not support color space / dynamic range profile, skip
+        if (std::find(profileList.begin(), profileList.end(), colorSpace)
+                == profileList.end() || !isColorSpaceCompatibleWithDynamicRangeAndPixelFormat(
+                        staticMeta, colorSpace, dynamicRangeProfile,
+                        PixelFormat::IMPLEMENTATION_DEFINED)) {
+            ndk::ScopedAStatus ret = mSession->close();
+            mSession = nullptr;
+            ASSERT_TRUE(ret.isOk());
+            ALOGV("Camera %s does not support color space %s with dynamic range profile %s and "
+                  "pixel format %d", name.c_str(), getColorSpaceProfileString(colorSpace),
+                  getDynamicRangeProfileString(dynamicRangeProfile),
+                  PixelFormat::IMPLEMENTATION_DEFINED);
+            continue;
+        }
+
+        ALOGV("Camera %s supports color space %s with dynamic range profile %s and pixel format %d",
+                name.c_str(), getColorSpaceProfileString(colorSpace),
+                getDynamicRangeProfileString(dynamicRangeProfile),
+                PixelFormat::IMPLEMENTATION_DEFINED);
+
+        // If an HDR dynamic range profile is reported in the color space profile list,
+        // the device must also have the dynamic range profiles map capability and contain
+        // the dynamic range profile in the map.
+        if (dynamicRangeProfile != static_cast<RequestAvailableDynamicRangeProfilesMap>(
+                ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD)) {
+            ASSERT_TRUE(is10BitDynamicRangeCapable(staticMeta));
+
+            std::vector<RequestAvailableDynamicRangeProfilesMap> dynamicRangeProfiles;
+            get10BitDynamicRangeProfiles(staticMeta, &dynamicRangeProfiles);
+            ASSERT_FALSE(dynamicRangeProfiles.empty());
+            ASSERT_FALSE(std::find(dynamicRangeProfiles.begin(), dynamicRangeProfiles.end(),
+                    dynamicRangeProfile) == dynamicRangeProfiles.end());
+        }
+
+        CameraMetadata req;
+        android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings;
+        ndk::ScopedAStatus ret =
+                mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &req);
+        ASSERT_TRUE(ret.isOk());
+
+        const camera_metadata_t* metadata =
+                reinterpret_cast<const camera_metadata_t*>(req.metadata.data());
+        size_t expectedSize = req.metadata.size();
+        int result = validate_camera_metadata_structure(metadata, &expectedSize);
+        ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+
+        size_t entryCount = get_camera_metadata_entry_count(metadata);
+        ASSERT_GT(entryCount, 0u);
+        defaultSettings = metadata;
+
+        const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock();
+        uint8_t* rawSettingsBuffer = (uint8_t*)settingsBuffer;
+        settings.metadata = std::vector(
+                rawSettingsBuffer, rawSettingsBuffer + get_camera_metadata_size(settingsBuffer));
+        overrideRotateAndCrop(&settings);
+
+        ret = mSession->close();
+        mSession = nullptr;
+        ASSERT_TRUE(ret.isOk());
+
+        std::vector<HalStream> halStreams;
+        bool supportsPartialResults = false;
+        bool useHalBufManager = false;
+        int32_t partialResultCount = 0;
+        Stream previewStream;
+        std::shared_ptr<DeviceCb> cb;
+
+        previewStream.usage = static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+                GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
+        configureStreams(name, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, &mSession,
+                         &previewStream, &halStreams, &supportsPartialResults, &partialResultCount,
+                         &useHalBufManager, &cb, 0,
+                         /*maxResolution*/ false, dynamicRangeProfile, colorSpace);
+        ASSERT_NE(mSession, nullptr);
+
+        ::aidl::android::hardware::common::fmq::MQDescriptor<
+                int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+                descriptor;
+        auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
+        ASSERT_TRUE(resultQueueRet.isOk());
+
+        std::shared_ptr<ResultMetadataQueue> resultQueue =
+                std::make_shared<ResultMetadataQueue>(descriptor);
+        if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
+            ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
+            resultQueue = nullptr;
+            // Don't use the queue onwards.
+        }
+
+        mInflightMap.clear();
+        // Stream as long as needed to fill the Hal inflight queue
+        std::vector<CaptureRequest> requests(halStreams[0].maxBuffers);
+
+        for (int32_t requestId = 0; requestId < requests.size(); requestId++) {
+            std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
+                    static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
+                    partialResultCount, std::unordered_set<std::string>(), resultQueue);
+
+            CaptureRequest& request = requests[requestId];
+            std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
+            outputBuffers.resize(halStreams.size());
+
+            size_t k = 0;
+            inflightReq->mOutstandingBufferIds.resize(halStreams.size());
+            std::vector<buffer_handle_t> graphicBuffers;
+            graphicBuffers.reserve(halStreams.size());
+
+            auto bufferId = requestId + 1;  // Buffer id value 0 is not valid
+            for (const auto& halStream : halStreams) {
+                buffer_handle_t buffer_handle;
+                if (useHalBufManager) {
+                    outputBuffers[k] = {halStream.id,   0,
+                                        NativeHandle(), BufferStatus::OK,
+                                        NativeHandle(), NativeHandle()};
+                } else {
+                    auto usage = android_convertGralloc1To0Usage(
+                            static_cast<uint64_t>(halStream.producerUsage),
+                            static_cast<uint64_t>(halStream.consumerUsage));
+                    allocateGraphicBuffer(previewStream.width, previewStream.height, usage,
+                                            halStream.overrideFormat, &buffer_handle);
+
+                    inflightReq->mOutstandingBufferIds[halStream.id][bufferId] = buffer_handle;
+                    graphicBuffers.push_back(buffer_handle);
+                    outputBuffers[k] = {
+                            halStream.id,     bufferId,       android::makeToAidl(buffer_handle),
+                            BufferStatus::OK, NativeHandle(), NativeHandle()};
+                }
+                k++;
+            }
+
+            request.inputBuffer = {
+                    -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
+            request.frameNumber = bufferId;
+            request.fmqSettingsSize = 0;
+            request.settings = settings;
+            request.inputWidth = 0;
+            request.inputHeight = 0;
+
+            {
+                std::unique_lock<std::mutex> l(mLock);
+                mInflightMap[bufferId] = inflightReq;
+            }
+        }
+
+        int32_t numRequestProcessed = 0;
+        std::vector<BufferCache> cachesToRemove;
+        ndk::ScopedAStatus returnStatus =
+            mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(numRequestProcessed, requests.size());
+
+        returnStatus = mSession->repeatingRequestEnd(requests.size() - 1,
+                std::vector<int32_t> {halStreams[0].id});
+        ASSERT_TRUE(returnStatus.isOk());
+
+        // We are keeping frame numbers and buffer ids consistent. Buffer id value of 0
+        // is used to indicate a buffer that is not present/available so buffer ids as well
+        // as frame numbers begin with 1.
+        for (int32_t frameNumber = 1; frameNumber <= requests.size(); frameNumber++) {
+            const auto& inflightReq = mInflightMap[frameNumber];
+            std::unique_lock<std::mutex> l(mLock);
+            while (!inflightReq->errorCodeValid &&
+                    ((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) {
+                auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+            }
+
+            ASSERT_FALSE(inflightReq->errorCodeValid);
+            ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
+
+            if (dynamicRangeProfile != static_cast<RequestAvailableDynamicRangeProfilesMap>(
+                    ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD)) {
+                verify10BitMetadata(mHandleImporter, *inflightReq, dynamicRangeProfile);
+            }
+        }
+
+        if (useHalBufManager) {
+            std::vector<int32_t> streamIds(halStreams.size());
+            for (size_t i = 0; i < streamIds.size(); i++) {
+                streamIds[i] = halStreams[i].id;
+            }
+            mSession->signalStreamFlush(streamIds, /*streamConfigCounter*/ 0);
+            cb->waitForBuffersReturned();
+        }
+
+        ret = mSession->close();
+        mSession = nullptr;
+        ASSERT_TRUE(ret.isOk());
+    }
+}
+
+void CameraAidlTest::processZoomSettingsOverrideRequests(
+        int32_t frameCount, const bool *overrideSequence, const bool *expectedResults) {
+    std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+    int64_t bufferId = 1;
+    int32_t frameNumber = 1;
+    CameraMetadata settings;
+    ndk::ScopedAStatus ret;
+    for (const auto& name : cameraDeviceNames) {
+        CameraMetadata meta;
+        std::shared_ptr<ICameraDevice> device;
+        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
+                               &device /*out*/);
+        camera_metadata_t* staticMeta =
+                clone_camera_metadata(reinterpret_cast<camera_metadata_t*>(meta.metadata.data()));
+
+        ret = mSession->close();
+        mSession = nullptr;
+        ASSERT_TRUE(ret.isOk());
+
+        // Device does not support zoom settnigs override
+        if (!supportZoomSettingsOverride(staticMeta)) {
+            continue;
+        }
+
+        if (!isPerFrameControl(staticMeta)) {
+            continue;
+        }
+
+        bool supportsPartialResults = false;
+        bool useHalBufManager = false;
+        int32_t partialResultCount = 0;
+        Stream previewStream;
+        std::vector<HalStream> halStreams;
+        std::shared_ptr<DeviceCb> cb;
+        configurePreviewStream(name, mProvider, &previewThreshold, &mSession /*out*/,
+                               &previewStream /*out*/, &halStreams /*out*/,
+                               &supportsPartialResults /*out*/, &partialResultCount /*out*/,
+                               &useHalBufManager /*out*/, &cb /*out*/);
+        ASSERT_NE(mSession, nullptr);
+
+        ::aidl::android::hardware::common::fmq::MQDescriptor<
+                int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+                descriptor;
+        auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
+        ASSERT_TRUE(resultQueueRet.isOk());
+
+        std::shared_ptr<ResultMetadataQueue> resultQueue =
+                std::make_shared<ResultMetadataQueue>(descriptor);
+        if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
+            ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
+            resultQueue = nullptr;
+            // Don't use the queue onwards.
+        }
+
+        ret = mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &settings);
+        ASSERT_TRUE(ret.isOk());
+
+        mInflightMap.clear();
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
+        std::vector<CaptureRequest> requests(frameCount);
+        std::vector<buffer_handle_t> buffers(frameCount);
+        std::vector<std::shared_ptr<InFlightRequest>> inflightReqs(frameCount);
+        std::vector<CameraMetadata> requestSettings(frameCount);
+
+        for (int32_t i = 0; i < frameCount; i++) {
+            std::unique_lock<std::mutex> l(mLock);
+            CaptureRequest& request = requests[i];
+            std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
+            outputBuffers.resize(1);
+            StreamBuffer& outputBuffer = outputBuffers[0];
+
+            if (useHalBufManager) {
+                outputBuffer = {halStreams[0].id, 0,
+                                NativeHandle(),   BufferStatus::OK,
+                                NativeHandle(),   NativeHandle()};
+            } else {
+                allocateGraphicBuffer(previewStream.width, previewStream.height,
+                                      android_convertGralloc1To0Usage(
+                                              static_cast<uint64_t>(halStreams[0].producerUsage),
+                                              static_cast<uint64_t>(halStreams[0].consumerUsage)),
+                                      halStreams[0].overrideFormat, &buffers[i]);
+                outputBuffer = {halStreams[0].id, bufferId + i,   ::android::makeToAidl(buffers[i]),
+                                BufferStatus::OK, NativeHandle(), NativeHandle()};
+            }
+
+            // Set appropriate settings override tag
+            requestMeta.append(reinterpret_cast<camera_metadata_t*>(settings.metadata.data()));
+            int32_t settingsOverride = overrideSequence[i] ?
+                    ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM : ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF;
+            ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_SETTINGS_OVERRIDE,
+                    &settingsOverride, 1));
+            camera_metadata_t* metaBuffer = requestMeta.release();
+            uint8_t* rawMetaBuffer = reinterpret_cast<uint8_t*>(metaBuffer);
+            requestSettings[i].metadata = std::vector(
+                    rawMetaBuffer, rawMetaBuffer + get_camera_metadata_size(metaBuffer));
+            overrideRotateAndCrop(&(requestSettings[i]));
+            request.frameNumber = frameNumber + i;
+            request.fmqSettingsSize = 0;
+            request.settings = requestSettings[i];
+            request.inputBuffer = {
+                    -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
+
+            inflightReqs[i] = std::make_shared<InFlightRequest>(1, false, supportsPartialResults,
+                                                                partialResultCount, resultQueue);
+            mInflightMap[frameNumber + i] = inflightReqs[i];
+        }
+
+        int32_t numRequestProcessed = 0;
+        std::vector<BufferCache> cachesToRemove;
+
+        ndk::ScopedAStatus returnStatus =
+                mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(numRequestProcessed, frameCount);
+
+        for (size_t i = 0; i < frameCount; i++) {
+            std::unique_lock<std::mutex> l(mLock);
+            while (!inflightReqs[i]->errorCodeValid && ((0 < inflightReqs[i]->numBuffersLeft) ||
+                                                        (!inflightReqs[i]->haveResultMetadata))) {
+                auto timeout = std::chrono::system_clock::now() +
+                               std::chrono::seconds(kStreamBufferTimeoutSec);
+                ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+            }
+
+            ASSERT_FALSE(inflightReqs[i]->errorCodeValid);
+            ASSERT_NE(inflightReqs[i]->resultOutputBuffers.size(), 0u);
+            ASSERT_EQ(previewStream.id, inflightReqs[i]->resultOutputBuffers[0].buffer.streamId);
+            ASSERT_FALSE(inflightReqs[i]->collectedResult.isEmpty());
+            ASSERT_TRUE(inflightReqs[i]->collectedResult.exists(ANDROID_CONTROL_SETTINGS_OVERRIDE));
+            camera_metadata_entry_t overrideResult =
+                    inflightReqs[i]->collectedResult.find(ANDROID_CONTROL_SETTINGS_OVERRIDE);
+            ASSERT_EQ(overrideResult.data.i32[0] == ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM,
+                    expectedResults[i]);
+            ASSERT_TRUE(inflightReqs[i]->collectedResult.exists(
+                    ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER));
+            camera_metadata_entry_t frameNumberEntry = inflightReqs[i]->collectedResult.find(
+                    ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER);
+            ALOGV("%s: i %zu, expcetedResults[i] %d, overrideResult is %d, frameNumber %d",
+                  __FUNCTION__, i, expectedResults[i], overrideResult.data.i32[0],
+                  frameNumberEntry.data.i32[0]);
+            if (expectedResults[i]) {
+                ASSERT_GT(frameNumberEntry.data.i32[0], inflightReqs[i]->frameNumber);
+            } else {
+                ASSERT_EQ(frameNumberEntry.data.i32[0], frameNumber + i);
+            }
+        }
+
+        ret = mSession->close();
+        mSession = nullptr;
+        ASSERT_TRUE(ret.isOk());
+    }
+}
+
+void CameraAidlTest::getSupportedSizes(const camera_metadata_t* ch, uint32_t tag, int32_t format,
+                                       std::vector<std::tuple<size_t, size_t>>* sizes /*out*/) {
+    if (sizes == nullptr) {
+        return;
+    }
+
+    camera_metadata_ro_entry entry;
+    int retcode = find_camera_metadata_ro_entry(ch, tag, &entry);
+    if ((0 == retcode) && (entry.count > 0)) {
+        // Scaler entry contains 4 elements (format, width, height, type)
+        for (size_t i = 0; i < entry.count; i += 4) {
+            if ((entry.data.i32[i] == format) &&
+                (entry.data.i32[i + 3] == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
+                sizes->push_back(std::make_tuple(entry.data.i32[i + 1], entry.data.i32[i + 2]));
+            }
+        }
+    }
+}
+
+void CameraAidlTest::getSupportedDurations(const camera_metadata_t* ch, uint32_t tag,
+                                           int32_t format,
+                                           const std::vector<std::tuple<size_t, size_t>>& sizes,
+                                           std::vector<int64_t>* durations /*out*/) {
+    if (durations == nullptr) {
+        return;
+    }
+
+    camera_metadata_ro_entry entry;
+    int retcode = find_camera_metadata_ro_entry(ch, tag, &entry);
+    if ((0 == retcode) && (entry.count > 0)) {
+        // Duration entry contains 4 elements (format, width, height, duration)
+        for (const auto& size : sizes) {
+            int64_t width = std::get<0>(size);
+            int64_t height = std::get<1>(size);
+            for (size_t i = 0; i < entry.count; i += 4) {
+                if ((entry.data.i64[i] == format) && (entry.data.i64[i + 1] == width) &&
+                    (entry.data.i64[i + 2] == height)) {
+                    durations->push_back(entry.data.i64[i + 3]);
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index f1de68f..fa21a06 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -17,7 +17,10 @@
 #ifndef HARDWARE_INTERFACES_CAMERA_PROVIDER_AIDL_VTS_CAMERA_AIDL_TEST_H_
 #define HARDWARE_INTERFACES_CAMERA_PROVIDER_AIDL_VTS_CAMERA_AIDL_TEST_H_
 
+// TODO: LOG_TAG should not be in header
+#ifndef LOG_TAG
 #define LOG_TAG "camera_aidl_hal_test"
+#endif
 
 #include <string>
 #include <unordered_map>
@@ -44,6 +47,8 @@
 
 #include <aidl/android/hardware/camera/provider/ICameraProvider.h>
 
+#include <aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.h>
+
 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
 
 #include <gtest/gtest.h>
@@ -72,6 +77,9 @@
 using ::aidl::android::hardware::camera::device::StreamBufferRet;
 using ::aidl::android::hardware::camera::device::StreamConfiguration;
 using ::aidl::android::hardware::camera::device::StreamConfigurationMode;
+using ::aidl::android::hardware::camera::metadata::RequestAvailableColorSpaceProfilesMap;
+using ::aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
+using ::aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases;
 using ::aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination;
 using ::aidl::android::hardware::camera::provider::ICameraProvider;
 
@@ -123,6 +131,28 @@
         YUV_REPROCESS,
     };
 
+    // Copied from ColorSpace.java (see Named)
+    enum ColorSpaceNamed {
+        SRGB,
+        LINEAR_SRGB,
+        EXTENDED_SRGB,
+        LINEAR_EXTENDED_SRGB,
+        BT709,
+        BT2020,
+        DCI_P3,
+        DISPLAY_P3,
+        NTSC_1953,
+        SMPTE_C,
+        ADOBE_RGB,
+        PRO_PHOTO_RGB,
+        ACES,
+        ACESCG,
+        CIE_XYZ,
+        CIE_LAB,
+        BT2020_HLG,
+        BT2020_PQ
+    };
+
     struct AvailableZSLInputOutput {
         int32_t inputFormat;
         int32_t outputFormat;
@@ -178,10 +208,12 @@
             bool* supportsPartialResults /*out*/, int32_t* partialResultCount /*out*/,
             bool* useHalBufManager /*out*/, std::shared_ptr<DeviceCb>* outCb /*out*/,
             uint32_t streamConfigCounter, bool maxResolution,
-            aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap
-                    prof = ::aidl::android::hardware::camera::metadata::
-                            RequestAvailableDynamicRangeProfilesMap::
-                                    ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+            RequestAvailableDynamicRangeProfilesMap dynamicRangeProf =
+                    RequestAvailableDynamicRangeProfilesMap::
+                            ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
+            RequestAvailableColorSpaceProfilesMap colorSpaceProf =
+                    RequestAvailableColorSpaceProfilesMap::
+                            ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED);
 
     void configurePreviewStreams(
             const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
@@ -201,6 +233,8 @@
             int32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/,
             std::shared_ptr<DeviceCb>* cb /*out*/, uint32_t streamConfigCounter = 0);
 
+    void configureStreamUseCaseInternal(const AvailableStream &threshold);
+
     void configureSingleStream(
             const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
             const AvailableStream* previewThreshold, uint64_t bufferUsage,
@@ -230,6 +264,8 @@
 
     static void verifyStreamUseCaseCharacteristics(const camera_metadata_t* metadata);
 
+    static void verifySettingsOverrideCharacteristics(const camera_metadata_t* metadata);
+
     static void verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device,
                                         const StreamConfiguration& config, bool expectedStatus,
                                         bool expectStreamCombQuery);
@@ -345,14 +381,51 @@
 
     static void get10BitDynamicRangeProfiles(
             const camera_metadata_t* staticMeta,
+            std::vector<RequestAvailableDynamicRangeProfilesMap>* profiles);
+
+    static bool reportsColorSpaces(const camera_metadata_t* staticMeta);
+
+    static void getColorSpaceProfiles(
+            const camera_metadata_t* staticMeta,
             std::vector<aidl::android::hardware::camera::metadata::
-                                RequestAvailableDynamicRangeProfilesMap>* profiles);
+                                RequestAvailableColorSpaceProfilesMap>* profiles);
+
+    static bool isColorSpaceCompatibleWithDynamicRangeAndPixelFormat(
+            const camera_metadata_t* staticMeta, RequestAvailableColorSpaceProfilesMap colorSpace,
+            RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile,
+            aidl::android::hardware::graphics::common::PixelFormat pixelFormat);
+
+    static const char* getColorSpaceProfileString(RequestAvailableColorSpaceProfilesMap colorSpace);
+
+    static const char* getDynamicRangeProfileString(
+            RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile);
+
+    static int32_t halFormatToPublicFormat(
+            aidl::android::hardware::graphics::common::PixelFormat pixelFormat);
 
     // Used by switchToOffline where a new result queue is created for offline reqs
     void updateInflightResultQueue(const std::shared_ptr<ResultMetadataQueue>& resultQueue);
 
     static Size getMinSize(Size a, Size b);
 
+    void processColorSpaceRequest(RequestAvailableColorSpaceProfilesMap colorSpace,
+                                  RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile);
+
+    void processZoomSettingsOverrideRequests(
+            int32_t frameCount, const bool *overrideSequence, const bool *expectedResults);
+
+    bool supportZoomSettingsOverride(const camera_metadata_t* staticMeta);
+    static bool supportsStreamUseCaseCap(const camera_metadata_t* staticMeta);
+    static bool supportsCroppedRawUseCase(const camera_metadata_t* staticMeta);
+    bool isPerFrameControl(const camera_metadata_t* staticMeta);
+
+    void getSupportedSizes(const camera_metadata_t* ch, uint32_t tag, int32_t format,
+                           std::vector<std::tuple<size_t, size_t>>* sizes /*out*/);
+
+    void getSupportedDurations(const camera_metadata_t* ch, uint32_t tag, int32_t format,
+                               const std::vector<std::tuple<size_t, size_t>>& sizes,
+                               std::vector<int64_t>* durations /*out*/);
+
   protected:
     // In-flight queue for tracking completion of capture requests.
     struct InFlightRequest {
@@ -497,10 +570,8 @@
     static bool matchDeviceName(const std::string& deviceName, const std::string& providerType,
                                 std::string* deviceVersion, std::string* cameraId);
 
-    static void verify10BitMetadata(
-            HandleImporter& importer, const InFlightRequest& request,
-            aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap
-                    profile);
+    static void verify10BitMetadata(HandleImporter& importer, const InFlightRequest& request,
+                                    RequestAvailableDynamicRangeProfilesMap profile);
 
     static void waitForReleaseFence(
             std::vector<InFlightRequest::StreamBufferAndTimestamp>& resultOutputBuffers);
diff --git a/camera/provider/default/Android.bp b/camera/provider/default/Android.bp
new file mode 100644
index 0000000..ed45cbe
--- /dev/null
+++ b/camera/provider/default/Android.bp
@@ -0,0 +1,104 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // 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_shared {
+    name: "android.hardware.camera.provider-V1-external-impl",
+    defaults: ["hidl_defaults"],
+    proprietary: true,
+    srcs: [
+        "ExternalCameraProvider.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.camera.common-V1-ndk",
+        "android.hardware.camera.device-V1-ndk",
+        "android.hardware.camera.provider-V1-ndk",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.graphics.mapper@4.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "camera.device-external-impl",
+        "libbinder_ndk",
+        "libcamera_metadata",
+        "libcutils",
+        "libfmq",
+        "libhardware",
+        "libhidlbase",
+        "liblog",
+        "libtinyxml2",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+    export_include_dirs: ["."],
+}
+
+cc_defaults {
+    name: "camera_external_service_defaults",
+    defaults: ["hidl_defaults"],
+    proprietary: true,
+    relative_install_path: "hw",
+    srcs: ["external-service.cpp"],
+    compile_multilib: "first",
+    shared_libs: [
+        "android.hardware.camera.common-V1-ndk",
+        "android.hardware.camera.device-V1-ndk",
+        "android.hardware.camera.provider-V1-ndk",
+        "android.hardware.camera.provider-V1-external-impl",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.graphics.mapper@4.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "camera.device-external-impl",
+        "libbinder_ndk",
+        "libcamera_metadata",
+        "libcutils",
+        "libfmq",
+        "libhardware",
+        "libhidlbase",
+        "liblog",
+        "libtinyxml2",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.camera.provider-V1-external-service",
+    defaults: ["camera_external_service_defaults"],
+    init_rc: ["android.hardware.camera.provider-V1-external-service.rc"],
+}
+
+cc_binary {
+    name: "android.hardware.camera.provider-V1-external-service-lazy",
+    overrides: ["android.hardware.camera.provider-V1-external-service"],
+    defaults: ["camera_external_service_defaults"],
+    init_rc: ["android.hardware.camera.provider-V1-external-service-lazy.rc"],
+    cflags: ["-DLAZY_SERVICE"],
+}
diff --git a/camera/provider/default/ExternalCameraProvider.cpp b/camera/provider/default/ExternalCameraProvider.cpp
new file mode 100644
index 0000000..4d2c847
--- /dev/null
+++ b/camera/provider/default/ExternalCameraProvider.cpp
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamPrvdr"
+// #define LOG_NDEBUG 0
+
+#include "ExternalCameraProvider.h"
+
+#include <ExternalCameraDevice.h>
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <convert.h>
+#include <cutils/properties.h>
+#include <linux/videodev2.h>
+#include <log/log.h>
+#include <sys/inotify.h>
+#include <regex>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::android::hardware::camera::device::implementation::ExternalCameraDevice;
+using ::android::hardware::camera::device::implementation::fromStatus;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+
+namespace {
+// "device@<version>/external/<id>"
+const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/external/(.+)");
+const int kMaxDevicePathLen = 256;
+constexpr char kDevicePath[] = "/dev/";
+constexpr char kPrefix[] = "video";
+constexpr int kPrefixLen = sizeof(kPrefix) - 1;
+constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen - 1;
+
+bool matchDeviceName(int cameraIdOffset, const std::string& deviceName, std::string* deviceVersion,
+                     std::string* cameraDevicePath) {
+    std::smatch sm;
+    if (std::regex_match(deviceName, sm, kDeviceNameRE)) {
+        if (deviceVersion != nullptr) {
+            *deviceVersion = sm[1];
+        }
+        if (cameraDevicePath != nullptr) {
+            *cameraDevicePath = "/dev/video" + std::to_string(std::stoi(sm[2]) - cameraIdOffset);
+        }
+        return true;
+    }
+    return false;
+}
+}  // namespace
+
+ExternalCameraProvider::ExternalCameraProvider() : mCfg(ExternalCameraConfig::loadFromCfg()) {
+    mHotPlugThread = std::make_shared<HotplugThread>(this);
+    mHotPlugThread->run();
+}
+
+ExternalCameraProvider::~ExternalCameraProvider() {
+    mHotPlugThread->requestExitAndWait();
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::setCallback(
+        const std::shared_ptr<ICameraProviderCallback>& in_callback) {
+    {
+        Mutex::Autolock _l(mLock);
+        mCallback = in_callback;
+    }
+
+    if (mCallback == nullptr) {
+        return fromStatus(Status::OK);
+    }
+
+    for (const auto& pair : mCameraStatusMap) {
+        mCallback->cameraDeviceStatusChange(pair.first, pair.second);
+    }
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::getVendorTags(
+        std::vector<VendorTagSection>* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+    // No vendor tag support for USB camera
+    *_aidl_return = {};
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::getCameraIdList(std::vector<std::string>* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+    // External camera HAL always report 0 camera, and extra cameras
+    // are just reported via cameraDeviceStatusChange callbacks
+    *_aidl_return = {};
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::getCameraDeviceInterface(
+        const std::string& in_cameraDeviceName, std::shared_ptr<ICameraDevice>* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+    std::string cameraDevicePath, deviceVersion;
+    bool match = matchDeviceName(mCfg.cameraIdOffset, in_cameraDeviceName, &deviceVersion,
+                                 &cameraDevicePath);
+
+    if (!match) {
+        *_aidl_return = nullptr;
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+
+    if (mCameraStatusMap.count(in_cameraDeviceName) == 0 ||
+        mCameraStatusMap[in_cameraDeviceName] != CameraDeviceStatus::PRESENT) {
+        *_aidl_return = nullptr;
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+
+    ALOGV("Constructing external camera device");
+    std::shared_ptr<ExternalCameraDevice> deviceImpl =
+            ndk::SharedRefBase::make<ExternalCameraDevice>(cameraDevicePath, mCfg);
+    if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
+        ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraDevicePath.c_str());
+        *_aidl_return = nullptr;
+        return fromStatus(Status::INTERNAL_ERROR);
+    }
+
+    IF_ALOGV() {
+        int interfaceVersion;
+        deviceImpl->getInterfaceVersion(&interfaceVersion);
+        ALOGV("%s: device interface version: %d", __FUNCTION__, interfaceVersion);
+    }
+
+    *_aidl_return = deviceImpl;
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::notifyDeviceStateChange(int64_t) {
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::getConcurrentCameraIds(
+        std::vector<ConcurrentCameraIdCombination>* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+    *_aidl_return = {};
+    return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::isConcurrentStreamCombinationSupported(
+        const std::vector<CameraIdAndStreamCombination>&, bool* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        return fromStatus(Status::ILLEGAL_ARGUMENT);
+    }
+    // No concurrent stream combinations are supported
+    *_aidl_return = false;
+    return fromStatus(Status::OK);
+}
+
+void ExternalCameraProvider::addExternalCamera(const char* devName) {
+    ALOGV("%s: ExtCam: adding %s to External Camera HAL!", __FUNCTION__, devName);
+    Mutex::Autolock _l(mLock);
+    std::string deviceName;
+    std::string cameraId =
+            std::to_string(mCfg.cameraIdOffset + std::atoi(devName + kDevicePrefixLen));
+    deviceName =
+            std::string("device@") + ExternalCameraDevice::kDeviceVersion + "/external/" + cameraId;
+    mCameraStatusMap[deviceName] = CameraDeviceStatus::PRESENT;
+    if (mCallback != nullptr) {
+        mCallback->cameraDeviceStatusChange(deviceName, CameraDeviceStatus::PRESENT);
+    }
+}
+
+void ExternalCameraProvider::deviceAdded(const char* devName) {
+    {
+        base::unique_fd fd(::open(devName, O_RDWR));
+        if (fd.get() < 0) {
+            ALOGE("%s open v4l2 device %s failed:%s", __FUNCTION__, devName, strerror(errno));
+            return;
+        }
+
+        struct v4l2_capability capability;
+        int ret = ioctl(fd.get(), VIDIOC_QUERYCAP, &capability);
+        if (ret < 0) {
+            ALOGE("%s v4l2 QUERYCAP %s failed", __FUNCTION__, devName);
+            return;
+        }
+
+        if (!(capability.device_caps & V4L2_CAP_VIDEO_CAPTURE)) {
+            ALOGW("%s device %s does not support VIDEO_CAPTURE", __FUNCTION__, devName);
+            return;
+        }
+    }
+
+    // See if we can initialize ExternalCameraDevice correctly
+    std::shared_ptr<ExternalCameraDevice> deviceImpl =
+            ndk::SharedRefBase::make<ExternalCameraDevice>(devName, mCfg);
+    if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
+        ALOGW("%s: Attempt to init camera device %s failed!", __FUNCTION__, devName);
+        return;
+    }
+    deviceImpl.reset();
+    addExternalCamera(devName);
+}
+
+void ExternalCameraProvider::deviceRemoved(const char* devName) {
+    Mutex::Autolock _l(mLock);
+    std::string deviceName;
+    std::string cameraId =
+            std::to_string(mCfg.cameraIdOffset + std::atoi(devName + kDevicePrefixLen));
+
+    deviceName =
+            std::string("device@") + ExternalCameraDevice::kDeviceVersion + "/external/" + cameraId;
+
+    if (mCameraStatusMap.erase(deviceName) == 0) {
+        // Unknown device, do not fire callback
+        ALOGE("%s: cannot find camera device to remove %s", __FUNCTION__, devName);
+        return;
+    }
+
+    if (mCallback != nullptr) {
+        mCallback->cameraDeviceStatusChange(deviceName, CameraDeviceStatus::NOT_PRESENT);
+    }
+}
+
+void ExternalCameraProvider::updateAttachedCameras() {
+    ALOGV("%s start scanning for existing V4L2 devices", __FUNCTION__);
+
+    // Find existing /dev/video* devices
+    DIR* devdir = opendir(kDevicePath);
+    if (devdir == nullptr) {
+        ALOGE("%s: cannot open %s! Exiting threadloop", __FUNCTION__, kDevicePath);
+        return;
+    }
+
+    struct dirent* de;
+    while ((de = readdir(devdir)) != nullptr) {
+        // Find external v4l devices that's existing before we start watching and add them
+        if (!strncmp(kPrefix, de->d_name, kPrefixLen)) {
+            std::string deviceId(de->d_name + kPrefixLen);
+            if (mCfg.mInternalDevices.count(deviceId) == 0) {
+                ALOGV("Non-internal v4l device %s found", de->d_name);
+                char v4l2DevicePath[kMaxDevicePathLen];
+                snprintf(v4l2DevicePath, kMaxDevicePathLen, "%s%s", kDevicePath, de->d_name);
+                deviceAdded(v4l2DevicePath);
+            }
+        }
+    }
+    closedir(devdir);
+}
+
+// Start ExternalCameraProvider::HotplugThread functions
+
+ExternalCameraProvider::HotplugThread::HotplugThread(ExternalCameraProvider* parent)
+    : mParent(parent), mInternalDevices(parent->mCfg.mInternalDevices) {}
+
+ExternalCameraProvider::HotplugThread::~HotplugThread() {
+    // Clean up inotify descriptor if needed.
+    if (mINotifyFD >= 0) {
+        close(mINotifyFD);
+    }
+}
+
+bool ExternalCameraProvider::HotplugThread::initialize() {
+    // Update existing cameras
+    mParent->updateAttachedCameras();
+
+    // Set up non-blocking fd. The threadLoop will be responsible for polling read at the
+    // desired frequency
+    mINotifyFD = inotify_init();
+    if (mINotifyFD < 0) {
+        ALOGE("%s: inotify init failed! Exiting threadloop", __FUNCTION__);
+        return false;
+    }
+
+    // Start watching /dev/ directory for created and deleted files
+    mWd = inotify_add_watch(mINotifyFD, kDevicePath, IN_CREATE | IN_DELETE);
+    if (mWd < 0) {
+        ALOGE("%s: inotify add watch failed! Exiting threadloop", __FUNCTION__);
+        return false;
+    }
+
+    mPollFd = {.fd = mINotifyFD, .events = POLLIN};
+
+    mIsInitialized = true;
+    return true;
+}
+
+bool ExternalCameraProvider::HotplugThread::threadLoop() {
+    // Initialize inotify descriptors if needed.
+    if (!mIsInitialized && !initialize()) {
+        return true;
+    }
+
+    // poll /dev/* and handle timeouts and error
+    int pollRet = poll(&mPollFd, /* fd_count= */ 1, /* timeout= */ 250);
+    if (pollRet == 0) {
+        // no read event in 100ms
+        mPollFd.revents = 0;
+        return true;
+    } else if (pollRet < 0) {
+        ALOGE("%s: error while polling for /dev/*: %d", __FUNCTION__, errno);
+        mPollFd.revents = 0;
+        return true;
+    } else if (mPollFd.revents & POLLERR) {
+        ALOGE("%s: polling /dev/ returned POLLERR", __FUNCTION__);
+        mPollFd.revents = 0;
+        return true;
+    } else if (mPollFd.revents & POLLHUP) {
+        ALOGE("%s: polling /dev/ returned POLLHUP", __FUNCTION__);
+        mPollFd.revents = 0;
+        return true;
+    } else if (mPollFd.revents & POLLNVAL) {
+        ALOGE("%s: polling /dev/ returned POLLNVAL", __FUNCTION__);
+        mPollFd.revents = 0;
+        return true;
+    }
+    // mPollFd.revents must contain POLLIN, so safe to reset it before reading
+    mPollFd.revents = 0;
+
+    uint64_t offset = 0;
+    ssize_t ret = read(mINotifyFD, mEventBuf, sizeof(mEventBuf));
+    if (ret < sizeof(struct inotify_event)) {
+        // invalid event. skip
+        return true;
+    }
+
+    while (offset < ret) {
+        struct inotify_event* event = (struct inotify_event*)&mEventBuf[offset];
+        offset += sizeof(struct inotify_event) + event->len;
+
+        if (event->wd != mWd) {
+            // event for an unrelated descriptor. ignore.
+            continue;
+        }
+
+        ALOGV("%s inotify_event %s", __FUNCTION__, event->name);
+        if (strncmp(kPrefix, event->name, kPrefixLen) != 0) {
+            // event not for /dev/video*. ignore.
+            continue;
+        }
+
+        std::string deviceId = event->name + kPrefixLen;
+        if (mInternalDevices.count(deviceId) != 0) {
+            // update to an internal device. ignore.
+            continue;
+        }
+
+        char v4l2DevicePath[kMaxDevicePathLen];
+        snprintf(v4l2DevicePath, kMaxDevicePathLen, "%s%s", kDevicePath, event->name);
+
+        if (event->mask & IN_CREATE) {
+            mParent->deviceAdded(v4l2DevicePath);
+        } else if (event->mask & IN_DELETE) {
+            mParent->deviceRemoved(v4l2DevicePath);
+        }
+    }
+    return true;
+}
+
+// End ExternalCameraProvider::HotplugThread functions
+
+}  // namespace implementation
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/provider/default/ExternalCameraProvider.h b/camera/provider/default/ExternalCameraProvider.h
new file mode 100644
index 0000000..347a53c
--- /dev/null
+++ b/camera/provider/default/ExternalCameraProvider.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_PROVIDER_DEFAULT_EXTERNALCAMERAPROVIDER_H_
+#define HARDWARE_INTERFACES_CAMERA_PROVIDER_DEFAULT_EXTERNALCAMERAPROVIDER_H_
+
+#include <ExternalCameraUtils.h>
+#include <SimpleThread.h>
+#include <aidl/android/hardware/camera/common/CameraDeviceStatus.h>
+#include <aidl/android/hardware/camera/common/VendorTagSection.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
+#include <aidl/android/hardware/camera/provider/BnCameraProvider.h>
+#include <aidl/android/hardware/camera/provider/CameraIdAndStreamCombination.h>
+#include <aidl/android/hardware/camera/provider/ConcurrentCameraIdCombination.h>
+#include <aidl/android/hardware/camera/provider/ICameraProviderCallback.h>
+#include <poll.h>
+#include <utils/Mutex.h>
+#include <utils/Thread.h>
+#include <thread>
+#include <unordered_map>
+#include <unordered_set>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
+using ::aidl::android::hardware::camera::common::VendorTagSection;
+using ::aidl::android::hardware::camera::device::ICameraDevice;
+using ::aidl::android::hardware::camera::provider::BnCameraProvider;
+using ::aidl::android::hardware::camera::provider::CameraIdAndStreamCombination;
+using ::aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination;
+using ::aidl::android::hardware::camera::provider::ICameraProviderCallback;
+using ::android::hardware::camera::common::helper::SimpleThread;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+
+class ExternalCameraProvider : public BnCameraProvider {
+  public:
+    ExternalCameraProvider();
+    ~ExternalCameraProvider() override;
+    ndk::ScopedAStatus setCallback(
+            const std::shared_ptr<ICameraProviderCallback>& in_callback) override;
+    ndk::ScopedAStatus getVendorTags(std::vector<VendorTagSection>* _aidl_return) override;
+    ndk::ScopedAStatus getCameraIdList(std::vector<std::string>* _aidl_return) override;
+    ndk::ScopedAStatus getCameraDeviceInterface(
+            const std::string& in_cameraDeviceName,
+            std::shared_ptr<ICameraDevice>* _aidl_return) override;
+    ndk::ScopedAStatus notifyDeviceStateChange(int64_t in_deviceState) override;
+    ndk::ScopedAStatus getConcurrentCameraIds(
+            std::vector<ConcurrentCameraIdCombination>* _aidl_return) override;
+    ndk::ScopedAStatus isConcurrentStreamCombinationSupported(
+            const std::vector<CameraIdAndStreamCombination>& in_configs,
+            bool* _aidl_return) override;
+
+  private:
+    void addExternalCamera(const char* devName);
+    void deviceAdded(const char* devName);
+    void deviceRemoved(const char* devName);
+    void updateAttachedCameras();
+
+    // A separate thread to monitor '/dev' directory for '/dev/video*' entries
+    // This thread calls back into ExternalCameraProvider when an actionable change is detected.
+    class HotplugThread : public SimpleThread {
+      public:
+        explicit HotplugThread(ExternalCameraProvider* parent);
+        ~HotplugThread() override;
+
+      protected:
+        bool threadLoop() override;
+
+      private:
+        // Returns true if thread initialization succeeded, and false if thread initialization
+        // failed.
+        bool initialize();
+
+        ExternalCameraProvider* mParent = nullptr;
+        const std::unordered_set<std::string> mInternalDevices;
+
+        bool mIsInitialized = false;
+
+        int mINotifyFD = -1;
+        int mWd = -1;
+
+        // struct to wrap mINotifyFD and poll it with timeout
+        struct pollfd mPollFd = {};
+        char mEventBuf[512] = {0};
+    };
+
+    Mutex mLock;
+    std::shared_ptr<ICameraProviderCallback> mCallback = nullptr;
+    std::unordered_map<std::string, CameraDeviceStatus> mCameraStatusMap;  // camera id -> status
+    const ExternalCameraConfig mCfg;
+    std::shared_ptr<HotplugThread> mHotPlugThread;
+};
+
+}  // namespace implementation
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_CAMERA_PROVIDER_DEFAULT_EXTERNALCAMERAPROVIDER_H_
diff --git a/camera/provider/default/android.hardware.camera.provider-V1-external-service-lazy.rc b/camera/provider/default/android.hardware.camera.provider-V1-external-service-lazy.rc
new file mode 100644
index 0000000..dcdd88c
--- /dev/null
+++ b/camera/provider/default/android.hardware.camera.provider-V1-external-service-lazy.rc
@@ -0,0 +1,10 @@
+service vendor.camera.provider-ext /vendor/bin/hw/android.hardware.camera.provider-V1-external-service-lazy
+    interface aidl android.hardware.camera.provider.ICameraProvider/external/0
+    class hal
+    oneshot
+    disabled
+    user cameraserver
+    group audio camera input drmrpc usb
+    ioprio rt 4
+    capabilities SYS_NICE
+    task_profiles CameraServiceCapacity MaxPerformance
\ No newline at end of file
diff --git a/camera/provider/default/android.hardware.camera.provider-V1-external-service.rc b/camera/provider/default/android.hardware.camera.provider-V1-external-service.rc
new file mode 100644
index 0000000..302c56f
--- /dev/null
+++ b/camera/provider/default/android.hardware.camera.provider-V1-external-service.rc
@@ -0,0 +1,8 @@
+service vendor.camera.provider-ext /vendor/bin/hw/android.hardware.camera.provider-V1-external-service
+    interface aidl android.hardware.camera.provider.ICameraProvider/external/0
+    class hal
+    user cameraserver
+    group audio camera input drmrpc usb
+    ioprio rt 4
+    capabilities SYS_NICE
+    task_profiles CameraServiceCapacity MaxPerformance
\ No newline at end of file
diff --git a/camera/provider/default/external-service.cpp b/camera/provider/default/external-service.cpp
new file mode 100644
index 0000000..b18f182
--- /dev/null
+++ b/camera/provider/default/external-service.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ExternalCameraProvider.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using ::android::hardware::camera::provider::implementation::ExternalCameraProvider;
+
+namespace {
+// Default recommended RPC thread count for camera provider implementations
+const int HWBINDER_THREAD_COUNT = 6;
+}  // namespace
+
+int main() {
+    ALOGI("CameraProvider: external webcam service is starting.");
+
+    ABinderProcess_setThreadPoolMaxThreadCount(HWBINDER_THREAD_COUNT);
+
+    std::shared_ptr<ExternalCameraProvider> defaultProvider =
+            ndk::SharedRefBase::make<ExternalCameraProvider>();
+    const std::string serviceName = std::string(ExternalCameraProvider::descriptor) + "/external/0";
+
+#ifdef LAZY_SERVICE
+    binder_exception_t ret = AServiceManager_registerLazyService(defaultProvider->asBinder().get(),
+                                                                 serviceName.c_str());
+    LOG_ALWAYS_FATAL_IF(ret != EX_NONE,
+                        "Error while registering lazy ext camera provider service: %d", ret);
+#else
+    binder_exception_t ret =
+            AServiceManager_addService(defaultProvider->asBinder().get(), serviceName.c_str());
+    LOG_ALWAYS_FATAL_IF(ret != EX_NONE, "Error while registering ext camera provider service: %d",
+                        ret);
+#endif
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
\ No newline at end of file
diff --git a/cas/OWNERS b/cas/OWNERS
new file mode 100644
index 0000000..473c8f26
--- /dev/null
+++ b/cas/OWNERS
@@ -0,0 +1 @@
+include /tv/input/OWNERS
diff --git a/cas/aidl/Android.bp b/cas/aidl/Android.bp
new file mode 100644
index 0000000..123d29d
--- /dev/null
+++ b/cas/aidl/Android.bp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.cas",
+    vendor_available: true,
+    srcs: ["android/hardware/cas/*.aidl"],
+    stability: "vintf",
+    imports: ["android.hardware.common-V2"],
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.common-V2"],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/cas/aidl/OWNERS b/cas/aidl/OWNERS
new file mode 100755
index 0000000..4c55752
--- /dev/null
+++ b/cas/aidl/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1344
+quxiangfang@google.com
+hgchen@google.com
diff --git a/cas/aidl/TEST_MAPPING b/cas/aidl/TEST_MAPPING
new file mode 100644
index 0000000..5bcd388
--- /dev/null
+++ b/cas/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalCasAidlTargetTest"
+    }
+  ]
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/.hash b/cas/aidl/aidl_api/android.hardware.cas/1/.hash
new file mode 100644
index 0000000..025bfbd
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/.hash
@@ -0,0 +1 @@
+bc51d8d70a55ec4723d3f73d0acf7003306bf69f
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/AidlCasPluginDescriptor.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/AidlCasPluginDescriptor.aidl
new file mode 100644
index 0000000..89d8625
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/AidlCasPluginDescriptor.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+parcelable AidlCasPluginDescriptor {
+  int caSystemId;
+  String name;
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/DestinationBuffer.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/DestinationBuffer.aidl
new file mode 100644
index 0000000..b69cc33
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/DestinationBuffer.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+union DestinationBuffer {
+  android.hardware.cas.SharedBuffer nonsecureMemory;
+  android.hardware.common.NativeHandle secureMemory;
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ICas.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ICas.aidl
new file mode 100644
index 0000000..903ab92
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ICas.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+interface ICas {
+  void closeSession(in byte[] sessionId);
+  byte[] openSessionDefault();
+  byte[] openSession(in android.hardware.cas.SessionIntent intent, in android.hardware.cas.ScramblingMode mode);
+  void processEcm(in byte[] sessionId, in byte[] ecm);
+  void processEmm(in byte[] emm);
+  void provision(in String provisionString);
+  void refreshEntitlements(in int refreshType, in byte[] refreshData);
+  void release();
+  void sendEvent(in int event, in int arg, in byte[] eventData);
+  void sendSessionEvent(in byte[] sessionId, in int event, in int arg, in byte[] eventData);
+  void setPrivateData(in byte[] pvtData);
+  void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ICasListener.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ICasListener.aidl
new file mode 100644
index 0000000..db75062
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ICasListener.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+interface ICasListener {
+  void onEvent(in int event, in int arg, in byte[] data);
+  void onSessionEvent(in byte[] sessionId, in int event, in int arg, in byte[] data);
+  void onStatusUpdate(in android.hardware.cas.StatusEvent event, in int number);
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/IDescrambler.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/IDescrambler.aidl
new file mode 100644
index 0000000..411891b
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/IDescrambler.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+interface IDescrambler {
+  int descramble(in android.hardware.cas.ScramblingControl scramblingControl, in android.hardware.cas.SubSample[] subSamples, in android.hardware.cas.SharedBuffer srcBuffer, in long srcOffset, in android.hardware.cas.DestinationBuffer dstBuffer, in long dstOffset);
+  void release();
+  boolean requiresSecureDecoderComponent(in String mime);
+  void setMediaCasSession(in byte[] sessionId);
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/IMediaCasService.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/IMediaCasService.aidl
new file mode 100644
index 0000000..1f945a7
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/IMediaCasService.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+interface IMediaCasService {
+  android.hardware.cas.IDescrambler createDescrambler(in int CA_system_id);
+  android.hardware.cas.ICas createPlugin(in int CA_system_id, in android.hardware.cas.ICasListener listener);
+  android.hardware.cas.AidlCasPluginDescriptor[] enumeratePlugins();
+  boolean isDescramblerSupported(in int CA_system_id);
+  boolean isSystemIdSupported(in int CA_system_id);
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ScramblingControl.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ScramblingControl.aidl
new file mode 100644
index 0000000..c8834ac
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ScramblingControl.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ScramblingControl {
+  UNSCRAMBLED = 0,
+  RESERVED = 1,
+  EVENKEY = 2,
+  ODDKEY = 3,
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ScramblingMode.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ScramblingMode.aidl
new file mode 100644
index 0000000..9d542cc
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/ScramblingMode.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ScramblingMode {
+  RESERVED = 0,
+  DVB_CSA1,
+  DVB_CSA2,
+  DVB_CSA3_STANDARD,
+  DVB_CSA3_MINIMAL,
+  DVB_CSA3_ENHANCE,
+  DVB_CISSA_V1,
+  DVB_IDSA,
+  MULTI2,
+  AES128,
+  AES_ECB,
+  AES_SCTE52,
+  TDES_ECB,
+  TDES_SCTE52,
+  AES_CBC,
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/SessionIntent.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/SessionIntent.aidl
new file mode 100644
index 0000000..00a2fd7
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/SessionIntent.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum SessionIntent {
+  LIVE,
+  PLAYBACK,
+  RECORD,
+  TIMESHIFT,
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/SharedBuffer.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/SharedBuffer.aidl
new file mode 100644
index 0000000..9200b1d
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/SharedBuffer.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+parcelable SharedBuffer {
+  android.hardware.common.Ashmem heapBase;
+  long offset;
+  long size;
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/Status.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/Status.aidl
new file mode 100644
index 0000000..3691009
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/Status.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+parcelable Status {
+  const int OK = 0;
+  const int ERROR_CAS_NO_LICENSE = 1;
+  const int ERROR_CAS_LICENSE_EXPIRED = 2;
+  const int ERROR_CAS_SESSION_NOT_OPENED = 3;
+  const int ERROR_CAS_CANNOT_HANDLE = 4;
+  const int ERROR_CAS_INVALID_STATE = 5;
+  const int BAD_VALUE = 6;
+  const int ERROR_CAS_NOT_PROVISIONED = 7;
+  const int ERROR_CAS_RESOURCE_BUSY = 8;
+  const int ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 9;
+  const int ERROR_CAS_TAMPER_DETECTED = 10;
+  const int ERROR_CAS_DEVICE_REVOKED = 11;
+  const int ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED = 12;
+  const int ERROR_CAS_DECRYPT = 13;
+  const int ERROR_CAS_UNKNOWN = 14;
+  const int ERROR_CAS_NEED_ACTIVATION = 15;
+  const int ERROR_CAS_NEED_PAIRING = 16;
+  const int ERROR_CAS_NO_CARD = 17;
+  const int ERROR_CAS_CARD_MUTE = 18;
+  const int ERROR_CAS_CARD_INVALID = 19;
+  const int ERROR_CAS_BLACKOUT = 20;
+  const int ERROR_CAS_REBOOTING = 21;
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/StatusEvent.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/StatusEvent.aidl
new file mode 100644
index 0000000..0cf37dd
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/StatusEvent.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum StatusEvent {
+  PLUGIN_PHYSICAL_MODULE_CHANGED,
+  PLUGIN_SESSION_NUMBER_CHANGED,
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/SubSample.aidl b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/SubSample.aidl
new file mode 100644
index 0000000..5bd1a1e
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/1/android/hardware/cas/SubSample.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+parcelable SubSample {
+  int numBytesOfClearData;
+  int numBytesOfEncryptedData;
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/AidlCasPluginDescriptor.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/AidlCasPluginDescriptor.aidl
new file mode 100644
index 0000000..89d8625
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/AidlCasPluginDescriptor.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+parcelable AidlCasPluginDescriptor {
+  int caSystemId;
+  String name;
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/DestinationBuffer.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/DestinationBuffer.aidl
new file mode 100644
index 0000000..b69cc33
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/DestinationBuffer.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+union DestinationBuffer {
+  android.hardware.cas.SharedBuffer nonsecureMemory;
+  android.hardware.common.NativeHandle secureMemory;
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICas.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICas.aidl
new file mode 100644
index 0000000..903ab92
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICas.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+interface ICas {
+  void closeSession(in byte[] sessionId);
+  byte[] openSessionDefault();
+  byte[] openSession(in android.hardware.cas.SessionIntent intent, in android.hardware.cas.ScramblingMode mode);
+  void processEcm(in byte[] sessionId, in byte[] ecm);
+  void processEmm(in byte[] emm);
+  void provision(in String provisionString);
+  void refreshEntitlements(in int refreshType, in byte[] refreshData);
+  void release();
+  void sendEvent(in int event, in int arg, in byte[] eventData);
+  void sendSessionEvent(in byte[] sessionId, in int event, in int arg, in byte[] eventData);
+  void setPrivateData(in byte[] pvtData);
+  void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICasListener.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICasListener.aidl
new file mode 100644
index 0000000..db75062
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICasListener.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+interface ICasListener {
+  void onEvent(in int event, in int arg, in byte[] data);
+  void onSessionEvent(in byte[] sessionId, in int event, in int arg, in byte[] data);
+  void onStatusUpdate(in android.hardware.cas.StatusEvent event, in int number);
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/IDescrambler.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/IDescrambler.aidl
new file mode 100644
index 0000000..411891b
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/IDescrambler.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+interface IDescrambler {
+  int descramble(in android.hardware.cas.ScramblingControl scramblingControl, in android.hardware.cas.SubSample[] subSamples, in android.hardware.cas.SharedBuffer srcBuffer, in long srcOffset, in android.hardware.cas.DestinationBuffer dstBuffer, in long dstOffset);
+  void release();
+  boolean requiresSecureDecoderComponent(in String mime);
+  void setMediaCasSession(in byte[] sessionId);
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/IMediaCasService.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/IMediaCasService.aidl
new file mode 100644
index 0000000..1f945a7
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/IMediaCasService.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+interface IMediaCasService {
+  android.hardware.cas.IDescrambler createDescrambler(in int CA_system_id);
+  android.hardware.cas.ICas createPlugin(in int CA_system_id, in android.hardware.cas.ICasListener listener);
+  android.hardware.cas.AidlCasPluginDescriptor[] enumeratePlugins();
+  boolean isDescramblerSupported(in int CA_system_id);
+  boolean isSystemIdSupported(in int CA_system_id);
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingControl.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingControl.aidl
new file mode 100644
index 0000000..c8834ac
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingControl.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ScramblingControl {
+  UNSCRAMBLED = 0,
+  RESERVED = 1,
+  EVENKEY = 2,
+  ODDKEY = 3,
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingMode.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingMode.aidl
new file mode 100644
index 0000000..9d542cc
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingMode.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ScramblingMode {
+  RESERVED = 0,
+  DVB_CSA1,
+  DVB_CSA2,
+  DVB_CSA3_STANDARD,
+  DVB_CSA3_MINIMAL,
+  DVB_CSA3_ENHANCE,
+  DVB_CISSA_V1,
+  DVB_IDSA,
+  MULTI2,
+  AES128,
+  AES_ECB,
+  AES_SCTE52,
+  TDES_ECB,
+  TDES_SCTE52,
+  AES_CBC,
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SessionIntent.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SessionIntent.aidl
new file mode 100644
index 0000000..00a2fd7
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SessionIntent.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum SessionIntent {
+  LIVE,
+  PLAYBACK,
+  RECORD,
+  TIMESHIFT,
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SharedBuffer.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SharedBuffer.aidl
new file mode 100644
index 0000000..9200b1d
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SharedBuffer.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+parcelable SharedBuffer {
+  android.hardware.common.Ashmem heapBase;
+  long offset;
+  long size;
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/Status.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/Status.aidl
new file mode 100644
index 0000000..3691009
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/Status.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+parcelable Status {
+  const int OK = 0;
+  const int ERROR_CAS_NO_LICENSE = 1;
+  const int ERROR_CAS_LICENSE_EXPIRED = 2;
+  const int ERROR_CAS_SESSION_NOT_OPENED = 3;
+  const int ERROR_CAS_CANNOT_HANDLE = 4;
+  const int ERROR_CAS_INVALID_STATE = 5;
+  const int BAD_VALUE = 6;
+  const int ERROR_CAS_NOT_PROVISIONED = 7;
+  const int ERROR_CAS_RESOURCE_BUSY = 8;
+  const int ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 9;
+  const int ERROR_CAS_TAMPER_DETECTED = 10;
+  const int ERROR_CAS_DEVICE_REVOKED = 11;
+  const int ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED = 12;
+  const int ERROR_CAS_DECRYPT = 13;
+  const int ERROR_CAS_UNKNOWN = 14;
+  const int ERROR_CAS_NEED_ACTIVATION = 15;
+  const int ERROR_CAS_NEED_PAIRING = 16;
+  const int ERROR_CAS_NO_CARD = 17;
+  const int ERROR_CAS_CARD_MUTE = 18;
+  const int ERROR_CAS_CARD_INVALID = 19;
+  const int ERROR_CAS_BLACKOUT = 20;
+  const int ERROR_CAS_REBOOTING = 21;
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/StatusEvent.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/StatusEvent.aidl
new file mode 100644
index 0000000..0cf37dd
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/StatusEvent.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum StatusEvent {
+  PLUGIN_PHYSICAL_MODULE_CHANGED,
+  PLUGIN_SESSION_NUMBER_CHANGED,
+}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SubSample.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SubSample.aidl
new file mode 100644
index 0000000..5bd1a1e
--- /dev/null
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SubSample.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.cas;
+/* @hide */
+@VintfStability
+parcelable SubSample {
+  int numBytesOfClearData;
+  int numBytesOfEncryptedData;
+}
diff --git a/cas/aidl/android/hardware/cas/AidlCasPluginDescriptor.aidl b/cas/aidl/android/hardware/cas/AidlCasPluginDescriptor.aidl
new file mode 100644
index 0000000..1dc7ac6
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/AidlCasPluginDescriptor.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+/**
+ * Describes a CAS plugin with its system ID and name.
+ * @hide
+ */
+@VintfStability
+parcelable AidlCasPluginDescriptor {
+    int caSystemId;
+    String name;
+}
diff --git a/cas/aidl/android/hardware/cas/DestinationBuffer.aidl b/cas/aidl/android/hardware/cas/DestinationBuffer.aidl
new file mode 100644
index 0000000..ac562dc
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/DestinationBuffer.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+import android.hardware.cas.SharedBuffer;
+import android.hardware.common.NativeHandle;
+
+/**
+ * @hide
+ */
+@VintfStability
+union DestinationBuffer {
+    /**
+     * If the buffer is SharedBuffer, the descrambled data must be written
+     * to user-space non-secure shared memory.
+     */
+    SharedBuffer nonsecureMemory;
+
+    /**
+     * If the buffer is presented by NativeHandle, the descrambled data must be written
+     * to secure memory referenced by the vendor's buffer allocator.
+     */
+    NativeHandle secureMemory;
+}
diff --git a/cas/aidl/android/hardware/cas/ICas.aidl b/cas/aidl/android/hardware/cas/ICas.aidl
new file mode 100644
index 0000000..272cb10
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/ICas.aidl
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+import android.hardware.cas.ScramblingMode;
+import android.hardware.cas.SessionIntent;
+
+/**
+ * ICas is the API to control the CAS. It is used to manage sessions, provision/refresh the cas
+ * system, and process the EMM/ECM messages. It also allows bi-directional, scheme-specific
+ * communications between the client and the cas system.
+ * @hide
+ */
+@VintfStability
+interface ICas {
+    /**
+     * Close a session.
+     *
+     * @param sessionId The id of the session to be closed.
+     */
+    void closeSession(in byte[] sessionId);
+
+    /**
+     * Open a session to descramble one or more streams without specifying intention
+     * and scrambling mode.
+     *
+     * @return sessionId The id of the newly opened session.
+     */
+    byte[] openSessionDefault();
+
+    /**
+     * Open a session to descramble one or more streams by specifying intention
+     * and scrambling mode.
+     *
+     * @param intent the intention of the session to be opened.
+     * @param mode the scrambling mode the session will use.
+     *
+     * @return sessionId The id of the newly opened session.
+     */
+    byte[] openSession(in SessionIntent intent, in ScramblingMode mode);
+
+    /**
+     * Process an ECM from the ECM stream for this session’s elementary stream.
+     *
+     * @param sessionId the id of the session which the ecm data applies to.
+     * @param ecm a byte array containing the ecm data.
+     */
+    void processEcm(in byte[] sessionId, in byte[] ecm);
+
+    /**
+     * Process an in-band EMM from the EMM stream.
+     *
+     * @param emm a byte array containing the emm data.
+     */
+    void processEmm(in byte[] emm);
+
+    /**
+     * Initiate a provisioning operation for a CA system.
+     *
+     * @param provisionString string containing information needed for the
+     * provisioning operation, the format of which is scheme and implementation
+     * specific.
+     */
+    void provision(in String provisionString);
+
+    /**
+     * Notify the CA system to refresh entitlement keys.
+     *
+     * @param refreshType the type of the refreshment.
+     * @param refreshData private data associated with the refreshment.
+     */
+    void refreshEntitlements(in int refreshType, in byte[] refreshData);
+
+    /**
+     * Release the descrambler instance.
+     */
+    void release();
+
+    /**
+     * Send an scheme-specific event to the CasPlugin.
+     *
+     * @param event an integer denoting a scheme-specific event to be sent.
+     * @param arg a scheme-specific integer argument for the event.
+     * @param data a byte array containing scheme-specific data for the event.
+     */
+    void sendEvent(in int event, in int arg, in byte[] eventData);
+
+    /**
+     * Send an scheme-specific session event to the CasPlugin.
+     *
+     * @param sessionId the id of an opened session.
+     * @param event an integer denoting a scheme-specific event to be sent.
+     * @param arg a scheme-specific integer argument for the event.
+     * @param data a byte array containing scheme-specific data for the event.
+     */
+    void sendSessionEvent(in byte[] sessionId, in int event, in int arg, in byte[] eventData);
+
+    /**
+     * Provide the CA private data from a CA_descriptor in the conditional
+     * access table to a CasPlugin.
+     *
+     * @param pvtData a byte array containing the private data, the format of
+     * which is scheme-specific and opaque to the framework.
+     */
+    void setPrivateData(in byte[] pvtData);
+
+    /**
+     * Provide the CA private data from a CA_descriptor in the program map
+     * table to a session.
+     *
+     * @param sessionId the id of the session which the private data applies to.
+     * @param pvtData a byte array containing the private data, the format of
+     * which is scheme-specific and opaque to the framework.
+     */
+    void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
+}
diff --git a/cas/aidl/android/hardware/cas/ICasListener.aidl b/cas/aidl/android/hardware/cas/ICasListener.aidl
new file mode 100644
index 0000000..21cd257
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/ICasListener.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+import android.hardware.cas.StatusEvent;
+
+/**
+ * @hide
+ */
+@VintfStability
+interface ICasListener {
+    /**
+     * Notify the listener of a scheme-specific event from the CA system.
+     *
+     * @param event an integer whose meaning is scheme-specific.
+     * @param arg an integer whose meaning is scheme-specific.
+     * @param data a byte array of data whose format and meaning are
+     * scheme-specific.
+     */
+    void onEvent(in int event, in int arg, in byte[] data);
+
+    /**
+     * Notify the listener of a scheme-specific session event from CA system.
+     *
+     * @param sessionId the id of an opened session.
+     * @param event an integer whose meaning is scheme-specific.
+     * @param arg an integer whose meaning is scheme-specific.
+     * @param data a byte array of data whose format and meaning are
+     * scheme-specific.
+     */
+    void onSessionEvent(in byte[] sessionId, in int event, in int arg, in byte[] data);
+
+    /**
+     * Notify the listener that the status of CAS system has changed.
+     *
+     * @param event the event type of status change.
+     * @param number value for status event.
+     *               For PLUGIN_PHYSICAL_MODULE_CHANGED event:
+     *               the positive number presents how many plugins are inserted;
+     *               the negative number presents how many plugins are removed.
+     *               Client must enumerate plugins after receive the event.
+     *               For PLUGIN_SESSION_NUMBER_CHANGED event:
+     *               the number presents how many sessions are supported
+     *               in the plugin.
+     */
+    void onStatusUpdate(in StatusEvent event, in int number);
+}
diff --git a/cas/aidl/android/hardware/cas/IDescrambler.aidl b/cas/aidl/android/hardware/cas/IDescrambler.aidl
new file mode 100644
index 0000000..0ac995c
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/IDescrambler.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+import android.hardware.cas.DestinationBuffer;
+import android.hardware.cas.ScramblingControl;
+import android.hardware.cas.SharedBuffer;
+import android.hardware.cas.SubSample;
+
+/**
+ * IDescrambler is the API to control the descrambling operations.
+ * @hide
+ */
+@VintfStability
+interface IDescrambler {
+    /**
+     * Descramble the data in a source SharedBuffer, described by an array of
+     * SubSample structures.
+     *
+     * @param scramblingControl an enumeration indicating the key that the subsamples
+     * were scrambled with.
+     * @param subSamples an array of SubSample structures describing the number of
+     * clear and scrambled bytes within each subsample.
+     * @param srcBuffer the SharedBuffer containing the source scrambled data.
+     * @param srcOffset the position where the source scrambled data starts at.
+     * @param dstBuffer the DestinationBuffer to hold the descrambled data.
+     * @param dstOffset the position where the descrambled data should start at.
+     *
+     * @return bytesWritten Number of bytes that have been successfully written.
+     */
+    int descramble(in ScramblingControl scramblingControl, in SubSample[] subSamples,
+            in SharedBuffer srcBuffer, in long srcOffset, in DestinationBuffer dstBuffer,
+            in long dstOffset);
+
+    /**
+     * Release the descrambler instance.
+     */
+    void release();
+
+    /**
+     * Query if the scrambling scheme requires the use of a secure decoder
+     * to decode data of the given mime type.
+     *
+     * @param mime the mime type of the media data.
+     * @return whether the descrambler requires a secure decoder.
+     */
+    boolean requiresSecureDecoderComponent(in String mime);
+
+    /**
+     * Associate a MediaCas session with this MediaDescrambler instance.
+     *
+     * @param sessionId the id of the session to associate with this descrambler instance.
+     */
+    void setMediaCasSession(in byte[] sessionId);
+}
diff --git a/cas/aidl/android/hardware/cas/IMediaCasService.aidl b/cas/aidl/android/hardware/cas/IMediaCasService.aidl
new file mode 100644
index 0000000..641c4a9
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/IMediaCasService.aidl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+import android.hardware.cas.AidlCasPluginDescriptor;
+import android.hardware.cas.ICas;
+import android.hardware.cas.ICasListener;
+import android.hardware.cas.IDescrambler;
+
+/**
+ * IMediaCasService is the main entry point for interacting with a vendor's
+ * cas HAL to create cas and descrambler plugin instances. A cas plugin instance
+ * opens cas sessions which are used to obtain keys for a descrambler session,
+ * which can in turn be used to descramble protected video content.
+ * @hide
+ */
+@VintfStability
+interface IMediaCasService {
+    /**
+     * Construct a new instance of a DescramblerPlugin given a CA_system_id.
+     *
+     * @param CA_system_id the id of the CA system.
+     * @return the newly created plugin interface.
+     */
+    IDescrambler createDescrambler(in int CA_system_id);
+
+    /**
+     * Construct a new instance of a CasPlugin given a CA_system_id.
+     *
+     * @param CA_system_id the id of the CA system.
+     * @param listener the event listener to receive events coming from the CasPlugin.
+     * @return the newly created CasPlugin interface.
+     */
+    ICas createPlugin(in int CA_system_id, in ICasListener listener);
+
+    /**
+     * List all available CA systems on the device.
+     *
+     * @return an array of descriptors for the available CA systems.
+     */
+    AidlCasPluginDescriptor[] enumeratePlugins();
+
+    /**
+     * Query if the descrambling scheme for a CA system is supported on this device.
+     *
+     * @param CA_system_id the id of the CA system.
+     * @return whether the specified descrambling scheme is supported on this device.
+     */
+    boolean isDescramblerSupported(in int CA_system_id);
+
+    /**
+     * Query if a certain CA system is supported on this device.
+     *
+     * @param CA_system_id the id of the CA system.
+     * @return whether the specified CA system is supported on this device.
+     */
+    boolean isSystemIdSupported(in int CA_system_id);
+}
diff --git a/cas/aidl/android/hardware/cas/ScramblingControl.aidl b/cas/aidl/android/hardware/cas/ScramblingControl.aidl
new file mode 100644
index 0000000..ba0e439
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/ScramblingControl.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+/**
+ * Enumerates the keys used to scramble the content.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum ScramblingControl {
+    UNSCRAMBLED = 0,
+    RESERVED = 1,
+    EVENKEY = 2,
+    ODDKEY = 3,
+}
diff --git a/cas/aidl/android/hardware/cas/ScramblingMode.aidl b/cas/aidl/android/hardware/cas/ScramblingMode.aidl
new file mode 100644
index 0000000..dfca8dc
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/ScramblingMode.aidl
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+/**
+ * The Scrambling Mode.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum ScramblingMode {
+    RESERVED = 0,
+
+    /**
+     * DVB (Digital Video Broadcasting) CSA1 (Common Scrambling Algorithm 1) is
+     * the default mode and shall be used when the scrambling descriptor
+     * is not present in the program map section. DVB scrambling mode is
+     * specified in ETSI EN 300 468 specification.
+     */
+    DVB_CSA1,
+
+    DVB_CSA2,
+
+    /**
+     * DVB-CSA3 in standard mode.
+     */
+    DVB_CSA3_STANDARD,
+
+    /**
+     * DVB-CSA3 in minimally enhanced mode.
+     */
+    DVB_CSA3_MINIMAL,
+
+    /**
+     * DVB-CSA3 in fully enhanced mode.
+     */
+    DVB_CSA3_ENHANCE,
+
+    /**
+     * DVB-CISSA version 1.
+     */
+    DVB_CISSA_V1,
+
+    /**
+     * ATIS-0800006 IIF Default Scrambling Algorithm (IDSA).
+     */
+    DVB_IDSA,
+
+    /**
+     * a symmetric key algorithm.
+     */
+    MULTI2,
+
+    /**
+     * Advanced Encryption System (AES) 128-bit Encryption mode.
+     */
+    AES128,
+
+    /**
+     * Advanced Encryption System (AES) Electronic Code Book (ECB) mode.
+     */
+    AES_ECB,
+
+    /**
+     * Advanced Encryption System (AES) Society of Cable Telecommunications
+     * Engineers (SCTE) 52 mode.
+     */
+    AES_SCTE52,
+
+    /**
+     * Triple Data Encryption Algorithm (TDES) Electronic Code Book (ECB) mode.
+     */
+    TDES_ECB,
+
+    /**
+     * Triple Data Encryption Algorithm (TDES) Society of Cable Telecommunications
+     * Engineers (SCTE) 52 mode.
+     */
+    TDES_SCTE52,
+
+    /**
+     * Advanced Encryption System (AES) Cipher Block Chaining (CBC) mode.
+     */
+    AES_CBC,
+}
diff --git a/cas/aidl/android/hardware/cas/SessionIntent.aidl b/cas/aidl/android/hardware/cas/SessionIntent.aidl
new file mode 100644
index 0000000..d7da137
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/SessionIntent.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+/**
+ * The intented usage for the session.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum SessionIntent {
+    /**
+     * Live Stream.
+     */
+    LIVE,
+
+    /**
+     * Playback Recorded Stream.
+     */
+    PLAYBACK,
+
+    /**
+     * Record Live Stream.
+     */
+    RECORD,
+
+    /**
+     * View the content with Time Shift capability
+     */
+    TIMESHIFT,
+}
diff --git a/cas/aidl/android/hardware/cas/SharedBuffer.aidl b/cas/aidl/android/hardware/cas/SharedBuffer.aidl
new file mode 100644
index 0000000..0c89cfe
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/SharedBuffer.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+import android.hardware.common.Ashmem;
+
+/**
+ * SharedBuffer describes a shared buffer which is defined by a heapBase, an
+ * offset and a size. The offset is relative to the shared memory base for the
+ * memory region identified by heapBase.
+ * @hide
+ */
+@VintfStability
+parcelable SharedBuffer {
+    /**
+     * Ashmem shared memory
+     */
+    Ashmem heapBase;
+
+    /**
+     * The offset from the shared memory base
+     */
+    long offset;
+
+    /**
+     * The size of the shared buffer in bytes
+     */
+    long size;
+}
diff --git a/cas/aidl/android/hardware/cas/Status.aidl b/cas/aidl/android/hardware/cas/Status.aidl
new file mode 100644
index 0000000..ba0bd65
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/Status.aidl
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+/**
+ * @hide
+ */
+@VintfStability
+parcelable Status {
+    /**
+     * The CAS plugin must return OK when an operation completes without any
+     * errors.
+     */
+    const int OK = 0;
+
+    /**
+     * The CAS plugin must return ERROR_CAS_NO_LICENSE, when descrambling is
+     * attempted and no license keys have been provided.
+     */
+    const int ERROR_CAS_NO_LICENSE = 1;
+
+    /**
+     * ERROR_CAS_LICENSE_EXPIRED must be returned when an attempt is made
+     * to use a license and the keys in that license have expired.
+     */
+    const int ERROR_CAS_LICENSE_EXPIRED = 2;
+
+    /**
+     * The CAS plugin must return ERROR_CAS_SESSION_NOT_OPENED when an
+     * attempt is made to use a session that has not been opened.
+     */
+    const int ERROR_CAS_SESSION_NOT_OPENED = 3;
+
+    /**
+     * The CAS plugin must return ERROR_CAS_CANNOT_HANDLE when an unsupported
+     * data format or operation is attempted.
+     */
+    const int ERROR_CAS_CANNOT_HANDLE = 4;
+
+    /**
+     * ERROR_CAS_INVALID_STATE must be returned when the device is in a state
+     * where it is not able to perform descrambling.
+     */
+    const int ERROR_CAS_INVALID_STATE = 5;
+
+    /**
+     * The CAS plugin must return BAD_VALUE whenever an illegal parameter is
+     * passed to one of the interface functions.
+     */
+    const int BAD_VALUE = 6;
+
+    /**
+     * The CAS plugin must return ERROR_CAS_NOT_PROVISIONED when the device
+     * has not yet been provisioned.
+     */
+    const int ERROR_CAS_NOT_PROVISIONED = 7;
+
+    /**
+     * ERROR_CAS_RESOURCE_BUSY must be returned when resources, such as CAS
+     * sessions or secure buffers are not available to perform a requested
+     * operation because they are already in use.
+     */
+    const int ERROR_CAS_RESOURCE_BUSY = 8;
+
+    /**
+     * The CAS Plugin must return ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION
+     * when the output protection level enabled on the device is not
+     * sufficient to meet the requirements in the license policy. HDCP is an
+     * example of a form of output protection.
+     */
+    const int ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 9;
+
+    /**
+     * The CAS Plugin must return ERROR_CAS_TAMPER_DETECTED if an attempt to
+     * tamper with the CAS system is detected.
+     */
+    const int ERROR_CAS_TAMPER_DETECTED = 10;
+
+    /**
+     * The CAS Plugin must return ERROR_CAS_DEVICE_REVOKED if the response
+     * indicates that the device has been revoked. Device revocation means
+     * that the device is no longer permitted to play content.
+     */
+    const int ERROR_CAS_DEVICE_REVOKED = 11;
+
+    /**
+     * The CAS plugin must return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED when
+     * descrambling is failing because the session is not initialized properly.
+     */
+    const int ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED = 12;
+
+    /**
+     * The CAS Plugin must return ERROR_CAS_DECRYPT if the DescramblerPlugin's
+     * descramble operation fails.
+     */
+    const int ERROR_CAS_DECRYPT = 13;
+
+    /**
+     * ERROR_CAS_UNKNOWN must be returned when a fatal failure occurs and no
+     * other defined error is appropriate.
+     */
+    const int ERROR_CAS_UNKNOWN = 14;
+
+    /**
+     * ERROR_CAS_NEED_ACTIVATION is used to trigger device activation process.
+     */
+    const int ERROR_CAS_NEED_ACTIVATION = 15;
+
+    /**
+     * ERROR_CAS_NEED_PAIRING is used to trigger pairing process.
+     */
+    const int ERROR_CAS_NEED_PAIRING = 16;
+
+    /**
+     * ERROR_CAS_NO_CARD is used to report no smart card for descrambling.
+     */
+    const int ERROR_CAS_NO_CARD = 17;
+
+    /**
+     * ERROR_CAS_CARD_MUTE is used to report smart card is muted for
+     * descrambling.
+     */
+    const int ERROR_CAS_CARD_MUTE = 18;
+
+    /**
+     *  ERROR_CAS_CARD_INVALID is used to report smart card isn't valid.
+     */
+    const int ERROR_CAS_CARD_INVALID = 19;
+
+    /**
+     *  ERROR_CAS_BLACKOUT is used to report geographical blackout.
+     */
+    const int ERROR_CAS_BLACKOUT = 20;
+
+    /**
+     * ERROR_CAS_REBOOTING is used to report CAS is during rebooting.
+     */
+    const int ERROR_CAS_REBOOTING = 21;
+}
diff --git a/cas/aidl/android/hardware/cas/StatusEvent.aidl b/cas/aidl/android/hardware/cas/StatusEvent.aidl
new file mode 100644
index 0000000..1fe732e
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/StatusEvent.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+/**
+ * The Event Type for status change.
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum StatusEvent {
+    /**
+     * The status of CAS plugin was changed due to physical module insertion or
+     * removal. Client must call enumeratePlugins to update plugins' status.
+     */
+    PLUGIN_PHYSICAL_MODULE_CHANGED,
+
+    /**
+     * The status of supported session number was changed due to physical module
+     * insertion or removal. Client must update session resource according to
+     * latest StatusMessage from the StatusEvent. The plugin supports unlimited
+     * session by default.
+     */
+    PLUGIN_SESSION_NUMBER_CHANGED,
+}
diff --git a/cas/aidl/android/hardware/cas/SubSample.aidl b/cas/aidl/android/hardware/cas/SubSample.aidl
new file mode 100644
index 0000000..8e1ff77
--- /dev/null
+++ b/cas/aidl/android/hardware/cas/SubSample.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.cas;
+
+/**
+ * A subsample consists of some number of bytes of clear (unscrambled)
+ * data followed by a number of bytes of scrambled data.
+ * @hide
+ */
+@VintfStability
+parcelable SubSample {
+    int numBytesOfClearData;
+    int numBytesOfEncryptedData;
+}
diff --git a/cas/aidl/default/Android.bp b/cas/aidl/default/Android.bp
new file mode 100755
index 0000000..3c16d57
--- /dev/null
+++ b/cas/aidl/default/Android.bp
@@ -0,0 +1,93 @@
+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_static {
+    name: "libcasexampleimpl",
+    vendor_available: true,
+
+    srcs: [
+        "CasImpl.cpp",
+        "DescramblerImpl.cpp",
+        "MediaCasService.cpp",
+        "SharedLibrary.cpp",
+        "TypeConvert.cpp",
+    ],
+
+    shared_libs: [
+        "android.hardware.cas-V1-ndk",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+        "libcutils",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+    ],
+    header_libs: [
+        "libstagefright_foundation_headers",
+        "media_plugin_headers",
+    ],
+}
+
+cc_defaults {
+    name: "cas_service_example_defaults",
+    vendor: true,
+    relative_install_path: "hw",
+
+    srcs: ["service.cpp"],
+
+    static_libs: [
+        "libaidlcommonsupport",
+        "libcasexampleimpl",
+    ],
+    shared_libs: [
+        "android.hardware.cas-V1-ndk",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+        "libcutils",
+    ],
+    header_libs: ["media_plugin_headers"],
+    vintf_fragments: ["android.hardware.cas-service.xml"],
+}
+
+cc_binary {
+    name: "android.hardware.cas-service.example",
+    defaults: ["cas_service_example_defaults"],
+    init_rc: ["cas-default.rc"],
+}
+
+cc_binary {
+    name: "android.hardware.cas-service.example-lazy",
+    defaults: ["cas_service_example_defaults"],
+    init_rc: ["cas-default-lazy.rc"],
+    cflags: ["-DLAZY_SERVICE"],
+}
+
+cc_fuzz {
+    name: "android.hardware.cas-service_fuzzer",
+    vendor: true,
+
+    defaults: ["service_fuzzer_defaults"],
+    srcs: ["fuzzer.cpp"],
+
+    shared_libs: [
+        "android.hardware.cas-V1-ndk",
+        "libcutils",
+        "liblog",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+        "libcasexampleimpl",
+    ],
+    header_libs: ["media_plugin_headers"],
+    fuzz_config: {
+        componentid: 1344,
+    },
+}
diff --git a/cas/aidl/default/CasImpl.cpp b/cas/aidl/default/CasImpl.cpp
new file mode 100755
index 0000000..f08fcc0
--- /dev/null
+++ b/cas/aidl/default/CasImpl.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ icensed 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 "android.hardware.cas-CasImpl"
+
+#include <media/cas/CasAPI.h>
+#include <utils/Log.h>
+
+#include "CasImpl.h"
+#include "TypeConvert.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+CasImpl::CasImpl(const shared_ptr<ICasListener>& listener) : mListener(listener) {
+    ALOGV("CTOR");
+}
+
+CasImpl::~CasImpl() {
+    ALOGV("DTOR");
+    release();
+}
+
+// static
+void CasImpl::OnEvent(void* appData, int32_t event, int32_t arg, uint8_t* data, size_t size) {
+    if (appData == NULL) {
+        ALOGE("Invalid appData!");
+        return;
+    }
+    CasImpl* casImpl = static_cast<CasImpl*>(appData);
+    casImpl->onEvent(event, arg, data, size);
+}
+
+// static
+void CasImpl::CallBackExt(void* appData, int32_t event, int32_t arg, uint8_t* data, size_t size,
+                          const CasSessionId* sessionId) {
+    if (appData == NULL) {
+        ALOGE("Invalid appData!");
+        return;
+    }
+    CasImpl* casImpl = static_cast<CasImpl*>(appData);
+    casImpl->onEvent(sessionId, event, arg, data, size);
+}
+
+// static
+void CasImpl::StatusUpdate(void* appData, int32_t event, int32_t arg) {
+    if (appData == NULL) {
+        ALOGE("Invalid appData!");
+        return;
+    }
+    CasImpl* casImpl = static_cast<CasImpl*>(appData);
+    casImpl->onStatusUpdate(event, arg);
+}
+
+void CasImpl::init(CasPlugin* plugin) {
+    shared_ptr<CasPlugin> holder(plugin);
+    atomic_store(&mPluginHolder, holder);
+}
+
+void CasImpl::onEvent(int32_t event, int32_t arg, uint8_t* data, size_t size) {
+    if (mListener == NULL) {
+        return;
+    }
+
+    vector<uint8_t> eventData;
+    if (data != NULL) {
+        eventData.assign(data, data + size);
+    }
+
+    mListener->onEvent(event, arg, eventData);
+}
+
+void CasImpl::onEvent(const CasSessionId* sessionId, int32_t event, int32_t arg, uint8_t* data,
+                      size_t size) {
+    if (mListener == NULL) {
+        return;
+    }
+
+    vector<uint8_t> eventData;
+    if (data != NULL) {
+        eventData.assign(data, data + size);
+    }
+
+    if (sessionId != NULL) {
+        mListener->onSessionEvent(*sessionId, event, arg, eventData);
+    } else {
+        mListener->onEvent(event, arg, eventData);
+    }
+}
+
+void CasImpl::onStatusUpdate(int32_t event, int32_t arg) {
+    if (mListener == NULL) {
+        return;
+    }
+    mListener->onStatusUpdate(static_cast<StatusEvent>(event), arg);
+}
+
+ScopedAStatus CasImpl::setPluginStatusUpdateCallback() {
+    ALOGV("%s", __FUNCTION__);
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+    return toStatus(holder->setStatusCallback(&CasImpl::StatusUpdate));
+}
+
+ScopedAStatus CasImpl::setPrivateData(const vector<uint8_t>& pvtData) {
+    ALOGV("%s", __FUNCTION__);
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+    return toStatus(holder->setPrivateData(pvtData));
+}
+
+ScopedAStatus CasImpl::openSessionDefault(vector<uint8_t>* sessionId) {
+    ALOGV("%s", __FUNCTION__);
+
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    status_t err = INVALID_OPERATION;
+    if (holder.get() != nullptr) {
+        err = holder->openSession(sessionId);
+        holder.reset();
+    }
+
+    return toStatus(err);
+}
+
+ScopedAStatus CasImpl::openSession(SessionIntent intent, ScramblingMode mode,
+                                   vector<uint8_t>* sessionId) {
+    ALOGV("%s", __FUNCTION__);
+
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    status_t err = INVALID_OPERATION;
+    if (holder.get() != nullptr) {
+        err = holder->openSession(static_cast<uint32_t>(intent), static_cast<uint32_t>(mode),
+                                  sessionId);
+        holder.reset();
+    }
+
+    return toStatus(err);
+}
+
+ScopedAStatus CasImpl::setSessionPrivateData(const vector<uint8_t>& sessionId,
+                                             const vector<uint8_t>& pvtData) {
+    ALOGV("%s: sessionId=%s", __FUNCTION__, sessionIdToString(sessionId).string());
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+    return toStatus(holder->setSessionPrivateData(sessionId, pvtData));
+}
+
+ScopedAStatus CasImpl::closeSession(const vector<uint8_t>& sessionId) {
+    ALOGV("%s: sessionId=%s", __FUNCTION__, sessionIdToString(sessionId).string());
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+    return toStatus(holder->closeSession(sessionId));
+}
+
+ScopedAStatus CasImpl::processEcm(const vector<uint8_t>& sessionId, const vector<uint8_t>& ecm) {
+    ALOGV("%s: sessionId=%s", __FUNCTION__, sessionIdToString(sessionId).string());
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+
+    return toStatus(holder->processEcm(sessionId, ecm));
+}
+
+ScopedAStatus CasImpl::processEmm(const vector<uint8_t>& emm) {
+    ALOGV("%s", __FUNCTION__);
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+
+    return toStatus(holder->processEmm(emm));
+}
+
+ScopedAStatus CasImpl::sendEvent(int32_t event, int32_t arg, const vector<uint8_t>& eventData) {
+    ALOGV("%s", __FUNCTION__);
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+
+    status_t err = holder->sendEvent(event, arg, eventData);
+    return toStatus(err);
+}
+
+ScopedAStatus CasImpl::sendSessionEvent(const vector<uint8_t>& sessionId, int32_t event,
+                                        int32_t arg, const vector<uint8_t>& eventData) {
+    ALOGV("%s", __FUNCTION__);
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+
+    status_t err = holder->sendSessionEvent(sessionId, event, arg, eventData);
+    return toStatus(err);
+}
+
+ScopedAStatus CasImpl::provision(const string& provisionString) {
+    ALOGV("%s: provisionString=%s", __FUNCTION__, provisionString.c_str());
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+
+    return toStatus(holder->provision(String8(provisionString.c_str())));
+}
+
+ScopedAStatus CasImpl::refreshEntitlements(int32_t refreshType,
+                                           const vector<uint8_t>& refreshData) {
+    ALOGV("%s", __FUNCTION__);
+    shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+
+    status_t err = holder->refreshEntitlements(refreshType, refreshData);
+    return toStatus(err);
+}
+
+ScopedAStatus CasImpl::release() {
+    ALOGV("%s: plugin=%p", __FUNCTION__, mPluginHolder.get());
+
+    shared_ptr<CasPlugin> holder(nullptr);
+    atomic_store(&mPluginHolder, holder);
+
+    return ScopedAStatus::ok();
+}
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/CasImpl.h b/cas/aidl/default/CasImpl.h
new file mode 100755
index 0000000..2488a7f
--- /dev/null
+++ b/cas/aidl/default/CasImpl.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/cas/BnCas.h>
+#include <aidl/android/hardware/cas/ICasListener.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+using namespace ::android;
+using namespace std;
+using ndk::ScopedAStatus;
+
+class CasImpl : public BnCas {
+  public:
+    CasImpl(const shared_ptr<ICasListener>& listener);
+    virtual ~CasImpl();
+
+    static void OnEvent(void* appData, int32_t event, int32_t arg, uint8_t* data, size_t size);
+
+    static void CallBackExt(void* appData, int32_t event, int32_t arg, uint8_t* data, size_t size,
+                            const CasSessionId* sessionId);
+
+    static void StatusUpdate(void* appData, int32_t event, int32_t arg);
+
+    void init(CasPlugin* plugin);
+    void onEvent(int32_t event, int32_t arg, uint8_t* data, size_t size);
+
+    void onEvent(const CasSessionId* sessionId, int32_t event, int32_t arg, uint8_t* data,
+                 size_t size);
+
+    void onStatusUpdate(int32_t event, int32_t arg);
+
+    // ICas inherits
+
+    ScopedAStatus setPluginStatusUpdateCallback();
+
+    virtual ScopedAStatus setPrivateData(const vector<uint8_t>& pvtData) override;
+
+    virtual ScopedAStatus openSessionDefault(vector<uint8_t>* sessionId) override;
+
+    virtual ScopedAStatus openSession(SessionIntent intent, ScramblingMode mode,
+                                      vector<uint8_t>* sessionId) override;
+
+    virtual ScopedAStatus closeSession(const vector<uint8_t>& sessionId) override;
+
+    virtual ScopedAStatus setSessionPrivateData(const vector<uint8_t>& sessionId,
+                                                const vector<uint8_t>& pvtData) override;
+
+    virtual ScopedAStatus processEcm(const vector<uint8_t>& sessionId,
+                                     const vector<uint8_t>& ecm) override;
+
+    virtual ScopedAStatus processEmm(const vector<uint8_t>& emm) override;
+
+    virtual ScopedAStatus sendEvent(int32_t event, int32_t arg,
+                                    const vector<uint8_t>& eventData) override;
+
+    virtual ScopedAStatus sendSessionEvent(const vector<uint8_t>& sessionId, int32_t event,
+                                           int32_t arg, const vector<uint8_t>& eventData) override;
+
+    virtual ScopedAStatus provision(const string& provisionString) override;
+
+    virtual ScopedAStatus refreshEntitlements(int32_t refreshType,
+                                              const vector<uint8_t>& refreshData) override;
+
+    virtual ScopedAStatus release() override;
+
+  private:
+    struct PluginHolder;
+    shared_ptr<CasPlugin> mPluginHolder;
+    shared_ptr<ICasListener> mListener;
+
+    DISALLOW_EVIL_CONSTRUCTORS(CasImpl);
+};
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/DescramblerImpl.cpp b/cas/aidl/default/DescramblerImpl.cpp
new file mode 100755
index 0000000..a96fd46
--- /dev/null
+++ b/cas/aidl/default/DescramblerImpl.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.cas-DescramblerImpl"
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <inttypes.h>
+#include <media/cas/DescramblerAPI.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <sys/mman.h>
+#include <utils/Log.h>
+
+#include "DescramblerImpl.h"
+#include "TypeConvert.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+#define CHECK_SUBSAMPLE_DEF(type)                                                                 \
+    static_assert(sizeof(SubSample) == sizeof(type::SubSample), "SubSample: size doesn't match"); \
+    static_assert(offsetof(SubSample, numBytesOfClearData) ==                                     \
+                          offsetof(type::SubSample, mNumBytesOfClearData),                        \
+                  "SubSample: numBytesOfClearData offset doesn't match");                         \
+    static_assert(offsetof(SubSample, numBytesOfEncryptedData) ==                                 \
+                          offsetof(type::SubSample, mNumBytesOfEncryptedData),                    \
+                  "SubSample: numBytesOfEncryptedData offset doesn't match")
+
+CHECK_SUBSAMPLE_DEF(DescramblerPlugin);
+CHECK_SUBSAMPLE_DEF(CryptoPlugin);
+
+DescramblerImpl::DescramblerImpl(DescramblerPlugin* plugin) : mPluginHolder(plugin) {
+    ALOGV("CTOR: plugin=%p", mPluginHolder.get());
+}
+
+DescramblerImpl::~DescramblerImpl() {
+    ALOGV("DTOR: plugin=%p", mPluginHolder.get());
+    release();
+}
+
+ScopedAStatus DescramblerImpl::setMediaCasSession(const vector<uint8_t>& in_sessionId) {
+    ALOGV("%s: sessionId=%s", __FUNCTION__, sessionIdToString(in_sessionId).string());
+
+    shared_ptr<DescramblerPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+
+    return toStatus(holder->setMediaCasSession(in_sessionId));
+}
+
+ScopedAStatus DescramblerImpl::requiresSecureDecoderComponent(const string& in_mime,
+                                                              bool* _aidl_return) {
+    shared_ptr<DescramblerPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        *_aidl_return = false;
+    }
+
+    *_aidl_return = holder->requiresSecureDecoderComponent(String8(in_mime.c_str()));
+    return ScopedAStatus::ok();
+}
+
+static inline bool validateRangeForSize(int64_t offset, int64_t length, int64_t size) {
+    return isInRange<int64_t, uint64_t>(0, (uint64_t)size, offset, (uint64_t)length);
+}
+
+ScopedAStatus DescramblerImpl::descramble(ScramblingControl scramblingControl,
+                                          const vector<SubSample>& subSamples,
+                                          const SharedBuffer& srcBuffer, int64_t srcOffset,
+                                          const DestinationBuffer& dstBuffer, int64_t dstOffset,
+                                          int32_t* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    // heapbase's size is stored in int64_t, but mapMemory's mmap will map size in
+    // size_t. If size is over SIZE_MAX, mapMemory mapMemory could succeed but the
+    // mapped memory's actual size will be smaller than the reported size.
+    if (srcBuffer.heapBase.size > SIZE_MAX) {
+        ALOGE("Invalid memory size: %" PRIu64 "", srcBuffer.heapBase.size);
+        android_errorWriteLog(0x534e4554, "79376389");
+        return toStatus(BAD_VALUE);
+    }
+
+    void* srcPtr = mmap(NULL, srcBuffer.heapBase.size, PROT_READ | PROT_WRITE, MAP_SHARED,
+                        srcBuffer.heapBase.fd.get(), 0);
+
+    // Validate if the offset and size in the SharedBuffer is consistent with the
+    // mapped heapbase, since the offset and size is controlled by client.
+    if (srcPtr == NULL) {
+        ALOGE("Failed to map src buffer.");
+        return toStatus(BAD_VALUE);
+    }
+    if (!validateRangeForSize(srcBuffer.offset, srcBuffer.size, srcBuffer.heapBase.size)) {
+        ALOGE("Invalid src buffer range: offset %" PRIu64 ", size %" PRIu64
+              ", srcMem"
+              "size %" PRIu64 "",
+              srcBuffer.offset, srcBuffer.size, srcBuffer.heapBase.size);
+        android_errorWriteLog(0x534e4554, "67962232");
+        return toStatus(BAD_VALUE);
+    }
+
+    // use 64-bit here to catch bad subsample size that might be overflowing.
+    uint64_t totalBytesInSubSamples = 0;
+    for (size_t i = 0; i < subSamples.size(); i++) {
+        uint32_t numBytesOfClearData = subSamples[i].numBytesOfClearData;
+        uint32_t numBytesOfEncryptedData = subSamples[i].numBytesOfEncryptedData;
+        totalBytesInSubSamples += (uint64_t)numBytesOfClearData + numBytesOfEncryptedData;
+    }
+    // Further validate if the specified srcOffset and requested total subsample size
+    // is consistent with the source shared buffer size.
+    if (!validateRangeForSize(srcOffset, totalBytesInSubSamples, srcBuffer.size)) {
+        ALOGE("Invalid srcOffset and subsample size: "
+              "srcOffset %" PRIu64 ", totalBytesInSubSamples %" PRIu64
+              ", srcBuffer"
+              "size %" PRIu64 "",
+              srcOffset, totalBytesInSubSamples, srcBuffer.size);
+        android_errorWriteLog(0x534e4554, "67962232");
+        return toStatus(BAD_VALUE);
+    }
+    srcPtr = (uint8_t*)srcPtr + srcBuffer.offset;
+
+    void* dstPtr = NULL;
+    if (dstBuffer.getTag() == DestinationBuffer::Tag::nonsecureMemory) {
+        // When using shared memory, src buffer is also used as dst,
+        // we don't map it again here.
+        dstPtr = srcPtr;
+
+        // In this case the dst and src would be the same buffer, need to validate
+        // dstOffset against the buffer size too.
+        if (!validateRangeForSize(dstOffset, totalBytesInSubSamples, srcBuffer.size)) {
+            ALOGE("Invalid dstOffset and subsample size: "
+                  "dstOffset %" PRIu64 ", totalBytesInSubSamples %" PRIu64
+                  ", srcBuffer"
+                  "size %" PRIu64 "",
+                  dstOffset, totalBytesInSubSamples, srcBuffer.size);
+            android_errorWriteLog(0x534e4554, "67962232");
+            return toStatus(BAD_VALUE);
+        }
+    } else {
+        native_handle_t* handle = makeFromAidl(dstBuffer.get<DestinationBuffer::secureMemory>());
+        dstPtr = static_cast<void*>(handle);
+    }
+
+    // Get a local copy of the shared_ptr for the plugin. Note that before
+    // calling the callback, this shared_ptr must be manually reset, since
+    // the client side could proceed as soon as the callback is called
+    // without waiting for this method to go out of scope.
+    shared_ptr<DescramblerPlugin> holder = atomic_load(&mPluginHolder);
+    if (holder.get() == nullptr) {
+        return toStatus(INVALID_OPERATION);
+    }
+
+    // Casting SubSample to DescramblerPlugin::SubSample, but need to ensure
+    // structs are actually identical
+
+    auto returnStatus =
+            holder->descramble(dstBuffer.getTag() != DestinationBuffer::Tag::nonsecureMemory,
+                               (DescramblerPlugin::ScramblingControl)scramblingControl,
+                               subSamples.size(), (DescramblerPlugin::SubSample*)subSamples.data(),
+                               srcPtr, srcOffset, dstPtr, dstOffset, NULL);
+
+    holder.reset();
+    *_aidl_return = returnStatus;
+    return toStatus(returnStatus >= 0 ? OK : returnStatus);
+}
+
+ScopedAStatus DescramblerImpl::release() {
+    ALOGV("%s: plugin=%p", __FUNCTION__, mPluginHolder.get());
+
+    shared_ptr<DescramblerPlugin> holder(nullptr);
+    atomic_store(&mPluginHolder, holder);
+
+    return ScopedAStatus::ok();
+}
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/DescramblerImpl.h b/cas/aidl/default/DescramblerImpl.h
new file mode 100755
index 0000000..2efc1a0
--- /dev/null
+++ b/cas/aidl/default/DescramblerImpl.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/cas/BnDescrambler.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+using namespace ::android;
+using namespace std;
+using ndk::ScopedAStatus;
+
+class DescramblerImpl : public BnDescrambler {
+  public:
+    DescramblerImpl(DescramblerPlugin* plugin);
+    virtual ~DescramblerImpl();
+
+    virtual ScopedAStatus setMediaCasSession(const vector<uint8_t>& in_sessionId) override;
+
+    virtual ScopedAStatus requiresSecureDecoderComponent(const string& in_mime,
+                                                         bool* _aidl_return) override;
+
+    virtual ScopedAStatus descramble(ScramblingControl in_scramblingControl,
+                                     const vector<SubSample>& in_subSamples,
+                                     const SharedBuffer& in_srcBuffer, int64_t in_srcOffset,
+                                     const DestinationBuffer& in_dstBuffer, int64_t in_dstOffset,
+                                     int32_t* _aidl_return) override;
+
+    virtual ScopedAStatus release() override;
+
+  private:
+    shared_ptr<DescramblerPlugin> mPluginHolder;
+
+    DISALLOW_EVIL_CONSTRUCTORS(DescramblerImpl);
+};
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/FactoryLoader.h b/cas/aidl/default/FactoryLoader.h
new file mode 100755
index 0000000..6a562f6
--- /dev/null
+++ b/cas/aidl/default/FactoryLoader.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <media/cas/CasAPI.h>
+#include <utils/KeyedVector.h>
+#include <utils/Mutex.h>
+#include "SharedLibrary.h"
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+using namespace ::android;
+
+template <class T>
+class FactoryLoader {
+  public:
+    FactoryLoader(const char* name) : mFactory(NULL), mCreateFactoryFuncName(name) {}
+
+    virtual ~FactoryLoader() { closeFactory(); }
+
+    bool findFactoryForScheme(int32_t CA_system_id, shared_ptr<SharedLibrary>* library = NULL,
+                              T** factory = NULL);
+
+    bool enumeratePlugins(vector<AidlCasPluginDescriptor>* results);
+
+  private:
+    typedef T* (*CreateFactoryFunc)();
+
+    Mutex mMapLock;
+    T* mFactory;
+    const char* mCreateFactoryFuncName;
+    shared_ptr<SharedLibrary> mLibrary;
+    KeyedVector<int32_t, String8> mCASystemIdToLibraryPathMap;
+    KeyedVector<String8, shared_ptr<SharedLibrary>> mLibraryPathToOpenLibraryMap;
+
+    bool loadFactoryForSchemeFromPath(const String8& path, int32_t CA_system_id,
+                                      shared_ptr<SharedLibrary>* library, T** factory);
+
+    bool queryPluginsFromPath(const String8& path, vector<AidlCasPluginDescriptor>* results);
+
+    bool openFactory(const String8& path);
+    void closeFactory();
+};
+
+template <class T>
+bool FactoryLoader<T>::findFactoryForScheme(int32_t CA_system_id,
+                                            shared_ptr<SharedLibrary>* library, T** factory) {
+    if (library != NULL) {
+        library->reset();
+    }
+    if (factory != NULL) {
+        *factory = NULL;
+    }
+
+    Mutex::Autolock autoLock(mMapLock);
+
+    // first check cache
+    ssize_t index = mCASystemIdToLibraryPathMap.indexOfKey(CA_system_id);
+    if (index >= 0) {
+        return loadFactoryForSchemeFromPath(mCASystemIdToLibraryPathMap[index], CA_system_id,
+                                            library, factory);
+    }
+
+    // no luck, have to search
+#ifdef __LP64__
+    String8 dirPath("/vendor/lib64/mediacas");
+#else
+    String8 dirPath("/vendor/lib/mediacas");
+#endif
+    DIR* pDir = opendir(dirPath.string());
+
+    if (pDir == NULL) {
+        ALOGE("Failed to open plugin directory %s", dirPath.string());
+        return false;
+    }
+
+    struct dirent* pEntry;
+    while ((pEntry = readdir(pDir))) {
+        String8 pluginPath = dirPath + "/" + pEntry->d_name;
+        if (pluginPath.getPathExtension() == ".so") {
+            if (loadFactoryForSchemeFromPath(pluginPath, CA_system_id, library, factory)) {
+                mCASystemIdToLibraryPathMap.add(CA_system_id, pluginPath);
+                closedir(pDir);
+
+                return true;
+            }
+        }
+    }
+
+    closedir(pDir);
+
+    ALOGE("Failed to find plugin");
+    return false;
+}
+
+template <class T>
+bool FactoryLoader<T>::enumeratePlugins(vector<AidlCasPluginDescriptor>* results) {
+    ALOGI("enumeratePlugins");
+
+    results->clear();
+
+#ifdef __LP64__
+    String8 dirPath("/vendor/lib64/mediacas");
+#else
+    String8 dirPath("/vendor/lib/mediacas");
+#endif
+    DIR* pDir = opendir(dirPath.string());
+
+    if (pDir == NULL) {
+        ALOGE("Failed to open plugin directory %s", dirPath.string());
+        return false;
+    }
+
+    Mutex::Autolock autoLock(mMapLock);
+
+    struct dirent* pEntry;
+    while ((pEntry = readdir(pDir))) {
+        String8 pluginPath = dirPath + "/" + pEntry->d_name;
+        if (pluginPath.getPathExtension() == ".so") {
+            queryPluginsFromPath(pluginPath, results);
+        }
+    }
+    closedir(pDir);
+    return true;
+}
+
+template <class T>
+bool FactoryLoader<T>::loadFactoryForSchemeFromPath(const String8& path, int32_t CA_system_id,
+                                                    shared_ptr<SharedLibrary>* library,
+                                                    T** factory) {
+    closeFactory();
+
+    if (!openFactory(path) || !mFactory->isSystemIdSupported(CA_system_id)) {
+        closeFactory();
+        return false;
+    }
+
+    if (library != NULL) {
+        *library = mLibrary;
+    }
+    if (factory != NULL) {
+        *factory = mFactory;
+    }
+    return true;
+}
+
+template <class T>
+bool FactoryLoader<T>::queryPluginsFromPath(const String8& path,
+                                            vector<AidlCasPluginDescriptor>* results) {
+    closeFactory();
+
+    vector<CasPluginDescriptor> descriptors;
+    if (!openFactory(path) || mFactory->queryPlugins(&descriptors) != OK) {
+        closeFactory();
+        return false;
+    }
+
+    for (auto it = descriptors.begin(); it != descriptors.end(); it++) {
+        results->push_back(
+                AidlCasPluginDescriptor{.caSystemId = it->CA_system_id, .name = it->name.c_str()});
+    }
+    return true;
+}
+
+template <class T>
+bool FactoryLoader<T>::openFactory(const String8& path) {
+    // get strong pointer to open shared library
+    ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
+    if (index >= 0) {
+        mLibrary = mLibraryPathToOpenLibraryMap[index];
+    } else {
+        index = mLibraryPathToOpenLibraryMap.add(path, NULL);
+    }
+
+    if (!mLibrary.get()) {
+        mLibrary = ::ndk::SharedRefBase::make<SharedLibrary>(path);
+        if (!*mLibrary) {
+            return false;
+        }
+
+        mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
+    }
+
+    CreateFactoryFunc createFactory = (CreateFactoryFunc)mLibrary->lookup(mCreateFactoryFuncName);
+    if (createFactory == NULL || (mFactory = createFactory()) == NULL) {
+        return false;
+    }
+    return true;
+}
+
+template <class T>
+void FactoryLoader<T>::closeFactory() {
+    delete mFactory;
+    mFactory = NULL;
+    mLibrary.reset();
+}
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/MediaCasService.cpp b/cas/aidl/default/MediaCasService.cpp
new file mode 100755
index 0000000..8285613
--- /dev/null
+++ b/cas/aidl/default/MediaCasService.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.cas-MediaCasService"
+
+#include <media/cas/CasAPI.h>
+#include <media/cas/DescramblerAPI.h>
+#include <utils/Log.h>
+
+#include "CasImpl.h"
+#include "DescramblerImpl.h"
+#include "MediaCasService.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+MediaCasService::MediaCasService()
+    : mCasLoader("createCasFactory"), mDescramblerLoader("createDescramblerFactory") {}
+
+MediaCasService::~MediaCasService() {}
+
+ScopedAStatus MediaCasService::enumeratePlugins(
+        vector<AidlCasPluginDescriptor>* aidlCasPluginDescriptors) {
+    ALOGV("%s", __FUNCTION__);
+
+    mCasLoader.enumeratePlugins(aidlCasPluginDescriptors);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MediaCasService::isSystemIdSupported(int32_t CA_system_id, bool* _aidl_return) {
+    ALOGV("isSystemIdSupported: CA_system_id=%d", CA_system_id);
+
+    *_aidl_return = mCasLoader.findFactoryForScheme(CA_system_id);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MediaCasService::createPlugin(int32_t CA_system_id,
+                                            const shared_ptr<ICasListener>& listener,
+                                            shared_ptr<ICas>* _aidl_return) {
+    ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
+    if (listener == NULL) ALOGV("%s: Listener is NULL", __FUNCTION__);
+
+    CasFactory* factory;
+    shared_ptr<SharedLibrary> library;
+    if (mCasLoader.findFactoryForScheme(CA_system_id, &library, &factory)) {
+        CasPlugin* plugin = NULL;
+        shared_ptr<CasImpl> casImpl = ::ndk::SharedRefBase::make<CasImpl>(listener);
+        if (factory->createPlugin(CA_system_id, casImpl.get(), &CasImpl::CallBackExt, &plugin) ==
+                    OK &&
+            plugin != NULL) {
+            casImpl->init(plugin);
+            *_aidl_return = casImpl;
+            casImpl->setPluginStatusUpdateCallback();
+        }
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MediaCasService::isDescramblerSupported(int32_t CA_system_id, bool* _aidl_return) {
+    ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
+
+    *_aidl_return = mDescramblerLoader.findFactoryForScheme(CA_system_id);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus MediaCasService::createDescrambler(int32_t CA_system_id,
+                                                 shared_ptr<IDescrambler>* _aidl_return) {
+    ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
+
+    DescramblerFactory* factory;
+    shared_ptr<SharedLibrary> library;
+    if (mDescramblerLoader.findFactoryForScheme(CA_system_id, &library, &factory)) {
+        DescramblerPlugin* plugin = NULL;
+        if (factory->createPlugin(CA_system_id, &plugin) == OK && plugin != NULL) {
+            *_aidl_return = ::ndk::SharedRefBase::make<DescramblerImpl>(plugin);
+        }
+    }
+
+    return ScopedAStatus::ok();
+}
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/MediaCasService.h b/cas/aidl/default/MediaCasService.h
new file mode 100755
index 0000000..9662313
--- /dev/null
+++ b/cas/aidl/default/MediaCasService.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <aidl/android/hardware/cas/BnMediaCasService.h>
+#include <media/cas/DescramblerAPI.h>
+
+#include "FactoryLoader.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+using namespace ::android;
+using namespace std;
+using ndk::ScopedAStatus;
+
+class MediaCasService : public BnMediaCasService {
+  public:
+    MediaCasService();
+
+    virtual ScopedAStatus enumeratePlugins(
+            vector<AidlCasPluginDescriptor>* aidlCasPluginDescriptors) override;
+
+    virtual ScopedAStatus isSystemIdSupported(int32_t in_CA_system_id, bool* _aidl_return) override;
+
+    virtual ScopedAStatus createPlugin(int32_t in_CA_system_id,
+                                       const shared_ptr<ICasListener>& in_listener,
+                                       shared_ptr<ICas>* _aidl_return) override;
+
+    virtual ScopedAStatus isDescramblerSupported(int32_t in_CA_system_id,
+                                                 bool* _aidl_return) override;
+
+    virtual ScopedAStatus createDescrambler(int32_t in_CA_system_id,
+                                            shared_ptr<IDescrambler>* _aidl_return) override;
+
+  private:
+    FactoryLoader<CasFactory> mCasLoader;
+    FactoryLoader<DescramblerFactory> mDescramblerLoader;
+
+    virtual ~MediaCasService();
+};
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/SharedLibrary.cpp b/cas/aidl/default/SharedLibrary.cpp
new file mode 100755
index 0000000..e79f383
--- /dev/null
+++ b/cas/aidl/default/SharedLibrary.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.cas-SharedLibrary"
+
+#include "SharedLibrary.h"
+#include <dlfcn.h>
+#include <utils/Log.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+SharedLibrary::SharedLibrary(const String8& path) {
+    mLibHandle = dlopen(path.string(), RTLD_NOW);
+}
+
+SharedLibrary::~SharedLibrary() {
+    if (mLibHandle != NULL) {
+        dlclose(mLibHandle);
+        mLibHandle = NULL;
+    }
+}
+
+bool SharedLibrary::operator!() const {
+    return mLibHandle == NULL;
+}
+
+void* SharedLibrary::lookup(const char* symbol) const {
+    if (!mLibHandle) {
+        return NULL;
+    }
+    // Clear last error before we load the symbol again,
+    // in case the caller didn't retrieve it.
+    (void)dlerror();
+    return dlsym(mLibHandle, symbol);
+}
+
+const char* SharedLibrary::lastError() const {
+    const char* error = dlerror();
+    return error ? error : "No errors or unknown error";
+}
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/SharedLibrary.h b/cas/aidl/default/SharedLibrary.h
new file mode 100755
index 0000000..d367866
--- /dev/null
+++ b/cas/aidl/default/SharedLibrary.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_interface_utils.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/String8.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+using namespace ::android;
+
+class SharedLibrary : public ndk::SharedRefBase {
+  public:
+    explicit SharedLibrary(const String8& path);
+    ~SharedLibrary();
+
+    bool operator!() const;
+    void* lookup(const char* symbol) const;
+    const char* lastError() const;
+
+  private:
+    void* mLibHandle;
+    DISALLOW_EVIL_CONSTRUCTORS(SharedLibrary);
+};
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/TypeConvert.cpp b/cas/aidl/default/TypeConvert.cpp
new file mode 100755
index 0000000..4f7005f
--- /dev/null
+++ b/cas/aidl/default/TypeConvert.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.cas-TypeConvert"
+
+#include <aidl/android/hardware/cas/Status.h>
+#include <utils/Log.h>
+
+#include "TypeConvert.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+ScopedAStatus toStatus(status_t legacyStatus) {
+    int status;
+    switch (legacyStatus) {
+        case OK:
+            return ndk::ScopedAStatus::ok();
+        case ERROR_CAS_NO_LICENSE:
+            status = Status::ERROR_CAS_NO_LICENSE;
+            break;
+        case ERROR_CAS_LICENSE_EXPIRED:
+            status = Status::ERROR_CAS_LICENSE_EXPIRED;
+            break;
+        case ERROR_CAS_SESSION_NOT_OPENED:
+            status = Status::ERROR_CAS_SESSION_NOT_OPENED;
+            break;
+        case ERROR_CAS_CANNOT_HANDLE:
+            status = Status::ERROR_CAS_CANNOT_HANDLE;
+            break;
+        case ERROR_CAS_TAMPER_DETECTED:
+            status = Status::ERROR_CAS_INVALID_STATE;
+            break;
+        case BAD_VALUE:
+            status = Status::BAD_VALUE;
+            break;
+        case ERROR_CAS_NOT_PROVISIONED:
+            status = Status::ERROR_CAS_NOT_PROVISIONED;
+            break;
+        case ERROR_CAS_RESOURCE_BUSY:
+            status = Status::ERROR_CAS_RESOURCE_BUSY;
+            break;
+        case ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION:
+            status = Status::ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION;
+            break;
+        case ERROR_CAS_DEVICE_REVOKED:
+            status = Status::ERROR_CAS_DEVICE_REVOKED;
+            break;
+        case ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED:
+            status = Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED;
+            break;
+        case ERROR_CAS_DECRYPT:
+            status = Status::ERROR_CAS_DECRYPT;
+            break;
+        case ERROR_CAS_NEED_ACTIVATION:
+            status = Status::ERROR_CAS_NEED_ACTIVATION;
+            break;
+        case ERROR_CAS_NEED_PAIRING:
+            status = Status::ERROR_CAS_NEED_PAIRING;
+            break;
+        case ERROR_CAS_NO_CARD:
+            status = Status::ERROR_CAS_NO_CARD;
+            break;
+        case ERROR_CAS_CARD_MUTE:
+            status = Status::ERROR_CAS_CARD_MUTE;
+            break;
+        case ERROR_CAS_CARD_INVALID:
+            status = Status::ERROR_CAS_CARD_INVALID;
+            break;
+        case ERROR_CAS_BLACKOUT:
+            status = Status::ERROR_CAS_BLACKOUT;
+            break;
+        default:
+            ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN", legacyStatus);
+            status = Status::ERROR_CAS_UNKNOWN;
+            break;
+    }
+    return ScopedAStatus::fromServiceSpecificError(status);
+}
+
+String8 sessionIdToString(const std::vector<uint8_t>& sessionId) {
+    String8 result;
+    for (auto it = sessionId.begin(); it != sessionId.end(); it++) {
+        result.appendFormat("%02x ", *it);
+    }
+    if (result.isEmpty()) {
+        result.append("(null)");
+    }
+    return result;
+}
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/TypeConvert.h b/cas/aidl/default/TypeConvert.h
new file mode 100755
index 0000000..ebfa286
--- /dev/null
+++ b/cas/aidl/default/TypeConvert.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_interface_utils.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/String8.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace cas {
+
+using namespace ::android;
+using ndk::ScopedAStatus;
+
+ScopedAStatus toStatus(status_t legacyStatus);
+
+String8 sessionIdToString(const std::vector<uint8_t>& sessionId);
+
+}  // namespace cas
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/cas/aidl/default/android.hardware.cas-service.xml b/cas/aidl/default/android.hardware.cas-service.xml
new file mode 100755
index 0000000..6389fe2
--- /dev/null
+++ b/cas/aidl/default/android.hardware.cas-service.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.cas</name>
+        <fqname>IMediaCasService/default</fqname>
+    </hal>
+</manifest>
diff --git a/cas/aidl/default/cas-default-lazy.rc b/cas/aidl/default/cas-default-lazy.rc
new file mode 100755
index 0000000..60b59ca
--- /dev/null
+++ b/cas/aidl/default/cas-default-lazy.rc
@@ -0,0 +1,9 @@
+service vendor.cas-default-lazy /vendor/bin/hw/android.hardware.cas-service.example-lazy
+    interface aidl android.hardware.cas.IMediaCasService/default
+    class hal
+    user media
+    group mediadrm drmrpc
+    ioprio rt 4
+    task_profiles ProcessCapacityHigh
+    oneshot
+    disabled
diff --git a/cas/aidl/default/cas-default.rc b/cas/aidl/default/cas-default.rc
new file mode 100755
index 0000000..e00b9c5
--- /dev/null
+++ b/cas/aidl/default/cas-default.rc
@@ -0,0 +1,7 @@
+service vendor.cas-default /vendor/bin/hw/android.hardware.cas-service.example
+    interface aidl android.hardware.cas.IMediaCasService/default
+    class hal
+    user media
+    group mediadrm drmrpc
+    ioprio rt 4
+    task_profiles ProcessCapacityHigh
diff --git a/cas/aidl/default/fuzzer.cpp b/cas/aidl/default/fuzzer.cpp
new file mode 100755
index 0000000..db1369e
--- /dev/null
+++ b/cas/aidl/default/fuzzer.cpp
@@ -0,0 +1,30 @@
+/*

+ * Copyright (C) 2022 The Android Open Source Project

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+#include <MediaCasService.h>

+#include <fuzzbinder/libbinder_ndk_driver.h>

+#include <fuzzer/FuzzedDataProvider.h>

+

+using aidl::android::hardware::cas::MediaCasService;

+using android::fuzzService;

+using ndk::SharedRefBase;

+

+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {

+    auto mediaCasServiceAidl = SharedRefBase::make<MediaCasService>();

+

+    fuzzService(mediaCasServiceAidl->asBinder().get(), FuzzedDataProvider(data, size));

+

+    return 0;

+}
\ No newline at end of file
diff --git a/cas/aidl/default/service.cpp b/cas/aidl/default/service.cpp
new file mode 100755
index 0000000..bed2f01
--- /dev/null
+++ b/cas/aidl/default/service.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef LAZY_SERVICE
+const bool kLazyService = true;
+#define LOG_TAG "android.hardware.cas-service.example-lazy"
+#else
+const bool kLazyService = false;
+#define LOG_TAG "android.hardware.cas-service.example"
+#endif
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "MediaCasService.h"
+
+using aidl::android::hardware::cas::MediaCasService;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(8);
+
+    // Setup hwbinder service
+    std::shared_ptr<MediaCasService> service = ::ndk::SharedRefBase::make<MediaCasService>();
+
+    const std::string instance = std::string() + MediaCasService::descriptor + "/default";
+    binder_status_t status;
+
+    if (kLazyService) {
+        status = AServiceManager_registerLazyService(service->asBinder().get(), instance.c_str());
+    } else {
+        status = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+    }
+    LOG_ALWAYS_FATAL_IF(status != STATUS_OK, "Error while registering cas service: %d", status);
+
+    ABinderProcess_joinThreadPool();
+    return 0;
+}
diff --git a/cas/aidl/vts/functional/Android.bp b/cas/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..295ae7c
--- /dev/null
+++ b/cas/aidl/vts/functional/Android.bp
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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_test {
+    name: "VtsHalCasAidlTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalCasAidlTargetTest.cpp"],
+    static_libs: [
+        "android.hardware.cas-V1-ndk",
+        "android.hardware.common-V2-ndk",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    disable_framework: true,
+}
diff --git a/cas/aidl/vts/functional/AndroidTest.xml b/cas/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..6e6af93
--- /dev/null
+++ b/cas/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs VtsHalCasAidlTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalCasAidlTargetTest->/data/local/tmp/VtsHalCasAidlTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalCasAidlTargetTest" />
+        <option name="native-test-timeout" value="30m" />
+    </test>
+</configuration>
diff --git a/cas/aidl/vts/functional/OWNERS b/cas/aidl/vts/functional/OWNERS
new file mode 100644
index 0000000..4c55752
--- /dev/null
+++ b/cas/aidl/vts/functional/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1344
+quxiangfang@google.com
+hgchen@google.com
diff --git a/cas/aidl/vts/functional/VtsHalCasAidlTargetTest.cpp b/cas/aidl/vts/functional/VtsHalCasAidlTargetTest.cpp
new file mode 100644
index 0000000..4c904a8
--- /dev/null
+++ b/cas/aidl/vts/functional/VtsHalCasAidlTargetTest.cpp
@@ -0,0 +1,840 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "mediacas_aidl_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/cas/BnCasListener.h>
+#include <aidl/android/hardware/cas/IMediaCasService.h>
+#include <aidl/android/hardware/cas/Status.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/ParcelFileDescriptor.h>
+#include <cutils/ashmem.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+
+#define CLEAR_KEY_SYSTEM_ID 0xF6D8
+#define INVALID_SYSTEM_ID 0
+#define WAIT_TIMEOUT 3000000000
+
+#define PROVISION_STR                                      \
+    "{                                                   " \
+    "  \"id\": 21140844,                                 " \
+    "  \"name\": \"Test Title\",                         " \
+    "  \"lowercase_organization_name\": \"Android\",     " \
+    "  \"asset_key\": {                                  " \
+    "  \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\"  " \
+    "  },                                                " \
+    "  \"cas_type\": 1,                                  " \
+    "  \"track_types\": [ ]                              " \
+    "}                                                   "
+
+using aidl::android::hardware::common::Ashmem;
+using android::Mutex;
+using namespace aidl::android::hardware::cas;
+using namespace ndk;
+using namespace std;
+using namespace testing;
+
+const uint8_t kEcmBinaryBuffer[] = {
+        0x00, 0x00, 0x01, 0xf0, 0x00, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x46, 0x00,
+        0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x27, 0x10, 0x02, 0x00,
+        0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0x0e, 0xe3, 0x91, 0xbc, 0xfd, 0x05, 0xb1, 0x60, 0x4f,
+        0x17, 0x82, 0xa4, 0x86, 0x9b, 0x23, 0x56, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+        0x27, 0x10, 0x02, 0x00, 0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0xd7, 0x43, 0x62, 0xf8, 0x1c,
+        0x62, 0x19, 0x05, 0xc7, 0x3a, 0x42, 0xcd, 0xfd, 0xd9, 0x13, 0x48,
+};
+
+const SubSample kSubSamples[] = {{162, 0}, {0, 184}, {0, 184}};
+
+const uint8_t kInBinaryBuffer[] = {
+        0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
+        0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
+        0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
+        0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
+        0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
+        0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
+        0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
+        0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
+        0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+        0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
+        0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x6e, 0x45, 0x21,
+        0x82, 0x38, 0xf0, 0x9d, 0x7d, 0x96, 0xe6, 0x94, 0xae, 0xe2, 0x87, 0x8f, 0x04, 0x49, 0xe5,
+        0xf6, 0x8c, 0x8b, 0x9a, 0x10, 0x18, 0xba, 0x94, 0xe9, 0x22, 0x31, 0x04, 0x7e, 0x60, 0x5b,
+        0xc4, 0x24, 0x00, 0x90, 0x62, 0x0d, 0xdc, 0x85, 0x74, 0x75, 0x78, 0xd0, 0x14, 0x08, 0xcb,
+        0x02, 0x1d, 0x7d, 0x9d, 0x34, 0xe8, 0x81, 0xb9, 0xf7, 0x09, 0x28, 0x79, 0x29, 0x8d, 0xe3,
+        0x14, 0xed, 0x5f, 0xca, 0xaf, 0xf4, 0x1c, 0x49, 0x15, 0xe1, 0x80, 0x29, 0x61, 0x76, 0x80,
+        0x43, 0xf8, 0x58, 0x53, 0x40, 0xd7, 0x31, 0x6d, 0x61, 0x81, 0x41, 0xe9, 0x77, 0x9f, 0x9c,
+        0xe1, 0x6d, 0xf2, 0xee, 0xd9, 0xc8, 0x67, 0xd2, 0x5f, 0x48, 0x73, 0xe3, 0x5c, 0xcd, 0xa7,
+        0x45, 0x58, 0xbb, 0xdd, 0x28, 0x1d, 0x68, 0xfc, 0xb4, 0xc6, 0xf6, 0x92, 0xf6, 0x30, 0x03,
+        0xaa, 0xe4, 0x32, 0xf6, 0x34, 0x51, 0x4b, 0x0f, 0x8c, 0xf9, 0xac, 0x98, 0x22, 0xfb, 0x49,
+        0xc8, 0xbf, 0xca, 0x8c, 0x80, 0x86, 0x5d, 0xd7, 0xa4, 0x52, 0xb1, 0xd9, 0xa6, 0x04, 0x4e,
+        0xb3, 0x2d, 0x1f, 0xb8, 0x35, 0xcc, 0x45, 0x6d, 0x9c, 0x20, 0xa7, 0xa4, 0x34, 0x59, 0x72,
+        0xe3, 0xae, 0xba, 0x49, 0xde, 0xd1, 0xaa, 0xee, 0x3d, 0x77, 0xfc, 0x5d, 0xc6, 0x1f, 0x9d,
+        0xac, 0xc2, 0x15, 0x66, 0xb8, 0xe1, 0x54, 0x4e, 0x74, 0x93, 0xdb, 0x9a, 0x24, 0x15, 0x6e,
+        0x20, 0xa3, 0x67, 0x3e, 0x5a, 0x24, 0x41, 0x5e, 0xb0, 0xe6, 0x35, 0x87, 0x1b, 0xc8, 0x7a,
+        0xf9, 0x77, 0x65, 0xe0, 0x01, 0xf2, 0x4c, 0xe4, 0x2b, 0xa9, 0x64, 0x96, 0x96, 0x0b, 0x46,
+        0xca, 0xea, 0x79, 0x0e, 0x78, 0xa3, 0x5f, 0x43, 0xfc, 0x47, 0x6a, 0x12, 0xfa, 0xc4, 0x33,
+        0x0e, 0x88, 0x1c, 0x19, 0x3a, 0x00, 0xc3, 0x4e, 0xb5, 0xd8, 0xfa, 0x8e, 0xf1, 0xbc, 0x3d,
+        0xb2, 0x7e, 0x50, 0x8d, 0x67, 0xc3, 0x6b, 0xed, 0xe2, 0xea, 0xa6, 0x1f, 0x25, 0x24, 0x7c,
+        0x94, 0x74, 0x50, 0x49, 0xe3, 0xc6, 0x58, 0x2e, 0xfd, 0x28, 0xb4, 0xc6, 0x73, 0xb1, 0x53,
+        0x74, 0x27, 0x94, 0x5c, 0xdf, 0x69, 0xb7, 0xa1, 0xd7, 0xf5, 0xd3, 0x8a, 0x2c, 0x2d, 0xb4,
+        0x5e, 0x8a, 0x16, 0x14, 0x54, 0x64, 0x6e, 0x00, 0x6b, 0x11, 0x59, 0x8a, 0x63, 0x38, 0x80,
+        0x76, 0xc3, 0xd5, 0x59, 0xf7, 0x3f, 0xd2, 0xfa, 0xa5, 0xca, 0x82, 0xff, 0x4a, 0x62, 0xf0,
+        0xe3, 0x42, 0xf9, 0x3b, 0x38, 0x27, 0x8a, 0x89, 0xaa, 0x50, 0x55, 0x4b, 0x29, 0xf1, 0x46,
+        0x7c, 0x75, 0xef, 0x65, 0xaf, 0x9b, 0x0d, 0x6d, 0xda, 0x25, 0x94, 0x14, 0xc1, 0x1b, 0xf0,
+        0xc5, 0x4c, 0x24, 0x0e, 0x65,
+};
+
+const uint8_t kOutRefBinaryBuffer[] = {
+        0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
+        0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
+        0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
+        0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
+        0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
+        0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
+        0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
+        0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
+        0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+        0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
+        0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x2d, 0x20,
+        0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d,
+        0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+        0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x3d,
+        0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68, 0x65,
+        0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
+        0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e,
+        0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20,
+        0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72,
+        0x6f, 0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
+        0x73, 0x3d, 0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71,
+        0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31,
+        0x2c, 0x31, 0x31, 0x20, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d,
+        0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66,
+        0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d,
+        0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68,
+        0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x64, 0x5f,
+        0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20,
+        0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69, 0x6e, 0x74, 0x65,
+        0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72, 0x61, 0x79,
+        0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
+        0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
+        0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68,
+        0x74, 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
+        0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20,
+        0x73, 0x63, 0x65, 0x6e, 0x65,
+};
+
+class MediaCasListener : public BnCasListener {
+  public:
+    virtual ScopedAStatus onEvent(int32_t event, int32_t arg,
+                                  const vector<uint8_t>& data) override {
+        Mutex::Autolock autoLock(mMsgLock);
+        mEvent = event;
+        mEventArg = arg;
+        mEventData = data;
+
+        mEventReceived = true;
+        mMsgCondition.signal();
+        return ScopedAStatus::ok();
+    }
+
+    virtual ScopedAStatus onSessionEvent(const vector<uint8_t>& sessionId, int32_t event,
+                                         int32_t arg, const vector<uint8_t>& data) override {
+        Mutex::Autolock autoLock(mMsgLock);
+        mSessionId = sessionId;
+        mEvent = event;
+        mEventArg = arg;
+        mEventData = data;
+
+        mEventReceived = true;
+        mMsgCondition.signal();
+        return ScopedAStatus::ok();
+    }
+
+    virtual ScopedAStatus onStatusUpdate(StatusEvent event, int32_t arg) override {
+        Mutex::Autolock autoLock(mMsgLock);
+        mStatusEvent = event;
+        mEventArg = arg;
+
+        mEventReceived = true;
+        mMsgCondition.signal();
+        return ScopedAStatus::ok();
+    }
+
+    void testEventEcho(shared_ptr<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
+                       vector<uint8_t>& eventData);
+
+    void testSessionEventEcho(shared_ptr<ICas>& mediaCas, const vector<uint8_t>& sessionId,
+                              int32_t& event, int32_t& eventArg, vector<uint8_t>& eventData);
+
+    void testStatusUpdate(shared_ptr<ICas>& mediaCas, vector<uint8_t>* sessionId,
+                          SessionIntent intent, ScramblingMode mode);
+
+  private:
+    int32_t mEvent = -1;
+    int32_t mEventArg = -1;
+    StatusEvent mStatusEvent;
+    bool mEventReceived = false;
+    vector<uint8_t> mEventData;
+    vector<uint8_t> mSessionId;
+    Mutex mMsgLock;
+    android::Condition mMsgCondition;
+};
+
+void MediaCasListener::testEventEcho(shared_ptr<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
+                                     vector<uint8_t>& eventData) {
+    mEventReceived = false;
+    auto returnStatus = mediaCas->sendEvent(event, eventArg, eventData);
+    EXPECT_TRUE(returnStatus.isOk());
+
+    Mutex::Autolock autoLock(mMsgLock);
+    while (!mEventReceived) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            ADD_FAILURE() << "event not received within timeout";
+            return;
+        }
+    }
+
+    EXPECT_EQ(mEvent, event);
+    EXPECT_EQ(mEventArg, eventArg);
+    EXPECT_TRUE(mEventData == eventData);
+}
+
+void MediaCasListener::testSessionEventEcho(shared_ptr<ICas>& mediaCas,
+                                            const vector<uint8_t>& sessionId, int32_t& event,
+                                            int32_t& eventArg, vector<uint8_t>& eventData) {
+    mEventReceived = false;
+    EXPECT_TRUE(mediaCas->sendSessionEvent(sessionId, event, eventArg, eventData).isOk());
+
+    Mutex::Autolock autoLock(mMsgLock);
+    while (!mEventReceived) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            ADD_FAILURE() << "event not received within timeout";
+            return;
+        }
+    }
+
+    EXPECT_TRUE(mSessionId == sessionId);
+    EXPECT_EQ(mEvent, event);
+    EXPECT_EQ(mEventArg, eventArg);
+    EXPECT_TRUE(mEventData == eventData);
+}
+
+void MediaCasListener::testStatusUpdate(shared_ptr<ICas>& mediaCas, vector<uint8_t>* sessionId,
+                                        SessionIntent intent, ScramblingMode mode) {
+    mEventReceived = false;
+    EXPECT_TRUE(mediaCas->openSession(intent, mode, sessionId).isOk());
+
+    Mutex::Autolock autoLock(mMsgLock);
+    while (!mEventReceived) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            ADD_FAILURE() << "event not received within timeout";
+            return;
+        }
+    }
+    EXPECT_EQ(mStatusEvent, static_cast<StatusEvent>(intent));
+    EXPECT_EQ(mEventArg, static_cast<int32_t>(mode));
+}
+
+class MediaCasAidlTest : public testing::TestWithParam<string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            mService = IMediaCasService::fromBinder(binder);
+        } else {
+            mService = nullptr;
+        }
+        ASSERT_NE(mService, nullptr);
+    }
+
+    shared_ptr<IMediaCasService> mService = nullptr;
+
+  protected:
+    static void description(const string& description) {
+        RecordProperty("description", description);
+    }
+
+    shared_ptr<ICas> mMediaCas;
+    shared_ptr<IDescrambler> mDescrambler;
+    shared_ptr<MediaCasListener> mCasListener;
+    typedef struct _OobInputTestParams {
+        const SubSample* subSamples;
+        int32_t numSubSamples;
+        int64_t imemSizeActual;
+        int64_t imemOffset;
+        int64_t imemSize;
+        int64_t srcOffset;
+        int64_t dstOffset;
+    } OobInputTestParams;
+
+    AssertionResult createCasPlugin(int32_t caSystemId);
+    AssertionResult openCasSessionDefault(vector<uint8_t>* sessionId);
+    AssertionResult openCasSession(vector<uint8_t>* sessionId, SessionIntent intent,
+                                   ScramblingMode mode);
+    AssertionResult descrambleTestInputBuffer(const shared_ptr<IDescrambler>& descrambler,
+                                              ScopedAStatus& descrambleStatus, uint8_t*& inMemory);
+    AssertionResult descrambleTestOobInput(const shared_ptr<IDescrambler>& descrambler,
+                                           ScopedAStatus& descrambleStatus,
+                                           const OobInputTestParams& params);
+};
+
+AssertionResult MediaCasAidlTest::createCasPlugin(int32_t caSystemId) {
+    bool isSystemIdSupported;
+    auto status = mService->isSystemIdSupported(caSystemId, &isSystemIdSupported);
+    bool skipDescrambler = false;
+    if (!status.isOk() || !isSystemIdSupported) {
+        return AssertionFailure();
+    }
+    bool isDescramblerSupported;
+    status = mService->isDescramblerSupported(caSystemId, &isDescramblerSupported);
+    if (!status.isOk() || !isDescramblerSupported) {
+        ALOGI("Skip Descrambler test since it's not required in cas.");
+        mDescrambler = nullptr;
+        skipDescrambler = true;
+    }
+
+    mCasListener = SharedRefBase::make<MediaCasListener>();
+    status = mService->createPlugin(caSystemId, mCasListener, &mMediaCas);
+    if (!status.isOk()) {
+        return AssertionFailure();
+    }
+    if (mMediaCas == nullptr) {
+        return AssertionFailure();
+    }
+
+    if (skipDescrambler) {
+        return AssertionSuccess();
+    }
+
+    status = mService->createDescrambler(caSystemId, &mDescrambler);
+    if (!status.isOk()) {
+        return AssertionFailure();
+    }
+
+    return AssertionResult(mDescrambler != nullptr);
+}
+
+AssertionResult MediaCasAidlTest::openCasSessionDefault(vector<uint8_t>* sessionId) {
+    return AssertionResult(mMediaCas->openSessionDefault(sessionId).isOk());
+}
+
+AssertionResult MediaCasAidlTest::openCasSession(vector<uint8_t>* sessionId, SessionIntent intent,
+                                                 ScramblingMode mode) {
+    return AssertionResult(mMediaCas->openSession(intent, mode, sessionId).isOk());
+}
+
+AssertionResult MediaCasAidlTest::descrambleTestInputBuffer(
+        const shared_ptr<IDescrambler>& descrambler, ScopedAStatus& descrambleStatus,
+        uint8_t*& sharedMemory) {
+    vector<SubSample> subSample(kSubSamples,
+                                kSubSamples + (sizeof(kSubSamples) / sizeof(SubSample)));
+
+    int size = sizeof(kInBinaryBuffer);
+    auto fd = ashmem_create_region("vts-cas", size);
+    if (fd < 0) {
+        ALOGE("ashmem_create_region failed");
+        return AssertionFailure();
+    }
+
+    sharedMemory =
+            static_cast<uint8_t*>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
+    if (sharedMemory == reinterpret_cast<uint8_t*>(MAP_FAILED)) {
+        ALOGE("mmap failed");
+        return AssertionFailure();
+    }
+
+    memcpy(sharedMemory, kInBinaryBuffer, size);
+
+    auto dupFd = dup(fd);
+
+    SharedBuffer srcBuffer = {.heapBase.fd = ScopedFileDescriptor(std::move(fd)),
+                              .heapBase.size = size,
+                              .offset = 0,
+                              .size = size};
+
+    SharedBuffer dupBuffer = {.heapBase.fd = ScopedFileDescriptor(dupFd),
+                              .heapBase.size = size,
+                              .offset = 0,
+                              .size = size};
+
+    DestinationBuffer dstBuffer;
+    dstBuffer.set<DestinationBuffer::nonsecureMemory>(std::move(dupBuffer));
+
+    int32_t outBytes;
+    descrambleStatus = descrambler->descramble(ScramblingControl::EVENKEY /*2*/, subSample,
+                                               srcBuffer, 0, dstBuffer, 0, &outBytes);
+    if (!descrambleStatus.isOk()) {
+        ALOGI("descramble failed, status=%d, outBytes=%u, error=%s", descrambleStatus.getStatus(),
+              outBytes, descrambleStatus.getDescription().c_str());
+    }
+    return AssertionResult(descrambleStatus.isOk());
+}
+
+AssertionResult MediaCasAidlTest::descrambleTestOobInput(
+        const shared_ptr<IDescrambler>& descrambler, ScopedAStatus& descrambleStatus,
+        const OobInputTestParams& params) {
+    vector<SubSample> subSample(params.subSamples, params.subSamples + params.numSubSamples);
+
+    auto fd = ashmem_create_region("vts-cas", params.imemSizeActual);
+    if (fd < 0) {
+        ALOGE("ashmem_create_region failed");
+        return AssertionFailure();
+    }
+
+    auto dupFd = dup(fd);
+
+    SharedBuffer srcBuffer = {.heapBase.fd = ScopedFileDescriptor(std::move(fd)),
+                              .heapBase.size = params.imemSizeActual,
+                              .offset = params.imemOffset,
+                              .size = params.imemSize};
+
+    SharedBuffer dupBuffer = {.heapBase.fd = ScopedFileDescriptor(dupFd),
+                              .heapBase.size = params.imemSizeActual,
+                              .offset = params.imemOffset,
+                              .size = params.imemSize};
+
+    DestinationBuffer dstBuffer;
+    dstBuffer.set<DestinationBuffer::nonsecureMemory>(std::move(dupBuffer));
+
+    int32_t outBytes;
+    descrambleStatus =
+            descrambler->descramble(ScramblingControl::EVENKEY /*2*/, subSample, srcBuffer,
+                                    params.srcOffset, dstBuffer, params.dstOffset, &outBytes);
+    if (!descrambleStatus.isOk()) {
+        ALOGI("descramble failed, status=%d, outBytes=%u, error=%s", descrambleStatus.getStatus(),
+              outBytes, descrambleStatus.getDescription().c_str());
+    }
+    return AssertionResult(descrambleStatus.isOk());
+}
+
+TEST_P(MediaCasAidlTest, EnumeratePlugins) {
+    description("Test enumerate plugins");
+
+    vector<AidlCasPluginDescriptor> descriptors;
+    EXPECT_TRUE(mService->enumeratePlugins(&descriptors).isOk());
+
+    if (descriptors.size() == 0) {
+        ALOGW("[   WARN   ] enumeratePlugins list empty");
+        return;
+    }
+
+    for (size_t i = 0; i < descriptors.size(); i++) {
+        int32_t caSystemId = descriptors[i].caSystemId;
+
+        ASSERT_TRUE(createCasPlugin(caSystemId));
+    }
+}
+
+TEST_P(MediaCasAidlTest, TestInvalidSystemIdFails) {
+    description("Test failure for invalid system ID");
+
+    bool isSystemIdSupported;
+    auto status = mService->isSystemIdSupported(INVALID_SYSTEM_ID, &isSystemIdSupported);
+
+    EXPECT_TRUE(status.isOk());
+    ASSERT_FALSE(isSystemIdSupported);
+
+    bool isDescramblerSupported;
+    status = mService->isDescramblerSupported(INVALID_SYSTEM_ID, &isDescramblerSupported);
+
+    EXPECT_TRUE(status.isOk());
+    ASSERT_FALSE(isDescramblerSupported);
+
+    shared_ptr<ICas> mediaCas;
+    shared_ptr<MediaCasListener> casListener = SharedRefBase::make<MediaCasListener>();
+    status = mService->createPlugin(INVALID_SYSTEM_ID, casListener, &mediaCas);
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(mediaCas, nullptr);
+
+    shared_ptr<IDescrambler> descrambler;
+    status = mService->createDescrambler(INVALID_SYSTEM_ID, &descrambler);
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(descrambler, nullptr);
+}
+
+TEST_P(MediaCasAidlTest, TestClearKeyPluginInstalled) {
+    description("Test if ClearKey plugin is installed");
+
+    vector<AidlCasPluginDescriptor> descriptors;
+    EXPECT_TRUE(mService->enumeratePlugins(&descriptors).isOk());
+
+    if (descriptors.size() == 0) {
+        ALOGW("[   WARN   ] enumeratePlugins list empty");
+    }
+
+    for (size_t i = 0; i < descriptors.size(); i++) {
+        int32_t caSystemId = descriptors[i].caSystemId;
+        if (CLEAR_KEY_SYSTEM_ID == caSystemId) {
+            return;
+        }
+    }
+
+    ADD_FAILURE() << "ClearKey plugin not installed";
+}
+
+TEST_P(MediaCasAidlTest, TestClearKeyDefaultSessionClosedAfterRelease) {
+    description("Test that all sessions are closed after a MediaCas object is released");
+
+    ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
+
+    EXPECT_TRUE(mMediaCas->provision(PROVISION_STR).isOk());
+
+    vector<uint8_t> sessionId;
+    ASSERT_TRUE(openCasSessionDefault(&sessionId));
+
+    vector<uint8_t> streamSessionId;
+    ASSERT_TRUE(openCasSessionDefault(&streamSessionId));
+
+    EXPECT_TRUE(mMediaCas->release().isOk());
+
+    if (mDescrambler != nullptr) {
+        auto status = mDescrambler->setMediaCasSession(sessionId);
+        EXPECT_FALSE(status.isOk());
+        EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, status.getServiceSpecificError());
+
+        status = mDescrambler->setMediaCasSession(streamSessionId);
+        EXPECT_FALSE(status.isOk());
+        EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, status.getServiceSpecificError());
+    }
+}
+
+TEST_P(MediaCasAidlTest, TestClearKeySessionClosedAfterRelease) {
+    description("Test that all sessions are closed after a MediaCas object is released");
+
+    ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
+
+    EXPECT_TRUE(mMediaCas->provision(PROVISION_STR).isOk());
+
+    SessionIntent intent = SessionIntent::LIVE;
+    ScramblingMode mode = ScramblingMode::DVB_CSA1;
+
+    vector<uint8_t> sessionId;
+    ASSERT_TRUE(openCasSession(&sessionId, intent, mode));
+
+    vector<uint8_t> streamSessionId;
+    ASSERT_TRUE(openCasSession(&streamSessionId, intent, mode));
+
+    EXPECT_TRUE(mMediaCas->release().isOk());
+
+    if (mDescrambler != nullptr) {
+        auto status = mDescrambler->setMediaCasSession(sessionId);
+        EXPECT_FALSE(status.isOk());
+        EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, status.getServiceSpecificError());
+
+        status = mDescrambler->setMediaCasSession(streamSessionId);
+        EXPECT_FALSE(status.isOk());
+        EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, status.getServiceSpecificError());
+    }
+}
+
+TEST_P(MediaCasAidlTest, TestClearKeyErrors) {
+    description("Test that invalid call sequences fail with expected error codes");
+
+    ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
+
+    /*
+     * Test MediaCas error codes
+     */
+    // Provision should fail with an invalid asset string
+    auto returnStatus = mMediaCas->provision("invalid asset string");
+    EXPECT_FALSE(returnStatus.isOk());
+    EXPECT_EQ(Status::ERROR_CAS_NO_LICENSE, returnStatus.getServiceSpecificError());
+
+    SessionIntent intent = SessionIntent::LIVE;
+    ScramblingMode mode = ScramblingMode::DVB_CSA1;
+
+    // Open a session, then close it so that it should become invalid
+    vector<uint8_t> invalidSessionId;
+    ASSERT_TRUE(openCasSession(&invalidSessionId, intent, mode));
+    EXPECT_TRUE(mMediaCas->closeSession(invalidSessionId).isOk());
+
+    // processEcm should fail with an invalid session id
+    vector<uint8_t> ecm(kEcmBinaryBuffer, kEcmBinaryBuffer + sizeof(kEcmBinaryBuffer));
+    returnStatus = mMediaCas->processEcm(invalidSessionId, ecm);
+    EXPECT_FALSE(returnStatus.isOk());
+    EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus.getServiceSpecificError());
+
+    vector<uint8_t> sessionId;
+    ASSERT_TRUE(openCasSession(&sessionId, intent, mode));
+
+    // processEcm should fail without provisioning
+    returnStatus = mMediaCas->processEcm(sessionId, ecm);
+    EXPECT_FALSE(returnStatus.isOk());
+    EXPECT_EQ(Status::ERROR_CAS_NOT_PROVISIONED, returnStatus.getServiceSpecificError());
+
+    EXPECT_TRUE(mMediaCas->provision(PROVISION_STR).isOk());
+
+    // processEcm should fail with ecm with bad descriptor count
+    ecm[17] = 0x03;  // change the descriptor count field to 3 (invalid)
+    returnStatus = mMediaCas->processEcm(sessionId, ecm);
+    EXPECT_FALSE(returnStatus.isOk());
+    EXPECT_EQ(Status::ERROR_CAS_UNKNOWN, returnStatus.getServiceSpecificError());
+
+    // processEcm should fail with ecm buffer that's too short
+    ecm.resize(8);
+    returnStatus = mMediaCas->processEcm(sessionId, ecm);
+    EXPECT_FALSE(returnStatus.isOk());
+    EXPECT_EQ(Status::BAD_VALUE, returnStatus.getServiceSpecificError());
+
+    if (mDescrambler != nullptr) {
+        /*
+         * Test MediaDescrambler error codes
+         */
+        // setMediaCasSession should fail with an invalid session id
+        returnStatus = mDescrambler->setMediaCasSession(invalidSessionId);
+        EXPECT_FALSE(returnStatus.isOk());
+        EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus.getServiceSpecificError());
+
+        // descramble should fail without a valid session
+        ScopedAStatus descrambleStatus = ScopedAStatus::ok();
+        uint8_t* sharedBuffer = nullptr;
+
+        ASSERT_FALSE(descrambleTestInputBuffer(mDescrambler, descrambleStatus, sharedBuffer));
+        EXPECT_EQ(Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED,
+                  descrambleStatus.getServiceSpecificError());
+
+        // Now set a valid session, should still fail because no valid ecm is processed
+        EXPECT_TRUE(mDescrambler->setMediaCasSession(sessionId).isOk());
+        ASSERT_FALSE(descrambleTestInputBuffer(mDescrambler, descrambleStatus, sharedBuffer));
+        EXPECT_EQ(Status::ERROR_CAS_DECRYPT, descrambleStatus.getServiceSpecificError());
+
+        // Verify that requiresSecureDecoderComponent handles empty mime
+        bool requiresSecureDecoderComponent = true;
+        EXPECT_TRUE(
+                mDescrambler->requiresSecureDecoderComponent("", &requiresSecureDecoderComponent)
+                        .isOk());
+        EXPECT_FALSE(requiresSecureDecoderComponent);
+
+        // Verify that requiresSecureDecoderComponent handles invalid mime
+        requiresSecureDecoderComponent = true;
+        EXPECT_TRUE(
+                mDescrambler->requiresSecureDecoderComponent("bad", &requiresSecureDecoderComponent)
+                        .isOk());
+        EXPECT_FALSE(requiresSecureDecoderComponent);
+    }
+}
+
+TEST_P(MediaCasAidlTest, TestClearKeyApisWithSession) {
+    description("Test that valid call sequences with SessionEvent send and receive");
+
+    ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
+
+    EXPECT_TRUE(mMediaCas->provision(PROVISION_STR).isOk());
+
+    vector<uint8_t> pvtData;
+    pvtData.resize(256);
+    EXPECT_TRUE(mMediaCas->setPrivateData(pvtData).isOk());
+
+    SessionIntent intent = SessionIntent::LIVE;
+    ScramblingMode mode = ScramblingMode::DVB_CSA1;
+
+    vector<uint8_t> sessionId;
+    ASSERT_TRUE(openCasSession(&sessionId, intent, mode));
+    EXPECT_TRUE(mMediaCas->setSessionPrivateData(sessionId, pvtData).isOk());
+
+    vector<uint8_t> streamSessionId;
+    ASSERT_TRUE(openCasSession(&streamSessionId, intent, mode));
+    EXPECT_TRUE(mMediaCas->setSessionPrivateData(streamSessionId, pvtData).isOk());
+
+    if (mDescrambler != nullptr) {
+        EXPECT_TRUE(mDescrambler->setMediaCasSession(sessionId).isOk());
+        EXPECT_TRUE(mDescrambler->setMediaCasSession(streamSessionId).isOk());
+    }
+
+    vector<uint8_t> nullPtrVector(0);
+    EXPECT_TRUE(mMediaCas->refreshEntitlements(3, nullPtrVector).isOk());
+
+    vector<uint8_t> refreshData{0, 1, 2, 3};
+    EXPECT_TRUE(mMediaCas->refreshEntitlements(10, refreshData).isOk());
+
+    int32_t eventID = 1;
+    int32_t eventArg = 2;
+    mCasListener->testEventEcho(mMediaCas, eventID, eventArg, nullPtrVector);
+    mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, nullPtrVector);
+
+    eventID = 3;
+    eventArg = 4;
+    vector<uint8_t> eventData{'e', 'v', 'e', 'n', 't', 'd', 'a', 't', 'a'};
+    mCasListener->testEventEcho(mMediaCas, eventID, eventArg, eventData);
+    mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, eventData);
+
+    mCasListener->testStatusUpdate(mMediaCas, &sessionId, intent, mode);
+
+    vector<uint8_t> clearKeyEmmData{'c', 'l', 'e', 'a', 'r', 'k', 'e', 'y', 'e', 'm', 'm'};
+    EXPECT_TRUE(mMediaCas->processEmm(clearKeyEmmData).isOk());
+
+    vector<uint8_t> ecm(kEcmBinaryBuffer, kEcmBinaryBuffer + sizeof(kEcmBinaryBuffer));
+    EXPECT_TRUE(mMediaCas->processEcm(sessionId, ecm).isOk());
+    EXPECT_TRUE(mMediaCas->processEcm(streamSessionId, ecm).isOk());
+
+    if (mDescrambler != nullptr) {
+        bool requiresSecureDecoderComponent = true;
+        EXPECT_TRUE(mDescrambler
+                            ->requiresSecureDecoderComponent("video/avc",
+                                                             &requiresSecureDecoderComponent)
+                            .isOk());
+        EXPECT_FALSE(requiresSecureDecoderComponent);
+
+        ScopedAStatus descrambleStatus = ScopedAStatus::ok();
+        uint8_t* sharedBuffer = nullptr;
+
+        ASSERT_TRUE(descrambleTestInputBuffer(mDescrambler, descrambleStatus, sharedBuffer));
+
+        int compareResult =
+                memcmp(static_cast<const void*>(sharedBuffer),
+                       static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
+        EXPECT_EQ(0, compareResult);
+
+        EXPECT_TRUE(mDescrambler->release().isOk());
+    }
+
+    EXPECT_TRUE(mMediaCas->release().isOk());
+}
+
+TEST_P(MediaCasAidlTest, TestClearKeyOobFails) {
+    description("Test that oob descramble request fails with expected error");
+
+    ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
+    EXPECT_TRUE(mMediaCas->provision(PROVISION_STR).isOk());
+
+    SessionIntent intent = SessionIntent::LIVE;
+    ScramblingMode mode = ScramblingMode::DVB_CSA1;
+
+    vector<uint8_t> sessionId;
+    ASSERT_TRUE(openCasSession(&sessionId, intent, mode));
+
+    if (mDescrambler != nullptr) {
+        EXPECT_TRUE(mDescrambler->setMediaCasSession(sessionId).isOk());
+    }
+
+    vector<uint8_t> ecm(kEcmBinaryBuffer, kEcmBinaryBuffer + sizeof(kEcmBinaryBuffer));
+    EXPECT_TRUE(mMediaCas->processEcm(sessionId, ecm).isOk());
+
+    if (mDescrambler != nullptr) {
+        ScopedAStatus descrambleStatus = ScopedAStatus::ok();
+
+        // test invalid src buffer offset
+        ASSERT_FALSE(
+                descrambleTestOobInput(mDescrambler, descrambleStatus,
+                                       {.subSamples = kSubSamples,
+                                        .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+                                        .imemSizeActual = sizeof(kInBinaryBuffer),
+                                        .imemOffset = 0xcccccc,
+                                        .imemSize = sizeof(kInBinaryBuffer),
+                                        .srcOffset = 0,
+                                        .dstOffset = 0}));
+        EXPECT_EQ(Status::BAD_VALUE, descrambleStatus.getServiceSpecificError());
+
+        // test invalid src buffer size
+        ASSERT_FALSE(
+                descrambleTestOobInput(mDescrambler, descrambleStatus,
+                                       {.subSamples = kSubSamples,
+                                        .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+                                        .imemSizeActual = sizeof(kInBinaryBuffer),
+                                        .imemOffset = 0,
+                                        .imemSize = 0xcccccc,
+                                        .srcOffset = 0,
+                                        .dstOffset = 0}));
+        EXPECT_EQ(Status::BAD_VALUE, descrambleStatus.getServiceSpecificError());
+
+        // test invalid src buffer size
+        ASSERT_FALSE(
+                descrambleTestOobInput(mDescrambler, descrambleStatus,
+                                       {.subSamples = kSubSamples,
+                                        .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+                                        .imemSizeActual = sizeof(kInBinaryBuffer),
+                                        .imemOffset = 1,
+                                        .imemSize = -1,
+                                        .srcOffset = 0,
+                                        .dstOffset = 0}));
+        EXPECT_EQ(Status::BAD_VALUE, descrambleStatus.getServiceSpecificError());
+
+        // test invalid srcOffset
+        ASSERT_FALSE(
+                descrambleTestOobInput(mDescrambler, descrambleStatus,
+                                       {.subSamples = kSubSamples,
+                                        .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+                                        .imemSizeActual = sizeof(kInBinaryBuffer),
+                                        .imemOffset = 0,
+                                        .imemSize = sizeof(kInBinaryBuffer),
+                                        .srcOffset = 0xcccccc,
+                                        .dstOffset = 0}));
+        EXPECT_EQ(Status::BAD_VALUE, descrambleStatus.getServiceSpecificError());
+
+        // test invalid dstOffset
+        ASSERT_FALSE(
+                descrambleTestOobInput(mDescrambler, descrambleStatus,
+                                       {.subSamples = kSubSamples,
+                                        .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+                                        .imemSizeActual = sizeof(kInBinaryBuffer),
+                                        .imemOffset = 0,
+                                        .imemSize = sizeof(kInBinaryBuffer),
+                                        .srcOffset = 0,
+                                        .dstOffset = 0xcccccc}));
+        EXPECT_EQ(Status::BAD_VALUE, descrambleStatus.getServiceSpecificError());
+
+        // test detection of oob subsample sizes
+        const SubSample invalidSubSamples1[] = {{162, 0}, {0, 184}, {0, 0xdddddd}};
+
+        ASSERT_FALSE(descrambleTestOobInput(
+                mDescrambler, descrambleStatus,
+                {.subSamples = invalidSubSamples1,
+                 .numSubSamples = sizeof(invalidSubSamples1) / sizeof(SubSample),
+                 .imemSizeActual = sizeof(kInBinaryBuffer),
+                 .imemOffset = 0,
+                 .imemSize = sizeof(kInBinaryBuffer),
+                 .srcOffset = 0,
+                 .dstOffset = 0}));
+        EXPECT_EQ(Status::BAD_VALUE, descrambleStatus.getServiceSpecificError());
+
+        // test detection of overflowing subsample sizes
+        const SubSample invalidSubSamples2[] = {{162, 0}, {0, 184}, {2, -1}};
+
+        ASSERT_FALSE(descrambleTestOobInput(
+                mDescrambler, descrambleStatus,
+                {.subSamples = invalidSubSamples2,
+                 .numSubSamples = sizeof(invalidSubSamples2) / sizeof(SubSample),
+                 .imemSizeActual = sizeof(kInBinaryBuffer),
+                 .imemOffset = 0,
+                 .imemSize = sizeof(kInBinaryBuffer),
+                 .srcOffset = 0,
+                 .dstOffset = 0}));
+        EXPECT_EQ(Status::BAD_VALUE, descrambleStatus.getServiceSpecificError());
+
+        EXPECT_TRUE(mDescrambler->release().isOk());
+    }
+    EXPECT_TRUE(mMediaCas->release().isOk());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaCasAidlTest);
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, MediaCasAidlTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IMediaCasService::descriptor)),
+        android::PrintInstanceNameToString);
+
+// Start thread pool to receive callbacks from AIDL service.
+int main(int argc, char** argv) {
+    InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
index 549d970..f3ea8e8 100644
--- a/common/aidl/Android.bp
+++ b/common/aidl/Android.bp
@@ -30,13 +30,17 @@
         ndk: {
             apex_available: [
                 "//apex_available:platform",
-                "com.android.bluetooth",
+                "com.android.btservices",
                 "com.android.media.swcodec",
                 "com.android.neuralnetworks",
             ],
             min_sdk_version: "29",
         },
+        rust: {
+            enabled: true,
+        }
     },
+    frozen: true,
     versions: [
         "1",
         "2",
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 6fd4200..3b022fc 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -24,18 +24,34 @@
     stability: "vintf",
     backend: {
         java: {
+            // There is no Java FMQ library, but we support the AIDL type
+            // to allow subsets of interfaces that include it to be used in Java
+            enabled: true,
             sdk_version: "module_current",
         },
         cpp: {
+            // FMQ will not be supported in the cpp backend because the parcelables
+            // are not stable enough for use in shared memory
             enabled: false,
         },
         ndk: {
             apex_available: [
                 "//apex_available:platform",
-                "com.android.bluetooth",
+                "com.android.btservices",
+                "com.android.media.swcodec",
             ],
             min_sdk_version: "29",
         },
+        rust: {
+            // FMQ is not supported in the rust backend
+            enabled: false,
+        },
     },
-    versions: ["1"],
+    frozen: true,
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.common-V2"],
+        },
+    ],
 }
diff --git a/common/support/NativeHandle.cpp b/common/support/NativeHandle.cpp
index 321d7a8..126ef2e 100644
--- a/common/support/NativeHandle.cpp
+++ b/common/support/NativeHandle.cpp
@@ -22,6 +22,13 @@
 
 using aidl::android::hardware::common::NativeHandle;
 
+/**
+ * Checks if a NativeHandle is null
+ */
+bool isAidlNativeHandleEmpty(const NativeHandle& handle) {
+    return handle.fds.empty() && handle.ints.empty();
+}
+
 static native_handle_t* fromAidl(const NativeHandle& handle, bool doDup) {
     native_handle_t* to = native_handle_create(handle.fds.size(), handle.ints.size());
     if (!to) return nullptr;
diff --git a/common/support/include/aidlcommonsupport/NativeHandle.h b/common/support/include/aidlcommonsupport/NativeHandle.h
index 10eecba..b5ea1dd 100644
--- a/common/support/include/aidlcommonsupport/NativeHandle.h
+++ b/common/support/include/aidlcommonsupport/NativeHandle.h
@@ -22,6 +22,11 @@
 namespace android {
 
 /**
+ * Checks if a NativeHandle is empty.
+ */
+bool isAidlNativeHandleEmpty(const aidl::android::hardware::common::NativeHandle& handle);
+
+/**
  * Creates a libcutils native handle from an AIDL native handle, but it does not
  * dup internally, so it will contain the same FDs as the handle itself. The
  * result should be deleted with native_handle_delete.
diff --git a/common/support/test.cpp b/common/support/test.cpp
index 2359277..9b79581 100644
--- a/common/support/test.cpp
+++ b/common/support/test.cpp
@@ -62,6 +62,7 @@
 
 TEST(ConvertNativeHandle, MakeFromAidlEmpty) {
     NativeHandle handle;
+    EXPECT_TRUE(isAidlNativeHandleEmpty(handle));
     native_handle_t* to = makeFromAidl(handle);
     checkEq(handle, to, false /*exceptFds*/);
     // no native_handle_close b/c fds are owned by NativeHandle
@@ -70,6 +71,7 @@
 
 TEST(ConvertNativeHandle, MakeFromAidl) {
     NativeHandle handle = makeTestAidlHandle();
+    EXPECT_FALSE(isAidlNativeHandleEmpty(handle));
     native_handle_t* to = makeFromAidl(handle);
     checkEq(handle, to, false /*exceptFds*/);
     // no native_handle_close b/c fds are owned by NativeHandle
@@ -106,6 +108,7 @@
 TEST(ConvertNativeHandle, MakeToAidlEmpty) {
     native_handle_t* handle = native_handle_create(0, 0);
     NativeHandle to = makeToAidl(handle);
+    EXPECT_TRUE(isAidlNativeHandleEmpty(to));
     checkEq(to, handle, false /*exceptFds*/);
     // no native_handle_close b/c fds are owned by NativeHandle now
     EXPECT_EQ(0, native_handle_delete(handle));
@@ -114,6 +117,7 @@
 TEST(ConvertNativeHandle, MakeToAidl) {
     native_handle_t* handle = makeTestLibcutilsHandle();
     NativeHandle to = makeToAidl(handle);
+    EXPECT_FALSE(isAidlNativeHandleEmpty(to));
     checkEq(to, handle, false /*exceptFds*/);
     // no native_handle_close b/c fds are owned by NativeHandle now
     EXPECT_EQ(0, native_handle_delete(handle));
@@ -122,6 +126,7 @@
 TEST(ConvertNativeHandle, DupToAidlEmpty) {
     native_handle_t* handle = native_handle_create(0, 0);
     NativeHandle to = dupToAidl(handle);
+    EXPECT_TRUE(isAidlNativeHandleEmpty(to));
     checkEq(to, handle, true /*exceptFds*/);
     EXPECT_EQ(0, native_handle_close(handle));
     EXPECT_EQ(0, native_handle_delete(handle));
@@ -130,6 +135,7 @@
 TEST(ConvertNativeHandle, DupToAidl) {
     native_handle_t* handle = makeTestLibcutilsHandle();
     NativeHandle to = dupToAidl(handle);
+    EXPECT_FALSE(isAidlNativeHandleEmpty(to));
     checkEq(to, handle, true /*exceptFds*/);
     EXPECT_EQ(0, native_handle_close(handle));
     EXPECT_EQ(0, native_handle_delete(handle));
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 422b37e..93b5380 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -22,26 +22,12 @@
 }
 
 vintf_compatibility_matrix {
-    name: "framework_compatibility_matrix.3.xml",
-    stem: "compatibility_matrix.3.xml",
-    srcs: [
-        "compatibility_matrix.3.xml",
-    ],
-    kernel_configs: [
-        "kernel_config_p_4.4",
-        "kernel_config_p_4.9",
-        "kernel_config_p_4.14",
-    ],
-}
-
-vintf_compatibility_matrix {
     name: "framework_compatibility_matrix.4.xml",
     stem: "compatibility_matrix.4.xml",
     srcs: [
         "compatibility_matrix.4.xml",
     ],
     kernel_configs: [
-        "kernel_config_q_4.9",
         "kernel_config_q_4.14",
         "kernel_config_q_4.19",
     ],
@@ -86,14 +72,13 @@
 }
 
 vintf_compatibility_matrix {
-    name: "framework_compatibility_matrix.current.xml",
-    enabled: false,
-    stem: "compatibility_matrix.current.xml",
+    name: "framework_compatibility_matrix.8.xml",
+    stem: "compatibility_matrix.8.xml",
     srcs: [
-        "compatibility_matrix.current.xml",
+        "compatibility_matrix.8.xml",
     ],
     kernel_configs: [
-        "kernel_config_current_5.10",
-        "kernel_config_current_5.15",
+        "kernel_config_u_5.15",
+        "kernel_config_u_6.1",
     ],
 }
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index d6a44d0..6e4c419 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -98,11 +98,11 @@
 endif # DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE
 
 my_system_matrix_deps := \
-    framework_compatibility_matrix.3.xml \
     framework_compatibility_matrix.4.xml \
     framework_compatibility_matrix.5.xml \
     framework_compatibility_matrix.6.xml \
     framework_compatibility_matrix.7.xml \
+    framework_compatibility_matrix.8.xml \
     framework_compatibility_matrix.device.xml \
 
 my_framework_matrix_deps += \
diff --git a/compatibility_matrices/compatibility_matrix.3.xml b/compatibility_matrices/compatibility_matrix.3.xml
deleted file mode 100644
index 0964c99..0000000
--- a/compatibility_matrices/compatibility_matrix.3.xml
+++ /dev/null
@@ -1,481 +0,0 @@
-<compatibility-matrix version="1.0" type="framework" level="3">
-    <hal format="hidl" optional="false">
-        <name>android.hardware.audio</name>
-        <version>4.0</version>
-        <interface>
-            <name>IDevicesFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.audio.effect</name>
-        <version>4.0</version>
-        <interface>
-            <name>IEffectsFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.authsecret</name>
-        <version>1.0</version>
-        <interface>
-            <name>IAuthSecret</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.automotive.audiocontrol</name>
-        <version>1.0</version>
-        <interface>
-            <name>IAudioControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.automotive.evs</name>
-        <version>1.0</version>
-        <interface>
-            <name>IEvsEnumerator</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.automotive.vehicle</name>
-        <version>2.0</version>
-        <interface>
-            <name>IVehicle</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.biometrics.fingerprint</name>
-        <version>2.1</version>
-        <interface>
-            <name>IBiometricsFingerprint</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.bluetooth</name>
-        <version>1.0</version>
-        <interface>
-            <name>IBluetoothHci</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.bluetooth.a2dp</name>
-        <version>1.0</version>
-        <interface>
-            <name>IBluetoothAudioOffload</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.boot</name>
-        <version>1.0</version>
-        <interface>
-            <name>IBootControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.broadcastradio</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IBroadcastRadioFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.broadcastradio</name>
-        <version>2.0</version>
-        <interface>
-            <name>IBroadcastRadio</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.camera.provider</name>
-        <version>2.4</version>
-        <interface>
-            <name>ICameraProvider</name>
-            <regex-instance>[^/]+/[0-9]+</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.cas</name>
-        <version>1.0</version>
-        <interface>
-            <name>IMediaCasService</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.configstore</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>ISurfaceFlingerConfigs</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.confirmationui</name>
-        <version>1.0</version>
-        <interface>
-            <name>IConfirmationUI</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.contexthub</name>
-        <version>1.0</version>
-        <interface>
-            <name>IContexthub</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.drm</name>
-        <version>1.0</version>
-        <interface>
-            <name>ICryptoFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-        <interface>
-            <name>IDrmFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.drm</name>
-        <version>1.1</version>
-        <interface>
-            <name>ICryptoFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-        <interface>
-            <name>IDrmFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.dumpstate</name>
-        <version>1.0</version>
-        <interface>
-            <name>IDumpstateDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.gatekeeper</name>
-        <version>1.0</version>
-        <interface>
-            <name>IGatekeeper</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.gnss</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IGnss</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
-         If the HIDL composer HAL exists, it must be at least version 2.0.
-         See DeviceManifestTest.GrallocHal -->
-    <hal format="hidl" optional="true">
-        <name>android.hardware.graphics.allocator</name>
-        <version>2.0</version>
-        <interface>
-            <name>IAllocator</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.graphics.composer</name>
-        <version>2.1-2</version>
-        <interface>
-            <name>IComposer</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.graphics.mapper</name>
-        <version>2.0-1</version>
-        <interface>
-            <name>IMapper</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <!-- Either the AIDL or the HIDL health HAL must exist on the device.
-         If the HIDL health HAL exists, it must be at least version 2.0.
-         See DeviceManifestTest.HealthHal -->
-    <hal format="hidl" optional="true">
-        <name>android.hardware.health</name>
-        <version>2.0</version>
-        <interface>
-            <name>IHealth</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.ir</name>
-        <version>1.0</version>
-        <interface>
-            <name>IConsumerIr</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.keymaster</name>
-        <version>3.0</version>
-        <version>4.0</version>
-        <interface>
-            <name>IKeymasterDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.keymaster</name>
-        <version>4.0</version>
-        <interface>
-            <name>IKeymasterDevice</name>
-            <instance>strongbox</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.light</name>
-        <version>2.0</version>
-        <interface>
-            <name>ILight</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.media.omx</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOmx</name>
-            <instance>default</instance>
-        </interface>
-        <interface>
-            <name>IOmxStore</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.memtrack</name>
-        <version>1.0</version>
-        <interface>
-            <name>IMemtrack</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.neuralnetworks</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IDevice</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.nfc</name>
-        <version>1.1</version>
-        <interface>
-            <name>INfc</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.oemlock</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOemLock</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.power</name>
-        <version>1.0-3</version>
-        <interface>
-            <name>IPower</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.radio</name>
-        <!-- ref: b/123249760. 1.3 added here since 1.3 and 1.4 introduced in Q -->
-        <version>1.0-3</version>
-        <interface>
-            <name>IRadio</name>
-            <instance>slot1</instance>
-            <instance>slot2</instance>
-            <instance>slot3</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.radio</name>
-        <version>1.0-2</version>
-        <interface>
-            <name>ISap</name>
-            <instance>slot1</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.radio.config</name>
-        <version>1.0</version>
-        <interface>
-            <name>IRadioConfig</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.renderscript</name>
-        <version>1.0</version>
-        <interface>
-            <name>IDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.secure_element</name>
-        <version>1.0</version>
-        <interface>
-            <name>ISecureElement</name>
-            <regex-instance>eSE[1-9][0-9]*</regex-instance>
-            <regex-instance>SIM[1-9][0-9]*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.sensors</name>
-        <version>1.0</version>
-        <interface>
-            <name>ISensors</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.soundtrigger</name>
-        <version>2.0-1</version>
-        <interface>
-            <name>ISoundTriggerHw</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tetheroffload.config</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOffloadConfig</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tetheroffload.control</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOffloadControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.thermal</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IThermal</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tv.cec</name>
-        <version>1.0</version>
-        <interface>
-            <name>IHdmiCec</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tv.input</name>
-        <version>1.0</version>
-        <interface>
-            <name>ITvInput</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.usb</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IUsb</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.usb.gadget</name>
-        <version>1.0</version>
-        <interface>
-            <name>IUsbGadget</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.vibrator</name>
-        <version>1.0-2</version>
-        <interface>
-            <name>IVibrator</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.vr</name>
-        <version>1.0</version>
-        <interface>
-            <name>IVr</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.weaver</name>
-        <version>1.0</version>
-        <interface>
-            <name>IWeaver</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.wifi</name>
-        <version>1.0-2</version>
-        <interface>
-            <name>IWifi</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.wifi.hostapd</name>
-        <version>1.0</version>
-        <interface>
-            <name>IHostapd</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.wifi.offload</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOffload</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.wifi.supplicant</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>ISupplicant</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-</compatibility-matrix>
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
index 8ef0b3a..b9fb3f4 100644
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ b/compatibility_matrices/compatibility_matrix.4.xml
@@ -7,7 +7,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.audio</name>
         <version>5.0</version>
         <interface>
@@ -15,7 +15,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.audio.effect</name>
         <version>5.0</version>
         <interface>
@@ -171,7 +171,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.gatekeeper</name>
         <version>1.0</version>
         <interface>
@@ -199,7 +199,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.graphics.composer</name>
         <version>2.1-3</version>
         <interface>
@@ -207,7 +207,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.graphics.mapper</name>
         <version>2.1</version>
         <version>3.0</version>
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index 12b85c7..b374c8c 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -7,7 +7,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.audio</name>
         <version>6.0</version>
         <interface>
@@ -15,7 +15,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.audio.effect</name>
         <version>6.0</version>
         <interface>
@@ -192,7 +192,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.gatekeeper</name>
         <version>1.0</version>
         <interface>
@@ -222,7 +222,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.graphics.composer</name>
         <version>2.1-4</version>
         <interface>
@@ -230,7 +230,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.graphics.mapper</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
         <version>2.1</version>
@@ -367,7 +367,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="false">
+    <hal format="aidl" optional="true">
         <name>android.hardware.power</name>
         <interface>
             <name>IPower</name>
diff --git a/compatibility_matrices/compatibility_matrix.6.xml b/compatibility_matrices/compatibility_matrix.6.xml
index e19d2dd..40ae655 100644
--- a/compatibility_matrices/compatibility_matrix.6.xml
+++ b/compatibility_matrices/compatibility_matrix.6.xml
@@ -7,7 +7,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.audio</name>
         <version>6.0</version>
         <version>7.0</version>
@@ -16,7 +16,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.audio.effect</name>
         <version>6.0</version>
         <version>7.0</version>
@@ -215,7 +215,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.gatekeeper</name>
         <version>1.0</version>
         <interface>
@@ -252,7 +252,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.graphics.composer</name>
         <version>2.1-4</version>
         <interface>
@@ -260,7 +260,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.graphics.mapper</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
         <version>2.1</version>
@@ -423,7 +423,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="false">
+    <hal format="aidl" optional="true">
         <name>android.hardware.power</name>
         <version>1-2</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.7.xml b/compatibility_matrices/compatibility_matrix.7.xml
index 18a1733..bc5a5c4 100644
--- a/compatibility_matrices/compatibility_matrix.7.xml
+++ b/compatibility_matrices/compatibility_matrix.7.xml
@@ -7,7 +7,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.audio</name>
         <version>6.0</version>
         <version>7.0-1</version>
@@ -16,7 +16,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.audio.effect</name>
         <version>6.0</version>
         <version>7.0</version>
@@ -238,7 +238,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.gatekeeper</name>
         <version>1.0</version>
         <interface>
@@ -316,7 +316,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.graphics.mapper</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
         <version>2.1</version>
@@ -327,7 +327,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="false">
+    <hal format="aidl" optional="true">
         <name>android.hardware.health</name>
         <version>1</version>
         <interface>
@@ -400,14 +400,6 @@
         </interface>
     </hal>
     <hal format="aidl" optional="true">
-        <name>android.hardware.security.dice</name>
-        <version>1</version>
-        <interface>
-            <name>IDiceDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
         <name>android.hardware.security.keymint</name>
         <version>1-2</version>
         <interface>
@@ -501,7 +493,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="aidl" optional="false">
+    <hal format="aidl" optional="true">
         <name>android.hardware.power</name>
         <version>2-3</version>
         <interface>
@@ -682,7 +674,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <hal format="hidl" optional="true">
         <name>android.hardware.thermal</name>
         <version>2.0</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml
new file mode 100644
index 0000000..5ea075a
--- /dev/null
+++ b/compatibility_matrices/compatibility_matrix.8.xml
@@ -0,0 +1,732 @@
+<compatibility-matrix version="1.0" type="framework" level="8">
+    <hal format="hidl" optional="true">
+        <name>android.hardware.audio</name>
+        <version>6.0</version>
+        <version>7.0-1</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.audio.effect</name>
+        <version>6.0</version>
+        <version>7.0</version>
+        <interface>
+            <name>IEffectsFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.audio.core</name>
+        <version>1</version>
+        <interface>
+            <name>IModule</name>
+            <instance>default</instance>
+            <instance>a2dp</instance>
+            <instance>bluetooth</instance>
+            <instance>hearing_aid</instance>
+            <instance>msd</instance>
+            <instance>r_submix</instance>
+            <instance>stub</instance>
+            <instance>usb</instance>
+        </interface>
+        <interface>
+            <name>IConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.audio.effect</name>
+        <version>1</version>
+        <interface>
+            <name>IFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.audio.sounddose</name>
+        <version>1</version>
+        <interface>
+            <name>ISoundDoseFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+         <name>android.hardware.authsecret</name>
+         <version>1</version>
+         <interface>
+             <name>IAuthSecret</name>
+             <instance>default</instance>
+         </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.audiocontrol</name>
+        <version>2-3</version>
+        <interface>
+            <name>IAudioControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.can</name>
+        <version>1</version>
+        <interface>
+            <name>ICanController</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.evs</name>
+        <version>1-2</version>
+        <interface>
+            <name>IEvsEnumerator</name>
+            <regex-instance>[a-z]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.occupant_awareness</name>
+        <version>1</version>
+        <interface>
+            <name>IOccupantAwareness</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.vehicle</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVehicle</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.remoteaccess</name>
+        <interface>
+            <name>IRemoteAccess</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.ivn</name>
+        <interface>
+            <name>IIvnAndroidDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.face</name>
+        <version>3</version>
+        <interface>
+            <name>IFace</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <version>3</version>
+        <interface>
+            <name>IFingerprint</name>
+            <instance>default</instance>
+            <instance>virtual</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IBluetoothHci</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <interface>
+            <name>IBluetoothHci</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth.audio</name>
+        <version>3</version>
+        <interface>
+            <name>IBluetoothAudioProviderFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.boot</name>
+        <interface>
+            <name>IBootControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <interface>
+            <name>IBroadcastRadio</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true" updatable-via-apex="true">
+        <name>android.hardware.camera.provider</name>
+        <version>1-2</version>
+        <interface>
+            <name>ICameraProvider</name>
+            <regex-instance>[^/]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.cas</name>
+        <interface>
+            <name>IMediaCasService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.confirmationui</name>
+        <version>1</version>
+        <interface>
+            <name>IConfirmationUI</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.contexthub</name>
+        <version>2</version>
+        <interface>
+            <name>IContextHub</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true" updatable-via-apex="true">
+        <name>android.hardware.drm</name>
+        <version>1</version>
+        <interface>
+            <name>IDrmFactory</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.dumpstate</name>
+        <interface>
+            <name>IDumpstateDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gatekeeper</name>
+        <version>1</version>
+        <interface>
+            <name>IGatekeeper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss</name>
+        <version>2-3</version>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss.visibility_control</name>
+        <version>1</version>
+        <interface>
+            <name>IGnssVisibilityControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss.measurement_corrections</name>
+        <version>1</version>
+        <interface>
+            <name>IMeasurementCorrectionsInterface</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.graphics.allocator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IAllocator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.graphics.composer3</name>
+        <version>2</version>
+        <interface>
+            <name>IComposer</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <!-- Either the native or the HIDL mapper HAL must exist on the device -->
+    <hal format="hidl" optional="true">
+        <name>android.hardware.graphics.mapper</name>
+        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
+        <version>2.1</version>
+        <version>3.0</version>
+        <version>4.0</version>
+        <interface>
+            <name>IMapper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.health</name>
+        <version>1-2</version>
+        <interface>
+            <name>IHealth</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.health.storage</name>
+        <version>1</version>
+        <interface>
+            <name>IStorage</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.identity</name>
+        <version>1-5</version>
+        <interface>
+            <name>IIdentityCredentialStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.net.nlinterceptor</name>
+        <interface>
+            <name>IInterceptor</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.oemlock</name>
+        <version>1</version>
+        <interface>
+            <name>IOemLock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.ir</name>
+        <version>1</version>
+        <interface>
+            <name>IConsumerIr</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.input.processor</name>
+        <version>1</version>
+        <interface>
+            <name>IInputProcessor</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-3</version>
+        <interface>
+            <name>IKeyMintDevice</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-3</version>
+        <interface>
+            <name>IRemotelyProvisionedComponent</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+            <instance>widevine</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.light</name>
+        <version>2</version>
+        <interface>
+            <name>ILights</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.media.c2</name>
+        <version>1.0-2</version>
+        <interface>
+            <name>IComponentStore</name>
+            <regex-instance>default[0-9]*</regex-instance>
+            <regex-instance>vendor[0-9]*_software</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.media.omx</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOmx</name>
+            <instance>default</instance>
+        </interface>
+        <interface>
+            <name>IOmxStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.memtrack</name>
+        <version>1</version>
+        <interface>
+            <name>IMemtrack</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.neuralnetworks</name>
+        <version>1-4</version>
+        <interface>
+            <name>IDevice</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.nfc</name>
+        <interface>
+            <name>INfc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.power</name>
+        <version>4</version>
+        <interface>
+            <name>IPower</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.power.stats</name>
+        <version>2</version>
+        <interface>
+            <name>IPowerStats</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.config</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.data</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioData</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.messaging</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioMessaging</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.modem</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioModem</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.network</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioNetwork</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.sim</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioSim</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.sap</name>
+        <version>1</version>
+        <interface>
+            <name>ISap</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.voice</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioVoice</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.ims</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioIms</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.ims.media</name>
+        <version>1</version>
+        <interface>
+            <name>IImsMedia</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.renderscript</name>
+        <version>1.0</version>
+        <interface>
+            <name>IDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.rebootescrow</name>
+        <version>1</version>
+        <interface>
+            <name>IRebootEscrow</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.secure_element</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureElement</name>
+            <regex-instance>eSE[1-9][0-9]*</regex-instance>
+            <regex-instance>SIM[1-9][0-9]*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.secureclock</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureClock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.sharedsecret</name>
+        <version>1</version>
+        <interface>
+            <name>ISharedSecret</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.sensors</name>
+        <version>2</version>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.soundtrigger</name>
+        <version>2.3</version>
+        <interface>
+            <name>ISoundTriggerHw</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+         <name>android.hardware.soundtrigger3</name>
+         <version>1</version>
+         <interface>
+             <name>ISoundTriggerHw</name>
+             <instance>default</instance>
+         </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.config</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOffloadConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.control</name>
+        <version>1.1</version>
+        <interface>
+            <name>IOffloadControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tetheroffload</name>
+        <version>1</version>
+        <interface>
+            <name>IOffload</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.thermal</name>
+        <version>1</version>
+        <interface>
+            <name>IThermal</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.hdmi.cec</name>
+        <version>1</version>
+        <interface>
+            <name>IHdmiCec</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.hdmi.earc</name>
+        <version>1</version>
+        <interface>
+            <name>IEArc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.hdmi.connection</name>
+        <version>1</version>
+        <interface>
+            <name>IHdmiConnection</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.tuner</name>
+        <version>1-2</version>
+        <interface>
+            <name>ITuner</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.input</name>
+        <version>1</version>
+        <interface>
+            <name>ITvInput</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.usb</name>
+        <version>1-2</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.usb.gadget</name>
+        <interface>
+            <name>IUsbGadget</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibrator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibratorManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.weaver</name>
+        <version>2</version>
+        <interface>
+            <name>IWeaver</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true" updatable-via-apex="true">
+        <name>android.hardware.wifi</name>
+        <version>1</version>
+        <interface>
+            <name>IWifi</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.uwb</name>
+        <version>1</version>
+        <interface>
+            <name>IUwb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.hostapd</name>
+        <version>1</version>
+        <interface>
+            <name>IHostapd</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.supplicant</name>
+        <version>2</version>
+        <interface>
+            <name>ISupplicant</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <!-- Either the native or the HIDL mapper HAL must exist on the device -->
+    <hal format="native" optional="true">
+        <name>mapper</name>
+        <version>5.0</version>
+        <interface>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+</compatibility-matrix>
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
new file mode 100644
index 0000000..188746d
--- /dev/null
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -0,0 +1,730 @@
+<!-- WARNING: This file is unused in the Android 14 branch. -->
+<compatibility-matrix version="1.0" type="framework" level="9">
+    <hal format="hidl" optional="true">
+        <name>android.hardware.audio</name>
+        <version>6.0</version>
+        <version>7.0-1</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.audio.effect</name>
+        <version>6.0</version>
+        <version>7.0</version>
+        <interface>
+            <name>IEffectsFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.audio.core</name>
+        <version>1</version>
+        <interface>
+            <name>IModule</name>
+            <instance>default</instance>
+            <instance>a2dp</instance>
+            <instance>bluetooth</instance>
+            <instance>hearing_aid</instance>
+            <instance>msd</instance>
+            <instance>r_submix</instance>
+            <instance>stub</instance>
+            <instance>usb</instance>
+        </interface>
+        <interface>
+            <name>IConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.audio.effect</name>
+        <version>1</version>
+        <interface>
+            <name>IFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.audio.sounddose</name>
+        <version>1</version>
+        <interface>
+            <name>ISoundDoseFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+         <name>android.hardware.authsecret</name>
+         <version>1</version>
+         <interface>
+             <name>IAuthSecret</name>
+             <instance>default</instance>
+         </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.audiocontrol</name>
+        <version>2-3</version>
+        <interface>
+            <name>IAudioControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.can</name>
+        <version>1</version>
+        <interface>
+            <name>ICanController</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.evs</name>
+        <version>1-2</version>
+        <interface>
+            <name>IEvsEnumerator</name>
+            <regex-instance>[a-z]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.occupant_awareness</name>
+        <version>1</version>
+        <interface>
+            <name>IOccupantAwareness</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.vehicle</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVehicle</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.remoteaccess</name>
+        <interface>
+            <name>IRemoteAccess</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.ivn</name>
+        <interface>
+            <name>IIvnAndroidDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.face</name>
+        <version>3</version>
+        <interface>
+            <name>IFace</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <version>3</version>
+        <interface>
+            <name>IFingerprint</name>
+            <instance>default</instance>
+            <instance>virtual</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IBluetoothHci</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <interface>
+            <name>IBluetoothHci</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth.audio</name>
+        <version>3</version>
+        <interface>
+            <name>IBluetoothAudioProviderFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.boot</name>
+        <interface>
+            <name>IBootControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <interface>
+            <name>IBroadcastRadio</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true" updatable-via-apex="true">
+        <name>android.hardware.camera.provider</name>
+        <version>1-2</version>
+        <interface>
+            <name>ICameraProvider</name>
+            <regex-instance>[^/]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.cas</name>
+        <interface>
+            <name>IMediaCasService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.confirmationui</name>
+        <version>1</version>
+        <interface>
+            <name>IConfirmationUI</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.contexthub</name>
+        <version>2</version>
+        <interface>
+            <name>IContextHub</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true" updatable-via-apex="true">
+        <name>android.hardware.drm</name>
+        <version>1</version>
+        <interface>
+            <name>IDrmFactory</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.dumpstate</name>
+        <interface>
+            <name>IDumpstateDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gatekeeper</name>
+        <version>1</version>
+        <interface>
+            <name>IGatekeeper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss</name>
+        <version>2-3</version>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss.visibility_control</name>
+        <version>1</version>
+        <interface>
+            <name>IGnssVisibilityControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss.measurement_corrections</name>
+        <version>1</version>
+        <interface>
+            <name>IMeasurementCorrectionsInterface</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.graphics.allocator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IAllocator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.graphics.composer3</name>
+        <version>2</version>
+        <interface>
+            <name>IComposer</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <!-- Either the native or the HIDL mapper HAL must exist on the device -->
+    <hal format="hidl" optional="true">
+        <name>android.hardware.graphics.mapper</name>
+        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
+        <version>2.1</version>
+        <version>3.0</version>
+        <version>4.0</version>
+        <interface>
+            <name>IMapper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.health</name>
+        <version>1-2</version>
+        <interface>
+            <name>IHealth</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.health.storage</name>
+        <version>1</version>
+        <interface>
+            <name>IStorage</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.identity</name>
+        <version>1-5</version>
+        <interface>
+            <name>IIdentityCredentialStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.net.nlinterceptor</name>
+        <interface>
+            <name>IInterceptor</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.oemlock</name>
+        <version>1</version>
+        <interface>
+            <name>IOemLock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.ir</name>
+        <version>1</version>
+        <interface>
+            <name>IConsumerIr</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.input.processor</name>
+        <version>1</version>
+        <interface>
+            <name>IInputProcessor</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-3</version>
+        <interface>
+            <name>IKeyMintDevice</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-3</version>
+        <interface>
+            <name>IRemotelyProvisionedComponent</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.light</name>
+        <version>2</version>
+        <interface>
+            <name>ILights</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.media.c2</name>
+        <version>1.0-2</version>
+        <interface>
+            <name>IComponentStore</name>
+            <regex-instance>default[0-9]*</regex-instance>
+            <regex-instance>vendor[0-9]*_software</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.memtrack</name>
+        <version>1</version>
+        <interface>
+            <name>IMemtrack</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.neuralnetworks</name>
+        <version>1-4</version>
+        <interface>
+            <name>IDevice</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.nfc</name>
+        <interface>
+            <name>INfc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.power</name>
+        <version>4</version>
+        <interface>
+            <name>IPower</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.power.stats</name>
+        <version>2</version>
+        <interface>
+            <name>IPowerStats</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.config</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.data</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioData</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.messaging</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioMessaging</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.modem</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioModem</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.network</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioNetwork</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.sim</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioSim</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.sap</name>
+        <version>1</version>
+        <interface>
+            <name>ISap</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.voice</name>
+        <version>2</version>
+        <interface>
+            <name>IRadioVoice</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.ims</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioIms</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.satellite</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioSatellite</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.ims.media</name>
+        <version>1</version>
+        <interface>
+            <name>IImsMedia</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.renderscript</name>
+        <version>1.0</version>
+        <interface>
+            <name>IDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.rebootescrow</name>
+        <version>1</version>
+        <interface>
+            <name>IRebootEscrow</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.secure_element</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureElement</name>
+            <regex-instance>eSE[1-9][0-9]*</regex-instance>
+            <regex-instance>SIM[1-9][0-9]*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.secureclock</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureClock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.sharedsecret</name>
+        <version>1</version>
+        <interface>
+            <name>ISharedSecret</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.sensors</name>
+        <version>2</version>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.soundtrigger</name>
+        <version>2.3</version>
+        <interface>
+            <name>ISoundTriggerHw</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+         <name>android.hardware.soundtrigger3</name>
+         <version>1</version>
+         <interface>
+             <name>ISoundTriggerHw</name>
+             <instance>default</instance>
+         </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.config</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOffloadConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.control</name>
+        <version>1.1</version>
+        <interface>
+            <name>IOffloadControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tetheroffload</name>
+        <version>1</version>
+        <interface>
+            <name>IOffload</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.thermal</name>
+        <version>1</version>
+        <interface>
+            <name>IThermal</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.hdmi.cec</name>
+        <version>1</version>
+        <interface>
+            <name>IHdmiCec</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.hdmi.earc</name>
+        <version>1</version>
+        <interface>
+            <name>IEArc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.hdmi.connection</name>
+        <version>1</version>
+        <interface>
+            <name>IHdmiConnection</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.tuner</name>
+        <version>1-2</version>
+        <interface>
+            <name>ITuner</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.input</name>
+        <version>1</version>
+        <interface>
+            <name>ITvInput</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.usb</name>
+        <version>1-2</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.usb.gadget</name>
+        <interface>
+            <name>IUsbGadget</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibrator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibratorManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.weaver</name>
+        <version>2</version>
+        <interface>
+            <name>IWeaver</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true" updatable-via-apex="true">
+        <name>android.hardware.wifi</name>
+        <version>1</version>
+        <interface>
+            <name>IWifi</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.uwb</name>
+        <version>1</version>
+        <interface>
+            <name>IUwb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.hostapd</name>
+        <version>1</version>
+        <interface>
+            <name>IHostapd</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.supplicant</name>
+        <version>2</version>
+        <interface>
+            <name>ISupplicant</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <!-- Either the native or the HIDL mapper HAL must exist on the device -->
+    <hal format="native" optional="true">
+        <name>mapper</name>
+        <version>5.0</version>
+        <interface>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+</compatibility-matrix>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
deleted file mode 100644
index 886f7f5..0000000
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ /dev/null
@@ -1,815 +0,0 @@
-<compatibility-matrix version="1.0" type="framework" level="8">
-    <hal format="hidl" optional="true">
-        <name>android.hardware.atrace</name>
-        <version>1.0</version>
-        <interface>
-            <name>IAtraceDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.audio</name>
-        <version>6.0</version>
-        <version>7.0-1</version>
-        <interface>
-            <name>IDevicesFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.audio.effect</name>
-        <version>6.0</version>
-        <version>7.0</version>
-        <interface>
-            <name>IEffectsFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-         <name>android.hardware.authsecret</name>
-         <version>1</version>
-         <interface>
-             <name>IAuthSecret</name>
-             <instance>default</instance>
-         </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.authsecret</name>
-        <version>1.0</version>
-        <interface>
-            <name>IAuthSecret</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.automotive.audiocontrol</name>
-        <interface>
-            <name>IAudioControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.automotive.can</name>
-        <version>1.0</version>
-        <interface>
-            <name>ICanBus</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-        <interface>
-            <name>ICanController</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.automotive.evs</name>
-        <interface>
-            <name>IEvsEnumerator</name>
-            <instance>default</instance>
-            <regex-instance>[a-z]+/[0-9]+</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.automotive.evs</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IEvsEnumerator</name>
-            <instance>default</instance>
-            <regex-instance>[a-z]+/[0-9]+</regex-instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.automotive.occupant_awareness</name>
-        <version>1</version>
-        <interface>
-            <name>IOccupantAwareness</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.automotive.vehicle</name>
-        <interface>
-            <name>IVehicle</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.automotive.vehicle</name>
-        <version>2.0</version>
-        <interface>
-            <name>IVehicle</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.biometrics.face</name>
-        <version>1.0</version>
-        <interface>
-            <name>IBiometricsFace</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.biometrics.face</name>
-        <version>2</version>
-        <interface>
-            <name>IFace</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.biometrics.fingerprint</name>
-        <version>2.1-3</version>
-        <interface>
-            <name>IBiometricsFingerprint</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.biometrics.fingerprint</name>
-        <version>2</version>
-        <interface>
-            <name>IFingerprint</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.bluetooth</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IBluetoothHci</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.bluetooth.audio</name>
-        <version>2</version>
-        <interface>
-            <name>IBluetoothAudioProviderFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.boot</name>
-        <version>1.2</version>
-        <interface>
-            <name>IBootControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.broadcastradio</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IBroadcastRadioFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.broadcastradio</name>
-        <version>2.0</version>
-        <interface>
-            <name>IBroadcastRadio</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.camera.provider</name>
-        <version>2.4-7</version>
-        <interface>
-            <name>ICameraProvider</name>
-            <regex-instance>[^/]+/[0-9]+</regex-instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.camera.provider</name>
-        <version>1</version>
-        <interface>
-            <name>ICameraProvider</name>
-            <regex-instance>[^/]+/[0-9]+</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.cas</name>
-        <version>1.1-2</version>
-        <interface>
-            <name>IMediaCasService</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.confirmationui</name>
-        <version>1.0</version>
-        <interface>
-            <name>IConfirmationUI</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.contexthub</name>
-        <interface>
-            <name>IContextHub</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.drm</name>
-        <version>1</version>
-        <interface>
-            <name>IDrmFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.drm</name>
-        <version>1.3-4</version>
-        <interface>
-            <name>ICryptoFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-        <interface>
-            <name>IDrmFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.dumpstate</name>
-        <interface>
-            <name>IDumpstateDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.gatekeeper</name>
-        <version>1.0</version>
-        <interface>
-            <name>IGatekeeper</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.gnss</name>
-        <version>2.0-1</version>
-        <interface>
-            <name>IGnss</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.gnss</name>
-        <version>2</version>
-        <interface>
-            <name>IGnss</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.gnss.visibility_control</name>
-        <version>1</version>
-        <interface>
-            <name>IGnssVisibilityControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.gnss.measurement_corrections</name>
-        <version>1</version>
-        <interface>
-            <name>IMeasurementCorrectionsInterface</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
-         If the HIDL composer HAL exists, it must be at least version 2.0.
-         See DeviceManifestTest.GrallocHal -->
-    <hal format="hidl" optional="true">
-        <name>android.hardware.graphics.allocator</name>
-        <!-- New, non-Go devices should use 4.0 or the AIDL hal.
-             See DeviceManifestTest.GrallocVersionCompatibility. -->
-        <version>2.0</version>
-        <version>3.0</version>
-        <version>4.0</version>
-        <interface>
-            <name>IAllocator</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.graphics.allocator</name>
-        <version>1</version>
-        <interface>
-            <name>IAllocator</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <!-- Either the AIDL or the HIDL composer HAL must exist on the device.
-         If the HIDL composer HAL exists, it must be at least version 2.1.
-         See DeviceManifestTest.ComposerHal -->
-    <hal format="hidl" optional="true">
-        <name>android.hardware.graphics.composer</name>
-        <version>2.1-4</version>
-        <interface>
-            <name>IComposer</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.graphics.composer3</name>
-        <version>1</version>
-        <interface>
-            <name>IComposer</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.graphics.mapper</name>
-        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
-        <version>2.1</version>
-        <version>3.0</version>
-        <version>4.0</version>
-        <interface>
-            <name>IMapper</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="false">
-        <name>android.hardware.health</name>
-        <version>1</version>
-        <interface>
-            <name>IHealth</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.health.storage</name>
-        <version>1</version>
-        <interface>
-            <name>IStorage</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.identity</name>
-        <version>1-4</version>
-        <interface>
-            <name>IIdentityCredentialStore</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.net.nlinterceptor</name>
-        <interface>
-            <name>IInterceptor</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.oemlock</name>
-        <version>1</version>
-        <interface>
-            <name>IOemLock</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.ir</name>
-        <version>1</version>
-        <interface>
-            <name>IConsumerIr</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.input.processor</name>
-        <version>1</version>
-        <interface>
-            <name>IInputProcessor</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.keymaster</name>
-        <version>3.0</version>
-        <version>4.0-1</version>
-        <interface>
-            <name>IKeymasterDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.keymaster</name>
-        <version>4.0-1</version>
-        <interface>
-            <name>IKeymasterDevice</name>
-            <instance>strongbox</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.security.dice</name>
-        <version>1</version>
-        <interface>
-            <name>IDiceDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.security.keymint</name>
-        <version>1-2</version>
-        <interface>
-            <name>IKeyMintDevice</name>
-            <instance>default</instance>
-            <instance>strongbox</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.security.keymint</name>
-        <version>1-2</version>
-        <interface>
-            <name>IRemotelyProvisionedComponent</name>
-            <instance>default</instance>
-            <instance>strongbox</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.light</name>
-        <version>2</version>
-        <interface>
-            <name>ILights</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.media.c2</name>
-        <version>1.0-2</version>
-        <interface>
-            <name>IComponentStore</name>
-            <regex-instance>default[0-9]*</regex-instance>
-            <regex-instance>vendor[0-9]*_software</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.media.omx</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOmx</name>
-            <instance>default</instance>
-        </interface>
-        <interface>
-            <name>IOmxStore</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.memtrack</name>
-        <version>1</version>
-        <interface>
-            <name>IMemtrack</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.neuralnetworks</name>
-        <version>1.0-3</version>
-        <interface>
-            <name>IDevice</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.neuralnetworks</name>
-        <version>1-4</version>
-        <interface>
-            <name>IDevice</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.nfc</name>
-        <version>1.2</version>
-        <interface>
-            <name>INfc</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.nfc</name>
-        <interface>
-            <name>INfc</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.oemlock</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOemLock</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="false">
-        <name>android.hardware.power</name>
-        <version>2-3</version>
-        <interface>
-            <name>IPower</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.power.stats</name>
-        <interface>
-            <name>IPowerStats</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.radio.config</name>
-        <version>1</version>
-        <interface>
-            <name>IRadioConfig</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.radio.data</name>
-        <version>1</version>
-        <interface>
-            <name>IRadioData</name>
-            <instance>slot1</instance>
-            <instance>slot2</instance>
-            <instance>slot3</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.radio.messaging</name>
-        <version>1</version>
-        <interface>
-            <name>IRadioMessaging</name>
-            <instance>slot1</instance>
-            <instance>slot2</instance>
-            <instance>slot3</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.radio.modem</name>
-        <version>1</version>
-        <interface>
-            <name>IRadioModem</name>
-            <instance>slot1</instance>
-            <instance>slot2</instance>
-            <instance>slot3</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.radio.network</name>
-        <version>1</version>
-        <interface>
-            <name>IRadioNetwork</name>
-            <instance>slot1</instance>
-            <instance>slot2</instance>
-            <instance>slot3</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.radio.sim</name>
-        <version>1</version>
-        <interface>
-            <name>IRadioSim</name>
-            <instance>slot1</instance>
-            <instance>slot2</instance>
-            <instance>slot3</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.radio.voice</name>
-        <version>1</version>
-        <interface>
-            <name>IRadioVoice</name>
-            <instance>slot1</instance>
-            <instance>slot2</instance>
-            <instance>slot3</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.radio</name>
-        <version>1.2</version>
-        <interface>
-            <name>ISap</name>
-            <instance>slot1</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.renderscript</name>
-        <version>1.0</version>
-        <interface>
-            <name>IDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.rebootescrow</name>
-        <version>1</version>
-        <interface>
-            <name>IRebootEscrow</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.secure_element</name>
-        <version>1.0-2</version>
-        <interface>
-            <name>ISecureElement</name>
-            <regex-instance>eSE[1-9][0-9]*</regex-instance>
-            <regex-instance>SIM[1-9][0-9]*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.security.secureclock</name>
-        <version>1</version>
-        <interface>
-            <name>ISecureClock</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.security.sharedsecret</name>
-        <version>1</version>
-        <interface>
-            <name>ISharedSecret</name>
-            <instance>default</instance>
-            <instance>strongbox</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.sensors</name>
-        <interface>
-            <name>ISensors</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.sensors</name>
-        <version>1.0</version>
-        <version>2.0-1</version>
-        <interface>
-            <name>ISensors</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.soundtrigger</name>
-        <version>2.3</version>
-        <interface>
-            <name>ISoundTriggerHw</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-         <name>android.hardware.soundtrigger3</name>
-         <version>1</version>
-         <interface>
-             <name>ISoundTriggerHw</name>
-             <instance>default</instance>
-         </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tetheroffload.config</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOffloadConfig</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tetheroffload.control</name>
-        <version>1.1</version>
-        <interface>
-            <name>IOffloadControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.thermal</name>
-        <version>2.0</version>
-        <interface>
-            <name>IThermal</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tv.cec</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IHdmiCec</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tv.input</name>
-        <version>1.0</version>
-        <interface>
-            <name>ITvInput</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.tv.tuner</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>ITuner</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.tv.tuner</name>
-        <version>1</version>
-        <interface>
-            <name>ITuner</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.usb</name>
-        <version>1.0-3</version>
-        <interface>
-            <name>IUsb</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.usb</name>
-        <interface>
-            <name>IUsb</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.usb.gadget</name>
-        <version>1.0-2</version>
-        <interface>
-            <name>IUsbGadget</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.vibrator</name>
-        <version>1-2</version>
-        <interface>
-            <name>IVibrator</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.vibrator</name>
-        <version>1-2</version>
-        <interface>
-            <name>IVibratorManager</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.weaver</name>
-        <version>1.0</version>
-        <interface>
-            <name>IWeaver</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.weaver</name>
-        <version>1</version>
-        <interface>
-            <name>IWeaver</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.wifi</name>
-        <version>1.3-6</version>
-        <interface>
-            <name>IWifi</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.uwb</name>
-        <version>1</version>
-        <interface>
-            <name>IUwb</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.wifi.hostapd</name>
-        <version>1</version>
-        <interface>
-            <name>IHostapd</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl" optional="true">
-        <name>android.hardware.wifi.supplicant</name>
-        <interface>
-            <name>ISupplicant</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-</compatibility-matrix>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index 6de9d03..3bc1786 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -52,6 +52,7 @@
             "android.hardware.radio.config@1.2",
             // AIDL
             "android.hardware.audio.common",
+            "android.hardware.audio.core.sounddose",
             "android.hardware.biometrics.common",
             "android.hardware.camera.metadata",
             "android.hardware.camera.device",
@@ -61,13 +62,17 @@
             "android.hardware.graphics.common",
             "android.hardware.input.common",
             "android.hardware.keymaster",
+            "android.hardware.media.bufferpool2",
             "android.hardware.radio",
+            "android.hardware.threadnetwork",
             "android.hardware.uwb.fira_android",
 
             // Fastboot HAL is only used by recovery. Recovery is owned by OEM. Framework
             // does not depend on this HAL, hence it is not declared in any manifests or matrices.
             "android.hardware.fastboot@1.0",
             "android.hardware.fastboot@1.1",
+            // Fastboot AIDL
+            "android.hardware.fastboot",
 
             // Deprecated HALs.
             // HIDL
@@ -80,6 +85,28 @@
             "android.hardware.nfc@1.0",
             // TODO(b/171260715) Remove when HAL definition is removed
             "android.hardware.radio.deprecated@1.0",
+
+            // TODO(b/205175891): File individual bugs for these HALs deprecated in P
+            "android.hardware.audio.effect@4.0",
+            "android.hardware.audio@4.0",
+            "android.hardware.bluetooth.a2dp@1.0",
+            "android.hardware.cas@1.0",
+            "android.hardware.configstore@1.0",
+            "android.hardware.gnss@1.0",
+            "android.hardware.gnss@1.1",
+            "android.hardware.graphics.mapper@2.0",
+            "android.hardware.nfc@1.1",
+            "android.hardware.radio.config@1.0",
+            "android.hardware.radio@1.0",
+            "android.hardware.radio@1.1",
+            "android.hardware.radio@1.3",
+            "android.hardware.thermal@1.0",
+            "android.hardware.thermal@1.1",
+            "android.hardware.wifi.offload@1.0",
+
+            // Under hardware/interfaces/staging, still in development
+            // AIDL
+            "android.hardware.media.c2",
     };
 
     auto package_has_prefix = [&](const std::string& prefix) {
diff --git a/confirmationui/1.0/default/OWNERS b/confirmationui/1.0/default/OWNERS
index 335660d..17aed51 100644
--- a/confirmationui/1.0/default/OWNERS
+++ b/confirmationui/1.0/default/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1124672
 jdanis@google.com
 swillden@google.com
diff --git a/confirmationui/1.0/vts/OWNERS b/confirmationui/1.0/vts/OWNERS
index e7aa8b4..aa07242 100644
--- a/confirmationui/1.0/vts/OWNERS
+++ b/confirmationui/1.0/vts/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 1124672
 jdanis@google.com
 swillden@google.com
 yim@google.com
diff --git a/confirmationui/OWNERS b/confirmationui/OWNERS
new file mode 100644
index 0000000..d3896df
--- /dev/null
+++ b/confirmationui/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1124672
+swillden@google.com
+subrahmanyaman@google.com
diff --git a/confirmationui/aidl/Android.bp b/confirmationui/aidl/Android.bp
new file mode 100644
index 0000000..51bde0a
--- /dev/null
+++ b/confirmationui/aidl/Android.bp
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 The Android Open-Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+    name: "android.hardware.confirmationui",
+    vendor_available: true,
+    imports: [
+        "android.hardware.security.keymint-V3",
+    ],
+    srcs: ["android/hardware/confirmationui/*.aidl"],
+    stability: "vintf",
+    backend: {
+        java: {
+            platform_apis: true,
+        },
+        ndk: {
+            apps_enabled: false,
+        },
+        cpp: {
+            enabled: false,
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.security.keymint-V3"],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/.hash b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/.hash
new file mode 100644
index 0000000..72b88d4
--- /dev/null
+++ b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/.hash
@@ -0,0 +1 @@
+4ae5a11c7bcce793ed8db5333483cc4296d3367e
diff --git a/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/IConfirmationResultCallback.aidl b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/IConfirmationResultCallback.aidl
new file mode 100644
index 0000000..6d6ec97
--- /dev/null
+++ b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/IConfirmationResultCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.confirmationui;
+@VintfStability
+interface IConfirmationResultCallback {
+  void result(in int error, in byte[] formattedMessage, in byte[] confirmationToken);
+}
diff --git a/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/IConfirmationUI.aidl b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/IConfirmationUI.aidl
new file mode 100644
index 0000000..9c03173
--- /dev/null
+++ b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/IConfirmationUI.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.confirmationui;
+@VintfStability
+interface IConfirmationUI {
+  void abort();
+  void deliverSecureInputEvent(in android.hardware.security.keymint.HardwareAuthToken secureInputToken);
+  void promptUserConfirmation(in android.hardware.confirmationui.IConfirmationResultCallback resultCB, in byte[] promptText, in byte[] extraData, in @utf8InCpp String locale, in android.hardware.confirmationui.UIOption[] uiOptions);
+  const int OK = 0;
+  const int CANCELED = 1;
+  const int ABORTED = 2;
+  const int OPERATION_PENDING = 3;
+  const int IGNORED = 4;
+  const int SYSTEM_ERROR = 5;
+  const int UNIMPLEMENTED = 6;
+  const int UNEXPECTED = 7;
+  const int UI_ERROR = 0x10000;
+  const int UI_ERROR_MISSING_GLYPH = 0x10001;
+  const int UI_ERROR_MESSAGE_TOO_LONG = 0x10002;
+  const int UI_ERROR_MALFORMED_UTF8ENCODING = 0x10003;
+  const int TEST_KEY_BYTE = 0xA5;
+  const int MAX_MESSAGE_SIZE = 0x1800;
+}
diff --git a/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/TestModeCommands.aidl b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/TestModeCommands.aidl
new file mode 100644
index 0000000..b8629d1
--- /dev/null
+++ b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/TestModeCommands.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.confirmationui;
+@Backing(type="int") @VintfStability
+enum TestModeCommands {
+  OK_EVENT = 0,
+  CANCEL_EVENT = 1,
+}
diff --git a/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/UIOption.aidl b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/UIOption.aidl
new file mode 100644
index 0000000..ebecf9e
--- /dev/null
+++ b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/1/android/hardware/confirmationui/UIOption.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.confirmationui;
+@Backing(type="int") @VintfStability
+enum UIOption {
+  ACCESSIBILITY_INVERTED = 0,
+  ACCESSIBILITY_MAGNIFIED = 1,
+}
diff --git a/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/IConfirmationResultCallback.aidl b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/IConfirmationResultCallback.aidl
new file mode 100644
index 0000000..6d6ec97
--- /dev/null
+++ b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/IConfirmationResultCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.confirmationui;
+@VintfStability
+interface IConfirmationResultCallback {
+  void result(in int error, in byte[] formattedMessage, in byte[] confirmationToken);
+}
diff --git a/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/IConfirmationUI.aidl b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/IConfirmationUI.aidl
new file mode 100644
index 0000000..c5c7aa7
--- /dev/null
+++ b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/IConfirmationUI.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.confirmationui;
+@VintfStability
+interface IConfirmationUI {
+  void abort();
+  void deliverSecureInputEvent(in android.hardware.security.keymint.HardwareAuthToken secureInputToken);
+  void promptUserConfirmation(in android.hardware.confirmationui.IConfirmationResultCallback resultCB, in byte[] promptText, in byte[] extraData, in @utf8InCpp String locale, in android.hardware.confirmationui.UIOption[] uiOptions);
+  const int OK = 0;
+  const int CANCELED = 1;
+  const int ABORTED = 2;
+  const int OPERATION_PENDING = 3;
+  const int IGNORED = 4;
+  const int SYSTEM_ERROR = 5;
+  const int UNIMPLEMENTED = 6;
+  const int UNEXPECTED = 7;
+  const int UI_ERROR = 65536;
+  const int UI_ERROR_MISSING_GLYPH = 65537;
+  const int UI_ERROR_MESSAGE_TOO_LONG = 65538;
+  const int UI_ERROR_MALFORMED_UTF8ENCODING = 65539;
+  const int TEST_KEY_BYTE = 165;
+  const int MAX_MESSAGE_SIZE = 6144;
+}
diff --git a/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/TestModeCommands.aidl b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/TestModeCommands.aidl
new file mode 100644
index 0000000..b8629d1
--- /dev/null
+++ b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/TestModeCommands.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.confirmationui;
+@Backing(type="int") @VintfStability
+enum TestModeCommands {
+  OK_EVENT = 0,
+  CANCEL_EVENT = 1,
+}
diff --git a/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/UIOption.aidl b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/UIOption.aidl
new file mode 100644
index 0000000..ebecf9e
--- /dev/null
+++ b/confirmationui/aidl/aidl_api/android.hardware.confirmationui/current/android/hardware/confirmationui/UIOption.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.confirmationui;
+@Backing(type="int") @VintfStability
+enum UIOption {
+  ACCESSIBILITY_INVERTED = 0,
+  ACCESSIBILITY_MAGNIFIED = 1,
+}
diff --git a/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl b/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl
new file mode 100644
index 0000000..92328a8
--- /dev/null
+++ b/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.confirmationui;
+
+import android.hardware.confirmationui.IConfirmationUI;
+
+/**
+ * Callback interface passed to IConfirmationUI::promptUserConfirmation().
+ * Informs the caller about the result of the prompt operation.
+ */
+@VintfStability
+interface IConfirmationResultCallback {
+    /**
+     * This callback is called by the confirmation provider when it stops prompting the user.
+     * Iff the user has confirmed the prompted text, error is IConfirmationUI::OK and the
+     * parameters formattedMessage and confirmationToken hold the values needed to request
+     * a signature from keymaster.
+     * In all other cases formattedMessage and confirmationToken must be of length 0.
+     *
+     * @param error - IConfirmationUI::OK: IFF the user has confirmed the prompt.
+     *              - IConfirmationUI::CANCELED: If the user has pressed the cancel button.
+     *              - IConfirmationUI::ABORTED: If IConfirmationUI::abort() was called.
+     *              - IConfirmationUI::SYSTEM_ERROR: If an unexpected System error occurred that
+     * prevented the TUI from being shut down gracefully.
+     *
+     * @param formattedMessage holds the prompt text and extra data.
+     *                         The message is CBOR (RFC 7049) encoded and has the following format:
+     *                         CBOR_MAP{ "prompt", <promptText>, "extra", <extraData> }
+     *                         The message is a CBOR encoded map (type 5) with the keys
+     *                         "prompt" and "extra". The keys are encoded as CBOR text string
+     *                         (type 3). The value <promptText> is encoded as CBOR text string
+     *                         (type 3), and the value <extraData> is encoded as CBOR byte string
+     *                         (type 2). The map must have exactly one key value pair for each of
+     *                         the keys "prompt" and "extra". Other keys are not allowed.
+     *                         The value of "prompt" is given by the proptText argument to
+     *                         IConfirmationUI::promptUserConfirmation and must not be modified
+     *                         by the implementation.
+     *                         The value of "extra" is given by the extraData argument to
+     *                         IConfirmationUI::promptUserConfirmation and must not be modified
+     *                         or interpreted by the implementation.
+     *
+     * @param confirmationToken a 32-byte HMAC-SHA256 value, computed over
+     *                          "confirmation token" || <formattedMessage>
+     *                          i.e. the literal UTF-8 encoded string "confirmation token", without
+     *                          the "", concatenated with the formatted message as returned in the
+     *                          formattedMessage argument. The HMAC is keyed with a 256-bit secret
+     *                          which is shared with Keymaster. In test mode the test key MUST be
+     *                          used (see TestModeCommands.aidl and
+     * IConfirmationUI::TEST_KEY_BYTE).
+     */
+    void result(in int error, in byte[] formattedMessage, in byte[] confirmationToken);
+}
diff --git a/confirmationui/aidl/android/hardware/confirmationui/IConfirmationUI.aidl b/confirmationui/aidl/android/hardware/confirmationui/IConfirmationUI.aidl
new file mode 100644
index 0000000..20032ce
--- /dev/null
+++ b/confirmationui/aidl/android/hardware/confirmationui/IConfirmationUI.aidl
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.confirmationui;
+
+import android.hardware.confirmationui.IConfirmationResultCallback;
+import android.hardware.confirmationui.UIOption;
+import android.hardware.security.keymint.HardwareAuthToken;
+
+@VintfStability
+interface IConfirmationUI {
+    // Possible Errors.
+    /**
+     * API call succeeded or the user gave approval (result callback).
+     */
+    const int OK = 0;
+    /**
+     * The user canceled the TUI (result callback).
+     */
+    const int CANCELED = 1;
+    /**
+     * IConfirmationUI::abort() was called. (result callback).
+     */
+    const int ABORTED = 2;
+    /**
+     * Cannot start another prompt.
+     */
+    const int OPERATION_PENDING = 3;
+    /**
+     * IConfirmationUI::deliverSecureInputEvent call was ignored.
+     */
+    const int IGNORED = 4;
+    /**
+     * An unexpected system error occurred.
+     */
+    const int SYSTEM_ERROR = 5;
+    /**
+     * Returned by an unimplemented API call.
+     */
+    const int UNIMPLEMENTED = 6;
+    /**
+     * This is returned when an error is diagnosed that should have been
+     * caught by earlier input sanitization. Should never be seen in production.
+     */
+    const int UNEXPECTED = 7;
+    /**
+     * General UI error.
+     */
+    const int UI_ERROR = 0x10000;
+    /**
+     * This is returned if there is no corresponding glyph for a character.
+     */
+    const int UI_ERROR_MISSING_GLYPH = 0x10001;
+    /**
+     * The implementation must return this error code on promptUserConfirmation if the
+     * resulting formatted message does not fit into MAX_MESSAGE_SIZE bytes. It is
+     * advised that the implementation formats the message upon receiving this API call to
+     * be able to diagnose this syndrome.
+     */
+    const int UI_ERROR_MESSAGE_TOO_LONG = 0x10002;
+    /**
+     * This is returned if the UTF8 encoding is malformed.
+     */
+    const int UI_ERROR_MALFORMED_UTF8ENCODING = 0x10003;
+
+    // Constants
+    /**
+     * The test key is 32byte word with all bytes set to TEST_KEY_BYTE.
+     */
+    const int TEST_KEY_BYTE = 0xA5;
+    /**
+     * This defines the maximum message size. This indirectly limits the size of the prompt text
+     * and the extra data that can be passed to the confirmation UI. The prompt text and extra data
+     * must fit in to this size including CBOR header information.
+     */
+    const int MAX_MESSAGE_SIZE = 0x1800;
+
+    /**
+     * Aborts a pending user prompt. This allows the framework to gracefully end a TUI dialog.
+     * If a TUI operation was pending the corresponding call back is informed with
+     * IConfirmationUI::ABORTED.
+     */
+    void abort();
+
+    /**
+     * DeliverSecureInput is used by the framework to deliver a secure input event to the
+     * confirmation provider.
+     *
+     * VTS test mode:
+     * This function can be used to test certain code paths non-interactively.
+     * See TestModeCommands.aidl for details.
+     *
+     * @param secureInputToken An authentication token as generated by Android authentication
+     *                         providers.
+     */
+    void deliverSecureInputEvent(in HardwareAuthToken secureInputToken);
+
+    /**
+     * Asynchronously initiates a confirmation UI dialog prompting the user to confirm a given text.
+     * The TUI prompt must be implemented in such a way that a positive response indicates with
+     * high confidence that a user has seen the given prompt text even if the Android framework
+     * including the kernel was compromised.
+     *
+     * Service status return:
+     *
+     * OK IFF the dialog was successfully started. In this case, and only in this
+     *                      case, the implementation must, eventually, call the callback to
+     *                      indicate completion.
+     * OPERATION_PENDING is returned when the confirmation provider is currently
+     *                      in use.
+     * SYSTEM_ERROR an error occurred trying to communicate with the confirmation
+     *                      provider (e.g. trusted app).
+     * UI_ERROR the confirmation provider encountered an issue with displaying
+     *                      the prompt text to the user.
+     *
+     * @param resultCB Implementation of IResultCallback. Used by the implementation to report
+     *                 the result of the current pending user prompt.
+     *
+     * @param promptText UTF-8 encoded bytes which is to be presented to the user.
+     *
+     * @param extraData A binary blob that must be included in the formatted output message as is.
+     *                  It is opaque to the implementation. Implementations must neither interpret
+     *                  nor modify the content.
+     *
+     * @param locale String specifying the locale that must be used by the TUI dialog. The string
+     *                      is an IETF BCP 47 tag.
+     *
+     * @param uiOptions A set of uiOptions manipulating how the confirmation prompt is displayed.
+     *                  Refer to UIOption in UIOptions.aidl for possible options.
+     */
+    void promptUserConfirmation(in IConfirmationResultCallback resultCB, in byte[] promptText,
+            in byte[] extraData, in @utf8InCpp String locale, in UIOption[] uiOptions);
+}
diff --git a/confirmationui/aidl/android/hardware/confirmationui/TestModeCommands.aidl b/confirmationui/aidl/android/hardware/confirmationui/TestModeCommands.aidl
new file mode 100644
index 0000000..70f69c9
--- /dev/null
+++ b/confirmationui/aidl/android/hardware/confirmationui/TestModeCommands.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.confirmationui;
+
+/**
+ * Test mode commands.
+ *
+ * IConfirmationUI::deliverSecureInputEvent can be used to test certain code paths.
+ * To that end, the caller passes an auth token that has an HMAC keyed with the test key
+ * (see IConfirmationUI::TEST_KEY_BYTE). Implementations first check the HMAC against test key.
+ * If the test key produces a matching HMAC, the implementation evaluates the challenge field
+ * of the auth token against the values defined in TestModeCommand.
+ * If the command indicates that a confirmation token is to be generated the test key MUST be used
+ * to generate this confirmation token.
+ *
+ * See command code for individual test command descriptions.
+ */
+@VintfStability
+@Backing(type="int")
+enum TestModeCommands {
+    /**
+     * Simulates the user pressing the OK button on the UI. If no operation is pending
+     * IConfirmationUI::IGNORED must be returned. A pending operation is finalized successfully
+     * see IConfirmationResultCallback::result, however, the test key
+     * (see IConfirmationUI::TEST_KEY_BYTE) MUST be used to generate the confirmation token.
+     */
+    OK_EVENT = 0,
+    /**
+     * Simulates the user pressing the CANCEL button on the UI. If no operation is pending
+     * IConfirmationUI::IGNORED must be returned. A pending operation is finalized as specified in
+     * IConfirmationResultCallback.aidl.
+     */
+    CANCEL_EVENT = 1,
+}
diff --git a/confirmationui/aidl/android/hardware/confirmationui/UIOption.aidl b/confirmationui/aidl/android/hardware/confirmationui/UIOption.aidl
new file mode 100644
index 0000000..b242c53
--- /dev/null
+++ b/confirmationui/aidl/android/hardware/confirmationui/UIOption.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.confirmationui;
+
+/**
+ * UI modification options.
+ */
+@VintfStability
+@Backing(type="int")
+enum UIOption {
+    /**
+     * Accessibility: Requests color inverted style.
+     */
+    ACCESSIBILITY_INVERTED = 0,
+    /**
+     * Accessibility: Requests magnified style.
+     */
+    ACCESSIBILITY_MAGNIFIED = 1,
+}
diff --git a/confirmationui/aidl/vts/functional/Android.bp b/confirmationui/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..ac2d53a
--- /dev/null
+++ b/confirmationui/aidl/vts/functional/Android.bp
@@ -0,0 +1,46 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalConfirmationUITargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "keymint_use_latest_hal_aidl_ndk_static",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "VtsHalConfirmationUITargetTest.cpp",
+    ],
+    static_libs: [
+        "android.hardware.confirmationui-V1-ndk",
+        "android.hardware.confirmationui-support-lib",
+        "android.hardware.security.secureclock-V1-ndk",
+        "libcn-cbor",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcrypto",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/confirmationui/aidl/vts/functional/VtsHalConfirmationUITargetTest.cpp b/confirmationui/aidl/vts/functional/VtsHalConfirmationUITargetTest.cpp
new file mode 100644
index 0000000..61dae8b
--- /dev/null
+++ b/confirmationui/aidl/vts/functional/VtsHalConfirmationUITargetTest.cpp
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ConfirmationIOAidlHalTest"
+
+#include <algorithm>
+#include <condition_variable>
+#include <future>
+#include <iostream>
+#include <memory>
+#include <mutex>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/confirmationui/BnConfirmationResultCallback.h>
+#include <aidl/android/hardware/confirmationui/IConfirmationUI.h>
+#include <aidl/android/hardware/confirmationui/TestModeCommands.h>
+#include <aidl/android/hardware/confirmationui/UIOption.h>
+#include <android-base/thread_annotations.h>
+#include <android/hardware/confirmationui/support/confirmationui_utils.h>
+#include <cutils/log.h>
+
+#include <openssl/hmac.h>
+#include <openssl/sha.h>
+
+#include <cn-cbor/cn-cbor.h>
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_status.h>
+
+static constexpr int TIMEOUT_PERIOD = 10;
+
+namespace aidl::android::hardware::confirmationui::test {
+using ::aidl::android::hardware::security::keymint::HardwareAuthenticatorType;
+using ::aidl::android::hardware::security::keymint::HardwareAuthToken;
+using ::android::hardware::confirmationui::support::auth_token_key_t;
+using ::android::hardware::confirmationui::support::ByteBufferProxy;
+using ::android::hardware::confirmationui::support::HMac;
+using ::android::hardware::confirmationui::support::hmac_t;
+using ::android::hardware::confirmationui::support::hton;
+using ::android::hardware::confirmationui::support::NullOr;
+using std::shared_ptr;
+using std::string;
+using std::vector;
+
+namespace {
+const auth_token_key_t testKey(static_cast<uint8_t>(IConfirmationUI::TEST_KEY_BYTE));
+
+class HMacImplementation {
+  public:
+    static NullOr<hmac_t> hmac256(const auth_token_key_t& key,
+                                  std::initializer_list<ByteBufferProxy> buffers) {
+        HMAC_CTX hmacCtx;
+        HMAC_CTX_init(&hmacCtx);
+        if (!HMAC_Init_ex(&hmacCtx, key.data(), key.size(), EVP_sha256(), nullptr)) {
+            return {};
+        }
+        for (auto& buffer : buffers) {
+            if (!HMAC_Update(&hmacCtx, buffer.data(), buffer.size())) {
+                return {};
+            }
+        }
+        hmac_t result;
+        if (!HMAC_Final(&hmacCtx, result.data(), nullptr)) {
+            return {};
+        }
+        return result;
+    }
+};
+
+using HMacer = HMac<HMacImplementation>;
+
+template <typename... Data>
+vector<uint8_t> testHMAC(const Data&... data) {
+    auto hmac = HMacer::hmac256(testKey, data...);
+    if (!hmac.isOk()) {
+        ADD_FAILURE() << "Failed to compute test hmac.  This is a self-test error.";
+        return {};
+    }
+    vector<uint8_t> result(hmac.value().size());
+    std::copy(hmac.value().data(), hmac.value().data() + hmac.value().size(), result.data());
+    return result;
+}
+
+template <typename T>
+auto toBytes(const T& v) -> const uint8_t (&)[sizeof(T)] {
+    return *reinterpret_cast<const uint8_t(*)[sizeof(T)]>(&v);
+}
+
+HardwareAuthToken makeTestToken(const TestModeCommands command, uint64_t timestamp = 0) {
+    HardwareAuthToken auth_token;
+    auth_token.challenge = static_cast<uint64_t>(command);
+    auth_token.userId = 0;
+    auth_token.authenticatorId = 0;
+    auth_token.authenticatorType = HardwareAuthenticatorType::NONE;
+    auth_token.timestamp = {static_cast<int64_t>(timestamp)};
+
+    // Canonical form  of auth-token v0
+    // version (1 byte)
+    // challenge (8 bytes)
+    // user_id (8 bytes)
+    // authenticator_id (8 bytes)
+    // authenticator_type (4 bytes)
+    // timestamp (8 bytes)
+    // total 37 bytes
+    auth_token.mac = testHMAC("\0",
+                              toBytes(auth_token.challenge),                //
+                              toBytes(auth_token.userId),                   //
+                              toBytes(auth_token.authenticatorId),          //
+                              toBytes(hton(auth_token.authenticatorType)),  //
+                              toBytes(hton(auth_token.timestamp)));         //
+
+    return auth_token;
+}
+
+#define DEBUG_CONFRIMATIONUI_UTILS_TEST
+
+#ifdef DEBUG_CONFRIMATIONUI_UTILS_TEST
+std::ostream& hexdump(std::ostream& out, const uint8_t* data, size_t size) {
+    for (size_t i = 0; i < size; ++i) {
+        uint8_t byte = data[i];
+        out << std::hex << std::setw(2) << std::setfill('0') << (unsigned)byte;
+        switch (i & 0xf) {
+            case 0xf:
+                out << "\n";
+                break;
+            case 7:
+                out << "  ";
+                break;
+            default:
+                out << " ";
+                break;
+        }
+    }
+    return out;
+}
+#endif
+
+constexpr char hex_value[256] = {0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 1,  2,  3,  4,  5,  6,  7, 8, 9, 0, 0, 0, 0, 0, 0,  // '0'..'9'
+                                 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 'A'..'F'
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 'a'..'f'
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
+                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+std::string hex2str(std::string a) {
+    std::string b;
+    size_t num = a.size() / 2;
+    b.resize(num);
+    for (size_t i = 0; i < num; i++) {
+        b[i] = (hex_value[a[i * 2] & 0xFF] << 4) + (hex_value[a[i * 2 + 1] & 0xFF]);
+    }
+    return b;
+}
+
+int getReturnCode(const ::ndk::ScopedAStatus& result) {
+    if (result.isOk()) return IConfirmationUI::OK;
+
+    if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+        return static_cast<int>(result.getServiceSpecificError());
+    }
+    return result.getStatus();
+}
+
+}  // namespace
+
+class ConfirmationUIAidlTest : public ::testing::TestWithParam<std::string> {
+  public:
+    void TearDown() override { confirmator_->abort(); }
+    void SetUp() override {
+        std::string name = GetParam();
+        ASSERT_TRUE(AServiceManager_isDeclared(name.c_str())) << name;
+        ndk::SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
+        ASSERT_NE(binder, nullptr);
+        confirmator_ = IConfirmationUI::fromBinder(binder);
+        ASSERT_NE(confirmator_, nullptr);
+    }
+
+    // Used as a mechanism to inform the test about data/event callback
+    inline void notify() {
+        std::unique_lock<std::mutex> lock(mtx_);
+        cv_.notify_one();
+    }
+
+    // Test code calls this function to wait for data/event callback
+    inline std::cv_status wait() {
+        std::unique_lock<std::mutex> lock(mtx_);
+        auto now = std::chrono::system_clock::now();
+        std::cv_status status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+        return status;
+    }
+
+  protected:
+    shared_ptr<IConfirmationUI> confirmator_;
+
+  private:
+    // synchronization objects
+    std::mutex mtx_;
+    std::condition_variable cv_;
+};
+
+class ConfirmationTestCallback
+    : public ::aidl::android::hardware::confirmationui::BnConfirmationResultCallback {
+  public:
+    ConfirmationTestCallback(ConfirmationUIAidlTest& parent) : parent_(parent){};
+    virtual ~ConfirmationTestCallback() = default;
+
+    ::ndk::ScopedAStatus result(int32_t err, const vector<uint8_t>& msg,
+                                const vector<uint8_t>& confToken) override {
+        error_ = err;
+        formattedMessage_ = msg;
+        confirmationToken_ = confToken;
+        parent_.notify();
+        return ndk::ScopedAStatus::ok();
+    }
+
+    bool verifyConfirmationToken() {
+        static constexpr char confirmationPrefix[] = "confirmation token";
+        EXPECT_EQ(32U, confirmationToken_.size());
+        return 32U == confirmationToken_.size() &&
+               !memcmp(confirmationToken_.data(),
+                       testHMAC(confirmationPrefix, formattedMessage_).data(), 32);
+    }
+
+    int error_;
+    vector<uint8_t> formattedMessage_;
+    vector<uint8_t> confirmationToken_;
+
+  private:
+    ConfirmationUIAidlTest& parent_;
+};
+
+struct CnCborDeleter {
+    void operator()(cn_cbor* ptr) { cn_cbor_free(ptr); }
+};
+
+typedef std::unique_ptr<cn_cbor, CnCborDeleter> CnCborPtr;
+
+// Simulates the User taping Ok
+TEST_P(ConfirmationUIAidlTest, UserOkTest) {
+    static constexpr char test_prompt[] = "Me first, gimme gimme!";
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    ASSERT_TRUE(confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}).isOk());
+    // Simulate the user taping ok.
+    ASSERT_TRUE(confirmator_->deliverSecureInputEvent(makeTestToken(TestModeCommands::OK_EVENT))
+                        .isOk());
+    // Wait for the callback.
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    ASSERT_EQ(IConfirmationUI::OK, conf_cb->error_);
+
+    ASSERT_TRUE(conf_cb->verifyConfirmationToken());
+
+    cn_cbor_errback cn_cbor_error;
+    auto parsed_message = CnCborPtr(cn_cbor_decode(
+            conf_cb->formattedMessage_.data(), conf_cb->formattedMessage_.size(), &cn_cbor_error));
+    // is parsable CBOR
+    ASSERT_TRUE(parsed_message.get());
+    // is a map
+    ASSERT_EQ(CN_CBOR_MAP, parsed_message->type);
+
+    // the message must have exactly 2 key value pairs.
+    // cn_cbor holds 2*<no_of_pairs> in the length field
+    ASSERT_EQ(4, parsed_message->length);
+    // map has key "prompt"
+    auto prompt = cn_cbor_mapget_string(parsed_message.get(), "prompt");
+    ASSERT_TRUE(prompt);
+    ASSERT_EQ(CN_CBOR_TEXT, prompt->type);
+    ASSERT_EQ(22, prompt->length);
+    ASSERT_EQ(0, memcmp(test_prompt, prompt->v.str, 22));
+    // map has key "extra"
+    auto extra_out = cn_cbor_mapget_string(parsed_message.get(), "extra");
+    ASSERT_TRUE(extra_out);
+    ASSERT_EQ(CN_CBOR_BYTES, extra_out->type);
+    ASSERT_EQ(3, extra_out->length);
+    ASSERT_EQ(0, memcmp(test_extra, extra_out->v.bytes, 3));
+}
+
+// Initiates a confirmation prompt with a message that is too long
+TEST_P(ConfirmationUIAidlTest, MessageTooLongTest) {
+    static constexpr uint8_t test_extra[IConfirmationUI::MAX_MESSAGE_SIZE] = {};
+    static constexpr char test_prompt[] = "D\'oh!";
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + sizeof(test_extra));
+    auto result = confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {});
+    ASSERT_EQ(IConfirmationUI::UI_ERROR_MESSAGE_TOO_LONG, getReturnCode(result));
+}
+
+// If the message gets very long some HAL implementations might fail even before the message
+// reaches the trusted app implementation. But the HAL must still diagnose the correct error.
+TEST_P(ConfirmationUIAidlTest, MessageWayTooLongTest) {
+    static constexpr uint8_t test_extra[(IConfirmationUI::MAX_MESSAGE_SIZE)*10] = {};
+    static constexpr char test_prompt[] = "D\'oh!";
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + sizeof(test_extra));
+    auto result = confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {});
+    ASSERT_EQ(IConfirmationUI::UI_ERROR_MESSAGE_TOO_LONG, getReturnCode(result));
+}
+
+// Simulates the User tapping the Cancel
+TEST_P(ConfirmationUIAidlTest, UserCancelTest) {
+    static constexpr char test_prompt[] = "Me first, gimme gimme!";
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    ASSERT_TRUE(confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}).isOk());
+
+    // Simulate the user taping ok.
+    ASSERT_TRUE(confirmator_->deliverSecureInputEvent(makeTestToken(TestModeCommands::CANCEL_EVENT))
+                        .isOk());
+    // Wait for the callback.
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    ASSERT_EQ(IConfirmationUI::CANCELED, conf_cb->error_);
+
+    ASSERT_EQ(0U, conf_cb->confirmationToken_.size());
+    ASSERT_EQ(0U, conf_cb->formattedMessage_.size());
+}
+
+// Simulates the framework cancelling an ongoing prompt
+TEST_P(ConfirmationUIAidlTest, AbortTest) {
+    static constexpr char test_prompt[] = "Me first, gimme gimme!";
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    ASSERT_TRUE(confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}).isOk());
+
+    confirmator_->abort();
+
+    // Wait for the callback.
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    ASSERT_EQ(IConfirmationUI::ABORTED, conf_cb->error_);
+    ASSERT_EQ(0U, conf_cb->confirmationToken_.size());
+    ASSERT_EQ(0U, conf_cb->formattedMessage_.size());
+}
+
+// Tests if the confirmation dialog can successfully render 100 'W' characters as required by
+// the design guidelines.
+TEST_P(ConfirmationUIAidlTest, PortableMessageTest1) {
+    static constexpr char test_prompt[] =
+            "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"
+            "WWWWWWWWWWWWWW";
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    ASSERT_TRUE(confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}).isOk());
+
+    confirmator_->abort();
+
+    // Wait for the callback.
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    ASSERT_EQ(IConfirmationUI::ABORTED, conf_cb->error_);
+    ASSERT_EQ(0U, conf_cb->confirmationToken_.size());
+    ASSERT_EQ(0U, conf_cb->formattedMessage_.size());
+}
+
+// Tests if the confirmation dialog can successfully render 100 'W' characters as required by
+// the design guidelines in magnified mode.
+TEST_P(ConfirmationUIAidlTest, PortableMessageTest1Magnified) {
+    static constexpr char test_prompt[] =
+            "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"
+            "WWWWWWWWWWWWWW";
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    ASSERT_TRUE(confirmator_
+                        ->promptUserConfirmation(conf_cb, prompt_text, extra, "en",
+                                                 {UIOption::ACCESSIBILITY_MAGNIFIED})
+                        .isOk());
+
+    confirmator_->abort();
+
+    // Wait for the callback.
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    ASSERT_EQ(IConfirmationUI::ABORTED, conf_cb->error_);
+    ASSERT_EQ(0U, conf_cb->confirmationToken_.size());
+    ASSERT_EQ(0U, conf_cb->formattedMessage_.size());
+}
+
+// Tests if the confirmation dialog can successfully render 8 groups of 12 'W' characters as
+// required by the design guidelines.
+TEST_P(ConfirmationUIAidlTest, PortableMessageTest2) {
+    static constexpr char test_prompt[] =
+            "WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW "
+            "WWWWWWWWWWWW WWWWWWWWWWWW";
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    ASSERT_TRUE(confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}).isOk());
+
+    confirmator_->abort();
+
+    // Wait for the callback.
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    ASSERT_EQ(IConfirmationUI::ABORTED, conf_cb->error_);
+    ASSERT_EQ(0U, conf_cb->confirmationToken_.size());
+    ASSERT_EQ(0U, conf_cb->formattedMessage_.size());
+}
+
+// Tests if the confirmation dialog can successfully render 8 groups of 12 'W' characters as
+// required by the design guidelines in magnified mode.
+TEST_P(ConfirmationUIAidlTest, PortableMessageTest2Magnified) {
+    static constexpr char test_prompt[] =
+            "WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW WWWWWWWWWWWW "
+            "WWWWWWWWWWWW WWWWWWWWWWWW";
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    ASSERT_TRUE(confirmator_
+                        ->promptUserConfirmation(conf_cb, prompt_text, extra, "en",
+                                                 {UIOption::ACCESSIBILITY_MAGNIFIED})
+                        .isOk());
+
+    confirmator_->abort();
+
+    // Wait for the callback.
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    ASSERT_EQ(IConfirmationUI::ABORTED, conf_cb->error_);
+    ASSERT_EQ(0U, conf_cb->confirmationToken_.size());
+    ASSERT_EQ(0U, conf_cb->formattedMessage_.size());
+}
+
+// Passing malformed UTF-8 to the confirmation UI
+// This test passes a string that ends in the middle of a multibyte character
+TEST_P(ConfirmationUIAidlTest, MalformedUTF8Test1) {
+    static constexpr char test_prompt[] = {char(0xc0), 0};
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    auto result = confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {});
+    ASSERT_EQ(IConfirmationUI::UI_ERROR_MALFORMED_UTF8ENCODING, getReturnCode(result));
+}
+
+// Passing malformed UTF-8 to the confirmation UI
+// This test passes a string with a 5-byte character.
+TEST_P(ConfirmationUIAidlTest, MalformedUTF8Test2) {
+    static constexpr char test_prompt[] = {char(0xf8), char(0x82), char(0x82),
+                                           char(0x82), char(0x82), 0};
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    auto result = confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {});
+    ASSERT_EQ(IConfirmationUI::UI_ERROR_MALFORMED_UTF8ENCODING, getReturnCode(result));
+}
+
+// Passing malformed UTF-8 to the confirmation UI
+// This test passes a string with a 2-byte character followed by a stray non UTF-8 character.
+TEST_P(ConfirmationUIAidlTest, MalformedUTF8Test3) {
+    static constexpr char test_prompt[] = {char(0xc0), char(0x82), char(0x83), 0};
+    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
+    shared_ptr<ConfirmationTestCallback> conf_cb =
+            ::ndk::SharedRefBase::make<ConfirmationTestCallback>(*this);
+    vector<uint8_t> prompt_text(test_prompt, test_prompt + strlen(test_prompt));
+    vector<uint8_t> extra(test_extra, test_extra + 3);
+    auto result = confirmator_->promptUserConfirmation(conf_cb, prompt_text, extra, "en", {});
+    ASSERT_EQ(IConfirmationUI::UI_ERROR_MALFORMED_UTF8ENCODING, getReturnCode(result));
+}
+
+// Test the implementation of HMAC SHA 256 against a golden blob.
+TEST(ConfirmationUITestSelfTest, HMAC256SelfTest) {
+    const char key_str[32] = "keykeykeykeykeykeykeykeykeykeyk";
+    const uint8_t(&key)[32] = *reinterpret_cast<const uint8_t(*)[32]>(key_str);
+    auto expected = hex2str("2377fbcaa7fb3f6c20cfa1d9ebc60e9922cf58c909e25e300f3cb57f7805c886");
+    auto result = HMacer::hmac256(key, "value1", "value2", "value3");
+
+#ifdef DEBUG_CONFRIMATIONUI_UTILS_TEST
+    hexdump(std::cout, reinterpret_cast<const uint8_t*>(expected.data()), 32) << std::endl;
+    hexdump(std::cout, result.value().data(), 32) << std::endl;
+#endif
+
+    ByteBufferProxy expected_bytes(expected);
+    ASSERT_TRUE(result.isOk());
+    ASSERT_EQ(expected, result.value());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ConfirmationUIAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, ConfirmationUIAidlTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IConfirmationUI::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+}  // namespace aidl::android::hardware::confirmationui::test
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/confirmationui/support/Android.bp b/confirmationui/support/Android.bp
index 6ab83f2..1200115 100644
--- a/confirmationui/support/Android.bp
+++ b/confirmationui/support/Android.bp
@@ -36,7 +36,7 @@
     ],
     export_include_dirs: [
         "include",
-    ]
+    ],
 }
 
 cc_test {
@@ -56,6 +56,5 @@
         "libhidlbase",
     ],
     test_suites: ["general-tests"],
-    clang: true,
-    cflags: [ "-O0" ],
+    cflags: ["-O0"],
 }
diff --git a/confirmationui/support/OWNERS b/confirmationui/support/OWNERS
index 335660d..17aed51 100644
--- a/confirmationui/support/OWNERS
+++ b/confirmationui/support/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1124672
 jdanis@google.com
 swillden@google.com
diff --git a/contexthub/1.0/default/OWNERS b/contexthub/1.0/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/contexthub/1.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/contexthub/1.0/vts/functional/OWNERS b/contexthub/1.0/vts/functional/OWNERS
deleted file mode 100644
index f254cd5..0000000
--- a/contexthub/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 156070
-#Context Hub team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/contexthub/1.1/default/OWNERS b/contexthub/1.1/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/contexthub/1.1/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/contexthub/1.1/vts/functional/OWNERS b/contexthub/1.1/vts/functional/OWNERS
deleted file mode 100644
index 2cf5bca..0000000
--- a/contexthub/1.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 156070
-include ../../../1.0/vts/functional/OWNERS
diff --git a/contexthub/1.2/default/OWNERS b/contexthub/1.2/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/contexthub/1.2/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/contexthub/1.2/vts/functional/OWNERS b/contexthub/1.2/vts/functional/OWNERS
deleted file mode 100644
index 2cf5bca..0000000
--- a/contexthub/1.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 156070
-include ../../../1.0/vts/functional/OWNERS
diff --git a/contexthub/OWNERS b/contexthub/OWNERS
new file mode 100644
index 0000000..d5cfc2e
--- /dev/null
+++ b/contexthub/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 156070
+arthuri@google.com
+bduddie@google.com
+stange@google.com
diff --git a/contexthub/aidl/Android.bp b/contexthub/aidl/Android.bp
index a865445..814bf3b 100644
--- a/contexthub/aidl/Android.bp
+++ b/contexthub/aidl/Android.bp
@@ -40,6 +40,12 @@
             version: "1",
             imports: [],
         },
+        {
+            version: "2",
+            imports: [],
+        },
+
     ],
+    frozen: true,
 
 }
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/.hash b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/.hash
new file mode 100644
index 0000000..44f517b
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/.hash
@@ -0,0 +1 @@
+b0fd976b134e549e03726d3ebeeae848e520d3d3
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/AsyncEventType.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/AsyncEventType.aidl
new file mode 100644
index 0000000..8e0ff89
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/AsyncEventType.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.contexthub;
+@Backing(type="int") @VintfStability
+enum AsyncEventType {
+  RESTARTED = 1,
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/ContextHubInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/ContextHubInfo.aidl
new file mode 100644
index 0000000..e573556
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/ContextHubInfo.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.contexthub;
+@VintfStability
+parcelable ContextHubInfo {
+  String name;
+  String vendor;
+  String toolchain;
+  int id;
+  float peakMips;
+  int maxSupportedMessageLengthBytes;
+  long chrePlatformId;
+  byte chreApiMajorVersion;
+  byte chreApiMinorVersion;
+  char chrePatchVersion;
+  String[] supportedPermissions;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/ContextHubMessage.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/ContextHubMessage.aidl
new file mode 100644
index 0000000..e38c251
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/ContextHubMessage.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.contexthub;
+@VintfStability
+parcelable ContextHubMessage {
+  long nanoappId;
+  char hostEndPoint;
+  int messageType;
+  byte[] messageBody;
+  String[] permissions;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/HostEndpointInfo.aidl
new file mode 100644
index 0000000..dabdbb6
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/HostEndpointInfo.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.contexthub;
+@VintfStability
+parcelable HostEndpointInfo {
+  char hostEndpointId;
+  android.hardware.contexthub.HostEndpointInfo.Type type;
+  @nullable String packageName;
+  @nullable String attributionTag;
+  @Backing(type="int") @VintfStability
+  enum Type {
+    FRAMEWORK = 1,
+    APP = 2,
+    NATIVE = 3,
+  }
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/IContextHub.aidl
new file mode 100644
index 0000000..de8d752
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/IContextHub.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.contexthub;
+@VintfStability
+interface IContextHub {
+  List<android.hardware.contexthub.ContextHubInfo> getContextHubs();
+  void loadNanoapp(in int contextHubId, in android.hardware.contexthub.NanoappBinary appBinary, in int transactionId);
+  void unloadNanoapp(in int contextHubId, in long appId, in int transactionId);
+  void disableNanoapp(in int contextHubId, in long appId, in int transactionId);
+  void enableNanoapp(in int contextHubId, in long appId, in int transactionId);
+  void onSettingChanged(in android.hardware.contexthub.Setting setting, in boolean enabled);
+  void queryNanoapps(in int contextHubId);
+  void registerCallback(in int contextHubId, in android.hardware.contexthub.IContextHubCallback cb);
+  void sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message);
+  void onHostEndpointConnected(in android.hardware.contexthub.HostEndpointInfo hostEndpointInfo);
+  void onHostEndpointDisconnected(char hostEndpointId);
+  long[] getPreloadedNanoappIds(in int contextHubId);
+  void onNanSessionStateChanged(in android.hardware.contexthub.NanSessionStateUpdate update);
+  void setTestMode(in boolean enable);
+  const int EX_CONTEXT_HUB_UNSPECIFIED = (-1) /* -1 */;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/IContextHubCallback.aidl
new file mode 100644
index 0000000..6163cfc
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/IContextHubCallback.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.contexthub;
+@VintfStability
+interface IContextHubCallback {
+  void handleNanoappInfo(in android.hardware.contexthub.NanoappInfo[] appInfo);
+  void handleContextHubMessage(in android.hardware.contexthub.ContextHubMessage msg, in String[] msgContentPerms);
+  void handleContextHubAsyncEvent(in android.hardware.contexthub.AsyncEventType evt);
+  void handleTransactionResult(in int transactionId, in boolean success);
+  void handleNanSessionRequest(in android.hardware.contexthub.NanSessionRequest request);
+  const int CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS = 10000;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanSessionRequest.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanSessionRequest.aidl
new file mode 100644
index 0000000..d539707
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanSessionRequest.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.contexthub;
+@VintfStability
+parcelable NanSessionRequest {
+  boolean enable;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanSessionStateUpdate.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanSessionStateUpdate.aidl
new file mode 100644
index 0000000..80771e2
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanSessionStateUpdate.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.contexthub;
+@VintfStability
+parcelable NanSessionStateUpdate {
+  boolean state;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanoappBinary.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanoappBinary.aidl
new file mode 100644
index 0000000..fdf3860
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanoappBinary.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.contexthub;
+@VintfStability
+parcelable NanoappBinary {
+  long nanoappId;
+  int nanoappVersion;
+  int flags;
+  byte targetChreApiMajorVersion;
+  byte targetChreApiMinorVersion;
+  byte[] customBinary;
+  const int FLAG_SIGNED = (1 << 0) /* 1 */;
+  const int FLAG_ENCRYPTED = (1 << 1) /* 2 */;
+  const int FLAG_TCM_CAPABLE = (1 << 2) /* 4 */;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanoappInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanoappInfo.aidl
new file mode 100644
index 0000000..7175d7f
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanoappInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.contexthub;
+@VintfStability
+parcelable NanoappInfo {
+  long nanoappId;
+  int nanoappVersion;
+  boolean enabled;
+  String[] permissions;
+  android.hardware.contexthub.NanoappRpcService[] rpcServices;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanoappRpcService.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanoappRpcService.aidl
new file mode 100644
index 0000000..a6a1644
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/NanoappRpcService.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.contexthub;
+@VintfStability
+parcelable NanoappRpcService {
+  long id;
+  int version;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/Setting.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/Setting.aidl
new file mode 100644
index 0000000..aeb720b
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/2/android/hardware/contexthub/Setting.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.contexthub;
+@Backing(type="byte") @VintfStability
+enum Setting {
+  LOCATION = 1,
+  WIFI_MAIN,
+  WIFI_SCANNING,
+  AIRPLANE_MODE,
+  MICROPHONE,
+  BT_MAIN,
+  BT_SCANNING,
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
index 84e8531..dabdbb6 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
@@ -42,5 +42,6 @@
   enum Type {
     FRAMEWORK = 1,
     APP = 2,
+    NATIVE = 3,
   }
 }
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
index f0676be..de8d752 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
@@ -45,5 +45,8 @@
   void sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message);
   void onHostEndpointConnected(in android.hardware.contexthub.HostEndpointInfo hostEndpointInfo);
   void onHostEndpointDisconnected(char hostEndpointId);
-  const int EX_CONTEXT_HUB_UNSPECIFIED = -1;
+  long[] getPreloadedNanoappIds(in int contextHubId);
+  void onNanSessionStateChanged(in android.hardware.contexthub.NanSessionStateUpdate update);
+  void setTestMode(in boolean enable);
+  const int EX_CONTEXT_HUB_UNSPECIFIED = (-1) /* -1 */;
 }
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
index f81f7cf..6163cfc 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
@@ -38,4 +38,6 @@
   void handleContextHubMessage(in android.hardware.contexthub.ContextHubMessage msg, in String[] msgContentPerms);
   void handleContextHubAsyncEvent(in android.hardware.contexthub.AsyncEventType evt);
   void handleTransactionResult(in int transactionId, in boolean success);
+  void handleNanSessionRequest(in android.hardware.contexthub.NanSessionRequest request);
+  const int CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS = 10000;
 }
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionRequest.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionRequest.aidl
new file mode 100644
index 0000000..d539707
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionRequest.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.contexthub;
+@VintfStability
+parcelable NanSessionRequest {
+  boolean enable;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionStateUpdate.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionStateUpdate.aidl
new file mode 100644
index 0000000..80771e2
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionStateUpdate.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.contexthub;
+@VintfStability
+parcelable NanSessionStateUpdate {
+  boolean state;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappBinary.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappBinary.aidl
index d53b28f..fdf3860 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappBinary.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappBinary.aidl
@@ -40,7 +40,7 @@
   byte targetChreApiMajorVersion;
   byte targetChreApiMinorVersion;
   byte[] customBinary;
-  const int FLAG_SIGNED = 1;
-  const int FLAG_ENCRYPTED = 2;
-  const int FLAG_TCM_CAPABLE = 4;
+  const int FLAG_SIGNED = (1 << 0) /* 1 */;
+  const int FLAG_ENCRYPTED = (1 << 1) /* 2 */;
+  const int FLAG_TCM_CAPABLE = (1 << 2) /* 4 */;
 }
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Setting.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Setting.aidl
index d998478..aeb720b 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Setting.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Setting.aidl
@@ -35,10 +35,10 @@
 @Backing(type="byte") @VintfStability
 enum Setting {
   LOCATION = 1,
-  WIFI_MAIN = 2,
-  WIFI_SCANNING = 3,
-  AIRPLANE_MODE = 4,
-  MICROPHONE = 5,
-  BT_MAIN = 6,
-  BT_SCANNING = 7,
+  WIFI_MAIN,
+  WIFI_SCANNING,
+  AIRPLANE_MODE,
+  MICROPHONE,
+  BT_MAIN,
+  BT_SCANNING,
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
index a9d6657..c083bb9 100644
--- a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
@@ -44,5 +44,8 @@
 
         /** This endpoint is an Android app. */
         APP = 2,
+
+        /** This endpoint is from an Android native program. */
+        NATIVE = 3,
     }
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
index 16666ef..9683d2d 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
@@ -20,7 +20,9 @@
 import android.hardware.contexthub.ContextHubMessage;
 import android.hardware.contexthub.HostEndpointInfo;
 import android.hardware.contexthub.IContextHubCallback;
+import android.hardware.contexthub.NanSessionStateUpdate;
 import android.hardware.contexthub.NanoappBinary;
+import android.hardware.contexthub.NanoappInfo;
 import android.hardware.contexthub.Setting;
 
 @VintfStability
@@ -195,6 +197,45 @@
     void onHostEndpointDisconnected(char hostEndpointId);
 
     /**
+     * Provides the list of preloaded nanoapp IDs on the system. The output of this API must
+     * not change.
+     *
+     * @param contextHubId The identifier of the Context Hub.
+     *
+     * @return The list of preloaded nanoapp IDs.
+     */
+    long[] getPreloadedNanoappIds(in int contextHubId);
+
+    /**
+     * Invoked when the state of the NAN session requested through handleNanSessionRequest()
+     * changes. This function may be invoked without a corresponding handleNanSessionRequest to
+     * indicate if a NAN session was terminated without a request due to resource limitations.
+     *
+     * If the state becomes disabled without an explicit request from the HAL, the HAL MUST
+     * explicitly invoke handleNanSessionRequest() at a later point in time to attempt to
+     * re-enable NAN.
+     *
+     * @param update Information about the latest NAN session state.
+     */
+    void onNanSessionStateChanged(in NanSessionStateUpdate update);
+
+    /**
+     * Puts the context hub in and out of test mode. Test mode is a clean state
+     * where tests can be executed in the same environment. If enable is true,
+     * this will enable test mode by unloading all nanoapps. If enable is false,
+     * this will disable test mode and reverse the actions of enabling test mode
+     * by loading all preloaded nanoapps. This puts CHRE in a normal state.
+     *
+     * This should only be used for a test environment, either through a
+     * @TestApi or development tools. This should not be used in a production
+     * environment.
+     *
+     * @param enable If true, put the context hub in test mode. If false, disable
+     *               test mode.
+     */
+    void setTestMode(in boolean enable);
+
+    /**
      * Error codes that are used as service specific errors with the AIDL return
      * value EX_SERVICE_SPECIFIC.
      */
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
index e385d48..bfcb51e 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.contexthub.AsyncEventType;
 import android.hardware.contexthub.ContextHubMessage;
+import android.hardware.contexthub.NanSessionRequest;
 import android.hardware.contexthub.NanoappInfo;
 
 @VintfStability
@@ -74,4 +75,24 @@
      *
      */
     void handleTransactionResult(in int transactionId, in boolean success);
+
+    /**
+     * This callback is passed by the Contexthub service to the HAL implementation to allow the HAL
+     * to request a WiFi NAN session is created to allow the Contexthub to be able to utilize NAN
+     * functionality.
+     *
+     * onNanSessionStateChanged() will be invoked asynchronously after the NAN session request has
+     * been completed. This must be done within CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS. If the
+     * request times out, onNanSessionStateChanged() will be invoked with the state that the session
+     * was previously in.
+     *
+     * @param request Request from the HAL indicating the latest NAN session state it would like.
+     */
+    void handleNanSessionRequest(in NanSessionRequest request);
+
+    /**
+     * Amount of time, in milliseconds, that a handleNanSessionRequest can be pending before the
+     * Contexthub service must respond.
+     */
+    const int CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS = 10000;
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/NanSessionRequest.aidl b/contexthub/aidl/android/hardware/contexthub/NanSessionRequest.aidl
new file mode 100644
index 0000000..c462ba1
--- /dev/null
+++ b/contexthub/aidl/android/hardware/contexthub/NanSessionRequest.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.contexthub;
+
+/**
+ * Contains information needed to request a state change for a NAN session.
+ */
+@VintfStability
+parcelable NanSessionRequest {
+    /**
+     * Whether the NAN session should be enabled or disabled depending on whether the Contexthub
+     * needs access to NAN.
+     */
+    boolean enable;
+}
diff --git a/contexthub/aidl/android/hardware/contexthub/NanSessionStateUpdate.aidl b/contexthub/aidl/android/hardware/contexthub/NanSessionStateUpdate.aidl
new file mode 100644
index 0000000..a58eda5
--- /dev/null
+++ b/contexthub/aidl/android/hardware/contexthub/NanSessionStateUpdate.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.contexthub;
+
+/**
+ * Contains information provided as a response to a NanSessionRequest.
+ */
+@VintfStability
+parcelable NanSessionStateUpdate {
+    /**
+     * True if the NAN session is currently enabled.
+     */
+    boolean state;
+}
diff --git a/contexthub/aidl/default/Android.bp b/contexthub/aidl/default/Android.bp
index 269057a..6ee7407 100644
--- a/contexthub/aidl/default/Android.bp
+++ b/contexthub/aidl/default/Android.bp
@@ -29,7 +29,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.contexthub-V1-ndk",
+        "android.hardware.contexthub-V2-ndk",
     ],
     export_include_dirs: ["include"],
     srcs: [
@@ -50,7 +50,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.contexthub-V1-ndk",
+        "android.hardware.contexthub-V2-ndk",
     ],
     static_libs: [
         "libcontexthubexampleimpl",
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 4c23cbc..5272957 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -76,6 +76,22 @@
     }
 }
 
+ScopedAStatus ContextHub::getPreloadedNanoappIds(int32_t /* in_contextHubId */,
+                                                 std::vector<int64_t>* out_preloadedNanoappIds) {
+    if (out_preloadedNanoappIds == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    for (uint64_t i = 0; i < 10; ++i) {
+        out_preloadedNanoappIds->push_back(i);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus ContextHub::onNanSessionStateChanged(const NanSessionStateUpdate& /*in_update*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
 ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId,
                                            const std::shared_ptr<IContextHubCallback>& in_cb) {
     if (in_contextHubId == kMockHubId) {
@@ -98,6 +114,10 @@
     }
 }
 
+ScopedAStatus ContextHub::setTestMode(bool /* enable */) {
+    return ndk::ScopedAStatus::ok();
+}
+
 ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
     mConnectedHostEndpoints.insert(in_info.hostEndpointId);
 
@@ -107,10 +127,9 @@
 ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
     if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) {
         mConnectedHostEndpoints.erase(in_hostEndpointId);
-        return ndk::ScopedAStatus::ok();
-    } else {
-        return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
     }
+
+    return ndk::ScopedAStatus::ok();
 }
 
 }  // namespace contexthub
diff --git a/contexthub/aidl/default/contexthub-default.xml b/contexthub/aidl/default/contexthub-default.xml
index e383c50..930f672 100644
--- a/contexthub/aidl/default/contexthub-default.xml
+++ b/contexthub/aidl/default/contexthub-default.xml
@@ -1,7 +1,10 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.contexthub</name>
-        <version>1</version>
-        <fqname>IContextHub/default</fqname>
+        <version>2</version>
+        <interface>
+            <name>IContextHub</name>
+            <instance>default</instance>
+        </interface>
     </hal>
 </manifest>
diff --git a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
index 03d8432..7a2cfd1 100644
--- a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
+++ b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
@@ -19,6 +19,7 @@
 #include <aidl/android/hardware/contexthub/BnContextHub.h>
 
 #include <unordered_set>
+#include <vector>
 
 namespace aidl {
 namespace android {
@@ -37,13 +38,17 @@
                                        int32_t in_transactionId) override;
     ::ndk::ScopedAStatus onSettingChanged(Setting in_setting, bool in_enabled) override;
     ::ndk::ScopedAStatus queryNanoapps(int32_t in_contextHubId) override;
+    ::ndk::ScopedAStatus getPreloadedNanoappIds(
+            int32_t in_contextHubId, std::vector<int64_t>* out_preloadedNanoappIds) override;
     ::ndk::ScopedAStatus registerCallback(
             int32_t in_contextHubId, const std::shared_ptr<IContextHubCallback>& in_cb) override;
     ::ndk::ScopedAStatus sendMessageToHub(int32_t in_contextHubId,
                                           const ContextHubMessage& in_message) override;
+    ::ndk::ScopedAStatus setTestMode(bool enable) override;
     ::ndk::ScopedAStatus onHostEndpointConnected(const HostEndpointInfo& in_info) override;
 
     ::ndk::ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override;
+    ::ndk::ScopedAStatus onNanSessionStateChanged(const NanSessionStateUpdate& in_update) override;
 
   private:
     static constexpr uint32_t kMockHubId = 0;
diff --git a/contexthub/aidl/vts/Android.bp b/contexthub/aidl/vts/Android.bp
index 673eac0..1534b40 100644
--- a/contexthub/aidl/vts/Android.bp
+++ b/contexthub/aidl/vts/Android.bp
@@ -32,7 +32,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.contexthub-V1-cpp",
+        "android.hardware.contexthub-V2-cpp",
         "VtsHalContexthubUtils",
     ],
     test_suites: [
diff --git a/contexthub/aidl/vts/OWNERS b/contexthub/aidl/vts/OWNERS
deleted file mode 100644
index 150818d..0000000
--- a/contexthub/aidl/vts/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file:/contexthub/common/vts/OWNERS
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index 3c01c6b..c1cc07c 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -42,6 +42,8 @@
 using ::android::hardware::contexthub::NanoappBinary;
 using ::android::hardware::contexthub::NanoappInfo;
 using ::android::hardware::contexthub::NanoappRpcService;
+using ::android::hardware::contexthub::NanSessionRequest;
+using ::android::hardware::contexthub::NanSessionStateUpdate;
 using ::android::hardware::contexthub::Setting;
 using ::android::hardware::contexthub::vts_utils::kNonExistentAppId;
 using ::android::hardware::contexthub::vts_utils::waitForCallback;
@@ -84,6 +86,26 @@
     }
 }
 
+TEST_P(ContextHubAidl, TestEnableTestMode) {
+    Status status = contextHub->setTestMode(true);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        ASSERT_TRUE(status.isOk());
+    }
+}
+
+TEST_P(ContextHubAidl, TestDisableTestMode) {
+    Status status = contextHub->setTestMode(false);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        ASSERT_TRUE(status.isOk());
+    }
+}
+
 class EmptyContextHubCallback : public android::hardware::contexthub::BnContextHubCallback {
   public:
     Status handleNanoappInfo(const std::vector<NanoappInfo>& /* appInfo */) override {
@@ -100,6 +122,10 @@
     Status handleTransactionResult(int32_t /* transactionId */, bool /* success */) override {
         return Status::ok();
     }
+
+    Status handleNanSessionRequest(const NanSessionRequest& /* request */) override {
+        return Status::ok();
+    }
 };
 
 TEST_P(ContextHubAidl, TestRegisterCallback) {
@@ -107,10 +133,6 @@
     ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk());
 }
 
-TEST_P(ContextHubAidl, TestRegisterNullCallback) {
-    ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk());
-}
-
 // Helper callback that puts the async appInfo callback data into a promise
 class QueryAppsCallback : public android::hardware::contexthub::BnContextHubCallback {
   public:
@@ -131,6 +153,10 @@
         return Status::ok();
     }
 
+    Status handleNanSessionRequest(const NanSessionRequest& /* request */) override {
+        return Status::ok();
+    }
+
     std::promise<std::vector<NanoappInfo>> promise;
 };
 
@@ -156,6 +182,18 @@
     }
 }
 
+// Calls getPreloadedNanoappsIds() and verifies there are preloaded nanoapps
+TEST_P(ContextHubAidl, TestGetPreloadedNanoappIds) {
+    std::vector<int64_t> preloadedNanoappIds;
+    Status status = contextHub->getPreloadedNanoappIds(getHubId(), &preloadedNanoappIds);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        ASSERT_TRUE(status.isOk());
+    }
+}
+
 // Helper callback that puts the TransactionResult for the expectedTransactionId into a
 // promise
 class TransactionResultCallback : public android::hardware::contexthub::BnContextHubCallback {
@@ -181,6 +219,10 @@
         return Status::ok();
     }
 
+    Status handleNanSessionRequest(const NanSessionRequest& /* request */) override {
+        return Status::ok();
+    }
+
     uint32_t expectedTransactionId = 0;
     std::promise<bool> promise;
 };
@@ -276,8 +318,6 @@
 
     ASSERT_TRUE(contextHub->onSettingChanged(setting, true /* enabled */).isOk());
     ASSERT_TRUE(contextHub->onSettingChanged(setting, false /* enabled */).isOk());
-
-    ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk());
 }
 
 TEST_P(ContextHubAidl, TestOnLocationSettingChanged) {
@@ -329,6 +369,7 @@
 TEST_P(ContextHubAidl, TestHostConnection) {
     constexpr char16_t kHostEndpointId = 1;
     HostEndpointInfo hostEndpointInfo;
+    hostEndpointInfo.type = HostEndpointInfo::Type::NATIVE;
     hostEndpointInfo.hostEndpointId = kHostEndpointId;
 
     ASSERT_TRUE(contextHub->onHostEndpointConnected(hostEndpointInfo).isOk());
@@ -341,6 +382,20 @@
     ASSERT_TRUE(contextHub->onHostEndpointDisconnected(kHostEndpointId).isOk());
 }
 
+TEST_P(ContextHubAidl, TestNanSessionStateChange) {
+    NanSessionStateUpdate update;
+    update.state = true;
+    Status status = contextHub->onNanSessionStateChanged(update);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        ASSERT_TRUE(status.isOk());
+        update.state = false;
+        ASSERT_TRUE(contextHub->onNanSessionStateChanged(update).isOk());
+    }
+}
+
 std::string PrintGeneratedTest(const testing::TestParamInfo<ContextHubAidl::ParamType>& info) {
     return std::string("CONTEXT_HUB_ID_") + std::to_string(std::get<1>(info.param));
 }
diff --git a/contexthub/common/default/1.X/OWNERS b/contexthub/common/default/1.X/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/contexthub/common/default/1.X/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/contexthub/common/vts/OWNERS b/contexthub/common/vts/OWNERS
deleted file mode 100644
index 161b2f0..0000000
--- a/contexthub/common/vts/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-#Context Hub team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-#VTS team
-dshi@google.com
-trong@google.com
diff --git a/current.txt b/current.txt
index afde7b1..754093f 100644
--- a/current.txt
+++ b/current.txt
@@ -929,4 +929,14 @@
 1bac6a7c8136dfb0414fe5639eec115aa2d12927e64a0642a43fb53225f099b2 android.hardware.wifi@1.6::IWifiStaIface
 0a800e010e8eb6eecdfdc96f04fd2ae2f417a79a74a7c0eec3a9f539199bccd4 android.hardware.wifi@1.6::types
 
+# ABI preserving changes to HALs during Android U
+2aa559cda86c358c6429114ef6bc72c1b43281e98f9eb6b4df5e7073c8d05767 android.hardware.automotive.vehicle@2.0::types
+42abd285a4293dadb8c89bc63b90cae2872fbffe90c4517aa3ea4965e8aecff7 android.hardware.graphics.common@1.2::types
+4f1a02d21a22104c734f71cdbba19b6f7e93d4ee107ff79f0dbdd171a8430e0e android.hardware.automotive.vehicle@2.0::types
+a2fbd9747fbb9ceb8c1090b5a24138312246502d5af0654a8c2b603a9bf521fc android.hardware.gnss@1.0::IGnssCallback
+889b59e3e7a59afa67bf19882a44f51a2f9e43b6556ec52baa9ec3efd1ef7fbe android.hardware.camera.device@3.2::types
+db37a1c757e2e69b1ec9c75a981a6987bd87a131d92ab6acc00e04d19f374281 android.hardware.automotive.vehicle@2.0::types
+997017f581406fca1675d2f612f7ccd73f0d04eadd54bf6212e6cf5971d0872d android.hardware.automotive.vehicle@2.0::types
+06983ffe6d75e90a22503a6d9fd14417f983a36bb060a80ad5915240d69b8a40 android.hardware.automotive.vehicle@2.0::types
+
 # There will be no more HIDL HALs. Use AIDL instead.
diff --git a/drm/README.md b/drm/README.md
new file mode 100644
index 0000000..d56288e
--- /dev/null
+++ b/drm/README.md
@@ -0,0 +1,13 @@
+# DRM HAL
+
+This is the underlying HAL implementation for `MediaDrm`/`MediaCrypto` (and
+their NDK counterparts).
+
+## Plugin-vendor-specific VTS modules
+
+The interface `DrmHalVTSVendorModule_V1` is compatible with all versions of the
+DRM HAL (hidl 1.0-1.4, aidl).
+
+Please see `./1.0/vts/doc/Drm_Vendor_Modules_v1.pdf`.
+
+TODO(b/266091099): convert `Drm_Vendor_Modules_v1.pdf` to Markdown.
\ No newline at end of file
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
index 0fdba31..fb04d84 100644
--- a/drm/aidl/Android.bp
+++ b/drm/aidl/Android.bp
@@ -23,10 +23,7 @@
             sdk_version: "module_current",
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
-            min_sdk_version: "current",
+            min_sdk_version: "UpsideDownCake",
         },
     },
     double_loadable: true,
diff --git a/drm/aidl/OWNERS b/drm/aidl/OWNERS
index fa8fd20..fe69725 100644
--- a/drm/aidl/OWNERS
+++ b/drm/aidl/OWNERS
@@ -1,4 +1,3 @@
 # Bug component: 49079
-edwinwong@google.com
 kelzhan@google.com
 robertshih@google.com
diff --git a/drm/aidl/vts/OWNERS b/drm/aidl/vts/OWNERS
index e44b93e..fe69725 100644
--- a/drm/aidl/vts/OWNERS
+++ b/drm/aidl/vts/OWNERS
@@ -1,4 +1,3 @@
-edwinwong@google.com
-jtinker@google.com
+# Bug component: 49079
 kelzhan@google.com
 robertshih@google.com
diff --git a/dumpstate/aidl/Android.bp b/dumpstate/aidl/Android.bp
index d9acc7a..1eb8b32 100644
--- a/dumpstate/aidl/Android.bp
+++ b/dumpstate/aidl/Android.bp
@@ -31,12 +31,8 @@
             enabled: false,
         },
         java: {
-            enabled: false,
-        },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
+            enabled: true,
+            sdk_version: "module_current",
         },
     },
     versions_with_info: [
diff --git a/fastboot/OWNERS b/fastboot/OWNERS
new file mode 100644
index 0000000..286b65f
--- /dev/null
+++ b/fastboot/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 1228891
+dvander@google.com
+elsk@google.com
+dhavale@google.com
diff --git a/fastboot/aidl/Android.bp b/fastboot/aidl/Android.bp
new file mode 100644
index 0000000..29423cb
--- /dev/null
+++ b/fastboot/aidl/Android.bp
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.fastboot",
+    vendor_available: true,
+    recovery_available: true,
+    srcs: ["android/hardware/fastboot/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            enabled: false,
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/fastboot/aidl/aidl_api/android.hardware.fastboot/1/.hash b/fastboot/aidl/aidl_api/android.hardware.fastboot/1/.hash
new file mode 100644
index 0000000..458ca94
--- /dev/null
+++ b/fastboot/aidl/aidl_api/android.hardware.fastboot/1/.hash
@@ -0,0 +1 @@
+da59ee6c3e1088cbace3b6a913077ce52ca2ef25
diff --git a/fastboot/aidl/aidl_api/android.hardware.fastboot/1/android/hardware/fastboot/FileSystemType.aidl b/fastboot/aidl/aidl_api/android.hardware.fastboot/1/android/hardware/fastboot/FileSystemType.aidl
new file mode 100644
index 0000000..b8a8828
--- /dev/null
+++ b/fastboot/aidl/aidl_api/android.hardware.fastboot/1/android/hardware/fastboot/FileSystemType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.fastboot;
+@Backing(type="byte") @VintfStability
+enum FileSystemType {
+  EXT4,
+  F2FS,
+  RAW,
+}
diff --git a/fastboot/aidl/aidl_api/android.hardware.fastboot/1/android/hardware/fastboot/IFastboot.aidl b/fastboot/aidl/aidl_api/android.hardware.fastboot/1/android/hardware/fastboot/IFastboot.aidl
new file mode 100644
index 0000000..445fcde
--- /dev/null
+++ b/fastboot/aidl/aidl_api/android.hardware.fastboot/1/android/hardware/fastboot/IFastboot.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.fastboot;
+@VintfStability
+interface IFastboot {
+  String doOemCommand(in String oemCmd);
+  void doOemSpecificErase();
+  int getBatteryVoltageFlashingThreshold();
+  boolean getOffModeChargeState();
+  android.hardware.fastboot.FileSystemType getPartitionType(in String partitionName);
+  String getVariant();
+  const int FAILURE_UNKNOWN = 1;
+}
diff --git a/fastboot/aidl/aidl_api/android.hardware.fastboot/current/android/hardware/fastboot/FileSystemType.aidl b/fastboot/aidl/aidl_api/android.hardware.fastboot/current/android/hardware/fastboot/FileSystemType.aidl
new file mode 100644
index 0000000..b15d037
--- /dev/null
+++ b/fastboot/aidl/aidl_api/android.hardware.fastboot/current/android/hardware/fastboot/FileSystemType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.fastboot;
+@Backing(type="byte") @VintfStability
+enum FileSystemType {
+  EXT4 = 0,
+  F2FS = 1,
+  RAW = 2,
+}
diff --git a/fastboot/aidl/aidl_api/android.hardware.fastboot/current/android/hardware/fastboot/IFastboot.aidl b/fastboot/aidl/aidl_api/android.hardware.fastboot/current/android/hardware/fastboot/IFastboot.aidl
new file mode 100644
index 0000000..445fcde
--- /dev/null
+++ b/fastboot/aidl/aidl_api/android.hardware.fastboot/current/android/hardware/fastboot/IFastboot.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.fastboot;
+@VintfStability
+interface IFastboot {
+  String doOemCommand(in String oemCmd);
+  void doOemSpecificErase();
+  int getBatteryVoltageFlashingThreshold();
+  boolean getOffModeChargeState();
+  android.hardware.fastboot.FileSystemType getPartitionType(in String partitionName);
+  String getVariant();
+  const int FAILURE_UNKNOWN = 1;
+}
diff --git a/fastboot/aidl/android/hardware/fastboot/FileSystemType.aidl b/fastboot/aidl/android/hardware/fastboot/FileSystemType.aidl
new file mode 100644
index 0000000..b4027ec
--- /dev/null
+++ b/fastboot/aidl/android/hardware/fastboot/FileSystemType.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.fastboot;
+
+@VintfStability
+@Backing(type="byte")
+enum FileSystemType {
+    /**
+     * Fourth extended file system.
+     */
+    EXT4,
+    /**
+     * Flash Friendly File System.
+     */
+    F2FS,
+    /**
+     * Raw file system.
+     */
+    RAW,
+}
diff --git a/fastboot/aidl/android/hardware/fastboot/IFastboot.aidl b/fastboot/aidl/android/hardware/fastboot/IFastboot.aidl
new file mode 100644
index 0000000..abdc215
--- /dev/null
+++ b/fastboot/aidl/android/hardware/fastboot/IFastboot.aidl
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.fastboot;
+
+import android.hardware.fastboot.FileSystemType;
+
+/**
+ * IFastboot interface implements vendor specific fastboot commands.
+ */
+@VintfStability
+interface IFastboot {
+    /**
+     * Status code for function.
+     * Operation failed due to unknown reason.
+     */
+    const int FAILURE_UNKNOWN = 1;
+    /**
+     * Executes a fastboot OEM command.
+     *
+     * @param oemCmd The oem command that is passed to the fastboot HAL.
+     * @return optional String if the operation is successful and output is expected
+     *         for the command.
+     * @throws :
+     *         - EX_ILLEGAL_ARGUMENT for bad arguments.
+     *         - EX_UNSUPPORTED_OPERATION for unsupported commands.
+     *         - EX_SERVICE_SPECIFIC with status FAILURE_UNKNOWN for other errors.
+     */
+    String doOemCommand(in String oemCmd);
+
+    /**
+     * Executes an OEM specific erase after fastboot erase userdata.
+     *
+     * @throws :
+     *         - EX_UNSUPPORTED_OPERATION if it is not supported.
+     *         - EX_SERVICE_SPECIFIC with status FAILURE_UNKNOWN for
+     *           unknown error in oem specific command or other errors.
+     */
+    void doOemSpecificErase();
+
+    /**
+     * Returns the minimum battery voltage required for flashing in mV.
+     *
+     * @return Minimum batterery voltage (in mV) required for flashing to
+     *         be successful.
+     * @throws :
+     *         - EX_SERVICE_SPECIFIC with status FAILURE_UNKNOWN if error.
+     */
+    int getBatteryVoltageFlashingThreshold();
+
+    /**
+     * Returns whether off-mode-charging is enabled. If enabled, the device
+     *      autoboots into a special mode when power is applied.
+     *
+     * @return Returns whether off-mode-charging is enabled.
+     * @throws :
+     *         - EX_SERVICE_SPECIFIC with status FAILURE_UNKNOWN if error.
+     */
+    boolean getOffModeChargeState();
+
+    /**
+     * Returns the file system type of the partition. Implementation is only
+     *       required for physical partitions that need to be wiped and reformatted.
+     * @param in partitionName Name of the partition.
+     * @return Returns the file system type of the partition. Type can be ext4,
+     *         f2fs or raw.
+     * @throws :
+     *         - EX_SERVICE_SPECIFIC with status FAILURE_UNKNOWN if the partition
+     *           is invalid or does not require reformatting.
+     */
+    FileSystemType getPartitionType(in String partitionName);
+
+    /**
+     * Returns an OEM-defined string indicating the variant of the device, for
+     * example, US and ROW.
+     * @return Indicates the device variant.
+     * @throws :
+     *         - EX_SERVICE_SPECIFIC with status FAILURE_UNKNOWN if error.
+     */
+    String getVariant();
+}
diff --git a/fastboot/aidl/default/Android.bp b/fastboot/aidl/default/Android.bp
new file mode 100644
index 0000000..cb38dcc
--- /dev/null
+++ b/fastboot/aidl/default/Android.bp
@@ -0,0 +1,43 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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_binary {
+    name: "android.hardware.fastboot-service.example_recovery",
+    init_rc: ["android.hardware.fastboot-service.example_recovery.rc"],
+    vintf_fragments: ["android.hardware.fastboot-service.example.xml"],
+    recovery: true,
+    srcs: [
+        "Fastboot.cpp",
+        "main.cpp",
+    ],
+    relative_install_path: "hw",
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.fastboot-V1-ndk",
+    ],
+}
diff --git a/fastboot/aidl/default/Fastboot.cpp b/fastboot/aidl/default/Fastboot.cpp
new file mode 100644
index 0000000..1ba73d3
--- /dev/null
+++ b/fastboot/aidl/default/Fastboot.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Fastboot.h"
+
+using ndk::ScopedAStatus;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace fastboot {
+
+ScopedAStatus Fastboot::getPartitionType(const std::string& in_partitionName,
+                                         FileSystemType* _aidl_return) {
+    if (in_partitionName.empty()) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                           "Invalid partition name");
+    }
+    *_aidl_return = FileSystemType::RAW;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Fastboot::doOemCommand(const std::string& in_oemCmd, std::string* _aidl_return) {
+    *_aidl_return = "";
+    if (in_oemCmd.empty()) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "Invalid command");
+    }
+    return ScopedAStatus::fromExceptionCodeWithMessage(
+            EX_UNSUPPORTED_OPERATION, "Command not supported in default implementation");
+}
+
+ScopedAStatus Fastboot::getVariant(std::string* _aidl_return) {
+    *_aidl_return = "NA";
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Fastboot::getOffModeChargeState(bool* _aidl_return) {
+    *_aidl_return = false;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Fastboot::getBatteryVoltageFlashingThreshold(int32_t* _aidl_return) {
+    *_aidl_return = 0;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Fastboot::doOemSpecificErase() {
+    return ScopedAStatus::fromExceptionCodeWithMessage(
+            EX_UNSUPPORTED_OPERATION, "Command not supported in default implementation");
+}
+
+}  // namespace fastboot
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/fastboot/aidl/default/Fastboot.h b/fastboot/aidl/default/Fastboot.h
new file mode 100644
index 0000000..48e2c38
--- /dev/null
+++ b/fastboot/aidl/default/Fastboot.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "aidl/android/hardware/fastboot/BnFastboot.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace fastboot {
+class Fastboot : public BnFastboot {
+    ::ndk::ScopedAStatus doOemCommand(const std::string& in_oemCmd,
+                                      std::string* _aidl_return) override;
+    ::ndk::ScopedAStatus doOemSpecificErase() override;
+    ::ndk::ScopedAStatus getBatteryVoltageFlashingThreshold(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getOffModeChargeState(bool* _aidl_return) override;
+    ::ndk::ScopedAStatus getPartitionType(
+            const std::string& in_partitionName,
+            ::aidl::android::hardware::fastboot::FileSystemType* _aidl_return) override;
+    ::ndk::ScopedAStatus getVariant(std::string* _aidl_return) override;
+};
+
+}  // namespace fastboot
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/fastboot/aidl/default/android.hardware.fastboot-service.example.xml b/fastboot/aidl/default/android.hardware.fastboot-service.example.xml
new file mode 100644
index 0000000..9490f98
--- /dev/null
+++ b/fastboot/aidl/default/android.hardware.fastboot-service.example.xml
@@ -0,0 +1,8 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.fastboot</name>
+        <version>1</version>
+        <fqname>IFastboot/default</fqname>
+    </hal>
+</manifest>
+
diff --git a/fastboot/aidl/default/android.hardware.fastboot-service.example_recovery.rc b/fastboot/aidl/default/android.hardware.fastboot-service.example_recovery.rc
new file mode 100644
index 0000000..5d4ee13
--- /dev/null
+++ b/fastboot/aidl/default/android.hardware.fastboot-service.example_recovery.rc
@@ -0,0 +1,6 @@
+service vendor.fastboot-default /system/bin/hw/android.hardware.fastboot-service.example_recovery
+    class hal
+    seclabel u:r:hal_fastboot_default:s0
+    user system
+    group system
+    interface aidl android.hardware.fastboot.IFastboot/default
diff --git a/fastboot/aidl/default/main.cpp b/fastboot/aidl/default/main.cpp
new file mode 100644
index 0000000..1b1b41d
--- /dev/null
+++ b/fastboot/aidl/default/main.cpp
@@ -0,0 +1,38 @@
+
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include "Fastboot.h"
+
+using aidl::android::hardware::fastboot::Fastboot;
+using aidl::android::hardware::fastboot::IFastboot;
+
+int main(int, char* argv[]) {
+    android::base::InitLogging(argv, android::base::KernelLogger);
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<IFastboot> service = ndk::SharedRefBase::make<Fastboot>();
+
+    const std::string instance = std::string(IFastboot::descriptor) + "/default";
+    auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status;
+    LOG(INFO) << "IFastboot AIDL service running...";
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/fastboot/aidl/fastbootshim/Android.bp b/fastboot/aidl/fastbootshim/Android.bp
new file mode 100644
index 0000000..c843c12
--- /dev/null
+++ b/fastboot/aidl/fastbootshim/Android.bp
@@ -0,0 +1,61 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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_defaults {
+    name: "libfastbootshim_defaults",
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    static_libs: [
+        "android.hardware.fastboot-V1-ndk",
+        "android.hardware.fastboot@1.0",
+        "android.hardware.fastboot@1.1",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+}
+
+// Shim library that wraps a HIDL Fastboot object into an AIDL Fastboot object.
+cc_library_static {
+    name: "libfastbootshim",
+    defaults: ["libfastbootshim_defaults"],
+    recovery_available: true,
+    srcs: [
+        "fastbootshim.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+}
diff --git a/fastboot/aidl/fastbootshim/fastbootshim.cpp b/fastboot/aidl/fastbootshim/fastbootshim.cpp
new file mode 100644
index 0000000..4ab67f3
--- /dev/null
+++ b/fastboot/aidl/fastbootshim/fastbootshim.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fastbootshim.h>
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Void;
+using ::android::hardware::fastboot::V1_0::FileSystemType;
+using ::android::hardware::fastboot::V1_0::Result;
+using ::android::hardware::fastboot::V1_0::Status;
+
+using ndk::ScopedAStatus;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace fastboot {
+ScopedAStatus ResultToAStatus(Result result) {
+    switch (result.status) {
+        case Status::SUCCESS:
+            return ScopedAStatus::ok();
+        case Status::NOT_SUPPORTED:
+            return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+        case Status::INVALID_ARGUMENT:
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        case Status::FAILURE_UNKNOWN:
+            return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                    BnFastboot::FAILURE_UNKNOWN, ("Error " + std::string(result.message)).c_str());
+    }
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            BnFastboot::FAILURE_UNKNOWN,
+            ("Unrecognized status value " + toString(result.status)).c_str());
+}
+FastbootShim::FastbootShim(const sp<HidlFastboot>& service) : service_(service) {}
+
+ScopedAStatus FastbootShim::getPartitionType(const std::string& in_partitionName,
+                                             FileSystemType* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    if (in_partitionName.empty()) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                           "Invalid partition name");
+    }
+    const hidl_string partition = in_partitionName;
+    auto ret = service_->getPartitionType(partition, [&](auto type, auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = static_cast<aidl::android::hardware::fastboot::FileSystemType>(type);
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::doOemCommand(const std::string& in_oemCmd, std::string* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    *_aidl_return = "";
+    if (in_oemCmd.empty()) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "Invalid command");
+    }
+    const hidl_string oemCmdArgs = in_oemCmd;
+    auto ret = service_->doOemCommand(oemCmdArgs, [&](auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = std::string(result.message.c_str());
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::getVariant(std::string* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    *_aidl_return = "";
+    auto ret = service_->getVariant([&](auto& variant, auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = std::string(variant.c_str());
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::getOffModeChargeState(bool* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    *_aidl_return = false;
+    auto ret = service_->getOffModeChargeState([&](auto state, auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = state;
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::getBatteryVoltageFlashingThreshold(int32_t* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    *_aidl_return = 0;
+    auto ret = service_->getBatteryVoltageFlashingThreshold([&](auto batteryVoltage, auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = batteryVoltage;
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::doOemSpecificErase() {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    auto ret = service_->doOemSpecificErase([&](auto& result) { out_result = result; });
+    return ResultToAStatus(out_result);
+}
+
+}  // namespace fastboot
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/fastboot/aidl/fastbootshim/include/fastbootshim.h b/fastboot/aidl/fastbootshim/include/fastbootshim.h
new file mode 100644
index 0000000..410a03e
--- /dev/null
+++ b/fastboot/aidl/fastbootshim/include/fastbootshim.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/fastboot/BnFastboot.h>
+#include <android/hardware/fastboot/1.1/IFastboot.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace fastboot {
+// Shim that wraps HIDL IFastboot with AIDL BnFastboot
+class FastbootShim : public BnFastboot {
+    using HidlFastboot = ::android::hardware::fastboot::V1_1::IFastboot;
+
+  public:
+    explicit FastbootShim(const ::android::sp<HidlFastboot>& service);
+    ::ndk::ScopedAStatus doOemCommand(const std::string& in_oemCmd,
+                                      std::string* _aidl_return) override;
+    ::ndk::ScopedAStatus doOemSpecificErase() override;
+    ::ndk::ScopedAStatus getBatteryVoltageFlashingThreshold(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getOffModeChargeState(bool* _aidl_return) override;
+    ::ndk::ScopedAStatus getPartitionType(
+            const std::string& in_partitionName,
+            ::aidl::android::hardware::fastboot::FileSystemType* _aidl_return) override;
+    ::ndk::ScopedAStatus getVariant(std::string* _aidl_return) override;
+
+  private:
+    ::android::sp<HidlFastboot> service_;
+};
+
+}  // namespace fastboot
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/gatekeeper/1.0/default/OWNERS b/gatekeeper/1.0/default/OWNERS
index 335660d..c97fba6 100644
--- a/gatekeeper/1.0/default/OWNERS
+++ b/gatekeeper/1.0/default/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1124862
 jdanis@google.com
 swillden@google.com
diff --git a/gatekeeper/1.0/software/OWNERS b/gatekeeper/1.0/software/OWNERS
index 335660d..c97fba6 100644
--- a/gatekeeper/1.0/software/OWNERS
+++ b/gatekeeper/1.0/software/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 1124862
 jdanis@google.com
 swillden@google.com
diff --git a/gatekeeper/1.0/vts/OWNERS b/gatekeeper/1.0/vts/OWNERS
index 738c710..ee2af97 100644
--- a/gatekeeper/1.0/vts/OWNERS
+++ b/gatekeeper/1.0/vts/OWNERS
@@ -1,3 +1,3 @@
-jdanis@google.com
+# Bug component: 1124862
 swillden@google.com
 guangzhu@google.com
diff --git a/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp b/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
index f3fa0b4..e938b01 100644
--- a/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
+++ b/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
@@ -244,6 +244,47 @@
 }
 
 /**
+ * Ensure that passwords containing a NUL byte aren't truncated
+ */
+TEST_P(GatekeeperHidlTest, PasswordIsBinaryData) {
+  GatekeeperResponse enrollRsp;
+  GatekeeperResponse verifyRsp;
+  hidl_vec<uint8_t> rightPassword = {'A', 'B', 'C', '\0', 'D', 'E', 'F'};
+  hidl_vec<uint8_t> wrongPassword = {'A', 'B', 'C', '\0', '\0', '\0', '\0'};
+
+  ALOGI("Testing Enroll+Verify of password with embedded NUL (expected success)");
+  enrollNewPassword(rightPassword, enrollRsp, true);
+  verifyPassword(rightPassword, enrollRsp.data, 1, verifyRsp, true);
+
+  ALOGI("Testing Verify of wrong password (expected failure)");
+  verifyPassword(wrongPassword, enrollRsp.data, 1, verifyRsp, false);
+
+  ALOGI("PasswordIsBinaryData test done");
+}
+
+/**
+ * Ensure that long passwords aren't truncated
+ */
+TEST_P(GatekeeperHidlTest, LongPassword) {
+  GatekeeperResponse enrollRsp;
+  GatekeeperResponse verifyRsp;
+  hidl_vec<uint8_t> password;
+
+  password.resize(64); // maximum length used by Android
+  memset(password.data(), 'A', password.size());
+
+  ALOGI("Testing Enroll+Verify of long password (expected success)");
+  enrollNewPassword(password, enrollRsp, true);
+  verifyPassword(password, enrollRsp.data, 1, verifyRsp, true);
+
+  ALOGI("Testing Verify of wrong password (expected failure)");
+  password[password.size() - 1] ^= 1;
+  verifyPassword(password, enrollRsp.data, 1, verifyRsp, false);
+
+  ALOGI("LongPassword test done");
+}
+
+/**
  * Ensure we can securely update password (keep the same
  * secure user_id) if we prove we know old password
  */
diff --git a/gatekeeper/OWNERS b/gatekeeper/OWNERS
new file mode 100644
index 0000000..5262dce
--- /dev/null
+++ b/gatekeeper/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 1124862
+drysdale@google.com
+guangzhu@google.com
+oarbildo@google.com
+subrahmanyaman@google.com
+swillden@google.com
diff --git a/gatekeeper/aidl/Android.bp b/gatekeeper/aidl/Android.bp
new file mode 100644
index 0000000..b050f6a
--- /dev/null
+++ b/gatekeeper/aidl/Android.bp
@@ -0,0 +1,37 @@
+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"],
+}
+
+aidl_interface {
+    name: "android.hardware.gatekeeper",
+    vendor_available: true,
+    imports: [
+        "android.hardware.security.keymint-V3",
+    ],
+    srcs: ["android/hardware/gatekeeper/*.aidl"],
+    stability: "vintf",
+    backend: {
+        java: {
+            platform_apis: true,
+        },
+        ndk: {
+            apps_enabled: false,
+        },
+        cpp: {
+            enabled: false,
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.security.keymint-V3"],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/.hash b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/.hash
new file mode 100644
index 0000000..f06e62b
--- /dev/null
+++ b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/.hash
@@ -0,0 +1 @@
+d877e8a1608a00fd9068bcd7e69ea480a7ea17f0
diff --git a/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/android/hardware/gatekeeper/GatekeeperEnrollResponse.aidl b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/android/hardware/gatekeeper/GatekeeperEnrollResponse.aidl
new file mode 100644
index 0000000..ae64ffc
--- /dev/null
+++ b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/android/hardware/gatekeeper/GatekeeperEnrollResponse.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gatekeeper;
+@VintfStability
+parcelable GatekeeperEnrollResponse {
+  int statusCode;
+  int timeoutMs;
+  long secureUserId;
+  byte[] data;
+}
diff --git a/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/android/hardware/gatekeeper/GatekeeperVerifyResponse.aidl b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/android/hardware/gatekeeper/GatekeeperVerifyResponse.aidl
new file mode 100644
index 0000000..f55da30
--- /dev/null
+++ b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/android/hardware/gatekeeper/GatekeeperVerifyResponse.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gatekeeper;
+@VintfStability
+parcelable GatekeeperVerifyResponse {
+  int statusCode;
+  int timeoutMs;
+  android.hardware.security.keymint.HardwareAuthToken hardwareAuthToken;
+}
diff --git a/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/android/hardware/gatekeeper/IGatekeeper.aidl b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/android/hardware/gatekeeper/IGatekeeper.aidl
new file mode 100644
index 0000000..ab74615
--- /dev/null
+++ b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/1/android/hardware/gatekeeper/IGatekeeper.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gatekeeper;
+@SensitiveData @VintfStability
+interface IGatekeeper {
+  void deleteAllUsers();
+  void deleteUser(in int uid);
+  android.hardware.gatekeeper.GatekeeperEnrollResponse enroll(in int uid, in byte[] currentPasswordHandle, in byte[] currentPassword, in byte[] desiredPassword);
+  android.hardware.gatekeeper.GatekeeperVerifyResponse verify(in int uid, in long challenge, in byte[] enrolledPasswordHandle, in byte[] providedPassword);
+  const int STATUS_REENROLL = 1;
+  const int STATUS_OK = 0;
+  const int ERROR_GENERAL_FAILURE = (-1) /* -1 */;
+  const int ERROR_RETRY_TIMEOUT = (-2) /* -2 */;
+  const int ERROR_NOT_IMPLEMENTED = (-3) /* -3 */;
+}
diff --git a/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/current/android/hardware/gatekeeper/GatekeeperEnrollResponse.aidl b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/current/android/hardware/gatekeeper/GatekeeperEnrollResponse.aidl
new file mode 100644
index 0000000..ae64ffc
--- /dev/null
+++ b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/current/android/hardware/gatekeeper/GatekeeperEnrollResponse.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gatekeeper;
+@VintfStability
+parcelable GatekeeperEnrollResponse {
+  int statusCode;
+  int timeoutMs;
+  long secureUserId;
+  byte[] data;
+}
diff --git a/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/current/android/hardware/gatekeeper/GatekeeperVerifyResponse.aidl b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/current/android/hardware/gatekeeper/GatekeeperVerifyResponse.aidl
new file mode 100644
index 0000000..f55da30
--- /dev/null
+++ b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/current/android/hardware/gatekeeper/GatekeeperVerifyResponse.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gatekeeper;
+@VintfStability
+parcelable GatekeeperVerifyResponse {
+  int statusCode;
+  int timeoutMs;
+  android.hardware.security.keymint.HardwareAuthToken hardwareAuthToken;
+}
diff --git a/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/current/android/hardware/gatekeeper/IGatekeeper.aidl b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/current/android/hardware/gatekeeper/IGatekeeper.aidl
new file mode 100644
index 0000000..1a6f1ff
--- /dev/null
+++ b/gatekeeper/aidl/aidl_api/android.hardware.gatekeeper/current/android/hardware/gatekeeper/IGatekeeper.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gatekeeper;
+@SensitiveData @VintfStability
+interface IGatekeeper {
+  void deleteAllUsers();
+  void deleteUser(in int uid);
+  android.hardware.gatekeeper.GatekeeperEnrollResponse enroll(in int uid, in byte[] currentPasswordHandle, in byte[] currentPassword, in byte[] desiredPassword);
+  android.hardware.gatekeeper.GatekeeperVerifyResponse verify(in int uid, in long challenge, in byte[] enrolledPasswordHandle, in byte[] providedPassword);
+  const int STATUS_REENROLL = 1;
+  const int STATUS_OK = 0;
+  const int ERROR_GENERAL_FAILURE = -1;
+  const int ERROR_RETRY_TIMEOUT = -2;
+  const int ERROR_NOT_IMPLEMENTED = -3;
+}
diff --git a/gatekeeper/aidl/android/hardware/gatekeeper/GatekeeperEnrollResponse.aidl b/gatekeeper/aidl/android/hardware/gatekeeper/GatekeeperEnrollResponse.aidl
new file mode 100644
index 0000000..227210b
--- /dev/null
+++ b/gatekeeper/aidl/android/hardware/gatekeeper/GatekeeperEnrollResponse.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gatekeeper;
+
+/**
+ * Gatekeeper response to enroll requests has this structure as mandatory part
+ */
+@VintfStability
+parcelable GatekeeperEnrollResponse {
+    /**
+     * Request completion status. The status code can be IGatekeeper::STATUS_OK
+     * or IGatekeeper::ERROR_RETRY_TIMEOUT.
+     */
+    int statusCode;
+    /**
+     * Retry timeout in ms, if code == IGatekeeper::ERROR_RETRY_TIMEOUT
+     * otherwise unused (0)
+     */
+    int timeoutMs;
+    /**
+     * secure user id.
+     */
+    long secureUserId;
+    /**
+     * optional crypto blob. Opaque to Android system.
+     */
+    byte[] data;
+}
diff --git a/gatekeeper/aidl/android/hardware/gatekeeper/GatekeeperVerifyResponse.aidl b/gatekeeper/aidl/android/hardware/gatekeeper/GatekeeperVerifyResponse.aidl
new file mode 100644
index 0000000..f8dbeeb
--- /dev/null
+++ b/gatekeeper/aidl/android/hardware/gatekeeper/GatekeeperVerifyResponse.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gatekeeper;
+
+import android.hardware.security.keymint.HardwareAuthToken;
+
+/**
+ * Gatekeeper response to verify requests has this structure as mandatory part
+ */
+@VintfStability
+parcelable GatekeeperVerifyResponse {
+    /**
+     * Request completion status. The status code can be IGatekeeper::STATUS_OK
+     * or IGatekeeper::ERROR_RETRY_TIMEOUT or IGatekeeper::STATUS_REENROLL.
+     */
+    int statusCode;
+    /**
+     * Retry timeout in ms, if code == IGatekeeper::ERROR_RETRY_TIMEOUT
+     * otherwise unused (0)
+     */
+    int timeoutMs;
+    /**
+     * On successful verification of the password,
+     * IGatekeeper implementations must return hardware auth token
+     * in the response.
+     */
+    HardwareAuthToken hardwareAuthToken;
+}
diff --git a/gatekeeper/aidl/android/hardware/gatekeeper/IGatekeeper.aidl b/gatekeeper/aidl/android/hardware/gatekeeper/IGatekeeper.aidl
new file mode 100644
index 0000000..215c6e6
--- /dev/null
+++ b/gatekeeper/aidl/android/hardware/gatekeeper/IGatekeeper.aidl
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gatekeeper;
+
+import android.hardware.gatekeeper.GatekeeperEnrollResponse;
+import android.hardware.gatekeeper.GatekeeperVerifyResponse;
+
+@VintfStability
+@SensitiveData
+interface IGatekeeper {
+    /**
+     * enroll and verify binder calls may return a ServiceSpecificException
+     * with the following error codes.
+     */
+    /* Success, but upper layers should re-enroll the verified password due to a version change. */
+    const int STATUS_REENROLL = 1;
+    /* operation is successful */
+    const int STATUS_OK = 0;
+    /* operation failed. */
+    const int ERROR_GENERAL_FAILURE = -1;
+    /* operation should  be retried after timeout. */
+    const int ERROR_RETRY_TIMEOUT = -2;
+    /* operation is not implemented. */
+    const int ERROR_NOT_IMPLEMENTED = -3;
+
+    /**
+     * Deletes all the enrolled_password_handles for all uid's. Once called,
+     * no users must be enrolled on the device.
+     * This is an optional method.
+     *
+     * Service status return:
+     *
+     * OK if all the users are deleted successfully.
+     * ERROR_GENERAL_FAILURE on failure.
+     * ERROR_NOT_IMPLEMENTED if not implemented.
+     */
+    void deleteAllUsers();
+
+    /**
+     * Deletes the enrolledPasswordHandle associated with the uid. Once deleted
+     * the user cannot be verified anymore.
+     * This is an optional method.
+     *
+     * Service status return:
+     *
+     * OK if user is deleted successfully.
+     * ERROR_GENERAL_FAILURE on failure.
+     * ERROR_NOT_IMPLEMENTED if not implemented.
+     *
+     * @param uid The Android user identifier
+     */
+    void deleteUser(in int uid);
+
+    /**
+     * Enrolls desiredPassword, which may be derived from a user selected pin
+     * or password, with the private key used only for enrolling authentication
+     * factor data.
+     *
+     * If there was already a password enrolled, current password handle must be
+     * passed in currentPasswordHandle, and current password must be passed in
+     * currentPassword. Valid currentPassword must verify() against
+     * currentPasswordHandle.
+     *
+     * Service status return:
+     *
+     * OK if password is enrolled successfully.
+     * ERROR_GENERAL_FAILURE on failure.
+     * ERROR_NOT_IMPLEMENTED if not implemented.
+     *
+     * @param uid The Android user identifier
+     *
+     * @param currentPasswordHandle The currently enrolled password handle the user
+     *    wants to replace. May be empty only if there's no currently enrolled
+     *    password. Otherwise must be non-empty.
+     *
+     * @param currentPassword The user's current password in plain text.
+     *    it MUST verify against current_password_handle if the latter is not-empty
+     *
+     * @param desiredPassword The new password the user wishes to enroll in
+     *    plaintext.
+     *
+     * @return
+     *    On success, data buffer must contain the new password handle referencing
+     *    the password provided in desiredPassword.
+     *    This buffer can be used on subsequent calls to enroll or
+     *    verify. response.statusCode must contain either ERROR_RETRY_TIMEOUT or
+     *    STATUS_OK. On error, this buffer must be empty. This method may return
+     *    ERROR_GENERAL_FAILURE on failure.
+     *    If ERROR_RETRY_TIMEOUT is returned, response.timeout must be non-zero.
+     */
+    GatekeeperEnrollResponse enroll(in int uid, in byte[] currentPasswordHandle,
+            in byte[] currentPassword, in byte[] desiredPassword);
+
+    /**
+     * Verifies that providedPassword matches enrolledPasswordHandle.
+     *
+     * Implementations of this module may retain the result of this call
+     * to attest to the recency of authentication.
+     *
+     * On success, returns verification token in response.data, which shall be
+     * usable to attest password verification to other trusted services.
+     *
+     * Service status return:
+     *
+     * OK if password is enrolled successfully.
+     * ERROR_GENERAL_FAILURE on failure.
+     * ERROR_NOT_IMPLEMENTED if not implemented.
+     *
+     * @param uid The Android user identifier
+     *
+     * @param challenge An optional challenge to authenticate against, or 0.
+     *    Used when a separate authenticator requests password verification,
+     *    or for transactional password authentication.
+     *
+     * @param enrolledPasswordHandle The currently enrolled password handle that
+     *    user wishes to verify against. Must be non-empty.
+     *
+     * @param providedPassword The plaintext password to be verified against the
+     *    enrolledPasswordHandle
+     *
+     * @return
+     *    On success, a HardwareAuthToken resulting from this verification is returned.
+     *    response.statusCode must contain either ERROR_RETRY_TIMEOUT or
+     *    or STATUS_REENROLL or STATUS_OK.
+     *    On error, data buffer must be empty.
+     *    This method may return ERROR_GENERAL_FAILURE on failure.
+     *    If password re-enrollment is necessary, it must return STATUS_REENROLL.
+     *    If ERROR_RETRY_TIMEOUT is returned, response.timeout must be non-zero.
+     */
+    GatekeeperVerifyResponse verify(in int uid, in long challenge, in byte[] enrolledPasswordHandle,
+            in byte[] providedPassword);
+}
diff --git a/gatekeeper/aidl/vts/functional/Android.bp b/gatekeeper/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..008f25c
--- /dev/null
+++ b/gatekeeper/aidl/vts/functional/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalGatekeeperTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+        "keymint_use_latest_hal_aidl_ndk_static",
+    ],
+    srcs: ["VtsHalGatekeeperTargetTest.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+        "libbase",
+    ],
+    static_libs: [
+        "android.hardware.gatekeeper-V1-ndk",
+        "android.hardware.security.secureclock-V1-ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/gatekeeper/aidl/vts/functional/VtsHalGatekeeperTargetTest.cpp b/gatekeeper/aidl/vts/functional/VtsHalGatekeeperTargetTest.cpp
new file mode 100644
index 0000000..c89243b
--- /dev/null
+++ b/gatekeeper/aidl/vts/functional/VtsHalGatekeeperTargetTest.cpp
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "gatekeeper_aidl_hal_test"
+
+#include <inttypes.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <cmath>
+#include <string>
+#include <vector>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/gatekeeper/GatekeeperEnrollResponse.h>
+#include <aidl/android/hardware/gatekeeper/GatekeeperVerifyResponse.h>
+#include <aidl/android/hardware/gatekeeper/IGatekeeper.h>
+#include <aidl/android/hardware/security/keymint/HardwareAuthToken.h>
+#include <android-base/endian.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <hardware/hw_auth_token.h>
+
+#include <log/log.h>
+
+using aidl::android::hardware::gatekeeper::GatekeeperEnrollResponse;
+using aidl::android::hardware::gatekeeper::GatekeeperVerifyResponse;
+using aidl::android::hardware::gatekeeper::IGatekeeper;
+using aidl::android::hardware::security::keymint::HardwareAuthToken;
+using Status = ::ndk::ScopedAStatus;
+
+struct GatekeeperRequest {
+    uint32_t uid;
+    uint64_t challenge;
+    std::vector<uint8_t> curPwdHandle;
+    std::vector<uint8_t> curPwd;
+    std::vector<uint8_t> newPwd;
+    GatekeeperRequest() : uid(0), challenge(0) {}
+};
+
+// ASSERT_* macros generate return "void" internally
+// we have to use EXPECT_* if we return anything but "void"
+static void verifyAuthToken(GatekeeperVerifyResponse& rsp) {
+    uint32_t auth_type = static_cast<uint32_t>(rsp.hardwareAuthToken.authenticatorType);
+    uint64_t auth_tstamp = static_cast<uint64_t>(rsp.hardwareAuthToken.timestamp.milliSeconds);
+
+    EXPECT_EQ(HW_AUTH_PASSWORD, auth_type);
+    EXPECT_NE(UINT64_C(~0), auth_tstamp);
+    ALOGI("Authenticator ID: %016" PRIX64, rsp.hardwareAuthToken.authenticatorId);
+    EXPECT_NE(UINT32_C(0), rsp.hardwareAuthToken.userId);
+}
+
+// The main test class for Gatekeeper AIDL HAL.
+class GatekeeperAidlTest : public ::testing::TestWithParam<std::string> {
+  protected:
+    void setUid(uint32_t uid) { uid_ = uid; }
+
+    Status doEnroll(GatekeeperRequest& req, GatekeeperEnrollResponse& rsp) {
+        Status ret;
+        while (true) {
+            ret = gatekeeper_->enroll(uid_, req.curPwdHandle, req.curPwd, req.newPwd, &rsp);
+            if (ret.isOk()) break;
+            if (getReturnStatusCode(ret) != IGatekeeper::ERROR_RETRY_TIMEOUT) break;
+            ALOGI("%s: got retry code; retrying in 1 sec", __func__);
+            sleep(1);
+        }
+        return ret;
+    }
+
+    Status doVerify(GatekeeperRequest& req, GatekeeperVerifyResponse& rsp) {
+        Status ret;
+        while (true) {
+            ret = gatekeeper_->verify(uid_, req.challenge, req.curPwdHandle, req.newPwd, &rsp);
+            if (ret.isOk()) break;
+            if (getReturnStatusCode(ret) != IGatekeeper::ERROR_RETRY_TIMEOUT) break;
+            ALOGI("%s: got retry code; retrying in 1 sec", __func__);
+            sleep(1);
+        }
+        return ret;
+    }
+
+    Status doDeleteUser() { return gatekeeper_->deleteUser(uid_); }
+
+    Status doDeleteAllUsers() { return gatekeeper_->deleteAllUsers(); }
+
+    void generatePassword(std::vector<uint8_t>& password, uint8_t seed) {
+        password.resize(16);
+        memset(password.data(), seed, password.size());
+    }
+
+    void checkEnroll(GatekeeperEnrollResponse& rsp, Status& ret, bool expectSuccess) {
+        if (expectSuccess) {
+            EXPECT_TRUE(ret.isOk());
+            EXPECT_EQ(IGatekeeper::STATUS_OK, rsp.statusCode);
+            EXPECT_NE(nullptr, rsp.data.data());
+            EXPECT_GT(rsp.data.size(), UINT32_C(0));
+            EXPECT_NE(UINT32_C(0), rsp.secureUserId);
+        } else {
+            EXPECT_EQ(IGatekeeper::ERROR_GENERAL_FAILURE, getReturnStatusCode(ret));
+            EXPECT_EQ(UINT32_C(0), rsp.data.size());
+        }
+    }
+
+    void checkVerify(GatekeeperVerifyResponse& rsp, Status& ret, uint64_t challenge,
+                     bool expectSuccess) {
+        if (expectSuccess) {
+            EXPECT_TRUE(ret.isOk());
+            EXPECT_GE(rsp.statusCode, IGatekeeper::STATUS_OK);
+            EXPECT_LE(rsp.statusCode, IGatekeeper::STATUS_REENROLL);
+
+            verifyAuthToken(rsp);
+            EXPECT_EQ(challenge, rsp.hardwareAuthToken.challenge);
+        } else {
+            EXPECT_EQ(IGatekeeper::ERROR_GENERAL_FAILURE, getReturnStatusCode(ret));
+        }
+    }
+
+    void enrollNewPassword(std::vector<uint8_t>& password, GatekeeperEnrollResponse& rsp,
+                           bool expectSuccess) {
+        GatekeeperRequest req;
+        req.newPwd = password;
+        Status ret = doEnroll(req, rsp);
+        checkEnroll(rsp, ret, expectSuccess);
+    }
+
+    void verifyPassword(std::vector<uint8_t>& password, std::vector<uint8_t>& passwordHandle,
+                        uint64_t challenge, GatekeeperVerifyResponse& verifyRsp,
+                        bool expectSuccess) {
+        GatekeeperRequest verifyReq;
+
+        // build verify request for the same password (we want it to succeed)
+        verifyReq.newPwd = password;
+        // use enrolled password handle we've got
+        verifyReq.curPwdHandle = passwordHandle;
+        verifyReq.challenge = challenge;
+        Status ret = doVerify(verifyReq, verifyRsp);
+        checkVerify(verifyRsp, ret, challenge, expectSuccess);
+    }
+
+    int32_t getReturnStatusCode(const Status& result) {
+        if (!result.isOk()) {
+            if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
+                return result.getServiceSpecificError();
+            }
+            return IGatekeeper::ERROR_GENERAL_FAILURE;
+        }
+        return IGatekeeper::STATUS_OK;
+    }
+
+  protected:
+    std::shared_ptr<IGatekeeper> gatekeeper_;
+    uint32_t uid_;
+
+  public:
+    GatekeeperAidlTest() : uid_(0) {}
+    virtual void SetUp() override {
+        gatekeeper_ = IGatekeeper::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(nullptr, gatekeeper_.get());
+        doDeleteAllUsers();
+    }
+
+    virtual void TearDown() override { doDeleteAllUsers(); }
+};
+
+/**
+ * Ensure we can enroll new password
+ */
+TEST_P(GatekeeperAidlTest, EnrollSuccess) {
+    std::vector<uint8_t> password;
+    GatekeeperEnrollResponse rsp;
+    ALOGI("Testing Enroll (expected success)");
+    generatePassword(password, 0);
+    enrollNewPassword(password, rsp, true);
+    ALOGI("Testing Enroll done");
+}
+
+/**
+ * Ensure we can not enroll empty password
+ */
+TEST_P(GatekeeperAidlTest, EnrollNoPassword) {
+    std::vector<uint8_t> password;
+    GatekeeperEnrollResponse rsp;
+    ALOGI("Testing Enroll (expected failure)");
+    enrollNewPassword(password, rsp, false);
+    ALOGI("Testing Enroll done");
+}
+
+/**
+ * Ensure we can successfully verify previously enrolled password
+ */
+TEST_P(GatekeeperAidlTest, VerifySuccess) {
+    GatekeeperEnrollResponse enrollRsp;
+    GatekeeperVerifyResponse verifyRsp;
+    std::vector<uint8_t> password;
+
+    ALOGI("Testing Enroll+Verify (expected success)");
+    generatePassword(password, 0);
+    enrollNewPassword(password, enrollRsp, true);
+    verifyPassword(password, enrollRsp.data, 1, verifyRsp, true);
+
+    ALOGI("Testing unenrolled password doesn't verify");
+    verifyRsp = {0, 0, {}};
+    generatePassword(password, 1);
+    verifyPassword(password, enrollRsp.data, 1, verifyRsp, false);
+    ALOGI("Testing Enroll+Verify done");
+}
+
+/**
+ * Ensure we can securely update password (keep the same
+ * secure user_id) if we prove we know old password
+ */
+TEST_P(GatekeeperAidlTest, TrustedReenroll) {
+    GatekeeperEnrollResponse enrollRsp;
+    GatekeeperRequest reenrollReq;
+    GatekeeperEnrollResponse reenrollRsp;
+    GatekeeperVerifyResponse verifyRsp;
+    GatekeeperVerifyResponse reenrollVerifyRsp;
+    std::vector<uint8_t> password;
+    std::vector<uint8_t> newPassword;
+
+    generatePassword(password, 0);
+
+    ALOGI("Testing Trusted Reenroll (expected success)");
+    enrollNewPassword(password, enrollRsp, true);
+    verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
+    ALOGI("Primary Enroll+Verify done");
+
+    generatePassword(newPassword, 1);
+    reenrollReq.newPwd = newPassword;
+    reenrollReq.curPwd = password;
+    reenrollReq.curPwdHandle = enrollRsp.data;
+
+    Status ret = doEnroll(reenrollReq, reenrollRsp);
+    checkEnroll(reenrollRsp, ret, true);
+    verifyPassword(newPassword, reenrollRsp.data, 0, reenrollVerifyRsp, true);
+    ALOGI("Trusted ReEnroll+Verify done");
+
+    verifyAuthToken(verifyRsp);
+    verifyAuthToken(reenrollVerifyRsp);
+    EXPECT_EQ(verifyRsp.hardwareAuthToken.userId, reenrollVerifyRsp.hardwareAuthToken.userId);
+    ALOGI("Testing Trusted Reenroll done");
+}
+
+/**
+ * Ensure we can update password (and get new
+ * secure user_id) if we don't know old password
+ */
+TEST_P(GatekeeperAidlTest, UntrustedReenroll) {
+    GatekeeperEnrollResponse enrollRsp;
+    GatekeeperEnrollResponse reenrollRsp;
+    GatekeeperVerifyResponse verifyRsp;
+    GatekeeperVerifyResponse reenrollVerifyRsp;
+    std::vector<uint8_t> password;
+    std::vector<uint8_t> newPassword;
+
+    ALOGI("Testing Untrusted Reenroll (expected success)");
+    generatePassword(password, 0);
+    enrollNewPassword(password, enrollRsp, true);
+    verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
+    ALOGI("Primary Enroll+Verify done");
+
+    generatePassword(newPassword, 1);
+    enrollNewPassword(newPassword, reenrollRsp, true);
+    verifyPassword(newPassword, reenrollRsp.data, 0, reenrollVerifyRsp, true);
+    ALOGI("Untrusted ReEnroll+Verify done");
+
+    verifyAuthToken(verifyRsp);
+    verifyAuthToken(reenrollVerifyRsp);
+    EXPECT_NE(verifyRsp.hardwareAuthToken.userId, reenrollVerifyRsp.hardwareAuthToken.userId);
+    ALOGI("Testing Untrusted Reenroll done");
+}
+
+/**
+ * Ensure we don't get successful verify with invalid data
+ */
+TEST_P(GatekeeperAidlTest, VerifyNoData) {
+    std::vector<uint8_t> password;
+    std::vector<uint8_t> passwordHandle;
+    GatekeeperVerifyResponse verifyRsp;
+
+    ALOGI("Testing Verify (expected failure)");
+    verifyPassword(password, passwordHandle, 0, verifyRsp, false);
+    ALOGI("Testing Verify done");
+}
+
+/**
+ * Ensure we can not verify password after we enrolled it and then deleted user
+ */
+TEST_P(GatekeeperAidlTest, DeleteUserTest) {
+    std::vector<uint8_t> password;
+    GatekeeperEnrollResponse enrollRsp;
+    GatekeeperVerifyResponse verifyRsp;
+    ALOGI("Testing deleteUser (expected success)");
+    setUid(10001);
+    generatePassword(password, 0);
+    enrollNewPassword(password, enrollRsp, true);
+    verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
+    ALOGI("Enroll+Verify done");
+    auto result = doDeleteUser();
+    EXPECT_TRUE(result.isOk() ||
+                (getReturnStatusCode(result) == IGatekeeper::ERROR_NOT_IMPLEMENTED));
+    ALOGI("DeleteUser done");
+    if (result.isOk()) {
+        verifyRsp = {0, 0, {}};
+        verifyPassword(password, enrollRsp.data, 0, verifyRsp, false);
+        ALOGI("Verify after Delete done (must fail)");
+    }
+    ALOGI("Testing deleteUser done: rsp=%" PRIi32, getReturnStatusCode(result));
+}
+
+/**
+ * Ensure we can not delete a user that does not exist
+ */
+TEST_P(GatekeeperAidlTest, DeleteInvalidUserTest) {
+    std::vector<uint8_t> password;
+    GatekeeperEnrollResponse enrollRsp;
+    GatekeeperVerifyResponse verifyRsp;
+    ALOGI("Testing deleteUser (expected failure)");
+    setUid(10002);
+    generatePassword(password, 0);
+    enrollNewPassword(password, enrollRsp, true);
+    verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
+    ALOGI("Enroll+Verify done");
+
+    // Delete the user
+    Status result1 = doDeleteUser();
+    EXPECT_TRUE(result1.isOk() ||
+                (getReturnStatusCode(result1) == IGatekeeper::ERROR_NOT_IMPLEMENTED));
+
+    // Delete the user again
+    Status result2 = doDeleteUser();
+    int32_t retCode2 = getReturnStatusCode(result2);
+    EXPECT_TRUE((retCode2 == IGatekeeper::ERROR_NOT_IMPLEMENTED) ||
+                (retCode2 == IGatekeeper::ERROR_GENERAL_FAILURE));
+    ALOGI("DeleteUser done");
+    ALOGI("Testing deleteUser done: rsp=%" PRIi32, retCode2);
+}
+
+/**
+ * Ensure we can not verify passwords after we enrolled them and then deleted
+ * all users
+ */
+TEST_P(GatekeeperAidlTest, DeleteAllUsersTest) {
+    struct UserData {
+        uint32_t userId;
+        std::vector<uint8_t> password;
+        GatekeeperEnrollResponse enrollRsp;
+        GatekeeperVerifyResponse verifyRsp;
+        UserData(int id) { userId = id; }
+    } users[3]{10001, 10002, 10003};
+    ALOGI("Testing deleteAllUsers (expected success)");
+
+    // enroll multiple users
+    for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
+        setUid(users[i].userId);
+        generatePassword(users[i].password, (i % 255) + 1);
+        enrollNewPassword(users[i].password, users[i].enrollRsp, true);
+    }
+    ALOGI("Multiple users enrolled");
+
+    // verify multiple users
+    for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
+        setUid(users[i].userId);
+        verifyPassword(users[i].password, users[i].enrollRsp.data, 0, users[i].verifyRsp, true);
+    }
+    ALOGI("Multiple users verified");
+
+    Status result = doDeleteAllUsers();
+    EXPECT_TRUE(result.isOk() ||
+                (getReturnStatusCode(result) == IGatekeeper::ERROR_NOT_IMPLEMENTED));
+    ALOGI("All users deleted");
+
+    if (result.isOk()) {
+        // verify multiple users after they are deleted; all must fail
+        for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
+            setUid(users[i].userId);
+            users[i].verifyRsp = {0, 0, {}};
+            verifyPassword(users[i].password, users[i].enrollRsp.data, 0, users[i].verifyRsp,
+                           false);
+        }
+        ALOGI("Multiple users verified after delete (all must fail)");
+    }
+
+    ALOGI("Testing deleteAllUsers done: rsp=%" PRIi32, getReturnStatusCode(result));
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GatekeeperAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+    PerInstance, GatekeeperAidlTest,
+    testing::ValuesIn(android::getAidlHalInstanceNames(IGatekeeper::descriptor)),
+    android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/gnss/1.0/IGnssCallback.hal b/gnss/1.0/IGnssCallback.hal
index 311ab21..512763e 100644
--- a/gnss/1.0/IGnssCallback.hal
+++ b/gnss/1.0/IGnssCallback.hal
@@ -37,7 +37,13 @@
         MSA                             = 1 << 2,
         /** GNSS supports single-shot fixes */
         SINGLE_SHOT                     = 1 << 3,
-        /** GNSS supports on demand time injection */
+        /**
+         * The platform periodically injects time to GNSS in addition to
+         * on-demand and occasional time updates.
+         *
+         * Note: The naming of "on demand" should be "periodic" instead.  This
+         * is the result of a historic implementation bug, b/73893222.
+         */
         ON_DEMAND_TIME                  = 1 << 4,
         /** GNSS supports Geofencing  */
         GEOFENCING                      = 1 << 5,
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index a73182e..300e8de 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-V2-ndk",
+        "android.hardware.gnss-V3-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/1.1/vts/functional/Android.bp b/gnss/1.1/vts/functional/Android.bp
index f8fad94..2414cbc 100644
--- a/gnss/1.1/vts/functional/Android.bp
+++ b/gnss/1.1/vts/functional/Android.bp
@@ -36,7 +36,7 @@
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@common-vts-lib",
-        "android.hardware.gnss-V2-cpp",
+        "android.hardware.gnss-V3-cpp",
     ],
     shared_libs: [
         "android.hardware.gnss.measurement_corrections@1.0",
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 769e8ae..83bc2cc 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-V2-ndk",
+        "android.hardware.gnss-V3-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp
index 2042dd9..e8db886 100644
--- a/gnss/2.0/vts/functional/Android.bp
+++ b/gnss/2.0/vts/functional/Android.bp
@@ -39,7 +39,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@2.1",
         "android.hardware.gnss@common-vts-lib",
-        "android.hardware.gnss-V2-cpp",
+        "android.hardware.gnss-V3-cpp",
     ],
     test_suites: [
         "general-tests",
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
index 2979f5c..4a4ce54 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-V2-ndk",
+        "android.hardware.gnss-V3-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp
index d7b6eeb..76f9d07 100644
--- a/gnss/2.1/vts/functional/Android.bp
+++ b/gnss/2.1/vts/functional/Android.bp
@@ -40,7 +40,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@2.1",
         "android.hardware.gnss@common-vts-lib",
-        "android.hardware.gnss-V2-cpp",
+        "android.hardware.gnss-V3-cpp",
     ],
     shared_libs: [
         "libvintf",
diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp
index 9f9090c..cb2c001 100644
--- a/gnss/aidl/Android.bp
+++ b/gnss/aidl/Android.bp
@@ -36,11 +36,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
@@ -51,7 +46,12 @@
             version: "2",
             imports: [],
         },
+        {
+            version: "3",
+            imports: [],
+        },
 
     ],
+    frozen: true,
 
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/.hash b/gnss/aidl/aidl_api/android.hardware.gnss/3/.hash
new file mode 100644
index 0000000..06d0e5d
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/.hash
@@ -0,0 +1 @@
+747fa8b8b4bb55d21f2c42446dd1b31de1dfbeaa
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/BlocklistedSource.aidl
new file mode 100644
index 0000000..ccb2b28
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/BlocklistedSource.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable BlocklistedSource {
+  android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN;
+  int svid;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/CorrelationVector.aidl
new file mode 100644
index 0000000..b959003
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/CorrelationVector.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable CorrelationVector {
+  double frequencyOffsetMps;
+  double samplingWidthM;
+  double samplingStartM;
+  int[] magnitude;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/ElapsedRealtime.aidl
new file mode 100644
index 0000000..5d7f51e
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/ElapsedRealtime.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable ElapsedRealtime {
+  int flags;
+  long timestampNs;
+  double timeUncertaintyNs;
+  const int HAS_TIMESTAMP_NS = (1 << 0) /* 1 */;
+  const int HAS_TIME_UNCERTAINTY_NS = (1 << 1) /* 2 */;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssClock.aidl
new file mode 100644
index 0000000..63edd44
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssClock.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable GnssClock {
+  int gnssClockFlags;
+  int leapSecond;
+  long timeNs;
+  double timeUncertaintyNs;
+  long fullBiasNs;
+  double biasNs;
+  double biasUncertaintyNs;
+  double driftNsps;
+  double driftUncertaintyNsps;
+  int hwClockDiscontinuityCount;
+  android.hardware.gnss.GnssSignalType referenceSignalTypeForIsb;
+  const int HAS_LEAP_SECOND = (1 << 0) /* 1 */;
+  const int HAS_TIME_UNCERTAINTY = (1 << 1) /* 2 */;
+  const int HAS_FULL_BIAS = (1 << 2) /* 4 */;
+  const int HAS_BIAS = (1 << 3) /* 8 */;
+  const int HAS_BIAS_UNCERTAINTY = (1 << 4) /* 16 */;
+  const int HAS_DRIFT = (1 << 5) /* 32 */;
+  const int HAS_DRIFT_UNCERTAINTY = (1 << 6) /* 64 */;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssConstellationType.aidl
new file mode 100644
index 0000000..fee2ef6
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssConstellationType.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.gnss;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum GnssConstellationType {
+  UNKNOWN = 0,
+  GPS = 1,
+  SBAS = 2,
+  GLONASS = 3,
+  QZSS = 4,
+  BEIDOU = 5,
+  GALILEO = 6,
+  IRNSS = 7,
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssData.aidl
new file mode 100644
index 0000000..54e3b21
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssData.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable GnssData {
+  android.hardware.gnss.GnssMeasurement[] measurements;
+  android.hardware.gnss.GnssClock clock;
+  android.hardware.gnss.ElapsedRealtime elapsedRealtime;
+  android.hardware.gnss.GnssData.GnssAgc[] gnssAgcs = {};
+  boolean isFullTracking;
+  @VintfStability
+  parcelable GnssAgc {
+    double agcLevelDb;
+    android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN;
+    long carrierFrequencyHz;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssLocation.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssLocation.aidl
new file mode 100644
index 0000000..e64d98a
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssLocation.aidl
@@ -0,0 +1,58 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+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 = 0x0001;
+  const int HAS_ALTITUDE = 0x0002;
+  const int HAS_SPEED = 0x0004;
+  const int HAS_BEARING = 0x0008;
+  const int HAS_HORIZONTAL_ACCURACY = 0x0010;
+  const int HAS_VERTICAL_ACCURACY = 0x0020;
+  const int HAS_SPEED_ACCURACY = 0x0040;
+  const int HAS_BEARING_ACCURACY = 0x0080;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssMeasurement.aidl
new file mode 100644
index 0000000..a2594af
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssMeasurement.aidl
@@ -0,0 +1,99 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable GnssMeasurement {
+  int flags;
+  int svid;
+  android.hardware.gnss.GnssSignalType signalType;
+  double timeOffsetNs;
+  int state;
+  long receivedSvTimeInNs;
+  long receivedSvTimeUncertaintyInNs;
+  double antennaCN0DbHz;
+  double basebandCN0DbHz;
+  double pseudorangeRateMps;
+  double pseudorangeRateUncertaintyMps;
+  int accumulatedDeltaRangeState;
+  double accumulatedDeltaRangeM;
+  double accumulatedDeltaRangeUncertaintyM;
+  long carrierCycles;
+  double carrierPhase;
+  double carrierPhaseUncertainty;
+  android.hardware.gnss.GnssMultipathIndicator multipathIndicator = android.hardware.gnss.GnssMultipathIndicator.UNKNOWN;
+  double snrDb;
+  double agcLevelDb;
+  double fullInterSignalBiasNs;
+  double fullInterSignalBiasUncertaintyNs;
+  double satelliteInterSignalBiasNs;
+  double satelliteInterSignalBiasUncertaintyNs;
+  android.hardware.gnss.SatellitePvt satellitePvt;
+  android.hardware.gnss.CorrelationVector[] correlationVectors;
+  const int HAS_SNR = (1 << 0) /* 1 */;
+  const int HAS_CARRIER_FREQUENCY = (1 << 9) /* 512 */;
+  const int HAS_CARRIER_CYCLES = (1 << 10) /* 1024 */;
+  const int HAS_CARRIER_PHASE = (1 << 11) /* 2048 */;
+  const int HAS_CARRIER_PHASE_UNCERTAINTY = (1 << 12) /* 4096 */;
+  const int HAS_AUTOMATIC_GAIN_CONTROL = (1 << 13) /* 8192 */;
+  const int HAS_FULL_ISB = (1 << 16) /* 65536 */;
+  const int HAS_FULL_ISB_UNCERTAINTY = (1 << 17) /* 131072 */;
+  const int HAS_SATELLITE_ISB = (1 << 18) /* 262144 */;
+  const int HAS_SATELLITE_ISB_UNCERTAINTY = (1 << 19) /* 524288 */;
+  const int HAS_SATELLITE_PVT = (1 << 20) /* 1048576 */;
+  const int HAS_CORRELATION_VECTOR = (1 << 21) /* 2097152 */;
+  const int STATE_UNKNOWN = 0;
+  const int STATE_CODE_LOCK = (1 << 0) /* 1 */;
+  const int STATE_BIT_SYNC = (1 << 1) /* 2 */;
+  const int STATE_SUBFRAME_SYNC = (1 << 2) /* 4 */;
+  const int STATE_TOW_DECODED = (1 << 3) /* 8 */;
+  const int STATE_MSEC_AMBIGUOUS = (1 << 4) /* 16 */;
+  const int STATE_SYMBOL_SYNC = (1 << 5) /* 32 */;
+  const int STATE_GLO_STRING_SYNC = (1 << 6) /* 64 */;
+  const int STATE_GLO_TOD_DECODED = (1 << 7) /* 128 */;
+  const int STATE_BDS_D2_BIT_SYNC = (1 << 8) /* 256 */;
+  const int STATE_BDS_D2_SUBFRAME_SYNC = (1 << 9) /* 512 */;
+  const int STATE_GAL_E1BC_CODE_LOCK = (1 << 10) /* 1024 */;
+  const int STATE_GAL_E1C_2ND_CODE_LOCK = (1 << 11) /* 2048 */;
+  const int STATE_GAL_E1B_PAGE_SYNC = (1 << 12) /* 4096 */;
+  const int STATE_SBAS_SYNC = (1 << 13) /* 8192 */;
+  const int STATE_TOW_KNOWN = (1 << 14) /* 16384 */;
+  const int STATE_GLO_TOD_KNOWN = (1 << 15) /* 32768 */;
+  const int STATE_2ND_CODE_LOCK = (1 << 16) /* 65536 */;
+  const int ADR_STATE_UNKNOWN = 0;
+  const int ADR_STATE_VALID = (1 << 0) /* 1 */;
+  const int ADR_STATE_RESET = (1 << 1) /* 2 */;
+  const int ADR_STATE_CYCLE_SLIP = (1 << 2) /* 4 */;
+  const int ADR_STATE_HALF_CYCLE_RESOLVED = (1 << 3) /* 8 */;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssMultipathIndicator.aidl
new file mode 100644
index 0000000..62ade9c
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssMultipathIndicator.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.gnss;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum GnssMultipathIndicator {
+  UNKNOWN = 0,
+  PRESENT = 1,
+  NOT_PRESENT = 2,
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssPowerStats.aidl
new file mode 100644
index 0000000..c4a9e61
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssPowerStats.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable GnssPowerStats {
+  android.hardware.gnss.ElapsedRealtime elapsedRealtime;
+  double totalEnergyMilliJoule;
+  double singlebandTrackingModeEnergyMilliJoule;
+  double multibandTrackingModeEnergyMilliJoule;
+  double singlebandAcquisitionModeEnergyMilliJoule;
+  double multibandAcquisitionModeEnergyMilliJoule;
+  double[] otherModesEnergyMilliJoule;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssSignalType.aidl
new file mode 100644
index 0000000..4a49547
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/GnssSignalType.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable GnssSignalType {
+  android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN;
+  double carrierFrequencyHz;
+  @utf8InCpp String codeType;
+  const @utf8InCpp String CODE_TYPE_A = "A";
+  const @utf8InCpp String CODE_TYPE_B = "B";
+  const @utf8InCpp String CODE_TYPE_C = "C";
+  const @utf8InCpp String CODE_TYPE_D = "D";
+  const @utf8InCpp String CODE_TYPE_I = "I";
+  const @utf8InCpp String CODE_TYPE_L = "L";
+  const @utf8InCpp String CODE_TYPE_M = "M";
+  const @utf8InCpp String CODE_TYPE_N = "N";
+  const @utf8InCpp String CODE_TYPE_P = "P";
+  const @utf8InCpp String CODE_TYPE_Q = "Q";
+  const @utf8InCpp String CODE_TYPE_S = "S";
+  const @utf8InCpp String CODE_TYPE_W = "W";
+  const @utf8InCpp String CODE_TYPE_X = "X";
+  const @utf8InCpp String CODE_TYPE_Y = "Y";
+  const @utf8InCpp String CODE_TYPE_Z = "Z";
+  const @utf8InCpp String CODE_TYPE_UNKNOWN = "UNKNOWN";
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnss.aidl
new file mode 100644
index 0000000..639539a
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnss.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IAGnss {
+  void setCallback(in android.hardware.gnss.IAGnssCallback callback);
+  void dataConnClosed();
+  void dataConnFailed();
+  void setServer(in android.hardware.gnss.IAGnssCallback.AGnssType type, in @utf8InCpp String hostname, in int port);
+  void dataConnOpen(in long networkHandle, in @utf8InCpp String apn, in android.hardware.gnss.IAGnss.ApnIpType apnIpType);
+  @Backing(type="int") @VintfStability
+  enum ApnIpType {
+    INVALID = 0,
+    IPV4 = 1,
+    IPV6 = 2,
+    IPV4V6 = 3,
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnssCallback.aidl
new file mode 100644
index 0000000..b2da8d9
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnssCallback.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IAGnssCallback {
+  void agnssStatusCb(in android.hardware.gnss.IAGnssCallback.AGnssType type, in android.hardware.gnss.IAGnssCallback.AGnssStatusValue status);
+  @Backing(type="int") @VintfStability
+  enum AGnssType {
+    SUPL = 1,
+    C2K = 2,
+    SUPL_EIMS = 3,
+    SUPL_IMS = 4,
+  }
+  @Backing(type="int") @VintfStability
+  enum AGnssStatusValue {
+    REQUEST_AGNSS_DATA_CONN = 1,
+    RELEASE_AGNSS_DATA_CONN = 2,
+    AGNSS_DATA_CONNECTED = 3,
+    AGNSS_DATA_CONN_DONE = 4,
+    AGNSS_DATA_CONN_FAILED = 5,
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnssRil.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnssRil.aidl
new file mode 100644
index 0000000..c8634ec
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnssRil.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+/* @hide */
+@VintfStability
+interface IAGnssRil {
+  void setCallback(in android.hardware.gnss.IAGnssRilCallback callback);
+  void setRefLocation(in android.hardware.gnss.IAGnssRil.AGnssRefLocation agnssReflocation);
+  void setSetId(in android.hardware.gnss.IAGnssRil.SetIdType type, in @utf8InCpp String setid);
+  void updateNetworkState(in android.hardware.gnss.IAGnssRil.NetworkAttributes attributes);
+  void injectNiSuplMessageData(in byte[] msgData, in int slotIndex);
+  const int NETWORK_CAPABILITY_NOT_METERED = 0x01;
+  const int NETWORK_CAPABILITY_NOT_ROAMING = 0x02;
+  @Backing(type="int") @VintfStability
+  enum AGnssRefLocationType {
+    GSM_CELLID = 1,
+    UMTS_CELLID = 2,
+    LTE_CELLID = 4,
+    NR_CELLID = 8,
+  }
+  @Backing(type="int") @VintfStability
+  enum SetIdType {
+    NONE = 0,
+    IMSI = 1,
+    MSISDM = 2,
+  }
+  @VintfStability
+  parcelable AGnssRefLocationCellID {
+    android.hardware.gnss.IAGnssRil.AGnssRefLocationType type;
+    int mcc;
+    int mnc;
+    int lac;
+    long cid;
+    int tac;
+    int pcid;
+    int arfcn;
+  }
+  @VintfStability
+  parcelable AGnssRefLocation {
+    android.hardware.gnss.IAGnssRil.AGnssRefLocationType type;
+    android.hardware.gnss.IAGnssRil.AGnssRefLocationCellID cellID;
+  }
+  @VintfStability
+  parcelable NetworkAttributes {
+    long networkHandle;
+    boolean isConnected;
+    int capabilities;
+    @utf8InCpp String apn;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnssRilCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnssRilCallback.aidl
new file mode 100644
index 0000000..3717026
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IAGnssRilCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+/* @hide */
+@VintfStability
+interface IAGnssRilCallback {
+  void requestSetIdCb(in int setIdflag);
+  void requestRefLocCb();
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnss.aidl
new file mode 100644
index 0000000..d1aaf2c
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnss.aidl
@@ -0,0 +1,103 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnss {
+  void setCallback(in android.hardware.gnss.IGnssCallback callback);
+  void close();
+  @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();
+  @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence();
+  @nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
+  android.hardware.gnss.IAGnss getExtensionAGnss();
+  android.hardware.gnss.IAGnssRil getExtensionAGnssRil();
+  android.hardware.gnss.IGnssDebug getExtensionGnssDebug();
+  android.hardware.gnss.visibility_control.IGnssVisibilityControl getExtensionGnssVisibilityControl();
+  void start();
+  void stop();
+  void injectTime(in long timeMs, in long timeReferenceMs, in int uncertaintyMs);
+  void injectLocation(in android.hardware.gnss.GnssLocation location);
+  void injectBestLocation(in android.hardware.gnss.GnssLocation location);
+  void deleteAidingData(in android.hardware.gnss.IGnss.GnssAidingData aidingDataFlags);
+  void setPositionMode(in android.hardware.gnss.IGnss.PositionModeOptions options);
+  android.hardware.gnss.IGnssAntennaInfo getExtensionGnssAntennaInfo();
+  @nullable android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsInterface getExtensionMeasurementCorrections();
+  void startSvStatus();
+  void stopSvStatus();
+  void startNmea();
+  void stopNmea();
+  const int ERROR_INVALID_ARGUMENT = 1;
+  const int ERROR_ALREADY_INIT = 2;
+  const int ERROR_GENERIC = 3;
+  @Backing(type="int") @VintfStability
+  enum GnssPositionMode {
+    STANDALONE = 0,
+    MS_BASED = 1,
+    MS_ASSISTED = 2,
+  }
+  @Backing(type="int") @VintfStability
+  enum GnssPositionRecurrence {
+    RECURRENCE_PERIODIC = 0,
+    RECURRENCE_SINGLE = 1,
+  }
+  @Backing(type="int") @VintfStability
+  enum GnssAidingData {
+    EPHEMERIS = 0x0001,
+    ALMANAC = 0x0002,
+    POSITION = 0x0004,
+    TIME = 0x0008,
+    IONO = 0x0010,
+    UTC = 0x0020,
+    HEALTH = 0x0040,
+    SVDIR = 0x0080,
+    SVSTEER = 0x0100,
+    SADATA = 0x0200,
+    RTI = 0x0400,
+    CELLDB_INFO = 0x8000,
+    ALL = 0xFFFF,
+  }
+  @VintfStability
+  parcelable PositionModeOptions {
+    android.hardware.gnss.IGnss.GnssPositionMode mode;
+    android.hardware.gnss.IGnss.GnssPositionRecurrence recurrence;
+    int minIntervalMs;
+    int preferredAccuracyMeters;
+    int preferredTimeMs;
+    boolean lowPowerMode;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssAntennaInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssAntennaInfo.aidl
new file mode 100644
index 0000000..43ad328
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssAntennaInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssAntennaInfo {
+  void setCallback(in android.hardware.gnss.IGnssAntennaInfoCallback callback);
+  void close();
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssAntennaInfoCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssAntennaInfoCallback.aidl
new file mode 100644
index 0000000..eb6abe5
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssAntennaInfoCallback.aidl
@@ -0,0 +1,61 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssAntennaInfoCallback {
+  void gnssAntennaInfoCb(in android.hardware.gnss.IGnssAntennaInfoCallback.GnssAntennaInfo[] gnssAntennaInfos);
+  @VintfStability
+  parcelable Row {
+    double[] row;
+  }
+  @VintfStability
+  parcelable Coord {
+    double x;
+    double xUncertainty;
+    double y;
+    double yUncertainty;
+    double z;
+    double zUncertainty;
+  }
+  @VintfStability
+  parcelable GnssAntennaInfo {
+    long carrierFrequencyHz;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Coord phaseCenterOffsetCoordinateMillimeters;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Row[] phaseCenterVariationCorrectionMillimeters;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Row[] phaseCenterVariationCorrectionUncertaintyMillimeters;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Row[] signalGainCorrectionDbi;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Row[] signalGainCorrectionUncertaintyDbi;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssBatching.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssBatching.aidl
new file mode 100644
index 0000000..a021f55
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssBatching.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssBatching {
+  void init(in android.hardware.gnss.IGnssBatchingCallback callback);
+  int getBatchSize();
+  void start(in android.hardware.gnss.IGnssBatching.Options options);
+  void flush();
+  void stop();
+  void cleanup();
+  const int WAKEUP_ON_FIFO_FULL = 0x01;
+  @VintfStability
+  parcelable Options {
+    long periodNanos;
+    float minDistanceMeters;
+    int flags;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssBatchingCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssBatchingCallback.aidl
new file mode 100644
index 0000000..b12a8bd
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssBatchingCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssBatchingCallback {
+  void gnssLocationBatchCb(in android.hardware.gnss.GnssLocation[] locations);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssCallback.aidl
new file mode 100644
index 0000000..61710d3
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssCallback.aidl
@@ -0,0 +1,97 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssCallback {
+  void gnssSetCapabilitiesCb(in int capabilities);
+  void gnssStatusCb(in android.hardware.gnss.IGnssCallback.GnssStatusValue status);
+  void gnssSvStatusCb(in android.hardware.gnss.IGnssCallback.GnssSvInfo[] svInfoList);
+  void gnssLocationCb(in android.hardware.gnss.GnssLocation location);
+  void gnssNmeaCb(in long timestamp, in @utf8InCpp String nmea);
+  void gnssAcquireWakelockCb();
+  void gnssReleaseWakelockCb();
+  void gnssSetSystemInfoCb(in android.hardware.gnss.IGnssCallback.GnssSystemInfo info);
+  void gnssRequestTimeCb();
+  void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
+  void gnssSetSignalTypeCapabilitiesCb(in android.hardware.gnss.GnssSignalType[] gnssSignalTypes);
+  const int CAPABILITY_SCHEDULING = (1 << 0) /* 1 */;
+  const int CAPABILITY_MSB = (1 << 1) /* 2 */;
+  const int CAPABILITY_MSA = (1 << 2) /* 4 */;
+  const int CAPABILITY_SINGLE_SHOT = (1 << 3) /* 8 */;
+  const int CAPABILITY_ON_DEMAND_TIME = (1 << 4) /* 16 */;
+  const int CAPABILITY_GEOFENCING = (1 << 5) /* 32 */;
+  const int CAPABILITY_MEASUREMENTS = (1 << 6) /* 64 */;
+  const int CAPABILITY_NAV_MESSAGES = (1 << 7) /* 128 */;
+  const int CAPABILITY_LOW_POWER_MODE = (1 << 8) /* 256 */;
+  const int CAPABILITY_SATELLITE_BLOCKLIST = (1 << 9) /* 512 */;
+  const int CAPABILITY_MEASUREMENT_CORRECTIONS = (1 << 10) /* 1024 */;
+  const int CAPABILITY_ANTENNA_INFO = (1 << 11) /* 2048 */;
+  const int CAPABILITY_CORRELATION_VECTOR = (1 << 12) /* 4096 */;
+  const int CAPABILITY_SATELLITE_PVT = (1 << 13) /* 8192 */;
+  const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = (1 << 14) /* 16384 */;
+  const int CAPABILITY_ACCUMULATED_DELTA_RANGE = (1 << 15) /* 32768 */;
+  @Backing(type="int") @VintfStability
+  enum GnssStatusValue {
+    NONE = 0,
+    SESSION_BEGIN = 1,
+    SESSION_END = 2,
+    ENGINE_ON = 3,
+    ENGINE_OFF = 4,
+  }
+  @Backing(type="int") @VintfStability
+  enum GnssSvFlags {
+    NONE = 0,
+    HAS_EPHEMERIS_DATA = (1 << 0) /* 1 */,
+    HAS_ALMANAC_DATA = (1 << 1) /* 2 */,
+    USED_IN_FIX = (1 << 2) /* 4 */,
+    HAS_CARRIER_FREQUENCY = (1 << 3) /* 8 */,
+  }
+  @VintfStability
+  parcelable GnssSvInfo {
+    int svid;
+    android.hardware.gnss.GnssConstellationType constellation;
+    float cN0Dbhz;
+    float basebandCN0DbHz;
+    float elevationDegrees;
+    float azimuthDegrees;
+    long carrierFrequencyHz;
+    int svFlag;
+  }
+  @VintfStability
+  parcelable GnssSystemInfo {
+    int yearOfHw;
+    @utf8InCpp String name;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssConfiguration.aidl
new file mode 100644
index 0000000..70df11a
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssConfiguration.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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssConfiguration {
+  void setSuplVersion(in int version);
+  void setSuplMode(in int mode);
+  void setLppProfile(in int lppProfile);
+  void setGlonassPositioningProtocol(in int protocol);
+  void setEmergencySuplPdn(in boolean enable);
+  void setEsExtensionSec(in int emergencyExtensionSeconds);
+  void setBlocklist(in android.hardware.gnss.BlocklistedSource[] blocklist);
+  const int SUPL_MODE_MSB = 0x01;
+  const int SUPL_MODE_MSA = 0x02;
+  const int LPP_PROFILE_USER_PLANE = 0x01;
+  const int LPP_PROFILE_CONTROL_PLANE = 0x02;
+  const int GLONASS_POS_PROTOCOL_RRC_CPLANE = 0x01;
+  const int GLONASS_POS_PROTOCOL_RRLP_UPLANE = 0x02;
+  const int GLONASS_POS_PROTOCOL_LPP_UPLANE = 0x04;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssDebug.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssDebug.aidl
new file mode 100644
index 0000000..591b533
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssDebug.aidl
@@ -0,0 +1,88 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssDebug {
+  android.hardware.gnss.IGnssDebug.DebugData getDebugData();
+  @Backing(type="int") @VintfStability
+  enum SatelliteEphemerisType {
+    EPHEMERIS = 0,
+    ALMANAC_ONLY = 1,
+    NOT_AVAILABLE = 2,
+  }
+  @Backing(type="int") @VintfStability
+  enum SatelliteEphemerisHealth {
+    GOOD = 0,
+    BAD = 1,
+    UNKNOWN = 2,
+  }
+  @VintfStability
+  parcelable TimeDebug {
+    long timeEstimateMs;
+    float timeUncertaintyNs;
+    float frequencyUncertaintyNsPerSec;
+  }
+  @VintfStability
+  parcelable PositionDebug {
+    boolean valid;
+    double latitudeDegrees;
+    double longitudeDegrees;
+    float altitudeMeters;
+    float speedMetersPerSec;
+    float bearingDegrees;
+    double horizontalAccuracyMeters;
+    double verticalAccuracyMeters;
+    double speedAccuracyMetersPerSecond;
+    double bearingAccuracyDegrees;
+    float ageSeconds;
+  }
+  @VintfStability
+  parcelable SatelliteData {
+    int svid;
+    android.hardware.gnss.GnssConstellationType constellation;
+    android.hardware.gnss.IGnssDebug.SatelliteEphemerisType ephemerisType;
+    android.hardware.gnss.SatellitePvt.SatelliteEphemerisSource ephemerisSource;
+    android.hardware.gnss.IGnssDebug.SatelliteEphemerisHealth ephemerisHealth;
+    float ephemerisAgeSeconds;
+    boolean serverPredictionIsAvailable;
+    float serverPredictionAgeSeconds;
+  }
+  @VintfStability
+  parcelable DebugData {
+    android.hardware.gnss.IGnssDebug.PositionDebug position;
+    android.hardware.gnss.IGnssDebug.TimeDebug time;
+    List<android.hardware.gnss.IGnssDebug.SatelliteData> satelliteDataArray;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssGeofence.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssGeofence.aidl
new file mode 100644
index 0000000..5065ad4
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssGeofence.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssGeofence {
+  void setCallback(in android.hardware.gnss.IGnssGeofenceCallback callback);
+  void addGeofence(in int geofenceId, in double latitudeDegrees, in double longitudeDegrees, in double radiusMeters, in int lastTransition, in int monitorTransitions, in int notificationResponsivenessMs, in int unknownTimerMs);
+  void pauseGeofence(in int geofenceId);
+  void resumeGeofence(in int geofenceId, in int monitorTransitions);
+  void removeGeofence(in int geofenceId);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssGeofenceCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssGeofenceCallback.aidl
new file mode 100644
index 0000000..90f9ebc
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssGeofenceCallback.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssGeofenceCallback {
+  void gnssGeofenceTransitionCb(in int geofenceId, in android.hardware.gnss.GnssLocation location, in int transition, in long timestampMillis);
+  void gnssGeofenceStatusCb(in int availability, in android.hardware.gnss.GnssLocation lastLocation);
+  void gnssGeofenceAddCb(in int geofenceId, in int status);
+  void gnssGeofenceRemoveCb(in int geofenceId, in int status);
+  void gnssGeofencePauseCb(in int geofenceId, in int status);
+  void gnssGeofenceResumeCb(in int geofenceId, in int status);
+  const int ENTERED = (1 << 0) /* 1 */;
+  const int EXITED = (1 << 1) /* 2 */;
+  const int UNCERTAIN = (1 << 2) /* 4 */;
+  const int UNAVAILABLE = (1 << 0) /* 1 */;
+  const int AVAILABLE = (1 << 1) /* 2 */;
+  const int OPERATION_SUCCESS = 0;
+  const int ERROR_TOO_MANY_GEOFENCES = (-100) /* -100 */;
+  const int ERROR_ID_EXISTS = (-101) /* -101 */;
+  const int ERROR_ID_UNKNOWN = (-102) /* -102 */;
+  const int ERROR_INVALID_TRANSITION = (-103) /* -103 */;
+  const int ERROR_GENERIC = (-149) /* -149 */;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssMeasurementCallback.aidl
new file mode 100644
index 0000000..624a7ae
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssMeasurementCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssMeasurementCallback {
+  void gnssMeasurementCb(in android.hardware.gnss.GnssData data);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssMeasurementInterface.aidl
new file mode 100644
index 0000000..6fe6a6c
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssMeasurementInterface {
+  void setCallback(in android.hardware.gnss.IGnssMeasurementCallback callback, in boolean enableFullTracking, in boolean enableCorrVecOutputs);
+  void close();
+  void setCallbackWithOptions(in android.hardware.gnss.IGnssMeasurementCallback callback, in android.hardware.gnss.IGnssMeasurementInterface.Options options);
+  @VintfStability
+  parcelable Options {
+    boolean enableFullTracking;
+    boolean enableCorrVecOutputs;
+    int intervalMs;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssNavigationMessageCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
new file mode 100644
index 0000000..57d0e68
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
@@ -0,0 +1,69 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssNavigationMessageCallback {
+  void gnssNavigationMessageCb(in android.hardware.gnss.IGnssNavigationMessageCallback.GnssNavigationMessage message);
+  @VintfStability
+  parcelable GnssNavigationMessage {
+    int svid;
+    android.hardware.gnss.IGnssNavigationMessageCallback.GnssNavigationMessage.GnssNavigationMessageType type;
+    int status;
+    int messageId;
+    int submessageId;
+    byte[] data;
+    const int STATUS_PARITY_PASSED = (1 << 0) /* 1 */;
+    const int STATUS_PARITY_REBUILT = (1 << 1) /* 2 */;
+    const int STATUS_UNKNOWN = 0;
+    @Backing(type="int") @VintfStability
+    enum GnssNavigationMessageType {
+      UNKNOWN = 0,
+      GPS_L1CA = 0x0101,
+      GPS_L2CNAV = 0x0102,
+      GPS_L5CNAV = 0x0103,
+      SBS = 0x0201,
+      GPS_CNAV2 = 0x0104,
+      GLO_L1CA = 0x0301,
+      QZS_L1CA = 0x0401,
+      BDS_D1 = 0x0501,
+      BDS_D2 = 0x0502,
+      BDS_CNAV1 = 0x0503,
+      BDS_CNAV2 = 0x0504,
+      GAL_I = 0x0601,
+      GAL_F = 0x0602,
+      IRN_L5CA = 0x0701,
+    }
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssNavigationMessageInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
new file mode 100644
index 0000000..187773d
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssNavigationMessageInterface {
+  void setCallback(in android.hardware.gnss.IGnssNavigationMessageCallback callback);
+  void close();
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPowerIndication.aidl
new file mode 100644
index 0000000..f77dbff
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPowerIndication.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssPowerIndication {
+  void setCallback(in android.hardware.gnss.IGnssPowerIndicationCallback callback);
+  oneway void requestGnssPowerStats();
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPowerIndicationCallback.aidl
new file mode 100644
index 0000000..07b10ad
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPowerIndicationCallback.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssPowerIndicationCallback {
+  void setCapabilitiesCb(in int capabilities);
+  oneway void gnssPowerStatsCb(in android.hardware.gnss.GnssPowerStats gnssPowerStats);
+  const int CAPABILITY_TOTAL = (1 << 0) /* 1 */;
+  const int CAPABILITY_SINGLEBAND_TRACKING = (1 << 1) /* 2 */;
+  const int CAPABILITY_MULTIBAND_TRACKING = (1 << 2) /* 4 */;
+  const int CAPABILITY_SINGLEBAND_ACQUISITION = (1 << 3) /* 8 */;
+  const int CAPABILITY_MULTIBAND_ACQUISITION = (1 << 4) /* 16 */;
+  const int CAPABILITY_OTHER_MODES = (1 << 5) /* 32 */;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPsds.aidl
new file mode 100644
index 0000000..3aee798
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPsds.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssPsds {
+  void injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData);
+  void setCallback(in android.hardware.gnss.IGnssPsdsCallback callback);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPsdsCallback.aidl
new file mode 100644
index 0000000..dadc9fb
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/IGnssPsdsCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+interface IGnssPsdsCallback {
+  void downloadRequestCb(in android.hardware.gnss.PsdsType psdsType);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/PsdsType.aidl
new file mode 100644
index 0000000..60b15d6
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/PsdsType.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.gnss;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum PsdsType {
+  LONG_TERM = 1,
+  NORMAL = 2,
+  REALTIME = 3,
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatelliteClockInfo.aidl
new file mode 100644
index 0000000..05f7733
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatelliteClockInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable SatelliteClockInfo {
+  double satHardwareCodeBiasMeters;
+  double satTimeCorrectionMeters;
+  double satClkDriftMps;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatellitePositionEcef.aidl
new file mode 100644
index 0000000..3d4f7ff
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatellitePositionEcef.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable SatellitePositionEcef {
+  double posXMeters;
+  double posYMeters;
+  double posZMeters;
+  double ureMeters;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatellitePvt.aidl
new file mode 100644
index 0000000..ae65f39
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatellitePvt.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable SatellitePvt {
+  int flags;
+  android.hardware.gnss.SatellitePositionEcef satPosEcef;
+  android.hardware.gnss.SatelliteVelocityEcef satVelEcef;
+  android.hardware.gnss.SatelliteClockInfo satClockInfo;
+  double ionoDelayMeters;
+  double tropoDelayMeters;
+  long timeOfClockSeconds;
+  int issueOfDataClock;
+  long timeOfEphemerisSeconds;
+  int issueOfDataEphemeris;
+  android.hardware.gnss.SatellitePvt.SatelliteEphemerisSource ephemerisSource = android.hardware.gnss.SatellitePvt.SatelliteEphemerisSource.OTHER;
+  const int HAS_POSITION_VELOCITY_CLOCK_INFO = (1 << 0) /* 1 */;
+  const int HAS_IONO = (1 << 1) /* 2 */;
+  const int HAS_TROPO = (1 << 2) /* 4 */;
+  @Backing(type="int") @VintfStability
+  enum SatelliteEphemerisSource {
+    DEMODULATED = 0,
+    SERVER_NORMAL = 1,
+    SERVER_LONG_TERM = 2,
+    OTHER = 3,
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatelliteVelocityEcef.aidl
new file mode 100644
index 0000000..94d0b34
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/SatelliteVelocityEcef.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.gnss;
+/* @hide */
+@VintfStability
+parcelable SatelliteVelocityEcef {
+  double velXMps;
+  double velYMps;
+  double velZMps;
+  double ureRateMps;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl
new file mode 100644
index 0000000..61909d0
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.gnss.measurement_corrections;
+/* @hide */
+@VintfStability
+interface IMeasurementCorrectionsCallback {
+  void setCapabilitiesCb(in int capabilities);
+  const int CAPABILITY_LOS_SATS = (1 << 0) /* 1 */;
+  const int CAPABILITY_EXCESS_PATH_LENGTH = (1 << 1) /* 2 */;
+  const int CAPABILITY_REFLECTING_PLANE = (1 << 2) /* 4 */;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl
new file mode 100644
index 0000000..bd30534
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.gnss.measurement_corrections;
+/* @hide */
+@VintfStability
+interface IMeasurementCorrectionsInterface {
+  void setCorrections(in android.hardware.gnss.measurement_corrections.MeasurementCorrections corrections);
+  void setCallback(in android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsCallback callback);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl
new file mode 100644
index 0000000..35fd79e
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.gnss.measurement_corrections;
+/* @hide */
+@VintfStability
+parcelable MeasurementCorrections {
+  double latitudeDegrees;
+  double longitudeDegrees;
+  double altitudeMeters;
+  double horizontalPositionUncertaintyMeters;
+  double verticalPositionUncertaintyMeters;
+  long toaGpsNanosecondsOfWeek;
+  android.hardware.gnss.measurement_corrections.SingleSatCorrection[] satCorrections;
+  boolean hasEnvironmentBearing;
+  float environmentBearingDegrees;
+  float environmentBearingUncertaintyDegrees;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
new file mode 100644
index 0000000..90c9e03
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.gnss.measurement_corrections;
+/* @hide */
+@VintfStability
+parcelable ReflectingPlane {
+  double latitudeDegrees;
+  double longitudeDegrees;
+  double altitudeMeters;
+  double reflectingPlaneAzimuthDegrees;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
new file mode 100644
index 0000000..72d32e4
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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.gnss.measurement_corrections;
+/* @hide */
+@VintfStability
+parcelable SingleSatCorrection {
+  int singleSatCorrectionFlags;
+  android.hardware.gnss.GnssConstellationType constellation;
+  int svid;
+  long carrierFrequencyHz;
+  float probSatIsLos;
+  float combinedExcessPathLengthMeters;
+  float combinedExcessPathLengthUncertaintyMeters;
+  float combinedAttenuationDb;
+  android.hardware.gnss.measurement_corrections.SingleSatCorrection.ExcessPathInfo[] excessPathInfos;
+  const int SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY = 0x0001;
+  const int SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH = 0x0002;
+  const int SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH_UNC = 0x0004;
+  const int SINGLE_SAT_CORRECTION_HAS_COMBINED_ATTENUATION = 0x0010;
+  @VintfStability
+  parcelable ExcessPathInfo {
+    int excessPathInfoFlags;
+    float excessPathLengthMeters;
+    float excessPathLengthUncertaintyMeters;
+    android.hardware.gnss.measurement_corrections.ReflectingPlane reflectingPlane;
+    float attenuationDb;
+    const int EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH = 0x0001;
+    const int EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH_UNC = 0x0002;
+    const int EXCESS_PATH_INFO_HAS_REFLECTING_PLANE = 0x0004;
+    const int EXCESS_PATH_INFO_HAS_ATTENUATION = 0x0008;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
new file mode 100644
index 0000000..d7a7a96
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.gnss.visibility_control;
+/* @hide */
+@VintfStability
+interface IGnssVisibilityControl {
+  void enableNfwLocationAccess(in @utf8InCpp String[] proxyApps);
+  void setCallback(in android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback callback);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl
new file mode 100644
index 0000000..c9b96f5
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/3/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl
@@ -0,0 +1,75 @@
+/*
+ * 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.gnss.visibility_control;
+/* @hide */
+@VintfStability
+interface IGnssVisibilityControlCallback {
+  void nfwNotifyCb(in android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwNotification notification);
+  boolean isInEmergencySession();
+  @Backing(type="int") @VintfStability
+  enum NfwProtocolStack {
+    CTRL_PLANE = 0,
+    SUPL = 1,
+    IMS = 10,
+    SIM = 11,
+    OTHER_PROTOCOL_STACK = 100,
+  }
+  @Backing(type="int") @VintfStability
+  enum NfwRequestor {
+    CARRIER = 0,
+    OEM = 10,
+    MODEM_CHIPSET_VENDOR = 11,
+    GNSS_CHIPSET_VENDOR = 12,
+    OTHER_CHIPSET_VENDOR = 13,
+    AUTOMOBILE_CLIENT = 20,
+    OTHER_REQUESTOR = 100,
+  }
+  @Backing(type="int") @VintfStability
+  enum NfwResponseType {
+    REJECTED = 0,
+    ACCEPTED_NO_LOCATION_PROVIDED = 1,
+    ACCEPTED_LOCATION_PROVIDED = 2,
+  }
+  @VintfStability
+  parcelable NfwNotification {
+    String proxyAppPackageName;
+    android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwProtocolStack protocolStack;
+    String otherProtocolStackName;
+    android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwRequestor requestor;
+    String requestorId;
+    android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwResponseType responseType;
+    boolean inEmergencyMode;
+    boolean isCachedLocation;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
index 31426f0..54e3b21 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
@@ -39,6 +39,7 @@
   android.hardware.gnss.GnssClock clock;
   android.hardware.gnss.ElapsedRealtime elapsedRealtime;
   android.hardware.gnss.GnssData.GnssAgc[] gnssAgcs = {};
+  boolean isFullTracking;
   @VintfStability
   parcelable GnssAgc {
     double agcLevelDb;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl
index 8930752..c782b6f 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl
@@ -39,6 +39,7 @@
   void setRefLocation(in android.hardware.gnss.IAGnssRil.AGnssRefLocation agnssReflocation);
   void setSetId(in android.hardware.gnss.IAGnssRil.SetIdType type, in @utf8InCpp String setid);
   void updateNetworkState(in android.hardware.gnss.IAGnssRil.NetworkAttributes attributes);
+  void injectNiSuplMessageData(in byte[] msgData, in int slotIndex);
   const int NETWORK_CAPABILITY_NOT_METERED = 1;
   const int NETWORK_CAPABILITY_NOT_ROAMING = 2;
   @Backing(type="int") @VintfStability
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
index 48c88f5..0247182 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
@@ -45,6 +45,7 @@
   void gnssSetSystemInfoCb(in android.hardware.gnss.IGnssCallback.GnssSystemInfo info);
   void gnssRequestTimeCb();
   void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
+  void gnssSetSignalTypeCapabilitiesCb(in android.hardware.gnss.GnssSignalType[] gnssSignalTypes);
   const int CAPABILITY_SCHEDULING = 1;
   const int CAPABILITY_MSB = 2;
   const int CAPABILITY_MSA = 4;
@@ -60,6 +61,7 @@
   const int CAPABILITY_CORRELATION_VECTOR = 4096;
   const int CAPABILITY_SATELLITE_PVT = 8192;
   const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 16384;
+  const int CAPABILITY_ACCUMULATED_DELTA_RANGE = 32768;
   @Backing(type="int") @VintfStability
   enum GnssStatusValue {
     NONE = 0,
diff --git a/gnss/aidl/android/hardware/gnss/GnssData.aidl b/gnss/aidl/android/hardware/gnss/GnssData.aidl
index 075a039..1bd8d48 100644
--- a/gnss/aidl/android/hardware/gnss/GnssData.aidl
+++ b/gnss/aidl/android/hardware/gnss/GnssData.aidl
@@ -99,4 +99,15 @@
      * weak to be acquired, the AGC value must still be reported.
      */
     GnssAgc[] gnssAgcs = {};
+
+    /**
+     * True indicates that the GNSS chipset switches off duty cycling. In such mode, no clock
+     * discontinuities are expected and, when supported, carrier phase should be continuous in good
+     * signal conditions. All non-blocklisted, healthy constellations, satellites and frequency
+     * bands that are meaningful to positioning accuracy must be tracked and reported in this mode.
+     *
+     * False indicates that the GNSS chipset optimizes power via duty cycling, constellations and
+     * frequency limits, etc.
+     */
+    boolean isFullTracking;
 }
diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
index db724a4..925df1a 100644
--- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
+++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
@@ -133,50 +133,50 @@
      * zero to the value in the table. The state flag with the widest range indicates the range of
      * the received GNSS satellite time value.
      *
-     * +---------------------------+--------------------+-----+-----------+--------------------+------+
-     * |                           |GPS/QZSS            |GLNS |BDS        |GAL                 |SBAS  |
-     * +---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |State Flag	               |L1    |L5I   |L5Q   |L1OF |B1I   |B1I |E1B   |E1C   |E5AQ  |L1    |
-     * |                           |C/A   |      |      |     |(D1)  |(D2)|      |      |      |C/A   |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_UNKNOWN              |0     |0     |0     |0    |0     |0   |0     |0     |0     |0     |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_CODE_LOCK            |1ms   |1 ms  |1 ms  |1 ms |1 ms  |1 ms|-     |-     |1 ms  |1 ms  |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_SYMBOL_SYNC          |20ms  |10 ms |1 ms  |10 ms|20 ms |2 ms|4 ms  |4 ms  |1 ms  |2 ms  |
-     * |                           |(opt.)|      |(opt.)|     |(opt.)|    |(opt.)|(opt.)|(opt.)|      |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_BIT_SYNC             |20 ms |20 ms |1 ms  |20 ms|20 ms |-   |8 ms  |-     |1 ms  |4 ms  |
-     * |                           |      |      |(opt.)|     |      |    |      |      |(opt.)|      |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_SUBFRAME_SYNC        |6s    |6s    |-     |2 s  |6 s   |-   |-     |-     |100 ms|-     |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_TOW_DECODED          |1 week|-     |-     |1 day|1 week|-   |1 week|-     |-     |1 week|
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_TOW_KNOWN            |1 week|-     |-     |1 day|1 week|-   |1 week|-     |-     |1 week|
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_GLO_STRING_SYNC      |-     |-     |-     |2 s  |-     |-   |-     |-     |-     |-     |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_GLO_TOD_DECODED      |-     |-     |-     |1 day|-     |-   |-     |-     |-     |-     |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_GLO_TOD_KNOWN        |-     |-     |-     |1 day|-     |-   |-     |-     |-     |-     |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_BDS_D2_BIT_SYNC      |-     |-     |-     |-    |-     |2 ms|-     |-     |-     |-     |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_BDS_D2_SUBFRAME_SYNC |-     |-     |-     |-    |-     |600 |-     |-     |-     |-     |
-     * |                           |      |      |      |     |      |ms  |      |      |      |      |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_GAL_E1BC_CODE_LOCK   |-     |-     |-     |-    |-     |-   |4 ms  |4 ms  |-     |-     |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_GAL_E1C_2ND_CODE_LOCK|-     |-     |-     |-    |-     |-   |-     |100 ms|-     |-     |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_2ND_CODE_LOCK        |-     |10 ms |20 ms |-    |-     |-	  |-     |100 ms|100 ms|-     |
-     * |                           |      |(opt.)|      |     |      |    |      |(opt.)|      |      |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_GAL_E1B_PAGE_SYNC    |-     |-     |-     |-    |-     |-   |2 s   |-     |-     |-     |
-     * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
-     * |STATE_SBAS_SYNC            |-     |-     |-     |-    |-     |-   |-     |-     |-     |1s    |
-     * +---------------------------+------+------+------+-----+------+----+------+------+------+------+
+     * +---------------------------+---------------------------+-----+---------------------------+--------------------+------+------+
+     * |                           |GPS/QZSS                   |GLNS |BDS                        |GAL                 |SBAS  |IRNSS |
+     * +---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |State Flag	               |L1    |L1C   |L5I   |L5Q   |L1OF |B1I   |B1I   |B1C   |B2AQ  |E1B   |E1C   |E5AQ  |L1    |L5C   |
+     * |                           |C/A   |(P)   |      |      |     |(D1)  |(D2)  |(P)   |      |      |      |      |C/A   |      |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_UNKNOWN              |0     |0     |0     |0     |0    |0     |0     |0     |0     |0     |0     |0     |0     |0     |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_CODE_LOCK            |1ms   |10 ms |1 ms  |1 ms  |1 ms |1 ms  |1 ms  |10 ms |1 ms  |-     |-     |1 ms  |1 ms  |1ms   |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_SYMBOL_SYNC          |-     |-     |10 ms |-     |10 ms|-     |2 ms  |-     |-     |-     |-     |-     |2 ms  |-     |
+     * |                           |      |      |      |      |     |      |      |      |      |      |      |      |      |      |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_BIT_SYNC             |20 ms |-     |20 ms |-     |20 ms|20 ms |-     |-     |-     |8 ms  |-     |-     |4 ms  |20 ms |
+     * |                           |      |      |      |      |     |      |      |      |      |      |      |      |      |      |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_SUBFRAME_SYNC        |6s    |-     |6s    |-     |-    |6 s   |-     |-     |100 ms|-     |-     |100 ms|-     |6s    |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_TOW_DECODED          |1 week|-     |1 week|-     |-    |1 week|1 week|-     |-     |1 week|1 week|-     |1 week|1 week|
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_TOW_KNOWN            |1 week|1 week|1 week|1 week|-    |1 week|1 week|1 week|1 week|1 week|1 week|1 week|1 week|1 week|
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_GLO_STRING_SYNC      |-     |-     |-     |-     |2 s  |-     |-     |-     |-     |-     |-     |-     |-     |-     |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_GLO_TOD_DECODED      |-     |-     |-     |-     |1 day|-     |-     |-     |-     |-     |-     |-     |-     |-     |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_GLO_TOD_KNOWN        |-     |-     |-     |-     |1 day|-     |-     |-     |-     |-     |-     |-     |-     |-     |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_BDS_D2_BIT_SYNC      |-     |-     |-     |-     |-    |-     |2 ms  |-     |-     |-     |-     |-     |-     |-     |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_BDS_D2_SUBFRAME_SYNC |-     |-     |-     |-     |-    |-     |600   |-     |-     |-     |-     |-     |-     |-     |
+     * |                           |      |      |      |      |     |      |ms    |      |      |      |      |      |      |      |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_GAL_E1BC_CODE_LOCK   |-     |-     |-     |-     |-    |-     |-     |-     |-     |4 ms  |4 ms  |-     |-     |-     |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_GAL_E1C_2ND_CODE_LOCK|-     |-     |-     |-     |-    |-     |-     |-     |-     |-     |100 ms|-     |-     |-     |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_2ND_CODE_LOCK        |-     |18000 |10 ms |20 ms |-    |-     |-	   |18000 |100 ms|-     |-     |100 ms|-     |-     |
+     * |                           |      |ms    |      |      |     |      |      |ms    |      |      |      |      |      |      |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_GAL_E1B_PAGE_SYNC    |-     |-     |-     |-     |-    |-     |-     |-     |-     |2 s   |-     |-     |-     |-     |
+     * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+     * |STATE_SBAS_SYNC            |-     |-     |-     |-     |-    |-     |-     |-     |-     |-     |-     |-     |1s    |-     |
+     * +---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
      *
      * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
      * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
diff --git a/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl b/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl
index 44847f0..5f2e261 100644
--- a/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl
+++ b/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl
@@ -164,4 +164,14 @@
      *
      */
     void updateNetworkState(in NetworkAttributes attributes);
+
+    /**
+     * Injects an SMS/WAP initiated SUPL message.
+     *
+     * @param msgData ASN.1 encoded SUPL INIT message. This is defined in
+     * UserPlane Location Protocol (Version 2.0.4).
+     * @param slotIndex Specifies the slot index (See
+     *         android.telephony.SubscriptionManager#getSlotIndex()) of the SUPL connection.
+     */
+    void injectNiSuplMessageData(in byte[] msgData, in int slotIndex);
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index 8633bea..0200625 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.gnss.GnssConstellationType;
 import android.hardware.gnss.GnssLocation;
+import android.hardware.gnss.GnssSignalType;
 import android.hardware.gnss.IGnssConfiguration;
 import android.hardware.gnss.IGnssPsds;
 
@@ -48,7 +49,13 @@
     /** Capability bit mask indicating that GNSS supports single-shot fixes */
     const int CAPABILITY_SINGLE_SHOT = 1 << 3;
 
-    /** Capability bit mask indicating that GNSS supports on demand time injection */
+    /**
+     * Capability bit indicating that the platform should periodically inject
+     * time to GNSS in addition to on-demand and occasional time updates.
+     *
+     * <p>Note:<em>The naming of "on demand" should be "periodic" instead.  This
+     * is the result of a historic implementation bug, b/73893222.</em>
+     */
     const int CAPABILITY_ON_DEMAND_TIME = 1 << 4;
 
     /** Capability bit mask indicating that GNSS supports Geofencing  */
@@ -81,6 +88,9 @@
     /** Capability bit mask indicating that GNSS supports measurement corrections for driving */
     const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 1 << 14;
 
+    /** Capability bit mask indicating that GNSS supports accumulated delta range */
+    const int CAPABILITY_ACCUMULATED_DELTA_RANGE = 1 << 15;
+
     /**
      * Callback to inform framework of the GNSS HAL implementation's capabilities.
      *
@@ -204,9 +214,12 @@
     /**
      * Callback for the HAL to pass a vector of GnssSvInfo back to the client.
      *
-     * If GnssMeasurement is registered, the SvStatus report interval is the same as the measurement
-     * interval, i.e., the interval the measurement engine runs at. If GnssMeasurement is not
-     * registered, the SvStatus interval is the same as the location interval.
+     * If only GnssMeasurement is registered, the SvStatus reporting interval must be
+     * the same as the measurement interval, i.e., the interval the measurement
+     * engine runs at. If only location is registered, the SvStatus interval must
+     * be the same as the location interval. If both GnssMeasurement and location
+     * are registered, then the SvStatus interval is the same as the lesser interval
+     * between the two.
      *
      * @param svInfo SV status information from HAL.
      */
@@ -308,4 +321,18 @@
      *        during-call to E911, or up to 5 minutes after end-of-call or text to E911).
      */
     void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
+
+    /**
+     * Callback to inform the framework of the list of GnssSignalTypes the GNSS HAL implementation
+     * supports.
+     *
+     * These capabilities are static at runtime, i.e., they represent the signal types the
+     * GNSS implementation supports without considering the temporary disabled signal types such as
+     * the blocklisted satellites/constellations or the constellations disabled by regional
+     * restrictions.
+     *
+     * @param gnssSignalTypes a list of GnssSignalTypes specifying the constellations, carrier
+     *     frequencies, and the code types the GNSS HAL implementation supports.
+     */
+    void gnssSetSignalTypeCapabilitiesCb(in GnssSignalType[] gnssSignalTypes);
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
index 8733754..33e9008 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -36,9 +36,9 @@
          * If true, GNSS chipset must switch off duty cycling. In such mode no clock discontinuities
          * are expected and, when supported, carrier phase should be continuous in good signal
          * conditions. All non-blocklisted, healthy constellations, satellites and frequency bands
-         * that the chipset supports must be reported in this mode. The GNSS chipset is allowed to
-         * consume more power in this mode. If false, API must optimize power via duty cycling,
-         * constellations and frequency limits, etc.
+         * that are meaningful to positioning accuracy must be tracked and reported in this mode.
+         * The GNSS chipset is allowed to consume more power in this mode. If false, API must
+         * optimize power via duty cycling, constellations and frequency limits, etc.
          */
         boolean enableFullTracking;
 
@@ -78,6 +78,9 @@
      * output rate of 1Hz (occasional intra-measurement time offsets in the range from 0-2000msec
      * can be tolerated.)
      *
+     * If setCallback() is invoked without a previous close(), the HAL must use the new callback
+     * and parameters to provide updates.
+     *
      * @param callback Handle to GnssMeasurement callback interface.
      * @param enableFullTracking If true, GNSS chipset must switch off duty cycling. In such mode
      *     no clock discontinuities are expected and, when supported, carrier phase should be
@@ -104,6 +107,9 @@
     /**
      * Initializes the interface and registers the callback routines with the HAL.
      *
+     * If setCallbackWithOptions() is invoked without a previous close(), the HAL must use the new
+     * callback and options to provide updates.
+     *
      * @param options See Options definition.
      */
     void setCallbackWithOptions(in IGnssMeasurementCallback callback, in Options options);
diff --git a/gnss/aidl/default/AGnssRil.cpp b/gnss/aidl/default/AGnssRil.cpp
index 2aa1abc..81b4f2a 100644
--- a/gnss/aidl/default/AGnssRil.cpp
+++ b/gnss/aidl/default/AGnssRil.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "AGnssRilAidl"
 
 #include "AGnssRil.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
 #include <inttypes.h>
 #include <log/log.h>
 
@@ -55,4 +56,15 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus AGnssRil::injectNiSuplMessageData(const std::vector<uint8_t>& msgData,
+                                                     int slotIndex) {
+    ALOGD("AGnssRil::injectNiSuplMessageData: msgData:%d bytes slotIndex:%d",
+          static_cast<int>(msgData.size()), slotIndex);
+    if (msgData.size() > 0) {
+        return ndk::ScopedAStatus::ok();
+    } else {
+        return ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_INVALID_ARGUMENT);
+    }
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/AGnssRil.h b/gnss/aidl/default/AGnssRil.h
index e205b69..76583ac 100644
--- a/gnss/aidl/default/AGnssRil.h
+++ b/gnss/aidl/default/AGnssRil.h
@@ -26,6 +26,8 @@
     ndk::ScopedAStatus setRefLocation(const AGnssRefLocation& agnssReflocation) override;
     ndk::ScopedAStatus setSetId(SetIdType type, const std::string& setid) override;
     ndk::ScopedAStatus updateNetworkState(const NetworkAttributes& attributes) override;
+    ndk::ScopedAStatus injectNiSuplMessageData(const std::vector<uint8_t>& msgData,
+                                               int slotIndex) override;
 
   private:
     // Synchronization lock for sCallback
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index c8ae6b2..ca5a41f 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -50,7 +50,7 @@
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.visibility_control@1.0",
-        "android.hardware.gnss-V2-ndk",
+        "android.hardware.gnss-V3-ndk",
     ],
     srcs: [
         "AGnssRil.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index cf2c90d..f1b9cbf 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -60,7 +60,8 @@
                   IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST |
                   IGnssCallback::CAPABILITY_SATELLITE_PVT |
                   IGnssCallback::CAPABILITY_CORRELATION_VECTOR |
-                  IGnssCallback::CAPABILITY_ANTENNA_INFO);
+                  IGnssCallback::CAPABILITY_ANTENNA_INFO |
+                  IGnssCallback::CAPABILITY_ACCUMULATED_DELTA_RANGE);
     auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities);
     if (!status.isOk()) {
         ALOGE("%s: Unable to invoke callback.gnssSetCapabilitiesCb", __func__);
@@ -68,13 +69,27 @@
 
     IGnssCallback::GnssSystemInfo systemInfo = {
             .yearOfHw = 2022,
-            .name = "Google Mock GNSS Implementation AIDL v2",
+            .name = "Google, Cuttlefish, AIDL v3",
     };
     status = sGnssCallback->gnssSetSystemInfoCb(systemInfo);
     if (!status.isOk()) {
         ALOGE("%s: Unable to invoke callback.gnssSetSystemInfoCb", __func__);
     }
-
+    GnssSignalType signalType1 = {
+            .constellation = GnssConstellationType::GPS,
+            .carrierFrequencyHz = 1.57542e+09,
+            .codeType = GnssSignalType::CODE_TYPE_C,
+    };
+    GnssSignalType signalType2 = {
+            .constellation = GnssConstellationType::GLONASS,
+            .carrierFrequencyHz = 1.5980625e+09,
+            .codeType = GnssSignalType::CODE_TYPE_C,
+    };
+    status = sGnssCallback->gnssSetSignalTypeCapabilitiesCb(
+            std::vector<GnssSignalType>({signalType1, signalType2}));
+    if (!status.isOk()) {
+        ALOGE("%s: Unable to invoke callback.gnssSetSignalTypeCapabilitiesCb", __func__);
+    }
     return ScopedAStatus::ok();
 }
 
@@ -310,6 +325,7 @@
     ALOGD("getExtensionGnssMeasurement");
     if (mGnssMeasurementInterface == nullptr) {
         mGnssMeasurementInterface = SharedRefBase::make<GnssMeasurementInterface>();
+        mGnssMeasurementInterface->setGnssInterface(static_cast<std::shared_ptr<Gnss>>(this));
     }
     *iGnssMeasurement = mGnssMeasurementInterface;
     return ScopedAStatus::ok();
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index df10fc8..00540cd 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -84,13 +84,13 @@
                                     IMeasurementCorrectionsInterface>* iMeasurementCorrections)
             override;
 
+    void reportSvStatus() const;
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
     std::shared_ptr<GnssMeasurementInterface> mGnssMeasurementInterface;
 
   private:
     void reportLocation(const GnssLocation&) const;
-    void reportSvStatus() const;
     void reportSvStatus(const std::vector<IGnssCallback::GnssSvInfo>& svInfoList) const;
     std::vector<IGnssCallback::GnssSvInfo> filterBlocklistedSatellites(
             std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList) const;
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
index 606de07..aab9e03 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.cpp
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -20,6 +20,7 @@
 #include <aidl/android/hardware/gnss/BnGnss.h>
 #include <log/log.h>
 #include "DeviceFileReader.h"
+#include "Gnss.h"
 #include "GnssRawMeasurementParser.h"
 #include "GnssReplayUtils.h"
 #include "Utils.h"
@@ -54,7 +55,7 @@
         ALOGW("GnssMeasurement callback already set. Resetting the callback...");
         stop();
     }
-    start(enableCorrVecOutputs);
+    start(enableCorrVecOutputs, enableFullTracking);
 
     return ndk::ScopedAStatus::ok();
 }
@@ -73,7 +74,7 @@
         stop();
     }
     mIntervalMs = std::max(options.intervalMs, 1000);
-    start(options.enableCorrVecOutputs);
+    start(options.enableCorrVecOutputs, options.enableFullTracking);
 
     return ndk::ScopedAStatus::ok();
 }
@@ -91,7 +92,8 @@
     return ndk::ScopedAStatus::ok();
 }
 
-void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) {
+void GnssMeasurementInterface::start(const bool enableCorrVecOutputs,
+                                     const bool enableFullTracking) {
     ALOGD("start");
 
     if (mIsActive) {
@@ -103,7 +105,7 @@
 
     mIsActive = true;
     mThreadBlocker.reset();
-    mThread = std::thread([this, enableCorrVecOutputs]() {
+    mThread = std::thread([this, enableCorrVecOutputs, enableFullTracking]() {
         int intervalMs;
         do {
             if (!mIsActive) {
@@ -122,8 +124,12 @@
                     this->reportMeasurement(*measurement);
                 }
             } else {
-                auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
+                auto measurement =
+                        Utils::getMockMeasurement(enableCorrVecOutputs, enableFullTracking);
                 this->reportMeasurement(measurement);
+                if (!mLocationEnabled) {
+                    mGnss->reportSvStatus();
+                }
             }
             intervalMs =
                     (mLocationEnabled) ? std::min(mLocationIntervalMs, mIntervalMs) : mIntervalMs;
@@ -162,6 +168,10 @@
     mLocationEnabled = enabled;
 }
 
+void GnssMeasurementInterface::setGnssInterface(const std::shared_ptr<Gnss>& gnss) {
+    mGnss = gnss;
+}
+
 void GnssMeasurementInterface::waitForStoppingThreads() {
     for (auto& future : mFutures) {
         ALOGD("Stopping previous thread.");
diff --git a/gnss/aidl/default/GnssMeasurementInterface.h b/gnss/aidl/default/GnssMeasurementInterface.h
index bb08027..926a4e7 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.h
+++ b/gnss/aidl/default/GnssMeasurementInterface.h
@@ -25,6 +25,7 @@
 #include "Utils.h"
 
 namespace aidl::android::hardware::gnss {
+class Gnss;
 
 struct GnssMeasurementInterface : public BnGnssMeasurementInterface {
   public:
@@ -39,9 +40,10 @@
             const Options& options) override;
     void setLocationInterval(const int intervalMs);
     void setLocationEnabled(const bool enabled);
+    void setGnssInterface(const std::shared_ptr<Gnss>& gnss);
 
   private:
-    void start(const bool enableCorrVecOutputs);
+    void start(const bool enableCorrVecOutputs, const bool enableFullTracking);
     void stop();
     void reportMeasurement(const GnssData&);
     void waitForStoppingThreads();
@@ -59,6 +61,8 @@
 
     // Synchronization lock for sCallback
     mutable std::mutex mMutex;
+
+    std::shared_ptr<Gnss> mGnss;
 };
 
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/gnss-default.xml b/gnss/aidl/default/gnss-default.xml
index 7449310..73b841e 100644
--- a/gnss/aidl/default/gnss-default.xml
+++ b/gnss/aidl/default/gnss-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.gnss</name>
-        <version>2</version>
+        <version>3</version>
         <interface>
             <name>IGnss</name>
             <instance>default</instance>
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index f02a41e..2a09a56 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -51,7 +51,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.gnss-V2-cpp",
+        "android.hardware.gnss-V3-cpp",
         "android.hardware.gnss@common-vts-lib",
     ],
     test_suites: [
diff --git a/gnss/aidl/vts/AndroidTest.xml b/gnss/aidl/vts/AndroidTest.xml
new file mode 100644
index 0000000..d203402
--- /dev/null
+++ b/gnss/aidl/vts/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs VtsHalGnssTargetTest.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalGnssTargetTest->/data/local/tmp/VtsHalGnssTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalGnssTargetTest" />
+        <option name="native-test-timeout" value="2m" />
+    </test>
+</configuration>
diff --git a/gnss/aidl/vts/GnssCallbackAidl.cpp b/gnss/aidl/vts/GnssCallbackAidl.cpp
index 2f6128b..2e34921 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.cpp
+++ b/gnss/aidl/vts/GnssCallbackAidl.cpp
@@ -18,11 +18,13 @@
 
 #include "GnssCallbackAidl.h"
 #include <log/log.h>
+#include <utils/SystemClock.h>
 
 using android::binder::Status;
 using android::hardware::gnss::GnssLocation;
 using GnssSvInfo = android::hardware::gnss::IGnssCallback::GnssSvInfo;
 using GnssSystemInfo = android::hardware::gnss::IGnssCallback::GnssSystemInfo;
+using GnssSignalType = android::hardware::gnss::GnssSignalType;
 
 Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
     ALOGI("Capabilities received %#08x", capabilities);
@@ -30,6 +32,20 @@
     return Status::ok();
 }
 
+Status GnssCallbackAidl::gnssSetSignalTypeCapabilitiesCb(
+        const std::vector<GnssSignalType>& signalTypes) {
+    ALOGI("SignalTypeCapabilities received");
+    std::ostringstream ss;
+    for (auto& signalType : signalTypes) {
+        ss << "[constellation=" << (int)signalType.constellation
+           << ", carrierFrequencyHz=" << signalType.carrierFrequencyHz
+           << ", codeType=" << signalType.codeType << "], ";
+    }
+    ALOGI("%s", ss.str().c_str());
+    signal_type_capabilities_cbq_.store(signalTypes);
+    return Status::ok();
+}
+
 Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue /* status */) {
     ALOGI("gnssStatusCb");
     return Status::ok();
@@ -38,6 +54,7 @@
 Status GnssCallbackAidl::gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) {
     ALOGI("gnssSvStatusCb. Size = %d", (int)svInfoList.size());
     sv_info_list_cbq_.store(svInfoList);
+    sv_info_list_timestamps_millis_cbq_.store(::android::elapsedRealtime());
     return Status::ok();
 }
 
diff --git a/gnss/aidl/vts/GnssCallbackAidl.h b/gnss/aidl/vts/GnssCallbackAidl.h
index a9495ba..82a0df4 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.h
+++ b/gnss/aidl/vts/GnssCallbackAidl.h
@@ -25,13 +25,17 @@
   public:
     GnssCallbackAidl()
         : capabilities_cbq_("capabilities"),
+          signal_type_capabilities_cbq_("signal_type_capabilities"),
           info_cbq_("system_info"),
           location_cbq_("location"),
           sv_info_list_cbq_("sv_info"),
+          sv_info_list_timestamps_millis_cbq_("sv_info_timestamps"),
           nmea_cbq_("nmea"){};
     ~GnssCallbackAidl(){};
 
     android::binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
+    android::binder::Status gnssSetSignalTypeCapabilitiesCb(
+            const std::vector<android::hardware::gnss::GnssSignalType>& signalTypes) override;
     android::binder::Status gnssStatusCb(const GnssStatusValue status) override;
     android::binder::Status gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) override;
     android::binder::Status gnssLocationCb(
@@ -45,11 +49,15 @@
                                                   const bool isUserEmergency) override;
 
     int last_capabilities_;
+    std::vector<android::hardware::gnss::GnssSignalType> last_signal_type_capabilities;
     android::hardware::gnss::IGnssCallback::GnssSystemInfo last_info_;
     android::hardware::gnss::GnssLocation last_location_;
 
     android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_;
     android::hardware::gnss::common::GnssCallbackEventQueue<
+            std::vector<android::hardware::gnss::GnssSignalType>>
+            signal_type_capabilities_cbq_;
+    android::hardware::gnss::common::GnssCallbackEventQueue<
             android::hardware::gnss::IGnssCallback::GnssSystemInfo>
             info_cbq_;
     android::hardware::gnss::common::GnssCallbackEventQueue<android::hardware::gnss::GnssLocation>
@@ -57,6 +65,8 @@
     android::hardware::gnss::common::GnssCallbackEventQueue<
             std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
             sv_info_list_cbq_;
+    android::hardware::gnss::common::GnssCallbackEventQueue<long>
+            sv_info_list_timestamps_millis_cbq_;
     android::hardware::gnss::common::GnssCallbackEventQueue<std::pair<int64_t, std::string>>
             nmea_cbq_;
 };
\ No newline at end of file
diff --git a/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp b/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp
index a553954..0d15b2a 100644
--- a/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp
+++ b/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp
@@ -24,9 +24,11 @@
 
 android::binder::Status GnssMeasurementCallbackAidl::gnssMeasurementCb(const GnssData& gnssData) {
     ALOGI("gnssMeasurementCb");
-    ALOGV("elapsedRealtime: flags = 0x%X, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf",
+    ALOGV("elapsedRealtime: flags = 0x%X, timestampNs: %" PRId64
+          ", timeUncertaintyNs=%lf"
+          " isFullTracking=%s",
           gnssData.elapsedRealtime.flags, gnssData.elapsedRealtime.timestampNs,
-          gnssData.elapsedRealtime.timeUncertaintyNs);
+          gnssData.elapsedRealtime.timeUncertaintyNs, gnssData.isFullTracking ? "true" : "false");
 
     gnss_data_cbq_.store(gnssData);
     return android::binder::Status::ok();
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 64e51c7..4f5e6a0 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -105,6 +105,15 @@
         EXPECT_TRUE(aidl_gnss_cb_->info_cbq_.retrieve(aidl_gnss_cb_->last_info_, TIMEOUT_SEC));
         EXPECT_EQ(aidl_gnss_cb_->info_cbq_.calledCount(), 1);
     }
+
+    /*
+     * SignalTypeCapabilities callback should trigger.
+     */
+    if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+        EXPECT_TRUE(aidl_gnss_cb_->signal_type_capabilities_cbq_.retrieve(
+                aidl_gnss_cb_->last_signal_type_capabilities, TIMEOUT_SEC));
+        EXPECT_EQ(aidl_gnss_cb_->signal_type_capabilities_cbq_.calledCount(), 1);
+    }
 }
 
 void GnssHalTest::TearDown() {
@@ -469,6 +478,52 @@
     }
 }
 
+void GnssHalTest::collectSvInfoListTimestamps(const int numMeasurementEvents,
+                                              const int timeoutSeconds,
+                                              std::vector<int>& deltasMs) {
+    aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.reset();
+    aidl_gnss_cb_->sv_info_list_cbq_.reset();
+
+    auto status = aidl_gnss_hal_->startSvStatus();
+    EXPECT_TRUE(status.isOk());
+    ASSERT_TRUE(aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.size() ==
+                aidl_gnss_cb_->sv_info_list_cbq_.size());
+    long lastElapsedRealtimeMillis = 0;
+    for (int i = 0; i < numMeasurementEvents; i++) {
+        long timeStamp;
+        ASSERT_TRUE(aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.retrieve(timeStamp,
+                                                                                timeoutSeconds));
+        if (lastElapsedRealtimeMillis != 0) {
+            deltasMs.push_back(timeStamp - lastElapsedRealtimeMillis);
+        }
+        lastElapsedRealtimeMillis = timeStamp;
+    }
+    status = aidl_gnss_hal_->stopSvStatus();
+    EXPECT_TRUE(status.isOk());
+}
+
+void GnssHalTest::checkGnssDataFields(const sp<GnssMeasurementCallbackAidl>& callback,
+                                      const int numMeasurementEvents, const int timeoutSeconds,
+                                      const bool isFullTracking) {
+    for (int i = 0; i < numMeasurementEvents; i++) {
+        GnssData lastGnssData;
+        ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, timeoutSeconds));
+        EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+        ASSERT_TRUE(lastGnssData.measurements.size() > 0);
+
+        // Validity check GnssData fields
+        checkGnssMeasurementClockFields(lastGnssData);
+        if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+            if (isFullTracking) {
+                EXPECT_EQ(lastGnssData.isFullTracking, isFullTracking);
+            }
+        }
+        for (const auto& measurement : lastGnssData.measurements) {
+            checkGnssMeasurementFields(measurement, lastGnssData);
+        }
+    }
+}
+
 void GnssHalTest::assertMeanAndStdev(int intervalMs, std::vector<int>& deltasMs) {
     double mean = computeMean(deltasMs);
     double stdev = computeStdev(mean, deltasMs);
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index c49c1b9..88d01c1 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -101,6 +101,11 @@
     void collectMeasurementIntervals(const sp<GnssMeasurementCallbackAidl>& callback,
                                      const int numMeasurementEvents, const int timeoutSeconds,
                                      std::vector<int>& deltaMs);
+    void collectSvInfoListTimestamps(const int numMeasurementEvents, const int timeoutSeconds,
+                                     std::vector<int>& deltasMs);
+    void checkGnssDataFields(const sp<GnssMeasurementCallbackAidl>& callback,
+                             const int numMeasurementEvents, const int timeoutSeconds,
+                             const bool isFullTracking);
     void assertMeanAndStdev(int intervalMillis, std::vector<int>& deltasMillis);
 
     sp<IGnssAidl> aidl_gnss_hal_;
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index c7fc32a..aa8bdfd 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -173,6 +173,7 @@
  * GnssCapabilities:
  * 1. Verifies that GNSS hardware supports measurement capabilities.
  * 2. Verifies that GNSS hardware supports Scheduling capabilities.
+ * 3. Verifies that GNSS hardware supports non-empty signal type capabilities.
  */
 TEST_P(GnssHalTest, GnssCapabilites) {
     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
@@ -182,6 +183,10 @@
         EXPECT_TRUE(aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_MEASUREMENTS);
     }
     EXPECT_TRUE(aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_SCHEDULING);
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+        return;
+    }
+    EXPECT_FALSE(aidl_gnss_cb_->last_signal_type_capabilities.empty());
 }
 
 /*
@@ -1082,6 +1087,7 @@
  * 2. Sets AGnssRilCallback.
  * 3. Update network state to connected and then disconnected.
  * 4. Sets reference location.
+ * 5. Injects empty NI message data and verifies that it returns an error.
  */
 TEST_P(GnssHalTest, TestAGnssRilExtension) {
     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
@@ -1125,6 +1131,11 @@
 
     status = iAGnssRil->setRefLocation(agnssReflocation);
     ASSERT_TRUE(status.isOk());
+
+    if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+        status = iAGnssRil->injectNiSuplMessageData(std::vector<uint8_t>(), 0);
+        ASSERT_FALSE(status.isOk());
+    }
 }
 
 /*
@@ -1396,8 +1407,9 @@
 
 /*
  * TestGnssMeasurementIntervals_WithoutLocation:
- * 1. start measurement with interval
- * 2. verify that the received measurement intervals have expected mean and stdev
+ * 1. Start measurement at intervals
+ * 2. Verify measurement are received at expected intervals
+ * 3. Verify status are reported at expected intervals
  */
 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_WithoutLocation) {
     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
@@ -1417,20 +1429,32 @@
         auto callback = sp<GnssMeasurementCallbackAidl>::make();
         startMeasurementWithInterval(intervals[i], iGnssMeasurement, callback);
 
-        std::vector<int> deltas;
-        collectMeasurementIntervals(callback, numEvents[i], /* timeoutSeconds= */ 10, deltas);
+        std::vector<int> measurementDeltas;
+        std::vector<int> svInfoListTimestampsDeltas;
 
+        collectMeasurementIntervals(callback, numEvents[i], /* timeoutSeconds= */ 10,
+                                    measurementDeltas);
+        if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+            collectSvInfoListTimestamps(numEvents[i], /* timeoutSeconds= */ 10,
+                                        svInfoListTimestampsDeltas);
+        }
         status = iGnssMeasurement->close();
         ASSERT_TRUE(status.isOk());
 
-        assertMeanAndStdev(intervals[i], deltas);
+        assertMeanAndStdev(intervals[i], measurementDeltas);
+
+        if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+            assertMeanAndStdev(intervals[i], svInfoListTimestampsDeltas);
+            EXPECT_TRUE(aidl_gnss_cb_->sv_info_list_cbq_.size() > 0);
+        }
     }
 }
 
 /*
  * TestGnssMeasurementIntervals_LocationOnBeforeMeasurement:
- * 1. start measurement with interval
- * 2. verify that the received measurement intervals have expected mean and stdev
+ * 1. Start location at 1s.
+ * 2. Start measurement at 2s. Verify measurements are received at 1s.
+ * 3. Stop measurement. Stop location.
  */
 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnBeforeMeasurement) {
     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
@@ -1465,15 +1489,17 @@
 }
 
 /*
- * TestGnssMeasurementIntervals:
- * 1. start measurement with interval
- * 2. verify that the received measurement intervals have expected mean and stdev
+ * TestGnssMeasurementIntervals_LocationOnAfterMeasurement:
+ * 1. Start measurement at 2s
+ * 2. Start location at 1s. Verify measurements are received at 1s
+ * 3. Stop location. Verify measurements are received at 2s
+ * 4. Stop measurement
  */
 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnAfterMeasurement) {
     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
         return;
     }
-
+    const int kFirstMeasTimeoutSec = 10;
     std::vector<int> intervals({2000});
 
     sp<IGnssMeasurementInterface> iGnssMeasurement;
@@ -1482,20 +1508,171 @@
     ASSERT_TRUE(iGnssMeasurement != nullptr);
 
     int locationIntervalMs = 1000;
-    // Start location first and then start measurement
+    // Start measurement first and then start location
     ALOGD("TestGnssMeasurementIntervals_LocationOnAfterMeasurement");
     for (auto& intervalMs : intervals) {
         auto callback = sp<GnssMeasurementCallbackAidl>::make();
         startMeasurementWithInterval(intervalMs, iGnssMeasurement, callback);
 
+        // Start location and verify the measurements are received at 1Hz
         StartAndCheckFirstLocation(locationIntervalMs, /* lowPowerMode= */ false);
         std::vector<int> deltas;
-        collectMeasurementIntervals(callback, /*numEvents=*/10, /*timeoutSeconds=*/10, deltas);
+        collectMeasurementIntervals(callback, /*numEvents=*/10, kFirstMeasTimeoutSec, deltas);
+        assertMeanAndStdev(locationIntervalMs, deltas);
 
+        // Stop location request and verify the measurements are received at 2s intervals
         StopAndClearLocations();
+        callback->gnss_data_cbq_.reset();
+        deltas.clear();
+        collectMeasurementIntervals(callback, /*numEvents=*/5, kFirstMeasTimeoutSec, deltas);
+        assertMeanAndStdev(intervalMs, deltas);
+
         status = iGnssMeasurement->close();
         ASSERT_TRUE(status.isOk());
-
-        assertMeanAndStdev(locationIntervalMs, deltas);
     }
 }
+
+/*
+ * TestGnssMeasurementIntervals_changeIntervals:
+ * This test ensures setCallback() can be called consecutively without close().
+ * 1. Start measurement with 20s interval and wait for 1 measurement.
+ * 2. Start measurement with 1s interval and wait for 5 measurements.
+ *    Verify the measurements were received at 1Hz.
+ * 3. Start measurement with 2s interval and wait for 5 measurements.
+ *    Verify the measurements were received at 2s intervals.
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementIntervals_changeIntervals) {
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+        return;
+    }
+    const int kFirstGnssMeasurementTimeoutSeconds = 10;
+    sp<IGnssMeasurementInterface> iGnssMeasurement;
+    auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+    auto callback = sp<GnssMeasurementCallbackAidl>::make();
+    std::vector<int> deltas;
+
+    // setCallback at 20s interval and wait for 1 measurement
+    startMeasurementWithInterval(20000, iGnssMeasurement, callback);
+    collectMeasurementIntervals(callback, /* numEvents= */ 1, kFirstGnssMeasurementTimeoutSeconds,
+                                deltas);
+
+    // setCallback at 1s interval and wait for 5 measurements
+    callback->gnss_data_cbq_.reset();
+    deltas.clear();
+    startMeasurementWithInterval(1000, iGnssMeasurement, callback);
+    collectMeasurementIntervals(callback, /* numEvents= */ 5, kFirstGnssMeasurementTimeoutSeconds,
+                                deltas);
+
+    // verify the measurements were received at 1Hz
+    assertMeanAndStdev(1000, deltas);
+
+    // setCallback at 2s interval and wait for 5 measurements
+    callback->gnss_data_cbq_.reset();
+    deltas.clear();
+    startMeasurementWithInterval(2000, iGnssMeasurement, callback);
+    collectMeasurementIntervals(callback, /* numEvents= */ 5, kFirstGnssMeasurementTimeoutSeconds,
+                                deltas);
+
+    // verify the measurements were received at 2s intervals
+    assertMeanAndStdev(2000, deltas);
+
+    status = iGnssMeasurement->close();
+    ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * TestGnssMeasurementIsFullTracking
+ * 1. Start measurement with enableFullTracking=true. Verify the received measurements have
+ *    isFullTracking=true.
+ * 2. Start measurement with enableFullTracking = false. Verify the received measurements have
+ *    isFullTracking=false.
+ * 3. Do step 1 again.
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementIsFullTracking) {
+    // GnssData.isFullTracking is added in the interface version 3
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+        return;
+    }
+    const int kFirstGnssMeasurementTimeoutSeconds = 10;
+    const int kNumMeasurementEvents = 5;
+    std::vector<bool> isFullTrackingList({true, false, true});
+
+    sp<IGnssMeasurementInterface> iGnssMeasurement;
+    auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+    ALOGD("TestGnssMeasurementIsFullTracking");
+    auto callback = sp<GnssMeasurementCallbackAidl>::make();
+    IGnssMeasurementInterface::Options options;
+    options.intervalMs = 1000;
+
+    for (auto isFullTracking : isFullTrackingList) {
+        options.enableFullTracking = isFullTracking;
+
+        callback->gnss_data_cbq_.reset();
+        auto status = iGnssMeasurement->setCallbackWithOptions(callback, options);
+        checkGnssDataFields(callback, kNumMeasurementEvents, kFirstGnssMeasurementTimeoutSeconds,
+                            isFullTracking);
+    }
+
+    status = iGnssMeasurement->close();
+    ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * TestAccumulatedDeltaRange:
+ * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
+ * 2. Start measurement with 1s interval and wait for up to 15 measurements.
+ * 3. Verify at least one measurement has a valid AccumulatedDeltaRange state.
+ */
+TEST_P(GnssHalTest, TestAccumulatedDeltaRange) {
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+        return;
+    }
+    if ((aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_ACCUMULATED_DELTA_RANGE) ==
+        0) {
+        return;
+    }
+
+    ALOGD("TestAccumulatedDeltaRange");
+
+    auto callback = sp<GnssMeasurementCallbackAidl>::make();
+    sp<IGnssMeasurementInterface> iGnssMeasurement;
+    auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+    IGnssMeasurementInterface::Options options;
+    options.intervalMs = 1000;
+    options.enableFullTracking = true;
+    status = iGnssMeasurement->setCallbackWithOptions(callback, options);
+    ASSERT_TRUE(status.isOk());
+
+    bool accumulatedDeltaRangeFound = false;
+    const int kNumMeasurementEvents = 15;
+
+    // setCallback at 1s interval and wait for 15 measurements
+    for (int i = 0; i < kNumMeasurementEvents; i++) {
+        GnssData lastGnssData;
+        ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, 10));
+        EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+        ASSERT_TRUE(lastGnssData.measurements.size() > 0);
+
+        // Validity check GnssData fields
+        checkGnssMeasurementClockFields(lastGnssData);
+        for (const auto& measurement : lastGnssData.measurements) {
+            if ((measurement.accumulatedDeltaRangeState & measurement.ADR_STATE_VALID) > 0) {
+                accumulatedDeltaRangeFound = true;
+                break;
+            }
+        }
+        if (accumulatedDeltaRangeFound) break;
+    }
+    ASSERT_TRUE(accumulatedDeltaRangeFound);
+    status = iGnssMeasurement->close();
+    ASSERT_TRUE(status.isOk());
+}
\ No newline at end of file
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index b896f04..4cf17a6 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -57,6 +57,6 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
-        "android.hardware.gnss-V2-ndk",
+        "android.hardware.gnss-V3-ndk",
     ],
 }
diff --git a/gnss/common/utils/default/DeviceFileReader.cpp b/gnss/common/utils/default/DeviceFileReader.cpp
index dfc086a..91e75eb 100644
--- a/gnss/common/utils/default/DeviceFileReader.cpp
+++ b/gnss/common/utils/default/DeviceFileReader.cpp
@@ -32,40 +32,52 @@
         return;
     }
 
-    int mGnssFd = open(deviceFilePath.c_str(), O_RDWR | O_NONBLOCK);
-
-    if (mGnssFd == -1) {
+    int gnss_fd, epoll_fd;
+    if ((gnss_fd = open(deviceFilePath.c_str(), O_RDWR | O_NONBLOCK)) == -1) {
+        return;
+    }
+    if (write(gnss_fd, command.c_str(), command.size()) <= 0) {
+        close(gnss_fd);
         return;
     }
 
-    int bytes_write = write(mGnssFd, command.c_str(), command.size());
-    if (bytes_write <= 0) {
-        close(mGnssFd);
+    // Create an epoll instance.
+    if ((epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) {
+        close(gnss_fd);
         return;
     }
 
+    // Add file descriptor to epoll instance.
     struct epoll_event ev, events[1];
-    ev.data.fd = mGnssFd;
+    memset(&ev, 0, sizeof(ev));
+    ev.data.fd = gnss_fd;
     ev.events = EPOLLIN;
-    int epoll_fd = epoll_create1(0);
-    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mGnssFd, &ev);
+    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, gnss_fd, &ev) == -1) {
+        close(gnss_fd);
+        close(epoll_fd);
+        return;
+    }
+
+    // Wait for device file event.
+    if (epoll_wait(epoll_fd, events, 1, mMinIntervalMs) == -1) {
+        close(gnss_fd);
+        close(epoll_fd);
+        return;
+    }
+
+    // Handle event and write data to string buffer.
     int bytes_read = -1;
     std::string inputStr = "";
-    int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs);
-
-    if (epoll_ret == -1) {
-        close(mGnssFd);
-        return;
-    }
     while (true) {
         memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
-        bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE);
+        bytes_read = read(gnss_fd, &inputBuffer, INPUT_BUFFER_SIZE);
         if (bytes_read <= 0) {
             break;
         }
         s_buffer_ += std::string(inputBuffer, bytes_read);
     }
-    close(mGnssFd);
+    close(gnss_fd);
+    close(epoll_fd);
 
     // Trim end of file mark(\n\n\n\n).
     auto pos = s_buffer_.find("\n\n\n\n");
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index 4de49f3..8303d93 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -102,7 +102,7 @@
             .receivedSvTimeUncertaintyInNs = 15,
             .cN0DbHz = 30.0,
             .pseudorangeRateMps = -484.13739013671875,
-            .pseudorangeRateUncertaintyMps = 1.0379999876022339,
+            .pseudorangeRateUncertaintyMps = 0.1037999987602233,
             .accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback::
                     GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN,
             .accumulatedDeltaRangeM = 0.0,
@@ -147,7 +147,7 @@
     return gnssData;
 }
 
-GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) {
+GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs, const bool enableFullTracking) {
     aidl::android::hardware::gnss::GnssSignalType signalType = {
             .constellation = GnssConstellationType::GLONASS,
             .carrierFrequencyHz = 1.59975e+09,
@@ -169,8 +169,8 @@
             .basebandCN0DbHz = 26.5,
             .agcLevelDb = 2.3,
             .pseudorangeRateMps = -484.13739013671875,
-            .pseudorangeRateUncertaintyMps = 1.0379999876022339,
-            .accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_UNKNOWN,
+            .pseudorangeRateUncertaintyMps = 0.1037999987602233,
+            .accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_VALID,
             .accumulatedDeltaRangeM = 1.52,
             .accumulatedDeltaRangeUncertaintyM = 2.43,
             .multipathIndicator = aidl::android::hardware::gnss::GnssMultipathIndicator::UNKNOWN,
@@ -258,7 +258,8 @@
     GnssData gnssData = {.measurements = {measurement},
                          .clock = clock,
                          .elapsedRealtime = timestamp,
-                         .gnssAgcs = std::vector({gnssAgc1, gnssAgc2})};
+                         .gnssAgcs = std::vector({gnssAgc1, gnssAgc2}),
+                         .isFullTracking = enableFullTracking};
     return gnssData;
 }
 
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index ad8f539..9be4a19 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -32,7 +32,7 @@
 
 struct Utils {
     static aidl::android::hardware::gnss::GnssData getMockMeasurement(
-            const bool enableCorrVecOutputs);
+            const bool enableCorrVecOutputs, const bool enableFullTracking);
     static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
     static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
 
diff --git a/gnss/common/utils/vts/Android.bp b/gnss/common/utils/vts/Android.bp
index f92e609..b5325b2 100644
--- a/gnss/common/utils/vts/Android.bp
+++ b/gnss/common/utils/vts/Android.bp
@@ -44,7 +44,7 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.measurement_corrections@1.1",
-        "android.hardware.gnss-V2-cpp",
+        "android.hardware.gnss-V3-cpp",
     ],
     static_libs: [
         "libgtest",
diff --git a/graphics/Android.bp b/graphics/Android.bp
new file mode 100644
index 0000000..2fbcb41
--- /dev/null
+++ b/graphics/Android.bp
@@ -0,0 +1,65 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_defaults {
+    name: "android.hardware.graphics.allocator-ndk_static",
+    static_libs: [
+        "android.hardware.graphics.allocator-V2-ndk",
+    ],
+    defaults: [
+        "android.hardware.graphics.common-ndk_static",
+    ],
+}
+
+cc_defaults {
+    name: "android.hardware.graphics.allocator-ndk_shared",
+    shared_libs: [
+        "android.hardware.graphics.allocator-V2-ndk",
+    ],
+    defaults: [
+        "android.hardware.graphics.common-ndk_shared",
+    ],
+}
+
+cc_defaults {
+    name: "android.hardware.graphics.common-ndk_static",
+    static_libs: [
+        "android.hardware.graphics.common-V4-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "android.hardware.graphics.common-ndk_shared",
+    shared_libs: [
+        "android.hardware.graphics.common-V4-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "android.hardware.graphics.composer3-ndk_static",
+    static_libs: [
+        "android.hardware.graphics.composer3-V2-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "android.hardware.graphics.composer3-ndk_shared",
+    shared_libs: [
+        "android.hardware.graphics.composer3-V2-ndk",
+    ],
+}
diff --git a/graphics/OWNERS b/graphics/OWNERS
index 75ceb23..1cb6015 100644
--- a/graphics/OWNERS
+++ b/graphics/OWNERS
@@ -6,4 +6,5 @@
 chrisforbes@google.com
 jreck@google.com
 lpy@google.com
+scroggo@google.com
 sumir@google.com
\ No newline at end of file
diff --git a/graphics/allocator/2.0/default/OWNERS b/graphics/allocator/2.0/default/OWNERS
deleted file mode 100644
index c9f24d0..0000000
--- a/graphics/allocator/2.0/default/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-chrisforbes@google.com
-jreck@google.com
-lpy@google.com
diff --git a/graphics/allocator/2.0/utils/OWNERS b/graphics/allocator/2.0/utils/OWNERS
deleted file mode 100644
index c9f24d0..0000000
--- a/graphics/allocator/2.0/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-chrisforbes@google.com
-jreck@google.com
-lpy@google.com
diff --git a/graphics/allocator/aidl/Android.bp b/graphics/allocator/aidl/Android.bp
index 272ab48..a3a2c55 100644
--- a/graphics/allocator/aidl/Android.bp
+++ b/graphics/allocator/aidl/Android.bp
@@ -14,9 +14,11 @@
         enabled: true,
         support_system_process: true,
     },
+    vndk_use_version: "2",
     srcs: ["android/hardware/graphics/allocator/*.aidl"],
     imports: [
         "android.hardware.common-V2",
+        "android.hardware.graphics.common-V4",
     ],
     stability: "vintf",
     backend: {
@@ -37,11 +39,20 @@
             min_sdk_version: "29",
         },
     },
+    frozen: true,
     versions_with_info: [
         {
             version: "1",
             imports: ["android.hardware.common-V2"],
         },
+        {
+            version: "2",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.graphics.common-V4",
+            ],
+        },
+
     ],
 
 }
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/.hash b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/.hash
new file mode 100644
index 0000000..cd11a09
--- /dev/null
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/.hash
@@ -0,0 +1 @@
+9499fec09c544e9de5be3c87125721600f8ade66
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/AllocationError.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/AllocationError.aidl
new file mode 100644
index 0000000..e50d170
--- /dev/null
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/AllocationError.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.allocator;
+@Backing(type="int") @VintfStability
+enum AllocationError {
+  BAD_DESCRIPTOR,
+  NO_RESOURCES,
+  UNSUPPORTED,
+}
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/AllocationResult.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/AllocationResult.aidl
new file mode 100644
index 0000000..73cfeb5
--- /dev/null
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/AllocationResult.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.allocator;
+@VintfStability
+parcelable AllocationResult {
+  int stride;
+  android.hardware.common.NativeHandle[] buffers;
+}
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
new file mode 100644
index 0000000..49c2497
--- /dev/null
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.allocator;
+@VintfStability
+parcelable BufferDescriptorInfo {
+  byte[128] name;
+  int width;
+  int height;
+  int layerCount;
+  android.hardware.graphics.common.PixelFormat format = android.hardware.graphics.common.PixelFormat.UNSPECIFIED;
+  android.hardware.graphics.common.BufferUsage usage = android.hardware.graphics.common.BufferUsage.CPU_READ_NEVER;
+  long reservedSize;
+  android.hardware.graphics.common.ExtendableType[] additionalOptions;
+}
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/IAllocator.aidl
new file mode 100644
index 0000000..66e49a7
--- /dev/null
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/2/android/hardware/graphics/allocator/IAllocator.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.allocator;
+@VintfStability
+interface IAllocator {
+  /**
+   * @deprecated As of android.hardware.graphics.allocator-V2 in combination with AIMAPPER_VERSION_5 this is deprecated & replaced with allocate2. If android.hardware.graphics.mapper@4 is still in use, however, this is still required to be implemented.
+   */
+  android.hardware.graphics.allocator.AllocationResult allocate(in byte[] descriptor, in int count);
+  android.hardware.graphics.allocator.AllocationResult allocate2(in android.hardware.graphics.allocator.BufferDescriptorInfo descriptor, in int count);
+  boolean isSupported(in android.hardware.graphics.allocator.BufferDescriptorInfo descriptor);
+  String getIMapperLibrarySuffix();
+}
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl
index 6e7b739..e50d170 100644
--- a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/AllocationError.aidl
@@ -34,7 +34,7 @@
 package android.hardware.graphics.allocator;
 @Backing(type="int") @VintfStability
 enum AllocationError {
-  BAD_DESCRIPTOR = 0,
-  NO_RESOURCES = 1,
-  UNSUPPORTED = 2,
+  BAD_DESCRIPTOR,
+  NO_RESOURCES,
+  UNSUPPORTED,
 }
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
new file mode 100644
index 0000000..49c2497
--- /dev/null
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.allocator;
+@VintfStability
+parcelable BufferDescriptorInfo {
+  byte[128] name;
+  int width;
+  int height;
+  int layerCount;
+  android.hardware.graphics.common.PixelFormat format = android.hardware.graphics.common.PixelFormat.UNSPECIFIED;
+  android.hardware.graphics.common.BufferUsage usage = android.hardware.graphics.common.BufferUsage.CPU_READ_NEVER;
+  long reservedSize;
+  android.hardware.graphics.common.ExtendableType[] additionalOptions;
+}
diff --git a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl
index fe0b0a2..66e49a7 100644
--- a/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl
+++ b/graphics/allocator/aidl/aidl_api/android.hardware.graphics.allocator/current/android/hardware/graphics/allocator/IAllocator.aidl
@@ -34,5 +34,11 @@
 package android.hardware.graphics.allocator;
 @VintfStability
 interface IAllocator {
+  /**
+   * @deprecated As of android.hardware.graphics.allocator-V2 in combination with AIMAPPER_VERSION_5 this is deprecated & replaced with allocate2. If android.hardware.graphics.mapper@4 is still in use, however, this is still required to be implemented.
+   */
   android.hardware.graphics.allocator.AllocationResult allocate(in byte[] descriptor, in int count);
+  android.hardware.graphics.allocator.AllocationResult allocate2(in android.hardware.graphics.allocator.BufferDescriptorInfo descriptor, in int count);
+  boolean isSupported(in android.hardware.graphics.allocator.BufferDescriptorInfo descriptor);
+  String getIMapperLibrarySuffix();
 }
diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationResult.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationResult.aidl
index 0774e25..76f1c95 100644
--- a/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationResult.aidl
+++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/AllocationResult.aidl
@@ -18,13 +18,17 @@
 
 import android.hardware.common.NativeHandle;
 
- /**
+/**
  * Result of an IAllocator::allocate call.
  *
  * @sa +ndk libnativewindow#AHardwareBuffer_Desc
  */
 @VintfStability
 parcelable AllocationResult {
+    /**
+     * The number of pixels between two consecutive rows of an allocated buffer, when the concept
+     * of consecutive rows is defined. Otherwise, it has no meaning.
+     */
     int stride;
     NativeHandle[] buffers;
-}
\ No newline at end of file
+}
diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
new file mode 100644
index 0000000..50aa2b7
--- /dev/null
+++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/BufferDescriptorInfo.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.allocator;
+
+import android.hardware.graphics.common.BufferUsage;
+import android.hardware.graphics.common.ExtendableType;
+import android.hardware.graphics.common.PixelFormat;
+
+@VintfStability
+parcelable BufferDescriptorInfo {
+    /**
+     * The name of the buffer in ASCII. Useful for debugging/tracing.
+     */
+    byte[128] name;
+
+    /**
+     * The width specifies how many columns of pixels must be in the
+     * allocated buffer, but does not necessarily represent the offset in
+     * columns between the same column in adjacent rows. The rows may be
+     * padded.
+     */
+    int width;
+
+    /**
+     * The height specifies how many rows of pixels must be in the
+     * allocated buffer.
+     */
+    int height;
+
+    /**
+     * The number of image layers that must be in the allocated buffer.
+     */
+    int layerCount;
+
+    /**
+     * Buffer pixel format. See PixelFormat.aidl in graphics/common for
+     * valid values
+     */
+    PixelFormat format = PixelFormat.UNSPECIFIED;
+
+    /**
+     * Buffer usage mask; valid flags can be found in the definition of
+     * BufferUsage.aidl in graphics/common
+     *
+     * The allocator must report isSupported() == false and reject any allocations
+     * with unrecognized buffer usages.
+     */
+    BufferUsage usage = BufferUsage.CPU_READ_NEVER;
+
+    /**
+     * The size in bytes of the reserved region associated with the buffer.
+     * See getReservedRegion for more information.
+     */
+    long reservedSize;
+
+    /**
+     * Extensible additional options that can be set.
+     *
+     * This is intended for options that do not change the overall usage, but which do impact
+     * how a buffer is allocated. An example of this is compression level, such as for
+     * the EGL_EXT_surface_compression extension.
+     *
+     * The allocator must report isSupported() == false and reject any allocations
+     * with unrecognized options.
+     */
+    ExtendableType[] additionalOptions;
+}
diff --git a/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
index 92dfd4f..2277bae 100644
--- a/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
+++ b/graphics/allocator/aidl/android/hardware/graphics/allocator/IAllocator.aidl
@@ -17,6 +17,7 @@
 package android.hardware.graphics.allocator;
 
 import android.hardware.graphics.allocator.AllocationResult;
+import android.hardware.graphics.allocator.BufferDescriptorInfo;
 
 @VintfStability
 interface IAllocator {
@@ -31,6 +32,45 @@
      * @param count The number of buffers to allocate.
      * @return An AllocationResult containing the result of the allocation
      * @throws AllocationError on failure
+     * @deprecated As of android.hardware.graphics.allocator-V2 in combination with
+     *             AIMAPPER_VERSION_5 this is deprecated & replaced with allocate2.
+     *             If android.hardware.graphics.mapper@4 is still in use, however, this is
+     *             still required to be implemented.
      */
     AllocationResult allocate(in byte[] descriptor, in int count);
+
+    /**
+     * Allocates buffers with the properties specified by the descriptor.
+     *
+     * Allocations should be optimized for usage bits provided in the
+     * descriptor.
+     *
+     * @param descriptor Properties of the buffers to allocate. This must be
+     *     obtained from IMapper::createDescriptor().
+     * @param count The number of buffers to allocate.
+     * @return An AllocationResult containing the result of the allocation
+     * @throws AllocationError on failure
+     */
+    AllocationResult allocate2(in BufferDescriptorInfo descriptor, in int count);
+
+    /**
+     * Test whether the given BufferDescriptorInfo is allocatable.
+     *
+     * If this function returns true, it means that a buffer with the given
+     * description can be allocated on this implementation, unless resource
+     * exhaustion occurs. If this function returns false, it means that the
+     * allocation of the given description will never succeed.
+     *
+     * @param description the description of the buffer
+     * @return supported whether the description is supported
+     */
+    boolean isSupported(in BufferDescriptorInfo descriptor);
+
+    /**
+     * Retrieve the library suffix to load for the IMapper SP-HAL. This library must implement the
+     * IMapper stable-C interface (android/hardware/graphics/mapper/IMapper.h).
+     *
+     * The library that will attempt to be loaded is "/vendor/lib[64]/hw/mapper.<imapper_suffix>.so"
+     */
+    String getIMapperLibrarySuffix();
 }
diff --git a/graphics/allocator/aidl/vts/Android.bp b/graphics/allocator/aidl/vts/Android.bp
index 99ffb24..630ab2a 100644
--- a/graphics/allocator/aidl/vts/Android.bp
+++ b/graphics/allocator/aidl/vts/Android.bp
@@ -27,6 +27,7 @@
     name: "VtsHalGraphicsAllocatorAidl_TargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
+        "android.hardware.graphics.allocator-ndk_shared",
         "use_libaidlvintf_gtest_helper_static",
         "hwui_defaults",
     ],
@@ -35,8 +36,6 @@
     ],
 
     shared_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
-        "android.hardware.graphics.common-V3-ndk",
         "android.hardware.graphics.mapper@4.0",
         "libEGL",
         "libGLESv2",
@@ -56,6 +55,7 @@
     ],
     header_libs: [
         "libhwui_internal_headers",
+        "libimapper_stablec",
     ],
     cflags: [
         "-Wall",
diff --git a/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp b/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
index 59af5cf..4778020 100644
--- a/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
+++ b/graphics/allocator/aidl/vts/VtsHalGraphicsAllocatorAidl_TargetTest.cpp
@@ -25,7 +25,10 @@
 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
 #include <aidlcommonsupport/NativeHandle.h>
 #include <android/binder_manager.h>
+#include <android/dlext.h>
 #include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+#include <dlfcn.h>
 #include <gtest/gtest.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
@@ -33,6 +36,7 @@
 #include <renderthread/EglManager.h>
 #include <utils/GLUtils.h>
 #include <vndk/hardware_buffer.h>
+#include <vndksupport/linker.h>
 #include <initializer_list>
 #include <optional>
 #include <string>
@@ -42,60 +46,70 @@
 using namespace aidl::android::hardware::graphics::common;
 using namespace android;
 using namespace android::hardware;
-using namespace android::hardware::graphics::mapper::V4_0;
+using IMapper4 = android::hardware::graphics::mapper::V4_0::IMapper;
+using Error = android::hardware::graphics::mapper::V4_0::Error;
+using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
 using android::uirenderer::AutoEglImage;
 using android::uirenderer::AutoGLFramebuffer;
 using android::uirenderer::AutoSkiaGlTexture;
 using android::uirenderer::renderthread::EglManager;
 
-static constexpr uint64_t pack(const std::initializer_list<BufferUsage>& usages) {
-    uint64_t ret = 0;
-    for (const auto u : usages) {
-        ret |= static_cast<uint64_t>(u);
-    }
-    return ret;
+typedef AIMapper_Error (*AIMapper_loadIMapperFn)(AIMapper* _Nullable* _Nonnull outImplementation);
+
+inline BufferUsage operator|(BufferUsage lhs, BufferUsage rhs) {
+    using T = std::underlying_type_t<BufferUsage>;
+    return static_cast<BufferUsage>(static_cast<T>(lhs) | static_cast<T>(rhs));
 }
 
-static constexpr hardware::graphics::common::V1_2::PixelFormat cast(PixelFormat format) {
-    return static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
+inline BufferUsage& operator|=(BufferUsage& lhs, BufferUsage rhs) {
+    lhs = lhs | rhs;
+    return lhs;
 }
 
+static IMapper4::BufferDescriptorInfo convert(const BufferDescriptorInfo& info) {
+    return IMapper4::BufferDescriptorInfo{
+            .name{reinterpret_cast<const char*>(info.name.data())},
+            .width = static_cast<uint32_t>(info.width),
+            .height = static_cast<uint32_t>(info.height),
+            .layerCount = static_cast<uint32_t>(info.layerCount),
+            .format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(info.format),
+            .usage = static_cast<uint64_t>(info.usage),
+            .reservedSize = 0,
+    };
+}
+
+class GraphicsTestsBase;
+
 class BufferHandle {
-    sp<IMapper> mMapper;
+    GraphicsTestsBase& mTestBase;
     native_handle_t* mRawHandle;
     bool mImported = false;
     uint32_t mStride;
-    const IMapper::BufferDescriptorInfo mInfo;
+    const BufferDescriptorInfo mInfo;
 
     BufferHandle(const BufferHandle&) = delete;
     void operator=(const BufferHandle&) = delete;
 
   public:
-    BufferHandle(const sp<IMapper> mapper, native_handle_t* handle, bool imported, uint32_t stride,
-                 const IMapper::BufferDescriptorInfo& info)
-        : mMapper(mapper), mRawHandle(handle), mImported(imported), mStride(stride), mInfo(info) {}
+    BufferHandle(GraphicsTestsBase& testBase, native_handle_t* handle, bool imported,
+                 uint32_t stride, const BufferDescriptorInfo& info)
+        : mTestBase(testBase),
+          mRawHandle(handle),
+          mImported(imported),
+          mStride(stride),
+          mInfo(info) {}
 
-    ~BufferHandle() {
-        if (mRawHandle == nullptr) return;
-
-        if (mImported) {
-            Error error = mMapper->freeBuffer(mRawHandle);
-            EXPECT_EQ(Error::NONE, error) << "failed to free buffer " << mRawHandle;
-        } else {
-            native_handle_close(mRawHandle);
-            native_handle_delete(mRawHandle);
-        }
-    }
+    ~BufferHandle();
 
     uint32_t stride() const { return mStride; }
 
     AHardwareBuffer_Desc describe() const {
         return {
-                .width = mInfo.width,
-                .height = mInfo.height,
-                .layers = mInfo.layerCount,
+                .width = static_cast<uint32_t>(mInfo.width),
+                .height = static_cast<uint32_t>(mInfo.height),
+                .layers = static_cast<uint32_t>(mInfo.layerCount),
                 .format = static_cast<uint32_t>(mInfo.format),
-                .usage = mInfo.usage,
+                .usage = static_cast<uint64_t>(mInfo.usage),
                 .stride = stride(),
                 .rfu0 = 0,
                 .rfu1 = 0,
@@ -114,25 +128,43 @@
 
 class GraphicsTestsBase {
   private:
+    friend class BufferHandle;
+    int32_t mIAllocatorVersion = 1;
     std::shared_ptr<IAllocator> mAllocator;
-    sp<IMapper> mMapper;
+    sp<IMapper4> mMapper4;
+    AIMapper* mAIMapper = nullptr;
 
   protected:
-    void Initialize(std::string allocatorService, std::string mapperService) {
+    void Initialize(std::string allocatorService) {
         mAllocator = IAllocator::fromBinder(
                 ndk::SpAIBinder(AServiceManager_checkService(allocatorService.c_str())));
-        mMapper = IMapper::getService(mapperService);
+        ASSERT_TRUE(mAllocator->getInterfaceVersion(&mIAllocatorVersion).isOk());
+        if (mIAllocatorVersion >= 2) {
+            std::string mapperSuffix;
+            auto status = mAllocator->getIMapperLibrarySuffix(&mapperSuffix);
+            ASSERT_TRUE(status.isOk());
+            std::string lib_name = "mapper." + mapperSuffix + ".so";
+            void* so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
+            ASSERT_NE(nullptr, so) << "Failed to load " << lib_name;
+            auto loadIMapper = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
+            ASSERT_NE(nullptr, loadIMapper) << "AIMapper_locaIMapper missing from " << lib_name;
+            ASSERT_EQ(AIMAPPER_ERROR_NONE, loadIMapper(&mAIMapper));
+            ASSERT_NE(mAIMapper, nullptr);
+        } else {
+            // Don't have IMapper 5, fall back to IMapper 4
+            mMapper4 = IMapper4::getService();
+            ASSERT_NE(nullptr, mMapper4.get()) << "failed to get mapper service";
+            ASSERT_FALSE(mMapper4->isRemote()) << "mapper is not in passthrough mode";
+        }
 
         ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
-        ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
-        ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
     }
 
-  public:
-    BufferDescriptor createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
+  private:
+    BufferDescriptor createDescriptor(const BufferDescriptorInfo& descriptorInfo) {
         BufferDescriptor descriptor;
-        mMapper->createDescriptor(
-                descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
+        mMapper4->createDescriptor(
+                convert(descriptorInfo), [&](const auto& tmpError, const auto& tmpDescriptor) {
                     ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
                     descriptor = tmpDescriptor;
                 });
@@ -140,14 +172,22 @@
         return descriptor;
     }
 
-    std::unique_ptr<BufferHandle> allocate(const IMapper::BufferDescriptorInfo& descriptorInfo) {
-        auto descriptor = createDescriptor(descriptorInfo);
-        if (::testing::Test::HasFatalFailure()) {
-            return nullptr;
-        }
-
+  public:
+    std::unique_ptr<BufferHandle> allocate(const BufferDescriptorInfo& descriptorInfo) {
         AllocationResult result;
-        auto status = mAllocator->allocate(descriptor, 1, &result);
+        ::ndk::ScopedAStatus status;
+        if (mIAllocatorVersion >= 2) {
+            status = mAllocator->allocate2(descriptorInfo, 1, &result);
+        } else {
+            auto descriptor = createDescriptor(descriptorInfo);
+            if (::testing::Test::HasFatalFailure()) {
+                return nullptr;
+            }
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+            status = mAllocator->allocate(descriptor, 1, &result);
+#pragma clang diagnostic pop  // deprecation
+        }
         if (!status.isOk()) {
             status_t error = status.getExceptionCode();
             if (error == EX_SERVICE_SPECIFIC) {
@@ -158,28 +198,50 @@
             }
             return nullptr;
         } else {
-            return std::make_unique<BufferHandle>(mMapper, dupFromAidl(result.buffers[0]), false,
+            return std::make_unique<BufferHandle>(*this, dupFromAidl(result.buffers[0]), false,
                                                   result.stride, descriptorInfo);
         }
     }
 
-    bool isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
+    bool isSupported(const BufferDescriptorInfo& descriptorInfo) {
         bool ret = false;
-        EXPECT_TRUE(mMapper->isSupported(descriptorInfo,
-                                         [&](auto error, bool supported) {
-                                             ASSERT_EQ(Error::NONE, error);
-                                             ret = supported;
-                                         })
-                            .isOk());
+        if (mIAllocatorVersion >= 2) {
+            EXPECT_TRUE(mAllocator->isSupported(descriptorInfo, &ret).isOk());
+        } else {
+            EXPECT_TRUE(mMapper4->isSupported(convert(descriptorInfo),
+                                              [&](auto error, bool supported) {
+                                                  ASSERT_EQ(Error::NONE, error);
+                                                  ret = supported;
+                                              })
+                                .isOk());
+        }
         return ret;
     }
+
+    int32_t allocatorVersion() const { return mIAllocatorVersion; }
 };
 
-class GraphicsAllocatorAidlTests
-    : public GraphicsTestsBase,
-      public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+BufferHandle::~BufferHandle() {
+    if (mRawHandle == nullptr) return;
+
+    if (mImported) {
+        if (mTestBase.mAIMapper) {
+            AIMapper_Error error = mTestBase.mAIMapper->v5.freeBuffer(mRawHandle);
+            EXPECT_EQ(AIMAPPER_ERROR_NONE, error);
+        } else {
+            Error error = mTestBase.mMapper4->freeBuffer(mRawHandle);
+            EXPECT_EQ(Error::NONE, error) << "failed to free buffer " << mRawHandle;
+        }
+    } else {
+        native_handle_close(mRawHandle);
+        native_handle_delete(mRawHandle);
+    }
+}
+
+class GraphicsAllocatorAidlTests : public GraphicsTestsBase,
+                                   public ::testing::TestWithParam<std::string> {
   public:
-    void SetUp() override { Initialize(std::get<0>(GetParam()), std::get<1>(GetParam())); }
+    void SetUp() override { Initialize(GetParam()); }
 
     void TearDown() override {}
 };
@@ -191,22 +253,22 @@
 
 class GraphicsFrontBufferTests
     : public GraphicsTestsBase,
-      public ::testing::TestWithParam<std::tuple<std::string, std::string, FlushMethod>> {
+      public ::testing::TestWithParam<std::tuple<std::string, FlushMethod>> {
   private:
     EglManager eglManager;
     std::function<void(EglManager&)> flush;
 
   public:
     void SetUp() override {
-        Initialize(std::get<0>(GetParam()), std::get<1>(GetParam()));
-        flush = std::get<2>(GetParam()).func;
+        Initialize(std::get<0>(GetParam()));
+        flush = std::get<1>(GetParam()).func;
         eglManager.initialize();
     }
 
     void TearDown() override { eglManager.destroy(); }
 
     void fillWithGpu(AHardwareBuffer* buffer, float red, float green, float blue, float alpha) {
-        const EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(buffer);
+        EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(buffer);
         AutoEglImage eglImage(eglManager.eglDisplay(), clientBuffer);
         AutoSkiaGlTexture glTexture;
         AutoGLFramebuffer glFbo;
@@ -235,41 +297,85 @@
     }
 };
 
-TEST_P(GraphicsAllocatorAidlTests, CreateDescriptorBasic) {
-    ASSERT_NO_FATAL_FAILURE(createDescriptor({
-            .name = "CPU_8888",
-            .width = 64,
-            .height = 64,
-            .layerCount = 1,
-            .format = cast(PixelFormat::RGBA_8888),
-            .usage = pack({BufferUsage::CPU_WRITE_OFTEN, BufferUsage::CPU_READ_OFTEN}),
-            .reservedSize = 0,
-    }));
-}
-
 TEST_P(GraphicsAllocatorAidlTests, CanAllocate) {
     auto buffer = allocate({
-            .name = "CPU_8888",
+            .name = {"CPU_8888"},
             .width = 64,
             .height = 64,
             .layerCount = 1,
-            .format = cast(PixelFormat::RGBA_8888),
-            .usage = pack({BufferUsage::CPU_WRITE_OFTEN, BufferUsage::CPU_READ_OFTEN}),
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
             .reservedSize = 0,
     });
     ASSERT_NE(nullptr, buffer.get());
     EXPECT_GE(buffer->stride(), 64);
 }
 
-TEST_P(GraphicsFrontBufferTests, FrontBufferGpuToCpu) {
-    IMapper::BufferDescriptorInfo info{
-            .name = "CPU_8888",
+TEST_P(GraphicsAllocatorAidlTests, RejectsUnknownUsages) {
+    if (allocatorVersion() < 2) {
+        GTEST_SKIP() << "Must be version 2+";
+        return;
+    }
+
+    constexpr auto FirstInvalidV2Usage = static_cast<BufferUsage>(1LL << 33);
+
+    BufferUsage invalidUsage;
+    if (allocatorVersion() == 2) {
+        invalidUsage = FirstInvalidV2Usage;
+    } else {
+        GTEST_FAIL() << "Unknown version " << allocatorVersion();
+    }
+
+    BufferDescriptorInfo info{
+            .name = {"CPU_8888"},
             .width = 64,
             .height = 64,
             .layerCount = 1,
-            .format = cast(PixelFormat::RGBA_8888),
-            .usage = pack({BufferUsage::GPU_RENDER_TARGET, BufferUsage::CPU_READ_OFTEN,
-                           BufferUsage::FRONT_BUFFER}),
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
+            .reservedSize = 0,
+    };
+
+    // First make sure we can allocate a known usage buffer as expected
+    EXPECT_TRUE(isSupported(info));
+    EXPECT_TRUE(allocate(info));
+
+    // Now add the unknown bit and verify it's rejected
+    info.usage |= invalidUsage;
+    EXPECT_FALSE(isSupported(info)) << "isSupported() returned true for unknown-to-HAL usage";
+    EXPECT_FALSE(allocate(info)) << "allocate succeeded for unknown-to-HAL usage";
+}
+
+TEST_P(GraphicsAllocatorAidlTests, RejectsUnknownOptions) {
+    if (allocatorVersion() < 2) {
+        GTEST_SKIP() << "Must be version 2+";
+        return;
+    }
+
+    BufferDescriptorInfo info{
+            .name = {"CPU_8888"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
+            .reservedSize = 0,
+    };
+    info.additionalOptions.push_back({"android.hardware.graphics.common.NotARealOption", 1});
+
+    EXPECT_FALSE(isSupported(info)) << "isSupported() returned true for unknown-to-HAL option";
+    EXPECT_FALSE(allocate(info)) << "allocate succeeded for unknown-to-HAL option";
+}
+
+TEST_P(GraphicsFrontBufferTests, FrontBufferGpuToCpu) {
+    BufferDescriptorInfo info{
+            .name = {"CPU_8888"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::GPU_RENDER_TARGET | BufferUsage::CPU_READ_OFTEN |
+                     BufferUsage::FRONT_BUFFER,
             .reservedSize = 0,
     };
     const bool supported = isSupported(info);
@@ -304,14 +410,14 @@
 }
 
 TEST_P(GraphicsFrontBufferTests, FrontBufferGpuToGpu) {
-    IMapper::BufferDescriptorInfo info{
-            .name = "CPU_8888",
+    BufferDescriptorInfo info{
+            .name = {"CPU_8888"},
             .width = 64,
             .height = 64,
             .layerCount = 1,
-            .format = cast(PixelFormat::RGBA_8888),
-            .usage = pack({BufferUsage::GPU_RENDER_TARGET, BufferUsage::GPU_TEXTURE,
-                           BufferUsage::FRONT_BUFFER}),
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::GPU_RENDER_TARGET | BufferUsage::GPU_TEXTURE |
+                     BufferUsage::FRONT_BUFFER,
             .reservedSize = 0,
     };
     const bool supported = isSupported(info);
@@ -344,11 +450,9 @@
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsAllocatorAidlTests);
-INSTANTIATE_TEST_CASE_P(
-        PerInstance, GraphicsAllocatorAidlTests,
-        testing::Combine(testing::ValuesIn(getAidlHalInstanceNames(IAllocator::descriptor)),
-                         testing::ValuesIn(getAllHalInstanceNames(IMapper::descriptor))),
-        PrintInstanceTupleNameToString<>);
+INSTANTIATE_TEST_CASE_P(PerInstance, GraphicsAllocatorAidlTests,
+                        testing::ValuesIn(getAidlHalInstanceNames(IAllocator::descriptor)),
+                        PrintInstanceNameToString);
 
 const auto FlushMethodsValues = testing::Values(
         FlushMethod{"glFinish", [](EglManager&) { glFinish(); }},
@@ -362,7 +466,7 @@
                     }},
         FlushMethod{"eglClientWaitSync", [](EglManager& eglManager) {
                         EGLDisplay display = eglManager.eglDisplay();
-                        EGLSyncKHR fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL);
+                        EGLSyncKHR fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
                         eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                              EGL_FOREVER_KHR);
                         eglDestroySyncKHR(display, fence);
@@ -371,9 +475,8 @@
 INSTANTIATE_TEST_CASE_P(
         PerInstance, GraphicsFrontBufferTests,
         testing::Combine(testing::ValuesIn(getAidlHalInstanceNames(IAllocator::descriptor)),
-                         testing::ValuesIn(getAllHalInstanceNames(IMapper::descriptor)),
                          FlushMethodsValues),
         [](auto info) -> std::string {
-            std::string name = std::to_string(info.index) + "/" + std::get<2>(info.param).name;
+            std::string name = std::to_string(info.index) + "/" + std::get<1>(info.param).name;
             return Sanitize(name);
-        });
+        });
\ No newline at end of file
diff --git a/graphics/bufferqueue/1.0/Android.bp b/graphics/bufferqueue/1.0/Android.bp
index 11559b2..82c71f1 100644
--- a/graphics/bufferqueue/1.0/Android.bp
+++ b/graphics/bufferqueue/1.0/Android.bp
@@ -27,7 +27,7 @@
     gen_java: true,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
         "com.android.media",
         "com.android.media.swcodec",
     ],
diff --git a/graphics/bufferqueue/2.0/Android.bp b/graphics/bufferqueue/2.0/Android.bp
index 552daff..3067e24 100644
--- a/graphics/bufferqueue/2.0/Android.bp
+++ b/graphics/bufferqueue/2.0/Android.bp
@@ -29,7 +29,7 @@
     gen_java: true,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
         "com.android.media",
         "com.android.media.swcodec",
     ],
diff --git a/graphics/common/1.0/Android.bp b/graphics/common/1.0/Android.bp
index 19c51cd..3288583 100644
--- a/graphics/common/1.0/Android.bp
+++ b/graphics/common/1.0/Android.bp
@@ -23,7 +23,7 @@
     gen_java_constants: true,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
         "com.android.media.swcodec",
         "test_com.android.media.swcodec",
     ],
diff --git a/graphics/common/1.1/Android.bp b/graphics/common/1.1/Android.bp
index 0f1b5bf..5d07eae 100644
--- a/graphics/common/1.1/Android.bp
+++ b/graphics/common/1.1/Android.bp
@@ -26,7 +26,7 @@
     gen_java_constants: true,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
         "com.android.media.swcodec",
         "test_com.android.media.swcodec",
     ],
diff --git a/graphics/common/1.2/Android.bp b/graphics/common/1.2/Android.bp
index ce3350d..4aa4af5 100644
--- a/graphics/common/1.2/Android.bp
+++ b/graphics/common/1.2/Android.bp
@@ -27,7 +27,7 @@
     gen_java_constants: true,
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
         "com.android.media.swcodec",
         "test_com.android.media.swcodec",
     ],
diff --git a/graphics/common/1.2/types.hal b/graphics/common/1.2/types.hal
index ebea1dc..07e9882 100644
--- a/graphics/common/1.2/types.hal
+++ b/graphics/common/1.2/types.hal
@@ -77,6 +77,8 @@
     HEIF = 0x1004,
 };
 
+@export(name="android_color_mode_v1_2_t", value_prefix="HAL_COLOR_MODE_",
+        export_parent="false")
 enum ColorMode : @1.1::ColorMode {
     /**
      * DISPLAY_BT2020 corresponds with display settings that implement the ITU-R
diff --git a/graphics/common/OWNERS b/graphics/common/OWNERS
deleted file mode 100644
index 94999ea..0000000
--- a/graphics/common/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 1075130
-adyabr@google.com
-alecmouri@google.com
-jreck@google.com
-scroggo@google.com
diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp
index 40a575d..02334e8 100644
--- a/graphics/common/aidl/Android.bp
+++ b/graphics/common/aidl/Android.bp
@@ -15,7 +15,7 @@
         enabled: true,
         support_system_process: true,
     },
-    vndk_use_version: "3",
+    vndk_use_version: "4",
     srcs: [
         "android/hardware/graphics/common/*.aidl",
     ],
@@ -39,7 +39,11 @@
             ],
             min_sdk_version: "29",
         },
+        rust: {
+            enabled: true,
+        },
     },
+    frozen: true,
     versions_with_info: [
         {
             version: "1",
@@ -59,5 +63,10 @@
                 "android.hardware.common-V2",
             ],
         },
+        {
+            version: "4",
+            imports: ["android.hardware.common-V2"],
+        },
+
     ],
 }
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/.hash b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/.hash
new file mode 100644
index 0000000..ef17b34
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/.hash
@@ -0,0 +1 @@
+9bcf4b83485ce912dc39108201504f77b8c96cef
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/AlphaInterpretation.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/AlphaInterpretation.aidl
new file mode 100644
index 0000000..ea60283
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/AlphaInterpretation.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AlphaInterpretation {
+  COVERAGE = 0,
+  MASK = 1,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BlendMode.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BlendMode.aidl
new file mode 100644
index 0000000..d1f61be
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BlendMode.aidl
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum BlendMode {
+  INVALID = 0,
+  NONE = 1,
+  PREMULTIPLIED = 2,
+  COVERAGE = 3,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BufferUsage.aidl
new file mode 100644
index 0000000..d42a6d5
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/BufferUsage.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum BufferUsage {
+  CPU_READ_MASK = 0xf,
+  CPU_READ_NEVER = 0,
+  CPU_READ_RARELY = 2,
+  CPU_READ_OFTEN = 3,
+  CPU_WRITE_MASK = (0xf << 4) /* 240 */,
+  CPU_WRITE_NEVER = (0 << 4) /* 0 */,
+  CPU_WRITE_RARELY = (2 << 4) /* 32 */,
+  CPU_WRITE_OFTEN = (3 << 4) /* 48 */,
+  GPU_TEXTURE = (1 << 8) /* 256 */,
+  GPU_RENDER_TARGET = (1 << 9) /* 512 */,
+  COMPOSER_OVERLAY = (1 << 11) /* 2048 */,
+  COMPOSER_CLIENT_TARGET = (1 << 12) /* 4096 */,
+  PROTECTED = (1 << 14) /* 16384 */,
+  COMPOSER_CURSOR = (1 << 15) /* 32768 */,
+  VIDEO_ENCODER = (1 << 16) /* 65536 */,
+  CAMERA_OUTPUT = (1 << 17) /* 131072 */,
+  CAMERA_INPUT = (1 << 18) /* 262144 */,
+  RENDERSCRIPT = (1 << 20) /* 1048576 */,
+  VIDEO_DECODER = (1 << 22) /* 4194304 */,
+  SENSOR_DIRECT_DATA = (1 << 23) /* 8388608 */,
+  GPU_DATA_BUFFER = (1 << 24) /* 16777216 */,
+  GPU_CUBE_MAP = (1 << 25) /* 33554432 */,
+  GPU_MIPMAP_COMPLETE = (1 << 26) /* 67108864 */,
+  HW_IMAGE_ENCODER = (1 << 27) /* 134217728 */,
+  FRONT_BUFFER = (1L << 32) /* 4294967296 */,
+  VENDOR_MASK = (0xf << 28) /* -268435456 */,
+  VENDOR_MASK_HI = ((1L * 0xffff) << 48) /* -281474976710656 */,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/ChromaSiting.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/ChromaSiting.aidl
new file mode 100644
index 0000000..b8af644
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/ChromaSiting.aidl
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum ChromaSiting {
+  NONE = 0,
+  UNKNOWN = 1,
+  SITED_INTERSTITIAL = 2,
+  COSITED_HORIZONTAL = 3,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/ColorTransform.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/ColorTransform.aidl
new file mode 100644
index 0000000..f74859b
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/ColorTransform.aidl
@@ -0,0 +1,45 @@
+/**
+ * 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.graphics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ColorTransform {
+  IDENTITY = 0,
+  ARBITRARY_MATRIX = 1,
+  VALUE_INVERSE = 2,
+  GRAYSCALE = 3,
+  CORRECT_PROTANOPIA = 4,
+  CORRECT_DEUTERANOPIA = 5,
+  CORRECT_TRITANOPIA = 6,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Compression.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Compression.aidl
new file mode 100644
index 0000000..4f155e1
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Compression.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum Compression {
+  NONE = 0,
+  DISPLAY_STREAM_COMPRESSION = 1,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Cta861_3.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Cta861_3.aidl
new file mode 100644
index 0000000..ec90c9c
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Cta861_3.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable Cta861_3 {
+  float maxContentLightLevel;
+  float maxFrameAverageLightLevel;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Dataspace.aidl
new file mode 100644
index 0000000..d9ff5aa
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Dataspace.aidl
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Dataspace {
+  UNKNOWN = 0x0,
+  ARBITRARY = 0x1,
+  STANDARD_SHIFT = 16,
+  STANDARD_MASK = (63 << 16) /* 4128768 */,
+  STANDARD_UNSPECIFIED = (0 << 16) /* 0 */,
+  STANDARD_BT709 = (1 << 16) /* 65536 */,
+  STANDARD_BT601_625 = (2 << 16) /* 131072 */,
+  STANDARD_BT601_625_UNADJUSTED = (3 << 16) /* 196608 */,
+  STANDARD_BT601_525 = (4 << 16) /* 262144 */,
+  STANDARD_BT601_525_UNADJUSTED = (5 << 16) /* 327680 */,
+  STANDARD_BT2020 = (6 << 16) /* 393216 */,
+  STANDARD_BT2020_CONSTANT_LUMINANCE = (7 << 16) /* 458752 */,
+  STANDARD_BT470M = (8 << 16) /* 524288 */,
+  STANDARD_FILM = (9 << 16) /* 589824 */,
+  STANDARD_DCI_P3 = (10 << 16) /* 655360 */,
+  STANDARD_ADOBE_RGB = (11 << 16) /* 720896 */,
+  TRANSFER_SHIFT = 22,
+  TRANSFER_MASK = (31 << 22) /* 130023424 */,
+  TRANSFER_UNSPECIFIED = (0 << 22) /* 0 */,
+  TRANSFER_LINEAR = (1 << 22) /* 4194304 */,
+  TRANSFER_SRGB = (2 << 22) /* 8388608 */,
+  TRANSFER_SMPTE_170M = (3 << 22) /* 12582912 */,
+  TRANSFER_GAMMA2_2 = (4 << 22) /* 16777216 */,
+  TRANSFER_GAMMA2_6 = (5 << 22) /* 20971520 */,
+  TRANSFER_GAMMA2_8 = (6 << 22) /* 25165824 */,
+  TRANSFER_ST2084 = (7 << 22) /* 29360128 */,
+  TRANSFER_HLG = (8 << 22) /* 33554432 */,
+  RANGE_SHIFT = 27,
+  RANGE_MASK = (7 << 27) /* 939524096 */,
+  RANGE_UNSPECIFIED = (0 << 27) /* 0 */,
+  RANGE_FULL = (1 << 27) /* 134217728 */,
+  RANGE_LIMITED = (2 << 27) /* 268435456 */,
+  RANGE_EXTENDED = (3 << 27) /* 402653184 */,
+  SRGB_LINEAR = (((1 << 16) | (1 << 22)) | (1 << 27)) /* 138477568 */,
+  SCRGB_LINEAR = (((1 << 16) | (1 << 22)) | (3 << 27)) /* 406913024 */,
+  SRGB = (((1 << 16) | (2 << 22)) | (1 << 27)) /* 142671872 */,
+  SCRGB = (((1 << 16) | (2 << 22)) | (3 << 27)) /* 411107328 */,
+  JFIF = (((2 << 16) | (3 << 22)) | (1 << 27)) /* 146931712 */,
+  BT601_625 = (((2 << 16) | (3 << 22)) | (2 << 27)) /* 281149440 */,
+  BT601_525 = (((4 << 16) | (3 << 22)) | (2 << 27)) /* 281280512 */,
+  BT709 = (((1 << 16) | (3 << 22)) | (2 << 27)) /* 281083904 */,
+  DCI_P3_LINEAR = (((10 << 16) | (1 << 22)) | (1 << 27)) /* 139067392 */,
+  DCI_P3 = (((10 << 16) | (5 << 22)) | (1 << 27)) /* 155844608 */,
+  DISPLAY_P3_LINEAR = (((10 << 16) | (1 << 22)) | (1 << 27)) /* 139067392 */,
+  DISPLAY_P3 = (((10 << 16) | (2 << 22)) | (1 << 27)) /* 143261696 */,
+  ADOBE_RGB = (((11 << 16) | (4 << 22)) | (1 << 27)) /* 151715840 */,
+  BT2020_LINEAR = (((6 << 16) | (1 << 22)) | (1 << 27)) /* 138805248 */,
+  BT2020 = (((6 << 16) | (3 << 22)) | (1 << 27)) /* 147193856 */,
+  BT2020_PQ = (((6 << 16) | (7 << 22)) | (1 << 27)) /* 163971072 */,
+  DEPTH = 0x1000,
+  SENSOR = 0x1001,
+  BT2020_ITU = (((6 << 16) | (3 << 22)) | (2 << 27)) /* 281411584 */,
+  BT2020_ITU_PQ = (((6 << 16) | (7 << 22)) | (2 << 27)) /* 298188800 */,
+  BT2020_ITU_HLG = (((6 << 16) | (8 << 22)) | (2 << 27)) /* 302383104 */,
+  BT2020_HLG = (((6 << 16) | (8 << 22)) | (1 << 27)) /* 168165376 */,
+  DISPLAY_BT2020 = (((6 << 16) | (2 << 22)) | (1 << 27)) /* 142999552 */,
+  DYNAMIC_DEPTH = 0x1002,
+  JPEG_APP_SEGMENTS = 0x1003,
+  HEIF = 0x1004,
+  JPEG_R = 0x1005,
+  BT709_FULL_RANGE = (((1 << 16) | (3 << 22)) | (1 << 27)) /* 146866176 */,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/DisplayDecorationSupport.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/DisplayDecorationSupport.aidl
new file mode 100644
index 0000000..27eff76
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/DisplayDecorationSupport.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.common;
+/* @hide */
+@VintfStability
+parcelable DisplayDecorationSupport {
+  android.hardware.graphics.common.PixelFormat format;
+  android.hardware.graphics.common.AlphaInterpretation alphaInterpretation;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/ExtendableType.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/ExtendableType.aidl
new file mode 100644
index 0000000..5ff1775
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/ExtendableType.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable ExtendableType {
+  @utf8InCpp String name;
+  long value = 0;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/FRect.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/FRect.aidl
new file mode 100644
index 0000000..7972e11
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/FRect.aidl
@@ -0,0 +1,42 @@
+/**
+ * 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable FRect {
+  float left;
+  float top;
+  float right;
+  float bottom;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HardwareBuffer.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HardwareBuffer.aidl
new file mode 100644
index 0000000..1817769
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HardwareBuffer.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable HardwareBuffer {
+  android.hardware.graphics.common.HardwareBufferDescription description;
+  android.hardware.common.NativeHandle handle;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HardwareBufferDescription.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HardwareBufferDescription.aidl
new file mode 100644
index 0000000..70f46a1
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HardwareBufferDescription.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable HardwareBufferDescription {
+  int width;
+  int height;
+  int layers;
+  android.hardware.graphics.common.PixelFormat format = android.hardware.graphics.common.PixelFormat.UNSPECIFIED;
+  android.hardware.graphics.common.BufferUsage usage = android.hardware.graphics.common.BufferUsage.CPU_READ_NEVER;
+  int stride;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Hdr.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Hdr.aidl
new file mode 100644
index 0000000..71927b6
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Hdr.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.graphics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Hdr {
+  INVALID = 0,
+  DOLBY_VISION = 1,
+  HDR10 = 2,
+  HLG = 3,
+  HDR10_PLUS = 4,
+  DOLBY_VISION_4K30 = 5,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HdrConversionCapability.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HdrConversionCapability.aidl
new file mode 100644
index 0000000..b74f7d7
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HdrConversionCapability.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.common;
+@VintfStability
+parcelable HdrConversionCapability {
+  android.hardware.graphics.common.Hdr sourceType;
+  android.hardware.graphics.common.Hdr outputType;
+  boolean addsLatency;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HdrConversionStrategy.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HdrConversionStrategy.aidl
new file mode 100644
index 0000000..db785cf
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/HdrConversionStrategy.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.common;
+@VintfStability
+union HdrConversionStrategy {
+  boolean passthrough = true;
+  android.hardware.graphics.common.Hdr[] autoAllowedHdrTypes;
+  android.hardware.graphics.common.Hdr forceHdrConversion;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Interlaced.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Interlaced.aidl
new file mode 100644
index 0000000..e04d2ab
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Interlaced.aidl
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum Interlaced {
+  NONE = 0,
+  TOP_BOTTOM = 1,
+  RIGHT_LEFT = 2,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PixelFormat.aidl
new file mode 100644
index 0000000..ed84a44
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PixelFormat.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum PixelFormat {
+  UNSPECIFIED = 0,
+  RGBA_8888 = 0x1,
+  RGBX_8888 = 0x2,
+  RGB_888 = 0x3,
+  RGB_565 = 0x4,
+  BGRA_8888 = 0x5,
+  YCBCR_422_SP = 0x10,
+  YCRCB_420_SP = 0x11,
+  YCBCR_422_I = 0x14,
+  RGBA_FP16 = 0x16,
+  RAW16 = 0x20,
+  BLOB = 0x21,
+  IMPLEMENTATION_DEFINED = 0x22,
+  YCBCR_420_888 = 0x23,
+  RAW_OPAQUE = 0x24,
+  RAW10 = 0x25,
+  RAW12 = 0x26,
+  RGBA_1010102 = 0x2B,
+  Y8 = 0x20203859,
+  Y16 = 0x20363159,
+  YV12 = 0x32315659,
+  DEPTH_16 = 0x30,
+  DEPTH_24 = 0x31,
+  DEPTH_24_STENCIL_8 = 0x32,
+  DEPTH_32F = 0x33,
+  DEPTH_32F_STENCIL_8 = 0x34,
+  STENCIL_8 = 0x35,
+  YCBCR_P010 = 0x36,
+  HSV_888 = 0x37,
+  R_8 = 0x38,
+  R_16_UINT = 0x39,
+  RG_1616_UINT = 0x3a,
+  RGBA_10101010 = 0x3b,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PlaneLayout.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PlaneLayout.aidl
new file mode 100644
index 0000000..a090975
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PlaneLayout.aidl
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable PlaneLayout {
+  android.hardware.graphics.common.PlaneLayoutComponent[] components;
+  long offsetInBytes;
+  long sampleIncrementInBits;
+  long strideInBytes;
+  long widthInSamples;
+  long heightInSamples;
+  long totalSizeInBytes;
+  long horizontalSubsampling;
+  long verticalSubsampling;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PlaneLayoutComponent.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PlaneLayoutComponent.aidl
new file mode 100644
index 0000000..0768240
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PlaneLayoutComponent.aidl
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable PlaneLayoutComponent {
+  android.hardware.graphics.common.ExtendableType type;
+  long offsetInBits;
+  long sizeInBits;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PlaneLayoutComponentType.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
new file mode 100644
index 0000000..e306751
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum PlaneLayoutComponentType {
+  Y = (1 << 0) /* 1 */,
+  CB = (1 << 1) /* 2 */,
+  CR = (1 << 2) /* 4 */,
+  R = (1 << 10) /* 1024 */,
+  G = (1 << 11) /* 2048 */,
+  B = (1 << 12) /* 4096 */,
+  RAW = (1 << 20) /* 1048576 */,
+  A = (1 << 30) /* 1073741824 */,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Point.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Point.aidl
new file mode 100644
index 0000000..af4705a
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Point.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable Point {
+  int x;
+  int y;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Rect.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Rect.aidl
new file mode 100644
index 0000000..463a68f
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Rect.aidl
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable Rect {
+  int left;
+  int top;
+  int right;
+  int bottom;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Smpte2086.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Smpte2086.aidl
new file mode 100644
index 0000000..dce9226
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Smpte2086.aidl
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable Smpte2086 {
+  android.hardware.graphics.common.XyColor primaryRed;
+  android.hardware.graphics.common.XyColor primaryGreen;
+  android.hardware.graphics.common.XyColor primaryBlue;
+  android.hardware.graphics.common.XyColor whitePoint;
+  float maxLuminance;
+  float minLuminance;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/StandardMetadataType.aidl
new file mode 100644
index 0000000..6e2e106
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/StandardMetadataType.aidl
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2019,libgralloctypes_helper 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.graphics.common;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum StandardMetadataType {
+  INVALID = 0,
+  BUFFER_ID = 1,
+  NAME = 2,
+  WIDTH = 3,
+  HEIGHT = 4,
+  LAYER_COUNT = 5,
+  PIXEL_FORMAT_REQUESTED = 6,
+  PIXEL_FORMAT_FOURCC = 7,
+  PIXEL_FORMAT_MODIFIER = 8,
+  USAGE = 9,
+  ALLOCATION_SIZE = 10,
+  PROTECTED_CONTENT = 11,
+  COMPRESSION = 12,
+  INTERLACED = 13,
+  CHROMA_SITING = 14,
+  PLANE_LAYOUTS = 15,
+  CROP = 16,
+  DATASPACE = 17,
+  BLEND_MODE = 18,
+  SMPTE2086 = 19,
+  CTA861_3 = 20,
+  SMPTE2094_40 = 21,
+  SMPTE2094_10 = 22,
+  STRIDE = 23,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Transform.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Transform.aidl
new file mode 100644
index 0000000..dbed57d
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/Transform.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.graphics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Transform {
+  NONE = 0,
+  FLIP_H = (1 << 0) /* 1 */,
+  FLIP_V = (1 << 1) /* 2 */,
+  ROT_90 = (1 << 2) /* 4 */,
+  ROT_180 = (FLIP_H | FLIP_V) /* 3 */,
+  ROT_270 = ((FLIP_H | FLIP_V) | ROT_90) /* 7 */,
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/XyColor.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/XyColor.aidl
new file mode 100644
index 0000000..e300f25
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/4/android/hardware/graphics/common/XyColor.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.common;
+/* @hide */
+@VintfStability
+parcelable XyColor {
+  float x;
+  float y;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl
index 668b033..563b6c1 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl
@@ -94,5 +94,6 @@
   DYNAMIC_DEPTH = 4098,
   JPEG_APP_SEGMENTS = 4099,
   HEIF = 4100,
+  JPEG_R = 4101,
   BT709_FULL_RANGE = 146866176,
 }
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Hdr.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Hdr.aidl
index 7bae45e..71927b6 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Hdr.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Hdr.aidl
@@ -35,8 +35,10 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum Hdr {
+  INVALID = 0,
   DOLBY_VISION = 1,
   HDR10 = 2,
   HLG = 3,
   HDR10_PLUS = 4,
+  DOLBY_VISION_4K30 = 5,
 }
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionCapability.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionCapability.aidl
new file mode 100644
index 0000000..b74f7d7
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionCapability.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.common;
+@VintfStability
+parcelable HdrConversionCapability {
+  android.hardware.graphics.common.Hdr sourceType;
+  android.hardware.graphics.common.Hdr outputType;
+  boolean addsLatency;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionStrategy.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionStrategy.aidl
new file mode 100644
index 0000000..db785cf
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionStrategy.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.common;
+@VintfStability
+union HdrConversionStrategy {
+  boolean passthrough = true;
+  android.hardware.graphics.common.Hdr[] autoAllowedHdrTypes;
+  android.hardware.graphics.common.Hdr forceHdrConversion;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
index 59d6468..68857e8 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
@@ -65,4 +65,7 @@
   YCBCR_P010 = 54,
   HSV_888 = 55,
   R_8 = 56,
+  R_16_UINT = 57,
+  RG_1616_UINT = 58,
+  RGBA_10101010 = 59,
 }
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/StandardMetadataType.aidl
index 06b31a2..6e2e106 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/StandardMetadataType.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/StandardMetadataType.aidl
@@ -58,4 +58,5 @@
   CTA861_3 = 20,
   SMPTE2094_40 = 21,
   SMPTE2094_10 = 22,
+  STRIDE = 23,
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
index 5e9360f..3ff0a65 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
@@ -87,7 +87,7 @@
      * Use the unadjusted KR = 0.2126, KB = 0.0722 luminance interpretation
      * for RGB conversion.
      */
-    STANDARD_BT709 = 1 << 16,  // 1 << STANDARD_SHIFT
+    STANDARD_BT709 = 1 << 16, // 1 << STANDARD_SHIFT
 
     /**
      * Primaries:       x       y
@@ -377,11 +377,19 @@
     RANGE_LIMITED = 2 << 27, // 2 << RANGE_SHIFT = 0x10000000
 
     /**
-     * Extended range is used for scRGB. Intended for use with
-     * floating point pixel formats. [0.0 - 1.0] is the standard
-     * sRGB space. Values outside the range 0.0 - 1.0 can encode
-     * color outside the sRGB gamut.
-     * Used to blend / merge multiple dataspaces on a single display.
+     * Extended range can be used in combination with FP16 to communicate scRGB or with
+     * SurfaceControl's setExtendedRangeBrightness(SurfaceControl, float, float)
+     * to indicate an HDR range.
+     *
+     * When used with floating point pixel formats and #STANDARD_BT709 then [0.0 - 1.0] is the
+     * standard sRGB space and values outside the range [0.0 - 1.0] can encode
+     * color outside the sRGB gamut. [-0.5, 7.5] is the standard scRGB range.
+     * Used to blend/merge multiple dataspaces on a single display.
+     *
+     * As of Android U in combination with composer3's mixed SDR/HDR feature then this may
+     * be combined with SurfaceControl's setExtendedRangeBrightness(SurfaceControl, float, float)
+     * and other formats such as RGBA_8888 or RGBA_1010102 to communicate a variable HDR
+     * brightness range, which in turn will influence that layer's dimming ratio when composited
      */
     RANGE_EXTENDED = 3 << 27, // 3 << RANGE_SHIFT = 0x18000000
 
@@ -397,7 +405,6 @@
      */
     SRGB_LINEAR = 1 << 16 | 1 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_FULL
 
-
     /**
      * scRGB linear encoding:
      *
@@ -412,7 +419,6 @@
      */
     SCRGB_LINEAR = 1 << 16 | 1 << 22 | 3 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_EXTENDED
 
-
     /**
      * sRGB gamma encoding:
      *
@@ -428,7 +434,6 @@
      */
     SRGB = 1 << 16 | 2 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_FULL
 
-
     /**
      * scRGB:
      *
@@ -470,8 +475,8 @@
      *
      * Use limited range, SMPTE 170M transfer and BT.601_625 standard.
      */
-    BT601_625 = 2 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_LIMITED
-
+    BT601_625 =
+            2 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_LIMITED
 
     /**
      * ITU-R Recommendation 601 (BT.601) - 525-line
@@ -480,7 +485,8 @@
      *
      * Use limited range, SMPTE 170M transfer and BT.601_525 standard.
      */
-    BT601_525 = 4 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_525 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+    BT601_525 =
+            4 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_525 | TRANSFER_SMPTE_170M | RANGE_LIMITED
 
     /**
      * ITU-R Recommendation 709 (BT.709)
@@ -491,7 +497,6 @@
      */
     BT709 = 1 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_LIMITED
 
-
     /**
      * SMPTE EG 432-1 and SMPTE RP 431-2.
      *
@@ -501,7 +506,6 @@
      */
     DCI_P3_LINEAR = 10 << 16 | 1 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL
 
-
     /**
      * SMPTE EG 432-1 and SMPTE RP 431-2.
      *
@@ -513,15 +517,14 @@
      */
     DCI_P3 = 10 << 16 | 5 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_GAMMA2_6 | RANGE_FULL
 
-
     /**
      * Display P3
      *
      * Display P3 uses same primaries and white-point as DCI-P3
      * linear transfer function makes this the same as DCI_P3_LINEAR.
      */
-    DISPLAY_P3_LINEAR = 10 << 16 | 1 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL
-
+    DISPLAY_P3_LINEAR =
+            10 << 16 | 1 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL
 
     /**
      * Display P3
@@ -531,7 +534,6 @@
      */
     DISPLAY_P3 = 10 << 16 | 2 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_SRGB | RANGE_FULL
 
-
     /**
      * Adobe RGB
      *
@@ -541,7 +543,6 @@
      */
     ADOBE_RGB = 11 << 16 | 4 << 22 | 1 << 27, // STANDARD_ADOBE_RGB | TRANSFER_GAMMA2_2 | RANGE_FULL
 
-
     /**
      * ITU-R Recommendation 2020 (BT.2020)
      *
@@ -551,7 +552,6 @@
      */
     BT2020_LINEAR = 6 << 16 | 1 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_LINEAR | RANGE_FULL
 
-
     /**
      * ITU-R Recommendation 2020 (BT.2020)
      *
@@ -570,7 +570,6 @@
      */
     BT2020_PQ = 6 << 16 | 7 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_FULL
 
-
     /**
      * Data spaces for non-color formats
      */
@@ -611,7 +610,8 @@
      *
      * Use limited range, SMPTE 170M transfer and BT2020 standard
      */
-    BT2020_ITU = 6 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+    BT2020_ITU =
+            6 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_LIMITED
 
     /**
      * ITU-R Recommendation 2100 (BT.2100)
@@ -621,7 +621,8 @@
      * Use limited/full range, PQ/HLG transfer, and BT2020 standard
      * limited range is the preferred / normative definition for BT.2100
      */
-    BT2020_ITU_PQ = 6 << 16 | 7 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED
+    BT2020_ITU_PQ =
+            6 << 16 | 7 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED
     BT2020_ITU_HLG = 6 << 16 | 8 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_LIMITED
     BT2020_HLG = 6 << 16 | 8 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_FULL
 
@@ -668,11 +669,27 @@
     HEIF = 0x1004,
 
     /**
+     * Ultra HDR
+     *
+     * JPEG image with embedded 10-bit recovery map following the Ultra HDR specification.
+     *
+     * This value must always remain aligned with the public ImageFormat Jpeg/R definition and is
+     * valid with formats:
+     *    HAL_PIXEL_FORMAT_BLOB: JPEG image encoded by Ultra HDR encoder according to
+     *    the <a href="https://developer.android.com/guide/topics/media/hdr-image-format">
+     *    Ultra HDR Image format specification</a>.
+     * The image contains a standard SDR JPEG and a recovery map. Ultra HDR decoders can use the
+     * map to recover the 10-bit input image.
+     */
+    JPEG_R = 0x1005,
+
+    /**
      * ITU-R Recommendation 709 (BT.709)
      *
      * High-definition television
      *
      * Use full range, SMPTE 170M transfer and BT.709 standard.
      */
-    BT709_FULL_RANGE = 1 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_FULL
+    BT709_FULL_RANGE =
+            1 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_FULL
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Hdr.aidl b/graphics/common/aidl/android/hardware/graphics/common/Hdr.aidl
index f543780..c9ba16b 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/Hdr.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Hdr.aidl
@@ -24,6 +24,10 @@
 @Backing(type="int")
 enum Hdr {
     /**
+     * Invalid HDR type
+     */
+    INVALID = 0,
+    /**
      * Device supports Dolby Vision HDR
      */
     DOLBY_VISION = 1,
@@ -39,4 +43,8 @@
      * Device supports HDR10+
      */
     HDR10_PLUS = 4,
+    /**
+     * If present, indicates that device supports Dolby Vision only up to 4k30hz graphics mode
+     */
+    DOLBY_VISION_4K30 = 5,
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/HdrConversionCapability.aidl b/graphics/common/aidl/android/hardware/graphics/common/HdrConversionCapability.aidl
new file mode 100644
index 0000000..d8524a5
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/HdrConversionCapability.aidl
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+import android.hardware.graphics.common.Hdr;
+
+/**
+ * Output parameter for IComposerClient.getHdrConversionCapabilities
+ */
+@VintfStability
+parcelable HdrConversionCapability {
+    /** sourceType is the HDR type that can be converted to outputType */
+    Hdr sourceType;
+
+    /**
+     * outputType is the HDR type/ SDR that the source type can be converted to. The value INVALID
+     * is used to depict SDR outputType.
+     */
+
+    Hdr outputType;
+
+    /**
+     * addsLatency is false if no latency added due to HDR conversion from sourceType to
+     * outputType, otherwise true.
+     */
+    boolean addsLatency;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/HdrConversionStrategy.aidl b/graphics/common/aidl/android/hardware/graphics/common/HdrConversionStrategy.aidl
new file mode 100644
index 0000000..71beaa0
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/HdrConversionStrategy.aidl
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+import android.hardware.graphics.common.Hdr;
+/**
+ * Input parameter for IComposerClient.setHdrConversionStrategy
+ */
+@VintfStability
+union HdrConversionStrategy {
+    /**
+     * When this parameter is set to true, HDR conversion is disabled by the
+     * implementation. The output HDR type will change dynamically to match the content. This value
+     * is never set to false, as other union values will be present in the false case.
+     */
+    boolean passthrough = true;
+
+    /**
+     * When this parameter is set, the output HDR type is selected by the
+     * implementation. The implementation is only allowed to set the output HDR type to the HDR
+     * types present in this list. If conversion to any of the autoHdrTypes types is not possible,
+     * the implementation should do no conversion.
+     */
+    Hdr[] autoAllowedHdrTypes;
+
+    /**
+     * When this parameter is set, the implementation should convert all
+     * content to this HDR type, when possible. If not possible, the functionality should be similar
+     * to passthrough=true.
+     */
+    Hdr forceHdrConversion;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
index ccf437b..2985212 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
@@ -506,4 +506,30 @@
      * The component values are unsigned normalized to the range [0, 1].
      */
     R_8 = 0x38,
+
+    /**
+     * 16-bit format with a single 16-bit component
+     *
+     * The component values are unsigned integers, whose interpretation is
+     * defined by the dataspace.
+     */
+    R_16_UINT = 0x39,
+
+    /**
+     * 32-bit format that has 16-bit R and G components, in that order,
+     * from the lowest memory address to the highest memory address.
+     *
+     * The component values are unsigned integers, whose interpretation is
+     * defined by the dataspace.
+     */
+    RG_1616_UINT = 0x3a,
+
+    /**
+     * 40-bit format that has 10-bit R, G, B, and A components, in that order,
+     * from the lowest memory address to the highest memory address.
+     *
+     * The component values are unsigned normalized to the range [0, 1], whose
+     * interpretation is defined by the dataspace.
+     */
+    RGBA_10101010 = 0x3b,
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
index 8126143..8cfdae6 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
@@ -22,9 +22,9 @@
  * This is an enum that defines the common types of gralloc 4 buffer metadata. The comments for
  * each enum include a description of the metadata that is associated with the type.
  *
- * IMapper@4.x must support getting the following standard buffer metadata types, with the exception
- * of SMPTE 2094-10 metadata. IMapper@4.x may support setting these standard buffer metadata types
- * as well.
+ * IMapper@4.x & later must support getting the following standard buffer metadata types, with the
+ * exception of SMPTE 2094-10 and SMPTE 2094-40 metadata. IMapper@4.x & later may support setting
+ * these standard buffer metadata types as well.
  *
  * When encoding these StandardMetadataTypes into a byte stream, the associated MetadataType is
  * is first encoded followed by the StandardMetadataType value. The MetadataType is encoded by
@@ -368,4 +368,17 @@
      * If this is unset when encoded into a byte stream, the byte stream is empty.
      */
     SMPTE2094_10 = 22,
+
+    /**
+     * Can be used to get the stride in pixels of the buffer allocation. This is the number of
+     * pixels between two consecutive rows of an allocated buffer, when the concept of consecutive
+     * rows is defined. Otherwise, it has no meaning.
+     *
+     * Must match the value returned in android.hardware.graphics.allocator.AllocationResult#stride
+     *
+     * This is required metadata in mapper5 and should be read-only.
+     *
+     * The metadata type is a uint32_t.
+     */
+    STRIDE = 23,
 }
diff --git a/graphics/composer/2.1/default/OWNERS b/graphics/composer/2.1/default/OWNERS
deleted file mode 100644
index 331c80d..0000000
--- a/graphics/composer/2.1/default/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
diff --git a/graphics/composer/2.1/utils/OWNERS b/graphics/composer/2.1/utils/OWNERS
deleted file mode 100644
index 83c4f5f..0000000
--- a/graphics/composer/2.1/utils/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
index ab67eb1..9ae6173 100644
--- a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
@@ -207,7 +207,7 @@
 
     bool executeSetClientTarget(uint16_t length) {
         // 4 parameters followed by N rectangles
-        if ((length - 4) % 4 != 0) {
+        if (!length || (length - 4) % 4 != 0) {
             return false;
         }
 
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
index 0171dd6..3527cca 100644
--- a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
@@ -25,7 +25,6 @@
     name: "libhwc2on1adapter",
     vendor: true,
 
-    clang: true,
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
index 3965d12..d613ba9 100644
--- a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
@@ -25,7 +25,6 @@
     name: "libhwc2onfbadapter",
     vendor: true,
 
-    clang: true,
     cflags: [
         "-Wall",
         "-Wextra",
@@ -37,6 +36,9 @@
     ],
 
     header_libs: ["libhardware_headers"],
-    shared_libs: ["liblog", "libsync"],
+    shared_libs: [
+        "liblog",
+        "libsync",
+    ],
     export_include_dirs: ["include"],
 }
diff --git a/graphics/composer/2.1/utils/vts/Android.bp b/graphics/composer/2.1/utils/vts/Android.bp
index c0a0c07..7b6a0e6 100644
--- a/graphics/composer/2.1/utils/vts/Android.bp
+++ b/graphics/composer/2.1/utils/vts/Android.bp
@@ -25,14 +25,16 @@
 
 cc_library_static {
     name: "android.hardware.graphics.composer@2.1-vts",
-    defaults: ["hidl_defaults"],
+    defaults: [
+        "android.hardware.graphics.allocator-ndk_static",
+        "hidl_defaults",
+    ],
     srcs: [
         "ComposerVts.cpp",
         "GraphicsComposerCallback.cpp",
         "TestCommandReader.cpp",
     ],
     static_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.composer@2.1",
         "android.hardware.graphics.mapper@2.0-vts",
         "android.hardware.graphics.mapper@3.0-vts",
@@ -40,7 +42,6 @@
         "libgtest",
     ],
     export_static_lib_headers: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.composer@2.1",
         "android.hardware.graphics.mapper@2.0-vts",
         "android.hardware.graphics.mapper@3.0-vts",
diff --git a/graphics/composer/2.1/vts/OWNERS b/graphics/composer/2.1/vts/OWNERS
deleted file mode 100644
index a643bbd..0000000
--- a/graphics/composer/2.1/vts/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
-
-# VTS team
-yim@google.com
-zhuoyao@google.com
diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp
index 502036e..0f6d7e8 100644
--- a/graphics/composer/2.1/vts/functional/Android.bp
+++ b/graphics/composer/2.1/vts/functional/Android.bp
@@ -25,7 +25,10 @@
 
 cc_test {
     name: "VtsHalGraphicsComposerV2_1TargetTest",
-    defaults: ["VtsHalTargetTestDefaults"],
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "android.hardware.graphics.allocator-ndk_static",
+    ],
     tidy_timeout_srcs: ["VtsHalGraphicsComposerV2_1TargetTest.cpp"],
     srcs: ["VtsHalGraphicsComposerV2_1TargetTest.cpp"],
 
@@ -42,7 +45,6 @@
         "android.hardware.graphics.mapper@4.0",
     ],
     static_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.allocator@4.0",
diff --git a/graphics/composer/2.1/vts/functional/OWNERS b/graphics/composer/2.1/vts/functional/OWNERS
deleted file mode 100644
index 3d970d1..0000000
--- a/graphics/composer/2.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 25423
-adyabr@google.com
-alecmouri@google.com
-sumir@google.com
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 4822678..9444d89 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -666,11 +666,13 @@
         ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
     }
 
-    NativeHandleWrapper allocate() {
+    NativeHandleWrapper allocate() { return allocate(mDisplayWidth, mDisplayHeight); }
+
+    NativeHandleWrapper allocate(uint32_t width, uint32_t height) {
         uint64_t usage =
                 static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN |
                                       BufferUsage::COMPOSER_OVERLAY);
-        return mGralloc->allocate(mDisplayWidth, mDisplayHeight, 1, PixelFormat::RGBA_8888, usage);
+        return mGralloc->allocate(width, height, 1, PixelFormat::RGBA_8888, usage);
     }
 
     void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
@@ -884,6 +886,106 @@
 }
 
 /**
+ * Test IComposerClient::Command::SET_LAYER_BUFFER with the behavior used for clearing buffer slots.
+ */
+TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER_multipleTimes) {
+    // A placeholder buffer used to clear buffer slots
+    auto clearSlotBuffer = allocate(1u, 1u);
+
+    //
+    // Set the layer buffer to the first buffer
+    //
+    auto handle1 = allocate();
+    ASSERT_NE(nullptr, handle1.get());
+    IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
+    Layer layer;
+    ASSERT_NO_FATAL_FAILURE(
+            layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->selectLayer(layer);
+    mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
+    mWriter->setLayerDisplayFrame(displayFrame);
+    mWriter->setLayerBuffer(0, handle1.get(), -1);
+    mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED() << "Composition change requested, skipping test";
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    //
+    // Set the layer buffer to the second buffer
+    //
+    auto handle2 = allocate();
+    ASSERT_NE(nullptr, handle2.get());
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->selectLayer(layer);
+    mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
+    mWriter->setLayerDisplayFrame(displayFrame);
+    mWriter->setLayerBuffer(1, handle2.get(), -1);
+    mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED() << "Composition change requested, skipping test";
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    //
+    // Set the layer buffer to the third buffer
+    //
+    auto handle3 = allocate();
+    ASSERT_NE(nullptr, handle3.get());
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->selectLayer(layer);
+    mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
+    mWriter->setLayerDisplayFrame(displayFrame);
+    mWriter->setLayerBuffer(2, handle3.get(), -1);
+    mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+    mWriter->validateDisplay();
+    execute();
+    if (mReader->mCompositionChanges.size() != 0) {
+        GTEST_SUCCEED() << "Composition change requested, skipping test";
+        return;
+    }
+    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    // Ensure we can clear multiple buffer slots and then restore the active buffer at the end
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->selectLayer(layer);
+    mWriter->setLayerBuffer(0, clearSlotBuffer.get(), -1);
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->selectLayer(layer);
+    mWriter->setLayerBuffer(1, clearSlotBuffer.get(), -1);
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->selectLayer(layer);
+    mWriter->setLayerBuffer(2, nullptr, -1);
+    mWriter->validateDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mWriter->presentDisplay();
+    execute();
+    ASSERT_EQ(0, mReader->mErrors.size());
+}
+
+/**
  * Test IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE.
  */
 TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_SURFACE_DAMAGE) {
diff --git a/graphics/composer/2.2/default/OWNERS b/graphics/composer/2.2/default/OWNERS
deleted file mode 100644
index e8f584d..0000000
--- a/graphics/composer/2.2/default/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
-
diff --git a/graphics/composer/2.2/utils/OWNERS b/graphics/composer/2.2/utils/OWNERS
deleted file mode 100644
index 331c80d..0000000
--- a/graphics/composer/2.2/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index cca5323..d11592f 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -25,7 +25,12 @@
 
 cc_library_static {
     name: "android.hardware.graphics.composer@2.2-vts",
-    defaults: ["hidl_defaults"],
+    defaults: [
+        "android.hardware.graphics.allocator-ndk_static",
+        "android.hardware.graphics.composer3-ndk_static",
+        "hidl_defaults",
+        "librenderengine_deps",
+    ],
     srcs: [
         "ComposerVts.cpp",
         "ReadbackVts.cpp",
@@ -35,10 +40,8 @@
         "libui",
     ],
     static_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.composer@2.1-vts",
         "android.hardware.graphics.composer@2.2",
-        "android.hardware.graphics.composer3-V1-ndk",
         "android.hardware.graphics.mapper@2.1-vts",
         "libarect",
         "libgtest",
@@ -53,7 +56,6 @@
         "android.hardware.graphics.mapper@4.0-vts",
     ],
     export_static_lib_headers: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.composer@2.1-vts",
         "android.hardware.graphics.composer@2.2",
         "android.hardware.graphics.mapper@2.1-vts",
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index b706596..d4f0281 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -129,12 +129,12 @@
 void ComposerClient::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
                                                  Dataspace* outDataspace) {
     mClient->getReadbackBufferAttributes(
-        display,
-        [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
-            ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
-            *outPixelFormat = tmpOutPixelFormat;
-            *outDataspace = tmpOutDataspace;
-        });
+            display,
+            [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
+                ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
+                *outPixelFormat = tmpOutPixelFormat;
+                *outDataspace = tmpOutDataspace;
+            });
 }
 
 void ComposerClient::getReadbackBufferFence(Display display, int32_t* outFence) {
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
index 4a33fb5..1700b2a 100644
--- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -71,14 +71,12 @@
                    });
     auto texture = std::make_shared<renderengine::impl::ExternalTexture>(
             mGraphicBuffer, *mRenderEngine, renderengine::impl::ExternalTexture::Usage::WRITEABLE);
-    auto [status, readyFence] = mRenderEngine
-                                        ->drawLayers(mDisplaySettings, compositionLayers, texture,
-                                                     true, std::move(bufferFence))
-                                        .get();
-    int fd = readyFence.release();
-    if (fd != -1) {
-        ASSERT_EQ(0, sync_wait(fd, -1));
-        ASSERT_EQ(0, close(fd));
+    auto result = mRenderEngine
+                          ->drawLayers(mDisplaySettings, compositionLayers, texture, true,
+                                       std::move(bufferFence))
+                          .get();
+    if (result.ok()) {
+        result.value()->waitForever(LOG_TAG);
     }
 }
 
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 960b62d..3476376 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -27,8 +27,9 @@
     name: "VtsHalGraphicsComposerV2_2TargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
-        // Needed for librenderengine
-        "skia_deps",
+        "android.hardware.graphics.allocator-ndk_static",
+        "android.hardware.graphics.composer3-ndk_static",
+        "librenderengine_deps",
     ],
     tidy_timeout_srcs: [
         "VtsHalGraphicsComposerV2_2ReadbackTest.cpp",
@@ -59,7 +60,6 @@
         "android.hardware.graphics.mapper@4.0",
     ],
     static_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.allocator@4.0",
@@ -68,7 +68,6 @@
         "android.hardware.graphics.composer@2.1-vts",
         "android.hardware.graphics.composer@2.2",
         "android.hardware.graphics.composer@2.2-vts",
-        "android.hardware.graphics.composer3-V1-ndk",
         "android.hardware.graphics.mapper@2.0-vts",
         "android.hardware.graphics.mapper@2.1-vts",
         "android.hardware.graphics.mapper@3.0-vts",
diff --git a/graphics/composer/2.2/vts/functional/OWNERS b/graphics/composer/2.2/vts/functional/OWNERS
deleted file mode 100644
index a4eb0ca..0000000
--- a/graphics/composer/2.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Bug component: 25423
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
-sumir@google.com
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 7e25a2e..13ae089 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -66,16 +66,16 @@
         mComposerCallback->setVsyncAllowed(false);
 
         mComposerClient->getRaw()->getReadbackBufferAttributes(
-            mPrimaryDisplay,
-            [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
-                mHasReadbackBuffer = tmpError == Error::NONE;
-                if (mHasReadbackBuffer) {
-                    mReadbackPixelFormat = tmpPixelFormat;
-                    mReadbackDataspace = tmpDataspace;
-                    ASSERT_LT(static_cast<PixelFormat>(0), mReadbackPixelFormat);
-                    ASSERT_NE(Dataspace::UNKNOWN, mReadbackDataspace);
-                }
-            });
+                mPrimaryDisplay,
+                [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+                    mHasReadbackBuffer = tmpError == Error::NONE;
+                    if (mHasReadbackBuffer) {
+                        mReadbackPixelFormat = tmpPixelFormat;
+                        mReadbackDataspace = tmpDataspace;
+                        ASSERT_LT(static_cast<PixelFormat>(0), mReadbackPixelFormat);
+                        ASSERT_NE(Dataspace::UNKNOWN, mReadbackDataspace);
+                    }
+                });
 
         mInvalidDisplayId = GetInvalidDisplayId();
     }
@@ -711,4 +711,4 @@
     }
 
     return RUN_ALL_TESTS();
-}
\ No newline at end of file
+}
diff --git a/graphics/composer/2.3/default/OWNERS b/graphics/composer/2.3/default/OWNERS
deleted file mode 100644
index 331c80d..0000000
--- a/graphics/composer/2.3/default/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
diff --git a/graphics/composer/2.3/utils/OWNERS b/graphics/composer/2.3/utils/OWNERS
deleted file mode 100644
index 331c80d..0000000
--- a/graphics/composer/2.3/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index afc22d8..5e9a287 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -87,6 +87,10 @@
             return;
         }
 
+        if (metadata.size() == 0) {
+            return;
+        }
+
         // space for numElements
         commandLength += 1;
 
diff --git a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h
index 02f6212..42996dd 100644
--- a/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h
+++ b/graphics/composer/2.3/utils/hal/include/composer-hal/2.3/ComposerCommandEngine.h
@@ -73,9 +73,7 @@
     }
 
     bool executeSetLayerPerFrameMetadataBlobs(uint16_t length) {
-        // must have at least one metadata blob
-        // of at least size 1 in queue (i.e {/*numBlobs=*/1, key, size, blob})
-        if (length < 4) {
+        if (length == 0) {
             return false;
         }
 
@@ -84,7 +82,7 @@
 
         std::vector<IComposerClient::PerFrameMetadataBlob> metadata;
 
-        for (size_t i = 0; i < numBlobs; i++) {
+        for (size_t i = 0; i < numBlobs && length >= 2; i++) {
             IComposerClient::PerFrameMetadataKey key =
                 static_cast<IComposerClient::PerFrameMetadataKey>(readSigned());
             uint32_t blobSize = read();
diff --git a/graphics/composer/2.3/utils/vts/Android.bp b/graphics/composer/2.3/utils/vts/Android.bp
index 7bc07a4..b372804 100644
--- a/graphics/composer/2.3/utils/vts/Android.bp
+++ b/graphics/composer/2.3/utils/vts/Android.bp
@@ -25,7 +25,10 @@
 
 cc_library_static {
     name: "android.hardware.graphics.composer@2.3-vts",
-    defaults: ["hidl_defaults"],
+    defaults: [
+        "android.hardware.graphics.allocator-ndk_static",
+        "hidl_defaults",
+    ],
     srcs: [
         "ComposerVts.cpp",
     ],
diff --git a/graphics/composer/2.3/vts/functional/Android.bp b/graphics/composer/2.3/vts/functional/Android.bp
index 40b77d5..13f2b11 100644
--- a/graphics/composer/2.3/vts/functional/Android.bp
+++ b/graphics/composer/2.3/vts/functional/Android.bp
@@ -25,7 +25,10 @@
 
 cc_test {
     name: "VtsHalGraphicsComposerV2_3TargetTest",
-    defaults: ["VtsHalTargetTestDefaults"],
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "android.hardware.graphics.allocator-ndk_static",
+    ],
     tidy_timeout_srcs: ["VtsHalGraphicsComposerV2_3TargetTest.cpp"],
     srcs: ["VtsHalGraphicsComposerV2_3TargetTest.cpp"],
 
@@ -43,7 +46,6 @@
         "android.hardware.graphics.mapper@4.0",
     ],
     static_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.allocator@4.0",
diff --git a/graphics/composer/2.3/vts/functional/OWNERS b/graphics/composer/2.3/vts/functional/OWNERS
deleted file mode 100644
index a4eb0ca..0000000
--- a/graphics/composer/2.3/vts/functional/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Bug component: 25423
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
-sumir@google.com
diff --git a/graphics/composer/2.4/default/OWNERS b/graphics/composer/2.4/default/OWNERS
deleted file mode 100644
index 331c80d..0000000
--- a/graphics/composer/2.4/default/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
diff --git a/graphics/composer/2.4/utils/OWNERS b/graphics/composer/2.4/utils/OWNERS
deleted file mode 100644
index 331c80d..0000000
--- a/graphics/composer/2.4/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
diff --git a/graphics/composer/2.4/utils/vts/Android.bp b/graphics/composer/2.4/utils/vts/Android.bp
index de31975..d2b2ffa 100644
--- a/graphics/composer/2.4/utils/vts/Android.bp
+++ b/graphics/composer/2.4/utils/vts/Android.bp
@@ -25,14 +25,16 @@
 
 cc_library_static {
     name: "android.hardware.graphics.composer@2.4-vts",
-    defaults: ["hidl_defaults"],
+    defaults: [
+        "android.hardware.graphics.allocator-ndk_static",
+        "hidl_defaults",
+    ],
     srcs: [
         "ComposerVts.cpp",
         "GraphicsComposerCallback.cpp",
         "TestCommandReader.cpp",
     ],
     static_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.composer@2.1",
         "android.hardware.graphics.composer@2.2",
         "android.hardware.graphics.composer@2.3-vts",
diff --git a/graphics/composer/2.4/vts/functional/Android.bp b/graphics/composer/2.4/vts/functional/Android.bp
index b73ea94..b4ab259 100644
--- a/graphics/composer/2.4/vts/functional/Android.bp
+++ b/graphics/composer/2.4/vts/functional/Android.bp
@@ -25,7 +25,10 @@
 
 cc_test {
     name: "VtsHalGraphicsComposerV2_4TargetTest",
-    defaults: ["VtsHalTargetTestDefaults"],
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "android.hardware.graphics.allocator-ndk_static",
+    ],
     tidy_timeout_srcs: ["VtsHalGraphicsComposerV2_4TargetTest.cpp"],
     srcs: ["VtsHalGraphicsComposerV2_4TargetTest.cpp"],
 
@@ -42,7 +45,6 @@
         "android.hardware.graphics.mapper@4.0",
     ],
     static_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.allocator@4.0",
diff --git a/graphics/composer/2.4/vts/functional/OWNERS b/graphics/composer/2.4/vts/functional/OWNERS
deleted file mode 100644
index a4eb0ca..0000000
--- a/graphics/composer/2.4/vts/functional/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Bug component: 25423
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-lpy@google.com
-sumir@google.com
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index fa294ff..35225d9 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -737,6 +737,39 @@
     }
 }
 
+/*
+ * Test that no two display configs are exactly the same.
+ */
+TEST_P(GraphicsComposerHidlTest, GetDisplayConfigNoRepetitions) {
+    for (const auto& display : mDisplays) {
+        std::vector<Config> configs = mComposerClient->getDisplayConfigs(display.get());
+        for (int i = 0; i < configs.size(); i++) {
+            for (int j = i + 1; j < configs.size(); j++) {
+                const int32_t width1 = mComposerClient->getDisplayAttribute_2_4(
+                        display.get(), configs[i], IComposerClient::Attribute::WIDTH);
+                const int32_t height1 = mComposerClient->getDisplayAttribute_2_4(
+                        display.get(), configs[i], IComposerClient::Attribute::HEIGHT);
+                const int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4(
+                        display.get(), configs[i], IComposerClient::Attribute::VSYNC_PERIOD);
+                const int32_t group1 = mComposerClient->getDisplayAttribute_2_4(
+                        display.get(), configs[i], IComposerClient::Attribute::CONFIG_GROUP);
+
+                const int32_t width2 = mComposerClient->getDisplayAttribute_2_4(
+                        display.get(), configs[j], IComposerClient::Attribute::WIDTH);
+                const int32_t height2 = mComposerClient->getDisplayAttribute_2_4(
+                        display.get(), configs[j], IComposerClient::Attribute::HEIGHT);
+                const int32_t vsyncPeriod2 = mComposerClient->getDisplayAttribute_2_4(
+                        display.get(), configs[j], IComposerClient::Attribute::VSYNC_PERIOD);
+                const int32_t group2 = mComposerClient->getDisplayAttribute_2_4(
+                        display.get(), configs[j], IComposerClient::Attribute::CONFIG_GROUP);
+
+                ASSERT_FALSE(width1 == width2 && height1 == height2 &&
+                             vsyncPeriod1 == vsyncPeriod2 && group1 == group2);
+            }
+        }
+    }
+}
+
 }  // namespace
 }  // namespace vts
 }  // namespace V2_4
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index 9b88d98..40448ec 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -31,12 +31,14 @@
         enabled: true,
         support_system_process: true,
     },
+    frozen: true,
+    vndk_use_version: "1",
     srcs: [
         "android/hardware/graphics/composer3/*.aidl",
     ],
     stability: "vintf",
     imports: [
-        "android.hardware.graphics.common-V3",
+        "android.hardware.graphics.common-V4",
         "android.hardware.common-V2",
     ],
     backend: {
@@ -57,19 +59,27 @@
         {
             version: "1",
             imports: [
-                "android.hardware.graphics.common-V3",
+                "android.hardware.graphics.common-V4",
                 "android.hardware.common-V2",
             ],
         },
+        {
+            version: "2",
+            imports: [
+                "android.hardware.graphics.common-V4",
+                "android.hardware.common-V2",
+            ],
+        },
+
     ],
 
 }
 
 cc_library_headers {
     name: "android.hardware.graphics.composer3-command-buffer",
+    defaults: ["android.hardware.graphics.composer3-ndk_shared"],
     vendor_available: true,
     shared_libs: [
-        "android.hardware.graphics.composer3-V1-ndk",
         "android.hardware.common-V2-ndk",
         "libbase",
         "libfmq",
@@ -87,12 +97,12 @@
 
 cc_test {
     name: "android.hardware.graphics.composer3-hidl2aidl-asserts",
+    defaults: ["android.hardware.graphics.composer3-ndk_shared"],
     vendor_available: true,
     srcs: ["android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp"],
     shared_libs: [
         "libbinder_ndk",
         "libhidlbase",
-        "android.hardware.graphics.composer3-V1-ndk",
         "android.hardware.graphics.composer@2.1",
         "android.hardware.graphics.composer@2.4",
     ],
diff --git a/graphics/composer/aidl/OWNERS b/graphics/composer/aidl/OWNERS
deleted file mode 100644
index 9028d9d..0000000
--- a/graphics/composer/aidl/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Bug component: 1075131
-
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-sumir@google.com
\ No newline at end of file
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/.hash b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/.hash
new file mode 100644
index 0000000..70d4ced
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/.hash
@@ -0,0 +1 @@
+b6d53bcf537cbe89633b1622e2b065ea17291234
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Buffer.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Buffer.aidl
new file mode 100644
index 0000000..a33ad23
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Buffer.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable Buffer {
+  int slot;
+  @nullable android.hardware.common.NativeHandle handle;
+  @nullable ParcelFileDescriptor fence;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Capability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Capability.aidl
new file mode 100644
index 0000000..f02f8aa
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Capability.aidl
@@ -0,0 +1,48 @@
+/**
+ * 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum Capability {
+  INVALID = 0,
+  SIDEBAND_STREAM = 1,
+  SKIP_CLIENT_COLOR_TRANSFORM = 2,
+  PRESENT_FENCE_IS_NOT_RELIABLE = 3,
+  /**
+   * @deprecated - enabled by default.
+   */
+  SKIP_VALIDATE = 4,
+  BOOT_DISPLAY_CONFIG = 5,
+  HDR_OUTPUT_CONVERSION_CONFIG = 6,
+  REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ChangedCompositionLayer.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ChangedCompositionLayer.aidl
new file mode 100644
index 0000000..7e47ba8
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ChangedCompositionLayer.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ChangedCompositionLayer {
+  long layer;
+  android.hardware.graphics.composer3.Composition composition;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
new file mode 100644
index 0000000..9a5ca97
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ChangedCompositionTypes {
+  long display;
+  android.hardware.graphics.composer3.ChangedCompositionLayer[] layers;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClientTarget.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClientTarget.aidl
new file mode 100644
index 0000000..7632707
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClientTarget.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ClientTarget {
+  android.hardware.graphics.composer3.Buffer buffer;
+  android.hardware.graphics.common.Dataspace dataspace;
+  android.hardware.graphics.common.Rect[] damage;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClientTargetProperty.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClientTargetProperty.aidl
new file mode 100644
index 0000000..d34d1b0
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClientTargetProperty.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ClientTargetProperty {
+  android.hardware.graphics.common.PixelFormat pixelFormat;
+  android.hardware.graphics.common.Dataspace dataspace;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
new file mode 100644
index 0000000..8fb6933
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@VintfStability
+parcelable ClientTargetPropertyWithBrightness {
+  long display;
+  android.hardware.graphics.composer3.ClientTargetProperty clientTargetProperty;
+  float brightness;
+  android.hardware.graphics.composer3.DimmingStage dimmingStage;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClockMonotonicTimestamp.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClockMonotonicTimestamp.aidl
new file mode 100644
index 0000000..480a85c
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ClockMonotonicTimestamp.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ClockMonotonicTimestamp {
+  long timestampNanos;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Color.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Color.aidl
new file mode 100644
index 0000000..8222909
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Color.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@VintfStability
+parcelable Color {
+  float r;
+  float g;
+  float b;
+  float a;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ColorMode.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ColorMode.aidl
new file mode 100644
index 0000000..53852b6
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ColorMode.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum ColorMode {
+  NATIVE = 0,
+  STANDARD_BT601_625 = 1,
+  STANDARD_BT601_625_UNADJUSTED = 2,
+  STANDARD_BT601_525 = 3,
+  STANDARD_BT601_525_UNADJUSTED = 4,
+  STANDARD_BT709 = 5,
+  DCI_P3 = 6,
+  SRGB = 7,
+  ADOBE_RGB = 8,
+  DISPLAY_P3 = 9,
+  BT2020 = 10,
+  BT2100_PQ = 11,
+  BT2100_HLG = 12,
+  DISPLAY_BT2020 = 13,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/CommandError.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/CommandError.aidl
new file mode 100644
index 0000000..103bfdc
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/CommandError.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable CommandError {
+  int commandIndex;
+  int errorCode;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/CommandResultPayload.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/CommandResultPayload.aidl
new file mode 100644
index 0000000..6892f06
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/CommandResultPayload.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+union CommandResultPayload {
+  android.hardware.graphics.composer3.CommandError error;
+  android.hardware.graphics.composer3.ChangedCompositionTypes changedCompositionTypes;
+  android.hardware.graphics.composer3.DisplayRequest displayRequest;
+  android.hardware.graphics.composer3.PresentFence presentFence;
+  android.hardware.graphics.composer3.ReleaseFences releaseFences;
+  android.hardware.graphics.composer3.PresentOrValidate presentOrValidateResult;
+  android.hardware.graphics.composer3.ClientTargetPropertyWithBrightness clientTargetProperty;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Composition.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Composition.aidl
new file mode 100644
index 0000000..34d6822
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/Composition.aidl
@@ -0,0 +1,45 @@
+/**
+ * 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum Composition {
+  INVALID = 0,
+  CLIENT = 1,
+  DEVICE = 2,
+  SOLID_COLOR = 3,
+  CURSOR = 4,
+  SIDEBAND = 5,
+  DISPLAY_DECORATION = 6,
+  REFRESH_RATE_INDICATOR = 7,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ContentType.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ContentType.aidl
new file mode 100644
index 0000000..d87b767
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ContentType.aidl
@@ -0,0 +1,42 @@
+/**
+ * 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum ContentType {
+  NONE = 0,
+  GRAPHICS = 1,
+  PHOTO = 2,
+  CINEMA = 3,
+  GAME = 4,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DimmingStage.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DimmingStage.aidl
new file mode 100644
index 0000000..44457f8
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DimmingStage.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum DimmingStage {
+  NONE = 0,
+  LINEAR = 1,
+  GAMMA_OETF = 2,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayAttribute.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayAttribute.aidl
new file mode 100644
index 0000000..8454c40
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayAttribute.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum DisplayAttribute {
+  INVALID = 0,
+  WIDTH = 1,
+  HEIGHT = 2,
+  VSYNC_PERIOD = 3,
+  DPI_X = 4,
+  DPI_Y = 5,
+  CONFIG_GROUP = 7,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayBrightness.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayBrightness.aidl
new file mode 100644
index 0000000..e765189
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayBrightness.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@VintfStability
+parcelable DisplayBrightness {
+  float brightness;
+  float brightnessNits;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayCapability.aidl
new file mode 100644
index 0000000..6eba887
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -0,0 +1,45 @@
+/**
+ * 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum DisplayCapability {
+  INVALID = 0,
+  SKIP_CLIENT_COLOR_TRANSFORM = 1,
+  DOZE = 2,
+  BRIGHTNESS = 3,
+  PROTECTED_CONTENTS = 4,
+  AUTO_LOW_LATENCY_MODE = 5,
+  SUSPEND = 6,
+  DISPLAY_IDLE_TIMER = 7,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayCommand.aidl
new file mode 100644
index 0000000..662240e
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -0,0 +1,48 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable DisplayCommand {
+  long display;
+  android.hardware.graphics.composer3.LayerCommand[] layers;
+  @nullable float[] colorTransformMatrix;
+  @nullable android.hardware.graphics.composer3.DisplayBrightness brightness;
+  @nullable android.hardware.graphics.composer3.ClientTarget clientTarget;
+  @nullable android.hardware.graphics.composer3.Buffer virtualDisplayOutputBuffer;
+  @nullable android.hardware.graphics.composer3.ClockMonotonicTimestamp expectedPresentTime;
+  boolean validateDisplay;
+  boolean acceptDisplayChanges;
+  boolean presentDisplay;
+  boolean presentOrValidateDisplay;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayConnectionType.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayConnectionType.aidl
new file mode 100644
index 0000000..640f82a
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayConnectionType.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum DisplayConnectionType {
+  INTERNAL = 0,
+  EXTERNAL = 1,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayContentSample.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayContentSample.aidl
new file mode 100644
index 0000000..c624536
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayContentSample.aidl
@@ -0,0 +1,42 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable DisplayContentSample {
+  long frameCount;
+  long[] sampleComponent0;
+  long[] sampleComponent1;
+  long[] sampleComponent2;
+  long[] sampleComponent3;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayContentSamplingAttributes.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayContentSamplingAttributes.aidl
new file mode 100644
index 0000000..7c6542f
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayContentSamplingAttributes.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable DisplayContentSamplingAttributes {
+  android.hardware.graphics.common.PixelFormat format;
+  android.hardware.graphics.common.Dataspace dataspace;
+  android.hardware.graphics.composer3.FormatColorComponent componentMask;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayIdentification.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayIdentification.aidl
new file mode 100644
index 0000000..a0cc9b0
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayIdentification.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable DisplayIdentification {
+  byte port;
+  byte[] data;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayRequest.aidl
new file mode 100644
index 0000000..e6db116
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -0,0 +1,48 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable DisplayRequest {
+  long display;
+  int mask;
+  android.hardware.graphics.composer3.DisplayRequest.LayerRequest[] layerRequests;
+  const int FLIP_CLIENT_TARGET = (1 << 0) /* 1 */;
+  const int WRITE_CLIENT_TARGET_TO_OUTPUT = (1 << 1) /* 2 */;
+  @VintfStability
+  parcelable LayerRequest {
+    long layer;
+    int mask;
+    const int CLEAR_CLIENT_TARGET = (1 << 0) /* 1 */;
+  }
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/FormatColorComponent.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/FormatColorComponent.aidl
new file mode 100644
index 0000000..89dae83
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/FormatColorComponent.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@Backing(type="byte") @VintfStability
+enum FormatColorComponent {
+  FORMAT_COMPONENT_0 = (1 << 0) /* 1 */,
+  FORMAT_COMPONENT_1 = (1 << 1) /* 2 */,
+  FORMAT_COMPONENT_2 = (1 << 2) /* 4 */,
+  FORMAT_COMPONENT_3 = (1 << 3) /* 8 */,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/HdrCapabilities.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/HdrCapabilities.aidl
new file mode 100644
index 0000000..80141d3
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/HdrCapabilities.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@VintfStability
+parcelable HdrCapabilities {
+  android.hardware.graphics.common.Hdr[] types;
+  float maxLuminance;
+  float maxAverageLuminance;
+  float minLuminance;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/IComposer.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/IComposer.aidl
new file mode 100644
index 0000000..21b9ad8
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/IComposer.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+interface IComposer {
+  android.hardware.graphics.composer3.IComposerClient createClient();
+  android.hardware.graphics.composer3.Capability[] getCapabilities();
+  const int EX_NO_RESOURCES = 6;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/IComposerCallback.aidl
new file mode 100644
index 0000000..2c08cbe
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+interface IComposerCallback {
+  void onHotplug(long display, boolean connected);
+  oneway void onRefresh(long display);
+  oneway void onSeamlessPossible(long display);
+  oneway void onVsync(long display, long timestamp, int vsyncPeriodNanos);
+  oneway void onVsyncPeriodTimingChanged(long display, in android.hardware.graphics.composer3.VsyncPeriodChangeTimeline updatedTimeline);
+  oneway void onVsyncIdle(long display);
+  oneway void onRefreshRateChangedDebug(in android.hardware.graphics.composer3.RefreshRateChangedDebugData data);
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/IComposerClient.aidl
new file mode 100644
index 0000000..cb85a88
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -0,0 +1,93 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+interface IComposerClient {
+  long createLayer(long display, int bufferSlotCount);
+  android.hardware.graphics.composer3.VirtualDisplay createVirtualDisplay(int width, int height, android.hardware.graphics.common.PixelFormat formatHint, int outputBufferSlotCount);
+  void destroyLayer(long display, long layer);
+  void destroyVirtualDisplay(long display);
+  android.hardware.graphics.composer3.CommandResultPayload[] executeCommands(in android.hardware.graphics.composer3.DisplayCommand[] commands);
+  int getActiveConfig(long display);
+  android.hardware.graphics.composer3.ColorMode[] getColorModes(long display);
+  float[] getDataspaceSaturationMatrix(android.hardware.graphics.common.Dataspace dataspace);
+  int getDisplayAttribute(long display, int config, android.hardware.graphics.composer3.DisplayAttribute attribute);
+  android.hardware.graphics.composer3.DisplayCapability[] getDisplayCapabilities(long display);
+  int[] getDisplayConfigs(long display);
+  android.hardware.graphics.composer3.DisplayConnectionType getDisplayConnectionType(long display);
+  android.hardware.graphics.composer3.DisplayIdentification getDisplayIdentificationData(long display);
+  String getDisplayName(long display);
+  int getDisplayVsyncPeriod(long display);
+  android.hardware.graphics.composer3.DisplayContentSample getDisplayedContentSample(long display, long maxFrames, long timestamp);
+  android.hardware.graphics.composer3.DisplayContentSamplingAttributes getDisplayedContentSamplingAttributes(long display);
+  android.hardware.graphics.common.Transform getDisplayPhysicalOrientation(long display);
+  android.hardware.graphics.composer3.HdrCapabilities getHdrCapabilities(long display);
+  int getMaxVirtualDisplayCount();
+  android.hardware.graphics.composer3.PerFrameMetadataKey[] getPerFrameMetadataKeys(long display);
+  android.hardware.graphics.composer3.ReadbackBufferAttributes getReadbackBufferAttributes(long display);
+  @nullable ParcelFileDescriptor getReadbackBufferFence(long display);
+  android.hardware.graphics.composer3.RenderIntent[] getRenderIntents(long display, android.hardware.graphics.composer3.ColorMode mode);
+  android.hardware.graphics.composer3.ContentType[] getSupportedContentTypes(long display);
+  @nullable android.hardware.graphics.common.DisplayDecorationSupport getDisplayDecorationSupport(long display);
+  void registerCallback(in android.hardware.graphics.composer3.IComposerCallback callback);
+  void setActiveConfig(long display, int config);
+  android.hardware.graphics.composer3.VsyncPeriodChangeTimeline setActiveConfigWithConstraints(long display, int config, in android.hardware.graphics.composer3.VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints);
+  void setBootDisplayConfig(long display, int config);
+  void clearBootDisplayConfig(long display);
+  int getPreferredBootDisplayConfig(long display);
+  void setAutoLowLatencyMode(long display, boolean on);
+  void setClientTargetSlotCount(long display, int clientTargetSlotCount);
+  void setColorMode(long display, android.hardware.graphics.composer3.ColorMode mode, android.hardware.graphics.composer3.RenderIntent intent);
+  void setContentType(long display, android.hardware.graphics.composer3.ContentType type);
+  void setDisplayedContentSamplingEnabled(long display, boolean enable, android.hardware.graphics.composer3.FormatColorComponent componentMask, long maxFrames);
+  void setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode);
+  void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in @nullable ParcelFileDescriptor releaseFence);
+  void setVsyncEnabled(long display, boolean enabled);
+  void setIdleTimerEnabled(long display, int timeoutMs);
+  android.hardware.graphics.composer3.OverlayProperties getOverlaySupport();
+  android.hardware.graphics.common.HdrConversionCapability[] getHdrConversionCapabilities();
+  android.hardware.graphics.common.Hdr setHdrConversionStrategy(in android.hardware.graphics.common.HdrConversionStrategy conversionStrategy);
+  void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled);
+  const int EX_BAD_CONFIG = 1;
+  const int EX_BAD_DISPLAY = 2;
+  const int EX_BAD_LAYER = 3;
+  const int EX_BAD_PARAMETER = 4;
+  const int EX_RESERVED = 5;
+  const int EX_NO_RESOURCES = 6;
+  const int EX_NOT_VALIDATED = 7;
+  const int EX_UNSUPPORTED = 8;
+  const int EX_SEAMLESS_NOT_ALLOWED = 9;
+  const int EX_SEAMLESS_NOT_POSSIBLE = 10;
+  const int INVALID_CONFIGURATION = 0x7fffffff;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/LayerBrightness.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/LayerBrightness.aidl
new file mode 100644
index 0000000..a726cc1
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/LayerBrightness.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable LayerBrightness {
+  float brightness;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/LayerCommand.aidl
new file mode 100644
index 0000000..6d32218
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -0,0 +1,58 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable LayerCommand {
+  long layer;
+  @nullable android.hardware.graphics.common.Point cursorPosition;
+  @nullable android.hardware.graphics.composer3.Buffer buffer;
+  @nullable android.hardware.graphics.common.Rect[] damage;
+  @nullable android.hardware.graphics.composer3.ParcelableBlendMode blendMode;
+  @nullable android.hardware.graphics.composer3.Color color;
+  @nullable android.hardware.graphics.composer3.ParcelableComposition composition;
+  @nullable android.hardware.graphics.composer3.ParcelableDataspace dataspace;
+  @nullable android.hardware.graphics.common.Rect displayFrame;
+  @nullable android.hardware.graphics.composer3.PlaneAlpha planeAlpha;
+  @nullable android.hardware.common.NativeHandle sidebandStream;
+  @nullable android.hardware.graphics.common.FRect sourceCrop;
+  @nullable android.hardware.graphics.composer3.ParcelableTransform transform;
+  @nullable android.hardware.graphics.common.Rect[] visibleRegion;
+  @nullable android.hardware.graphics.composer3.ZOrder z;
+  @nullable float[] colorTransform;
+  @nullable android.hardware.graphics.composer3.LayerBrightness brightness;
+  @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata;
+  @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
+  @nullable android.hardware.graphics.common.Rect[] blockingRegion;
+  @nullable int[] bufferSlotsToClear;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/OverlayProperties.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/OverlayProperties.aidl
new file mode 100644
index 0000000..7d31ea3
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/OverlayProperties.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.composer3;
+@VintfStability
+parcelable OverlayProperties {
+  android.hardware.graphics.composer3.OverlayProperties.SupportedBufferCombinations[] combinations;
+  boolean supportMixedColorSpaces;
+  parcelable SupportedBufferCombinations {
+    android.hardware.graphics.common.PixelFormat[] pixelFormats;
+    android.hardware.graphics.common.Dataspace[] standards;
+    android.hardware.graphics.common.Dataspace[] transfers;
+    android.hardware.graphics.common.Dataspace[] ranges;
+  }
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableBlendMode.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableBlendMode.aidl
new file mode 100644
index 0000000..f1fee5f
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableBlendMode.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ParcelableBlendMode {
+  android.hardware.graphics.common.BlendMode blendMode;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableComposition.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableComposition.aidl
new file mode 100644
index 0000000..98fbb66
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableComposition.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ParcelableComposition {
+  android.hardware.graphics.composer3.Composition composition;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableDataspace.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableDataspace.aidl
new file mode 100644
index 0000000..76ecf85
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableDataspace.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ParcelableDataspace {
+  android.hardware.graphics.common.Dataspace dataspace;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableTransform.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableTransform.aidl
new file mode 100644
index 0000000..b673656
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ParcelableTransform.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ParcelableTransform {
+  android.hardware.graphics.common.Transform transform;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PerFrameMetadata.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PerFrameMetadata.aidl
new file mode 100644
index 0000000..cd1f351
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PerFrameMetadata.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable PerFrameMetadata {
+  android.hardware.graphics.composer3.PerFrameMetadataKey key;
+  float value;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PerFrameMetadataBlob.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PerFrameMetadataBlob.aidl
new file mode 100644
index 0000000..c1e74d9
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PerFrameMetadataBlob.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable PerFrameMetadataBlob {
+  android.hardware.graphics.composer3.PerFrameMetadataKey key;
+  byte[] blob;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
new file mode 100644
index 0000000..10a7dee
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
@@ -0,0 +1,50 @@
+/**
+ * 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum PerFrameMetadataKey {
+  DISPLAY_RED_PRIMARY_X,
+  DISPLAY_RED_PRIMARY_Y,
+  DISPLAY_GREEN_PRIMARY_X,
+  DISPLAY_GREEN_PRIMARY_Y,
+  DISPLAY_BLUE_PRIMARY_X,
+  DISPLAY_BLUE_PRIMARY_Y,
+  WHITE_POINT_X,
+  WHITE_POINT_Y,
+  MAX_LUMINANCE,
+  MIN_LUMINANCE,
+  MAX_CONTENT_LIGHT_LEVEL,
+  MAX_FRAME_AVERAGE_LIGHT_LEVEL,
+  HDR10_PLUS_SEI,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PlaneAlpha.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PlaneAlpha.aidl
new file mode 100644
index 0000000..c48c2a8
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PlaneAlpha.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable PlaneAlpha {
+  float alpha;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PowerMode.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PowerMode.aidl
new file mode 100644
index 0000000..f587d4d
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PowerMode.aidl
@@ -0,0 +1,42 @@
+/**
+ * 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum PowerMode {
+  OFF = 0,
+  DOZE = 1,
+  DOZE_SUSPEND = 3,
+  ON = 2,
+  ON_SUSPEND = 4,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PresentFence.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PresentFence.aidl
new file mode 100644
index 0000000..3bb09cd
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PresentFence.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable PresentFence {
+  long display;
+  ParcelFileDescriptor fence;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PresentOrValidate.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PresentOrValidate.aidl
new file mode 100644
index 0000000..dbfac22
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable PresentOrValidate {
+  long display;
+  android.hardware.graphics.composer3.PresentOrValidate.Result result;
+  @VintfStability
+  enum Result {
+    Validated,
+    Presented,
+  }
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ReadbackBufferAttributes.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ReadbackBufferAttributes.aidl
new file mode 100644
index 0000000..bb51bdc
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ReadbackBufferAttributes.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ReadbackBufferAttributes {
+  android.hardware.graphics.common.PixelFormat format;
+  android.hardware.graphics.common.Dataspace dataspace;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
new file mode 100644
index 0000000..2b9801a
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@VintfStability
+parcelable RefreshRateChangedDebugData {
+  long display;
+  int vsyncPeriodNanos;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ReleaseFences.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ReleaseFences.aidl
new file mode 100644
index 0000000..d623661
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ReleaseFences.aidl
@@ -0,0 +1,44 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ReleaseFences {
+  long display;
+  android.hardware.graphics.composer3.ReleaseFences.Layer[] layers;
+  @VintfStability
+  parcelable Layer {
+    long layer;
+    ParcelFileDescriptor fence;
+  }
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/RenderIntent.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/RenderIntent.aidl
new file mode 100644
index 0000000..5670c10
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/RenderIntent.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum RenderIntent {
+  COLORIMETRIC = 0,
+  ENHANCE = 1,
+  TONE_MAP_COLORIMETRIC = 2,
+  TONE_MAP_ENHANCE = 3,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/VirtualDisplay.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/VirtualDisplay.aidl
new file mode 100644
index 0000000..886be2e
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/VirtualDisplay.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable VirtualDisplay {
+  long display;
+  android.hardware.graphics.common.PixelFormat format;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/VsyncPeriodChangeConstraints.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/VsyncPeriodChangeConstraints.aidl
new file mode 100644
index 0000000..df38c11
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/VsyncPeriodChangeConstraints.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable VsyncPeriodChangeConstraints {
+  long desiredTimeNanos;
+  boolean seamlessRequired;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/VsyncPeriodChangeTimeline.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/VsyncPeriodChangeTimeline.aidl
new file mode 100644
index 0000000..9fb3999
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/VsyncPeriodChangeTimeline.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable VsyncPeriodChangeTimeline {
+  long newVsyncAppliedTimeNanos;
+  boolean refreshRequired;
+  long refreshTimeNanos;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ZOrder.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ZOrder.aidl
new file mode 100644
index 0000000..ea96ea3
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/2/android/hardware/graphics/composer3/ZOrder.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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.graphics.composer3;
+@VintfStability
+parcelable ZOrder {
+  int z;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
index b89f7d5..f02f8aa 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
@@ -38,6 +38,11 @@
   SIDEBAND_STREAM = 1,
   SKIP_CLIENT_COLOR_TRANSFORM = 2,
   PRESENT_FENCE_IS_NOT_RELIABLE = 3,
+  /**
+   * @deprecated - enabled by default.
+   */
   SKIP_VALIDATE = 4,
   BOOT_DISPLAY_CONFIG = 5,
+  HDR_OUTPUT_CONVERSION_CONFIG = 6,
+  REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl
index d2d8f04..34d6822 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl
@@ -41,4 +41,5 @@
   CURSOR = 4,
   SIDEBAND = 5,
   DISPLAY_DECORATION = 6,
+  REFRESH_RATE_INDICATOR = 7,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
index 13462ce..00598eb 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -37,12 +37,12 @@
   long display;
   int mask;
   android.hardware.graphics.composer3.DisplayRequest.LayerRequest[] layerRequests;
-  const int FLIP_CLIENT_TARGET = 1;
-  const int WRITE_CLIENT_TARGET_TO_OUTPUT = 2;
+  const int FLIP_CLIENT_TARGET = (1 << 0);
+  const int WRITE_CLIENT_TARGET_TO_OUTPUT = (1 << 1);
   @VintfStability
   parcelable LayerRequest {
     long layer;
     int mask;
-    const int CLEAR_CLIENT_TARGET = 1;
+    const int CLEAR_CLIENT_TARGET = (1 << 0);
   }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl
index 4b737de..1990350 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl
@@ -34,8 +34,8 @@
 package android.hardware.graphics.composer3;
 @Backing(type="byte") @VintfStability
 enum FormatColorComponent {
-  FORMAT_COMPONENT_0 = 1,
-  FORMAT_COMPONENT_1 = 2,
-  FORMAT_COMPONENT_2 = 4,
-  FORMAT_COMPONENT_3 = 8,
+  FORMAT_COMPONENT_0 = (1 << 0),
+  FORMAT_COMPONENT_1 = (1 << 1),
+  FORMAT_COMPONENT_2 = (1 << 2),
+  FORMAT_COMPONENT_3 = (1 << 3),
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
index 21620e7..2c08cbe 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -40,4 +40,5 @@
   oneway void onVsync(long display, long timestamp, int vsyncPeriodNanos);
   oneway void onVsyncPeriodTimingChanged(long display, in android.hardware.graphics.composer3.VsyncPeriodChangeTimeline updatedTimeline);
   oneway void onVsyncIdle(long display);
+  oneway void onRefreshRateChangedDebug(in android.hardware.graphics.composer3.RefreshRateChangedDebugData data);
 }
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 b49f239..cb85a88 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
@@ -75,6 +75,10 @@
   void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in @nullable ParcelFileDescriptor releaseFence);
   void setVsyncEnabled(long display, boolean enabled);
   void setIdleTimerEnabled(long display, int timeoutMs);
+  android.hardware.graphics.composer3.OverlayProperties getOverlaySupport();
+  android.hardware.graphics.common.HdrConversionCapability[] getHdrConversionCapabilities();
+  android.hardware.graphics.common.Hdr setHdrConversionStrategy(in android.hardware.graphics.common.HdrConversionStrategy conversionStrategy);
+  void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled);
   const int EX_BAD_CONFIG = 1;
   const int EX_BAD_DISPLAY = 2;
   const int EX_BAD_LAYER = 3;
@@ -85,5 +89,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;
+  const int INVALID_CONFIGURATION = 0x7fffffff;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
index 0c5fac9..6d32218 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -54,4 +54,5 @@
   @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata;
   @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
   @nullable android.hardware.graphics.common.Rect[] blockingRegion;
+  @nullable int[] bufferSlotsToClear;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl
new file mode 100644
index 0000000..7d31ea3
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.composer3;
+@VintfStability
+parcelable OverlayProperties {
+  android.hardware.graphics.composer3.OverlayProperties.SupportedBufferCombinations[] combinations;
+  boolean supportMixedColorSpaces;
+  parcelable SupportedBufferCombinations {
+    android.hardware.graphics.common.PixelFormat[] pixelFormats;
+    android.hardware.graphics.common.Dataspace[] standards;
+    android.hardware.graphics.common.Dataspace[] transfers;
+    android.hardware.graphics.common.Dataspace[] ranges;
+  }
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
index 8722f87..10a7dee 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
@@ -34,17 +34,17 @@
 package android.hardware.graphics.composer3;
 @Backing(type="int") @VintfStability
 enum PerFrameMetadataKey {
-  DISPLAY_RED_PRIMARY_X = 0,
-  DISPLAY_RED_PRIMARY_Y = 1,
-  DISPLAY_GREEN_PRIMARY_X = 2,
-  DISPLAY_GREEN_PRIMARY_Y = 3,
-  DISPLAY_BLUE_PRIMARY_X = 4,
-  DISPLAY_BLUE_PRIMARY_Y = 5,
-  WHITE_POINT_X = 6,
-  WHITE_POINT_Y = 7,
-  MAX_LUMINANCE = 8,
-  MIN_LUMINANCE = 9,
-  MAX_CONTENT_LIGHT_LEVEL = 10,
-  MAX_FRAME_AVERAGE_LIGHT_LEVEL = 11,
-  HDR10_PLUS_SEI = 12,
+  DISPLAY_RED_PRIMARY_X,
+  DISPLAY_RED_PRIMARY_Y,
+  DISPLAY_GREEN_PRIMARY_X,
+  DISPLAY_GREEN_PRIMARY_Y,
+  DISPLAY_BLUE_PRIMARY_X,
+  DISPLAY_BLUE_PRIMARY_Y,
+  WHITE_POINT_X,
+  WHITE_POINT_Y,
+  MAX_LUMINANCE,
+  MIN_LUMINANCE,
+  MAX_CONTENT_LIGHT_LEVEL,
+  MAX_FRAME_AVERAGE_LIGHT_LEVEL,
+  HDR10_PLUS_SEI,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
index e6ddeba..dbfac22 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -38,7 +38,7 @@
   android.hardware.graphics.composer3.PresentOrValidate.Result result;
   @VintfStability
   enum Result {
-    Validated = 0,
-    Presented = 1,
+    Validated,
+    Presented,
   }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
new file mode 100644
index 0000000..2b9801a
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@VintfStability
+parcelable RefreshRateChangedDebugData {
+  long display;
+  int vsyncPeriodNanos;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
index 2f9eab9..4638610 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
@@ -55,6 +55,7 @@
      * For this capability to be worthwhile the device implementation of
      * presentDisplay should fail as fast as possible in the case a
      * validateDisplay step is needed.
+     * @deprecated - enabled by default.
      */
     SKIP_VALIDATE = 4,
 
@@ -66,4 +67,23 @@
      * @see IComposerClient.getPreferredBootDisplayConfig
      */
     BOOT_DISPLAY_CONFIG = 5,
+
+    /**
+     * Specifies that the device supports HDR output conversion.
+     *
+     * @see IComposerClient.getHdrConversionCapabilities
+     * @see IComposerClient.setHdrConversionStrategy
+     */
+    HDR_OUTPUT_CONVERSION_CONFIG = 6,
+
+    /**
+     * Specifies that the device supports the callback onRefreshRateChangedDebug
+     * to pass information about the refresh rate.
+     * The refresh rate from the callback is used to update the refresh rate
+     * overlay indicator.
+     *
+     * @see IComposerClient.setRefreshRateChangedCallbackDebugEnabled
+     * @see IComposerCallback.onRefreshRateChangedDebug
+     */
+    REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
index ddd45b7..9e8c768 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
@@ -23,7 +23,6 @@
 parcelable ChangedCompositionTypes {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
index ba6fe97..ea54a89 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
@@ -23,7 +23,6 @@
 parcelable ClientTargetPropertyWithBrightness {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
index 82b218b..37912b0 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
@@ -86,4 +86,14 @@
      * to either DEVICE or CLIENT.
      */
     DISPLAY_DECORATION = 6,
+
+    /**
+     * This composition type is similar to DEVICE, with a single difference,
+     * that indicates to HWC that this layer update is not considered an activity
+     * of any sort. For example, If HWC maintains a timer for activity to switch
+     * the display mode from a power save mode, it should not reset that timer.
+     *
+     * Upon validateDisplay, the device may request a change from this type to CLIENT.
+     */
+    REFRESH_RATE_INDICATOR = 7,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
index b6df147..4f69aee 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -26,7 +26,6 @@
 parcelable DisplayCommand {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
index 27fe1e6..3a50b6e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -34,7 +34,6 @@
 
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
index 67954d4..f4384b7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.graphics.composer3;
 
+import android.hardware.graphics.composer3.RefreshRateChangedDebugData;
 import android.hardware.graphics.composer3.VsyncPeriodChangeTimeline;
 
 @VintfStability
@@ -96,4 +97,25 @@
      * @param display is the display whose vsync cadence changed due to panel idle mode.
      */
     oneway void onVsyncIdle(long display);
+
+    /**
+     * Notifies the client the vsyncPeriod of the display changed.
+     * Whether or not to call this callback is managed by
+     * IComposerClient.setRefreshRateChangedCallbackDebugEnabled
+     *
+     * Immediate callback is required after the setRefreshRateChangedCallbackDebugEnabled
+     * called.
+     * When the panel refresh rate changes, as a result of a setActiveConfig or
+     * setActiveConfigWithConstraints, this callback should be called with the new panel
+     * refresh rate. In addition, when the panel refresh rate is changed by other means,
+     * such as idleness or DOZE power state, this callback should be called as well.
+     *
+     * This callback is used for debug purposes, and not for scheduling frames,
+     * therefore synchronization is not required.
+     *
+     * @see IComposerClient.setRefreshRateChangedCallbackDebugEnabled
+     *
+     * @param data is the data for the callback when refresh rate changed.
+     */
+    oneway void onRefreshRateChangedDebug(in RefreshRateChangedDebugData data);
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index a4ea64f..4e77f86 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -17,6 +17,9 @@
 package android.hardware.graphics.composer3;
 
 import android.hardware.graphics.common.DisplayDecorationSupport;
+import android.hardware.graphics.common.Hdr;
+import android.hardware.graphics.common.HdrConversionCapability;
+import android.hardware.graphics.common.HdrConversionStrategy;
 import android.hardware.graphics.common.Transform;
 import android.hardware.graphics.composer3.ClientTargetProperty;
 import android.hardware.graphics.composer3.ColorMode;
@@ -32,6 +35,7 @@
 import android.hardware.graphics.composer3.FormatColorComponent;
 import android.hardware.graphics.composer3.HdrCapabilities;
 import android.hardware.graphics.composer3.IComposerCallback;
+import android.hardware.graphics.composer3.OverlayProperties;
 import android.hardware.graphics.composer3.PerFrameMetadataKey;
 import android.hardware.graphics.composer3.PowerMode;
 import android.hardware.graphics.composer3.ReadbackBufferAttributes;
@@ -814,4 +818,50 @@
      *
      */
     void setIdleTimerEnabled(long display, int timeoutMs);
+
+    /**
+     * Hardware overlays is a technique to composite different buffers directly to the screen
+     * while bypassing GPU composition.
+     *
+     * This function returns what the device's overlays support.
+     *
+     * @exception EX_UNSUPPORTED when not supported by the underlying HAL
+     *
+     * @return the overlay properties of the device.
+     */
+    OverlayProperties getOverlaySupport();
+
+    /**
+     * Returns the array of HDR conversion capability. Each HdrConversionCapability depicts that
+     * HDR conversion is possible from sourceType to outputType. This doesn't change after
+     * initialization.
+     *
+     * @exception EX_UNSUPPORTED when not supported by the underlying HAL
+     *
+     * @see setHdrConversionStrategy
+     */
+    HdrConversionCapability[] getHdrConversionCapabilities();
+
+    /**
+     * Sets the of HDR conversion strategy.
+     *
+     * @return the chosen HDR type in case HdrConversionStrategy has autoAllowedHdrTypes set. In
+     * other cases, return HDR type INVALID.
+     * @exception EX_UNSUPPORTED when not supported by the underlying HAL
+     *
+     * @see getHdrConversionCapabilities
+     */
+    Hdr setHdrConversionStrategy(in HdrConversionStrategy conversionStrategy);
+
+    /*
+     * Sets either the callback for the refresh rate change is enabled or disabled
+     * for the provided display.
+     *
+     * @see IComposerCallback.onRefreshRateChangedDebug
+     *
+     * @param display is the display on which the callback is enabled on.
+     * @param enabled true when refresh rate callback is enabled,
+     *        false when refresh rate callback is disabled.
+     */
+    void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled);
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index f3b67a9..fd50be9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -258,4 +258,11 @@
      * the screen.
      */
     @nullable Rect[] blockingRegion;
+
+    /**
+     * Specifies which buffer slots should be cleared of buffer references
+     * because these buffers will no longer be used and the memory should
+     * be freed.
+     */
+    @nullable int[] bufferSlotsToClear;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl
new file mode 100644
index 0000000..c25eea4
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3;
+
+@VintfStability
+parcelable OverlayProperties {
+    parcelable SupportedBufferCombinations {
+        // List of pixelformats, standards, transfers and ranges dataspaces that can be used
+        // together.
+        // The pixelformats, standards, transfers and ranges stored inside are valid
+        // combinations.
+        // Dataspace identifies three components of colors - standard, transfer and
+        // range.
+        android.hardware.graphics.common.PixelFormat[] pixelFormats;
+        android.hardware.graphics.common.Dataspace[] standards;
+        android.hardware.graphics.common.Dataspace[] transfers;
+        android.hardware.graphics.common.Dataspace[] ranges;
+    }
+    // Array of all valid pixelformat, standard, transfer and range combinations.
+    // If all supported formats work with all standards, transfers and ranges,
+    // then this list may only have 1 entry.
+    // If some dataspaces, e.g. scRGB (STANDARD_BT709 | TRANSFER_SRGB | RANGE_EXTENDED),
+    // only work with specific formats, then this list may contain more than 1 entry.
+    // If some ranges, e.g. RANGE_LIMITED, only work with specific
+    // formats/standards/transfers, then this list may contain more than 1 entry.
+    SupportedBufferCombinations[] combinations;
+
+    // True if the DPU is able to color manage at least two overlays
+    // with different input colorspaces, false otherwise.
+    boolean supportMixedColorSpaces;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
index 244b4e5..b757656 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
@@ -20,7 +20,6 @@
 parcelable PresentFence {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
index 5ae8940..e15dbf2 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -20,7 +20,6 @@
 parcelable PresentOrValidate {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
new file mode 100644
index 0000000..c1f78d6
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
@@ -0,0 +1,30 @@
+/**
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3;
+
+@VintfStability
+parcelable RefreshRateChangedDebugData {
+    /**
+     * The display for which the debug data is for.
+     */
+    long display;
+
+    /**
+     * The display vsync period in nanoseconds.
+     */
+    int vsyncPeriodNanos;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
index 459a042..58649d5 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
@@ -20,7 +20,6 @@
 parcelable ReleaseFences {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
     @VintfStability
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
index 27dce76..76ba24b 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
@@ -19,8 +19,8 @@
 #include <algorithm>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <unordered_map>
-#include <unordered_set>
 #include <vector>
 
 #include <inttypes.h>
@@ -41,8 +41,15 @@
 
 class ComposerClientReader {
   public:
+    explicit ComposerClientReader(std::optional<int64_t> display = {}) : mDisplay(display) {}
+
     ~ComposerClientReader() { resetData(); }
 
+    ComposerClientReader(ComposerClientReader&&) = default;
+
+    ComposerClientReader(const ComposerClientReader&) = delete;
+    ComposerClientReader& operator=(const ComposerClientReader&) = delete;
+
     // Parse and execute commands from the command queue.  The commands are
     // actually return values from the server and will be saved in ReturnData.
     void parse(std::vector<CommandResultPayload>&& results) {
@@ -85,6 +92,7 @@
 
     void hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
                     uint32_t* outNumLayerRequestMasks) const {
+        LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
         auto found = mReturnData.find(display);
         if (found == mReturnData.end()) {
             *outNumChangedCompositionTypes = 0;
@@ -100,6 +108,7 @@
 
     // Get and clear saved changed composition types.
     std::vector<ChangedCompositionLayer> takeChangedCompositionTypes(int64_t display) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
         auto found = mReturnData.find(display);
         if (found == mReturnData.end()) {
             return {};
@@ -111,6 +120,7 @@
 
     // Get and clear saved display requests.
     DisplayRequest takeDisplayRequests(int64_t display) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
         auto found = mReturnData.find(display);
         if (found == mReturnData.end()) {
             return {};
@@ -122,6 +132,7 @@
 
     // Get and clear saved release fences.
     std::vector<ReleaseFences::Layer> takeReleaseFences(int64_t display) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
         auto found = mReturnData.find(display);
         if (found == mReturnData.end()) {
             return {};
@@ -133,6 +144,7 @@
 
     // Get and clear saved present fence.
     ndk::ScopedFileDescriptor takePresentFence(int64_t display) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
         auto found = mReturnData.find(display);
         if (found == mReturnData.end()) {
             return {};
@@ -144,6 +156,7 @@
 
     // Get what stage succeeded during PresentOrValidate: Present or Validate
     std::optional<PresentOrValidate::Result> takePresentOrValidateStage(int64_t display) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
         auto found = mReturnData.find(display);
         if (found == mReturnData.end()) {
             return std::nullopt;
@@ -154,6 +167,7 @@
 
     // Get the client target properties requested by hardware composer.
     ClientTargetPropertyWithBrightness takeClientTargetProperty(int64_t display) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
         auto found = mReturnData.find(display);
 
         // If not found, return the default values.
@@ -177,32 +191,38 @@
     void parseSetError(CommandError&& error) { mErrors.emplace_back(error); }
 
     void parseSetChangedCompositionTypes(ChangedCompositionTypes&& changedCompositionTypes) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && changedCompositionTypes.display != *mDisplay);
         auto& data = mReturnData[changedCompositionTypes.display];
         data.changedLayers = std::move(changedCompositionTypes.layers);
     }
 
     void parseSetDisplayRequests(DisplayRequest&& displayRequest) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && displayRequest.display != *mDisplay);
         auto& data = mReturnData[displayRequest.display];
         data.displayRequests = std::move(displayRequest);
     }
 
     void parseSetPresentFence(PresentFence&& presentFence) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && presentFence.display != *mDisplay);
         auto& data = mReturnData[presentFence.display];
         data.presentFence = std::move(presentFence.fence);
     }
 
     void parseSetReleaseFences(ReleaseFences&& releaseFences) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && releaseFences.display != *mDisplay);
         auto& data = mReturnData[releaseFences.display];
         data.releasedLayers = std::move(releaseFences.layers);
     }
 
     void parseSetPresentOrValidateDisplayResult(const PresentOrValidate&& presentOrValidate) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && presentOrValidate.display != *mDisplay);
         auto& data = mReturnData[presentOrValidate.display];
         data.presentOrValidateState = std::move(presentOrValidate.result);
     }
 
     void parseSetClientTargetProperty(
             const ClientTargetPropertyWithBrightness&& clientTargetProperty) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && clientTargetProperty.display != *mDisplay);
         auto& data = mReturnData[clientTargetProperty.display];
         data.clientTargetProperty = std::move(clientTargetProperty);
     }
@@ -222,6 +242,7 @@
 
     std::vector<CommandError> mErrors;
     std::unordered_map<int64_t, ReturnData> mReturnData;
+    const std::optional<int64_t> mDisplay;
 };
 
 }  // namespace aidl::android::hardware::graphics::composer3
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
index 1d81f7b..2e902e5 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -19,8 +19,6 @@
 #include <algorithm>
 #include <limits>
 #include <memory>
-#include <unordered_map>
-#include <unordered_set>
 #include <vector>
 
 #include <inttypes.h>
@@ -59,19 +57,18 @@
 
 namespace aidl::android::hardware::graphics::composer3 {
 
-class ComposerClientWriter {
+class ComposerClientWriter final {
   public:
     static constexpr std::optional<ClockMonotonicTimestamp> kNoTimestamp = std::nullopt;
 
-    ComposerClientWriter() { reset(); }
+    explicit ComposerClientWriter(int64_t display) : mDisplay(display) { reset(); }
 
-    virtual ~ComposerClientWriter() { reset(); }
+    ~ComposerClientWriter() { reset(); }
 
-    void reset() {
-        mDisplayCommand.reset();
-        mLayerCommand.reset();
-        mCommands.clear();
-    }
+    ComposerClientWriter(ComposerClientWriter&&) = default;
+
+    ComposerClientWriter(const ComposerClientWriter&) = delete;
+    ComposerClientWriter& operator=(const ComposerClientWriter&) = delete;
 
     void setColorTransform(int64_t display, const float* matrix) {
         std::vector<float> matVec;
@@ -88,7 +85,7 @@
     void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
                          int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
         ClientTarget clientTargetCommand;
-        clientTargetCommand.buffer = getBuffer(slot, target, acquireFence);
+        clientTargetCommand.buffer = getBufferCommand(slot, target, acquireFence);
         clientTargetCommand.dataspace = dataspace;
         clientTargetCommand.damage.assign(damage.begin(), damage.end());
         getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
@@ -97,7 +94,7 @@
     void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
                          int releaseFence) {
         getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
-                getBuffer(slot, buffer, releaseFence));
+                getBufferCommand(slot, buffer, releaseFence));
     }
 
     void validateDisplay(int64_t display,
@@ -129,7 +126,20 @@
 
     void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
                         const native_handle_t* buffer, int acquireFence) {
-        getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence);
+        getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
+    }
+
+    void setLayerBufferWithNewCommand(int64_t display, int64_t layer, uint32_t slot,
+                                      const native_handle_t* buffer, int acquireFence) {
+        flushLayerCommand();
+        getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
+        flushLayerCommand();
+    }
+
+    void setLayerBufferSlotsToClear(int64_t display, int64_t layer,
+                                    const std::vector<uint32_t>& slotsToClear) {
+        getLayerCommand(display, layer)
+                .bufferSlotsToClear.emplace(slotsToClear.begin(), slotsToClear.end());
     }
 
     void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
@@ -219,18 +229,21 @@
         getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end());
     }
 
-    const std::vector<DisplayCommand>& getPendingCommands() {
+    std::vector<DisplayCommand> takePendingCommands() {
         flushLayerCommand();
         flushDisplayCommand();
-        return mCommands;
+        std::vector<DisplayCommand> moved = std::move(mCommands);
+        mCommands.clear();
+        return moved;
     }
 
   private:
     std::optional<DisplayCommand> mDisplayCommand;
     std::optional<LayerCommand> mLayerCommand;
     std::vector<DisplayCommand> mCommands;
+    const int64_t mDisplay;
 
-    Buffer getBuffer(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
+    Buffer getBufferCommand(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
         Buffer bufferCommand;
         bufferCommand.slot = static_cast<int32_t>(slot);
         if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
@@ -254,6 +267,7 @@
 
     DisplayCommand& getDisplayCommand(int64_t display) {
         if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) {
+            LOG_ALWAYS_FATAL_IF(display != mDisplay);
             flushLayerCommand();
             flushDisplayCommand();
             mDisplayCommand.emplace();
@@ -271,6 +285,12 @@
         }
         return *mLayerCommand;
     }
+
+    void reset() {
+        mDisplayCommand.reset();
+        mLayerCommand.reset();
+        mCommands.clear();
+    }
 };
 
 }  // namespace aidl::android::hardware::graphics::composer3
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerServiceWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerServiceWriter.h
index 34cda6a..b50b84b 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerServiceWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerServiceWriter.h
@@ -18,6 +18,7 @@
 
 #include <aidl/android/hardware/graphics/composer3/CommandResultPayload.h>
 #include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
+#include <android-base/logging.h>
 #include <inttypes.h>
 #include <string.h>
 
@@ -26,8 +27,6 @@
 #include <memory>
 #include <vector>
 
-#include "Util.h"
-
 namespace aidl::android::hardware::graphics::composer3::impl {
 
 class ComposerServiceWriter {
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index 1e70a0e..60360fd 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -28,8 +28,9 @@
     defaults: [
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
-        // Needed for librenderengine
-        "skia_deps",
+        "librenderengine_deps",
+        "android.hardware.graphics.common-ndk_static",
+        "android.hardware.graphics.composer3-ndk_static",
     ],
     srcs: [
         "VtsHalGraphicsComposer3_TargetTest.cpp",
@@ -53,7 +54,6 @@
         "libgui",
         "libhidlbase",
         "libprocessgroup",
-        "libtinyxml2",
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.graphics.mapper@2.1",
         "android.hardware.graphics.mapper@3.0",
@@ -67,8 +67,6 @@
         "android.hardware.graphics.composer3-command-buffer",
     ],
     static_libs: [
-        "android.hardware.graphics.composer3-V1-ndk",
-        "android.hardware.graphics.common-V3-ndk",
         "android.hardware.graphics.common@1.2",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
index d534943..7b3a2b4 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
@@ -29,6 +29,11 @@
     mVsyncAllowed = allowed;
 }
 
+void GraphicsComposerCallback::setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed) {
+    std::scoped_lock lock(mMutex);
+    mRefreshRateChangedDebugDataEnabledCallbackAllowed = allowed;
+}
+
 std::vector<int64_t> GraphicsComposerCallback::getDisplays() const {
     std::scoped_lock lock(mMutex);
     return mDisplays;
@@ -79,6 +84,21 @@
     return ret;
 }
 
+std::vector<RefreshRateChangedDebugData>
+GraphicsComposerCallback::takeListOfRefreshRateChangedDebugData() {
+    std::scoped_lock lock(mMutex);
+
+    std::vector<RefreshRateChangedDebugData> ret;
+    ret.swap(mRefreshRateChangedDebugData);
+
+    return ret;
+}
+
+int32_t GraphicsComposerCallback::getInvalidRefreshRateDebugEnabledCallbackCount() const {
+    std::scoped_lock lock(mMutex);
+    return mInvalidRefreshRateDebugEnabledCallbackCount;
+}
+
 ::ndk::ScopedAStatus GraphicsComposerCallback::onHotplug(int64_t in_display, bool in_connected) {
     std::scoped_lock lock(mMutex);
 
@@ -124,6 +144,19 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus GraphicsComposerCallback::onRefreshRateChangedDebug(
+        const RefreshRateChangedDebugData& data) {
+    std::scoped_lock lock(mMutex);
+
+    const auto it = std::find(mDisplays.begin(), mDisplays.end(), data.display);
+    if (mRefreshRateChangedDebugDataEnabledCallbackAllowed && it != mDisplays.end()) {
+        mRefreshRateChangedDebugData.push_back(data);
+    } else {
+        mInvalidRefreshRateDebugEnabledCallbackCount++;
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
 ::ndk::ScopedAStatus GraphicsComposerCallback::onVsyncPeriodTimingChanged(
         int64_t in_display,
         const ::aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline&
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.h b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
index e54da34..13e992a 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
@@ -26,6 +26,8 @@
   public:
     void setVsyncAllowed(bool allowed);
 
+    void setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed);
+
     std::vector<int64_t> getDisplays() const;
 
     int32_t getInvalidHotplugCount() const;
@@ -44,6 +46,10 @@
 
     std::optional<VsyncPeriodChangeTimeline> takeLastVsyncPeriodChangeTimeline();
 
+    std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData();
+
+    int32_t getInvalidRefreshRateDebugEnabledCallbackCount() const;
+
   private:
     virtual ::ndk::ScopedAStatus onHotplug(int64_t in_display, bool in_connected) override;
     virtual ::ndk::ScopedAStatus onRefresh(int64_t in_display) override;
@@ -55,15 +61,21 @@
             const ::aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline&
                     in_updatedTimeline) override;
     virtual ::ndk::ScopedAStatus onVsyncIdle(int64_t in_display) override;
+    virtual ::ndk::ScopedAStatus onRefreshRateChangedDebug(
+            const RefreshRateChangedDebugData&) override;
 
     mutable std::mutex mMutex;
     // the set of all currently connected displays
     std::vector<int64_t> mDisplays GUARDED_BY(mMutex);
     // true only when vsync is enabled
     bool mVsyncAllowed GUARDED_BY(mMutex) = true;
+    // true only when RefreshRateChangedCallbackDebugEnabled is set to true.
+    bool mRefreshRateChangedDebugDataEnabledCallbackAllowed GUARDED_BY(mMutex) = false;
 
     std::optional<VsyncPeriodChangeTimeline> mTimeline GUARDED_BY(mMutex);
 
+    std::vector<RefreshRateChangedDebugData> mRefreshRateChangedDebugData GUARDED_BY(mMutex);
+
     int32_t mVsyncIdleCount GUARDED_BY(mMutex) = 0;
     int64_t mVsyncIdleTime GUARDED_BY(mMutex) = 0;
 
@@ -73,6 +85,7 @@
     int32_t mInvalidVsyncCount GUARDED_BY(mMutex) = 0;
     int32_t mInvalidVsyncPeriodChangeCount GUARDED_BY(mMutex) = 0;
     int32_t mInvalidSeamlessPossibleCount GUARDED_BY(mMutex) = 0;
+    int32_t mInvalidRefreshRateDebugEnabledCallbackCount GUARDED_BY(mMutex) = 0;
 };
 
 }  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/OWNERS b/graphics/composer/aidl/vts/OWNERS
deleted file mode 100644
index d95d98d..0000000
--- a/graphics/composer/aidl/vts/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Bug component: 199413815
-
-# Graphics team
-adyabr@google.com
-alecmouri@google.com
-ramindani@google.com
diff --git a/graphics/composer/aidl/vts/RenderEngineVts.cpp b/graphics/composer/aidl/vts/RenderEngineVts.cpp
index 71b011c..66779c8 100644
--- a/graphics/composer/aidl/vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/vts/RenderEngineVts.cpp
@@ -66,14 +66,12 @@
     auto texture = std::make_shared<::android::renderengine::impl::ExternalTexture>(
             mGraphicBuffer, *mRenderEngine,
             ::android::renderengine::impl::ExternalTexture::Usage::WRITEABLE);
-    auto [status, readyFence] = mRenderEngine
-                                        ->drawLayers(mDisplaySettings, compositionLayers, texture,
-                                                     true, std::move(bufferFence))
-                                        .get();
-    int fd = readyFence.release();
-    if (fd != -1) {
-        ASSERT_EQ(0, sync_wait(fd, -1));
-        ASSERT_EQ(0, close(fd));
+    auto result = mRenderEngine
+                          ->drawLayers(mDisplaySettings, compositionLayers, texture, true,
+                                       std::move(bufferFence))
+                          .get();
+    if (result.ok()) {
+        result.value()->waitForever(LOG_TAG);
     }
 }
 
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.cpp b/graphics/composer/aidl/vts/VtsComposerClient.cpp
index dd4161e..25b0ca0 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.cpp
+++ b/graphics/composer/aidl/vts/VtsComposerClient.cpp
@@ -58,6 +58,12 @@
     return verifyComposerCallbackParams() && destroyAllLayers();
 }
 
+std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() {
+    int32_t version = 1;
+    auto status = mComposerClient->getInterfaceVersion(&version);
+    return {std::move(status), version};
+}
+
 std::pair<ScopedAStatus, VirtualDisplay> VtsComposerClient::createVirtualDisplay(
         int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount) {
     VirtualDisplay outVirtualDisplay;
@@ -113,6 +119,24 @@
     return updateDisplayProperties(vtsDisplay, config);
 }
 
+ScopedAStatus VtsComposerClient::setPeakRefreshRateConfig(VtsDisplay* vtsDisplay) {
+    const auto displayId = vtsDisplay->getDisplayId();
+    auto [activeStatus, activeConfig] = getActiveConfig(displayId);
+    EXPECT_TRUE(activeStatus.isOk());
+    auto peakDisplayConfig = vtsDisplay->getDisplayConfig(activeConfig);
+    auto peakConfig = activeConfig;
+
+    const auto displayConfigs = vtsDisplay->getDisplayConfigs();
+    for (const auto [config, displayConfig] : displayConfigs) {
+        if (displayConfig.configGroup == peakDisplayConfig.configGroup &&
+            displayConfig.vsyncPeriod < peakDisplayConfig.vsyncPeriod) {
+            peakDisplayConfig = displayConfig;
+            peakConfig = config;
+        }
+    }
+    return setActiveConfig(vtsDisplay, peakConfig);
+}
+
 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute(
         int64_t display, int32_t config, DisplayAttribute displayAttribute) {
     int32_t outDisplayAttribute;
@@ -331,6 +355,20 @@
     return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
 }
 
+std::pair<ScopedAStatus, std::vector<common::HdrConversionCapability>>
+VtsComposerClient::getHdrConversionCapabilities() {
+    std::vector<common::HdrConversionCapability> hdrConversionCapability;
+    return {mComposerClient->getHdrConversionCapabilities(&hdrConversionCapability),
+            hdrConversionCapability};
+}
+
+std::pair<ScopedAStatus, common::Hdr> VtsComposerClient::setHdrConversionStrategy(
+        const common::HdrConversionStrategy& conversionStrategy) {
+    common::Hdr preferredHdrOutputType;
+    return {mComposerClient->setHdrConversionStrategy(conversionStrategy, &preferredHdrOutputType),
+            preferredHdrOutputType};
+}
+
 std::pair<ScopedAStatus, common::Transform> VtsComposerClient::getDisplayPhysicalOrientation(
         int64_t display) {
     common::Transform outDisplayOrientation;
@@ -338,6 +376,11 @@
             outDisplayOrientation};
 }
 
+std::pair<ScopedAStatus, composer3::OverlayProperties> VtsComposerClient::getOverlaySupport() {
+    OverlayProperties properties;
+    return {mComposerClient->getOverlaySupport(&properties), properties};
+}
+
 ScopedAStatus VtsComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeoutMs) {
     return mComposerClient->setIdleTimerEnabled(display, timeoutMs);
 }
@@ -350,6 +393,17 @@
     return mComposerCallback->getVsyncIdleTime();
 }
 
+ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display,
+                                                                                bool enabled) {
+    mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled);
+    return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled);
+}
+
+std::vector<RefreshRateChangedDebugData>
+VtsComposerClient::takeListOfRefreshRateChangedDebugData() {
+    return mComposerCallback->takeListOfRefreshRateChangedDebugData();
+}
+
 int64_t VtsComposerClient::getInvalidDisplayId() {
     // returns an invalid display id (one that has not been registered to a
     // display. Currently assuming that a device will never have close to
@@ -514,6 +568,10 @@
             ALOGE("Invalid seamless possible count");
             isValid = false;
         }
+        if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) {
+            ALOGE("Invalid refresh rate debug enabled callback count");
+            isValid = false;
+        }
     }
     return isValid;
 }
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index 74c5da5..ea3318c 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -35,6 +35,7 @@
 #include <string>
 #include <thread>
 #include <unordered_map>
+#include <unordered_set>
 #include "GraphicsComposerCallback.h"
 
 using aidl::android::hardware::graphics::common::Dataspace;
@@ -60,6 +61,8 @@
 
     bool tearDown();
 
+    std::pair<ScopedAStatus, int32_t> getInterfaceVersion();
+
     std::pair<ScopedAStatus, VirtualDisplay> createVirtualDisplay(int32_t width, int32_t height,
                                                                   PixelFormat pixelFormat,
                                                                   int32_t bufferSlotCount);
@@ -74,6 +77,8 @@
 
     ScopedAStatus setActiveConfig(VtsDisplay* vtsDisplay, int32_t config);
 
+    ScopedAStatus setPeakRefreshRateConfig(VtsDisplay* vtsDisplay);
+
     std::pair<ScopedAStatus, int32_t> getDisplayAttribute(int64_t display, int32_t config,
                                                           DisplayAttribute displayAttribute);
 
@@ -160,6 +165,12 @@
 
     std::pair<ScopedAStatus, int32_t> getPreferredBootDisplayConfig(int64_t display);
 
+    std::pair<ScopedAStatus, std::vector<common::HdrConversionCapability>>
+    getHdrConversionCapabilities();
+
+    std::pair<ScopedAStatus, common::Hdr> setHdrConversionStrategy(
+            const common::HdrConversionStrategy& conversionStrategy);
+
     std::pair<ScopedAStatus, common::Transform> getDisplayPhysicalOrientation(int64_t display);
 
     ScopedAStatus setIdleTimerEnabled(int64_t display, int32_t timeoutMs);
@@ -172,6 +183,12 @@
 
     std::pair<ScopedAStatus, std::vector<VtsDisplay>> getDisplays();
 
+    std::pair<ScopedAStatus, OverlayProperties> getOverlaySupport();
+
+    ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t display, bool enabled);
+
+    std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData();
+
   private:
     ScopedAStatus addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config);
     ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config);
@@ -231,15 +248,17 @@
     };
 
     void addDisplayConfig(int32_t config, DisplayConfig displayConfig) {
-        displayConfigs.insert({config, displayConfig});
+        mDisplayConfigs.insert({config, displayConfig});
     }
 
-    DisplayConfig getDisplayConfig(int32_t config) { return displayConfigs.find(config)->second; }
+    DisplayConfig getDisplayConfig(int32_t config) { return mDisplayConfigs.find(config)->second; }
+
+    std::unordered_map<int32_t, DisplayConfig> getDisplayConfigs() { return mDisplayConfigs; }
 
   private:
     int64_t mDisplayId;
     int32_t mDisplayWidth;
     int32_t mDisplayHeight;
-    std::unordered_map<int32_t, DisplayConfig> displayConfigs;
+    std::unordered_map<int32_t, DisplayConfig> mDisplayConfigs;
 };
 }  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 46dde09..9b849cc 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -31,12 +31,6 @@
 #include "RenderEngineVts.h"
 #include "VtsComposerClient.h"
 
-// tinyxml2 does implicit conversions >:(
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-#include <tinyxml2.h>
-#pragma clang diagnostic pop
-
 namespace aidl::android::hardware::graphics::composer3::vts {
 namespace {
 
@@ -53,6 +47,7 @@
         const auto& [status, displays] = mComposerClient->getDisplays();
         ASSERT_TRUE(status.isOk());
         mDisplays = displays;
+        mWriter.reset(new ComposerClientWriter(getPrimaryDisplayId()));
 
         setTestColorModes();
 
@@ -128,87 +123,16 @@
         return {false, graphicBuffer};
     }
 
-    uint64_t getStableDisplayId(int64_t display) {
-        const auto& [status, identification] =
-                mComposerClient->getDisplayIdentificationData(display);
-        EXPECT_TRUE(status.isOk());
-
-        if (const auto info = ::android::parseDisplayIdentificationData(
-                    static_cast<uint8_t>(identification.port), identification.data)) {
-            return info->id.value;
-        }
-
-        return ::android::PhysicalDisplayId::fromPort(static_cast<uint8_t>(identification.port))
-                .value;
-    }
-
-    // Gets the per-display XML config
-    std::unique_ptr<tinyxml2::XMLDocument> getDisplayConfigXml(int64_t display) {
-        std::stringstream pathBuilder;
-        pathBuilder << "/vendor/etc/displayconfig/display_id_" << getStableDisplayId(display)
-                    << ".xml";
-        const std::string path = pathBuilder.str();
-        auto document = std::make_unique<tinyxml2::XMLDocument>();
-        const tinyxml2::XMLError error = document->LoadFile(path.c_str());
-        if (error == tinyxml2::XML_SUCCESS) {
-            return document;
-        } else {
-            return nullptr;
-        }
-    }
-
-    // Gets the max display brightness for this display.
-    // If the display config xml does not exist, then assume that the display is not well-configured
-    // enough to provide a display brightness, so return nullopt.
-    std::optional<float> getMaxDisplayBrightnessNits(int64_t display) {
-        const auto document = getDisplayConfigXml(display);
-        if (!document) {
-            // Assume the device doesn't support display brightness
-            return std::nullopt;
-        }
-
-        const auto root = document->RootElement();
-        if (!root) {
-            // If there's somehow no root element, then this isn't a valid config
-            return std::nullopt;
-        }
-
-        const auto screenBrightnessMap = root->FirstChildElement("screenBrightnessMap");
-        if (!screenBrightnessMap) {
-            // A valid display config must have a screen brightness map
-            return std::nullopt;
-        }
-
-        auto point = screenBrightnessMap->FirstChildElement("point");
-        float maxNits = -1.f;
-        while (point != nullptr) {
-            const auto nits = point->FirstChildElement("nits");
-            if (nits) {
-                maxNits = std::max(maxNits, nits->FloatText(-1.f));
-            }
-            point = point->NextSiblingElement("point");
-        }
-
-        if (maxNits < 0.f) {
-            // If we got here, then there were no point elements containing a nit value, so this
-            // config isn't valid
-            return std::nullopt;
-        }
-
-        return maxNits;
-    }
-
     void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
         for (const auto& layer : layers) {
-            layer->write(mWriter);
+            layer->write(*mWriter);
         }
         execute();
     }
 
     void execute() {
-        const auto& commands = mWriter.getPendingCommands();
+        auto commands = mWriter->takePendingCommands();
         if (commands.empty()) {
-            mWriter.reset();
             return;
         }
 
@@ -216,7 +140,6 @@
         ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
 
         mReader.parse(std::move(results));
-        mWriter.reset();
     }
 
     bool getHasReadbackBuffer() {
@@ -236,7 +159,7 @@
     std::vector<VtsDisplay> mDisplays;
     // use the slot count usually set by SF
     std::vector<ColorMode> mTestColorModes;
-    ComposerClientWriter mWriter;
+    std::unique_ptr<ComposerClientWriter> mWriter;
     ComposerClientReader mReader;
     std::unique_ptr<TestRenderEngine> mTestRenderEngine;
     common::PixelFormat mPixelFormat;
@@ -297,7 +220,7 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         // if hwc cannot handle and asks for composition change,
         // just succeed the test
@@ -306,7 +229,7 @@
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -349,14 +272,14 @@
                 getDisplayHeight(), common::PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
-        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
         ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
 
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
 
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
@@ -365,7 +288,7 @@
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
 
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -395,7 +318,7 @@
         layer->setColor(BLUE);
         layer->setDisplayFrame(coloredSquare);
         layer->setZOrder(10);
-        layer->write(mWriter);
+        layer->write(*mWriter);
 
         // This following buffer call should have no effect
         const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
@@ -403,8 +326,8 @@
         const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
         ASSERT_TRUE(graphicBufferStatus);
         const auto& buffer = graphicBuffer->handle;
-        mWriter.setLayerBuffer(getPrimaryDisplayId(), layer->getLayer(), /*slot*/ 0, buffer,
-                               /*acquireFence*/ -1);
+        mWriter->setLayerBuffer(getPrimaryDisplayId(), layer->getLayer(), /*slot*/ 0, buffer,
+                                /*acquireFence*/ -1);
 
         // expected color for each pixel
         std::vector<Color> expectedColors(
@@ -415,7 +338,7 @@
                                       getDisplayHeight(), mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
 
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
@@ -423,7 +346,7 @@
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -533,7 +456,7 @@
                                                        getDisplayHeight(), PixelFormat::RGBA_FP16);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
-        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
 
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
@@ -542,7 +465,7 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
 
         auto changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
@@ -572,17 +495,17 @@
             int32_t clientFence;
             const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
             ASSERT_EQ(::android::OK, unlockStatus);
-            mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
-                                    clientDataspace, std::vector<common::Rect>(1, damage));
-            layer->setToClientComposition(mWriter);
-            mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+            mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
+                                     clientDataspace, std::vector<common::Rect>(1, damage));
+            layer->setToClientComposition(*mWriter);
+            mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
             execute();
             changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
             ASSERT_TRUE(changedCompositionTypes.empty());
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
 
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -631,9 +554,9 @@
         deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
                                       static_cast<int32_t>(deviceLayer->getHeight())});
         deviceLayer->setZOrder(10);
-        deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
         ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
-        deviceLayer->write(mWriter);
+        deviceLayer->write(*mWriter);
 
         PixelFormat clientFormat = PixelFormat::RGBA_8888;
         auto clientUsage = static_cast<uint32_t>(
@@ -651,8 +574,8 @@
                                     getDisplayHeight()};
         clientLayer->setDisplayFrame(clientFrame);
         clientLayer->setZOrder(0);
-        clientLayer->write(mWriter);
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        clientLayer->write(*mWriter);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
 
         auto changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
@@ -678,16 +601,16 @@
         int32_t clientFence;
         const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
         ASSERT_EQ(::android::OK, unlockStatus);
-        mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
-                                clientDataspace, std::vector<common::Rect>(1, clientFrame));
-        clientLayer->setToClientComposition(mWriter);
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
+                                 clientDataspace, std::vector<common::Rect>(1, clientFrame));
+        clientLayer->setToClientComposition(*mWriter);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
         ASSERT_TRUE(changedCompositionTypes.empty());
         ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -718,7 +641,7 @@
                                                        getDisplayHeight(), PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
-        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
         ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
 
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
@@ -729,14 +652,14 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -757,11 +680,11 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -798,7 +721,7 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
@@ -806,7 +729,7 @@
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -846,7 +769,7 @@
                                                        getDisplayHeight(), PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
-        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
         layer->setSourceCrop({0, static_cast<float>(getDisplayHeight() / 2),
                               static_cast<float>(getDisplayWidth()),
                               static_cast<float>(getDisplayHeight())});
@@ -862,14 +785,14 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -920,13 +843,13 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
             return;
         }
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -942,11 +865,11 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -958,32 +881,6 @@
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerBrightnessDims) {
-    const auto& [status, capabilities] =
-            mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
-    ASSERT_TRUE(status.isOk());
-
-    const bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
-                                             DisplayCapability::BRIGHTNESS) != capabilities.end();
-
-    if (!brightnessSupport) {
-        GTEST_SUCCEED() << "Cannot verify dimming behavior without brightness support";
-        return;
-    }
-
-    const std::optional<float> maxBrightnessNitsOptional =
-            getMaxDisplayBrightnessNits(getPrimaryDisplayId());
-
-    ASSERT_TRUE(maxBrightnessNitsOptional.has_value());
-
-    const float maxBrightnessNits = *maxBrightnessNitsOptional;
-
-    // Preconditions to successfully run are knowing the max brightness and successfully applying
-    // the max brightness
-    ASSERT_GT(maxBrightnessNits, 0.f);
-    mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.f, maxBrightnessNits);
-    execute();
-    ASSERT_TRUE(mReader.takeErrors().empty());
-
     for (ColorMode mode : mTestColorModes) {
         EXPECT_TRUE(mComposerClient
                             ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
@@ -1000,11 +897,14 @@
         const common::Rect redRect = {0, 0, getDisplayWidth(), getDisplayHeight() / 2};
         const common::Rect dimmerRedRect = {0, getDisplayHeight() / 2, getDisplayWidth(),
                                             getDisplayHeight()};
+
+        static constexpr float kMaxBrightnessNits = 300.f;
+
         const auto redLayer =
                 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
         redLayer->setColor(RED);
         redLayer->setDisplayFrame(redRect);
-        redLayer->setWhitePointNits(maxBrightnessNits);
+        redLayer->setWhitePointNits(kMaxBrightnessNits);
         redLayer->setBrightness(1.f);
 
         const auto dimmerRedLayer =
@@ -1014,7 +914,7 @@
         // Intentionally use a small dimming ratio as some implementations may be more likely to
         // kick into GPU composition to apply dithering when the dimming ratio is high.
         static constexpr float kDimmingRatio = 0.9f;
-        dimmerRedLayer->setWhitePointNits(maxBrightnessNits * kDimmingRatio);
+        dimmerRedLayer->setWhitePointNits(kMaxBrightnessNits * kDimmingRatio);
         dimmerRedLayer->setBrightness(kDimmingRatio);
 
         const std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, dimmerRedLayer};
@@ -1030,7 +930,7 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED()
@@ -1038,7 +938,7 @@
                     << toString(mode);
             continue;
         }
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -1088,7 +988,7 @@
                                                        getDisplayHeight(), PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
-        layer->setDataspace(Dataspace::UNKNOWN, mWriter);
+        layer->setDataspace(Dataspace::UNKNOWN, *mWriter);
         ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
 
         layer->setBlendMode(blendMode);
@@ -1165,14 +1065,14 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -1210,14 +1110,14 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -1250,14 +1150,14 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -1323,7 +1223,7 @@
                                       getDisplayHeight(), mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         mLayer->setTransform(Transform::FLIP_H);
-        mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
 
         std::vector<Color> expectedColors(
                 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -1334,14 +1234,14 @@
 
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -1369,7 +1269,7 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         mLayer->setTransform(Transform::FLIP_V);
-        mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
 
         std::vector<Color> expectedColors(
                 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -1380,14 +1280,14 @@
 
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -1414,7 +1314,7 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         mLayer->setTransform(Transform::ROT_180);
-        mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+        mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
 
         std::vector<Color> expectedColors(
                 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -1426,14 +1326,14 @@
 
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED();
             return;
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        mWriter->presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index 047109e..323e358 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/graphics/common/BlendMode.h>
@@ -32,9 +33,11 @@
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
 #include <algorithm>
+#include <iterator>
 #include <numeric>
 #include <string>
 #include <thread>
+#include <unordered_map>
 #include "GraphicsComposerCallback.h"
 #include "VtsComposerClient.h"
 
@@ -115,6 +118,12 @@
                 [&](const Capability& activeCapability) { return activeCapability == capability; });
     }
 
+    int getInterfaceVersion() {
+        const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
+        EXPECT_TRUE(versionStatus.isOk());
+        return version;
+    }
+
     const VtsDisplay& getPrimaryDisplay() const { return mDisplays[0]; }
 
     int64_t getPrimaryDisplayId() const { return getPrimaryDisplay().getDisplayId(); }
@@ -618,6 +627,80 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlTest, GetHdrConversionCapabilities) {
+    if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
+        GTEST_SUCCEED() << "HDR output conversion not supported";
+        return;
+    }
+    const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
+    EXPECT_TRUE(status.isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Passthrough) {
+    if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
+        GTEST_SUCCEED() << "HDR output conversion not supported";
+        return;
+    }
+    common::HdrConversionStrategy hdrConversionStrategy;
+    hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::passthrough>(true);
+    const auto& [status, preferredHdrOutputType] =
+            mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
+}
+
+TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Force) {
+    if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
+        GTEST_SUCCEED() << "HDR output conversion not supported";
+        return;
+    }
+    const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
+    const auto& [status2, hdrCapabilities] =
+            mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
+    const auto& hdrTypes = hdrCapabilities.types;
+    for (auto conversionCapability : conversionCapabilities) {
+        if (conversionCapability.outputType != common::Hdr::INVALID) {
+            if (std::find(hdrTypes.begin(), hdrTypes.end(), conversionCapability.outputType) ==
+                hdrTypes.end()) {
+                continue;
+            }
+            common::HdrConversionStrategy hdrConversionStrategy;
+            hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::forceHdrConversion>(
+                    conversionCapability.outputType);
+            const auto& [statusSet, preferredHdrOutputType] =
+                    mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
+            EXPECT_TRUE(statusSet.isOk());
+            EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
+        }
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Auto) {
+    if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
+        GTEST_SUCCEED() << "HDR output conversion not supported";
+        return;
+    }
+    const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
+    const auto& [status2, hdrCapabilities] =
+            mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
+    if (hdrCapabilities.types.size() <= 0) {
+        return;
+    }
+    std::vector<aidl::android::hardware::graphics::common::Hdr> autoHdrTypes;
+    for (auto conversionCapability : conversionCapabilities) {
+        if (conversionCapability.outputType != common::Hdr::INVALID) {
+            autoHdrTypes.push_back(conversionCapability.outputType);
+        }
+    }
+    common::HdrConversionStrategy hdrConversionStrategy;
+    hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::autoAllowedHdrTypes>(
+            autoHdrTypes);
+    const auto& [statusSet, preferredHdrOutputType] =
+            mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
+    EXPECT_TRUE(statusSet.isOk());
+    EXPECT_NE(common::Hdr::INVALID, preferredHdrOutputType);
+}
+
 TEST_P(GraphicsComposerAidlTest, SetAutoLowLatencyMode_BadDisplay) {
     auto status = mComposerClient->setAutoLowLatencyMode(getInvalidDisplayId(), /*isEnabled*/ true);
     EXPECT_FALSE(status.isOk());
@@ -808,6 +891,39 @@
     EXPECT_TRUE(status.isOk());
 }
 
+TEST_P(GraphicsComposerAidlTest, GetOverlaySupport) {
+    if (getInterfaceVersion() <= 1) {
+        GTEST_SUCCEED() << "Device does not support the new API for overlay support";
+        return;
+    }
+
+    const auto& [status, properties] = mComposerClient->getOverlaySupport();
+    if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+        status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+        GTEST_SUCCEED() << "getOverlaySupport is not supported";
+        return;
+    }
+
+    ASSERT_TRUE(status.isOk());
+    for (const auto& i : properties.combinations) {
+        for (const auto standard : i.standards) {
+            const auto val = static_cast<int32_t>(standard) &
+                             static_cast<int32_t>(common::Dataspace::STANDARD_MASK);
+            ASSERT_TRUE(val == static_cast<int32_t>(standard));
+        }
+        for (const auto transfer : i.transfers) {
+            const auto val = static_cast<int32_t>(transfer) &
+                             static_cast<int32_t>(common::Dataspace::TRANSFER_MASK);
+            ASSERT_TRUE(val == static_cast<int32_t>(transfer));
+        }
+        for (const auto range : i.ranges) {
+            const auto val = static_cast<int32_t>(range) &
+                             static_cast<int32_t>(common::Dataspace::RANGE_MASK);
+            ASSERT_TRUE(val == static_cast<int32_t>(range));
+        }
+    }
+}
+
 TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation_BadDisplay) {
     const auto& [status, _] = mComposerClient->getDisplayPhysicalOrientation(getInvalidDisplayId());
 
@@ -1065,17 +1181,21 @@
     }
 
     void execute() {
-        const auto& commands = mWriter.getPendingCommands();
-        if (commands.empty()) {
-            mWriter.reset();
-            return;
+        std::vector<CommandResultPayload> payloads;
+        for (auto& [_, writer] : mWriters) {
+            auto commands = writer.takePendingCommands();
+            if (commands.empty()) {
+                continue;
+            }
+
+            auto [status, results] = mComposerClient->executeCommands(commands);
+            ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
+
+            payloads.reserve(payloads.size() + results.size());
+            payloads.insert(payloads.end(), std::make_move_iterator(results.begin()),
+                            std::make_move_iterator(results.end()));
         }
-
-        auto [status, results] = mComposerClient->executeCommands(commands);
-        ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
-
-        mReader.parse(std::move(results));
-        mWriter.reset();
+        mReader.parse(std::move(payloads));
     }
 
     static inline auto toTimePoint(nsecs_t time) {
@@ -1111,17 +1231,29 @@
         }
     }
 
-    sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
+    bool checkIfCallbackRefreshRateChangedDebugEnabledReceived(
+            std::function<bool(RefreshRateChangedDebugData)> filter) {
+        const auto list = mComposerClient->takeListOfRefreshRateChangedDebugData();
+        return std::any_of(list.begin(), list.end(), [&](auto refreshRateChangedDebugData) {
+            return filter(refreshRateChangedDebugData);
+        });
+    }
+
+    sp<GraphicBuffer> allocate(uint32_t width, uint32_t height,
+                               ::android::PixelFormat pixelFormat) {
         return sp<GraphicBuffer>::make(
-                static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
-                static_cast<uint32_t>(getPrimaryDisplay().getDisplayHeight()), pixelFormat,
-                /*layerCount*/ 1U,
-                (static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
-                 static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
-                 static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY)),
+                width, height, pixelFormat, /*layerCount*/ 1U,
+                static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                        static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+                        static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY),
                 "VtsHalGraphicsComposer3_TargetTest");
     }
 
+    sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
+        return allocate(static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
+                        static_cast<uint32_t>(getPrimaryDisplay().getDisplayHeight()), pixelFormat);
+    }
+
     void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
         if (timeline != nullptr) {
             // Refresh time should be before newVsyncAppliedTimeNanos
@@ -1139,6 +1271,7 @@
         const auto& [status, layer] =
                 mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount);
         EXPECT_TRUE(status.isOk());
+        auto& writer = getWriter(display.getDisplayId());
         {
             const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
             ASSERT_NE(nullptr, buffer);
@@ -1147,15 +1280,15 @@
 
             configureLayer(display, layer, Composition::DEVICE, display.getFrameRect(),
                            display.getCrop());
-            mWriter.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
-                                   /*acquireFence*/ -1);
-            mWriter.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
+            writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
+                                  /*acquireFence*/ -1);
+            writer.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
 
-            mWriter.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
+            writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
             execute();
             ASSERT_TRUE(mReader.takeErrors().empty());
 
-            mWriter.presentDisplay(display.getDisplayId());
+            writer.presentDisplay(display.getDisplayId());
             execute();
             ASSERT_TRUE(mReader.takeErrors().empty());
         }
@@ -1164,15 +1297,15 @@
             const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
             ASSERT_NE(nullptr, buffer->handle);
 
-            mWriter.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
-                                   /*acquireFence*/ -1);
-            mWriter.setLayerSurfaceDamage(display.getDisplayId(), layer,
-                                          std::vector<Rect>(1, {0, 0, 10, 10}));
-            mWriter.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
+            writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
+                                  /*acquireFence*/ -1);
+            writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
+                                         std::vector<Rect>(1, {0, 0, 10, 10}));
+            writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
             execute();
             ASSERT_TRUE(mReader.takeErrors().empty());
 
-            mWriter.presentDisplay(display.getDisplayId());
+            writer.presentDisplay(display.getDisplayId());
             execute();
         }
 
@@ -1181,11 +1314,12 @@
 
     sp<::android::Fence> presentAndGetFence(
             std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
-        mWriter.validateDisplay(getPrimaryDisplayId(), expectedPresentTime);
+        auto& writer = getWriter(getPrimaryDisplayId());
+        writer.validateDisplay(getPrimaryDisplayId(), expectedPresentTime);
         execute();
         EXPECT_TRUE(mReader.takeErrors().empty());
 
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        writer.presentDisplay(getPrimaryDisplayId());
         execute();
         EXPECT_TRUE(mReader.takeErrors().empty());
 
@@ -1208,7 +1342,7 @@
         return vsyncPeriod;
     }
 
-    int64_t createOnScreenLayer() {
+    int64_t createOnScreenLayer(Composition composition = Composition::DEVICE) {
         const auto& [status, layer] =
                 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
         EXPECT_TRUE(status.isOk());
@@ -1216,11 +1350,25 @@
                           getPrimaryDisplay().getDisplayHeight()};
         FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
                        (float)getPrimaryDisplay().getDisplayHeight()};
-        configureLayer(getPrimaryDisplay(), layer, Composition::DEVICE, displayFrame, cropRect);
-        mWriter.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN);
+        configureLayer(getPrimaryDisplay(), layer, composition, displayFrame, cropRect);
+        auto& writer = getWriter(getPrimaryDisplayId());
+        writer.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN);
         return layer;
     }
 
+    void sendBufferUpdate(int64_t layer) {
+        const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+        ASSERT_NE(nullptr, buffer->handle);
+
+        auto& writer = getWriter(getPrimaryDisplayId());
+        writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
+                              /*acquireFence*/ -1);
+
+        const sp<::android::Fence> presentFence =
+                presentAndGetFence(ComposerClientWriter::kNoTimestamp);
+        presentFence->waitForever(LOG_TAG);
+    }
+
     bool hasDisplayCapability(int64_t display, DisplayCapability cap) {
         const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(display);
         EXPECT_TRUE(status.isOk());
@@ -1317,8 +1465,9 @@
         ASSERT_NE(nullptr, buffer2);
 
         const auto layer = createOnScreenLayer();
-        mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer1->handle,
-                               /*acquireFence*/ -1);
+        auto& writer = getWriter(getPrimaryDisplayId());
+        writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer1->handle,
+                              /*acquireFence*/ -1);
         const sp<::android::Fence> presentFence1 =
                 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
         presentFence1->waitForever(LOG_TAG);
@@ -1328,8 +1477,8 @@
             expectedPresentTime += *framesDelay * vsyncPeriod;
         }
 
-        mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer2->handle,
-                               /*acquireFence*/ -1);
+        writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer2->handle,
+                              /*acquireFence*/ -1);
         const auto setExpectedPresentTime = [&]() -> std::optional<ClockMonotonicTimestamp> {
             if (!framesDelay.has_value()) {
                 return ComposerClientWriter::kNoTimestamp;
@@ -1350,17 +1499,18 @@
 
     void configureLayer(const VtsDisplay& display, int64_t layer, Composition composition,
                         const Rect& displayFrame, const FRect& cropRect) {
-        mWriter.setLayerCompositionType(display.getDisplayId(), layer, composition);
-        mWriter.setLayerDisplayFrame(display.getDisplayId(), layer, displayFrame);
-        mWriter.setLayerPlaneAlpha(display.getDisplayId(), layer, /*alpha*/ 1);
-        mWriter.setLayerSourceCrop(display.getDisplayId(), layer, cropRect);
-        mWriter.setLayerTransform(display.getDisplayId(), layer, static_cast<Transform>(0));
-        mWriter.setLayerVisibleRegion(display.getDisplayId(), layer,
-                                      std::vector<Rect>(1, displayFrame));
-        mWriter.setLayerZOrder(display.getDisplayId(), layer, /*z*/ 10);
-        mWriter.setLayerBlendMode(display.getDisplayId(), layer, BlendMode::NONE);
-        mWriter.setLayerSurfaceDamage(display.getDisplayId(), layer,
-                                      std::vector<Rect>(1, displayFrame));
+        auto& writer = getWriter(display.getDisplayId());
+        writer.setLayerCompositionType(display.getDisplayId(), layer, composition);
+        writer.setLayerDisplayFrame(display.getDisplayId(), layer, displayFrame);
+        writer.setLayerPlaneAlpha(display.getDisplayId(), layer, /*alpha*/ 1);
+        writer.setLayerSourceCrop(display.getDisplayId(), layer, cropRect);
+        writer.setLayerTransform(display.getDisplayId(), layer, static_cast<Transform>(0));
+        writer.setLayerVisibleRegion(display.getDisplayId(), layer,
+                                     std::vector<Rect>(1, displayFrame));
+        writer.setLayerZOrder(display.getDisplayId(), layer, /*z*/ 10);
+        writer.setLayerBlendMode(display.getDisplayId(), layer, BlendMode::NONE);
+        writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
+                                     std::vector<Rect>(1, displayFrame));
     }
     // clang-format off
     const std::array<float, 16> kIdentity = {{
@@ -1371,12 +1521,20 @@
     }};
     // clang-format on
 
-    ComposerClientWriter mWriter;
+    ComposerClientWriter& getWriter(int64_t display) {
+        auto [it, _] = mWriters.try_emplace(display, display);
+        return it->second;
+    }
+
     ComposerClientReader mReader;
+
+  private:
+    std::unordered_map<int64_t, ComposerClientWriter> mWriters;
 };
 
 TEST_P(GraphicsComposerAidlCommandTest, SetColorTransform) {
-    mWriter.setColorTransform(getPrimaryDisplayId(), kIdentity.data());
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setColorTransform(getPrimaryDisplayId(), kIdentity.data());
     execute();
 }
 
@@ -1384,7 +1542,8 @@
     const auto& [status, layer] =
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(status.isOk());
-    mWriter.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
     execute();
 
     const auto errors = mReader.takeErrors();
@@ -1395,13 +1554,15 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) {
+    EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
     const auto& [status, capabilities] =
             mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
     ASSERT_TRUE(status.isOk());
     bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
                                        DisplayCapability::BRIGHTNESS) != capabilities.end();
+    auto& writer = getWriter(getPrimaryDisplayId());
     if (!brightnessSupport) {
-        mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
+        writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
         execute();
         const auto errors = mReader.takeErrors();
         EXPECT_EQ(1, errors.size());
@@ -1410,23 +1571,23 @@
         return;
     }
 
-    mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.0f, -1.f);
+    writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.0f, -1.f);
     execute();
     EXPECT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
+    writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
     execute();
     EXPECT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.0f, -1.f);
+    writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.0f, -1.f);
     execute();
     EXPECT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -1.0f, -1.f);
+    writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -1.0f, -1.f);
     execute();
     EXPECT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 2.0f, -1.f);
+    writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 2.0f, -1.f);
     execute();
     {
         const auto errors = mReader.takeErrors();
@@ -1434,7 +1595,7 @@
         EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
     }
 
-    mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -2.0f, -1.f);
+    writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -2.0f, -1.f);
     execute();
     {
         const auto errors = mReader.takeErrors();
@@ -1447,8 +1608,9 @@
     EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kBufferSlotCount)
                         .isOk());
 
-    mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
-                            Dataspace::UNKNOWN, std::vector<Rect>());
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
+                           Dataspace::UNKNOWN, std::vector<Rect>());
 
     execute();
 }
@@ -1468,24 +1630,28 @@
 
     const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
     const auto handle = buffer->handle;
-    mWriter.setOutputBuffer(display.display, /*slot*/ 0, handle, /*releaseFence*/ -1);
+    auto& writer = getWriter(display.display);
+    writer.setOutputBuffer(display.display, /*slot*/ 0, handle, /*releaseFence*/ -1);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, ValidDisplay) {
-    mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, AcceptDisplayChanges) {
-    mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
-    mWriter.acceptDisplayChanges(getPrimaryDisplayId());
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+    writer.acceptDisplayChanges(getPrimaryDisplayId());
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, PresentDisplay) {
-    mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
-    mWriter.presentDisplay(getPrimaryDisplayId());
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+    writer.presentDisplay(getPrimaryDisplayId());
     execute();
 }
 
@@ -1506,6 +1672,7 @@
     const auto& [renderIntentsStatus, renderIntents] =
             mComposerClient->getRenderIntents(getPrimaryDisplayId(), ColorMode::NATIVE);
     EXPECT_TRUE(renderIntentsStatus.isOk());
+    auto& writer = getWriter(getPrimaryDisplayId());
     for (auto intent : renderIntents) {
         EXPECT_TRUE(mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE, intent)
                             .isOk());
@@ -1523,10 +1690,10 @@
         FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
                        (float)getPrimaryDisplay().getDisplayHeight()};
         configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
-        mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle,
-                               /*acquireFence*/ -1);
-        mWriter.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
-        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+        writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle,
+                              /*acquireFence*/ -1);
+        writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
+        writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
             GTEST_SUCCEED() << "Composition change requested, skipping test";
@@ -1534,18 +1701,18 @@
         }
 
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        writer.presentDisplay(getPrimaryDisplayId());
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
         const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
         const auto handle2 = buffer2->handle;
         ASSERT_NE(nullptr, handle2);
-        mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle2,
-                               /*acquireFence*/ -1);
-        mWriter.setLayerSurfaceDamage(getPrimaryDisplayId(), layer,
-                                      std::vector<Rect>(1, {0, 0, 10, 10}));
-        mWriter.presentDisplay(getPrimaryDisplayId());
+        writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle2,
+                              /*acquireFence*/ -1);
+        writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer,
+                                     std::vector<Rect>(1, {0, 0, 10, 10}));
+        writer.presentDisplay(getPrimaryDisplayId());
         execute();
     }
 }
@@ -1559,15 +1726,16 @@
     const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
-    mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
 
     Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
                       getPrimaryDisplay().getDisplayHeight()};
     FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
                    (float)getPrimaryDisplay().getDisplayHeight()};
     configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
-    mWriter.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
-    mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+    writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
+    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
 
     execute();
 
@@ -1575,15 +1743,15 @@
         GTEST_SUCCEED() << "Composition change requested, skipping test";
         return;
     }
-    mWriter.presentDisplay(getPrimaryDisplayId());
+    writer.presentDisplay(getPrimaryDisplayId());
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 1, /*y*/ 1);
+    writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 1, /*y*/ 1);
     execute();
 
-    mWriter.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 0, /*y*/ 0);
-    mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
-    mWriter.presentDisplay(getPrimaryDisplayId());
+    writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 0, /*y*/ 0);
+    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+    writer.presentDisplay(getPrimaryDisplayId());
     execute();
 }
 
@@ -1595,10 +1763,109 @@
     const auto& [layerStatus, layer] =
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
-    mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
     execute();
 }
 
+TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferSlotsToClear) {
+    // Older HAL versions use a backwards compatible way of clearing buffer slots
+    const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
+    ASSERT_TRUE(versionStatus.isOk());
+    if (version <= 1) {
+        GTEST_SUCCEED() << "HAL at version 1 or lower does not have "
+                           "LayerCommand::bufferSlotsToClear.";
+        return;
+    }
+
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+    EXPECT_TRUE(layerStatus.isOk());
+    auto& writer = getWriter(getPrimaryDisplayId());
+
+    // setup 3 buffers in the buffer cache, with the last buffer being active
+    // then emulate the Android platform code that clears all 3 buffer slots
+
+    const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+    ASSERT_NE(nullptr, buffer1);
+    const auto handle1 = buffer1->handle;
+    writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+    ASSERT_NE(nullptr, buffer2);
+    const auto handle2 = buffer2->handle;
+    writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+    ASSERT_NE(nullptr, buffer3);
+    const auto handle3 = buffer3->handle;
+    writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    // Ensure we can clear all 3 buffer slots, even the active buffer - it is assumed the
+    // current active buffer's slot will be cleared, but still remain the active buffer and no
+    // errors will occur.
+    writer.setLayerBufferSlotsToClear(getPrimaryDisplayId(), layer, {0, 1, 2});
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+    EXPECT_TRUE(layerStatus.isOk());
+    auto& writer = getWriter(getPrimaryDisplayId());
+
+    // Setup 3 buffers in the buffer cache, with the last buffer being active. Then, emulate the
+    // Android platform code that clears all 3 buffer slots by setting all but the active buffer
+    // slot to a placeholder buffer, and then restoring the active buffer.
+
+    // This is used on HALs that don't support setLayerBufferSlotsToClear (version <= 3.1).
+
+    const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+    ASSERT_NE(nullptr, buffer1);
+    const auto handle1 = buffer1->handle;
+    writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+    ASSERT_NE(nullptr, buffer2);
+    const auto handle2 = buffer2->handle;
+    writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+    ASSERT_NE(nullptr, buffer3);
+    const auto handle3 = buffer3->handle;
+    writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    // Older versions of the HAL clear all but the active buffer slot with a placeholder buffer,
+    // and then restoring the current active buffer at the end
+    auto clearSlotBuffer = allocate(1u, 1u, ::android::PIXEL_FORMAT_RGB_888);
+    ASSERT_NE(nullptr, clearSlotBuffer);
+    auto clearSlotBufferHandle = clearSlotBuffer->handle;
+
+    // clear buffer slots 0 and 1 with new layer commands... and then...
+    writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 0,
+                                        clearSlotBufferHandle, /*acquireFence*/ -1);
+    writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 1,
+                                        clearSlotBufferHandle, /*acquireFence*/ -1);
+    // ...reset the layer buffer to the current active buffer slot with a final new command
+    writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /*slot*/ 2, nullptr,
+                                        /*acquireFence*/ -1);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
     const auto& [layerStatus, layer] =
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
@@ -1607,15 +1874,16 @@
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    mWriter.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
+    writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>());
+    writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>());
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -1628,15 +1896,16 @@
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    mWriter.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
+    writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
+    writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -1646,15 +1915,16 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::PREMULTIPLIED);
+    writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::PREMULTIPLIED);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::COVERAGE);
+    writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::COVERAGE);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -1664,11 +1934,12 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerColor(getPrimaryDisplayId(), layer, Color{0.0f, 0.0f, 0.0f, 0.0f});
+    writer.setLayerColor(getPrimaryDisplayId(), layer, Color{0.0f, 0.0f, 0.0f, 0.0f});
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -1678,19 +1949,20 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::DEVICE);
+    writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::DEVICE);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::SOLID_COLOR);
+    writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::SOLID_COLOR);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CURSOR);
+    writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CURSOR);
     execute();
 }
 
@@ -1721,9 +1993,10 @@
 
         configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
                           display.getCrop());
-        mWriter.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
-                               /*acquireFence*/ -1);
-        mWriter.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
+        auto& writer = getWriter(display.getDisplayId());
+        writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
+                              /*acquireFence*/ -1);
+        writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         if (support) {
             ASSERT_TRUE(mReader.takeErrors().empty());
@@ -1740,7 +2013,8 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
     execute();
 }
 
@@ -1749,7 +2023,8 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
     execute();
 }
 
@@ -1758,11 +2033,12 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 1.0f);
+    writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 1.0f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -1781,7 +2057,8 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
     execute();
 }
 
@@ -1790,7 +2067,8 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
     execute();
 }
 
@@ -1799,39 +2077,40 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_H);
+    writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_H);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_V);
+    writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_V);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_90);
+    writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_90);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_180);
+    writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_180);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_270);
+    writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_270);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerTransform(getPrimaryDisplayId(), layer,
-                              static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
-                                                     static_cast<int>(Transform::ROT_90)));
+    writer.setLayerTransform(getPrimaryDisplayId(), layer,
+                             static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
+                                                    static_cast<int>(Transform::ROT_90)));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerTransform(getPrimaryDisplayId(), layer,
-                              static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
-                                                     static_cast<int>(Transform::ROT_90)));
+    writer.setLayerTransform(getPrimaryDisplayId(), layer,
+                             static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
+                                                    static_cast<int>(Transform::ROT_90)));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -1844,15 +2123,16 @@
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    mWriter.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
+    writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
+    writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -1862,11 +2142,12 @@
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
     EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 0);
+    writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 0);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -1888,6 +2169,7 @@
      *  white (D65)     0.3127  0.3290
      */
 
+    auto& writer = getWriter(getPrimaryDisplayId());
     std::vector<PerFrameMetadata> aidlMetadata;
     aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
     aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
@@ -1901,7 +2183,7 @@
     aidlMetadata.push_back({PerFrameMetadataKey::MIN_LUMINANCE, 0.1f});
     aidlMetadata.push_back({PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
     aidlMetadata.push_back({PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
-    mWriter.setLayerPerFrameMetadata(getPrimaryDisplayId(), layer, aidlMetadata);
+    writer.setLayerPerFrameMetadata(getPrimaryDisplayId(), layer, aidlMetadata);
     execute();
 
     const auto errors = mReader.takeErrors();
@@ -1918,19 +2200,20 @@
     const auto& [layerStatus, layer] =
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
 
-    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, 1.f);
+    writer.setLayerBrightness(getPrimaryDisplayId(), layer, 1.f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, 0.f);
+    writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, -1.f);
+    writer.setLayerBrightness(getPrimaryDisplayId(), layer, -1.f);
     execute();
     {
         const auto errors = mReader.takeErrors();
@@ -1938,7 +2221,7 @@
         EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
     }
 
-    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, std::nanf(""));
+    writer.setLayerBrightness(getPrimaryDisplayId(), layer, std::nanf(""));
     execute();
     {
         const auto errors = mReader.takeErrors();
@@ -2103,8 +2386,9 @@
     ASSERT_NE(nullptr, buffer->handle);
 
     const auto layer = createOnScreenLayer();
-    mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
-                           /*acquireFence*/ -1);
+    auto& writer = getWriter(getPrimaryDisplayId());
+    writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
+                          /*acquireFence*/ -1);
     int32_t vsyncIdleCount = mComposerClient->getVsyncIdleCount();
     auto earlyVsyncIdleTime = systemTime() + std::chrono::nanoseconds(2s).count();
     EXPECT_TRUE(
@@ -2122,6 +2406,245 @@
     EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
 }
 
+TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Unsupported) {
+    if (getInterfaceVersion() <= 1) {
+        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is "
+                           "not supported on older version of the service";
+        return;
+    }
+    if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
+        auto status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(
+                getPrimaryDisplayId(), /*enabled*/ true);
+        EXPECT_FALSE(status.isOk());
+        EXPECT_NO_FATAL_FAILURE(
+                assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
+
+        status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(getPrimaryDisplayId(),
+                                                                            /*enabled*/ false);
+        EXPECT_FALSE(status.isOk());
+        EXPECT_NO_FATAL_FAILURE(
+                assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Enabled) {
+    if (getInterfaceVersion() <= 1) {
+        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is "
+                           "not supported on older version of the service";
+        return;
+    }
+    if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
+        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
+        return;
+    }
+
+    const auto displayId = getPrimaryDisplayId();
+    EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
+    // Enable the callback
+    ASSERT_TRUE(mComposerClient
+                        ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+                                                                    /*enabled*/ true)
+                        .isOk());
+    std::this_thread::sleep_for(100ms);
+
+    const auto displayFilter = [displayId](auto refreshRateChangedDebugData) {
+        return displayId == refreshRateChangedDebugData.display;
+    };
+
+    // Check that we immediately got a callback
+    EXPECT_TRUE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter));
+
+    ASSERT_TRUE(mComposerClient
+                        ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+                                                                    /*enabled*/ false)
+                        .isOk());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest,
+       SetRefreshRateChangedCallbackDebugEnabled_noCallbackWhenIdle) {
+    if (getInterfaceVersion() <= 1) {
+        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is "
+                           "not supported on older version of the service";
+        return;
+    }
+    if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
+        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
+        return;
+    }
+
+    auto display = getEditablePrimaryDisplay();
+    const auto displayId = display.getDisplayId();
+
+    if (!hasDisplayCapability(displayId, DisplayCapability::DISPLAY_IDLE_TIMER)) {
+        GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
+        return;
+    }
+
+    EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
+    EXPECT_TRUE(mComposerClient->setPeakRefreshRateConfig(&display).isOk());
+
+    ASSERT_TRUE(mComposerClient->setIdleTimerEnabled(displayId, /*timeoutMs*/ 500).isOk());
+    // Enable the callback
+    ASSERT_TRUE(mComposerClient
+                        ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+                                                                    /*enabled*/ true)
+                        .isOk());
+
+    const auto displayFilter = [displayId](auto refreshRateChangedDebugData) {
+        return displayId == refreshRateChangedDebugData.display;
+    };
+
+    int retryCount = 3;
+    do {
+        // Wait for 1s so that we enter the idle state
+        std::this_thread::sleep_for(1s);
+        if (!checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter)) {
+            // DID NOT receive a callback, we are in the idle state.
+            break;
+        }
+    } while (--retryCount > 0);
+
+    if (retryCount == 0) {
+        GTEST_SUCCEED() << "Unable to enter the idle mode";
+        return;
+    }
+
+    // Send the REFRESH_RATE_INDICATOR update
+    ASSERT_NO_FATAL_FAILURE(
+            sendBufferUpdate(createOnScreenLayer(Composition::REFRESH_RATE_INDICATOR)));
+    std::this_thread::sleep_for(1s);
+    EXPECT_FALSE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter))
+            << "A callback should not be received for REFRESH_RATE_INDICATOR";
+
+    EXPECT_TRUE(mComposerClient
+                        ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+                                                                    /*enabled*/ false)
+                        .isOk());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest,
+       SetRefreshRateChangedCallbackDebugEnabled_SetActiveConfigWithConstraints) {
+    if (getInterfaceVersion() <= 1) {
+        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is "
+                           "not supported on older version of the service";
+        return;
+    }
+    if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
+        GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
+        return;
+    }
+
+    VsyncPeriodChangeConstraints constraints;
+    constraints.seamlessRequired = false;
+    constraints.desiredTimeNanos = systemTime();
+
+    for (VtsDisplay& display : mDisplays) {
+        const auto displayId = display.getDisplayId();
+        EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
+
+        // Enable the callback
+        ASSERT_TRUE(mComposerClient
+                            ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true)
+                            .isOk());
+
+        forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) {
+            const int32_t vsyncPeriod1 = display.getDisplayConfig(config1).vsyncPeriod;
+            const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;
+
+            if (vsyncPeriod1 == vsyncPeriod2) {
+                return;  // continue
+            }
+
+            EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
+            sendRefreshFrame(display, nullptr);
+
+            const auto& [status, timeline] =
+                    mComposerClient->setActiveConfigWithConstraints(&display, config2, constraints);
+            EXPECT_TRUE(status.isOk());
+
+            if (timeline.refreshRequired) {
+                sendRefreshFrame(display, &timeline);
+            }
+
+            const auto callbackFilter = [displayId,
+                                         vsyncPeriod2](auto refreshRateChangedDebugData) {
+                constexpr int kVsyncThreshold = 1000;
+                return displayId == refreshRateChangedDebugData.display &&
+                       std::abs(vsyncPeriod2 - refreshRateChangedDebugData.vsyncPeriodNanos) <=
+                               kVsyncThreshold;
+            };
+
+            int retryCount = 3;
+            do {
+                std::this_thread::sleep_for(100ms);
+                if (checkIfCallbackRefreshRateChangedDebugEnabledReceived(callbackFilter)) {
+                    GTEST_SUCCEED() << "Received a callback successfully";
+                    break;
+                }
+            } while (--retryCount > 0);
+
+            if (retryCount == 0) {
+                GTEST_FAIL() << "failed to get a callback for the display " << displayId
+                             << " with config " << config2;
+            }
+        });
+
+        EXPECT_TRUE(
+                mComposerClient
+                        ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false)
+                        .isOk());
+    }
+}
+
+/*
+ * Test that no two display configs are exactly the same.
+ */
+TEST_P(GraphicsComposerAidlTest, GetDisplayConfigNoRepetitions) {
+    for (const auto& display : mDisplays) {
+        const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
+        for (std::vector<int>::size_type i = 0; i < configs.size(); i++) {
+            for (std::vector<int>::size_type j = i + 1; j < configs.size(); j++) {
+                const auto& [widthStatus1, width1] = mComposerClient->getDisplayAttribute(
+                        display.getDisplayId(), configs[i], DisplayAttribute::WIDTH);
+                const auto& [heightStatus1, height1] = mComposerClient->getDisplayAttribute(
+                        display.getDisplayId(), configs[i], DisplayAttribute::HEIGHT);
+                const auto& [vsyncPeriodStatus1, vsyncPeriod1] =
+                        mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[i],
+                                                             DisplayAttribute::VSYNC_PERIOD);
+                const auto& [groupStatus1, group1] = mComposerClient->getDisplayAttribute(
+                        display.getDisplayId(), configs[i], DisplayAttribute::CONFIG_GROUP);
+
+                const auto& [widthStatus2, width2] = mComposerClient->getDisplayAttribute(
+                        display.getDisplayId(), configs[j], DisplayAttribute::WIDTH);
+                const auto& [heightStatus2, height2] = mComposerClient->getDisplayAttribute(
+                        display.getDisplayId(), configs[j], DisplayAttribute::HEIGHT);
+                const auto& [vsyncPeriodStatus2, vsyncPeriod2] =
+                        mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[j],
+                                                             DisplayAttribute::VSYNC_PERIOD);
+                const auto& [groupStatus2, group2] = mComposerClient->getDisplayAttribute(
+                        display.getDisplayId(), configs[j], DisplayAttribute::CONFIG_GROUP);
+
+                ASSERT_FALSE(width1 == width2 && height1 == height2 &&
+                             vsyncPeriod1 == vsyncPeriod2 && group1 == group2);
+            }
+        }
+    }
+}
+
+/**
+ * Test Capability::SKIP_VALIDATE
+ *
+ * Capability::SKIP_VALIDATE has been deprecated and should not be enabled.
+ */
+TEST_P(GraphicsComposerAidlCommandTest, SkipValidateDeprecatedTest) {
+    if (getInterfaceVersion() <= 1) {
+        GTEST_SUCCEED() << "HAL at version 1 or lower can contain Capability::SKIP_VALIDATE.";
+        return;
+    }
+    ASSERT_FALSE(hasCapability(Capability::SKIP_VALIDATE))
+            << "Found Capability::SKIP_VALIDATE capability.";
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, GraphicsComposerAidlCommandTest,
diff --git a/graphics/mapper/2.0/default/OWNERS b/graphics/mapper/2.0/default/OWNERS
deleted file mode 100644
index c9f24d0..0000000
--- a/graphics/mapper/2.0/default/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-chrisforbes@google.com
-jreck@google.com
-lpy@google.com
diff --git a/graphics/mapper/2.0/utils/OWNERS b/graphics/mapper/2.0/utils/OWNERS
deleted file mode 100644
index c9f24d0..0000000
--- a/graphics/mapper/2.0/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-chrisforbes@google.com
-jreck@google.com
-lpy@google.com
diff --git a/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h
index db7e67d..5f0a176 100644
--- a/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h
+++ b/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/Gralloc1Hal.h
@@ -259,19 +259,22 @@
 
         for (int i = 0; i < 3; i++) {
             const auto& plane = flex.planes[i];
-            // must have 8-bit depth
-            if (plane.bits_per_component != 8 || plane.bits_used != 8) {
+            // Must be a positive multiple of 8.
+            if (plane.bits_per_component <= 0 || (plane.bits_per_component % 8) != 0) {
                 return false;
             }
-
+            // Must be between 1 and bits_per_component, inclusive.
+            if (plane.bits_used < 1 || plane.bits_used > plane.bits_per_component) {
+                return false;
+            }
             if (plane.component == FLEX_COMPONENT_Y) {
                 // Y must not be interleaved
-                if (plane.h_increment != 1) {
+                if (plane.h_increment != 1 && plane.h_increment != 2) {
                     return false;
                 }
             } else {
                 // Cb and Cr can be interleaved
-                if (plane.h_increment != 1 && plane.h_increment != 2) {
+                if (plane.h_increment != 1 && plane.h_increment != 2 && plane.h_increment != 4) {
                     return false;
                 }
             }
diff --git a/graphics/mapper/2.0/vts/OWNERS b/graphics/mapper/2.0/vts/OWNERS
deleted file mode 100644
index 62e3f2a..0000000
--- a/graphics/mapper/2.0/vts/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 25423
-chrisforbes@google.com
-jreck@google.com
-lpy@google.com
-sumir@google.com
diff --git a/graphics/mapper/2.1/default/OWNERS b/graphics/mapper/2.1/default/OWNERS
deleted file mode 100644
index c9f24d0..0000000
--- a/graphics/mapper/2.1/default/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-chrisforbes@google.com
-jreck@google.com
-lpy@google.com
diff --git a/graphics/mapper/2.1/utils/OWNERS b/graphics/mapper/2.1/utils/OWNERS
deleted file mode 100644
index c9f24d0..0000000
--- a/graphics/mapper/2.1/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-chrisforbes@google.com
-jreck@google.com
-lpy@google.com
diff --git a/graphics/mapper/2.1/vts/OWNERS b/graphics/mapper/2.1/vts/OWNERS
deleted file mode 100644
index 43c018a..0000000
--- a/graphics/mapper/2.1/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 25423
-include ../../2.0/vts/OWNERS
diff --git a/graphics/mapper/3.0/utils/OWNERS b/graphics/mapper/3.0/utils/OWNERS
deleted file mode 100644
index c9f24d0..0000000
--- a/graphics/mapper/3.0/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-chrisforbes@google.com
-jreck@google.com
-lpy@google.com
diff --git a/graphics/mapper/3.0/vts/OWNERS b/graphics/mapper/3.0/vts/OWNERS
deleted file mode 100644
index 43c018a..0000000
--- a/graphics/mapper/3.0/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 25423
-include ../../2.0/vts/OWNERS
diff --git a/graphics/mapper/4.0/utils/OWNERS b/graphics/mapper/4.0/utils/OWNERS
deleted file mode 100644
index c9f24d0..0000000
--- a/graphics/mapper/4.0/utils/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Graphics team
-chrisforbes@google.com
-jreck@google.com
-lpy@google.com
diff --git a/graphics/mapper/4.0/utils/vts/Android.bp b/graphics/mapper/4.0/utils/vts/Android.bp
index 7abf5db..51e871b 100644
--- a/graphics/mapper/4.0/utils/vts/Android.bp
+++ b/graphics/mapper/4.0/utils/vts/Android.bp
@@ -25,16 +25,18 @@
 
 cc_library_static {
     name: "android.hardware.graphics.mapper@4.0-vts",
-    defaults: ["VtsHalTargetTestDefaults"],
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "android.hardware.graphics.allocator-ndk_static",
+        "android.hardware.graphics.common-ndk_static",
+    ],
     srcs: ["MapperVts.cpp"],
     cflags: [
         "-O0",
         "-g",
     ],
     static_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.allocator@4.0",
-        "android.hardware.graphics.common-V3-ndk",
         "android.hardware.graphics.mapper@4.0",
         "libaidlcommonsupport",
     ],
@@ -44,9 +46,8 @@
         "libvndksupport",
     ],
     export_static_lib_headers: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.allocator@4.0",
-        "android.hardware.graphics.common-V3-ndk",
+        "android.hardware.graphics.common-V4-ndk",
         "android.hardware.graphics.mapper@4.0",
     ],
     export_include_dirs: ["include"],
diff --git a/graphics/mapper/4.0/vts/OWNERS b/graphics/mapper/4.0/vts/OWNERS
deleted file mode 100644
index 43c018a..0000000
--- a/graphics/mapper/4.0/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 25423
-include ../../2.0/vts/OWNERS
diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp
index e830633..6208ae9 100644
--- a/graphics/mapper/4.0/vts/functional/Android.bp
+++ b/graphics/mapper/4.0/vts/functional/Android.bp
@@ -27,18 +27,18 @@
     name: "VtsHalGraphicsMapperV4_0TargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
+        "android.hardware.graphics.allocator-ndk_shared",
+        "android.hardware.graphics.common-ndk_static",
         "use_libaidlvintf_gtest_helper_static",
     ],
     srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"],
     static_libs: [
-        "android.hardware.graphics.common-V3-ndk",
         "android.hardware.graphics.mapper@4.0-vts",
         "libaidlcommonsupport",
         "libgralloctypes",
         "libsync",
     ],
     shared_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
         "android.hardware.graphics.allocator@4.0",
         "android.hardware.graphics.common@1.0",
         "android.hardware.graphics.common@1.1",
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 2ec98d4..e4a84e1 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -954,7 +954,6 @@
     EXPECT_EQ(PlaneLayoutComponentType::RAW,
               static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
     EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
-    EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
 
     ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
 }
@@ -996,7 +995,6 @@
     EXPECT_EQ(PlaneLayoutComponentType::RAW,
               static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
     EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
-    EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
 
     ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
 }
diff --git a/graphics/mapper/stable-c/Android.bp b/graphics/mapper/stable-c/Android.bp
new file mode 100644
index 0000000..1d01a02
--- /dev/null
+++ b/graphics/mapper/stable-c/Android.bp
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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: "libimapper_stablec",
+    export_include_dirs: ["include"],
+    vendor_available: true,
+    header_libs: [
+        "libarect_headers",
+    ],
+    export_header_lib_headers: [
+        "libarect_headers",
+    ],
+    // TODO(b/214400477) Remove apex_available
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+        "test_com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
+}
+
+cc_library_shared {
+    name: "libimapper_stablec_abicheck",
+    visibility: ["//visibility:private"],
+    defaults: [
+        "android.hardware.graphics.allocator-ndk_shared",
+        "android.hardware.graphics.common-ndk_shared",
+    ],
+    header_libs: [
+        "libimapper_stablec",
+    ],
+    srcs: [
+        "imapper5_abicheck.cpp",
+    ],
+    header_abi_checker: {
+        enabled: true,
+        symbol_file: "imapper.map.txt",
+    },
+}
+
+cc_library_headers {
+    name: "libimapper_providerutils",
+    vendor_available: true,
+    export_include_dirs: ["implutils/include"],
+    header_libs: [
+        "libbase_headers",
+        "libimapper_stablec",
+    ],
+    export_header_lib_headers: [
+        "libbase_headers",
+        "libimapper_stablec",
+    ],
+    // TODO(b/214400477) Remove apex_available
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+        "test_com.android.media.swcodec",
+    ],
+    min_sdk_version: "29",
+}
+
+cc_test {
+    name: "libimapper_providerutils_tests",
+    defaults: [
+        "android.hardware.graphics.allocator-ndk_shared",
+        "android.hardware.graphics.common-ndk_shared",
+    ],
+    header_libs: [
+        "libimapper_providerutils",
+    ],
+    srcs: [
+        "implutils/impltests.cpp",
+    ],
+    shared_libs: [
+        "libgralloctypes",
+        "libhidlbase",
+    ],
+    visibility: [":__subpackages__"],
+    cpp_std: "experimental",
+}
+
+cc_test {
+    name: "VtsHalGraphicsMapperStableC_TargetTest",
+    cpp_std: "experimental",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+        "android.hardware.graphics.allocator-ndk_shared",
+        "android.hardware.graphics.common-ndk_shared",
+    ],
+    srcs: [
+        "vts/VtsHalGraphicsMapperStableC_TargetTest.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder_ndk",
+        "libbase",
+        "libsync",
+        "libvndksupport",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+        "libgralloctypes",
+        "libgtest",
+    ],
+    header_libs: [
+        "libimapper_stablec",
+        "libimapper_providerutils",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/graphics/mapper/stable-c/README.md b/graphics/mapper/stable-c/README.md
new file mode 100644
index 0000000..0b9b499
--- /dev/null
+++ b/graphics/mapper/stable-c/README.md
@@ -0,0 +1,109 @@
+# IMapper "stable-c" HAL
+
+Starting with gralloc version 5, IMapper is now exposed as a C API instead of through HIDL or AIDL.
+This is due to HIDL being deprecated, and AIDL not wanting to support a pass-through mode & pointers
+for just a couple of clients such as IMapper. So instead a stable C API is used to fill this gap.
+
+## Implementing
+
+To provide an implementation a library implementing the AIMapper API interface should be provided
+in `/vendor/lib[64]/hw/mapper.<imapper_suffix>.so`. The `<imapper_suffix>` should be specified
+as the `<instance>` in the VINTF manifest `<interface>` section. For example:
+```xml
+<manifest version="1.0" type="device">
+    <hal format="native">
+        <name>mapper</name>
+        <version>5.0</version>
+        <interface>
+            <instance>minigbm</instance>
+        </interface>
+    </hal>
+</manifest>
+```
+defines that the IMapper 5.0 library is provided by `/vendor/lib[64]/hw/mapper.minigbm.so`.
+
+This library must export the following `extern "C"` symbols:
+
+### `ANDROID_HAL_STABLEC_VERSION`
+
+This is a uint32_t that should simply be set to the exported AIMapper version. For example:
+```c++
+extern "C" uint32_t ANDROID_HAL_STABLEC_VERSION = AIMAPPER_VERSION_5;
+```
+
+### `AIMapper_loadIMapper`
+
+This is what should actually load the HAL interface. The full type signature is
+```c++
+extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation)
+```
+
+See `include/android/hardware/graphics/mapper/IMapper.h` for complete documentation on what
+this function must return.
+
+To make it easier to implement this C API, a header-only helper library is provided called
+`libimapper_providerutils`. This library handles mapping from the C API struct to a C++ class
+as well as provides helpers for encoding & decoding metadata, largely replacing the role that
+`libgralloctypes` filled with IMapper 4.
+
+To use this library, create a class that extends from `IMapperV5Impl` and use `IMapperProvider` to
+implement `AIMapper_loadIMapper`:
+
+```c++
+// The IMapper interface itself
+#include <android/hardware/graphics/mapper/IMapper.h>
+// Helpers for reading & writing metadata
+#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
+// Helper for providing the implementation interface
+#include <android/hardware/graphics/mapper/utils/IMapperProvider.h>
+
+// Define an IMapperV5 implementation
+class CrosGrallocMapperV5 final : public vendor::mapper::IMapperV5Impl {
+    // Override all the methods of IMapperV5Impl
+      AIMapper_Error importBuffer(const native_handle_t* _Nonnull handle,
+                              buffer_handle_t _Nullable* _Nonnull outBufferHandle) override;
+      [etc...]
+};
+
+// Expose the required C symbols
+
+extern "C" uint32_t ANDROID_HAL_STABLEC_VERSION = AIMAPPER_VERSION_5;
+
+extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
+    // Define an IMapperProvider for our V5 implementation
+    static vendor::mapper::IMapperProvider<CrosGrallocMapperV5> provider;
+    return provider.load(outImplementation);
+}
+```
+
+A complete example, including using IMapperMetadataTypes, can be found in the cuttlefish
+implementation in `//external/minigbm/cros_gralloc/mapper_stablec`
+
+### Testing
+
+As with HIDL & AIDL HALs, a VTS test is provided to validate the implementation. It is found in the
+`vts` folder and may be run using `$ atest VtsHalGraphicsMapperStableC_TargetTest`
+
+## Using
+
+It is strongly recommended that clients use either the `AHardwareBuffer` (preferred) or
+`GraphicBufferMapper` (from libui) APIs to use the mapper HAL rather than attempting to use
+`AIMapper` directly.
+
+## Version changes
+
+### Version 5
+
+* Initial introduction of this HAL interface
+* Largely feature-equivalent to IMapper4
+* Requires allocator-V2
+* Removes `BufferDescriptorInfo`;
+* IsSupported has moved to IAllocator
+* Removes `validateBufferSize`, validation is instead handled by clients using metadata queries
+* Getting the following StandardMetadataType is now mandatory:
+  * STRIDE
+* Setting the following StandardMetadataTypes is now mandatory:
+  * DATASPACE
+  * SMPTE2086
+  * CTA861_3
+  * BLEND_MODE
diff --git a/graphics/mapper/stable-c/imapper.map.txt b/graphics/mapper/stable-c/imapper.map.txt
new file mode 100644
index 0000000..43abd33
--- /dev/null
+++ b/graphics/mapper/stable-c/imapper.map.txt
@@ -0,0 +1,4 @@
+LIBIMAPPER { # introduced=UpsideDownCake
+  global:
+    AIMapper_loadIMapper;
+}
diff --git a/graphics/mapper/stable-c/imapper5_abicheck.cpp b/graphics/mapper/stable-c/imapper5_abicheck.cpp
new file mode 100644
index 0000000..92f7198
--- /dev/null
+++ b/graphics/mapper/stable-c/imapper5_abicheck.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/graphics/mapper/IMapper.h>
+
+AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
+    static AIMapper mapper = {AIMAPPER_VERSION_5, {}};
+    *outImplementation = &mapper;
+    return AIMAPPER_ERROR_NONE;
+}
\ No newline at end of file
diff --git a/graphics/mapper/stable-c/implutils/impltests.cpp b/graphics/mapper/stable-c/implutils/impltests.cpp
new file mode 100644
index 0000000..01a1db9
--- /dev/null
+++ b/graphics/mapper/stable-c/implutils/impltests.cpp
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
+#include <android/hardware/graphics/mapper/utils/IMapperProvider.h>
+#include <drm/drm_fourcc.h>
+#include <gralloctypes/Gralloc4.h>
+#include <span>
+#include <vector>
+
+using namespace ::android;
+using namespace ::android::hardware::graphics::mapper;
+using namespace ::aidl::android::hardware::graphics::common;
+namespace gralloc4 = ::android::gralloc4;
+using ::android::hardware::hidl_vec;
+
+// These tests are primarily interested in hitting all the different *types* that can be
+// serialized/deserialized than in exhaustively testing all the StandardMetadataTypes.
+// Exhaustive testing of the actual metadata types is relegated for IMapper's VTS suite
+// where meaning & correctness of values are more narrowly defined (eg, read-only values)
+
+static constexpr auto HeaderSize = 69;
+
+static std::span<uint8_t> SkipHeader(std::vector<uint8_t>& buffer) {
+    return std::span<uint8_t>(buffer).subspan(HeaderSize);
+}
+
+static std::vector<PlaneLayout> fakePlaneLayouts() {
+    PlaneLayout myPlaneLayout;
+    myPlaneLayout.offsetInBytes = 10;
+    myPlaneLayout.sampleIncrementInBits = 11;
+    myPlaneLayout.strideInBytes = 12;
+    myPlaneLayout.widthInSamples = 13;
+    myPlaneLayout.heightInSamples = 14;
+    myPlaneLayout.totalSizeInBytes = 15;
+    myPlaneLayout.horizontalSubsampling = 16;
+    myPlaneLayout.verticalSubsampling = 17;
+
+    myPlaneLayout.components.resize(3);
+    for (int i = 0; i < myPlaneLayout.components.size(); i++) {
+        auto& it = myPlaneLayout.components[i];
+        it.type = ExtendableType{"Plane ID", 40 + i};
+        it.offsetInBits = 20 + i;
+        it.sizeInBits = 30 + i;
+    }
+
+    return std::vector<PlaneLayout>{myPlaneLayout, PlaneLayout{}};
+}
+
+TEST(Metadata, setGetBufferId) {
+    using BufferId = StandardMetadata<StandardMetadataType::BUFFER_ID>::value;
+
+    std::vector<uint8_t> buffer(10000, 0);
+    int64_t* payload = reinterpret_cast<int64_t*>(SkipHeader(buffer).data());
+    *payload = 42;
+
+    EXPECT_EQ(8 + HeaderSize, BufferId::encode(18, buffer.data(), 0));
+    EXPECT_EQ(42, *payload);
+    EXPECT_EQ(8 + HeaderSize, BufferId::encode(18, buffer.data(), buffer.size()));
+    EXPECT_EQ(18, *payload);
+    EXPECT_FALSE(BufferId::decode(buffer.data(), 0));
+    auto read = BufferId::decode(buffer.data(), buffer.size());
+    EXPECT_TRUE(read.has_value());
+    EXPECT_EQ(18, read.value_or(0));
+}
+
+TEST(Metadata, setGetDataspace) {
+    using DataspaceValue = StandardMetadata<StandardMetadataType::DATASPACE>::value;
+    using intType = std::underlying_type_t<Dataspace>;
+    std::vector<uint8_t> buffer(10000, 0);
+    auto data = SkipHeader(buffer);
+
+    EXPECT_EQ(4 + HeaderSize, DataspaceValue::encode(Dataspace::BT2020, buffer.data(), 0));
+    EXPECT_EQ(0, *reinterpret_cast<intType*>(data.data()));
+    EXPECT_EQ(4 + HeaderSize,
+              DataspaceValue::encode(Dataspace::BT2020, buffer.data(), buffer.size()));
+    EXPECT_EQ(static_cast<intType>(Dataspace::BT2020), *reinterpret_cast<intType*>(data.data()));
+    EXPECT_FALSE(DataspaceValue::decode(buffer.data(), 0));
+    auto read = DataspaceValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    EXPECT_EQ(Dataspace::BT2020, *read);
+}
+
+TEST(Metadata, setGetValidName) {
+    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
+
+    std::vector<uint8_t> buffer(10000, 'a');
+
+    // len("Hello") + sizeof(int64)
+    constexpr int expectedSize = 5 + sizeof(int64_t) + HeaderSize;
+    EXPECT_EQ(expectedSize, NameValue::encode("Hello", buffer.data(), buffer.size()));
+    EXPECT_EQ(5, *reinterpret_cast<int64_t*>(SkipHeader(buffer).data()));
+    // Verify didn't write past the end of the desired size
+    EXPECT_EQ('a', buffer[expectedSize]);
+
+    auto readValue = NameValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(readValue.has_value());
+    EXPECT_EQ(5, readValue->length());
+    EXPECT_EQ("Hello", *readValue);
+}
+
+TEST(Metadata, setGetInvalidName) {
+    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
+
+    std::vector<uint8_t> buffer;
+    buffer.resize(12 + HeaderSize, 'a');
+    buffer[buffer.size() - 1] = '\0';
+
+    // len("This is a long string") + sizeof(int64)
+    constexpr int expectedSize = 21 + sizeof(int64_t) + HeaderSize;
+    EXPECT_EQ(expectedSize,
+              NameValue::encode("This is a long string", buffer.data(), buffer.size()));
+    EXPECT_EQ(21, *reinterpret_cast<int64_t*>(SkipHeader(buffer).data()));
+
+    auto readValue = NameValue::decode(buffer.data(), buffer.size());
+    EXPECT_FALSE(readValue.has_value());
+    readValue = NameValue::decode(buffer.data(), 0);
+    ASSERT_FALSE(readValue.has_value());
+}
+
+TEST(Metadata, wouldOverflowName) {
+    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
+    std::vector<uint8_t> buffer(10000, 0);
+
+    // int_max + sizeof(int64) overflows int32
+    std::string_view bad_string{"badbeef", std::numeric_limits<int32_t>::max()};
+    EXPECT_EQ(-AIMAPPER_ERROR_BAD_VALUE,
+              NameValue::encode(bad_string, buffer.data(), buffer.size()));
+
+    // check barely overflows
+    bad_string = std::string_view{"badbeef", std::numeric_limits<int32_t>::max() - 7};
+    EXPECT_EQ(-AIMAPPER_ERROR_BAD_VALUE,
+              NameValue::encode(bad_string, buffer.data(), buffer.size()));
+}
+
+TEST(Metadata, setGetMismatchedWidthHight) {
+    // Validates that the header is properly validated on decode
+    using WidthValue = StandardMetadata<StandardMetadataType::WIDTH>::value;
+    using HeightValue = StandardMetadata<StandardMetadataType::HEIGHT>::value;
+    std::vector<uint8_t> buffer(10000, 0);
+
+    EXPECT_EQ(8 + HeaderSize, WidthValue::encode(100, buffer.data(), buffer.size()));
+    EXPECT_EQ(100, *reinterpret_cast<uint64_t*>(SkipHeader(buffer).data()));
+    auto read = WidthValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    EXPECT_EQ(100, *read);
+    read = HeightValue::decode(buffer.data(), buffer.size());
+    EXPECT_FALSE(read.has_value());
+}
+
+TEST(Metadata, setGetCompression) {
+    using CompressionValue = StandardMetadata<StandardMetadataType::COMPRESSION>::value;
+    ExtendableType myCompression{"bestest_compression_ever", 42};
+    std::vector<uint8_t> buffer(10000, 0);
+    const int expectedSize =
+            myCompression.name.length() + sizeof(int64_t) + sizeof(int64_t) + HeaderSize;
+    EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), 0));
+    EXPECT_EQ(0, buffer[0]);
+    EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), buffer.size()));
+    EXPECT_EQ(myCompression.name.length(), *reinterpret_cast<int64_t*>(SkipHeader(buffer).data()));
+    EXPECT_FALSE(CompressionValue::decode(buffer.data(), 0).has_value());
+    auto read = CompressionValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    EXPECT_EQ(myCompression, read.value());
+}
+
+TEST(Metadata, setGetPlaneLayout) {
+    using PlaneLayoutValue = StandardMetadata<StandardMetadataType::PLANE_LAYOUTS>::value;
+
+    std::vector<PlaneLayout> layouts = fakePlaneLayouts();
+
+    std::vector<uint8_t> buffer(10000, 0);
+    constexpr int componentSize = 8 + (4 * sizeof(int64_t));
+    constexpr int firstLayoutSize = (8 + 1) * sizeof(int64_t) + (3 * componentSize);
+    constexpr int secondLayoutSize = (8 + 1) * sizeof(int64_t);
+    constexpr int expectedSize = firstLayoutSize + secondLayoutSize + sizeof(int64_t) + HeaderSize;
+    EXPECT_EQ(expectedSize, PlaneLayoutValue::encode(layouts, buffer.data(), 0));
+    EXPECT_EQ(0, buffer[0]);
+    EXPECT_EQ(expectedSize, PlaneLayoutValue::encode(layouts, buffer.data(), buffer.size()));
+    int64_t* payload = reinterpret_cast<int64_t*>(SkipHeader(buffer).data());
+    EXPECT_EQ(3, payload[1]);
+    EXPECT_EQ(8, payload[2]);
+    EXPECT_EQ(40, payload[4]);
+    EXPECT_EQ(31, payload[11]);
+    EXPECT_EQ(22, payload[15]);
+    EXPECT_EQ(10, payload[17]);
+    EXPECT_EQ(11, payload[18]);
+    EXPECT_FALSE(PlaneLayoutValue::decode(buffer.data(), 0).has_value());
+    auto read = PlaneLayoutValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    EXPECT_EQ(layouts, *read);
+}
+
+TEST(Metadata, setGetRects) {
+    using RectsValue = StandardMetadata<StandardMetadataType::CROP>::value;
+    std::vector<uint8_t> buffer(10000, 0);
+    std::vector<Rect> cropRects{2};
+    cropRects[0] = Rect{10, 11, 12, 13};
+    cropRects[1] = Rect{20, 21, 22, 23};
+
+    constexpr int expectedSize = sizeof(int64_t) + (8 * sizeof(int32_t)) + HeaderSize;
+    EXPECT_EQ(expectedSize, RectsValue::encode(cropRects, buffer.data(), buffer.size()));
+    EXPECT_EQ(2, reinterpret_cast<int64_t*>(SkipHeader(buffer).data())[0]);
+    EXPECT_EQ(10, reinterpret_cast<int32_t*>(SkipHeader(buffer).data())[2]);
+    auto read = RectsValue::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    EXPECT_EQ(cropRects.size(), read->size());
+    EXPECT_EQ(cropRects, *read);
+}
+
+TEST(Metadata, setGetSmpte2086) {
+    using Smpte2086Value = StandardMetadata<StandardMetadataType::SMPTE2086>::value;
+    Smpte2086 source;
+    source.minLuminance = 12.335f;
+    source.maxLuminance = 452.889f;
+    source.whitePoint = XyColor{-6.f, -9.f};
+    source.primaryRed = XyColor{.1f, .2f};
+    source.primaryGreen = XyColor{.3f, .4f};
+    source.primaryBlue = XyColor{.5f, .6f};
+
+    constexpr int expectedSize = 10 * sizeof(float) + HeaderSize;
+    std::vector<uint8_t> buffer(10000, 0);
+    EXPECT_EQ(expectedSize, Smpte2086Value::encode(source, buffer.data(), buffer.size()));
+    auto read = Smpte2086Value::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    ASSERT_TRUE(read->has_value());
+    EXPECT_EQ(source, read->value());
+
+    // A valid encoding of a nullopt
+    read = Smpte2086Value::decode(nullptr, 0);
+    ASSERT_TRUE(read.has_value());
+    EXPECT_FALSE(read->has_value());
+}
+
+TEST(Metadata, setGetCta861_3) {
+    using Cta861_3Value = StandardMetadata<StandardMetadataType::CTA861_3>::value;
+    Cta861_3 source;
+    source.maxFrameAverageLightLevel = 244.55f;
+    source.maxContentLightLevel = 202.202f;
+
+    constexpr int expectedSize = 2 * sizeof(float) + HeaderSize;
+    std::vector<uint8_t> buffer(10000, 0);
+    EXPECT_EQ(expectedSize, Cta861_3Value::encode(source, buffer.data(), buffer.size()));
+    auto read = Cta861_3Value::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    ASSERT_TRUE(read->has_value());
+    EXPECT_EQ(source, read->value());
+
+    // A valid encoding of a nullopt
+    read = Cta861_3Value::decode(nullptr, 0);
+    ASSERT_TRUE(read.has_value());
+    EXPECT_FALSE(read->has_value());
+}
+
+TEST(Metadata, setGetSmpte2094_10) {
+    using SMPTE2094_10Value = StandardMetadata<StandardMetadataType::SMPTE2094_10>::value;
+
+    std::vector<uint8_t> buffer(10000, 0);
+    EXPECT_EQ(0, SMPTE2094_10Value::encode(std::nullopt, buffer.data(), buffer.size()));
+    auto read = SMPTE2094_10Value::decode(buffer.data(), 0);
+    ASSERT_TRUE(read.has_value());
+    EXPECT_FALSE(read->has_value());
+
+    const std::vector<uint8_t> emptyBuffer;
+    EXPECT_EQ(sizeof(int64_t) + HeaderSize,
+              SMPTE2094_10Value::encode(emptyBuffer, buffer.data(), buffer.size()));
+    read = SMPTE2094_10Value::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    ASSERT_TRUE(read->has_value());
+    EXPECT_EQ(0, read->value().size());
+
+    const std::vector<uint8_t> simpleBuffer{0, 1, 2, 3, 4, 5};
+    EXPECT_EQ(sizeof(int64_t) + 6 + HeaderSize,
+              SMPTE2094_10Value::encode(simpleBuffer, buffer.data(), buffer.size()));
+    read = SMPTE2094_10Value::decode(buffer.data(), buffer.size());
+    ASSERT_TRUE(read.has_value());
+    ASSERT_TRUE(read->has_value());
+    EXPECT_EQ(6, read->value().size());
+    EXPECT_EQ(simpleBuffer, read->value());
+}
+
+TEST(MetadataProvider, bufferId) {
+    using BufferId = StandardMetadata<StandardMetadataType::BUFFER_ID>::value;
+    std::vector<uint8_t> buffer(10000, 0);
+    int result = provideStandardMetadata(StandardMetadataType::BUFFER_ID, buffer.data(),
+                                         buffer.size(), []<StandardMetadataType T>(auto&& provide) {
+                                             if constexpr (T == StandardMetadataType::BUFFER_ID) {
+                                                 return provide(42);
+                                             }
+                                             return 0;
+                                         });
+
+    EXPECT_EQ(8 + HeaderSize, result);
+    auto read = BufferId::decode(buffer.data(), buffer.size());
+    EXPECT_EQ(42, read.value_or(0));
+}
+
+TEST(MetadataProvider, allJumpsWork) {
+    const auto& values = ndk::internal::enum_values<StandardMetadataType>;
+    auto get = [](StandardMetadataType type) -> int {
+        return provideStandardMetadata(type, nullptr, 0, []<StandardMetadataType T>(auto&&) {
+            return static_cast<int>(T) + 100;
+        });
+    };
+
+    for (auto& type : values) {
+        const int expected = type == StandardMetadataType::INVALID ? -AIMAPPER_ERROR_UNSUPPORTED
+                                                                   : static_cast<int>(type) + 100;
+        EXPECT_EQ(expected, get(type));
+    }
+}
+
+TEST(MetadataProvider, invalid) {
+    int result = provideStandardMetadata(StandardMetadataType::INVALID, nullptr, 0,
+                                         []<StandardMetadataType T>(auto&&) { return 10; });
+
+    EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, result);
+}
+
+TEST(MetadataProvider, outOfBounds) {
+    int result = provideStandardMetadata(static_cast<StandardMetadataType>(-1), nullptr, 0,
+                                         []<StandardMetadataType T>(auto&&) { return 10; });
+    EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, result) << "-1 should have resulted in UNSUPPORTED";
+
+    result = provideStandardMetadata(static_cast<StandardMetadataType>(100), nullptr, 0,
+                                     []<StandardMetadataType T>(auto&&) { return 10; });
+    EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, result)
+            << "100 (out of range) should have resulted in UNSUPPORTED";
+}
+
+template <StandardMetadataType T>
+std::vector<uint8_t> encode(const typename StandardMetadata<T>::value_type& value) {
+    using Value = typename StandardMetadata<T>::value;
+
+    int desiredSize = Value::encode(value, nullptr, 0);
+    EXPECT_GE(desiredSize, 0);
+    std::vector<uint8_t> buffer;
+    buffer.resize(desiredSize);
+    EXPECT_EQ(desiredSize, Value::encode(value, buffer.data(), buffer.size()));
+    return buffer;
+}
+
+TEST(MetadataGralloc4Interop, BufferId) {
+    auto mpbuf = encode<StandardMetadataType::BUFFER_ID>(42);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeBufferId(42, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Name) {
+    auto mpbuf = encode<StandardMetadataType::NAME>("Hello, Interop!");
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeName("Hello, Interop!", &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Width) {
+    auto mpbuf = encode<StandardMetadataType::WIDTH>(128);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeWidth(128, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Height) {
+    auto mpbuf = encode<StandardMetadataType::HEIGHT>(64);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeHeight(64, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, LayerCount) {
+    auto mpbuf = encode<StandardMetadataType::LAYER_COUNT>(3);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeLayerCount(3, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, PixelFormatRequested) {
+    auto mpbuf = encode<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(PixelFormat::RGBX_8888);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatRequested(
+                                hardware::graphics::common::V1_2::PixelFormat::RGBX_8888, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, PixelFormatFourcc) {
+    auto mpbuf = encode<StandardMetadataType::PIXEL_FORMAT_FOURCC>(DRM_FORMAT_ABGR8888);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatFourCC(DRM_FORMAT_ABGR8888, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, PixelFormatModifier) {
+    auto mpbuf = encode<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(123456);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatModifier(123456, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Usage) {
+    auto mpbuf = encode<StandardMetadataType::USAGE>(BufferUsage::COMPOSER_OVERLAY);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR,
+              gralloc4::encodeUsage(
+                      static_cast<uint64_t>(
+                              hardware::graphics::common::V1_2::BufferUsage::COMPOSER_OVERLAY),
+                      &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, AllocationSize) {
+    auto mpbuf = encode<StandardMetadataType::ALLOCATION_SIZE>(10200);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeAllocationSize(10200, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, ProtectedContent) {
+    auto mpbuf = encode<StandardMetadataType::PROTECTED_CONTENT>(1);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeProtectedContent(1, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Compression) {
+    auto mpbuf = encode<StandardMetadataType::COMPRESSION>(
+            gralloc4::Compression_DisplayStreamCompression);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR,
+              gralloc4::encodeCompression(gralloc4::Compression_DisplayStreamCompression, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Interlaced) {
+    auto mpbuf = encode<StandardMetadataType::INTERLACED>(gralloc4::Interlaced_TopBottom);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeInterlaced(gralloc4::Interlaced_TopBottom, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, ChromeSitting) {
+    auto mpbuf =
+            encode<StandardMetadataType::CHROMA_SITING>(gralloc4::ChromaSiting_SitedInterstitial);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR,
+              gralloc4::encodeChromaSiting(gralloc4::ChromaSiting_SitedInterstitial, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, PlaneLayouts) {
+    auto mpbuf = encode<StandardMetadataType::PLANE_LAYOUTS>(fakePlaneLayouts());
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodePlaneLayouts(fakePlaneLayouts(), &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Crop) {
+    std::vector<Rect> cropRects{Rect{10, 11, 12, 13}, Rect{20, 21, 22, 23}};
+    auto mpbuf = encode<StandardMetadataType::CROP>(cropRects);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeCrop(cropRects, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Dataspace) {
+    auto mpbuf = encode<StandardMetadataType::DATASPACE>(Dataspace::DISPLAY_P3);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeDataspace(Dataspace::DISPLAY_P3, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, BlendMode) {
+    auto mpbuf = encode<StandardMetadataType::BLEND_MODE>(BlendMode::PREMULTIPLIED);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeBlendMode(BlendMode::PREMULTIPLIED, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Smpte2086) {
+    Smpte2086 hdrdata{XyColor{.1f, .2f}, XyColor{.3f, .4f}, XyColor{.5f, .6f},
+                      XyColor{.7f, .8f}, 452.889f,          12.335f};
+
+    auto mpbuf = encode<StandardMetadataType::SMPTE2086>(hdrdata);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2086(hdrdata, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Cta861_3) {
+    Cta861_3 hdrdata{302.202f, 244.55f};
+    auto mpbuf = encode<StandardMetadataType::CTA861_3>(hdrdata);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeCta861_3(hdrdata, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Smpte2094_10) {
+    auto mpbuf = encode<StandardMetadataType::SMPTE2094_10>(std::nullopt);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_10(std::nullopt, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+
+    std::vector<uint8_t> hdrdata{1, 2, 3, 4, 5, 6};
+    mpbuf = encode<StandardMetadataType::SMPTE2094_10>(hdrdata);
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_10(hdrdata, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
+
+TEST(MetadataGralloc4Interop, Smpte2094_40) {
+    auto mpbuf = encode<StandardMetadataType::SMPTE2094_40>(std::nullopt);
+    hidl_vec<uint8_t> g4buf;
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_40(std::nullopt, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+
+    std::vector<uint8_t> hdrdata{1, 2, 3, 4, 5, 6};
+    mpbuf = encode<StandardMetadataType::SMPTE2094_40>(hdrdata);
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_40(hdrdata, &g4buf));
+    EXPECT_EQ(g4buf, mpbuf);
+}
diff --git a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
new file mode 100644
index 0000000..0e6d3dc
--- /dev/null
+++ b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/Cta861_3.h>
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidl/android/hardware/graphics/common/ExtendableType.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayout.h>
+#include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/common/Smpte2086.h>
+#include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
+#include <aidl/android/hardware/graphics/common/XyColor.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+
+#include <cinttypes>
+#include <string_view>
+#include <type_traits>
+#include <vector>
+
+namespace android::hardware::graphics::mapper {
+
+using ::aidl::android::hardware::graphics::common::BlendMode;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::aidl::android::hardware::graphics::common::Cta861_3;
+using ::aidl::android::hardware::graphics::common::Dataspace;
+using ::aidl::android::hardware::graphics::common::ExtendableType;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+using ::aidl::android::hardware::graphics::common::PlaneLayout;
+using ::aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using ::aidl::android::hardware::graphics::common::Rect;
+using ::aidl::android::hardware::graphics::common::Smpte2086;
+using ::aidl::android::hardware::graphics::common::StandardMetadataType;
+using ::aidl::android::hardware::graphics::common::XyColor;
+
+class MetadataWriter {
+  private:
+    uint8_t* _Nonnull mDest;
+    size_t mSizeRemaining = 0;
+    int32_t mDesiredSize = 0;
+
+    void* _Nullable reserve(size_t sizeToWrite) {
+        if (mDesiredSize < 0) {
+            // Error state
+            return nullptr;
+        }
+        if (__builtin_add_overflow(mDesiredSize, sizeToWrite, &mDesiredSize)) {
+            // Overflowed, abort writing any further data
+            mDesiredSize = -AIMAPPER_ERROR_BAD_VALUE;
+            mSizeRemaining = 0;
+            return nullptr;
+        }
+        if (sizeToWrite > mSizeRemaining) {
+            mSizeRemaining = 0;
+            return nullptr;
+        } else {
+            mSizeRemaining -= sizeToWrite;
+            uint8_t* whereToWrite = mDest;
+            mDest += sizeToWrite;
+            return whereToWrite;
+        }
+    }
+
+  public:
+    explicit MetadataWriter(void* _Nullable destBuffer, size_t destBufferSize)
+        : mDest(reinterpret_cast<uint8_t*>(destBuffer)), mSizeRemaining(destBufferSize) {}
+
+    [[nodiscard]] int32_t desiredSize() const { return mDesiredSize; }
+
+    template <typename HEADER>
+    MetadataWriter& writeHeader() {
+        return write(HEADER::name).template write<int64_t>(HEADER::value);
+    }
+
+    template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
+    MetadataWriter& write(T value) {
+        auto sizeToWrite = sizeof(T);
+        if (void* dest = reserve(sizeToWrite)) {
+            memcpy(dest, &value, sizeToWrite);
+        }
+        return *this;
+    }
+
+    MetadataWriter& write(float value) {
+        auto sizeToWrite = sizeof(float);
+        if (void* dest = reserve(sizeToWrite)) {
+            memcpy(dest, &value, sizeToWrite);
+        }
+        return *this;
+    }
+
+    MetadataWriter& write(const std::string_view& value) {
+        auto sizeToWrite = value.length();
+        write<int64_t>(sizeToWrite);
+        if (void* dest = reserve(sizeToWrite)) {
+            memcpy(dest, value.data(), sizeToWrite);
+        }
+        return *this;
+    }
+
+    MetadataWriter& write(const std::vector<uint8_t>& value) {
+        auto sizeToWrite = value.size();
+        write<int64_t>(sizeToWrite);
+        if (void* dest = reserve(sizeToWrite)) {
+            memcpy(dest, value.data(), sizeToWrite);
+        }
+        return *this;
+    }
+
+    MetadataWriter& write(const ExtendableType& value) {
+        return write(value.name).write(value.value);
+    }
+
+    MetadataWriter& write(const XyColor& value) { return write(value.x).write(value.y); }
+};
+
+class MetadataReader {
+  private:
+    const uint8_t* _Nonnull mSrc;
+    size_t mSizeRemaining = 0;
+    bool mOk = true;
+
+    const void* _Nullable advance(size_t size) {
+        if (mOk && mSizeRemaining >= size) {
+            const void* buf = mSrc;
+            mSrc += size;
+            mSizeRemaining -= size;
+            return buf;
+        }
+        mOk = false;
+        return nullptr;
+    }
+
+  public:
+    explicit MetadataReader(const void* _Nonnull metadata, size_t metadataSize)
+        : mSrc(reinterpret_cast<const uint8_t*>(metadata)), mSizeRemaining(metadataSize) {}
+
+    [[nodiscard]] size_t remaining() const { return mSizeRemaining; }
+    [[nodiscard]] bool ok() const { return mOk; }
+
+    template <typename HEADER>
+    MetadataReader& checkHeader() {
+        if (HEADER::name != readString()) {
+            mOk = false;
+        }
+        auto value = readInt<int64_t>();
+        if (!value || *value != HEADER::value) {
+            mOk = false;
+        }
+        return *this;
+    }
+
+    template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
+    MetadataReader& read(T& dest) {
+        if (const void* src = advance(sizeof(T))) {
+            memcpy(&dest, src, sizeof(T));
+        }
+        return *this;
+    }
+
+    MetadataReader& read(float& dest) {
+        if (const void* src = advance(sizeof(float))) {
+            memcpy(&dest, src, sizeof(float));
+        }
+        return *this;
+    }
+
+    MetadataReader& read(std::string& dest) {
+        dest = readString();
+        return *this;
+    }
+
+    MetadataReader& read(ExtendableType& dest) {
+        dest.name = readString();
+        read(dest.value);
+        return *this;
+    }
+
+    MetadataReader& read(XyColor& dest) {
+        read(dest.x);
+        read(dest.y);
+        return *this;
+    }
+
+    template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
+    [[nodiscard]] std::optional<T> readInt() {
+        auto sizeToRead = sizeof(T);
+        if (const void* src = advance(sizeof(T))) {
+            T ret;
+            memcpy(&ret, src, sizeToRead);
+            return ret;
+        }
+        return std::nullopt;
+    }
+
+    [[nodiscard]] std::string_view readString() {
+        auto lengthOpt = readInt<int64_t>();
+        if (!lengthOpt) {
+            return std::string_view{};
+        }
+        size_t length = lengthOpt.value();
+        if (const void* src = advance(length)) {
+            return std::string_view{reinterpret_cast<const char*>(src), length};
+        }
+        return std::string_view{};
+    }
+
+    [[nodiscard]] std::optional<ExtendableType> readExtendable() {
+        ExtendableType ret;
+        ret.name = readString();
+        auto value = readInt<int64_t>();
+        if (value) {
+            ret.value = value.value();
+            return ret;
+        } else {
+            return std::nullopt;
+        }
+    }
+
+    [[nodiscard]] std::vector<uint8_t> readBuffer() {
+        std::vector<uint8_t> ret;
+        size_t length = readInt<int64_t>().value_or(0);
+        if (const void* src = advance(length)) {
+            ret.resize(length);
+            memcpy(ret.data(), src, length);
+        }
+        return ret;
+    }
+};
+
+template <typename HEADER, typename T, class Enable = void>
+struct MetadataValue {};
+
+template <typename HEADER, typename T>
+struct MetadataValue<HEADER, T, std::enable_if_t<std::is_integral_v<T>>> {
+    [[nodiscard]] static int32_t encode(T value, void* _Nullable destBuffer,
+                                        size_t destBufferSize) {
+        return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
+                .write(value)
+                .desiredSize();
+    }
+
+    [[nodiscard]] static std::optional<T> decode(const void* _Nonnull metadata,
+                                                 size_t metadataSize) {
+        return MetadataReader{metadata, metadataSize}
+                .template checkHeader<HEADER>()
+                .template readInt<T>();
+    }
+};
+
+template <typename HEADER, typename T>
+struct MetadataValue<HEADER, T, std::enable_if_t<std::is_enum_v<T>>> {
+    [[nodiscard]] static int32_t encode(T value, void* _Nullable destBuffer,
+                                        size_t destBufferSize) {
+        return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
+                .write(static_cast<std::underlying_type_t<T>>(value))
+                .desiredSize();
+    }
+
+    [[nodiscard]] static std::optional<T> decode(const void* _Nonnull metadata,
+                                                 size_t metadataSize) {
+        std::underlying_type_t<T> temp;
+        return MetadataReader{metadata, metadataSize}.template checkHeader<HEADER>().read(temp).ok()
+                       ? std::optional<T>(static_cast<T>(temp))
+                       : std::nullopt;
+    }
+};
+
+template <typename HEADER>
+struct MetadataValue<HEADER, std::string> {
+    [[nodiscard]] static int32_t encode(const std::string_view& value, void* _Nullable destBuffer,
+                                        size_t destBufferSize) {
+        return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
+                .write(value)
+                .desiredSize();
+    }
+
+    [[nodiscard]] static std::optional<std::string> decode(const void* _Nonnull metadata,
+                                                           size_t metadataSize) {
+        auto reader = MetadataReader{metadata, metadataSize}.template checkHeader<HEADER>();
+        auto result = reader.readString();
+        return reader.ok() ? std::optional<std::string>{result} : std::nullopt;
+    }
+};
+
+template <typename HEADER>
+struct MetadataValue<HEADER, ExtendableType> {
+    static_assert(sizeof(int64_t) == sizeof(ExtendableType::value));
+
+    [[nodiscard]] static int32_t encode(const ExtendableType& value, void* _Nullable destBuffer,
+                                        size_t destBufferSize) {
+        return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
+                .write(value)
+                .desiredSize();
+    }
+
+    [[nodiscard]] static std::optional<ExtendableType> decode(const void* _Nonnull metadata,
+                                                              size_t metadataSize) {
+        return MetadataReader{metadata, metadataSize}
+                .template checkHeader<HEADER>()
+                .readExtendable();
+    }
+};
+
+template <typename HEADER>
+struct MetadataValue<HEADER, std::vector<PlaneLayout>> {
+    [[nodiscard]] static int32_t encode(const std::vector<PlaneLayout>& values,
+                                        void* _Nullable destBuffer, size_t destBufferSize) {
+        MetadataWriter writer{destBuffer, destBufferSize};
+        writer.template writeHeader<HEADER>();
+        writer.write<int64_t>(values.size());
+        for (const auto& value : values) {
+            writer.write<int64_t>(value.components.size());
+            for (const auto& component : value.components) {
+                writer.write(component.type)
+                        .write<int64_t>(component.offsetInBits)
+                        .write<int64_t>(component.sizeInBits);
+            }
+            writer.write<int64_t>(value.offsetInBytes)
+                    .write<int64_t>(value.sampleIncrementInBits)
+                    .write<int64_t>(value.strideInBytes)
+                    .write<int64_t>(value.widthInSamples)
+                    .write<int64_t>(value.heightInSamples)
+                    .write<int64_t>(value.totalSizeInBytes)
+                    .write<int64_t>(value.horizontalSubsampling)
+                    .write<int64_t>(value.verticalSubsampling);
+        }
+        return writer.desiredSize();
+    }
+
+    using DecodeResult = std::optional<std::vector<PlaneLayout>>;
+    [[nodiscard]] static DecodeResult decode(const void* _Nonnull metadata, size_t metadataSize) {
+        std::vector<PlaneLayout> values;
+        MetadataReader reader{metadata, metadataSize};
+        reader.template checkHeader<HEADER>();
+        auto numPlanes = reader.readInt<int64_t>().value_or(0);
+        values.reserve(numPlanes);
+        for (int i = 0; i < numPlanes && reader.ok(); i++) {
+            PlaneLayout& value = values.emplace_back();
+            auto numPlaneComponents = reader.readInt<int64_t>().value_or(0);
+            value.components.reserve(numPlaneComponents);
+            for (int j = 0; j < numPlaneComponents && reader.ok(); j++) {
+                PlaneLayoutComponent& component = value.components.emplace_back();
+                reader.read(component.type)
+                        .read<int64_t>(component.offsetInBits)
+                        .read<int64_t>(component.sizeInBits);
+            }
+            reader.read<int64_t>(value.offsetInBytes)
+                    .read<int64_t>(value.sampleIncrementInBits)
+                    .read<int64_t>(value.strideInBytes)
+                    .read<int64_t>(value.widthInSamples)
+                    .read<int64_t>(value.heightInSamples)
+                    .read<int64_t>(value.totalSizeInBytes)
+                    .read<int64_t>(value.horizontalSubsampling)
+                    .read<int64_t>(value.verticalSubsampling);
+        }
+        return reader.ok() ? DecodeResult{std::move(values)} : std::nullopt;
+    }
+};
+
+template <typename HEADER>
+struct MetadataValue<HEADER, std::vector<Rect>> {
+    [[nodiscard]] static int32_t encode(const std::vector<Rect>& value, void* _Nullable destBuffer,
+                                        size_t destBufferSize) {
+        MetadataWriter writer{destBuffer, destBufferSize};
+        writer.template writeHeader<HEADER>();
+        writer.write<int64_t>(value.size());
+        for (auto& rect : value) {
+            writer.write<int32_t>(rect.left)
+                    .write<int32_t>(rect.top)
+                    .write<int32_t>(rect.right)
+                    .write<int32_t>(rect.bottom);
+        }
+        return writer.desiredSize();
+    }
+
+    using DecodeResult = std::optional<std::vector<Rect>>;
+    [[nodiscard]] static DecodeResult decode(const void* _Nonnull metadata, size_t metadataSize) {
+        MetadataReader reader{metadata, metadataSize};
+        reader.template checkHeader<HEADER>();
+        std::vector<Rect> value;
+        auto numRects = reader.readInt<int64_t>().value_or(0);
+        value.reserve(numRects);
+        for (int i = 0; i < numRects && reader.ok(); i++) {
+            Rect& rect = value.emplace_back();
+            reader.read<int32_t>(rect.left)
+                    .read<int32_t>(rect.top)
+                    .read<int32_t>(rect.right)
+                    .read<int32_t>(rect.bottom);
+        }
+        return reader.ok() ? DecodeResult{std::move(value)} : std::nullopt;
+    }
+};
+
+template <typename HEADER>
+struct MetadataValue<HEADER, std::optional<Smpte2086>> {
+    [[nodiscard]] static int32_t encode(const std::optional<Smpte2086>& optValue,
+                                        void* _Nullable destBuffer, size_t destBufferSize) {
+        if (optValue.has_value()) {
+            const auto& value = *optValue;
+            return MetadataWriter{destBuffer, destBufferSize}
+                    .template writeHeader<HEADER>()
+                    .write(value.primaryRed)
+                    .write(value.primaryGreen)
+                    .write(value.primaryBlue)
+                    .write(value.whitePoint)
+                    .write(value.maxLuminance)
+                    .write(value.minLuminance)
+                    .desiredSize();
+        } else {
+            return 0;
+        }
+    }
+
+    // Double optional because the value type itself is an optional<>
+    using DecodeResult = std::optional<std::optional<Smpte2086>>;
+    [[nodiscard]] static DecodeResult decode(const void* _Nullable metadata, size_t metadataSize) {
+        std::optional<Smpte2086> optValue{std::nullopt};
+        if (metadataSize > 0) {
+            Smpte2086 value;
+            MetadataReader reader{metadata, metadataSize};
+            reader.template checkHeader<HEADER>();
+            reader.read(value.primaryRed)
+                    .read(value.primaryGreen)
+                    .read(value.primaryBlue)
+                    .read(value.whitePoint)
+                    .read(value.maxLuminance)
+                    .read(value.minLuminance);
+            if (reader.ok()) {
+                optValue = std::move(value);
+            } else {
+                return std::nullopt;
+            }
+        }
+        return DecodeResult{std::move(optValue)};
+    }
+};
+
+template <typename HEADER>
+struct MetadataValue<HEADER, std::optional<Cta861_3>> {
+    [[nodiscard]] static int32_t encode(const std::optional<Cta861_3>& optValue,
+                                        void* _Nullable destBuffer, size_t destBufferSize) {
+        if (optValue.has_value()) {
+            const auto& value = *optValue;
+            return MetadataWriter{destBuffer, destBufferSize}
+                    .template writeHeader<HEADER>()
+                    .write(value.maxContentLightLevel)
+                    .write(value.maxFrameAverageLightLevel)
+                    .desiredSize();
+        } else {
+            return 0;
+        }
+    }
+
+    // Double optional because the value type itself is an optional<>
+    using DecodeResult = std::optional<std::optional<Cta861_3>>;
+    [[nodiscard]] static DecodeResult decode(const void* _Nullable metadata, size_t metadataSize) {
+        std::optional<Cta861_3> optValue{std::nullopt};
+        if (metadataSize > 0) {
+            MetadataReader reader{metadata, metadataSize};
+            reader.template checkHeader<HEADER>();
+            Cta861_3 value;
+            reader.read(value.maxContentLightLevel).read(value.maxFrameAverageLightLevel);
+            if (reader.ok()) {
+                optValue = std::move(value);
+            } else {
+                return std::nullopt;
+            }
+        }
+        return DecodeResult{std::move(optValue)};
+    }
+};
+
+template <typename HEADER>
+struct MetadataValue<HEADER, std::optional<std::vector<uint8_t>>> {
+    [[nodiscard]] static int32_t encode(const std::optional<std::vector<uint8_t>>& value,
+                                        void* _Nullable destBuffer, size_t destBufferSize) {
+        if (!value.has_value()) {
+            return 0;
+        }
+        return MetadataWriter{destBuffer, destBufferSize}
+                .template writeHeader<HEADER>()
+                .write(*value)
+                .desiredSize();
+    }
+
+    using DecodeResult = std::optional<std::optional<std::vector<uint8_t>>>;
+    [[nodiscard]] static DecodeResult decode(const void* _Nonnull metadata, size_t metadataSize) {
+        std::optional<std::vector<uint8_t>> optValue;
+        if (metadataSize > 0) {
+            MetadataReader reader{metadata, metadataSize};
+            reader.template checkHeader<HEADER>();
+            auto value = reader.readBuffer();
+            if (reader.ok()) {
+                optValue = std::move(value);
+            } else {
+                return std::nullopt;
+            }
+        }
+        return DecodeResult{std::move(optValue)};
+    }
+};
+
+template <StandardMetadataType>
+struct StandardMetadata {};
+
+#define DEFINE_TYPE(typeName, typeArg)                                                            \
+    template <>                                                                                   \
+    struct StandardMetadata<StandardMetadataType::typeName> {                                     \
+        using value_type = typeArg;                                                               \
+        struct Header {                                                                           \
+            static constexpr auto name = "android.hardware.graphics.common.StandardMetadataType"; \
+            static constexpr auto value = static_cast<int64_t>(StandardMetadataType::typeName);   \
+        };                                                                                        \
+        using value = MetadataValue<Header, value_type>;                                          \
+        static_assert(                                                                            \
+                StandardMetadataType::typeName ==                                                 \
+                        ndk::internal::enum_values<StandardMetadataType>[static_cast<size_t>(     \
+                                StandardMetadataType::typeName)],                                 \
+                "StandardMetadataType must have equivalent value to index");                      \
+    }
+
+DEFINE_TYPE(BUFFER_ID, uint64_t);
+DEFINE_TYPE(NAME, std::string);
+DEFINE_TYPE(WIDTH, uint64_t);
+DEFINE_TYPE(HEIGHT, uint64_t);
+DEFINE_TYPE(LAYER_COUNT, uint64_t);
+DEFINE_TYPE(PIXEL_FORMAT_REQUESTED, PixelFormat);
+DEFINE_TYPE(PIXEL_FORMAT_FOURCC, uint32_t);
+DEFINE_TYPE(PIXEL_FORMAT_MODIFIER, uint64_t);
+DEFINE_TYPE(USAGE, BufferUsage);
+DEFINE_TYPE(ALLOCATION_SIZE, uint64_t);
+DEFINE_TYPE(PROTECTED_CONTENT, uint64_t);
+DEFINE_TYPE(COMPRESSION, ExtendableType);
+DEFINE_TYPE(INTERLACED, ExtendableType);
+DEFINE_TYPE(CHROMA_SITING, ExtendableType);
+DEFINE_TYPE(PLANE_LAYOUTS, std::vector<PlaneLayout>);
+DEFINE_TYPE(CROP, std::vector<Rect>);
+DEFINE_TYPE(DATASPACE, Dataspace);
+DEFINE_TYPE(BLEND_MODE, BlendMode);
+DEFINE_TYPE(SMPTE2086, std::optional<Smpte2086>);
+DEFINE_TYPE(CTA861_3, std::optional<Cta861_3>);
+DEFINE_TYPE(SMPTE2094_10, std::optional<std::vector<uint8_t>>);
+DEFINE_TYPE(SMPTE2094_40, std::optional<std::vector<uint8_t>>);
+DEFINE_TYPE(STRIDE, uint32_t);
+
+#undef DEFINE_TYPE
+
+#if defined(__cplusplus) && __cplusplus >= 202002L
+
+template <typename F, std::size_t... I>
+void invokeWithStandardMetadata(F&& f, StandardMetadataType type, std::index_sequence<I...>) {
+    // Setup the jump table, mapping from each type to a springboard that invokes the template
+    // function with the appropriate concrete type
+    using F_PTR = decltype(&f);
+    using THUNK = void (*)(F_PTR);
+    static constexpr auto jump = std::array<THUNK, sizeof...(I)>{[](F_PTR fp) {
+        constexpr StandardMetadataType type = ndk::internal::enum_values<StandardMetadataType>[I];
+        if constexpr (type != StandardMetadataType::INVALID) {
+            (*fp)(StandardMetadata<type>{});
+        }
+    }...};
+
+    auto index = static_cast<size_t>(type);
+    if (index >= 0 && index < jump.size()) {
+        jump[index](&f);
+    }
+}
+
+template <typename F, typename StandardMetadataSequence = std::make_index_sequence<
+                              ndk::internal::enum_values<StandardMetadataType>.size()>>
+int32_t provideStandardMetadata(StandardMetadataType type, void* _Nullable destBuffer,
+                                size_t destBufferSize, F&& f) {
+    int32_t retVal = -AIMAPPER_ERROR_UNSUPPORTED;
+    invokeWithStandardMetadata(
+            [&]<StandardMetadataType T>(StandardMetadata<T>) {
+                retVal = f.template operator()<T>(
+                        [&](const typename StandardMetadata<T>::value_type& value) -> int32_t {
+                            return StandardMetadata<T>::value::encode(value, destBuffer,
+                                                                      destBufferSize);
+                        });
+            },
+            type, StandardMetadataSequence{});
+    return retVal;
+}
+
+template <typename F, typename StandardMetadataSequence = std::make_index_sequence<
+                              ndk::internal::enum_values<StandardMetadataType>.size()>>
+AIMapper_Error applyStandardMetadata(StandardMetadataType type, const void* _Nonnull metadata,
+                                     size_t metadataSize, F&& f) {
+    AIMapper_Error retVal = AIMAPPER_ERROR_UNSUPPORTED;
+    invokeWithStandardMetadata(
+            [&]<StandardMetadataType T>(StandardMetadata<T>) {
+                auto value = StandardMetadata<T>::value::decode(metadata, metadataSize);
+                if (value.has_value()) {
+                    retVal = f.template operator()<T>(std::move(*value));
+                } else {
+                    retVal = AIMAPPER_ERROR_BAD_VALUE;
+                }
+            },
+            type, StandardMetadataSequence{});
+    return retVal;
+}
+
+#endif
+
+}  // namespace android::hardware::graphics::mapper
\ No newline at end of file
diff --git a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperProvider.h b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperProvider.h
new file mode 100644
index 0000000..957fdc9
--- /dev/null
+++ b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperProvider.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/unique_fd.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+#include <log/log.h>
+
+#include <mutex>
+#include <optional>
+#include <type_traits>
+
+/**
+ * Helper utilities for providing an IMapper-StableC implementation.
+ */
+
+namespace vendor::mapper {
+
+/**
+ * Extend from this interface to provide Version 5 of the IMapper interface
+ */
+struct IMapperV5Impl {
+    static const auto version = AIMAPPER_VERSION_5;
+    virtual ~IMapperV5Impl() = default;
+
+    virtual AIMapper_Error importBuffer(const native_handle_t* _Nonnull handle,
+                                        buffer_handle_t _Nullable* _Nonnull outBufferHandle) = 0;
+
+    virtual AIMapper_Error freeBuffer(buffer_handle_t _Nonnull buffer) = 0;
+
+    virtual AIMapper_Error getTransportSize(buffer_handle_t _Nonnull buffer,
+                                            uint32_t* _Nonnull outNumFds,
+                                            uint32_t* _Nonnull outNumInts) = 0;
+
+    virtual AIMapper_Error lock(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage,
+                                ARect accessRegion, int acquireFence,
+                                void* _Nullable* _Nonnull outData) = 0;
+
+    virtual AIMapper_Error unlock(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence) = 0;
+
+    virtual AIMapper_Error flushLockedBuffer(buffer_handle_t _Nonnull buffer) = 0;
+
+    virtual AIMapper_Error rereadLockedBuffer(buffer_handle_t _Nonnull buffer) = 0;
+
+    virtual int32_t getMetadata(buffer_handle_t _Nonnull buffer, AIMapper_MetadataType metadataType,
+                                void* _Nullable destBuffer, size_t destBufferSize) = 0;
+
+    virtual int32_t getStandardMetadata(buffer_handle_t _Nonnull buffer,
+                                        int64_t standardMetadataType, void* _Nullable destBuffer,
+                                        size_t destBufferSize) = 0;
+
+    virtual AIMapper_Error setMetadata(buffer_handle_t _Nonnull buffer,
+                                       AIMapper_MetadataType metadataType,
+                                       const void* _Nonnull metadata, size_t metadataSize) = 0;
+
+    virtual AIMapper_Error setStandardMetadata(buffer_handle_t _Nonnull buffer,
+                                               int64_t standardMetadataType,
+                                               const void* _Nonnull metadata,
+                                               size_t metadataSize) = 0;
+
+    virtual AIMapper_Error listSupportedMetadataTypes(
+            const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
+            size_t* _Nonnull outNumberOfDescriptions) = 0;
+
+    virtual AIMapper_Error dumpBuffer(buffer_handle_t _Nonnull bufferHandle,
+                                      AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+                                      void* _Null_unspecified context) = 0;
+
+    virtual AIMapper_Error dumpAllBuffers(
+            AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
+            AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+            void* _Null_unspecified context) = 0;
+
+    virtual AIMapper_Error getReservedRegion(buffer_handle_t _Nonnull buffer,
+                                             void* _Nullable* _Nonnull outReservedRegion,
+                                             uint64_t* _Nonnull outReservedSize) = 0;
+};
+
+namespace provider {
+#ifndef __cpp_inline_variables
+#error "Only C++17 & newer is supported; inline variables is missing"
+#endif
+
+inline void* _Nullable sIMapperInstance = nullptr;
+}  // namespace provider
+
+template <typename IMPL>
+class IMapperProvider {
+  private:
+    static_assert(IMPL::version >= AIMAPPER_VERSION_5, "Must be at least AIMAPPER_VERSION_5");
+    static_assert(std::is_final_v<IMPL>, "Implementation must be final");
+    static_assert(std::is_constructible_v<IMPL>, "Implementation must have a no-args constructor");
+
+    std::once_flag mLoadOnceFlag;
+    std::optional<IMPL> mImpl;
+    AIMapper mMapper = {};
+
+    static IMPL& impl() {
+        return *reinterpret_cast<IMapperProvider<IMPL>*>(provider::sIMapperInstance)->mImpl;
+    }
+
+    void bindV5() {
+        mMapper.v5 = {
+                .importBuffer = [](const native_handle_t* _Nonnull handle,
+                                   buffer_handle_t _Nullable* _Nonnull outBufferHandle)
+                        -> AIMapper_Error { return impl().importBuffer(handle, outBufferHandle); },
+
+                .freeBuffer = [](buffer_handle_t _Nonnull buffer) -> AIMapper_Error {
+                    return impl().freeBuffer(buffer);
+                },
+
+                .getTransportSize = [](buffer_handle_t _Nonnull buffer,
+                                       uint32_t* _Nonnull outNumFds,
+                                       uint32_t* _Nonnull outNumInts) -> AIMapper_Error {
+                    return impl().getTransportSize(buffer, outNumFds, outNumInts);
+                },
+
+                .lock = [](buffer_handle_t _Nonnull buffer, uint64_t cpuUsage, ARect accessRegion,
+                           int acquireFence, void* _Nullable* _Nonnull outData) -> AIMapper_Error {
+                    return impl().lock(buffer, cpuUsage, accessRegion, acquireFence, outData);
+                },
+
+                .unlock = [](buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence)
+                        -> AIMapper_Error { return impl().unlock(buffer, releaseFence); },
+
+                .flushLockedBuffer = [](buffer_handle_t _Nonnull buffer) -> AIMapper_Error {
+                    return impl().flushLockedBuffer(buffer);
+                },
+
+                .rereadLockedBuffer = [](buffer_handle_t _Nonnull buffer) -> AIMapper_Error {
+                    return impl().rereadLockedBuffer(buffer);
+                },
+
+                .getMetadata = [](buffer_handle_t _Nonnull buffer,
+                                  AIMapper_MetadataType metadataType, void* _Nullable destBuffer,
+                                  size_t destBufferSize) -> int32_t {
+                    return impl().getMetadata(buffer, metadataType, destBuffer, destBufferSize);
+                },
+
+                .getStandardMetadata = [](buffer_handle_t _Nonnull buffer,
+                                          int64_t standardMetadataType, void* _Nullable destBuffer,
+                                          size_t destBufferSize) -> int32_t {
+                    return impl().getStandardMetadata(buffer, standardMetadataType, destBuffer,
+                                                      destBufferSize);
+                },
+
+                .setMetadata = [](buffer_handle_t _Nonnull buffer,
+                                  AIMapper_MetadataType metadataType, const void* _Nonnull metadata,
+                                  size_t metadataSize) -> AIMapper_Error {
+                    return impl().setMetadata(buffer, metadataType, metadata, metadataSize);
+                },
+
+                .setStandardMetadata =
+                        [](buffer_handle_t _Nonnull buffer, int64_t standardMetadataType,
+                           const void* _Nonnull metadata, size_t metadataSize) -> AIMapper_Error {
+                    return impl().setStandardMetadata(buffer, standardMetadataType, metadata,
+                                                      metadataSize);
+                },
+
+                .listSupportedMetadataTypes =
+                        [](const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
+                           size_t* _Nonnull outNumberOfDescriptions) -> AIMapper_Error {
+                    return impl().listSupportedMetadataTypes(outDescriptionList,
+                                                             outNumberOfDescriptions);
+                },
+
+                .dumpBuffer = [](buffer_handle_t _Nonnull bufferHandle,
+                                 AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+                                 void* _Null_unspecified context) -> AIMapper_Error {
+                    return impl().dumpBuffer(bufferHandle, dumpBufferCallback, context);
+                },
+
+                .dumpAllBuffers =
+                        [](AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
+                           AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+                           void* _Null_unspecified context) {
+                            return impl().dumpAllBuffers(beginDumpBufferCallback,
+                                                         dumpBufferCallback, context);
+                        },
+
+                .getReservedRegion = [](buffer_handle_t _Nonnull buffer,
+                                        void* _Nullable* _Nonnull outReservedRegion,
+                                        uint64_t* _Nonnull outReservedSize) -> AIMapper_Error {
+                    return impl().getReservedRegion(buffer, outReservedRegion, outReservedSize);
+                },
+        };
+    }
+
+  public:
+    explicit IMapperProvider() = default;
+
+    AIMapper_Error load(AIMapper* _Nullable* _Nonnull outImplementation) {
+        std::call_once(mLoadOnceFlag, [this] {
+            LOG_ALWAYS_FATAL_IF(provider::sIMapperInstance != nullptr,
+                                "AIMapper implementation already loaded!");
+            provider::sIMapperInstance = this;
+            mImpl.emplace();
+            mMapper.version = IMPL::version;
+            if (IMPL::version >= AIMAPPER_VERSION_5) {
+                bindV5();
+            }
+        });
+        *outImplementation = &mMapper;
+        return AIMAPPER_ERROR_NONE;
+    }
+};
+
+}  // namespace vendor::mapper
diff --git a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
new file mode 100644
index 0000000..75e436d
--- /dev/null
+++ b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
@@ -0,0 +1,691 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ *  IMapper Stable-C HAL interface
+ *
+ *  This file represents the sphal interface between libui & the IMapper HAL implementation.
+ *  A vendor implementation of this interface is retrieved by looking up the vendor imapper
+ *  implementation library via the IAllocator AIDL interface.
+ *
+ *  This interface is not intended for general use.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#include <android/rect.h>
+#include <cutils/native_handle.h>
+
+__BEGIN_DECLS
+
+/**
+ * AIMapper versioning
+ *
+ * IMapper versions 0-1 are pre-treble
+ * IMapper versions 2-4 are HIDL
+ * C-style AIMapper API starts at 5
+ */
+enum AIMapper_Version : uint32_t {
+    AIMAPPER_VERSION_5 = 5,
+};
+
+/**
+ * Possible AIMapper errors
+ * Values are the same as IMapper 4.0's Error type for simplicity
+ */
+enum AIMapper_Error : int32_t {
+    /**
+     * No error.
+     */
+    AIMAPPER_ERROR_NONE = 0,
+    /**
+     * Invalid BufferDescriptor.
+     */
+    AIMAPPER_ERROR_BAD_DESCRIPTOR = 1,
+    /**
+     * Invalid buffer handle.
+     */
+    AIMAPPER_ERROR_BAD_BUFFER = 2,
+    /**
+     * Invalid HardwareBufferDescription.
+     */
+    AIMAPPER_ERROR_BAD_VALUE = 3,
+    /**
+     * Resource unavailable.
+     */
+    AIMAPPER_ERROR_NO_RESOURCES = 5,
+    /**
+     * Permanent failure.
+     */
+    AIMAPPER_ERROR_UNSUPPORTED = 7,
+};
+
+/**
+ * MetadataType represents the different types of buffer metadata that could be
+ * associated with a buffer. It is used by IMapper to help get and set buffer metadata
+ * on the buffer's native handle.
+ *
+ * Standard buffer metadata will have the name field set to
+ * "android.hardware.graphics.common.StandardMetadataType" and will contain values
+ * from StandardMetadataType.aidl.
+ *
+ * Vendor-provided metadata should be prefixed with a "vendor.mycompanyname.*" namespace. It is
+ * recommended that the metadata follows the pattern of StandardMetadaType.aidl. That is, an
+ * aidl-defined enum with @VendorStability on it and the naming then matching that type such
+ * as "vendor.mycompanyname.graphics.common.MetadataType" with the value field then set to the
+ * aidl's enum value.
+ *
+ * Each company should create their own enum & namespace. The name
+ * field prevents values from different companies from colliding.
+ */
+typedef struct AIMapper_MetadataType {
+    const char* _Nonnull name;
+    int64_t value;
+} AIMapper_MetadataType;
+
+typedef struct AIMapper_MetadataTypeDescription {
+    /**
+     * The `name` of the metadataType must be valid for the lifetime of the process
+     */
+    AIMapper_MetadataType metadataType;
+    /**
+     * description should contain a string representation of the MetadataType.
+     *
+     * For example: "MyExampleMetadataType is a 64-bit timestamp in nanoseconds
+     * that indicates when a buffer is decoded. It is set by the media HAL after
+     * a buffer is decoded. It is used by the display HAL for hardware
+     * synchronization".
+     *
+     * This field is required for any non-StandardMetadataTypes. For StandardMetadataTypes this
+     * field may be null. The lifetime of this pointer must be valid for the duration of the
+     * process (that is, a static const char*).
+     */
+    const char* _Nullable description;
+    /**
+     * isGettable represents if the MetadataType can be get.
+     */
+    bool isGettable;
+    /**
+     * isSettable represents if the MetadataType can be set.
+     */
+    bool isSettable;
+
+    /** Reserved for future use; must be zero-initialized currently */
+    uint8_t reserved[32];
+} AIMapper_MetadataTypeDescription;
+
+/**
+ * Callback that is passed to dumpBuffer.
+ *
+ * @param context The caller-provided void* that was passed to dumpBuffer.
+ * @param metadataType The type of the metadata passed to the callback
+ * @param value A pointer to the value of the metadata. The lifetime of this pointer is only
+ *              valid for the duration of the call
+ * @param valueSize The size of the value buffer.
+ */
+typedef void (*AIMapper_DumpBufferCallback)(void* _Null_unspecified context,
+                                            AIMapper_MetadataType metadataType,
+                                            const void* _Nonnull value, size_t valueSize);
+
+/**
+ * Callback that is passed to dumpAllBuffers.
+ *
+ * Indicates that a buffer is about to be dumped. Will be followed by N calls to
+ * AIMapper_DumpBufferCallback for all the metadata for this buffer.
+ *
+ * @param context The caller-provided void* that was passed to dumpAllBuffers.
+ */
+typedef void (*AIMapper_BeginDumpBufferCallback)(void* _Null_unspecified context);
+
+/**
+ * Implementation of AIMAPPER_VERSION_5
+ * All functions must not be null & must provide a valid implementation.
+ */
+typedef struct AIMapperV5 {
+    /**
+     * Imports a raw buffer handle to create an imported buffer handle for use
+     * with the rest of the mapper or with other in-process libraries.
+     *
+     * A buffer handle is considered raw when it is cloned (e.g., with
+     * `native_handle_clone()`) from another buffer handle locally, or when it
+     * is received from another HAL server/client or another process. A raw
+     * buffer handle must not be used to access the underlying graphic
+     * buffer. It must be imported to create an imported handle first.
+     *
+     * This function must at least validate the raw handle before creating the
+     * imported handle. It must also support importing the same raw handle
+     * multiple times to create multiple imported handles. The imported handle
+     * must be considered valid everywhere in the process, including in
+     * another instance of the mapper.
+     *
+     * Because of passthrough HALs, a raw buffer handle received from a HAL
+     * may actually have been imported in the process. importBuffer() must treat
+     * such a handle as if it is raw and must not return `BAD_BUFFER`. The
+     * returned handle is independent from the input handle as usual, and
+     * freeBuffer() must be called on it when it is no longer needed.
+     *
+     * @param handle Raw buffer handle to import.
+     * @param outBufferHandle The resulting imported buffer handle.
+     * @return Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the raw handle is invalid.
+     *     - `NO_RESOURCES` if the raw handle cannot be imported due to
+     *       unavailability of resources.
+     */
+    AIMapper_Error (*_Nonnull importBuffer)(const native_handle_t* _Nonnull handle,
+                                            buffer_handle_t _Nullable* _Nonnull outBufferHandle);
+
+    /**
+     * Frees a buffer handle. Buffer handles returned by importBuffer() must be
+     * freed with this function when no longer needed.
+     *
+     * This function must free up all resources allocated by importBuffer() for
+     * the imported handle. For example, if the imported handle was created
+     * with `native_handle_create()`, this function must call
+     * `native_handle_close()` and `native_handle_delete()`.
+     *
+     * @param buffer Imported buffer handle.
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the buffer is invalid.
+     */
+    AIMapper_Error (*_Nonnull freeBuffer)(buffer_handle_t _Nonnull buffer);
+
+    /**
+     * Calculates the transport size of a buffer. An imported buffer handle is a
+     * raw buffer handle with the process-local runtime data appended. This
+     * function, for example, allows a caller to omit the process-local runtime
+     * data at the tail when serializing the imported buffer handle.
+     *
+     * Note that a client might or might not omit the process-local runtime data
+     * when sending an imported buffer handle. The mapper must support both
+     * cases on the receiving end.
+     *
+     * @param buffer Buffer to get the transport size from.
+     * @param outNumFds The number of file descriptors needed for transport.
+     * @param outNumInts The number of integers needed for transport.
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the buffer is invalid.
+     */
+    AIMapper_Error (*_Nonnull getTransportSize)(buffer_handle_t _Nonnull buffer,
+                                                uint32_t* _Nonnull outNumFds,
+                                                uint32_t* _Nonnull outNumInts);
+
+    /**
+     * Locks the given buffer for the specified CPU usage.
+     *
+     * Locking the same buffer simultaneously from multiple threads is
+     * permitted, but if any of the threads attempt to lock the buffer for
+     * writing, the behavior is undefined, except that it must not cause
+     * process termination or block the client indefinitely. Leaving the
+     * buffer content in an indeterminate state or returning an error are both
+     * acceptable.
+     *
+     * 1D buffers (width = size in bytes, height = 1, pixel_format = BLOB) must
+     * "lock in place" and behave similar to shared memory. That is, multiple threads or processes
+     * may lock the buffer for reading & writing and the results must follow the device's memory
+     * model.
+     *
+     * The client must not modify the content of the buffer outside of
+     * @p accessRegion, and the device need not guarantee that content outside
+     * of @p accessRegion is valid for reading. The result of reading or writing
+     * outside of @p accessRegion is undefined, except that it must not cause
+     * process termination.
+     *
+     * An accessRegion of all-zeros means the entire buffer. That is, it is
+     * equivalent to '(0,0)-(buffer width, buffer height)'.
+     *
+     * This function can lock both single-planar and multi-planar formats. The caller
+     * should use get() to get information about the buffer they are locking.
+     * get() can be used to get information about the planes, offsets, stride,
+     * etc.
+     *
+     * This function must also work on buffers with
+     * `AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_*` if supported by the device, as well
+     * as with any other formats requested by multimedia codecs when they are
+     * configured with a flexible-YUV-compatible color format.
+     *
+     * On success, @p data must be filled with a pointer to the locked buffer
+     * memory. This address will represent the top-left corner of the entire
+     * buffer, even if @p accessRegion does not begin at the top-left corner.
+     *
+     * The locked buffer must adhere to the format requested at allocation time
+     * in the BufferDescriptorInfo.
+     *
+     * @param buffer Buffer to lock.
+     * @param cpuUsage CPU usage flags to request. See BufferUsage.aidl for possible values.
+     * @param accessRegion Portion of the buffer that the client intends to
+     *     access.
+     * @param acquireFence Handle containing a file descriptor referring to a
+     *     sync fence object, which will be signaled when it is safe for the
+     *     mapper to lock the buffer. @p acquireFence may be an empty fence (-1) if
+     *     it is already safe to lock. Ownership is passed to the callee and it is the
+     *     implementations responsibility to ensure it is closed even when an error
+     *     occurs.
+     * @param outData CPU-accessible pointer to the buffer data.
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the buffer is invalid or is incompatible with this
+     *       function.
+     *     - `BAD_VALUE` if @p cpuUsage is 0, contains non-CPU usage flags, or
+     *       is incompatible with the buffer. Also if the @p accessRegion is
+     *       outside the bounds of the buffer or the accessRegion is invalid.
+     *     - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
+     *       that locking may succeed at a later time.
+     * @return data CPU-accessible pointer to the buffer data.
+     */
+    AIMapper_Error (*_Nonnull lock)(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage,
+                                    ARect accessRegion, int acquireFence,
+                                    void* _Nullable* _Nonnull outData);
+
+    /**
+     * Unlocks a buffer to indicate all CPU accesses to the buffer have
+     * completed.
+     *
+     * @param buffer Buffer to unlock.
+     * @param releaseFence Handle containing a file descriptor referring to a
+     *     sync fence object. The sync fence object will be signaled when the
+     *     mapper has completed any pending work. @p releaseFence may be an
+     *     empty fence (-1).
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the buffer is invalid or not locked.
+     */
+    AIMapper_Error (*_Nonnull unlock)(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence);
+
+    /**
+     * Flushes the contents of a locked buffer.
+     *
+     * This function flushes the CPUs caches for the range of all the buffer's
+     * planes and metadata. This should behave similarly to unlock() except the
+     * buffer should remain mapped to the CPU.
+     *
+     * The client is still responsible for calling unlock() when it is done
+     * with all CPU accesses to the buffer.
+     *
+     * If non-CPU blocks are simultaneously writing the buffer, the locked
+     * copy should still be flushed but what happens is undefined except that
+     * it should not cause any crashes.
+     *
+     * @param buffer Buffer to flush.
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the buffer is invalid or not locked.
+     */
+    AIMapper_Error (*_Nonnull flushLockedBuffer)(buffer_handle_t _Nonnull buffer);
+
+    /**
+     * Rereads the contents of a locked buffer.
+     *
+     * This should fetch the most recent copy of the locked buffer.
+     *
+     * It may reread locked copies of the buffer in other processes.
+     *
+     * The client is still responsible for calling unlock() when it is done
+     * with all CPU accesses to the buffer.
+     *
+     * @param buffer Buffer to reread.
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the buffer is invalid or not locked.
+     *     - `NO_RESOURCES` if the buffer cannot be reread at this time. Note
+     *       that rereading may succeed at a later time.
+     */
+    AIMapper_Error (*_Nonnull rereadLockedBuffer)(buffer_handle_t _Nonnull buffer);
+
+    /**
+     * Description for get(...), set(...) and getFromBufferDescriptorInfo(...)
+     *
+     * ------------ Overview -----------------------------------
+     * Gralloc 4 adds support for getting and setting buffer metadata on a buffer.
+     *
+     * To get buffer metadata, the client passes in a buffer handle and a token that
+     * represents the type of buffer metadata they would like to get. IMapper returns
+     * a byte stream that contains the buffer metadata. To set the buffer metadata, the
+     * client passes in a buffer handle and a token that represents the type of buffer
+     * metadata they would like to set and a byte stream that contains the buffer metadata
+     * they are setting.
+     *
+     * Buffer metadata is global for a buffer. When the metadata is set on the buffer
+     * in a process, the updated metadata should be available to all other processes.
+     * Please see "Storing and Propagating Metadata" below for more details.
+     *
+     * The getter and setter functions have been optimized for easy vendor extension.
+     * They do not require a formal extension to add support for getting and setting
+     * vendor defined buffer metadata. See "Buffer Metadata Token" and
+     * "Buffer Metadata Stream" below for more details.
+     *
+     * ------------ Storing and Propagating Metadata -----------
+     * Buffer metadata must be global. Any changes to the metadata must be propagated
+     * to all other processes immediately. Vendors may chose how they would like support
+     * this functionality.
+     *
+     * We recommend supporting this functionality by allocating an extra page of shared
+     * memory and storing it in the buffer's native_handle_t. The buffer metadata can
+     * be stored in the extra page of shared memory. Set operations are automatically
+     * propagated to all other processes.
+     *
+     * ------------ Buffer Metadata Synchronization ------------
+     * There are no explicit buffer metadata synchronization primitives. Many devices
+     * before gralloc 4 already support getting and setting of global buffer metadata
+     * with no explicit synchronization primitives. Adding synchronization primitives
+     * would just add unnecessary complexity.
+     *
+     * The general rule is if a process has permission to write to a buffer, they
+     * have permission to write to the buffer's writable metadata. If a process has permission
+     * to read from a buffer, they have permission to read the buffer's metadata.
+     *
+     * There is one exception to this rule. Fences CANNOT be used to protect a buffer's
+     * metadata. A process should finish writing to a buffer's metadata before
+     * sending the buffer to another process that will read or write to the buffer.
+     * This exception is needed because sometimes userspace needs to read the
+     * buffer's metadata before the buffer's contents are ready.
+     *
+     * As a simple example: an app renders to a buffer and then displays the buffer.
+     * In this example when the app renders to the buffer, both the buffer and its
+     * metadata need to be updated. The app's process queues up its work on the GPU
+     * and gets back an acquire fence. The app's process must update the buffer's
+     * metadata before enqueuing the buffer to SurfaceFlinger. The app process CANNOT
+     * update the buffer's metadata after enqueuing the buffer. When HardwareComposer
+     * receives the buffer, it is immediately safe to read the buffer's metadata
+     * and use it to program the display driver. To read the buffer's contents,
+     * display driver must still wait on the acquire fence.
+     *
+     * ------------ Buffer Metadata Token ----------------------
+     * In order to allow arbitrary vendor defined metadata, the token used to access
+     * metadata is defined defined as a struct that has a string representing
+     * the enum type and an int that represents the enum value. The string protects
+     * different enum values from colliding.
+     *
+     * The token struct (MetadataType) is defined as a C struct since it
+     * is passed into a C function. The standard buffer metadata types are NOT
+     * defined as a C enum but instead as an AIDL enum to allow for broader usage across
+     * other HALs and libraries. By putting the enum in the
+     * stable AIDL (hardware/interfaces/graphics/common/aidl/android/hardware/
+     * graphics/common/StandardMetadataType.aidl), vendors will be able to optionally
+     * choose to support future standard buffer metadata types without upgrading
+     * IMapper versions. For more information see the description of "struct MetadataType".
+     *
+     * ------------ Buffer Metadata Stream ---------------------
+     * The buffer metadata is get and set as a void* buffer. By getting
+     * and setting buffer metadata as a generic buffer, vendors can use the standard
+     * getters and setter functions defined here. Vendors do NOT need to add their own
+     * getters and setter functions for each new type of buffer metadata.
+     *
+     * Converting buffer metadata into a byte stream can be non-trivial. For the standard
+     * buffer metadata types defined in StandardMetadataType.aidl, there are also
+     * support functions that will encode the buffer metadata into a byte stream
+     * and decode the buffer metadata from a byte stream. We STRONGLY recommend using
+     * these support functions. The framework will use them when getting and setting
+     * metadata. The support functions are defined in
+     * frameworks/native/libs/gralloc/types/include/gralloctypes/Gralloc4.h.
+     */
+
+    /**
+     * Gets the buffer metadata for a given MetadataType.
+     *
+     * Buffer metadata can be changed after allocation so clients should avoid "caching"
+     * the buffer metadata. For example, if the video resolution changes and the buffers
+     * are not reallocated, several buffer metadata values may change without warning.
+     * Clients should not expect the values to be constant. They should requery them every
+     * frame. The only exception is buffer metadata that is determined at allocation
+     * time. For StandardMetadataType values, only BUFFER_ID, NAME, WIDTH,
+     * HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and USAGE are safe to cache because
+     * they are determined at allocation time.
+     *
+     * @param buffer Buffer containing desired metadata
+     * @param metadataType MetadataType for the metadata value being queried
+     * @param destBuffer Pointer to a buffer in which to store the result of the get() call; if
+     * null, the computed output size or error must still be returned.
+     * @param destBufferSize How large the destBuffer buffer is. If destBuffer is null this must be
+     * 0.
+     * @return The number of bytes written to `destBuffer` or which would have been written
+     *         if `destBufferSize` was large enough.
+     *         A negative value indicates an error, which may be
+     *         - `BAD_BUFFER` if the raw handle is invalid.
+     *         - `UNSUPPORTED` when metadataType is unknown/unsupported.
+     *            IMapper must support getting all StandardMetadataType.aidl values defined
+     *            at the time the device first launches.
+     */
+    int32_t (*_Nonnull getMetadata)(buffer_handle_t _Nonnull buffer,
+                                    AIMapper_MetadataType metadataType, void* _Nullable destBuffer,
+                                    size_t destBufferSize);
+
+    /**
+     * Gets the buffer metadata for a StandardMetadataType.
+     *
+     * This is equivalent to `getMetadata` when passed an AIMapper_MetadataType with name
+     * set to "android.hardware.graphics.common.StandardMetadataType"
+     *
+     * Buffer metadata can be changed after allocation so clients should avoid "caching"
+     * the buffer metadata. For example, if the video resolution changes and the buffers
+     * are not reallocated, several buffer metadata values may change without warning.
+     * Clients should not expect the values to be constant. They should requery them every
+     * frame. The only exception is buffer metadata that is determined at allocation
+     * time. For StandardMetadataType values, only BUFFER_ID, NAME, WIDTH,
+     * HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and USAGE are safe to cache because
+     * they are determined at allocation time.
+     *
+     * @param buffer Buffer containing desired metadata
+     * @param standardMetadataType StandardMetadataType for the metadata value being queried
+     * @param destBuffer Pointer to a buffer in which to store the result of the get() call; if
+     * null, the computed output size or error must still be returned.
+     * @param destBufferSize How large the destBuffer buffer is. If destBuffer is null this must be
+     * 0.
+     * @return The number of bytes written to `destBuffer` or which would have been written
+     *         if `destBufferSize` was large enough.
+     *         A negative value indicates an error, which may be
+     *         - `BAD_BUFFER` if the raw handle is invalid.
+     *         - `UNSUPPORTED` when metadataType is unknown/unsupported.
+     *            IMapper must support getting all StandardMetadataType.aidl values defined
+     *            at the time the device first launches.
+     */
+    int32_t (*_Nonnull getStandardMetadata)(buffer_handle_t _Nonnull buffer,
+                                            int64_t standardMetadataType,
+                                            void* _Nullable destBuffer, size_t destBufferSize);
+
+    /**
+     * Sets the global value for a given MetadataType.
+     *
+     * Metadata fields are not required to be settable. This function can
+     * return Error::UNSUPPORTED whenever it doesn't support setting a
+     * particular Metadata field.
+     *
+     * The framework will attempt to set the following StandardMetadataType
+     * values: DATASPACE, SMPTE2086, CTA861_3, and BLEND_MODE.
+     * We require everyone to support setting those fields. Framework will also attempt to set
+     * SMPTE2094_40 and SMPTE2094_10 if available, and it is required to support setting those
+     * if it is possible to get them. If a device's Composer implementation supports a field,
+     * it should be supported here. Over time these metadata fields will be moved out of
+     * Composer/BufferQueue/etc. and into the buffer's Metadata fields.
+     *
+     * @param buffer Buffer receiving desired metadata
+     * @param metadataType MetadataType for the metadata value being set
+     * @param metadata Pointer to a buffer of bytes representing the value associated with
+     * @param metadataSize The size of the metadata buffer
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the raw handle is invalid.
+     *     - `BAD_VALUE` when the field is constant and can never be set (such as
+     *       BUFFER_ID, NAME, WIDTH, HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and
+     *       USAGE)
+     *     - `NO_RESOURCES` if the set cannot be fulfilled due to unavailability of
+     *        resources.
+     *     - `UNSUPPORTED` when metadataType is unknown/unsupported or setting
+     *       it is unsupported. Unsupported should also be returned if the metadata
+     *       is malformed.
+     */
+    AIMapper_Error (*_Nonnull setMetadata)(buffer_handle_t _Nonnull buffer,
+                                           AIMapper_MetadataType metadataType,
+                                           const void* _Nonnull metadata, size_t metadataSize);
+
+    /**
+     * Sets the global value for a given MetadataType.
+     *
+     * This is equivalent to `setMetadata` when passed an AIMapper_MetadataType with name
+     * set to "android.hardware.graphics.common.StandardMetadataType"
+     *
+     * Metadata fields are not required to be settable. This function can
+     * return Error::UNSUPPORTED whenever it doesn't support setting a
+     * particular Metadata field.
+     *
+     * The framework will attempt to set the following StandardMetadataType
+     * values: DATASPACE, SMPTE2086, CTA861_3, and BLEND_MODE.
+     * We require everyone to support setting those fields. Framework will also attempt to set
+     * SMPTE2094_40 and SMPTE2094_10 if available, and it is required to support setting those
+     * if it is possible to get them. If a device's Composer implementation supports a field,
+     * it should be supported here. Over time these metadata fields will be moved out of
+     * Composer/BufferQueue/etc. and into the buffer's Metadata fields.
+     *
+     * @param buffer Buffer receiving desired metadata
+     * @param standardMetadataType StandardMetadataType for the metadata value being set
+     * @param metadata Pointer to a buffer of bytes representing the value associated with
+     * @param metadataSize The size of the metadata buffer
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the raw handle is invalid.
+     *     - `BAD_VALUE` when the field is constant and can never be set (such as
+     *       BUFFER_ID, NAME, WIDTH, HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and
+     *       USAGE)
+     *     - `NO_RESOURCES` if the set cannot be fulfilled due to unavailability of
+     *        resources.
+     *     - `UNSUPPORTED` when metadataType is unknown/unsupported or setting
+     *       it is unsupported. Unsupported should also be returned if the metadata
+     *       is malformed.
+     */
+    AIMapper_Error (*_Nonnull setStandardMetadata)(buffer_handle_t _Nonnull buffer,
+                                                   int64_t standardMetadataType,
+                                                   const void* _Nonnull metadata,
+                                                   size_t metadataSize);
+
+    /**
+     * Lists all the MetadataTypes supported by IMapper as well as a description
+     * of each supported MetadataType. For StandardMetadataTypes, the description
+     * string can be left empty.
+     *
+     * This list is expected to be static & thus the returned array must be valid for the
+     * lifetime of the process.
+     *
+     * @param outDescriptionList The list of descriptions
+     * @param outNumberOfDescriptions How many descriptions are in `outDescriptionList`
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `UNSUPPORTED` if there's any error
+     */
+    AIMapper_Error (*_Nonnull listSupportedMetadataTypes)(
+            const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
+            size_t* _Nonnull outNumberOfDescriptions);
+
+    /**
+     * Dumps a buffer's metadata.
+     *
+     * @param buffer The buffer to dump the metadata for
+     * @param dumpBufferCallback Callback that will be invoked for each of the metadata fields
+     * @param context A caller-provided context to be passed to the dumpBufferCallback
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the raw handle is invalid.
+     *     - `NO_RESOURCES` if the get cannot be fulfilled due to unavailability of
+     *       resources.
+     */
+    AIMapper_Error (*_Nonnull dumpBuffer)(buffer_handle_t _Nonnull buffer,
+                                          AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+                                          void* _Null_unspecified context);
+
+    /**
+     * Dump the metadata for all imported buffers in the current process
+     *
+     * The HAL implementation should invoke beginDumpCallback before dumping a buffer's metadata,
+     * followed by N calls to dumpBufferCallback for that buffer's metadata fields. The call
+     * sequence should follow this pseudocode:
+     *
+     * for (auto buffer : gListOfImportedBuffers) {
+     *    beginDumpCallback(context);
+     *    for (auto metadata : buffer->allMetadata()) {
+     *        dumpBufferCallback(context, metadata...);
+     *    }
+     * }
+     *
+     * @param beginDumpCallback Signals that a buffer is about to be dumped
+     * @param dumpBufferCallback Callback that will be invoked for each of the metadata fields
+     * @param context A caller-provided context to be passed to beginDumpCallback and
+     *                dumpBufferCallback
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the raw handle is invalid.
+     *     - `NO_RESOURCES` if the get cannot be fulfilled due to unavailability of
+     *       resources.
+     */
+    AIMapper_Error (*_Nonnull dumpAllBuffers)(
+            AIMapper_BeginDumpBufferCallback _Nonnull beginDumpCallback,
+            AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
+            void* _Null_unspecified context);
+
+    /**
+     * Returns the region of shared memory associated with the buffer that is
+     * reserved for client use.
+     *
+     * The shared memory may be allocated from any shared memory allocator.
+     * The shared memory must be CPU-accessible and virtually contiguous. The
+     * starting address must be word-aligned.
+     *
+     * This function may only be called after importBuffer() has been called by the
+     * client. The reserved region must remain accessible until freeBuffer() has
+     * been called. After freeBuffer() has been called, the client must not access
+     * the reserved region.
+     *
+     * This reserved memory may be used in future versions of Android to
+     * help clients implement backwards compatible features without requiring
+     * IAllocator/IMapper updates.
+     *
+     * @param buffer Imported buffer handle.
+     * @param outReservedRegion CPU-accessible pointer to the reserved region
+     * @param outReservedSize the size of the reservedRegion that was requested
+     *    in the BufferDescriptorInfo.
+     * @return error Error status of the call, which may be
+     *     - `NONE` upon success.
+     *     - `BAD_BUFFER` if the buffer is invalid.
+     */
+    AIMapper_Error (*_Nonnull getReservedRegion)(buffer_handle_t _Nonnull buffer,
+                                                 void* _Nullable* _Nonnull outReservedRegion,
+                                                 uint64_t* _Nonnull outReservedSize);
+
+} AIMapperV5;
+
+/**
+ * Return value for AIMapper_loadIMapper
+ *
+ * Note: This struct's size is not fixed and callers must never store it by-value as a result.
+ *       Only fields up to those covered by `version` are allowed to be accessed.
+ */
+typedef struct AIMapper {
+    alignas(alignof(max_align_t)) AIMapper_Version version;
+    AIMapperV5 v5;
+} AIMapper;
+
+/**
+ * Loads the vendor-provided implementation of AIMapper
+ * @return Error status of the call.
+ *          - `NONE` upon success
+ *          - `UNSUPPORTED` if no implementation is available
+ */
+AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation);
+
+__END_DECLS
\ No newline at end of file
diff --git a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
new file mode 100644
index 0000000..2c06353
--- /dev/null
+++ b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
@@ -0,0 +1,1786 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "VtsHalGraphicsMapperStableC_TargetTest"
+
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/allocator/AllocationError.h>
+#include <aidl/android/hardware/graphics/allocator/AllocationResult.h>
+#include <aidl/android/hardware/graphics/allocator/IAllocator.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android/binder_enums.h>
+#include <android/binder_manager.h>
+#include <android/dlext.h>
+#include <android/hardware/graphics/mapper/IMapper.h>
+#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
+#include <gralloctypes/Gralloc4.h>
+#include <hidl/GtestPrinter.h>
+#include <system/graphics.h>
+
+#include <dlfcn.h>
+#include <drm/drm_fourcc.h>
+#include <gtest/gtest.h>
+#include <vndksupport/linker.h>
+#include <initializer_list>
+#include <optional>
+#include <string>
+#include <tuple>
+#include <vector>
+
+using namespace aidl::android::hardware::graphics::allocator;
+using namespace aidl::android::hardware::graphics::common;
+using namespace android;
+using namespace android::hardware;
+using namespace ::android::hardware::graphics::mapper;
+
+typedef AIMapper_Error (*AIMapper_loadIMapperFn)(AIMapper* _Nullable* _Nonnull outImplementation);
+
+inline constexpr BufferUsage operator|(BufferUsage lhs, BufferUsage rhs) {
+    using T = std::underlying_type_t<BufferUsage>;
+    return static_cast<BufferUsage>(static_cast<T>(lhs) | static_cast<T>(rhs));
+}
+
+inline BufferUsage& operator|=(BufferUsage& lhs, BufferUsage rhs) {
+    lhs = lhs | rhs;
+    return lhs;
+}
+
+struct YCbCr {
+    android_ycbcr yCbCr;
+    int64_t horizontalSubSampling;
+    int64_t verticalSubSampling;
+};
+
+constexpr const char* STANDARD_METADATA_NAME =
+        "android.hardware.graphics.common.StandardMetadataType";
+
+static bool isStandardMetadata(AIMapper_MetadataType metadataType) {
+    return strcmp(STANDARD_METADATA_NAME, metadataType.name) == 0;
+}
+
+static std::string toString(const std::vector<StandardMetadataType> types) {
+    std::stringstream buf;
+    buf << "[";
+    for (auto type : types) {
+        buf << toString(type) << ", ";
+    }
+    buf.seekp(-2, buf.cur);
+    buf << "]";
+    return buf.str();
+}
+
+class BufferHandle {
+    AIMapper* mIMapper;
+    buffer_handle_t mHandle = nullptr;
+
+  public:
+    explicit BufferHandle(AIMapper* mapper, native_handle_t* rawHandle) : mIMapper(mapper) {
+        EXPECT_EQ(AIMAPPER_ERROR_NONE, mIMapper->v5.importBuffer(rawHandle, &mHandle));
+    }
+
+    explicit BufferHandle(BufferHandle&& other) { *this = std::move(other); }
+
+    BufferHandle& operator=(BufferHandle&& other) noexcept {
+        reset();
+        mIMapper = other.mIMapper;
+        mHandle = other.mHandle;
+        other.mHandle = nullptr;
+        return *this;
+    }
+
+    ~BufferHandle() { reset(); }
+
+    constexpr explicit operator bool() const noexcept { return mHandle != nullptr; }
+
+    buffer_handle_t operator*() const noexcept { return mHandle; }
+
+    void reset() {
+        if (mHandle != nullptr) {
+            EXPECT_EQ(AIMAPPER_ERROR_NONE, mIMapper->v5.freeBuffer(mHandle));
+            mHandle = nullptr;
+        }
+    }
+};
+
+class BufferAllocation {
+    AIMapper* mIMapper;
+    native_handle_t* mRawHandle;
+    uint32_t mStride;
+    const BufferDescriptorInfo mInfo;
+
+  public:
+    BufferAllocation(const BufferAllocation&) = delete;
+    void operator=(const BufferAllocation&) = delete;
+
+    BufferAllocation(AIMapper* mapper, native_handle_t* handle, uint32_t stride,
+                     const BufferDescriptorInfo& info)
+        : mIMapper(mapper), mRawHandle(handle), mStride(stride), mInfo(info) {}
+
+    ~BufferAllocation() {
+        if (mRawHandle == nullptr) return;
+
+        native_handle_close(mRawHandle);
+        native_handle_delete(mRawHandle);
+    }
+
+    uint32_t stride() const { return mStride; }
+    const BufferDescriptorInfo& info() const { return mInfo; }
+
+    BufferHandle import() { return BufferHandle{mIMapper, mRawHandle}; }
+
+    const native_handle_t* rawHandle() const { return mRawHandle; }
+};
+
+class GraphicsTestsBase {
+  private:
+    friend class BufferAllocation;
+    int32_t mIAllocatorVersion = 1;
+    std::shared_ptr<IAllocator> mAllocator;
+    AIMapper* mIMapper = nullptr;
+    AIMapper_loadIMapperFn mIMapperLoader;
+    int32_t* mIMapperHALVersion = nullptr;
+
+  protected:
+    void Initialize(std::shared_ptr<IAllocator> allocator) {
+        mAllocator = allocator;
+        ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
+        ASSERT_TRUE(mAllocator->getInterfaceVersion(&mIAllocatorVersion).isOk());
+        ASSERT_GE(mIAllocatorVersion, 2);
+        std::string mapperSuffix;
+        auto status = mAllocator->getIMapperLibrarySuffix(&mapperSuffix);
+        ASSERT_TRUE(status.isOk()) << "Failed to get IMapper library suffix";
+        std::string lib_name = "mapper." + mapperSuffix + ".so";
+        void* so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
+        ASSERT_NE(nullptr, so) << "Failed to load " << lib_name;
+        mIMapperLoader = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
+        ASSERT_NE(nullptr, mIMapperLoader) << "AIMapper_locaIMapper missing from " << lib_name;
+        ASSERT_EQ(AIMAPPER_ERROR_NONE, mIMapperLoader(&mIMapper));
+        ASSERT_NE(mIMapper, nullptr);
+        mIMapperHALVersion = (int32_t*)dlsym(so, "ANDROID_HAL_MAPPER_VERSION");
+    }
+
+  public:
+    AIMapper_loadIMapperFn getIMapperLoader() const { return mIMapperLoader; }
+    int32_t* getHalVersion() const { return mIMapperHALVersion; }
+
+    std::unique_ptr<BufferAllocation> allocate(const BufferDescriptorInfo& descriptorInfo) {
+        AllocationResult result;
+        ::ndk::ScopedAStatus status = mAllocator->allocate2(descriptorInfo, 1, &result);
+        if (!status.isOk()) {
+            status_t error = status.getExceptionCode();
+            if (error == EX_SERVICE_SPECIFIC) {
+                error = status.getServiceSpecificError();
+                EXPECT_NE(OK, error) << "Failed to set error properly";
+            } else {
+                EXPECT_EQ(OK, error) << "Allocation transport failure";
+            }
+            return nullptr;
+        } else {
+            return std::make_unique<BufferAllocation>(mIMapper, dupFromAidl(result.buffers[0]),
+                                                      result.stride, descriptorInfo);
+        }
+    }
+
+    std::unique_ptr<BufferAllocation> allocateGeneric() {
+        return allocate({
+                .name = {"VTS_TEMP"},
+                .width = 64,
+                .height = 64,
+                .layerCount = 1,
+                .format = PixelFormat::RGBA_8888,
+                .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+                .reservedSize = 0,
+        });
+    }
+
+    bool isSupported(const BufferDescriptorInfo& descriptorInfo) {
+        bool ret = false;
+        EXPECT_TRUE(mAllocator->isSupported(descriptorInfo, &ret).isOk());
+        return ret;
+    }
+
+    AIMapper* mapper() const { return mIMapper; }
+
+    template <StandardMetadataType T>
+    auto getStandardMetadata(buffer_handle_t bufferHandle)
+            -> decltype(StandardMetadata<T>::value::decode(nullptr, 0)) {
+        using Value = typename StandardMetadata<T>::value;
+        std::vector<uint8_t> buffer;
+        // Initial guess
+        buffer.resize(512);
+        int32_t sizeRequired = mapper()->v5.getStandardMetadata(
+                bufferHandle, static_cast<int64_t>(T), buffer.data(), buffer.size());
+        if (sizeRequired < 0) {
+            EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, sizeRequired)
+                    << "Received something other than UNSUPPORTED from valid getStandardMetadata "
+                       "call";
+            return std::nullopt;
+        }
+        if (sizeRequired > buffer.size()) {
+            buffer.resize(sizeRequired);
+            sizeRequired = mapper()->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
+                                                            buffer.data(), buffer.size());
+        }
+        if (sizeRequired < 0 || sizeRequired > buffer.size()) {
+            ADD_FAILURE() << "getStandardMetadata failed, received " << sizeRequired
+                          << " with buffer size " << buffer.size();
+            // Generate a fail type
+            return std::nullopt;
+        }
+        return Value::decode(buffer.data(), sizeRequired);
+    }
+
+    template <StandardMetadataType T>
+    AIMapper_Error setStandardMetadata(buffer_handle_t bufferHandle,
+                                       const typename StandardMetadata<T>::value_type& value) {
+        using Value = typename StandardMetadata<T>::value;
+        int32_t sizeRequired = Value::encode(value, nullptr, 0);
+        if (sizeRequired < 0) {
+            EXPECT_GE(sizeRequired, 0) << "Failed to calculate required size";
+            return static_cast<AIMapper_Error>(-sizeRequired);
+        }
+        std::vector<uint8_t> buffer;
+        buffer.resize(sizeRequired);
+        sizeRequired = Value::encode(value, buffer.data(), buffer.size());
+        if (sizeRequired < 0 || sizeRequired > buffer.size()) {
+            ADD_FAILURE() << "Failed to encode with calculated size " << sizeRequired
+                          << "; buffer size" << buffer.size();
+            return static_cast<AIMapper_Error>(-sizeRequired);
+        }
+        return mapper()->v5.setStandardMetadata(bufferHandle, static_cast<int64_t>(T),
+                                                buffer.data(), sizeRequired);
+    }
+
+    void verifyRGBA8888PlaneLayouts(const std::vector<PlaneLayout>& planeLayouts) {
+        ASSERT_EQ(1, planeLayouts.size());
+
+        const auto& planeLayout = planeLayouts.front();
+
+        ASSERT_EQ(4, planeLayout.components.size());
+
+        int64_t offsetInBitsR = -1;
+        int64_t offsetInBitsG = -1;
+        int64_t offsetInBitsB = -1;
+        int64_t offsetInBitsA = -1;
+
+        for (const auto& component : planeLayout.components) {
+            if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
+                continue;
+            }
+            EXPECT_EQ(8, component.sizeInBits);
+            if (component.type.value == gralloc4::PlaneLayoutComponentType_R.value) {
+                offsetInBitsR = component.offsetInBits;
+            }
+            if (component.type.value == gralloc4::PlaneLayoutComponentType_G.value) {
+                offsetInBitsG = component.offsetInBits;
+            }
+            if (component.type.value == gralloc4::PlaneLayoutComponentType_B.value) {
+                offsetInBitsB = component.offsetInBits;
+            }
+            if (component.type.value == gralloc4::PlaneLayoutComponentType_A.value) {
+                offsetInBitsA = component.offsetInBits;
+            }
+        }
+
+        EXPECT_EQ(0, offsetInBitsR);
+        EXPECT_EQ(8, offsetInBitsG);
+        EXPECT_EQ(16, offsetInBitsB);
+        EXPECT_EQ(24, offsetInBitsA);
+
+        EXPECT_EQ(0, planeLayout.offsetInBytes);
+        EXPECT_EQ(32, planeLayout.sampleIncrementInBits);
+        // Skip testing stride because any stride is valid
+        EXPECT_LE(planeLayout.widthInSamples * planeLayout.heightInSamples * 4,
+                  planeLayout.totalSizeInBytes);
+        EXPECT_EQ(1, planeLayout.horizontalSubsampling);
+        EXPECT_EQ(1, planeLayout.verticalSubsampling);
+    }
+
+    void fillRGBA8888(uint8_t* data, uint32_t height, size_t strideInBytes, size_t widthInBytes) {
+        for (uint32_t y = 0; y < height; y++) {
+            memset(data, y, widthInBytes);
+            data += strideInBytes;
+        }
+    }
+
+    void verifyRGBA8888(const buffer_handle_t bufferHandle, const uint8_t* data, uint32_t height,
+                        size_t strideInBytes, size_t widthInBytes) {
+        auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(bufferHandle);
+        ASSERT_TRUE(decodeResult.has_value());
+        const auto& planeLayouts = *decodeResult;
+        ASSERT_TRUE(planeLayouts.size() > 0);
+
+        verifyRGBA8888PlaneLayouts(planeLayouts);
+
+        for (uint32_t y = 0; y < height; y++) {
+            for (size_t i = 0; i < widthInBytes; i++) {
+                EXPECT_EQ(static_cast<uint8_t>(y), data[i]);
+            }
+            data += strideInBytes;
+        }
+    }
+
+    void traverseYCbCrData(const android_ycbcr& yCbCr, int32_t width, int32_t height,
+                           int64_t hSubsampling, int64_t vSubsampling,
+                           std::function<void(uint8_t*, uint8_t)> traverseFuncion) {
+        auto yData = static_cast<uint8_t*>(yCbCr.y);
+        auto cbData = static_cast<uint8_t*>(yCbCr.cb);
+        auto crData = static_cast<uint8_t*>(yCbCr.cr);
+        auto yStride = yCbCr.ystride;
+        auto cStride = yCbCr.cstride;
+        auto chromaStep = yCbCr.chroma_step;
+
+        for (uint32_t y = 0; y < height; y++) {
+            for (uint32_t x = 0; x < width; x++) {
+                auto val = static_cast<uint8_t>(height * y + x);
+
+                traverseFuncion(yData + yStride * y + x, val);
+
+                if (y % vSubsampling == 0 && x % hSubsampling == 0) {
+                    uint32_t subSampleX = x / hSubsampling;
+                    uint32_t subSampleY = y / vSubsampling;
+                    const auto subSampleOffset = cStride * subSampleY + chromaStep * subSampleX;
+                    const auto subSampleVal =
+                            static_cast<uint8_t>(height * subSampleY + subSampleX);
+
+                    traverseFuncion(cbData + subSampleOffset, subSampleVal);
+                    traverseFuncion(crData + subSampleOffset, subSampleVal + 1);
+                }
+            }
+        }
+    }
+
+    void fillYCbCrData(const android_ycbcr& yCbCr, int32_t width, int32_t height,
+                       int64_t hSubsampling, int64_t vSubsampling) {
+        traverseYCbCrData(yCbCr, width, height, hSubsampling, vSubsampling,
+                          [](auto address, auto fillingData) { *address = fillingData; });
+    }
+
+    void verifyYCbCrData(const android_ycbcr& yCbCr, int32_t width, int32_t height,
+                         int64_t hSubsampling, int64_t vSubsampling) {
+        traverseYCbCrData(
+                yCbCr, width, height, hSubsampling, vSubsampling,
+                [](auto address, auto expectedData) { EXPECT_EQ(*address, expectedData); });
+    }
+
+    constexpr uint64_t bitsToBytes(int64_t bits) { return bits / 8; }
+    constexpr uint64_t bytesToBits(int64_t bytes) { return bytes * 8; }
+
+    void getAndroidYCbCr(buffer_handle_t bufferHandle, uint8_t* data, android_ycbcr* outYCbCr,
+                         int64_t* hSubsampling, int64_t* vSubsampling) {
+        auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(bufferHandle);
+        ASSERT_TRUE(decodeResult.has_value());
+        const auto& planeLayouts = *decodeResult;
+        ASSERT_TRUE(planeLayouts.size() > 0);
+
+        outYCbCr->y = nullptr;
+        outYCbCr->cb = nullptr;
+        outYCbCr->cr = nullptr;
+        outYCbCr->ystride = 0;
+        outYCbCr->cstride = 0;
+        outYCbCr->chroma_step = 0;
+
+        for (const auto& planeLayout : planeLayouts) {
+            for (const auto& planeLayoutComponent : planeLayout.components) {
+                if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
+                    continue;
+                }
+                ASSERT_EQ(0, planeLayoutComponent.offsetInBits % 8);
+
+                uint8_t* tmpData = data + planeLayout.offsetInBytes +
+                                   bitsToBytes(planeLayoutComponent.offsetInBits);
+                uint64_t sampleIncrementInBytes;
+
+                auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
+                switch (type) {
+                    case PlaneLayoutComponentType::Y:
+                        ASSERT_EQ(nullptr, outYCbCr->y);
+                        ASSERT_EQ(8, planeLayoutComponent.sizeInBits);
+                        ASSERT_EQ(8, planeLayout.sampleIncrementInBits);
+                        outYCbCr->y = tmpData;
+                        outYCbCr->ystride = planeLayout.strideInBytes;
+                        break;
+
+                    case PlaneLayoutComponentType::CB:
+                    case PlaneLayoutComponentType::CR:
+                        ASSERT_EQ(0, planeLayout.sampleIncrementInBits % 8);
+
+                        sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
+                        ASSERT_TRUE(sampleIncrementInBytes == 1 || sampleIncrementInBytes == 2);
+
+                        if (outYCbCr->cstride == 0 && outYCbCr->chroma_step == 0) {
+                            outYCbCr->cstride = planeLayout.strideInBytes;
+                            outYCbCr->chroma_step = sampleIncrementInBytes;
+                        } else {
+                            ASSERT_EQ(outYCbCr->cstride, planeLayout.strideInBytes);
+                            ASSERT_EQ(outYCbCr->chroma_step, sampleIncrementInBytes);
+                        }
+
+                        if (*hSubsampling == 0 && *vSubsampling == 0) {
+                            *hSubsampling = planeLayout.horizontalSubsampling;
+                            *vSubsampling = planeLayout.verticalSubsampling;
+                        } else {
+                            ASSERT_EQ(*hSubsampling, planeLayout.horizontalSubsampling);
+                            ASSERT_EQ(*vSubsampling, planeLayout.verticalSubsampling);
+                        }
+
+                        if (type == PlaneLayoutComponentType::CB) {
+                            ASSERT_EQ(nullptr, outYCbCr->cb);
+                            outYCbCr->cb = tmpData;
+                        } else {
+                            ASSERT_EQ(nullptr, outYCbCr->cr);
+                            outYCbCr->cr = tmpData;
+                        }
+                        break;
+                    default:
+                        break;
+                };
+            }
+        }
+
+        ASSERT_NE(nullptr, outYCbCr->y);
+        ASSERT_NE(nullptr, outYCbCr->cb);
+        ASSERT_NE(nullptr, outYCbCr->cr);
+    }
+
+    YCbCr getAndroidYCbCr_P010(const native_handle_t* bufferHandle, uint8_t* data) {
+        YCbCr yCbCr_P010;
+        auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(bufferHandle);
+        if (!decodeResult.has_value()) {
+            ADD_FAILURE() << "failed to get plane layout";
+            return YCbCr{};
+        }
+        const auto& planeLayouts = *decodeResult;
+        EXPECT_EQ(2, planeLayouts.size());
+        EXPECT_EQ(1, planeLayouts[0].components.size());
+        EXPECT_EQ(2, planeLayouts[1].components.size());
+
+        yCbCr_P010.yCbCr.y = nullptr;
+        yCbCr_P010.yCbCr.cb = nullptr;
+        yCbCr_P010.yCbCr.cr = nullptr;
+        yCbCr_P010.yCbCr.ystride = 0;
+        yCbCr_P010.yCbCr.cstride = 0;
+        yCbCr_P010.yCbCr.chroma_step = 0;
+        int64_t cb_offset = 0;
+        int64_t cr_offset = 0;
+
+        for (const auto& planeLayout : planeLayouts) {
+            for (const auto& planeLayoutComponent : planeLayout.components) {
+                if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
+                    continue;
+                }
+
+                uint8_t* tmpData = data + planeLayout.offsetInBytes +
+                                   bitsToBytes(planeLayoutComponent.offsetInBits);
+                uint64_t sampleIncrementInBytes = 0;
+                auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
+                switch (type) {
+                    case PlaneLayoutComponentType::Y:
+                        // For specs refer:
+                        // https://docs.microsoft.com/en-us/windows/win32/medfound/10-bit-and-16-bit-yuv-video-formats
+                        EXPECT_EQ(6, planeLayoutComponent.offsetInBits);
+                        EXPECT_EQ(nullptr, yCbCr_P010.yCbCr.y);
+                        EXPECT_EQ(10, planeLayoutComponent.sizeInBits);
+                        EXPECT_EQ(16, planeLayout.sampleIncrementInBits);
+
+                        yCbCr_P010.yCbCr.y = tmpData;
+                        yCbCr_P010.yCbCr.ystride = planeLayout.strideInBytes;
+                        break;
+
+                    case PlaneLayoutComponentType::CB:
+                    case PlaneLayoutComponentType::CR:
+                        sampleIncrementInBytes = bitsToBytes(planeLayout.sampleIncrementInBits);
+                        EXPECT_EQ(4, sampleIncrementInBytes);
+
+                        if (yCbCr_P010.yCbCr.cstride == 0 && yCbCr_P010.yCbCr.chroma_step == 0) {
+                            yCbCr_P010.yCbCr.cstride = planeLayout.strideInBytes;
+                            yCbCr_P010.yCbCr.chroma_step = sampleIncrementInBytes;
+                        } else {
+                            EXPECT_EQ(yCbCr_P010.yCbCr.cstride, planeLayout.strideInBytes);
+                            EXPECT_EQ(yCbCr_P010.yCbCr.chroma_step, sampleIncrementInBytes);
+                        }
+
+                        if (yCbCr_P010.horizontalSubSampling == 0 &&
+                            yCbCr_P010.verticalSubSampling == 0) {
+                            yCbCr_P010.horizontalSubSampling = planeLayout.horizontalSubsampling;
+                            yCbCr_P010.verticalSubSampling = planeLayout.verticalSubsampling;
+                        } else {
+                            EXPECT_EQ(yCbCr_P010.horizontalSubSampling,
+                                      planeLayout.horizontalSubsampling);
+                            EXPECT_EQ(yCbCr_P010.verticalSubSampling,
+                                      planeLayout.verticalSubsampling);
+                        }
+
+                        if (type == PlaneLayoutComponentType::CB) {
+                            EXPECT_EQ(nullptr, yCbCr_P010.yCbCr.cb);
+                            yCbCr_P010.yCbCr.cb = tmpData;
+                            cb_offset = planeLayoutComponent.offsetInBits;
+                        } else {
+                            EXPECT_EQ(nullptr, yCbCr_P010.yCbCr.cr);
+                            yCbCr_P010.yCbCr.cr = tmpData;
+                            cr_offset = planeLayoutComponent.offsetInBits;
+                        }
+                        break;
+                    default:
+                        break;
+                };
+            }
+        }
+
+        EXPECT_EQ(cb_offset + bytesToBits(2), cr_offset);
+        EXPECT_NE(nullptr, yCbCr_P010.yCbCr.y);
+        EXPECT_NE(nullptr, yCbCr_P010.yCbCr.cb);
+        EXPECT_NE(nullptr, yCbCr_P010.yCbCr.cr);
+        return yCbCr_P010;
+    }
+};
+
+class GraphicsMapperStableCTests
+    : public GraphicsTestsBase,
+      public ::testing::TestWithParam<std::tuple<std::string, std::shared_ptr<IAllocator>>> {
+  public:
+    void SetUp() override { Initialize(std::get<1>(GetParam())); }
+
+    void TearDown() override {}
+};
+
+TEST_P(GraphicsMapperStableCTests, VersionChecks) {
+    ASSERT_NE(nullptr, getHalVersion()) << "Resolving ANDROID_HAL_MAPPER_VERSION symbol failed";
+    int32_t halVersion = *getHalVersion();
+    EXPECT_EQ(halVersion, AIMAPPER_VERSION_5) << "Unrecognized ANDROID_HAL_MAPPER_VERSION";
+    EXPECT_EQ(mapper()->version, AIMAPPER_VERSION_5) << "Unrecognized AIMapper::version";
+    EXPECT_EQ(halVersion, mapper()->version)
+            << "AIMapper version & ANDROID_HAL_MAPPER_VERSION don't agree";
+}
+
+TEST_P(GraphicsMapperStableCTests, AllV5CallbacksDefined) {
+    ASSERT_GE(mapper()->version, AIMAPPER_VERSION_5);
+
+    EXPECT_TRUE(mapper()->v5.importBuffer);
+    EXPECT_TRUE(mapper()->v5.freeBuffer);
+    EXPECT_TRUE(mapper()->v5.getTransportSize);
+    EXPECT_TRUE(mapper()->v5.lock);
+    EXPECT_TRUE(mapper()->v5.unlock);
+    EXPECT_TRUE(mapper()->v5.flushLockedBuffer);
+    EXPECT_TRUE(mapper()->v5.rereadLockedBuffer);
+    EXPECT_TRUE(mapper()->v5.getMetadata);
+    EXPECT_TRUE(mapper()->v5.getStandardMetadata);
+    EXPECT_TRUE(mapper()->v5.setMetadata);
+    EXPECT_TRUE(mapper()->v5.setStandardMetadata);
+    EXPECT_TRUE(mapper()->v5.listSupportedMetadataTypes);
+    EXPECT_TRUE(mapper()->v5.dumpBuffer);
+    EXPECT_TRUE(mapper()->v5.getReservedRegion);
+}
+
+TEST_P(GraphicsMapperStableCTests, DualLoadIsIdentical) {
+    ASSERT_GE(mapper()->version, AIMAPPER_VERSION_5);
+    AIMapper* secondMapper;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, getIMapperLoader()(&secondMapper));
+
+    EXPECT_EQ(secondMapper->v5.importBuffer, mapper()->v5.importBuffer);
+    EXPECT_EQ(secondMapper->v5.freeBuffer, mapper()->v5.freeBuffer);
+    EXPECT_EQ(secondMapper->v5.getTransportSize, mapper()->v5.getTransportSize);
+    EXPECT_EQ(secondMapper->v5.lock, mapper()->v5.lock);
+    EXPECT_EQ(secondMapper->v5.unlock, mapper()->v5.unlock);
+    EXPECT_EQ(secondMapper->v5.flushLockedBuffer, mapper()->v5.flushLockedBuffer);
+    EXPECT_EQ(secondMapper->v5.rereadLockedBuffer, mapper()->v5.rereadLockedBuffer);
+    EXPECT_EQ(secondMapper->v5.getMetadata, mapper()->v5.getMetadata);
+    EXPECT_EQ(secondMapper->v5.getStandardMetadata, mapper()->v5.getStandardMetadata);
+    EXPECT_EQ(secondMapper->v5.setMetadata, mapper()->v5.setMetadata);
+    EXPECT_EQ(secondMapper->v5.setStandardMetadata, mapper()->v5.setStandardMetadata);
+    EXPECT_EQ(secondMapper->v5.listSupportedMetadataTypes, mapper()->v5.listSupportedMetadataTypes);
+    EXPECT_EQ(secondMapper->v5.dumpBuffer, mapper()->v5.dumpBuffer);
+    EXPECT_EQ(secondMapper->v5.getReservedRegion, mapper()->v5.getReservedRegion);
+}
+
+TEST_P(GraphicsMapperStableCTests, CanAllocate) {
+    auto buffer = allocate({
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    });
+    ASSERT_NE(nullptr, buffer.get());
+    EXPECT_GE(buffer->stride(), 64);
+}
+
+TEST_P(GraphicsMapperStableCTests, ImportFreeBuffer) {
+    auto buffer = allocate({
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    });
+    ASSERT_NE(nullptr, buffer.get());
+    EXPECT_GE(buffer->stride(), 64);
+
+    {
+        auto import1 = buffer->import();
+        auto import2 = buffer->import();
+        EXPECT_TRUE(import1);
+        EXPECT_TRUE(import2);
+        EXPECT_NE(*import1, *import2);
+    }
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
+ */
+TEST_P(GraphicsMapperStableCTests, ImportFreeBufferSingleton) {
+    auto buffer = allocate({
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    });
+    ASSERT_NE(nullptr, buffer.get());
+    EXPECT_GE(buffer->stride(), 64);
+
+    buffer_handle_t bufferHandle = nullptr;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.importBuffer(buffer->rawHandle(), &bufferHandle));
+    ASSERT_NE(nullptr, bufferHandle);
+
+    AIMapper* secondMapper;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, getIMapperLoader()(&secondMapper));
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, secondMapper->v5.freeBuffer(bufferHandle));
+}
+
+/**
+ * Test IMapper::importBuffer with invalid buffers.
+ */
+TEST_P(GraphicsMapperStableCTests, ImportBufferNegative) {
+    native_handle_t* invalidHandle = nullptr;
+    buffer_handle_t bufferHandle = nullptr;
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.importBuffer(invalidHandle, &bufferHandle))
+            << "importBuffer with nullptr did not fail with BAD_BUFFER";
+
+    invalidHandle = native_handle_create(0, 0);
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.importBuffer(invalidHandle, &bufferHandle))
+            << "importBuffer with invalid handle did not fail with BAD_BUFFER";
+    native_handle_delete(invalidHandle);
+}
+
+/**
+ * Test IMapper::freeBuffer with invalid buffers.
+ */
+TEST_P(GraphicsMapperStableCTests, FreeBufferNegative) {
+    native_handle_t* bufferHandle = nullptr;
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.freeBuffer(bufferHandle))
+            << "freeBuffer with nullptr did not fail with BAD_BUFFER";
+
+    bufferHandle = native_handle_create(0, 0);
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.freeBuffer(bufferHandle))
+            << "freeBuffer with invalid handle did not fail with BAD_BUFFER";
+    native_handle_delete(bufferHandle);
+
+    auto buffer = allocateGeneric();
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.freeBuffer(buffer->rawHandle()))
+            << "freeBuffer with un-imported handle did not fail with BAD_BUFFER";
+}
+
+/**
+ * Test IMapper::lock and IMapper::unlock.
+ */
+TEST_P(GraphicsMapperStableCTests, LockUnlockBasic) {
+    constexpr auto usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN;
+    auto buffer = allocate({
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = usage,
+            .reservedSize = 0,
+    });
+    ASSERT_NE(nullptr, buffer.get());
+
+    // lock buffer for writing
+    const auto& info = buffer->info();
+    const auto stride = buffer->stride();
+    const ARect region{0, 0, info.width, info.height};
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE,
+              mapper()->v5.lock(*handle, static_cast<int64_t>(usage), region, -1, (void**)&data));
+
+    // RGBA_8888
+    fillRGBA8888(data, info.height, stride * 4, info.width * 4);
+
+    int releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+
+    // lock again for reading
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(usage), region,
+                                                     releaseFence, (void**)&data));
+    releaseFence = -1;
+
+    ASSERT_NO_FATAL_FAILURE(verifyRGBA8888(*handle, data, info.height, stride * 4, info.width * 4));
+
+    releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+    }
+}
+
+/**
+ *  Test multiple operations associated with different color formats
+ */
+TEST_P(GraphicsMapperStableCTests, Lock_YCRCB_420_SP) {
+    BufferDescriptorInfo info{
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::YCRCB_420_SP,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    };
+    auto buffer = allocate(info);
+    if (!buffer) {
+        ASSERT_FALSE(isSupported(info));
+        GTEST_SUCCEED() << "YCRCB_420_SP format is unsupported";
+        return;
+    }
+
+    // lock buffer for writing
+    const ARect region{0, 0, info.width, info.height};
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, -1, (void**)&data));
+
+    android_ycbcr yCbCr;
+    int64_t hSubsampling = 0;
+    int64_t vSubsampling = 0;
+    ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+    constexpr uint32_t kCbCrSubSampleFactor = 2;
+    ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
+    ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
+
+    auto cbData = static_cast<uint8_t*>(yCbCr.cb);
+    auto crData = static_cast<uint8_t*>(yCbCr.cr);
+    ASSERT_EQ(crData + 1, cbData);
+    ASSERT_EQ(2, yCbCr.chroma_step);
+
+    fillYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+    int releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+
+    // lock again for reading
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, releaseFence, (void**)&data));
+    releaseFence = -1;
+
+    ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+    verifyYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+    releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, YV12SubsampleMetadata) {
+    BufferDescriptorInfo info{
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::YV12,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    };
+    auto buffer = allocate(info);
+    ASSERT_NE(nullptr, buffer.get());
+
+    // lock buffer for writing
+    const ARect region{0, 0, info.width, info.height};
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, -1, (void**)&data));
+
+    auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*handle);
+    ASSERT_TRUE(decodeResult.has_value());
+    const auto& planeLayouts = *decodeResult;
+
+    ASSERT_EQ(3, planeLayouts.size());
+
+    auto yPlane = planeLayouts[0];
+    auto crPlane = planeLayouts[1];
+    auto cbPlane = planeLayouts[2];
+
+    constexpr uint32_t kCbCrSubSampleFactor = 2;
+    EXPECT_EQ(kCbCrSubSampleFactor, crPlane.horizontalSubsampling);
+    EXPECT_EQ(kCbCrSubSampleFactor, crPlane.verticalSubsampling);
+
+    EXPECT_EQ(kCbCrSubSampleFactor, cbPlane.horizontalSubsampling);
+    EXPECT_EQ(kCbCrSubSampleFactor, cbPlane.verticalSubsampling);
+
+    const long chromaSampleWidth = info.width / kCbCrSubSampleFactor;
+    const long chromaSampleHeight = info.height / kCbCrSubSampleFactor;
+
+    EXPECT_EQ(info.width, yPlane.widthInSamples);
+    EXPECT_EQ(info.height, yPlane.heightInSamples);
+
+    EXPECT_EQ(chromaSampleWidth, crPlane.widthInSamples);
+    EXPECT_EQ(chromaSampleHeight, crPlane.heightInSamples);
+
+    EXPECT_EQ(chromaSampleWidth, cbPlane.widthInSamples);
+    EXPECT_EQ(chromaSampleHeight, cbPlane.heightInSamples);
+
+    EXPECT_LE(crPlane.widthInSamples, crPlane.strideInBytes);
+    EXPECT_LE(cbPlane.widthInSamples, cbPlane.strideInBytes);
+
+    int releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_YV12) {
+    BufferDescriptorInfo info{
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::YV12,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    };
+    auto buffer = allocate(info);
+    ASSERT_NE(nullptr, buffer.get());
+
+    // lock buffer for writing
+    const ARect region{0, 0, info.width, info.height};
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, -1, (void**)&data));
+
+    android_ycbcr yCbCr;
+    int64_t hSubsampling = 0;
+    int64_t vSubsampling = 0;
+    ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+    constexpr uint32_t kCbCrSubSampleFactor = 2;
+    ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
+    ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
+
+    auto cbData = static_cast<uint8_t*>(yCbCr.cb);
+    auto crData = static_cast<uint8_t*>(yCbCr.cr);
+    ASSERT_EQ(crData + yCbCr.cstride * info.height / vSubsampling, cbData);
+    ASSERT_EQ(1, yCbCr.chroma_step);
+
+    fillYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+    int releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+
+    // lock again for reading
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, releaseFence, (void**)&data));
+    releaseFence = -1;
+
+    ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+    verifyYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_YCBCR_420_888) {
+    BufferDescriptorInfo info{
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::YCBCR_420_888,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    };
+    auto buffer = allocate(info);
+    ASSERT_NE(nullptr, buffer.get());
+
+    // lock buffer for writing
+    const ARect region{0, 0, info.width, info.height};
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, -1, (void**)&data));
+
+    android_ycbcr yCbCr;
+    int64_t hSubsampling = 0;
+    int64_t vSubsampling = 0;
+    ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+    constexpr uint32_t kCbCrSubSampleFactor = 2;
+    ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
+    ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
+
+    fillYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+    int releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+
+    // lock again for reading
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, releaseFence, (void**)&data));
+    releaseFence = -1;
+
+    ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
+
+    verifyYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
+
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_RAW10) {
+    BufferDescriptorInfo info{
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RAW10,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    };
+    auto buffer = allocate(info);
+    if (!buffer) {
+        ASSERT_FALSE(isSupported(info));
+        GTEST_SUCCEED() << "RAW10 format is unsupported";
+        return;
+    }
+
+    // lock buffer for writing
+    const ARect region{0, 0, info.width, info.height};
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, -1, (void**)&data));
+
+    auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*handle);
+    ASSERT_TRUE(decodeResult.has_value());
+    const auto& planeLayouts = *decodeResult;
+
+    ASSERT_EQ(1, planeLayouts.size());
+    auto planeLayout = planeLayouts[0];
+
+    EXPECT_EQ(0, planeLayout.sampleIncrementInBits);
+    EXPECT_EQ(1, planeLayout.horizontalSubsampling);
+    EXPECT_EQ(1, planeLayout.verticalSubsampling);
+
+    ASSERT_EQ(1, planeLayout.components.size());
+    auto planeLayoutComponent = planeLayout.components[0];
+
+    EXPECT_EQ(PlaneLayoutComponentType::RAW,
+              static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
+    EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
+    EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
+
+    int releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_RAW12) {
+    BufferDescriptorInfo info{
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RAW12,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    };
+    auto buffer = allocate(info);
+    if (!buffer) {
+        ASSERT_FALSE(isSupported(info));
+        GTEST_SUCCEED() << "RAW12 format is unsupported";
+        return;
+    }
+
+    // lock buffer for writing
+    const ARect region{0, 0, info.width, info.height};
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, -1, (void**)&data));
+
+    auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*handle);
+    ASSERT_TRUE(decodeResult.has_value());
+    const auto& planeLayouts = *decodeResult;
+
+    ASSERT_EQ(1, planeLayouts.size());
+    auto planeLayout = planeLayouts[0];
+
+    EXPECT_EQ(0, planeLayout.sampleIncrementInBits);
+    EXPECT_EQ(1, planeLayout.horizontalSubsampling);
+    EXPECT_EQ(1, planeLayout.verticalSubsampling);
+
+    ASSERT_EQ(1, planeLayout.components.size());
+    auto planeLayoutComponent = planeLayout.components[0];
+
+    EXPECT_EQ(PlaneLayoutComponentType::RAW,
+              static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
+    EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
+    EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
+
+    int releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, Lock_YCBCR_P010) {
+    BufferDescriptorInfo info{
+            .name = {"VTS_TEMP"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::YCBCR_P010,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    };
+    auto buffer = allocate(info);
+    if (!buffer) {
+        ASSERT_FALSE(isSupported(info));
+        GTEST_SUCCEED() << "YCBCR_P010 format is unsupported";
+        return;
+    }
+
+    // lock buffer for writing
+    const ARect region{0, 0, info.width, info.height};
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                     region, -1, (void**)&data));
+
+    YCbCr yCbCr;
+    ASSERT_NO_FATAL_FAILURE(yCbCr = getAndroidYCbCr_P010(*handle, data));
+
+    constexpr uint32_t kCbCrSubSampleFactor = 2;
+    ASSERT_EQ(kCbCrSubSampleFactor, yCbCr.horizontalSubSampling);
+    ASSERT_EQ(kCbCrSubSampleFactor, yCbCr.verticalSubSampling);
+
+    ASSERT_EQ(0, info.height % 2);
+
+    // fill the data
+    fillYCbCrData(yCbCr.yCbCr, info.width, info.height, yCbCr.horizontalSubSampling,
+                  yCbCr.verticalSubSampling);
+    // verify the YCbCr data
+    verifyYCbCrData(yCbCr.yCbCr, info.width, info.height, yCbCr.horizontalSubSampling,
+                    yCbCr.verticalSubSampling);
+
+    int releaseFence = -1;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, LockBadAccessRegion) {
+    auto buffer = allocateGeneric();
+    ASSERT_NE(nullptr, buffer);
+    const auto& info = buffer->info();
+
+    // lock buffer for writing
+    const ARect region{0, 0, info.width * 2, info.height * 2};
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_VALUE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+                                                          region, -1, (void**)&data));
+}
+
+TEST_P(GraphicsMapperStableCTests, UnlockNegative) {
+    native_handle_t* invalidHandle = nullptr;
+    int releaseFence = -1;
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(invalidHandle, &releaseFence))
+            << "unlock with nullptr did not fail with BAD_BUFFER";
+
+    invalidHandle = native_handle_create(0, 0);
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(invalidHandle, &releaseFence))
+            << "unlock with invalid handle did not fail with BAD_BUFFER";
+    native_handle_delete(invalidHandle);
+
+    auto buffer = allocateGeneric();
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(buffer->rawHandle(), &releaseFence))
+            << "unlock with un-imported handle did not fail with BAD_BUFFER";
+}
+
+TEST_P(GraphicsMapperStableCTests, UnlockNotImported) {
+    int releaseFence = -1;
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(buffer->rawHandle(), &releaseFence))
+            << "unlock with un-imported handle did not fail with BAD_BUFFER";
+}
+
+TEST_P(GraphicsMapperStableCTests, UnlockNotLocked) {
+    int releaseFence = -1;
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(*bufferHandle, &releaseFence))
+            << "unlock with unlocked handle did not fail with BAD_BUFFER";
+}
+
+TEST_P(GraphicsMapperStableCTests, LockUnlockNested) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    const ARect region{0, 0, buffer->info().width, buffer->info().height};
+    auto usage = static_cast<int64_t>(buffer->info().usage);
+    auto handle = buffer->import();
+    uint8_t* data = nullptr;
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, usage, region, -1, (void**)&data));
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, usage, region, -1, (void**)&data))
+            << "Second lock failed";
+    int releaseFence = -1;
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+        releaseFence = -1;
+    }
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence))
+            << "Second unlock failed";
+    if (releaseFence != -1) {
+        close(releaseFence);
+        releaseFence = -1;
+    }
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(*handle, &releaseFence))
+            << "Third, unmatched, unlock should have failed with BAD_BUFFER";
+}
+
+TEST_P(GraphicsMapperStableCTests, FlushRereadBasic) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    const auto& info = buffer->info();
+    const auto stride = buffer->stride();
+    const ARect region{0, 0, buffer->info().width, buffer->info().height};
+
+    auto writeHandle = buffer->import();
+    auto readHandle = buffer->import();
+    ASSERT_TRUE(writeHandle && readHandle);
+
+    // lock buffer for writing
+
+    uint8_t* writeData;
+    EXPECT_EQ(AIMAPPER_ERROR_NONE,
+              mapper()->v5.lock(*writeHandle, static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN),
+                                region, -1, (void**)&writeData));
+
+    uint8_t* readData;
+    EXPECT_EQ(AIMAPPER_ERROR_NONE,
+              mapper()->v5.lock(*readHandle, static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN),
+                                region, -1, (void**)&readData));
+
+    fillRGBA8888(writeData, info.height, stride * 4, info.width * 4);
+
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.flushLockedBuffer(*writeHandle));
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.rereadLockedBuffer(*readHandle));
+
+    ASSERT_NO_FATAL_FAILURE(
+            verifyRGBA8888(*readHandle, readData, info.height, stride * 4, info.width * 4));
+
+    int releaseFence = -1;
+
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*readHandle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+        releaseFence = -1;
+    }
+
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*writeHandle, &releaseFence));
+    if (releaseFence != -1) {
+        close(releaseFence);
+        releaseFence = -1;
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, FlushLockedBufferBadBuffer) {
+    // Amazingly this is enough to make the compiler happy even though flushLockedBuffer
+    // is _Nonnull :shrug:
+    buffer_handle_t badBuffer = nullptr;
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.flushLockedBuffer(badBuffer));
+}
+
+TEST_P(GraphicsMapperStableCTests, RereadLockedBufferBadBuffer) {
+    buffer_handle_t badBuffer = nullptr;
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.rereadLockedBuffer(badBuffer));
+}
+
+TEST_P(GraphicsMapperStableCTests, GetBufferId) {
+    auto buffer = allocateGeneric();
+    auto bufferHandle = buffer->import();
+    auto bufferId = getStandardMetadata<StandardMetadataType::BUFFER_ID>(*bufferHandle);
+    ASSERT_TRUE(bufferId.has_value());
+
+    auto buffer2 = allocateGeneric();
+    auto bufferHandle2 = buffer2->import();
+    auto bufferId2 = getStandardMetadata<StandardMetadataType::BUFFER_ID>(*bufferHandle2);
+    ASSERT_TRUE(bufferId2.has_value());
+
+    EXPECT_NE(*bufferId, *bufferId2);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetName) {
+    auto buffer = allocate({
+            .name = {"Hello, World!"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    });
+    auto bufferHandle = buffer->import();
+    auto name = getStandardMetadata<StandardMetadataType::NAME>(*bufferHandle);
+    ASSERT_TRUE(name.has_value());
+    EXPECT_EQ(*name, "Hello, World!");
+}
+
+TEST_P(GraphicsMapperStableCTests, GetWidthHeight) {
+    auto buffer = allocate({
+            .name = {"Hello, World!"},
+            .width = 64,
+            .height = 128,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    });
+    auto bufferHandle = buffer->import();
+    auto value = getStandardMetadata<StandardMetadataType::WIDTH>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(*value, 64);
+    value = getStandardMetadata<StandardMetadataType::HEIGHT>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(*value, 128);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetLayerCount) {
+    auto buffer = allocateGeneric();
+    auto bufferHandle = buffer->import();
+    auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(*value, buffer->info().layerCount);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetPixelFormatRequested) {
+    auto buffer = allocateGeneric();
+    auto bufferHandle = buffer->import();
+    auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(*value, buffer->info().format);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetPixelFormatFourCC) {
+    auto buffer = allocate({
+            .name = {"Hello, World!"},
+            .width = 64,
+            .height = 128,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    });
+    {
+        auto bufferHandle = buffer->import();
+        auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(*bufferHandle);
+        ASSERT_TRUE(value.has_value());
+        EXPECT_EQ(*value, DRM_FORMAT_ABGR8888);
+    }
+
+    buffer = allocate({
+            .name = {"yv12"},
+            .width = 64,
+            .height = 128,
+            .layerCount = 1,
+            .format = PixelFormat::YV12,
+            .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
+            .reservedSize = 0,
+    });
+    {
+        auto bufferHandle = buffer->import();
+        auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(*bufferHandle);
+        ASSERT_TRUE(value.has_value());
+        EXPECT_EQ(*value, DRM_FORMAT_YVU420);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetPixelFormatModifier) {
+    auto buffer = allocateGeneric();
+    auto bufferHandle = buffer->import();
+    auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    // Only the upper 8-bits are defined and is just the vendor ID, the lower 56 bits are
+    // then vendor specific. So there's not anything useful to assert here beyond just that
+    // we successfully queried a value
+}
+
+TEST_P(GraphicsMapperStableCTests, GetUsage) {
+    auto buffer = allocateGeneric();
+    auto bufferHandle = buffer->import();
+    auto value = getStandardMetadata<StandardMetadataType::USAGE>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(buffer->info().usage, *value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetAllocationSize) {
+    auto buffer = allocateGeneric();
+    auto bufferHandle = buffer->import();
+    auto value = getStandardMetadata<StandardMetadataType::ALLOCATION_SIZE>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    const auto estimatedSize = buffer->stride() * buffer->info().height * 4;
+    // This buffer has CPU usage, so we expect at least stride * height * 4 since it should be
+    // generally linear uncompressed.
+    EXPECT_GE(*value, estimatedSize)
+            << "Expected allocation size to be at least stride * height * 4bpp";
+    // Might need refining, but hopefully this a generous-enough upper-bound?
+    EXPECT_LT(*value, estimatedSize * 2)
+            << "Expected allocation size to less than double stride * height * 4bpp";
+}
+
+TEST_P(GraphicsMapperStableCTests, GetProtectedContent) {
+    const BufferDescriptorInfo info{
+            .name = {"prot8888"},
+            .width = 64,
+            .height = 64,
+            .layerCount = 1,
+            .format = PixelFormat::RGBA_8888,
+            .usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY,
+            .reservedSize = 0,
+    };
+    auto buffer = allocate(info);
+    if (!buffer) {
+        ASSERT_FALSE(isSupported(info))
+                << "Allocation of trivial sized buffer failed, so isSupported() must be false";
+        GTEST_SUCCEED() << "PROTECTED RGBA_8888 is unsupported";
+        return;
+    }
+    auto bufferHandle = buffer->import();
+    auto value = getStandardMetadata<StandardMetadataType::PROTECTED_CONTENT>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(*value, 1);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetCompression) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(gralloc4::Compression_None.name, value->name);
+    EXPECT_EQ(gralloc4::Compression_None.value, value->value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetInterlaced) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::INTERLACED>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(gralloc4::Interlaced_None.name, value->name);
+    EXPECT_EQ(gralloc4::Interlaced_None.value, value->value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetChromaSiting) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::CHROMA_SITING>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(gralloc4::ChromaSiting_None.name, value->name);
+    EXPECT_EQ(gralloc4::ChromaSiting_None.value, value->value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetPlaneLayouts) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    ASSERT_NO_FATAL_FAILURE(verifyRGBA8888PlaneLayouts(*value));
+}
+
+TEST_P(GraphicsMapperStableCTests, GetCrop) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::CROP>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(1, value->size());
+    const Rect expected{0, 0, buffer->info().width, buffer->info().height};
+    EXPECT_EQ(expected, value->at(0));
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSetDataspace) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::DATASPACE>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(Dataspace::UNKNOWN, *value);
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, setStandardMetadata<StandardMetadataType::DATASPACE>(
+                                           *bufferHandle, Dataspace::DISPLAY_P3));
+    value = getStandardMetadata<StandardMetadataType::DATASPACE>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(Dataspace::DISPLAY_P3, *value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSetBlendMode) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(BlendMode::INVALID, *value);
+    EXPECT_EQ(AIMAPPER_ERROR_NONE, setStandardMetadata<StandardMetadataType::BLEND_MODE>(
+                                           *bufferHandle, BlendMode::COVERAGE));
+    value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(BlendMode::COVERAGE, *value);
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSetSmpte2086) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_FALSE(value->has_value());
+
+    // TODO: Maybe use something resembling real values, but validation isn't supposed to happen
+    // here anyway so :shrug:
+    const Smpte2086 awesomeHdr{
+            XyColor{1.f, 1.f},      XyColor{2.f, 2.f}, XyColor{3.f, 3.f},
+            XyColor{400.f, 1000.f}, 100000.0f,         0.0001f,
+    };
+    EXPECT_EQ(AIMAPPER_ERROR_NONE,
+              setStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle, awesomeHdr));
+    value = getStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    ASSERT_TRUE(value->has_value());
+    EXPECT_EQ(awesomeHdr, *value);
+
+    EXPECT_EQ(AIMAPPER_ERROR_NONE,
+              setStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle, std::nullopt));
+    value = getStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_FALSE(value->has_value());
+}
+
+TEST_P(GraphicsMapperStableCTests, GetCta861_3) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_FALSE(value->has_value());
+
+    const Cta861_3 genericHlgish{1000.f, 140.f};
+    EXPECT_EQ(AIMAPPER_ERROR_NONE,
+              setStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle, genericHlgish));
+    value = getStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    ASSERT_TRUE(value->has_value());
+    EXPECT_EQ(genericHlgish, *value);
+
+    EXPECT_EQ(AIMAPPER_ERROR_NONE,
+              setStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle, std::nullopt));
+    value = getStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_FALSE(value->has_value());
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSmpte2094_10) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_10>(*bufferHandle);
+    if (value.has_value()) {
+        EXPECT_FALSE(value->has_value());
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetSmpte2094_40) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_40>(*bufferHandle);
+    if (value.has_value()) {
+        EXPECT_FALSE(value->has_value());
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetStride) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    auto value = getStandardMetadata<StandardMetadataType::STRIDE>(*bufferHandle);
+    ASSERT_TRUE(value.has_value());
+    EXPECT_EQ(buffer->stride(), *value);
+}
+
+TEST_P(GraphicsMapperStableCTests, SupportsRequiredGettersSetters) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    const AIMapper_MetadataTypeDescription* descriptions = nullptr;
+    size_t descriptionCount = 0;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE,
+              mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
+    std::vector<StandardMetadataType> requiredGetters = {
+            StandardMetadataType::BUFFER_ID,
+            StandardMetadataType::NAME,
+            StandardMetadataType::WIDTH,
+            StandardMetadataType::HEIGHT,
+            StandardMetadataType::LAYER_COUNT,
+            StandardMetadataType::PIXEL_FORMAT_REQUESTED,
+            StandardMetadataType::PIXEL_FORMAT_FOURCC,
+            StandardMetadataType::PIXEL_FORMAT_MODIFIER,
+            StandardMetadataType::USAGE,
+            StandardMetadataType::ALLOCATION_SIZE,
+            StandardMetadataType::PROTECTED_CONTENT,
+            StandardMetadataType::COMPRESSION,
+            StandardMetadataType::INTERLACED,
+            StandardMetadataType::CHROMA_SITING,
+            StandardMetadataType::PLANE_LAYOUTS,
+            StandardMetadataType::CROP,
+            StandardMetadataType::DATASPACE,
+            StandardMetadataType::BLEND_MODE,
+            StandardMetadataType::SMPTE2086,
+            StandardMetadataType::CTA861_3,
+            StandardMetadataType::STRIDE,
+    };
+
+    std::vector<StandardMetadataType> requiredSetters = {
+            StandardMetadataType::DATASPACE,
+            StandardMetadataType::BLEND_MODE,
+            StandardMetadataType::SMPTE2086,
+            StandardMetadataType::CTA861_3,
+    };
+
+    for (int i = 0; i < descriptionCount; i++) {
+        const auto& it = descriptions[i];
+        if (isStandardMetadata(it.metadataType)) {
+            EXPECT_GT(it.metadataType.value, static_cast<int64_t>(StandardMetadataType::INVALID));
+            EXPECT_LT(it.metadataType.value,
+                      ndk::internal::enum_values<StandardMetadataType>.size());
+
+            if (it.isGettable) {
+                std::erase(requiredGetters,
+                           static_cast<StandardMetadataType>(it.metadataType.value));
+            }
+            if (it.isSettable) {
+                std::erase(requiredSetters,
+                           static_cast<StandardMetadataType>(it.metadataType.value));
+            }
+        } else {
+            EXPECT_NE(nullptr, it.description) << "Non-standard metadata must have a description";
+            int len = strlen(it.description);
+            EXPECT_GE(len, 0) << "Non-standard metadata must have a description";
+        }
+    }
+
+    EXPECT_EQ(0, requiredGetters.size()) << "Missing required getters" << toString(requiredGetters);
+    EXPECT_EQ(0, requiredSetters.size()) << "Missing required setters" << toString(requiredSetters);
+}
+
+/*
+ * Test that verifies that if the optional StandardMetadataTypes have getters, they have
+ * the required setters as well
+ */
+TEST_P(GraphicsMapperStableCTests, CheckRequiredSettersIfHasGetters) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    const AIMapper_MetadataTypeDescription* descriptions = nullptr;
+    size_t descriptionCount = 0;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE,
+              mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
+
+    for (int i = 0; i < descriptionCount; i++) {
+        const auto& it = descriptions[i];
+        if (isStandardMetadata(it.metadataType)) {
+            const auto type = static_cast<StandardMetadataType>(it.metadataType.value);
+            switch (type) {
+                case StandardMetadataType::SMPTE2094_10:
+                case StandardMetadataType::SMPTE2094_40:
+                    if (it.isGettable) {
+                        EXPECT_TRUE(it.isSettable)
+                                << "Type " << toString(type) << " must be settable if gettable";
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, ListSupportedWorks) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+    const AIMapper_MetadataTypeDescription* descriptions = nullptr;
+    size_t descriptionCount = 0;
+    ASSERT_EQ(AIMAPPER_ERROR_NONE,
+              mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
+
+    std::vector<uint8_t> metadataBuffer;
+    auto get = [&](AIMapper_MetadataType metadataType) -> int32_t {
+        int32_t size = mapper()->v5.getMetadata(*bufferHandle, metadataType, nullptr, 0);
+        if (size >= 0) {
+            metadataBuffer.resize(size);
+            size = mapper()->v5.getMetadata(*bufferHandle, metadataType, metadataBuffer.data(),
+                                            metadataBuffer.size());
+            EXPECT_EQ(size, metadataBuffer.size());
+        }
+        return size;
+    };
+
+    for (int i = 0; i < descriptionCount; i++) {
+        const auto& it = descriptions[i];
+        if (!isStandardMetadata(it.metadataType)) {
+            continue;
+        }
+        if (!it.isGettable) {
+            EXPECT_FALSE(it.isSettable)
+                    << "StandardMetadata that isn't gettable must not be settable";
+            continue;
+        }
+        EXPECT_GE(get(it.metadataType), 0)
+                << "Get failed for claimed supported getter of "
+                << toString(static_cast<StandardMetadataType>(it.metadataType.value));
+        if (it.isSettable) {
+            EXPECT_EQ(AIMAPPER_ERROR_NONE,
+                      mapper()->v5.setMetadata(*bufferHandle, it.metadataType,
+                                               metadataBuffer.data(), metadataBuffer.size()))
+                    << "Failed to set metadata for "
+                    << toString(static_cast<StandardMetadataType>(it.metadataType.value));
+        }
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetMetadataBadValue) {
+    auto get = [this](StandardMetadataType type) -> AIMapper_Error {
+        // This is a _Nonnull parameter, but this is enough obfuscation to fool the linter
+        buffer_handle_t buffer = nullptr;
+        int32_t ret =
+                mapper()->v5.getStandardMetadata(buffer, static_cast<int64_t>(type), nullptr, 0);
+        return (ret < 0) ? (AIMapper_Error)-ret : AIMAPPER_ERROR_NONE;
+    };
+
+    for (auto type : ndk::enum_range<StandardMetadataType>()) {
+        if (type == StandardMetadataType::INVALID) {
+            continue;
+        }
+        EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, get(type)) << "Wrong error for " << toString(type);
+    }
+}
+
+TEST_P(GraphicsMapperStableCTests, GetUnsupportedMetadata) {
+    auto buffer = allocateGeneric();
+    ASSERT_TRUE(buffer);
+    auto bufferHandle = buffer->import();
+    ASSERT_TRUE(bufferHandle);
+
+    int result = mapper()->v5.getMetadata(*bufferHandle, {"Fake", 1}, nullptr, 0);
+    EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
+
+    result = mapper()->v5.getStandardMetadata(
+            *bufferHandle, static_cast<int64_t>(StandardMetadataType::INVALID), nullptr, 0);
+    EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
+
+    constexpr int64_t unknownStandardType = ndk::internal::enum_values<StandardMetadataType>.size();
+    result = mapper()->v5.getStandardMetadata(*bufferHandle, unknownStandardType, nullptr, 0);
+    EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
+}
+
+std::vector<std::tuple<std::string, std::shared_ptr<IAllocator>>> getIAllocatorsAtLeastVersion(
+        int32_t minVersion) {
+    auto instanceNames = getAidlHalInstanceNames(IAllocator::descriptor);
+    std::vector<std::tuple<std::string, std::shared_ptr<IAllocator>>> filteredInstances;
+    filteredInstances.reserve(instanceNames.size());
+    for (const auto& name : instanceNames) {
+        auto allocator =
+                IAllocator::fromBinder(ndk::SpAIBinder(AServiceManager_checkService(name.c_str())));
+        int32_t version = 0;
+        if (allocator->getInterfaceVersion(&version).isOk()) {
+            if (version >= minVersion) {
+                filteredInstances.emplace_back(name, std::move(allocator));
+            }
+        }
+    }
+    return filteredInstances;
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperStableCTests);
+INSTANTIATE_TEST_CASE_P(PerInstance, GraphicsMapperStableCTests,
+                        testing::ValuesIn(getIAllocatorsAtLeastVersion(2)),
+                        [](auto info) -> std::string {
+                            std::string name =
+                                    std::to_string(info.index) + "/" + std::get<0>(info.param);
+                            return Sanitize(name);
+                        });
\ No newline at end of file
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index f0cd33f..e288f17 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -36,23 +36,24 @@
             enabled: true,
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: [],
         },
+        {
+            version: "2",
+            imports: [],
+        },
+
     ],
+    frozen: true,
 
 }
 
-cc_library {
-    name: "android.hardware.health-translate-ndk",
+cc_defaults {
+    name: "android.hardware.health-translate-ndk_defaults",
     vendor_available: true,
     recovery_available: true,
     host_supported: true,
@@ -60,7 +61,6 @@
     shared_libs: [
         "libbinder_ndk",
         "libhidlbase",
-        "android.hardware.health-V1-ndk",
         "android.hardware.health@2.0",
         "android.hardware.health@2.1",
     ],
@@ -76,11 +76,28 @@
     },
 }
 
+cc_library {
+    name: "android.hardware.health-translate-ndk",
+    defaults: ["android.hardware.health-translate-ndk_defaults"],
+    shared_libs: [
+        "android.hardware.health-V2-ndk",
+    ],
+}
+
+// TODO(b/251425963): remove when android.hardware.health is upgraded to V2.
+cc_library {
+    name: "android.hardware.health-translate-V1-ndk",
+    defaults: ["android.hardware.health-translate-ndk_defaults"],
+    shared_libs: [
+        "android.hardware.health-V1-ndk",
+    ],
+}
+
 java_library {
     name: "android.hardware.health-translate-java",
     srcs: ["android/hardware/health/Translate.java"],
     libs: [
-        "android.hardware.health-V1-java",
+        "android.hardware.health-V2-java",
         "android.hardware.health-V2.0-java",
         "android.hardware.health-V2.1-java",
     ],
diff --git a/health/aidl/OWNERS b/health/aidl/OWNERS
index fcad499..0f1bee2 100644
--- a/health/aidl/OWNERS
+++ b/health/aidl/OWNERS
@@ -1,4 +1,5 @@
 # Bug component: 30545
 elsk@google.com
 smoreland@google.com
-stayfan@google.com
+wjack@google.com
+apelosi@google.com
diff --git a/health/aidl/aidl_api/android.hardware.health/2/.hash b/health/aidl/aidl_api/android.hardware.health/2/.hash
new file mode 100644
index 0000000..384f780
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/.hash
@@ -0,0 +1 @@
+d92c40b74b56341959d2ad70271145fdbd70b5c7
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryCapacityLevel.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryCapacityLevel.aidl
new file mode 100644
index 0000000..4d70588
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryCapacityLevel.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.health;
+@Backing(type="int") @VintfStability
+enum BatteryCapacityLevel {
+  UNSUPPORTED = (-1) /* -1 */,
+  UNKNOWN,
+  CRITICAL,
+  LOW,
+  NORMAL,
+  HIGH,
+  FULL,
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryChargingPolicy.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryChargingPolicy.aidl
new file mode 100644
index 0000000..42fbf95
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryChargingPolicy.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.health;
+@Backing(type="int") @VintfStability
+enum BatteryChargingPolicy {
+  INVALID = 0,
+  DEFAULT = 1,
+  LONG_LIFE = 2,
+  ADAPTIVE = 3,
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryChargingState.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryChargingState.aidl
new file mode 100644
index 0000000..e21eb28
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryChargingState.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.health;
+@Backing(type="int") @VintfStability
+enum BatteryChargingState {
+  INVALID = 0,
+  NORMAL = 1,
+  TOO_COLD = 2,
+  TOO_HOT = 3,
+  LONG_LIFE = 4,
+  ADAPTIVE = 5,
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryHealth.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryHealth.aidl
new file mode 100644
index 0000000..8d13198
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryHealth.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.health;
+@Backing(type="int") @VintfStability
+enum BatteryHealth {
+  UNKNOWN = 1,
+  GOOD = 2,
+  OVERHEAT = 3,
+  DEAD = 4,
+  OVER_VOLTAGE = 5,
+  UNSPECIFIED_FAILURE = 6,
+  COLD = 7,
+  FAIR = 8,
+  NOT_AVAILABLE = 11,
+  INCONSISTENT = 12,
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryHealthData.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryHealthData.aidl
new file mode 100644
index 0000000..2dd01b1
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryHealthData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.health;
+@VintfStability
+parcelable BatteryHealthData {
+  long batteryManufacturingDateSeconds;
+  long batteryFirstUsageSeconds;
+  long batteryStateOfHealth;
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryStatus.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryStatus.aidl
new file mode 100644
index 0000000..340b2ec
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/BatteryStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.health;
+@Backing(type="int") @VintfStability
+enum BatteryStatus {
+  UNKNOWN = 1,
+  CHARGING = 2,
+  DISCHARGING = 3,
+  NOT_CHARGING = 4,
+  FULL = 5,
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/DiskStats.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/DiskStats.aidl
new file mode 100644
index 0000000..5aa5890
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/DiskStats.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.health;
+@VintfStability
+parcelable DiskStats {
+  long reads;
+  long readMerges;
+  long readSectors;
+  long readTicks;
+  long writes;
+  long writeMerges;
+  long writeSectors;
+  long writeTicks;
+  long ioInFlight;
+  long ioTicks;
+  long ioInQueue;
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/HealthInfo.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/HealthInfo.aidl
new file mode 100644
index 0000000..bfa1475
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/HealthInfo.aidl
@@ -0,0 +1,64 @@
+/*
+ * 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.health;
+@VintfStability
+parcelable HealthInfo {
+  boolean chargerAcOnline;
+  boolean chargerUsbOnline;
+  boolean chargerWirelessOnline;
+  boolean chargerDockOnline;
+  int maxChargingCurrentMicroamps;
+  int maxChargingVoltageMicrovolts;
+  android.hardware.health.BatteryStatus batteryStatus;
+  android.hardware.health.BatteryHealth batteryHealth;
+  boolean batteryPresent;
+  int batteryLevel;
+  int batteryVoltageMillivolts;
+  int batteryTemperatureTenthsCelsius;
+  int batteryCurrentMicroamps;
+  int batteryCycleCount;
+  int batteryFullChargeUah;
+  int batteryChargeCounterUah;
+  String batteryTechnology;
+  int batteryCurrentAverageMicroamps;
+  android.hardware.health.DiskStats[] diskStats;
+  android.hardware.health.StorageInfo[] storageInfos;
+  android.hardware.health.BatteryCapacityLevel batteryCapacityLevel;
+  long batteryChargeTimeToFullNowSeconds;
+  int batteryFullChargeDesignCapacityUah;
+  android.hardware.health.BatteryChargingState chargingState;
+  android.hardware.health.BatteryChargingPolicy chargingPolicy;
+  @nullable android.hardware.health.BatteryHealthData batteryHealthData;
+  const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = (-1) /* -1 */;
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/IHealth.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/IHealth.aidl
new file mode 100644
index 0000000..b49dfff
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/IHealth.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.health;
+@VintfStability
+interface IHealth {
+  void registerCallback(in android.hardware.health.IHealthInfoCallback callback);
+  void unregisterCallback(in android.hardware.health.IHealthInfoCallback callback);
+  void update();
+  int getChargeCounterUah();
+  int getCurrentNowMicroamps();
+  int getCurrentAverageMicroamps();
+  int getCapacity();
+  long getEnergyCounterNwh();
+  android.hardware.health.BatteryStatus getChargeStatus();
+  android.hardware.health.StorageInfo[] getStorageInfo();
+  android.hardware.health.DiskStats[] getDiskStats();
+  android.hardware.health.HealthInfo getHealthInfo();
+  void setChargingPolicy(android.hardware.health.BatteryChargingPolicy in_value);
+  android.hardware.health.BatteryChargingPolicy getChargingPolicy();
+  android.hardware.health.BatteryHealthData getBatteryHealthData();
+  const int STATUS_UNKNOWN = 2;
+  const int STATUS_CALLBACK_DIED = 4;
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/IHealthInfoCallback.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/IHealthInfoCallback.aidl
new file mode 100644
index 0000000..1b6366f
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/IHealthInfoCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.health;
+@VintfStability
+interface IHealthInfoCallback {
+  oneway void healthInfoChanged(in android.hardware.health.HealthInfo info);
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/StorageInfo.aidl b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/StorageInfo.aidl
new file mode 100644
index 0000000..eaae5a6
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/2/android/hardware/health/StorageInfo.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.health;
+@VintfStability
+parcelable StorageInfo {
+  int eol;
+  int lifetimeA;
+  int lifetimeB;
+  String version;
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
index e543886..4d70588 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
@@ -34,11 +34,11 @@
 package android.hardware.health;
 @Backing(type="int") @VintfStability
 enum BatteryCapacityLevel {
-  UNSUPPORTED = -1,
-  UNKNOWN = 0,
-  CRITICAL = 1,
-  LOW = 2,
-  NORMAL = 3,
-  HIGH = 4,
-  FULL = 5,
+  UNSUPPORTED = (-1) /* -1 */,
+  UNKNOWN,
+  CRITICAL,
+  LOW,
+  NORMAL,
+  HIGH,
+  FULL,
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryChargingPolicy.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryChargingPolicy.aidl
new file mode 100644
index 0000000..42fbf95
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryChargingPolicy.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.health;
+@Backing(type="int") @VintfStability
+enum BatteryChargingPolicy {
+  INVALID = 0,
+  DEFAULT = 1,
+  LONG_LIFE = 2,
+  ADAPTIVE = 3,
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryChargingState.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryChargingState.aidl
new file mode 100644
index 0000000..e21eb28
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryChargingState.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.health;
+@Backing(type="int") @VintfStability
+enum BatteryChargingState {
+  INVALID = 0,
+  NORMAL = 1,
+  TOO_COLD = 2,
+  TOO_HOT = 3,
+  LONG_LIFE = 4,
+  ADAPTIVE = 5,
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealth.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealth.aidl
index 4ce7952..8d13198 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealth.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealth.aidl
@@ -41,4 +41,7 @@
   OVER_VOLTAGE = 5,
   UNSPECIFIED_FAILURE = 6,
   COLD = 7,
+  FAIR = 8,
+  NOT_AVAILABLE = 11,
+  INCONSISTENT = 12,
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
new file mode 100644
index 0000000..2dd01b1
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.health;
+@VintfStability
+parcelable BatteryHealthData {
+  long batteryManufacturingDateSeconds;
+  long batteryFirstUsageSeconds;
+  long batteryStateOfHealth;
+}
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
index 97d9e84..bfa1475 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
@@ -57,5 +57,8 @@
   android.hardware.health.BatteryCapacityLevel batteryCapacityLevel;
   long batteryChargeTimeToFullNowSeconds;
   int batteryFullChargeDesignCapacityUah;
-  const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = -1;
+  android.hardware.health.BatteryChargingState chargingState;
+  android.hardware.health.BatteryChargingPolicy chargingPolicy;
+  @nullable android.hardware.health.BatteryHealthData batteryHealthData;
+  const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = (-1) /* -1 */;
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/IHealth.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/IHealth.aidl
index 7016ae4..b49dfff 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/IHealth.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/IHealth.aidl
@@ -46,6 +46,9 @@
   android.hardware.health.StorageInfo[] getStorageInfo();
   android.hardware.health.DiskStats[] getDiskStats();
   android.hardware.health.HealthInfo getHealthInfo();
+  void setChargingPolicy(android.hardware.health.BatteryChargingPolicy in_value);
+  android.hardware.health.BatteryChargingPolicy getChargingPolicy();
+  android.hardware.health.BatteryHealthData getBatteryHealthData();
   const int STATUS_UNKNOWN = 2;
   const int STATUS_CALLBACK_DIED = 4;
 }
diff --git a/health/aidl/android/hardware/health/BatteryChargingPolicy.aidl b/health/aidl/android/hardware/health/BatteryChargingPolicy.aidl
new file mode 100644
index 0000000..0aeee41
--- /dev/null
+++ b/health/aidl/android/hardware/health/BatteryChargingPolicy.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.health;
+
+/**
+ * Battery charging policy.
+ */
+@VintfStability
+@Backing(type="int")
+enum BatteryChargingPolicy {
+    INVALID = 0,
+    /**
+     * default policy
+     */
+    DEFAULT = 1,
+    /**
+     * @see BatteryChargingState.LONG_LIFE
+     */
+    LONG_LIFE = 2,
+    /**
+     * @see BatteryChargingState.ADAPTIVE
+     */
+    ADAPTIVE = 3,
+}
diff --git a/health/aidl/android/hardware/health/BatteryChargingState.aidl b/health/aidl/android/hardware/health/BatteryChargingState.aidl
new file mode 100644
index 0000000..af62077
--- /dev/null
+++ b/health/aidl/android/hardware/health/BatteryChargingState.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.health;
+
+/**
+ * Possible values for Battery Health.
+ * Note: These are currently in sync with BatteryManager and must not
+ * be extended / altered.
+ */
+@VintfStability
+@Backing(type="int")
+enum BatteryChargingState {
+    INVALID = 0,
+    /**
+     * Default state.
+     */
+    NORMAL = 1,
+    /**
+     * Reported when the battery is too cold to charge at a normal
+     * rate or stopped charging due to low temperature.
+     */
+    TOO_COLD = 2,
+    /**
+     * Reported when the battery is too hot to charge at a normal
+     * rate or stopped charging due to hot temperature.
+     */
+    TOO_HOT = 3,
+    /**
+     * The device is using a special charging profile that designed
+     * to prevent accelerated aging.
+     */
+    LONG_LIFE = 4,
+    /**
+     * The device is using a special charging profile designed to
+     * improve battery cycle life, performances or both.
+     */
+    ADAPTIVE = 5,
+}
diff --git a/health/aidl/android/hardware/health/BatteryHealth.aidl b/health/aidl/android/hardware/health/BatteryHealth.aidl
index 2b6e51f..65abdc2 100644
--- a/health/aidl/android/hardware/health/BatteryHealth.aidl
+++ b/health/aidl/android/hardware/health/BatteryHealth.aidl
@@ -24,8 +24,15 @@
 @VintfStability
 @Backing(type="int")
 enum BatteryHealth {
+    /**
+     * Battery health is not supported from the device.
+     */
     UNKNOWN = 1,
     GOOD = 2,
+    /**
+     * Must be consistent with BatteryChargingState.
+     * If BatteryHealth is OVERHEAT, then BatteryChargingState must be TOO_HOT.
+     */
     OVERHEAT = 3,
     DEAD = 4,
     OVER_VOLTAGE = 5,
@@ -33,5 +40,28 @@
      * Battery experienced an unknown/unspecified failure.
      */
     UNSPECIFIED_FAILURE = 6,
+    /**
+     * Must be consistent with BatteryChargingState.
+     * If BatteryHealth is COLD, then BatteryChargingState must be TOO_COLD.
+     */
     COLD = 7,
+    /**
+     * Battery health is marginal.
+     */
+    FAIR = 8,
+    /**
+     * The reserve data below 10 are used to recognize the battery real health.
+     */
+    /**
+     * There is not enough information to determine an accurate
+     * value. The value might become UNSPECIFIED_FAILURE, DEAD
+     * or any other state except for UNKNOWN later.
+     */
+    NOT_AVAILABLE = 11,
+    /**
+     * The internal data is inconsistent and the battery needs to
+     * go through a recalibration process. The value might become
+     * UNSPECIFIED_FAILURE, DEAD or any other state except for UNKNOWN later.
+     */
+    INCONSISTENT = 12,
 }
diff --git a/health/aidl/android/hardware/health/BatteryHealthData.aidl b/health/aidl/android/hardware/health/BatteryHealthData.aidl
new file mode 100644
index 0000000..594bcce
--- /dev/null
+++ b/health/aidl/android/hardware/health/BatteryHealthData.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.health;
+
+/*
+ * Battery health data
+ */
+@VintfStability
+parcelable BatteryHealthData {
+    /**
+     * Battery manufacturing date is reported in epoch.
+     */
+    long batteryManufacturingDateSeconds;
+    /**
+     * The date of first usage is reported in epoch.
+     */
+    long batteryFirstUsageSeconds;
+    /**
+     * Measured battery state of health (remaining estimate full charge capacity
+     * relative to the rated capacity in %).
+     * Value must be 0 if batteryStatus is UNKNOWN.
+     * Otherwise, value must be in the range 0 to 100.
+     */
+    long batteryStateOfHealth;
+}
diff --git a/health/aidl/android/hardware/health/HealthInfo.aidl b/health/aidl/android/hardware/health/HealthInfo.aidl
index 5b98baf..af84089 100644
--- a/health/aidl/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/android/hardware/health/HealthInfo.aidl
@@ -17,7 +17,10 @@
 package android.hardware.health;
 
 import android.hardware.health.BatteryCapacityLevel;
+import android.hardware.health.BatteryChargingPolicy;
+import android.hardware.health.BatteryChargingState;
 import android.hardware.health.BatteryHealth;
+import android.hardware.health.BatteryHealthData;
 import android.hardware.health.BatteryStatus;
 import android.hardware.health.DiskStats;
 import android.hardware.health.StorageInfo;
@@ -133,4 +136,16 @@
      * Value must be less than 100 000 000 µAh if known.
      */
     int batteryFullChargeDesignCapacityUah;
+    /**
+     * Battery charging state
+     */
+    BatteryChargingState chargingState;
+    /**
+     * Battery charging policy. See {@link BatteryChargingPolicy} for more details.
+     */
+    BatteryChargingPolicy chargingPolicy;
+    /**
+     * Battery health data
+     */
+    @nullable BatteryHealthData batteryHealthData;
 }
diff --git a/health/aidl/android/hardware/health/IHealth.aidl b/health/aidl/android/hardware/health/IHealth.aidl
index d541eca..bdfe07a 100644
--- a/health/aidl/android/hardware/health/IHealth.aidl
+++ b/health/aidl/android/hardware/health/IHealth.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.health;
 
+import android.hardware.health.BatteryChargingPolicy;
+import android.hardware.health.BatteryHealthData;
 import android.hardware.health.BatteryStatus;
 import android.hardware.health.DiskStats;
 import android.hardware.health.HealthInfo;
@@ -102,7 +104,7 @@
      *           if this property is not supported
      *                 (e.g. the file that stores this property does not exist),
      *         - Return service specific error with code STATUS_UNKNOWN
-     *           for for other errors.
+     *           for other errors.
      */
     int getCurrentNowMicroamps();
 
@@ -120,7 +122,7 @@
      *           if this property is not supported
      *                 (e.g. the file that stores this property does not exist),
      *         - Return service specific error with code STATUS_UNKNOWN
-     *           for for other errors.
+     *           for other errors.
      */
     int getCurrentAverageMicroamps();
 
@@ -134,7 +136,7 @@
      *           if this property is not supported
      *                 (e.g. the file that stores this property does not exist),
      *         - Return service specific error with code STATUS_UNKNOWN
-     *           for for other errors.
+     *           for other errors.
      */
     int getCapacity();
 
@@ -146,7 +148,7 @@
      *         - Return exception with code EX_UNSUPPORTED_OPERATION
      *           if this property is not supported,
      *         - Return service specific error with code STATUS_UNKNOWN
-     *           for for other errors.
+     *           for other errors.
      */
     long getEnergyCounterNwh();
 
@@ -197,7 +199,47 @@
      *         - Return exception with code EX_UNSUPPORTED_OPERATION
      *           if this API is not supported,
      *         - Return service specific error with code STATUS_UNKNOWN
-     *           for for other errors.
+     *           for other errors.
      */
     HealthInfo getHealthInfo();
+
+    /**
+     * Set battery charging policy
+     *
+     * @return If error, return service specific error with code:
+     *         - Return exception with code EX_UNSUPPORTED_OPERATION
+     *           if this property is not supported
+     *                 (e.g. the file that stores this property does not exist),
+     *         - Return status with code INVALID_OPERATION
+     *           if the operation failed.
+     *         - Return service specific error with code STATUS_UNKNOWN
+     *           for other errors.
+     */
+    void setChargingPolicy(BatteryChargingPolicy in_value);
+
+    /**
+     * Get current battery charging policy
+     *
+     * @return current battery charging policy if successful.
+     *         If error:
+     *         - Return exception with code EX_UNSUPPORTED_OPERATION
+     *           if this property is not supported
+     *                 (e.g. the file that stores this property does not exist),
+     *         - Return service specific error with code STATUS_UNKNOWN
+     *           for other errors.
+     */
+    BatteryChargingPolicy getChargingPolicy();
+
+    /**
+     * Get battery health data
+     *
+     * @return Battery health data if successful.
+     *         If error:
+     *         - Return exception with code EX_UNSUPPORTED_OPERATION
+     *           if this property is not supported
+     *                 (e.g. the file that stores this property does not exist),
+     *         - Return service specific error with code STATUS_UNKNOWN
+     *           for other errors.
+     */
+    BatteryHealthData getBatteryHealthData();
 }
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 8eab997..b51e4f3 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -29,7 +29,7 @@
         "libcutils",
         "liblog",
         "libutils",
-        "android.hardware.health-V1-ndk",
+        "android.hardware.health-V2-ndk",
 
         // TODO(b/177269435): remove when BatteryMonitor works with AIDL HealthInfo.
         "libhidlbase",
@@ -48,7 +48,7 @@
     name: "libhealth_aidl_charger_defaults",
     shared_libs: [
         // common
-        "android.hardware.health-V1-ndk",
+        "android.hardware.health-V2-ndk",
         "libbase",
         "libcutils",
         "liblog",
@@ -159,3 +159,51 @@
     init_rc: ["android.hardware.health-service.example_recovery.rc"],
     overrides: ["charger.recovery"],
 }
+
+// AIDL Fuzz version of libhealth2impl.
+cc_library_static {
+    name: "fuzz_libhealth_aidl_impl",
+    defaults: [
+        "libhealth_aidl_common_defaults",
+        "libhealth_aidl_charger_defaults",
+    ],
+    recovery_available: true,
+    export_include_dirs: ["include"],
+    export_static_lib_headers: [
+        "libbatterymonitor",
+    ],
+    srcs: [
+        "ChargerUtils.cpp",
+        "health-convert.cpp",
+        "HalHealthLoop.cpp",
+        "Health.cpp",
+        "LinkedCallback.cpp",
+    ],
+    target: {
+        recovery: {
+            exclude_srcs: [
+                "ChargerUtils.cpp",
+            ],
+        },
+    },
+}
+
+cc_fuzz {
+    name: "android.hardware.health-service.aidl_fuzzer",
+    defaults: [
+        "libhealth_aidl_impl_user",
+        "service_fuzzer_defaults",
+    ],
+    static_libs: [
+        "android.hardware.health-V2-ndk",
+        "libbase",
+        "liblog",
+        "fuzz_libhealth_aidl_impl",
+    ],
+    srcs: ["fuzzer.cpp"],
+    fuzz_config: {
+        cc: [
+            "hamzeh@google.com",
+        ],
+    },
+}
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index d41d01a..f401643 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -115,6 +115,47 @@
                        BatteryStatus::UNKNOWN, out);
 }
 
+ndk::ScopedAStatus Health::setChargingPolicy(BatteryChargingPolicy in_value) {
+    ::android::status_t err = battery_monitor_.setChargingPolicy(static_cast<int>(in_value));
+
+    switch (err) {
+        case ::android::OK:
+            return ndk::ScopedAStatus::ok();
+        case ::android::NAME_NOT_FOUND:
+            return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+        case ::android::BAD_VALUE:
+            return ndk::ScopedAStatus::fromStatus(::android::INVALID_OPERATION);
+        default:
+            return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                    IHealth::STATUS_UNKNOWN, ::android::statusToString(err).c_str());
+    }
+}
+
+ndk::ScopedAStatus Health::getChargingPolicy(BatteryChargingPolicy* out) {
+    return GetProperty(&battery_monitor_, ::android::BATTERY_PROP_CHARGING_POLICY,
+                       BatteryChargingPolicy::DEFAULT, out);
+}
+
+ndk::ScopedAStatus Health::getBatteryHealthData(BatteryHealthData* out) {
+    if (auto res =
+                GetProperty<int64_t>(&battery_monitor_, ::android::BATTERY_PROP_MANUFACTURING_DATE,
+                                     0, &out->batteryManufacturingDateSeconds);
+        !res.isOk()) {
+        LOG(WARNING) << "Cannot get Manufacturing_date: " << res.getDescription();
+    }
+    if (auto res = GetProperty<int64_t>(&battery_monitor_, ::android::BATTERY_PROP_FIRST_USAGE_DATE,
+                                        0, &out->batteryFirstUsageSeconds);
+        !res.isOk()) {
+        LOG(WARNING) << "Cannot get First_usage_date: " << res.getDescription();
+    }
+    if (auto res = GetProperty<int64_t>(&battery_monitor_, ::android::BATTERY_PROP_STATE_OF_HEALTH,
+                                        0, &out->batteryStateOfHealth);
+        !res.isOk()) {
+        LOG(WARNING) << "Cannot get Battery_state_of_health: " << res.getDescription();
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus Health::getDiskStats(std::vector<DiskStats>*) {
     // This implementation does not support DiskStats. An implementation may extend this
     // class and override this function to support disk stats.
diff --git a/health/aidl/default/android.hardware.health-service.example.xml b/health/aidl/default/android.hardware.health-service.example.xml
index 98026cb..1fe9b8d 100644
--- a/health/aidl/default/android.hardware.health-service.example.xml
+++ b/health/aidl/default/android.hardware.health-service.example.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.health</name>
-        <version>1</version>
+        <version>2</version>
         <fqname>IHealth/default</fqname>
     </hal>
 </manifest>
diff --git a/health/aidl/default/fuzzer.cpp b/health/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..b7c6d39
--- /dev/null
+++ b/health/aidl/default/fuzzer.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <health-impl/Health.h>
+#include <health/utils.h>
+
+using aidl::android::hardware::health::Health;
+using android::fuzzService;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto config = std::make_unique<healthd_config>();
+    ::android::hardware::health::InitHealthdConfig(config.get());
+    auto binder = ndk::SharedRefBase::make<Health>("default", std::move(config));
+
+    fuzzService(binder->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
\ No newline at end of file
diff --git a/health/aidl/default/include/health-impl/Health.h b/health/aidl/default/include/health-impl/Health.h
index 6bd4946..dc3a0ef 100644
--- a/health/aidl/default/include/health-impl/Health.h
+++ b/health/aidl/default/include/health-impl/Health.h
@@ -72,6 +72,10 @@
     ndk::ScopedAStatus getDiskStats(std::vector<DiskStats>* out) override;
     ndk::ScopedAStatus getStorageInfo(std::vector<StorageInfo>* out) override;
 
+    ndk::ScopedAStatus setChargingPolicy(BatteryChargingPolicy in_value) override;
+    ndk::ScopedAStatus getChargingPolicy(BatteryChargingPolicy* out) override;
+    ndk::ScopedAStatus getBatteryHealthData(BatteryHealthData* out) override;
+
     // A subclass may override these to provide a different implementation.
     binder_status_t dump(int fd, const char** args, uint32_t num_args) override;
 
diff --git a/health/aidl/vts/functional/Android.bp b/health/aidl/vts/functional/Android.bp
index f9da79f..b735a87 100644
--- a/health/aidl/vts/functional/Android.bp
+++ b/health/aidl/vts/functional/Android.bp
@@ -39,7 +39,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.health-V1-ndk",
+        "android.hardware.health-V2-ndk",
         "libgmock",
     ],
     header_libs: [
diff --git a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
index 3e07188..783ce11 100644
--- a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
+++ b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
@@ -225,6 +225,87 @@
     ASSERT_THAT(value, IsValidEnum<BatteryStatus>());
 }
 
+/*
+ * Tests the values returned by getChargingPolicy() from interface IHealth.
+ */
+TEST_P(HealthAidl, getChargingPolicy) {
+    int32_t version = 0;
+    auto status = health->getInterfaceVersion(&version);
+    ASSERT_TRUE(status.isOk()) << status;
+    if (version < 2) {
+        GTEST_SKIP() << "Support in health hal v2 for EU Ecodesign";
+    }
+    BatteryChargingPolicy value;
+    status = health->getChargingPolicy(&value);
+    ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
+    if (!status.isOk()) return;
+    ASSERT_THAT(value, IsValidEnum<BatteryChargingPolicy>());
+}
+
+/*
+ * Tests that setChargingPolicy() writes the value and compared the returned
+ * value by getChargingPolicy() from interface IHealth.
+ */
+TEST_P(HealthAidl, setChargingPolicy) {
+    int32_t version = 0;
+    auto status = health->getInterfaceVersion(&version);
+    ASSERT_TRUE(status.isOk()) << status;
+    if (version < 2) {
+        GTEST_SKIP() << "Support in health hal v2 for EU Ecodesign";
+    }
+
+    BatteryChargingPolicy value;
+
+    /* set ChargingPolicy*/
+    status = health->setChargingPolicy(BatteryChargingPolicy::LONG_LIFE);
+    ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
+    if (!status.isOk()) return;
+
+    /* get ChargingPolicy*/
+    status = health->getChargingPolicy(&value);
+    ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
+    if (!status.isOk()) return;
+    // the result of getChargingPolicy will be one of default(1), ADAPTIVE_AON(2)
+    // ADAPTIVE_AC(3) or LONG_LIFE(4). default(1) means NOT_SUPPORT
+    ASSERT_THAT(static_cast<int>(value), AnyOf(Eq(1), Eq(4)));
+}
+
+MATCHER(IsValidHealthData, "") {
+    *result_listener << "value is " << arg.toString() << ".";
+    if (!ExplainMatchResult(Ge(-1), arg.batteryManufacturingDateSeconds, result_listener)) {
+        *result_listener << " for batteryManufacturingDateSeconds.";
+        return false;
+    }
+    if (!ExplainMatchResult(Ge(-1), arg.batteryFirstUsageSeconds, result_listener)) {
+        *result_listener << " for batteryFirstUsageSeconds.";
+        return false;
+    }
+    if (!ExplainMatchResult(Ge(-1), arg.batteryStateOfHealth, result_listener)) {
+        *result_listener << " for batteryStateOfHealth.";
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Tests the values returned by getBatteryHealthData() from interface IHealth.
+ */
+TEST_P(HealthAidl, getBatteryHealthData) {
+    int32_t version = 0;
+    auto status = health->getInterfaceVersion(&version);
+    ASSERT_TRUE(status.isOk()) << status;
+    if (version < 2) {
+        GTEST_SKIP() << "Support in health hal v2 for EU Ecodesign";
+    }
+
+    BatteryHealthData value;
+    status = health->getBatteryHealthData(&value);
+    ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
+    if (!status.isOk()) return;
+    ASSERT_THAT(value, IsValidHealthData());
+}
+
 MATCHER(IsValidStorageInfo, "") {
     *result_listener << "value is " << arg.toString() << ".";
     if (!ExplainMatchResult(InClosedRange(0, 3), arg.eol, result_listener)) {
diff --git a/health/storage/aidl/Android.bp b/health/storage/aidl/Android.bp
index 4cd9263..c614efb 100644
--- a/health/storage/aidl/Android.bp
+++ b/health/storage/aidl/Android.bp
@@ -33,11 +33,6 @@
         java: {
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
index 3a1415f..14c32ae 100644
--- a/health/utils/libhealthshim/Android.bp
+++ b/health/utils/libhealthshim/Android.bp
@@ -34,7 +34,7 @@
         "-Werror",
     ],
     static_libs: [
-        "android.hardware.health-V1-ndk",
+        "android.hardware.health-V2-ndk",
         "android.hardware.health-translate-ndk",
         "android.hardware.health@1.0",
         "android.hardware.health@2.0",
diff --git a/health/utils/libhealthshim/include/health-shim/shim.h b/health/utils/libhealthshim/include/health-shim/shim.h
index f36fa5d..ff6849b 100644
--- a/health/utils/libhealthshim/include/health-shim/shim.h
+++ b/health/utils/libhealthshim/include/health-shim/shim.h
@@ -45,6 +45,9 @@
     ndk::ScopedAStatus getStorageInfo(std::vector<StorageInfo>* _aidl_return) override;
     ndk::ScopedAStatus getDiskStats(std::vector<DiskStats>* _aidl_return) override;
     ndk::ScopedAStatus getHealthInfo(HealthInfo* _aidl_return) override;
+    ndk::ScopedAStatus setChargingPolicy(BatteryChargingPolicy in_value) override;
+    ndk::ScopedAStatus getChargingPolicy(BatteryChargingPolicy* _aidl_return) override;
+    ndk::ScopedAStatus getBatteryHealthData(BatteryHealthData* _aidl_return) override;
 
   private:
     ::android::sp<HidlHealth> service_;
diff --git a/health/utils/libhealthshim/shim.cpp b/health/utils/libhealthshim/shim.cpp
index 1329679..6a5f512 100644
--- a/health/utils/libhealthshim/shim.cpp
+++ b/health/utils/libhealthshim/shim.cpp
@@ -217,4 +217,20 @@
     return ReturnAndResultToStatus(ret, out_result);
 }
 
+ScopedAStatus HealthShim::setChargingPolicy(BatteryChargingPolicy in_value) {
+    in_value = static_cast<BatteryChargingPolicy>(0);
+    return ResultToStatus(Result::NOT_SUPPORTED);
+}
+
+ScopedAStatus HealthShim::getChargingPolicy(BatteryChargingPolicy* out) {
+    *out = static_cast<BatteryChargingPolicy>(0);
+    return ResultToStatus(Result::NOT_SUPPORTED);
+}
+
+ScopedAStatus HealthShim::getBatteryHealthData(BatteryHealthData* out) {
+    out->batteryManufacturingDateSeconds = 0;
+    out->batteryFirstUsageSeconds = 0;
+    return ResultToStatus(Result::NOT_SUPPORTED);
+}
+
 }  // namespace aidl::android::hardware::health
diff --git a/identity/OWNERS b/identity/OWNERS
index 6969910..9353bbc 100644
--- a/identity/OWNERS
+++ b/identity/OWNERS
@@ -1,2 +1,4 @@
+# Bug component: 1084909
+
 swillden@google.com
 zeuthen@google.com
diff --git a/identity/aidl/Android.bp b/identity/aidl/Android.bp
index 920a4b9..da70406 100644
--- a/identity/aidl/Android.bp
+++ b/identity/aidl/Android.bp
@@ -14,18 +14,16 @@
         "android/hardware/identity/*.aidl",
     ],
     imports: [
-        "android.hardware.keymaster",
-        "android.hardware.security.keymint",
+        "android.hardware.keymaster-V3",
+        "android.hardware.security.rkp-V3",
     ],
     stability: "vintf",
+    frozen: true,
     backend: {
         java: {
             platform_apis: true,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apps_enabled: false,
         },
     },
@@ -34,31 +32,62 @@
             version: "1",
             imports: [
                 "android.hardware.keymaster-V3",
-                "android.hardware.security.keymint-V1",
+                "android.hardware.security.rkp-V1",
             ],
         },
         {
             version: "2",
             imports: [
                 "android.hardware.keymaster-V3",
-                "android.hardware.security.keymint-V1",
+                "android.hardware.security.rkp-V1",
             ],
         },
         {
             version: "3",
             imports: [
                 "android.hardware.keymaster-V3",
-                "android.hardware.security.keymint-V1",
+                "android.hardware.security.rkp-V1",
             ],
         },
         {
             version: "4",
             imports: [
                 "android.hardware.keymaster-V3",
-                "android.hardware.security.keymint-V2",
+                "android.hardware.security.rkp-V3",
+            ],
+        },
+        {
+            version: "5",
+            imports: [
+                "android.hardware.keymaster-V3",
+                "android.hardware.security.rkp-V3",
             ],
         },
 
     ],
 
 }
+
+// cc_defaults that includes the latest Identity AIDL library.
+// Modules that depend on Identity directly can include this cc_defaults to
+// avoid managing dependency versions explicitly.
+cc_defaults {
+    name: "identity_use_latest_hal_aidl_ndk_static",
+    static_libs: [
+        "android.hardware.identity-V5-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "identity_use_latest_hal_aidl_ndk_shared",
+    shared_libs: [
+        "android.hardware.identity-V5-ndk",
+    ],
+}
+
+cc_defaults {
+    name: "identity_use_latest_hal_aidl_cpp_static",
+    static_libs: [
+        "android.hardware.identity-V5-cpp",
+    ],
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/.hash b/identity/aidl/aidl_api/android.hardware.identity/5/.hash
new file mode 100644
index 0000000..158dc4f
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/.hash
@@ -0,0 +1 @@
+63f77d853b84219479b25418b1ce6fd1553f30db
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/Certificate.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/Certificate.aidl
new file mode 100644
index 0000000..83e1797
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/Certificate.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.identity;
+@VintfStability
+parcelable Certificate {
+  byte[] encodedCertificate;
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/CipherSuite.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/CipherSuite.aidl
new file mode 100644
index 0000000..e6ec04e
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/CipherSuite.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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.identity;
+@Backing(type="int") @VintfStability
+enum CipherSuite {
+  CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 = 1,
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/HardwareInformation.aidl
new file mode 100644
index 0000000..9b96ea8
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/HardwareInformation.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 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.identity;
+@VintfStability
+parcelable HardwareInformation {
+  @utf8InCpp String credentialStoreName;
+  @utf8InCpp String credentialStoreAuthorName;
+  int dataChunkSize;
+  boolean isDirectAccess;
+  @utf8InCpp String[] supportedDocTypes;
+  boolean isRemoteKeyProvisioningSupported = false;
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IIdentityCredential.aidl
new file mode 100644
index 0000000..4f2fe0b
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IIdentityCredential.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 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.identity;
+@VintfStability
+interface IIdentityCredential {
+  /**
+   * @deprecated use deleteCredentalWithChallenge() instead.
+   */
+  byte[] deleteCredential();
+  byte[] createEphemeralKeyPair();
+  void setReaderEphemeralPublicKey(in byte[] publicKey);
+  long createAuthChallenge();
+  void startRetrieval(in android.hardware.identity.SecureAccessControlProfile[] accessControlProfiles, in android.hardware.keymaster.HardwareAuthToken authToken, in byte[] itemsRequest, in byte[] signingKeyBlob, in byte[] sessionTranscript, in byte[] readerSignature, in int[] requestCounts);
+  void startRetrieveEntryValue(in @utf8InCpp String nameSpace, in @utf8InCpp String name, in int entrySize, in int[] accessControlProfileIds);
+  byte[] retrieveEntryValue(in byte[] encryptedContent);
+  @SuppressWarnings(value={"out-array"}) void finishRetrieval(out byte[] mac, out byte[] deviceNameSpaces);
+  @SuppressWarnings(value={"out-array"}) android.hardware.identity.Certificate generateSigningKeyPair(out byte[] signingKeyBlob);
+  void setRequestedNamespaces(in android.hardware.identity.RequestNamespace[] requestNamespaces);
+  void setVerificationToken(in android.hardware.keymaster.VerificationToken verificationToken);
+  byte[] deleteCredentialWithChallenge(in byte[] challenge);
+  byte[] proveOwnership(in byte[] challenge);
+  android.hardware.identity.IWritableIdentityCredential updateCredential();
+  @SuppressWarnings(value={"out-array"}) void finishRetrievalWithSignature(out byte[] mac, out byte[] deviceNameSpaces, out byte[] ecdsaSignature);
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IIdentityCredentialStore.aidl
new file mode 100644
index 0000000..31ca8b1
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 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.identity;
+@VintfStability
+interface IIdentityCredentialStore {
+  android.hardware.identity.HardwareInformation getHardwareInformation();
+  android.hardware.identity.IWritableIdentityCredential createCredential(in @utf8InCpp String docType, in boolean testCredential);
+  android.hardware.identity.IIdentityCredential getCredential(in android.hardware.identity.CipherSuite cipherSuite, in byte[] credentialData);
+  android.hardware.identity.IPresentationSession createPresentationSession(in android.hardware.identity.CipherSuite cipherSuite);
+  android.hardware.security.keymint.IRemotelyProvisionedComponent getRemotelyProvisionedComponent();
+  const int STATUS_OK = 0;
+  const int STATUS_FAILED = 1;
+  const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2;
+  const int STATUS_INVALID_DATA = 3;
+  const int STATUS_INVALID_AUTH_TOKEN = 4;
+  const int STATUS_INVALID_ITEMS_REQUEST_MESSAGE = 5;
+  const int STATUS_READER_SIGNATURE_CHECK_FAILED = 6;
+  const int STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND = 7;
+  const int STATUS_USER_AUTHENTICATION_FAILED = 8;
+  const int STATUS_READER_AUTHENTICATION_FAILED = 9;
+  const int STATUS_NO_ACCESS_CONTROL_PROFILES = 10;
+  const int STATUS_NOT_IN_REQUEST_MESSAGE = 11;
+  const int STATUS_SESSION_TRANSCRIPT_MISMATCH = 12;
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IPresentationSession.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IPresentationSession.aidl
new file mode 100644
index 0000000..705dc29
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IPresentationSession.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.identity;
+@VintfStability
+interface IPresentationSession {
+  byte[] getEphemeralKeyPair();
+  long getAuthChallenge();
+  void setReaderEphemeralPublicKey(in byte[] publicKey);
+  void setSessionTranscript(in byte[] sessionTranscript);
+  android.hardware.identity.IIdentityCredential getCredential(in byte[] credentialData);
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IWritableIdentityCredential.aidl
new file mode 100644
index 0000000..5377349
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 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.identity;
+@VintfStability
+interface IWritableIdentityCredential {
+  android.hardware.identity.Certificate[] getAttestationCertificate(in byte[] attestationApplicationId, in byte[] attestationChallenge);
+  void startPersonalization(in int accessControlProfileCount, in int[] entryCounts);
+  android.hardware.identity.SecureAccessControlProfile addAccessControlProfile(in int id, in android.hardware.identity.Certificate readerCertificate, in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId);
+  void beginAddEntry(in int[] accessControlProfileIds, in @utf8InCpp String nameSpace, in @utf8InCpp String name, in int entrySize);
+  byte[] addEntryValue(in byte[] content);
+  @SuppressWarnings(value={"out-array"}) void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature);
+  void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize);
+  void setRemotelyProvisionedAttestationKey(in byte[] attestationKeyBlob, in byte[] attestationCertificate);
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/RequestDataItem.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/RequestDataItem.aidl
new file mode 100644
index 0000000..cec8e0c
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/RequestDataItem.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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.identity;
+@VintfStability
+parcelable RequestDataItem {
+  @utf8InCpp String name;
+  long size;
+  int[] accessControlProfileIds;
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/RequestNamespace.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/RequestNamespace.aidl
new file mode 100644
index 0000000..05b9ec2
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/RequestNamespace.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.identity;
+@VintfStability
+parcelable RequestNamespace {
+  @utf8InCpp String namespaceName;
+  android.hardware.identity.RequestDataItem[] items;
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/SecureAccessControlProfile.aidl b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/SecureAccessControlProfile.aidl
new file mode 100644
index 0000000..2003594
--- /dev/null
+++ b/identity/aidl/aidl_api/android.hardware.identity/5/android/hardware/identity/SecureAccessControlProfile.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 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.identity;
+@VintfStability
+parcelable SecureAccessControlProfile {
+  int id;
+  android.hardware.identity.Certificate readerCertificate;
+  boolean userAuthenticationRequired;
+  long timeoutMillis;
+  long secureUserId;
+  byte[] mac;
+}
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
index 5065641..4f2fe0b 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
@@ -51,4 +51,5 @@
   byte[] deleteCredentialWithChallenge(in byte[] challenge);
   byte[] proveOwnership(in byte[] challenge);
   android.hardware.identity.IWritableIdentityCredential updateCredential();
+  @SuppressWarnings(value={"out-array"}) void finishRetrievalWithSignature(out byte[] mac, out byte[] deviceNameSpaces, out byte[] ecdsaSignature);
 }
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 82b0a83..df8e2bd 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -194,7 +194,8 @@
      * is permissible for this to be empty in which case the readerSignature parameter
      * must also be empty. If this is not the case, the call fails with STATUS_FAILED.
      *
-     * If the SessionTranscript CBOR is not empty, the X and Y coordinates of the public
+     * If mdoc session encryption is used (e.g. createEphemeralKeyPair() has been called)
+     * and the SessionTranscript CBOR is not empty, the X and Y coordinates of the public
      * part of the key-pair previously generated by createEphemeralKeyPair() must appear
      * somewhere in the bytes of the CBOR. Each of these coordinates must appear encoded
      * with the most significant bits first and use the exact amount of bits indicated by
@@ -239,8 +240,8 @@
      *   and remove the corresponding requests from the counts.
      */
     void startRetrieval(in SecureAccessControlProfile[] accessControlProfiles,
-        in HardwareAuthToken authToken, in byte[] itemsRequest, in byte[] signingKeyBlob,
-        in byte[] sessionTranscript, in byte[] readerSignature, in int[] requestCounts);
+            in HardwareAuthToken authToken, in byte[] itemsRequest, in byte[] signingKeyBlob,
+            in byte[] sessionTranscript, in byte[] readerSignature, in int[] requestCounts);
 
     /**
      * Starts retrieving an entry, subject to access control requirements.  Entries must be
@@ -271,8 +272,8 @@
      *     is given and this profile wasn't passed to startRetrieval() this call fails
      *     with STATUS_INVALID_DATA.
      */
-    void startRetrieveEntryValue(in @utf8InCpp String nameSpace, in @utf8InCpp String name,
-                                 in int entrySize, in int[] accessControlProfileIds);
+    void startRetrieveEntryValue(in @utf8InCpp String nameSpace,
+            in @utf8InCpp String name, in int entrySize, in int[] accessControlProfileIds);
 
     /**
      * Retrieves an entry value, or part of one, if the entry value is larger than gcmChunkSize.
@@ -293,11 +294,13 @@
      * returned data.
      *
      * If signingKeyBlob or the sessionTranscript parameter passed to startRetrieval() is
-     * empty then the returned MAC will be empty.
+     * empty or if mdoc session encryption is not being used (e.g. if createEphemeralKeyPair()
+     * was not called) then the returned MAC will be empty.
      *
-     * @param out mac is empty if signingKeyBlob or the sessionTranscript passed to
-     *    startRetrieval() is empty. Otherwise it is a COSE_Mac0 with empty payload
-     *    and the detached content is set to DeviceAuthenticationBytes as defined below.
+     * @param out mac is empty if signingKeyBlob, or the sessionTranscript passed to
+     *    startRetrieval() is empty, or if mdoc session encryption is not being used (e.g. if
+     *    createEphemeralKeyPair() was not called). Otherwise it is a COSE_Mac0 with empty
+     *    payload and the detached content is set to DeviceAuthenticationBytes as defined below.
      *    This code is produced by using the key agreement and key derivation function
      *    from the ciphersuite with the authentication private key and the reader
      *    ephemeral public key to compute a shared message authentication code (MAC)
@@ -367,7 +370,8 @@
      *  - issuer: CN shall be set to "Android Identity Credential Key". (fixed value:
      *    same on all certs)
      *
-     *  - validity: should be from current time and one year in the future (365 days).
+     *  - validity: should be from current time and 31536000 seconds in the
+     *    future (approximately 365 days).
      *
      *  - subjectPublicKeyInfo: must contain attested public key.
      *
@@ -407,13 +411,13 @@
      */
     void setRequestedNamespaces(in RequestNamespace[] requestNamespaces);
 
-   /**
-    * Sets the VerificationToken. This method must be called before startRetrieval() is
-    * called. This token uses the same challenge as returned by createAuthChallenge().
-    *
-    * @param verificationToken
-    *   The verification token. This token is only valid if the timestamp field is non-zero.
-    */
+    /**
+     * Sets the VerificationToken. This method must be called before startRetrieval() is
+     * called. This token uses the same challenge as returned by createAuthChallenge().
+     *
+     * @param verificationToken
+     *   The verification token. This token is only valid if the timestamp field is non-zero.
+     */
     void setVerificationToken(in VerificationToken verificationToken);
 
     /**
@@ -485,4 +489,20 @@
      * @return an IWritableIdentityCredential
      */
     IWritableIdentityCredential updateCredential();
+
+    /**
+     * Like finishRetrieval() but also returns an ECDSA signature in addition to the MAC.
+     *
+     * See section 9.1.3.6 of ISO/IEC 18013-5:2021 for details of how the signature is calculated.
+     *
+     * Unlike MACing, an ECDSA signature will be returned even if mdoc session encryption isn't
+     * being used.
+     *
+     * This method was introduced in API version 5.
+     *
+     * @param ecdsaSignature a COSE_Sign1 signature described above.
+     */
+    @SuppressWarnings(value={"out-array"})
+    void finishRetrievalWithSignature(
+            out byte[] mac, out byte[] deviceNameSpaces, out byte[] ecdsaSignature);
 }
diff --git a/identity/aidl/android/hardware/identity/IPresentationSession.aidl b/identity/aidl/android/hardware/identity/IPresentationSession.aidl
index b0449f0..0a06740 100644
--- a/identity/aidl/android/hardware/identity/IPresentationSession.aidl
+++ b/identity/aidl/android/hardware/identity/IPresentationSession.aidl
@@ -70,6 +70,17 @@
      *
      * This can be empty but if it's non-empty it must be valid CBOR.
      *
+     * If mdoc session encryption is used (e.g. getEphemeralKeyPair() has been called)
+     * and the SessionTranscript CBOR is not empty, the X and Y coordinates of the public
+     * part of the key-pair previously generated by createEphemeralKeyPair() must appear
+     * somewhere in the bytes of the CBOR. Each of these coordinates must appear encoded
+     * with the most significant bits first and use the exact amount of bits indicated by
+     * the key size of the ephemeral keys. For example, if the ephemeral key is using the
+     * P-256 curve then the 32 bytes for the X coordinate encoded with the most significant
+     * bits first must appear somewhere in the CBOR and ditto for the 32 bytes for the Y
+     * coordinate. If this is not satisfied, the call fails with
+     * STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND.
+     *
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
      * must be returned.
      *
diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index 31ab400..7bc3c8d 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -10,6 +10,10 @@
 cc_library_static {
     name: "android.hardware.identity-libeic-hal-common",
     vendor_available: true,
+    defaults: [
+        "identity_use_latest_hal_aidl_ndk_static",
+        "keymint_use_latest_hal_aidl_ndk_static",
+    ],
     srcs: [
         "common/IdentityCredential.cpp",
         "common/IdentityCredentialStore.cpp",
@@ -40,9 +44,8 @@
         "libsoft_attestation_cert",
         "libpuresoftkeymasterdevice",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-V4-ndk",
         "android.hardware.keymaster-V3-ndk",
-        "android.hardware.security.keymint-V2-ndk",
+        "android.hardware.security.rkp-V3-ndk",
     ],
 }
 
@@ -83,6 +86,7 @@
     vintf_fragments: ["identity-default.xml"],
     vendor: true,
     defaults: [
+        "identity_use_latest_hal_aidl_ndk_static",
         "keymint_use_latest_hal_aidl_ndk_static",
     ],
     cflags: [
@@ -106,10 +110,10 @@
         "libsoft_attestation_cert",
         "libpuresoftkeymasterdevice",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-V4-ndk",
         "android.hardware.keymaster-V3-ndk",
         "android.hardware.identity-libeic-hal-common",
         "android.hardware.identity-libeic-library",
+        "android.hardware.security.rkp-V3-ndk",
     ],
     srcs: [
         "service.cpp",
diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc
index 3fd9f1d..803df64 100644
--- a/identity/aidl/default/EicOpsImpl.cc
+++ b/identity/aidl/default/EicOpsImpl.cc
@@ -100,6 +100,7 @@
     if (size != EIC_SHA256_DIGEST_SIZE) {
         LOG(ERROR) << "Expected 32 bytes from HMAC_Final, got " << size;
     }
+    HMAC_CTX_cleanup(realCtx);
 }
 
 void eicOpsSha256Init(EicSha256Ctx* ctx) {
@@ -394,14 +395,17 @@
     }
 
     if (BN_bn2binpad(sig->r, signature, 32) != 32) {
+        ECDSA_SIG_free(sig);
         eicDebug("Error encoding r");
         return false;
     }
     if (BN_bn2binpad(sig->s, signature + 32, 32) != 32) {
+        ECDSA_SIG_free(sig);
         eicDebug("Error encoding s");
         return false;
     }
 
+    ECDSA_SIG_free(sig);
     return true;
 }
 
@@ -485,7 +489,7 @@
 }
 
 bool eicOpsEcdh(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
-                const uint8_t privateKey[EIC_P256_PUB_KEY_SIZE],
+                const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
                 uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE]) {
     vector<uint8_t> pubKeyVec(EIC_P256_PUB_KEY_SIZE + 1);
     pubKeyVec[0] = 0x04;
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp
index 9b9a749..8551ab7 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.cpp
+++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp
@@ -596,10 +596,10 @@
     return eicPresentationStartRetrieveEntries(&ctx_);
 }
 
-bool FakeSecureHardwarePresentationProxy::calcMacKey(
+bool FakeSecureHardwarePresentationProxy::prepareDeviceAuthentication(
         const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& readerEphemeralPublicKey,
         const vector<uint8_t>& signingKeyBlob, const string& docType,
-        unsigned int numNamespacesWithValues, size_t expectedProofOfProvisioningSize) {
+        unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize) {
     if (!validateId(__func__)) {
         return false;
     }
@@ -608,10 +608,10 @@
         eicDebug("Unexpected size %zd of signingKeyBlob, expected 60", signingKeyBlob.size());
         return false;
     }
-    return eicPresentationCalcMacKey(&ctx_, sessionTranscript.data(), sessionTranscript.size(),
-                                     readerEphemeralPublicKey.data(), signingKeyBlob.data(),
-                                     docType.c_str(), docType.size(), numNamespacesWithValues,
-                                     expectedProofOfProvisioningSize);
+    return eicPresentationPrepareDeviceAuthentication(
+            &ctx_, sessionTranscript.data(), sessionTranscript.size(),
+            readerEphemeralPublicKey.data(), readerEphemeralPublicKey.size(), signingKeyBlob.data(),
+            docType.c_str(), docType.size(), numNamespacesWithValues, expectedDeviceNamespacesSize);
 }
 
 AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue(
@@ -673,6 +673,25 @@
     return content;
 }
 
+optional<pair<vector<uint8_t>, vector<uint8_t>>>
+FakeSecureHardwarePresentationProxy::finishRetrievalWithSignature() {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
+    vector<uint8_t> mac(32);
+    size_t macSize = 32;
+    vector<uint8_t> ecdsaSignature(EIC_ECDSA_P256_SIGNATURE_SIZE);
+    size_t ecdsaSignatureSize = EIC_ECDSA_P256_SIGNATURE_SIZE;
+    if (!eicPresentationFinishRetrievalWithSignature(&ctx_, mac.data(), &macSize,
+                                                     ecdsaSignature.data(), &ecdsaSignatureSize)) {
+        return std::nullopt;
+    }
+    mac.resize(macSize);
+    ecdsaSignature.resize(ecdsaSignatureSize);
+    return std::make_pair(mac, ecdsaSignature);
+}
+
 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::finishRetrieval() {
     if (!validateId(__func__)) {
         return std::nullopt;
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h
index 2512074..b56ab93 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.h
+++ b/identity/aidl/default/FakeSecureHardwareProxy.h
@@ -175,11 +175,11 @@
                                 const vector<uint8_t>& requestMessage, int coseSignAlg,
                                 const vector<uint8_t>& readerSignatureOfToBeSigned) override;
 
-    bool calcMacKey(const vector<uint8_t>& sessionTranscript,
-                    const vector<uint8_t>& readerEphemeralPublicKey,
-                    const vector<uint8_t>& signingKeyBlob, const string& docType,
-                    unsigned int numNamespacesWithValues,
-                    size_t expectedProofOfProvisioningSize) override;
+    bool prepareDeviceAuthentication(const vector<uint8_t>& sessionTranscript,
+                                     const vector<uint8_t>& readerEphemeralPublicKey,
+                                     const vector<uint8_t>& signingKeyBlob, const string& docType,
+                                     unsigned int numNamespacesWithValues,
+                                     size_t expectedDeviceNamespacesSize) override;
 
     AccessCheckResult startRetrieveEntryValue(
             const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries,
@@ -191,6 +191,8 @@
 
     optional<vector<uint8_t>> finishRetrieval() override;
 
+    optional<pair<vector<uint8_t>, vector<uint8_t>>> finishRetrievalWithSignature() override;
+
     optional<vector<uint8_t>> deleteCredential(const string& docType,
                                                const vector<uint8_t>& challenge,
                                                bool includeChallenge,
diff --git a/identity/aidl/default/android.hardware.identity_credential.xml b/identity/aidl/default/android.hardware.identity_credential.xml
index 20b2710..a49ddca 100644
--- a/identity/aidl/default/android.hardware.identity_credential.xml
+++ b/identity/aidl/default/android.hardware.identity_credential.xml
@@ -14,5 +14,5 @@
      limitations under the License.
 -->
 <permissions>
-  <feature name="android.hardware.identity_credential" version="202201" />
+  <feature name="android.hardware.identity_credential" version="202301" />
 </permissions>
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index ff80752..4c3b7b2 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -457,17 +457,16 @@
     }
 
     if (session_) {
-        // If presenting in a session, the TA has already done this check.
-
+        // If presenting in a session, the TA has already done the check for (X, Y) as done
+        // below, see eicSessionSetSessionTranscript().
     } else {
-        // To prevent replay-attacks, we check that the public part of the ephemeral
-        // key we previously created, is present in the DeviceEngagement part of
-        // SessionTranscript as a COSE_Key, in uncompressed form.
+        // If mdoc session encryption is in use, check that the
+        // public part of the ephemeral key we previously created, is
+        // present in the DeviceEngagement part of SessionTranscript
+        // as a COSE_Key, in uncompressed form.
         //
         // We do this by just searching for the X and Y coordinates.
-        //
-        // Would be nice to move this check to the TA.
-        if (sessionTranscript.size() > 0) {
+        if (sessionTranscript.size() > 0 && ephemeralPublicKey_.size() > 0) {
             auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_);
             if (!getXYSuccess) {
                 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -608,33 +607,36 @@
     // Finally, pass info so the HMAC key can be derived and the TA can start
     // creating the DeviceNameSpaces CBOR...
     if (!session_) {
-        if (sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0 &&
-            signingKeyBlob.size() > 0) {
-            // We expect the reader ephemeral public key to be same size and curve
-            // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH
-            // won't work. So its length should be 65 bytes and it should be
-            // starting with 0x04.
-            if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) {
-                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                        IIdentityCredentialStore::STATUS_FAILED,
-                        "Reader public key is not in expected format"));
+        if (sessionTranscript_.size() > 0 && signingKeyBlob.size() > 0) {
+            vector<uint8_t> eReaderKeyP256;
+            if (readerPublicKey_.size() > 0) {
+                // If set, we expect the reader ephemeral public key to be same size and curve
+                // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH won't
+                // work. So its length should be 65 bytes and it should be starting with 0x04.
+                if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) {
+                    return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                            IIdentityCredentialStore::STATUS_FAILED,
+                            "Reader public key is not in expected format"));
+                }
+                eReaderKeyP256 =
+                        vector<uint8_t>(readerPublicKey_.begin() + 1, readerPublicKey_.end());
             }
-            vector<uint8_t> pubKeyP256(readerPublicKey_.begin() + 1, readerPublicKey_.end());
-            if (!hwProxy_->calcMacKey(sessionTranscript_, pubKeyP256, signingKeyBlob, docType_,
-                                      numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
+            if (!hwProxy_->prepareDeviceAuthentication(
+                        sessionTranscript_, eReaderKeyP256, signingKeyBlob, docType_,
+                        numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
                 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                         IIdentityCredentialStore::STATUS_FAILED,
                         "Error starting retrieving entries"));
             }
         }
     } else {
-        if (session_->getSessionTranscript().size() > 0 &&
-            session_->getReaderEphemeralPublicKey().size() > 0 && signingKeyBlob.size() > 0) {
+        if (session_->getSessionTranscript().size() > 0 && signingKeyBlob.size() > 0) {
             // Don't actually pass the reader ephemeral public key in, the TA will get
             // it from the session object.
             //
-            if (!hwProxy_->calcMacKey(sessionTranscript_, {}, signingKeyBlob, docType_,
-                                      numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
+            if (!hwProxy_->prepareDeviceAuthentication(sessionTranscript_, {}, signingKeyBlob,
+                                                       docType_, numNamespacesWithValues,
+                                                       expectedDeviceNameSpacesSize_)) {
                 return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                         IIdentityCredentialStore::STATUS_FAILED,
                         "Error starting retrieving entries"));
@@ -924,8 +926,9 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<uint8_t>* outMac,
-                                                       vector<uint8_t>* outDeviceNameSpaces) {
+ndk::ScopedAStatus IdentityCredential::finishRetrievalWithSignature(
+        vector<uint8_t>* outMac, vector<uint8_t>* outDeviceNameSpaces,
+        vector<uint8_t>* outEcdsaSignature) {
     ndk::ScopedAStatus status = ensureHwProxy();
     if (!status.isOk()) {
         return status;
@@ -948,17 +951,34 @@
                         .c_str()));
     }
 
+    optional<vector<uint8_t>> digestToBeMaced;
+    optional<vector<uint8_t>> signatureToBeSigned;
+
+    // This relies on the fact that binder calls never pass a nullptr
+    // for out parameters. Hence if it's null here we know this was
+    // called from finishRetrieval() below.
+    if (outEcdsaSignature == nullptr) {
+        digestToBeMaced = hwProxy_->finishRetrieval();
+        if (!digestToBeMaced) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Error generating digestToBeMaced"));
+        }
+    } else {
+        auto macAndSignature = hwProxy_->finishRetrievalWithSignature();
+        if (!macAndSignature) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Error generating digestToBeMaced and signatureToBeSigned"));
+        }
+        digestToBeMaced = macAndSignature->first;
+        signatureToBeSigned = macAndSignature->second;
+    }
+
     // If the TA calculated a MAC (it might not have), format it as a COSE_Mac0
     //
-    optional<vector<uint8_t>> mac;
-    optional<vector<uint8_t>> digestToBeMaced = hwProxy_->finishRetrieval();
-
-    // The MAC not being set means an error occurred.
-    if (!digestToBeMaced) {
-        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                IIdentityCredentialStore::STATUS_INVALID_DATA, "Error generating digestToBeMaced"));
-    }
     // Size 0 means that the MAC isn't set. If it's set, it has to be 32 bytes.
+    optional<vector<uint8_t>> mac;
     if (digestToBeMaced.value().size() != 0) {
         if (digestToBeMaced.value().size() != 32) {
             return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -967,12 +987,27 @@
         }
         mac = support::coseMacWithDigest(digestToBeMaced.value(), {} /* data */);
     }
-
     *outMac = mac.value_or(vector<uint8_t>({}));
+
+    optional<vector<uint8_t>> signature;
+    if (signatureToBeSigned && signatureToBeSigned.value().size() != 0) {
+        signature = support::coseSignEcDsaWithSignature(signatureToBeSigned.value(), {},  // data
+                                                        {});  // certificateChain
+    }
+    if (outEcdsaSignature != nullptr) {
+        *outEcdsaSignature = signature.value_or(vector<uint8_t>({}));
+    }
+
     *outDeviceNameSpaces = encodedDeviceNameSpaces;
+
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<uint8_t>* outMac,
+                                                       vector<uint8_t>* outDeviceNameSpaces) {
+    return finishRetrievalWithSignature(outMac, outDeviceNameSpaces, nullptr);
+}
+
 ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair(
         vector<uint8_t>* outSigningKeyBlob, Certificate* outSigningKeyCertificate) {
     if (session_) {
diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h
index 5929829..1e0cd64 100644
--- a/identity/aidl/default/common/IdentityCredential.h
+++ b/identity/aidl/default/common/IdentityCredential.h
@@ -92,6 +92,10 @@
     ndk::ScopedAStatus updateCredential(
             shared_ptr<IWritableIdentityCredential>* outWritableCredential) override;
 
+    ndk::ScopedAStatus finishRetrievalWithSignature(vector<uint8_t>* outMac,
+                                                    vector<uint8_t>* outDeviceNameSpaces,
+                                                    vector<uint8_t>* outEcdsaSignature) override;
+
   private:
     ndk::ScopedAStatus deleteCredentialCommon(const vector<uint8_t>& challenge,
                                               bool includeChallenge,
diff --git a/identity/aidl/default/common/PresentationSession.cpp b/identity/aidl/default/common/PresentationSession.cpp
index 2eb7f2e..cf5b066 100644
--- a/identity/aidl/default/common/PresentationSession.cpp
+++ b/identity/aidl/default/common/PresentationSession.cpp
@@ -54,19 +54,6 @@
     }
     id_ = id.value();
 
-    optional<vector<uint8_t>> ephemeralKeyPriv = hwProxy_->getEphemeralKeyPair();
-    if (!ephemeralKeyPriv) {
-        LOG(ERROR) << "Error getting ephemeral private key for session";
-        return IIdentityCredentialStore::STATUS_FAILED;
-    }
-    optional<vector<uint8_t>> ephemeralKeyPair =
-            support::ecPrivateKeyToKeyPair(ephemeralKeyPriv.value());
-    if (!ephemeralKeyPair) {
-        LOG(ERROR) << "Error creating ephemeral key-pair";
-        return IIdentityCredentialStore::STATUS_FAILED;
-    }
-    ephemeralKeyPair_ = ephemeralKeyPair.value();
-
     optional<uint64_t> authChallenge = hwProxy_->getAuthChallenge();
     if (!authChallenge) {
         LOG(ERROR) << "Error getting authChallenge for session";
@@ -78,6 +65,23 @@
 }
 
 ndk::ScopedAStatus PresentationSession::getEphemeralKeyPair(vector<uint8_t>* outKeyPair) {
+    if (ephemeralKeyPair_.size() == 0) {
+        optional<vector<uint8_t>> ephemeralKeyPriv = hwProxy_->getEphemeralKeyPair();
+        if (!ephemeralKeyPriv) {
+            LOG(ERROR) << "Error getting ephemeral private key for session";
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_FAILED,
+                    "Error getting ephemeral private key for session"));
+        }
+        optional<vector<uint8_t>> ephemeralKeyPair =
+                support::ecPrivateKeyToKeyPair(ephemeralKeyPriv.value());
+        if (!ephemeralKeyPair) {
+            LOG(ERROR) << "Error creating ephemeral key-pair";
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_FAILED, "Error creating ephemeral key-pair"));
+        }
+        ephemeralKeyPair_ = ephemeralKeyPair.value();
+    }
     *outKeyPair = ephemeralKeyPair_;
     return ndk::ScopedAStatus::ok();
 }
diff --git a/identity/aidl/default/common/PresentationSession.h b/identity/aidl/default/common/PresentationSession.h
index 4cb174a..b3d46f9 100644
--- a/identity/aidl/default/common/PresentationSession.h
+++ b/identity/aidl/default/common/PresentationSession.h
@@ -72,9 +72,11 @@
 
     // Set by initialize()
     uint64_t id_;
-    vector<uint8_t> ephemeralKeyPair_;
     uint64_t authChallenge_;
 
+    // Set by getEphemeralKeyPair()
+    vector<uint8_t> ephemeralKeyPair_;
+
     // Set by setReaderEphemeralPublicKey()
     vector<uint8_t> readerPublicKey_;
 
diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h
index 9f63ad8..6463318 100644
--- a/identity/aidl/default/common/SecureHardwareProxy.h
+++ b/identity/aidl/default/common/SecureHardwareProxy.h
@@ -194,11 +194,12 @@
                                         const vector<uint8_t>& requestMessage, int coseSignAlg,
                                         const vector<uint8_t>& readerSignatureOfToBeSigned) = 0;
 
-    virtual bool calcMacKey(const vector<uint8_t>& sessionTranscript,
-                            const vector<uint8_t>& readerEphemeralPublicKey,
-                            const vector<uint8_t>& signingKeyBlob, const string& docType,
-                            unsigned int numNamespacesWithValues,
-                            size_t expectedProofOfProvisioningSize) = 0;
+    virtual bool prepareDeviceAuthentication(const vector<uint8_t>& sessionTranscript,
+                                             const vector<uint8_t>& readerEphemeralPublicKey,
+                                             const vector<uint8_t>& signingKeyBlob,
+                                             const string& docType,
+                                             unsigned int numNamespacesWithValues,
+                                             size_t expectedDeviceNamespacesSize) = 0;
 
     virtual AccessCheckResult startRetrieveEntryValue(
             const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries,
@@ -209,6 +210,7 @@
             const vector<int32_t>& accessControlProfileIds) = 0;
 
     virtual optional<vector<uint8_t>> finishRetrieval();
+    virtual optional<pair<vector<uint8_t>, vector<uint8_t>>> finishRetrievalWithSignature();
 
     virtual optional<vector<uint8_t>> deleteCredential(const string& docType,
                                                        const vector<uint8_t>& challenge,
diff --git a/identity/aidl/default/identity-default.xml b/identity/aidl/default/identity-default.xml
index cc0ddc7..d0d43af 100644
--- a/identity/aidl/default/identity-default.xml
+++ b/identity/aidl/default/identity-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.identity</name>
-        <version>4</version>
+        <version>5</version>
         <interface>
             <name>IIdentityCredentialStore</name>
             <instance>default</instance>
diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c
index 104a559..23fd0b3 100644
--- a/identity/aidl/default/libeic/EicPresentation.c
+++ b/identity/aidl/default/libeic/EicPresentation.c
@@ -557,87 +557,11 @@
     return true;
 }
 
-bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTranscript,
-                               size_t sessionTranscriptSize,
-                               const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE],
-                               const uint8_t signingKeyBlob[60], const char* docType,
-                               size_t docTypeLength, unsigned int numNamespacesWithValues,
-                               size_t expectedDeviceNamespacesSize) {
-    if (ctx->sessionId != 0) {
-        EicSession* session = eicSessionGetForId(ctx->sessionId);
-        if (session == NULL) {
-            eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId);
-            return false;
-        }
-        EicSha256Ctx sha256;
-        uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE];
-        eicOpsSha256Init(&sha256);
-        eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize);
-        eicOpsSha256Final(&sha256, sessionTranscriptSha256);
-        if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256,
-                            EIC_SHA256_DIGEST_SIZE) != 0) {
-            eicDebug("SessionTranscript mismatch");
-            return false;
-        }
-        readerEphemeralPublicKey = session->readerEphemeralPublicKey;
-    }
-
-    uint8_t signingKeyPriv[EIC_P256_PRIV_KEY_SIZE];
-    if (!eicOpsDecryptAes128Gcm(ctx->storageKey, signingKeyBlob, 60, (const uint8_t*)docType,
-                                docTypeLength, signingKeyPriv)) {
-        eicDebug("Error decrypting signingKeyBlob");
-        return false;
-    }
-
-    uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE];
-    if (!eicOpsEcdh(readerEphemeralPublicKey, signingKeyPriv, sharedSecret)) {
-        eicDebug("ECDH failed");
-        return false;
-    }
-
-    EicCbor cbor;
-    eicCborInit(&cbor, NULL, 0);
-    eicCborAppendSemantic(&cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
-    eicCborAppendByteString(&cbor, sessionTranscript, sessionTranscriptSize);
-    uint8_t salt[EIC_SHA256_DIGEST_SIZE];
-    eicCborFinal(&cbor, salt);
-
-    const uint8_t info[7] = {'E', 'M', 'a', 'c', 'K', 'e', 'y'};
-    uint8_t derivedKey[32];
-    if (!eicOpsHkdf(sharedSecret, EIC_P256_COORDINATE_SIZE, salt, sizeof(salt), info, sizeof(info),
-                    derivedKey, sizeof(derivedKey))) {
-        eicDebug("HKDF failed");
-        return false;
-    }
-
-    eicCborInitHmacSha256(&ctx->cbor, NULL, 0, derivedKey, sizeof(derivedKey));
-    ctx->buildCbor = true;
-
-    // What we're going to calculate the HMAC-SHA256 is the COSE ToBeMaced
-    // structure which looks like the following:
-    //
-    // MAC_structure = [
-    //   context : "MAC" / "MAC0",
-    //   protected : empty_or_serialized_map,
-    //   external_aad : bstr,
-    //   payload : bstr
-    // ]
-    //
-    eicCborAppendArray(&ctx->cbor, 4);
-    eicCborAppendStringZ(&ctx->cbor, "MAC0");
-
-    // The COSE Encoded protected headers is just a single field with
-    // COSE_LABEL_ALG (1) -> COSE_ALG_HMAC_256_256 (5). For simplicitly we just
-    // hard-code the CBOR encoding:
-    static const uint8_t coseEncodedProtectedHeaders[] = {0xa1, 0x01, 0x05};
-    eicCborAppendByteString(&ctx->cbor, coseEncodedProtectedHeaders,
-                            sizeof(coseEncodedProtectedHeaders));
-
-    // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
-    // so external_aad is the empty bstr
-    static const uint8_t externalAad[0] = {};
-    eicCborAppendByteString(&ctx->cbor, externalAad, sizeof(externalAad));
-
+// Helper used to append the DeviceAuthencation prelude, used for both MACing and ECDSA signing.
+static size_t appendDeviceAuthentication(EicCbor* cbor, const uint8_t* sessionTranscript,
+                                         size_t sessionTranscriptSize, const char* docType,
+                                         size_t docTypeLength,
+                                         size_t expectedDeviceNamespacesSize) {
     // For the payload, the _encoded_ form follows here. We handle this by simply
     // opening a bstr, and then writing the CBOR. This requires us to know the
     // size of said bstr, ahead of time... the CBOR to be written is
@@ -674,26 +598,148 @@
     dabCalculatedSize += calculatedSize;
 
     // Begin the bytestring for DeviceAuthenticationBytes;
-    eicCborBegin(&ctx->cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, dabCalculatedSize);
+    eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, dabCalculatedSize);
 
-    eicCborAppendSemantic(&ctx->cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+    eicCborAppendSemantic(cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
 
     // Begins the bytestring for DeviceAuthentication;
-    eicCborBegin(&ctx->cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, calculatedSize);
+    eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, calculatedSize);
 
-    eicCborAppendArray(&ctx->cbor, 4);
-    eicCborAppendStringZ(&ctx->cbor, "DeviceAuthentication");
-    eicCborAppend(&ctx->cbor, sessionTranscript, sessionTranscriptSize);
-    eicCborAppendString(&ctx->cbor, docType, docTypeLength);
+    eicCborAppendArray(cbor, 4);
+    eicCborAppendStringZ(cbor, "DeviceAuthentication");
+    eicCborAppend(cbor, sessionTranscript, sessionTranscriptSize);
+    eicCborAppendString(cbor, docType, docTypeLength);
 
     // For the payload, the _encoded_ form follows here. We handle this by simply
     // opening a bstr, and then writing the CBOR. This requires us to know the
     // size of said bstr, ahead of time.
-    eicCborAppendSemantic(&ctx->cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
-    eicCborBegin(&ctx->cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, expectedDeviceNamespacesSize);
-    ctx->expectedCborSizeAtEnd = expectedDeviceNamespacesSize + ctx->cbor.size;
+    eicCborAppendSemantic(cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+    eicCborBegin(cbor, EIC_CBOR_MAJOR_TYPE_BYTE_STRING, expectedDeviceNamespacesSize);
+    size_t expectedCborSizeAtEnd = expectedDeviceNamespacesSize + cbor->size;
 
-    eicCborAppendMap(&ctx->cbor, numNamespacesWithValues);
+    return expectedCborSizeAtEnd;
+}
+
+bool eicPresentationPrepareDeviceAuthentication(
+        EicPresentation* ctx, const uint8_t* sessionTranscript, size_t sessionTranscriptSize,
+        const uint8_t* readerEphemeralPublicKey, size_t readerEphemeralPublicKeySize,
+        const uint8_t signingKeyBlob[60], const char* docType, size_t docTypeLength,
+        unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize) {
+    if (ctx->sessionId != 0) {
+        if (readerEphemeralPublicKeySize != 0) {
+            eicDebug("In a session but readerEphemeralPublicKeySize is non-zero");
+            return false;
+        }
+        EicSession* session = eicSessionGetForId(ctx->sessionId);
+        if (session == NULL) {
+            eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId);
+            return false;
+        }
+        EicSha256Ctx sha256;
+        uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE];
+        eicOpsSha256Init(&sha256);
+        eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize);
+        eicOpsSha256Final(&sha256, sessionTranscriptSha256);
+        if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256,
+                            EIC_SHA256_DIGEST_SIZE) != 0) {
+            eicDebug("SessionTranscript mismatch");
+            return false;
+        }
+        readerEphemeralPublicKey = session->readerEphemeralPublicKey;
+        readerEphemeralPublicKeySize = session->readerEphemeralPublicKeySize;
+    }
+
+    // Stash the decrypted DeviceKey in context since we'll need it later in
+    // eicPresentationFinishRetrievalWithSignature()
+    if (!eicOpsDecryptAes128Gcm(ctx->storageKey, signingKeyBlob, 60, (const uint8_t*)docType,
+                                docTypeLength, ctx->deviceKeyPriv)) {
+        eicDebug("Error decrypting signingKeyBlob");
+        return false;
+    }
+
+    // We can only do MACing if EReaderKey has been set... it might not have been set if for
+    // example mdoc session encryption isn't in use. In that case we can still do ECDSA
+    if (readerEphemeralPublicKeySize > 0) {
+        if (readerEphemeralPublicKeySize != EIC_P256_PUB_KEY_SIZE) {
+            eicDebug("Unexpected size %zd for readerEphemeralPublicKeySize",
+                     readerEphemeralPublicKeySize);
+            return false;
+        }
+
+        uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE];
+        if (!eicOpsEcdh(readerEphemeralPublicKey, ctx->deviceKeyPriv, sharedSecret)) {
+            eicDebug("ECDH failed");
+            return false;
+        }
+
+        EicCbor cbor;
+        eicCborInit(&cbor, NULL, 0);
+        eicCborAppendSemantic(&cbor, EIC_CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+        eicCborAppendByteString(&cbor, sessionTranscript, sessionTranscriptSize);
+        uint8_t salt[EIC_SHA256_DIGEST_SIZE];
+        eicCborFinal(&cbor, salt);
+
+        const uint8_t info[7] = {'E', 'M', 'a', 'c', 'K', 'e', 'y'};
+        uint8_t derivedKey[32];
+        if (!eicOpsHkdf(sharedSecret, EIC_P256_COORDINATE_SIZE, salt, sizeof(salt), info,
+                        sizeof(info), derivedKey, sizeof(derivedKey))) {
+            eicDebug("HKDF failed");
+            return false;
+        }
+
+        eicCborInitHmacSha256(&ctx->cbor, NULL, 0, derivedKey, sizeof(derivedKey));
+
+        // What we're going to calculate the HMAC-SHA256 is the COSE ToBeMaced
+        // structure which looks like the following:
+        //
+        // MAC_structure = [
+        //   context : "MAC" / "MAC0",
+        //   protected : empty_or_serialized_map,
+        //   external_aad : bstr,
+        //   payload : bstr
+        // ]
+        //
+        eicCborAppendArray(&ctx->cbor, 4);
+        eicCborAppendStringZ(&ctx->cbor, "MAC0");
+
+        // The COSE Encoded protected headers is just a single field with
+        // COSE_LABEL_ALG (1) -> COSE_ALG_HMAC_256_256 (5). For simplicitly we just
+        // hard-code the CBOR encoding:
+        static const uint8_t coseEncodedProtectedHeaders[] = {0xa1, 0x01, 0x05};
+        eicCborAppendByteString(&ctx->cbor, coseEncodedProtectedHeaders,
+                                sizeof(coseEncodedProtectedHeaders));
+
+        // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
+        // so external_aad is the empty bstr
+        static const uint8_t externalAad[0] = {};
+        eicCborAppendByteString(&ctx->cbor, externalAad, sizeof(externalAad));
+
+        // Append DeviceAuthentication prelude and open the DeviceSigned map...
+        ctx->expectedCborSizeAtEnd =
+                appendDeviceAuthentication(&ctx->cbor, sessionTranscript, sessionTranscriptSize,
+                                           docType, docTypeLength, expectedDeviceNamespacesSize);
+        eicCborAppendMap(&ctx->cbor, numNamespacesWithValues);
+        ctx->buildCbor = true;
+    }
+
+    // Now do the same for ECDSA signatures...
+    //
+    eicCborInit(&ctx->cborEcdsa, NULL, 0);
+    eicCborAppendArray(&ctx->cborEcdsa, 4);
+    eicCborAppendStringZ(&ctx->cborEcdsa, "Signature1");
+    static const uint8_t coseEncodedProtectedHeadersEcdsa[] = {0xa1, 0x01, 0x26};
+    eicCborAppendByteString(&ctx->cborEcdsa, coseEncodedProtectedHeadersEcdsa,
+                            sizeof(coseEncodedProtectedHeadersEcdsa));
+    static const uint8_t externalAadEcdsa[0] = {};
+    eicCborAppendByteString(&ctx->cborEcdsa, externalAadEcdsa, sizeof(externalAadEcdsa));
+
+    // Append DeviceAuthentication prelude and open the DeviceSigned map...
+    ctx->expectedCborEcdsaSizeAtEnd =
+            appendDeviceAuthentication(&ctx->cborEcdsa, sessionTranscript, sessionTranscriptSize,
+                                       docType, docTypeLength, expectedDeviceNamespacesSize);
+    eicCborAppendMap(&ctx->cborEcdsa, numNamespacesWithValues);
+    ctx->buildCborEcdsa = true;
+
     return true;
 }
 
@@ -702,6 +748,7 @@
     // state objects here.
     ctx->requestMessageValidated = false;
     ctx->buildCbor = false;
+    ctx->buildCborEcdsa = false;
     ctx->accessControlProfileMaskValidated = 0;
     ctx->accessControlProfileMaskUsesReaderAuth = 0;
     ctx->accessControlProfileMaskFailedReaderAuth = 0;
@@ -724,6 +771,9 @@
     if (newNamespaceNumEntries > 0) {
         eicCborAppendString(&ctx->cbor, nameSpace, nameSpaceLength);
         eicCborAppendMap(&ctx->cbor, newNamespaceNumEntries);
+
+        eicCborAppendString(&ctx->cborEcdsa, nameSpace, nameSpaceLength);
+        eicCborAppendMap(&ctx->cborEcdsa, newNamespaceNumEntries);
     }
 
     // We'll need to calc and store a digest of additionalData to check that it's the same
@@ -778,6 +828,7 @@
 
     if (result == EIC_ACCESS_CHECK_RESULT_OK) {
         eicCborAppendString(&ctx->cbor, name, nameLength);
+        eicCborAppendString(&ctx->cborEcdsa, name, nameLength);
         ctx->accessCheckOk = true;
     }
     return result;
@@ -821,6 +872,7 @@
     }
 
     eicCborAppend(&ctx->cbor, content, encryptedContentSize - 28);
+    eicCborAppend(&ctx->cborEcdsa, content, encryptedContentSize - 28);
 
     return true;
 }
@@ -842,6 +894,40 @@
         return false;
     }
     eicCborFinal(&ctx->cbor, digestToBeMaced);
+
+    return true;
+}
+
+bool eicPresentationFinishRetrievalWithSignature(EicPresentation* ctx, uint8_t* digestToBeMaced,
+                                                 size_t* digestToBeMacedSize,
+                                                 uint8_t* signatureOfToBeSigned,
+                                                 size_t* signatureOfToBeSignedSize) {
+    if (!eicPresentationFinishRetrieval(ctx, digestToBeMaced, digestToBeMacedSize)) {
+        return false;
+    }
+
+    if (!ctx->buildCborEcdsa) {
+        *signatureOfToBeSignedSize = 0;
+        return true;
+    }
+    if (*signatureOfToBeSignedSize != EIC_ECDSA_P256_SIGNATURE_SIZE) {
+        return false;
+    }
+
+    // This verifies that the correct expectedDeviceNamespacesSize value was
+    // passed in at eicPresentationCalcMacKey() time.
+    if (ctx->cborEcdsa.size != ctx->expectedCborEcdsaSizeAtEnd) {
+        eicDebug("CBOR ECDSA size is %zd, was expecting %zd", ctx->cborEcdsa.size,
+                 ctx->expectedCborEcdsaSizeAtEnd);
+        return false;
+    }
+    uint8_t cborSha256[EIC_SHA256_DIGEST_SIZE];
+    eicCborFinal(&ctx->cborEcdsa, cborSha256);
+    if (!eicOpsEcDsa(ctx->deviceKeyPriv, cborSha256, signatureOfToBeSigned)) {
+        eicDebug("Error signing DeviceAuthentication");
+        return false;
+    }
+    eicDebug("set the signature");
     return true;
 }
 
diff --git a/identity/aidl/default/libeic/EicPresentation.h b/identity/aidl/default/libeic/EicPresentation.h
index a031890..cd3162a 100644
--- a/identity/aidl/default/libeic/EicPresentation.h
+++ b/identity/aidl/default/libeic/EicPresentation.h
@@ -76,6 +76,7 @@
     // aren't.
     bool requestMessageValidated;
     bool buildCbor;
+    bool buildCborEcdsa;
 
     // Set to true initialized as a test credential.
     bool testCredential;
@@ -101,6 +102,12 @@
 
     size_t expectedCborSizeAtEnd;
     EicCbor cbor;
+
+    // The selected DeviceKey / AuthKey
+    uint8_t deviceKeyPriv[EIC_P256_PRIV_KEY_SIZE];
+
+    EicCbor cborEcdsa;
+    size_t expectedCborEcdsaSizeAtEnd;
 } EicPresentation;
 
 // If sessionId is zero (EIC_PRESENTATION_ID_UNSET), the presentation object is not associated
@@ -214,14 +221,13 @@
     EIC_ACCESS_CHECK_RESULT_READER_AUTHENTICATION_FAILED,
 } EicAccessCheckResult;
 
-// Passes enough information to calculate the MACing key
+// Passes enough information to calculate the MACing key and/or prepare ECDSA signing
 //
-bool eicPresentationCalcMacKey(EicPresentation* ctx, const uint8_t* sessionTranscript,
-                               size_t sessionTranscriptSize,
-                               const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE],
-                               const uint8_t signingKeyBlob[60], const char* docType,
-                               size_t docTypeLength, unsigned int numNamespacesWithValues,
-                               size_t expectedDeviceNamespacesSize);
+bool eicPresentationPrepareDeviceAuthentication(
+        EicPresentation* ctx, const uint8_t* sessionTranscript, size_t sessionTranscriptSize,
+        const uint8_t* readerEphemeralPublicKey, size_t readerEphemeralPublicKeySize,
+        const uint8_t signingKeyBlob[60], const char* docType, size_t docTypeLength,
+        unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize);
 
 // The scratchSpace should be set to a buffer at least 512 bytes (ideally 1024
 // bytes, the bigger the better). It's done this way to avoid allocating stack
@@ -253,6 +259,13 @@
 bool eicPresentationFinishRetrieval(EicPresentation* ctx, uint8_t* digestToBeMaced,
                                     size_t* digestToBeMacedSize);
 
+// Like eicPresentationFinishRetrieval() but also returns an ECDSA signature.
+//
+bool eicPresentationFinishRetrievalWithSignature(EicPresentation* ctx, uint8_t* digestToBeMaced,
+                                                 size_t* digestToBeMacedSize,
+                                                 uint8_t* signatureOfToBeSigned,
+                                                 size_t* signatureOfToBeSignedSize);
+
 // The data returned in |signatureOfToBeSigned| contains the ECDSA signature of
 // the ToBeSigned CBOR from RFC 8051 "4.4. Signing and Verification Process"
 // where content is set to the ProofOfDeletion CBOR.
diff --git a/identity/aidl/default/libeic/EicSession.c b/identity/aidl/default/libeic/EicSession.c
index d0c7a0d..e44fa68 100644
--- a/identity/aidl/default/libeic/EicSession.c
+++ b/identity/aidl/default/libeic/EicSession.c
@@ -84,30 +84,35 @@
 bool eicSessionGetEphemeralKeyPair(EicSession* ctx,
                                    uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]) {
     eicMemCpy(ephemeralPrivateKey, ctx->ephemeralPrivateKey, EIC_P256_PRIV_KEY_SIZE);
+    ctx->getEphemeralKeyPairCalled = true;
     return true;
 }
 
 bool eicSessionSetReaderEphemeralPublicKey(
         EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]) {
     eicMemCpy(ctx->readerEphemeralPublicKey, readerEphemeralPublicKey, EIC_P256_PUB_KEY_SIZE);
+    ctx->readerEphemeralPublicKeySize = EIC_P256_PUB_KEY_SIZE;
     return true;
 }
 
 bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript,
                                     size_t sessionTranscriptSize) {
-    // Only accept the SessionTranscript if X and Y from the ephemeral key
-    // we created is somewhere in SessionTranscript...
+    // If mdoc session encryption is in use, only accept the
+    // SessionTranscript if X and Y from the ephemeral key we created
+    // is somewhere in SessionTranscript...
     //
-    if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey,
-                  EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
-        eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript");
-        return false;
-    }
-    if (eicMemMem(sessionTranscript, sessionTranscriptSize,
-                  ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2,
-                  EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
-        eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript");
-        return false;
+    if (ctx->getEphemeralKeyPairCalled) {
+        if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey,
+                      EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
+            eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript");
+            return false;
+        }
+        if (eicMemMem(sessionTranscript, sessionTranscriptSize,
+                      ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2,
+                      EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
+            eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript");
+            return false;
+        }
     }
 
     // To save space we only store the SHA-256 of SessionTranscript
diff --git a/identity/aidl/default/libeic/EicSession.h b/identity/aidl/default/libeic/EicSession.h
index 0303dae..ae9babf 100644
--- a/identity/aidl/default/libeic/EicSession.h
+++ b/identity/aidl/default/libeic/EicSession.h
@@ -31,6 +31,9 @@
     // A non-zero number unique for this EicSession instance
     uint32_t id;
 
+    // Set to true iff eicSessionGetEphemeralKeyPair() has been called.
+    bool getEphemeralKeyPairCalled;
+
     // The challenge generated at construction time by eicSessionInit().
     uint64_t authChallenge;
 
@@ -41,6 +44,7 @@
 
     uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE];
 
+    size_t readerEphemeralPublicKeySize;
 } EicSession;
 
 bool eicSessionInit(EicSession* ctx);
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 51ab110..6f7ab54 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -11,6 +11,7 @@
     name: "VtsHalIdentityTargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
+        "identity_use_latest_hal_aidl_cpp_static",
         "keymint_use_latest_hal_aidl_cpp_static",
         "keymint_use_latest_hal_aidl_ndk_static",
         "use_libaidlvintf_gtest_helper_static",
@@ -38,6 +39,8 @@
         "libcrypto",
     ],
     static_libs: [
+        "android.hardware.security.rkp-V3-cpp",
+        "android.hardware.security.rkp-V3-ndk",
         "android.hardware.security.secureclock-V1-ndk",
         "libcppbor_external",
         "libcppcose_rkp",
@@ -46,7 +49,6 @@
         "libpuresoftkeymasterdevice",
         "android.hardware.keymaster@4.0",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-V4-cpp",
         "android.hardware.keymaster-V3-cpp",
         "android.hardware.keymaster-V3-ndk",
         "libkeymaster4support",
diff --git a/identity/aidl/vts/AndroidTest.xml b/identity/aidl/vts/AndroidTest.xml
new file mode 100644
index 0000000..67132b0
--- /dev/null
+++ b/identity/aidl/vts/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs VtsHalIdentityTargetTest.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push"
+                value="VtsHalIdentityTargetTest->/data/local/tmp/VtsHalIdentityTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalIdentityTargetTest" />
+        <option name="native-test-timeout" value="300000"/>
+    </test>
+</configuration>
diff --git a/identity/aidl/vts/EndToEndTests.cpp b/identity/aidl/vts/EndToEndTests.cpp
index 67db915..ae9035b 100644
--- a/identity/aidl/vts/EndToEndTests.cpp
+++ b/identity/aidl/vts/EndToEndTests.cpp
@@ -441,8 +441,18 @@
     }
 
     vector<uint8_t> mac;
+    vector<uint8_t> ecdsaSignature;
     vector<uint8_t> deviceNameSpacesEncoded;
-    ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    // API version 5 (feature version 202301) returns both MAC and ECDSA signature.
+    if (halApiVersion_ >= 5) {
+        ASSERT_TRUE(credential
+                            ->finishRetrievalWithSignature(&mac, &deviceNameSpacesEncoded,
+                                                           &ecdsaSignature)
+                            .isOk());
+        ASSERT_GT(ecdsaSignature.size(), 0);
+    } else {
+        ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    }
     cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
     ASSERT_EQ(
             "{\n"
@@ -475,6 +485,21 @@
     ASSERT_TRUE(calculatedMac);
     EXPECT_EQ(mac, calculatedMac);
 
+    if (ecdsaSignature.size() > 0) {
+        vector<uint8_t> encodedDeviceAuthentication =
+                cppbor::Array()
+                        .add("DeviceAuthentication")
+                        .add(sessionTranscript.clone())
+                        .add(docType)
+                        .add(cppbor::SemanticTag(24, deviceNameSpacesEncoded))
+                        .encode();
+        vector<uint8_t> deviceAuthenticationBytes =
+                cppbor::SemanticTag(24, encodedDeviceAuthentication).encode();
+        EXPECT_TRUE(support::coseCheckEcDsaSignature(ecdsaSignature,
+                                                     deviceAuthenticationBytes,  // Detached content
+                                                     signingPubKey.value()));
+    }
+
     // Also perform an additional empty request. This is what mDL applications
     // are envisioned to do - one call to get the data elements, another to get
     // an empty DeviceSignedItems and corresponding MAC.
@@ -486,7 +511,16 @@
                                 signingKeyBlob, sessionTranscriptEncoded, {},  // readerSignature,
                                 testEntriesEntryCounts)
                         .isOk());
-    ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    // API version 5 (feature version 202301) returns both MAC and ECDSA signature.
+    if (halApiVersion_ >= 5) {
+        ASSERT_TRUE(credential
+                            ->finishRetrievalWithSignature(&mac, &deviceNameSpacesEncoded,
+                                                           &ecdsaSignature)
+                            .isOk());
+        ASSERT_GT(ecdsaSignature.size(), 0);
+    } else {
+        ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    }
     cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
     ASSERT_EQ("{}", cborPretty);
     // Calculate DeviceAuthentication and MAC (MACing key hasn't changed)
@@ -497,6 +531,21 @@
     ASSERT_TRUE(calculatedMac);
     EXPECT_EQ(mac, calculatedMac);
 
+    if (ecdsaSignature.size() > 0) {
+        vector<uint8_t> encodedDeviceAuthentication =
+                cppbor::Array()
+                        .add("DeviceAuthentication")
+                        .add(sessionTranscript.clone())
+                        .add(docType)
+                        .add(cppbor::SemanticTag(24, deviceNameSpacesEncoded))
+                        .encode();
+        vector<uint8_t> deviceAuthenticationBytes =
+                cppbor::SemanticTag(24, encodedDeviceAuthentication).encode();
+        EXPECT_TRUE(support::coseCheckEcDsaSignature(ecdsaSignature,
+                                                     deviceAuthenticationBytes,  // Detached content
+                                                     signingPubKey.value()));
+    }
+
     // Some mDL apps might send a request but with a single empty
     // namespace. Check that too.
     RequestNamespace emptyRequestNS;
@@ -508,7 +557,16 @@
                                 signingKeyBlob, sessionTranscriptEncoded, {},  // readerSignature,
                                 testEntriesEntryCounts)
                         .isOk());
-    ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    // API version 5 (feature version 202301) returns both MAC and ECDSA signature.
+    if (halApiVersion_ >= 5) {
+        ASSERT_TRUE(credential
+                            ->finishRetrievalWithSignature(&mac, &deviceNameSpacesEncoded,
+                                                           &ecdsaSignature)
+                            .isOk());
+        ASSERT_GT(ecdsaSignature.size(), 0);
+    } else {
+        ASSERT_TRUE(credential->finishRetrieval(&mac, &deviceNameSpacesEncoded).isOk());
+    }
     cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
     ASSERT_EQ("{}", cborPretty);
     // Calculate DeviceAuthentication and MAC (MACing key hasn't changed)
@@ -518,6 +576,248 @@
                                      eMacKey.value());            // EMacKey
     ASSERT_TRUE(calculatedMac);
     EXPECT_EQ(mac, calculatedMac);
+
+    if (ecdsaSignature.size() > 0) {
+        vector<uint8_t> encodedDeviceAuthentication =
+                cppbor::Array()
+                        .add("DeviceAuthentication")
+                        .add(sessionTranscript.clone())
+                        .add(docType)
+                        .add(cppbor::SemanticTag(24, deviceNameSpacesEncoded))
+                        .encode();
+        vector<uint8_t> deviceAuthenticationBytes =
+                cppbor::SemanticTag(24, encodedDeviceAuthentication).encode();
+        EXPECT_TRUE(support::coseCheckEcDsaSignature(ecdsaSignature,
+                                                     deviceAuthenticationBytes,  // Detached content
+                                                     signingPubKey.value()));
+    }
+}
+
+TEST_P(EndToEndTests, noSessionEncryption) {
+    if (halApiVersion_ < 5) {
+        GTEST_SKIP() << "Need HAL API version 5, have " << halApiVersion_;
+    }
+
+    const vector<test_utils::TestProfile> testProfiles = {// Profile 0 (no authentication)
+                                                          {0, {}, false, 0}};
+
+    HardwareAuthToken authToken;
+    VerificationToken verificationToken;
+    authToken.challenge = 0;
+    authToken.userId = 0;
+    authToken.authenticatorId = 0;
+    authToken.authenticatorType = ::android::hardware::keymaster::HardwareAuthenticatorType::NONE;
+    authToken.timestamp.milliSeconds = 0;
+    authToken.mac.clear();
+    verificationToken.challenge = 0;
+    verificationToken.timestamp.milliSeconds = 0;
+    verificationToken.securityLevel = ::android::hardware::keymaster::SecurityLevel::SOFTWARE;
+    verificationToken.mac.clear();
+
+    // Here's the actual test data:
+    const vector<test_utils::TestEntryData> testEntries = {
+            {"PersonalData", "Last name", string("Turing"), vector<int32_t>{0}},
+            {"PersonalData", "Birth date", string("19120623"), vector<int32_t>{0}},
+            {"PersonalData", "First name", string("Alan"), vector<int32_t>{0}},
+    };
+    const vector<int32_t> testEntriesEntryCounts = {3};
+    HardwareInformation hwInfo;
+    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
+
+    string cborPretty;
+    sp<IWritableIdentityCredential> writableCredential;
+    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
+                                                    true /* testCredential */));
+
+    string challenge = "attestationChallenge";
+    test_utils::AttestationData attData(writableCredential, challenge,
+                                        {1} /* atteestationApplicationId */);
+    ASSERT_TRUE(attData.result.isOk())
+            << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
+
+    // This is kinda of a hack but we need to give the size of
+    // ProofOfProvisioning that we'll expect to receive.
+    const int32_t expectedProofOfProvisioningSize = 230;
+    // OK to fail, not available in v1 HAL
+    writableCredential->setExpectedProofOfProvisioningSize(expectedProofOfProvisioningSize);
+    ASSERT_TRUE(
+            writableCredential->startPersonalization(testProfiles.size(), testEntriesEntryCounts)
+                    .isOk());
+
+    optional<vector<SecureAccessControlProfile>> secureProfiles =
+            test_utils::addAccessControlProfiles(writableCredential, testProfiles);
+    ASSERT_TRUE(secureProfiles);
+
+    // Uses TestEntryData* pointer as key and values are the encrypted blobs. This
+    // is a little hacky but it works well enough.
+    map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
+
+    for (const auto& entry : testEntries) {
+        ASSERT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
+                                         encryptedBlobs, true));
+    }
+
+    vector<uint8_t> credentialData;
+    vector<uint8_t> proofOfProvisioningSignature;
+    ASSERT_TRUE(
+            writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature)
+                    .isOk());
+
+    // Validate the proofOfProvisioning which was returned
+    optional<vector<uint8_t>> proofOfProvisioning =
+            support::coseSignGetPayload(proofOfProvisioningSignature);
+    ASSERT_TRUE(proofOfProvisioning);
+    cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
+    EXPECT_EQ(
+            "[\n"
+            "  'ProofOfProvisioning',\n"
+            "  'org.iso.18013-5.2019.mdl',\n"
+            "  [\n"
+            "    {\n"
+            "      'id' : 0,\n"
+            "    },\n"
+            "  ],\n"
+            "  {\n"
+            "    'PersonalData' : [\n"
+            "      {\n"
+            "        'name' : 'Last name',\n"
+            "        'value' : 'Turing',\n"
+            "        'accessControlProfiles' : [0, ],\n"
+            "      },\n"
+            "      {\n"
+            "        'name' : 'Birth date',\n"
+            "        'value' : '19120623',\n"
+            "        'accessControlProfiles' : [0, ],\n"
+            "      },\n"
+            "      {\n"
+            "        'name' : 'First name',\n"
+            "        'value' : 'Alan',\n"
+            "        'accessControlProfiles' : [0, ],\n"
+            "      },\n"
+            "    ],\n"
+            "  },\n"
+            "  true,\n"
+            "]",
+            cborPretty);
+
+    optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
+            attData.attestationCertificate[0].encodedCertificate);
+    ASSERT_TRUE(credentialPubKey);
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
+                                                 {},  // Additional data
+                                                 credentialPubKey.value()));
+    writableCredential = nullptr;
+
+    // Extract doctype, storage key, and credentialPrivKey from credentialData... this works
+    // only because we asked for a test-credential meaning that the HBK is all zeroes.
+    auto [exSuccess, exDocType, exStorageKey, exCredentialPrivKey, exSha256Pop] =
+            extractFromTestCredentialData(credentialData);
+
+    ASSERT_TRUE(exSuccess);
+    ASSERT_EQ(exDocType, "org.iso.18013-5.2019.mdl");
+    // ... check that the public key derived from the private key matches what was
+    // in the certificate.
+    optional<vector<uint8_t>> exCredentialKeyPair =
+            support::ecPrivateKeyToKeyPair(exCredentialPrivKey);
+    ASSERT_TRUE(exCredentialKeyPair);
+    optional<vector<uint8_t>> exCredentialPubKey =
+            support::ecKeyPairGetPublicKey(exCredentialKeyPair.value());
+    ASSERT_TRUE(exCredentialPubKey);
+    ASSERT_EQ(exCredentialPubKey.value(), credentialPubKey.value());
+
+    sp<IIdentityCredential> credential;
+    ASSERT_TRUE(credentialStore_
+                        ->getCredential(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                credentialData, &credential)
+                        .isOk());
+    ASSERT_NE(credential, nullptr);
+
+    // Calculate sessionTranscript, make something that resembles what you'd use for
+    // an over-the-Internet presentation not using mdoc session encryption.
+    cppbor::Array sessionTranscript =
+            cppbor::Array()
+                    .add(cppbor::Null())  // DeviceEngagementBytes isn't used.
+                    .add(cppbor::Null())  // EReaderKeyBytes isn't used.
+                    .add(cppbor::Array()  // Proprietary handover structure follows.
+                                 .add(cppbor::Tstr("TestHandover"))
+                                 .add(cppbor::Bstr(vector<uint8_t>{1, 2, 3}))
+                                 .add(cppbor::Bstr(vector<uint8_t>{9, 8, 7, 6})));
+    vector<uint8_t> sessionTranscriptEncoded = sessionTranscript.encode();
+
+    // Generate the key that will be used to sign AuthenticatedData.
+    vector<uint8_t> signingKeyBlob;
+    Certificate signingKeyCertificate;
+    ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
+    optional<vector<uint8_t>> signingPubKey =
+            support::certificateChainGetTopMostKey(signingKeyCertificate.encodedCertificate);
+    EXPECT_TRUE(signingPubKey);
+    test_utils::verifyAuthKeyCertificate(signingKeyCertificate.encodedCertificate);
+
+    vector<RequestNamespace> requestedNamespaces = test_utils::buildRequestNamespaces(testEntries);
+    ASSERT_TRUE(credential->setRequestedNamespaces(requestedNamespaces).isOk());
+    ASSERT_TRUE(credential->setVerificationToken(verificationToken).isOk());
+    Status status = credential->startRetrieval(
+            secureProfiles.value(), authToken, {} /* itemsRequestBytes*/, signingKeyBlob,
+            sessionTranscriptEncoded, {} /* readerSignature */, testEntriesEntryCounts);
+    ASSERT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+
+    for (const auto& entry : testEntries) {
+        ASSERT_TRUE(credential
+                            ->startRetrieveEntryValue(entry.nameSpace, entry.name,
+                                                      entry.valueCbor.size(), entry.profileIds)
+                            .isOk());
+
+        auto it = encryptedBlobs.find(&entry);
+        ASSERT_NE(it, encryptedBlobs.end());
+        const vector<vector<uint8_t>>& encryptedChunks = it->second;
+
+        vector<uint8_t> content;
+        for (const auto& encryptedChunk : encryptedChunks) {
+            vector<uint8_t> chunk;
+            ASSERT_TRUE(credential->retrieveEntryValue(encryptedChunk, &chunk).isOk());
+            content.insert(content.end(), chunk.begin(), chunk.end());
+        }
+        EXPECT_EQ(content, entry.valueCbor);
+    }
+
+    vector<uint8_t> mac;
+    vector<uint8_t> ecdsaSignature;
+    vector<uint8_t> deviceNameSpacesEncoded;
+    status = credential->finishRetrievalWithSignature(&mac, &deviceNameSpacesEncoded,
+                                                      &ecdsaSignature);
+    ASSERT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+    // MACing should NOT work since we're not using session encryption
+    ASSERT_EQ(0, mac.size());
+
+    // ECDSA signatures should work, however. Check this.
+    ASSERT_GT(ecdsaSignature.size(), 0);
+
+    cborPretty = cppbor::prettyPrint(deviceNameSpacesEncoded, 32, {});
+    ASSERT_EQ(
+            "{\n"
+            "  'PersonalData' : {\n"
+            "    'Last name' : 'Turing',\n"
+            "    'Birth date' : '19120623',\n"
+            "    'First name' : 'Alan',\n"
+            "  },\n"
+            "}",
+            cborPretty);
+
+    string docType = "org.iso.18013-5.2019.mdl";
+
+    vector<uint8_t> encodedDeviceAuthentication =
+            cppbor::Array()
+                    .add("DeviceAuthentication")
+                    .add(sessionTranscript.clone())
+                    .add(docType)
+                    .add(cppbor::SemanticTag(24, deviceNameSpacesEncoded))
+                    .encode();
+    vector<uint8_t> deviceAuthenticationBytes =
+            cppbor::SemanticTag(24, encodedDeviceAuthentication).encode();
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(ecdsaSignature,
+                                                 deviceAuthenticationBytes,  // Detached content
+                                                 signingPubKey.value()));
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EndToEndTests);
diff --git a/identity/aidl/vts/Util.cpp b/identity/aidl/vts/Util.cpp
index 4f5c121..ad9281c 100644
--- a/identity/aidl/vts/Util.cpp
+++ b/identity/aidl/vts/Util.cpp
@@ -73,7 +73,7 @@
     ndkMacedPublicKey.macedKey = macedPublicKey.macedKey;
 
     vector<uint8_t> publicKeyBits;
-    check_maced_pubkey(ndkMacedPublicKey, /*testMode=*/true, &publicKeyBits);
+    check_maced_pubkey(ndkMacedPublicKey, /*testMode=*/false, &publicKeyBits);
 
     ::aidl::android::hardware::security::keymint::EVP_PKEY_Ptr publicKey;
     p256_pub_key(publicKeyBits, &publicKey);
diff --git a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
index 94d4c88..eb74fa2 100644
--- a/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
+++ b/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp
@@ -125,7 +125,8 @@
 
     MacedPublicKey macedPublicKey;
     std::vector<uint8_t> attestationKey;
-    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
+    // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here.
+    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey);
     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
 
     optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
@@ -176,7 +177,8 @@
 
     MacedPublicKey macedPublicKey;
     std::vector<uint8_t> attestationKey;
-    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/true, &macedPublicKey, &attestationKey);
+    // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here.
+    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey);
     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
 
     optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
diff --git a/identity/support/Android.bp b/identity/support/Android.bp
index 4e3d1f7..3096fe5 100644
--- a/identity/support/Android.bp
+++ b/identity/support/Android.bp
@@ -65,57 +65,3 @@
     ],
     test_suites: ["general-tests"],
 }
-
-// --
-
-cc_library {
-    name: "libcppbor",
-    vendor_available: true,
-    host_supported: true,
-    srcs: [
-        "src/cppbor.cpp",
-        "src/cppbor_parse.cpp",
-    ],
-    export_include_dirs: [
-        "include/cppbor",
-    ],
-    shared_libs: [
-        "libbase",
-    ],
-}
-
-cc_test {
-    name: "cppbor_test",
-    tidy_timeout_srcs: [
-        "tests/cppbor_test.cpp",
-    ],
-    srcs: [
-        "tests/cppbor_test.cpp",
-    ],
-    shared_libs: [
-        "libcppbor_external",
-        "libbase",
-    ],
-    static_libs: [
-        "libgmock",
-    ],
-    test_suites: ["general-tests"],
-}
-
-cc_test_host {
-    name: "cppbor_host_test",
-    tidy_timeout_srcs: [
-        "tests/cppbor_test.cpp",
-    ],
-    srcs: [
-        "tests/cppbor_test.cpp",
-    ],
-    shared_libs: [
-        "libcppbor_external",
-        "libbase",
-    ],
-    static_libs: [
-        "libgmock",
-    ],
-    test_suites: ["general-tests"],
-}
diff --git a/identity/support/include/cppbor/README.md b/identity/support/include/cppbor/README.md
deleted file mode 100644
index 723bfcf..0000000
--- a/identity/support/include/cppbor/README.md
+++ /dev/null
@@ -1,216 +0,0 @@
-CppBor: A Modern C++ CBOR Parser and Generator
-==============================================
-
-CppBor provides a natural and easy-to-use syntax for constructing and
-parsing CBOR messages.  It does not (yet) support all features of
-CBOR, nor (yet) support validation against CDDL schemata, though both
-are planned.  CBOR features that aren't supported include:
-
-* Indefinite length values
-* Semantic tagging
-* Floating point
-
-CppBor requires C++-17.
-
-## CBOR representation
-
-CppBor represents CBOR data items as instances of the `Item` class or,
-more precisely, as instances of subclasses of `Item`, since `Item` is a
-pure interface.  The subclasses of `Item` correspond almost one-to-one
-with CBOR major types, and are named to match the CDDL names to which
-they correspond.  They are:
-
-* `Uint` corresponds to major type 0, and can hold unsigned integers
-  up through (2^64 - 1).
-* `Nint` corresponds to major type 1.  It can only hold values from -1
-  to -(2^63 - 1), since it's internal representation is an int64_t.
-  This can be fixed, but it seems unlikely that applications will need
-  the omitted range from -(2^63) to (2^64 - 1), since it's
-  inconvenient to represent them in many programming languages.
-* `Int` is an abstract base of `Uint` and `Nint` that facilitates
-  working with all signed integers representable with int64_t.
-* `Bstr` corresponds to major type 2, a byte string.
-* `Tstr` corresponds to major type 3, a text string.
-* `Array` corresponds to major type 4, an Array.  It holds a
-  variable-length array of `Item`s.
-* `Map` corresponds to major type 5, a Map.  It holds a
-  variable-length array of pairs of `Item`s.
-* `Simple` corresponds to major type 7.  It's an abstract class since
-  items require more specific type.
-* `Bool` is the only currently-implemented subclass of `Simple`.
-
-Note that major type 6, semantic tag, is not yet implemented.
-
-In practice, users of CppBor will rarely use most of these classes
-when generating CBOR encodings.  This is because CppBor provides
-straightforward conversions from the obvious normal C++ types.
-Specifically, the following conversions are provided in appropriate
-contexts:
-
-* Signed and unsigned integers convert to `Uint` or `Nint`, as
-  appropriate.
-* `std::string`, `std::string_view`, `const char*` and
-  `std::pair<char iterator, char iterator>` convert to `Tstr`.
-* `std::vector<uint8_t>`, `std::pair<uint8_t iterator, uint8_t
-  iterator>` and `std::pair<uint8_t*, size_t>` convert to `Bstr`.
-* `bool` converts to `Bool`.
-
-## CBOR generation
-
-### Complete tree generation
-
-The set of `encode` methods in `Item` provide the interface for
-producing encoded CBOR.  The basic process for "complete tree"
-generation (as opposed to "incremental" generation, which is discussed
-below) is to construct an `Item` which models the data to be encoded,
-and then call one of the `encode` methods, whichever is convenient for
-the encoding destination.  A trivial example:
-
-```
-cppbor::Uint val(0);
-std::vector<uint8_t> encoding = val.encode();
-```
-
-    It's relatively rare that single values are encoded as above.  More often, the
-    "root" data item will be an `Array` or `Map` which contains a more complex structure.For example
-    :
-
-``` using cppbor::Map;
-using cppbor::Array;
-
-std::vector<uint8_t> vec =  // ...
-    Map val("key1", Array(Map("key_a", 99 "key_b", vec), "foo"), "key2", true);
-std::vector<uint8_t> encoding = val.encode();
-```
-
-This creates a map with two entries, with `Tstr` keys "Outer1" and
-"Outer2", respectively.  The "Outer1" entry has as its value an
-`Array` containing a `Map` and a `Tstr`.  The "Outer2" entry has a
-`Bool` value.
-
-This example demonstrates how automatic conversion of C++ types to
-CppBor `Item` subclass instances is done.  Where the caller provides a
-C++ or C string, a `Tstr` entry is added.  Where the caller provides
-an integer literal or variable, a `Uint` or `Nint` is added, depending
-on whether the value is positive or negative.
-
-As an alternative, a more fluent-style API is provided for building up
-structures.  For example:
-
-```
-using cppbor::Map;
-using cppbor::Array;
-
-std::vector<uint8_t> vec =  // ...
-    Map val();
-val.add("key1", Array().add(Map().add("key_a", 99).add("key_b", vec)).add("foo")).add("key2", true);
-std::vector<uint8_t> encoding = val.encode();
-```
-
-    An advantage of this interface over the constructor -
-    based creation approach above is that it need not be done all at once
-        .The `add` methods return a reference to the object added to to allow calls to be chained,
-    but chaining is not necessary; calls can be made
-sequentially, as the data to add is available.
-
-#### `encode` methods
-
-There are several variations of `Item::encode`, all of which
-accomplish the same task but output the encoded data in different
-ways, and with somewhat different performance characteristics.  The
-provided options are:
-
-* `bool encode(uint8\_t** pos, const uint8\_t* end)` encodes into the
-  buffer referenced by the range [`*pos`, end).  `*pos` is moved.  If
-  the encoding runs out of buffer space before finishing, the method
-  returns false.  This is the most efficient way to encode, into an
-  already-allocated buffer.
-* `void encode(EncodeCallback encodeCallback)` calls `encodeCallback`
-  for each encoded byte.  It's the responsibility of the implementor
-  of the callback to behave safely in the event that the output buffer
-  (if applicable) is exhausted.  This is less efficient than the prior
-  method because it imposes an additional function call for each byte.
-* `template </*...*/> void encode(OutputIterator i)`
-  encodes into the provided iterator.  SFINAE ensures that the
-  template doesn't match for non-iterators.  The implementation
-  actually uses the callback-based method, plus has whatever overhead
-  the iterator adds.
-* `std::vector<uint8_t> encode()` creates a new std::vector, reserves
-  sufficient capacity to hold the encoding, and inserts the encoded
-  bytes with a std::pushback_iterator and the previous method.
-* `std::string toString()` does the same as the previous method, but
-  returns a string instead of a vector.
-
-### Incremental generation
-
-Incremental generation requires deeper understanding of CBOR, because
-the library can't do as much to ensure that the output is valid.  The
-basic tool for intcremental generation is the `encodeHeader`
-function.  There are two variations, one which writes into a buffer,
-and one which uses a callback.  Both simply write out the bytes of a
-header.  To construct the same map as in the above examples,
-incrementally, one might write:
-
-```
-using namespace cppbor;  // For example brevity
-
-std::vector encoding;
-auto iter = std::back_inserter(result);
-encodeHeader(MAP, 2 /* # of map entries */, iter);
-std::string s = "key1";
-encodeHeader(TSTR, s.size(), iter);
-std::copy(s.begin(), s.end(), iter);
-encodeHeader(ARRAY, 2 /* # of array entries */, iter);
-Map().add("key_a", 99).add("key_b", vec).encode(iter)
-s = "foo";
-encodeHeader(TSTR, foo.size(), iter);
-std::copy(s.begin(), s.end(), iter);
-s = "key2";
-encodeHeader(TSTR, foo.size(), iter);
-std::copy(s.begin(), s.end(), iter);
-encodeHeader(SIMPLE, TRUE, iter);
-```
-
-As the above example demonstrates, the styles can be mixed -- Note the
-creation and encoding of the inner Map using the fluent style.
-
-## Parsing
-
-CppBor also supports parsing of encoded CBOR data, with the same
-feature set as encoding.  There are two basic approaches to parsing,
-"full" and "stream"
-
-### Full parsing
-
-Full parsing means completely parsing a (possibly-compound) data
-item from a byte buffer.  The `parse` functions that do not take a
-`ParseClient` pointer do this.  They return a `ParseResult` which is a
-tuple of three values:
-
-* std::unique_ptr<Item> that points to the parsed item, or is nullptr
-  if there was a parse error.
-* const uint8_t* that points to the byte after the end of the decoded
-  item, or to the first unparseable byte in the event of an error.
-* std::string that is empty on success or contains an error message if
-  a parse error occurred.
-
-Assuming a successful parse, you can then use `Item::type()` to
-discover the type of the parsed item (e.g. MAP), and then use the
-appropriate `Item::as*()` method (e.g. `Item::asMap()`) to get a
-pointer to an interface which allows you to retrieve specific values.
-
-### Stream parsing
-
-Stream parsing is more complex, but more flexible.  To use
-StreamParsing, you must create your own subclass of `ParseClient` and
-call one of the `parse` functions that accepts it.  See the
-`ParseClient` methods docstrings for details.
-
-One unusual feature of stream parsing is that the `ParseClient`
-callback methods not only provide the parsed Item, but also pointers
-to the portion of the buffer that encode that Item.  This is useful
-if, for example, you want to find an element inside of a structure,
-and then copy the encoding of that sub-structure, without bothering to
-parse the rest.
-
-The full parser is implemented with the stream parser.
diff --git a/identity/support/include/cppbor/cppbor.h b/identity/support/include/cppbor/cppbor.h
deleted file mode 100644
index af5d82e..0000000
--- a/identity/support/include/cppbor/cppbor.h
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <functional>
-#include <iterator>
-#include <memory>
-#include <numeric>
-#include <string>
-#include <vector>
-
-namespace cppbor {
-
-enum MajorType : uint8_t {
-    UINT = 0 << 5,
-    NINT = 1 << 5,
-    BSTR = 2 << 5,
-    TSTR = 3 << 5,
-    ARRAY = 4 << 5,
-    MAP = 5 << 5,
-    SEMANTIC = 6 << 5,
-    SIMPLE = 7 << 5,
-};
-
-enum SimpleType {
-    BOOLEAN,
-    NULL_T,  // Only two supported, as yet.
-};
-
-enum SpecialAddlInfoValues : uint8_t {
-    FALSE = 20,
-    TRUE = 21,
-    NULL_V = 22,
-    ONE_BYTE_LENGTH = 24,
-    TWO_BYTE_LENGTH = 25,
-    FOUR_BYTE_LENGTH = 26,
-    EIGHT_BYTE_LENGTH = 27,
-};
-
-class Item;
-class Uint;
-class Nint;
-class Int;
-class Tstr;
-class Bstr;
-class Simple;
-class Bool;
-class Array;
-class Map;
-class Null;
-class Semantic;
-
-/**
- * Returns the size of a CBOR header that contains the additional info value addlInfo.
- */
-size_t headerSize(uint64_t addlInfo);
-
-/**
- * Encodes a CBOR header with the specified type and additional info into the range [pos, end).
- * Returns a pointer to one past the last byte written, or nullptr if there isn't sufficient space
- * to write the header.
- */
-uint8_t* encodeHeader(MajorType type, uint64_t addlInfo, uint8_t* pos, const uint8_t* end);
-
-using EncodeCallback = std::function<void(uint8_t)>;
-
-/**
- * Encodes a CBOR header with the specified type and additional info, passing each byte in turn to
- * encodeCallback.
- */
-void encodeHeader(MajorType type, uint64_t addlInfo, EncodeCallback encodeCallback);
-
-/**
- * Encodes a CBOR header with the specified type and additional info, writing each byte to the
- * provided OutputIterator.
- */
-template <typename OutputIterator,
-          typename = std::enable_if_t<std::is_base_of_v<
-                  std::output_iterator_tag,
-                  typename std::iterator_traits<OutputIterator>::iterator_category>>>
-void encodeHeader(MajorType type, uint64_t addlInfo, OutputIterator iter) {
-    return encodeHeader(type, addlInfo, [&](uint8_t v) { *iter++ = v; });
-}
-
-/**
- * Item represents a CBOR-encodeable data item.  Item is an abstract interface with a set of virtual
- * methods that allow encoding of the item or conversion to the appropriate derived type.
- */
-class Item {
-  public:
-    virtual ~Item() {}
-
-    /**
-     * Returns the CBOR type of the item.
-     */
-    virtual MajorType type() const = 0;
-
-    // These methods safely downcast an Item to the appropriate subclass.
-    virtual const Int* asInt() const { return nullptr; }
-    virtual const Uint* asUint() const { return nullptr; }
-    virtual const Nint* asNint() const { return nullptr; }
-    virtual const Tstr* asTstr() const { return nullptr; }
-    virtual const Bstr* asBstr() const { return nullptr; }
-    virtual const Simple* asSimple() const { return nullptr; }
-    virtual const Map* asMap() const { return nullptr; }
-    virtual const Array* asArray() const { return nullptr; }
-    virtual const Semantic* asSemantic() const { return nullptr; }
-
-    /**
-     * Returns true if this is a "compound" item, i.e. one that contains one or more other items.
-     */
-    virtual bool isCompound() const { return false; }
-
-    bool operator==(const Item& other) const&;
-    bool operator!=(const Item& other) const& { return !(*this == other); }
-
-    /**
-     * Returns the number of bytes required to encode this Item into CBOR.  Note that if this is a
-     * complex Item, calling this method will require walking the whole tree.
-     */
-    virtual size_t encodedSize() const = 0;
-
-    /**
-     * Encodes the Item into buffer referenced by range [*pos, end).  Returns a pointer to one past
-     * the last position written.  Returns nullptr if there isn't enough space to encode.
-     */
-    virtual uint8_t* encode(uint8_t* pos, const uint8_t* end) const = 0;
-
-    /**
-     * Encodes the Item by passing each encoded byte to encodeCallback.
-     */
-    virtual void encode(EncodeCallback encodeCallback) const = 0;
-
-    /**
-     * Clones the Item
-     */
-    virtual std::unique_ptr<Item> clone() const = 0;
-
-    /**
-     * Encodes the Item into the provided OutputIterator.
-     */
-    template <typename OutputIterator,
-              typename = typename std::iterator_traits<OutputIterator>::iterator_category>
-    void encode(OutputIterator i) const {
-        return encode([&](uint8_t v) { *i++ = v; });
-    }
-
-    /**
-     * Encodes the Item into a new std::vector<uint8_t>.
-     */
-    std::vector<uint8_t> encode() const {
-        std::vector<uint8_t> retval;
-        retval.reserve(encodedSize());
-        encode(std::back_inserter(retval));
-        return retval;
-    }
-
-    /**
-     * Encodes the Item into a new std::string.
-     */
-    std::string toString() const {
-        std::string retval;
-        retval.reserve(encodedSize());
-        encode([&](uint8_t v) { retval.push_back(v); });
-        return retval;
-    }
-
-    /**
-     * Encodes only the header of the Item.
-     */
-    inline uint8_t* encodeHeader(uint64_t addlInfo, uint8_t* pos, const uint8_t* end) const {
-        return ::cppbor::encodeHeader(type(), addlInfo, pos, end);
-    }
-
-    /**
-     * Encodes only the header of the Item.
-     */
-    inline void encodeHeader(uint64_t addlInfo, EncodeCallback encodeCallback) const {
-        ::cppbor::encodeHeader(type(), addlInfo, encodeCallback);
-    }
-};
-
-/**
- * Int is an abstraction that allows Uint and Nint objects to be manipulated without caring about
- * the sign.
- */
-class Int : public Item {
-  public:
-    bool operator==(const Int& other) const& { return value() == other.value(); }
-
-    virtual int64_t value() const = 0;
-
-    const Int* asInt() const override { return this; }
-};
-
-/**
- * Uint is a concrete Item that implements CBOR major type 0.
- */
-class Uint : public Int {
-  public:
-    static constexpr MajorType kMajorType = UINT;
-
-    explicit Uint(uint64_t v) : mValue(v) {}
-
-    bool operator==(const Uint& other) const& { return mValue == other.mValue; }
-
-    MajorType type() const override { return kMajorType; }
-    const Uint* asUint() const override { return this; }
-
-    size_t encodedSize() const override { return headerSize(mValue); }
-
-    int64_t value() const override { return mValue; }
-    uint64_t unsignedValue() const { return mValue; }
-
-    using Item::encode;
-    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
-        return encodeHeader(mValue, pos, end);
-    }
-    void encode(EncodeCallback encodeCallback) const override {
-        encodeHeader(mValue, encodeCallback);
-    }
-
-    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Uint>(mValue); }
-
-  private:
-    uint64_t mValue;
-};
-
-/**
- * Nint is a concrete Item that implements CBOR major type 1.
-
- * Note that it is incapable of expressing the full range of major type 1 values, becaue it can only
- * express values that fall into the range [std::numeric_limits<int64_t>::min(), -1].  It cannot
- * express values in the range [std::numeric_limits<int64_t>::min() - 1,
- * -std::numeric_limits<uint64_t>::max()].
- */
-class Nint : public Int {
-  public:
-    static constexpr MajorType kMajorType = NINT;
-
-    explicit Nint(int64_t v);
-
-    bool operator==(const Nint& other) const& { return mValue == other.mValue; }
-
-    MajorType type() const override { return kMajorType; }
-    const Nint* asNint() const override { return this; }
-    size_t encodedSize() const override { return headerSize(addlInfo()); }
-
-    int64_t value() const override { return mValue; }
-
-    using Item::encode;
-    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
-        return encodeHeader(addlInfo(), pos, end);
-    }
-    void encode(EncodeCallback encodeCallback) const override {
-        encodeHeader(addlInfo(), encodeCallback);
-    }
-
-    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Nint>(mValue); }
-
-  private:
-    uint64_t addlInfo() const { return -1LL - mValue; }
-
-    int64_t mValue;
-};
-
-/**
- * Bstr is a concrete Item that implements major type 2.
- */
-class Bstr : public Item {
-  public:
-    static constexpr MajorType kMajorType = BSTR;
-
-    // Construct from a vector
-    explicit Bstr(std::vector<uint8_t> v) : mValue(std::move(v)) {}
-
-    // Construct from a string
-    explicit Bstr(const std::string& v)
-        : mValue(reinterpret_cast<const uint8_t*>(v.data()),
-                 reinterpret_cast<const uint8_t*>(v.data()) + v.size()) {}
-
-    // Construct from a pointer/size pair
-    explicit Bstr(const std::pair<const uint8_t*, size_t>& buf)
-        : mValue(buf.first, buf.first + buf.second) {}
-
-    // Construct from a pair of iterators
-    template <typename I1, typename I2,
-              typename = typename std::iterator_traits<I1>::iterator_category,
-              typename = typename std::iterator_traits<I2>::iterator_category>
-    explicit Bstr(const std::pair<I1, I2>& pair) : mValue(pair.first, pair.second) {}
-
-    // Construct from an iterator range.
-    template <typename I1, typename I2,
-              typename = typename std::iterator_traits<I1>::iterator_category,
-              typename = typename std::iterator_traits<I2>::iterator_category>
-    Bstr(I1 begin, I2 end) : mValue(begin, end) {}
-
-    bool operator==(const Bstr& other) const& { return mValue == other.mValue; }
-
-    MajorType type() const override { return kMajorType; }
-    const Bstr* asBstr() const override { return this; }
-    size_t encodedSize() const override { return headerSize(mValue.size()) + mValue.size(); }
-    using Item::encode;
-    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override;
-    void encode(EncodeCallback encodeCallback) const override {
-        encodeHeader(mValue.size(), encodeCallback);
-        encodeValue(encodeCallback);
-    }
-
-    const std::vector<uint8_t>& value() const { return mValue; }
-
-    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Bstr>(mValue); }
-
-  private:
-    void encodeValue(EncodeCallback encodeCallback) const;
-
-    std::vector<uint8_t> mValue;
-};
-
-/**
- * Bstr is a concrete Item that implements major type 3.
- */
-class Tstr : public Item {
-  public:
-    static constexpr MajorType kMajorType = TSTR;
-
-    // Construct from a string
-    explicit Tstr(std::string v) : mValue(std::move(v)) {}
-
-    // Construct from a string_view
-    explicit Tstr(const std::string_view& v) : mValue(v) {}
-
-    // Construct from a C string
-    explicit Tstr(const char* v) : mValue(std::string(v)) {}
-
-    // Construct from a pair of iterators
-    template <typename I1, typename I2,
-              typename = typename std::iterator_traits<I1>::iterator_category,
-              typename = typename std::iterator_traits<I2>::iterator_category>
-    explicit Tstr(const std::pair<I1, I2>& pair) : mValue(pair.first, pair.second) {}
-
-    // Construct from an iterator range
-    template <typename I1, typename I2,
-              typename = typename std::iterator_traits<I1>::iterator_category,
-              typename = typename std::iterator_traits<I2>::iterator_category>
-    Tstr(I1 begin, I2 end) : mValue(begin, end) {}
-
-    bool operator==(const Tstr& other) const& { return mValue == other.mValue; }
-
-    MajorType type() const override { return kMajorType; }
-    const Tstr* asTstr() const override { return this; }
-    size_t encodedSize() const override { return headerSize(mValue.size()) + mValue.size(); }
-    using Item::encode;
-    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override;
-    void encode(EncodeCallback encodeCallback) const override {
-        encodeHeader(mValue.size(), encodeCallback);
-        encodeValue(encodeCallback);
-    }
-
-    const std::string& value() const { return mValue; }
-
-    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Tstr>(mValue); }
-
-  private:
-    void encodeValue(EncodeCallback encodeCallback) const;
-
-    std::string mValue;
-};
-
-/**
- * CompoundItem is an abstract Item that provides common functionality for Items that contain other
- * items, i.e. Arrays (CBOR type 4) and Maps (CBOR type 5).
- */
-class CompoundItem : public Item {
-  public:
-    bool operator==(const CompoundItem& other) const&;
-
-    virtual size_t size() const { return mEntries.size(); }
-
-    bool isCompound() const override { return true; }
-
-    size_t encodedSize() const override {
-        return std::accumulate(mEntries.begin(), mEntries.end(), headerSize(size()),
-                               [](size_t sum, auto& entry) { return sum + entry->encodedSize(); });
-    }
-
-    using Item::encode;  // Make base versions visible.
-    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override;
-    void encode(EncodeCallback encodeCallback) const override;
-
-    virtual uint64_t addlInfo() const = 0;
-
-  protected:
-    std::vector<std::unique_ptr<Item>> mEntries;
-};
-
-/*
- * Array is a concrete Item that implements CBOR major type 4.
- *
- * Note that Arrays are not copyable.  This is because copying them is expensive and making them
- * move-only ensures that they're never copied accidentally.  If you actually want to copy an Array,
- * use the clone() method.
- */
-class Array : public CompoundItem {
-  public:
-    static constexpr MajorType kMajorType = ARRAY;
-
-    Array() = default;
-    Array(const Array& other) = delete;
-    Array(Array&&) = default;
-    Array& operator=(const Array&) = delete;
-    Array& operator=(Array&&) = default;
-
-    /**
-     * Construct an Array from a variable number of arguments of different types.  See
-     * details::makeItem below for details on what types may be provided.  In general, this accepts
-     * all of the types you'd expect and doest the things you'd expect (integral values are addes as
-     * Uint or Nint, std::string and char* are added as Tstr, bools are added as Bool, etc.).
-     */
-    template <typename... Args, typename Enable>
-    Array(Args&&... args);
-
-    /**
-     * Append a single element to the Array, of any compatible type.
-     */
-    template <typename T>
-    Array& add(T&& v) &;
-    template <typename T>
-    Array&& add(T&& v) &&;
-
-    const std::unique_ptr<Item>& operator[](size_t index) const { return mEntries[index]; }
-    std::unique_ptr<Item>& operator[](size_t index) { return mEntries[index]; }
-
-    MajorType type() const override { return kMajorType; }
-    const Array* asArray() const override { return this; }
-
-    virtual std::unique_ptr<Item> clone() const override;
-
-    uint64_t addlInfo() const override { return size(); }
-};
-
-/*
- * Map is a concrete Item that implements CBOR major type 5.
- *
- * Note that Maps are not copyable.  This is because copying them is expensive and making them
- * move-only ensures that they're never copied accidentally.  If you actually want to copy a
- * Map, use the clone() method.
- */
-class Map : public CompoundItem {
-  public:
-    static constexpr MajorType kMajorType = MAP;
-
-    Map() = default;
-    Map(const Map& other) = delete;
-    Map(Map&&) = default;
-    Map& operator=(const Map& other) = delete;
-    Map& operator=(Map&&) = default;
-
-    /**
-     * Construct a Map from a variable number of arguments of different types.  An even number of
-     * arguments must be provided (this is verified statically). See details::makeItem below for
-     * details on what types may be provided.  In general, this accepts all of the types you'd
-     * expect and doest the things you'd expect (integral values are addes as Uint or Nint,
-     * std::string and char* are added as Tstr, bools are added as Bool, etc.).
-     */
-    template <typename... Args, typename Enable>
-    Map(Args&&... args);
-
-    /**
-     * Append a key/value pair to the Map, of any compatible types.
-     */
-    template <typename Key, typename Value>
-    Map& add(Key&& key, Value&& value) &;
-    template <typename Key, typename Value>
-    Map&& add(Key&& key, Value&& value) &&;
-
-    size_t size() const override {
-        assertInvariant();
-        return mEntries.size() / 2;
-    }
-
-    template <typename Key, typename Enable>
-    std::pair<std::unique_ptr<Item>&, bool> get(Key key);
-
-    std::pair<const std::unique_ptr<Item>&, const std::unique_ptr<Item>&> operator[](
-            size_t index) const {
-        assertInvariant();
-        return {mEntries[index * 2], mEntries[index * 2 + 1]};
-    }
-
-    std::pair<std::unique_ptr<Item>&, std::unique_ptr<Item>&> operator[](size_t index) {
-        assertInvariant();
-        return {mEntries[index * 2], mEntries[index * 2 + 1]};
-    }
-
-    MajorType type() const override { return kMajorType; }
-    const Map* asMap() const override { return this; }
-
-    virtual std::unique_ptr<Item> clone() const override;
-
-    uint64_t addlInfo() const override { return size(); }
-
-  private:
-    void assertInvariant() const;
-};
-
-class Semantic : public CompoundItem {
-  public:
-    static constexpr MajorType kMajorType = SEMANTIC;
-
-    template <typename T>
-    explicit Semantic(uint64_t value, T&& child);
-
-    Semantic(const Semantic& other) = delete;
-    Semantic(Semantic&&) = default;
-    Semantic& operator=(const Semantic& other) = delete;
-    Semantic& operator=(Semantic&&) = default;
-
-    size_t size() const override {
-        assertInvariant();
-        return 1;
-    }
-
-    size_t encodedSize() const override {
-        return std::accumulate(mEntries.begin(), mEntries.end(), headerSize(mValue),
-                               [](size_t sum, auto& entry) { return sum + entry->encodedSize(); });
-    }
-
-    MajorType type() const override { return kMajorType; }
-    const Semantic* asSemantic() const override { return this; }
-
-    const std::unique_ptr<Item>& child() const {
-        assertInvariant();
-        return mEntries[0];
-    }
-
-    std::unique_ptr<Item>& child() {
-        assertInvariant();
-        return mEntries[0];
-    }
-
-    uint64_t value() const { return mValue; }
-
-    uint64_t addlInfo() const override { return value(); }
-
-    virtual std::unique_ptr<Item> clone() const override {
-        assertInvariant();
-        return std::make_unique<Semantic>(mValue, mEntries[0]->clone());
-    }
-
-  protected:
-    Semantic() = default;
-    Semantic(uint64_t value) : mValue(value) {}
-    uint64_t mValue;
-
-  private:
-    void assertInvariant() const;
-};
-
-/**
- * Simple is abstract Item that implements CBOR major type 7.  It is intended to be subclassed to
- * create concrete Simple types.  At present only Bool is provided.
- */
-class Simple : public Item {
-  public:
-    static constexpr MajorType kMajorType = SIMPLE;
-
-    bool operator==(const Simple& other) const&;
-
-    virtual SimpleType simpleType() const = 0;
-    MajorType type() const override { return kMajorType; }
-
-    const Simple* asSimple() const override { return this; }
-
-    virtual const Bool* asBool() const { return nullptr; };
-    virtual const Null* asNull() const { return nullptr; };
-};
-
-/**
- * Bool is a concrete type that implements CBOR major type 7, with additional item values for TRUE
- * and FALSE.
- */
-class Bool : public Simple {
-  public:
-    static constexpr SimpleType kSimpleType = BOOLEAN;
-
-    explicit Bool(bool v) : mValue(v) {}
-
-    bool operator==(const Bool& other) const& { return mValue == other.mValue; }
-
-    SimpleType simpleType() const override { return kSimpleType; }
-    const Bool* asBool() const override { return this; }
-
-    size_t encodedSize() const override { return 1; }
-
-    using Item::encode;
-    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
-        return encodeHeader(mValue ? TRUE : FALSE, pos, end);
-    }
-    void encode(EncodeCallback encodeCallback) const override {
-        encodeHeader(mValue ? TRUE : FALSE, encodeCallback);
-    }
-
-    bool value() const { return mValue; }
-
-    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Bool>(mValue); }
-
-  private:
-    bool mValue;
-};
-
-/**
- * Null is a concrete type that implements CBOR major type 7, with additional item value for NULL
- */
-class Null : public Simple {
-  public:
-    static constexpr SimpleType kSimpleType = NULL_T;
-
-    explicit Null() {}
-
-    SimpleType simpleType() const override { return kSimpleType; }
-    const Null* asNull() const override { return this; }
-
-    size_t encodedSize() const override { return 1; }
-
-    using Item::encode;
-    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
-        return encodeHeader(NULL_V, pos, end);
-    }
-    void encode(EncodeCallback encodeCallback) const override {
-        encodeHeader(NULL_V, encodeCallback);
-    }
-
-    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Null>(); }
-};
-
-template <typename T>
-std::unique_ptr<T> downcastItem(std::unique_ptr<Item>&& v) {
-    static_assert(std::is_base_of_v<Item, T> && !std::is_abstract_v<T>,
-                  "returned type is not an Item or is an abstract class");
-    if (v && T::kMajorType == v->type()) {
-        if constexpr (std::is_base_of_v<Simple, T>) {
-            if (T::kSimpleType != v->asSimple()->simpleType()) {
-                return nullptr;
-            }
-        }
-        return std::unique_ptr<T>(static_cast<T*>(v.release()));
-    } else {
-        return nullptr;
-    }
-}
-
-/**
- * Details. Mostly you shouldn't have to look below, except perhaps at the docstring for makeItem.
- */
-namespace details {
-
-template <typename T, typename V, typename Enable = void>
-struct is_iterator_pair_over : public std::false_type {};
-
-template <typename I1, typename I2, typename V>
-struct is_iterator_pair_over<
-        std::pair<I1, I2>, V,
-        typename std::enable_if_t<std::is_same_v<V, typename std::iterator_traits<I1>::value_type>>>
-    : public std::true_type {};
-
-template <typename T, typename V, typename Enable = void>
-struct is_unique_ptr_of_subclass_of_v : public std::false_type {};
-
-template <typename T, typename P>
-struct is_unique_ptr_of_subclass_of_v<T, std::unique_ptr<P>,
-                                      typename std::enable_if_t<std::is_base_of_v<T, P>>>
-    : public std::true_type {};
-
-/* check if type is one of std::string (1), std::string_view (2), null-terminated char* (3) or pair
- *     of iterators (4)*/
-template <typename T, typename Enable = void>
-struct is_text_type_v : public std::false_type {};
-
-template <typename T>
-struct is_text_type_v<
-        T, typename std::enable_if_t<
-                   /* case 1 */  //
-                   std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, std::string>
-                   /* case 2 */  //
-                   || std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, std::string_view>
-                   /* case 3 */                                                 //
-                   || std::is_same_v<std::remove_cv_t<std::decay_t<T>>, char*>  //
-                   || std::is_same_v<std::remove_cv_t<std::decay_t<T>>, const char*>
-                   /* case 4 */
-                   || details::is_iterator_pair_over<T, char>::value>> : public std::true_type {};
-
-/**
- * Construct a unique_ptr<Item> from many argument types. Accepts:
- *
- * (a) booleans;
- * (b) integers, all sizes and signs;
- * (c) text strings, as defined by is_text_type_v above;
- * (d) byte strings, as std::vector<uint8_t>(d1), pair of iterators (d2) or pair<uint8_t*, size_T>
- *     (d3); and
- * (e) Item subclass instances, including Array and Map.  Items may be provided by naked pointer
- *     (e1), unique_ptr (e2), reference (e3) or value (e3).  If provided by reference or value, will
- *     be moved if possible.  If provided by pointer, ownership is taken.
- * (f) null pointer;
- */
-template <typename T>
-std::unique_ptr<Item> makeItem(T v) {
-    Item* p = nullptr;
-    if constexpr (/* case a */ std::is_same_v<T, bool>) {
-        p = new Bool(v);
-    } else if constexpr (/* case b */ std::is_integral_v<T>) {  // b
-        if (v < 0) {
-            p = new Nint(v);
-        } else {
-            p = new Uint(static_cast<uint64_t>(v));
-        }
-    } else if constexpr (/* case c */  //
-                         details::is_text_type_v<T>::value) {
-        p = new Tstr(v);
-    } else if constexpr (/* case d1 */  //
-                         std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
-                                        std::vector<uint8_t>>
-                         /* case d2 */  //
-                         || details::is_iterator_pair_over<T, uint8_t>::value
-                         /* case d3 */  //
-                         || std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
-                                           std::pair<uint8_t*, size_t>>) {
-        p = new Bstr(v);
-    } else if constexpr (/* case e1 */  //
-                         std::is_pointer_v<T> &&
-                         std::is_base_of_v<Item, std::remove_pointer_t<T>>) {
-        p = v;
-    } else if constexpr (/* case e2 */  //
-                         details::is_unique_ptr_of_subclass_of_v<Item, T>::value) {
-        p = v.release();
-    } else if constexpr (/* case e3 */  //
-                         std::is_base_of_v<Item, T>) {
-        p = new T(std::move(v));
-    } else if constexpr (/* case f */ std::is_null_pointer_v<T>) {
-        p = new Null();
-    } else {
-        // It's odd that this can't be static_assert(false), since it shouldn't be evaluated if one
-        // of the above ifs matches.  But static_assert(false) always triggers.
-        static_assert(std::is_same_v<T, bool>, "makeItem called with unsupported type");
-    }
-    return std::unique_ptr<Item>(p);
-}
-
-}  // namespace details
-
-template <typename... Args,
-          /* Prevent use as copy ctor */ typename = std::enable_if_t<
-                  (sizeof...(Args)) != 1 ||
-                  !(std::is_same_v<Array, std::remove_cv_t<std::remove_reference_t<Args>>> || ...)>>
-Array::Array(Args&&... args) {
-    mEntries.reserve(sizeof...(args));
-    (mEntries.push_back(details::makeItem(std::forward<Args>(args))), ...);
-}
-
-template <typename T>
-Array& Array::add(T&& v) & {
-    mEntries.push_back(details::makeItem(std::forward<T>(v)));
-    return *this;
-}
-
-template <typename T>
-Array&& Array::add(T&& v) && {
-    mEntries.push_back(details::makeItem(std::forward<T>(v)));
-    return std::move(*this);
-}
-
-template <typename... Args,
-          /* Prevent use as copy ctor */ typename = std::enable_if_t<(sizeof...(Args)) != 1>>
-Map::Map(Args&&... args) {
-    static_assert((sizeof...(Args)) % 2 == 0, "Map must have an even number of entries");
-    mEntries.reserve(sizeof...(args));
-    (mEntries.push_back(details::makeItem(std::forward<Args>(args))), ...);
-}
-
-template <typename Key, typename Value>
-Map& Map::add(Key&& key, Value&& value) & {
-    mEntries.push_back(details::makeItem(std::forward<Key>(key)));
-    mEntries.push_back(details::makeItem(std::forward<Value>(value)));
-    return *this;
-}
-
-template <typename Key, typename Value>
-Map&& Map::add(Key&& key, Value&& value) && {
-    this->add(std::forward<Key>(key), std::forward<Value>(value));
-    return std::move(*this);
-}
-
-template <typename Key, typename = std::enable_if_t<std::is_integral_v<Key> ||
-                                                    details::is_text_type_v<Key>::value>>
-std::pair<std::unique_ptr<Item>&, bool> Map::get(Key key) {
-    assertInvariant();
-    auto keyItem = details::makeItem(key);
-    for (size_t i = 0; i < mEntries.size(); i += 2) {
-        if (*keyItem == *mEntries[i]) {
-            return {mEntries[i + 1], true};
-        }
-    }
-    return {keyItem, false};
-}
-
-template <typename T>
-Semantic::Semantic(uint64_t value, T&& child) : mValue(value) {
-    mEntries.reserve(1);
-    mEntries.push_back(details::makeItem(std::forward<T>(child)));
-}
-
-}  // namespace cppbor
diff --git a/identity/support/include/cppbor/cppbor_parse.h b/identity/support/include/cppbor/cppbor_parse.h
deleted file mode 100644
index 66cd5a3..0000000
--- a/identity/support/include/cppbor/cppbor_parse.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "cppbor.h"
-
-namespace cppbor {
-
-using ParseResult = std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
-                               std::string /* errMsg */>;
-
-/**
- * Parse the first CBOR data item (possibly compound) from the range [begin, end).
- *
- * Returns a tuple of Item pointer, buffer pointer and error message.  If parsing is successful, the
- * Item pointer is non-null, the buffer pointer points to the first byte after the
- * successfully-parsed item and the error message string is empty.  If parsing fails, the Item
- * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
- * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
- * too large for the remining buffer, etc.) and the string contains an error message describing the
- * problem encountered.
- */
-ParseResult parse(const uint8_t* begin, const uint8_t* end);
-
-/**
- * Parse the first CBOR data item (possibly compound) from the byte vector.
- *
- * Returns a tuple of Item pointer, buffer pointer and error message.  If parsing is successful, the
- * Item pointer is non-null, the buffer pointer points to the first byte after the
- * successfully-parsed item and the error message string is empty.  If parsing fails, the Item
- * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
- * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
- * too large for the remining buffer, etc.) and the string contains an error message describing the
- * problem encountered.
- */
-inline ParseResult parse(const std::vector<uint8_t>& encoding) {
-    return parse(encoding.data(), encoding.data() + encoding.size());
-}
-
-/**
- * Parse the first CBOR data item (possibly compound) from the range [begin, begin + size).
- *
- * Returns a tuple of Item pointer, buffer pointer and error message.  If parsing is successful, the
- * Item pointer is non-null, the buffer pointer points to the first byte after the
- * successfully-parsed item and the error message string is empty.  If parsing fails, the Item
- * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
- * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
- * too large for the remining buffer, etc.) and the string contains an error message describing the
- * problem encountered.
- */
-inline ParseResult parse(const uint8_t* begin, size_t size) {
-    return parse(begin, begin + size);
-}
-
-class ParseClient;
-
-/**
- * Parse the CBOR data in the range [begin, end) in streaming fashion, calling methods on the
- * provided ParseClient when elements are found.
- */
-void parse(const uint8_t* begin, const uint8_t* end, ParseClient* parseClient);
-
-/**
- * Parse the CBOR data in the vector in streaming fashion, calling methods on the
- * provided ParseClient when elements are found.
- */
-inline void parse(const std::vector<uint8_t>& encoding, ParseClient* parseClient) {
-    return parse(encoding.data(), encoding.data() + encoding.size(), parseClient);
-}
-
-/**
- * A pure interface that callers of the streaming parse functions must implement.
- */
-class ParseClient {
-  public:
-    virtual ~ParseClient() {}
-
-    /**
-     * Called when an item is found.  The Item pointer points to the found item; use type() and
-     * the appropriate as*() method to examine the value.  hdrBegin points to the first byte of the
-     * header, valueBegin points to the first byte of the value and end points one past the end of
-     * the item.  In the case of header-only items, such as integers, and compound items (ARRAY,
-     * MAP or SEMANTIC) whose end has not yet been found, valueBegin and end are equal and point to
-     * the byte past the header.
-     *
-     * Note that for compound types (ARRAY, MAP, and SEMANTIC), the Item will have no content.  For
-     * Map and Array items, the size() method will return a correct value, but the index operators
-     * are unsafe, and the object cannot be safely compared with another Array/Map.
-     *
-     * The method returns a ParseClient*.  In most cases "return this;" will be the right answer,
-     * but a different ParseClient may be returned, which the parser will begin using. If the method
-     * returns nullptr, parsing will be aborted immediately.
-     */
-    virtual ParseClient* item(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
-                              const uint8_t* valueBegin, const uint8_t* end) = 0;
-
-    /**
-     * Called when the end of a compound item (MAP or ARRAY) is found.  The item argument will be
-     * the same one passed to the item() call -- and may be empty if item() moved its value out.
-     * hdrBegin, valueBegin and end point to the beginning of the item header, the beginning of the
-     * first contained value, and one past the end of the last contained value, respectively.
-     *
-     * Note that the Item will have no content.
-     *
-     * As with item(), itemEnd() can change the ParseClient by returning a different one, or end the
-     * parsing by returning nullptr;
-     */
-    virtual ParseClient* itemEnd(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
-                                 const uint8_t* valueBegin, const uint8_t* end) = 0;
-
-    /**
-     * Called when parsing encounters an error.  position is set to the first unparsed byte (one
-     * past the last successfully-parsed byte) and errorMessage contains an message explaining what
-     * sort of error occurred.
-     */
-    virtual void error(const uint8_t* position, const std::string& errorMessage) = 0;
-};
-
-}  // namespace cppbor
diff --git a/identity/support/src/cppbor.cpp b/identity/support/src/cppbor.cpp
deleted file mode 100644
index d289985..0000000
--- a/identity/support/src/cppbor.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "cppbor.h"
-#include "cppbor_parse.h"
-
-#define LOG_TAG "CppBor"
-#include <android-base/logging.h>
-
-namespace cppbor {
-
-namespace {
-
-template <typename T, typename Iterator, typename = std::enable_if<std::is_unsigned<T>::value>>
-Iterator writeBigEndian(T value, Iterator pos) {
-    for (unsigned i = 0; i < sizeof(value); ++i) {
-        *pos++ = static_cast<uint8_t>(value >> (8 * (sizeof(value) - 1)));
-        value = static_cast<T>(value << 8);
-    }
-    return pos;
-}
-
-template <typename T, typename = std::enable_if<std::is_unsigned<T>::value>>
-void writeBigEndian(T value, std::function<void(uint8_t)>& cb) {
-    for (unsigned i = 0; i < sizeof(value); ++i) {
-        cb(static_cast<uint8_t>(value >> (8 * (sizeof(value) - 1))));
-        value = static_cast<T>(value << 8);
-    }
-}
-
-}  // namespace
-
-size_t headerSize(uint64_t addlInfo) {
-    if (addlInfo < ONE_BYTE_LENGTH) return 1;
-    if (addlInfo <= std::numeric_limits<uint8_t>::max()) return 2;
-    if (addlInfo <= std::numeric_limits<uint16_t>::max()) return 3;
-    if (addlInfo <= std::numeric_limits<uint32_t>::max()) return 5;
-    return 9;
-}
-
-uint8_t* encodeHeader(MajorType type, uint64_t addlInfo, uint8_t* pos, const uint8_t* end) {
-    size_t sz = headerSize(addlInfo);
-    if (end - pos < static_cast<ssize_t>(sz)) return nullptr;
-    switch (sz) {
-        case 1:
-            *pos++ = type | static_cast<uint8_t>(addlInfo);
-            return pos;
-        case 2:
-            *pos++ = type | ONE_BYTE_LENGTH;
-            *pos++ = static_cast<uint8_t>(addlInfo);
-            return pos;
-        case 3:
-            *pos++ = type | TWO_BYTE_LENGTH;
-            return writeBigEndian(static_cast<uint16_t>(addlInfo), pos);
-        case 5:
-            *pos++ = type | FOUR_BYTE_LENGTH;
-            return writeBigEndian(static_cast<uint32_t>(addlInfo), pos);
-        case 9:
-            *pos++ = type | EIGHT_BYTE_LENGTH;
-            return writeBigEndian(addlInfo, pos);
-        default:
-            CHECK(false);  // Impossible to get here.
-            return nullptr;
-    }
-}
-
-void encodeHeader(MajorType type, uint64_t addlInfo, EncodeCallback encodeCallback) {
-    size_t sz = headerSize(addlInfo);
-    switch (sz) {
-        case 1:
-            encodeCallback(type | static_cast<uint8_t>(addlInfo));
-            break;
-        case 2:
-            encodeCallback(type | ONE_BYTE_LENGTH);
-            encodeCallback(static_cast<uint8_t>(addlInfo));
-            break;
-        case 3:
-            encodeCallback(type | TWO_BYTE_LENGTH);
-            writeBigEndian(static_cast<uint16_t>(addlInfo), encodeCallback);
-            break;
-        case 5:
-            encodeCallback(type | FOUR_BYTE_LENGTH);
-            writeBigEndian(static_cast<uint32_t>(addlInfo), encodeCallback);
-            break;
-        case 9:
-            encodeCallback(type | EIGHT_BYTE_LENGTH);
-            writeBigEndian(addlInfo, encodeCallback);
-            break;
-        default:
-            CHECK(false);  // Impossible to get here.
-    }
-}
-
-bool Item::operator==(const Item& other) const& {
-    if (type() != other.type()) return false;
-    switch (type()) {
-        case UINT:
-            return *asUint() == *(other.asUint());
-        case NINT:
-            return *asNint() == *(other.asNint());
-        case BSTR:
-            return *asBstr() == *(other.asBstr());
-        case TSTR:
-            return *asTstr() == *(other.asTstr());
-        case ARRAY:
-            return *asArray() == *(other.asArray());
-        case MAP:
-            return *asMap() == *(other.asMap());
-        case SIMPLE:
-            return *asSimple() == *(other.asSimple());
-        case SEMANTIC:
-            return *asSemantic() == *(other.asSemantic());
-        default:
-            CHECK(false);  // Impossible to get here.
-            return false;
-    }
-}
-
-Nint::Nint(int64_t v) : mValue(v) {
-    CHECK(v < 0) << "Only negative values allowed";
-}
-
-bool Simple::operator==(const Simple& other) const& {
-    if (simpleType() != other.simpleType()) return false;
-
-    switch (simpleType()) {
-        case BOOLEAN:
-            return *asBool() == *(other.asBool());
-        case NULL_T:
-            return true;
-        default:
-            CHECK(false);  // Impossible to get here.
-            return false;
-    }
-}
-
-uint8_t* Bstr::encode(uint8_t* pos, const uint8_t* end) const {
-    pos = encodeHeader(mValue.size(), pos, end);
-    if (!pos || end - pos < static_cast<ptrdiff_t>(mValue.size())) return nullptr;
-    return std::copy(mValue.begin(), mValue.end(), pos);
-}
-
-void Bstr::encodeValue(EncodeCallback encodeCallback) const {
-    for (auto c : mValue) {
-        encodeCallback(c);
-    }
-}
-
-uint8_t* Tstr::encode(uint8_t* pos, const uint8_t* end) const {
-    pos = encodeHeader(mValue.size(), pos, end);
-    if (!pos || end - pos < static_cast<ptrdiff_t>(mValue.size())) return nullptr;
-    return std::copy(mValue.begin(), mValue.end(), pos);
-}
-
-void Tstr::encodeValue(EncodeCallback encodeCallback) const {
-    for (auto c : mValue) {
-        encodeCallback(static_cast<uint8_t>(c));
-    }
-}
-
-bool CompoundItem::operator==(const CompoundItem& other) const& {
-    return type() == other.type()             //
-           && addlInfo() == other.addlInfo()  //
-           // Can't use vector::operator== because the contents are pointers.  std::equal lets us
-           // provide a predicate that does the dereferencing.
-           && std::equal(mEntries.begin(), mEntries.end(), other.mEntries.begin(),
-                         [](auto& a, auto& b) -> bool { return *a == *b; });
-}
-
-uint8_t* CompoundItem::encode(uint8_t* pos, const uint8_t* end) const {
-    pos = encodeHeader(addlInfo(), pos, end);
-    if (!pos) return nullptr;
-    for (auto& entry : mEntries) {
-        pos = entry->encode(pos, end);
-        if (!pos) return nullptr;
-    }
-    return pos;
-}
-
-void CompoundItem::encode(EncodeCallback encodeCallback) const {
-    encodeHeader(addlInfo(), encodeCallback);
-    for (auto& entry : mEntries) {
-        entry->encode(encodeCallback);
-    }
-}
-
-void Map::assertInvariant() const {
-    CHECK(mEntries.size() % 2 == 0);
-}
-
-std::unique_ptr<Item> Map::clone() const {
-    assertInvariant();
-    auto res = std::make_unique<Map>();
-    for (size_t i = 0; i < mEntries.size(); i += 2) {
-        res->add(mEntries[i]->clone(), mEntries[i + 1]->clone());
-    }
-    return res;
-}
-
-std::unique_ptr<Item> Array::clone() const {
-    auto res = std::make_unique<Array>();
-    for (size_t i = 0; i < mEntries.size(); i++) {
-        res->add(mEntries[i]->clone());
-    }
-    return res;
-}
-
-void Semantic::assertInvariant() const {
-    CHECK(mEntries.size() == 1);
-}
-
-}  // namespace cppbor
diff --git a/identity/support/src/cppbor_parse.cpp b/identity/support/src/cppbor_parse.cpp
deleted file mode 100644
index c9ebb8a..0000000
--- a/identity/support/src/cppbor_parse.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "cppbor_parse.h"
-
-#include <sstream>
-#include <stack>
-
-#define LOG_TAG "CppBor"
-#include <android-base/logging.h>
-
-namespace cppbor {
-
-namespace {
-
-std::string insufficientLengthString(size_t bytesNeeded, size_t bytesAvail,
-                                     const std::string& type) {
-    std::stringstream errStream;
-    errStream << "Need " << bytesNeeded << " byte(s) for " << type << ", have " << bytesAvail
-              << ".";
-    return errStream.str();
-}
-
-template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
-std::tuple<bool, uint64_t, const uint8_t*> parseLength(const uint8_t* pos, const uint8_t* end,
-                                                       ParseClient* parseClient) {
-    if (pos + sizeof(T) > end) {
-        parseClient->error(pos - 1, insufficientLengthString(sizeof(T), end - pos, "length field"));
-        return {false, 0, pos};
-    }
-
-    const uint8_t* intEnd = pos + sizeof(T);
-    T result = 0;
-    do {
-        result = static_cast<T>((result << 8) | *pos++);
-    } while (pos < intEnd);
-    return {true, result, pos};
-}
-
-std::tuple<const uint8_t*, ParseClient*> parseRecursively(const uint8_t* begin, const uint8_t* end,
-                                                          ParseClient* parseClient);
-
-std::tuple<const uint8_t*, ParseClient*> handleUint(uint64_t value, const uint8_t* hdrBegin,
-                                                    const uint8_t* hdrEnd,
-                                                    ParseClient* parseClient) {
-    std::unique_ptr<Item> item = std::make_unique<Uint>(value);
-    return {hdrEnd,
-            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
-}
-
-std::tuple<const uint8_t*, ParseClient*> handleNint(uint64_t value, const uint8_t* hdrBegin,
-                                                    const uint8_t* hdrEnd,
-                                                    ParseClient* parseClient) {
-    if (value > std::numeric_limits<int64_t>::max()) {
-        parseClient->error(hdrBegin, "NINT values that don't fit in int64_t are not supported.");
-        return {hdrBegin, nullptr /* end parsing */};
-    }
-    std::unique_ptr<Item> item = std::make_unique<Nint>(-1 - static_cast<uint64_t>(value));
-    return {hdrEnd,
-            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
-}
-
-std::tuple<const uint8_t*, ParseClient*> handleBool(uint64_t value, const uint8_t* hdrBegin,
-                                                    const uint8_t* hdrEnd,
-                                                    ParseClient* parseClient) {
-    std::unique_ptr<Item> item = std::make_unique<Bool>(value == TRUE);
-    return {hdrEnd,
-            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
-}
-
-std::tuple<const uint8_t*, ParseClient*> handleNull(const uint8_t* hdrBegin, const uint8_t* hdrEnd,
-                                                    ParseClient* parseClient) {
-    std::unique_ptr<Item> item = std::make_unique<Null>();
-    return {hdrEnd,
-            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
-}
-
-template <typename T>
-std::tuple<const uint8_t*, ParseClient*> handleString(uint64_t length, const uint8_t* hdrBegin,
-                                                      const uint8_t* valueBegin, const uint8_t* end,
-                                                      const std::string& errLabel,
-                                                      ParseClient* parseClient) {
-    if (end - valueBegin < static_cast<ssize_t>(length)) {
-        parseClient->error(hdrBegin, insufficientLengthString(length, end - valueBegin, errLabel));
-        return {hdrBegin, nullptr /* end parsing */};
-    }
-
-    std::unique_ptr<Item> item = std::make_unique<T>(valueBegin, valueBegin + length);
-    return {valueBegin + length,
-            parseClient->item(item, hdrBegin, valueBegin, valueBegin + length)};
-}
-
-class IncompleteItem {
-  public:
-    virtual ~IncompleteItem() {}
-    virtual void add(std::unique_ptr<Item> item) = 0;
-};
-
-class IncompleteArray : public Array, public IncompleteItem {
-  public:
-    IncompleteArray(size_t size) : mSize(size) {}
-
-    // We return the "complete" size, rather than the actual size.
-    size_t size() const override { return mSize; }
-
-    void add(std::unique_ptr<Item> item) override {
-        mEntries.reserve(mSize);
-        mEntries.push_back(std::move(item));
-    }
-
-  private:
-    size_t mSize;
-};
-
-class IncompleteMap : public Map, public IncompleteItem {
-  public:
-    IncompleteMap(size_t size) : mSize(size) {}
-
-    // We return the "complete" size, rather than the actual size.
-    size_t size() const override { return mSize; }
-
-    void add(std::unique_ptr<Item> item) override {
-        mEntries.reserve(mSize * 2);
-        mEntries.push_back(std::move(item));
-    }
-
-  private:
-    size_t mSize;
-};
-
-class IncompleteSemantic : public Semantic, public IncompleteItem {
-  public:
-    IncompleteSemantic(uint64_t value) : Semantic(value) {}
-
-    // We return the "complete" size, rather than the actual size.
-    size_t size() const override { return 1; }
-
-    void add(std::unique_ptr<Item> item) override {
-        mEntries.reserve(1);
-        mEntries.push_back(std::move(item));
-    }
-};
-
-std::tuple<const uint8_t*, ParseClient*> handleEntries(size_t entryCount, const uint8_t* hdrBegin,
-                                                       const uint8_t* pos, const uint8_t* end,
-                                                       const std::string& typeName,
-                                                       ParseClient* parseClient) {
-    while (entryCount > 0) {
-        --entryCount;
-        if (pos == end) {
-            parseClient->error(hdrBegin, "Not enough entries for " + typeName + ".");
-            return {hdrBegin, nullptr /* end parsing */};
-        }
-        std::tie(pos, parseClient) = parseRecursively(pos, end, parseClient);
-        if (!parseClient) return {hdrBegin, nullptr};
-    }
-    return {pos, parseClient};
-}
-
-std::tuple<const uint8_t*, ParseClient*> handleCompound(
-        std::unique_ptr<Item> item, uint64_t entryCount, const uint8_t* hdrBegin,
-        const uint8_t* valueBegin, const uint8_t* end, const std::string& typeName,
-        ParseClient* parseClient) {
-    parseClient =
-            parseClient->item(item, hdrBegin, valueBegin, valueBegin /* don't know the end yet */);
-    if (!parseClient) return {hdrBegin, nullptr};
-
-    const uint8_t* pos;
-    std::tie(pos, parseClient) =
-            handleEntries(entryCount, hdrBegin, valueBegin, end, typeName, parseClient);
-    if (!parseClient) return {hdrBegin, nullptr};
-
-    return {pos, parseClient->itemEnd(item, hdrBegin, valueBegin, pos)};
-}
-
-std::tuple<const uint8_t*, ParseClient*> parseRecursively(const uint8_t* begin, const uint8_t* end,
-                                                          ParseClient* parseClient) {
-    const uint8_t* pos = begin;
-
-    MajorType type = static_cast<MajorType>(*pos & 0xE0);
-    uint8_t tagInt = *pos & 0x1F;
-    ++pos;
-
-    bool success = true;
-    uint64_t addlData;
-    if (tagInt < ONE_BYTE_LENGTH || tagInt > EIGHT_BYTE_LENGTH) {
-        addlData = tagInt;
-    } else {
-        switch (tagInt) {
-            case ONE_BYTE_LENGTH:
-                std::tie(success, addlData, pos) = parseLength<uint8_t>(pos, end, parseClient);
-                break;
-
-            case TWO_BYTE_LENGTH:
-                std::tie(success, addlData, pos) = parseLength<uint16_t>(pos, end, parseClient);
-                break;
-
-            case FOUR_BYTE_LENGTH:
-                std::tie(success, addlData, pos) = parseLength<uint32_t>(pos, end, parseClient);
-                break;
-
-            case EIGHT_BYTE_LENGTH:
-                std::tie(success, addlData, pos) = parseLength<uint64_t>(pos, end, parseClient);
-                break;
-
-            default:
-                CHECK(false);  //  It's impossible to get here
-                break;
-        }
-    }
-
-    if (!success) return {begin, nullptr};
-
-    switch (type) {
-        case UINT:
-            return handleUint(addlData, begin, pos, parseClient);
-
-        case NINT:
-            return handleNint(addlData, begin, pos, parseClient);
-
-        case BSTR:
-            return handleString<Bstr>(addlData, begin, pos, end, "byte string", parseClient);
-
-        case TSTR:
-            return handleString<Tstr>(addlData, begin, pos, end, "text string", parseClient);
-
-        case ARRAY:
-            return handleCompound(std::make_unique<IncompleteArray>(addlData), addlData, begin, pos,
-                                  end, "array", parseClient);
-
-        case MAP:
-            return handleCompound(std::make_unique<IncompleteMap>(addlData), addlData * 2, begin,
-                                  pos, end, "map", parseClient);
-
-        case SEMANTIC:
-            return handleCompound(std::make_unique<IncompleteSemantic>(addlData), 1, begin, pos,
-                                  end, "semantic", parseClient);
-
-        case SIMPLE:
-            switch (addlData) {
-                case TRUE:
-                case FALSE:
-                    return handleBool(addlData, begin, pos, parseClient);
-                case NULL_V:
-                    return handleNull(begin, pos, parseClient);
-            }
-    }
-    CHECK(false);  // Impossible to get here.
-    return {};
-}
-
-class FullParseClient : public ParseClient {
-  public:
-    virtual ParseClient* item(std::unique_ptr<Item>& item, const uint8_t*, const uint8_t*,
-                              const uint8_t* end) override {
-        if (mParentStack.empty() && !item->isCompound()) {
-            // This is the first and only item.
-            mTheItem = std::move(item);
-            mPosition = end;
-            return nullptr;  //  We're done.
-        }
-
-        if (item->isCompound()) {
-            // Starting a new compound data item, i.e. a new parent.  Save it on the parent stack.
-            // It's safe to save a raw pointer because the unique_ptr is guaranteed to stay in
-            // existence until the corresponding itemEnd() call.
-            assert(dynamic_cast<CompoundItem*>(item.get()));
-            mParentStack.push(static_cast<CompoundItem*>(item.get()));
-            return this;
-        } else {
-            appendToLastParent(std::move(item));
-            return this;
-        }
-    }
-
-    virtual ParseClient* itemEnd(std::unique_ptr<Item>& item, const uint8_t*, const uint8_t*,
-                                 const uint8_t* end) override {
-        CHECK(item->isCompound() && item.get() == mParentStack.top());
-        mParentStack.pop();
-
-        if (mParentStack.empty()) {
-            mTheItem = std::move(item);
-            mPosition = end;
-            return nullptr;  // We're done
-        } else {
-            appendToLastParent(std::move(item));
-            return this;
-        }
-    }
-
-    virtual void error(const uint8_t* position, const std::string& errorMessage) override {
-        mPosition = position;
-        mErrorMessage = errorMessage;
-    }
-
-    std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
-               std::string /* errMsg */>
-    parseResult() {
-        std::unique_ptr<Item> p = std::move(mTheItem);
-        return {std::move(p), mPosition, std::move(mErrorMessage)};
-    }
-
-  private:
-    void appendToLastParent(std::unique_ptr<Item> item) {
-        auto parent = mParentStack.top();
-        assert(dynamic_cast<IncompleteItem*>(parent));
-        if (parent->type() == ARRAY) {
-            static_cast<IncompleteArray*>(parent)->add(std::move(item));
-        } else if (parent->type() == MAP) {
-            static_cast<IncompleteMap*>(parent)->add(std::move(item));
-        } else if (parent->type() == SEMANTIC) {
-            static_cast<IncompleteSemantic*>(parent)->add(std::move(item));
-        } else {
-            CHECK(false);  // Impossible to get here.
-        }
-    }
-
-    std::unique_ptr<Item> mTheItem;
-    std::stack<CompoundItem*> mParentStack;
-    const uint8_t* mPosition = nullptr;
-    std::string mErrorMessage;
-};
-
-}  // anonymous namespace
-
-void parse(const uint8_t* begin, const uint8_t* end, ParseClient* parseClient) {
-    parseRecursively(begin, end, parseClient);
-}
-
-std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
-           std::string /* errMsg */>
-parse(const uint8_t* begin, const uint8_t* end) {
-    FullParseClient parseClient;
-    parse(begin, end, &parseClient);
-    return parseClient.parseResult();
-}
-
-}  // namespace cppbor
diff --git a/identity/support/tests/cppbor_test.cpp b/identity/support/tests/cppbor_test.cpp
deleted file mode 100644
index 3eb5598..0000000
--- a/identity/support/tests/cppbor_test.cpp
+++ /dev/null
@@ -1,1013 +0,0 @@
-/*
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iomanip>
-#include <sstream>
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "cppbor.h"
-#include "cppbor_parse.h"
-
-using namespace cppbor;
-using namespace std;
-
-using ::testing::_;
-using ::testing::AllOf;
-using ::testing::ByRef;
-using ::testing::InSequence;
-using ::testing::IsNull;
-using ::testing::NotNull;
-using ::testing::Return;
-using ::testing::Truly;
-using ::testing::Unused;
-
-string hexDump(const string& str) {
-    stringstream s;
-    for (auto c : str) {
-        s << setfill('0') << setw(2) << hex << (static_cast<unsigned>(c) & 0xff);
-    }
-    return s.str();
-}
-
-TEST(SimpleValueTest, UnsignedValueSizes) {
-    // Check that unsigned integers encode to correct lengths, and that encodedSize() is correct.
-    vector<pair<uint64_t /* value */, size_t /* expected encoded size */>> testCases{
-            {0, 1},
-            {1, 1},
-            {23, 1},
-            {24, 2},
-            {255, 2},
-            {256, 3},
-            {65535, 3},
-            {65536, 5},
-            {4294967295, 5},
-            {4294967296, 9},
-            {std::numeric_limits<uint64_t>::max(), 9},
-    };
-    for (auto& testCase : testCases) {
-        Uint val(testCase.first);
-        EXPECT_EQ(testCase.second, val.encodedSize()) << "Wrong size for value " << testCase.first;
-        EXPECT_EQ(val.encodedSize(), val.toString().size())
-                << "encodedSize and encoding disagree for value " << testCase.first;
-    }
-}
-
-TEST(SimpleValueTest, UnsignedValueEncodings) {
-    EXPECT_EQ("\x00"s, Uint(0u).toString());
-    EXPECT_EQ("\x01"s, Uint(1u).toString());
-    EXPECT_EQ("\x0a"s, Uint(10u).toString());
-    EXPECT_EQ("\x17"s, Uint(23u).toString());
-    EXPECT_EQ("\x18\x18"s, Uint(24u).toString());
-    EXPECT_EQ("\x18\x19"s, Uint(25u).toString());
-    EXPECT_EQ("\x18\x64"s, Uint(100u).toString());
-    EXPECT_EQ("\x19\x03\xe8"s, Uint(1000u).toString());
-    EXPECT_EQ("\x1a\x00\x0f\x42\x40"s, Uint(1000000u).toString());
-    EXPECT_EQ("\x1b\x00\x00\x00\xe8\xd4\xa5\x10\x00"s, Uint(1000000000000u).toString());
-    EXPECT_EQ("\x1B\x7f\xff\xff\xff\xff\xff\xff\xff"s,
-              Uint(std::numeric_limits<int64_t>::max()).toString());
-}
-
-TEST(SimpleValueTest, NegativeValueEncodings) {
-    EXPECT_EQ("\x20"s, Nint(-1).toString());
-    EXPECT_EQ("\x28"s, Nint(-9).toString());
-    EXPECT_EQ("\x29"s, Nint(-10).toString());
-    EXPECT_EQ("\x36"s, Nint(-23).toString());
-    EXPECT_EQ("\x37"s, Nint(-24).toString());
-    EXPECT_EQ("\x38\x18"s, Nint(-25).toString());
-    EXPECT_EQ("\x38\x62"s, Nint(-99).toString());
-    EXPECT_EQ("\x38\x63"s, Nint(-100).toString());
-    EXPECT_EQ("\x39\x03\xe6"s, Nint(-999).toString());
-    EXPECT_EQ("\x39\x03\xe7"s, Nint(-1000).toString());
-    EXPECT_EQ("\x3a\x00\x0f\x42\x3F"s, Nint(-1000000).toString());
-    EXPECT_EQ("\x3b\x00\x00\x00\xe8\xd4\xa5\x0f\xff"s, Nint(-1000000000000).toString());
-    EXPECT_EQ("\x3B\x7f\xff\xff\xff\xff\xff\xff\xff"s,
-              Nint(std::numeric_limits<int64_t>::min()).toString());
-}
-
-TEST(SimpleValueDeathTest, NegativeValueEncodings) {
-    EXPECT_DEATH(Nint(0), "");
-    EXPECT_DEATH(Nint(1), "");
-}
-
-TEST(SimpleValueTest, BooleanEncodings) {
-    EXPECT_EQ("\xf4"s, Bool(false).toString());
-    EXPECT_EQ("\xf5"s, Bool(true).toString());
-}
-
-TEST(SimpleValueTest, ByteStringEncodings) {
-    EXPECT_EQ("\x40", Bstr("").toString());
-    EXPECT_EQ("\x41\x61", Bstr("a").toString());
-    EXPECT_EQ("\x41\x41", Bstr("A").toString());
-    EXPECT_EQ("\x44\x49\x45\x54\x46", Bstr("IETF").toString());
-    EXPECT_EQ("\x42\x22\x5c", Bstr("\"\\").toString());
-    EXPECT_EQ("\x42\xc3\xbc", Bstr("\xc3\xbc").toString());
-    EXPECT_EQ("\x43\xe6\xb0\xb4", Bstr("\xe6\xb0\xb4").toString());
-    EXPECT_EQ("\x44\xf0\x90\x85\x91", Bstr("\xf0\x90\x85\x91").toString());
-    EXPECT_EQ("\x44\x01\x02\x03\x04", Bstr("\x01\x02\x03\x04").toString());
-    EXPECT_EQ("\x44\x40\x40\x40\x40", Bstr("@@@@").toString());
-}
-
-TEST(SimpleValueTest, TextStringEncodings) {
-    EXPECT_EQ("\x60"s, Tstr("").toString());
-    EXPECT_EQ("\x61\x61"s, Tstr("a").toString());
-    EXPECT_EQ("\x61\x41"s, Tstr("A").toString());
-    EXPECT_EQ("\x64\x49\x45\x54\x46"s, Tstr("IETF").toString());
-    EXPECT_EQ("\x62\x22\x5c"s, Tstr("\"\\").toString());
-    EXPECT_EQ("\x62\xc3\xbc"s, Tstr("\xc3\xbc").toString());
-    EXPECT_EQ("\x63\xe6\xb0\xb4"s, Tstr("\xe6\xb0\xb4").toString());
-    EXPECT_EQ("\x64\xf0\x90\x85\x91"s, Tstr("\xf0\x90\x85\x91").toString());
-    EXPECT_EQ("\x64\x01\x02\x03\x04"s, Tstr("\x01\x02\x03\x04").toString());
-}
-
-TEST(IsIteratorPairOverTest, All) {
-    EXPECT_TRUE((
-            details::is_iterator_pair_over<pair<string::iterator, string::iterator>, char>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<pair<string::const_iterator, string::iterator>,
-                                                char>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<pair<string::iterator, string::const_iterator>,
-                                                char>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<pair<char*, char*>, char>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<pair<const char*, char*>, char>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<pair<char*, const char*>, char>::value));
-    EXPECT_FALSE((details::is_iterator_pair_over<pair<string::iterator, string::iterator>,
-                                                 uint8_t>::value));
-    EXPECT_FALSE((details::is_iterator_pair_over<pair<char*, char*>, uint8_t>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<
-                 pair<vector<uint8_t>::iterator, vector<uint8_t>::iterator>, uint8_t>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<
-                 pair<vector<uint8_t>::const_iterator, vector<uint8_t>::iterator>,
-                 uint8_t>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<
-                 pair<vector<uint8_t>::iterator, vector<uint8_t>::const_iterator>,
-                 uint8_t>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<pair<uint8_t*, uint8_t*>, uint8_t>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<pair<const uint8_t*, uint8_t*>, uint8_t>::value));
-    EXPECT_TRUE((details::is_iterator_pair_over<pair<uint8_t*, const uint8_t*>, uint8_t>::value));
-    EXPECT_FALSE((details::is_iterator_pair_over<
-                  pair<vector<uint8_t>::iterator, vector<uint8_t>::iterator>, char>::value));
-    EXPECT_FALSE((details::is_iterator_pair_over<pair<uint8_t*, const uint8_t*>, char>::value));
-}
-
-TEST(MakeEntryTest, Boolean) {
-    EXPECT_EQ("\xf4"s, details::makeItem(false)->toString());
-}
-
-TEST(MakeEntryTest, Integers) {
-    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint8_t>(0))->toString());
-    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint16_t>(0))->toString());
-    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint32_t>(0))->toString());
-    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint64_t>(0))->toString());
-    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int8_t>(0))->toString());
-    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int16_t>(0))->toString());
-    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int32_t>(0))->toString());
-    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int64_t>(0))->toString());
-    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int8_t>(-1))->toString());
-    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int16_t>(-1))->toString());
-    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int32_t>(-1))->toString());
-    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int64_t>(-1))->toString());
-
-    EXPECT_EQ("\x1b\xff\xff\xff\xff\xff\xff\xff\xff"s,
-              details::makeItem(static_cast<uint64_t>(std::numeric_limits<uint64_t>::max()))
-                      ->toString());
-}
-
-TEST(MakeEntryTest, StdStrings) {
-    string s1("hello");
-    const string s2("hello");
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s1)->toString());  // copy of string
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s,
-              details::makeItem(s2)->toString());  // copy of const string
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s,
-              details::makeItem(std::move(s1))->toString());  // move string
-    EXPECT_EQ(0U, s1.size());                                 // Prove string was moved, not copied.
-}
-
-TEST(MakeEntryTest, StdStringViews) {
-    string_view s1("hello");
-    const string_view s2("hello");
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s1)->toString());
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s2)->toString());
-}
-
-TEST(MakeEntryTest, CStrings) {
-    char s1[] = "hello";
-    const char s2[] = "hello";
-    const char* s3 = "hello";
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s1)->toString());
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s2)->toString());
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s3)->toString());
-}
-
-TEST(MakeEntryTest, StringIteratorPairs) {
-    // Use iterators from string to prove that "real" iterators work
-    string s1 = "hello"s;
-    pair<string::iterator, string::iterator> p1 = make_pair(s1.begin(), s1.end());
-
-    const pair<string::iterator, string::iterator> p2 = p1;
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p1)->toString());
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p2)->toString());
-
-    // Use char*s  as iterators
-    const char* s2 = "hello";
-    pair p3 = make_pair(s2, s2 + 5);
-    const pair p4 = p3;
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p3)->toString());
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p4)->toString());
-}
-
-TEST(MakeEntryTest, ByteStrings) {
-    vector<uint8_t> v1 = {0x00, 0x01, 0x02};
-    const vector<uint8_t> v2 = {0x00, 0x01, 0x02};
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(v1)->toString());  // copy of vector
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(v2)->toString());  // copy of const vector
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(std::move(v1))->toString());  // move vector
-    EXPECT_EQ(0U, v1.size());  // Prove vector was moved, not copied.
-}
-
-TEST(MakeEntryTest, ByteStringIteratorPairs) {
-    using vec = vector<uint8_t>;
-    using iter = vec::iterator;
-    vec v1 = {0x00, 0x01, 0x02};
-    pair<iter, iter> p1 = make_pair(v1.begin(), v1.end());
-    const pair<iter, iter> p2 = make_pair(v1.begin(), v1.end());
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p1)->toString());
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p2)->toString());
-
-    // Use uint8_t*s as iterators
-    uint8_t v2[] = {0x00, 0x01, 0x02};
-    uint8_t* v3 = v2;
-    pair<uint8_t*, uint8_t*> p3 = make_pair(v2, v2 + 3);
-    const pair<uint8_t*, uint8_t*> p4 = make_pair(v2, v2 + 3);
-    pair<uint8_t*, uint8_t*> p5 = make_pair(v3, v3 + 3);
-    const pair<uint8_t*, uint8_t*> p6 = make_pair(v3, v3 + 3);
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p3)->toString());
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p4)->toString());
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p5)->toString());
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p6)->toString());
-}
-
-TEST(MakeEntryTest, ByteStringBuffers) {
-    uint8_t v1[] = {0x00, 0x01, 0x02};
-    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(make_pair(v1, 3))->toString());
-}
-
-TEST(MakeEntryTest, ItemPointer) {
-    Uint* p1 = new Uint(0);
-    EXPECT_EQ("\x00"s, details::makeItem(p1)->toString());
-    EXPECT_EQ("\x60"s, details::makeItem(new Tstr(string()))->toString());
-}
-
-TEST(MakeEntryTest, ItemReference) {
-    Tstr str("hello"s);
-    Tstr& strRef = str;
-    const Tstr& strConstRef = str;
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(str)->toString());
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(strRef)->toString());
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(strConstRef)->toString());
-    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(std::move(str))->toString());
-    EXPECT_EQ("\x60"s, details::makeItem(str)->toString());  // Prove that it moved
-
-    EXPECT_EQ("\x00"s, details::makeItem(Uint(0))->toString());
-
-    EXPECT_EQ("\x43\x00\x01\x02"s,
-              details::makeItem(Bstr(vector<uint8_t>{0x00, 0x01, 0x02}))->toString());
-
-    EXPECT_EQ("\x80"s, details::makeItem(Array())->toString());
-    EXPECT_EQ("\xa0"s, details::makeItem(Map())->toString());
-}
-
-TEST(CompoundValueTest, ArrayOfInts) {
-    EXPECT_EQ("\x80"s, Array().toString());
-    Array(Uint(0)).toString();
-
-    EXPECT_EQ("\x81\x00"s, Array(Uint(0U)).toString());
-    EXPECT_EQ("\x82\x00\x01"s, Array(Uint(0), Uint(1)).toString());
-    EXPECT_EQ("\x83\x00\x01\x38\x62"s, Array(Uint(0), Uint(1), Nint(-99)).toString());
-
-    EXPECT_EQ("\x81\x00"s, Array(0).toString());
-    EXPECT_EQ("\x82\x00\x01"s, Array(0, 1).toString());
-    EXPECT_EQ("\x83\x00\x01\x38\x62"s, Array(0, 1, -99).toString());
-}
-
-TEST(CompoundValueTest, MapOfInts) {
-    EXPECT_EQ("\xA0"s, Map().toString());
-    EXPECT_EQ("\xA1\x00\x01"s, Map(Uint(0), Uint(1)).toString());
-    // Maps with an odd number of arguments will fail to compile.  Uncomment the next lines to test.
-    // EXPECT_EQ("\xA1\x00"s, Map(Int(0)).toString());
-    // EXPECT_EQ("\xA1\x00\x01\x02"s, Map(Int(0), Int(1), Int(2)).toString());
-}
-
-TEST(CompoundValueTest, MixedArray) {
-    vector<uint8_t> vec = {3, 2, 1};
-    EXPECT_EQ("\x84\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
-              Array(Uint(1), Nint(-1), Bstr(vec), Tstr("hello")).toString());
-
-    EXPECT_EQ("\x84\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
-              Array(1, -1, vec, "hello").toString());
-}
-
-TEST(CompoundValueTest, MixedMap) {
-    vector<uint8_t> vec = {3, 2, 1};
-    EXPECT_EQ("\xA2\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
-              Map(Uint(1), Nint(-1), Bstr(vec), Tstr("hello")).toString());
-
-    EXPECT_EQ("\xA2\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
-              Map(1, -1, vec, "hello").toString());
-}
-
-TEST(CompoundValueTest, NestedStructures) {
-    vector<uint8_t> vec = {3, 2, 1};
-
-    string expectedEncoding =
-            "\xA2\x66\x4F\x75\x74\x65\x72\x31\x82\xA2\x66\x49\x6E\x6E\x65\x72\x31\x18\x63\x66\x49"
-            "\x6E"
-            "\x6E\x65\x72\x32\x43\x03\x02\x01\x63\x66\x6F\x6F\x66\x4F\x75\x74\x65\x72\x32\x0A"s;
-
-    // Do it with explicitly-created Items
-    EXPECT_EQ(expectedEncoding,
-              Map(Tstr("Outer1"),
-                  Array(  //
-                          Map(Tstr("Inner1"), Uint(99), Tstr("Inner2"), Bstr(vec)), Tstr("foo")),
-                  Tstr("Outer2"),  //
-                  Uint(10))
-                      .toString());
-    EXPECT_EQ(3U, vec.size());
-
-    // Now just use convertible types
-    EXPECT_EQ(expectedEncoding, Map("Outer1",
-                                    Array(Map("Inner1", 99,  //
-                                              "Inner2", vec),
-                                          "foo"),
-                                    "Outer2", 10)
-                                        .toString());
-    EXPECT_EQ(3U, vec.size());
-
-    // Finally, do it with the .add() method.  This is slightly less efficient, but has the
-    // advantage you can build a structure up incrementally, or somewhat fluently if you like.
-    // First, fluently.
-    EXPECT_EQ(expectedEncoding, Map().add("Outer1", Array().add(Map()  //
-                                                                        .add("Inner1", 99)
-                                                                        .add("Inner2", vec))
-                                                            .add("foo"))
-                                        .add("Outer2", 10)
-                                        .toString());
-    EXPECT_EQ(3U, vec.size());
-
-    // Next, more incrementally
-    Array arr;
-    arr.add(Map()  //
-                    .add("Inner1", 99)
-                    .add("Inner2", vec))
-            .add("foo");
-    EXPECT_EQ(3U, vec.size());
-
-    Map m;
-    m.add("Outer1", std::move(arr));  // Moving is necessary; Map and Array cannot be copied.
-    m.add("Outer2", 10);
-    auto s = m.toString();
-    EXPECT_EQ(expectedEncoding, s);
-}
-
-TEST(EncodingMethodsTest, AllVariants) {
-    Map map;
-    map.add("key1", Array().add(Map()  //
-                                        .add("key_a", 9999999)
-                                        .add("key_b", std::vector<uint8_t>{0x01, 0x02, 0x03})
-                                        .add("key_c", std::numeric_limits<uint64_t>::max())
-                                        .add("key_d", std::numeric_limits<int16_t>::min()))
-                            .add("foo"))
-            .add("key2", true);
-
-    std::vector<uint8_t> buf;
-    buf.resize(map.encodedSize());
-
-    EXPECT_EQ(buf.data() + buf.size(), map.encode(buf.data(), buf.data() + buf.size()));
-
-    EXPECT_EQ(buf, map.encode());
-
-    std::vector<uint8_t> buf2;
-    map.encode(std::back_inserter(buf2));
-    EXPECT_EQ(buf, buf2);
-
-    auto iter = buf.begin();
-    map.encode([&](uint8_t c) { EXPECT_EQ(c, *iter++); });
-}
-
-TEST(EncodingMethodsTest, UintWithTooShortBuf) {
-    Uint val(100000);
-    vector<uint8_t> buf(val.encodedSize() - 1);
-    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
-}
-
-TEST(EncodingMethodsTest, TstrWithTooShortBuf) {
-    Tstr val("01234567890123456789012345"s);
-    vector<uint8_t> buf(1);
-    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
-
-    buf.resize(val.encodedSize() - 1);
-    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
-}
-
-TEST(EncodingMethodsTest, BstrWithTooShortBuf) {
-    Bstr val("01234567890123456789012345"s);
-    vector<uint8_t> buf(1);
-    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
-
-    buf.resize(val.encodedSize() - 1);
-    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
-}
-
-TEST(EncodingMethodsTest, ArrayWithTooShortBuf) {
-    Array val("a", 5, -100);
-
-    std::vector<uint8_t> buf(val.encodedSize() - 1);
-    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
-}
-
-TEST(EncodingMethodsTest, MapWithTooShortBuf) {
-    Map map;
-    map.add("key1", Array().add(Map()  //
-                                        .add("key_a", 99)
-                                        .add("key_b", std::vector<uint8_t>{0x01, 0x02, 0x03}))
-                            .add("foo"))
-            .add("key2", true);
-
-    std::vector<uint8_t> buf(map.encodedSize() - 1);
-    EXPECT_EQ(nullptr, map.encode(buf.data(), buf.data() + buf.size()));
-}
-
-TEST(EqualityTest, Uint) {
-    Uint val(99);
-    EXPECT_EQ(val, Uint(99));
-
-    EXPECT_NE(val, Uint(98));
-    EXPECT_NE(val, Nint(-1));
-    EXPECT_NE(val, Tstr("99"));
-    EXPECT_NE(val, Bstr("99"));
-    EXPECT_NE(val, Bool(false));
-    EXPECT_NE(val, Array(99, 1));
-    EXPECT_NE(val, Map(99, 1));
-}
-
-TEST(EqualityTest, Nint) {
-    Nint val(-1);
-    EXPECT_EQ(val, Nint(-1));
-
-    EXPECT_NE(val, Uint(99));
-    EXPECT_NE(val, Nint(-4));
-    EXPECT_NE(val, Tstr("99"));
-    EXPECT_NE(val, Bstr("99"));
-    EXPECT_NE(val, Bool(false));
-    EXPECT_NE(val, Array(99));
-    EXPECT_NE(val, Map(99, 1));
-}
-
-TEST(EqualityTest, Tstr) {
-    Tstr val("99");
-    EXPECT_EQ(val, Tstr("99"));
-
-    EXPECT_NE(val, Uint(99));
-    EXPECT_NE(val, Nint(-1));
-    EXPECT_NE(val, Nint(-4));
-    EXPECT_NE(val, Tstr("98"));
-    EXPECT_NE(val, Bstr("99"));
-    EXPECT_NE(val, Bool(false));
-    EXPECT_NE(val, Array(99, 1));
-    EXPECT_NE(val, Map(99, 1));
-}
-
-TEST(EqualityTest, Bstr) {
-    Bstr val("99");
-    EXPECT_EQ(val, Bstr("99"));
-
-    EXPECT_NE(val, Uint(99));
-    EXPECT_NE(val, Nint(-1));
-    EXPECT_NE(val, Nint(-4));
-    EXPECT_NE(val, Tstr("99"));
-    EXPECT_NE(val, Bstr("98"));
-    EXPECT_NE(val, Bool(false));
-    EXPECT_NE(val, Array(99, 1));
-    EXPECT_NE(val, Map(99, 1));
-}
-
-TEST(EqualityTest, Bool) {
-    Bool val(false);
-    EXPECT_EQ(val, Bool(false));
-
-    EXPECT_NE(val, Uint(99));
-    EXPECT_NE(val, Nint(-1));
-    EXPECT_NE(val, Nint(-4));
-    EXPECT_NE(val, Tstr("99"));
-    EXPECT_NE(val, Bstr("98"));
-    EXPECT_NE(val, Bool(true));
-    EXPECT_NE(val, Array(99, 1));
-    EXPECT_NE(val, Map(99, 1));
-}
-
-TEST(EqualityTest, Array) {
-    Array val(99, 1);
-    EXPECT_EQ(val, Array(99, 1));
-
-    EXPECT_NE(val, Uint(99));
-    EXPECT_NE(val, Nint(-1));
-    EXPECT_NE(val, Nint(-4));
-    EXPECT_NE(val, Tstr("99"));
-    EXPECT_NE(val, Bstr("98"));
-    EXPECT_NE(val, Bool(true));
-    EXPECT_NE(val, Array(99, 2));
-    EXPECT_NE(val, Array(98, 1));
-    EXPECT_NE(val, Array(99, 1, 2));
-    EXPECT_NE(val, Map(99, 1));
-}
-
-TEST(EqualityTest, Map) {
-    Map val(99, 1);
-    EXPECT_EQ(val, Map(99, 1));
-
-    EXPECT_NE(val, Uint(99));
-    EXPECT_NE(val, Nint(-1));
-    EXPECT_NE(val, Nint(-4));
-    EXPECT_NE(val, Tstr("99"));
-    EXPECT_NE(val, Bstr("98"));
-    EXPECT_NE(val, Bool(true));
-    EXPECT_NE(val, Array(99, 1));
-    EXPECT_NE(val, Map(99, 2));
-    EXPECT_NE(val, Map(99, 1, 99, 2));
-}
-
-TEST(ConvertTest, Uint) {
-    unique_ptr<Item> item = details::makeItem(10);
-
-    EXPECT_EQ(UINT, item->type());
-    EXPECT_NE(nullptr, item->asInt());
-    EXPECT_NE(nullptr, item->asUint());
-    EXPECT_EQ(nullptr, item->asNint());
-    EXPECT_EQ(nullptr, item->asTstr());
-    EXPECT_EQ(nullptr, item->asBstr());
-    EXPECT_EQ(nullptr, item->asSimple());
-    EXPECT_EQ(nullptr, item->asMap());
-    EXPECT_EQ(nullptr, item->asArray());
-
-    EXPECT_EQ(10, item->asInt()->value());
-    EXPECT_EQ(10, item->asUint()->value());
-}
-
-TEST(ConvertTest, Nint) {
-    unique_ptr<Item> item = details::makeItem(-10);
-
-    EXPECT_EQ(NINT, item->type());
-    EXPECT_NE(nullptr, item->asInt());
-    EXPECT_EQ(nullptr, item->asUint());
-    EXPECT_NE(nullptr, item->asNint());
-    EXPECT_EQ(nullptr, item->asTstr());
-    EXPECT_EQ(nullptr, item->asBstr());
-    EXPECT_EQ(nullptr, item->asSimple());
-    EXPECT_EQ(nullptr, item->asMap());
-    EXPECT_EQ(nullptr, item->asArray());
-
-    EXPECT_EQ(-10, item->asInt()->value());
-    EXPECT_EQ(-10, item->asNint()->value());
-}
-
-TEST(ConvertTest, Tstr) {
-    unique_ptr<Item> item = details::makeItem("hello");
-
-    EXPECT_EQ(TSTR, item->type());
-    EXPECT_EQ(nullptr, item->asInt());
-    EXPECT_EQ(nullptr, item->asUint());
-    EXPECT_EQ(nullptr, item->asNint());
-    EXPECT_NE(nullptr, item->asTstr());
-    EXPECT_EQ(nullptr, item->asBstr());
-    EXPECT_EQ(nullptr, item->asSimple());
-    EXPECT_EQ(nullptr, item->asMap());
-    EXPECT_EQ(nullptr, item->asArray());
-
-    EXPECT_EQ("hello"s, item->asTstr()->value());
-}
-
-TEST(ConvertTest, Bstr) {
-    vector<uint8_t> vec{0x23, 0x24, 0x22};
-    unique_ptr<Item> item = details::makeItem(vec);
-
-    EXPECT_EQ(BSTR, item->type());
-    EXPECT_EQ(nullptr, item->asInt());
-    EXPECT_EQ(nullptr, item->asUint());
-    EXPECT_EQ(nullptr, item->asNint());
-    EXPECT_EQ(nullptr, item->asTstr());
-    EXPECT_NE(nullptr, item->asBstr());
-    EXPECT_EQ(nullptr, item->asSimple());
-    EXPECT_EQ(nullptr, item->asMap());
-    EXPECT_EQ(nullptr, item->asArray());
-
-    EXPECT_EQ(vec, item->asBstr()->value());
-}
-
-TEST(ConvertTest, Bool) {
-    unique_ptr<Item> item = details::makeItem(false);
-
-    EXPECT_EQ(SIMPLE, item->type());
-    EXPECT_EQ(nullptr, item->asInt());
-    EXPECT_EQ(nullptr, item->asUint());
-    EXPECT_EQ(nullptr, item->asNint());
-    EXPECT_EQ(nullptr, item->asTstr());
-    EXPECT_EQ(nullptr, item->asBstr());
-    EXPECT_NE(nullptr, item->asSimple());
-    EXPECT_EQ(nullptr, item->asMap());
-    EXPECT_EQ(nullptr, item->asArray());
-
-    EXPECT_EQ(BOOLEAN, item->asSimple()->simpleType());
-    EXPECT_NE(nullptr, item->asSimple()->asBool());
-
-    EXPECT_FALSE(item->asSimple()->asBool()->value());
-}
-
-TEST(ConvertTest, Map) {
-    unique_ptr<Item> item(new Map);
-
-    EXPECT_EQ(MAP, item->type());
-    EXPECT_EQ(nullptr, item->asInt());
-    EXPECT_EQ(nullptr, item->asUint());
-    EXPECT_EQ(nullptr, item->asNint());
-    EXPECT_EQ(nullptr, item->asTstr());
-    EXPECT_EQ(nullptr, item->asBstr());
-    EXPECT_EQ(nullptr, item->asSimple());
-    EXPECT_NE(nullptr, item->asMap());
-    EXPECT_EQ(nullptr, item->asArray());
-
-    EXPECT_EQ(0U, item->asMap()->size());
-}
-
-TEST(ConvertTest, Array) {
-    unique_ptr<Item> item(new Array);
-
-    EXPECT_EQ(ARRAY, item->type());
-    EXPECT_EQ(nullptr, item->asInt());
-    EXPECT_EQ(nullptr, item->asUint());
-    EXPECT_EQ(nullptr, item->asNint());
-    EXPECT_EQ(nullptr, item->asTstr());
-    EXPECT_EQ(nullptr, item->asBstr());
-    EXPECT_EQ(nullptr, item->asSimple());
-    EXPECT_EQ(nullptr, item->asMap());
-    EXPECT_NE(nullptr, item->asArray());
-
-    EXPECT_EQ(0U, item->asArray()->size());
-}
-
-class MockParseClient : public ParseClient {
-  public:
-    MOCK_METHOD4(item, ParseClient*(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
-                                    const uint8_t* valueBegin, const uint8_t* end));
-    MOCK_METHOD4(itemEnd, ParseClient*(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
-                                       const uint8_t* valueBegin, const uint8_t* end));
-    MOCK_METHOD2(error, void(const uint8_t* position, const std::string& errorMessage));
-};
-
-MATCHER_P(IsType, value, std::string("Type ") + (negation ? "doesn't match" : "matches")) {
-    return arg->type() == value;
-}
-
-MATCHER_P(MatchesItem, value, "") {
-    return arg && *arg == value;
-}
-
-MATCHER_P(IsArrayOfSize, value, "") {
-    return arg->type() == ARRAY && arg->asArray()->size() == value;
-}
-
-MATCHER_P(IsMapOfSize, value, "") {
-    return arg->type() == MAP && arg->asMap()->size() == value;
-}
-
-TEST(StreamParseTest, Uint) {
-    MockParseClient mpc;
-
-    Uint val(100);
-    auto encoded = val.encode();
-    uint8_t* encBegin = encoded.data();
-    uint8_t* encEnd = encoded.data() + encoded.size();
-
-    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encEnd, encEnd)).WillOnce(Return(&mpc));
-    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
-    EXPECT_CALL(mpc, error(_, _)).Times(0);
-
-    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
-}
-
-TEST(StreamParseTest, Nint) {
-    MockParseClient mpc;
-
-    Nint val(-10);
-    auto encoded = val.encode();
-    uint8_t* encBegin = encoded.data();
-    uint8_t* encEnd = encoded.data() + encoded.size();
-
-    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encEnd, encEnd)).WillOnce(Return(&mpc));
-
-    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
-    EXPECT_CALL(mpc, error(_, _)).Times(0);
-
-    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
-}
-
-TEST(StreamParseTest, Bool) {
-    MockParseClient mpc;
-
-    Bool val(true);
-    auto encoded = val.encode();
-    uint8_t* encBegin = encoded.data();
-    uint8_t* encEnd = encoded.data() + encoded.size();
-
-    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encEnd, encEnd)).WillOnce(Return(&mpc));
-    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
-    EXPECT_CALL(mpc, error(_, _)).Times(0);
-
-    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
-}
-
-TEST(StreamParseTest, Tstr) {
-    MockParseClient mpc;
-
-    Tstr val("Hello");
-    auto encoded = val.encode();
-    uint8_t* encBegin = encoded.data();
-    uint8_t* encEnd = encoded.data() + encoded.size();
-
-    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encBegin + 1, encEnd)).WillOnce(Return(&mpc));
-    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
-    EXPECT_CALL(mpc, error(_, _)).Times(0);
-
-    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
-}
-
-TEST(StreamParseTest, Bstr) {
-    MockParseClient mpc;
-
-    Bstr val("Hello");
-    auto encoded = val.encode();
-    uint8_t* encBegin = encoded.data();
-    uint8_t* encEnd = encoded.data() + encoded.size();
-
-    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encBegin + 1, encEnd)).WillOnce(Return(&mpc));
-    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
-    EXPECT_CALL(mpc, error(_, _)).Times(0);
-
-    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
-}
-
-TEST(StreamParseTest, Array) {
-    MockParseClient mpc;
-
-    Array val("Hello", 4, Array(-9, "Goodbye"), std::numeric_limits<uint64_t>::max());
-    ASSERT_NE(val[2]->asArray(), nullptr);
-    const Array& interior = *(val[2]->asArray());
-    auto encoded = val.encode();
-    uint8_t* encBegin = encoded.data();
-    uint8_t* encEnd = encoded.data() + encoded.size();
-
-    {
-        InSequence s;
-        const uint8_t* pos = encBegin;
-        EXPECT_CALL(mpc, item(IsArrayOfSize(val.size()), pos, pos + 1, pos + 1))
-                .WillOnce(Return(&mpc));
-        ++pos;
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[0])), pos, pos + 1, pos + 6))
-                .WillOnce(Return(&mpc));
-        pos += 6;
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[1])), pos, pos + 1, pos + 1))
-                .WillOnce(Return(&mpc));
-        ++pos;
-        const uint8_t* innerArrayBegin = pos;
-        EXPECT_CALL(mpc, item(IsArrayOfSize(interior.size()), pos, pos + 1, pos + 1))
-                .WillOnce(Return(&mpc));
-        ++pos;
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[0])), pos, pos + 1, pos + 1))
-                .WillOnce(Return(&mpc));
-        ++pos;
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[1])), pos, pos + 1, pos + 8))
-                .WillOnce(Return(&mpc));
-        pos += 8;
-        EXPECT_CALL(mpc, itemEnd(IsArrayOfSize(interior.size()), innerArrayBegin,
-                                 innerArrayBegin + 1, pos))
-                .WillOnce(Return(&mpc));
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[3])), pos, pos + 9, pos + 9))
-                .WillOnce(Return(&mpc));
-        EXPECT_CALL(mpc, itemEnd(IsArrayOfSize(val.size()), encBegin, encBegin + 1, encEnd))
-                .WillOnce(Return(&mpc));
-    }
-
-    EXPECT_CALL(mpc, error(_, _))  //
-            .Times(0);
-
-    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
-}
-
-TEST(StreamParseTest, Map) {
-    MockParseClient mpc;
-
-    Map val("Hello", 4, Array(-9, "Goodbye"), std::numeric_limits<uint64_t>::max());
-    ASSERT_NE(val[1].first->asArray(), nullptr);
-    const Array& interior = *(val[1].first->asArray());
-    auto encoded = val.encode();
-    uint8_t* encBegin = encoded.data();
-    uint8_t* encEnd = encoded.data() + encoded.size();
-
-    {
-        InSequence s;
-        const uint8_t* pos = encBegin;
-        EXPECT_CALL(mpc, item(_, pos, pos + 1, pos + 1)).WillOnce(Return(&mpc));
-        ++pos;
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[0].first)), pos, pos + 1, pos + 6))
-                .WillOnce(Return(&mpc));
-        pos += 6;
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[0].second)), pos, pos + 1, pos + 1))
-                .WillOnce(Return(&mpc));
-        ++pos;
-        const uint8_t* innerArrayBegin = pos;
-        EXPECT_CALL(mpc, item(IsArrayOfSize(interior.size()), pos, pos + 1, pos + 1))
-                .WillOnce(Return(&mpc));
-        ++pos;
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[0])), pos, pos + 1, pos + 1))
-                .WillOnce(Return(&mpc));
-        ++pos;
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[1])), pos, pos + 1, pos + 8))
-                .WillOnce(Return(&mpc));
-        pos += 8;
-        EXPECT_CALL(mpc, itemEnd(IsArrayOfSize(interior.size()), innerArrayBegin,
-                                 innerArrayBegin + 1, pos))
-                .WillOnce(Return(&mpc));
-        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[1].second)), pos, pos + 9, pos + 9))
-                .WillOnce(Return(&mpc));
-        EXPECT_CALL(mpc, itemEnd(IsMapOfSize(val.size()), encBegin, encBegin + 1, encEnd))
-                .WillOnce(Return(&mpc));
-    }
-
-    EXPECT_CALL(mpc, error(_, _))  //
-            .Times(0);
-
-    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
-}
-
-TEST(StreamParseTest, Semantic) {
-    MockParseClient mpc;
-
-    vector<uint8_t> encoded;
-    auto iter = back_inserter(encoded);
-    encodeHeader(SEMANTIC, 0, iter);
-    Uint(999).encode(iter);
-
-    EXPECT_CALL(mpc, item(_, _, _, _)).Times(0);
-    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
-    EXPECT_CALL(mpc, error(encoded.data(), "Semantic tags not supported"));
-
-    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
-}
-
-TEST(FullParserTest, Uint) {
-    Uint val(10);
-
-    auto [item, pos, message] = parse(val.encode());
-    EXPECT_THAT(item, MatchesItem(val));
-}
-
-TEST(FullParserTest, Nint) {
-    Nint val(-10);
-
-    auto [item, pos, message] = parse(val.encode());
-    EXPECT_THAT(item, MatchesItem(val));
-
-    vector<uint8_t> minNint = {0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
-
-    std::tie(item, pos, message) = parse(minNint);
-    EXPECT_THAT(item, NotNull());
-    EXPECT_EQ(item->asNint()->value(), std::numeric_limits<int64_t>::min());
-}
-
-TEST(FullParserTest, NintOutOfRange) {
-    vector<uint8_t> outOfRangeNint = {0x3B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
-
-    auto [item, pos, message] = parse(outOfRangeNint);
-    EXPECT_THAT(item, IsNull());
-    EXPECT_EQ(pos, outOfRangeNint.data());
-    EXPECT_EQ(message, "NINT values that don't fit in int64_t are not supported.");
-}
-
-TEST(FullParserTest, Tstr) {
-    Tstr val("Hello");
-
-    auto [item, pos, message] = parse(val.encode());
-    EXPECT_THAT(item, MatchesItem(val));
-}
-
-TEST(FullParserTest, Bstr) {
-    Bstr val("\x00\x01\0x02"s);
-
-    auto [item, pos, message] = parse(val.encode());
-    EXPECT_THAT(item, MatchesItem(val));
-}
-
-TEST(FullParserTest, Array) {
-    Array val("hello", -4, 3);
-
-    auto encoded = val.encode();
-    auto [item, pos, message] = parse(encoded);
-    EXPECT_THAT(item, MatchesItem(ByRef(val)));
-    EXPECT_EQ(pos, encoded.data() + encoded.size());
-    EXPECT_EQ("", message);
-
-    // We've already checked it all, but walk it just for fun.
-    ASSERT_NE(nullptr, item->asArray());
-    const Array& arr = *(item->asArray());
-    ASSERT_EQ(arr[0]->type(), TSTR);
-    EXPECT_EQ(arr[0]->asTstr()->value(), "hello");
-}
-
-TEST(FullParserTest, Map) {
-    Map val("hello", -4, 3, Bstr("hi"));
-
-    auto [item, pos, message] = parse(val.encode());
-    EXPECT_THAT(item, MatchesItem(ByRef(val)));
-}
-
-TEST(FullParserTest, Complex) {
-    vector<uint8_t> vec = {0x01, 0x02, 0x08, 0x03};
-    Map val("Outer1",
-            Array(Map("Inner1", 99,  //
-                      "Inner2", vec),
-                  "foo"),
-            "Outer2", 10);
-
-    std::unique_ptr<Item> item;
-    const uint8_t* pos;
-    std::string message;
-    std::tie(item, pos, message) = parse(val.encode());
-    EXPECT_THAT(item, MatchesItem(ByRef(val)));
-}
-
-TEST(FullParserTest, IncompleteUint) {
-    Uint val(1000);
-
-    auto encoding = val.encode();
-    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 1);
-    EXPECT_EQ(nullptr, item.get());
-    EXPECT_EQ(encoding.data(), pos);
-    EXPECT_EQ("Need 2 byte(s) for length field, have 1.", message);
-}
-
-TEST(FullParserTest, IncompleteString) {
-    Tstr val("hello");
-
-    auto encoding = val.encode();
-    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 2);
-    EXPECT_EQ(nullptr, item.get());
-    EXPECT_EQ(encoding.data(), pos);
-    EXPECT_EQ("Need 5 byte(s) for text string, have 3.", message);
-}
-
-TEST(FullParserTest, ArrayWithInsufficientEntries) {
-    Array val(1, 2, 3, 4);
-
-    auto encoding = val.encode();
-    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 1);
-    EXPECT_EQ(nullptr, item.get());
-    EXPECT_EQ(encoding.data(), pos);
-    EXPECT_EQ("Not enough entries for array.", message);
-}
-
-TEST(FullParserTest, ArrayWithTruncatedEntry) {
-    Array val(1, 2, 3, 400000);
-
-    auto encoding = val.encode();
-    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 1);
-    EXPECT_EQ(nullptr, item.get());
-    EXPECT_EQ(encoding.data() + encoding.size() - 5, pos);
-    EXPECT_EQ("Need 4 byte(s) for length field, have 3.", message);
-}
-
-TEST(FullParserTest, MapWithTruncatedEntry) {
-    Map val(1, 2, 300000, 4);
-
-    auto encoding = val.encode();
-    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 2);
-    EXPECT_EQ(nullptr, item.get());
-    EXPECT_EQ(encoding.data() + 3, pos);
-    EXPECT_EQ("Need 4 byte(s) for length field, have 3.", message);
-}
-int main(int argc, char** argv) {
-    ::testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-}
diff --git a/input/OWNERS b/input/OWNERS
new file mode 100644
index 0000000..21d208f
--- /dev/null
+++ b/input/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 136048
+include platform/frameworks/base:/INPUT_OWNERS
diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp
index 5ff1457..22346ed 100644
--- a/input/classifier/1.0/vts/functional/Android.bp
+++ b/input/classifier/1.0/vts/functional/Android.bp
@@ -25,6 +25,7 @@
 
 cc_test {
     name: "VtsHalInputClassifierV1_0TargetTest",
+    cpp_std: "c++20",
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
         ":inputconstants_aidl",
diff --git a/input/common/aidl/Android.bp b/input/common/aidl/Android.bp
index 390d8b5..95a14b2 100644
--- a/input/common/aidl/Android.bp
+++ b/input/common/aidl/Android.bp
@@ -9,6 +9,7 @@
 
 aidl_interface {
     name: "android.hardware.input.common",
+    host_supported: true,
     vendor_available: true,
     srcs: ["android/hardware/input/common/*.aidl"],
     stability: "vintf",
diff --git a/input/processor/aidl/Android.bp b/input/processor/aidl/Android.bp
index 354816e..f1a73d2 100644
--- a/input/processor/aidl/Android.bp
+++ b/input/processor/aidl/Android.bp
@@ -9,10 +9,11 @@
 
 aidl_interface {
     name: "android.hardware.input.processor",
+    host_supported: true,
     vendor_available: true,
     srcs: ["android/hardware/input/processor/*.aidl"],
     imports: [
-        "android.hardware.input.common",
+        "android.hardware.input.common-V1",
     ],
     stability: "vintf",
     backend: {
diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp
index 2485f5b..25f6c8f 100644
--- a/ir/aidl/Android.bp
+++ b/ir/aidl/Android.bp
@@ -33,11 +33,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
diff --git a/ir/aidl/default/Android.bp b/ir/aidl/default/Android.bp
index a4fb439..a8096c2 100644
--- a/ir/aidl/default/Android.bp
+++ b/ir/aidl/default/Android.bp
@@ -36,6 +36,7 @@
         "liblog",
         "libutils",
         "android.hardware.ir-V1-ndk",
+        "libhardware"
     ],
 
     srcs: ["main.cpp"],
diff --git a/ir/aidl/default/android.hardware.ir-service.example.rc b/ir/aidl/default/android.hardware.ir-service.example.rc
index 56def64..d27f282 100644
--- a/ir/aidl/default/android.hardware.ir-service.example.rc
+++ b/ir/aidl/default/android.hardware.ir-service.example.rc
@@ -1,4 +1,4 @@
 service vendor.ir-default /vendor/bin/hw/android.hardware.ir-service.example
     class hal
-    user nobody
-    group nobody
+    user system
+    group system
diff --git a/ir/aidl/default/main.cpp b/ir/aidl/default/main.cpp
index 7c4a816..92376fc 100644
--- a/ir/aidl/default/main.cpp
+++ b/ir/aidl/default/main.cpp
@@ -15,49 +15,77 @@
  */
 
 #include <aidl/android/hardware/ir/BnConsumerIr.h>
+#include <aidl/android/hardware/ir/ConsumerIrFreqRange.h>
 #include <android-base/logging.h>
 #include <android/binder_interface_utils.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <hardware/consumerir.h>
 #include <numeric>
 
+#include <log/log.h>
+
+using ::aidl::android::hardware::ir::ConsumerIrFreqRange;
+
 namespace aidl::android::hardware::ir {
 
-const std::vector<ConsumerIrFreqRange> kSupportedFreqs = {
-        {2000, 4000},
-        {10000, 30000},
-};
-
 class ConsumerIr : public BnConsumerIr {
+  public:
+    ConsumerIr();
+  private:
     ::ndk::ScopedAStatus getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) override;
     ::ndk::ScopedAStatus transmit(int32_t in_carrierFreqHz,
                                   const std::vector<int32_t>& in_pattern) override;
+    consumerir_device_t *mDevice = nullptr;
 };
 
-::ndk::ScopedAStatus ConsumerIr::getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) {
-    *_aidl_return = kSupportedFreqs;
-    return ::ndk::ScopedAStatus::ok();
+ConsumerIr::ConsumerIr() {
+    const hw_module_t *hw_module = NULL;
+
+    int ret = hw_get_module(CONSUMERIR_HARDWARE_MODULE_ID, &hw_module);
+    if (ret != 0) {
+        ALOGE("hw_get_module %s failed: %d", CONSUMERIR_HARDWARE_MODULE_ID, ret);
+        return;
+    }
+    ret = hw_module->methods->open(hw_module, CONSUMERIR_TRANSMITTER, (hw_device_t **) &mDevice);
+    if (ret < 0) {
+        // note - may want to make this a fatal error - otherwise the service will crash when it's used
+        ALOGE("Can't open consumer IR transmitter, error: %d", ret);
+        // in case it's modified
+        mDevice = nullptr;
+    }
 }
 
-bool isSupportedFreq(int32_t freq) {
-    for (const auto& range : kSupportedFreqs) {
-        if (freq >= range.minHz && freq <= range.maxHz) return true;
+::ndk::ScopedAStatus ConsumerIr::getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) {
+    int32_t len = mDevice->get_num_carrier_freqs(mDevice);
+    if (len < 0) {
+        (*_aidl_return).clear();
+        return ::ndk::ScopedAStatus::ok();
     }
-    return false;
+
+    consumerir_freq_range_t *rangeAr = new consumerir_freq_range_t[len];
+    bool success = (mDevice->get_carrier_freqs(mDevice, len, rangeAr) >= 0);
+    if (!success) {
+        (*_aidl_return).clear();
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    (*_aidl_return).resize(len);
+    for (int32_t i = 0; i < len; i++) {
+        (*_aidl_return)[i].minHz = static_cast<uint32_t>(rangeAr[i].min);
+        (*_aidl_return)[i].maxHz = static_cast<uint32_t>(rangeAr[i].max);
+    }
+    return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreqHz,
                                           const std::vector<int32_t>& in_pattern) {
-    if (isSupportedFreq(in_carrierFreqHz)) {
-        // trasmit the pattern, each integer is number of microseconds in an
-        // alternating on/off state.
-        usleep(std::accumulate(in_pattern.begin(), in_pattern.end(), 0));
+    if (in_carrierFreqHz > 0) {
+        mDevice->transmit(mDevice, in_carrierFreqHz, in_pattern.data(), in_pattern.size());
         return ::ndk::ScopedAStatus::ok();
     } else {
-        // unsupported operation
         return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
     }
-    return ::ndk::ScopedAStatus::ok();
 }
 
 }  // namespace aidl::android::hardware::ir
diff --git a/keymaster/3.0/default/OWNERS b/keymaster/3.0/default/OWNERS
deleted file mode 100644
index 335660d..0000000
--- a/keymaster/3.0/default/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-jdanis@google.com
-swillden@google.com
diff --git a/keymaster/3.0/vts/OWNERS b/keymaster/3.0/vts/OWNERS
deleted file mode 100644
index 846bb84..0000000
--- a/keymaster/3.0/vts/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-drysdale@google.com
-jdanis@google.com
-swillden@google.com
-yim@google.com
-yuexima@google.com
diff --git a/keymaster/3.0/vts/functional/OWNERS b/keymaster/3.0/vts/functional/OWNERS
deleted file mode 100644
index 2ef9086..0000000
--- a/keymaster/3.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 189335
-swillden@google.com
diff --git a/keymaster/4.0/default/OWNERS b/keymaster/4.0/default/OWNERS
deleted file mode 100644
index 335660d..0000000
--- a/keymaster/4.0/default/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-jdanis@google.com
-swillden@google.com
diff --git a/keymaster/4.0/support/OWNERS b/keymaster/4.0/support/OWNERS
deleted file mode 100644
index a9efe66..0000000
--- a/keymaster/4.0/support/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-jdanis@google.com
-swillden@google.com
-jbires@google.com
diff --git a/keymaster/4.0/vts/OWNERS b/keymaster/4.0/vts/OWNERS
deleted file mode 100644
index 0d6fa6c..0000000
--- a/keymaster/4.0/vts/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-drysdale@google.com
-jbires@google.com
-jdanis@google.com
-swillden@google.com
-yim@google.com
-yuexima@google.com
diff --git a/keymaster/4.0/vts/functional/BootloaderStateTest.cpp b/keymaster/4.0/vts/functional/BootloaderStateTest.cpp
index f874767..912b59b 100644
--- a/keymaster/4.0/vts/functional/BootloaderStateTest.cpp
+++ b/keymaster/4.0/vts/functional/BootloaderStateTest.cpp
@@ -33,7 +33,6 @@
 
 // Since this test needs to talk to Keymaster HAL, it can only run as root. Thus,
 // bootloader can not be locked.
-// @CddTest = 9.10/C-0-2
 class BootloaderStateTest : public KeymasterHidlTest {
   public:
     virtual void SetUp() override {
diff --git a/keymaster/4.0/vts/functional/OWNERS b/keymaster/4.0/vts/functional/OWNERS
deleted file mode 100644
index 2ef9086..0000000
--- a/keymaster/4.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 189335
-swillden@google.com
diff --git a/keymaster/4.0/vts/performance/Benchmark.cpp b/keymaster/4.0/vts/performance/Benchmark.cpp
index 96ef5bf..e5fdff2 100644
--- a/keymaster/4.0/vts/performance/Benchmark.cpp
+++ b/keymaster/4.0/vts/performance/Benchmark.cpp
@@ -315,7 +315,7 @@
 
     SecurityLevel getSecurityLevel() { return securityLevel_; }
 
-    const string& GenerateMessage(int size) {
+    const string GenerateMessage(int size) {
         for (const string& message : message_cache_) {
             if (message.size() == size) {
                 return message;
@@ -323,7 +323,7 @@
         }
         string message = string(size, 'x');
         message_cache_.push_back(message);
-        return std::move(message);
+        return message;
     }
 
     optional<BlockMode> getBlockMode(string transform) {
@@ -714,4 +714,4 @@
         return 1;
     }
     ::benchmark::RunSpecifiedBenchmarks();
-}
\ No newline at end of file
+}
diff --git a/keymaster/4.1/default/OWNERS b/keymaster/4.1/default/OWNERS
deleted file mode 100644
index 2b2ad2a..0000000
--- a/keymaster/4.1/default/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-jbires@google.com
-jdanis@google.com
-swillden@google.com
-zeuthen@google.com
\ No newline at end of file
diff --git a/keymaster/4.1/support/OWNERS b/keymaster/4.1/support/OWNERS
deleted file mode 100644
index 2b2ad2a..0000000
--- a/keymaster/4.1/support/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-jbires@google.com
-jdanis@google.com
-swillden@google.com
-zeuthen@google.com
\ No newline at end of file
diff --git a/keymaster/4.1/vts/OWNERS b/keymaster/4.1/vts/OWNERS
deleted file mode 100644
index 24ed042..0000000
--- a/keymaster/4.1/vts/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-drysdale@google.com
-jbires@google.com
-jdanis@google.com
-swillden@google.com
-zeuthen@google.com
\ No newline at end of file
diff --git a/keymaster/4.1/vts/functional/OWNERS b/keymaster/4.1/vts/functional/OWNERS
deleted file mode 100644
index 2ef9086..0000000
--- a/keymaster/4.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 189335
-swillden@google.com
diff --git a/keymaster/OWNERS b/keymaster/OWNERS
new file mode 100644
index 0000000..ac8bd83
--- /dev/null
+++ b/keymaster/OWNERS
@@ -0,0 +1,14 @@
+# Bug component: 1084733
+
+# Please assign all bugs related to /hardware/interfaces/keymaster to the team alias:
+#
+#    android-hardware-security@google.com
+#
+# This will get them auto-assigned to the on-call triage engineer, ensuring quickest response.
+
+drysdale@google.com
+eranm@google.com
+hasinitg@google.com
+jbires@google.com
+swillden@google.com
+zeuthen@google.com
diff --git a/keymaster/aidl/Android.bp b/keymaster/aidl/Android.bp
index c4b6740..0f2debd 100644
--- a/keymaster/aidl/Android.bp
+++ b/keymaster/aidl/Android.bp
@@ -18,15 +18,25 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
-    versions: [
-        "1",
-        "2",
-        "3",
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+        {
+            version: "2",
+            imports: [],
+        },
+        {
+            version: "3",
+            imports: [],
+        },
+        {
+            version: "4",
+            imports: [],
+        },
+
     ],
+    frozen: true,
 }
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/4/.hash b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/.hash
new file mode 100644
index 0000000..cfa2965
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/.hash
@@ -0,0 +1 @@
+d60ca1bb57f94508910cac7b8910c85e2a49a11f
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/HardwareAuthToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/HardwareAuthToken.aidl
new file mode 100644
index 0000000..6e84e98
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/HardwareAuthToken.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 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.keymaster;
+/* @hide */
+@VintfStability
+parcelable HardwareAuthToken {
+  long challenge;
+  long userId;
+  long authenticatorId;
+  android.hardware.keymaster.HardwareAuthenticatorType authenticatorType = android.hardware.keymaster.HardwareAuthenticatorType.NONE;
+  android.hardware.keymaster.Timestamp timestamp;
+  byte[] mac;
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/HardwareAuthenticatorType.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/HardwareAuthenticatorType.aidl
new file mode 100644
index 0000000..9526bed
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/HardwareAuthenticatorType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 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.keymaster;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum HardwareAuthenticatorType {
+  NONE = 0,
+  PASSWORD = (1 << 0) /* 1 */,
+  FINGERPRINT = (1 << 1) /* 2 */,
+  ANY = 0xFFFFFFFF,
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/SecurityLevel.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/SecurityLevel.aidl
new file mode 100644
index 0000000..d32ef68
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/SecurityLevel.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.keymaster;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum SecurityLevel {
+  SOFTWARE = 0,
+  TRUSTED_ENVIRONMENT = 1,
+  STRONGBOX = 2,
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/Timestamp.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/Timestamp.aidl
new file mode 100644
index 0000000..5b7b37a
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/Timestamp.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.keymaster;
+/* @hide */
+@VintfStability
+parcelable Timestamp {
+  long milliSeconds;
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/VerificationToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/VerificationToken.aidl
new file mode 100644
index 0000000..10fa5e1
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/4/android/hardware/keymaster/VerificationToken.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.keymaster;
+/* @hide */
+@VintfStability
+parcelable VerificationToken {
+  long challenge;
+  android.hardware.keymaster.Timestamp timestamp;
+  android.hardware.keymaster.SecurityLevel securityLevel = android.hardware.keymaster.SecurityLevel.SOFTWARE;
+  byte[] mac;
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthToken.aidl
index 4f21cba..6e84e98 100644
--- a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthToken.aidl
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthToken.aidl
@@ -1,14 +1,30 @@
+/*
+ * Copyright 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 interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// 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 changes to the AIDL files built
+// 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
@@ -16,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.keymaster;
+/* @hide */
 @VintfStability
 parcelable HardwareAuthToken {
   long challenge;
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthenticatorType.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthenticatorType.aidl
index 924567f..0a40549 100644
--- a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthenticatorType.aidl
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/HardwareAuthenticatorType.aidl
@@ -1,14 +1,30 @@
+/*
+ * Copyright 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 interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// 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 changes to the AIDL files built
+// 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
@@ -16,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.keymaster;
+/* @hide */
 @Backing(type="int") @VintfStability
 enum HardwareAuthenticatorType {
   NONE = 0,
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/SecurityLevel.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/SecurityLevel.aidl
index 127c1bf..d32ef68 100644
--- a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/SecurityLevel.aidl
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/SecurityLevel.aidl
@@ -1,14 +1,30 @@
+/*
+ * 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 interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// 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 changes to the AIDL files built
+// 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
@@ -16,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.keymaster;
+/* @hide */
 @Backing(type="int") @VintfStability
 enum SecurityLevel {
   SOFTWARE = 0,
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/Timestamp.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/Timestamp.aidl
index 45fa1ae..5b7b37a 100644
--- a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/Timestamp.aidl
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/Timestamp.aidl
@@ -1,14 +1,30 @@
+/*
+ * Copyright 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 interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// 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 changes to the AIDL files built
+// 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
@@ -16,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.keymaster;
+/* @hide */
 @VintfStability
 parcelable Timestamp {
   long milliSeconds;
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl
index b116dac..10fa5e1 100644
--- a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl
@@ -1,14 +1,30 @@
+/*
+ * 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 interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// 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 changes to the AIDL files built
+// 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
@@ -16,6 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.keymaster;
+/* @hide */
 @VintfStability
 parcelable VerificationToken {
   long challenge;
diff --git a/keymaster/aidl/android/hardware/keymaster/HardwareAuthToken.aidl b/keymaster/aidl/android/hardware/keymaster/HardwareAuthToken.aidl
index 99b036a..427c192 100644
--- a/keymaster/aidl/android/hardware/keymaster/HardwareAuthToken.aidl
+++ b/keymaster/aidl/android/hardware/keymaster/HardwareAuthToken.aidl
@@ -16,8 +16,8 @@
 
 package android.hardware.keymaster;
 
-import android.hardware.keymaster.Timestamp;
 import android.hardware.keymaster.HardwareAuthenticatorType;
+import android.hardware.keymaster.Timestamp;
 
 /**
  * HardwareAuthToken is used to prove successful user authentication, to unlock the use of a key.
@@ -27,10 +27,10 @@
  * begin(), update(), and finish() to prove that authentication occurred.  See those methods for
  * more details.  It is up to the caller to determine which of the generated auth tokens is
  * appropriate for a given key operation.
+ * @hide
  */
 @VintfStability
 parcelable HardwareAuthToken {
-
     /**
      * challenge is a value that's used to enable authentication tokens to authorize specific
      * events.  The primary use case for challenge is to authorize an IKeymasterDevice cryptographic
@@ -49,7 +49,7 @@
      *  but is created in an authentication application in the secure environment, such as the
      *  Fingerprint application.
      */
-    long authenticatorId;  // Secure authenticator ID.
+    long authenticatorId; // Secure authenticator ID.
 
     /**
      * authenticatorType describes the type of authentication that took place, e.g. password or
diff --git a/keymaster/aidl/android/hardware/keymaster/HardwareAuthenticatorType.aidl b/keymaster/aidl/android/hardware/keymaster/HardwareAuthenticatorType.aidl
index 3141858..7a303a7 100644
--- a/keymaster/aidl/android/hardware/keymaster/HardwareAuthenticatorType.aidl
+++ b/keymaster/aidl/android/hardware/keymaster/HardwareAuthenticatorType.aidl
@@ -20,6 +20,7 @@
  * Hardware authentication type, used by HardwareAuthTokens to specify the mechanism used to
  * authentiate the user, and in KeyCharacteristics to specify the allowable mechanisms for
  * authenticating to activate a key.
+ * @hide
  */
 @VintfStability
 @Backing(type="int")
diff --git a/keymaster/aidl/android/hardware/keymaster/SecurityLevel.aidl b/keymaster/aidl/android/hardware/keymaster/SecurityLevel.aidl
index 00578a4..0b84392 100644
--- a/keymaster/aidl/android/hardware/keymaster/SecurityLevel.aidl
+++ b/keymaster/aidl/android/hardware/keymaster/SecurityLevel.aidl
@@ -18,6 +18,7 @@
 
 /**
  * Device security levels.
+ * @hide
  */
 @VintfStability
 @Backing(type="int")
diff --git a/keymaster/aidl/android/hardware/keymaster/Timestamp.aidl b/keymaster/aidl/android/hardware/keymaster/Timestamp.aidl
index 19ea944..0b0c36f 100644
--- a/keymaster/aidl/android/hardware/keymaster/Timestamp.aidl
+++ b/keymaster/aidl/android/hardware/keymaster/Timestamp.aidl
@@ -16,14 +16,13 @@
 
 package android.hardware.keymaster;
 
-
 /**
  * Time in milliseconds since some arbitrary point in time.  Time must be monotonically increasing,
  * and a secure environment's notion of "current time" must not repeat until the Android device
  * reboots, or until at least 50 million years have elapsed (note that this requirement is satisfied
  * by setting the clock to zero during each boot, and then counting time accurately).
+ * @hide
  */
-
 @VintfStability
 parcelable Timestamp {
     long milliSeconds;
diff --git a/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl b/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl
index 5efd937..ceee941 100644
--- a/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl
+++ b/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl
@@ -24,6 +24,7 @@
  *
  * This version of the parcelable currently don't use the parametersVerified field since it's not
  * needed for time-based verification. This can be added in a later version, if needed.
+ * @hide
  */
 @VintfStability
 parcelable VerificationToken {
@@ -39,7 +40,6 @@
      */
     Timestamp timestamp;
 
-
     /**
      * SecurityLevel of the secure environment that generated the token.
      */
diff --git a/light/aidl/Android.bp b/light/aidl/Android.bp
index 6f478d7..c11934f 100644
--- a/light/aidl/Android.bp
+++ b/light/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
diff --git a/light/aidl/aidl_api/android.hardware.light/2/.hash b/light/aidl/aidl_api/android.hardware.light/2/.hash
index d27f4ad..2d4e7f0 100644
--- a/light/aidl/aidl_api/android.hardware.light/2/.hash
+++ b/light/aidl/aidl_api/android.hardware.light/2/.hash
@@ -1 +1,2 @@
 c8b1e8ebb88c57dcb2c350a8d9b722e77dd864c8
+c7d3d941d303c70d1c22759a0b09e41930c1cddb
diff --git a/light/aidl/aidl_api/android.hardware.light/2/android/hardware/light/HwLight.aidl b/light/aidl/aidl_api/android.hardware.light/2/android/hardware/light/HwLight.aidl
index 25a2dce..5ac2a34 100644
--- a/light/aidl/aidl_api/android.hardware.light/2/android/hardware/light/HwLight.aidl
+++ b/light/aidl/aidl_api/android.hardware.light/2/android/hardware/light/HwLight.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.light;
-@VintfStability
+@RustDerive(Clone=true, Copy=true) @VintfStability
 parcelable HwLight {
   int id;
   int ordinal;
diff --git a/light/aidl/aidl_api/android.hardware.light/2/android/hardware/light/HwLightState.aidl b/light/aidl/aidl_api/android.hardware.light/2/android/hardware/light/HwLightState.aidl
index 40e520b..2878ce2 100644
--- a/light/aidl/aidl_api/android.hardware.light/2/android/hardware/light/HwLightState.aidl
+++ b/light/aidl/aidl_api/android.hardware.light/2/android/hardware/light/HwLightState.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.light;
-@VintfStability
+@RustDerive(Clone=true, Copy=true) @VintfStability
 parcelable HwLightState {
   int color;
   android.hardware.light.FlashMode flashMode;
diff --git a/light/aidl/aidl_api/android.hardware.light/current/android/hardware/light/HwLight.aidl b/light/aidl/aidl_api/android.hardware.light/current/android/hardware/light/HwLight.aidl
index 25a2dce..5ac2a34 100644
--- a/light/aidl/aidl_api/android.hardware.light/current/android/hardware/light/HwLight.aidl
+++ b/light/aidl/aidl_api/android.hardware.light/current/android/hardware/light/HwLight.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.light;
-@VintfStability
+@RustDerive(Clone=true, Copy=true) @VintfStability
 parcelable HwLight {
   int id;
   int ordinal;
diff --git a/light/aidl/aidl_api/android.hardware.light/current/android/hardware/light/HwLightState.aidl b/light/aidl/aidl_api/android.hardware.light/current/android/hardware/light/HwLightState.aidl
index 40e520b..2878ce2 100644
--- a/light/aidl/aidl_api/android.hardware.light/current/android/hardware/light/HwLightState.aidl
+++ b/light/aidl/aidl_api/android.hardware.light/current/android/hardware/light/HwLightState.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.light;
-@VintfStability
+@RustDerive(Clone=true, Copy=true) @VintfStability
 parcelable HwLightState {
   int color;
   android.hardware.light.FlashMode flashMode;
diff --git a/light/aidl/android/hardware/light/HwLight.aidl b/light/aidl/android/hardware/light/HwLight.aidl
index 43fdb4b..8db32cc 100644
--- a/light/aidl/android/hardware/light/HwLight.aidl
+++ b/light/aidl/android/hardware/light/HwLight.aidl
@@ -22,7 +22,7 @@
  * A description of a single light. Multiple lights can map to the same physical
  * LED. Separate physical LEDs are always represented by separate instances.
  */
-@VintfStability
+@RustDerive(Clone=true, Copy=true) @VintfStability
 parcelable HwLight {
     /**
      * Integer ID used for controlling this light
diff --git a/light/aidl/android/hardware/light/HwLightState.aidl b/light/aidl/android/hardware/light/HwLightState.aidl
index 24d3250..3ba6c78 100644
--- a/light/aidl/android/hardware/light/HwLightState.aidl
+++ b/light/aidl/android/hardware/light/HwLightState.aidl
@@ -25,7 +25,7 @@
  * Not all lights must support all parameters. If you
  * can do something backward-compatible, do it.
  */
-@VintfStability
+@RustDerive(Clone=true, Copy=true) @VintfStability
 parcelable HwLightState {
     /**
      * The color of the LED in ARGB.
diff --git a/light/aidl/default/Lights.cpp b/light/aidl/default/Lights.cpp
index 74747d5..9bf3b20 100644
--- a/light/aidl/default/Lights.cpp
+++ b/light/aidl/default/Lights.cpp
@@ -23,12 +23,21 @@
 namespace hardware {
 namespace light {
 
+static constexpr int kNumDefaultLights = 3;
+
 ndk::ScopedAStatus Lights::setLightState(int id, const HwLightState& state) {
     LOG(INFO) << "Lights setting state for id=" << id << " to color " << std::hex << state.color;
-    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    if (id <= 0 || id > kNumDefaultLights) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    } else {
+        return ndk::ScopedAStatus::ok();
+    }
 }
 
-ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* /*lights*/) {
+ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* lights) {
+    for (int i = 1; i <= kNumDefaultLights; i++) {
+        lights->push_back({i, i});
+    }
     LOG(INFO) << "Lights reporting supported lights";
     return ndk::ScopedAStatus::ok();
 }
diff --git a/light/aidl/default/Lights.h b/light/aidl/default/Lights.h
index 8cba5a1..cba147f 100644
--- a/light/aidl/default/Lights.h
+++ b/light/aidl/default/Lights.h
@@ -23,10 +23,10 @@
 namespace hardware {
 namespace light {
 
-// Default implementation that reports no supported lights.
+// Default implementation that reports a few placeholder lights.
 class Lights : public BnLights {
     ndk::ScopedAStatus setLightState(int id, const HwLightState& state) override;
-    ndk::ScopedAStatus getLights(std::vector<HwLight>* types) override;
+    ndk::ScopedAStatus getLights(std::vector<HwLight>* lights) override;
 };
 
 }  // namespace light
diff --git a/media/OWNERS b/media/OWNERS
new file mode 100644
index 0000000..71a53ef
--- /dev/null
+++ b/media/OWNERS
@@ -0,0 +1,7 @@
+# Bug component: 25690
+
+# Media team
+jgus@google.com
+lajos@google.com
+taklee@google.com
+wonsik@google.com
diff --git a/media/bufferpool/aidl/Android.bp b/media/bufferpool/aidl/Android.bp
new file mode 100644
index 0000000..8caf525
--- /dev/null
+++ b/media/bufferpool/aidl/Android.bp
@@ -0,0 +1,61 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.media.bufferpool2",
+    vendor_available: true,
+    double_loadable: true,
+    srcs: ["android/hardware/media/bufferpool2/*.aidl"],
+    imports: [
+        "android.hardware.common-V2",
+        "android.hardware.common.fmq-V1",
+    ],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            enabled: false,
+        },
+        ndk: {
+            enabled: true,
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.media.swcodec",
+            ],
+            min_sdk_version: "29",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.common.fmq-V1",
+            ],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/.hash b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/.hash
new file mode 100644
index 0000000..f591377
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/.hash
@@ -0,0 +1 @@
+b44598709e65cdb5184a8956aac5495b5dec6c0a
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/Buffer.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/Buffer.aidl
new file mode 100644
index 0000000..4ea0bba
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/Buffer.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+parcelable Buffer {
+  int id;
+  android.hardware.common.NativeHandle buffer;
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/BufferInvalidationMessage.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/BufferInvalidationMessage.aidl
new file mode 100644
index 0000000..181286c
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/BufferInvalidationMessage.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@FixedSize @VintfStability
+parcelable BufferInvalidationMessage {
+  int messageId;
+  int fromBufferId;
+  int toBufferId;
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/BufferStatus.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/BufferStatus.aidl
new file mode 100644
index 0000000..13174ff
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/BufferStatus.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@Backing(type="int") @VintfStability
+enum BufferStatus {
+  NOT_USED = 0,
+  USED = 1,
+  TRANSFER_TO = 2,
+  TRANSFER_FROM = 3,
+  TRANSFER_TIMEOUT = 4,
+  TRANSFER_LOST = 5,
+  TRANSFER_FETCH = 6,
+  TRANSFER_OK = 7,
+  TRANSFER_ERROR = 8,
+  INVALIDATION_ACK = 9,
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/BufferStatusMessage.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/BufferStatusMessage.aidl
new file mode 100644
index 0000000..7e79a36
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/BufferStatusMessage.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@FixedSize @VintfStability
+parcelable BufferStatusMessage {
+  long transactionId;
+  int bufferId;
+  android.hardware.media.bufferpool2.BufferStatus status;
+  long connectionId;
+  long targetConnectionId;
+  long timestampUs;
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IAccessor.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IAccessor.aidl
new file mode 100644
index 0000000..4053797
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IAccessor.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+interface IAccessor {
+  android.hardware.media.bufferpool2.IAccessor.ConnectionInfo connect(in android.hardware.media.bufferpool2.IObserver observer);
+  @VintfStability
+  parcelable ConnectionInfo {
+    android.hardware.media.bufferpool2.IConnection connection;
+    long connectionId;
+    int msgId;
+    android.hardware.common.fmq.MQDescriptor<android.hardware.media.bufferpool2.BufferStatusMessage,android.hardware.common.fmq.SynchronizedReadWrite> toFmqDesc;
+    android.hardware.common.fmq.MQDescriptor<android.hardware.media.bufferpool2.BufferInvalidationMessage,android.hardware.common.fmq.UnsynchronizedWrite> fromFmqDesc;
+  }
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IClientManager.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IClientManager.aidl
new file mode 100644
index 0000000..5899a40
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IClientManager.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+interface IClientManager {
+  android.hardware.media.bufferpool2.IClientManager.Registration registerSender(in android.hardware.media.bufferpool2.IAccessor bufferPool);
+  @VintfStability
+  parcelable Registration {
+    long connectionId;
+    boolean isNew = true;
+  }
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IConnection.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IConnection.aidl
new file mode 100644
index 0000000..844e920
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IConnection.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+interface IConnection {
+  android.hardware.media.bufferpool2.IConnection.FetchResult[] fetch(in android.hardware.media.bufferpool2.IConnection.FetchInfo[] fetchInfos);
+  void sync();
+  parcelable FetchInfo {
+    long transactionId;
+    int bufferId;
+  }
+  union FetchResult {
+    android.hardware.media.bufferpool2.Buffer buffer;
+    int failure;
+  }
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IObserver.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IObserver.aidl
new file mode 100644
index 0000000..2d8cffe
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/IObserver.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+interface IObserver {
+  oneway void onMessage(in long connectionId, in int msgId);
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/ResultStatus.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/ResultStatus.aidl
new file mode 100644
index 0000000..4bc3889
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/1/android/hardware/media/bufferpool2/ResultStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+parcelable ResultStatus {
+  const int OK = 0;
+  const int NO_MEMORY = 1;
+  const int ALREADY_EXISTS = 2;
+  const int NOT_FOUND = 3;
+  const int CRITICAL_ERROR = 4;
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl
new file mode 100644
index 0000000..4ea0bba
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/Buffer.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+parcelable Buffer {
+  int id;
+  android.hardware.common.NativeHandle buffer;
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/BufferInvalidationMessage.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/BufferInvalidationMessage.aidl
new file mode 100644
index 0000000..181286c
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/BufferInvalidationMessage.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@FixedSize @VintfStability
+parcelable BufferInvalidationMessage {
+  int messageId;
+  int fromBufferId;
+  int toBufferId;
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/BufferStatus.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/BufferStatus.aidl
new file mode 100644
index 0000000..13174ff
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/BufferStatus.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@Backing(type="int") @VintfStability
+enum BufferStatus {
+  NOT_USED = 0,
+  USED = 1,
+  TRANSFER_TO = 2,
+  TRANSFER_FROM = 3,
+  TRANSFER_TIMEOUT = 4,
+  TRANSFER_LOST = 5,
+  TRANSFER_FETCH = 6,
+  TRANSFER_OK = 7,
+  TRANSFER_ERROR = 8,
+  INVALIDATION_ACK = 9,
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/BufferStatusMessage.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/BufferStatusMessage.aidl
new file mode 100644
index 0000000..7e79a36
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/BufferStatusMessage.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@FixedSize @VintfStability
+parcelable BufferStatusMessage {
+  long transactionId;
+  int bufferId;
+  android.hardware.media.bufferpool2.BufferStatus status;
+  long connectionId;
+  long targetConnectionId;
+  long timestampUs;
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IAccessor.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IAccessor.aidl
new file mode 100644
index 0000000..4053797
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IAccessor.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+interface IAccessor {
+  android.hardware.media.bufferpool2.IAccessor.ConnectionInfo connect(in android.hardware.media.bufferpool2.IObserver observer);
+  @VintfStability
+  parcelable ConnectionInfo {
+    android.hardware.media.bufferpool2.IConnection connection;
+    long connectionId;
+    int msgId;
+    android.hardware.common.fmq.MQDescriptor<android.hardware.media.bufferpool2.BufferStatusMessage,android.hardware.common.fmq.SynchronizedReadWrite> toFmqDesc;
+    android.hardware.common.fmq.MQDescriptor<android.hardware.media.bufferpool2.BufferInvalidationMessage,android.hardware.common.fmq.UnsynchronizedWrite> fromFmqDesc;
+  }
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
new file mode 100644
index 0000000..5899a40
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+interface IClientManager {
+  android.hardware.media.bufferpool2.IClientManager.Registration registerSender(in android.hardware.media.bufferpool2.IAccessor bufferPool);
+  @VintfStability
+  parcelable Registration {
+    long connectionId;
+    boolean isNew = true;
+  }
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IConnection.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IConnection.aidl
new file mode 100644
index 0000000..844e920
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IConnection.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+interface IConnection {
+  android.hardware.media.bufferpool2.IConnection.FetchResult[] fetch(in android.hardware.media.bufferpool2.IConnection.FetchInfo[] fetchInfos);
+  void sync();
+  parcelable FetchInfo {
+    long transactionId;
+    int bufferId;
+  }
+  union FetchResult {
+    android.hardware.media.bufferpool2.Buffer buffer;
+    int failure;
+  }
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IObserver.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IObserver.aidl
new file mode 100644
index 0000000..2d8cffe
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IObserver.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+interface IObserver {
+  oneway void onMessage(in long connectionId, in int msgId);
+}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/ResultStatus.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/ResultStatus.aidl
new file mode 100644
index 0000000..4bc3889
--- /dev/null
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/ResultStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.media.bufferpool2;
+@VintfStability
+parcelable ResultStatus {
+  const int OK = 0;
+  const int NO_MEMORY = 1;
+  const int ALREADY_EXISTS = 2;
+  const int NOT_FOUND = 3;
+  const int CRITICAL_ERROR = 4;
+}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl
new file mode 100644
index 0000000..976f674
--- /dev/null
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/Buffer.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.bufferpool2;
+
+import android.hardware.common.NativeHandle;
+
+/**
+ * Generic buffer for fast recycling for media/stagefright.
+ *
+ * During media pipeline buffer references are created, shared and
+ * destroyed frequently. The underlying buffers are allocated on demand
+ * by a buffer pool, and are recycled to the buffer pool when they are
+ * no longer referenced by the clients.
+ *
+ * E.g. ion or gralloc buffer
+ */
+@VintfStability
+parcelable Buffer {
+    int id;
+    NativeHandle buffer;
+}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/BufferInvalidationMessage.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/BufferInvalidationMessage.aidl
new file mode 100644
index 0000000..ad03cd5
--- /dev/null
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/BufferInvalidationMessage.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.bufferpool2;
+
+/*
+ * Buffer pool sends a buffer invalidation message to clients in order to
+ * ensure fast reclamation of the buffers. Buffer pool implementation on
+ * clients must release the invalidated buffers right away after finishing
+ * the use of buffers upon receiving a buffer invalidation message.
+ * Users cannot delay or control timing of the handling/reception of
+ * invalidation messages. Buffer pool implementation must guarantee timely
+ * handling of invalidation messages.
+ */
+@VintfStability
+@FixedSize
+parcelable BufferInvalidationMessage {
+    int messageId;
+    /**
+     * Buffers from fromBufferId to toBufferId must be invalidated.
+     * fromBufferId is inclusive, but toBufferId is not inclusive.
+     * If fromBufferId > toBufferID, wrap happens. In that case
+     * the wrap is based on UINT32_MAX.
+     */
+    int fromBufferId;
+    int toBufferId;
+}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/BufferStatus.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/BufferStatus.aidl
new file mode 100644
index 0000000..b63aee2
--- /dev/null
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/BufferStatus.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.bufferpool2;
+
+/**
+ * Buffer ownership status for the specified client.
+ * Buffer transfer status for the specified buffer transafer transaction.
+ * BufferStatus is posted along with BufferStatusMessage from a client to
+ * the buffer pool for synchronization after status change.
+ */
+@VintfStability
+@Backing(type="int")
+enum BufferStatus {
+    /**
+     * No longer used by the specified client.
+     */
+    NOT_USED = 0,
+    /**
+     * Buffer is acquired by the specified client.
+     */
+    USED = 1,
+    /**
+     * Buffer is sent by the specified client.
+     */
+    TRANSFER_TO = 2,
+    /**
+     * Buffer transfer is acked by the receiver client.
+     */
+    TRANSFER_FROM = 3,
+    /**
+     * Buffer transfer is timed out by receiver client.
+     */
+    TRANSFER_TIMEOUT = 4,
+    /**
+     * Buffer transfer is not acked by the receiver.
+     */
+    TRANSFER_LOST = 5,
+    /**
+     * Buffer fetch request from the client.
+     */
+    TRANSFER_FETCH = 6,
+    /**
+     * Buffer transaction succeeded.
+     */
+    TRANSFER_OK = 7,
+    /**
+     * Buffer transaction failure.
+     */
+    TRANSFER_ERROR = 8,
+    /**
+     * Buffer invalidation ack.
+     */
+    INVALIDATION_ACK = 9,
+}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/BufferStatusMessage.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/BufferStatusMessage.aidl
new file mode 100644
index 0000000..e3fd8f0
--- /dev/null
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/BufferStatusMessage.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.bufferpool2;
+
+import android.hardware.media.bufferpool2.BufferStatus;
+
+/**
+ * Buffer ownership status change message. This message is
+ * sent via fmq to the buffer pool from client processes.
+ */
+@VintfStability
+@FixedSize
+parcelable BufferStatusMessage {
+    /**
+     * Transaction Id = (SenderId : sender local transaction Id)
+     * Transaction Id is created from sender and posted via fmq within
+     * TRANSFER_TO message.
+     */
+    long transactionId;
+    int bufferId;
+    BufferStatus status;
+    /**
+     * Used by the buffer pool, not by client.
+     */
+    long connectionId;
+    /**
+     * Valid only when TRANSFER_TO is posted.
+     */
+    long targetConnectionId;
+    /**
+     * Used by the buffer pool, not by client.
+     * Monotonic timestamp in Us since fixed point in time as decided
+     * by the sender of the message
+     */
+    long timestampUs;
+}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IAccessor.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IAccessor.aidl
new file mode 100644
index 0000000..0fa5961
--- /dev/null
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IAccessor.aidl
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.bufferpool2;
+
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.hardware.common.fmq.UnsynchronizedWrite;
+
+
+import android.hardware.media.bufferpool2.BufferInvalidationMessage;
+import android.hardware.media.bufferpool2.BufferStatusMessage;
+import android.hardware.media.bufferpool2.IConnection;
+import android.hardware.media.bufferpool2.IObserver;
+
+/**
+ * IAccessor creates IConnection which is used from IClientManager in order to
+ * use functionality of the specified buffer pool.
+ */
+@VintfStability
+interface IAccessor {
+    @VintfStability
+     /**
+     * Connection information between the bufferpool process and the receiver
+     * process. The information is used from the receiver process in order to
+     * receive buffers from the bufferpool process.
+     */
+    parcelable ConnectionInfo {
+        /**
+        * The interface to get shared buffers from the bufferpool.
+        */
+        IConnection connection;
+        /**
+         * The identifier for a (sender/receiver) pair during buffer transfer.
+         * This is system wide unique.
+         */
+        long connectionId;
+        /**
+         * Id of the most recent message from bufferpool. This is monotonic.
+         */
+        int msgId;
+        /**
+         * The FMQ descriptor for sending buffer status messages back to bufferpool
+         */
+        MQDescriptor<BufferStatusMessage, SynchronizedReadWrite> toFmqDesc;
+        /**
+         * The FMQ descriptor for receiving buffer invalidation messages from bufferpool
+         */
+        MQDescriptor<BufferInvalidationMessage, UnsynchronizedWrite> fromFmqDesc;
+    }
+
+    /**
+     * Registers a new client and creates IConnection to the buffer pool for
+     * the client. IConnection and FMQ are used by IClientManager in order to
+     * communicate with the buffer pool. Via FMQ IClientManager sends
+     * BufferStatusMessage(s) to the buffer pool.
+     *
+     * FMQ is used to send buffer ownership status changes to a buffer pool
+     * from a buffer pool client. A buffer pool synchronizes FMQ messages when
+     * there is an aidl request from the clients. Every client has its own
+     * connection and FMQ to communicate with the buffer pool. So sending an
+     * FMQ message on behalf of other clients is not possible.
+     *
+     * FMQ messages are sent when a buffer is acquired or released. Also, FMQ
+     * messages are sent when a buffer is transferred from a client to another
+     * client. FMQ has its own ID from a buffer pool. A client is specified
+     * with the ID.
+     *
+     * To transfer a buffer, a sender must send an FMQ message. The message
+     * must include a receiver's ID and a transaction ID. A receiver must send
+     * the transaction ID to fetch a buffer from a buffer pool. Since the
+     * sender already registered the receiver via an FMQ message, The buffer
+     * pool must verify the receiver with the transaction ID. In order to
+     * prevent faking a receiver, a connection to a buffer pool from client is
+     * made and kept private. Also part of transaction ID is a sender ID in
+     * order to prevent fake transactions from other clients. This must be
+     * verified with an FMQ message from a buffer pool.
+     *
+     * @param observer The buffer pool event observer from the client.
+     *     Observer is provided to ensure FMQ messages are processed even when
+     *     client processes are idle. Buffer invalidation caused by
+     *     reconfiguration does not call observer. Buffer invalidation caused
+     *     by termination of pipeline call observer in order to ensure
+     *     invalidation is done after pipeline completion.
+     * @return ConnectionInfo The information regarding the established
+     *     connection
+     * @@throws ServiceSpecificException with one of the following values:
+     *     ResultStatus::NO_MEMORY        - Memory allocation failure occurred.
+     *     ResultStatus::ALREADY_EXISTS   - A connection was already made.
+     *     ResultStatus::CRITICAL_ERROR   - Other errors.
+     */
+    ConnectionInfo connect(in IObserver observer);
+}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
new file mode 100644
index 0000000..a3054cb
--- /dev/null
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.bufferpool2;
+
+import android.hardware.media.bufferpool2.IAccessor;
+
+/**
+ * IClientManager manages IConnection(s) inside a process. A locally
+ * created IConnection represents a communication node(receiver) with the
+ * specified buffer pool(IAccessor).
+ * IConnection(s) are not exposed to other processes(IClientManager).
+ * IClientManager instance must be unique within a process.
+ */
+@VintfStability
+interface IClientManager {
+    /**
+     * Result of registerSender.
+     */
+    @VintfStability
+    parcelable Registration {
+        /** registered connection id    */
+        long connectionId;
+        /** true when the connection is new */
+        boolean isNew = true;
+    }
+    /**
+     * Sets up a buffer receiving communication node for the specified
+     * buffer pool. A manager must create a IConnection to the buffer
+     * pool if it does not already have a connection.
+     *
+     * @param bufferPool a buffer pool which is specified with the IAccessor.
+     *     The specified buffer pool is the owner of received buffers.
+     * @return the Id of the communication node to the buffer pool.
+     *     This id is used in FMQ to notify IAccessor that a buffer has been
+     *     sent to that connection during transfers.
+     * @throws ServiceSpecificException with one of the following values:
+     *     ResultStatus::NO_MEMORY        - Memory allocation failure occurred.
+     *     ResultStatus::CRITICAL_ERROR   - Other errors.
+     */
+    Registration registerSender(in IAccessor bufferPool);
+}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IConnection.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IConnection.aidl
new file mode 100644
index 0000000..68367c7
--- /dev/null
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IConnection.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.bufferpool2;
+
+import android.hardware.media.bufferpool2.Buffer;
+import android.hardware.media.bufferpool2.ResultStatus;
+
+/**
+ * A connection to a buffer pool which handles requests from a buffer pool
+ * client. The connection must be made in order to receive buffers from
+ * other buffer pool clients.
+ */
+@VintfStability
+interface IConnection {
+
+    parcelable FetchInfo {
+        /**
+         * Unique transaction id for buffer transferring.
+         */
+        long transactionId;
+        /**
+         * Id of the buffer to be fetched.
+         */
+        int bufferId;
+    }
+
+    union FetchResult {
+        /**
+         * The fetched buffer on successful fetch.
+         */
+        Buffer buffer;
+        /**
+         * The reason of the request failure. Possible values are below.
+         *
+         * ResultStatus::NOT_FOUND        - A buffer was not found due to invalidation.
+         * ResultStatus::CRITICAL_ERROR   - Other errors.
+         */
+        int failure;
+    }
+
+    /**
+     * Retrieves buffers using an array of FetchInfo.
+     * Each element of FetchInfo array contains a bufferId and a transactionId
+     * for each buffer to fetch. The method must be called from receiving side of buffers
+     * during transferring only when the specified buffer is neither cached nor used.
+     *
+     * The method could have partial failures, in the case other successfully fetched buffers
+     * will be in returned result along with the failures. The order of the returned result
+     * will be the same with the fetchInfos.
+     *
+     * @param fetchInfos information of buffers to fetch
+     * @return Requested buffers.
+     *         If there are failures, reasons of failures are also included.
+     * @throws ServiceSpecificException with one of the following values:
+     *     ResultStatus::NO_MEMORY        - Memory allocation failure occurred.
+     *     ResultStatus::CRITICAL_ERROR   - Other errors.
+     */
+    FetchResult[] fetch(in FetchInfo[] fetchInfos);
+
+    /**
+     * Enforce processing of unprocessed bufferpool messages.
+     *
+     * BufferPool implementation optimizes message processing by piggy-backing approach.
+     * This method can ensure pending bufferpool messages being processed timely.
+     */
+    void sync();
+}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IObserver.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IObserver.aidl
new file mode 100644
index 0000000..07d1c3e
--- /dev/null
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IObserver.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.bufferpool2;
+
+/**
+ * IObserver listens on notifications from the buffer pool. On receiving
+ * notifications, FMQ messages from the specific buffer pool which are already
+ * in the FMQ are processed.
+ */
+@VintfStability
+interface IObserver {
+    /**
+     * The specific buffer pool sent a message to the client. Calling this
+     * method from the buffer pool enforces a buffer pool client process the
+     * message.
+     *
+     * @param connectionId the connection Id of the specific buffer pool client
+     * @param msgId Id of the most recent message
+     */
+    oneway void onMessage(in long connectionId, in int msgId);
+}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/ResultStatus.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/ResultStatus.aidl
new file mode 100644
index 0000000..003d147
--- /dev/null
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/ResultStatus.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.bufferpool2;
+
+@VintfStability
+parcelable ResultStatus {
+    const int OK = 0;
+    const int NO_MEMORY = 1;
+    const int ALREADY_EXISTS = 2;
+    const int NOT_FOUND = 3;
+    const int CRITICAL_ERROR = 4;
+}
diff --git a/media/bufferpool/aidl/default/Accessor.cpp b/media/bufferpool/aidl/default/Accessor.cpp
new file mode 100644
index 0000000..3d206ac
--- /dev/null
+++ b/media/bufferpool/aidl/default/Accessor.cpp
@@ -0,0 +1,509 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "AidlBufferPoolAcc"
+//#define LOG_NDEBUG 0
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <thread>
+
+#include "Accessor.h"
+#include "Connection.h"
+#include "DataHelper.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+namespace {
+    static constexpr nsecs_t kEvictGranularityNs = 1000000000; // 1 sec
+    static constexpr nsecs_t kEvictDurationNs = 5000000000; // 5 secs
+}
+
+#ifdef __ANDROID_VNDK__
+static constexpr uint32_t kSeqIdVndkBit = 1U << 31;
+#else
+static constexpr uint32_t kSeqIdVndkBit = 0;
+#endif
+
+static constexpr uint32_t kSeqIdMax = 0x7fffffff;
+uint32_t Accessor::sSeqId = time(nullptr) & kSeqIdMax;
+
+namespace {
+// anonymous namespace
+static std::shared_ptr<ConnectionDeathRecipient> sConnectionDeathRecipient =
+    std::make_shared<ConnectionDeathRecipient>();
+
+void serviceDied(void *cookie) {
+    if (sConnectionDeathRecipient) {
+        sConnectionDeathRecipient->onDead(cookie);
+    }
+}
+}
+
+std::shared_ptr<ConnectionDeathRecipient> Accessor::getConnectionDeathRecipient() {
+    return sConnectionDeathRecipient;
+}
+
+ConnectionDeathRecipient::ConnectionDeathRecipient() {
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(
+            AIBinder_DeathRecipient_new(serviceDied));
+}
+
+void ConnectionDeathRecipient::add(
+        int64_t connectionId,
+        const std::shared_ptr<Accessor> &accessor) {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (mAccessors.find(connectionId) == mAccessors.end()) {
+        mAccessors.insert(std::make_pair(connectionId, accessor));
+    }
+}
+
+void ConnectionDeathRecipient::remove(int64_t connectionId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    mAccessors.erase(connectionId);
+    auto it = mConnectionToCookie.find(connectionId);
+    if (it != mConnectionToCookie.end()) {
+        void * cookie = it->second;
+        mConnectionToCookie.erase(it);
+        auto cit = mCookieToConnections.find(cookie);
+        if (cit != mCookieToConnections.end()) {
+            cit->second.erase(connectionId);
+            if (cit->second.size() == 0) {
+                mCookieToConnections.erase(cit);
+            }
+        }
+    }
+}
+
+void ConnectionDeathRecipient::addCookieToConnection(
+        void *cookie,
+        int64_t connectionId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    if (mAccessors.find(connectionId) == mAccessors.end()) {
+        return;
+    }
+    mConnectionToCookie.insert(std::make_pair(connectionId, cookie));
+    auto it = mCookieToConnections.find(cookie);
+    if (it != mCookieToConnections.end()) {
+        it->second.insert(connectionId);
+    } else {
+        mCookieToConnections.insert(std::make_pair(
+                cookie, std::set<int64_t>{connectionId}));
+    }
+}
+
+void ConnectionDeathRecipient::onDead(void *cookie) {
+    std::map<int64_t, const std::weak_ptr<Accessor>> connectionsToClose;
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+
+        auto it = mCookieToConnections.find(cookie);
+        if (it != mCookieToConnections.end()) {
+            for (auto conIt = it->second.begin(); conIt != it->second.end(); ++conIt) {
+                auto accessorIt = mAccessors.find(*conIt);
+                if (accessorIt != mAccessors.end()) {
+                    connectionsToClose.insert(std::make_pair(*conIt, accessorIt->second));
+                    mAccessors.erase(accessorIt);
+                }
+                mConnectionToCookie.erase(*conIt);
+            }
+            mCookieToConnections.erase(it);
+        }
+    }
+
+    if (connectionsToClose.size() > 0) {
+        std::shared_ptr<Accessor> accessor;
+        for (auto it = connectionsToClose.begin(); it != connectionsToClose.end(); ++it) {
+            accessor = it->second.lock();
+
+            if (accessor) {
+                accessor->close(it->first);
+                ALOGD("connection %lld closed on death", (long long)it->first);
+            }
+        }
+    }
+}
+
+AIBinder_DeathRecipient *ConnectionDeathRecipient::getRecipient() {
+    return mDeathRecipient.get();
+}
+
+::ndk::ScopedAStatus Accessor::connect(const std::shared_ptr<::aidl::android::hardware::media::bufferpool2::IObserver>& in_observer, ::aidl::android::hardware::media::bufferpool2::IAccessor::ConnectionInfo* _aidl_return) {
+    std::shared_ptr<Connection> connection;
+    ConnectionId connectionId;
+    uint32_t msgId;
+    StatusDescriptor statusDesc;
+    InvalidationDescriptor invDesc;
+    BufferPoolStatus status = connect(
+            in_observer, false, &connection, &connectionId, &msgId, &statusDesc, &invDesc);
+    if (status == ResultStatus::OK) {
+        _aidl_return->connection = connection;
+        _aidl_return->connectionId = connectionId;
+        _aidl_return->msgId = msgId;
+        _aidl_return->toFmqDesc = std::move(statusDesc);
+        _aidl_return->fromFmqDesc = std::move(invDesc);
+        return ::ndk::ScopedAStatus::ok();
+    }
+    return ::ndk::ScopedAStatus::fromServiceSpecificError(status);
+}
+
+Accessor::Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator)
+    : mAllocator(allocator), mScheduleEvictTs(0) {}
+
+Accessor::~Accessor() {
+}
+
+bool Accessor::isValid() {
+    return mBufferPool.isValid();
+}
+
+BufferPoolStatus Accessor::flush() {
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    mBufferPool.flush(ref<Accessor>());
+    return ResultStatus::OK;
+}
+
+BufferPoolStatus Accessor::allocate(
+        ConnectionId connectionId,
+        const std::vector<uint8_t> &params,
+        BufferId *bufferId, const native_handle_t** handle) {
+    std::unique_lock<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    BufferPoolStatus status = ResultStatus::OK;
+    if (!mBufferPool.getFreeBuffer(mAllocator, params, bufferId, handle)) {
+        lock.unlock();
+        std::shared_ptr<BufferPoolAllocation> alloc;
+        size_t allocSize;
+        status = mAllocator->allocate(params, &alloc, &allocSize);
+        lock.lock();
+        if (status == ResultStatus::OK) {
+            status = mBufferPool.addNewBuffer(alloc, allocSize, params, bufferId, handle);
+        }
+        ALOGV("create a buffer %d : %u %p",
+              status == ResultStatus::OK, *bufferId, *handle);
+    }
+    if (status == ResultStatus::OK) {
+        // TODO: handle ownBuffer failure
+        mBufferPool.handleOwnBuffer(connectionId, *bufferId);
+    }
+    mBufferPool.cleanUp();
+    scheduleEvictIfNeeded();
+    return status;
+}
+
+BufferPoolStatus Accessor::fetch(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, const native_handle_t** handle) {
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    auto found = mBufferPool.mTransactions.find(transactionId);
+    if (found != mBufferPool.mTransactions.end() &&
+            contains(&mBufferPool.mPendingTransactions,
+                     connectionId, transactionId)) {
+        if (found->second->mSenderValidated &&
+                found->second->mStatus == BufferStatus::TRANSFER_FROM &&
+                found->second->mBufferId == bufferId) {
+            found->second->mStatus = BufferStatus::TRANSFER_FETCH;
+            auto bufferIt = mBufferPool.mBuffers.find(bufferId);
+            if (bufferIt != mBufferPool.mBuffers.end()) {
+                mBufferPool.mStats.onBufferFetched();
+                *handle = bufferIt->second->handle();
+                return ResultStatus::OK;
+            }
+        }
+    }
+    mBufferPool.cleanUp();
+    scheduleEvictIfNeeded();
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus Accessor::connect(
+        const std::shared_ptr<IObserver> &observer, bool local,
+        std::shared_ptr<Connection> *connection, ConnectionId *pConnectionId,
+        uint32_t *pMsgId,
+        StatusDescriptor* statusDescPtr,
+        InvalidationDescriptor* invDescPtr) {
+    std::shared_ptr<Connection> newConnection = ::ndk::SharedRefBase::make<Connection>();
+    BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        if (newConnection) {
+            int32_t pid = getpid();
+            ConnectionId id = (int64_t)pid << 32 | sSeqId | kSeqIdVndkBit;
+            status = mBufferPool.mObserver.open(id, statusDescPtr);
+            if (status == ResultStatus::OK) {
+                newConnection->initialize(ref<Accessor>(), id);
+                *connection = newConnection;
+                *pConnectionId = id;
+                *pMsgId = mBufferPool.mInvalidation.mInvalidationId;
+                mBufferPool.mConnectionIds.insert(id);
+                mBufferPool.mInvalidationChannel.getDesc(invDescPtr);
+                mBufferPool.mInvalidation.onConnect(id, observer);
+                if (sSeqId == kSeqIdMax) {
+                   sSeqId = 0;
+                } else {
+                    ++sSeqId;
+                }
+            }
+
+        }
+        mBufferPool.processStatusMessages();
+        mBufferPool.cleanUp();
+        scheduleEvictIfNeeded();
+    }
+    if (!local && status == ResultStatus::OK) {
+        std::shared_ptr<Accessor> accessor(ref<Accessor>());
+        sConnectionDeathRecipient->add(*pConnectionId, accessor);
+    }
+    return status;
+}
+
+BufferPoolStatus Accessor::close(ConnectionId connectionId) {
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        ALOGV("connection close %lld: %u", (long long)connectionId, mBufferPool.mInvalidation.mId);
+        mBufferPool.processStatusMessages();
+        mBufferPool.handleClose(connectionId);
+        mBufferPool.mObserver.close(connectionId);
+        mBufferPool.mInvalidation.onClose(connectionId);
+        // Since close# will be called after all works are finished, it is OK to
+        // evict unused buffers.
+        mBufferPool.cleanUp(true);
+        scheduleEvictIfNeeded();
+    }
+    sConnectionDeathRecipient->remove(connectionId);
+    return ResultStatus::OK;
+}
+
+void Accessor::cleanUp(bool clearCache) {
+    // transaction timeout, buffer caching TTL handling
+    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+    mBufferPool.processStatusMessages();
+    mBufferPool.cleanUp(clearCache);
+}
+
+void Accessor::handleInvalidateAck() {
+    std::map<ConnectionId, const std::shared_ptr<IObserver>> observers;
+    uint32_t invalidationId;
+    {
+        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+        mBufferPool.processStatusMessages();
+        mBufferPool.mInvalidation.onHandleAck(&observers, &invalidationId);
+    }
+    // Do not hold lock for send invalidations
+    size_t deadClients = 0;
+    for (auto it = observers.begin(); it != observers.end(); ++it) {
+        const std::shared_ptr<IObserver> observer = it->second;
+        if (observer) {
+            ::ndk::ScopedAStatus status = observer->onMessage(it->first, invalidationId);
+            if (!status.isOk()) {
+                ++deadClients;
+            }
+        }
+    }
+    if (deadClients > 0) {
+        ALOGD("During invalidation found %zu dead clients", deadClients);
+    }
+}
+
+void Accessor::invalidatorThread(
+            std::map<uint32_t, const std::weak_ptr<Accessor>> &accessors,
+            std::mutex &mutex,
+            std::condition_variable &cv,
+            bool &ready) {
+    constexpr uint32_t NUM_SPIN_TO_INCREASE_SLEEP = 1024;
+    constexpr uint32_t NUM_SPIN_TO_LOG = 1024*8;
+    constexpr useconds_t MAX_SLEEP_US = 10000;
+    uint32_t numSpin = 0;
+    useconds_t sleepUs = 1;
+
+    while(true) {
+        std::map<uint32_t, const std::weak_ptr<Accessor>> copied;
+        {
+            std::unique_lock<std::mutex> lock(mutex);
+            while (!ready) {
+                numSpin = 0;
+                sleepUs = 1;
+                cv.wait(lock);
+            }
+            copied.insert(accessors.begin(), accessors.end());
+        }
+        std::list<ConnectionId> erased;
+        for (auto it = copied.begin(); it != copied.end(); ++it) {
+            const std::shared_ptr<Accessor> acc = it->second.lock();
+            if (!acc) {
+                erased.push_back(it->first);
+            } else {
+                acc->handleInvalidateAck();
+            }
+        }
+        {
+            std::unique_lock<std::mutex> lock(mutex);
+            for (auto it = erased.begin(); it != erased.end(); ++it) {
+                accessors.erase(*it);
+            }
+            if (accessors.size() == 0) {
+                ready = false;
+            } else {
+                // N.B. Since there is not a efficient way to wait over FMQ,
+                // polling over the FMQ is the current way to prevent draining
+                // CPU.
+                lock.unlock();
+                ++numSpin;
+                if (numSpin % NUM_SPIN_TO_INCREASE_SLEEP == 0 &&
+                    sleepUs < MAX_SLEEP_US) {
+                    sleepUs *= 10;
+                }
+                if (numSpin % NUM_SPIN_TO_LOG == 0) {
+                    ALOGW("invalidator thread spinning");
+                }
+                ::usleep(sleepUs);
+            }
+        }
+    }
+}
+
+Accessor::AccessorInvalidator::AccessorInvalidator() : mReady(false) {
+    std::thread invalidator(
+            invalidatorThread,
+            std::ref(mAccessors),
+            std::ref(mMutex),
+            std::ref(mCv),
+            std::ref(mReady));
+    invalidator.detach();
+}
+
+void Accessor::AccessorInvalidator::addAccessor(
+        uint32_t accessorId, const std::weak_ptr<Accessor> &accessor) {
+    bool notify = false;
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (mAccessors.find(accessorId) == mAccessors.end()) {
+        if (!mReady) {
+            mReady = true;
+            notify = true;
+        }
+        mAccessors.emplace(accessorId, accessor);
+        ALOGV("buffer invalidation added bp:%u %d", accessorId, notify);
+    }
+    lock.unlock();
+    if (notify) {
+        mCv.notify_one();
+    }
+}
+
+void Accessor::AccessorInvalidator::delAccessor(uint32_t accessorId) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    mAccessors.erase(accessorId);
+    ALOGV("buffer invalidation deleted bp:%u", accessorId);
+    if (mAccessors.size() == 0) {
+        mReady = false;
+    }
+}
+
+std::unique_ptr<Accessor::AccessorInvalidator> Accessor::sInvalidator;
+
+void Accessor::createInvalidator() {
+    if (!sInvalidator) {
+        sInvalidator = std::make_unique<Accessor::AccessorInvalidator>();
+    }
+}
+
+void Accessor::evictorThread(
+        std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
+        std::mutex &mutex,
+        std::condition_variable &cv) {
+    std::list<const std::weak_ptr<Accessor>> evictList;
+    while (true) {
+        int expired = 0;
+        int evicted = 0;
+        {
+            nsecs_t now = systemTime();
+            std::unique_lock<std::mutex> lock(mutex);
+            while (accessors.size() == 0) {
+                cv.wait(lock);
+            }
+            auto it = accessors.begin();
+            while (it != accessors.end()) {
+                if (now > (it->second + kEvictDurationNs)) {
+                    ++expired;
+                    evictList.push_back(it->first);
+                    it = accessors.erase(it);
+                } else {
+                    ++it;
+                }
+            }
+        }
+        // evict idle accessors;
+        for (auto it = evictList.begin(); it != evictList.end(); ++it) {
+            const std::shared_ptr<Accessor> accessor = it->lock();
+            if (accessor) {
+                accessor->cleanUp(true);
+                ++evicted;
+            }
+        }
+        if (expired > 0) {
+            ALOGD("evictor expired: %d, evicted: %d", expired, evicted);
+        }
+        evictList.clear();
+        ::usleep(kEvictGranularityNs / 1000);
+    }
+}
+
+Accessor::AccessorEvictor::AccessorEvictor() {
+    std::thread evictor(
+            evictorThread,
+            std::ref(mAccessors),
+            std::ref(mMutex),
+            std::ref(mCv));
+    evictor.detach();
+}
+
+void Accessor::AccessorEvictor::addAccessor(
+        const std::weak_ptr<Accessor> &accessor, nsecs_t ts) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    bool notify = mAccessors.empty();
+    auto it = mAccessors.find(accessor);
+    if (it == mAccessors.end()) {
+        mAccessors.emplace(accessor, ts);
+    } else {
+        it->second = ts;
+    }
+    if (notify) {
+        mCv.notify_one();
+    }
+}
+
+std::unique_ptr<Accessor::AccessorEvictor> Accessor::sEvictor;
+
+void Accessor::createEvictor() {
+    if (!sEvictor) {
+        sEvictor = std::make_unique<Accessor::AccessorEvictor>();
+    }
+}
+
+void Accessor::scheduleEvictIfNeeded() {
+    nsecs_t now = systemTime();
+
+    if (now > (mScheduleEvictTs + kEvictGranularityNs)) {
+        mScheduleEvictTs = now;
+        sEvictor->addAccessor(ref<Accessor>(), now);
+    }
+}
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implemntation {
diff --git a/media/bufferpool/aidl/default/Accessor.h b/media/bufferpool/aidl/default/Accessor.h
new file mode 100644
index 0000000..85e2fa7
--- /dev/null
+++ b/media/bufferpool/aidl/default/Accessor.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/media/bufferpool2/BnAccessor.h>
+#include <aidl/android/hardware/media/bufferpool2/IObserver.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+#include <memory>
+#include <map>
+#include <set>
+#include <condition_variable>
+
+#include "BufferPool.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+struct Connection;
+using ::aidl::android::hardware::media::bufferpool2::IObserver;
+using ::aidl::android::hardware::media::bufferpool2::IAccessor;
+
+/**
+ * Receives death notifications from remote connections.
+ * On death notifications, the connections are closed and used resources
+ * are released.
+ */
+struct ConnectionDeathRecipient {
+    ConnectionDeathRecipient();
+    /**
+     * Registers a newly connected connection from remote processes.
+     */
+    void add(int64_t connectionId, const std::shared_ptr<Accessor> &accessor);
+
+    /**
+     * Removes a connection.
+     */
+    void remove(int64_t connectionId);
+
+    void addCookieToConnection(void *cookie, int64_t connectionId);
+
+    void onDead(void *cookie);
+
+    AIBinder_DeathRecipient *getRecipient();
+
+private:
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+
+    std::mutex mLock;
+    std::map<void *, std::set<int64_t>>  mCookieToConnections;
+    std::map<int64_t, void *> mConnectionToCookie;
+    std::map<int64_t, const std::weak_ptr<Accessor>> mAccessors;
+};
+
+/**
+ * A buffer pool accessor which enables a buffer pool to communicate with buffer
+ * pool clients. 1:1 correspondense holds between a buffer pool and an accessor.
+ */
+struct Accessor : public BnAccessor {
+    // Methods from ::aidl::android::hardware::media::bufferpool2::IAccessor.
+    ::ndk::ScopedAStatus connect(const std::shared_ptr<IObserver>& in_observer,
+                                 IAccessor::ConnectionInfo* _aidl_return) override;
+
+    /**
+     * Creates a buffer pool accessor which uses the specified allocator.
+     *
+     * @param allocator buffer allocator.
+     */
+    explicit Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator);
+
+    /** Destructs a buffer pool accessor. */
+    ~Accessor();
+
+    /** Returns whether the accessor is valid. */
+    bool isValid();
+
+    /** Invalidates all buffers which are owned by bufferpool */
+    BufferPoolStatus flush();
+
+    /** Allocates a buffer from a buffer pool.
+     *
+     * @param connectionId  the connection id of the client.
+     * @param params        the allocation parameters.
+     * @param bufferId      the id of the allocated buffer.
+     * @param handle        the native handle of the allocated buffer.
+     *
+     * @return OK when a buffer is successfully allocated.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus allocate(
+            ConnectionId connectionId,
+            const std::vector<uint8_t>& params,
+            BufferId *bufferId,
+            const native_handle_t** handle);
+
+    /**
+     * Fetches a buffer for the specified transaction.
+     *
+     * @param connectionId  the id of receiving connection(client).
+     * @param transactionId the id of the transfer transaction.
+     * @param bufferId      the id of the buffer to be fetched.
+     * @param handle        the native handle of the fetched buffer.
+     *
+     * @return OK when a buffer is successfully fetched.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus fetch(
+            ConnectionId connectionId,
+            TransactionId transactionId,
+            BufferId bufferId,
+            const native_handle_t** handle);
+
+    /**
+     * Makes a connection to the buffer pool. The buffer pool client uses the
+     * created connection in order to communicate with the buffer pool. An
+     * FMQ for buffer status message is also created for the client.
+     *
+     * @param observer      client observer for buffer invalidation
+     * @param local         true when a connection request comes from local process,
+     *                      false otherwise.
+     * @param connection    created connection
+     * @param pConnectionId the id of the created connection
+     * @param pMsgId        the id of the recent buffer pool message
+     * @param statusDescPtr FMQ descriptor for shared buffer status message
+     *                      queue between a buffer pool and the client.
+     * @param invDescPtr    FMQ descriptor for buffer invalidation message
+     *                      queue from a buffer pool to the client.
+     *
+     * @return OK when a connection is successfully made.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus connect(
+            const std::shared_ptr<IObserver>& observer,
+            bool local,
+            std::shared_ptr<Connection> *connection, ConnectionId *pConnectionId,
+            uint32_t *pMsgId,
+            StatusDescriptor* statusDescPtr,
+            InvalidationDescriptor* invDescPtr);
+
+    /**
+     * Closes the specified connection to the client.
+     *
+     * @param connectionId  the id of the connection.
+     *
+     * @return OK when the connection is closed.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus close(ConnectionId connectionId);
+
+    /**
+     * Processes pending buffer status messages and performs periodic cache
+     * cleaning.
+     *
+     * @param clearCache    if clearCache is true, it frees all buffers waiting
+     *                      to be recycled.
+     */
+    void cleanUp(bool clearCache);
+
+    /**
+     * ACK on buffer invalidation messages
+     */
+    void handleInvalidateAck();
+
+    /**
+     * Gets a death_recipient for remote connection death.
+     */
+    static std::shared_ptr<ConnectionDeathRecipient> getConnectionDeathRecipient();
+
+    static void createInvalidator();
+
+    static void createEvictor();
+
+private:
+    // ConnectionId = pid : (timestamp_created + seqId)
+    // in order to guarantee uniqueness for each connection
+    static uint32_t sSeqId;
+
+    const std::shared_ptr<BufferPoolAllocator> mAllocator;
+    nsecs_t mScheduleEvictTs;
+    BufferPool mBufferPool;
+
+    struct  AccessorInvalidator {
+        std::map<uint32_t, const std::weak_ptr<Accessor>> mAccessors;
+        std::mutex mMutex;
+        std::condition_variable mCv;
+        bool mReady;
+
+        AccessorInvalidator();
+        void addAccessor(uint32_t accessorId, const std::weak_ptr<Accessor> &accessor);
+        void delAccessor(uint32_t accessorId);
+    };
+
+    static std::unique_ptr<AccessorInvalidator> sInvalidator;
+
+    static void invalidatorThread(
+        std::map<uint32_t, const std::weak_ptr<Accessor>> &accessors,
+        std::mutex &mutex,
+        std::condition_variable &cv,
+        bool &ready);
+
+    struct AccessorEvictor {
+        std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> mAccessors;
+        std::mutex mMutex;
+        std::condition_variable mCv;
+
+        AccessorEvictor();
+        void addAccessor(const std::weak_ptr<Accessor> &accessor, nsecs_t ts);
+    };
+
+    static std::unique_ptr<AccessorEvictor> sEvictor;
+
+    static void evictorThread(
+        std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
+        std::mutex &mutex,
+        std::condition_variable &cv);
+
+    void scheduleEvictIfNeeded();
+
+    friend struct BufferPool;
+};
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Android.bp b/media/bufferpool/aidl/default/Android.bp
new file mode 100644
index 0000000..11a6163
--- /dev/null
+++ b/media/bufferpool/aidl/default/Android.bp
@@ -0,0 +1,50 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_av_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+    name: "libstagefright_aidl_bufferpool2",
+    vendor_available: true,
+    min_sdk_version: "29",
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.media.swcodec",
+        "test_com.android.media.swcodec",
+    ],
+    srcs: [
+        "Accessor.cpp",
+        "BufferPool.cpp",
+        "BufferPoolClient.cpp",
+        "BufferStatus.cpp",
+        "ClientManager.cpp",
+        "Connection.cpp",
+        "Observer.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+    ],
+    export_shared_lib_headers: [
+        "libfmq",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    double_loadable: true,
+    cflags: [
+        "-DBUFFERPOOL_CLONE_HANDLES",
+    ],
+}
diff --git a/media/bufferpool/aidl/default/BufferPool.cpp b/media/bufferpool/aidl/default/BufferPool.cpp
new file mode 100644
index 0000000..ed4574f
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPool.cpp
@@ -0,0 +1,540 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlBufferPool"
+//#define LOG_NDEBUG 0
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <thread>
+#include "Accessor.h"
+#include "BufferPool.h"
+#include "Connection.h"
+#include "DataHelper.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+namespace {
+    static constexpr int64_t kCleanUpDurationMs = 500; // 0.5 sec
+    static constexpr int64_t kLogDurationMs = 5000; // 5 secs
+
+    static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
+    static constexpr size_t kMinBufferCountForEviction = 25;
+    static constexpr size_t kMaxUnusedBufferCount = 64;
+    static constexpr size_t kUnusedBufferCountTarget = kMaxUnusedBufferCount - 16;
+}
+
+BufferPool::BufferPool()
+    : mTimestampMs(::android::elapsedRealtime()),
+      mLastCleanUpMs(mTimestampMs),
+      mLastLogMs(mTimestampMs),
+      mSeq(0),
+      mStartSeq(0) {
+    mValid = mInvalidationChannel.isValid();
+}
+
+
+// Statistics helper
+template<typename T, typename S>
+int percentage(T base, S total) {
+    return int(total ? 0.5 + 100. * static_cast<S>(base) / total : 0);
+}
+
+std::atomic<std::uint32_t> BufferPool::Invalidation::sInvSeqId(0);
+
+BufferPool::~BufferPool() {
+    std::lock_guard<std::mutex> lock(mMutex);
+    ALOGD("Destruction - bufferpool2 %p "
+          "cached: %zu/%zuM, %zu/%d%% in use; "
+          "allocs: %zu, %d%% recycled; "
+          "transfers: %zu, %d%% unfetched",
+          this, mStats.mBuffersCached, mStats.mSizeCached >> 20,
+          mStats.mBuffersInUse, percentage(mStats.mBuffersInUse, mStats.mBuffersCached),
+          mStats.mTotalAllocations, percentage(mStats.mTotalRecycles, mStats.mTotalAllocations),
+          mStats.mTotalTransfers,
+          percentage(mStats.mTotalTransfers - mStats.mTotalFetches, mStats.mTotalTransfers));
+}
+
+void BufferPool::Invalidation::onConnect(
+        ConnectionId conId, const std::shared_ptr<IObserver>& observer) {
+    mAcks[conId] = mInvalidationId; // starts from current invalidationId
+    mObservers.insert(std::make_pair(conId, observer));
+}
+
+void BufferPool::Invalidation::onClose(ConnectionId conId) {
+    mAcks.erase(conId);
+    mObservers.erase(conId);
+}
+
+void BufferPool::Invalidation::onAck(
+        ConnectionId conId,
+        uint32_t msgId) {
+    auto it = mAcks.find(conId);
+    if (it == mAcks.end()) {
+        ALOGW("ACK from inconsistent connection! %lld", (long long)conId);
+        return;
+    }
+    if (isMessageLater(msgId, it->second)) {
+        mAcks[conId] = msgId;
+    }
+}
+
+void BufferPool::Invalidation::onBufferInvalidated(
+        BufferId bufferId,
+        BufferInvalidationChannel &channel) {
+    for (auto it = mPendings.begin(); it != mPendings.end();) {
+        if (it->isInvalidated(bufferId)) {
+            uint32_t msgId = 0;
+            if (it->mNeedsAck) {
+                msgId = ++mInvalidationId;
+                if (msgId == 0) {
+                    // wrap happens
+                    msgId = ++mInvalidationId;
+                }
+            }
+            channel.postInvalidation(msgId, it->mFrom, it->mTo);
+            it = mPendings.erase(it);
+            continue;
+        }
+        ++it;
+    }
+}
+
+void BufferPool::Invalidation::onInvalidationRequest(
+        bool needsAck,
+        uint32_t from,
+        uint32_t to,
+        size_t left,
+        BufferInvalidationChannel &channel,
+        const std::shared_ptr<Accessor> &impl) {
+        uint32_t msgId = 0;
+    if (needsAck) {
+        msgId = ++mInvalidationId;
+        if (msgId == 0) {
+            // wrap happens
+            msgId = ++mInvalidationId;
+        }
+    }
+    ALOGV("bufferpool2 invalidation requested and queued");
+    if (left == 0) {
+        channel.postInvalidation(msgId, from, to);
+    } else {
+        ALOGV("bufferpoo2 invalidation requested and pending");
+        Pending pending(needsAck, from, to, left, impl);
+        mPendings.push_back(pending);
+    }
+    Accessor::sInvalidator->addAccessor(mId, impl);
+}
+
+void BufferPool::Invalidation::onHandleAck(
+        std::map<ConnectionId, const std::shared_ptr<IObserver>> *observers,
+        uint32_t *invalidationId) {
+    if (mInvalidationId != 0) {
+        *invalidationId = mInvalidationId;
+        std::set<int> deads;
+        for (auto it = mAcks.begin(); it != mAcks.end(); ++it) {
+            if (it->second != mInvalidationId) {
+                const std::shared_ptr<IObserver> observer = mObservers[it->first];
+                if (observer) {
+                    observers->emplace(it->first, observer);
+                    ALOGV("connection %lld will call observer (%u: %u)",
+                          (long long)it->first, it->second, mInvalidationId);
+                    // N.B: onMessage will be called later. ignore possibility of
+                    // onMessage# oneway call being lost.
+                    it->second = mInvalidationId;
+                } else {
+                    ALOGV("bufferpool2 observer died %lld", (long long)it->first);
+                    deads.insert(it->first);
+                }
+            }
+        }
+        if (deads.size() > 0) {
+            for (auto it = deads.begin(); it != deads.end(); ++it) {
+                onClose(*it);
+            }
+        }
+    }
+    if (mPendings.size() == 0) {
+        // All invalidation Ids are synced and no more pending invalidations.
+        Accessor::sInvalidator->delAccessor(mId);
+    }
+}
+
+bool BufferPool::handleOwnBuffer(
+        ConnectionId connectionId, BufferId bufferId) {
+
+    bool added = insert(&mUsingBuffers, connectionId, bufferId);
+    if (added) {
+        auto iter = mBuffers.find(bufferId);
+        iter->second->mOwnerCount++;
+    }
+    insert(&mUsingConnections, bufferId, connectionId);
+    return added;
+}
+
+bool BufferPool::handleReleaseBuffer(
+        ConnectionId connectionId, BufferId bufferId) {
+    bool deleted = erase(&mUsingBuffers, connectionId, bufferId);
+    if (deleted) {
+        auto iter = mBuffers.find(bufferId);
+        iter->second->mOwnerCount--;
+        if (iter->second->mOwnerCount == 0 &&
+                iter->second->mTransactionCount == 0) {
+            if (!iter->second->mInvalidated) {
+                mStats.onBufferUnused(iter->second->mAllocSize);
+                mFreeBuffers.insert(bufferId);
+            } else {
+                mStats.onBufferUnused(iter->second->mAllocSize);
+                mStats.onBufferEvicted(iter->second->mAllocSize);
+                mBuffers.erase(iter);
+                mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+            }
+        }
+    }
+    erase(&mUsingConnections, bufferId, connectionId);
+    ALOGV("release buffer %u : %d", bufferId, deleted);
+    return deleted;
+}
+
+bool BufferPool::handleTransferTo(const BufferStatusMessage &message) {
+    auto completed = mCompletedTransactions.find(
+            message.transactionId);
+    if (completed != mCompletedTransactions.end()) {
+        // already completed
+        mCompletedTransactions.erase(completed);
+        return true;
+    }
+    // the buffer should exist and be owned.
+    auto bufferIter = mBuffers.find(message.bufferId);
+    if (bufferIter == mBuffers.end() ||
+            !contains(&mUsingBuffers, message.connectionId, FromAidl(message.bufferId))) {
+        return false;
+    }
+    auto found = mTransactions.find(message.transactionId);
+    if (found != mTransactions.end()) {
+        // transfer_from was received earlier.
+        found->second->mSender = message.connectionId;
+        found->second->mSenderValidated = true;
+        return true;
+    }
+    if (mConnectionIds.find(message.targetConnectionId) == mConnectionIds.end()) {
+        // N.B: it could be fake or receive connection already closed.
+        ALOGD("bufferpool2 %p receiver connection %lld is no longer valid",
+              this, (long long)message.targetConnectionId);
+        return false;
+    }
+    mStats.onBufferSent();
+    mTransactions.insert(std::make_pair(
+            message.transactionId,
+            std::make_unique<TransactionStatus>(message, mTimestampMs)));
+    insert(&mPendingTransactions, message.targetConnectionId,
+           FromAidl(message.transactionId));
+    bufferIter->second->mTransactionCount++;
+    return true;
+}
+
+bool BufferPool::handleTransferFrom(const BufferStatusMessage &message) {
+    auto found = mTransactions.find(message.transactionId);
+    if (found == mTransactions.end()) {
+        // TODO: is it feasible to check ownership here?
+        mStats.onBufferSent();
+        mTransactions.insert(std::make_pair(
+                message.transactionId,
+                std::make_unique<TransactionStatus>(message, mTimestampMs)));
+        insert(&mPendingTransactions, message.connectionId,
+               FromAidl(message.transactionId));
+        auto bufferIter = mBuffers.find(message.bufferId);
+        bufferIter->second->mTransactionCount++;
+    } else {
+        if (message.connectionId == found->second->mReceiver) {
+            found->second->mStatus = BufferStatus::TRANSFER_FROM;
+        }
+    }
+    return true;
+}
+
+bool BufferPool::handleTransferResult(const BufferStatusMessage &message) {
+    auto found = mTransactions.find(message.transactionId);
+    if (found != mTransactions.end()) {
+        bool deleted = erase(&mPendingTransactions, message.connectionId,
+                             FromAidl(message.transactionId));
+        if (deleted) {
+            if (!found->second->mSenderValidated) {
+                mCompletedTransactions.insert(message.transactionId);
+            }
+            auto bufferIter = mBuffers.find(message.bufferId);
+            if (message.status == BufferStatus::TRANSFER_OK) {
+                handleOwnBuffer(message.connectionId, message.bufferId);
+            }
+            bufferIter->second->mTransactionCount--;
+            if (bufferIter->second->mOwnerCount == 0
+                && bufferIter->second->mTransactionCount == 0) {
+                if (!bufferIter->second->mInvalidated) {
+                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                    mFreeBuffers.insert(message.bufferId);
+                } else {
+                    mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                    mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+                    mBuffers.erase(bufferIter);
+                    mInvalidation.onBufferInvalidated(message.bufferId, mInvalidationChannel);
+                }
+            }
+            mTransactions.erase(found);
+        }
+        ALOGV("transfer finished %llu %u - %d", (unsigned long long)message.transactionId,
+              message.bufferId, deleted);
+        return deleted;
+    }
+    ALOGV("transfer not found %llu %u", (unsigned long long)message.transactionId,
+          message.bufferId);
+    return false;
+}
+
+void BufferPool::processStatusMessages() {
+    std::vector<BufferStatusMessage> messages;
+    mObserver.getBufferStatusChanges(messages);
+    mTimestampMs = ::android::elapsedRealtime();
+    for (BufferStatusMessage& message: messages) {
+        bool ret = false;
+        switch (message.status) {
+            case BufferStatus::NOT_USED:
+                ret = handleReleaseBuffer(
+                        message.connectionId, message.bufferId);
+                break;
+            case BufferStatus::USED:
+                // not happening
+                break;
+            case BufferStatus::TRANSFER_TO:
+                ret = handleTransferTo(message);
+                break;
+            case BufferStatus::TRANSFER_FROM:
+                ret = handleTransferFrom(message);
+                break;
+            case BufferStatus::TRANSFER_TIMEOUT:
+                // TODO
+                break;
+            case BufferStatus::TRANSFER_LOST:
+                // TODO
+                break;
+            case BufferStatus::TRANSFER_FETCH:
+                // not happening
+                break;
+            case BufferStatus::TRANSFER_OK:
+            case BufferStatus::TRANSFER_ERROR:
+                ret = handleTransferResult(message);
+                break;
+            case BufferStatus::INVALIDATION_ACK:
+                mInvalidation.onAck(message.connectionId, message.bufferId);
+                ret = true;
+                break;
+        }
+        if (ret == false) {
+            ALOGW("buffer status message processing failure - message : %d connection : %lld",
+                  message.status, (long long)message.connectionId);
+        }
+    }
+    messages.clear();
+}
+
+bool BufferPool::handleClose(ConnectionId connectionId) {
+    // Cleaning buffers
+    auto buffers = mUsingBuffers.find(connectionId);
+    if (buffers != mUsingBuffers.end()) {
+        for (const BufferId& bufferId : buffers->second) {
+            bool deleted = erase(&mUsingConnections, bufferId, connectionId);
+            if (deleted) {
+                auto bufferIter = mBuffers.find(bufferId);
+                bufferIter->second->mOwnerCount--;
+                if (bufferIter->second->mOwnerCount == 0 &&
+                        bufferIter->second->mTransactionCount == 0) {
+                    // TODO: handle freebuffer insert fail
+                    if (!bufferIter->second->mInvalidated) {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mFreeBuffers.insert(bufferId);
+                    } else {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+                        mBuffers.erase(bufferIter);
+                        mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+                    }
+                }
+            }
+        }
+        mUsingBuffers.erase(buffers);
+    }
+
+    // Cleaning transactions
+    auto pending = mPendingTransactions.find(connectionId);
+    if (pending != mPendingTransactions.end()) {
+        for (const TransactionId& transactionId : pending->second) {
+            auto iter = mTransactions.find(transactionId);
+            if (iter != mTransactions.end()) {
+                if (!iter->second->mSenderValidated) {
+                    mCompletedTransactions.insert(transactionId);
+                }
+                BufferId bufferId = iter->second->mBufferId;
+                auto bufferIter = mBuffers.find(bufferId);
+                bufferIter->second->mTransactionCount--;
+                if (bufferIter->second->mOwnerCount == 0 &&
+                    bufferIter->second->mTransactionCount == 0) {
+                    // TODO: handle freebuffer insert fail
+                    if (!bufferIter->second->mInvalidated) {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mFreeBuffers.insert(bufferId);
+                    } else {
+                        mStats.onBufferUnused(bufferIter->second->mAllocSize);
+                        mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+                        mBuffers.erase(bufferIter);
+                        mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+                    }
+                }
+                mTransactions.erase(iter);
+            }
+        }
+    }
+    mConnectionIds.erase(connectionId);
+    return true;
+}
+
+bool BufferPool::getFreeBuffer(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        const std::vector<uint8_t> &params, BufferId *pId,
+        const native_handle_t** handle) {
+    auto bufferIt = mFreeBuffers.begin();
+    for (;bufferIt != mFreeBuffers.end(); ++bufferIt) {
+        BufferId bufferId = *bufferIt;
+        if (allocator->compatible(params, mBuffers[bufferId]->mConfig)) {
+            break;
+        }
+    }
+    if (bufferIt != mFreeBuffers.end()) {
+        BufferId id = *bufferIt;
+        mFreeBuffers.erase(bufferIt);
+        mStats.onBufferRecycled(mBuffers[id]->mAllocSize);
+        *handle = mBuffers[id]->handle();
+        *pId = id;
+        ALOGV("recycle a buffer %u %p", id, *handle);
+        return true;
+    }
+    return false;
+}
+
+BufferPoolStatus BufferPool::addNewBuffer(
+        const std::shared_ptr<BufferPoolAllocation> &alloc,
+        const size_t allocSize,
+        const std::vector<uint8_t> &params,
+        BufferId *pId,
+        const native_handle_t** handle) {
+
+    BufferId bufferId = mSeq++;
+    if (mSeq == Connection::SYNC_BUFFERID) {
+        mSeq = 0;
+    }
+    std::unique_ptr<InternalBuffer> buffer =
+            std::make_unique<InternalBuffer>(
+                    bufferId, alloc, allocSize, params);
+    if (buffer) {
+        auto res = mBuffers.insert(std::make_pair(
+                bufferId, std::move(buffer)));
+        if (res.second) {
+            mStats.onBufferAllocated(allocSize);
+            *handle = alloc->handle();
+            *pId = bufferId;
+            return ResultStatus::OK;
+        }
+    }
+    return ResultStatus::NO_MEMORY;
+}
+
+void BufferPool::cleanUp(bool clearCache) {
+    if (clearCache || mTimestampMs > mLastCleanUpMs + kCleanUpDurationMs ||
+            mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
+        mLastCleanUpMs = mTimestampMs;
+        if (mTimestampMs > mLastLogMs + kLogDurationMs ||
+                mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
+            mLastLogMs = mTimestampMs;
+            ALOGD("bufferpool2 %p : %zu(%zu size) total buffers - "
+                  "%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - "
+                  "%zu/%zu (fetch/transfer)",
+                  this, mStats.mBuffersCached, mStats.mSizeCached,
+                  mStats.mBuffersInUse, mStats.mSizeInUse,
+                  mStats.mTotalRecycles, mStats.mTotalAllocations,
+                  mStats.mTotalFetches, mStats.mTotalTransfers);
+        }
+        for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
+            if (!clearCache && mStats.buffersNotInUse() <= kUnusedBufferCountTarget &&
+                    (mStats.mSizeCached < kMinAllocBytesForEviction ||
+                     mBuffers.size() < kMinBufferCountForEviction)) {
+                break;
+            }
+            auto it = mBuffers.find(*freeIt);
+            if (it != mBuffers.end() &&
+                    it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
+                mStats.onBufferEvicted(it->second->mAllocSize);
+                mBuffers.erase(it);
+                freeIt = mFreeBuffers.erase(freeIt);
+            } else {
+                ++freeIt;
+                ALOGW("bufferpool2 inconsistent!");
+            }
+        }
+    }
+}
+
+void BufferPool::invalidate(
+        bool needsAck, BufferId from, BufferId to,
+        const std::shared_ptr<Accessor> &impl) {
+    for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
+        if (isBufferInRange(from, to, *freeIt)) {
+            auto it = mBuffers.find(*freeIt);
+            if (it != mBuffers.end() &&
+                it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
+                mStats.onBufferEvicted(it->second->mAllocSize);
+                mBuffers.erase(it);
+                freeIt = mFreeBuffers.erase(freeIt);
+                continue;
+            } else {
+                ALOGW("bufferpool2 inconsistent!");
+            }
+        }
+        ++freeIt;
+    }
+
+    size_t left = 0;
+    for (auto it = mBuffers.begin(); it != mBuffers.end(); ++it) {
+        if (isBufferInRange(from, to, it->first)) {
+            it->second->invalidate();
+            ++left;
+        }
+    }
+    mInvalidation.onInvalidationRequest(needsAck, from, to, left, mInvalidationChannel, impl);
+}
+
+void BufferPool::flush(const std::shared_ptr<Accessor> &impl) {
+    BufferId from = mStartSeq;
+    BufferId to = mSeq;
+    mStartSeq = mSeq;
+    // TODO: needsAck params
+    ALOGV("buffer invalidation request bp:%u %u %u", mInvalidation.mId, from, to);
+    if (from != to) {
+        invalidate(true, from, to, impl);
+    }
+}
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferPool.h b/media/bufferpool/aidl/default/BufferPool.h
new file mode 100644
index 0000000..1529a53
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPool.h
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <map>
+#include <set>
+#include <vector>
+#include <mutex>
+#include <condition_variable>
+#include <utils/Timers.h>
+
+#include "BufferStatus.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using BufferStatus = aidl::android::hardware::media::bufferpool2::BufferStatus;
+using BufferStatusMessage = aidl::android::hardware::media::bufferpool2::BufferStatusMessage;
+
+struct Accessor;
+struct InternalBuffer;
+struct TransactionStatus;
+
+/**
+ * Buffer pool implementation.
+ *
+ * Handles buffer status messages. Handles buffer allocation/recycling.
+ * Handles buffer transfer between buffer pool clients.
+ */
+struct BufferPool {
+private:
+    std::mutex mMutex;
+    int64_t mTimestampMs;
+    int64_t mLastCleanUpMs;
+    int64_t mLastLogMs;
+    BufferId mSeq;
+    BufferId mStartSeq;
+    bool mValid;
+    BufferStatusObserver mObserver;
+    BufferInvalidationChannel mInvalidationChannel;
+
+    std::map<ConnectionId, std::set<BufferId>> mUsingBuffers;
+    std::map<BufferId, std::set<ConnectionId>> mUsingConnections;
+
+    std::map<ConnectionId, std::set<TransactionId>> mPendingTransactions;
+    // Transactions completed before TRANSFER_TO message arrival.
+    // Fetch does not occur for the transactions.
+    // Only transaction id is kept for the transactions in short duration.
+    std::set<TransactionId> mCompletedTransactions;
+    // Currently active(pending) transations' status & information.
+    std::map<TransactionId, std::unique_ptr<TransactionStatus>>
+            mTransactions;
+
+    std::map<BufferId, std::unique_ptr<InternalBuffer>> mBuffers;
+    std::set<BufferId> mFreeBuffers;
+    std::set<ConnectionId> mConnectionIds;
+
+    struct Invalidation {
+        static std::atomic<std::uint32_t> sInvSeqId;
+
+        struct Pending {
+            bool mNeedsAck;
+            uint32_t mFrom;
+            uint32_t mTo;
+            size_t mLeft;
+            const std::weak_ptr<Accessor> mImpl;
+            Pending(bool needsAck, uint32_t from, uint32_t to, size_t left,
+                    const std::shared_ptr<Accessor> &impl)
+                    : mNeedsAck(needsAck),
+                      mFrom(from),
+                      mTo(to),
+                      mLeft(left),
+                      mImpl(impl)
+            {}
+
+            bool isInvalidated(uint32_t bufferId) {
+                return isBufferInRange(mFrom, mTo, bufferId) && --mLeft == 0;
+            }
+        };
+
+        std::list<Pending> mPendings;
+        std::map<ConnectionId, uint32_t> mAcks;
+        std::map<ConnectionId, const std::shared_ptr<IObserver>> mObservers;
+        uint32_t mInvalidationId;
+        uint32_t mId;
+
+        Invalidation() : mInvalidationId(0), mId(sInvSeqId.fetch_add(1)) {}
+
+        void onConnect(ConnectionId conId, const std::shared_ptr<IObserver> &observer);
+
+        void onClose(ConnectionId conId);
+
+        void onAck(ConnectionId conId, uint32_t msgId);
+
+        void onBufferInvalidated(
+                BufferId bufferId,
+                BufferInvalidationChannel &channel);
+
+        void onInvalidationRequest(
+                bool needsAck, uint32_t from, uint32_t to, size_t left,
+                BufferInvalidationChannel &channel,
+                const std::shared_ptr<Accessor> &impl);
+
+        void onHandleAck(
+                std::map<ConnectionId, const std::shared_ptr<IObserver>> *observers,
+                uint32_t *invalidationId);
+    } mInvalidation;
+    /// Buffer pool statistics which tracks allocation and transfer statistics.
+    struct Stats {
+        /// Total size of allocations which are used or available to use.
+        /// (bytes or pixels)
+        size_t mSizeCached;
+        /// # of cached buffers which are used or available to use.
+        size_t mBuffersCached;
+        /// Total size of allocations which are currently used. (bytes or pixels)
+        size_t mSizeInUse;
+        /// # of currently used buffers
+        size_t mBuffersInUse;
+
+        /// # of allocations called on bufferpool. (# of fetched from BlockPool)
+        size_t mTotalAllocations;
+        /// # of allocations that were served from the cache.
+        /// (# of allocator alloc prevented)
+        size_t mTotalRecycles;
+        /// # of buffer transfers initiated.
+        size_t mTotalTransfers;
+        /// # of transfers that had to be fetched.
+        size_t mTotalFetches;
+
+        Stats()
+            : mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0),
+              mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {}
+
+        /// # of currently unused buffers
+        size_t buffersNotInUse() const {
+            ALOG_ASSERT(mBuffersCached >= mBuffersInUse);
+            return mBuffersCached - mBuffersInUse;
+        }
+
+        /// A new buffer is allocated on an allocation request.
+        void onBufferAllocated(size_t allocSize) {
+            mSizeCached += allocSize;
+            mBuffersCached++;
+
+            mSizeInUse += allocSize;
+            mBuffersInUse++;
+
+            mTotalAllocations++;
+        }
+
+        /// A buffer is evicted and destroyed.
+        void onBufferEvicted(size_t allocSize) {
+            mSizeCached -= allocSize;
+            mBuffersCached--;
+        }
+
+        /// A buffer is recycled on an allocation request.
+        void onBufferRecycled(size_t allocSize) {
+            mSizeInUse += allocSize;
+            mBuffersInUse++;
+
+            mTotalAllocations++;
+            mTotalRecycles++;
+        }
+
+        /// A buffer is available to be recycled.
+        void onBufferUnused(size_t allocSize) {
+            mSizeInUse -= allocSize;
+            mBuffersInUse--;
+        }
+
+        /// A buffer transfer is initiated.
+        void onBufferSent() {
+            mTotalTransfers++;
+        }
+
+        /// A buffer fetch is invoked by a buffer transfer.
+        void onBufferFetched() {
+            mTotalFetches++;
+        }
+    } mStats;
+
+    bool isValid() {
+        return mValid;
+    }
+
+    void invalidate(bool needsAck, BufferId from, BufferId to,
+                    const std::shared_ptr<Accessor> &impl);
+
+    static void createInvalidator();
+
+public:
+    /** Creates a buffer pool. */
+    BufferPool();
+
+    /** Destroys a buffer pool. */
+    ~BufferPool();
+
+    /**
+     * Processes all pending buffer status messages, and returns the result.
+     * Each status message is handled by methods with 'handle' prefix.
+     */
+    void processStatusMessages();
+
+    /**
+     * Handles a buffer being owned by a connection.
+     *
+     * @param connectionId  the id of the buffer owning connection.
+     * @param bufferId      the id of the buffer.
+     *
+     * @return {@code true} when the buffer is owned,
+     *         {@code false} otherwise.
+     */
+    bool handleOwnBuffer(ConnectionId connectionId, BufferId bufferId);
+
+    /**
+     * Handles a buffer being released by a connection.
+     *
+     * @param connectionId  the id of the buffer owning connection.
+     * @param bufferId      the id of the buffer.
+     *
+     * @return {@code true} when the buffer ownership is released,
+     *         {@code false} otherwise.
+     */
+    bool handleReleaseBuffer(ConnectionId connectionId, BufferId bufferId);
+
+    /**
+     * Handles a transfer transaction start message from the sender.
+     *
+     * @param message   a buffer status message for the transaction.
+     *
+     * @result {@code true} when transfer_to message is acknowledged,
+     *         {@code false} otherwise.
+     */
+    bool handleTransferTo(const BufferStatusMessage &message);
+
+    /**
+     * Handles a transfer transaction being acked by the receiver.
+     *
+     * @param message   a buffer status message for the transaction.
+     *
+     * @result {@code true} when transfer_from message is acknowledged,
+     *         {@code false} otherwise.
+     */
+    bool handleTransferFrom(const BufferStatusMessage &message);
+
+    /**
+     * Handles a transfer transaction result message from the receiver.
+     *
+     * @param message   a buffer status message for the transaction.
+     *
+     * @result {@code true} when the existing transaction is finished,
+     *         {@code false} otherwise.
+     */
+    bool handleTransferResult(const BufferStatusMessage &message);
+
+    /**
+     * Handles a connection being closed, and returns the result. All the
+     * buffers and transactions owned by the connection will be cleaned up.
+     * The related FMQ will be cleaned up too.
+     *
+     * @param connectionId  the id of the connection.
+     *
+     * @result {@code true} when the connection existed,
+     *         {@code false} otherwise.
+     */
+    bool handleClose(ConnectionId connectionId);
+
+    /**
+     * Recycles a existing free buffer if it is possible.
+     *
+     * @param allocator the buffer allocator
+     * @param params    the allocation parameters.
+     * @param pId       the id of the recycled buffer.
+     * @param handle    the native handle of the recycled buffer.
+     *
+     * @return {@code true} when a buffer is recycled, {@code false}
+     *         otherwise.
+     */
+    bool getFreeBuffer(
+            const std::shared_ptr<BufferPoolAllocator> &allocator,
+            const std::vector<uint8_t> &params,
+            BufferId *pId, const native_handle_t **handle);
+
+    /**
+     * Adds a newly allocated buffer to bufferpool.
+     *
+     * @param alloc     the newly allocated buffer.
+     * @param allocSize the size of the newly allocated buffer.
+     * @param params    the allocation parameters.
+     * @param pId       the buffer id for the newly allocated buffer.
+     * @param handle    the native handle for the newly allocated buffer.
+     *
+     * @return OK when an allocation is successfully allocated.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus addNewBuffer(
+            const std::shared_ptr<BufferPoolAllocation> &alloc,
+            const size_t allocSize,
+            const std::vector<uint8_t> &params,
+            BufferId *pId,
+            const native_handle_t **handle);
+
+    /**
+     * Processes pending buffer status messages and performs periodic cache
+     * cleaning.
+     *
+     * @param clearCache    if clearCache is true, it frees all buffers
+     *                      waiting to be recycled.
+     */
+    void cleanUp(bool clearCache = false);
+
+    /**
+     * Processes pending buffer status messages and invalidate all current
+     * free buffers. Active buffers are invalidated after being inactive.
+     */
+    void flush(const std::shared_ptr<Accessor> &impl);
+
+    friend struct Accessor;
+};
+
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.cpp b/media/bufferpool/aidl/default/BufferPoolClient.cpp
new file mode 100644
index 0000000..e9777d8
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPoolClient.cpp
@@ -0,0 +1,858 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlBufferPoolCli"
+//#define LOG_NDEBUG 0
+
+#include <thread>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <utils/Log.h>
+#include "BufferPoolClient.h"
+#include "Accessor.h"
+#include "Connection.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::IConnection;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using FetchInfo = aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo;
+using FetchResult = aidl::android::hardware::media::bufferpool2::IConnection::FetchResult;
+
+static constexpr int64_t kReceiveTimeoutMs = 2000; // 2s
+static constexpr int kPostMaxRetry = 3;
+static constexpr int kCacheTtlMs = 1000;
+static constexpr size_t kMaxCachedBufferCount = 64;
+static constexpr size_t kCachedBufferCountTarget = kMaxCachedBufferCount - 16;
+
+class BufferPoolClient::Impl
+        : public std::enable_shared_from_this<BufferPoolClient::Impl> {
+public:
+    explicit Impl(const std::shared_ptr<Accessor> &accessor,
+                  const std::shared_ptr<IObserver> &observer);
+
+    explicit Impl(const std::shared_ptr<IAccessor> &accessor,
+                  const std::shared_ptr<IObserver> &observer);
+
+    bool isValid() {
+        return mValid;
+    }
+
+    bool isLocal() {
+        return mValid && mLocal;
+    }
+
+    ConnectionId getConnectionId() {
+        return mConnectionId;
+    }
+
+    std::shared_ptr<IAccessor> &getAccessor() {
+        return mAccessor;
+    }
+
+    bool isActive(int64_t *lastTransactionMs, bool clearCache);
+
+    void receiveInvalidation(uint32_t msgID);
+
+    BufferPoolStatus flush();
+
+    BufferPoolStatus allocate(const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    BufferPoolStatus receive(
+            TransactionId transactionId, BufferId bufferId,
+            int64_t timestampMs,
+            native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer);
+
+    void postBufferRelease(BufferId bufferId);
+
+    bool postSend(
+            BufferId bufferId, ConnectionId receiver,
+            TransactionId *transactionId, int64_t *timestampMs);
+private:
+
+    bool postReceive(
+            BufferId bufferId, TransactionId transactionId,
+            int64_t timestampMs);
+
+    bool postReceiveResult(
+            BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync);
+
+    void trySyncFromRemote();
+
+    bool syncReleased(uint32_t msgId = 0);
+
+    void evictCaches(bool clearCache = false);
+
+    void invalidateBuffer(BufferId id);
+
+    void invalidateRange(BufferId from, BufferId to);
+
+    BufferPoolStatus allocateBufferHandle(
+            const std::vector<uint8_t>& params, BufferId *bufferId,
+            native_handle_t **handle);
+
+    BufferPoolStatus fetchBufferHandle(
+            TransactionId transactionId, BufferId bufferId,
+            native_handle_t **handle);
+
+    struct BlockPoolDataDtor;
+    struct ClientBuffer;
+
+    bool mLocal;
+    bool mValid;
+    std::shared_ptr<IAccessor> mAccessor;
+    std::shared_ptr<Connection> mLocalConnection;
+    std::shared_ptr<IConnection> mRemoteConnection;
+    uint32_t mSeqId;
+    ConnectionId mConnectionId;
+    int64_t mLastEvictCacheMs;
+    std::unique_ptr<BufferInvalidationListener> mInvalidationListener;
+
+    // CachedBuffers
+    struct BufferCache {
+        std::mutex mLock;
+        bool mCreating;
+        std::condition_variable mCreateCv;
+        std::map<BufferId, std::unique_ptr<ClientBuffer>> mBuffers;
+        int mActive;
+        int64_t mLastChangeMs;
+
+        BufferCache() : mCreating(false), mActive(0),
+                mLastChangeMs(::android::elapsedRealtime()) {}
+
+        void incActive_l() {
+            ++mActive;
+            mLastChangeMs = ::android::elapsedRealtime();
+        }
+
+        void decActive_l() {
+            --mActive;
+            mLastChangeMs = ::android::elapsedRealtime();
+        }
+
+        int cachedBufferCount() const {
+            return mBuffers.size() - mActive;
+        }
+    } mCache;
+
+    // FMQ - release notifier
+    struct ReleaseCache {
+        std::mutex mLock;
+        std::list<BufferId> mReleasingIds;
+        std::list<BufferId> mReleasedIds;
+        uint32_t mInvalidateId; // TODO: invalidation ACK to bufferpool
+        bool mInvalidateAck;
+        std::unique_ptr<BufferStatusChannel> mStatusChannel;
+
+        ReleaseCache() : mInvalidateId(0), mInvalidateAck(true) {}
+    } mReleasing;
+
+    // This lock is held during synchronization from remote side.
+    // In order to minimize remote calls and locking duration, this lock is held
+    // by best effort approach using try_lock().
+    std::mutex mRemoteSyncLock;
+};
+
+struct BufferPoolClient::Impl::BlockPoolDataDtor {
+    BlockPoolDataDtor(const std::shared_ptr<BufferPoolClient::Impl> &impl)
+            : mImpl(impl) {}
+
+    void operator()(BufferPoolData *buffer) {
+        BufferId id = buffer->mId;
+        delete buffer;
+
+        auto impl = mImpl.lock();
+        if (impl && impl->isValid()) {
+            impl->postBufferRelease(id);
+        }
+    }
+    const std::weak_ptr<BufferPoolClient::Impl> mImpl;
+};
+
+struct BufferPoolClient::Impl::ClientBuffer {
+private:
+    int64_t mExpireMs;
+    bool mHasCache;
+    ConnectionId mConnectionId;
+    BufferId mId;
+    native_handle_t *mHandle;
+    std::weak_ptr<BufferPoolData> mCache;
+
+    void updateExpire() {
+        mExpireMs = ::android::elapsedRealtime() + kCacheTtlMs;
+    }
+
+public:
+    ClientBuffer(
+            ConnectionId connectionId, BufferId id, native_handle_t *handle)
+            : mHasCache(false), mConnectionId(connectionId),
+              mId(id), mHandle(handle) {
+        mExpireMs = ::android::elapsedRealtime() + kCacheTtlMs;
+    }
+
+    ~ClientBuffer() {
+        if (mHandle) {
+            native_handle_close(mHandle);
+            native_handle_delete(mHandle);
+        }
+    }
+
+    BufferId id() const {
+        return mId;
+    }
+
+    bool expire() const {
+        int64_t now = ::android::elapsedRealtime();
+        return now >= mExpireMs;
+    }
+
+    bool hasCache() const {
+        return mHasCache;
+    }
+
+    std::shared_ptr<BufferPoolData> fetchCache(native_handle_t **pHandle) {
+        if (mHasCache) {
+            std::shared_ptr<BufferPoolData> cache = mCache.lock();
+            if (cache) {
+                *pHandle = mHandle;
+            }
+            return cache;
+        }
+        return nullptr;
+    }
+
+    std::shared_ptr<BufferPoolData> createCache(
+            const std::shared_ptr<BufferPoolClient::Impl> &impl,
+            native_handle_t **pHandle) {
+        if (!mHasCache) {
+            // Allocates a raw ptr in order to avoid sending #postBufferRelease
+            // from deleter, in case of native_handle_clone failure.
+            BufferPoolData *ptr = new BufferPoolData(mConnectionId, mId);
+            if (ptr) {
+                std::shared_ptr<BufferPoolData> cache(ptr, BlockPoolDataDtor(impl));
+                if (cache) {
+                    mCache = cache;
+                    mHasCache = true;
+                    *pHandle = mHandle;
+                    return cache;
+                }
+            }
+            if (ptr) {
+                delete ptr;
+            }
+        }
+        return nullptr;
+    }
+
+    bool onCacheRelease() {
+        if (mHasCache) {
+            // TODO: verify mCache is not valid;
+            updateExpire();
+            mHasCache = false;
+            return true;
+        }
+        return false;
+    }
+};
+
+BufferPoolClient::Impl::Impl(const std::shared_ptr<Accessor> &accessor,
+                             const std::shared_ptr<IObserver> &observer)
+    : mLocal(true), mValid(false), mAccessor(accessor), mSeqId(0),
+      mLastEvictCacheMs(::android::elapsedRealtime()) {
+    StatusDescriptor statusDesc;
+    InvalidationDescriptor invDesc;
+    BufferPoolStatus status = accessor->connect(
+            observer, true,
+            &mLocalConnection, &mConnectionId, &mReleasing.mInvalidateId,
+            &statusDesc, &invDesc);
+    if (status == ResultStatus::OK) {
+        mReleasing.mStatusChannel =
+                std::make_unique<BufferStatusChannel>(statusDesc);
+        mInvalidationListener =
+                std::make_unique<BufferInvalidationListener>(invDesc);
+        mValid = mReleasing.mStatusChannel &&
+                mReleasing.mStatusChannel->isValid() &&
+                mInvalidationListener &&
+                mInvalidationListener->isValid();
+    }
+}
+
+BufferPoolClient::Impl::Impl(const std::shared_ptr<IAccessor> &accessor,
+                             const std::shared_ptr<IObserver> &observer)
+    : mLocal(false), mValid(false), mAccessor(accessor), mSeqId(0),
+      mLastEvictCacheMs(::android::elapsedRealtime()) {
+    IAccessor::ConnectionInfo conInfo;
+    bool valid = false;
+    if(accessor->connect(observer, &conInfo).isOk()) {
+        auto channel = std::make_unique<BufferStatusChannel>(conInfo.toFmqDesc);
+        auto observer = std::make_unique<BufferInvalidationListener>(conInfo.fromFmqDesc);
+
+        if (channel && channel->isValid()
+            && observer && observer->isValid()) {
+            mRemoteConnection = conInfo.connection;
+            mConnectionId = conInfo.connectionId;
+            mReleasing.mInvalidateId = conInfo.msgId;
+            mReleasing.mStatusChannel = std::move(channel);
+            mInvalidationListener = std::move(observer);
+            valid = true;
+        }
+    }
+    mValid = valid;
+}
+
+bool BufferPoolClient::Impl::isActive(int64_t *lastTransactionMs, bool clearCache) {
+    bool active = false;
+    {
+        std::lock_guard<std::mutex> lock(mCache.mLock);
+        syncReleased();
+        evictCaches(clearCache);
+        *lastTransactionMs = mCache.mLastChangeMs;
+        active = mCache.mActive > 0;
+    }
+    if (mValid && mLocal && mLocalConnection) {
+        mLocalConnection->cleanUp(clearCache);
+        return true;
+    }
+    return active;
+}
+
+void BufferPoolClient::Impl::receiveInvalidation(uint32_t messageId) {
+    std::lock_guard<std::mutex> lock(mCache.mLock);
+    syncReleased(messageId);
+    // TODO: evict cache required?
+}
+
+BufferPoolStatus BufferPoolClient::Impl::flush() {
+    if (!mLocal || !mLocalConnection || !mValid) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    {
+        std::unique_lock<std::mutex> lock(mCache.mLock);
+        syncReleased();
+        evictCaches();
+        return mLocalConnection->flush();
+    }
+}
+
+BufferPoolStatus BufferPoolClient::Impl::allocate(
+        const std::vector<uint8_t> &params,
+        native_handle_t **pHandle,
+        std::shared_ptr<BufferPoolData> *buffer) {
+    if (!mLocal || !mLocalConnection || !mValid) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    BufferId bufferId;
+    native_handle_t *handle = nullptr;
+    buffer->reset();
+    BufferPoolStatus status = allocateBufferHandle(params, &bufferId, &handle);
+    if (status == ResultStatus::OK) {
+        if (handle) {
+            std::unique_lock<std::mutex> lock(mCache.mLock);
+            syncReleased();
+            evictCaches();
+            auto cacheIt = mCache.mBuffers.find(bufferId);
+            if (cacheIt != mCache.mBuffers.end()) {
+                // TODO: verify it is recycled. (not having active ref)
+                mCache.mBuffers.erase(cacheIt);
+            }
+            auto clientBuffer = std::make_unique<ClientBuffer>(
+                    mConnectionId, bufferId, handle);
+            if (clientBuffer) {
+                auto result = mCache.mBuffers.insert(std::make_pair(
+                        bufferId, std::move(clientBuffer)));
+                if (result.second) {
+                    *buffer = result.first->second->createCache(
+                            shared_from_this(), pHandle);
+                    if (*buffer) {
+                        mCache.incActive_l();
+                    }
+                }
+            }
+        }
+        if (!*buffer) {
+            ALOGV("client cache creation failure %d: %lld",
+                  handle != nullptr, (long long)mConnectionId);
+            status = ResultStatus::NO_MEMORY;
+            postBufferRelease(bufferId);
+        }
+    }
+    return status;
+}
+
+BufferPoolStatus BufferPoolClient::Impl::receive(
+        TransactionId transactionId, BufferId bufferId, int64_t timestampMs,
+        native_handle_t **pHandle,
+        std::shared_ptr<BufferPoolData> *buffer) {
+    if (!mValid) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    if (timestampMs != 0) {
+        timestampMs += kReceiveTimeoutMs;
+    }
+    if (!postReceive(bufferId, transactionId, timestampMs)) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+    buffer->reset();
+    while(1) {
+        std::unique_lock<std::mutex> lock(mCache.mLock);
+        syncReleased();
+        evictCaches();
+        auto cacheIt = mCache.mBuffers.find(bufferId);
+        if (cacheIt != mCache.mBuffers.end()) {
+            if (cacheIt->second->hasCache()) {
+                *buffer = cacheIt->second->fetchCache(pHandle);
+                if (!*buffer) {
+                    // check transfer time_out
+                    lock.unlock();
+                    std::this_thread::yield();
+                    continue;
+                }
+                ALOGV("client receive from reference %lld", (long long)mConnectionId);
+                break;
+            } else {
+                *buffer = cacheIt->second->createCache(shared_from_this(), pHandle);
+                if (*buffer) {
+                    mCache.incActive_l();
+                }
+                ALOGV("client receive from cache %lld", (long long)mConnectionId);
+                break;
+            }
+        } else {
+            if (!mCache.mCreating) {
+                mCache.mCreating = true;
+                lock.unlock();
+                native_handle_t* handle = nullptr;
+                status = fetchBufferHandle(transactionId, bufferId, &handle);
+                lock.lock();
+                if (status == ResultStatus::OK) {
+                    if (handle) {
+                        auto clientBuffer = std::make_unique<ClientBuffer>(
+                                mConnectionId, bufferId, handle);
+                        if (clientBuffer) {
+                            auto result = mCache.mBuffers.insert(
+                                    std::make_pair(bufferId, std::move(
+                                            clientBuffer)));
+                            if (result.second) {
+                                *buffer = result.first->second->createCache(
+                                        shared_from_this(), pHandle);
+                                if (*buffer) {
+                                    mCache.incActive_l();
+                                }
+                            }
+                        }
+                    }
+                    if (!*buffer) {
+                        status = ResultStatus::NO_MEMORY;
+                    }
+                }
+                mCache.mCreating = false;
+                lock.unlock();
+                mCache.mCreateCv.notify_all();
+                break;
+            }
+            mCache.mCreateCv.wait(lock);
+        }
+    }
+    bool needsSync = false;
+    bool posted = postReceiveResult(bufferId, transactionId,
+                                      *buffer ? true : false, &needsSync);
+    ALOGV("client receive %lld - %u : %s (%d)", (long long)mConnectionId, bufferId,
+          *buffer ? "ok" : "fail", posted);
+    if (mValid && mLocal && mLocalConnection) {
+        mLocalConnection->cleanUp(false);
+    }
+    if (needsSync && mRemoteConnection) {
+        trySyncFromRemote();
+    }
+    if (*buffer) {
+        if (!posted) {
+            buffer->reset();
+            return ResultStatus::CRITICAL_ERROR;
+        }
+        return ResultStatus::OK;
+    }
+    return status;
+}
+
+
+void BufferPoolClient::Impl::postBufferRelease(BufferId bufferId) {
+    std::lock_guard<std::mutex> lock(mReleasing.mLock);
+    mReleasing.mReleasingIds.push_back(bufferId);
+    mReleasing.mStatusChannel->postBufferRelease(
+            mConnectionId, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
+}
+
+// TODO: revise ad-hoc posting data structure
+bool BufferPoolClient::Impl::postSend(
+        BufferId bufferId, ConnectionId receiver,
+        TransactionId *transactionId, int64_t *timestampMs) {
+    {
+        // TODO: don't need to call syncReleased every time
+        std::lock_guard<std::mutex> lock(mCache.mLock);
+        syncReleased();
+    }
+    bool ret = false;
+    bool needsSync = false;
+    {
+        std::lock_guard<std::mutex> lock(mReleasing.mLock);
+        *timestampMs = ::android::elapsedRealtime();
+        *transactionId = (mConnectionId << 32) | mSeqId++;
+        // TODO: retry, add timeout, target?
+        ret =  mReleasing.mStatusChannel->postBufferStatusMessage(
+                *transactionId, bufferId, BufferStatus::TRANSFER_TO, mConnectionId,
+                receiver, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
+        needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
+    }
+    if (mValid && mLocal && mLocalConnection) {
+        mLocalConnection->cleanUp(false);
+    }
+    if (needsSync && mRemoteConnection) {
+        trySyncFromRemote();
+    }
+    return ret;
+}
+
+bool BufferPoolClient::Impl::postReceive(
+        BufferId bufferId, TransactionId transactionId, int64_t timestampMs) {
+    for (int i = 0; i < kPostMaxRetry; ++i) {
+        std::unique_lock<std::mutex> lock(mReleasing.mLock);
+        int64_t now = ::android::elapsedRealtime();
+        if (timestampMs == 0 || now < timestampMs) {
+            bool result = mReleasing.mStatusChannel->postBufferStatusMessage(
+                    transactionId, bufferId, BufferStatus::TRANSFER_FROM,
+                    mConnectionId, -1, mReleasing.mReleasingIds,
+                    mReleasing.mReleasedIds);
+            if (result) {
+                return true;
+            }
+            lock.unlock();
+            std::this_thread::yield();
+        } else {
+            mReleasing.mStatusChannel->postBufferStatusMessage(
+                    transactionId, bufferId, BufferStatus::TRANSFER_TIMEOUT,
+                    mConnectionId, -1, mReleasing.mReleasingIds,
+                    mReleasing.mReleasedIds);
+            return false;
+        }
+    }
+    return false;
+}
+
+bool BufferPoolClient::Impl::postReceiveResult(
+        BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync) {
+    std::lock_guard<std::mutex> lock(mReleasing.mLock);
+    // TODO: retry, add timeout
+    bool ret = mReleasing.mStatusChannel->postBufferStatusMessage(
+            transactionId, bufferId,
+            result ? BufferStatus::TRANSFER_OK : BufferStatus::TRANSFER_ERROR,
+            mConnectionId, -1, mReleasing.mReleasingIds,
+            mReleasing.mReleasedIds);
+    *needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
+    return ret;
+}
+
+void BufferPoolClient::Impl::trySyncFromRemote() {
+    if (mRemoteSyncLock.try_lock()) {
+        bool needsSync = false;
+        {
+            std::lock_guard<std::mutex> lock(mReleasing.mLock);
+            needsSync = mReleasing.mStatusChannel->needsSync();
+        }
+        if (needsSync) {
+            if (!mRemoteConnection->sync().isOk()) {
+                ALOGD("sync from client %lld failed: bufferpool process died.",
+                      (long long)mConnectionId);
+            }
+        }
+        mRemoteSyncLock.unlock();
+    }
+}
+
+// should have mCache.mLock
+bool BufferPoolClient::Impl::syncReleased(uint32_t messageId) {
+    bool cleared = false;
+    {
+        std::lock_guard<std::mutex> lock(mReleasing.mLock);
+        if (mReleasing.mReleasingIds.size() > 0) {
+            mReleasing.mStatusChannel->postBufferRelease(
+                    mConnectionId, mReleasing.mReleasingIds,
+                    mReleasing.mReleasedIds);
+        }
+        if (mReleasing.mReleasedIds.size() > 0) {
+            for (BufferId& id: mReleasing.mReleasedIds) {
+                ALOGV("client release buffer %lld - %u", (long long)mConnectionId, id);
+                auto found = mCache.mBuffers.find(id);
+                if (found != mCache.mBuffers.end()) {
+                    if (found->second->onCacheRelease()) {
+                        mCache.decActive_l();
+                    } else {
+                        // should not happen!
+                        ALOGW("client %lld cache release status inconsistent!",
+                            (long long)mConnectionId);
+                    }
+                } else {
+                    // should not happen!
+                    ALOGW("client %lld cache status inconsistent!", (long long)mConnectionId);
+                }
+            }
+            mReleasing.mReleasedIds.clear();
+            cleared = true;
+        }
+    }
+    std::vector<BufferInvalidationMessage> invalidations;
+    mInvalidationListener->getInvalidations(invalidations);
+    uint32_t lastMsgId = 0;
+    if (invalidations.size() > 0) {
+        for (auto it = invalidations.begin(); it != invalidations.end(); ++it) {
+            if (it->messageId != 0) {
+                lastMsgId = it->messageId;
+            }
+            if (it->fromBufferId == it->toBufferId) {
+                // TODO: handle fromBufferId = UINT32_MAX
+                invalidateBuffer(it->fromBufferId);
+            } else {
+                invalidateRange(it->fromBufferId, it->toBufferId);
+            }
+        }
+    }
+    {
+        std::lock_guard<std::mutex> lock(mReleasing.mLock);
+        if (lastMsgId != 0) {
+            if (isMessageLater(lastMsgId, mReleasing.mInvalidateId)) {
+                mReleasing.mInvalidateId = lastMsgId;
+                mReleasing.mInvalidateAck = false;
+            }
+        } else if (messageId != 0) {
+            // messages are drained.
+            if (isMessageLater(messageId, mReleasing.mInvalidateId)) {
+                mReleasing.mInvalidateId = messageId;
+                mReleasing.mInvalidateAck = true;
+            }
+        }
+        if (!mReleasing.mInvalidateAck) {
+            // post ACK
+            mReleasing.mStatusChannel->postBufferInvalidateAck(
+                    mConnectionId,
+                    mReleasing.mInvalidateId, &mReleasing.mInvalidateAck);
+            ALOGV("client %lld invalidateion ack (%d) %u",
+                (long long)mConnectionId,
+                mReleasing.mInvalidateAck, mReleasing.mInvalidateId);
+        }
+    }
+    return cleared;
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::evictCaches(bool clearCache) {
+    int64_t now = ::android::elapsedRealtime();
+    if (now >= mLastEvictCacheMs + kCacheTtlMs ||
+            clearCache || mCache.cachedBufferCount() > kMaxCachedBufferCount) {
+        size_t evicted = 0;
+        for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
+            if (!it->second->hasCache() && (it->second->expire() ||
+                        clearCache || mCache.cachedBufferCount() > kCachedBufferCountTarget)) {
+                it = mCache.mBuffers.erase(it);
+                ++evicted;
+            } else {
+                ++it;
+            }
+        }
+        ALOGV("cache count %lld : total %zu, active %d, evicted %zu",
+              (long long)mConnectionId, mCache.mBuffers.size(), mCache.mActive, evicted);
+        mLastEvictCacheMs = now;
+    }
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::invalidateBuffer(BufferId id) {
+    for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end(); ++it) {
+        if (id == it->second->id()) {
+            if (!it->second->hasCache()) {
+                mCache.mBuffers.erase(it);
+                ALOGV("cache invalidated %lld : buffer %u",
+                      (long long)mConnectionId, id);
+            } else {
+                ALOGW("Inconsistent invalidation %lld : activer buffer!! %u",
+                      (long long)mConnectionId, (unsigned int)id);
+            }
+            break;
+        }
+    }
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::invalidateRange(BufferId from, BufferId to) {
+    size_t invalidated = 0;
+    for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
+        if (!it->second->hasCache()) {
+            BufferId bid = it->second->id();
+            if (from < to) {
+                if (from <= bid && bid < to) {
+                    ++invalidated;
+                    it = mCache.mBuffers.erase(it);
+                    continue;
+                }
+            } else {
+                if (from <= bid || bid < to) {
+                    ++invalidated;
+                    it = mCache.mBuffers.erase(it);
+                    continue;
+                }
+            }
+        }
+        ++it;
+    }
+    ALOGV("cache invalidated %lld : # of invalidated %zu",
+          (long long)mConnectionId, invalidated);
+}
+
+BufferPoolStatus BufferPoolClient::Impl::allocateBufferHandle(
+        const std::vector<uint8_t>& params, BufferId *bufferId,
+        native_handle_t** handle) {
+    if (mLocalConnection) {
+        const native_handle_t* allocHandle = nullptr;
+        BufferPoolStatus status = mLocalConnection->allocate(
+                params, bufferId, &allocHandle);
+        if (status == ResultStatus::OK) {
+            *handle = native_handle_clone(allocHandle);
+        }
+        ALOGV("client allocate result %lld %d : %u clone %p",
+              (long long)mConnectionId, status == ResultStatus::OK,
+              *handle ? *bufferId : 0 , *handle);
+        return status;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus BufferPoolClient::Impl::fetchBufferHandle(
+        TransactionId transactionId, BufferId bufferId,
+        native_handle_t **handle) {
+    std::shared_ptr<IConnection> connection;
+    if (mLocal) {
+        connection = mLocalConnection;
+    } else {
+        connection = mRemoteConnection;
+    }
+    std::vector<FetchInfo> infos;
+    std::vector<FetchResult> results;
+    infos.emplace_back(FetchInfo{ToAidl(transactionId), ToAidl(bufferId)});
+    ndk::ScopedAStatus status = connection->fetch(infos, &results);
+    if (!status.isOk()) {
+        BufferPoolStatus svcSpecific = status.getServiceSpecificError();
+        return svcSpecific ? svcSpecific : ResultStatus::CRITICAL_ERROR;
+    }
+    if (results[0].getTag() == FetchResult::buffer) {
+        *handle = ::android::dupFromAidl(results[0].get<FetchResult::buffer>().buffer);
+        return ResultStatus::OK;
+    }
+    return results[0].get<FetchResult::failure>();
+}
+
+
+BufferPoolClient::BufferPoolClient(const std::shared_ptr<Accessor> &accessor,
+                                   const std::shared_ptr<IObserver> &observer) {
+    mImpl = std::make_shared<Impl>(accessor, observer);
+}
+
+BufferPoolClient::BufferPoolClient(const std::shared_ptr<IAccessor> &accessor,
+                                   const std::shared_ptr<IObserver> &observer) {
+    mImpl = std::make_shared<Impl>(accessor, observer);
+}
+
+BufferPoolClient::~BufferPoolClient() {
+    // TODO: how to handle orphaned buffers?
+}
+
+bool BufferPoolClient::isValid() {
+    return mImpl && mImpl->isValid();
+}
+
+bool BufferPoolClient::isLocal() {
+    return mImpl && mImpl->isLocal();
+}
+
+bool BufferPoolClient::isActive(int64_t *lastTransactionMs, bool clearCache) {
+    if (!isValid()) {
+        *lastTransactionMs = 0;
+        return false;
+    }
+    return mImpl->isActive(lastTransactionMs, clearCache);
+}
+
+ConnectionId BufferPoolClient::getConnectionId() {
+    if (isValid()) {
+        return mImpl->getConnectionId();
+    }
+    return -1;
+}
+
+BufferPoolStatus BufferPoolClient::getAccessor(std::shared_ptr<IAccessor> *accessor) {
+    if (isValid()) {
+        *accessor = mImpl->getAccessor();
+        return ResultStatus::OK;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void BufferPoolClient::receiveInvalidation(uint32_t msgId) {
+    ALOGV("bufferpool2 client recv inv %u", msgId);
+    if (isValid()) {
+        mImpl->receiveInvalidation(msgId);
+    }
+}
+
+BufferPoolStatus BufferPoolClient::flush() {
+    if (isValid()) {
+        return mImpl->flush();
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus BufferPoolClient::allocate(
+        const std::vector<uint8_t> &params,
+        native_handle_t **handle,
+        std::shared_ptr<BufferPoolData> *buffer) {
+    if (isValid()) {
+        return mImpl->allocate(params, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus BufferPoolClient::receive(
+        TransactionId transactionId, BufferId bufferId, int64_t timestampMs,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    if (isValid()) {
+        return mImpl->receive(transactionId, bufferId, timestampMs, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus BufferPoolClient::postSend(
+        ConnectionId receiverId,
+        const std::shared_ptr<BufferPoolData> &buffer,
+        TransactionId *transactionId,
+        int64_t *timestampMs) {
+    if (isValid()) {
+        bool result = mImpl->postSend(
+                buffer->mId, receiverId, transactionId, timestampMs);
+        return result ? ResultStatus::OK : ResultStatus::CRITICAL_ERROR;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.h b/media/bufferpool/aidl/default/BufferPoolClient.h
new file mode 100644
index 0000000..80fd43e
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPoolClient.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <aidl/android/hardware/media/bufferpool2/IAccessor.h>
+#include <aidl/android/hardware/media/bufferpool2/IObserver.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::IAccessor;
+using aidl::android::hardware::media::bufferpool2::IObserver;
+
+struct Accessor;
+
+/**
+ * A buffer pool client for a buffer pool. For a specific buffer pool, at most
+ * one buffer pool client exists per process. This class will not be exposed
+ * outside. A buffer pool client will be used via ClientManager.
+ */
+class BufferPoolClient {
+public:
+    /**
+     * Creates a buffer pool client from a local buffer pool
+     * (via ClientManager#create).
+     */
+    explicit BufferPoolClient(const std::shared_ptr<Accessor> &accessor,
+                              const std::shared_ptr<IObserver> &observer);
+
+    /**
+     * Creates a buffer pool client from a remote buffer pool
+     * (via ClientManager#registerSender).
+     * Note: A buffer pool client created with remote buffer pool cannot
+     * allocate a buffer.
+     */
+    explicit BufferPoolClient(const std::shared_ptr<IAccessor> &accessor,
+                              const std::shared_ptr<IObserver> &observer);
+
+    /** Destructs a buffer pool client. */
+    ~BufferPoolClient();
+
+private:
+    bool isValid();
+
+    bool isLocal();
+
+    bool isActive(int64_t *lastTransactionMs, bool clearCache);
+
+    ConnectionId getConnectionId();
+
+    BufferPoolStatus getAccessor(std::shared_ptr<IAccessor> *accessor);
+
+    void receiveInvalidation(uint32_t msgId);
+
+    BufferPoolStatus flush();
+
+    BufferPoolStatus allocate(const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    BufferPoolStatus receive(TransactionId transactionId,
+                         BufferId bufferId,
+                         int64_t timestampMs,
+                         native_handle_t **handle,
+                         std::shared_ptr<BufferPoolData> *buffer);
+
+    BufferPoolStatus postSend(ConnectionId receiver,
+                          const std::shared_ptr<BufferPoolData> &buffer,
+                          TransactionId *transactionId,
+                          int64_t *timestampMs);
+
+    class Impl;
+    std::shared_ptr<Impl> mImpl;
+
+    friend struct ClientManager;
+    friend struct Observer;
+};
+
+}  // namespace aidl::android::hardware::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferStatus.cpp b/media/bufferpool/aidl/default/BufferStatus.cpp
new file mode 100644
index 0000000..19caa1e
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferStatus.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlBufferPoolStatus"
+//#define LOG_NDEBUG 0
+
+#include <thread>
+#include <time.h>
+#include <aidl/android/hardware/media/bufferpool2/BufferStatus.h>
+#include "BufferStatus.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::BufferStatus;
+
+bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId) {
+    return curMsgId != prevMsgId && curMsgId - prevMsgId < prevMsgId - curMsgId;
+}
+
+bool isBufferInRange(BufferId from, BufferId to, BufferId bufferId) {
+    if (from < to) {
+        return from <= bufferId && bufferId < to;
+    } else { // wrap happens
+        return from <= bufferId || bufferId < to;
+    }
+}
+
+static constexpr int kNumElementsInQueue = 1024*16;
+static constexpr int kMinElementsToSyncInQueue = 128;
+
+BufferPoolStatus BufferStatusObserver::open(
+        ConnectionId id, StatusDescriptor* fmqDescPtr) {
+    if (mBufferStatusQueues.find(id) != mBufferStatusQueues.end()) {
+        ALOGE("connection id collision %lld", (unsigned long long)id);
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    auto queue = std::make_unique<BufferStatusQueue>(kNumElementsInQueue);
+    if (!queue || queue->isValid() == false) {
+        return ResultStatus::NO_MEMORY;
+    }
+    *fmqDescPtr = queue->dupeDesc();
+    auto result = mBufferStatusQueues.insert(
+            std::make_pair(id, std::move(queue)));
+    if (!result.second) {
+        return ResultStatus::NO_MEMORY;
+    }
+    return ResultStatus::OK;
+}
+
+BufferPoolStatus BufferStatusObserver::close(ConnectionId id) {
+    if (mBufferStatusQueues.find(id) == mBufferStatusQueues.end()) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    mBufferStatusQueues.erase(id);
+    return ResultStatus::OK;
+}
+
+void BufferStatusObserver::getBufferStatusChanges(std::vector<BufferStatusMessage> &messages) {
+    for (auto it = mBufferStatusQueues.begin(); it != mBufferStatusQueues.end(); ++it) {
+        BufferStatusMessage message;
+        size_t avail = it->second->availableToRead();
+        while (avail > 0) {
+            if (!it->second->read(&message, 1)) {
+                // Since available # of reads are already confirmed,
+                // this should not happen.
+                // TODO: error handling (spurious client?)
+                ALOGW("FMQ message cannot be read from %lld", (long long)it->first);
+                return;
+            }
+            message.connectionId = it->first;
+            messages.push_back(message);
+            --avail;
+        }
+    }
+}
+
+BufferStatusChannel::BufferStatusChannel(
+        const StatusDescriptor &fmqDesc) {
+    auto queue = std::make_unique<BufferStatusQueue>(fmqDesc);
+    if (!queue || queue->isValid() == false) {
+        mValid = false;
+        return;
+    }
+    mValid  = true;
+    mBufferStatusQueue = std::move(queue);
+}
+
+bool BufferStatusChannel::isValid() {
+    return mValid;
+}
+
+bool BufferStatusChannel::needsSync() {
+    if (mValid) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        return avail + kMinElementsToSyncInQueue < kNumElementsInQueue;
+    }
+    return false;
+}
+
+void BufferStatusChannel::postBufferRelease(
+        ConnectionId connectionId,
+        std::list<BufferId> &pending, std::list<BufferId> &posted) {
+    if (mValid && pending.size() > 0) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        avail = std::min(avail, pending.size());
+        BufferStatusMessage message;
+        for (size_t i = 0 ; i < avail; ++i) {
+            BufferId id = pending.front();
+            message.status = BufferStatus::NOT_USED;
+            message.bufferId = id;
+            message.connectionId = connectionId;
+            if (!mBufferStatusQueue->write(&message, 1)) {
+                // Since available # of writes are already confirmed,
+                // this should not happen.
+                // TODO: error handing?
+                ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                return;
+            }
+            pending.pop_front();
+            posted.push_back(id);
+        }
+    }
+}
+
+void BufferStatusChannel::postBufferInvalidateAck(
+        ConnectionId connectionId,
+        uint32_t invalidateId,
+        bool *invalidated) {
+    if (mValid && !*invalidated) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        if (avail > 0) {
+            BufferStatusMessage message;
+            message.status = BufferStatus::INVALIDATION_ACK;
+            message.bufferId = invalidateId;
+            message.connectionId = connectionId;
+            if (!mBufferStatusQueue->write(&message, 1)) {
+                // Since available # of writes are already confirmed,
+                // this should not happen.
+                // TODO: error handing?
+                ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                return;
+            }
+            *invalidated = true;
+        }
+    }
+}
+
+bool BufferStatusChannel::postBufferStatusMessage(
+        TransactionId transactionId, BufferId bufferId,
+        BufferStatus status, ConnectionId connectionId, ConnectionId targetId,
+        std::list<BufferId> &pending, std::list<BufferId> &posted) {
+    if (mValid) {
+        size_t avail = mBufferStatusQueue->availableToWrite();
+        size_t numPending = pending.size();
+        if (avail >= numPending + 1) {
+            BufferStatusMessage release, message;
+            for (size_t i = 0; i < numPending; ++i) {
+                BufferId id = pending.front();
+                release.status = BufferStatus::NOT_USED;
+                release.bufferId = id;
+                release.connectionId = connectionId;
+                if (!mBufferStatusQueue->write(&release, 1)) {
+                    // Since available # of writes are already confirmed,
+                    // this should not happen.
+                    // TODO: error handling?
+                    ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                    return false;
+                }
+                pending.pop_front();
+                posted.push_back(id);
+            }
+            message.transactionId = transactionId;
+            message.bufferId = bufferId;
+            message.status = status;
+            message.connectionId = connectionId;
+            message.targetConnectionId = targetId;
+            // TODO : timesatamp
+            message.timestampUs = 0;
+            if (!mBufferStatusQueue->write(&message, 1)) {
+                // Since available # of writes are already confirmed,
+                // this should not happen.
+                ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+                return false;
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+BufferInvalidationListener::BufferInvalidationListener(
+        const InvalidationDescriptor &fmqDesc) {
+    std::unique_ptr<BufferInvalidationQueue> queue =
+            std::make_unique<BufferInvalidationQueue>(fmqDesc);
+    if (!queue || queue->isValid() == false) {
+        mValid = false;
+        return;
+    }
+    mValid  = true;
+    mBufferInvalidationQueue = std::move(queue);
+    // drain previous messages
+    size_t avail = std::min(
+            mBufferInvalidationQueue->availableToRead(), (size_t) kNumElementsInQueue);
+    std::vector<BufferInvalidationMessage> temp(avail);
+    if (avail > 0) {
+        mBufferInvalidationQueue->read(temp.data(), avail);
+    }
+}
+
+void BufferInvalidationListener::getInvalidations(
+        std::vector<BufferInvalidationMessage> &messages) {
+    // Try twice in case of overflow.
+    // TODO: handling overflow though it may not happen.
+    for (int i = 0; i < 2; ++i) {
+        size_t avail = std::min(
+                mBufferInvalidationQueue->availableToRead(), (size_t) kNumElementsInQueue);
+        if (avail > 0) {
+            std::vector<BufferInvalidationMessage> temp(avail);
+            if (mBufferInvalidationQueue->read(temp.data(), avail)) {
+                messages.reserve(messages.size() + avail);
+                for (auto it = temp.begin(); it != temp.end(); ++it) {
+                    messages.push_back(*it);
+                }
+                break;
+            }
+        } else {
+            return;
+        }
+    }
+}
+
+bool BufferInvalidationListener::isValid() {
+    return mValid;
+}
+
+BufferInvalidationChannel::BufferInvalidationChannel()
+    : mValid(true),
+      mBufferInvalidationQueue(
+              std::make_unique<BufferInvalidationQueue>(kNumElementsInQueue, true)) {
+    if (!mBufferInvalidationQueue || mBufferInvalidationQueue->isValid() == false) {
+        mValid = false;
+    }
+}
+
+bool BufferInvalidationChannel::isValid() {
+    return mValid;
+}
+
+void BufferInvalidationChannel::getDesc(InvalidationDescriptor *fmqDescPtr) {
+    if (mValid) {
+        *fmqDescPtr = mBufferInvalidationQueue->dupeDesc();
+    }
+    // TODO: writing invalid descriptor?
+}
+
+void BufferInvalidationChannel::postInvalidation(
+        uint32_t msgId, BufferId fromId, BufferId toId) {
+    BufferInvalidationMessage message;
+
+    message.messageId = msgId;
+    message.fromBufferId = fromId;
+    message.toBufferId = toId;
+    // TODO: handle failure (it does not happen normally.)
+    mBufferInvalidationQueue->write(&message);
+}
+
+}  // namespace ::aidl::android::hardware::media::bufferpool2::implementation
+
diff --git a/media/bufferpool/aidl/default/BufferStatus.h b/media/bufferpool/aidl/default/BufferStatus.h
new file mode 100644
index 0000000..3dd92f4
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferStatus.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <bufferpool2/BufferPoolTypes.h>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <vector>
+#include <list>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId);
+
+bool isBufferInRange(BufferId from, BufferId to, BufferId bufferId);
+
+/**
+ * A collection of buffer status message FMQ for a buffer pool. buffer
+ * ownership/status change messages are sent via the FMQs from the clients.
+ */
+class BufferStatusObserver {
+private:
+    std::map<ConnectionId, std::unique_ptr<BufferStatusQueue>>
+            mBufferStatusQueues;
+
+public:
+    /** Creates a buffer status message FMQ for the specified
+     * connection(client).
+     *
+     * @param connectionId  connection Id of the specified client.
+     * @param fmqDescPtr    ptr of created FMQ's descriptor.
+     *
+     * @return OK if FMQ is created successfully.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus open(ConnectionId id, StatusDescriptor* _Nonnull fmqDescPtr);
+
+    /** Closes a buffer status message FMQ for the specified
+     * connection(client).
+     *
+     * @param connectionId  connection Id of the specified client.
+     *
+     * @return OK if the specified connection is closed successfully.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus close(ConnectionId id);
+
+    /** Retrieves all pending FMQ buffer status messages from clients.
+     *
+     * @param messages  retrieved pending messages.
+     */
+    void getBufferStatusChanges(std::vector<BufferStatusMessage> &messages);
+};
+
+/**
+ * A buffer status message FMQ for a buffer pool client. Buffer ownership/status
+ * change messages are sent via the fmq to the buffer pool.
+ */
+class BufferStatusChannel {
+private:
+    bool mValid;
+    std::unique_ptr<BufferStatusQueue> mBufferStatusQueue;
+
+public:
+    /**
+     * Connects to a buffer status message FMQ from a descriptor of
+     * the created FMQ.
+     *
+     * @param fmqDesc   Descriptor of the created FMQ.
+     */
+    BufferStatusChannel(const StatusDescriptor &fmqDesc);
+
+    /** Returns whether the FMQ is connected successfully. */
+    bool isValid();
+
+    /** Returns whether the FMQ needs to be synced from the buffer pool */
+    bool needsSync();
+
+    /**
+     * Posts a buffer release message to the buffer pool.
+     *
+     * @param connectionId  connection Id of the client.
+     * @param pending       currently pending buffer release messages.
+     * @param posted        posted buffer release messages.
+     */
+    void postBufferRelease(
+            ConnectionId connectionId,
+            std::list<BufferId> &pending, std::list<BufferId> &posted);
+
+    /**
+     * Posts a buffer status message regarding the specified buffer
+     * transfer transaction.
+     *
+     * @param transactionId Id of the specified transaction.
+     * @param bufferId      buffer Id of the specified transaction.
+     * @param status        new status of the buffer.
+     * @param connectionId  connection Id of the client.
+     * @param targetId      connection Id of the receiver(only when the sender
+     *                      posts a status message).
+     * @param pending       currently pending buffer release messages.
+     * @param posted        posted buffer release messages.
+     *
+     * @return {@code true} when the specified message is posted,
+     *         {@code false} otherwise.
+     */
+    bool postBufferStatusMessage(
+            TransactionId transactionId,
+            BufferId bufferId,
+            BufferStatus status,
+            ConnectionId connectionId,
+            ConnectionId targetId,
+            std::list<BufferId> &pending, std::list<BufferId> &posted);
+
+    /**
+     * Posts a buffer invaliadation message to the buffer pool.
+     *
+     * @param connectionId  connection Id of the client.
+     * @param invalidateId  invalidation ack to the buffer pool.
+     *                      if invalidation id is zero, the ack will not be
+     *                      posted.
+     * @param invalidated   sets {@code true} only when the invalidation ack is
+     *                      posted.
+     */
+    void postBufferInvalidateAck(
+            ConnectionId connectionId,
+            uint32_t invalidateId,
+            bool* _Nonnull invalidated);
+};
+
+/**
+ * A buffer invalidation FMQ for a buffer pool client. Buffer invalidation
+ * messages are received via the fmq from the buffer pool. Buffer invalidation
+ * messages are handled as soon as possible.
+ */
+class BufferInvalidationListener {
+private:
+    bool mValid;
+    std::unique_ptr<BufferInvalidationQueue> mBufferInvalidationQueue;
+
+public:
+    /**
+     * Connects to a buffer invalidation FMQ from a descriptor of the created FMQ.
+     *
+     * @param fmqDesc   Descriptor of the created FMQ.
+     */
+    BufferInvalidationListener(const InvalidationDescriptor &fmqDesc);
+
+    /** Retrieves all pending buffer invalidation messages from the buffer pool.
+     *
+     * @param messages  retrieved pending messages.
+     */
+    void getInvalidations(std::vector<BufferInvalidationMessage> &messages);
+
+    /** Returns whether the FMQ is connected successfully. */
+    bool isValid();
+};
+
+/**
+ * A buffer invalidation FMQ for a buffer pool. A buffer pool will send buffer
+ * invalidation messages to the clients via the FMQ. The FMQ is shared among
+ * buffer pool clients.
+ */
+class BufferInvalidationChannel {
+private:
+    bool mValid;
+    std::unique_ptr<BufferInvalidationQueue> mBufferInvalidationQueue;
+
+public:
+    /**
+     * Creates a buffer invalidation FMQ for a buffer pool.
+     */
+    BufferInvalidationChannel();
+
+    /** Returns whether the FMQ is connected successfully. */
+    bool isValid();
+
+    /**
+     * Retrieves the descriptor of a buffer invalidation FMQ. the descriptor may
+     * be passed to the client for buffer invalidation handling.
+     *
+     * @param fmqDescPtr    ptr of created FMQ's descriptor.
+     */
+    void getDesc(InvalidationDescriptor* _Nonnull fmqDescPtr);
+
+    /** Posts a buffer invalidation for invalidated buffers.
+     *
+     * @param msgId     Invalidation message id which is used when clients send
+     *                  acks back via BufferStatusMessage
+     * @param fromId    The start bufferid of the invalidated buffers(inclusive)
+     * @param toId      The end bufferId of the invalidated buffers(inclusive)
+     */
+    void postInvalidation(uint32_t msgId, BufferId fromId, BufferId toId);
+};
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/ClientManager.cpp b/media/bufferpool/aidl/default/ClientManager.cpp
new file mode 100644
index 0000000..de1db50
--- /dev/null
+++ b/media/bufferpool/aidl/default/ClientManager.cpp
@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "AidlBufferPoolMgr"
+//#define LOG_NDEBUG 0
+
+#include <aidl/android/hardware/media/bufferpool2/ResultStatus.h>
+#include <bufferpool2/ClientManager.h>
+
+#include <sys/types.h>
+#include <utils/SystemClock.h>
+#include <unistd.h>
+#include <utils/Log.h>
+
+#include <chrono>
+
+#include "BufferPoolClient.h"
+#include "Observer.h"
+#include "Accessor.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using namespace std::chrono_literals;
+
+using Registration = aidl::android::hardware::media::bufferpool2::IClientManager::Registration;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+
+static constexpr int64_t kRegisterTimeoutMs = 500; // 0.5 sec
+static constexpr int64_t kCleanUpDurationMs = 1000; // TODO: 1 sec tune
+static constexpr int64_t kClientTimeoutMs = 5000; // TODO: 5 secs tune
+
+class ClientManager::Impl {
+public:
+    Impl();
+
+    // BnRegisterSender
+    BufferPoolStatus registerSender(const std::shared_ptr<IAccessor> &accessor,
+                                Registration *pRegistration);
+
+    // BpRegisterSender
+    BufferPoolStatus registerSender(const std::shared_ptr<IClientManager> &receiver,
+                                ConnectionId senderId,
+                                ConnectionId *receiverId,
+                                bool *isNew);
+
+    BufferPoolStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+                        ConnectionId *pConnectionId);
+
+    BufferPoolStatus close(ConnectionId connectionId);
+
+    BufferPoolStatus flush(ConnectionId connectionId);
+
+    BufferPoolStatus allocate(ConnectionId connectionId,
+                          const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    BufferPoolStatus receive(ConnectionId connectionId,
+                         TransactionId transactionId,
+                         BufferId bufferId,
+                         int64_t timestampMs,
+                         native_handle_t **handle,
+                         std::shared_ptr<BufferPoolData> *buffer);
+
+    BufferPoolStatus postSend(ConnectionId receiverId,
+                          const std::shared_ptr<BufferPoolData> &buffer,
+                          TransactionId *transactionId,
+                          int64_t *timestampMs);
+
+    BufferPoolStatus getAccessor(ConnectionId connectionId,
+                             std::shared_ptr<IAccessor> *accessor);
+
+    void cleanUp(bool clearCache = false);
+
+private:
+    // In order to prevent deadlock between multiple locks,
+    // always lock ClientCache.lock before locking ActiveClients.lock.
+    struct ClientCache {
+        // This lock is held for brief duration.
+        // Blocking operation is not performed while holding the lock.
+        std::mutex mMutex;
+        std::list<std::pair<const std::weak_ptr<IAccessor>, const std::weak_ptr<BufferPoolClient>>>
+                mClients;
+        std::condition_variable mConnectCv;
+        bool mConnecting;
+        int64_t mLastCleanUpMs;
+
+        ClientCache() : mConnecting(false), mLastCleanUpMs(::android::elapsedRealtime()) {}
+    } mCache;
+
+    // Active clients which can be retrieved via ConnectionId
+    struct ActiveClients {
+        // This lock is held for brief duration.
+        // Blocking operation is not performed holding the lock.
+        std::mutex mMutex;
+        std::map<ConnectionId, const std::shared_ptr<BufferPoolClient>>
+                mClients;
+    } mActive;
+
+    std::shared_ptr<Observer> mObserver;
+};
+
+ClientManager::Impl::Impl()
+    : mObserver(::ndk::SharedRefBase::make<Observer>()) {}
+
+BufferPoolStatus ClientManager::Impl::registerSender(
+        const std::shared_ptr<IAccessor> &accessor, Registration *pRegistration) {
+    cleanUp();
+    int64_t timeoutMs = ::android::elapsedRealtime() + kRegisterTimeoutMs;
+    do {
+        std::unique_lock<std::mutex> lock(mCache.mMutex);
+        for (auto it = mCache.mClients.begin(); it != mCache.mClients.end(); ++it) {
+            std::shared_ptr<IAccessor> sAccessor = it->first.lock();
+            if (sAccessor && sAccessor.get() == accessor.get()) {
+                const std::shared_ptr<BufferPoolClient> client = it->second.lock();
+                if (client) {
+                    std::lock_guard<std::mutex> lock(mActive.mMutex);
+                    pRegistration->connectionId = client->getConnectionId();
+                    if (mActive.mClients.find(pRegistration->connectionId)
+                            != mActive.mClients.end()) {
+                        ALOGV("register existing connection %lld",
+                              (long long)pRegistration->connectionId);
+                        pRegistration->isNew = false;
+                        return ResultStatus::OK;
+                    }
+                }
+                mCache.mClients.erase(it);
+                break;
+            }
+        }
+        if (!mCache.mConnecting) {
+            mCache.mConnecting = true;
+            lock.unlock();
+            BufferPoolStatus result = ResultStatus::OK;
+            const std::shared_ptr<BufferPoolClient> client =
+                    std::make_shared<BufferPoolClient>(accessor, mObserver);
+            lock.lock();
+            if (!client) {
+                result = ResultStatus::NO_MEMORY;
+            } else if (!client->isValid()) {
+                result = ResultStatus::CRITICAL_ERROR;
+            }
+            if (result == ResultStatus::OK) {
+                // TODO: handle insert fail. (malloc fail)
+                const std::weak_ptr<BufferPoolClient> wclient = client;
+                mCache.mClients.push_back(std::make_pair(accessor, wclient));
+                ConnectionId conId = client->getConnectionId();
+                mObserver->addClient(conId, wclient);
+                {
+                    std::lock_guard<std::mutex> lock(mActive.mMutex);
+                    mActive.mClients.insert(std::make_pair(conId, client));
+                }
+                pRegistration->connectionId = conId;
+                pRegistration->isNew = true;
+                ALOGV("register new connection %lld", (long long)conId);
+            }
+            mCache.mConnecting = false;
+            lock.unlock();
+            mCache.mConnectCv.notify_all();
+            return result;
+        }
+        mCache.mConnectCv.wait_for(lock, kRegisterTimeoutMs*1ms);
+    } while (::android::elapsedRealtime() < timeoutMs);
+    // TODO: return timeout error
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::Impl::registerSender(
+        const std::shared_ptr<IClientManager> &receiver,
+        ConnectionId senderId,
+        ConnectionId *receiverId,
+        bool *isNew) {
+    std::shared_ptr<IAccessor> accessor;
+    bool local = false;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(senderId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        it->second->getAccessor(&accessor);
+        local = it->second->isLocal();
+    }
+    if (accessor) {
+        Registration registration;
+        ::ndk::ScopedAStatus status = receiver->registerSender(accessor, &registration);
+        if (!status.isOk()) {
+            return ResultStatus::CRITICAL_ERROR;
+        } else if (local) {
+            std::shared_ptr<ConnectionDeathRecipient> recipient =
+                    Accessor::getConnectionDeathRecipient();
+            if (recipient)  {
+                ALOGV("client death recipient registered %lld", (long long)*receiverId);
+                recipient->addCookieToConnection(receiver->asBinder().get(), *receiverId);
+                AIBinder_linkToDeath(receiver->asBinder().get(), recipient->getRecipient(),
+                                     receiver->asBinder().get());
+            }
+        }
+        *receiverId = registration.connectionId;
+        *isNew = registration.isNew;
+        return ResultStatus::OK;
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::Impl::create(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        ConnectionId *pConnectionId) {
+    std::shared_ptr<Accessor> accessor = ::ndk::SharedRefBase::make<Accessor>(allocator);
+    if (!accessor || !accessor->isValid()) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    // TODO: observer is local. use direct call instead of hidl call.
+    std::shared_ptr<BufferPoolClient> client =
+            std::make_shared<BufferPoolClient>(accessor, mObserver);
+    if (!client || !client->isValid()) {
+        return ResultStatus::CRITICAL_ERROR;
+    }
+    // Since a new bufferpool is created, evict memories which are used by
+    // existing bufferpools and clients.
+    cleanUp(true);
+    {
+        // TODO: handle insert fail. (malloc fail)
+        std::lock_guard<std::mutex> lock(mCache.mMutex);
+        const std::weak_ptr<BufferPoolClient> wclient = client;
+        mCache.mClients.push_back(std::make_pair(accessor, wclient));
+        ConnectionId conId = client->getConnectionId();
+        mObserver->addClient(conId, wclient);
+        {
+            std::lock_guard<std::mutex> lock(mActive.mMutex);
+            mActive.mClients.insert(std::make_pair(conId, client));
+        }
+        *pConnectionId = conId;
+        ALOGV("create new connection %lld", (long long)*pConnectionId);
+    }
+    return ResultStatus::OK;
+}
+
+BufferPoolStatus ClientManager::Impl::close(ConnectionId connectionId) {
+    std::unique_lock<std::mutex> lock1(mCache.mMutex);
+    std::unique_lock<std::mutex> lock2(mActive.mMutex);
+    auto it = mActive.mClients.find(connectionId);
+    if (it != mActive.mClients.end()) {
+        std::shared_ptr<IAccessor> accessor;
+        it->second->getAccessor(&accessor);
+        std::shared_ptr<BufferPoolClient> closing = it->second;
+        mActive.mClients.erase(connectionId);
+        for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
+            // clean up dead client caches
+            std::shared_ptr<IAccessor> cAccessor = cit->first.lock();
+            if (!cAccessor || (accessor && cAccessor.get() ==  accessor.get())) {
+                cit = mCache.mClients.erase(cit);
+            } else {
+                cit++;
+            }
+        }
+        lock2.unlock();
+        lock1.unlock();
+        closing->flush();
+        return ResultStatus::OK;
+    }
+    return ResultStatus::NOT_FOUND;
+}
+
+BufferPoolStatus ClientManager::Impl::flush(ConnectionId connectionId) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->flush();
+}
+
+BufferPoolStatus ClientManager::Impl::allocate(
+        ConnectionId connectionId, const std::vector<uint8_t> &params,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+#ifdef BUFFERPOOL_CLONE_HANDLES
+    native_handle_t *origHandle;
+    BufferPoolStatus res = client->allocate(params, &origHandle, buffer);
+    if (res != ResultStatus::OK) {
+        return res;
+    }
+    *handle = native_handle_clone(origHandle);
+    if (handle == NULL) {
+        buffer->reset();
+        return ResultStatus::NO_MEMORY;
+    }
+    return ResultStatus::OK;
+#else
+    return client->allocate(params, handle, buffer);
+#endif
+}
+
+BufferPoolStatus ClientManager::Impl::receive(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, int64_t timestampMs,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+#ifdef BUFFERPOOL_CLONE_HANDLES
+    native_handle_t *origHandle;
+    BufferPoolStatus res = client->receive(
+            transactionId, bufferId, timestampMs, &origHandle, buffer);
+    if (res != ResultStatus::OK) {
+        return res;
+    }
+    *handle = native_handle_clone(origHandle);
+    if (handle == NULL) {
+        buffer->reset();
+        return ResultStatus::NO_MEMORY;
+    }
+    return ResultStatus::OK;
+#else
+    return client->receive(transactionId, bufferId, timestampMs, handle, buffer);
+#endif
+}
+
+BufferPoolStatus ClientManager::Impl::postSend(
+        ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
+        TransactionId *transactionId, int64_t *timestampMs) {
+    ConnectionId connectionId = buffer->mConnectionId;
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->postSend(receiverId, buffer, transactionId, timestampMs);
+}
+
+BufferPoolStatus ClientManager::Impl::getAccessor(
+        ConnectionId connectionId, std::shared_ptr<IAccessor> *accessor) {
+    std::shared_ptr<BufferPoolClient> client;
+    {
+        std::lock_guard<std::mutex> lock(mActive.mMutex);
+        auto it = mActive.mClients.find(connectionId);
+        if (it == mActive.mClients.end()) {
+            return ResultStatus::NOT_FOUND;
+        }
+        client = it->second;
+    }
+    return client->getAccessor(accessor);
+}
+
+void ClientManager::Impl::cleanUp(bool clearCache) {
+    int64_t now = ::android::elapsedRealtime();
+    int64_t lastTransactionMs;
+    std::lock_guard<std::mutex> lock1(mCache.mMutex);
+    if (clearCache || mCache.mLastCleanUpMs + kCleanUpDurationMs < now) {
+        std::lock_guard<std::mutex> lock2(mActive.mMutex);
+        int cleaned = 0;
+        for (auto it = mActive.mClients.begin(); it != mActive.mClients.end();) {
+            if (!it->second->isActive(&lastTransactionMs, clearCache)) {
+                if (lastTransactionMs + kClientTimeoutMs < now) {
+                  std::shared_ptr<IAccessor> accessor;
+                    it->second->getAccessor(&accessor);
+                    it = mActive.mClients.erase(it);
+                    ++cleaned;
+                    continue;
+                }
+            }
+            ++it;
+        }
+        for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
+            // clean up dead client caches
+          std::shared_ptr<IAccessor> cAccessor = cit->first.lock();
+            if (!cAccessor) {
+                cit = mCache.mClients.erase(cit);
+            } else {
+                ++cit;
+            }
+        }
+        ALOGV("# of cleaned connections: %d", cleaned);
+        mCache.mLastCleanUpMs = now;
+    }
+}
+
+::ndk::ScopedAStatus ClientManager::registerSender(
+        const std::shared_ptr<IAccessor>& in_bufferPool, Registration* _aidl_return) {
+    BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+    if (mImpl) {
+        status = mImpl->registerSender(in_bufferPool, _aidl_return);
+    }
+    if (status != ResultStatus::OK) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(status);
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+// Methods for local use.
+std::shared_ptr<ClientManager> ClientManager::sInstance;
+std::mutex ClientManager::sInstanceLock;
+
+std::shared_ptr<ClientManager> ClientManager::getInstance() {
+    std::lock_guard<std::mutex> lock(sInstanceLock);
+    if (!sInstance) {
+        sInstance = ::ndk::SharedRefBase::make<ClientManager>();
+        // TODO: configure thread count for threadpool properly
+        // after b/261652496 is resolved.
+    }
+    Accessor::createInvalidator();
+    Accessor::createEvictor();
+    return sInstance;
+}
+
+ClientManager::ClientManager() : mImpl(new Impl()) {}
+
+ClientManager::~ClientManager() {
+}
+
+BufferPoolStatus ClientManager::create(
+        const std::shared_ptr<BufferPoolAllocator> &allocator,
+        ConnectionId *pConnectionId) {
+    if (mImpl) {
+        return mImpl->create(allocator, pConnectionId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::registerSender(
+        const std::shared_ptr<IClientManager> &receiver,
+        ConnectionId senderId,
+        ConnectionId *receiverId,
+        bool *isNew) {
+    if (mImpl) {
+        return mImpl->registerSender(receiver, senderId, receiverId, isNew);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::close(ConnectionId connectionId) {
+    if (mImpl) {
+        return mImpl->close(connectionId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::flush(ConnectionId connectionId) {
+    if (mImpl) {
+        return mImpl->flush(connectionId);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::allocate(
+        ConnectionId connectionId, const std::vector<uint8_t> &params,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    if (mImpl) {
+        return mImpl->allocate(connectionId, params, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::receive(
+        ConnectionId connectionId, TransactionId transactionId,
+        BufferId bufferId, int64_t timestampMs,
+        native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+    if (mImpl) {
+        return mImpl->receive(connectionId, transactionId, bufferId,
+                              timestampMs, handle, buffer);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::postSend(
+        ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
+        TransactionId *transactionId, int64_t* timestampMs) {
+    if (mImpl && buffer) {
+        return mImpl->postSend(receiverId, buffer, transactionId, timestampMs);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void ClientManager::cleanUp() {
+    if (mImpl) {
+        mImpl->cleanUp(true);
+    }
+}
+
+}  // namespace ::aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Connection.cpp b/media/bufferpool/aidl/default/Connection.cpp
new file mode 100644
index 0000000..53d350d
--- /dev/null
+++ b/media/bufferpool/aidl/default/Connection.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "AidlBufferPoolCon"
+//#define LOG_NDEBUG 0
+
+#include <aidlcommonsupport/NativeHandle.h>
+
+#include "Connection.h"
+#include "Accessor.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using Buffer = aidl::android::hardware::media::bufferpool2::Buffer;
+using FetchInfo = aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo;
+using FetchResult = aidl::android::hardware::media::bufferpool2::IConnection::FetchResult;
+
+::ndk::ScopedAStatus Connection::fetch(const std::vector<FetchInfo>& in_fetchInfos,
+                           std::vector<FetchResult>* _aidl_return) {
+    int success = 0;
+    int failure = 0;
+    if (mInitialized && mAccessor) {
+        for (auto it = in_fetchInfos.begin(); it != in_fetchInfos.end(); ++it) {
+            if (fetch(it->transactionId, it->bufferId, _aidl_return)) {
+                success++;
+            } else {
+                failure++;
+            }
+        }
+        if (failure > 0) {
+            ALOGD("total fetch %d, failure %d", success + failure, failure);
+        }
+        return ::ndk::ScopedAStatus::ok();
+    }
+    return ::ndk::ScopedAStatus::fromServiceSpecificError(ResultStatus::CRITICAL_ERROR);
+}
+
+::ndk::ScopedAStatus Connection::sync() {
+    if (mInitialized && mAccessor) {
+        mAccessor->cleanUp(false);
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+
+bool Connection::fetch(TransactionId transactionId, BufferId bufferId,
+                       std::vector<FetchResult> *result) {
+    BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+    const native_handle_t *handle = nullptr;
+    status = mAccessor->fetch(
+            mConnectionId, transactionId, bufferId, &handle);
+    if (status == ResultStatus::OK) {
+        result->emplace_back(FetchResult::make<FetchResult::buffer>());
+        result->back().get<FetchResult::buffer>().id = bufferId;
+        result->back().get<FetchResult::buffer>().buffer = ::android::dupToAidl(handle);
+        return true;
+    }
+    result->emplace_back(FetchResult::make<FetchResult::failure>(status));
+    return false;
+}
+
+Connection::Connection() : mInitialized(false), mConnectionId(-1LL) {}
+
+Connection::~Connection() {
+    if (mInitialized && mAccessor) {
+        mAccessor->close(mConnectionId);
+    }
+}
+
+void Connection::initialize(
+        const std::shared_ptr<Accessor>& accessor, ConnectionId connectionId) {
+    if (!mInitialized) {
+        mAccessor = accessor;
+        mConnectionId = connectionId;
+        mInitialized = true;
+    }
+}
+
+BufferPoolStatus Connection::flush() {
+    if (mInitialized && mAccessor) {
+        return mAccessor->flush();
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus Connection::allocate(
+        const std::vector<uint8_t> &params, BufferId *bufferId,
+        const native_handle_t **handle) {
+    if (mInitialized && mAccessor) {
+        return mAccessor->allocate(mConnectionId, params, bufferId, handle);
+    }
+    return ResultStatus::CRITICAL_ERROR;
+}
+
+void Connection::cleanUp(bool clearCache) {
+    if (mInitialized && mAccessor) {
+        mAccessor->cleanUp(clearCache);
+    }
+}
+
+}  // namespace ::aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Connection.h b/media/bufferpool/aidl/default/Connection.h
new file mode 100644
index 0000000..d8298af
--- /dev/null
+++ b/media/bufferpool/aidl/default/Connection.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+
+#include <aidl/android/hardware/media/bufferpool2/BnConnection.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+struct Accessor;
+
+struct Connection : public BnConnection {
+    // Methods from ::aidl::android::hardware::media::bufferpool2::IConnection.
+    ::ndk::ScopedAStatus fetch(const std::vector<::aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo>& in_fetchInfos, std::vector<::aidl::android::hardware::media::bufferpool2::IConnection::FetchResult>* _aidl_return) override;
+
+    // Methods from ::aidl::android::hardware::media::bufferpool2::IConnection.
+    ::ndk::ScopedAStatus sync() override;
+
+    /**
+     * Invalidates all buffers which are active and/or are ready to be recycled.
+     */
+    BufferPoolStatus flush();
+
+    /**
+     * Allocates a buffer using the specified parameters. Recycles a buffer if
+     * it is possible. The returned buffer can be transferred to other remote
+     * clients(Connection).
+     *
+     * @param params    allocation parameters.
+     * @param bufferId  Id of the allocated buffer.
+     * @param handle    native handle of the allocated buffer.
+     *
+     * @return OK if a buffer is successfully allocated.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus allocate(const std::vector<uint8_t> &params,
+                          BufferId *bufferId, const native_handle_t **handle);
+
+    /**
+     * Processes pending buffer status messages and performs periodic cache cleaning
+     * from bufferpool.
+     *
+     * @param clearCache    if clearCache is true, bufferpool frees all buffers
+     *                      waiting to be recycled.
+     */
+    void cleanUp(bool clearCache);
+
+    /** Destructs a connection. */
+    ~Connection();
+
+    /** Creates a connection. */
+    Connection();
+
+    /**
+     * Initializes with the specified buffer pool and the connection id.
+     * The connection id should be unique in the whole system.
+     *
+     * @param accessor      the specified buffer pool.
+     * @param connectionId  Id.
+     */
+    void initialize(const std::shared_ptr<Accessor> &accessor, ConnectionId connectionId);
+
+    enum : uint32_t {
+        SYNC_BUFFERID = UINT32_MAX,
+    };
+
+private:
+    bool mInitialized;
+    std::shared_ptr<Accessor> mAccessor;
+    ConnectionId mConnectionId;
+
+    bool fetch(
+        uint64_t transactionId,
+        uint32_t bufferId,
+        std::vector<::aidl::android::hardware::media::bufferpool2::IConnection::FetchResult>
+                *result);
+};
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/DataHelper.h b/media/bufferpool/aidl/default/DataHelper.h
new file mode 100644
index 0000000..a90b3c7
--- /dev/null
+++ b/media/bufferpool/aidl/default/DataHelper.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/media/bufferpool2/BufferStatusMessage.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+#include <map>
+#include <set>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool insert(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    auto iter = mapOfSet->find(key);
+    if (iter == mapOfSet->end()) {
+        std::set<U> valueSet{value};
+        mapOfSet->insert(std::make_pair(key, valueSet));
+        return true;
+    } else if (iter->second.find(value)  == iter->second.end()) {
+        iter->second.insert(value);
+        return true;
+    }
+    return false;
+}
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool erase(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    bool ret = false;
+    auto iter = mapOfSet->find(key);
+    if (iter != mapOfSet->end()) {
+        if (iter->second.erase(value) > 0) {
+            ret = true;
+        }
+        if (iter->second.size() == 0) {
+            mapOfSet->erase(iter);
+        }
+    }
+    return ret;
+}
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool contains(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+    auto iter = mapOfSet->find(key);
+    if (iter != mapOfSet->end()) {
+        auto setIter = iter->second.find(value);
+        return setIter != iter->second.end();
+    }
+    return false;
+}
+
+// Buffer data structure for internal BufferPool use.(storage/fetching)
+struct InternalBuffer {
+    BufferId mId;
+    size_t mOwnerCount;
+    size_t mTransactionCount;
+    const std::shared_ptr<BufferPoolAllocation> mAllocation;
+    const size_t mAllocSize;
+    const std::vector<uint8_t> mConfig;
+    bool mInvalidated;
+
+    InternalBuffer(
+            BufferId id,
+            const std::shared_ptr<BufferPoolAllocation> &alloc,
+            const size_t allocSize,
+            const std::vector<uint8_t> &allocConfig)
+            : mId(id), mOwnerCount(0), mTransactionCount(0),
+            mAllocation(alloc), mAllocSize(allocSize), mConfig(allocConfig),
+            mInvalidated(false) {}
+
+    const native_handle_t *handle() {
+        return mAllocation->handle();
+    }
+
+    void invalidate() {
+        mInvalidated = true;
+    }
+};
+
+// Buffer transacion status/message data structure for internal BufferPool use.
+struct TransactionStatus {
+    TransactionId mId;
+    BufferId mBufferId;
+    ConnectionId mSender;
+    ConnectionId mReceiver;
+    BufferStatus mStatus;
+    int64_t mTimestampMs;
+    bool mSenderValidated;
+
+    TransactionStatus(const BufferStatusMessage &message, int64_t timestampMs) {
+        mId = message.transactionId;
+        mBufferId = message.bufferId;
+        mStatus = message.status;
+        mTimestampMs = timestampMs;
+        if (mStatus == BufferStatus::TRANSFER_TO) {
+            mSender = message.connectionId;
+            mReceiver = message.targetConnectionId;
+            mSenderValidated = true;
+        } else {
+            mSender = -1LL;
+            mReceiver = message.connectionId;
+            mSenderValidated = false;
+        }
+    }
+};
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Observer.cpp b/media/bufferpool/aidl/default/Observer.cpp
new file mode 100644
index 0000000..a22e825
--- /dev/null
+++ b/media/bufferpool/aidl/default/Observer.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Observer.h"
+#include "BufferPoolClient.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+Observer::Observer() {
+}
+
+Observer::~Observer() {
+}
+
+::ndk::ScopedAStatus Observer::onMessage(int64_t in_connectionId, int32_t in_msgId) {
+    std::unique_lock<std::mutex> lock(mLock);
+    auto it = mClients.find(in_connectionId);
+    if (it != mClients.end()) {
+        const std::shared_ptr<BufferPoolClient> client = it->second.lock();
+        if (!client) {
+            mClients.erase(it);
+        } else {
+            lock.unlock();
+            client->receiveInvalidation(in_msgId);
+        }
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+void Observer::addClient(ConnectionId connectionId,
+                         const std::weak_ptr<BufferPoolClient> &wclient) {
+    std::lock_guard<std::mutex> lock(mLock);
+    for (auto it = mClients.begin(); it != mClients.end();) {
+        if (!it->second.lock() || it->first == connectionId) {
+            it = mClients.erase(it);
+        } else {
+            ++it;
+        }
+    }
+    mClients.insert(std::make_pair(connectionId, wclient));
+
+}
+
+void Observer::delClient(ConnectionId connectionId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    mClients.erase(connectionId);
+}
+
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Observer.h b/media/bufferpool/aidl/default/Observer.h
new file mode 100644
index 0000000..febb21b
--- /dev/null
+++ b/media/bufferpool/aidl/default/Observer.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <map>
+#include <memory>
+#include <mutex>
+#include <aidl/android/hardware/media/bufferpool2/BnObserver.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+class BufferPoolClient;
+
+struct Observer : public BnObserver {
+    ::ndk::ScopedAStatus onMessage(int64_t in_connectionId, int32_t in_msgId) override;
+
+    ~Observer();
+
+    void addClient(ConnectionId connectionId,
+                   const std::weak_ptr<BufferPoolClient> &wclient);
+
+    void delClient(ConnectionId connectionId);
+
+private:
+    Observer();
+
+    friend class ::ndk::SharedRefBase;
+
+    std::mutex mLock;
+    std::map<ConnectionId, const std::weak_ptr<BufferPoolClient>> mClients;
+};
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
+
diff --git a/media/bufferpool/aidl/default/include/bufferpool2/BufferPoolTypes.h b/media/bufferpool/aidl/default/include/bufferpool2/BufferPoolTypes.h
new file mode 100644
index 0000000..b833362
--- /dev/null
+++ b/media/bufferpool/aidl/default/include/bufferpool2/BufferPoolTypes.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cutils/native_handle.h>
+#include <fmq/AidlMessageQueue.h>
+#include <aidl/android/hardware/media/bufferpool2/BufferStatusMessage.h>
+#include <aidl/android/hardware/media/bufferpool2/BufferInvalidationMessage.h>
+#include <aidl/android/hardware/media/bufferpool2/ResultStatus.h>
+
+namespace aidl::android::hardware::media::bufferpool2 {
+
+struct BufferPoolData {
+    // For local use, to specify a bufferpool (client connection) for buffers.
+    // Retrieved from returned info of IAccessor#connect(android.hardware.media.bufferpool@2.0).
+    int64_t mConnectionId;
+    // BufferId
+    uint32_t mId;
+
+    BufferPoolData() : mConnectionId(0), mId(0) {}
+
+    BufferPoolData(
+            int64_t connectionId, uint32_t id)
+            : mConnectionId(connectionId), mId(id) {}
+
+    ~BufferPoolData() {}
+};
+
+namespace implementation {
+
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
+
+using aidl::android::hardware::media::bufferpool2::BufferStatusMessage;
+using aidl::android::hardware::media::bufferpool2::BufferInvalidationMessage;
+
+typedef uint32_t BufferId;
+typedef uint64_t TransactionId;
+typedef int64_t ConnectionId;
+typedef int32_t BufferPoolStatus;
+
+// AIDL hal description language does not support unsigned.
+int32_t static inline ToAidl(BufferId id) {return static_cast<int32_t>(id);}
+int64_t static inline ToAidl(TransactionId id) {return static_cast<int64_t>(id);}
+
+BufferId static inline FromAidl(int32_t id) {return static_cast<BufferId>(id);}
+TransactionId static inline FromAidl(int64_t id) {return static_cast<TransactionId>(id);}
+
+enum : ConnectionId {
+    INVALID_CONNECTIONID = 0,
+};
+
+typedef ::android::AidlMessageQueue<BufferStatusMessage, SynchronizedReadWrite> BufferStatusQueue;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<BufferStatusMessage, SynchronizedReadWrite>
+        StatusDescriptor;
+
+typedef ::android::AidlMessageQueue<BufferInvalidationMessage, UnsynchronizedWrite>
+        BufferInvalidationQueue;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<BufferInvalidationMessage, UnsynchronizedWrite>
+        InvalidationDescriptor;
+
+/**
+ * Allocation wrapper class for buffer pool.
+ */
+struct BufferPoolAllocation {
+    const native_handle_t *mHandle;
+
+    const native_handle_t *handle() {
+        return mHandle;
+    }
+
+    BufferPoolAllocation(const native_handle_t *handle) : mHandle(handle) {}
+
+    ~BufferPoolAllocation() {};
+};
+
+/**
+ * Allocator wrapper class for buffer pool.
+ */
+class BufferPoolAllocator {
+public:
+
+    /**
+     * Allocate an allocation(buffer) for buffer pool.
+     *
+     * @param params    allocation parameters
+     * @param alloc     created allocation
+     * @param allocSize size of created allocation
+     *
+     * @return OK when an allocation is created successfully.
+     */
+    virtual BufferPoolStatus allocate(
+            const std::vector<uint8_t> &params,
+            std::shared_ptr<BufferPoolAllocation> *alloc,
+            size_t *allocSize) = 0;
+
+    /**
+     * Returns whether allocation parameters of an old allocation are
+     * compatible with new allocation parameters.
+     */
+    virtual bool compatible(const std::vector<uint8_t> &newParams,
+                            const std::vector<uint8_t> &oldParams) = 0;
+
+protected:
+    BufferPoolAllocator() = default;
+
+    virtual ~BufferPoolAllocator() = default;
+};
+
+}  // namespace implementation
+}  // namespace aidl::android::hareware::media::bufferpool2
+
diff --git a/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
new file mode 100644
index 0000000..bff75ba
--- /dev/null
+++ b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/media/bufferpool2/IAccessor.h>
+#include <aidl/android/hardware/media/bufferpool2/BnClientManager.h>
+#include <memory>
+#include "BufferPoolTypes.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::BnClientManager;
+using aidl::android::hardware::media::bufferpool2::IClientManager;
+using aidl::android::hardware::media::bufferpool2::IAccessor;
+
+struct ClientManager : public BnClientManager {
+    // Methods from ::aidl::android::hardware::media::bufferpool2::IClientManager follow.
+    ::ndk::ScopedAStatus registerSender(
+        const std::shared_ptr<IAccessor>& in_bufferPool,
+        ::aidl::android::hardware::media::bufferpool2::IClientManager::Registration* _aidl_return)
+        override;
+
+    /** Gets an instance. */
+    static std::shared_ptr<ClientManager> getInstance();
+
+    /**
+     * Creates a local connection with a newly created buffer pool.
+     *
+     * @param allocator     for new buffer allocation.
+     * @param pConnectionId Id of the created connection. This is
+     *                      system-wide unique.
+     *
+     * @return OK when a buffer pool and a local connection is successfully
+     *         created.
+     *         ResultStatus::NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+                        ConnectionId *pConnectionId);
+
+    /**
+     * Register a created connection as sender for remote process.
+     *
+     * @param receiver      The remote receiving process.
+     * @param senderId      A local connection which will send buffers to.
+     * @param receiverId    Id of the created receiving connection on the receiver
+     *                      process.
+     * @param isNew         @true when the receiving connection is newly created.
+     *
+     * @return OK when the receiving connection is successfully created on the
+     *         receiver process.
+     *         NOT_FOUND when the sender connection was not found.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus registerSender(const std::shared_ptr<IClientManager> &receiver,
+                                ConnectionId senderId,
+                                ConnectionId *receiverId,
+                                bool *isNew);
+
+    /**
+     * Closes the specified connection.
+     *
+     * @param connectionId  The id of the connection.
+     *
+     * @return OK when the connection is closed.
+     *         NOT_FOUND when the specified connection was not found.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus close(ConnectionId connectionId);
+
+    /**
+     * Evicts cached allocations. If it's local connection, release the
+     * previous allocations and do not recycle current active allocations.
+     *
+     * @param connectionId The id of the connection.
+     *
+     * @return OK when the connection is resetted.
+     *         NOT_FOUND when the specified connection was not found.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus flush(ConnectionId connectionId);
+
+    /**
+     * Allocates a buffer from the specified connection. The output parameter
+     * handle is cloned from the internal handle. So it is safe to use directly,
+     * and it should be deleted and destroyed after use.
+     *
+     * @param connectionId  The id of the connection.
+     * @param params        The allocation parameters.
+     * @param handle        The native handle to the allocated buffer. handle
+     *                      should be cloned before use.
+     * @param buffer        The allocated buffer.
+     *
+     * @return OK when a buffer was allocated successfully.
+     *         NOT_FOUND when the specified connection was not found.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus allocate(ConnectionId connectionId,
+                          const std::vector<uint8_t> &params,
+                          native_handle_t **handle,
+                          std::shared_ptr<BufferPoolData> *buffer);
+
+    /**
+     * Receives a buffer for the transaction. The output parameter handle is
+     * cloned from the internal handle. So it is safe to use directly, and it
+     * should be deleted and destoyed after use.
+     *
+     * @param connectionId  The id of the receiving connection.
+     * @param transactionId The id for the transaction.
+     * @param bufferId      The id for the buffer.
+     * @param timestampMs   The timestamp of the buffer is being sent.
+     * @param handle        The native handle to the allocated buffer. handle
+     *                      should be cloned before use.
+     * @param buffer        The received buffer.
+     *
+     * @return OK when a buffer was received successfully.
+     *         NOT_FOUND when the specified connection was not found.
+     *         NO_MEMORY when there is no memory.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus receive(ConnectionId connectionId,
+                         TransactionId transactionId,
+                         BufferId bufferId,
+                         int64_t timestampMs,
+                          native_handle_t **handle,
+                         std::shared_ptr<BufferPoolData> *buffer);
+
+    /**
+     * Posts a buffer transfer transaction to the buffer pool. Sends a buffer
+     * to other remote clients(connection) after this call has been succeeded.
+     *
+     * @param receiverId    The id of the receiving connection.
+     * @param buffer        to transfer
+     * @param transactionId Id of the transfer transaction.
+     * @param timestampMs   The timestamp of the buffer transaction is being
+     *                      posted.
+     *
+     * @return OK when a buffer transaction was posted successfully.
+     *         NOT_FOUND when the sending connection was not found.
+     *         CRITICAL_ERROR otherwise.
+     */
+    BufferPoolStatus postSend(ConnectionId receiverId,
+                          const std::shared_ptr<BufferPoolData> &buffer,
+                          TransactionId *transactionId,
+                          int64_t *timestampMs);
+
+    /**
+     *  Time out inactive lingering connections and close.
+     */
+    void cleanUp();
+
+    /** Destructs the manager of buffer pool clients.  */
+    ~ClientManager();
+private:
+    static std::shared_ptr<ClientManager> sInstance;
+    static std::mutex sInstanceLock;
+
+    class Impl;
+    const std::unique_ptr<Impl> mImpl;
+
+    friend class ::ndk::SharedRefBase;
+
+    ClientManager();
+};
+
+}  // namespace aidl::android::hardware::media::bufferpool2::implementation
+
diff --git a/media/bufferpool/aidl/default/tests/Android.bp b/media/bufferpool/aidl/default/tests/Android.bp
new file mode 100644
index 0000000..549af57
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/Android.bp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_av_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsVndkAidlBufferpool2V1_0TargetSingleTest",
+    test_suites: ["device-tests"],
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "single.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+        "libstagefright_aidl_bufferpool2"
+    ],
+    compile_multilib: "both",
+}
+
+cc_test {
+    name: "VtsVndkAidlBufferpool2V1_0TargetMultiTest",
+    test_suites: ["device-tests"],
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "multi.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+        "libstagefright_aidl_bufferpool2"
+    ],
+    compile_multilib: "both",
+}
+
+cc_test {
+    name: "VtsVndkAidlBufferpool2V1_0TargetCondTest",
+    test_suites: ["device-tests"],
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "allocator.cpp",
+        "cond.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libutils",
+        "android.hardware.media.bufferpool2-V1-ndk",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+        "libstagefright_aidl_bufferpool2"
+    ],
+    compile_multilib: "both",
+}
diff --git a/media/bufferpool/aidl/default/tests/allocator.cpp b/media/bufferpool/aidl/default/tests/allocator.cpp
new file mode 100644
index 0000000..16b33a6
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/allocator.cpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/ashmem.h>
+#include <sys/mman.h>
+#include "allocator.h"
+
+union Params {
+  struct {
+    uint32_t capacity;
+  } data;
+  uint8_t array[0];
+  Params() : data{0} {}
+  Params(uint32_t size)
+      : data{size} {}
+};
+
+
+namespace {
+
+struct HandleAshmem : public native_handle_t {
+  HandleAshmem(int ashmemFd, size_t size)
+    : native_handle_t(cHeader),
+    mFds{ ashmemFd },
+    mInts{ int (size & 0xFFFFFFFF), int((uint64_t(size) >> 32) & 0xFFFFFFFF), kMagic } {}
+
+  int ashmemFd() const { return mFds.mAshmem; }
+  size_t size() const {
+    return size_t(unsigned(mInts.mSizeLo))
+        | size_t(uint64_t(unsigned(mInts.mSizeHi)) << 32);
+  }
+
+  static bool isValid(const native_handle_t * const o);
+
+protected:
+  struct {
+    int mAshmem;
+  } mFds;
+  struct {
+    int mSizeLo;
+    int mSizeHi;
+    int mMagic;
+  } mInts;
+
+private:
+  enum {
+    kMagic = 'ahm\x00',
+    numFds = sizeof(mFds) / sizeof(int),
+    numInts = sizeof(mInts) / sizeof(int),
+    version = sizeof(native_handle_t)
+  };
+  const static native_handle_t cHeader;
+};
+
+const native_handle_t HandleAshmem::cHeader = {
+  HandleAshmem::version,
+  HandleAshmem::numFds,
+  HandleAshmem::numInts,
+  {}
+};
+
+bool HandleAshmem::isValid(const native_handle_t * const o) {
+  if (!o || memcmp(o, &cHeader, sizeof(cHeader))) {
+    return false;
+  }
+  const HandleAshmem *other = static_cast<const HandleAshmem*>(o);
+  return other->mInts.mMagic == kMagic;
+}
+
+class AllocationAshmem {
+private:
+  AllocationAshmem(int ashmemFd, size_t capacity, bool res)
+    : mHandle(ashmemFd, capacity),
+      mInit(res) {}
+
+public:
+  static AllocationAshmem *Alloc(size_t size) {
+    constexpr static const char *kAllocationTag = "bufferpool_test";
+    int ashmemFd = ashmem_create_region(kAllocationTag, size);
+    return new AllocationAshmem(ashmemFd, size, ashmemFd >= 0);
+  }
+
+  ~AllocationAshmem() {
+    if (mInit) {
+      native_handle_close(&mHandle);
+    }
+  }
+
+  const HandleAshmem *handle() {
+    return &mHandle;
+  }
+
+private:
+  HandleAshmem mHandle;
+  bool mInit;
+  // TODO: mapping and map fd
+};
+
+struct AllocationDtor {
+  AllocationDtor(const std::shared_ptr<AllocationAshmem> &alloc)
+      : mAlloc(alloc) {}
+
+  void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
+
+  const std::shared_ptr<AllocationAshmem> mAlloc;
+};
+
+}
+
+void IpcMutex::init() {
+  pthread_mutexattr_t mattr;
+  pthread_mutexattr_init(&mattr);
+  pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
+  pthread_mutex_init(&lock, &mattr);
+  pthread_mutexattr_destroy(&mattr);
+
+  pthread_condattr_t cattr;
+  pthread_condattr_init(&cattr);
+  pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
+  pthread_cond_init(&cond, &cattr);
+  pthread_condattr_destroy(&cattr);
+}
+
+IpcMutex *IpcMutex::Import(void *pMutex) {
+  return reinterpret_cast<IpcMutex *>(pMutex);
+}
+
+
+BufferPoolStatus TestBufferPoolAllocator::allocate(
+    const std::vector<uint8_t> &params,
+    std::shared_ptr<BufferPoolAllocation> *alloc,
+    size_t *allocSize) {
+  Params ashmemParams;
+  memcpy(&ashmemParams, params.data(), std::min(sizeof(Params), params.size()));
+
+  std::shared_ptr<AllocationAshmem> ashmemAlloc =
+      std::shared_ptr<AllocationAshmem>(
+          AllocationAshmem::Alloc(ashmemParams.data.capacity));
+  if (ashmemAlloc) {
+    BufferPoolAllocation *ptr = new BufferPoolAllocation(ashmemAlloc->handle());
+    if (ptr) {
+      *alloc = std::shared_ptr<BufferPoolAllocation>(ptr, AllocationDtor(ashmemAlloc));
+      if (*alloc) {
+          *allocSize = ashmemParams.data.capacity;
+          return ResultStatus::OK;
+      }
+      delete ptr;
+      return ResultStatus::NO_MEMORY;
+    }
+  }
+  return ResultStatus::CRITICAL_ERROR;
+}
+
+bool TestBufferPoolAllocator::compatible(const std::vector<uint8_t> &newParams,
+                                        const std::vector<uint8_t> &oldParams) {
+  size_t newSize = newParams.size();
+  size_t oldSize = oldParams.size();
+  if (newSize == oldSize) {
+    for (size_t i = 0; i < newSize; ++i) {
+      if (newParams[i] != oldParams[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+  return false;
+}
+
+bool TestBufferPoolAllocator::Fill(const native_handle_t *handle, const unsigned char val) {
+  if (!HandleAshmem::isValid(handle)) {
+    return false;
+  }
+  const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+  unsigned char *ptr = (unsigned char *)mmap(
+      NULL, o->size(), PROT_READ|PROT_WRITE, MAP_SHARED, o->ashmemFd(), 0);
+
+  if (ptr != MAP_FAILED) {
+    for (size_t i = 0; i < o->size(); ++i) {
+      ptr[i] = val;
+    }
+    munmap(ptr, o->size());
+    return true;
+  }
+  return false;
+}
+
+bool TestBufferPoolAllocator::Verify(const native_handle_t *handle, const unsigned char val) {
+  if (!HandleAshmem::isValid(handle)) {
+    return false;
+  }
+  const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+  unsigned char *ptr = (unsigned char *)mmap(
+      NULL, o->size(), PROT_READ, MAP_SHARED, o->ashmemFd(), 0);
+
+  if (ptr != MAP_FAILED) {
+    bool res = true;
+    for (size_t i = 0; i < o->size(); ++i) {
+      if (ptr[i] != val) {
+        res = false;
+        break;
+      }
+    }
+    munmap(ptr, o->size());
+    return res;
+  }
+  return false;
+}
+
+bool TestBufferPoolAllocator::MapMemoryForMutex(const native_handle_t *handle, void **mem) {
+  if (!HandleAshmem::isValid(handle)) {
+    return false;
+  }
+  const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+  *mem = mmap(
+      NULL, o->size(), PROT_READ|PROT_WRITE, MAP_SHARED, o->ashmemFd(), 0);
+  if (*mem == MAP_FAILED || *mem == nullptr) {
+    return false;
+  }
+  return true;
+}
+
+bool TestBufferPoolAllocator::UnmapMemoryForMutex(void *mem) {
+  munmap(mem, sizeof(IpcMutex));
+  return true;
+}
+
+void getTestAllocatorParams(std::vector<uint8_t> *params) {
+  constexpr static int kAllocationSize = 1024 * 10;
+  Params ashmemParams(kAllocationSize);
+
+  params->assign(ashmemParams.array, ashmemParams.array + sizeof(ashmemParams));
+}
+
+void getIpcMutexParams(std::vector<uint8_t> *params) {
+  Params ashmemParams(sizeof(IpcMutex));
+
+  params->assign(ashmemParams.array, ashmemParams.array + sizeof(ashmemParams));
+}
diff --git a/media/bufferpool/aidl/default/tests/allocator.h b/media/bufferpool/aidl/default/tests/allocator.h
new file mode 100644
index 0000000..7e7203f
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/allocator.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <pthread.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+using aidl::android::hardware::media::bufferpool2::implementation::
+    BufferPoolStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::
+    BufferPoolAllocation;
+using aidl::android::hardware::media::bufferpool2::implementation::
+    BufferPoolAllocator;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+
+struct IpcMutex {
+  pthread_mutex_t lock;
+  pthread_cond_t cond;
+  int counter = 0;
+  bool signalled = false;
+
+  void init();
+
+  static IpcMutex *Import(void *mem);
+};
+
+// buffer allocator for the tests
+class TestBufferPoolAllocator : public BufferPoolAllocator {
+ public:
+  TestBufferPoolAllocator() {}
+
+  ~TestBufferPoolAllocator() override {}
+
+  BufferPoolStatus allocate(const std::vector<uint8_t> &params,
+                        std::shared_ptr<BufferPoolAllocation> *alloc,
+                        size_t *allocSize) override;
+
+  bool compatible(const std::vector<uint8_t> &newParams,
+                  const std::vector<uint8_t> &oldParams) override;
+
+  static bool Fill(const native_handle_t *handle, const unsigned char val);
+
+  static bool Verify(const native_handle_t *handle, const unsigned char val);
+
+  static bool MapMemoryForMutex(const native_handle_t *handle, void **mem);
+
+  static bool UnmapMemoryForMutex(void *mem);
+};
+
+// retrieve buffer allocator parameters
+void getTestAllocatorParams(std::vector<uint8_t> *params);
+
+void getIpcMutexParams(std::vector<uint8_t> *params);
diff --git a/media/bufferpool/aidl/default/tests/cond.cpp b/media/bufferpool/aidl/default/tests/cond.cpp
new file mode 100644
index 0000000..6d469ce
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/cond.cpp
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_stability.h>
+#include <android-base/logging.h>
+#include <bufferpool2/ClientManager.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <memory>
+#include <vector>
+
+#include "allocator.h"
+
+using aidl::android::hardware::media::bufferpool2::IClientManager;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferId;
+using aidl::android::hardware::media::bufferpool2::implementation::ClientManager;
+using aidl::android::hardware::media::bufferpool2::implementation::ConnectionId;
+using aidl::android::hardware::media::bufferpool2::implementation::TransactionId;
+using aidl::android::hardware::media::bufferpool2::BufferPoolData;
+
+namespace {
+
+const std::string testInstance  = std::string() + ClientManager::descriptor + "/condtest";
+
+// communication message types between processes.
+enum PipeCommand : int32_t {
+    INIT_OK = 0,
+    INIT_ERROR,
+    SEND,
+    RECEIVE_OK,
+    RECEIVE_ERROR,
+};
+
+// communication message between processes.
+union PipeMessage {
+    struct  {
+        int32_t command;
+        BufferId bufferId;
+        ConnectionId connectionId;
+        TransactionId transactionId;
+        int64_t  timestampUs;
+    } data;
+    char array[0];
+};
+
+constexpr int kSignalInt = 200;
+
+// media.bufferpool test setup
+class BufferpoolMultiTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    BufferPoolStatus status;
+    mReceiverPid = -1;
+    mConnectionValid = false;
+
+    ASSERT_TRUE(pipe(mCommandPipeFds) == 0);
+    ASSERT_TRUE(pipe(mResultPipeFds) == 0);
+
+    mReceiverPid = fork();
+    ASSERT_TRUE(mReceiverPid >= 0);
+
+    if (mReceiverPid == 0) {
+      doReceiver();
+      // In order to ignore gtest behaviour, wait for being killed from
+      // tearDown
+      pause();
+    }
+
+    mManager = ClientManager::getInstance();
+    ASSERT_NE(mManager, nullptr);
+
+    mAllocator = std::make_shared<TestBufferPoolAllocator>();
+    ASSERT_TRUE((bool)mAllocator);
+
+    status = mManager->create(mAllocator, &mConnectionId);
+    ASSERT_TRUE(status == ResultStatus::OK);
+    mConnectionValid = true;
+  }
+
+  virtual void TearDown() override {
+    if (mReceiverPid > 0) {
+      kill(mReceiverPid, SIGKILL);
+      int wstatus;
+      wait(&wstatus);
+    }
+
+    if (mConnectionValid) {
+      mManager->close(mConnectionId);
+    }
+  }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
+
+  std::shared_ptr<ClientManager> mManager;
+  std::shared_ptr<BufferPoolAllocator> mAllocator;
+  bool mConnectionValid;
+  ConnectionId mConnectionId;
+  pid_t mReceiverPid;
+  int mCommandPipeFds[2];
+  int mResultPipeFds[2];
+
+  bool sendMessage(int *pipes, const PipeMessage &message) {
+    int ret = write(pipes[1], message.array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  bool receiveMessage(int *pipes, PipeMessage *message) {
+    int ret = read(pipes[0], message->array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  void doReceiver() {
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    PipeMessage message;
+    mManager = ClientManager::getInstance();
+    if (!mManager) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    auto binder = mManager->asBinder();
+    AIBinder_forceDowngradeToSystemStability(binder.get());
+    binder_status_t status =
+        AServiceManager_addService(binder.get(), testInstance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+    if (status != android::OK) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    message.data.command = PipeCommand::INIT_OK;
+    sendMessage(mResultPipeFds, message);
+
+    int val = 0;
+    receiveMessage(mCommandPipeFds, &message);
+    {
+      native_handle_t *rhandle = nullptr;
+      std::shared_ptr<BufferPoolData> rbuffer;
+      void *mem = nullptr;
+      IpcMutex *mutex = nullptr;
+      BufferPoolStatus status = mManager->receive(
+          message.data.connectionId, message.data.transactionId,
+          message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
+      mManager->close(message.data.connectionId);
+      if (status != ResultStatus::OK) {
+          message.data.command = PipeCommand::RECEIVE_ERROR;
+          sendMessage(mResultPipeFds, message);
+          return;
+      }
+      if (!TestBufferPoolAllocator::MapMemoryForMutex(rhandle, &mem)) {
+          message.data.command = PipeCommand::RECEIVE_ERROR;
+          sendMessage(mResultPipeFds, message);
+          return;
+      }
+      mutex = IpcMutex::Import(mem);
+      pthread_mutex_lock(&(mutex->lock));
+      while (mutex->signalled != true) {
+          pthread_cond_wait(&(mutex->cond), &(mutex->lock));
+      }
+      val = mutex->counter;
+      pthread_mutex_unlock(&(mutex->lock));
+
+      (void)TestBufferPoolAllocator::UnmapMemoryForMutex(mem);
+      if (rhandle) {
+        native_handle_close(rhandle);
+        native_handle_delete(rhandle);
+      }
+    }
+    if (val == kSignalInt) {
+      message.data.command = PipeCommand::RECEIVE_OK;
+    } else {
+      message.data.command = PipeCommand::RECEIVE_ERROR;
+    }
+    sendMessage(mResultPipeFds, message);
+  }
+};
+
+// Buffer transfer test between processes.
+TEST_F(BufferpoolMultiTest, TransferBuffer) {
+  BufferPoolStatus status;
+  PipeMessage message;
+
+  ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
+  ABinderProcess_setThreadPoolMaxThreadCount(1);
+  ABinderProcess_startThreadPool();
+
+
+  std::shared_ptr<IClientManager> receiver =
+      IClientManager::fromBinder(
+          ndk::SpAIBinder(AServiceManager_waitForService(testInstance.c_str())));
+  ASSERT_NE(receiver, nullptr);
+  ConnectionId receiverId;
+
+  bool isNew = true;
+  status = mManager->registerSender(receiver, mConnectionId, &receiverId, &isNew);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  {
+    native_handle_t *shandle = nullptr;
+    std::shared_ptr<BufferPoolData> sbuffer;
+    TransactionId transactionId;
+    int64_t postUs;
+    std::vector<uint8_t> vecParams;
+    void *mem = nullptr;
+    IpcMutex *mutex = nullptr;
+
+    getIpcMutexParams(&vecParams);
+    status = mManager->allocate(mConnectionId, vecParams, &shandle, &sbuffer);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    ASSERT_TRUE(TestBufferPoolAllocator::MapMemoryForMutex(shandle, &mem));
+
+    mutex = new(mem) IpcMutex();
+    mutex->init();
+
+    status = mManager->postSend(receiverId, sbuffer, &transactionId, &postUs);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    message.data.command = PipeCommand::SEND;
+    message.data.bufferId = sbuffer->mId;
+    message.data.connectionId = receiverId;
+    message.data.transactionId = transactionId;
+    message.data.timestampUs = postUs;
+    sendMessage(mCommandPipeFds, message);
+    for (int i=0; i < 200000000; ++i) {
+      // no-op in order to ensure
+      // pthread_cond_wait is called before pthread_cond_signal
+    }
+    pthread_mutex_lock(&(mutex->lock));
+    mutex->counter = kSignalInt;
+    mutex->signalled = true;
+    pthread_cond_signal(&(mutex->cond));
+    pthread_mutex_unlock(&(mutex->lock));
+    (void)TestBufferPoolAllocator::UnmapMemoryForMutex(mem);
+    if (shandle) {
+      native_handle_close(shandle);
+      native_handle_delete(shandle);
+    }
+  }
+  EXPECT_TRUE(receiveMessage(mResultPipeFds, &message));
+  EXPECT_TRUE(message.data.command == PipeCommand::RECEIVE_OK);
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/media/bufferpool/aidl/default/tests/multi.cpp b/media/bufferpool/aidl/default/tests/multi.cpp
new file mode 100644
index 0000000..8806eb0
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/multi.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_stability.h>
+#include <android-base/logging.h>
+#include <bufferpool2/ClientManager.h>
+
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <memory>
+#include <vector>
+
+#include "allocator.h"
+
+using aidl::android::hardware::media::bufferpool2::IClientManager;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferId;
+using aidl::android::hardware::media::bufferpool2::implementation::ClientManager;
+using aidl::android::hardware::media::bufferpool2::implementation::ConnectionId;
+using aidl::android::hardware::media::bufferpool2::implementation::TransactionId;
+using aidl::android::hardware::media::bufferpool2::BufferPoolData;
+
+namespace {
+
+const std::string testInstance  = std::string() + ClientManager::descriptor + "/multitest";
+
+// communication message types between processes.
+enum PipeCommand : int32_t {
+    INIT_OK = 0,
+    INIT_ERROR,
+    SEND,
+    RECEIVE_OK,
+    RECEIVE_ERROR,
+};
+
+// communication message between processes.
+union PipeMessage {
+    struct  {
+        int32_t command;
+        BufferId bufferId;
+        ConnectionId connectionId;
+        TransactionId transactionId;
+        int64_t  timestampUs;
+    } data;
+    char array[0];
+};
+
+// media.bufferpool test setup
+class BufferpoolMultiTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    BufferPoolStatus status;
+    mReceiverPid = -1;
+    mConnectionValid = false;
+
+    ASSERT_TRUE(pipe(mCommandPipeFds) == 0);
+    ASSERT_TRUE(pipe(mResultPipeFds) == 0);
+
+    mReceiverPid = fork();
+    ASSERT_TRUE(mReceiverPid >= 0);
+
+    if (mReceiverPid == 0) {
+      doReceiver();
+      // In order to ignore gtest behaviour, wait for being killed from
+      // tearDown
+      pause();
+    }
+    mManager = ClientManager::getInstance();
+    ASSERT_NE(mManager, nullptr);
+
+    mAllocator = std::make_shared<TestBufferPoolAllocator>();
+    ASSERT_TRUE((bool)mAllocator);
+
+    status = mManager->create(mAllocator, &mConnectionId);
+    ASSERT_TRUE(status == ResultStatus::OK);
+    mConnectionValid = true;
+  }
+
+  virtual void TearDown() override {
+    if (mReceiverPid > 0) {
+      kill(mReceiverPid, SIGKILL);
+      int wstatus;
+      wait(&wstatus);
+    }
+
+    if (mConnectionValid) {
+      mManager->close(mConnectionId);
+    }
+  }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
+
+  std::shared_ptr<ClientManager> mManager;
+  std::shared_ptr<BufferPoolAllocator> mAllocator;
+  bool mConnectionValid;
+  ConnectionId mConnectionId;
+  pid_t mReceiverPid;
+  int mCommandPipeFds[2];
+  int mResultPipeFds[2];
+
+  bool sendMessage(int *pipes, const PipeMessage &message) {
+    int ret = write(pipes[1], message.array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  bool receiveMessage(int *pipes, PipeMessage *message) {
+    int ret = read(pipes[0], message->array, sizeof(PipeMessage));
+    return ret == sizeof(PipeMessage);
+  }
+
+  void doReceiver() {
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    PipeMessage message;
+    mManager = ClientManager::getInstance();
+    if (!mManager) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    auto binder = mManager->asBinder();
+    AIBinder_forceDowngradeToSystemStability(binder.get());
+    binder_status_t status =
+        AServiceManager_addService(binder.get(), testInstance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+    if (status != android::OK) {
+      message.data.command = PipeCommand::INIT_ERROR;
+      sendMessage(mResultPipeFds, message);
+      return;
+    }
+    message.data.command = PipeCommand::INIT_OK;
+    sendMessage(mResultPipeFds, message);
+
+    receiveMessage(mCommandPipeFds, &message);
+    {
+      native_handle_t *rhandle = nullptr;
+      std::shared_ptr<BufferPoolData> rbuffer;
+      BufferPoolStatus status = mManager->receive(
+          message.data.connectionId, message.data.transactionId,
+          message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
+      mManager->close(message.data.connectionId);
+      if (status != ResultStatus::OK) {
+        message.data.command = PipeCommand::RECEIVE_ERROR;
+        sendMessage(mResultPipeFds, message);
+        return;
+      }
+      if (!TestBufferPoolAllocator::Verify(rhandle, 0x77)) {
+        message.data.command = PipeCommand::RECEIVE_ERROR;
+        sendMessage(mResultPipeFds, message);
+        return;
+      }
+      if (rhandle) {
+        native_handle_close(rhandle);
+        native_handle_delete(rhandle);
+      }
+    }
+    message.data.command = PipeCommand::RECEIVE_OK;
+    sendMessage(mResultPipeFds, message);
+  }
+};
+
+// Buffer transfer test between processes.
+TEST_F(BufferpoolMultiTest, TransferBuffer) {
+  BufferPoolStatus status;
+  PipeMessage message;
+
+  ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
+  ABinderProcess_setThreadPoolMaxThreadCount(1);
+  ABinderProcess_startThreadPool();
+
+  std::shared_ptr<IClientManager> receiver = IClientManager::fromBinder(ndk::SpAIBinder(
+      AServiceManager_waitForService(testInstance.c_str())));
+  ASSERT_NE(receiver, nullptr);
+  ConnectionId receiverId;
+
+  bool isNew = true;
+  status = mManager->registerSender(receiver, mConnectionId, &receiverId, &isNew);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  {
+    native_handle_t *shandle = nullptr;
+    std::shared_ptr<BufferPoolData> sbuffer;
+    TransactionId transactionId;
+    int64_t postUs;
+    std::vector<uint8_t> vecParams;
+
+    getTestAllocatorParams(&vecParams);
+    status = mManager->allocate(mConnectionId, vecParams, &shandle, &sbuffer);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    ASSERT_TRUE(TestBufferPoolAllocator::Fill(shandle, 0x77));
+    if (shandle) {
+        native_handle_close(shandle);
+        native_handle_delete(shandle);
+    }
+
+    status = mManager->postSend(receiverId, sbuffer, &transactionId, &postUs);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    message.data.command = PipeCommand::SEND;
+    message.data.bufferId = sbuffer->mId;
+    message.data.connectionId = receiverId;
+    message.data.transactionId = transactionId;
+    message.data.timestampUs = postUs;
+    sendMessage(mCommandPipeFds, message);
+  }
+  EXPECT_TRUE(receiveMessage(mResultPipeFds, &message));
+  EXPECT_TRUE(message.data.command == PipeCommand::RECEIVE_OK);
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/media/bufferpool/aidl/default/tests/single.cpp b/media/bufferpool/aidl/default/tests/single.cpp
new file mode 100644
index 0000000..66aa5e9
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/single.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <bufferpool2/ClientManager.h>
+#include <unistd.h>
+#include <iostream>
+#include <memory>
+#include <vector>
+#include "allocator.h"
+
+using aidl::android::hardware::media::bufferpool2::implementation::BufferId;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferPoolStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::ClientManager;
+using aidl::android::hardware::media::bufferpool2::implementation::ConnectionId;
+using aidl::android::hardware::media::bufferpool2::implementation::TransactionId;
+using aidl::android::hardware::media::bufferpool2::BufferPoolData;
+
+namespace {
+
+// Number of iteration for buffer allocation test.
+constexpr static int kNumAllocationTest = 3;
+
+// Number of iteration for buffer recycling test.
+constexpr static int kNumRecycleTest = 3;
+
+// media.bufferpool test setup
+class BufferpoolSingleTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    BufferPoolStatus status;
+    mConnectionValid = false;
+
+    mManager = ClientManager::getInstance();
+    ASSERT_NE(mManager, nullptr);
+
+    mAllocator = std::make_shared<TestBufferPoolAllocator>();
+    ASSERT_TRUE((bool)mAllocator);
+
+    status = mManager->create(mAllocator, &mConnectionId);
+    ASSERT_TRUE(status == ResultStatus::OK);
+
+    mConnectionValid = true;
+
+    bool isNew = true;
+    status = mManager->registerSender(mManager, mConnectionId, &mReceiverId, &isNew);
+    ASSERT_TRUE(status == ResultStatus::OK && isNew == false &&
+                mReceiverId == mConnectionId);
+  }
+
+  virtual void TearDown() override {
+    if (mConnectionValid) {
+      mManager->close(mConnectionId);
+    }
+  }
+
+ protected:
+  static void description(const std::string& description) {
+    RecordProperty("description", description);
+  }
+
+  std::shared_ptr<ClientManager> mManager;
+  std::shared_ptr<BufferPoolAllocator> mAllocator;
+  bool mConnectionValid;
+  ConnectionId mConnectionId;
+  ConnectionId mReceiverId;
+
+};
+
+// Buffer allocation test.
+// Check whether each buffer allocation is done successfully with
+// unique buffer id.
+TEST_F(BufferpoolSingleTest, AllocateBuffer) {
+  BufferPoolStatus status;
+  std::vector<uint8_t> vecParams;
+  getTestAllocatorParams(&vecParams);
+
+  std::shared_ptr<BufferPoolData> buffer[kNumAllocationTest];
+  native_handle_t *allocHandle = nullptr;
+  for (int i = 0; i < kNumAllocationTest; ++i) {
+    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer[i]);
+    ASSERT_TRUE(status == ResultStatus::OK);
+    if (allocHandle) {
+      native_handle_close(allocHandle);
+      native_handle_delete(allocHandle);
+    }
+  }
+  for (int i = 0; i < kNumAllocationTest; ++i) {
+    for (int j = i + 1; j < kNumAllocationTest; ++j) {
+      ASSERT_TRUE(buffer[i]->mId != buffer[j]->mId);
+    }
+  }
+  EXPECT_TRUE(kNumAllocationTest > 1);
+}
+
+// Buffer recycle test.
+// Check whether de-allocated buffers are recycled.
+TEST_F(BufferpoolSingleTest, RecycleBuffer) {
+  BufferPoolStatus status;
+  std::vector<uint8_t> vecParams;
+  getTestAllocatorParams(&vecParams);
+
+  BufferId bid[kNumRecycleTest];
+  for (int i = 0; i < kNumRecycleTest; ++i) {
+    std::shared_ptr<BufferPoolData> buffer;
+    native_handle_t *allocHandle = nullptr;
+    status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer);
+    ASSERT_TRUE(status == ResultStatus::OK);
+    bid[i] = buffer->mId;
+    if (allocHandle) {
+      native_handle_close(allocHandle);
+      native_handle_delete(allocHandle);
+    }
+  }
+  for (int i = 1; i < kNumRecycleTest; ++i) {
+    ASSERT_TRUE(bid[i - 1] == bid[i]);
+  }
+  EXPECT_TRUE(kNumRecycleTest > 1);
+}
+
+// Buffer transfer test.
+// Check whether buffer is transferred to another client successfully.
+TEST_F(BufferpoolSingleTest, TransferBuffer) {
+  BufferPoolStatus status;
+  std::vector<uint8_t> vecParams;
+  getTestAllocatorParams(&vecParams);
+  std::shared_ptr<BufferPoolData> sbuffer, rbuffer;
+  native_handle_t *allocHandle = nullptr;
+  native_handle_t *recvHandle = nullptr;
+
+  TransactionId transactionId;
+  int64_t postMs;
+
+  status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &sbuffer);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x77));
+  status = mManager->postSend(mReceiverId, sbuffer, &transactionId, &postMs);
+  ASSERT_TRUE(status == ResultStatus::OK);
+  status = mManager->receive(mReceiverId, transactionId, sbuffer->mId, postMs,
+                             &recvHandle, &rbuffer);
+  EXPECT_TRUE(status == ResultStatus::OK);
+  ASSERT_TRUE(TestBufferPoolAllocator::Verify(recvHandle, 0x77));
+
+  if (allocHandle) {
+    native_handle_close(allocHandle);
+    native_handle_delete(allocHandle);
+  }
+  if (recvHandle) {
+    native_handle_close(recvHandle);
+    native_handle_delete(recvHandle);
+  }
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  LOG(INFO) << "Test result = " << status;
+  return status;
+}
diff --git a/memtrack/aidl/Android.bp b/memtrack/aidl/Android.bp
index 79effcb..0d1c241 100644
--- a/memtrack/aidl/Android.bp
+++ b/memtrack/aidl/Android.bp
@@ -39,5 +39,6 @@
             },
         },
     },
+    frozen: true,
     versions: ["1"],
 }
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 29b31d2..8048e62 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -27,7 +27,6 @@
     name: "neuralnetworks_vts_functional_defaults",
     defaults: [
         "VtsHalTargetTestDefaults",
-        "neuralnetworks_float16",
     ],
 }
 
@@ -90,7 +89,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index e9d4b76..7c1c118 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -58,7 +58,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.2/utils/src/BurstUtils.cpp b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
index b589c46..c4c096d 100644
--- a/neuralnetworks/1.2/utils/src/BurstUtils.cpp
+++ b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
@@ -190,12 +190,13 @@
     size_t index = 0;
 
     // validate packet information
-    if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+    if (index >= data.size() ||
+        data.at(index).getDiscriminator() != discriminator::packetInformation) {
         return NN_ERROR() << "FMQ Request packet ill-formed";
     }
 
     // unpackage packet information
-    const FmqRequestDatum::PacketInformation& packetInfo = data[index].packetInformation();
+    const FmqRequestDatum::PacketInformation& packetInfo = data.at(index).packetInformation();
     index++;
     const uint32_t packetSize = packetInfo.packetSize;
     const uint32_t numberOfInputOperands = packetInfo.numberOfInputOperands;
@@ -212,13 +213,14 @@
     inputs.reserve(numberOfInputOperands);
     for (size_t operand = 0; operand < numberOfInputOperands; ++operand) {
         // validate input operand information
-        if (data[index].getDiscriminator() != discriminator::inputOperandInformation) {
+        if (index >= data.size() ||
+            data.at(index).getDiscriminator() != discriminator::inputOperandInformation) {
             return NN_ERROR() << "FMQ Request packet ill-formed";
         }
 
         // unpackage operand information
         const FmqRequestDatum::OperandInformation& operandInfo =
-                data[index].inputOperandInformation();
+                data.at(index).inputOperandInformation();
         index++;
         const bool hasNoValue = operandInfo.hasNoValue;
         const V1_0::DataLocation location = operandInfo.location;
@@ -229,12 +231,13 @@
         dimensions.reserve(numberOfDimensions);
         for (size_t i = 0; i < numberOfDimensions; ++i) {
             // validate dimension
-            if (data[index].getDiscriminator() != discriminator::inputOperandDimensionValue) {
+            if (index >= data.size() ||
+                data.at(index).getDiscriminator() != discriminator::inputOperandDimensionValue) {
                 return NN_ERROR() << "FMQ Request packet ill-formed";
             }
 
             // unpackage dimension
-            const uint32_t dimension = data[index].inputOperandDimensionValue();
+            const uint32_t dimension = data.at(index).inputOperandDimensionValue();
             index++;
 
             // store result
@@ -251,13 +254,14 @@
     outputs.reserve(numberOfOutputOperands);
     for (size_t operand = 0; operand < numberOfOutputOperands; ++operand) {
         // validate output operand information
-        if (data[index].getDiscriminator() != discriminator::outputOperandInformation) {
+        if (index >= data.size() ||
+            data.at(index).getDiscriminator() != discriminator::outputOperandInformation) {
             return NN_ERROR() << "FMQ Request packet ill-formed";
         }
 
         // unpackage operand information
         const FmqRequestDatum::OperandInformation& operandInfo =
-                data[index].outputOperandInformation();
+                data.at(index).outputOperandInformation();
         index++;
         const bool hasNoValue = operandInfo.hasNoValue;
         const V1_0::DataLocation location = operandInfo.location;
@@ -268,12 +272,13 @@
         dimensions.reserve(numberOfDimensions);
         for (size_t i = 0; i < numberOfDimensions; ++i) {
             // validate dimension
-            if (data[index].getDiscriminator() != discriminator::outputOperandDimensionValue) {
+            if (index >= data.size() ||
+                data.at(index).getDiscriminator() != discriminator::outputOperandDimensionValue) {
                 return NN_ERROR() << "FMQ Request packet ill-formed";
             }
 
             // unpackage dimension
-            const uint32_t dimension = data[index].outputOperandDimensionValue();
+            const uint32_t dimension = data.at(index).outputOperandDimensionValue();
             index++;
 
             // store result
@@ -290,12 +295,13 @@
     slots.reserve(numberOfPools);
     for (size_t pool = 0; pool < numberOfPools; ++pool) {
         // validate input operand information
-        if (data[index].getDiscriminator() != discriminator::poolIdentifier) {
+        if (index >= data.size() ||
+            data.at(index).getDiscriminator() != discriminator::poolIdentifier) {
             return NN_ERROR() << "FMQ Request packet ill-formed";
         }
 
         // unpackage operand information
-        const int32_t poolId = data[index].poolIdentifier();
+        const int32_t poolId = data.at(index).poolIdentifier();
         index++;
 
         // store result
@@ -303,17 +309,17 @@
     }
 
     // validate measureTiming
-    if (data[index].getDiscriminator() != discriminator::measureTiming) {
+    if (index >= data.size() || data.at(index).getDiscriminator() != discriminator::measureTiming) {
         return NN_ERROR() << "FMQ Request packet ill-formed";
     }
 
     // unpackage measureTiming
-    const V1_2::MeasureTiming measure = data[index].measureTiming();
+    const V1_2::MeasureTiming measure = data.at(index).measureTiming();
     index++;
 
     // validate packet information
     if (index != packetSize) {
-        return NN_ERROR() << "FMQ Result packet ill-formed";
+        return NN_ERROR() << "FMQ Request packet ill-formed";
     }
 
     // return request
@@ -328,12 +334,13 @@
     size_t index = 0;
 
     // validate packet information
-    if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+    if (index >= data.size() ||
+        data.at(index).getDiscriminator() != discriminator::packetInformation) {
         return NN_ERROR() << "FMQ Result packet ill-formed";
     }
 
     // unpackage packet information
-    const FmqResultDatum::PacketInformation& packetInfo = data[index].packetInformation();
+    const FmqResultDatum::PacketInformation& packetInfo = data.at(index).packetInformation();
     index++;
     const uint32_t packetSize = packetInfo.packetSize;
     const V1_0::ErrorStatus errorStatus = packetInfo.errorStatus;
@@ -349,12 +356,13 @@
     outputShapes.reserve(numberOfOperands);
     for (size_t operand = 0; operand < numberOfOperands; ++operand) {
         // validate operand information
-        if (data[index].getDiscriminator() != discriminator::operandInformation) {
+        if (index >= data.size() ||
+            data.at(index).getDiscriminator() != discriminator::operandInformation) {
             return NN_ERROR() << "FMQ Result packet ill-formed";
         }
 
         // unpackage operand information
-        const FmqResultDatum::OperandInformation& operandInfo = data[index].operandInformation();
+        const FmqResultDatum::OperandInformation& operandInfo = data.at(index).operandInformation();
         index++;
         const bool isSufficient = operandInfo.isSufficient;
         const uint32_t numberOfDimensions = operandInfo.numberOfDimensions;
@@ -364,12 +372,13 @@
         dimensions.reserve(numberOfDimensions);
         for (size_t i = 0; i < numberOfDimensions; ++i) {
             // validate dimension
-            if (data[index].getDiscriminator() != discriminator::operandDimensionValue) {
+            if (index >= data.size() ||
+                data.at(index).getDiscriminator() != discriminator::operandDimensionValue) {
                 return NN_ERROR() << "FMQ Result packet ill-formed";
             }
 
             // unpackage dimension
-            const uint32_t dimension = data[index].operandDimensionValue();
+            const uint32_t dimension = data.at(index).operandDimensionValue();
             index++;
 
             // store result
@@ -381,12 +390,13 @@
     }
 
     // validate execution timing
-    if (data[index].getDiscriminator() != discriminator::executionTiming) {
+    if (index >= data.size() ||
+        data.at(index).getDiscriminator() != discriminator::executionTiming) {
         return NN_ERROR() << "FMQ Result packet ill-formed";
     }
 
     // unpackage execution timing
-    const V1_2::Timing timing = data[index].executionTiming();
+    const V1_2::Timing timing = data.at(index).executionTiming();
     index++;
 
     // validate packet information
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 2177924..7e4b5bb 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -85,7 +85,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
index 3d783d9..fe38e61 100644
--- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
@@ -1262,7 +1262,7 @@
         FILE* pFile = fopen(filename.c_str(), "a");
         uint32_t appendLength = getRandomInt(1, 256);
         for (uint32_t i = 0; i < appendLength; i++) {
-            ASSERT_NE(fputc(getRandomInt<uint8_t>(0, 255), pFile), EOF);
+            ASSERT_NE(fputc(getRandomInt<uint16_t>(0, 255), pFile), EOF);
         }
         fclose(pFile);
         *skip = false;
diff --git a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
index a2013ec..f2cfa3f 100644
--- a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
@@ -1253,7 +1253,7 @@
         FILE* pFile = fopen(filename.c_str(), "a");
         uint32_t appendLength = getRandomInt(1, 256);
         for (uint32_t i = 0; i < appendLength; i++) {
-            ASSERT_NE(fputc(getRandomInt<uint8_t>(0, 255), pFile), EOF);
+            ASSERT_NE(fputc(getRandomInt<uint16_t>(0, 255), pFile), EOF);
         }
         fclose(pFile);
         *skip = false;
diff --git a/neuralnetworks/TEST_MAPPING b/neuralnetworks/TEST_MAPPING
index d296828..3218206 100644
--- a/neuralnetworks/TEST_MAPPING
+++ b/neuralnetworks/TEST_MAPPING
@@ -17,54 +17,10 @@
     },
     {
       "name": "neuralnetworks_utils_hal_aidl_test"
-    },
-    {
-      "name": "VtsHalNeuralnetworksV1_0TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
-    },
-    {
-      "name": "VtsHalNeuralnetworksV1_1TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
     }
   ],
   "presubmit-large": [
     {
-      "name": "VtsHalNeuralnetworksV1_2TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
-    },
-    {
-      "name": "VtsHalNeuralnetworksV1_3TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
-    },
-    {
       "name": "VtsHalNeuralnetworksTargetTest",
       "options": [
         {
diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp
index db1188d..be86879 100644
--- a/neuralnetworks/aidl/Android.bp
+++ b/neuralnetworks/aidl/Android.bp
@@ -17,7 +17,7 @@
     stability: "vintf",
     imports: [
         "android.hardware.common-V2",
-        "android.hardware.graphics.common-V3",
+        "android.hardware.graphics.common-V4",
     ],
     backend: {
         java: {
@@ -40,28 +40,28 @@
             version: "1",
             imports: [
                 "android.hardware.common-V2",
-                "android.hardware.graphics.common-V3",
+                "android.hardware.graphics.common-V4",
             ],
         },
         {
             version: "2",
             imports: [
                 "android.hardware.common-V2",
-                "android.hardware.graphics.common-V3",
+                "android.hardware.graphics.common-V4",
             ],
         },
         {
             version: "3",
             imports: [
                 "android.hardware.common-V2",
-                "android.hardware.graphics.common-V3",
+                "android.hardware.graphics.common-V4",
             ],
         },
         {
             version: "4",
             imports: [
                 "android.hardware.common-V2",
-                "android.hardware.graphics.common-V3",
+                "android.hardware.graphics.common-V4",
             ],
         },
 
diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp
index 3258092..f0b458a 100644
--- a/neuralnetworks/aidl/utils/Android.bp
+++ b/neuralnetworks/aidl/utils/Android.bp
@@ -25,7 +25,10 @@
 
 cc_defaults {
     name: "neuralnetworks_utils_hal_aidl_defaults",
-    defaults: ["neuralnetworks_utils_defaults"],
+    defaults: [
+        "android.hardware.graphics.common-ndk_static",
+        "neuralnetworks_utils_defaults",
+    ],
     srcs: [
         // AIDL utils that a driver may depend on.
         "src/BufferTracker.cpp",
@@ -38,7 +41,6 @@
     export_include_dirs: ["include"],
     cflags: ["-Wthread-safety"],
     static_libs: [
-        "android.hardware.graphics.common-V3-ndk",
         "libaidlcommonsupport",
         "libarect",
         "neuralnetworks_types",
@@ -90,9 +92,9 @@
 // AIDL features can include this cc_defaults to avoid managing dependency versions explicitly.
 cc_defaults {
     name: "neuralnetworks_use_latest_utils_hal_aidl",
+    defaults: ["android.hardware.graphics.common-ndk_static"],
     static_libs: [
         "android.hardware.common-V2-ndk",
-        "android.hardware.graphics.common-V3-ndk",
         "android.hardware.neuralnetworks-V4-ndk",
         "neuralnetworks_utils_hal_aidl",
     ],
diff --git a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
index 7451f7e..da0fe64 100644
--- a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
@@ -1068,7 +1068,7 @@
         FILE* pFile = fopen(filename.c_str(), "a");
         uint32_t appendLength = getRandomInt(1, 256);
         for (uint32_t i = 0; i < appendLength; i++) {
-            ASSERT_NE(fputc(getRandomInt<uint8_t>(0, 255), pFile), EOF);
+            ASSERT_NE(fputc(getRandomInt<uint16_t>(0, 255), pFile), EOF);
         }
         fclose(pFile);
         *skip = false;
diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
index dcf8451..e344458 100644
--- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
@@ -736,8 +736,8 @@
                     // If a sync fence is returned, try start another run waiting for the sync
                     // fence.
                     if (testConfig.reusable) {
-                        ret = execution->executeFenced(waitFor, kNoDeadline, kNoDuration,
-                                                       &executionResult);
+                        // Nothing to do because at most one execution may occur on a reusable
+                        // execution object at any given time.
                     } else if (testConfig.useConfig) {
                         ret = preparedModel->executeFencedWithConfig(
                                 request, waitFor,
diff --git a/nfc/aidl/Android.bp b/nfc/aidl/Android.bp
index b9578f4..09a45d1 100644
--- a/nfc/aidl/Android.bp
+++ b/nfc/aidl/Android.bp
@@ -34,11 +34,6 @@
             sdk_version: "module_current",
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
diff --git a/oemlock/aidl/Android.bp b/oemlock/aidl/Android.bp
index d1930f9..1c19bb1 100644
--- a/oemlock/aidl/Android.bp
+++ b/oemlock/aidl/Android.bp
@@ -16,11 +16,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/oemlock/aidl/default/OemLock.cpp b/oemlock/aidl/default/OemLock.cpp
index 646b532..234a8a9 100644
--- a/oemlock/aidl/default/OemLock.cpp
+++ b/oemlock/aidl/default/OemLock.cpp
@@ -24,29 +24,31 @@
 // Methods from ::android::hardware::oemlock::IOemLock follow.
 
 ::ndk::ScopedAStatus OemLock::getName(std::string *out_name) {
-    (void)out_name;
+    *out_name = "SomeCoolName";
     return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus OemLock::setOemUnlockAllowedByCarrier(bool in_allowed, const std::vector<uint8_t> &in_signature, OemLockSecureStatus *_aidl_return) {
-    (void)in_allowed;
+    // Default impl doesn't care about a valid vendor signature
     (void)in_signature;
-    (void)_aidl_return;
+
+    mAllowedByCarrier = in_allowed;
+    *_aidl_return = OemLockSecureStatus::OK;
     return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus OemLock::isOemUnlockAllowedByCarrier(bool *out_allowed) {
-    (void)out_allowed;
+    *out_allowed = mAllowedByCarrier;
     return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus OemLock::setOemUnlockAllowedByDevice(bool in_allowed) {
-    (void)in_allowed;
+    mAllowedByDevice = in_allowed;
     return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus OemLock::isOemUnlockAllowedByDevice(bool *out_allowed) {
-    (void)out_allowed;
+    *out_allowed = mAllowedByDevice;
     return ::ndk::ScopedAStatus::ok();
 }
 
diff --git a/oemlock/aidl/default/OemLock.h b/oemlock/aidl/default/OemLock.h
index b0df414..9dff21a 100644
--- a/oemlock/aidl/default/OemLock.h
+++ b/oemlock/aidl/default/OemLock.h
@@ -36,6 +36,10 @@
     ::ndk::ScopedAStatus isOemUnlockAllowedByDevice(bool* out_allowed) override;
     ::ndk::ScopedAStatus setOemUnlockAllowedByCarrier(bool in_allowed, const std::vector<uint8_t>& in_signature, OemLockSecureStatus* _aidl_return) override;
     ::ndk::ScopedAStatus setOemUnlockAllowedByDevice(bool in_allowed) override;
+
+  private:
+    bool mAllowedByCarrier = false;
+    bool mAllowedByDevice = false;
 };
 
 } // namespace oemlock
diff --git a/power/OWNERS b/power/OWNERS
new file mode 100644
index 0000000..7229b22
--- /dev/null
+++ b/power/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 826709
+
+# ADPF virtual team
+lpy@google.com
+wvw@google.com
diff --git a/power/TEST_MAPPING b/power/TEST_MAPPING
new file mode 100644
index 0000000..c0963f9
--- /dev/null
+++ b/power/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalPowerTargetTest"
+    }
+  ]
+}
diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp
index e4708f8..082572d 100644
--- a/power/aidl/Android.bp
+++ b/power/aidl/Android.bp
@@ -35,11 +35,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
@@ -54,7 +49,12 @@
             version: "3",
             imports: [],
         },
+        {
+            version: "4",
+            imports: [],
+        },
 
     ],
+    frozen: true,
 
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/4/.hash b/power/aidl/aidl_api/android.hardware.power/4/.hash
new file mode 100644
index 0000000..10f7e2c
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/4/.hash
@@ -0,0 +1 @@
+141ac3bb33bb4f524de020669f12599c18cdd67f
diff --git a/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/Boost.aidl b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/Boost.aidl
new file mode 100644
index 0000000..8ee15ef
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/Boost.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.power;
+@Backing(type="int") @VintfStability
+enum Boost {
+  INTERACTION,
+  DISPLAY_UPDATE_IMMINENT,
+  ML_ACC,
+  AUDIO_LAUNCH,
+  CAMERA_LAUNCH,
+  CAMERA_SHOT,
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/IPower.aidl
new file mode 100644
index 0000000..ae03313
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/IPower.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.power;
+@VintfStability
+interface IPower {
+  oneway void setMode(in android.hardware.power.Mode type, in boolean enabled);
+  boolean isModeSupported(in android.hardware.power.Mode type);
+  oneway void setBoost(in android.hardware.power.Boost type, in int durationMs);
+  boolean isBoostSupported(in android.hardware.power.Boost type);
+  android.hardware.power.IPowerHintSession createHintSession(in int tgid, in int uid, in int[] threadIds, in long durationNanos);
+  long getHintSessionPreferredRate();
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/IPowerHintSession.aidl b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/IPowerHintSession.aidl
new file mode 100644
index 0000000..e6809da
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/IPowerHintSession.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.power;
+@VintfStability
+interface IPowerHintSession {
+  oneway void updateTargetWorkDuration(long targetDurationNanos);
+  oneway void reportActualWorkDuration(in android.hardware.power.WorkDuration[] durations);
+  oneway void pause();
+  oneway void resume();
+  oneway void close();
+  oneway void sendHint(android.hardware.power.SessionHint hint);
+  void setThreads(in int[] threadIds);
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/Mode.aidl b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/Mode.aidl
new file mode 100644
index 0000000..efbb300
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/Mode.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.power;
+@Backing(type="int") @VintfStability
+enum Mode {
+  DOUBLE_TAP_TO_WAKE,
+  LOW_POWER,
+  SUSTAINED_PERFORMANCE,
+  FIXED_PERFORMANCE,
+  VR,
+  LAUNCH,
+  EXPENSIVE_RENDERING,
+  INTERACTIVE,
+  DEVICE_IDLE,
+  DISPLAY_INACTIVE,
+  AUDIO_STREAMING_LOW_LATENCY,
+  CAMERA_STREAMING_SECURE,
+  CAMERA_STREAMING_LOW,
+  CAMERA_STREAMING_MID,
+  CAMERA_STREAMING_HIGH,
+  GAME,
+  GAME_LOADING,
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/SessionHint.aidl b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/SessionHint.aidl
new file mode 100644
index 0000000..9c1f381
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/SessionHint.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@Backing(type="int") @VintfStability
+enum SessionHint {
+  CPU_LOAD_UP = 0,
+  CPU_LOAD_DOWN = 1,
+  CPU_LOAD_RESET = 2,
+  CPU_LOAD_RESUME = 3,
+  POWER_EFFICIENCY = 4,
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/WorkDuration.aidl b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/WorkDuration.aidl
new file mode 100644
index 0000000..e86cd40
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/4/android/hardware/power/WorkDuration.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.power;
+@VintfStability
+parcelable WorkDuration {
+  long timeStampNanos;
+  long durationNanos;
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
index 1d3ecb7..e6809da 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
@@ -39,4 +39,6 @@
   oneway void pause();
   oneway void resume();
   oneway void close();
+  oneway void sendHint(android.hardware.power.SessionHint hint);
+  void setThreads(in int[] threadIds);
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
new file mode 100644
index 0000000..9c1f381
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@Backing(type="int") @VintfStability
+enum SessionHint {
+  CPU_LOAD_UP = 0,
+  CPU_LOAD_DOWN = 1,
+  CPU_LOAD_RESET = 2,
+  CPU_LOAD_RESUME = 3,
+  POWER_EFFICIENCY = 4,
+}
diff --git a/power/aidl/android/hardware/power/IPowerHintSession.aidl b/power/aidl/android/hardware/power/IPowerHintSession.aidl
index c289448..7db0ea1 100644
--- a/power/aidl/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/android/hardware/power/IPowerHintSession.aidl
@@ -16,10 +16,11 @@
 
 package android.hardware.power;
 
+import android.hardware.power.SessionHint;
 import android.hardware.power.WorkDuration;
 
 @VintfStability
-oneway interface IPowerHintSession {
+interface IPowerHintSession {
     /**
      * Updates the desired duration of a previously-created thread group.
      *
@@ -28,7 +29,7 @@
      *
      * @param targetDurationNanos the new desired duration in nanoseconds
      */
-    void updateTargetWorkDuration(long targetDurationNanos);
+    oneway void updateTargetWorkDuration(long targetDurationNanos);
 
     /**
      * Reports the actual duration of a thread group.
@@ -40,20 +41,44 @@
      * @param actualDurationMicros how long the thread group took to complete its
      *        last task in nanoseconds
      */
-    void reportActualWorkDuration(in WorkDuration[] durations);
+    oneway void reportActualWorkDuration(in WorkDuration[] durations);
 
     /**
      * Pause the session when the application is not allowed to send hint in framework.
      */
-    void pause();
+    oneway void pause();
 
     /**
      * Resume the session when the application is allowed to send hint in framework.
      */
-    void resume();
+    oneway void resume();
 
     /**
      * Close the session to release resources.
      */
-    void close();
+    oneway void close();
+
+    /**
+     * Gives information to the PowerHintSession about upcoming or unexpected
+     * changes in load to supplement the normal updateTarget/reportActual cycle.
+     *
+     * @param hint The hint to provide to the PowerHintSession
+     */
+    oneway void sendHint(SessionHint hint);
+
+    /**
+     * Sets a list of threads to the power hint session. This operation will replace
+     * the current list of threads with the given list of threads. If there's already
+     * boost for the replaced threads, a reset must be performed for the replaced
+     * threads. Note that this is not an oneway method.
+     *
+     * @param threadIds The list of threads to be associated
+     * with this session.
+     *
+     * @throws ScopedAStatus Status of the operation. If status code is not
+     *    STATUS_OK, getMessage() must be populated with the human-readable
+     *    error message. If the list of thread ids is empty, EX_ILLEGAL_ARGUMENT
+     *    must be thrown.
+     */
+    void setThreads(in int[] threadIds);
 }
diff --git a/power/aidl/android/hardware/power/SessionHint.aidl b/power/aidl/android/hardware/power/SessionHint.aidl
new file mode 100644
index 0000000..a172e12
--- /dev/null
+++ b/power/aidl/android/hardware/power/SessionHint.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+@VintfStability
+@Backing(type="int")
+enum SessionHint {
+    /**
+     * This hint indicates an increase in CPU workload intensity. It means that
+     * this hint session needs extra CPU resources to meet the target duration.
+     * This hint must be sent before reporting the actual duration to the session.
+     */
+    CPU_LOAD_UP = 0,
+
+    /**
+     * This hint indicates a decrease in CPU workload intensity. It means that
+     * this hint session can reduce CPU resources and still meet the target duration.
+     */
+    CPU_LOAD_DOWN = 1,
+
+    /**
+     * This hint indicates an upcoming CPU workload that is completely changed and
+     * unknown. It means that the hint session should reset CPU resources to a known
+     * baseline to prepare for an arbitrary load, and must wake up if inactive.
+     */
+    CPU_LOAD_RESET = 2,
+
+    /**
+     * This hint indicates that the most recent CPU workload is resuming after a
+     * period of inactivity. It means that the hint session should allocate similar
+     * CPU resources to what was used previously, and must wake up if inactive.
+     */
+    CPU_LOAD_RESUME = 3,
+
+    /**
+     * This hint indicates that this power hint session should be applied with a
+     * power-efficient-first scheduling strategy. This means the work of this
+     * power hint session is noncritical despite its CPU intensity.
+     */
+    POWER_EFFICIENCY = 4,
+}
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index 223b9d5..da91ee6 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -30,11 +30,12 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.power-V3-ndk",
+        "android.hardware.power-V4-ndk",
     ],
     srcs: [
         "main.cpp",
         "Power.cpp",
+        "PowerHintSession.cpp",
     ],
 }
 
diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp
index 7f08f44..8fe370c 100644
--- a/power/aidl/default/Power.cpp
+++ b/power/aidl/default/Power.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "Power.h"
+#include "PowerHintSession.h"
 
 #include <android-base/logging.h>
 
@@ -25,42 +26,53 @@
 namespace impl {
 namespace example {
 
+using namespace std::chrono_literals;
+
+using ndk::ScopedAStatus;
+
 const std::vector<Boost> BOOST_RANGE{ndk::enum_range<Boost>().begin(),
                                      ndk::enum_range<Boost>().end()};
 const std::vector<Mode> MODE_RANGE{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
 
-ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
+ScopedAStatus Power::setMode(Mode type, bool enabled) {
     LOG(VERBOSE) << "Power setMode: " << static_cast<int32_t>(type) << " to: " << enabled;
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) {
+ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) {
     LOG(INFO) << "Power isModeSupported: " << static_cast<int32_t>(type);
     *_aidl_return = type >= MODE_RANGE.front() && type <= MODE_RANGE.back();
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
+ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
     LOG(VERBOSE) << "Power setBoost: " << static_cast<int32_t>(type)
                  << ", duration: " << durationMs;
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) {
+ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) {
     LOG(INFO) << "Power isBoostSupported: " << static_cast<int32_t>(type);
     *_aidl_return = type >= BOOST_RANGE.front() && type <= BOOST_RANGE.back();
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector<int32_t>&, int64_t,
-                                            std::shared_ptr<IPowerHintSession>* _aidl_return) {
-    *_aidl_return = nullptr;
-    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector<int32_t>& tids, int64_t,
+                                       std::shared_ptr<IPowerHintSession>* _aidl_return) {
+    if (tids.size() == 0) {
+        *_aidl_return = nullptr;
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    std::shared_ptr<IPowerHintSession> powerHintSession =
+            ndk::SharedRefBase::make<PowerHintSession>();
+    mPowerHintSessions.push_back(powerHintSession);
+    *_aidl_return = powerHintSession;
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) {
-    *outNanoseconds = -1;
-    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) {
+    *outNanoseconds = std::chrono::nanoseconds(1ms).count();
+    return ScopedAStatus::ok();
 }
 
 }  // namespace example
diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h
index ef6439d..7f8405e 100644
--- a/power/aidl/default/Power.h
+++ b/power/aidl/default/Power.h
@@ -26,6 +26,7 @@
 namespace example {
 
 class Power : public BnPower {
+  public:
     ndk::ScopedAStatus setMode(Mode type, bool enabled) override;
     ndk::ScopedAStatus isModeSupported(Mode type, bool* _aidl_return) override;
     ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override;
@@ -35,6 +36,9 @@
                                          int64_t durationNanos,
                                          std::shared_ptr<IPowerHintSession>* _aidl_return) override;
     ndk::ScopedAStatus getHintSessionPreferredRate(int64_t* outNanoseconds) override;
+
+  private:
+    std::vector<std::shared_ptr<IPowerHintSession>> mPowerHintSessions;
 };
 
 }  // namespace example
diff --git a/power/aidl/default/PowerHintSession.cpp b/power/aidl/default/PowerHintSession.cpp
new file mode 100644
index 0000000..f395800
--- /dev/null
+++ b/power/aidl/default/PowerHintSession.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PowerHintSession.h"
+
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::power::impl::example {
+
+using ndk::ScopedAStatus;
+
+PowerHintSession::PowerHintSession() {}
+
+ScopedAStatus PowerHintSession::updateTargetWorkDuration(int64_t targetDurationNanos) {
+    LOG(VERBOSE) << __func__ << "target duration in nanoseconds: " << targetDurationNanos;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus PowerHintSession::reportActualWorkDuration(
+        const std::vector<WorkDuration>& /* durations */) {
+    LOG(VERBOSE) << __func__;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus PowerHintSession::pause() {
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus PowerHintSession::resume() {
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus PowerHintSession::close() {
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus PowerHintSession::sendHint(SessionHint /* hint */) {
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus PowerHintSession::setThreads(const std::vector<int32_t>& threadIds) {
+    if (threadIds.size() == 0) {
+        LOG(ERROR) << "Error: threadIds.size() shouldn't be " << threadIds.size();
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    return ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/default/PowerHintSession.h b/power/aidl/default/PowerHintSession.h
new file mode 100644
index 0000000..1d74716
--- /dev/null
+++ b/power/aidl/default/PowerHintSession.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/power/BnPowerHintSession.h>
+#include <aidl/android/hardware/power/SessionHint.h>
+#include <aidl/android/hardware/power/WorkDuration.h>
+
+namespace aidl::android::hardware::power::impl::example {
+
+class PowerHintSession : public BnPowerHintSession {
+  public:
+    explicit PowerHintSession();
+    ndk::ScopedAStatus updateTargetWorkDuration(int64_t targetDurationNanos) override;
+    ndk::ScopedAStatus reportActualWorkDuration(
+            const std::vector<WorkDuration>& durations) override;
+    ndk::ScopedAStatus pause() override;
+    ndk::ScopedAStatus resume() override;
+    ndk::ScopedAStatus close() override;
+    ndk::ScopedAStatus sendHint(SessionHint hint) override;
+    ndk::ScopedAStatus setThreads(const std::vector<int32_t>& threadIds) override;
+};
+
+}  // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/default/power-default.xml b/power/aidl/default/power-default.xml
index 927ba22..f5dd6b9 100644
--- a/power/aidl/default/power-default.xml
+++ b/power/aidl/default/power-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.power</name>
-        <version>3</version>
+        <version>4</version>
         <fqname>IPower/default</fqname>
     </hal>
 </manifest>
diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp
index ea398ac..56c98bd 100644
--- a/power/aidl/vts/Android.bp
+++ b/power/aidl/vts/Android.bp
@@ -32,9 +32,10 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.power-V3-ndk",
+        "android.hardware.power-V4-ndk",
     ],
     test_suites: [
+        "general-tests",
         "vts",
     ],
 }
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index 2cfa04a..c2216f8 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -34,12 +34,16 @@
 using android::hardware::power::IPower;
 using android::hardware::power::IPowerHintSession;
 using android::hardware::power::Mode;
+using android::hardware::power::SessionHint;
 using android::hardware::power::WorkDuration;
 
 const std::vector<Boost> kBoosts{ndk::enum_range<Boost>().begin(), ndk::enum_range<Boost>().end()};
 
 const std::vector<Mode> kModes{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
 
+const std::vector<SessionHint> kSessionHints{ndk::enum_range<SessionHint>().begin(),
+                                             ndk::enum_range<SessionHint>().end()};
+
 const std::vector<Boost> kInvalidBoosts = {
         static_cast<Boost>(static_cast<int32_t>(kBoosts.front()) - 1),
         static_cast<Boost>(static_cast<int32_t>(kBoosts.back()) + 1),
@@ -50,6 +54,11 @@
         static_cast<Mode>(static_cast<int32_t>(kModes.back()) + 1),
 };
 
+const std::vector<SessionHint> kInvalidSessionHints = {
+        static_cast<SessionHint>(static_cast<int32_t>(kSessionHints.front()) - 1),
+        static_cast<SessionHint>(static_cast<int32_t>(kSessionHints.back()) + 1),
+};
+
 class DurationWrapper : public WorkDuration {
   public:
     DurationWrapper(int64_t dur, int64_t time) {
@@ -83,6 +92,18 @@
         DurationWrapper(1000000000L, 4L),
 };
 
+// DEVICEs launching with Android 11 MUST meet the requirements for the
+// target-level=5 compatibility_matrix file.
+const uint64_t kCompatibilityMatrix5ApiLevel = 30;
+
+// DEVICEs launching with Android 13 MUST meet the requirements for the
+// target-level=7 compatibility_matrix file.
+const uint64_t kCompatibilityMatrix7ApiLevel = 33;
+
+// DEVICEs launching with Android 14 MUST meet the requirements for the
+// target-level=8 compatibility_matrix file.
+const uint64_t kCompatibilityMatrix8ApiLevel = 34;
+
 inline bool isUnknownOrUnsupported(const ndk::ScopedAStatus& status) {
     return status.getStatus() == STATUS_UNKNOWN_TRANSACTION ||
            status.getExceptionCode() == EX_UNSUPPORTED_OPERATION;
@@ -94,9 +115,13 @@
         AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
         ASSERT_NE(binder, nullptr);
         power = IPower::fromBinder(ndk::SpAIBinder(binder));
+
+        mApiLevel = GetUintProperty<uint64_t>("ro.vendor.api_level", 0);
+        ASSERT_NE(mApiLevel, 0);
     }
 
     std::shared_ptr<IPower> power;
+    uint64_t mApiLevel;
 };
 
 TEST_P(PowerAidl, setMode) {
@@ -152,11 +177,11 @@
 TEST_P(PowerAidl, getHintSessionPreferredRate) {
     int64_t rate = -1;
     auto status = power->getHintSessionPreferredRate(&rate);
-    if (!status.isOk()) {
+    if (mApiLevel < kCompatibilityMatrix7ApiLevel && !status.isOk()) {
         EXPECT_TRUE(isUnknownOrUnsupported(status));
-        return;
+        GTEST_SKIP() << "DEVICE not launching with Android 13 and beyond.";
     }
-
+    ASSERT_TRUE(status.isOk());
     // At least 1ms rate limit from HAL
     ASSERT_GE(rate, 1000000);
 }
@@ -164,10 +189,11 @@
 TEST_P(PowerAidl, createAndCloseHintSession) {
     std::shared_ptr<IPowerHintSession> session;
     auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session);
-    if (!status.isOk()) {
+    if (mApiLevel < kCompatibilityMatrix7ApiLevel && !status.isOk()) {
         EXPECT_TRUE(isUnknownOrUnsupported(status));
-        return;
+        GTEST_SKIP() << "DEVICE not launching with Android 13 and beyond.";
     }
+    ASSERT_TRUE(status.isOk());
     ASSERT_NE(nullptr, session);
     ASSERT_TRUE(session->pause().isOk());
     ASSERT_TRUE(session->resume().isOk());
@@ -175,12 +201,18 @@
     ASSERT_TRUE(session->close().isOk());
     session.reset();
 }
+
 TEST_P(PowerAidl, createHintSessionFailed) {
     std::shared_ptr<IPowerHintSession> session;
     auto status = power->createHintSession(getpid(), getuid(), kEmptyTids, 16666666L, &session);
+
+    // Regardless of whether V2 and beyond is supported, the status is always not STATUS_OK.
     ASSERT_FALSE(status.isOk());
-    if (isUnknownOrUnsupported(status)) {
-        return;
+
+    // If device not launching with Android 13 and beyond, check whether it's supported,
+    // if not, skip the test.
+    if (mApiLevel < kCompatibilityMatrix7ApiLevel && isUnknownOrUnsupported(status)) {
+        GTEST_SKIP() << "DEVICE not launching with Android 13 and beyond.";
     }
     ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
 }
@@ -188,27 +220,62 @@
 TEST_P(PowerAidl, updateAndReportDurations) {
     std::shared_ptr<IPowerHintSession> session;
     auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session);
-    if (!status.isOk()) {
+    if (mApiLevel < kCompatibilityMatrix7ApiLevel && !status.isOk()) {
         EXPECT_TRUE(isUnknownOrUnsupported(status));
-        return;
+        GTEST_SKIP() << "DEVICE not launching with Android 13 and beyond.";
     }
+    ASSERT_TRUE(status.isOk());
     ASSERT_NE(nullptr, session);
 
     ASSERT_TRUE(session->updateTargetWorkDuration(16666667LL).isOk());
     ASSERT_TRUE(session->reportActualWorkDuration(kDurations).isOk());
 }
 
+TEST_P(PowerAidl, sendSessionHint) {
+    std::shared_ptr<IPowerHintSession> session;
+    auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session);
+    if (!status.isOk()) {
+        EXPECT_TRUE(isUnknownOrUnsupported(status));
+        return;
+    }
+    for (const auto& sessionHint : kSessionHints) {
+        ASSERT_TRUE(session->sendHint(sessionHint).isOk());
+    }
+    for (const auto& sessionHint : kInvalidSessionHints) {
+        ASSERT_TRUE(session->sendHint(sessionHint).isOk());
+    }
+}
+
+TEST_P(PowerAidl, setThreads) {
+    std::shared_ptr<IPowerHintSession> session;
+    auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session);
+    if (mApiLevel < kCompatibilityMatrix7ApiLevel && !status.isOk()) {
+        EXPECT_TRUE(isUnknownOrUnsupported(status));
+        GTEST_SKIP() << "DEVICE not launching with Android 13 and beyond.";
+    }
+    ASSERT_TRUE(status.isOk());
+
+    status = session->setThreads(kEmptyTids);
+    if (mApiLevel < kCompatibilityMatrix8ApiLevel && isUnknownOrUnsupported(status)) {
+        GTEST_SKIP() << "DEVICE not launching with Android 14 and beyond.";
+    }
+    ASSERT_FALSE(status.isOk());
+    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+
+    status = session->setThreads(kSelfTids);
+    ASSERT_TRUE(status.isOk());
+}
+
 // FIXED_PERFORMANCE mode is required for all devices which ship on Android 11
 // or later
 TEST_P(PowerAidl, hasFixedPerformance) {
-    auto apiLevel = GetUintProperty<uint64_t>("ro.vendor.api_level", 0);
-    ASSERT_NE(apiLevel, 0);
-
-    if (apiLevel >= 30) {
-        bool supported;
-        ASSERT_TRUE(power->isModeSupported(Mode::FIXED_PERFORMANCE, &supported).isOk());
-        ASSERT_TRUE(supported);
+    if (mApiLevel < kCompatibilityMatrix5ApiLevel) {
+        GTEST_SKIP() << "FIXED_PERFORMANCE mode is only required for all devices launching Android "
+                        "11 or later.";
     }
+    bool supported;
+    ASSERT_TRUE(power->isModeSupported(Mode::FIXED_PERFORMANCE, &supported).isOk());
+    ASSERT_TRUE(supported);
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerAidl);
@@ -217,6 +284,7 @@
                          ::android::PrintInstanceNameToString);
 
 }  // namespace
+}  // namespace aidl::android::hardware::power
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
@@ -224,5 +292,3 @@
     ABinderProcess_startThreadPool();
     return RUN_ALL_TESTS();
 }
-
-}  // namespace aidl::android::hardware::power
diff --git a/power/stats/aidl/Android.bp b/power/stats/aidl/Android.bp
index 48d3c51..43bcfc8 100644
--- a/power/stats/aidl/Android.bp
+++ b/power/stats/aidl/Android.bp
@@ -32,15 +32,22 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
         cpp: {
             enabled: true,
         },
     },
     host_supported: true,
-    versions: ["1"],
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+        {
+            version: "2",
+            imports: [],
+        },
+
+    ],
+    frozen: true,
+
 }
diff --git a/power/stats/aidl/OWNERS b/power/stats/aidl/OWNERS
index b290b49..e0d66d7 100644
--- a/power/stats/aidl/OWNERS
+++ b/power/stats/aidl/OWNERS
@@ -1,3 +1,4 @@
-bsschwar@google.com
+darrenhsu@google.com
+joaodias@google.com
 krossmo@google.com
-tstrudel@google.com
+vincentwang@google.com
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/.hash b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/.hash
new file mode 100644
index 0000000..b715ccb
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/.hash
@@ -0,0 +1 @@
+c3e113101b731c666717eb579492efa287a8f529
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/Channel.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/Channel.aidl
new file mode 100644
index 0000000..d1048a4
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/Channel.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.power.stats;
+@VintfStability
+parcelable Channel {
+  int id;
+  @utf8InCpp String name;
+  @utf8InCpp String subsystem;
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumer.aidl
new file mode 100644
index 0000000..13f528d
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumer.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.power.stats;
+@VintfStability
+parcelable EnergyConsumer {
+  int id;
+  int ordinal;
+  android.hardware.power.stats.EnergyConsumerType type = android.hardware.power.stats.EnergyConsumerType.OTHER;
+  @utf8InCpp String name;
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumerAttribution.aidl
new file mode 100644
index 0000000..ee12068
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumerAttribution.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.power.stats;
+@VintfStability
+parcelable EnergyConsumerAttribution {
+  int uid;
+  long energyUWs;
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumerResult.aidl
new file mode 100644
index 0000000..7d8aa98
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumerResult.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.power.stats;
+@VintfStability
+parcelable EnergyConsumerResult {
+  int id;
+  long timestampMs;
+  long energyUWs;
+  android.hardware.power.stats.EnergyConsumerAttribution[] attribution;
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumerType.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumerType.aidl
new file mode 100644
index 0000000..02b612b
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyConsumerType.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.power.stats;
+@VintfStability
+enum EnergyConsumerType {
+  OTHER,
+  BLUETOOTH,
+  CPU_CLUSTER,
+  DISPLAY,
+  GNSS,
+  MOBILE_RADIO,
+  WIFI,
+  CAMERA,
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyMeasurement.aidl
new file mode 100644
index 0000000..ffe3aa4
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/EnergyMeasurement.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.power.stats;
+@VintfStability
+parcelable EnergyMeasurement {
+  int id;
+  long timestampMs;
+  long durationMs;
+  long energyUWs;
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/IPowerStats.aidl
new file mode 100644
index 0000000..7917515
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/IPowerStats.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.power.stats;
+@VintfStability
+interface IPowerStats {
+  android.hardware.power.stats.PowerEntity[] getPowerEntityInfo();
+  android.hardware.power.stats.StateResidencyResult[] getStateResidency(in int[] powerEntityIds);
+  android.hardware.power.stats.EnergyConsumer[] getEnergyConsumerInfo();
+  android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(in int[] energyConsumerIds);
+  android.hardware.power.stats.Channel[] getEnergyMeterInfo();
+  android.hardware.power.stats.EnergyMeasurement[] readEnergyMeter(in int[] channelIds);
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/PowerEntity.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/PowerEntity.aidl
new file mode 100644
index 0000000..f42e715
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/PowerEntity.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.power.stats;
+@VintfStability
+parcelable PowerEntity {
+  int id;
+  @utf8InCpp String name;
+  android.hardware.power.stats.State[] states;
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/State.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/State.aidl
new file mode 100644
index 0000000..cf29dd7
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/State.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.power.stats;
+@VintfStability
+parcelable State {
+  int id;
+  @utf8InCpp String name;
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/StateResidency.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/StateResidency.aidl
new file mode 100644
index 0000000..0af35b3
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/StateResidency.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.power.stats;
+@VintfStability
+parcelable StateResidency {
+  int id;
+  long totalTimeInStateMs;
+  long totalStateEntryCount;
+  long lastEntryTimestampMs;
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/StateResidencyResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/StateResidencyResult.aidl
new file mode 100644
index 0000000..14358b7
--- /dev/null
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/2/android/hardware/power/stats/StateResidencyResult.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.power.stats;
+@VintfStability
+parcelable StateResidencyResult {
+  int id;
+  android.hardware.power.stats.StateResidency[] stateResidencyData;
+}
diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl
index ce3e1f5..28bd59e 100644
--- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl
+++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl
@@ -40,4 +40,5 @@
   GNSS = 4,
   MOBILE_RADIO = 5,
   WIFI = 6,
+  CAMERA = 7,
 }
diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerType.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerType.aidl
index d871ced..ea70785 100644
--- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerType.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerType.aidl
@@ -26,4 +26,5 @@
     GNSS,
     MOBILE_RADIO,
     WIFI,
+    CAMERA,
 }
diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp
index 66be5f9..d3ab29b 100644
--- a/power/stats/aidl/default/Android.bp
+++ b/power/stats/aidl/default/Android.bp
@@ -30,7 +30,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.power.stats-V1-ndk",
+        "android.hardware.power.stats-V2-ndk",
     ],
     srcs: [
         "main.cpp",
diff --git a/power/stats/aidl/default/power.stats-default.xml b/power/stats/aidl/default/power.stats-default.xml
index 3b1a216..b64ea7e 100644
--- a/power/stats/aidl/default/power.stats-default.xml
+++ b/power/stats/aidl/default/power.stats-default.xml
@@ -1,6 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.power.stats</name>
+        <version>2</version>
         <fqname>IPowerStats/default</fqname>
     </hal>
 </manifest>
diff --git a/radio/1.0/Android.bp b/radio/1.0/Android.bp
index 8d0d782..e49a50d 100644
--- a/radio/1.0/Android.bp
+++ b/radio/1.0/Android.bp
@@ -25,7 +25,7 @@
     ],
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
+        "com.android.btservices",
     ],
     gen_java: true,
 }
diff --git a/radio/1.2/vts/functional/AndroidTest.xml b/radio/1.2/vts/functional/AndroidTest.xml
index e25249b..4a0be56 100644
--- a/radio/1.2/vts/functional/AndroidTest.xml
+++ b/radio/1.2/vts/functional/AndroidTest.xml
@@ -30,6 +30,7 @@
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
         <option name="module-name" value="VtsHalRadioV1_2TargetTest" />
     </test>
 </configuration>
diff --git a/radio/1.3/vts/functional/AndroidTest.xml b/radio/1.3/vts/functional/AndroidTest.xml
index 44b7419..a2cd791 100644
--- a/radio/1.3/vts/functional/AndroidTest.xml
+++ b/radio/1.3/vts/functional/AndroidTest.xml
@@ -30,6 +30,7 @@
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
         <option name="module-name" value="VtsHalRadioV1_3TargetTest" />
     </test>
 </configuration>
diff --git a/radio/1.4/vts/functional/AndroidTest.xml b/radio/1.4/vts/functional/AndroidTest.xml
index d0843e6..54051ed 100644
--- a/radio/1.4/vts/functional/AndroidTest.xml
+++ b/radio/1.4/vts/functional/AndroidTest.xml
@@ -30,6 +30,7 @@
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
         <option name="module-name" value="VtsHalRadioV1_4TargetTest" />
     </test>
 </configuration>
diff --git a/radio/1.5/vts/functional/AndroidTest.xml b/radio/1.5/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..d3617c8
--- /dev/null
+++ b/radio/1.5/vts/functional/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs VtsHalRadioV1_5TargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
+
+    <!-- TODO: b/154638140, b/152655658: bad interactions -->
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+    <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalRadioV1_5TargetTest->/data/local/tmp/VtsHalRadioV1_5TargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
+        <option name="module-name" value="VtsHalRadioV1_5TargetTest" />
+    </test>
+</configuration>
diff --git a/radio/1.6/vts/functional/AndroidTest.xml b/radio/1.6/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..c3ecdb0
--- /dev/null
+++ b/radio/1.6/vts/functional/AndroidTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs VtsHalRadioV1_6TargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
+
+    <!-- TODO: b/154638140, b/152655658: bad interactions -->
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+    <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalRadioV1_6TargetTest->/data/local/tmp/VtsHalRadioV1_6TargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
+        <option name="module-name" value="VtsHalRadioV1_6TargetTest" />
+    </test>
+</configuration>
diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp
index 72f160d..09f845b 100644
--- a/radio/aidl/Android.bp
+++ b/radio/aidl/Android.bp
@@ -12,25 +12,26 @@
     vendor_available: true,
     host_supported: true,
     srcs: ["android/hardware/radio/*.aidl"],
+    frozen: true,
     stability: "vintf",
     backend: {
         cpp: {
-            enabled: false,
+            enabled: true,
         },
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: [],
         },
+        {
+            version: "2",
+            imports: [],
+        },
+
     ],
 
 }
@@ -40,26 +41,27 @@
     vendor_available: true,
     host_supported: true,
     srcs: ["android/hardware/radio/config/*.aidl"],
+    frozen: true,
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V2"],
     backend: {
         cpp: {
-            enabled: false,
+            enabled: true,
         },
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: ["android.hardware.radio-V1"],
         },
+        {
+            version: "2",
+            imports: ["android.hardware.radio-V2"],
+        },
+
     ],
 
 }
@@ -70,26 +72,27 @@
     host_supported: true,
     srcs: ["android/hardware/radio/data/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V2"],
     backend: {
         cpp: {
-            enabled: false,
+            enabled: true,
         },
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: ["android.hardware.radio-V1"],
         },
+        {
+            version: "2",
+            imports: ["android.hardware.radio-V2"],
+        },
+
     ],
+    frozen: true,
 
 }
 
@@ -99,26 +102,27 @@
     host_supported: true,
     srcs: ["android/hardware/radio/messaging/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V2"],
     backend: {
         cpp: {
-            enabled: false,
+            enabled: true,
         },
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: ["android.hardware.radio-V1"],
         },
+        {
+            version: "2",
+            imports: ["android.hardware.radio-V2"],
+        },
+
     ],
+    frozen: true,
 
 }
 
@@ -128,26 +132,27 @@
     host_supported: true,
     srcs: ["android/hardware/radio/modem/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V2"],
     backend: {
         cpp: {
-            enabled: false,
+            enabled: true,
         },
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: ["android.hardware.radio-V1"],
         },
+        {
+            version: "2",
+            imports: ["android.hardware.radio-V2"],
+        },
+
     ],
+    frozen: true,
 
 }
 
@@ -157,26 +162,56 @@
     host_supported: true,
     srcs: ["android/hardware/radio/network/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V2"],
     backend: {
         cpp: {
-            enabled: false,
+            enabled: true,
         },
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: ["android.hardware.radio-V1"],
         },
+        {
+            version: "2",
+            imports: ["android.hardware.radio-V2"],
+        },
+
     ],
+    frozen: true,
+
+}
+
+aidl_interface {
+    name: "android.hardware.radio.sap",
+    vendor_available: true,
+    host_supported: true,
+    srcs: ["android/hardware/radio/sap/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: true,
+        },
+        java: {
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.btservices",
+            ],
+            sdk_version: "module_current",
+            min_sdk_version: "Tiramisu",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
 
 }
 
@@ -187,21 +222,16 @@
     srcs: ["android/hardware/radio/sim/*.aidl"],
     stability: "vintf",
     imports: [
-        "android.hardware.radio",
-        "android.hardware.radio.config",
+        "android.hardware.radio-V2",
+        "android.hardware.radio.config-V2",
     ],
     backend: {
         cpp: {
-            enabled: false,
+            enabled: true,
         },
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
@@ -211,7 +241,16 @@
                 "android.hardware.radio.config-V1",
             ],
         },
+        {
+            version: "2",
+            imports: [
+                "android.hardware.radio-V2",
+                "android.hardware.radio.config-V2",
+            ],
+        },
+
     ],
+    frozen: true,
 
 }
 
@@ -221,25 +260,80 @@
     host_supported: true,
     srcs: ["android/hardware/radio/voice/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio"],
+    imports: ["android.hardware.radio-V2"],
     backend: {
         cpp: {
-            enabled: false,
+            enabled: true,
         },
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: ["android.hardware.radio-V1"],
         },
+        {
+            version: "2",
+            imports: ["android.hardware.radio-V2"],
+        },
+
     ],
+    frozen: true,
+
+}
+
+aidl_interface {
+    name: "android.hardware.radio.ims.media",
+    vendor_available: true,
+    srcs: ["android/hardware/radio/ims/media/*.aidl"],
+    stability: "vintf",
+    imports: [
+        "android.hardware.radio-V2",
+        "android.hardware.radio.data-V2",
+    ],
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [
+                "android.hardware.radio-V2",
+                "android.hardware.radio.data-V2",
+            ],
+        },
+    ],
+    frozen: true,
+
+}
+
+aidl_interface {
+    name: "android.hardware.radio.ims",
+    vendor_available: true,
+    srcs: ["android/hardware/radio/ims/*.aidl"],
+    stability: "vintf",
+    imports: ["android.hardware.radio-V2"],
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.radio-V2"],
+        },
+    ],
+    frozen: true,
 
 }
diff --git a/radio/aidl/OWNERS b/radio/aidl/OWNERS
new file mode 100644
index 0000000..7b01aad
--- /dev/null
+++ b/radio/aidl/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 20868
+include ../1.0/vts/OWNERS
+
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/2/.hash b/radio/aidl/aidl_api/android.hardware.radio.config/2/.hash
new file mode 100644
index 0000000..a399832
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/2/.hash
@@ -0,0 +1 @@
+0be135cf3de9586d6aabb58cb6af0ba425431743
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/IRadioConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/IRadioConfig.aidl
new file mode 100644
index 0000000..a48a89b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/IRadioConfig.aidl
@@ -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.
+ *
+ *
+ * This interface is used by telephony and telecom to talk to cellular radio for the purpose of
+ * radio configuration, and it is not associated with any specific modem or slot.
+ * All the functions have minimum one parameter:
+ * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
+ * duration of a method call. If clients provide colliding serials (including passing the same
+ * serial to different methods), multiple responses (one for each method call) must still be served.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.config;
+@VintfStability
+interface IRadioConfig {
+  oneway void getHalDeviceCapabilities(in int serial);
+  oneway void getNumOfLiveModems(in int serial);
+  oneway void getPhoneCapability(in int serial);
+  oneway void getSimSlotsStatus(in int serial);
+  oneway void setNumOfLiveModems(in int serial, in byte numOfLiveModems);
+  oneway void setPreferredDataModem(in int serial, in byte modemId);
+  oneway void setResponseFunctions(in android.hardware.radio.config.IRadioConfigResponse radioConfigResponse, in android.hardware.radio.config.IRadioConfigIndication radioConfigIndication);
+  oneway void setSimSlotsMapping(in int serial, in android.hardware.radio.config.SlotPortMapping[] slotMap);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/IRadioConfigIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/IRadioConfigIndication.aidl
new file mode 100644
index 0000000..994e337
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/IRadioConfigIndication.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.config;
+@VintfStability
+interface IRadioConfigIndication {
+  oneway void simSlotsStatusChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.config.SimSlotStatus[] slotStatus);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/IRadioConfigResponse.aidl
new file mode 100644
index 0000000..038b0ae
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.config;
+@VintfStability
+interface IRadioConfigResponse {
+  oneway void getHalDeviceCapabilitiesResponse(in android.hardware.radio.RadioResponseInfo info, in boolean modemReducedFeatureSet1);
+  oneway void getNumOfLiveModemsResponse(in android.hardware.radio.RadioResponseInfo info, in byte numOfLiveModems);
+  oneway void getPhoneCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.config.PhoneCapability phoneCapability);
+  oneway void getSimSlotsStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.config.SimSlotStatus[] slotStatus);
+  oneway void setNumOfLiveModemsResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setPreferredDataModemResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setSimSlotsMappingResponse(in android.hardware.radio.RadioResponseInfo info);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
new file mode 100644
index 0000000..74017e4
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.config;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum MultipleEnabledProfilesMode {
+  NONE,
+  MEP_A1,
+  MEP_A2,
+  MEP_B,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/PhoneCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/PhoneCapability.aidl
new file mode 100644
index 0000000..db3a4c6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/PhoneCapability.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.config;
+@JavaDerive(toString=true) @VintfStability
+parcelable PhoneCapability {
+  byte maxActiveData;
+  byte maxActiveInternetData;
+  boolean isInternetLingeringSupported;
+  byte[] logicalModemIds;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/SimPortInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/SimPortInfo.aidl
new file mode 100644
index 0000000..b5d31ad
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/SimPortInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.config;
+@JavaDerive(toString=true) @VintfStability
+parcelable SimPortInfo {
+  String iccId;
+  int logicalSlotId;
+  boolean portActive;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/SimSlotStatus.aidl
new file mode 100644
index 0000000..c264dfd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/SimSlotStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.config;
+@JavaDerive(toString=true) @VintfStability
+parcelable SimSlotStatus {
+  int cardState;
+  String atr;
+  String eid;
+  android.hardware.radio.config.SimPortInfo[] portInfo;
+  android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode = android.hardware.radio.config.MultipleEnabledProfilesMode.NONE;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/SlotPortMapping.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/SlotPortMapping.aidl
new file mode 100644
index 0000000..31271ee
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/2/android/hardware/radio/config/SlotPortMapping.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.config;
+@JavaDerive(toString=true) @VintfStability
+parcelable SlotPortMapping {
+  int physicalSlotId;
+  int portId;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
new file mode 100644
index 0000000..74017e4
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.config;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum MultipleEnabledProfilesMode {
+  NONE,
+  MEP_A1,
+  MEP_A2,
+  MEP_B,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
index be4c080..c264dfd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
@@ -38,4 +38,5 @@
   String atr;
   String eid;
   android.hardware.radio.config.SimPortInfo[] portInfo;
+  android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode = android.hardware.radio.config.MultipleEnabledProfilesMode.NONE;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/.hash b/radio/aidl/aidl_api/android.hardware.radio.data/2/.hash
new file mode 100644
index 0000000..566a475
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/.hash
@@ -0,0 +1 @@
+cb458326b02e0e87143f24118543e8cc7d6a9e8e
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/ApnAuthType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/ApnAuthType.aidl
new file mode 100644
index 0000000..a33ad6e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/ApnAuthType.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.data;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ApnAuthType {
+  NO_PAP_NO_CHAP,
+  PAP_NO_CHAP,
+  NO_PAP_CHAP,
+  PAP_CHAP,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/ApnTypes.aidl
new file mode 100644
index 0000000..9133c7b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/ApnTypes.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.data;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ApnTypes {
+  NONE = 0,
+  DEFAULT = (1 << 0) /* 1 */,
+  MMS = (1 << 1) /* 2 */,
+  SUPL = (1 << 2) /* 4 */,
+  DUN = (1 << 3) /* 8 */,
+  HIPRI = (1 << 4) /* 16 */,
+  FOTA = (1 << 5) /* 32 */,
+  IMS = (1 << 6) /* 64 */,
+  CBS = (1 << 7) /* 128 */,
+  IA = (1 << 8) /* 256 */,
+  EMERGENCY = (1 << 9) /* 512 */,
+  MCX = (1 << 10) /* 1024 */,
+  XCAP = (1 << 11) /* 2048 */,
+  VSIM = (1 << 12) /* 4096 */,
+  BIP = (1 << 13) /* 8192 */,
+  ENTERPRISE = (1 << 14) /* 16384 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataCallFailCause.aidl
new file mode 100644
index 0000000..28d122d
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataCallFailCause.aidl
@@ -0,0 +1,381 @@
+/*
+ * 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.data;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum DataCallFailCause {
+  NONE = 0,
+  OPERATOR_BARRED = 0x08,
+  NAS_SIGNALLING = 0x0E,
+  INSUFFICIENT_RESOURCES = 0x1A,
+  MISSING_UNKNOWN_APN = 0x1B,
+  UNKNOWN_PDP_ADDRESS_TYPE = 0x1C,
+  USER_AUTHENTICATION = 0x1D,
+  ACTIVATION_REJECT_GGSN = 0x1E,
+  ACTIVATION_REJECT_UNSPECIFIED = 0x1F,
+  SERVICE_OPTION_NOT_SUPPORTED = 0x20,
+  SERVICE_OPTION_NOT_SUBSCRIBED = 0x21,
+  SERVICE_OPTION_OUT_OF_ORDER = 0x22,
+  NSAPI_IN_USE = 0x23,
+  REGULAR_DEACTIVATION = 0x24,
+  QOS_NOT_ACCEPTED = 0x25,
+  NETWORK_FAILURE = 0x26,
+  UMTS_REACTIVATION_REQ = 0x27,
+  FEATURE_NOT_SUPP = 0x28,
+  TFT_SEMANTIC_ERROR = 0x29,
+  TFT_SYTAX_ERROR = 0x2A,
+  UNKNOWN_PDP_CONTEXT = 0x2B,
+  FILTER_SEMANTIC_ERROR = 0x2C,
+  FILTER_SYTAX_ERROR = 0x2D,
+  PDP_WITHOUT_ACTIVE_TFT = 0x2E,
+  ONLY_IPV4_ALLOWED = 0x32,
+  ONLY_IPV6_ALLOWED = 0x33,
+  ONLY_SINGLE_BEARER_ALLOWED = 0x34,
+  ESM_INFO_NOT_RECEIVED = 0x35,
+  PDN_CONN_DOES_NOT_EXIST = 0x36,
+  MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37,
+  MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41,
+  UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42,
+  INVALID_TRANSACTION_ID = 0x51,
+  MESSAGE_INCORRECT_SEMANTIC = 0x5F,
+  INVALID_MANDATORY_INFO = 0x60,
+  MESSAGE_TYPE_UNSUPPORTED = 0x61,
+  MSG_TYPE_NONCOMPATIBLE_STATE = 0x62,
+  UNKNOWN_INFO_ELEMENT = 0x63,
+  CONDITIONAL_IE_ERROR = 0x64,
+  MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65,
+  PROTOCOL_ERRORS = 0x6F,
+  APN_TYPE_CONFLICT = 0x70,
+  INVALID_PCSCF_ADDR = 0x71,
+  INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72,
+  EMM_ACCESS_BARRED = 0x73,
+  EMERGENCY_IFACE_ONLY = 0x74,
+  IFACE_MISMATCH = 0x75,
+  COMPANION_IFACE_IN_USE = 0x76,
+  IP_ADDRESS_MISMATCH = 0x77,
+  IFACE_AND_POL_FAMILY_MISMATCH = 0x78,
+  EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79,
+  AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A,
+  OEM_DCFAILCAUSE_1 = 0x1001,
+  OEM_DCFAILCAUSE_2 = 0x1002,
+  OEM_DCFAILCAUSE_3 = 0x1003,
+  OEM_DCFAILCAUSE_4 = 0x1004,
+  OEM_DCFAILCAUSE_5 = 0x1005,
+  OEM_DCFAILCAUSE_6 = 0x1006,
+  OEM_DCFAILCAUSE_7 = 0x1007,
+  OEM_DCFAILCAUSE_8 = 0x1008,
+  OEM_DCFAILCAUSE_9 = 0x1009,
+  OEM_DCFAILCAUSE_10 = 0x100A,
+  OEM_DCFAILCAUSE_11 = 0x100B,
+  OEM_DCFAILCAUSE_12 = 0x100C,
+  OEM_DCFAILCAUSE_13 = 0x100D,
+  OEM_DCFAILCAUSE_14 = 0x100E,
+  OEM_DCFAILCAUSE_15 = 0x100F,
+  VOICE_REGISTRATION_FAIL = (-1) /* -1 */,
+  DATA_REGISTRATION_FAIL = (-2) /* -2 */,
+  SIGNAL_LOST = (-3) /* -3 */,
+  PREF_RADIO_TECH_CHANGED = (-4) /* -4 */,
+  RADIO_POWER_OFF = (-5) /* -5 */,
+  TETHERED_CALL_ACTIVE = (-6) /* -6 */,
+  ERROR_UNSPECIFIED = 0xffff,
+  LLC_SNDCP = 0x19,
+  ACTIVATION_REJECTED_BCM_VIOLATION = 0x30,
+  COLLISION_WITH_NETWORK_INITIATED_REQUEST = 0x38,
+  ONLY_IPV4V6_ALLOWED = 0x39,
+  ONLY_NON_IP_ALLOWED = 0x3A,
+  UNSUPPORTED_QCI_VALUE = 0x3B,
+  BEARER_HANDLING_NOT_SUPPORTED = 0x3C,
+  INVALID_DNS_ADDR = 0x7B,
+  INVALID_PCSCF_OR_DNS_ADDRESS = 0x7C,
+  CALL_PREEMPT_BY_EMERGENCY_APN = 0x7F,
+  UE_INITIATED_DETACH_OR_DISCONNECT = 0x80,
+  MIP_FA_REASON_UNSPECIFIED = 0x7D0,
+  MIP_FA_ADMIN_PROHIBITED = 0x7D1,
+  MIP_FA_INSUFFICIENT_RESOURCES = 0x7D2,
+  MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7D3,
+  MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 0x7D4,
+  MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 0x7D5,
+  MIP_FA_MALFORMED_REQUEST = 0x7D6,
+  MIP_FA_MALFORMED_REPLY = 0x7D7,
+  MIP_FA_ENCAPSULATION_UNAVAILABLE = 0x7D8,
+  MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 0x7D9,
+  MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 0x7DA,
+  MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 0x7DB,
+  MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 0x7DC,
+  MIP_FA_MISSING_NAI = 0x7DD,
+  MIP_FA_MISSING_HOME_AGENT = 0x7DE,
+  MIP_FA_MISSING_HOME_ADDRESS = 0x7DF,
+  MIP_FA_UNKNOWN_CHALLENGE = 0x7E0,
+  MIP_FA_MISSING_CHALLENGE = 0x7E1,
+  MIP_FA_STALE_CHALLENGE = 0x7E2,
+  MIP_HA_REASON_UNSPECIFIED = 0x7E3,
+  MIP_HA_ADMIN_PROHIBITED = 0x7E4,
+  MIP_HA_INSUFFICIENT_RESOURCES = 0x7E5,
+  MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7E6,
+  MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 0x7E7,
+  MIP_HA_REGISTRATION_ID_MISMATCH = 0x7E8,
+  MIP_HA_MALFORMED_REQUEST = 0x7E9,
+  MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 0x7EA,
+  MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 0x7EB,
+  MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 0x7EC,
+  MIP_HA_ENCAPSULATION_UNAVAILABLE = 0x7ED,
+  CLOSE_IN_PROGRESS = 0x7EE,
+  NETWORK_INITIATED_TERMINATION = 0x7EF,
+  MODEM_APP_PREEMPTED = 0x7F0,
+  PDN_IPV4_CALL_DISALLOWED = 0x7F1,
+  PDN_IPV4_CALL_THROTTLED = 0x7F2,
+  PDN_IPV6_CALL_DISALLOWED = 0x7F3,
+  PDN_IPV6_CALL_THROTTLED = 0x7F4,
+  MODEM_RESTART = 0x7F5,
+  PDP_PPP_NOT_SUPPORTED = 0x7F6,
+  UNPREFERRED_RAT = 0x7F7,
+  PHYSICAL_LINK_CLOSE_IN_PROGRESS = 0x7F8,
+  APN_PENDING_HANDOVER = 0x7F9,
+  PROFILE_BEARER_INCOMPATIBLE = 0x7FA,
+  SIM_CARD_CHANGED = 0x7FB,
+  LOW_POWER_MODE_OR_POWERING_DOWN = 0x7FC,
+  APN_DISABLED = 0x7FD,
+  MAX_PPP_INACTIVITY_TIMER_EXPIRED = 0x7FE,
+  IPV6_ADDRESS_TRANSFER_FAILED = 0x7FF,
+  TRAT_SWAP_FAILED = 0x800,
+  EHRPD_TO_HRPD_FALLBACK = 0x801,
+  MIP_CONFIG_FAILURE = 0x802,
+  PDN_INACTIVITY_TIMER_EXPIRED = 0x803,
+  MAX_IPV4_CONNECTIONS = 0x804,
+  MAX_IPV6_CONNECTIONS = 0x805,
+  APN_MISMATCH = 0x806,
+  IP_VERSION_MISMATCH = 0x807,
+  DUN_CALL_DISALLOWED = 0x808,
+  INTERNAL_EPC_NONEPC_TRANSITION = 0x809,
+  INTERFACE_IN_USE = 0x80A,
+  APN_DISALLOWED_ON_ROAMING = 0x80B,
+  APN_PARAMETERS_CHANGED = 0x80C,
+  NULL_APN_DISALLOWED = 0x80D,
+  THERMAL_MITIGATION = 0x80E,
+  DATA_SETTINGS_DISABLED = 0x80F,
+  DATA_ROAMING_SETTINGS_DISABLED = 0x810,
+  DDS_SWITCHED = 0x811,
+  FORBIDDEN_APN_NAME = 0x812,
+  DDS_SWITCH_IN_PROGRESS = 0x813,
+  CALL_DISALLOWED_IN_ROAMING = 0x814,
+  NON_IP_NOT_SUPPORTED = 0x815,
+  PDN_NON_IP_CALL_THROTTLED = 0x816,
+  PDN_NON_IP_CALL_DISALLOWED = 0x817,
+  CDMA_LOCK = 0x818,
+  CDMA_INTERCEPT = 0x819,
+  CDMA_REORDER = 0x81A,
+  CDMA_RELEASE_DUE_TO_SO_REJECTION = 0x81B,
+  CDMA_INCOMING_CALL = 0x81C,
+  CDMA_ALERT_STOP = 0x81D,
+  CHANNEL_ACQUISITION_FAILURE = 0x81E,
+  MAX_ACCESS_PROBE = 0x81F,
+  CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION = 0x820,
+  NO_RESPONSE_FROM_BASE_STATION = 0x821,
+  REJECTED_BY_BASE_STATION = 0x822,
+  CONCURRENT_SERVICES_INCOMPATIBLE = 0x823,
+  NO_CDMA_SERVICE = 0x824,
+  RUIM_NOT_PRESENT = 0x825,
+  CDMA_RETRY_ORDER = 0x826,
+  ACCESS_BLOCK = 0x827,
+  ACCESS_BLOCK_ALL = 0x828,
+  IS707B_MAX_ACCESS_PROBES = 0x829,
+  THERMAL_EMERGENCY = 0x82A,
+  CONCURRENT_SERVICES_NOT_ALLOWED = 0x82B,
+  INCOMING_CALL_REJECTED = 0x82C,
+  NO_SERVICE_ON_GATEWAY = 0x82D,
+  NO_GPRS_CONTEXT = 0x82E,
+  ILLEGAL_MS = 0x82F,
+  ILLEGAL_ME = 0x830,
+  GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 0x831,
+  GPRS_SERVICES_NOT_ALLOWED = 0x832,
+  MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 0x833,
+  IMPLICITLY_DETACHED = 0x834,
+  PLMN_NOT_ALLOWED = 0x835,
+  LOCATION_AREA_NOT_ALLOWED = 0x836,
+  GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 0x837,
+  PDP_DUPLICATE = 0x838,
+  UE_RAT_CHANGE = 0x839,
+  CONGESTION = 0x83A,
+  NO_PDP_CONTEXT_ACTIVATED = 0x83B,
+  ACCESS_CLASS_DSAC_REJECTION = 0x83C,
+  PDP_ACTIVATE_MAX_RETRY_FAILED = 0x83D,
+  RADIO_ACCESS_BEARER_FAILURE = 0x83E,
+  ESM_UNKNOWN_EPS_BEARER_CONTEXT = 0x83F,
+  DRB_RELEASED_BY_RRC = 0x840,
+  CONNECTION_RELEASED = 0x841,
+  EMM_DETACHED = 0x842,
+  EMM_ATTACH_FAILED = 0x843,
+  EMM_ATTACH_STARTED = 0x844,
+  LTE_NAS_SERVICE_REQUEST_FAILED = 0x845,
+  DUPLICATE_BEARER_ID = 0x846,
+  ESM_COLLISION_SCENARIOS = 0x847,
+  ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 0x848,
+  ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 0x849,
+  ESM_BAD_OTA_MESSAGE = 0x84A,
+  ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 0x84B,
+  ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 0x84C,
+  DS_EXPLICIT_DEACTIVATION = 0x84D,
+  ESM_LOCAL_CAUSE_NONE = 0x84E,
+  LTE_THROTTLING_NOT_REQUIRED = 0x84F,
+  ACCESS_CONTROL_LIST_CHECK_FAILURE = 0x850,
+  SERVICE_NOT_ALLOWED_ON_PLMN = 0x851,
+  EMM_T3417_EXPIRED = 0x852,
+  EMM_T3417_EXT_EXPIRED = 0x853,
+  RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 0x854,
+  RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 0x855,
+  RRC_UPLINK_CONNECTION_RELEASE = 0x856,
+  RRC_UPLINK_RADIO_LINK_FAILURE = 0x857,
+  RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 0x858,
+  RRC_CONNECTION_ACCESS_STRATUM_FAILURE = 0x859,
+  RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS = 0x85A,
+  RRC_CONNECTION_ACCESS_BARRED = 0x85B,
+  RRC_CONNECTION_CELL_RESELECTION = 0x85C,
+  RRC_CONNECTION_CONFIG_FAILURE = 0x85D,
+  RRC_CONNECTION_TIMER_EXPIRED = 0x85E,
+  RRC_CONNECTION_LINK_FAILURE = 0x85F,
+  RRC_CONNECTION_CELL_NOT_CAMPED = 0x860,
+  RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE = 0x861,
+  RRC_CONNECTION_REJECT_BY_NETWORK = 0x862,
+  RRC_CONNECTION_NORMAL_RELEASE = 0x863,
+  RRC_CONNECTION_RADIO_LINK_FAILURE = 0x864,
+  RRC_CONNECTION_REESTABLISHMENT_FAILURE = 0x865,
+  RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER = 0x866,
+  RRC_CONNECTION_ABORT_REQUEST = 0x867,
+  RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 0x868,
+  NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 0x869,
+  NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 0x86A,
+  ESM_PROCEDURE_TIME_OUT = 0x86B,
+  INVALID_CONNECTION_ID = 0x86C,
+  MAXIMIUM_NSAPIS_EXCEEDED = 0x86D,
+  INVALID_PRIMARY_NSAPI = 0x86E,
+  CANNOT_ENCODE_OTA_MESSAGE = 0x86F,
+  RADIO_ACCESS_BEARER_SETUP_FAILURE = 0x870,
+  PDP_ESTABLISH_TIMEOUT_EXPIRED = 0x871,
+  PDP_MODIFY_TIMEOUT_EXPIRED = 0x872,
+  PDP_INACTIVE_TIMEOUT_EXPIRED = 0x873,
+  PDP_LOWERLAYER_ERROR = 0x874,
+  PDP_MODIFY_COLLISION = 0x875,
+  /**
+   * @deprecated use MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED instead.
+   */
+  MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
+  MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
+  NAS_REQUEST_REJECTED_BY_NETWORK = 0x877,
+  RRC_CONNECTION_INVALID_REQUEST = 0x878,
+  RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 0x879,
+  RRC_CONNECTION_RF_UNAVAILABLE = 0x87A,
+  RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 0x87B,
+  RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 0x87C,
+  RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 0x87D,
+  RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 0x87E,
+  RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 0x87F,
+  IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 0x880,
+  IMEI_NOT_ACCEPTED = 0x881,
+  EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 0x882,
+  EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 0x883,
+  MSC_TEMPORARILY_NOT_REACHABLE = 0x884,
+  CS_DOMAIN_NOT_AVAILABLE = 0x885,
+  ESM_FAILURE = 0x886,
+  MAC_FAILURE = 0x887,
+  SYNCHRONIZATION_FAILURE = 0x888,
+  UE_SECURITY_CAPABILITIES_MISMATCH = 0x889,
+  SECURITY_MODE_REJECTED = 0x88A,
+  UNACCEPTABLE_NON_EPS_AUTHENTICATION = 0x88B,
+  CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 0x88C,
+  NO_EPS_BEARER_CONTEXT_ACTIVATED = 0x88D,
+  INVALID_EMM_STATE = 0x88E,
+  NAS_LAYER_FAILURE = 0x88F,
+  MULTIPLE_PDP_CALL_NOT_ALLOWED = 0x890,
+  EMBMS_NOT_ENABLED = 0x891,
+  IRAT_HANDOVER_FAILED = 0x892,
+  EMBMS_REGULAR_DEACTIVATION = 0x893,
+  TEST_LOOPBACK_REGULAR_DEACTIVATION = 0x894,
+  LOWER_LAYER_REGISTRATION_FAILURE = 0x895,
+  DATA_PLAN_EXPIRED = 0x896,
+  UMTS_HANDOVER_TO_IWLAN = 0x897,
+  EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 0x898,
+  EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 0x899,
+  EVDO_HDR_CHANGED = 0x89A,
+  EVDO_HDR_EXITED = 0x89B,
+  EVDO_HDR_NO_SESSION = 0x89C,
+  EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 0x89D,
+  EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 0x89E,
+  FAILED_TO_ACQUIRE_COLOCATED_HDR = 0x89F,
+  OTASP_COMMIT_IN_PROGRESS = 0x8A0,
+  NO_HYBRID_HDR_SERVICE = 0x8A1,
+  HDR_NO_LOCK_GRANTED = 0x8A2,
+  DBM_OR_SMS_IN_PROGRESS = 0x8A3,
+  HDR_FADE = 0x8A4,
+  HDR_ACCESS_FAILURE = 0x8A5,
+  UNSUPPORTED_1X_PREV = 0x8A6,
+  LOCAL_END = 0x8A7,
+  NO_SERVICE = 0x8A8,
+  FADE = 0x8A9,
+  NORMAL_RELEASE = 0x8AA,
+  ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 0x8AB,
+  REDIRECTION_OR_HANDOFF_IN_PROGRESS = 0x8AC,
+  EMERGENCY_MODE = 0x8AD,
+  PHONE_IN_USE = 0x8AE,
+  INVALID_MODE = 0x8AF,
+  INVALID_SIM_STATE = 0x8B0,
+  NO_COLLOCATED_HDR = 0x8B1,
+  UE_IS_ENTERING_POWERSAVE_MODE = 0x8B2,
+  DUAL_SWITCH = 0x8B3,
+  PPP_TIMEOUT = 0x8B4,
+  PPP_AUTH_FAILURE = 0x8B5,
+  PPP_OPTION_MISMATCH = 0x8B6,
+  PPP_PAP_FAILURE = 0x8B7,
+  PPP_CHAP_FAILURE = 0x8B8,
+  PPP_CLOSE_IN_PROGRESS = 0x8B9,
+  LIMITED_TO_IPV4 = 0x8BA,
+  LIMITED_TO_IPV6 = 0x8BB,
+  VSNCP_TIMEOUT = 0x8BC,
+  VSNCP_GEN_ERROR = 0x8BD,
+  VSNCP_APN_UNAUTHORIZED = 0x8BE,
+  VSNCP_PDN_LIMIT_EXCEEDED = 0x8BF,
+  VSNCP_NO_PDN_GATEWAY_ADDRESS = 0x8C0,
+  VSNCP_PDN_GATEWAY_UNREACHABLE = 0x8C1,
+  VSNCP_PDN_GATEWAY_REJECT = 0x8C2,
+  VSNCP_INSUFFICIENT_PARAMETERS = 0x8C3,
+  VSNCP_RESOURCE_UNAVAILABLE = 0x8C4,
+  VSNCP_ADMINISTRATIVELY_PROHIBITED = 0x8C5,
+  VSNCP_PDN_ID_IN_USE = 0x8C6,
+  VSNCP_SUBSCRIBER_LIMITATION = 0x8C7,
+  VSNCP_PDN_EXISTS_FOR_THIS_APN = 0x8C8,
+  VSNCP_RECONNECT_NOT_ALLOWED = 0x8C9,
+  IPV6_PREFIX_UNAVAILABLE = 0x8CA,
+  HANDOFF_PREFERENCE_CHANGED = 0x8CB,
+  SLICE_REJECTED = 0x8CC,
+  MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD,
+  ALL_MATCHING_RULES_FAILED = 0x8CE,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataProfileInfo.aidl
new file mode 100644
index 0000000..0136fa4
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataProfileInfo.aidl
@@ -0,0 +1,67 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable DataProfileInfo {
+  int profileId;
+  String apn;
+  android.hardware.radio.data.PdpProtocolType protocol;
+  android.hardware.radio.data.PdpProtocolType roamingProtocol;
+  android.hardware.radio.data.ApnAuthType authType;
+  String user;
+  String password;
+  int type;
+  int maxConnsTime;
+  int maxConns;
+  int waitTime;
+  boolean enabled;
+  int supportedApnTypesBitmap;
+  int bearerBitmap;
+  int mtuV4;
+  int mtuV6;
+  boolean preferred;
+  boolean persistent;
+  boolean alwaysOn;
+  android.hardware.radio.data.TrafficDescriptor trafficDescriptor;
+  const int ID_DEFAULT = 0;
+  const int ID_TETHERED = 1;
+  const int ID_IMS = 2;
+  const int ID_FOTA = 3;
+  const int ID_CBS = 4;
+  const int ID_OEM_BASE = 1000;
+  const int ID_INVALID = 0xFFFFFFFF;
+  const int TYPE_COMMON = 0;
+  const int TYPE_3GPP = 1;
+  const int TYPE_3GPP2 = 2;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataRequestReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataRequestReason.aidl
new file mode 100644
index 0000000..0ddaff1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataRequestReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.data;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum DataRequestReason {
+  NORMAL = 1,
+  SHUTDOWN = 2,
+  HANDOVER = 3,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataThrottlingAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataThrottlingAction.aidl
new file mode 100644
index 0000000..e80a764
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/DataThrottlingAction.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.data;
+@Backing(type="byte") @JavaDerive(toString=true) @VintfStability
+enum DataThrottlingAction {
+  NO_DATA_THROTTLING,
+  THROTTLE_SECONDARY_CARRIER,
+  THROTTLE_ANCHOR_CARRIER,
+  HOLD,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/EpsQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/EpsQos.aidl
new file mode 100644
index 0000000..5b9aaa0
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/EpsQos.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable EpsQos {
+  int qci;
+  android.hardware.radio.data.QosBandwidth downlink;
+  android.hardware.radio.data.QosBandwidth uplink;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/IRadioData.aidl
new file mode 100644
index 0000000..7b572f1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/IRadioData.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.data;
+@VintfStability
+interface IRadioData {
+  oneway void allocatePduSessionId(in int serial);
+  oneway void cancelHandover(in int serial, in int callId);
+  oneway void deactivateDataCall(in int serial, in int cid, in android.hardware.radio.data.DataRequestReason reason);
+  oneway void getDataCallList(in int serial);
+  oneway void getSlicingConfig(in int serial);
+  oneway void releasePduSessionId(in int serial, in int id);
+  oneway void responseAcknowledgement();
+  oneway void setDataAllowed(in int serial, in boolean allow);
+  oneway void setDataProfile(in int serial, in android.hardware.radio.data.DataProfileInfo[] profiles);
+  oneway void setDataThrottling(in int serial, in android.hardware.radio.data.DataThrottlingAction dataThrottlingAction, in long completionDurationMillis);
+  oneway void setInitialAttachApn(in int serial, in @nullable android.hardware.radio.data.DataProfileInfo dataProfileInfo);
+  oneway void setResponseFunctions(in android.hardware.radio.data.IRadioDataResponse radioDataResponse, in android.hardware.radio.data.IRadioDataIndication radioDataIndication);
+  oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.data.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.data.DataRequestReason reason, in android.hardware.radio.data.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.data.SliceInfo sliceInfo, in boolean matchAllRuleAllowed);
+  oneway void startHandover(in int serial, in int callId);
+  oneway void startKeepalive(in int serial, in android.hardware.radio.data.KeepaliveRequest keepalive);
+  oneway void stopKeepalive(in int serial, in int sessionHandle);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/IRadioDataIndication.aidl
new file mode 100644
index 0000000..0ffa1f7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/IRadioDataIndication.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.data;
+@VintfStability
+interface IRadioDataIndication {
+  oneway void dataCallListChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SetupDataCallResult[] dcList);
+  oneway void keepaliveStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.KeepaliveStatus status);
+  oneway void pcoData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.PcoDataInfo pco);
+  oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.DataProfileInfo dataProfileInfo);
+  oneway void slicingConfigChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SlicingConfig slicingConfig);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/IRadioDataResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/IRadioDataResponse.aidl
new file mode 100644
index 0000000..4edc17d
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/IRadioDataResponse.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.data;
+@VintfStability
+interface IRadioDataResponse {
+  oneway void acknowledgeRequest(in int serial);
+  oneway void allocatePduSessionIdResponse(in android.hardware.radio.RadioResponseInfo info, in int id);
+  oneway void cancelHandoverResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void deactivateDataCallResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getDataCallListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.data.SetupDataCallResult[] dcResponse);
+  oneway void getSlicingConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.data.SlicingConfig slicingConfig);
+  oneway void releasePduSessionIdResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setDataAllowedResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setDataProfileResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setDataThrottlingResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setInitialAttachApnResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setupDataCallResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.data.SetupDataCallResult dcResponse);
+  oneway void startHandoverResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void startKeepaliveResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.data.KeepaliveStatus status);
+  oneway void stopKeepaliveResponse(in android.hardware.radio.RadioResponseInfo info);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/KeepaliveRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/KeepaliveRequest.aidl
new file mode 100644
index 0000000..592a54a
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/KeepaliveRequest.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable KeepaliveRequest {
+  int type;
+  byte[] sourceAddress;
+  int sourcePort;
+  byte[] destinationAddress;
+  int destinationPort;
+  int maxKeepaliveIntervalMillis;
+  int cid;
+  const int TYPE_NATT_IPV4 = 0;
+  const int TYPE_NATT_IPV6 = 1;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/KeepaliveStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/KeepaliveStatus.aidl
new file mode 100644
index 0000000..82b0fc8
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/KeepaliveStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable KeepaliveStatus {
+  int sessionHandle;
+  int code;
+  const int CODE_ACTIVE = 0;
+  const int CODE_INACTIVE = 1;
+  const int CODE_PENDING = 2;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/LinkAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/LinkAddress.aidl
new file mode 100644
index 0000000..77d637b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/LinkAddress.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable LinkAddress {
+  String address;
+  int addressProperties;
+  long deprecationTime;
+  long expirationTime;
+  const int ADDRESS_PROPERTY_NONE = 0;
+  const int ADDRESS_PROPERTY_DEPRECATED = 0x20;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/NrQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/NrQos.aidl
new file mode 100644
index 0000000..660a531
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/NrQos.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable NrQos {
+  int fiveQi;
+  android.hardware.radio.data.QosBandwidth downlink;
+  android.hardware.radio.data.QosBandwidth uplink;
+  byte qfi;
+  /**
+   * @deprecated use averagingWindowMillis;
+   */
+  char averagingWindowMs;
+  int averagingWindowMillis = AVERAGING_WINDOW_UNKNOWN /* -1 */;
+  const byte FLOW_ID_RANGE_MIN = 1;
+  const byte FLOW_ID_RANGE_MAX = 63;
+  const int AVERAGING_WINDOW_UNKNOWN = (-1) /* -1 */;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/OsAppId.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/OsAppId.aidl
new file mode 100644
index 0000000..8595d52
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/OsAppId.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable OsAppId {
+  byte[] osAppId;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/PcoDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/PcoDataInfo.aidl
new file mode 100644
index 0000000..033b12f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/PcoDataInfo.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable PcoDataInfo {
+  int cid;
+  String bearerProto;
+  int pcoId;
+  byte[] contents;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/PdpProtocolType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/PdpProtocolType.aidl
new file mode 100644
index 0000000..1e5970d
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/PdpProtocolType.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.data;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum PdpProtocolType {
+  UNKNOWN = (-1) /* -1 */,
+  IP = 0,
+  IPV6 = 1,
+  IPV4V6 = 2,
+  PPP = 3,
+  NON_IP = 4,
+  UNSTRUCTURED = 5,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/PortRange.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/PortRange.aidl
new file mode 100644
index 0000000..470a9c1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/PortRange.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable PortRange {
+  int start;
+  int end;
+  const int PORT_RANGE_MIN = 20;
+  const int PORT_RANGE_MAX = 65535;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/Qos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/Qos.aidl
new file mode 100644
index 0000000..ca06e41
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/Qos.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+union Qos {
+  boolean noinit;
+  android.hardware.radio.data.EpsQos eps;
+  android.hardware.radio.data.NrQos nr;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosBandwidth.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosBandwidth.aidl
new file mode 100644
index 0000000..6d4b7a9
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosBandwidth.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable QosBandwidth {
+  int maxBitrateKbps;
+  int guaranteedBitrateKbps;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilter.aidl
new file mode 100644
index 0000000..a3d4ced
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilter.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable QosFilter {
+  String[] localAddresses;
+  String[] remoteAddresses;
+  @nullable android.hardware.radio.data.PortRange localPort;
+  @nullable android.hardware.radio.data.PortRange remotePort;
+  byte protocol;
+  android.hardware.radio.data.QosFilterTypeOfService tos;
+  android.hardware.radio.data.QosFilterIpv6FlowLabel flowLabel;
+  android.hardware.radio.data.QosFilterIpsecSpi spi;
+  byte direction;
+  int precedence;
+  const byte DIRECTION_DOWNLINK = 0;
+  const byte DIRECTION_UPLINK = 1;
+  const byte DIRECTION_BIDIRECTIONAL = 2;
+  const byte PROTOCOL_UNSPECIFIED = (-1) /* -1 */;
+  const byte PROTOCOL_TCP = 6;
+  const byte PROTOCOL_UDP = 17;
+  const byte PROTOCOL_ESP = 50;
+  const byte PROTOCOL_AH = 51;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilterIpsecSpi.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilterIpsecSpi.aidl
new file mode 100644
index 0000000..4b75340
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilterIpsecSpi.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+union QosFilterIpsecSpi {
+  boolean noinit;
+  int value;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
new file mode 100644
index 0000000..3fb34ea
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+union QosFilterIpv6FlowLabel {
+  boolean noinit;
+  int value;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilterTypeOfService.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilterTypeOfService.aidl
new file mode 100644
index 0000000..fa85b5a
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosFilterTypeOfService.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+union QosFilterTypeOfService {
+  boolean noinit;
+  byte value;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosSession.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosSession.aidl
new file mode 100644
index 0000000..bbfdd2d
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/QosSession.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable QosSession {
+  int qosSessionId;
+  android.hardware.radio.data.Qos qos;
+  android.hardware.radio.data.QosFilter[] qosFilters;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/RouteSelectionDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/RouteSelectionDescriptor.aidl
new file mode 100644
index 0000000..acbdbd0
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/RouteSelectionDescriptor.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable RouteSelectionDescriptor {
+  byte precedence;
+  android.hardware.radio.data.PdpProtocolType sessionType;
+  byte sscMode;
+  android.hardware.radio.data.SliceInfo[] sliceInfo;
+  String[] dnn;
+  const byte SSC_MODE_UNKNOWN = (-1) /* -1 */;
+  const byte SSC_MODE_1 = 1;
+  const byte SSC_MODE_2 = 2;
+  const byte SSC_MODE_3 = 3;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/SetupDataCallResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/SetupDataCallResult.aidl
new file mode 100644
index 0000000..83f9db6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/SetupDataCallResult.aidl
@@ -0,0 +1,62 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable SetupDataCallResult {
+  android.hardware.radio.data.DataCallFailCause cause;
+  long suggestedRetryTime;
+  int cid;
+  int active;
+  android.hardware.radio.data.PdpProtocolType type;
+  String ifname;
+  android.hardware.radio.data.LinkAddress[] addresses;
+  String[] dnses;
+  String[] gateways;
+  String[] pcscf;
+  int mtuV4;
+  int mtuV6;
+  android.hardware.radio.data.Qos defaultQos;
+  android.hardware.radio.data.QosSession[] qosSessions;
+  byte handoverFailureMode;
+  int pduSessionId;
+  @nullable android.hardware.radio.data.SliceInfo sliceInfo;
+  android.hardware.radio.data.TrafficDescriptor[] trafficDescriptors;
+  const int DATA_CONNECTION_STATUS_INACTIVE = 0;
+  const int DATA_CONNECTION_STATUS_DORMANT = 1;
+  const int DATA_CONNECTION_STATUS_ACTIVE = 2;
+  const byte HANDOVER_FAILURE_MODE_LEGACY = 0;
+  const byte HANDOVER_FAILURE_MODE_DO_FALLBACK = 1;
+  const byte HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER = 2;
+  const byte HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL = 3;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/SliceInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/SliceInfo.aidl
new file mode 100644
index 0000000..efe4816
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/SliceInfo.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable SliceInfo {
+  byte sliceServiceType;
+  int sliceDifferentiator;
+  byte mappedHplmnSst;
+  int mappedHplmnSd;
+  byte status;
+  const byte SERVICE_TYPE_NONE = 0;
+  const byte SERVICE_TYPE_EMBB = 1;
+  const byte SERVICE_TYPE_URLLC = 2;
+  const byte SERVICE_TYPE_MIOT = 3;
+  const byte STATUS_UNKNOWN = 0;
+  const byte STATUS_CONFIGURED = 1;
+  const byte STATUS_ALLOWED = 2;
+  const byte STATUS_REJECTED_NOT_AVAILABLE_IN_PLMN = 3;
+  const byte STATUS_REJECTED_NOT_AVAILABLE_IN_REG_AREA = 4;
+  const byte STATUS_DEFAULT_CONFIGURED = 5;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/SlicingConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/SlicingConfig.aidl
new file mode 100644
index 0000000..b00febe
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/SlicingConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable SlicingConfig {
+  android.hardware.radio.data.UrspRule[] urspRules;
+  android.hardware.radio.data.SliceInfo[] sliceInfo;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/TrafficDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/TrafficDescriptor.aidl
new file mode 100644
index 0000000..d7b0654
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/TrafficDescriptor.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable TrafficDescriptor {
+  @nullable String dnn;
+  @nullable android.hardware.radio.data.OsAppId osAppId;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/UrspRule.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/UrspRule.aidl
new file mode 100644
index 0000000..7002fd1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/2/android/hardware/radio/data/UrspRule.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.data;
+@JavaDerive(toString=true) @VintfStability
+parcelable UrspRule {
+  int precedence;
+  android.hardware.radio.data.TrafficDescriptor[] trafficDescriptors;
+  android.hardware.radio.data.RouteSelectionDescriptor[] routeSelectionDescriptor;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl
index 86272c2..a33ad6e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl
@@ -34,8 +34,8 @@
 package android.hardware.radio.data;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum ApnAuthType {
-  NO_PAP_NO_CHAP = 0,
-  PAP_NO_CHAP = 1,
-  NO_PAP_CHAP = 2,
-  PAP_CHAP = 3,
+  NO_PAP_NO_CHAP,
+  PAP_NO_CHAP,
+  NO_PAP_CHAP,
+  PAP_CHAP,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
index 1518a57..45d22c8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
@@ -35,19 +35,19 @@
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum ApnTypes {
   NONE = 0,
-  DEFAULT = 1,
-  MMS = 2,
-  SUPL = 4,
-  DUN = 8,
-  HIPRI = 16,
-  FOTA = 32,
-  IMS = 64,
-  CBS = 128,
-  IA = 256,
-  EMERGENCY = 512,
-  MCX = 1024,
-  XCAP = 2048,
-  VSIM = 4096,
-  BIP = 8192,
-  ENTERPRISE = 16384,
+  DEFAULT = (1 << 0),
+  MMS = (1 << 1),
+  SUPL = (1 << 2),
+  DUN = (1 << 3),
+  HIPRI = (1 << 4),
+  FOTA = (1 << 5),
+  IMS = (1 << 6),
+  CBS = (1 << 7),
+  IA = (1 << 8),
+  EMERGENCY = (1 << 9),
+  MCX = (1 << 10),
+  XCAP = (1 << 11),
+  VSIM = (1 << 12),
+  BIP = (1 << 13),
+  ENTERPRISE = (1 << 14),
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
index d7d6983..8a3fd4f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
@@ -35,343 +35,347 @@
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum DataCallFailCause {
   NONE = 0,
-  OPERATOR_BARRED = 8,
-  NAS_SIGNALLING = 14,
-  INSUFFICIENT_RESOURCES = 26,
-  MISSING_UNKNOWN_APN = 27,
-  UNKNOWN_PDP_ADDRESS_TYPE = 28,
-  USER_AUTHENTICATION = 29,
-  ACTIVATION_REJECT_GGSN = 30,
-  ACTIVATION_REJECT_UNSPECIFIED = 31,
-  SERVICE_OPTION_NOT_SUPPORTED = 32,
-  SERVICE_OPTION_NOT_SUBSCRIBED = 33,
-  SERVICE_OPTION_OUT_OF_ORDER = 34,
-  NSAPI_IN_USE = 35,
-  REGULAR_DEACTIVATION = 36,
-  QOS_NOT_ACCEPTED = 37,
-  NETWORK_FAILURE = 38,
-  UMTS_REACTIVATION_REQ = 39,
-  FEATURE_NOT_SUPP = 40,
-  TFT_SEMANTIC_ERROR = 41,
-  TFT_SYTAX_ERROR = 42,
-  UNKNOWN_PDP_CONTEXT = 43,
-  FILTER_SEMANTIC_ERROR = 44,
-  FILTER_SYTAX_ERROR = 45,
-  PDP_WITHOUT_ACTIVE_TFT = 46,
-  ONLY_IPV4_ALLOWED = 50,
-  ONLY_IPV6_ALLOWED = 51,
-  ONLY_SINGLE_BEARER_ALLOWED = 52,
-  ESM_INFO_NOT_RECEIVED = 53,
-  PDN_CONN_DOES_NOT_EXIST = 54,
-  MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 55,
-  MAX_ACTIVE_PDP_CONTEXT_REACHED = 65,
-  UNSUPPORTED_APN_IN_CURRENT_PLMN = 66,
-  INVALID_TRANSACTION_ID = 81,
-  MESSAGE_INCORRECT_SEMANTIC = 95,
-  INVALID_MANDATORY_INFO = 96,
-  MESSAGE_TYPE_UNSUPPORTED = 97,
-  MSG_TYPE_NONCOMPATIBLE_STATE = 98,
-  UNKNOWN_INFO_ELEMENT = 99,
-  CONDITIONAL_IE_ERROR = 100,
-  MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 101,
-  PROTOCOL_ERRORS = 111,
-  APN_TYPE_CONFLICT = 112,
-  INVALID_PCSCF_ADDR = 113,
-  INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 114,
-  EMM_ACCESS_BARRED = 115,
-  EMERGENCY_IFACE_ONLY = 116,
-  IFACE_MISMATCH = 117,
-  COMPANION_IFACE_IN_USE = 118,
-  IP_ADDRESS_MISMATCH = 119,
-  IFACE_AND_POL_FAMILY_MISMATCH = 120,
-  EMM_ACCESS_BARRED_INFINITE_RETRY = 121,
-  AUTH_FAILURE_ON_EMERGENCY_CALL = 122,
-  OEM_DCFAILCAUSE_1 = 4097,
-  OEM_DCFAILCAUSE_2 = 4098,
-  OEM_DCFAILCAUSE_3 = 4099,
-  OEM_DCFAILCAUSE_4 = 4100,
-  OEM_DCFAILCAUSE_5 = 4101,
-  OEM_DCFAILCAUSE_6 = 4102,
-  OEM_DCFAILCAUSE_7 = 4103,
-  OEM_DCFAILCAUSE_8 = 4104,
-  OEM_DCFAILCAUSE_9 = 4105,
-  OEM_DCFAILCAUSE_10 = 4106,
-  OEM_DCFAILCAUSE_11 = 4107,
-  OEM_DCFAILCAUSE_12 = 4108,
-  OEM_DCFAILCAUSE_13 = 4109,
-  OEM_DCFAILCAUSE_14 = 4110,
-  OEM_DCFAILCAUSE_15 = 4111,
-  VOICE_REGISTRATION_FAIL = -1,
-  DATA_REGISTRATION_FAIL = -2,
-  SIGNAL_LOST = -3,
-  PREF_RADIO_TECH_CHANGED = -4,
-  RADIO_POWER_OFF = -5,
-  TETHERED_CALL_ACTIVE = -6,
-  ERROR_UNSPECIFIED = 65535,
-  LLC_SNDCP = 25,
-  ACTIVATION_REJECTED_BCM_VIOLATION = 48,
-  COLLISION_WITH_NETWORK_INITIATED_REQUEST = 56,
-  ONLY_IPV4V6_ALLOWED = 57,
-  ONLY_NON_IP_ALLOWED = 58,
-  UNSUPPORTED_QCI_VALUE = 59,
-  BEARER_HANDLING_NOT_SUPPORTED = 60,
-  INVALID_DNS_ADDR = 123,
-  INVALID_PCSCF_OR_DNS_ADDRESS = 124,
-  CALL_PREEMPT_BY_EMERGENCY_APN = 127,
-  UE_INITIATED_DETACH_OR_DISCONNECT = 128,
-  MIP_FA_REASON_UNSPECIFIED = 2000,
-  MIP_FA_ADMIN_PROHIBITED = 2001,
-  MIP_FA_INSUFFICIENT_RESOURCES = 2002,
-  MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 2003,
-  MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 2004,
-  MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 2005,
-  MIP_FA_MALFORMED_REQUEST = 2006,
-  MIP_FA_MALFORMED_REPLY = 2007,
-  MIP_FA_ENCAPSULATION_UNAVAILABLE = 2008,
-  MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 2009,
-  MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 2010,
-  MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 2011,
-  MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 2012,
-  MIP_FA_MISSING_NAI = 2013,
-  MIP_FA_MISSING_HOME_AGENT = 2014,
-  MIP_FA_MISSING_HOME_ADDRESS = 2015,
-  MIP_FA_UNKNOWN_CHALLENGE = 2016,
-  MIP_FA_MISSING_CHALLENGE = 2017,
-  MIP_FA_STALE_CHALLENGE = 2018,
-  MIP_HA_REASON_UNSPECIFIED = 2019,
-  MIP_HA_ADMIN_PROHIBITED = 2020,
-  MIP_HA_INSUFFICIENT_RESOURCES = 2021,
-  MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 2022,
-  MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 2023,
-  MIP_HA_REGISTRATION_ID_MISMATCH = 2024,
-  MIP_HA_MALFORMED_REQUEST = 2025,
-  MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 2026,
-  MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 2027,
-  MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 2028,
-  MIP_HA_ENCAPSULATION_UNAVAILABLE = 2029,
-  CLOSE_IN_PROGRESS = 2030,
-  NETWORK_INITIATED_TERMINATION = 2031,
-  MODEM_APP_PREEMPTED = 2032,
-  PDN_IPV4_CALL_DISALLOWED = 2033,
-  PDN_IPV4_CALL_THROTTLED = 2034,
-  PDN_IPV6_CALL_DISALLOWED = 2035,
-  PDN_IPV6_CALL_THROTTLED = 2036,
-  MODEM_RESTART = 2037,
-  PDP_PPP_NOT_SUPPORTED = 2038,
-  UNPREFERRED_RAT = 2039,
-  PHYSICAL_LINK_CLOSE_IN_PROGRESS = 2040,
-  APN_PENDING_HANDOVER = 2041,
-  PROFILE_BEARER_INCOMPATIBLE = 2042,
-  SIM_CARD_CHANGED = 2043,
-  LOW_POWER_MODE_OR_POWERING_DOWN = 2044,
-  APN_DISABLED = 2045,
-  MAX_PPP_INACTIVITY_TIMER_EXPIRED = 2046,
-  IPV6_ADDRESS_TRANSFER_FAILED = 2047,
-  TRAT_SWAP_FAILED = 2048,
-  EHRPD_TO_HRPD_FALLBACK = 2049,
-  MIP_CONFIG_FAILURE = 2050,
-  PDN_INACTIVITY_TIMER_EXPIRED = 2051,
-  MAX_IPV4_CONNECTIONS = 2052,
-  MAX_IPV6_CONNECTIONS = 2053,
-  APN_MISMATCH = 2054,
-  IP_VERSION_MISMATCH = 2055,
-  DUN_CALL_DISALLOWED = 2056,
-  INTERNAL_EPC_NONEPC_TRANSITION = 2057,
-  INTERFACE_IN_USE = 2058,
-  APN_DISALLOWED_ON_ROAMING = 2059,
-  APN_PARAMETERS_CHANGED = 2060,
-  NULL_APN_DISALLOWED = 2061,
-  THERMAL_MITIGATION = 2062,
-  DATA_SETTINGS_DISABLED = 2063,
-  DATA_ROAMING_SETTINGS_DISABLED = 2064,
-  DDS_SWITCHED = 2065,
-  FORBIDDEN_APN_NAME = 2066,
-  DDS_SWITCH_IN_PROGRESS = 2067,
-  CALL_DISALLOWED_IN_ROAMING = 2068,
-  NON_IP_NOT_SUPPORTED = 2069,
-  PDN_NON_IP_CALL_THROTTLED = 2070,
-  PDN_NON_IP_CALL_DISALLOWED = 2071,
-  CDMA_LOCK = 2072,
-  CDMA_INTERCEPT = 2073,
-  CDMA_REORDER = 2074,
-  CDMA_RELEASE_DUE_TO_SO_REJECTION = 2075,
-  CDMA_INCOMING_CALL = 2076,
-  CDMA_ALERT_STOP = 2077,
-  CHANNEL_ACQUISITION_FAILURE = 2078,
-  MAX_ACCESS_PROBE = 2079,
-  CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION = 2080,
-  NO_RESPONSE_FROM_BASE_STATION = 2081,
-  REJECTED_BY_BASE_STATION = 2082,
-  CONCURRENT_SERVICES_INCOMPATIBLE = 2083,
-  NO_CDMA_SERVICE = 2084,
-  RUIM_NOT_PRESENT = 2085,
-  CDMA_RETRY_ORDER = 2086,
-  ACCESS_BLOCK = 2087,
-  ACCESS_BLOCK_ALL = 2088,
-  IS707B_MAX_ACCESS_PROBES = 2089,
-  THERMAL_EMERGENCY = 2090,
-  CONCURRENT_SERVICES_NOT_ALLOWED = 2091,
-  INCOMING_CALL_REJECTED = 2092,
-  NO_SERVICE_ON_GATEWAY = 2093,
-  NO_GPRS_CONTEXT = 2094,
-  ILLEGAL_MS = 2095,
-  ILLEGAL_ME = 2096,
-  GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 2097,
-  GPRS_SERVICES_NOT_ALLOWED = 2098,
-  MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 2099,
-  IMPLICITLY_DETACHED = 2100,
-  PLMN_NOT_ALLOWED = 2101,
-  LOCATION_AREA_NOT_ALLOWED = 2102,
-  GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 2103,
-  PDP_DUPLICATE = 2104,
-  UE_RAT_CHANGE = 2105,
-  CONGESTION = 2106,
-  NO_PDP_CONTEXT_ACTIVATED = 2107,
-  ACCESS_CLASS_DSAC_REJECTION = 2108,
-  PDP_ACTIVATE_MAX_RETRY_FAILED = 2109,
-  RADIO_ACCESS_BEARER_FAILURE = 2110,
-  ESM_UNKNOWN_EPS_BEARER_CONTEXT = 2111,
-  DRB_RELEASED_BY_RRC = 2112,
-  CONNECTION_RELEASED = 2113,
-  EMM_DETACHED = 2114,
-  EMM_ATTACH_FAILED = 2115,
-  EMM_ATTACH_STARTED = 2116,
-  LTE_NAS_SERVICE_REQUEST_FAILED = 2117,
-  DUPLICATE_BEARER_ID = 2118,
-  ESM_COLLISION_SCENARIOS = 2119,
-  ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 2120,
-  ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 2121,
-  ESM_BAD_OTA_MESSAGE = 2122,
-  ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 2123,
-  ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 2124,
-  DS_EXPLICIT_DEACTIVATION = 2125,
-  ESM_LOCAL_CAUSE_NONE = 2126,
-  LTE_THROTTLING_NOT_REQUIRED = 2127,
-  ACCESS_CONTROL_LIST_CHECK_FAILURE = 2128,
-  SERVICE_NOT_ALLOWED_ON_PLMN = 2129,
-  EMM_T3417_EXPIRED = 2130,
-  EMM_T3417_EXT_EXPIRED = 2131,
-  RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 2132,
-  RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 2133,
-  RRC_UPLINK_CONNECTION_RELEASE = 2134,
-  RRC_UPLINK_RADIO_LINK_FAILURE = 2135,
-  RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 2136,
-  RRC_CONNECTION_ACCESS_STRATUM_FAILURE = 2137,
-  RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS = 2138,
-  RRC_CONNECTION_ACCESS_BARRED = 2139,
-  RRC_CONNECTION_CELL_RESELECTION = 2140,
-  RRC_CONNECTION_CONFIG_FAILURE = 2141,
-  RRC_CONNECTION_TIMER_EXPIRED = 2142,
-  RRC_CONNECTION_LINK_FAILURE = 2143,
-  RRC_CONNECTION_CELL_NOT_CAMPED = 2144,
-  RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE = 2145,
-  RRC_CONNECTION_REJECT_BY_NETWORK = 2146,
-  RRC_CONNECTION_NORMAL_RELEASE = 2147,
-  RRC_CONNECTION_RADIO_LINK_FAILURE = 2148,
-  RRC_CONNECTION_REESTABLISHMENT_FAILURE = 2149,
-  RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER = 2150,
-  RRC_CONNECTION_ABORT_REQUEST = 2151,
-  RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 2152,
-  NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 2153,
-  NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 2154,
-  ESM_PROCEDURE_TIME_OUT = 2155,
-  INVALID_CONNECTION_ID = 2156,
-  MAXIMIUM_NSAPIS_EXCEEDED = 2157,
-  INVALID_PRIMARY_NSAPI = 2158,
-  CANNOT_ENCODE_OTA_MESSAGE = 2159,
-  RADIO_ACCESS_BEARER_SETUP_FAILURE = 2160,
-  PDP_ESTABLISH_TIMEOUT_EXPIRED = 2161,
-  PDP_MODIFY_TIMEOUT_EXPIRED = 2162,
-  PDP_INACTIVE_TIMEOUT_EXPIRED = 2163,
-  PDP_LOWERLAYER_ERROR = 2164,
-  PDP_MODIFY_COLLISION = 2165,
-  MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 2166,
-  NAS_REQUEST_REJECTED_BY_NETWORK = 2167,
-  RRC_CONNECTION_INVALID_REQUEST = 2168,
-  RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 2169,
-  RRC_CONNECTION_RF_UNAVAILABLE = 2170,
-  RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 2171,
-  RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 2172,
-  RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 2173,
-  RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 2174,
-  RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 2175,
-  IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 2176,
-  IMEI_NOT_ACCEPTED = 2177,
-  EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 2178,
-  EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 2179,
-  MSC_TEMPORARILY_NOT_REACHABLE = 2180,
-  CS_DOMAIN_NOT_AVAILABLE = 2181,
-  ESM_FAILURE = 2182,
-  MAC_FAILURE = 2183,
-  SYNCHRONIZATION_FAILURE = 2184,
-  UE_SECURITY_CAPABILITIES_MISMATCH = 2185,
-  SECURITY_MODE_REJECTED = 2186,
-  UNACCEPTABLE_NON_EPS_AUTHENTICATION = 2187,
-  CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 2188,
-  NO_EPS_BEARER_CONTEXT_ACTIVATED = 2189,
-  INVALID_EMM_STATE = 2190,
-  NAS_LAYER_FAILURE = 2191,
-  MULTIPLE_PDP_CALL_NOT_ALLOWED = 2192,
-  EMBMS_NOT_ENABLED = 2193,
-  IRAT_HANDOVER_FAILED = 2194,
-  EMBMS_REGULAR_DEACTIVATION = 2195,
-  TEST_LOOPBACK_REGULAR_DEACTIVATION = 2196,
-  LOWER_LAYER_REGISTRATION_FAILURE = 2197,
-  DATA_PLAN_EXPIRED = 2198,
-  UMTS_HANDOVER_TO_IWLAN = 2199,
-  EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 2200,
-  EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 2201,
-  EVDO_HDR_CHANGED = 2202,
-  EVDO_HDR_EXITED = 2203,
-  EVDO_HDR_NO_SESSION = 2204,
-  EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 2205,
-  EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 2206,
-  FAILED_TO_ACQUIRE_COLOCATED_HDR = 2207,
-  OTASP_COMMIT_IN_PROGRESS = 2208,
-  NO_HYBRID_HDR_SERVICE = 2209,
-  HDR_NO_LOCK_GRANTED = 2210,
-  DBM_OR_SMS_IN_PROGRESS = 2211,
-  HDR_FADE = 2212,
-  HDR_ACCESS_FAILURE = 2213,
-  UNSUPPORTED_1X_PREV = 2214,
-  LOCAL_END = 2215,
-  NO_SERVICE = 2216,
-  FADE = 2217,
-  NORMAL_RELEASE = 2218,
-  ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219,
-  REDIRECTION_OR_HANDOFF_IN_PROGRESS = 2220,
-  EMERGENCY_MODE = 2221,
-  PHONE_IN_USE = 2222,
-  INVALID_MODE = 2223,
-  INVALID_SIM_STATE = 2224,
-  NO_COLLOCATED_HDR = 2225,
-  UE_IS_ENTERING_POWERSAVE_MODE = 2226,
-  DUAL_SWITCH = 2227,
-  PPP_TIMEOUT = 2228,
-  PPP_AUTH_FAILURE = 2229,
-  PPP_OPTION_MISMATCH = 2230,
-  PPP_PAP_FAILURE = 2231,
-  PPP_CHAP_FAILURE = 2232,
-  PPP_CLOSE_IN_PROGRESS = 2233,
-  LIMITED_TO_IPV4 = 2234,
-  LIMITED_TO_IPV6 = 2235,
-  VSNCP_TIMEOUT = 2236,
-  VSNCP_GEN_ERROR = 2237,
-  VSNCP_APN_UNAUTHORIZED = 2238,
-  VSNCP_PDN_LIMIT_EXCEEDED = 2239,
-  VSNCP_NO_PDN_GATEWAY_ADDRESS = 2240,
-  VSNCP_PDN_GATEWAY_UNREACHABLE = 2241,
-  VSNCP_PDN_GATEWAY_REJECT = 2242,
-  VSNCP_INSUFFICIENT_PARAMETERS = 2243,
-  VSNCP_RESOURCE_UNAVAILABLE = 2244,
-  VSNCP_ADMINISTRATIVELY_PROHIBITED = 2245,
-  VSNCP_PDN_ID_IN_USE = 2246,
-  VSNCP_SUBSCRIBER_LIMITATION = 2247,
-  VSNCP_PDN_EXISTS_FOR_THIS_APN = 2248,
-  VSNCP_RECONNECT_NOT_ALLOWED = 2249,
-  IPV6_PREFIX_UNAVAILABLE = 2250,
-  HANDOFF_PREFERENCE_CHANGED = 2251,
-  SLICE_REJECTED = 2252,
-  MATCH_ALL_RULE_NOT_ALLOWED = 2253,
-  ALL_MATCHING_RULES_FAILED = 2254,
+  OPERATOR_BARRED = 0x08,
+  NAS_SIGNALLING = 0x0E,
+  INSUFFICIENT_RESOURCES = 0x1A,
+  MISSING_UNKNOWN_APN = 0x1B,
+  UNKNOWN_PDP_ADDRESS_TYPE = 0x1C,
+  USER_AUTHENTICATION = 0x1D,
+  ACTIVATION_REJECT_GGSN = 0x1E,
+  ACTIVATION_REJECT_UNSPECIFIED = 0x1F,
+  SERVICE_OPTION_NOT_SUPPORTED = 0x20,
+  SERVICE_OPTION_NOT_SUBSCRIBED = 0x21,
+  SERVICE_OPTION_OUT_OF_ORDER = 0x22,
+  NSAPI_IN_USE = 0x23,
+  REGULAR_DEACTIVATION = 0x24,
+  QOS_NOT_ACCEPTED = 0x25,
+  NETWORK_FAILURE = 0x26,
+  UMTS_REACTIVATION_REQ = 0x27,
+  FEATURE_NOT_SUPP = 0x28,
+  TFT_SEMANTIC_ERROR = 0x29,
+  TFT_SYTAX_ERROR = 0x2A,
+  UNKNOWN_PDP_CONTEXT = 0x2B,
+  FILTER_SEMANTIC_ERROR = 0x2C,
+  FILTER_SYTAX_ERROR = 0x2D,
+  PDP_WITHOUT_ACTIVE_TFT = 0x2E,
+  ONLY_IPV4_ALLOWED = 0x32,
+  ONLY_IPV6_ALLOWED = 0x33,
+  ONLY_SINGLE_BEARER_ALLOWED = 0x34,
+  ESM_INFO_NOT_RECEIVED = 0x35,
+  PDN_CONN_DOES_NOT_EXIST = 0x36,
+  MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37,
+  MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41,
+  UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42,
+  INVALID_TRANSACTION_ID = 0x51,
+  MESSAGE_INCORRECT_SEMANTIC = 0x5F,
+  INVALID_MANDATORY_INFO = 0x60,
+  MESSAGE_TYPE_UNSUPPORTED = 0x61,
+  MSG_TYPE_NONCOMPATIBLE_STATE = 0x62,
+  UNKNOWN_INFO_ELEMENT = 0x63,
+  CONDITIONAL_IE_ERROR = 0x64,
+  MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65,
+  PROTOCOL_ERRORS = 0x6F,
+  APN_TYPE_CONFLICT = 0x70,
+  INVALID_PCSCF_ADDR = 0x71,
+  INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72,
+  EMM_ACCESS_BARRED = 0x73,
+  EMERGENCY_IFACE_ONLY = 0x74,
+  IFACE_MISMATCH = 0x75,
+  COMPANION_IFACE_IN_USE = 0x76,
+  IP_ADDRESS_MISMATCH = 0x77,
+  IFACE_AND_POL_FAMILY_MISMATCH = 0x78,
+  EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79,
+  AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A,
+  OEM_DCFAILCAUSE_1 = 0x1001,
+  OEM_DCFAILCAUSE_2 = 0x1002,
+  OEM_DCFAILCAUSE_3 = 0x1003,
+  OEM_DCFAILCAUSE_4 = 0x1004,
+  OEM_DCFAILCAUSE_5 = 0x1005,
+  OEM_DCFAILCAUSE_6 = 0x1006,
+  OEM_DCFAILCAUSE_7 = 0x1007,
+  OEM_DCFAILCAUSE_8 = 0x1008,
+  OEM_DCFAILCAUSE_9 = 0x1009,
+  OEM_DCFAILCAUSE_10 = 0x100A,
+  OEM_DCFAILCAUSE_11 = 0x100B,
+  OEM_DCFAILCAUSE_12 = 0x100C,
+  OEM_DCFAILCAUSE_13 = 0x100D,
+  OEM_DCFAILCAUSE_14 = 0x100E,
+  OEM_DCFAILCAUSE_15 = 0x100F,
+  VOICE_REGISTRATION_FAIL = (-1),
+  DATA_REGISTRATION_FAIL = (-2),
+  SIGNAL_LOST = (-3),
+  PREF_RADIO_TECH_CHANGED = (-4),
+  RADIO_POWER_OFF = (-5),
+  TETHERED_CALL_ACTIVE = (-6),
+  ERROR_UNSPECIFIED = 0xffff,
+  LLC_SNDCP = 0x19,
+  ACTIVATION_REJECTED_BCM_VIOLATION = 0x30,
+  COLLISION_WITH_NETWORK_INITIATED_REQUEST = 0x38,
+  ONLY_IPV4V6_ALLOWED = 0x39,
+  ONLY_NON_IP_ALLOWED = 0x3A,
+  UNSUPPORTED_QCI_VALUE = 0x3B,
+  BEARER_HANDLING_NOT_SUPPORTED = 0x3C,
+  INVALID_DNS_ADDR = 0x7B,
+  INVALID_PCSCF_OR_DNS_ADDRESS = 0x7C,
+  CALL_PREEMPT_BY_EMERGENCY_APN = 0x7F,
+  UE_INITIATED_DETACH_OR_DISCONNECT = 0x80,
+  MIP_FA_REASON_UNSPECIFIED = 0x7D0,
+  MIP_FA_ADMIN_PROHIBITED = 0x7D1,
+  MIP_FA_INSUFFICIENT_RESOURCES = 0x7D2,
+  MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7D3,
+  MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 0x7D4,
+  MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 0x7D5,
+  MIP_FA_MALFORMED_REQUEST = 0x7D6,
+  MIP_FA_MALFORMED_REPLY = 0x7D7,
+  MIP_FA_ENCAPSULATION_UNAVAILABLE = 0x7D8,
+  MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 0x7D9,
+  MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 0x7DA,
+  MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 0x7DB,
+  MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 0x7DC,
+  MIP_FA_MISSING_NAI = 0x7DD,
+  MIP_FA_MISSING_HOME_AGENT = 0x7DE,
+  MIP_FA_MISSING_HOME_ADDRESS = 0x7DF,
+  MIP_FA_UNKNOWN_CHALLENGE = 0x7E0,
+  MIP_FA_MISSING_CHALLENGE = 0x7E1,
+  MIP_FA_STALE_CHALLENGE = 0x7E2,
+  MIP_HA_REASON_UNSPECIFIED = 0x7E3,
+  MIP_HA_ADMIN_PROHIBITED = 0x7E4,
+  MIP_HA_INSUFFICIENT_RESOURCES = 0x7E5,
+  MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7E6,
+  MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 0x7E7,
+  MIP_HA_REGISTRATION_ID_MISMATCH = 0x7E8,
+  MIP_HA_MALFORMED_REQUEST = 0x7E9,
+  MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 0x7EA,
+  MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 0x7EB,
+  MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 0x7EC,
+  MIP_HA_ENCAPSULATION_UNAVAILABLE = 0x7ED,
+  CLOSE_IN_PROGRESS = 0x7EE,
+  NETWORK_INITIATED_TERMINATION = 0x7EF,
+  MODEM_APP_PREEMPTED = 0x7F0,
+  PDN_IPV4_CALL_DISALLOWED = 0x7F1,
+  PDN_IPV4_CALL_THROTTLED = 0x7F2,
+  PDN_IPV6_CALL_DISALLOWED = 0x7F3,
+  PDN_IPV6_CALL_THROTTLED = 0x7F4,
+  MODEM_RESTART = 0x7F5,
+  PDP_PPP_NOT_SUPPORTED = 0x7F6,
+  UNPREFERRED_RAT = 0x7F7,
+  PHYSICAL_LINK_CLOSE_IN_PROGRESS = 0x7F8,
+  APN_PENDING_HANDOVER = 0x7F9,
+  PROFILE_BEARER_INCOMPATIBLE = 0x7FA,
+  SIM_CARD_CHANGED = 0x7FB,
+  LOW_POWER_MODE_OR_POWERING_DOWN = 0x7FC,
+  APN_DISABLED = 0x7FD,
+  MAX_PPP_INACTIVITY_TIMER_EXPIRED = 0x7FE,
+  IPV6_ADDRESS_TRANSFER_FAILED = 0x7FF,
+  TRAT_SWAP_FAILED = 0x800,
+  EHRPD_TO_HRPD_FALLBACK = 0x801,
+  MIP_CONFIG_FAILURE = 0x802,
+  PDN_INACTIVITY_TIMER_EXPIRED = 0x803,
+  MAX_IPV4_CONNECTIONS = 0x804,
+  MAX_IPV6_CONNECTIONS = 0x805,
+  APN_MISMATCH = 0x806,
+  IP_VERSION_MISMATCH = 0x807,
+  DUN_CALL_DISALLOWED = 0x808,
+  INTERNAL_EPC_NONEPC_TRANSITION = 0x809,
+  INTERFACE_IN_USE = 0x80A,
+  APN_DISALLOWED_ON_ROAMING = 0x80B,
+  APN_PARAMETERS_CHANGED = 0x80C,
+  NULL_APN_DISALLOWED = 0x80D,
+  THERMAL_MITIGATION = 0x80E,
+  DATA_SETTINGS_DISABLED = 0x80F,
+  DATA_ROAMING_SETTINGS_DISABLED = 0x810,
+  DDS_SWITCHED = 0x811,
+  FORBIDDEN_APN_NAME = 0x812,
+  DDS_SWITCH_IN_PROGRESS = 0x813,
+  CALL_DISALLOWED_IN_ROAMING = 0x814,
+  NON_IP_NOT_SUPPORTED = 0x815,
+  PDN_NON_IP_CALL_THROTTLED = 0x816,
+  PDN_NON_IP_CALL_DISALLOWED = 0x817,
+  CDMA_LOCK = 0x818,
+  CDMA_INTERCEPT = 0x819,
+  CDMA_REORDER = 0x81A,
+  CDMA_RELEASE_DUE_TO_SO_REJECTION = 0x81B,
+  CDMA_INCOMING_CALL = 0x81C,
+  CDMA_ALERT_STOP = 0x81D,
+  CHANNEL_ACQUISITION_FAILURE = 0x81E,
+  MAX_ACCESS_PROBE = 0x81F,
+  CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION = 0x820,
+  NO_RESPONSE_FROM_BASE_STATION = 0x821,
+  REJECTED_BY_BASE_STATION = 0x822,
+  CONCURRENT_SERVICES_INCOMPATIBLE = 0x823,
+  NO_CDMA_SERVICE = 0x824,
+  RUIM_NOT_PRESENT = 0x825,
+  CDMA_RETRY_ORDER = 0x826,
+  ACCESS_BLOCK = 0x827,
+  ACCESS_BLOCK_ALL = 0x828,
+  IS707B_MAX_ACCESS_PROBES = 0x829,
+  THERMAL_EMERGENCY = 0x82A,
+  CONCURRENT_SERVICES_NOT_ALLOWED = 0x82B,
+  INCOMING_CALL_REJECTED = 0x82C,
+  NO_SERVICE_ON_GATEWAY = 0x82D,
+  NO_GPRS_CONTEXT = 0x82E,
+  ILLEGAL_MS = 0x82F,
+  ILLEGAL_ME = 0x830,
+  GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 0x831,
+  GPRS_SERVICES_NOT_ALLOWED = 0x832,
+  MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 0x833,
+  IMPLICITLY_DETACHED = 0x834,
+  PLMN_NOT_ALLOWED = 0x835,
+  LOCATION_AREA_NOT_ALLOWED = 0x836,
+  GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 0x837,
+  PDP_DUPLICATE = 0x838,
+  UE_RAT_CHANGE = 0x839,
+  CONGESTION = 0x83A,
+  NO_PDP_CONTEXT_ACTIVATED = 0x83B,
+  ACCESS_CLASS_DSAC_REJECTION = 0x83C,
+  PDP_ACTIVATE_MAX_RETRY_FAILED = 0x83D,
+  RADIO_ACCESS_BEARER_FAILURE = 0x83E,
+  ESM_UNKNOWN_EPS_BEARER_CONTEXT = 0x83F,
+  DRB_RELEASED_BY_RRC = 0x840,
+  CONNECTION_RELEASED = 0x841,
+  EMM_DETACHED = 0x842,
+  EMM_ATTACH_FAILED = 0x843,
+  EMM_ATTACH_STARTED = 0x844,
+  LTE_NAS_SERVICE_REQUEST_FAILED = 0x845,
+  DUPLICATE_BEARER_ID = 0x846,
+  ESM_COLLISION_SCENARIOS = 0x847,
+  ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 0x848,
+  ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 0x849,
+  ESM_BAD_OTA_MESSAGE = 0x84A,
+  ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 0x84B,
+  ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 0x84C,
+  DS_EXPLICIT_DEACTIVATION = 0x84D,
+  ESM_LOCAL_CAUSE_NONE = 0x84E,
+  LTE_THROTTLING_NOT_REQUIRED = 0x84F,
+  ACCESS_CONTROL_LIST_CHECK_FAILURE = 0x850,
+  SERVICE_NOT_ALLOWED_ON_PLMN = 0x851,
+  EMM_T3417_EXPIRED = 0x852,
+  EMM_T3417_EXT_EXPIRED = 0x853,
+  RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 0x854,
+  RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 0x855,
+  RRC_UPLINK_CONNECTION_RELEASE = 0x856,
+  RRC_UPLINK_RADIO_LINK_FAILURE = 0x857,
+  RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 0x858,
+  RRC_CONNECTION_ACCESS_STRATUM_FAILURE = 0x859,
+  RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS = 0x85A,
+  RRC_CONNECTION_ACCESS_BARRED = 0x85B,
+  RRC_CONNECTION_CELL_RESELECTION = 0x85C,
+  RRC_CONNECTION_CONFIG_FAILURE = 0x85D,
+  RRC_CONNECTION_TIMER_EXPIRED = 0x85E,
+  RRC_CONNECTION_LINK_FAILURE = 0x85F,
+  RRC_CONNECTION_CELL_NOT_CAMPED = 0x860,
+  RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE = 0x861,
+  RRC_CONNECTION_REJECT_BY_NETWORK = 0x862,
+  RRC_CONNECTION_NORMAL_RELEASE = 0x863,
+  RRC_CONNECTION_RADIO_LINK_FAILURE = 0x864,
+  RRC_CONNECTION_REESTABLISHMENT_FAILURE = 0x865,
+  RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER = 0x866,
+  RRC_CONNECTION_ABORT_REQUEST = 0x867,
+  RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 0x868,
+  NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 0x869,
+  NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 0x86A,
+  ESM_PROCEDURE_TIME_OUT = 0x86B,
+  INVALID_CONNECTION_ID = 0x86C,
+  MAXIMIUM_NSAPIS_EXCEEDED = 0x86D,
+  INVALID_PRIMARY_NSAPI = 0x86E,
+  CANNOT_ENCODE_OTA_MESSAGE = 0x86F,
+  RADIO_ACCESS_BEARER_SETUP_FAILURE = 0x870,
+  PDP_ESTABLISH_TIMEOUT_EXPIRED = 0x871,
+  PDP_MODIFY_TIMEOUT_EXPIRED = 0x872,
+  PDP_INACTIVE_TIMEOUT_EXPIRED = 0x873,
+  PDP_LOWERLAYER_ERROR = 0x874,
+  PDP_MODIFY_COLLISION = 0x875,
+  /**
+   * @deprecated use MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED instead.
+   */
+  MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
+  MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
+  NAS_REQUEST_REJECTED_BY_NETWORK = 0x877,
+  RRC_CONNECTION_INVALID_REQUEST = 0x878,
+  RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 0x879,
+  RRC_CONNECTION_RF_UNAVAILABLE = 0x87A,
+  RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 0x87B,
+  RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 0x87C,
+  RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 0x87D,
+  RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 0x87E,
+  RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 0x87F,
+  IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 0x880,
+  IMEI_NOT_ACCEPTED = 0x881,
+  EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 0x882,
+  EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 0x883,
+  MSC_TEMPORARILY_NOT_REACHABLE = 0x884,
+  CS_DOMAIN_NOT_AVAILABLE = 0x885,
+  ESM_FAILURE = 0x886,
+  MAC_FAILURE = 0x887,
+  SYNCHRONIZATION_FAILURE = 0x888,
+  UE_SECURITY_CAPABILITIES_MISMATCH = 0x889,
+  SECURITY_MODE_REJECTED = 0x88A,
+  UNACCEPTABLE_NON_EPS_AUTHENTICATION = 0x88B,
+  CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 0x88C,
+  NO_EPS_BEARER_CONTEXT_ACTIVATED = 0x88D,
+  INVALID_EMM_STATE = 0x88E,
+  NAS_LAYER_FAILURE = 0x88F,
+  MULTIPLE_PDP_CALL_NOT_ALLOWED = 0x890,
+  EMBMS_NOT_ENABLED = 0x891,
+  IRAT_HANDOVER_FAILED = 0x892,
+  EMBMS_REGULAR_DEACTIVATION = 0x893,
+  TEST_LOOPBACK_REGULAR_DEACTIVATION = 0x894,
+  LOWER_LAYER_REGISTRATION_FAILURE = 0x895,
+  DATA_PLAN_EXPIRED = 0x896,
+  UMTS_HANDOVER_TO_IWLAN = 0x897,
+  EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 0x898,
+  EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 0x899,
+  EVDO_HDR_CHANGED = 0x89A,
+  EVDO_HDR_EXITED = 0x89B,
+  EVDO_HDR_NO_SESSION = 0x89C,
+  EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 0x89D,
+  EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 0x89E,
+  FAILED_TO_ACQUIRE_COLOCATED_HDR = 0x89F,
+  OTASP_COMMIT_IN_PROGRESS = 0x8A0,
+  NO_HYBRID_HDR_SERVICE = 0x8A1,
+  HDR_NO_LOCK_GRANTED = 0x8A2,
+  DBM_OR_SMS_IN_PROGRESS = 0x8A3,
+  HDR_FADE = 0x8A4,
+  HDR_ACCESS_FAILURE = 0x8A5,
+  UNSUPPORTED_1X_PREV = 0x8A6,
+  LOCAL_END = 0x8A7,
+  NO_SERVICE = 0x8A8,
+  FADE = 0x8A9,
+  NORMAL_RELEASE = 0x8AA,
+  ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 0x8AB,
+  REDIRECTION_OR_HANDOFF_IN_PROGRESS = 0x8AC,
+  EMERGENCY_MODE = 0x8AD,
+  PHONE_IN_USE = 0x8AE,
+  INVALID_MODE = 0x8AF,
+  INVALID_SIM_STATE = 0x8B0,
+  NO_COLLOCATED_HDR = 0x8B1,
+  UE_IS_ENTERING_POWERSAVE_MODE = 0x8B2,
+  DUAL_SWITCH = 0x8B3,
+  PPP_TIMEOUT = 0x8B4,
+  PPP_AUTH_FAILURE = 0x8B5,
+  PPP_OPTION_MISMATCH = 0x8B6,
+  PPP_PAP_FAILURE = 0x8B7,
+  PPP_CHAP_FAILURE = 0x8B8,
+  PPP_CLOSE_IN_PROGRESS = 0x8B9,
+  LIMITED_TO_IPV4 = 0x8BA,
+  LIMITED_TO_IPV6 = 0x8BB,
+  VSNCP_TIMEOUT = 0x8BC,
+  VSNCP_GEN_ERROR = 0x8BD,
+  VSNCP_APN_UNAUTHORIZED = 0x8BE,
+  VSNCP_PDN_LIMIT_EXCEEDED = 0x8BF,
+  VSNCP_NO_PDN_GATEWAY_ADDRESS = 0x8C0,
+  VSNCP_PDN_GATEWAY_UNREACHABLE = 0x8C1,
+  VSNCP_PDN_GATEWAY_REJECT = 0x8C2,
+  VSNCP_INSUFFICIENT_PARAMETERS = 0x8C3,
+  VSNCP_RESOURCE_UNAVAILABLE = 0x8C4,
+  VSNCP_ADMINISTRATIVELY_PROHIBITED = 0x8C5,
+  VSNCP_PDN_ID_IN_USE = 0x8C6,
+  VSNCP_SUBSCRIBER_LIMITATION = 0x8C7,
+  VSNCP_PDN_EXISTS_FOR_THIS_APN = 0x8C8,
+  VSNCP_RECONNECT_NOT_ALLOWED = 0x8C9,
+  IPV6_PREFIX_UNAVAILABLE = 0x8CA,
+  HANDOFF_PREFERENCE_CHANGED = 0x8CB,
+  SLICE_REJECTED = 0x8CC,
+  MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD,
+  ALL_MATCHING_RULES_FAILED = 0x8CE,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
index 16fada1..0136fa4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
@@ -60,7 +60,7 @@
   const int ID_FOTA = 3;
   const int ID_CBS = 4;
   const int ID_OEM_BASE = 1000;
-  const int ID_INVALID = -1;
+  const int ID_INVALID = 0xFFFFFFFF;
   const int TYPE_COMMON = 0;
   const int TYPE_3GPP = 1;
   const int TYPE_3GPP2 = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl
index 4f976cd..e80a764 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl
@@ -34,8 +34,8 @@
 package android.hardware.radio.data;
 @Backing(type="byte") @JavaDerive(toString=true) @VintfStability
 enum DataThrottlingAction {
-  NO_DATA_THROTTLING = 0,
-  THROTTLE_SECONDARY_CARRIER = 1,
-  THROTTLE_ANCHOR_CARRIER = 2,
-  HOLD = 3,
+  NO_DATA_THROTTLING,
+  THROTTLE_SECONDARY_CARRIER,
+  THROTTLE_ANCHOR_CARRIER,
+  HOLD,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
index 48e646e..77d637b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
@@ -39,5 +39,5 @@
   long deprecationTime;
   long expirationTime;
   const int ADDRESS_PROPERTY_NONE = 0;
-  const int ADDRESS_PROPERTY_DEPRECATED = 32;
+  const int ADDRESS_PROPERTY_DEPRECATED = 0x20;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
index 62f6204..be859b7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
@@ -38,7 +38,12 @@
   android.hardware.radio.data.QosBandwidth downlink;
   android.hardware.radio.data.QosBandwidth uplink;
   byte qfi;
+  /**
+   * @deprecated use averagingWindowMillis;
+   */
   char averagingWindowMs;
+  int averagingWindowMillis = AVERAGING_WINDOW_UNKNOWN;
   const byte FLOW_ID_RANGE_MIN = 1;
   const byte FLOW_ID_RANGE_MAX = 63;
+  const int AVERAGING_WINDOW_UNKNOWN = (-1);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl
index 9771e5c..d1c4a62 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl
@@ -34,7 +34,7 @@
 package android.hardware.radio.data;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum PdpProtocolType {
-  UNKNOWN = -1,
+  UNKNOWN = (-1),
   IP = 0,
   IPV6 = 1,
   IPV4V6 = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
index e22b359..de45cc5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
@@ -47,7 +47,7 @@
   const byte DIRECTION_DOWNLINK = 0;
   const byte DIRECTION_UPLINK = 1;
   const byte DIRECTION_BIDIRECTIONAL = 2;
-  const byte PROTOCOL_UNSPECIFIED = -1;
+  const byte PROTOCOL_UNSPECIFIED = (-1);
   const byte PROTOCOL_TCP = 6;
   const byte PROTOCOL_UDP = 17;
   const byte PROTOCOL_ESP = 50;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
index 434ee7d..d83df81 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
@@ -39,7 +39,7 @@
   byte sscMode;
   android.hardware.radio.data.SliceInfo[] sliceInfo;
   String[] dnn;
-  const byte SSC_MODE_UNKNOWN = -1;
+  const byte SSC_MODE_UNKNOWN = (-1);
   const byte SSC_MODE_1 = 1;
   const byte SSC_MODE_2 = 2;
   const byte SSC_MODE_3 = 3;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/.hash b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/.hash
new file mode 100644
index 0000000..c57de33
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/.hash
@@ -0,0 +1 @@
+af4dcb2aeff14e1352901a2a240c03d0a5377da9
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/AmrMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/AmrMode.aidl
new file mode 100644
index 0000000..37e3b25
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/AmrMode.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum AmrMode {
+  AMR_MODE_0 = (1 << 0) /* 1 */,
+  AMR_MODE_1 = (1 << 1) /* 2 */,
+  AMR_MODE_2 = (1 << 2) /* 4 */,
+  AMR_MODE_3 = (1 << 3) /* 8 */,
+  AMR_MODE_4 = (1 << 4) /* 16 */,
+  AMR_MODE_5 = (1 << 5) /* 32 */,
+  AMR_MODE_6 = (1 << 6) /* 64 */,
+  AMR_MODE_7 = (1 << 7) /* 128 */,
+  AMR_MODE_8 = (1 << 8) /* 256 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/AmrParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/AmrParams.aidl
new file mode 100644
index 0000000..36edb7f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/AmrParams.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable AmrParams {
+  android.hardware.radio.ims.media.AmrMode amrMode;
+  boolean octetAligned;
+  int maxRedundancyMillis;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/AnbrMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/AnbrMode.aidl
new file mode 100644
index 0000000..c108c07
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/AnbrMode.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims.media;
+@JavaDerive(toString=true) @VintfStability
+parcelable AnbrMode {
+  android.hardware.radio.ims.media.CodecMode anbrUplinkMode;
+  android.hardware.radio.ims.media.CodecMode anbrDownlinkMode;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CallQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CallQuality.aidl
new file mode 100644
index 0000000..fff6e1c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CallQuality.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims.media;
+@VintfStability
+parcelable CallQuality {
+  int downlinkCallQualityLevel;
+  int uplinkCallQualityLevel;
+  int callDuration;
+  int numRtpPacketsTransmitted;
+  int numRtpPacketsReceived;
+  int numRtpPacketsTransmittedLost;
+  int numRtpPacketsNotReceived;
+  int averageRelativeJitter;
+  int maxRelativeJitter;
+  int averageRoundTripTime;
+  int codecType;
+  boolean rtpInactivityDetected;
+  boolean rxSilenceDetected;
+  boolean txSilenceDetected;
+  int numVoiceFrames;
+  int numNoDataFrames;
+  int numDroppedRtpPackets;
+  long minPlayoutDelayMillis;
+  long maxPlayoutDelayMillis;
+  int numRtpSidPacketsReceived;
+  int numRtpDuplicatePackets;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecMode.aidl
new file mode 100644
index 0000000..0e9140f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims.media;
+@JavaDerive(toString=true) @VintfStability
+union CodecMode {
+  boolean noinit;
+  android.hardware.radio.ims.media.AmrMode amr;
+  android.hardware.radio.ims.media.EvsMode evs;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecParams.aidl
new file mode 100644
index 0000000..3da2dbd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecParams.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable CodecParams {
+  android.hardware.radio.ims.media.CodecType codecType;
+  byte rxPayloadTypeNumber;
+  byte txPayloadTypeNumber;
+  byte samplingRateKHz;
+  boolean dtxEnabled;
+  android.hardware.radio.ims.media.CodecSpecificParams codecSpecificParams;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecSpecificParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecSpecificParams.aidl
new file mode 100644
index 0000000..08e3f0f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecSpecificParams.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.ims.media;
+@VintfStability
+union CodecSpecificParams {
+  android.hardware.radio.ims.media.AmrParams amr;
+  android.hardware.radio.ims.media.EvsParams evs;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecType.aidl
new file mode 100644
index 0000000..e4193cd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/CodecType.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum CodecType {
+  AMR = (1 << 0) /* 1 */,
+  AMR_WB = (1 << 1) /* 2 */,
+  EVS = (1 << 2) /* 4 */,
+  PCMA = (1 << 3) /* 8 */,
+  PCMU = (1 << 4) /* 16 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/DtmfParams.aidl
new file mode 100644
index 0000000..5523fd8
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/DtmfParams.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable DtmfParams {
+  byte rxPayloadTypeNumber;
+  byte txPayloadTypeNumber;
+  byte samplingRateKHz;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/EvsBandwidth.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/EvsBandwidth.aidl
new file mode 100644
index 0000000..db3eb29
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/EvsBandwidth.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum EvsBandwidth {
+  NONE = 0,
+  NARROW_BAND = (1 << 0) /* 1 */,
+  WIDE_BAND = (1 << 1) /* 2 */,
+  SUPER_WIDE_BAND = (1 << 2) /* 4 */,
+  FULL_BAND = (1 << 3) /* 8 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/EvsMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/EvsMode.aidl
new file mode 100644
index 0000000..fb1f14d
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/EvsMode.aidl
@@ -0,0 +1,58 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum EvsMode {
+  EVS_MODE_0 = (1 << 0) /* 1 */,
+  EVS_MODE_1 = (1 << 1) /* 2 */,
+  EVS_MODE_2 = (1 << 2) /* 4 */,
+  EVS_MODE_3 = (1 << 3) /* 8 */,
+  EVS_MODE_4 = (1 << 4) /* 16 */,
+  EVS_MODE_5 = (1 << 5) /* 32 */,
+  EVS_MODE_6 = (1 << 6) /* 64 */,
+  EVS_MODE_7 = (1 << 7) /* 128 */,
+  EVS_MODE_8 = (1 << 8) /* 256 */,
+  EVS_MODE_9 = (1 << 9) /* 512 */,
+  EVS_MODE_10 = (1 << 10) /* 1024 */,
+  EVS_MODE_11 = (1 << 11) /* 2048 */,
+  EVS_MODE_12 = (1 << 12) /* 4096 */,
+  EVS_MODE_13 = (1 << 13) /* 8192 */,
+  EVS_MODE_14 = (1 << 14) /* 16384 */,
+  EVS_MODE_15 = (1 << 15) /* 32768 */,
+  EVS_MODE_16 = (1 << 16) /* 65536 */,
+  EVS_MODE_17 = (1 << 17) /* 131072 */,
+  EVS_MODE_18 = (1 << 18) /* 262144 */,
+  EVS_MODE_19 = (1 << 19) /* 524288 */,
+  EVS_MODE_20 = (1 << 20) /* 1048576 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/EvsParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/EvsParams.aidl
new file mode 100644
index 0000000..735eb08
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/EvsParams.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable EvsParams {
+  android.hardware.radio.ims.media.EvsBandwidth bandwidth;
+  android.hardware.radio.ims.media.EvsMode evsMode;
+  byte channelAwareMode;
+  boolean useHeaderFullOnly;
+  boolean useEvsModeSwitch;
+  byte codecModeRequest;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMedia.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMedia.aidl
new file mode 100644
index 0000000..30793e5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMedia.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+interface IImsMedia {
+  oneway void setListener(in android.hardware.radio.ims.media.IImsMediaListener mediaListener);
+  oneway void openSession(int sessionId, in android.hardware.radio.ims.media.LocalEndPoint localEndPoint, in android.hardware.radio.ims.media.RtpConfig config);
+  oneway void closeSession(int sessionId);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMediaListener.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMediaListener.aidl
new file mode 100644
index 0000000..40f7107
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMediaListener.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+interface IImsMediaListener {
+  oneway void onOpenSessionSuccess(int sessionId, android.hardware.radio.ims.media.IImsMediaSession session);
+  oneway void onOpenSessionFailure(int sessionId, android.hardware.radio.ims.media.RtpError error);
+  oneway void onSessionClosed(int sessionId);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMediaSession.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMediaSession.aidl
new file mode 100644
index 0000000..ea9f3a4
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMediaSession.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.ims.media;
+@VintfStability
+interface IImsMediaSession {
+  oneway void setListener(in android.hardware.radio.ims.media.IImsMediaSessionListener sessionListener);
+  oneway void modifySession(in android.hardware.radio.ims.media.RtpConfig config);
+  oneway void sendDtmf(char dtmfDigit, int duration);
+  oneway void startDtmf(char dtmfDigit);
+  oneway void stopDtmf();
+  oneway void sendHeaderExtension(in List<android.hardware.radio.ims.media.RtpHeaderExtension> extensions);
+  oneway void setMediaQualityThreshold(in android.hardware.radio.ims.media.MediaQualityThreshold threshold);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl
new file mode 100644
index 0000000..cb221df
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.ims.media;
+@VintfStability
+interface IImsMediaSessionListener {
+  oneway void onModifySessionResponse(in android.hardware.radio.ims.media.RtpConfig config, android.hardware.radio.ims.media.RtpError error);
+  oneway void onFirstMediaPacketReceived(in android.hardware.radio.ims.media.RtpConfig config);
+  oneway void onHeaderExtensionReceived(in List<android.hardware.radio.ims.media.RtpHeaderExtension> extensions);
+  oneway void notifyMediaQualityStatus(in android.hardware.radio.ims.media.MediaQualityStatus quality);
+  oneway void triggerAnbrQuery(in android.hardware.radio.ims.media.RtpConfig config);
+  oneway void onDtmfReceived(char dtmfDigit, int durationMs);
+  oneway void onCallQualityChanged(in android.hardware.radio.ims.media.CallQuality callQuality);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/LocalEndPoint.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/LocalEndPoint.aidl
new file mode 100644
index 0000000..6ec5156
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/LocalEndPoint.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable LocalEndPoint {
+  ParcelFileDescriptor rtpFd;
+  ParcelFileDescriptor rtcpFd;
+  int modemId;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/MediaDirection.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/MediaDirection.aidl
new file mode 100644
index 0000000..0e9eaee
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/MediaDirection.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum MediaDirection {
+  NO_FLOW = 0,
+  RTP_TX = (1 << 0) /* 1 */,
+  RTP_RX = (1 << 1) /* 2 */,
+  RTCP_TX = (1 << 2) /* 4 */,
+  RTCP_RX = (1 << 3) /* 8 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/MediaQualityStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/MediaQualityStatus.aidl
new file mode 100644
index 0000000..4accf53
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/MediaQualityStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.ims.media;
+@VintfStability
+parcelable MediaQualityStatus {
+  int rtpInactivityTimeMillis;
+  int rtcpInactivityTimeMillis;
+  int rtpPacketLossRate;
+  int rtpJitterMillis;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/MediaQualityThreshold.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
new file mode 100644
index 0000000..31cf373
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable MediaQualityThreshold {
+  int[] rtpInactivityTimerMillis;
+  int rtcpInactivityTimerMillis;
+  int rtpPacketLossDurationMillis;
+  int rtpHysteresisTimeInMillis;
+  int[] rtpPacketLossRate;
+  int[] rtpJitterMillis;
+  boolean notifyCurrentStatus;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtcpConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtcpConfig.aidl
new file mode 100644
index 0000000..6a76d85
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtcpConfig.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.ims.media;
+@VintfStability
+parcelable RtcpConfig {
+  String canonicalName;
+  int transmitPort;
+  int transmitIntervalSec;
+  int rtcpXrBlocks;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl
new file mode 100644
index 0000000..289c810
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum RtcpXrReportBlockType {
+  RTCPXR_NONE = 0,
+  RTCPXR_LOSS_RLE_REPORT_BLOCK = (1 << 0) /* 1 */,
+  RTCPXR_DUPLICATE_RLE_REPORT_BLOCK = (1 << 1) /* 2 */,
+  RTCPXR_PACKET_RECEIPT_TIMES_REPORT_BLOCK = (1 << 2) /* 4 */,
+  RTCPXR_RECEIVER_REFERENCE_TIME_REPORT_BLOCK = (1 << 3) /* 8 */,
+  RTCPXR_DLRR_REPORT_BLOCK = (1 << 4) /* 16 */,
+  RTCPXR_STATISTICS_SUMMARY_REPORT_BLOCK = (1 << 5) /* 32 */,
+  RTCPXR_VOIP_METRICS_REPORT_BLOCK = (1 << 6) /* 64 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpAddress.aidl
new file mode 100644
index 0000000..35357d1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpAddress.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable RtpAddress {
+  String ipAddress;
+  int portNumber;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpConfig.aidl
new file mode 100644
index 0000000..8a826f6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable RtpConfig {
+  int direction;
+  android.hardware.radio.AccessNetwork accessNetwork;
+  android.hardware.radio.ims.media.RtpAddress remoteAddress;
+  android.hardware.radio.ims.media.RtpSessionParams sessionParams;
+  android.hardware.radio.ims.media.RtcpConfig rtcpConfig;
+  android.hardware.radio.ims.media.AnbrMode anbrModeParams;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpError.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpError.aidl
new file mode 100644
index 0000000..41b0aeb
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpError.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum RtpError {
+  NONE = 0,
+  INVALID_PARAM = 1,
+  NOT_READY = 2,
+  NO_MEMORY = 3,
+  NO_RESOURCES = 4,
+  PORT_UNAVAILABLE = 5,
+  NOT_SUPPORTED = 6,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpHeaderExtension.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
new file mode 100644
index 0000000..83b8a31
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable RtpHeaderExtension {
+  int localId;
+  byte[] data;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpSessionParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpSessionParams.aidl
new file mode 100644
index 0000000..13a7487
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/1/android/hardware/radio/ims/media/RtpSessionParams.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable RtpSessionParams {
+  byte pTimeMillis;
+  int maxPtimeMillis;
+  byte dscp;
+  android.hardware.radio.ims.media.DtmfParams dtmfParams;
+  android.hardware.radio.ims.media.CodecParams codecParams;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrMode.aidl
new file mode 100644
index 0000000..37e3b25
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrMode.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum AmrMode {
+  AMR_MODE_0 = (1 << 0) /* 1 */,
+  AMR_MODE_1 = (1 << 1) /* 2 */,
+  AMR_MODE_2 = (1 << 2) /* 4 */,
+  AMR_MODE_3 = (1 << 3) /* 8 */,
+  AMR_MODE_4 = (1 << 4) /* 16 */,
+  AMR_MODE_5 = (1 << 5) /* 32 */,
+  AMR_MODE_6 = (1 << 6) /* 64 */,
+  AMR_MODE_7 = (1 << 7) /* 128 */,
+  AMR_MODE_8 = (1 << 8) /* 256 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.aidl
new file mode 100644
index 0000000..36edb7f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable AmrParams {
+  android.hardware.radio.ims.media.AmrMode amrMode;
+  boolean octetAligned;
+  int maxRedundancyMillis;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl
new file mode 100644
index 0000000..c108c07
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims.media;
+@JavaDerive(toString=true) @VintfStability
+parcelable AnbrMode {
+  android.hardware.radio.ims.media.CodecMode anbrUplinkMode;
+  android.hardware.radio.ims.media.CodecMode anbrDownlinkMode;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl
new file mode 100644
index 0000000..fff6e1c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims.media;
+@VintfStability
+parcelable CallQuality {
+  int downlinkCallQualityLevel;
+  int uplinkCallQualityLevel;
+  int callDuration;
+  int numRtpPacketsTransmitted;
+  int numRtpPacketsReceived;
+  int numRtpPacketsTransmittedLost;
+  int numRtpPacketsNotReceived;
+  int averageRelativeJitter;
+  int maxRelativeJitter;
+  int averageRoundTripTime;
+  int codecType;
+  boolean rtpInactivityDetected;
+  boolean rxSilenceDetected;
+  boolean txSilenceDetected;
+  int numVoiceFrames;
+  int numNoDataFrames;
+  int numDroppedRtpPackets;
+  long minPlayoutDelayMillis;
+  long maxPlayoutDelayMillis;
+  int numRtpSidPacketsReceived;
+  int numRtpDuplicatePackets;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl
new file mode 100644
index 0000000..0e9140f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims.media;
+@JavaDerive(toString=true) @VintfStability
+union CodecMode {
+  boolean noinit;
+  android.hardware.radio.ims.media.AmrMode amr;
+  android.hardware.radio.ims.media.EvsMode evs;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl
new file mode 100644
index 0000000..3da2dbd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable CodecParams {
+  android.hardware.radio.ims.media.CodecType codecType;
+  byte rxPayloadTypeNumber;
+  byte txPayloadTypeNumber;
+  byte samplingRateKHz;
+  boolean dtxEnabled;
+  android.hardware.radio.ims.media.CodecSpecificParams codecSpecificParams;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.aidl
new file mode 100644
index 0000000..08e3f0f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.ims.media;
+@VintfStability
+union CodecSpecificParams {
+  android.hardware.radio.ims.media.AmrParams amr;
+  android.hardware.radio.ims.media.EvsParams evs;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecType.aidl
new file mode 100644
index 0000000..e4193cd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecType.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum CodecType {
+  AMR = (1 << 0) /* 1 */,
+  AMR_WB = (1 << 1) /* 2 */,
+  EVS = (1 << 2) /* 4 */,
+  PCMA = (1 << 3) /* 8 */,
+  PCMU = (1 << 4) /* 16 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
new file mode 100644
index 0000000..5523fd8
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable DtmfParams {
+  byte rxPayloadTypeNumber;
+  byte txPayloadTypeNumber;
+  byte samplingRateKHz;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsBandwidth.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsBandwidth.aidl
new file mode 100644
index 0000000..db3eb29
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsBandwidth.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum EvsBandwidth {
+  NONE = 0,
+  NARROW_BAND = (1 << 0) /* 1 */,
+  WIDE_BAND = (1 << 1) /* 2 */,
+  SUPER_WIDE_BAND = (1 << 2) /* 4 */,
+  FULL_BAND = (1 << 3) /* 8 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsMode.aidl
new file mode 100644
index 0000000..fb1f14d
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsMode.aidl
@@ -0,0 +1,58 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum EvsMode {
+  EVS_MODE_0 = (1 << 0) /* 1 */,
+  EVS_MODE_1 = (1 << 1) /* 2 */,
+  EVS_MODE_2 = (1 << 2) /* 4 */,
+  EVS_MODE_3 = (1 << 3) /* 8 */,
+  EVS_MODE_4 = (1 << 4) /* 16 */,
+  EVS_MODE_5 = (1 << 5) /* 32 */,
+  EVS_MODE_6 = (1 << 6) /* 64 */,
+  EVS_MODE_7 = (1 << 7) /* 128 */,
+  EVS_MODE_8 = (1 << 8) /* 256 */,
+  EVS_MODE_9 = (1 << 9) /* 512 */,
+  EVS_MODE_10 = (1 << 10) /* 1024 */,
+  EVS_MODE_11 = (1 << 11) /* 2048 */,
+  EVS_MODE_12 = (1 << 12) /* 4096 */,
+  EVS_MODE_13 = (1 << 13) /* 8192 */,
+  EVS_MODE_14 = (1 << 14) /* 16384 */,
+  EVS_MODE_15 = (1 << 15) /* 32768 */,
+  EVS_MODE_16 = (1 << 16) /* 65536 */,
+  EVS_MODE_17 = (1 << 17) /* 131072 */,
+  EVS_MODE_18 = (1 << 18) /* 262144 */,
+  EVS_MODE_19 = (1 << 19) /* 524288 */,
+  EVS_MODE_20 = (1 << 20) /* 1048576 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl
new file mode 100644
index 0000000..735eb08
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable EvsParams {
+  android.hardware.radio.ims.media.EvsBandwidth bandwidth;
+  android.hardware.radio.ims.media.EvsMode evsMode;
+  byte channelAwareMode;
+  boolean useHeaderFullOnly;
+  boolean useEvsModeSwitch;
+  byte codecModeRequest;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMedia.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMedia.aidl
new file mode 100644
index 0000000..30793e5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMedia.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+interface IImsMedia {
+  oneway void setListener(in android.hardware.radio.ims.media.IImsMediaListener mediaListener);
+  oneway void openSession(int sessionId, in android.hardware.radio.ims.media.LocalEndPoint localEndPoint, in android.hardware.radio.ims.media.RtpConfig config);
+  oneway void closeSession(int sessionId);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaListener.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaListener.aidl
new file mode 100644
index 0000000..40f7107
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaListener.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+interface IImsMediaListener {
+  oneway void onOpenSessionSuccess(int sessionId, android.hardware.radio.ims.media.IImsMediaSession session);
+  oneway void onOpenSessionFailure(int sessionId, android.hardware.radio.ims.media.RtpError error);
+  oneway void onSessionClosed(int sessionId);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSession.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSession.aidl
new file mode 100644
index 0000000..ea9f3a4
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSession.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.ims.media;
+@VintfStability
+interface IImsMediaSession {
+  oneway void setListener(in android.hardware.radio.ims.media.IImsMediaSessionListener sessionListener);
+  oneway void modifySession(in android.hardware.radio.ims.media.RtpConfig config);
+  oneway void sendDtmf(char dtmfDigit, int duration);
+  oneway void startDtmf(char dtmfDigit);
+  oneway void stopDtmf();
+  oneway void sendHeaderExtension(in List<android.hardware.radio.ims.media.RtpHeaderExtension> extensions);
+  oneway void setMediaQualityThreshold(in android.hardware.radio.ims.media.MediaQualityThreshold threshold);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl
new file mode 100644
index 0000000..cb221df
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.ims.media;
+@VintfStability
+interface IImsMediaSessionListener {
+  oneway void onModifySessionResponse(in android.hardware.radio.ims.media.RtpConfig config, android.hardware.radio.ims.media.RtpError error);
+  oneway void onFirstMediaPacketReceived(in android.hardware.radio.ims.media.RtpConfig config);
+  oneway void onHeaderExtensionReceived(in List<android.hardware.radio.ims.media.RtpHeaderExtension> extensions);
+  oneway void notifyMediaQualityStatus(in android.hardware.radio.ims.media.MediaQualityStatus quality);
+  oneway void triggerAnbrQuery(in android.hardware.radio.ims.media.RtpConfig config);
+  oneway void onDtmfReceived(char dtmfDigit, int durationMs);
+  oneway void onCallQualityChanged(in android.hardware.radio.ims.media.CallQuality callQuality);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/LocalEndPoint.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/LocalEndPoint.aidl
new file mode 100644
index 0000000..6ec5156
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/LocalEndPoint.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable LocalEndPoint {
+  ParcelFileDescriptor rtpFd;
+  ParcelFileDescriptor rtcpFd;
+  int modemId;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaDirection.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaDirection.aidl
new file mode 100644
index 0000000..0e9eaee
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaDirection.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum MediaDirection {
+  NO_FLOW = 0,
+  RTP_TX = (1 << 0) /* 1 */,
+  RTP_RX = (1 << 1) /* 2 */,
+  RTCP_TX = (1 << 2) /* 4 */,
+  RTCP_RX = (1 << 3) /* 8 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.aidl
new file mode 100644
index 0000000..4accf53
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.ims.media;
+@VintfStability
+parcelable MediaQualityStatus {
+  int rtpInactivityTimeMillis;
+  int rtcpInactivityTimeMillis;
+  int rtpPacketLossRate;
+  int rtpJitterMillis;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
new file mode 100644
index 0000000..31cf373
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable MediaQualityThreshold {
+  int[] rtpInactivityTimerMillis;
+  int rtcpInactivityTimerMillis;
+  int rtpPacketLossDurationMillis;
+  int rtpHysteresisTimeInMillis;
+  int[] rtpPacketLossRate;
+  int[] rtpJitterMillis;
+  boolean notifyCurrentStatus;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.aidl
new file mode 100644
index 0000000..6a76d85
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.ims.media;
+@VintfStability
+parcelable RtcpConfig {
+  String canonicalName;
+  int transmitPort;
+  int transmitIntervalSec;
+  int rtcpXrBlocks;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl
new file mode 100644
index 0000000..289c810
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum RtcpXrReportBlockType {
+  RTCPXR_NONE = 0,
+  RTCPXR_LOSS_RLE_REPORT_BLOCK = (1 << 0) /* 1 */,
+  RTCPXR_DUPLICATE_RLE_REPORT_BLOCK = (1 << 1) /* 2 */,
+  RTCPXR_PACKET_RECEIPT_TIMES_REPORT_BLOCK = (1 << 2) /* 4 */,
+  RTCPXR_RECEIVER_REFERENCE_TIME_REPORT_BLOCK = (1 << 3) /* 8 */,
+  RTCPXR_DLRR_REPORT_BLOCK = (1 << 4) /* 16 */,
+  RTCPXR_STATISTICS_SUMMARY_REPORT_BLOCK = (1 << 5) /* 32 */,
+  RTCPXR_VOIP_METRICS_REPORT_BLOCK = (1 << 6) /* 64 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.aidl
new file mode 100644
index 0000000..35357d1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable RtpAddress {
+  String ipAddress;
+  int portNumber;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl
new file mode 100644
index 0000000..8a826f6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable RtpConfig {
+  int direction;
+  android.hardware.radio.AccessNetwork accessNetwork;
+  android.hardware.radio.ims.media.RtpAddress remoteAddress;
+  android.hardware.radio.ims.media.RtpSessionParams sessionParams;
+  android.hardware.radio.ims.media.RtcpConfig rtcpConfig;
+  android.hardware.radio.ims.media.AnbrMode anbrModeParams;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpError.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpError.aidl
new file mode 100644
index 0000000..41b0aeb
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpError.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.ims.media;
+@Backing(type="int") @VintfStability
+enum RtpError {
+  NONE = 0,
+  INVALID_PARAM = 1,
+  NOT_READY = 2,
+  NO_MEMORY = 3,
+  NO_RESOURCES = 4,
+  PORT_UNAVAILABLE = 5,
+  NOT_SUPPORTED = 6,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
new file mode 100644
index 0000000..83b8a31
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable RtpHeaderExtension {
+  int localId;
+  byte[] data;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl
new file mode 100644
index 0000000..13a7487
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.ims.media;
+@VintfStability
+parcelable RtpSessionParams {
+  byte pTimeMillis;
+  int maxPtimeMillis;
+  byte dscp;
+  android.hardware.radio.ims.media.DtmfParams dtmfParams;
+  android.hardware.radio.ims.media.CodecParams codecParams;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/.hash b/radio/aidl/aidl_api/android.hardware.radio.ims/1/.hash
new file mode 100644
index 0000000..9d5f5c1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/.hash
@@ -0,0 +1 @@
+b09f8d98a60fbe74cefaca7aea9903ab5450110a
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ConnectionFailureInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ConnectionFailureInfo.aidl
new file mode 100644
index 0000000..90e75f9
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ConnectionFailureInfo.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable ConnectionFailureInfo {
+  android.hardware.radio.ims.ConnectionFailureInfo.ConnectionFailureReason failureReason;
+  int causeCode;
+  int waitTimeMillis;
+  @Backing(type="int") @VintfStability
+  enum ConnectionFailureReason {
+    REASON_ACCESS_DENIED = 1,
+    REASON_NAS_FAILURE = 2,
+    REASON_RACH_FAILURE = 3,
+    REASON_RLC_FAILURE = 4,
+    REASON_RRC_REJECT = 5,
+    REASON_RRC_TIMEOUT = 6,
+    REASON_NO_SERVICE = 7,
+    REASON_PDN_NOT_AVAILABLE = 8,
+    REASON_RF_BUSY = 9,
+    REASON_UNSPECIFIED = 0xFFFF,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/EpsFallbackReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/EpsFallbackReason.aidl
new file mode 100644
index 0000000..ebea903
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/EpsFallbackReason.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EpsFallbackReason {
+  NO_NETWORK_TRIGGER = 1,
+  NO_NETWORK_RESPONSE = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/IRadioIms.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/IRadioIms.aidl
new file mode 100644
index 0000000..4df8709
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/IRadioIms.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@VintfStability
+interface IRadioIms {
+  oneway void setSrvccCallInfo(int serial, in android.hardware.radio.ims.SrvccCall[] srvccCalls);
+  oneway void updateImsRegistrationInfo(int serial, in android.hardware.radio.ims.ImsRegistration imsRegistration);
+  oneway void startImsTraffic(int serial, int token, android.hardware.radio.ims.ImsTrafficType imsTrafficType, android.hardware.radio.AccessNetwork accessNetworkType, android.hardware.radio.ims.ImsCall.Direction trafficDirection);
+  oneway void stopImsTraffic(int serial, int token);
+  oneway void triggerEpsFallback(int serial, in android.hardware.radio.ims.EpsFallbackReason reason);
+  oneway void setResponseFunctions(in android.hardware.radio.ims.IRadioImsResponse radioImsResponse, in android.hardware.radio.ims.IRadioImsIndication radioImsIndication);
+  oneway void sendAnbrQuery(int serial, android.hardware.radio.ims.ImsStreamType mediaType, android.hardware.radio.ims.ImsStreamDirection direction, int bitsPerSecond);
+  oneway void updateImsCallStatus(int serial, in android.hardware.radio.ims.ImsCall[] imsCalls);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/IRadioImsIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/IRadioImsIndication.aidl
new file mode 100644
index 0000000..ef6b4cc
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/IRadioImsIndication.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@VintfStability
+interface IRadioImsIndication {
+  oneway void onConnectionSetupFailure(in android.hardware.radio.RadioIndicationType type, int token, in android.hardware.radio.ims.ConnectionFailureInfo info);
+  oneway void notifyAnbr(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.ims.ImsStreamType mediaType, in android.hardware.radio.ims.ImsStreamDirection direction, int bitsPerSecond);
+  oneway void triggerImsDeregistration(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.ims.ImsDeregistrationReason reason);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/IRadioImsResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/IRadioImsResponse.aidl
new file mode 100644
index 0000000..053ba46
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/IRadioImsResponse.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@VintfStability
+interface IRadioImsResponse {
+  oneway void setSrvccCallInfoResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void updateImsRegistrationInfoResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void startImsTrafficResponse(in android.hardware.radio.RadioResponseInfo info, in @nullable android.hardware.radio.ims.ConnectionFailureInfo failureInfo);
+  oneway void stopImsTrafficResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void triggerEpsFallbackResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void sendAnbrQueryResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void updateImsCallStatusResponse(in android.hardware.radio.RadioResponseInfo info);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsCall.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsCall.aidl
new file mode 100644
index 0000000..6e14830
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsCall.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImsCall {
+  int index;
+  android.hardware.radio.ims.ImsCall.CallType callType;
+  android.hardware.radio.AccessNetwork accessNetwork;
+  android.hardware.radio.ims.ImsCall.CallState callState;
+  android.hardware.radio.ims.ImsCall.Direction direction;
+  boolean isHeldByRemote;
+  @Backing(type="int")
+  enum CallType {
+    NORMAL,
+    EMERGENCY,
+  }
+  @Backing(type="int")
+  enum CallState {
+    ACTIVE,
+    HOLDING,
+    DIALING,
+    ALERTING,
+    INCOMING,
+    WAITING,
+    DISCONNECTING,
+    DISCONNECTED,
+  }
+  @Backing(type="int")
+  enum Direction {
+    INCOMING,
+    OUTGOING,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsDeregistrationReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsDeregistrationReason.aidl
new file mode 100644
index 0000000..b04e559
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsDeregistrationReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsDeregistrationReason {
+  REASON_SIM_REMOVED = 1,
+  REASON_SIM_REFRESH = 2,
+  REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsRegistration.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsRegistration.aidl
new file mode 100644
index 0000000..7ed6baf
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsRegistration.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImsRegistration {
+  android.hardware.radio.ims.ImsRegistrationState regState;
+  android.hardware.radio.AccessNetwork accessNetworkType;
+  android.hardware.radio.ims.SuggestedAction suggestedAction;
+  int capabilities;
+  const int IMS_MMTEL_CAPABILITY_NONE = 0;
+  const int IMS_MMTEL_CAPABILITY_VOICE = (1 << 0) /* 1 */;
+  const int IMS_MMTEL_CAPABILITY_VIDEO = (1 << 1) /* 2 */;
+  const int IMS_MMTEL_CAPABILITY_SMS = (1 << 2) /* 4 */;
+  const int IMS_RCS_CAPABILITIES = (1 << 3) /* 8 */;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsRegistrationState.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsRegistrationState.aidl
new file mode 100644
index 0000000..6302b47
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsRegistrationState.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsRegistrationState {
+  NOT_REGISTERED,
+  REGISTERED,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsStreamDirection.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsStreamDirection.aidl
new file mode 100644
index 0000000..cf2e4f1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsStreamDirection.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsStreamDirection {
+  UPLINK = 1,
+  DOWNLINK = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsStreamType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsStreamType.aidl
new file mode 100644
index 0000000..10c477f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsStreamType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @VintfStability
+enum ImsStreamType {
+  AUDIO = 1,
+  VIDEO = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsTrafficType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsTrafficType.aidl
new file mode 100644
index 0000000..b1a0b77
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/ImsTrafficType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsTrafficType {
+  EMERGENCY,
+  EMERGENCY_SMS,
+  VOICE,
+  VIDEO,
+  SMS,
+  REGISTRATION,
+  UT_XCAP,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/SrvccCall.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/SrvccCall.aidl
new file mode 100644
index 0000000..5119b0f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/SrvccCall.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable SrvccCall {
+  int index;
+  android.hardware.radio.ims.SrvccCall.CallType callType;
+  int callState;
+  android.hardware.radio.ims.SrvccCall.CallSubState callSubstate;
+  android.hardware.radio.ims.SrvccCall.ToneType ringbackToneType;
+  boolean isMpty;
+  boolean isMT;
+  String number;
+  int numPresentation;
+  String name;
+  int namePresentation;
+  @Backing(type="int") @VintfStability
+  enum CallType {
+    NORMAL,
+    EMERGENCY,
+  }
+  @Backing(type="int") @VintfStability
+  enum CallSubState {
+    NONE,
+    PREALERTING,
+  }
+  @Backing(type="int") @VintfStability
+  enum ToneType {
+    NONE,
+    LOCAL,
+    NETWORK,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/SuggestedAction.aidl
new file mode 100644
index 0000000..bbe170e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/1/android/hardware/radio/ims/SuggestedAction.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum SuggestedAction {
+  NONE,
+  TRIGGER_PLMN_BLOCK,
+  TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl
new file mode 100644
index 0000000..90e75f9
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable ConnectionFailureInfo {
+  android.hardware.radio.ims.ConnectionFailureInfo.ConnectionFailureReason failureReason;
+  int causeCode;
+  int waitTimeMillis;
+  @Backing(type="int") @VintfStability
+  enum ConnectionFailureReason {
+    REASON_ACCESS_DENIED = 1,
+    REASON_NAS_FAILURE = 2,
+    REASON_RACH_FAILURE = 3,
+    REASON_RLC_FAILURE = 4,
+    REASON_RRC_REJECT = 5,
+    REASON_RRC_TIMEOUT = 6,
+    REASON_NO_SERVICE = 7,
+    REASON_PDN_NOT_AVAILABLE = 8,
+    REASON_RF_BUSY = 9,
+    REASON_UNSPECIFIED = 0xFFFF,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/EpsFallbackReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/EpsFallbackReason.aidl
new file mode 100644
index 0000000..ebea903
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/EpsFallbackReason.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EpsFallbackReason {
+  NO_NETWORK_TRIGGER = 1,
+  NO_NETWORK_RESPONSE = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioIms.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioIms.aidl
new file mode 100644
index 0000000..4df8709
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioIms.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@VintfStability
+interface IRadioIms {
+  oneway void setSrvccCallInfo(int serial, in android.hardware.radio.ims.SrvccCall[] srvccCalls);
+  oneway void updateImsRegistrationInfo(int serial, in android.hardware.radio.ims.ImsRegistration imsRegistration);
+  oneway void startImsTraffic(int serial, int token, android.hardware.radio.ims.ImsTrafficType imsTrafficType, android.hardware.radio.AccessNetwork accessNetworkType, android.hardware.radio.ims.ImsCall.Direction trafficDirection);
+  oneway void stopImsTraffic(int serial, int token);
+  oneway void triggerEpsFallback(int serial, in android.hardware.radio.ims.EpsFallbackReason reason);
+  oneway void setResponseFunctions(in android.hardware.radio.ims.IRadioImsResponse radioImsResponse, in android.hardware.radio.ims.IRadioImsIndication radioImsIndication);
+  oneway void sendAnbrQuery(int serial, android.hardware.radio.ims.ImsStreamType mediaType, android.hardware.radio.ims.ImsStreamDirection direction, int bitsPerSecond);
+  oneway void updateImsCallStatus(int serial, in android.hardware.radio.ims.ImsCall[] imsCalls);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsIndication.aidl
new file mode 100644
index 0000000..ef6b4cc
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsIndication.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@VintfStability
+interface IRadioImsIndication {
+  oneway void onConnectionSetupFailure(in android.hardware.radio.RadioIndicationType type, int token, in android.hardware.radio.ims.ConnectionFailureInfo info);
+  oneway void notifyAnbr(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.ims.ImsStreamType mediaType, in android.hardware.radio.ims.ImsStreamDirection direction, int bitsPerSecond);
+  oneway void triggerImsDeregistration(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.ims.ImsDeregistrationReason reason);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsResponse.aidl
new file mode 100644
index 0000000..053ba46
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsResponse.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@VintfStability
+interface IRadioImsResponse {
+  oneway void setSrvccCallInfoResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void updateImsRegistrationInfoResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void startImsTrafficResponse(in android.hardware.radio.RadioResponseInfo info, in @nullable android.hardware.radio.ims.ConnectionFailureInfo failureInfo);
+  oneway void stopImsTrafficResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void triggerEpsFallbackResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void sendAnbrQueryResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void updateImsCallStatusResponse(in android.hardware.radio.RadioResponseInfo info);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl
new file mode 100644
index 0000000..6e14830
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImsCall {
+  int index;
+  android.hardware.radio.ims.ImsCall.CallType callType;
+  android.hardware.radio.AccessNetwork accessNetwork;
+  android.hardware.radio.ims.ImsCall.CallState callState;
+  android.hardware.radio.ims.ImsCall.Direction direction;
+  boolean isHeldByRemote;
+  @Backing(type="int")
+  enum CallType {
+    NORMAL,
+    EMERGENCY,
+  }
+  @Backing(type="int")
+  enum CallState {
+    ACTIVE,
+    HOLDING,
+    DIALING,
+    ALERTING,
+    INCOMING,
+    WAITING,
+    DISCONNECTING,
+    DISCONNECTED,
+  }
+  @Backing(type="int")
+  enum Direction {
+    INCOMING,
+    OUTGOING,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
new file mode 100644
index 0000000..b04e559
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsDeregistrationReason {
+  REASON_SIM_REMOVED = 1,
+  REASON_SIM_REFRESH = 2,
+  REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl
new file mode 100644
index 0000000..be5e004
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImsRegistration {
+  android.hardware.radio.ims.ImsRegistrationState regState;
+  android.hardware.radio.AccessNetwork accessNetworkType;
+  android.hardware.radio.ims.SuggestedAction suggestedAction;
+  int capabilities;
+  const int IMS_MMTEL_CAPABILITY_NONE = 0;
+  const int IMS_MMTEL_CAPABILITY_VOICE = (1 << 0);
+  const int IMS_MMTEL_CAPABILITY_VIDEO = (1 << 1);
+  const int IMS_MMTEL_CAPABILITY_SMS = (1 << 2);
+  const int IMS_RCS_CAPABILITIES = (1 << 3);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistrationState.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistrationState.aidl
new file mode 100644
index 0000000..6302b47
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistrationState.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsRegistrationState {
+  NOT_REGISTERED,
+  REGISTERED,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamDirection.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamDirection.aidl
new file mode 100644
index 0000000..cf2e4f1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamDirection.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsStreamDirection {
+  UPLINK = 1,
+  DOWNLINK = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamType.aidl
new file mode 100644
index 0000000..10c477f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @VintfStability
+enum ImsStreamType {
+  AUDIO = 1,
+  VIDEO = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsTrafficType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsTrafficType.aidl
new file mode 100644
index 0000000..b1a0b77
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsTrafficType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsTrafficType {
+  EMERGENCY,
+  EMERGENCY_SMS,
+  VOICE,
+  VIDEO,
+  SMS,
+  REGISTRATION,
+  UT_XCAP,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl
new file mode 100644
index 0000000..5119b0f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable SrvccCall {
+  int index;
+  android.hardware.radio.ims.SrvccCall.CallType callType;
+  int callState;
+  android.hardware.radio.ims.SrvccCall.CallSubState callSubstate;
+  android.hardware.radio.ims.SrvccCall.ToneType ringbackToneType;
+  boolean isMpty;
+  boolean isMT;
+  String number;
+  int numPresentation;
+  String name;
+  int namePresentation;
+  @Backing(type="int") @VintfStability
+  enum CallType {
+    NORMAL,
+    EMERGENCY,
+  }
+  @Backing(type="int") @VintfStability
+  enum CallSubState {
+    NONE,
+    PREALERTING,
+  }
+  @Backing(type="int") @VintfStability
+  enum ToneType {
+    NONE,
+    LOCAL,
+    NETWORK,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
new file mode 100644
index 0000000..bbe170e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum SuggestedAction {
+  NONE,
+  TRIGGER_PLMN_BLOCK,
+  TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/.hash b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/.hash
new file mode 100644
index 0000000..280bdb1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/.hash
@@ -0,0 +1 @@
+50aefda34c9dd40090c8d5925e71d5b84530c3d0
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
new file mode 100644
index 0000000..39e2be2
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaBroadcastSmsConfigInfo {
+  int serviceCategory;
+  int language;
+  boolean selected;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsAck.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsAck.aidl
new file mode 100644
index 0000000..befdbde
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsAck.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaSmsAck {
+  boolean errorClass;
+  int smsCauseCode;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsAddress.aidl
new file mode 100644
index 0000000..ab29c77
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsAddress.aidl
@@ -0,0 +1,68 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaSmsAddress {
+  int digitMode;
+  boolean isNumberModeDataNetwork;
+  int numberType;
+  int numberPlan;
+  byte[] digits;
+  const int DIGIT_MODE_FOUR_BIT = 0;
+  const int DIGIT_MODE_EIGHT_BIT = 1;
+  const int NUMBER_PLAN_UNKNOWN = 0;
+  const int NUMBER_PLAN_TELEPHONY = 1;
+  const int NUMBER_PLAN_RESERVED_2 = 2;
+  const int NUMBER_PLAN_DATA = 3;
+  const int NUMBER_PLAN_TELEX = 4;
+  const int NUMBER_PLAN_RESERVED_5 = 5;
+  const int NUMBER_PLAN_RESERVED_6 = 6;
+  const int NUMBER_PLAN_RESERVED_7 = 7;
+  const int NUMBER_PLAN_RESERVED_8 = 8;
+  const int NUMBER_PLAN_PRIVATE = 9;
+  const int NUMBER_PLAN_RESERVED_10 = 10;
+  const int NUMBER_PLAN_RESERVED_11 = 11;
+  const int NUMBER_PLAN_RESERVED_12 = 12;
+  const int NUMBER_PLAN_RESERVED_13 = 13;
+  const int NUMBER_PLAN_RESERVED_14 = 14;
+  const int NUMBER_PLAN_RESERVED_15 = 15;
+  const int NUMBER_TYPE_UNKNOWN = 0;
+  const int NUMBER_TYPE_INTERNATIONAL_OR_DATA_IP = 1;
+  const int NUMBER_TYPE_NATIONAL_OR_INTERNET_MAIL = 2;
+  const int NUMBER_TYPE_NETWORK = 3;
+  const int NUMBER_TYPE_SUBSCRIBER = 4;
+  const int NUMBER_TYPE_ALPHANUMERIC = 5;
+  const int NUMBER_TYPE_ABBREVIATED = 6;
+  const int NUMBER_TYPE_RESERVED_7 = 7;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsMessage.aidl
new file mode 100644
index 0000000..867596c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsMessage.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaSmsMessage {
+  int teleserviceId;
+  boolean isServicePresent;
+  int serviceCategory;
+  android.hardware.radio.messaging.CdmaSmsAddress address;
+  android.hardware.radio.messaging.CdmaSmsSubaddress subAddress;
+  byte[] bearerData;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
new file mode 100644
index 0000000..d67fe8c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaSmsSubaddress {
+  int subaddressType;
+  boolean odd;
+  byte[] digits;
+  const int SUBADDRESS_TYPE_NSAP = 0;
+  const int SUBADDRESS_TYPE_USER_SPECIFIED = 1;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
new file mode 100644
index 0000000..b0a7f98
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaSmsWriteArgs {
+  int status;
+  android.hardware.radio.messaging.CdmaSmsMessage message;
+  const int STATUS_REC_UNREAD = 0;
+  const int STATUS_REC_READ = 1;
+  const int STATUS_STO_UNSENT = 2;
+  const int STATUS_STO_SENT = 3;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
new file mode 100644
index 0000000..46604ca
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable GsmBroadcastSmsConfigInfo {
+  int fromServiceId;
+  int toServiceId;
+  int fromCodeScheme;
+  int toCodeScheme;
+  boolean selected;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/GsmSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/GsmSmsMessage.aidl
new file mode 100644
index 0000000..4df7fd2
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/GsmSmsMessage.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable GsmSmsMessage {
+  String smscPdu;
+  String pdu;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/IRadioMessaging.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/IRadioMessaging.aidl
new file mode 100644
index 0000000..dfec59a
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/IRadioMessaging.aidl
@@ -0,0 +1,60 @@
+/*
+ * 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.messaging;
+@VintfStability
+interface IRadioMessaging {
+  oneway void acknowledgeIncomingGsmSmsWithPdu(in int serial, in boolean success, in String ackPdu);
+  oneway void acknowledgeLastIncomingCdmaSms(in int serial, in android.hardware.radio.messaging.CdmaSmsAck smsAck);
+  oneway void acknowledgeLastIncomingGsmSms(in int serial, in boolean success, in android.hardware.radio.messaging.SmsAcknowledgeFailCause cause);
+  oneway void deleteSmsOnRuim(in int serial, in int index);
+  oneway void deleteSmsOnSim(in int serial, in int index);
+  oneway void getCdmaBroadcastConfig(in int serial);
+  oneway void getGsmBroadcastConfig(in int serial);
+  oneway void getSmscAddress(in int serial);
+  oneway void reportSmsMemoryStatus(in int serial, in boolean available);
+  oneway void responseAcknowledgement();
+  oneway void sendCdmaSms(in int serial, in android.hardware.radio.messaging.CdmaSmsMessage sms);
+  oneway void sendCdmaSmsExpectMore(in int serial, in android.hardware.radio.messaging.CdmaSmsMessage sms);
+  oneway void sendImsSms(in int serial, in android.hardware.radio.messaging.ImsSmsMessage message);
+  oneway void sendSms(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message);
+  oneway void sendSmsExpectMore(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message);
+  oneway void setCdmaBroadcastActivation(in int serial, in boolean activate);
+  oneway void setCdmaBroadcastConfig(in int serial, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configInfo);
+  oneway void setGsmBroadcastActivation(in int serial, in boolean activate);
+  oneway void setGsmBroadcastConfig(in int serial, in android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configInfo);
+  oneway void setResponseFunctions(in android.hardware.radio.messaging.IRadioMessagingResponse radioMessagingResponse, in android.hardware.radio.messaging.IRadioMessagingIndication radioMessagingIndication);
+  oneway void setSmscAddress(in int serial, in String smsc);
+  oneway void writeSmsToRuim(in int serial, in android.hardware.radio.messaging.CdmaSmsWriteArgs cdmaSms);
+  oneway void writeSmsToSim(in int serial, in android.hardware.radio.messaging.SmsWriteArgs smsWriteArgs);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/IRadioMessagingIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
new file mode 100644
index 0000000..8f7824f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.messaging;
+@VintfStability
+interface IRadioMessagingIndication {
+  oneway void cdmaNewSms(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.messaging.CdmaSmsMessage msg);
+  oneway void cdmaRuimSmsStorageFull(in android.hardware.radio.RadioIndicationType type);
+  oneway void newBroadcastSms(in android.hardware.radio.RadioIndicationType type, in byte[] data);
+  oneway void newSms(in android.hardware.radio.RadioIndicationType type, in byte[] pdu);
+  oneway void newSmsOnSim(in android.hardware.radio.RadioIndicationType type, in int recordNumber);
+  oneway void newSmsStatusReport(in android.hardware.radio.RadioIndicationType type, in byte[] pdu);
+  oneway void simSmsStorageFull(in android.hardware.radio.RadioIndicationType type);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
new file mode 100644
index 0000000..c3af7a6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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.messaging;
+@VintfStability
+interface IRadioMessagingResponse {
+  oneway void acknowledgeIncomingGsmSmsWithPduResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void acknowledgeLastIncomingCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void acknowledgeLastIncomingGsmSmsResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void acknowledgeRequest(in int serial);
+  oneway void deleteSmsOnRuimResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void deleteSmsOnSimResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configs);
+  oneway void getGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configs);
+  oneway void getSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info, in String smsc);
+  oneway void reportSmsMemoryStatusResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void sendCdmaSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
+  oneway void sendCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
+  oneway void sendImsSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
+  oneway void sendSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
+  oneway void sendSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
+  oneway void setCdmaBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setGsmBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void writeSmsToRuimResponse(in android.hardware.radio.RadioResponseInfo info, in int index);
+  oneway void writeSmsToSimResponse(in android.hardware.radio.RadioResponseInfo info, in int index);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/ImsSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/ImsSmsMessage.aidl
new file mode 100644
index 0000000..85f62b7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/ImsSmsMessage.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImsSmsMessage {
+  android.hardware.radio.RadioTechnologyFamily tech;
+  boolean retry;
+  int messageRef;
+  android.hardware.radio.messaging.CdmaSmsMessage[] cdmaMessage;
+  android.hardware.radio.messaging.GsmSmsMessage[] gsmMessage;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/SendSmsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/SendSmsResult.aidl
new file mode 100644
index 0000000..32f7a5c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/SendSmsResult.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable SendSmsResult {
+  int messageRef;
+  String ackPDU;
+  int errorCode;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
new file mode 100644
index 0000000..d061c9e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.messaging;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum SmsAcknowledgeFailCause {
+  MEMORY_CAPACITY_EXCEEDED = 0xD3,
+  UNSPECIFIED_ERROR = 0XFF,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/SmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/SmsWriteArgs.aidl
new file mode 100644
index 0000000..489cc07
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/2/android/hardware/radio/messaging/SmsWriteArgs.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.messaging;
+@JavaDerive(toString=true) @VintfStability
+parcelable SmsWriteArgs {
+  int status;
+  String pdu;
+  String smsc;
+  const int STATUS_REC_UNREAD = 0;
+  const int STATUS_REC_READ = 1;
+  const int STATUS_STO_UNSENT = 2;
+  const int STATUS_STO_SENT = 3;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
index 019b185..d061c9e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
@@ -34,6 +34,6 @@
 package android.hardware.radio.messaging;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum SmsAcknowledgeFailCause {
-  MEMORY_CAPACITY_EXCEEDED = 211,
-  UNSPECIFIED_ERROR = 255,
+  MEMORY_CAPACITY_EXCEEDED = 0xD3,
+  UNSPECIFIED_ERROR = 0XFF,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/.hash b/radio/aidl/aidl_api/android.hardware.radio.modem/2/.hash
new file mode 100644
index 0000000..4618320
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/.hash
@@ -0,0 +1 @@
+09927560afccc75a063944fbbab3af48099261ca
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ActivityStatsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ActivityStatsInfo.aidl
new file mode 100644
index 0000000..7e22ee0
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ActivityStatsInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.modem;
+@JavaDerive(toString=true) @VintfStability
+parcelable ActivityStatsInfo {
+  int sleepModeTimeMs;
+  int idleModeTimeMs;
+  android.hardware.radio.modem.ActivityStatsTechSpecificInfo[] techSpecificInfo;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
new file mode 100644
index 0000000..08ed9a5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.modem;
+@JavaDerive(toString=true) @VintfStability
+parcelable ActivityStatsTechSpecificInfo {
+  android.hardware.radio.AccessNetwork rat;
+  int frequencyRange;
+  int[] txmModetimeMs;
+  int rxModeTimeMs;
+  const int FREQUENCY_RANGE_UNKNOWN = 0;
+  const int FREQUENCY_RANGE_LOW = 1;
+  const int FREQUENCY_RANGE_MID = 2;
+  const int FREQUENCY_RANGE_HIGH = 3;
+  const int FREQUENCY_RANGE_MMWAVE = 4;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/DeviceStateType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/DeviceStateType.aidl
new file mode 100644
index 0000000..acc0b22
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/DeviceStateType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.modem;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum DeviceStateType {
+  POWER_SAVE_MODE,
+  CHARGING_STATE,
+  LOW_DATA_EXPECTED,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/HardwareConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/HardwareConfig.aidl
new file mode 100644
index 0000000..3a0ec25
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/HardwareConfig.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.modem;
+@JavaDerive(toString=true) @VintfStability
+parcelable HardwareConfig {
+  int type;
+  String uuid;
+  int state;
+  android.hardware.radio.modem.HardwareConfigModem[] modem;
+  android.hardware.radio.modem.HardwareConfigSim[] sim;
+  const int STATE_ENABLED = 0;
+  const int STATE_STANDBY = 1;
+  const int STATE_DISABLED = 2;
+  const int TYPE_MODEM = 0;
+  const int TYPE_SIM = 1;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/HardwareConfigModem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/HardwareConfigModem.aidl
new file mode 100644
index 0000000..62bb160
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/HardwareConfigModem.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.modem;
+@JavaDerive(toString=true) @VintfStability
+parcelable HardwareConfigModem {
+  int rilModel;
+  android.hardware.radio.RadioTechnology rat;
+  int maxVoiceCalls;
+  int maxDataCalls;
+  int maxStandby;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/HardwareConfigSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/HardwareConfigSim.aidl
new file mode 100644
index 0000000..5810982
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/HardwareConfigSim.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.modem;
+@JavaDerive(toString=true) @VintfStability
+parcelable HardwareConfigSim {
+  String modemUuid;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/IRadioModem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/IRadioModem.aidl
new file mode 100644
index 0000000..8546be7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/IRadioModem.aidl
@@ -0,0 +1,67 @@
+/*
+ * 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.modem;
+@VintfStability
+interface IRadioModem {
+  oneway void enableModem(in int serial, in boolean on);
+  oneway void getBasebandVersion(in int serial);
+  /**
+   * @deprecated use getImei(int serial)
+   */
+  oneway void getDeviceIdentity(in int serial);
+  oneway void getHardwareConfig(in int serial);
+  oneway void getModemActivityInfo(in int serial);
+  oneway void getModemStackStatus(in int serial);
+  oneway void getRadioCapability(in int serial);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
+  oneway void nvReadItem(in int serial, in android.hardware.radio.modem.NvItem itemId);
+  oneway void nvResetConfig(in int serial, in android.hardware.radio.modem.ResetNvType resetType);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
+  oneway void nvWriteCdmaPrl(in int serial, in byte[] prl);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
+  oneway void nvWriteItem(in int serial, in android.hardware.radio.modem.NvWriteItem item);
+  oneway void requestShutdown(in int serial);
+  oneway void responseAcknowledgement();
+  oneway void sendDeviceState(in int serial, in android.hardware.radio.modem.DeviceStateType deviceStateType, in boolean state);
+  oneway void setRadioCapability(in int serial, in android.hardware.radio.modem.RadioCapability rc);
+  oneway void setRadioPower(in int serial, in boolean powerOn, in boolean forEmergencyCall, in boolean preferredForEmergencyCall);
+  oneway void setResponseFunctions(in android.hardware.radio.modem.IRadioModemResponse radioModemResponse, in android.hardware.radio.modem.IRadioModemIndication radioModemIndication);
+  oneway void getImei(in int serial);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/IRadioModemIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/IRadioModemIndication.aidl
new file mode 100644
index 0000000..514ff9a
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/IRadioModemIndication.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.modem;
+@VintfStability
+interface IRadioModemIndication {
+  oneway void hardwareConfigChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.modem.HardwareConfig[] configs);
+  oneway void modemReset(in android.hardware.radio.RadioIndicationType type, in String reason);
+  oneway void radioCapabilityIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.modem.RadioCapability rc);
+  oneway void radioStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.modem.RadioState radioState);
+  oneway void rilConnected(in android.hardware.radio.RadioIndicationType type);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/IRadioModemResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/IRadioModemResponse.aidl
new file mode 100644
index 0000000..5955439
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/IRadioModemResponse.aidl
@@ -0,0 +1,66 @@
+/*
+ * 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.modem;
+@VintfStability
+interface IRadioModemResponse {
+  oneway void acknowledgeRequest(in int serial);
+  oneway void enableModemResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getBasebandVersionResponse(in android.hardware.radio.RadioResponseInfo info, in String version);
+  /**
+   * @deprecated use getImeiResponse(RadioResponseInfo responseInfo, ImeiInfo imeiInfo)
+   */
+  oneway void getDeviceIdentityResponse(in android.hardware.radio.RadioResponseInfo info, in String imei, in String imeisv, in String esn, in String meid);
+  oneway void getHardwareConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.HardwareConfig[] config);
+  oneway void getModemActivityInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.ActivityStatsInfo activityInfo);
+  oneway void getModemStackStatusResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
+  oneway void getRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.RadioCapability rc);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
+  oneway void nvReadItemResponse(in android.hardware.radio.RadioResponseInfo info, in String result);
+  oneway void nvResetConfigResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
+  oneway void nvWriteCdmaPrlResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
+  oneway void nvWriteItemResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void requestShutdownResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void sendDeviceStateResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.RadioCapability rc);
+  oneway void setRadioPowerResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getImeiResponse(in android.hardware.radio.RadioResponseInfo responseInfo, in @nullable android.hardware.radio.modem.ImeiInfo imeiInfo);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ImeiInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ImeiInfo.aidl
new file mode 100644
index 0000000..f8776ec
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ImeiInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.modem;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImeiInfo {
+  android.hardware.radio.modem.ImeiInfo.ImeiType type;
+  String imei;
+  String svn;
+  @Backing(type="int") @VintfStability
+  enum ImeiType {
+    PRIMARY = 1,
+    SECONDARY = 2,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/NvItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/NvItem.aidl
new file mode 100644
index 0000000..b80d7ac
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/NvItem.aidl
@@ -0,0 +1,81 @@
+/*
+ * 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.modem;
+/**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum NvItem {
+  CDMA_MEID = 1,
+  CDMA_MIN = 2,
+  CDMA_MDN = 3,
+  CDMA_ACCOLC = 4,
+  DEVICE_MSL = 11,
+  RTN_RECONDITIONED_STATUS = 12,
+  RTN_ACTIVATION_DATE = 13,
+  RTN_LIFE_TIMER = 14,
+  RTN_LIFE_CALLS = 15,
+  RTN_LIFE_DATA_TX = 16,
+  RTN_LIFE_DATA_RX = 17,
+  OMADM_HFA_LEVEL = 18,
+  MIP_PROFILE_NAI = 31,
+  MIP_PROFILE_HOME_ADDRESS = 32,
+  MIP_PROFILE_AAA_AUTH = 33,
+  MIP_PROFILE_HA_AUTH = 34,
+  MIP_PROFILE_PRI_HA_ADDR = 35,
+  MIP_PROFILE_SEC_HA_ADDR = 36,
+  MIP_PROFILE_REV_TUN_PREF = 37,
+  MIP_PROFILE_HA_SPI = 38,
+  MIP_PROFILE_AAA_SPI = 39,
+  MIP_PROFILE_MN_HA_SS = 40,
+  MIP_PROFILE_MN_AAA_SS = 41,
+  CDMA_PRL_VERSION = 51,
+  CDMA_BC10 = 52,
+  CDMA_BC14 = 53,
+  CDMA_SO68 = 54,
+  CDMA_SO73_COP0 = 55,
+  CDMA_SO73_COP1TO7 = 56,
+  CDMA_1X_ADVANCED_ENABLED = 57,
+  CDMA_EHRPD_ENABLED = 58,
+  CDMA_EHRPD_FORCED = 59,
+  LTE_BAND_ENABLE_25 = 71,
+  LTE_BAND_ENABLE_26 = 72,
+  LTE_BAND_ENABLE_41 = 73,
+  LTE_SCAN_PRIORITY_25 = 74,
+  LTE_SCAN_PRIORITY_26 = 75,
+  LTE_SCAN_PRIORITY_41 = 76,
+  LTE_HIDDEN_BAND_PRIORITY_25 = 77,
+  LTE_HIDDEN_BAND_PRIORITY_26 = 78,
+  LTE_HIDDEN_BAND_PRIORITY_41 = 79,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/NvWriteItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/NvWriteItem.aidl
new file mode 100644
index 0000000..6a786bc
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/NvWriteItem.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.modem;
+/**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
+@JavaDerive(toString=true) @VintfStability
+parcelable NvWriteItem {
+  android.hardware.radio.modem.NvItem itemId;
+  String value;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/RadioCapability.aidl
new file mode 100644
index 0000000..f2e2858
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/RadioCapability.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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.modem;
+@JavaDerive(toString=true) @VintfStability
+parcelable RadioCapability {
+  int session;
+  int phase;
+  int raf;
+  String logicalModemUuid;
+  int status;
+  const int PHASE_CONFIGURED = 0;
+  const int PHASE_START = 1;
+  const int PHASE_APPLY = 2;
+  const int PHASE_UNSOL_RSP = 3;
+  const int PHASE_FINISH = 4;
+  const int STATUS_NONE = 0;
+  const int STATUS_SUCCESS = 1;
+  const int STATUS_FAIL = 2;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/RadioState.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/RadioState.aidl
new file mode 100644
index 0000000..57f2941
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/RadioState.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.modem;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum RadioState {
+  OFF = 0,
+  UNAVAILABLE = 1,
+  ON = 10,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ResetNvType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ResetNvType.aidl
new file mode 100644
index 0000000..37622b1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/2/android/hardware/radio/modem/ResetNvType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.modem;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ResetNvType {
+  RELOAD,
+  ERASE,
+  FACTORY_RESET,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl
index 4e8c6d7..acc0b22 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl
@@ -34,7 +34,7 @@
 package android.hardware.radio.modem;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum DeviceStateType {
-  POWER_SAVE_MODE = 0,
-  CHARGING_STATE = 1,
-  LOW_DATA_EXPECTED = 2,
+  POWER_SAVE_MODE,
+  CHARGING_STATE,
+  LOW_DATA_EXPECTED,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl
index 41eff51..8546be7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl
@@ -36,14 +36,26 @@
 interface IRadioModem {
   oneway void enableModem(in int serial, in boolean on);
   oneway void getBasebandVersion(in int serial);
+  /**
+   * @deprecated use getImei(int serial)
+   */
   oneway void getDeviceIdentity(in int serial);
   oneway void getHardwareConfig(in int serial);
   oneway void getModemActivityInfo(in int serial);
   oneway void getModemStackStatus(in int serial);
   oneway void getRadioCapability(in int serial);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
   oneway void nvReadItem(in int serial, in android.hardware.radio.modem.NvItem itemId);
   oneway void nvResetConfig(in int serial, in android.hardware.radio.modem.ResetNvType resetType);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
   oneway void nvWriteCdmaPrl(in int serial, in byte[] prl);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
   oneway void nvWriteItem(in int serial, in android.hardware.radio.modem.NvWriteItem item);
   oneway void requestShutdown(in int serial);
   oneway void responseAcknowledgement();
@@ -51,4 +63,5 @@
   oneway void setRadioCapability(in int serial, in android.hardware.radio.modem.RadioCapability rc);
   oneway void setRadioPower(in int serial, in boolean powerOn, in boolean forEmergencyCall, in boolean preferredForEmergencyCall);
   oneway void setResponseFunctions(in android.hardware.radio.modem.IRadioModemResponse radioModemResponse, in android.hardware.radio.modem.IRadioModemIndication radioModemIndication);
+  oneway void getImei(in int serial);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl
index dcaff45..5955439 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl
@@ -37,17 +37,30 @@
   oneway void acknowledgeRequest(in int serial);
   oneway void enableModemResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void getBasebandVersionResponse(in android.hardware.radio.RadioResponseInfo info, in String version);
+  /**
+   * @deprecated use getImeiResponse(RadioResponseInfo responseInfo, ImeiInfo imeiInfo)
+   */
   oneway void getDeviceIdentityResponse(in android.hardware.radio.RadioResponseInfo info, in String imei, in String imeisv, in String esn, in String meid);
   oneway void getHardwareConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.HardwareConfig[] config);
   oneway void getModemActivityInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.ActivityStatsInfo activityInfo);
   oneway void getModemStackStatusResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
   oneway void getRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.RadioCapability rc);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
   oneway void nvReadItemResponse(in android.hardware.radio.RadioResponseInfo info, in String result);
   oneway void nvResetConfigResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
   oneway void nvWriteCdmaPrlResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
   oneway void nvWriteItemResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void requestShutdownResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void sendDeviceStateResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.RadioCapability rc);
   oneway void setRadioPowerResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getImeiResponse(in android.hardware.radio.RadioResponseInfo responseInfo, in @nullable android.hardware.radio.modem.ImeiInfo imeiInfo);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl
new file mode 100644
index 0000000..f8776ec
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.modem;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImeiInfo {
+  android.hardware.radio.modem.ImeiInfo.ImeiType type;
+  String imei;
+  String svn;
+  @Backing(type="int") @VintfStability
+  enum ImeiType {
+    PRIMARY = 1,
+    SECONDARY = 2,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl
index 3e27643..b80d7ac 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl
@@ -32,6 +32,9 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
+/**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum NvItem {
   CDMA_MEID = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
index 17b7de0..6a786bc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
@@ -32,6 +32,9 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.modem;
+/**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
 @JavaDerive(toString=true) @VintfStability
 parcelable NvWriteItem {
   android.hardware.radio.modem.NvItem itemId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
index e3b5796..37622b1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
@@ -34,7 +34,7 @@
 package android.hardware.radio.modem;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum ResetNvType {
-  RELOAD = 0,
-  ERASE = 1,
-  FACTORY_RESET = 2,
+  RELOAD,
+  ERASE,
+  FACTORY_RESET,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/.hash b/radio/aidl/aidl_api/android.hardware.radio.network/2/.hash
new file mode 100644
index 0000000..d3889fa
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/.hash
@@ -0,0 +1 @@
+1b6608f238bd0b1c642df315621a7b605eafc883
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
new file mode 100644
index 0000000..28d8862
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+union AccessTechnologySpecificInfo {
+  boolean noinit;
+  android.hardware.radio.network.Cdma2000RegistrationInfo cdmaInfo;
+  android.hardware.radio.network.EutranRegistrationInfo eutranInfo;
+  android.hardware.radio.network.NrVopsInfo ngranNrVopsInfo;
+  boolean geranDtmSupported;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/BarringInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/BarringInfo.aidl
new file mode 100644
index 0000000..e105b39
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/BarringInfo.aidl
@@ -0,0 +1,85 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable BarringInfo {
+  int serviceType;
+  int barringType;
+  @nullable android.hardware.radio.network.BarringTypeSpecificInfo barringTypeSpecificInfo;
+  const int BARRING_TYPE_NONE = 0;
+  const int BARRING_TYPE_CONDITIONAL = 1;
+  const int BARRING_TYPE_UNCONDITIONAL = 2;
+  const int SERVICE_TYPE_CS_SERVICE = 0;
+  const int SERVICE_TYPE_PS_SERVICE = 1;
+  const int SERVICE_TYPE_CS_VOICE = 2;
+  const int SERVICE_TYPE_MO_SIGNALLING = 3;
+  const int SERVICE_TYPE_MO_DATA = 4;
+  const int SERVICE_TYPE_CS_FALLBACK = 5;
+  const int SERVICE_TYPE_MMTEL_VOICE = 6;
+  const int SERVICE_TYPE_MMTEL_VIDEO = 7;
+  const int SERVICE_TYPE_EMERGENCY = 8;
+  const int SERVICE_TYPE_SMS = 9;
+  const int SERVICE_TYPE_OPERATOR_1 = 1001;
+  const int SERVICE_TYPE_OPERATOR_2 = 1002;
+  const int SERVICE_TYPE_OPERATOR_3 = 1003;
+  const int SERVICE_TYPE_OPERATOR_4 = 1004;
+  const int SERVICE_TYPE_OPERATOR_5 = 1005;
+  const int SERVICE_TYPE_OPERATOR_6 = 1006;
+  const int SERVICE_TYPE_OPERATOR_7 = 1007;
+  const int SERVICE_TYPE_OPERATOR_8 = 1008;
+  const int SERVICE_TYPE_OPERATOR_9 = 1009;
+  const int SERVICE_TYPE_OPERATOR_10 = 1010;
+  const int SERVICE_TYPE_OPERATOR_11 = 1011;
+  const int SERVICE_TYPE_OPERATOR_12 = 1012;
+  const int SERVICE_TYPE_OPERATOR_13 = 1013;
+  const int SERVICE_TYPE_OPERATOR_14 = 1014;
+  const int SERVICE_TYPE_OPERATOR_15 = 1015;
+  const int SERVICE_TYPE_OPERATOR_16 = 1016;
+  const int SERVICE_TYPE_OPERATOR_17 = 1017;
+  const int SERVICE_TYPE_OPERATOR_18 = 1018;
+  const int SERVICE_TYPE_OPERATOR_19 = 1019;
+  const int SERVICE_TYPE_OPERATOR_20 = 1020;
+  const int SERVICE_TYPE_OPERATOR_21 = 1021;
+  const int SERVICE_TYPE_OPERATOR_22 = 1022;
+  const int SERVICE_TYPE_OPERATOR_23 = 1023;
+  const int SERVICE_TYPE_OPERATOR_24 = 1024;
+  const int SERVICE_TYPE_OPERATOR_25 = 1025;
+  const int SERVICE_TYPE_OPERATOR_26 = 1026;
+  const int SERVICE_TYPE_OPERATOR_27 = 1027;
+  const int SERVICE_TYPE_OPERATOR_28 = 1028;
+  const int SERVICE_TYPE_OPERATOR_29 = 1029;
+  const int SERVICE_TYPE_OPERATOR_30 = 1030;
+  const int SERVICE_TYPE_OPERATOR_31 = 1031;
+  const int SERVICE_TYPE_OPERATOR_32 = 1032;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/BarringTypeSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
new file mode 100644
index 0000000..a813633
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable BarringTypeSpecificInfo {
+  int factor;
+  int timeSeconds;
+  boolean isBarred;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
new file mode 100644
index 0000000..e8fb79e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable Cdma2000RegistrationInfo {
+  boolean cssSupported;
+  int roamingIndicator;
+  int systemIsInPrl;
+  int defaultRoamingIndicator;
+  const int PRL_INDICATOR_NOT_REGISTERED = (-1) /* -1 */;
+  const int PRL_INDICATOR_NOT_IN_PRL = 0;
+  const int PRL_INDICATOR_IN_PRL = 1;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CdmaRoamingType.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CdmaRoamingType.aidl
new file mode 100644
index 0000000..2a4db70
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CdmaRoamingType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum CdmaRoamingType {
+  HOME_NETWORK,
+  AFFILIATED_ROAM,
+  ANY_ROAM,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CdmaSignalStrength.aidl
new file mode 100644
index 0000000..e2f97bf
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CdmaSignalStrength.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaSignalStrength {
+  int dbm;
+  int ecio;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellConnectionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellConnectionStatus.aidl
new file mode 100644
index 0000000..5ce3b3e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellConnectionStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum CellConnectionStatus {
+  NONE,
+  PRIMARY_SERVING,
+  SECONDARY_SERVING,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentity.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentity.aidl
new file mode 100644
index 0000000..2ee92de
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentity.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+union CellIdentity {
+  boolean noinit;
+  android.hardware.radio.network.CellIdentityGsm gsm;
+  android.hardware.radio.network.CellIdentityWcdma wcdma;
+  android.hardware.radio.network.CellIdentityTdscdma tdscdma;
+  android.hardware.radio.network.CellIdentityCdma cdma;
+  android.hardware.radio.network.CellIdentityLte lte;
+  android.hardware.radio.network.CellIdentityNr nr;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityCdma.aidl
new file mode 100644
index 0000000..d659a28
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellIdentityCdma {
+  int networkId;
+  int systemId;
+  int baseStationId;
+  int longitude;
+  int latitude;
+  android.hardware.radio.network.OperatorInfo operatorNames;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityGsm.aidl
new file mode 100644
index 0000000..d3193be
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityGsm.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellIdentityGsm {
+  String mcc;
+  String mnc;
+  int lac;
+  int cid;
+  int arfcn;
+  byte bsic;
+  android.hardware.radio.network.OperatorInfo operatorNames;
+  String[] additionalPlmns;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityLte.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityLte.aidl
new file mode 100644
index 0000000..2ae7b43
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityLte.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellIdentityLte {
+  String mcc;
+  String mnc;
+  int ci;
+  int pci;
+  int tac;
+  int earfcn;
+  android.hardware.radio.network.OperatorInfo operatorNames;
+  int bandwidth;
+  String[] additionalPlmns;
+  @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo;
+  android.hardware.radio.network.EutranBands[] bands;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityNr.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityNr.aidl
new file mode 100644
index 0000000..b30af50
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityNr.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellIdentityNr {
+  String mcc;
+  String mnc;
+  long nci;
+  int pci;
+  int tac;
+  int nrarfcn;
+  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/2/android/hardware/radio/network/CellIdentityTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityTdscdma.aidl
new file mode 100644
index 0000000..e99d147
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityTdscdma.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellIdentityTdscdma {
+  String mcc;
+  String mnc;
+  int lac;
+  int cid;
+  int cpid;
+  int uarfcn;
+  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/2/android/hardware/radio/network/CellIdentityWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityWcdma.aidl
new file mode 100644
index 0000000..12001fc
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellIdentityWcdma.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellIdentityWcdma {
+  String mcc;
+  String mnc;
+  int lac;
+  int cid;
+  int psc;
+  int uarfcn;
+  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/2/android/hardware/radio/network/CellInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfo.aidl
new file mode 100644
index 0000000..467c6b7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellInfo {
+  boolean registered;
+  android.hardware.radio.network.CellConnectionStatus connectionStatus;
+  android.hardware.radio.network.CellInfoRatSpecificInfo ratSpecificInfo;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoCdma.aidl
new file mode 100644
index 0000000..e3bf46b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoCdma.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellInfoCdma {
+  android.hardware.radio.network.CellIdentityCdma cellIdentityCdma;
+  android.hardware.radio.network.CdmaSignalStrength signalStrengthCdma;
+  android.hardware.radio.network.EvdoSignalStrength signalStrengthEvdo;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoGsm.aidl
new file mode 100644
index 0000000..84dcd07
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoGsm.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellInfoGsm {
+  android.hardware.radio.network.CellIdentityGsm cellIdentityGsm;
+  android.hardware.radio.network.GsmSignalStrength signalStrengthGsm;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoLte.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoLte.aidl
new file mode 100644
index 0000000..221340b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoLte.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellInfoLte {
+  android.hardware.radio.network.CellIdentityLte cellIdentityLte;
+  android.hardware.radio.network.LteSignalStrength signalStrengthLte;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoNr.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoNr.aidl
new file mode 100644
index 0000000..b392c1d
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoNr.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellInfoNr {
+  android.hardware.radio.network.CellIdentityNr cellIdentityNr;
+  android.hardware.radio.network.NrSignalStrength signalStrengthNr;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
new file mode 100644
index 0000000..4ab0640
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+union CellInfoRatSpecificInfo {
+  android.hardware.radio.network.CellInfoGsm gsm;
+  android.hardware.radio.network.CellInfoWcdma wcdma;
+  android.hardware.radio.network.CellInfoTdscdma tdscdma;
+  android.hardware.radio.network.CellInfoLte lte;
+  android.hardware.radio.network.CellInfoNr nr;
+  android.hardware.radio.network.CellInfoCdma cdma;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoTdscdma.aidl
new file mode 100644
index 0000000..138b35c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoTdscdma.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellInfoTdscdma {
+  android.hardware.radio.network.CellIdentityTdscdma cellIdentityTdscdma;
+  android.hardware.radio.network.TdscdmaSignalStrength signalStrengthTdscdma;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoWcdma.aidl
new file mode 100644
index 0000000..cf7b135
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/CellInfoWcdma.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable CellInfoWcdma {
+  android.hardware.radio.network.CellIdentityWcdma cellIdentityWcdma;
+  android.hardware.radio.network.WcdmaSignalStrength signalStrengthWcdma;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
new file mode 100644
index 0000000..fe734c8
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable ClosedSubscriberGroupInfo {
+  boolean csgIndication;
+  String homeNodebName;
+  int csgIdentity;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/Domain.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/Domain.aidl
new file mode 100644
index 0000000..2daeadd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/Domain.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum Domain {
+  CS = (1 << 0) /* 1 */,
+  PS = (1 << 1) /* 2 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyMode.aidl
new file mode 100644
index 0000000..071e6b5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EmergencyMode {
+  EMERGENCY_WWAN = 1,
+  EMERGENCY_WLAN = 2,
+  EMERGENCY_CALLBACK = 3,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
new file mode 100644
index 0000000..2797aff
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable EmergencyNetworkScanTrigger {
+  android.hardware.radio.AccessNetwork[] accessNetwork;
+  android.hardware.radio.network.EmergencyScanType scanType;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyRegResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyRegResult.aidl
new file mode 100644
index 0000000..7d99a53
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyRegResult.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable EmergencyRegResult {
+  android.hardware.radio.AccessNetwork accessNetwork;
+  android.hardware.radio.network.RegState regState;
+  android.hardware.radio.network.Domain emcDomain;
+  boolean isVopsSupported;
+  boolean isEmcBearerSupported;
+  byte nwProvidedEmc;
+  byte nwProvidedEmf;
+  String mcc = "";
+  String mnc = "";
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyScanType.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyScanType.aidl
new file mode 100644
index 0000000..5e86c76
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EmergencyScanType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EmergencyScanType {
+  NO_PREFERENCE = 0,
+  LIMITED_SERVICE = 1,
+  FULL_SERVICE = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EutranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EutranBands.aidl
new file mode 100644
index 0000000..57fac3f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EutranBands.aidl
@@ -0,0 +1,97 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EutranBands {
+  BAND_1 = 1,
+  BAND_2 = 2,
+  BAND_3 = 3,
+  BAND_4 = 4,
+  BAND_5 = 5,
+  BAND_6 = 6,
+  BAND_7 = 7,
+  BAND_8 = 8,
+  BAND_9 = 9,
+  BAND_10 = 10,
+  BAND_11 = 11,
+  BAND_12 = 12,
+  BAND_13 = 13,
+  BAND_14 = 14,
+  BAND_17 = 17,
+  BAND_18 = 18,
+  BAND_19 = 19,
+  BAND_20 = 20,
+  BAND_21 = 21,
+  BAND_22 = 22,
+  BAND_23 = 23,
+  BAND_24 = 24,
+  BAND_25 = 25,
+  BAND_26 = 26,
+  BAND_27 = 27,
+  BAND_28 = 28,
+  BAND_30 = 30,
+  BAND_31 = 31,
+  BAND_33 = 33,
+  BAND_34 = 34,
+  BAND_35 = 35,
+  BAND_36 = 36,
+  BAND_37 = 37,
+  BAND_38 = 38,
+  BAND_39 = 39,
+  BAND_40 = 40,
+  BAND_41 = 41,
+  BAND_42 = 42,
+  BAND_43 = 43,
+  BAND_44 = 44,
+  BAND_45 = 45,
+  BAND_46 = 46,
+  BAND_47 = 47,
+  BAND_48 = 48,
+  BAND_65 = 65,
+  BAND_66 = 66,
+  BAND_68 = 68,
+  BAND_70 = 70,
+  BAND_49 = 49,
+  BAND_50 = 50,
+  BAND_51 = 51,
+  BAND_52 = 52,
+  BAND_53 = 53,
+  BAND_71 = 71,
+  BAND_72 = 72,
+  BAND_73 = 73,
+  BAND_74 = 74,
+  BAND_85 = 85,
+  BAND_87 = 87,
+  BAND_88 = 88,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EutranRegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EutranRegistrationInfo.aidl
new file mode 100644
index 0000000..2321cac
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EutranRegistrationInfo.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable EutranRegistrationInfo {
+  android.hardware.radio.network.LteVopsInfo lteVopsInfo;
+  android.hardware.radio.network.NrIndicators nrIndicators;
+  android.hardware.radio.network.EutranRegistrationInfo.AttachResultType lteAttachResultType;
+  int extraInfo;
+  const int EXTRA_CSFB_NOT_PREFERRED = (1 << 0) /* 1 */;
+  const int EXTRA_SMS_ONLY = (1 << 1) /* 2 */;
+  enum AttachResultType {
+    NONE,
+    EPS_ONLY,
+    COMBINED,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EvdoSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EvdoSignalStrength.aidl
new file mode 100644
index 0000000..7c56711
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/EvdoSignalStrength.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable EvdoSignalStrength {
+  int dbm;
+  int ecio;
+  int signalNoiseRatio;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/GeranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/GeranBands.aidl
new file mode 100644
index 0000000..135935f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/GeranBands.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum GeranBands {
+  BAND_T380 = 1,
+  BAND_T410 = 2,
+  BAND_450 = 3,
+  BAND_480 = 4,
+  BAND_710 = 5,
+  BAND_750 = 6,
+  BAND_T810 = 7,
+  BAND_850 = 8,
+  BAND_P900 = 9,
+  BAND_E900 = 10,
+  BAND_R900 = 11,
+  BAND_DCS1800 = 12,
+  BAND_PCS1900 = 13,
+  BAND_ER900 = 14,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/GsmSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/GsmSignalStrength.aidl
new file mode 100644
index 0000000..2b53b39
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/GsmSignalStrength.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable GsmSignalStrength {
+  int signalStrength;
+  int bitErrorRate;
+  int timingAdvance;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IRadioNetwork.aidl
new file mode 100644
index 0000000..382ddd8
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IRadioNetwork.aidl
@@ -0,0 +1,84 @@
+/*
+ * 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.network;
+@VintfStability
+interface IRadioNetwork {
+  oneway void getAllowedNetworkTypesBitmap(in int serial);
+  oneway void getAvailableBandModes(in int serial);
+  oneway void getAvailableNetworks(in int serial);
+  oneway void getBarringInfo(in int serial);
+  oneway void getCdmaRoamingPreference(in int serial);
+  oneway void getCellInfoList(in int serial);
+  oneway void getDataRegistrationState(in int serial);
+  /**
+   * @deprecated Deprecated starting from Android U.
+   */
+  oneway void getImsRegistrationState(in int serial);
+  oneway void getNetworkSelectionMode(in int serial);
+  oneway void getOperator(in int serial);
+  oneway void getSignalStrength(in int serial);
+  oneway void getSystemSelectionChannels(in int serial);
+  oneway void getVoiceRadioTechnology(in int serial);
+  oneway void getVoiceRegistrationState(in int serial);
+  oneway void isNrDualConnectivityEnabled(in int serial);
+  oneway void responseAcknowledgement();
+  oneway void setAllowedNetworkTypesBitmap(in int serial, in int networkTypeBitmap);
+  oneway void setBandMode(in int serial, in android.hardware.radio.network.RadioBandMode mode);
+  oneway void setBarringPassword(in int serial, in String facility, in String oldPassword, in String newPassword);
+  oneway void setCdmaRoamingPreference(in int serial, in android.hardware.radio.network.CdmaRoamingType type);
+  oneway void setCellInfoListRate(in int serial, in int rate);
+  oneway void setIndicationFilter(in int serial, in int indicationFilter);
+  oneway void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, in int[] thresholdsUplinkKbps, in android.hardware.radio.AccessNetwork accessNetwork);
+  oneway void setLocationUpdates(in int serial, in boolean enable);
+  oneway void setNetworkSelectionModeAutomatic(in int serial);
+  oneway void setNetworkSelectionModeManual(in int serial, in String operatorNumeric, in android.hardware.radio.AccessNetwork ran);
+  oneway void setNrDualConnectivityState(in int serial, in android.hardware.radio.network.NrDualConnectivityState nrDualConnectivityState);
+  oneway void setResponseFunctions(in android.hardware.radio.network.IRadioNetworkResponse radioNetworkResponse, in android.hardware.radio.network.IRadioNetworkIndication radioNetworkIndication);
+  oneway void setSignalStrengthReportingCriteria(in int serial, in android.hardware.radio.network.SignalThresholdInfo[] signalThresholdInfos);
+  oneway void setSuppServiceNotifications(in int serial, in boolean enable);
+  oneway void setSystemSelectionChannels(in int serial, in boolean specifyChannels, in android.hardware.radio.network.RadioAccessSpecifier[] specifiers);
+  oneway void startNetworkScan(in int serial, in android.hardware.radio.network.NetworkScanRequest request);
+  oneway void stopNetworkScan(in int serial);
+  oneway void supplyNetworkDepersonalization(in int serial, in String netPin);
+  oneway void setUsageSetting(in int serial, in android.hardware.radio.network.UsageSetting usageSetting);
+  oneway void getUsageSetting(in int serial);
+  oneway void setEmergencyMode(int serial, in android.hardware.radio.network.EmergencyMode emcModeType);
+  oneway void triggerEmergencyNetworkScan(int serial, in android.hardware.radio.network.EmergencyNetworkScanTrigger request);
+  oneway void cancelEmergencyNetworkScan(int serial, boolean resetScan);
+  oneway void exitEmergencyMode(in int serial);
+  oneway void setNullCipherAndIntegrityEnabled(in int serial, in boolean enabled);
+  oneway void isNullCipherAndIntegrityEnabled(in int serial);
+  oneway void isN1ModeEnabled(in int serial);
+  oneway void setN1ModeEnabled(in int serial, boolean enable);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IRadioNetworkIndication.aidl
new file mode 100644
index 0000000..0f017ea
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.network;
+@VintfStability
+interface IRadioNetworkIndication {
+  oneway void barringInfoChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellIdentity cellIdentity, in android.hardware.radio.network.BarringInfo[] barringInfos);
+  oneway void cdmaPrlChanged(in android.hardware.radio.RadioIndicationType type, in int version);
+  oneway void cellInfoList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellInfo[] records);
+  oneway void currentLinkCapacityEstimate(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.LinkCapacityEstimate lce);
+  oneway void currentPhysicalChannelConfigs(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.PhysicalChannelConfig[] configs);
+  oneway void currentSignalStrength(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.SignalStrength signalStrength);
+  oneway void imsNetworkStateChanged(in android.hardware.radio.RadioIndicationType type);
+  oneway void networkScanResult(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.NetworkScanResult result);
+  oneway void networkStateChanged(in android.hardware.radio.RadioIndicationType type);
+  oneway void nitzTimeReceived(in android.hardware.radio.RadioIndicationType type, in String nitzTime, in long receivedTimeMs, in long ageMs);
+  oneway void registrationFailed(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellIdentity cellIdentity, in String chosenPlmn, in int domain, in int causeCode, in int additionalCauseCode);
+  oneway void restrictedStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.PhoneRestrictedState state);
+  oneway void suppSvcNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.SuppSvcNotification suppSvc);
+  oneway void voiceRadioTechChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioTechnology rat);
+  oneway void emergencyNetworkScanResult(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.EmergencyRegResult result);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IRadioNetworkResponse.aidl
new file mode 100644
index 0000000..bfe8fa3
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -0,0 +1,83 @@
+/*
+ * 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.network;
+@VintfStability
+interface IRadioNetworkResponse {
+  oneway void acknowledgeRequest(in int serial);
+  oneway void getAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in int networkTypeBitmap);
+  oneway void getAvailableBandModesResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RadioBandMode[] bandModes);
+  oneway void getAvailableNetworksResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.OperatorInfo[] networkInfos);
+  oneway void getBarringInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellIdentity cellIdentity, in android.hardware.radio.network.BarringInfo[] barringInfos);
+  oneway void getCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CdmaRoamingType type);
+  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);
+  /**
+   * @deprecated Deprecated starting from Android U.
+   */
+  oneway void getImsRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isRegistered, in android.hardware.radio.RadioTechnologyFamily ratFamily);
+  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);
+  oneway void getSystemSelectionChannelsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RadioAccessSpecifier[] specifiers);
+  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 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);
+  oneway void setCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setCellInfoListRateResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setIndicationFilterResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setLinkCapacityReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setLocationUpdatesResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setNetworkSelectionModeAutomaticResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setNetworkSelectionModeManualResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setNrDualConnectivityStateResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setSignalStrengthReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setSuppServiceNotificationsResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setSystemSelectionChannelsResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void startNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void stopNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void supplyNetworkDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
+  oneway void setUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.UsageSetting usageSetting);
+  oneway void setEmergencyModeResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.EmergencyRegResult regState);
+  oneway void triggerEmergencyNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void exitEmergencyModeResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void cancelEmergencyNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setNullCipherAndIntegrityEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void isNullCipherAndIntegrityEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
+  oneway void isN1ModeEnabledResponse(in android.hardware.radio.RadioResponseInfo info, boolean isEnabled);
+  oneway void setN1ModeEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IndicationFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IndicationFilter.aidl
new file mode 100644
index 0000000..cd538c8
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/IndicationFilter.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum IndicationFilter {
+  NONE = 0,
+  ALL = (~0) /* -1 */,
+  SIGNAL_STRENGTH = (1 << 0) /* 1 */,
+  FULL_NETWORK_STATE = (1 << 1) /* 2 */,
+  DATA_CALL_DORMANCY_CHANGED = (1 << 2) /* 4 */,
+  LINK_CAPACITY_ESTIMATE = (1 << 3) /* 8 */,
+  PHYSICAL_CHANNEL_CONFIG = (1 << 4) /* 16 */,
+  REGISTRATION_FAILURE = (1 << 5) /* 32 */,
+  BARRING_INFO = (1 << 6) /* 64 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LceDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LceDataInfo.aidl
new file mode 100644
index 0000000..27b16c1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LceDataInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable LceDataInfo {
+  int lastHopCapacityKbps;
+  byte confidenceLevel;
+  boolean lceSuspended;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LinkCapacityEstimate.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LinkCapacityEstimate.aidl
new file mode 100644
index 0000000..5707b8e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LinkCapacityEstimate.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable LinkCapacityEstimate {
+  int downlinkCapacityKbps;
+  int uplinkCapacityKbps;
+  int secondaryDownlinkCapacityKbps;
+  int secondaryUplinkCapacityKbps;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LteSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LteSignalStrength.aidl
new file mode 100644
index 0000000..b5b8579
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LteSignalStrength.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable LteSignalStrength {
+  int signalStrength;
+  int rsrp;
+  int rsrq;
+  int rssnr;
+  int cqi;
+  int timingAdvance;
+  int cqiTableIndex;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LteVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LteVopsInfo.aidl
new file mode 100644
index 0000000..6d8dd4e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/LteVopsInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable LteVopsInfo {
+  boolean isVopsSupported;
+  boolean isEmcBearerSupported;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NetworkScanRequest.aidl
new file mode 100644
index 0000000..6039740
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable NetworkScanRequest {
+  int type;
+  int interval;
+  android.hardware.radio.network.RadioAccessSpecifier[] specifiers;
+  int maxSearchTime;
+  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;
+  const int MAX_SEARCH_TIME_RANGE_MAX = 3600;
+  const int SCAN_INTERVAL_RANGE_MIN = 5;
+  const int SCAN_INTERVAL_RANGE_MAX = 300;
+  const int SCAN_TYPE_ONE_SHOT = 0;
+  const int SCAN_TYPE_PERIODIC = 1;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NetworkScanResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NetworkScanResult.aidl
new file mode 100644
index 0000000..4e392d0
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NetworkScanResult.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable NetworkScanResult {
+  int status;
+  android.hardware.radio.RadioError error;
+  android.hardware.radio.network.CellInfo[] networkInfos;
+  const int SCAN_STATUS_PARTIAL = 1;
+  const int SCAN_STATUS_COMPLETE = 2;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NgranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NgranBands.aidl
new file mode 100644
index 0000000..5904690
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NgranBands.aidl
@@ -0,0 +1,90 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum NgranBands {
+  BAND_1 = 1,
+  BAND_2 = 2,
+  BAND_3 = 3,
+  BAND_5 = 5,
+  BAND_7 = 7,
+  BAND_8 = 8,
+  BAND_12 = 12,
+  BAND_14 = 14,
+  BAND_18 = 18,
+  BAND_20 = 20,
+  BAND_25 = 25,
+  BAND_26 = 26,
+  BAND_28 = 28,
+  BAND_29 = 29,
+  BAND_30 = 30,
+  BAND_34 = 34,
+  BAND_38 = 38,
+  BAND_39 = 39,
+  BAND_40 = 40,
+  BAND_41 = 41,
+  BAND_46 = 46,
+  BAND_48 = 48,
+  BAND_50 = 50,
+  BAND_51 = 51,
+  BAND_53 = 53,
+  BAND_65 = 65,
+  BAND_66 = 66,
+  BAND_70 = 70,
+  BAND_71 = 71,
+  BAND_74 = 74,
+  BAND_75 = 75,
+  BAND_76 = 76,
+  BAND_77 = 77,
+  BAND_78 = 78,
+  BAND_79 = 79,
+  BAND_80 = 80,
+  BAND_81 = 81,
+  BAND_82 = 82,
+  BAND_83 = 83,
+  BAND_84 = 84,
+  BAND_86 = 86,
+  BAND_89 = 89,
+  BAND_90 = 90,
+  BAND_91 = 91,
+  BAND_92 = 92,
+  BAND_93 = 93,
+  BAND_94 = 94,
+  BAND_95 = 95,
+  BAND_96 = 96,
+  BAND_257 = 257,
+  BAND_258 = 258,
+  BAND_260 = 260,
+  BAND_261 = 261,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrDualConnectivityState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrDualConnectivityState.aidl
new file mode 100644
index 0000000..62c2a56
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrDualConnectivityState.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@Backing(type="byte") @JavaDerive(toString=true) @VintfStability
+enum NrDualConnectivityState {
+  ENABLE = 1,
+  DISABLE = 2,
+  DISABLE_IMMEDIATE = 3,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrIndicators.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrIndicators.aidl
new file mode 100644
index 0000000..88429f6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrIndicators.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable NrIndicators {
+  boolean isEndcAvailable;
+  boolean isDcNrRestricted;
+  boolean isNrAvailable;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrSignalStrength.aidl
new file mode 100644
index 0000000..7d6ab82
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrSignalStrength.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable NrSignalStrength {
+  int ssRsrp;
+  int ssRsrq;
+  int ssSinr;
+  int csiRsrp;
+  int csiRsrq;
+  int csiSinr;
+  int csiCqiTableIndex;
+  byte[] csiCqiReport;
+  int timingAdvance = 0x7FFFFFFF;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrVopsInfo.aidl
new file mode 100644
index 0000000..e5a0a70
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/NrVopsInfo.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable NrVopsInfo {
+  byte vopsSupported;
+  byte emcSupported;
+  byte emfSupported;
+  const byte EMC_INDICATOR_NOT_SUPPORTED = 0;
+  const byte EMC_INDICATOR_NR_CONNECTED_TO_5GCN = 1;
+  const byte EMC_INDICATOR_EUTRA_CONNECTED_TO_5GCN = 2;
+  const byte EMC_INDICATOR_BOTH_NR_EUTRA_CONNECTED_TO_5GCN = 3;
+  const byte EMF_INDICATOR_NOT_SUPPORTED = 0;
+  const byte EMF_INDICATOR_NR_CONNECTED_TO_5GCN = 1;
+  const byte EMF_INDICATOR_EUTRA_CONNECTED_TO_5GCN = 2;
+  const byte EMF_INDICATOR_BOTH_NR_EUTRA_CONNECTED_TO_5GCN = 3;
+  const byte VOPS_INDICATOR_VOPS_NOT_SUPPORTED = 0;
+  const byte VOPS_INDICATOR_VOPS_OVER_3GPP = 1;
+  const byte VOPS_INDICATOR_VOPS_OVER_NON_3GPP = 2;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/OperatorInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/OperatorInfo.aidl
new file mode 100644
index 0000000..034150e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/OperatorInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable OperatorInfo {
+  String alphaLong;
+  String alphaShort;
+  String operatorNumeric;
+  int status;
+  const int STATUS_UNKNOWN = 0;
+  const int STATUS_AVAILABLE = 1;
+  const int STATUS_CURRENT = 2;
+  const int STATUS_FORBIDDEN = 3;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/PhoneRestrictedState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/PhoneRestrictedState.aidl
new file mode 100644
index 0000000..4e3e39e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/PhoneRestrictedState.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum PhoneRestrictedState {
+  NONE = 0x00,
+  CS_EMERGENCY = 0x01,
+  CS_NORMAL = 0x02,
+  CS_ALL = 0x04,
+  PS_ALL = 0x10,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/PhysicalChannelConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/PhysicalChannelConfig.aidl
new file mode 100644
index 0000000..928c6b7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/PhysicalChannelConfig.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable PhysicalChannelConfig {
+  android.hardware.radio.network.CellConnectionStatus status;
+  android.hardware.radio.RadioTechnology rat;
+  int downlinkChannelNumber;
+  int uplinkChannelNumber;
+  int cellBandwidthDownlinkKhz;
+  int cellBandwidthUplinkKhz;
+  int[] contextIds;
+  int physicalCellId;
+  android.hardware.radio.network.PhysicalChannelConfigBand band;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/PhysicalChannelConfigBand.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
new file mode 100644
index 0000000..efc64a6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+union PhysicalChannelConfigBand {
+  boolean noinit;
+  android.hardware.radio.network.GeranBands geranBand;
+  android.hardware.radio.network.UtranBands utranBand;
+  android.hardware.radio.network.EutranBands eutranBand;
+  android.hardware.radio.network.NgranBands ngranBand;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RadioAccessSpecifier.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RadioAccessSpecifier.aidl
new file mode 100644
index 0000000..1566bb5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RadioAccessSpecifier.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable RadioAccessSpecifier {
+  android.hardware.radio.AccessNetwork accessNetwork;
+  android.hardware.radio.network.RadioAccessSpecifierBands bands;
+  int[] channels;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RadioAccessSpecifierBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
new file mode 100644
index 0000000..a6ac12a
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+union RadioAccessSpecifierBands {
+  boolean noinit;
+  android.hardware.radio.network.GeranBands[] geranBands;
+  android.hardware.radio.network.UtranBands[] utranBands;
+  android.hardware.radio.network.EutranBands[] eutranBands;
+  android.hardware.radio.network.NgranBands[] ngranBands;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RadioBandMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RadioBandMode.aidl
new file mode 100644
index 0000000..74696fb
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RadioBandMode.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum RadioBandMode {
+  BAND_MODE_UNSPECIFIED,
+  BAND_MODE_EURO,
+  BAND_MODE_USA,
+  BAND_MODE_JPN,
+  BAND_MODE_AUS,
+  BAND_MODE_AUS_2,
+  BAND_MODE_CELL_800,
+  BAND_MODE_PCS,
+  BAND_MODE_JTACS,
+  BAND_MODE_KOREA_PCS,
+  BAND_MODE_5_450M,
+  BAND_MODE_IMT2000,
+  BAND_MODE_7_700M_2,
+  BAND_MODE_8_1800M,
+  BAND_MODE_9_900M,
+  BAND_MODE_10_800M_2,
+  BAND_MODE_EURO_PAMR_400M,
+  BAND_MODE_AWS,
+  BAND_MODE_USA_2500M,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RegState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RegState.aidl
new file mode 100644
index 0000000..711c9ac
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RegState.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum RegState {
+  NOT_REG_MT_NOT_SEARCHING_OP = 0,
+  REG_HOME = 1,
+  NOT_REG_MT_SEARCHING_OP = 2,
+  REG_DENIED = 3,
+  UNKNOWN = 4,
+  REG_ROAMING = 5,
+  NOT_REG_MT_NOT_SEARCHING_OP_EM = 10,
+  NOT_REG_MT_SEARCHING_OP_EM = 12,
+  REG_DENIED_EM = 13,
+  UNKNOWN_EM = 14,
+  REG_EM = 20,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RegStateResult.aidl
new file mode 100644
index 0000000..f0a03ae
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RegStateResult.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable RegStateResult {
+  android.hardware.radio.network.RegState regState;
+  android.hardware.radio.RadioTechnology rat;
+  android.hardware.radio.network.RegistrationFailCause reasonForDenial;
+  android.hardware.radio.network.CellIdentity cellIdentity;
+  String registeredPlmn;
+  android.hardware.radio.network.AccessTechnologySpecificInfo accessTechnologySpecificInfo;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RegistrationFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RegistrationFailCause.aidl
new file mode 100644
index 0000000..8acf8ab
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/RegistrationFailCause.aidl
@@ -0,0 +1,89 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum RegistrationFailCause {
+  NONE = 0,
+  IMSI_UNKNOWN_IN_HLR = 2,
+  ILLEGAL_MS = 3,
+  IMSI_UNKNOWN_IN_VLR = 4,
+  IMEI_NOT_ACCEPTED = 5,
+  ILLEGAL_ME = 6,
+  GPRS_SERVICES_NOT_ALLOWED = 7,
+  GPRS_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 8,
+  MS_IDENTITY_CANNOT_BE_DERIVED_BY_NETWORK = 9,
+  IMPLICITLY_DETACHED = 10,
+  PLMN_NOT_ALLOWED = 11,
+  LOCATION_AREA_NOT_ALLOWED = 12,
+  ROAMING_NOT_ALLOWED = 13,
+  GPRS_SERVICES_NOT_ALLOWED_IN_PLMN = 14,
+  NO_SUITABLE_CELLS = 15,
+  MSC_TEMPORARILY_NOT_REACHABLE = 15,
+  NETWORK_FAILURE = 17,
+  MAC_FAILURE = 20,
+  SYNC_FAILURE = 21,
+  CONGESTION = 22,
+  GSM_AUTHENTICATION_UNACCEPTABLE = 23,
+  NOT_AUTHORIZED_FOR_THIS_CSG = 25,
+  SMS_PROVIDED_BY_GPRS_IN_ROUTING_AREA,
+  SERVICE_OPTION_NOT_SUPPORTED = 32,
+  SERVICE_OPTION_NOT_SUBSCRIBED = 33,
+  SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER = 34,
+  CALL_CANNOT_BE_IDENTIFIED = 38,
+  NO_PDP_CONTEXT_ACTIVATED = 40,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_1 = 48,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_2 = 49,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_3 = 50,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_4 = 51,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_5 = 52,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_6 = 53,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_7 = 54,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_8 = 55,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_9 = 56,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_10 = 57,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_11 = 58,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_12 = 59,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_13 = 60,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_14 = 61,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_15 = 62,
+  RETRY_UPON_ENTRY_INTO_NEW_CELL_16 = 63,
+  SEMANTICALLY_INCORRECT_MESSAGE = 95,
+  INVALID_MANDATORY_INFORMATION = 96,
+  MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED = 97,
+  MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98,
+  INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED = 99,
+  CONDITIONAL_IE_ERROR = 100,
+  MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101,
+  PROTOCOL_ERROR_UNSPECIFIED = 111,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/SignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/SignalStrength.aidl
new file mode 100644
index 0000000..1c50190
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/SignalStrength.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable SignalStrength {
+  android.hardware.radio.network.GsmSignalStrength gsm;
+  android.hardware.radio.network.CdmaSignalStrength cdma;
+  android.hardware.radio.network.EvdoSignalStrength evdo;
+  android.hardware.radio.network.LteSignalStrength lte;
+  android.hardware.radio.network.TdscdmaSignalStrength tdscdma;
+  android.hardware.radio.network.WcdmaSignalStrength wcdma;
+  android.hardware.radio.network.NrSignalStrength nr;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/SignalThresholdInfo.aidl
new file mode 100644
index 0000000..744eed7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable SignalThresholdInfo {
+  int signalMeasurement;
+  int hysteresisMs;
+  int hysteresisDb;
+  int[] thresholds;
+  boolean isEnabled;
+  android.hardware.radio.AccessNetwork ran;
+  const int SIGNAL_MEASUREMENT_TYPE_RSSI = 1;
+  const int SIGNAL_MEASUREMENT_TYPE_RSCP = 2;
+  const int SIGNAL_MEASUREMENT_TYPE_RSRP = 3;
+  const int SIGNAL_MEASUREMENT_TYPE_RSRQ = 4;
+  const int SIGNAL_MEASUREMENT_TYPE_RSSNR = 5;
+  const int SIGNAL_MEASUREMENT_TYPE_SSRSRP = 6;
+  const int SIGNAL_MEASUREMENT_TYPE_SSRSRQ = 7;
+  const int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8;
+  const int SIGNAL_MEASUREMENT_TYPE_ECNO = 9;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/SuppSvcNotification.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/SuppSvcNotification.aidl
new file mode 100644
index 0000000..b62c71b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/SuppSvcNotification.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable SuppSvcNotification {
+  boolean isMT;
+  int code;
+  int index;
+  int type;
+  String number;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/TdscdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/TdscdmaSignalStrength.aidl
new file mode 100644
index 0000000..d74c950
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/TdscdmaSignalStrength.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable TdscdmaSignalStrength {
+  int signalStrength;
+  int bitErrorRate;
+  int rscp;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/UsageSetting.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/UsageSetting.aidl
new file mode 100644
index 0000000..3ca16b5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/UsageSetting.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum UsageSetting {
+  VOICE_CENTRIC = 1,
+  DATA_CENTRIC = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/UtranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/UtranBands.aidl
new file mode 100644
index 0000000..8be3da2
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/UtranBands.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum UtranBands {
+  BAND_1 = 1,
+  BAND_2 = 2,
+  BAND_3 = 3,
+  BAND_4 = 4,
+  BAND_5 = 5,
+  BAND_6 = 6,
+  BAND_7 = 7,
+  BAND_8 = 8,
+  BAND_9 = 9,
+  BAND_10 = 10,
+  BAND_11 = 11,
+  BAND_12 = 12,
+  BAND_13 = 13,
+  BAND_14 = 14,
+  BAND_19 = 19,
+  BAND_20 = 20,
+  BAND_21 = 21,
+  BAND_22 = 22,
+  BAND_25 = 25,
+  BAND_26 = 26,
+  BAND_A = 101,
+  BAND_B = 102,
+  BAND_C = 103,
+  BAND_D = 104,
+  BAND_E = 105,
+  BAND_F = 106,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/WcdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/WcdmaSignalStrength.aidl
new file mode 100644
index 0000000..9112527
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/2/android/hardware/radio/network/WcdmaSignalStrength.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable WcdmaSignalStrength {
+  int signalStrength;
+  int bitErrorRate;
+  int rscp;
+  int ecno;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
index 74c4e29..927f9ac 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
@@ -38,7 +38,7 @@
   int roamingIndicator;
   int systemIsInPrl;
   int defaultRoamingIndicator;
-  const int PRL_INDICATOR_NOT_REGISTERED = -1;
+  const int PRL_INDICATOR_NOT_REGISTERED = (-1);
   const int PRL_INDICATOR_NOT_IN_PRL = 0;
   const int PRL_INDICATOR_IN_PRL = 1;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
index 24ec26b..2a4db70 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
@@ -34,7 +34,7 @@
 package android.hardware.radio.network;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CdmaRoamingType {
-  HOME_NETWORK = 0,
-  AFFILIATED_ROAM = 1,
-  ANY_ROAM = 2,
+  HOME_NETWORK,
+  AFFILIATED_ROAM,
+  ANY_ROAM,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl
index 8986d71..5ce3b3e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl
@@ -34,7 +34,7 @@
 package android.hardware.radio.network;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CellConnectionStatus {
-  NONE = 0,
-  PRIMARY_SERVING = 1,
-  SECONDARY_SERVING = 2,
+  NONE,
+  PRIMARY_SERVING,
+  SECONDARY_SERVING,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl
index 209cf5e..6b022b6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl
@@ -34,6 +34,6 @@
 package android.hardware.radio.network;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum Domain {
-  CS = 1,
-  PS = 2,
+  CS = (1 << 0),
+  PS = (1 << 1),
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyMode.aidl
new file mode 100644
index 0000000..071e6b5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EmergencyMode {
+  EMERGENCY_WWAN = 1,
+  EMERGENCY_WLAN = 2,
+  EMERGENCY_CALLBACK = 3,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
new file mode 100644
index 0000000..2797aff
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable EmergencyNetworkScanTrigger {
+  android.hardware.radio.AccessNetwork[] accessNetwork;
+  android.hardware.radio.network.EmergencyScanType scanType;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl
new file mode 100644
index 0000000..7d99a53
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable EmergencyRegResult {
+  android.hardware.radio.AccessNetwork accessNetwork;
+  android.hardware.radio.network.RegState regState;
+  android.hardware.radio.network.Domain emcDomain;
+  boolean isVopsSupported;
+  boolean isEmcBearerSupported;
+  byte nwProvidedEmc;
+  byte nwProvidedEmf;
+  String mcc = "";
+  String mnc = "";
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyScanType.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyScanType.aidl
new file mode 100644
index 0000000..5e86c76
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyScanType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EmergencyScanType {
+  NO_PREFERENCE = 0,
+  LIMITED_SERVICE = 1,
+  FULL_SERVICE = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
index dfbf881..90e342a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
@@ -36,4 +36,13 @@
 parcelable EutranRegistrationInfo {
   android.hardware.radio.network.LteVopsInfo lteVopsInfo;
   android.hardware.radio.network.NrIndicators nrIndicators;
+  android.hardware.radio.network.EutranRegistrationInfo.AttachResultType lteAttachResultType;
+  int extraInfo;
+  const int EXTRA_CSFB_NOT_PREFERRED = (1 << 0);
+  const int EXTRA_SMS_ONLY = (1 << 1);
+  enum AttachResultType {
+    NONE,
+    EPS_ONLY,
+    COMBINED,
+  }
 }
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 2b70e45..382ddd8 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
@@ -41,6 +41,9 @@
   oneway void getCdmaRoamingPreference(in int serial);
   oneway void getCellInfoList(in int serial);
   oneway void getDataRegistrationState(in int serial);
+  /**
+   * @deprecated Deprecated starting from Android U.
+   */
   oneway void getImsRegistrationState(in int serial);
   oneway void getNetworkSelectionMode(in int serial);
   oneway void getOperator(in int serial);
@@ -70,4 +73,12 @@
   oneway void supplyNetworkDepersonalization(in int serial, in String netPin);
   oneway void setUsageSetting(in int serial, in android.hardware.radio.network.UsageSetting usageSetting);
   oneway void getUsageSetting(in int serial);
+  oneway void setEmergencyMode(int serial, in android.hardware.radio.network.EmergencyMode emcModeType);
+  oneway void triggerEmergencyNetworkScan(int serial, in android.hardware.radio.network.EmergencyNetworkScanTrigger request);
+  oneway void cancelEmergencyNetworkScan(int serial, boolean resetScan);
+  oneway void exitEmergencyMode(in int serial);
+  oneway void setNullCipherAndIntegrityEnabled(in int serial, in boolean enabled);
+  oneway void isNullCipherAndIntegrityEnabled(in int serial);
+  oneway void isN1ModeEnabled(in int serial);
+  oneway void setN1ModeEnabled(in int serial, boolean enable);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
index bd03c51..0f017ea 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -48,4 +48,5 @@
   oneway void restrictedStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.PhoneRestrictedState state);
   oneway void suppSvcNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.SuppSvcNotification suppSvc);
   oneway void voiceRadioTechChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioTechnology rat);
+  oneway void emergencyNetworkScanResult(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.EmergencyRegResult result);
 }
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 5f6c736..bfe8fa3 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
@@ -42,6 +42,9 @@
   oneway void getCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CdmaRoamingType type);
   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);
+  /**
+   * @deprecated Deprecated starting from Android U.
+   */
   oneway void getImsRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isRegistered, in android.hardware.radio.RadioTechnologyFamily ratFamily);
   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);
@@ -69,4 +72,12 @@
   oneway void supplyNetworkDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
   oneway void setUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void getUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.UsageSetting usageSetting);
+  oneway void setEmergencyModeResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.EmergencyRegResult regState);
+  oneway void triggerEmergencyNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void exitEmergencyModeResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void cancelEmergencyNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setNullCipherAndIntegrityEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void isNullCipherAndIntegrityEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
+  oneway void isN1ModeEnabledResponse(in android.hardware.radio.RadioResponseInfo info, boolean isEnabled);
+  oneway void setN1ModeEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl
index d9ed68e..00ba346 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl
@@ -35,12 +35,12 @@
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum IndicationFilter {
   NONE = 0,
-  ALL = -1,
-  SIGNAL_STRENGTH = 1,
-  FULL_NETWORK_STATE = 2,
-  DATA_CALL_DORMANCY_CHANGED = 4,
-  LINK_CAPACITY_ESTIMATE = 8,
-  PHYSICAL_CHANNEL_CONFIG = 16,
-  REGISTRATION_FAILURE = 32,
-  BARRING_INFO = 64,
+  ALL = (~0),
+  SIGNAL_STRENGTH = (1 << 0),
+  FULL_NETWORK_STATE = (1 << 1),
+  DATA_CALL_DORMANCY_CHANGED = (1 << 2),
+  LINK_CAPACITY_ESTIMATE = (1 << 3),
+  PHYSICAL_CHANNEL_CONFIG = (1 << 4),
+  REGISTRATION_FAILURE = (1 << 5),
+  BARRING_INFO = (1 << 6),
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
index 98bbe6b..7d6ab82 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
@@ -42,4 +42,5 @@
   int csiSinr;
   int csiCqiTableIndex;
   byte[] csiCqiReport;
+  int timingAdvance = 0x7FFFFFFF;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl
index 41555f9..4e3e39e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl
@@ -34,9 +34,9 @@
 package android.hardware.radio.network;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum PhoneRestrictedState {
-  NONE = 0,
-  CS_EMERGENCY = 1,
-  CS_NORMAL = 2,
-  CS_ALL = 4,
-  PS_ALL = 16,
+  NONE = 0x00,
+  CS_EMERGENCY = 0x01,
+  CS_NORMAL = 0x02,
+  CS_ALL = 0x04,
+  PS_ALL = 0x10,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl
index e9a9f60..74696fb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl
@@ -34,23 +34,23 @@
 package android.hardware.radio.network;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioBandMode {
-  BAND_MODE_UNSPECIFIED = 0,
-  BAND_MODE_EURO = 1,
-  BAND_MODE_USA = 2,
-  BAND_MODE_JPN = 3,
-  BAND_MODE_AUS = 4,
-  BAND_MODE_AUS_2 = 5,
-  BAND_MODE_CELL_800 = 6,
-  BAND_MODE_PCS = 7,
-  BAND_MODE_JTACS = 8,
-  BAND_MODE_KOREA_PCS = 9,
-  BAND_MODE_5_450M = 10,
-  BAND_MODE_IMT2000 = 11,
-  BAND_MODE_7_700M_2 = 12,
-  BAND_MODE_8_1800M = 13,
-  BAND_MODE_9_900M = 14,
-  BAND_MODE_10_800M_2 = 15,
-  BAND_MODE_EURO_PAMR_400M = 16,
-  BAND_MODE_AWS = 17,
-  BAND_MODE_USA_2500M = 18,
+  BAND_MODE_UNSPECIFIED,
+  BAND_MODE_EURO,
+  BAND_MODE_USA,
+  BAND_MODE_JPN,
+  BAND_MODE_AUS,
+  BAND_MODE_AUS_2,
+  BAND_MODE_CELL_800,
+  BAND_MODE_PCS,
+  BAND_MODE_JTACS,
+  BAND_MODE_KOREA_PCS,
+  BAND_MODE_5_450M,
+  BAND_MODE_IMT2000,
+  BAND_MODE_7_700M_2,
+  BAND_MODE_8_1800M,
+  BAND_MODE_9_900M,
+  BAND_MODE_10_800M_2,
+  BAND_MODE_EURO_PAMR_400M,
+  BAND_MODE_AWS,
+  BAND_MODE_USA_2500M,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl
index e6e7999..711c9ac 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl
@@ -44,4 +44,5 @@
   NOT_REG_MT_SEARCHING_OP_EM = 12,
   REG_DENIED_EM = 13,
   UNKNOWN_EM = 14,
+  REG_EM = 20,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
index e2cd44c..8acf8ab 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
@@ -56,7 +56,7 @@
   CONGESTION = 22,
   GSM_AUTHENTICATION_UNACCEPTABLE = 23,
   NOT_AUTHORIZED_FOR_THIS_CSG = 25,
-  SMS_PROVIDED_BY_GPRS_IN_ROUTING_AREA = 26,
+  SMS_PROVIDED_BY_GPRS_IN_ROUTING_AREA,
   SERVICE_OPTION_NOT_SUPPORTED = 32,
   SERVICE_OPTION_NOT_SUBSCRIBED = 33,
   SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER = 34,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
index 040932c..744eed7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -48,4 +48,5 @@
   const int SIGNAL_MEASUREMENT_TYPE_SSRSRP = 6;
   const int SIGNAL_MEASUREMENT_TYPE_SSRSRQ = 7;
   const int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8;
+  const int SIGNAL_MEASUREMENT_TYPE_ECNO = 9;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/1/.hash b/radio/aidl/aidl_api/android.hardware.radio.sap/1/.hash
new file mode 100644
index 0000000..876503f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/1/.hash
@@ -0,0 +1 @@
+dacee485b56bd1e1e5b5bcdedbd20e71ac24444b
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/ISap.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/ISap.aidl
new file mode 100644
index 0000000..37391e9
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/ISap.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@VintfStability
+interface ISap {
+  oneway void apduReq(in int serial, in android.hardware.radio.sap.SapApduType type, in byte[] command);
+  oneway void connectReq(in int serial, in int maxMsgSizeBytes);
+  oneway void disconnectReq(in int serial);
+  oneway void powerReq(in int serial, in boolean powerOn);
+  oneway void resetSimReq(in int serial);
+  oneway void setCallback(in android.hardware.radio.sap.ISapCallback sapCallback);
+  oneway void setTransferProtocolReq(in int serial, in android.hardware.radio.sap.SapTransferProtocol transferProtocol);
+  oneway void transferAtrReq(in int serial);
+  oneway void transferCardReaderStatusReq(in int serial);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/ISapCallback.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/ISapCallback.aidl
new file mode 100644
index 0000000..d507709
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/ISapCallback.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@VintfStability
+interface ISapCallback {
+  oneway void apduResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode, in byte[] apduRsp);
+  oneway void connectResponse(in int serial, in android.hardware.radio.sap.SapConnectRsp sapConnectRsp, in int maxMsgSizeBytes);
+  oneway void disconnectIndication(in int serial, in android.hardware.radio.sap.SapDisconnectType disconnectType);
+  oneway void disconnectResponse(in int serial);
+  oneway void errorResponse(in int serial);
+  oneway void powerResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode);
+  oneway void resetSimResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode);
+  oneway void statusIndication(in int serial, in android.hardware.radio.sap.SapStatus status);
+  oneway void transferAtrResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode, in byte[] atr);
+  oneway void transferCardReaderStatusResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode, in int cardReaderStatus);
+  oneway void transferProtocolResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapApduType.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapApduType.aidl
new file mode 100644
index 0000000..6cef92b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapApduType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapApduType {
+  APDU,
+  APDU7816,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapConnectRsp.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapConnectRsp.aidl
new file mode 100644
index 0000000..841dfe3
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapConnectRsp.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapConnectRsp {
+  SUCCESS,
+  CONNECT_FAILURE,
+  MSG_SIZE_TOO_LARGE,
+  MSG_SIZE_TOO_SMALL,
+  CONNECT_OK_CALL_ONGOING,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapDisconnectType.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapDisconnectType.aidl
new file mode 100644
index 0000000..dace1e1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapDisconnectType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapDisconnectType {
+  GRACEFUL,
+  IMMEDIATE,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapResultCode.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapResultCode.aidl
new file mode 100644
index 0000000..a2a6df0
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapResultCode.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+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/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapStatus.aidl
new file mode 100644
index 0000000..6988c99
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapStatus {
+  UNKNOWN_ERROR,
+  CARD_RESET,
+  CARD_NOT_ACCESSIBLE,
+  CARD_REMOVED,
+  CARD_INSERTED,
+  RECOVERED,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapTransferProtocol.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapTransferProtocol.aidl
new file mode 100644
index 0000000..3c6852e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/1/android/hardware/radio/sap/SapTransferProtocol.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapTransferProtocol {
+  T0,
+  T1,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/ISap.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/ISap.aidl
new file mode 100644
index 0000000..37391e9
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/ISap.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@VintfStability
+interface ISap {
+  oneway void apduReq(in int serial, in android.hardware.radio.sap.SapApduType type, in byte[] command);
+  oneway void connectReq(in int serial, in int maxMsgSizeBytes);
+  oneway void disconnectReq(in int serial);
+  oneway void powerReq(in int serial, in boolean powerOn);
+  oneway void resetSimReq(in int serial);
+  oneway void setCallback(in android.hardware.radio.sap.ISapCallback sapCallback);
+  oneway void setTransferProtocolReq(in int serial, in android.hardware.radio.sap.SapTransferProtocol transferProtocol);
+  oneway void transferAtrReq(in int serial);
+  oneway void transferCardReaderStatusReq(in int serial);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/ISapCallback.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/ISapCallback.aidl
new file mode 100644
index 0000000..d507709
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/ISapCallback.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@VintfStability
+interface ISapCallback {
+  oneway void apduResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode, in byte[] apduRsp);
+  oneway void connectResponse(in int serial, in android.hardware.radio.sap.SapConnectRsp sapConnectRsp, in int maxMsgSizeBytes);
+  oneway void disconnectIndication(in int serial, in android.hardware.radio.sap.SapDisconnectType disconnectType);
+  oneway void disconnectResponse(in int serial);
+  oneway void errorResponse(in int serial);
+  oneway void powerResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode);
+  oneway void resetSimResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode);
+  oneway void statusIndication(in int serial, in android.hardware.radio.sap.SapStatus status);
+  oneway void transferAtrResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode, in byte[] atr);
+  oneway void transferCardReaderStatusResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode, in int cardReaderStatus);
+  oneway void transferProtocolResponse(in int serial, in android.hardware.radio.sap.SapResultCode resultCode);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapApduType.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapApduType.aidl
new file mode 100644
index 0000000..6cef92b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapApduType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapApduType {
+  APDU,
+  APDU7816,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapConnectRsp.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapConnectRsp.aidl
new file mode 100644
index 0000000..841dfe3
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapConnectRsp.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapConnectRsp {
+  SUCCESS,
+  CONNECT_FAILURE,
+  MSG_SIZE_TOO_LARGE,
+  MSG_SIZE_TOO_SMALL,
+  CONNECT_OK_CALL_ONGOING,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapDisconnectType.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapDisconnectType.aidl
new file mode 100644
index 0000000..dace1e1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapDisconnectType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapDisconnectType {
+  GRACEFUL,
+  IMMEDIATE,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapResultCode.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapResultCode.aidl
new file mode 100644
index 0000000..a2a6df0
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapResultCode.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+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/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapStatus.aidl
new file mode 100644
index 0000000..6988c99
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapStatus {
+  UNKNOWN_ERROR,
+  CARD_RESET,
+  CARD_NOT_ACCESSIBLE,
+  CARD_REMOVED,
+  CARD_INSERTED,
+  RECOVERED,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapTransferProtocol.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapTransferProtocol.aidl
new file mode 100644
index 0000000..3c6852e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapTransferProtocol.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.sap;
+@Backing(type="int") @VintfStability
+enum SapTransferProtocol {
+  T0,
+  T1,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/.hash b/radio/aidl/aidl_api/android.hardware.radio.sim/2/.hash
new file mode 100644
index 0000000..54ba274
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/.hash
@@ -0,0 +1 @@
+4f348cc7aca716cc41c09ea95895c4b261231035
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/AppStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/AppStatus.aidl
new file mode 100644
index 0000000..8a41fb9
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/AppStatus.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable AppStatus {
+  int appType;
+  int appState;
+  android.hardware.radio.sim.PersoSubstate persoSubstate;
+  String aidPtr;
+  String appLabelPtr;
+  boolean pin1Replaced;
+  android.hardware.radio.sim.PinState pin1;
+  android.hardware.radio.sim.PinState pin2;
+  const int APP_STATE_UNKNOWN = 0;
+  const int APP_STATE_DETECTED = 1;
+  const int APP_STATE_PIN = 2;
+  const int APP_STATE_PUK = 3;
+  const int APP_STATE_SUBSCRIPTION_PERSO = 4;
+  const int APP_STATE_READY = 5;
+  const int APP_TYPE_UNKNOWN = 0;
+  const int APP_TYPE_SIM = 1;
+  const int APP_TYPE_USIM = 2;
+  const int APP_TYPE_RUIM = 3;
+  const int APP_TYPE_CSIM = 4;
+  const int APP_TYPE_ISIM = 5;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CardPowerState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CardPowerState.aidl
new file mode 100644
index 0000000..6bc3919
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CardPowerState.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.sim;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum CardPowerState {
+  POWER_DOWN,
+  POWER_UP,
+  POWER_UP_PASS_THROUGH,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CardStatus.aidl
new file mode 100644
index 0000000..46cb7be
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CardStatus.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable CardStatus {
+  int cardState;
+  android.hardware.radio.sim.PinState universalPinState;
+  int gsmUmtsSubscriptionAppIndex;
+  int cdmaSubscriptionAppIndex;
+  int imsSubscriptionAppIndex;
+  android.hardware.radio.sim.AppStatus[] applications;
+  String atr;
+  String iccid;
+  String eid;
+  android.hardware.radio.config.SlotPortMapping slotMap;
+  android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode = android.hardware.radio.config.MultipleEnabledProfilesMode.NONE;
+  const int STATE_ABSENT = 0;
+  const int STATE_PRESENT = 1;
+  const int STATE_ERROR = 2;
+  const int STATE_RESTRICTED = 3;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/Carrier.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/Carrier.aidl
new file mode 100644
index 0000000..cc56888
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/Carrier.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable Carrier {
+  String mcc;
+  String mnc;
+  int matchType;
+  String matchData;
+  const int MATCH_TYPE_ALL = 0;
+  const int MATCH_TYPE_SPN = 1;
+  const int MATCH_TYPE_IMSI_PREFIX = 2;
+  const int MATCH_TYPE_GID1 = 3;
+  const int MATCH_TYPE_GID2 = 4;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CarrierRestrictions.aidl
new file mode 100644
index 0000000..3700de3
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable CarrierRestrictions {
+  android.hardware.radio.sim.Carrier[] allowedCarriers;
+  android.hardware.radio.sim.Carrier[] excludedCarriers;
+  boolean allowedCarriersPrioritized;
+  android.hardware.radio.sim.CarrierRestrictions.CarrierRestrictionStatus status;
+  @Backing(type="int") @VintfStability
+  enum CarrierRestrictionStatus {
+    UNKNOWN = 0,
+    NOT_RESTRICTED = 1,
+    RESTRICTED = 2,
+  }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CdmaSubscriptionSource.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
new file mode 100644
index 0000000..080aa5e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.sim;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum CdmaSubscriptionSource {
+  RUIM_SIM,
+  NV,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IRadioSim.aidl
new file mode 100644
index 0000000..901b251
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IRadioSim.aidl
@@ -0,0 +1,77 @@
+/*
+ * 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.sim;
+@VintfStability
+interface IRadioSim {
+  oneway void areUiccApplicationsEnabled(in int serial);
+  oneway void changeIccPin2ForApp(in int serial, in String oldPin2, in String newPin2, in String aid);
+  oneway void changeIccPinForApp(in int serial, in String oldPin, in String newPin, in String aid);
+  oneway void enableUiccApplications(in int serial, in boolean enable);
+  oneway void getAllowedCarriers(in int serial);
+  oneway void getCdmaSubscription(in int serial);
+  oneway void getCdmaSubscriptionSource(in int serial);
+  oneway void getFacilityLockForApp(in int serial, in String facility, in String password, in int serviceClass, in String appId);
+  oneway void getIccCardStatus(in int serial);
+  oneway void getImsiForApp(in int serial, in String aid);
+  oneway void getSimPhonebookCapacity(in int serial);
+  oneway void getSimPhonebookRecords(in int serial);
+  /**
+   * @deprecated use iccCloseLogicalChannelWithSessionInfo instead.
+   */
+  oneway void iccCloseLogicalChannel(in int serial, in int channelId);
+  oneway void iccIoForApp(in int serial, in android.hardware.radio.sim.IccIo iccIo);
+  oneway void iccOpenLogicalChannel(in int serial, in String aid, in int p2);
+  oneway void iccTransmitApduBasicChannel(in int serial, in android.hardware.radio.sim.SimApdu message);
+  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 responseAcknowledgement();
+  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 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);
+  oneway void setFacilityLockForApp(in int serial, in String facility, in boolean lockState, in String password, in int serviceClass, in String appId);
+  oneway void setResponseFunctions(in android.hardware.radio.sim.IRadioSimResponse radioSimResponse, in android.hardware.radio.sim.IRadioSimIndication radioSimIndication);
+  oneway void setSimCardPower(in int serial, in android.hardware.radio.sim.CardPowerState powerUp);
+  oneway void setUiccSubscription(in int serial, in android.hardware.radio.sim.SelectUiccSub uiccSub);
+  oneway void supplyIccPin2ForApp(in int serial, in String pin2, in String aid);
+  oneway void supplyIccPinForApp(in int serial, in String pin, in String aid);
+  oneway void supplyIccPuk2ForApp(in int serial, in String puk2, in String pin2, in String aid);
+  oneway void supplyIccPukForApp(in int serial, in String puk, in String pin, in String aid);
+  oneway void supplySimDepersonalization(in int serial, in android.hardware.radio.sim.PersoSubstate persoType, in String controlKey);
+  oneway void updateSimPhonebookRecords(in int serial, in android.hardware.radio.sim.PhonebookRecordInfo recordInfo);
+  oneway void iccCloseLogicalChannelWithSessionInfo(in int serial, in android.hardware.radio.sim.SessionInfo sessionInfo);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IRadioSimIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IRadioSimIndication.aidl
new file mode 100644
index 0000000..d4371b8
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IRadioSimIndication.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.sim;
+@VintfStability
+interface IRadioSimIndication {
+  oneway void carrierInfoForImsiEncryption(in android.hardware.radio.RadioIndicationType info);
+  oneway void cdmaSubscriptionSourceChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.sim.CdmaSubscriptionSource cdmaSource);
+  oneway void simPhonebookChanged(in android.hardware.radio.RadioIndicationType type);
+  oneway void simPhonebookRecordsReceived(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.sim.PbReceivedStatus status, in android.hardware.radio.sim.PhonebookRecordInfo[] records);
+  oneway void simRefresh(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.sim.SimRefreshResult refreshResult);
+  oneway void simStatusChanged(in android.hardware.radio.RadioIndicationType type);
+  oneway void stkEventNotify(in android.hardware.radio.RadioIndicationType type, in String cmd);
+  oneway void stkProactiveCommand(in android.hardware.radio.RadioIndicationType type, in String cmd);
+  oneway void stkSessionEnd(in android.hardware.radio.RadioIndicationType type);
+  oneway void subscriptionStatusChanged(in android.hardware.radio.RadioIndicationType type, in boolean activate);
+  oneway void uiccApplicationsEnablementChanged(in android.hardware.radio.RadioIndicationType type, in boolean enabled);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IRadioSimResponse.aidl
new file mode 100644
index 0000000..d7c2100
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -0,0 +1,76 @@
+/*
+ * 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.sim;
+@VintfStability
+interface IRadioSimResponse {
+  oneway void acknowledgeRequest(in int serial);
+  oneway void areUiccApplicationsEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enabled);
+  oneway void changeIccPin2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
+  oneway void changeIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
+  oneway void enableUiccApplicationsResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.CarrierRestrictions carriers, in android.hardware.radio.sim.SimLockMultiSimPolicy multiSimPolicy);
+  oneway void getCdmaSubscriptionResponse(in android.hardware.radio.RadioResponseInfo info, in String mdn, in String hSid, in String hNid, in String min, in String prl);
+  oneway void getCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.CdmaSubscriptionSource source);
+  oneway void getFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int response);
+  oneway void getIccCardStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.CardStatus cardStatus);
+  oneway void getImsiForAppResponse(in android.hardware.radio.RadioResponseInfo info, in String imsi);
+  oneway void getSimPhonebookCapacityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.PhonebookCapacity capacity);
+  oneway void getSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated use iccCloseLogicalChannelWithSessionInfoResponse instead.
+   */
+  oneway void iccCloseLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void iccIoForAppResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult iccIo);
+  oneway void iccOpenLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in int channelId, in byte[] selectResponse);
+  oneway void iccTransmitApduBasicChannelResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult result);
+  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 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);
+  oneway void setAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setCarrierInfoForImsiEncryptionResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int retry);
+  oneway void setSimCardPowerResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setUiccSubscriptionResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void supplyIccPin2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
+  oneway void supplyIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
+  oneway void supplyIccPuk2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
+  oneway void supplyIccPukForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
+  oneway void supplySimDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.PersoSubstate persoType, in int remainingRetries);
+  oneway void updateSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info, in int updatedRecordIndex);
+  oneway void iccCloseLogicalChannelWithSessionInfoResponse(in android.hardware.radio.RadioResponseInfo info);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IccIo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IccIo.aidl
new file mode 100644
index 0000000..5a312dc
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IccIo.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable IccIo {
+  int command;
+  int fileId;
+  String path;
+  int p1;
+  int p2;
+  int p3;
+  String data;
+  String pin2;
+  String aid;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IccIoResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IccIoResult.aidl
new file mode 100644
index 0000000..6c6bde2
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/IccIoResult.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable IccIoResult {
+  int sw1;
+  int sw2;
+  String simResponse;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/ImsiEncryptionInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
new file mode 100644
index 0000000..05e71cd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImsiEncryptionInfo {
+  String mcc;
+  String mnc;
+  byte[] carrierKey;
+  String keyIdentifier;
+  long expirationTime;
+  byte keyType;
+  const byte PUBLIC_KEY_TYPE_EPDG = 1;
+  const byte PUBLIC_KEY_TYPE_WLAN = 2;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PbReceivedStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PbReceivedStatus.aidl
new file mode 100644
index 0000000..5e96fc6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PbReceivedStatus.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.sim;
+@Backing(type="byte") @JavaDerive(toString=true) @VintfStability
+enum PbReceivedStatus {
+  PB_RECEIVED_OK = 1,
+  PB_RECEIVED_ERROR = 2,
+  PB_RECEIVED_ABORT = 3,
+  PB_RECEIVED_FINAL = 4,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PersoSubstate.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PersoSubstate.aidl
new file mode 100644
index 0000000..dc1d960
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PersoSubstate.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.sim;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum PersoSubstate {
+  UNKNOWN,
+  IN_PROGRESS,
+  READY,
+  SIM_NETWORK,
+  SIM_NETWORK_SUBSET,
+  SIM_CORPORATE,
+  SIM_SERVICE_PROVIDER,
+  SIM_SIM,
+  SIM_NETWORK_PUK,
+  SIM_NETWORK_SUBSET_PUK,
+  SIM_CORPORATE_PUK,
+  SIM_SERVICE_PROVIDER_PUK,
+  SIM_SIM_PUK,
+  RUIM_NETWORK1,
+  RUIM_NETWORK2,
+  RUIM_HRPD,
+  RUIM_CORPORATE,
+  RUIM_SERVICE_PROVIDER,
+  RUIM_RUIM,
+  RUIM_NETWORK1_PUK,
+  RUIM_NETWORK2_PUK,
+  RUIM_HRPD_PUK,
+  RUIM_CORPORATE_PUK,
+  RUIM_SERVICE_PROVIDER_PUK,
+  RUIM_RUIM_PUK,
+  SIM_SPN,
+  SIM_SPN_PUK,
+  SIM_SP_EHPLMN,
+  SIM_SP_EHPLMN_PUK,
+  SIM_ICCID,
+  SIM_ICCID_PUK,
+  SIM_IMPI,
+  SIM_IMPI_PUK,
+  SIM_NS_SP,
+  SIM_NS_SP_PUK,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PhonebookCapacity.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PhonebookCapacity.aidl
new file mode 100644
index 0000000..7531c96
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PhonebookCapacity.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable PhonebookCapacity {
+  int maxAdnRecords;
+  int usedAdnRecords;
+  int maxEmailRecords;
+  int usedEmailRecords;
+  int maxAdditionalNumberRecords;
+  int usedAdditionalNumberRecords;
+  int maxNameLen;
+  int maxNumberLen;
+  int maxEmailLen;
+  int maxAdditionalNumberLen;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PhonebookRecordInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PhonebookRecordInfo.aidl
new file mode 100644
index 0000000..2e96a4b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PhonebookRecordInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable PhonebookRecordInfo {
+  int recordId;
+  String name;
+  String number;
+  String[] emails;
+  String[] additionalNumbers;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PinState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PinState.aidl
new file mode 100644
index 0000000..663ea73
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/PinState.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.sim;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum PinState {
+  UNKNOWN,
+  ENABLED_NOT_VERIFIED,
+  ENABLED_VERIFIED,
+  DISABLED,
+  ENABLED_BLOCKED,
+  ENABLED_PERM_BLOCKED,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SelectUiccSub.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SelectUiccSub.aidl
new file mode 100644
index 0000000..02121e6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SelectUiccSub.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable SelectUiccSub {
+  int slot;
+  int appIndex;
+  int subType;
+  int actStatus;
+  const int SUBSCRIPTION_TYPE_1 = 0;
+  const int SUBSCRIPTION_TYPE_2 = 1;
+  const int SUBSCRIPTION_TYPE_3 = 2;
+  const int ACT_STATUS_DEACTIVATE = 0;
+  const int ACT_STATUS_ACTIVATE = 1;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SessionInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SessionInfo.aidl
new file mode 100644
index 0000000..1329141
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SessionInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable SessionInfo {
+  int sessionId;
+  boolean isEs10 = false;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SimApdu.aidl
new file mode 100644
index 0000000..c391e5a
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SimApdu.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable SimApdu {
+  int sessionId;
+  int cla;
+  int instruction;
+  int p1;
+  int p2;
+  int p3;
+  String data;
+  boolean isEs10 = false;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
new file mode 100644
index 0000000..d59fcab
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.sim;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum SimLockMultiSimPolicy {
+  NO_MULTISIM_POLICY,
+  ONE_VALID_SIM_MUST_BE_PRESENT,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SimRefreshResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SimRefreshResult.aidl
new file mode 100644
index 0000000..69bf476
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/2/android/hardware/radio/sim/SimRefreshResult.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable SimRefreshResult {
+  int type;
+  int efId;
+  String aid;
+  const int TYPE_SIM_FILE_UPDATE = 0;
+  const int TYPE_SIM_INIT = 1;
+  const int TYPE_SIM_RESET = 2;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl
index 05bc13a..6bc3919 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl
@@ -34,7 +34,7 @@
 package android.hardware.radio.sim;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CardPowerState {
-  POWER_DOWN = 0,
-  POWER_UP = 1,
-  POWER_UP_PASS_THROUGH = 2,
+  POWER_DOWN,
+  POWER_UP,
+  POWER_UP_PASS_THROUGH,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
index 9000d43..46cb7be 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
@@ -44,6 +44,7 @@
   String iccid;
   String eid;
   android.hardware.radio.config.SlotPortMapping slotMap;
+  android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode = android.hardware.radio.config.MultipleEnabledProfilesMode.NONE;
   const int STATE_ABSENT = 0;
   const int STATE_PRESENT = 1;
   const int STATE_ERROR = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
index 944f1ca..3700de3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -37,4 +37,11 @@
   android.hardware.radio.sim.Carrier[] allowedCarriers;
   android.hardware.radio.sim.Carrier[] excludedCarriers;
   boolean allowedCarriersPrioritized;
+  android.hardware.radio.sim.CarrierRestrictions.CarrierRestrictionStatus status;
+  @Backing(type="int") @VintfStability
+  enum CarrierRestrictionStatus {
+    UNKNOWN = 0,
+    NOT_RESTRICTED = 1,
+    RESTRICTED = 2,
+  }
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
index 13469f3..080aa5e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
@@ -34,6 +34,6 @@
 package android.hardware.radio.sim;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CdmaSubscriptionSource {
-  RUIM_SIM = 0,
-  NV = 1,
+  RUIM_SIM,
+  NV,
 }
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 85a0c71..901b251 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
@@ -46,6 +46,9 @@
   oneway void getImsiForApp(in int serial, in String aid);
   oneway void getSimPhonebookCapacity(in int serial);
   oneway void getSimPhonebookRecords(in int serial);
+  /**
+   * @deprecated use iccCloseLogicalChannelWithSessionInfo instead.
+   */
   oneway void iccCloseLogicalChannel(in int serial, in int channelId);
   oneway void iccIoForApp(in int serial, in android.hardware.radio.sim.IccIo iccIo);
   oneway void iccOpenLogicalChannel(in int serial, in String aid, in int p2);
@@ -70,4 +73,5 @@
   oneway void supplyIccPukForApp(in int serial, in String puk, in String pin, in String aid);
   oneway void supplySimDepersonalization(in int serial, in android.hardware.radio.sim.PersoSubstate persoType, in String controlKey);
   oneway void updateSimPhonebookRecords(in int serial, in android.hardware.radio.sim.PhonebookRecordInfo recordInfo);
+  oneway void iccCloseLogicalChannelWithSessionInfo(in int serial, in android.hardware.radio.sim.SessionInfo sessionInfo);
 }
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 8e68e30..d7c2100 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
@@ -47,6 +47,9 @@
   oneway void getImsiForAppResponse(in android.hardware.radio.RadioResponseInfo info, in String imsi);
   oneway void getSimPhonebookCapacityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.PhonebookCapacity capacity);
   oneway void getSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated use iccCloseLogicalChannelWithSessionInfoResponse instead.
+   */
   oneway void iccCloseLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void iccIoForAppResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult iccIo);
   oneway void iccOpenLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in int channelId, in byte[] selectResponse);
@@ -69,4 +72,5 @@
   oneway void supplyIccPukForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
   oneway void supplySimDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.PersoSubstate persoType, in int remainingRetries);
   oneway void updateSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info, in int updatedRecordIndex);
+  oneway void iccCloseLogicalChannelWithSessionInfoResponse(in android.hardware.radio.RadioResponseInfo info);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl
index e33769e..dc1d960 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl
@@ -34,39 +34,39 @@
 package android.hardware.radio.sim;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum PersoSubstate {
-  UNKNOWN = 0,
-  IN_PROGRESS = 1,
-  READY = 2,
-  SIM_NETWORK = 3,
-  SIM_NETWORK_SUBSET = 4,
-  SIM_CORPORATE = 5,
-  SIM_SERVICE_PROVIDER = 6,
-  SIM_SIM = 7,
-  SIM_NETWORK_PUK = 8,
-  SIM_NETWORK_SUBSET_PUK = 9,
-  SIM_CORPORATE_PUK = 10,
-  SIM_SERVICE_PROVIDER_PUK = 11,
-  SIM_SIM_PUK = 12,
-  RUIM_NETWORK1 = 13,
-  RUIM_NETWORK2 = 14,
-  RUIM_HRPD = 15,
-  RUIM_CORPORATE = 16,
-  RUIM_SERVICE_PROVIDER = 17,
-  RUIM_RUIM = 18,
-  RUIM_NETWORK1_PUK = 19,
-  RUIM_NETWORK2_PUK = 20,
-  RUIM_HRPD_PUK = 21,
-  RUIM_CORPORATE_PUK = 22,
-  RUIM_SERVICE_PROVIDER_PUK = 23,
-  RUIM_RUIM_PUK = 24,
-  SIM_SPN = 25,
-  SIM_SPN_PUK = 26,
-  SIM_SP_EHPLMN = 27,
-  SIM_SP_EHPLMN_PUK = 28,
-  SIM_ICCID = 29,
-  SIM_ICCID_PUK = 30,
-  SIM_IMPI = 31,
-  SIM_IMPI_PUK = 32,
-  SIM_NS_SP = 33,
-  SIM_NS_SP_PUK = 34,
+  UNKNOWN,
+  IN_PROGRESS,
+  READY,
+  SIM_NETWORK,
+  SIM_NETWORK_SUBSET,
+  SIM_CORPORATE,
+  SIM_SERVICE_PROVIDER,
+  SIM_SIM,
+  SIM_NETWORK_PUK,
+  SIM_NETWORK_SUBSET_PUK,
+  SIM_CORPORATE_PUK,
+  SIM_SERVICE_PROVIDER_PUK,
+  SIM_SIM_PUK,
+  RUIM_NETWORK1,
+  RUIM_NETWORK2,
+  RUIM_HRPD,
+  RUIM_CORPORATE,
+  RUIM_SERVICE_PROVIDER,
+  RUIM_RUIM,
+  RUIM_NETWORK1_PUK,
+  RUIM_NETWORK2_PUK,
+  RUIM_HRPD_PUK,
+  RUIM_CORPORATE_PUK,
+  RUIM_SERVICE_PROVIDER_PUK,
+  RUIM_RUIM_PUK,
+  SIM_SPN,
+  SIM_SPN_PUK,
+  SIM_SP_EHPLMN,
+  SIM_SP_EHPLMN_PUK,
+  SIM_ICCID,
+  SIM_ICCID_PUK,
+  SIM_IMPI,
+  SIM_IMPI_PUK,
+  SIM_NS_SP,
+  SIM_NS_SP_PUK,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl
index 5cdc6d1..663ea73 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl
@@ -34,10 +34,10 @@
 package android.hardware.radio.sim;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum PinState {
-  UNKNOWN = 0,
-  ENABLED_NOT_VERIFIED = 1,
-  ENABLED_VERIFIED = 2,
-  DISABLED = 3,
-  ENABLED_BLOCKED = 4,
-  ENABLED_PERM_BLOCKED = 5,
+  UNKNOWN,
+  ENABLED_NOT_VERIFIED,
+  ENABLED_VERIFIED,
+  DISABLED,
+  ENABLED_BLOCKED,
+  ENABLED_PERM_BLOCKED,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.aidl
new file mode 100644
index 0000000..1329141
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable SessionInfo {
+  int sessionId;
+  boolean isEs10 = false;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
index 2201345..c391e5a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
@@ -41,4 +41,5 @@
   int p2;
   int p3;
   String data;
+  boolean isEs10 = false;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
index 4ded3e9..d59fcab 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
@@ -34,6 +34,6 @@
 package android.hardware.radio.sim;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum SimLockMultiSimPolicy {
-  NO_MULTISIM_POLICY = 0,
-  ONE_VALID_SIM_MUST_BE_PRESENT = 1,
+  NO_MULTISIM_POLICY,
+  ONE_VALID_SIM_MUST_BE_PRESENT,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/.hash b/radio/aidl/aidl_api/android.hardware.radio.voice/2/.hash
new file mode 100644
index 0000000..eef445d
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/.hash
@@ -0,0 +1 @@
+8c5e0d53dc67b5ed221b2da0570a17684d973a20
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/AudioQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/AudioQuality.aidl
new file mode 100644
index 0000000..1ab2902
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/AudioQuality.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.voice;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum AudioQuality {
+  UNSPECIFIED,
+  AMR,
+  AMR_WB,
+  GSM_EFR,
+  GSM_FR,
+  GSM_HR,
+  EVRC,
+  EVRC_B,
+  EVRC_WB,
+  EVRC_NW,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/Call.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/Call.aidl
new file mode 100644
index 0000000..10d2ee7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/Call.aidl
@@ -0,0 +1,62 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable Call {
+  int state;
+  int index;
+  int toa;
+  boolean isMpty;
+  boolean isMT;
+  byte als;
+  boolean isVoice;
+  boolean isVoicePrivacy;
+  String number;
+  int numberPresentation;
+  String name;
+  int namePresentation;
+  android.hardware.radio.voice.UusInfo[] uusInfo;
+  android.hardware.radio.voice.AudioQuality audioQuality;
+  String forwardedNumber;
+  const int PRESENTATION_ALLOWED = 0;
+  const int PRESENTATION_RESTRICTED = 1;
+  const int PRESENTATION_UNKNOWN = 2;
+  const int PRESENTATION_PAYPHONE = 3;
+  const int STATE_ACTIVE = 0;
+  const int STATE_HOLDING = 1;
+  const int STATE_DIALING = 2;
+  const int STATE_ALERTING = 3;
+  const int STATE_INCOMING = 4;
+  const int STATE_WAITING = 5;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CallForwardInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CallForwardInfo.aidl
new file mode 100644
index 0000000..8e7aaab
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CallForwardInfo.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CallForwardInfo {
+  int status;
+  int reason;
+  int serviceClass;
+  int toa;
+  String number;
+  int timeSeconds;
+  const int STATUS_DISABLE = 0;
+  const int STATUS_ENABLE = 1;
+  const int STATUS_INTERROGATE = 2;
+  const int STATUS_REGISTRATION = 3;
+  const int STATUS_ERASURE = 4;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaCallWaiting.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaCallWaiting.aidl
new file mode 100644
index 0000000..310f9a0
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaCallWaiting.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaCallWaiting {
+  String number;
+  int numberPresentation;
+  String name;
+  android.hardware.radio.voice.CdmaSignalInfoRecord signalInfoRecord;
+  int numberType;
+  int numberPlan;
+  const int NUMBER_PLAN_UNKNOWN = 0;
+  const int NUMBER_PLAN_ISDN = 1;
+  const int NUMBER_PLAN_DATA = 3;
+  const int NUMBER_PLAN_TELEX = 4;
+  const int NUMBER_PLAN_NATIONAL = 8;
+  const int NUMBER_PLAN_PRIVATE = 9;
+  const int NUMBER_PRESENTATION_ALLOWED = 0;
+  const int NUMBER_PRESENTATION_RESTRICTED = 1;
+  const int NUMBER_PRESENTATION_UNKNOWN = 2;
+  const int NUMBER_TYPE_UNKNOWN = 0;
+  const int NUMBER_TYPE_INTERNATIONAL = 1;
+  const int NUMBER_TYPE_NATIONAL = 2;
+  const int NUMBER_TYPE_NETWORK_SPECIFIC = 3;
+  const int NUMBER_TYPE_SUBSCRIBER = 4;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
new file mode 100644
index 0000000..b6b562c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaDisplayInfoRecord {
+  String alphaBuf;
+  const int CDMA_ALPHA_INFO_BUFFER_LENGTH = 64;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaInformationRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaInformationRecord.aidl
new file mode 100644
index 0000000..24ae775
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaInformationRecord.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaInformationRecord {
+  int name;
+  android.hardware.radio.voice.CdmaDisplayInfoRecord[] display;
+  android.hardware.radio.voice.CdmaNumberInfoRecord[] number;
+  android.hardware.radio.voice.CdmaSignalInfoRecord[] signal;
+  android.hardware.radio.voice.CdmaRedirectingNumberInfoRecord[] redir;
+  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;
+  const int NAME_CONNECTED_NUMBER = 3;
+  const int NAME_SIGNAL = 4;
+  const int NAME_REDIRECTING_NUMBER = 5;
+  const int NAME_LINE_CONTROL = 6;
+  const int NAME_EXTENDED_DISPLAY = 7;
+  const int NAME_T53_CLIR = 8;
+  const int NAME_T53_RELEASE = 9;
+  const int NAME_T53_AUDIO_CONTROL = 10;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
new file mode 100644
index 0000000..e34b393
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaLineControlInfoRecord {
+  byte lineCtrlPolarityIncluded;
+  byte lineCtrlToggle;
+  byte lineCtrlReverse;
+  byte lineCtrlPowerDenial;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
new file mode 100644
index 0000000..aeb0347
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaNumberInfoRecord {
+  String number;
+  byte numberType;
+  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/2/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
new file mode 100644
index 0000000..fad3841
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.voice;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum CdmaOtaProvisionStatus {
+  SPL_UNLOCKED,
+  SPC_RETRIES_EXCEEDED,
+  A_KEY_EXCHANGED,
+  SSD_UPDATED,
+  NAM_DOWNLOADED,
+  MDN_DOWNLOADED,
+  IMSI_DOWNLOADED,
+  PRL_DOWNLOADED,
+  COMMITTED,
+  OTAPA_STARTED,
+  OTAPA_STOPPED,
+  OTAPA_ABORTED,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
new file mode 100644
index 0000000..b61b91b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaRedirectingNumberInfoRecord {
+  android.hardware.radio.voice.CdmaNumberInfoRecord redirectingNumber;
+  int redirectingReason;
+  const int REDIRECTING_REASON_UNKNOWN = 0;
+  const int REDIRECTING_REASON_CALL_FORWARDING_BUSY = 1;
+  const int REDIRECTING_REASON_CALL_FORWARDING_NO_REPLY = 2;
+  const int REDIRECTING_REASON_CALLED_DTE_OUT_OF_ORDER = 9;
+  const int REDIRECTING_REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10;
+  const int REDIRECTING_REASON_CALL_FORWARDING_UNCONDITIONAL = 15;
+  const int REDIRECTING_REASON_RESERVED = 16;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
new file mode 100644
index 0000000..6c7b264
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaSignalInfoRecord {
+  boolean isPresent;
+  byte signalType;
+  byte alertPitch;
+  byte signal;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
new file mode 100644
index 0000000..438231c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaT53AudioControlInfoRecord {
+  byte upLink;
+  byte downLink;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
new file mode 100644
index 0000000..1b254f5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable CdmaT53ClirInfoRecord {
+  byte cause;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CfData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CfData.aidl
new file mode 100644
index 0000000..7e799c7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/CfData.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @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/2/android/hardware/radio/voice/ClipStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/ClipStatus.aidl
new file mode 100644
index 0000000..a34149a
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/ClipStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.voice;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ClipStatus {
+  CLIP_PROVISIONED,
+  CLIP_UNPROVISIONED,
+  UNKNOWN,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/Dial.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/Dial.aidl
new file mode 100644
index 0000000..2b2e759
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/Dial.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable Dial {
+  String address;
+  int clir;
+  android.hardware.radio.voice.UusInfo[] uusInfo;
+  const int CLIR_DEFAULT = 0;
+  const int CLIR_INVOCATION = 1;
+  const int CLIR_SUPPRESSION = 2;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/EmergencyCallRouting.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/EmergencyCallRouting.aidl
new file mode 100644
index 0000000..4e1dfc0
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/EmergencyCallRouting.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.voice;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EmergencyCallRouting {
+  UNKNOWN,
+  EMERGENCY,
+  NORMAL,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/EmergencyNumber.aidl
new file mode 100644
index 0000000..f2a7d8c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable EmergencyNumber {
+  String number;
+  String mcc;
+  String mnc;
+  int categories;
+  String[] urns;
+  int sources;
+  const int SOURCE_NETWORK_SIGNALING = (1 << 0) /* 1 */;
+  const int SOURCE_SIM = (1 << 1) /* 2 */;
+  const int SOURCE_MODEM_CONFIG = (1 << 2) /* 4 */;
+  const int SOURCE_DEFAULT = (1 << 3) /* 8 */;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/EmergencyServiceCategory.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/EmergencyServiceCategory.aidl
new file mode 100644
index 0000000..3a0cdae
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/EmergencyServiceCategory.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.voice;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EmergencyServiceCategory {
+  UNSPECIFIED = 0,
+  POLICE = (1 << 0) /* 1 */,
+  AMBULANCE = (1 << 1) /* 2 */,
+  FIRE_BRIGADE = (1 << 2) /* 4 */,
+  MARINE_GUARD = (1 << 3) /* 8 */,
+  MOUNTAIN_RESCUE = (1 << 4) /* 16 */,
+  MIEC = (1 << 5) /* 32 */,
+  AIEC = (1 << 6) /* 64 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/IRadioVoice.aidl
new file mode 100644
index 0000000..603b1d6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/IRadioVoice.aidl
@@ -0,0 +1,76 @@
+/*
+ * 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.voice;
+@VintfStability
+interface IRadioVoice {
+  oneway void acceptCall(in int serial);
+  oneway void cancelPendingUssd(in int serial);
+  oneway void conference(in int serial);
+  oneway void dial(in int serial, in android.hardware.radio.voice.Dial dialInfo);
+  oneway void emergencyDial(in int serial, in android.hardware.radio.voice.Dial dialInfo, in int categories, in String[] urns, in android.hardware.radio.voice.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting);
+  oneway void exitEmergencyCallbackMode(in int serial);
+  oneway void explicitCallTransfer(in int serial);
+  oneway void getCallForwardStatus(in int serial, in android.hardware.radio.voice.CallForwardInfo callInfo);
+  oneway void getCallWaiting(in int serial, in int serviceClass);
+  oneway void getClip(in int serial);
+  oneway void getClir(in int serial);
+  oneway void getCurrentCalls(in int serial);
+  oneway void getLastCallFailCause(in int serial);
+  oneway void getMute(in int serial);
+  oneway void getPreferredVoicePrivacy(in int serial);
+  oneway void getTtyMode(in int serial);
+  oneway void handleStkCallSetupRequestFromSim(in int serial, in boolean accept);
+  oneway void hangup(in int serial, in int gsmIndex);
+  oneway void hangupForegroundResumeBackground(in int serial);
+  oneway void hangupWaitingOrBackground(in int serial);
+  oneway void isVoNrEnabled(in int serial);
+  oneway void rejectCall(in int serial);
+  oneway void responseAcknowledgement();
+  oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off);
+  oneway void sendCdmaFeatureCode(in int serial, in String featureCode);
+  oneway void sendDtmf(in int serial, in String s);
+  oneway void sendUssd(in int serial, in String ussd);
+  oneway void separateConnection(in int serial, in int gsmIndex);
+  oneway void setCallForward(in int serial, in android.hardware.radio.voice.CallForwardInfo callInfo);
+  oneway void setCallWaiting(in int serial, in boolean enable, in int serviceClass);
+  oneway void setClir(in int serial, in int status);
+  oneway void setMute(in int serial, in boolean enable);
+  oneway void setPreferredVoicePrivacy(in int serial, in boolean enable);
+  oneway void setResponseFunctions(in android.hardware.radio.voice.IRadioVoiceResponse radioVoiceResponse, in android.hardware.radio.voice.IRadioVoiceIndication radioVoiceIndication);
+  oneway void setTtyMode(in int serial, in android.hardware.radio.voice.TtyMode mode);
+  oneway void setVoNrEnabled(in int serial, in boolean enable);
+  oneway void startDtmf(in int serial, in String s);
+  oneway void stopDtmf(in int serial);
+  oneway void switchWaitingOrHoldingAndActive(in int serial);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/IRadioVoiceIndication.aidl
new file mode 100644
index 0000000..189ed43
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.voice;
+@VintfStability
+interface IRadioVoiceIndication {
+  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.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);
+  oneway void exitEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type);
+  oneway void indicateRingbackTone(in android.hardware.radio.RadioIndicationType type, in boolean start);
+  oneway void onSupplementaryServiceIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.StkCcUnsolSsResult ss);
+  oneway void onUssd(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.UssdModeType modeType, in String msg);
+  oneway void resendIncallMute(in android.hardware.radio.RadioIndicationType type);
+  oneway void srvccStateNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.SrvccState state);
+  oneway void stkCallControlAlphaNotify(in android.hardware.radio.RadioIndicationType type, in String alpha);
+  oneway void stkCallSetup(in android.hardware.radio.RadioIndicationType type, in long timeout);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/IRadioVoiceResponse.aidl
new file mode 100644
index 0000000..7acc044
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -0,0 +1,75 @@
+/*
+ * 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.voice;
+@VintfStability
+interface IRadioVoiceResponse {
+  oneway void acceptCallResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void acknowledgeRequest(in int serial);
+  oneway void cancelPendingUssdResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void conferenceResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void dialResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void emergencyDialResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void exitEmergencyCallbackModeResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void explicitCallTransferResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getCallForwardStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.CallForwardInfo[] callForwardInfos);
+  oneway void getCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable, in int serviceClass);
+  oneway void getClipResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.ClipStatus status);
+  oneway void getClirResponse(in android.hardware.radio.RadioResponseInfo info, in int n, in int m);
+  oneway void getCurrentCallsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.Call[] calls);
+  oneway void getLastCallFailCauseResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.LastCallFailCauseInfo failCauseinfo);
+  oneway void getMuteResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable);
+  oneway void getPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable);
+  oneway void getTtyModeResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.TtyMode mode);
+  oneway void handleStkCallSetupRequestFromSimResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void hangupConnectionResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void hangupForegroundResumeBackgroundResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void hangupWaitingOrBackgroundResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void isVoNrEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable);
+  oneway void rejectCallResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void sendBurstDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void sendCdmaFeatureCodeResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void sendDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void sendUssdResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void separateConnectionResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setCallForwardResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setClirResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setMuteResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setTtyModeResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setVoNrEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void startDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void stopDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void switchWaitingOrHoldingAndActiveResponse(in android.hardware.radio.RadioResponseInfo info);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/LastCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/LastCallFailCause.aidl
new file mode 100644
index 0000000..7d54623
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/LastCallFailCause.aidl
@@ -0,0 +1,133 @@
+/*
+ * 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.voice;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum LastCallFailCause {
+  UNOBTAINABLE_NUMBER = 1,
+  NO_ROUTE_TO_DESTINATION = 3,
+  CHANNEL_UNACCEPTABLE = 6,
+  OPERATOR_DETERMINED_BARRING = 8,
+  NORMAL = 16,
+  BUSY = 17,
+  NO_USER_RESPONDING = 18,
+  NO_ANSWER_FROM_USER = 19,
+  CALL_REJECTED = 21,
+  NUMBER_CHANGED = 22,
+  PREEMPTION = 25,
+  DESTINATION_OUT_OF_ORDER = 27,
+  INVALID_NUMBER_FORMAT = 28,
+  FACILITY_REJECTED = 29,
+  RESP_TO_STATUS_ENQUIRY = 30,
+  NORMAL_UNSPECIFIED = 31,
+  CONGESTION = 34,
+  NETWORK_OUT_OF_ORDER = 38,
+  TEMPORARY_FAILURE = 41,
+  SWITCHING_EQUIPMENT_CONGESTION = 42,
+  ACCESS_INFORMATION_DISCARDED = 43,
+  REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE = 44,
+  RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47,
+  QOS_UNAVAILABLE = 49,
+  REQUESTED_FACILITY_NOT_SUBSCRIBED = 50,
+  INCOMING_CALLS_BARRED_WITHIN_CUG = 55,
+  BEARER_CAPABILITY_NOT_AUTHORIZED = 57,
+  BEARER_CAPABILITY_UNAVAILABLE = 58,
+  SERVICE_OPTION_NOT_AVAILABLE = 63,
+  BEARER_SERVICE_NOT_IMPLEMENTED = 65,
+  ACM_LIMIT_EXCEEDED = 68,
+  REQUESTED_FACILITY_NOT_IMPLEMENTED = 69,
+  ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70,
+  SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79,
+  INVALID_TRANSACTION_IDENTIFIER = 81,
+  USER_NOT_MEMBER_OF_CUG = 87,
+  INCOMPATIBLE_DESTINATION = 88,
+  INVALID_TRANSIT_NW_SELECTION = 91,
+  SEMANTICALLY_INCORRECT_MESSAGE = 95,
+  INVALID_MANDATORY_INFORMATION = 96,
+  MESSAGE_TYPE_NON_IMPLEMENTED = 97,
+  MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98,
+  INFORMATION_ELEMENT_NON_EXISTENT = 99,
+  CONDITIONAL_IE_ERROR = 100,
+  MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101,
+  RECOVERY_ON_TIMER_EXPIRED = 102,
+  PROTOCOL_ERROR_UNSPECIFIED = 111,
+  INTERWORKING_UNSPECIFIED = 127,
+  CALL_BARRED = 240,
+  FDN_BLOCKED = 241,
+  IMSI_UNKNOWN_IN_VLR = 242,
+  IMEI_NOT_ACCEPTED = 243,
+  DIAL_MODIFIED_TO_USSD = 244,
+  DIAL_MODIFIED_TO_SS = 245,
+  DIAL_MODIFIED_TO_DIAL = 246,
+  RADIO_OFF = 247,
+  OUT_OF_SERVICE = 248,
+  NO_VALID_SIM = 249,
+  RADIO_INTERNAL_ERROR = 250,
+  NETWORK_RESP_TIMEOUT = 251,
+  NETWORK_REJECT = 252,
+  RADIO_ACCESS_FAILURE = 253,
+  RADIO_LINK_FAILURE = 254,
+  RADIO_LINK_LOST = 255,
+  RADIO_UPLINK_FAILURE = 256,
+  RADIO_SETUP_FAILURE = 257,
+  RADIO_RELEASE_NORMAL = 258,
+  RADIO_RELEASE_ABNORMAL = 259,
+  ACCESS_CLASS_BLOCKED = 260,
+  NETWORK_DETACH = 261,
+  CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000,
+  CDMA_DROP = 1001,
+  CDMA_INTERCEPT = 1002,
+  CDMA_REORDER = 1003,
+  CDMA_SO_REJECT = 1004,
+  CDMA_RETRY_ORDER = 1005,
+  CDMA_ACCESS_FAILURE = 1006,
+  CDMA_PREEMPTED = 1007,
+  CDMA_NOT_EMERGENCY = 1008,
+  CDMA_ACCESS_BLOCKED = 1009,
+  OEM_CAUSE_1 = 0xf001,
+  OEM_CAUSE_2 = 0xf002,
+  OEM_CAUSE_3 = 0xf003,
+  OEM_CAUSE_4 = 0xf004,
+  OEM_CAUSE_5 = 0xf005,
+  OEM_CAUSE_6 = 0xf006,
+  OEM_CAUSE_7 = 0xf007,
+  OEM_CAUSE_8 = 0xf008,
+  OEM_CAUSE_9 = 0xf009,
+  OEM_CAUSE_10 = 0xf00a,
+  OEM_CAUSE_11 = 0xf00b,
+  OEM_CAUSE_12 = 0xf00c,
+  OEM_CAUSE_13 = 0xf00d,
+  OEM_CAUSE_14 = 0xf00e,
+  OEM_CAUSE_15 = 0xf00f,
+  ERROR_UNSPECIFIED = 0xffff,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/LastCallFailCauseInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
new file mode 100644
index 0000000..221acf7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable LastCallFailCauseInfo {
+  android.hardware.radio.voice.LastCallFailCause causeCode;
+  String vendorCause;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/SrvccState.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/SrvccState.aidl
new file mode 100644
index 0000000..4b5c216
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/SrvccState.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.voice;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum SrvccState {
+  HANDOVER_STARTED,
+  HANDOVER_COMPLETED,
+  HANDOVER_FAILED,
+  HANDOVER_CANCELED,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/SsInfoData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/SsInfoData.aidl
new file mode 100644
index 0000000..f18b404
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/SsInfoData.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable SsInfoData {
+  int[] ssInfo;
+  const int SS_INFO_MAX = 4;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/StkCcUnsolSsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
new file mode 100644
index 0000000..f04942b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
@@ -0,0 +1,84 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable StkCcUnsolSsResult {
+  int serviceType;
+  int requestType;
+  int teleserviceType;
+  int serviceClass;
+  android.hardware.radio.RadioError result;
+  android.hardware.radio.voice.SsInfoData[] ssInfo;
+  android.hardware.radio.voice.CfData[] cfData;
+  const int REQUEST_TYPE_ACTIVATION = 0;
+  const int REQUEST_TYPE_DEACTIVATION = 1;
+  const int REQUEST_TYPE_INTERROGATION = 2;
+  const int REQUEST_TYPE_REGISTRATION = 3;
+  const int REQUEST_TYPE_ERASURE = 4;
+  const int SERVICE_TYPE_CFU = 0;
+  const int SERVICE_TYPE_CF_BUSY = 1;
+  const int SERVICE_TYPE_CF_NO_REPLY = 2;
+  const int SERVICE_TYPE_CF_NOT_REACHABLE = 3;
+  const int SERVICE_TYPE_CF_ALL = 4;
+  const int SERVICE_TYPE_CF_ALL_CONDITIONAL = 5;
+  const int SERVICE_TYPE_CLIP = 6;
+  const int SERVICE_TYPE_CLIR = 7;
+  const int SERVICE_TYPE_COLP = 8;
+  const int SERVICE_TYPE_COLR = 9;
+  const int SERVICE_TYPE_WAIT = 10;
+  const int SERVICE_TYPE_BAOC = 11;
+  const int SERVICE_TYPE_BAOIC = 12;
+  const int SERVICE_TYPE_BAOIC_EXC_HOME = 13;
+  const int SERVICE_TYPE_BAIC = 14;
+  const int SERVICE_TYPE_BAIC_ROAMING = 15;
+  const int SERVICE_TYPE_ALL_BARRING = 16;
+  const int SERVICE_TYPE_OUTGOING_BARRING = 17;
+  const int SERVICE_TYPE_INCOMING_BARRING = 18;
+  const int TELESERVICE_TYPE_ALL_TELE_AND_BEARER_SERVICES = 0;
+  const int TELESERVICE_TYPE_ALL_TELESEVICES = 1;
+  const int TELESERVICE_TYPE_TELEPHONY = 2;
+  const int TELESERVICE_TYPE_ALL_DATA_TELESERVICES = 3;
+  const int TELESERVICE_TYPE_SMS_SERVICES = 4;
+  const int TELESERVICE_TYPE_ALL_TELESERVICES_EXCEPT_SMS = 5;
+  const int SUPP_SERVICE_CLASS_NONE = 0;
+  const int SUPP_SERVICE_CLASS_VOICE = (1 << 0) /* 1 */;
+  const int SUPP_SERVICE_CLASS_DATA = (1 << 1) /* 2 */;
+  const int SUPP_SERVICE_CLASS_FAX = (1 << 2) /* 4 */;
+  const int SUPP_SERVICE_CLASS_SMS = (1 << 3) /* 8 */;
+  const int SUPP_SERVICE_CLASS_DATA_SYNC = (1 << 4) /* 16 */;
+  const int SUPP_SERVICE_CLASS_DATA_ASYNC = (1 << 5) /* 32 */;
+  const int SUPP_SERVICE_CLASS_PACKET = (1 << 6) /* 64 */;
+  const int SUPP_SERVICE_CLASS_PAD = (1 << 7) /* 128 */;
+  const int SUPP_SERVICE_CLASS_MAX = (1 << 7) /* 128 */;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/TtyMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/TtyMode.aidl
new file mode 100644
index 0000000..e432e65
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/TtyMode.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.voice;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum TtyMode {
+  OFF,
+  FULL,
+  HCO,
+  VCO,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/UssdModeType.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/UssdModeType.aidl
new file mode 100644
index 0000000..424e73f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/UssdModeType.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.voice;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum UssdModeType {
+  NOTIFY,
+  REQUEST,
+  NW_RELEASE,
+  LOCAL_CLIENT,
+  NOT_SUPPORTED,
+  NW_TIMEOUT,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/UusInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/UusInfo.aidl
new file mode 100644
index 0000000..9313760
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/2/android/hardware/radio/voice/UusInfo.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.voice;
+@JavaDerive(toString=true) @VintfStability
+parcelable UusInfo {
+  int uusType;
+  int uusDcs;
+  String uusData;
+  const int UUS_DCS_USP = 0;
+  const int UUS_DCS_OSIHLP = 1;
+  const int UUS_DCS_X244 = 2;
+  const int UUS_DCS_RMCF = 3;
+  const int UUS_DCS_IA5C = 4;
+  const int UUS_TYPE_TYPE1_IMPLICIT = 0;
+  const int UUS_TYPE_TYPE1_REQUIRED = 1;
+  const int UUS_TYPE_TYPE1_NOT_REQUIRED = 2;
+  const int UUS_TYPE_TYPE2_REQUIRED = 3;
+  const int UUS_TYPE_TYPE2_NOT_REQUIRED = 4;
+  const int UUS_TYPE_TYPE3_REQUIRED = 5;
+  const int UUS_TYPE_TYPE3_NOT_REQUIRED = 6;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl
index 15669ac..1ab2902 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl
@@ -34,14 +34,14 @@
 package android.hardware.radio.voice;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum AudioQuality {
-  UNSPECIFIED = 0,
-  AMR = 1,
-  AMR_WB = 2,
-  GSM_EFR = 3,
-  GSM_FR = 4,
-  GSM_HR = 5,
-  EVRC = 6,
-  EVRC_B = 7,
-  EVRC_WB = 8,
-  EVRC_NW = 9,
+  UNSPECIFIED,
+  AMR,
+  AMR_WB,
+  GSM_EFR,
+  GSM_FR,
+  GSM_HR,
+  EVRC,
+  EVRC_B,
+  EVRC_WB,
+  EVRC_NW,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
index 7877fda..fad3841 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
@@ -34,16 +34,16 @@
 package android.hardware.radio.voice;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CdmaOtaProvisionStatus {
-  SPL_UNLOCKED = 0,
-  SPC_RETRIES_EXCEEDED = 1,
-  A_KEY_EXCHANGED = 2,
-  SSD_UPDATED = 3,
-  NAM_DOWNLOADED = 4,
-  MDN_DOWNLOADED = 5,
-  IMSI_DOWNLOADED = 6,
-  PRL_DOWNLOADED = 7,
-  COMMITTED = 8,
-  OTAPA_STARTED = 9,
-  OTAPA_STOPPED = 10,
-  OTAPA_ABORTED = 11,
+  SPL_UNLOCKED,
+  SPC_RETRIES_EXCEEDED,
+  A_KEY_EXCHANGED,
+  SSD_UPDATED,
+  NAM_DOWNLOADED,
+  MDN_DOWNLOADED,
+  IMSI_DOWNLOADED,
+  PRL_DOWNLOADED,
+  COMMITTED,
+  OTAPA_STARTED,
+  OTAPA_STOPPED,
+  OTAPA_ABORTED,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl
index 3fbb0d8..a34149a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl
@@ -34,7 +34,7 @@
 package android.hardware.radio.voice;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum ClipStatus {
-  CLIP_PROVISIONED = 0,
-  CLIP_UNPROVISIONED = 1,
-  UNKNOWN = 2,
+  CLIP_PROVISIONED,
+  CLIP_UNPROVISIONED,
+  UNKNOWN,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl
index 07f011d..4e1dfc0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl
@@ -34,7 +34,7 @@
 package android.hardware.radio.voice;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum EmergencyCallRouting {
-  UNKNOWN = 0,
-  EMERGENCY = 1,
-  NORMAL = 2,
+  UNKNOWN,
+  EMERGENCY,
+  NORMAL,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
index 98df8cd..ac3867e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -40,8 +40,8 @@
   int categories;
   String[] urns;
   int sources;
-  const int SOURCE_NETWORK_SIGNALING = 1;
-  const int SOURCE_SIM = 2;
-  const int SOURCE_MODEM_CONFIG = 4;
-  const int SOURCE_DEFAULT = 8;
+  const int SOURCE_NETWORK_SIGNALING = (1 << 0);
+  const int SOURCE_SIM = (1 << 1);
+  const int SOURCE_MODEM_CONFIG = (1 << 2);
+  const int SOURCE_DEFAULT = (1 << 3);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl
index 042dd61..0a70d2d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl
@@ -35,11 +35,11 @@
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum EmergencyServiceCategory {
   UNSPECIFIED = 0,
-  POLICE = 1,
-  AMBULANCE = 2,
-  FIRE_BRIGADE = 4,
-  MARINE_GUARD = 8,
-  MOUNTAIN_RESCUE = 16,
-  MIEC = 32,
-  AIEC = 64,
+  POLICE = (1 << 0),
+  AMBULANCE = (1 << 1),
+  FIRE_BRIGADE = (1 << 2),
+  MARINE_GUARD = (1 << 3),
+  MOUNTAIN_RESCUE = (1 << 4),
+  MIEC = (1 << 5),
+  AIEC = (1 << 6),
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
index 1740134..7d54623 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
@@ -114,20 +114,20 @@
   CDMA_PREEMPTED = 1007,
   CDMA_NOT_EMERGENCY = 1008,
   CDMA_ACCESS_BLOCKED = 1009,
-  OEM_CAUSE_1 = 61441,
-  OEM_CAUSE_2 = 61442,
-  OEM_CAUSE_3 = 61443,
-  OEM_CAUSE_4 = 61444,
-  OEM_CAUSE_5 = 61445,
-  OEM_CAUSE_6 = 61446,
-  OEM_CAUSE_7 = 61447,
-  OEM_CAUSE_8 = 61448,
-  OEM_CAUSE_9 = 61449,
-  OEM_CAUSE_10 = 61450,
-  OEM_CAUSE_11 = 61451,
-  OEM_CAUSE_12 = 61452,
-  OEM_CAUSE_13 = 61453,
-  OEM_CAUSE_14 = 61454,
-  OEM_CAUSE_15 = 61455,
-  ERROR_UNSPECIFIED = 65535,
+  OEM_CAUSE_1 = 0xf001,
+  OEM_CAUSE_2 = 0xf002,
+  OEM_CAUSE_3 = 0xf003,
+  OEM_CAUSE_4 = 0xf004,
+  OEM_CAUSE_5 = 0xf005,
+  OEM_CAUSE_6 = 0xf006,
+  OEM_CAUSE_7 = 0xf007,
+  OEM_CAUSE_8 = 0xf008,
+  OEM_CAUSE_9 = 0xf009,
+  OEM_CAUSE_10 = 0xf00a,
+  OEM_CAUSE_11 = 0xf00b,
+  OEM_CAUSE_12 = 0xf00c,
+  OEM_CAUSE_13 = 0xf00d,
+  OEM_CAUSE_14 = 0xf00e,
+  OEM_CAUSE_15 = 0xf00f,
+  ERROR_UNSPECIFIED = 0xffff,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl
index 864374b..4b5c216 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl
@@ -34,8 +34,8 @@
 package android.hardware.radio.voice;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum SrvccState {
-  HANDOVER_STARTED = 0,
-  HANDOVER_COMPLETED = 1,
-  HANDOVER_FAILED = 2,
-  HANDOVER_CANCELED = 3,
+  HANDOVER_STARTED,
+  HANDOVER_COMPLETED,
+  HANDOVER_FAILED,
+  HANDOVER_CANCELED,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
index 50bb1fd..75f3de5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
@@ -72,13 +72,13 @@
   const int TELESERVICE_TYPE_SMS_SERVICES = 4;
   const int TELESERVICE_TYPE_ALL_TELESERVICES_EXCEPT_SMS = 5;
   const int SUPP_SERVICE_CLASS_NONE = 0;
-  const int SUPP_SERVICE_CLASS_VOICE = 1;
-  const int SUPP_SERVICE_CLASS_DATA = 2;
-  const int SUPP_SERVICE_CLASS_FAX = 4;
-  const int SUPP_SERVICE_CLASS_SMS = 8;
-  const int SUPP_SERVICE_CLASS_DATA_SYNC = 16;
-  const int SUPP_SERVICE_CLASS_DATA_ASYNC = 32;
-  const int SUPP_SERVICE_CLASS_PACKET = 64;
-  const int SUPP_SERVICE_CLASS_PAD = 128;
-  const int SUPP_SERVICE_CLASS_MAX = 128;
+  const int SUPP_SERVICE_CLASS_VOICE = (1 << 0);
+  const int SUPP_SERVICE_CLASS_DATA = (1 << 1);
+  const int SUPP_SERVICE_CLASS_FAX = (1 << 2);
+  const int SUPP_SERVICE_CLASS_SMS = (1 << 3);
+  const int SUPP_SERVICE_CLASS_DATA_SYNC = (1 << 4);
+  const int SUPP_SERVICE_CLASS_DATA_ASYNC = (1 << 5);
+  const int SUPP_SERVICE_CLASS_PACKET = (1 << 6);
+  const int SUPP_SERVICE_CLASS_PAD = (1 << 7);
+  const int SUPP_SERVICE_CLASS_MAX = (1 << 7);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl
index 77417e8..e432e65 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl
@@ -34,8 +34,8 @@
 package android.hardware.radio.voice;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum TtyMode {
-  OFF = 0,
-  FULL = 1,
-  HCO = 2,
-  VCO = 3,
+  OFF,
+  FULL,
+  HCO,
+  VCO,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
index ad243d2..424e73f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
@@ -34,10 +34,10 @@
 package android.hardware.radio.voice;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum UssdModeType {
-  NOTIFY = 0,
-  REQUEST = 1,
-  NW_RELEASE = 2,
-  LOCAL_CLIENT = 3,
-  NOT_SUPPORTED = 4,
-  NW_TIMEOUT = 5,
+  NOTIFY,
+  REQUEST,
+  NW_RELEASE,
+  LOCAL_CLIENT,
+  NOT_SUPPORTED,
+  NW_TIMEOUT,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/.hash b/radio/aidl/aidl_api/android.hardware.radio/2/.hash
new file mode 100644
index 0000000..f7a1438
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/.hash
@@ -0,0 +1 @@
+bb059adfc597be7a26032661374ee203320b3494
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/AccessNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/AccessNetwork.aidl
new file mode 100644
index 0000000..9641651
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/AccessNetwork.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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") @JavaDerive(toString=true) @VintfStability
+enum AccessNetwork {
+  UNKNOWN,
+  GERAN,
+  UTRAN,
+  EUTRAN,
+  CDMA2000,
+  IWLAN,
+  NGRAN,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioAccessFamily.aidl
new file mode 100644
index 0000000..b7b074b
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioAccessFamily.aidl
@@ -0,0 +1,61 @@
+/*
+ * 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") @JavaDerive(toString=true) @VintfStability
+enum RadioAccessFamily {
+  UNKNOWN = (1 << android.hardware.radio.RadioTechnology.UNKNOWN) /* 1 */,
+  GPRS = (1 << android.hardware.radio.RadioTechnology.GPRS) /* 2 */,
+  EDGE = (1 << android.hardware.radio.RadioTechnology.EDGE) /* 4 */,
+  UMTS = (1 << android.hardware.radio.RadioTechnology.UMTS) /* 8 */,
+  IS95A = (1 << android.hardware.radio.RadioTechnology.IS95A) /* 16 */,
+  IS95B = (1 << android.hardware.radio.RadioTechnology.IS95B) /* 32 */,
+  ONE_X_RTT = (1 << android.hardware.radio.RadioTechnology.ONE_X_RTT) /* 64 */,
+  EVDO_0 = (1 << android.hardware.radio.RadioTechnology.EVDO_0) /* 128 */,
+  EVDO_A = (1 << android.hardware.radio.RadioTechnology.EVDO_A) /* 256 */,
+  HSDPA = (1 << android.hardware.radio.RadioTechnology.HSDPA) /* 512 */,
+  HSUPA = (1 << android.hardware.radio.RadioTechnology.HSUPA) /* 1024 */,
+  HSPA = (1 << android.hardware.radio.RadioTechnology.HSPA) /* 2048 */,
+  EVDO_B = (1 << android.hardware.radio.RadioTechnology.EVDO_B) /* 4096 */,
+  EHRPD = (1 << android.hardware.radio.RadioTechnology.EHRPD) /* 8192 */,
+  LTE = (1 << android.hardware.radio.RadioTechnology.LTE) /* 16384 */,
+  HSPAP = (1 << android.hardware.radio.RadioTechnology.HSPAP) /* 32768 */,
+  GSM = (1 << android.hardware.radio.RadioTechnology.GSM) /* 65536 */,
+  TD_SCDMA = (1 << android.hardware.radio.RadioTechnology.TD_SCDMA) /* 131072 */,
+  IWLAN = (1 << android.hardware.radio.RadioTechnology.IWLAN) /* 262144 */,
+  /**
+   * @deprecated use LTE instead.
+   */
+  LTE_CA = (1 << android.hardware.radio.RadioTechnology.LTE_CA) /* 524288 */,
+  NR = (1 << android.hardware.radio.RadioTechnology.NR) /* 1048576 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioConst.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioConst.aidl
new file mode 100644
index 0000000..9785825
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioConst.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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;
+@JavaDerive(toString=true) @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) /* -1 */;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioError.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioError.aidl
new file mode 100644
index 0000000..98606e5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioError.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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") @JavaDerive(toString=true) @VintfStability
+enum RadioError {
+  NONE = 0,
+  RADIO_NOT_AVAILABLE = 1,
+  GENERIC_FAILURE = 2,
+  PASSWORD_INCORRECT = 3,
+  SIM_PIN2 = 4,
+  SIM_PUK2 = 5,
+  REQUEST_NOT_SUPPORTED = 6,
+  CANCELLED = 7,
+  OP_NOT_ALLOWED_DURING_VOICE_CALL = 8,
+  OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9,
+  SMS_SEND_FAIL_RETRY = 10,
+  SIM_ABSENT = 11,
+  SUBSCRIPTION_NOT_AVAILABLE = 12,
+  MODE_NOT_SUPPORTED = 13,
+  FDN_CHECK_FAILURE = 14,
+  ILLEGAL_SIM_OR_ME = 15,
+  MISSING_RESOURCE = 16,
+  NO_SUCH_ELEMENT = 17,
+  DIAL_MODIFIED_TO_USSD = 18,
+  DIAL_MODIFIED_TO_SS = 19,
+  DIAL_MODIFIED_TO_DIAL = 20,
+  USSD_MODIFIED_TO_DIAL = 21,
+  USSD_MODIFIED_TO_SS = 22,
+  USSD_MODIFIED_TO_USSD = 23,
+  SS_MODIFIED_TO_DIAL = 24,
+  SS_MODIFIED_TO_USSD = 25,
+  SUBSCRIPTION_NOT_SUPPORTED = 26,
+  SS_MODIFIED_TO_SS = 27,
+  LCE_NOT_SUPPORTED = 36,
+  NO_MEMORY = 37,
+  INTERNAL_ERR = 38,
+  SYSTEM_ERR = 39,
+  MODEM_ERR = 40,
+  INVALID_STATE = 41,
+  NO_RESOURCES = 42,
+  SIM_ERR = 43,
+  INVALID_ARGUMENTS = 44,
+  INVALID_SIM_STATE = 45,
+  INVALID_MODEM_STATE = 46,
+  INVALID_CALL_ID = 47,
+  NO_SMS_TO_ACK = 48,
+  NETWORK_ERR = 49,
+  REQUEST_RATE_LIMITED = 50,
+  SIM_BUSY = 51,
+  SIM_FULL = 52,
+  NETWORK_REJECT = 53,
+  OPERATION_NOT_ALLOWED = 54,
+  EMPTY_RECORD = 55,
+  INVALID_SMS_FORMAT = 56,
+  ENCODING_ERR = 57,
+  INVALID_SMSC_ADDRESS = 58,
+  NO_SUCH_ENTRY = 59,
+  NETWORK_NOT_READY = 60,
+  NOT_PROVISIONED = 61,
+  NO_SUBSCRIPTION = 62,
+  NO_NETWORK_FOUND = 63,
+  DEVICE_IN_USE = 64,
+  ABORTED = 65,
+  INVALID_RESPONSE = 66,
+  OEM_ERROR_1 = 501,
+  OEM_ERROR_2 = 502,
+  OEM_ERROR_3 = 503,
+  OEM_ERROR_4 = 504,
+  OEM_ERROR_5 = 505,
+  OEM_ERROR_6 = 506,
+  OEM_ERROR_7 = 507,
+  OEM_ERROR_8 = 508,
+  OEM_ERROR_9 = 509,
+  OEM_ERROR_10 = 510,
+  OEM_ERROR_11 = 511,
+  OEM_ERROR_12 = 512,
+  OEM_ERROR_13 = 513,
+  OEM_ERROR_14 = 514,
+  OEM_ERROR_15 = 515,
+  OEM_ERROR_16 = 516,
+  OEM_ERROR_17 = 517,
+  OEM_ERROR_18 = 518,
+  OEM_ERROR_19 = 519,
+  OEM_ERROR_20 = 520,
+  OEM_ERROR_21 = 521,
+  OEM_ERROR_22 = 522,
+  OEM_ERROR_23 = 523,
+  OEM_ERROR_24 = 524,
+  OEM_ERROR_25 = 525,
+  SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 67,
+  ACCESS_BARRED = 68,
+  BLOCKED_DUE_TO_CALL = 69,
+  RF_HARDWARE_ISSUE = 70,
+  NO_RF_CALIBRATION_INFO = 71,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioIndicationType.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioIndicationType.aidl
new file mode 100644
index 0000000..58b35a5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioIndicationType.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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") @JavaDerive(toString=true) @VintfStability
+enum RadioIndicationType {
+  UNSOLICITED,
+  UNSOLICITED_ACK_EXP,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioResponseInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioResponseInfo.aidl
new file mode 100644
index 0000000..b2a7a06
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioResponseInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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;
+@JavaDerive(toString=true) @VintfStability
+parcelable RadioResponseInfo {
+  android.hardware.radio.RadioResponseType type;
+  int serial;
+  android.hardware.radio.RadioError error;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioResponseInfoModem.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioResponseInfoModem.aidl
new file mode 100644
index 0000000..37ed7bb
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioResponseInfoModem.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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;
+@JavaDerive(toString=true) @VintfStability
+parcelable RadioResponseInfoModem {
+  android.hardware.radio.RadioResponseType type;
+  int serial;
+  android.hardware.radio.RadioError error;
+  boolean isEnabled;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioResponseType.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioResponseType.aidl
new file mode 100644
index 0000000..1ee62bd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioResponseType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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") @JavaDerive(toString=true) @VintfStability
+enum RadioResponseType {
+  SOLICITED,
+  SOLICITED_ACK,
+  SOLICITED_ACK_EXP,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioTechnology.aidl
new file mode 100644
index 0000000..b6af5aa
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioTechnology.aidl
@@ -0,0 +1,61 @@
+/*
+ * 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") @JavaDerive(toString=true) @VintfStability
+enum RadioTechnology {
+  UNKNOWN,
+  GPRS,
+  EDGE,
+  UMTS,
+  IS95A,
+  IS95B,
+  ONE_X_RTT,
+  EVDO_0,
+  EVDO_A,
+  HSDPA,
+  HSUPA,
+  HSPA,
+  EVDO_B,
+  EHRPD,
+  LTE,
+  HSPAP,
+  GSM,
+  TD_SCDMA,
+  IWLAN,
+  /**
+   * @deprecated use LTE instead and indicate carrier aggregation through multiple physical channel configurations in IRadioNetwork::currentPhysicalChannelConfigs.
+   */
+  LTE_CA,
+  NR,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioTechnologyFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioTechnologyFamily.aidl
new file mode 100644
index 0000000..2af7e53
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio/2/android/hardware/radio/RadioTechnologyFamily.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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") @JavaDerive(toString=true) @VintfStability
+enum RadioTechnologyFamily {
+  THREE_GPP,
+  THREE_GPP2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
index 8ce689f..9641651 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
@@ -34,11 +34,11 @@
 package android.hardware.radio;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum AccessNetwork {
-  UNKNOWN = 0,
-  GERAN = 1,
-  UTRAN = 2,
-  EUTRAN = 3,
-  CDMA2000 = 4,
-  IWLAN = 5,
-  NGRAN = 6,
+  UNKNOWN,
+  GERAN,
+  UTRAN,
+  EUTRAN,
+  CDMA2000,
+  IWLAN,
+  NGRAN,
 }
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 ecc2a9b..b7b074b 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
@@ -34,25 +34,28 @@
 package android.hardware.radio;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioAccessFamily {
-  UNKNOWN = 1,
-  GPRS = 2,
-  EDGE = 4,
-  UMTS = 8,
-  IS95A = 16,
-  IS95B = 32,
-  ONE_X_RTT = 64,
-  EVDO_0 = 128,
-  EVDO_A = 256,
-  HSDPA = 512,
-  HSUPA = 1024,
-  HSPA = 2048,
-  EVDO_B = 4096,
-  EHRPD = 8192,
-  LTE = 16384,
-  HSPAP = 32768,
-  GSM = 65536,
-  TD_SCDMA = 131072,
-  IWLAN = 262144,
-  LTE_CA = 524288,
-  NR = 1048576,
+  UNKNOWN = (1 << android.hardware.radio.RadioTechnology.UNKNOWN) /* 1 */,
+  GPRS = (1 << android.hardware.radio.RadioTechnology.GPRS) /* 2 */,
+  EDGE = (1 << android.hardware.radio.RadioTechnology.EDGE) /* 4 */,
+  UMTS = (1 << android.hardware.radio.RadioTechnology.UMTS) /* 8 */,
+  IS95A = (1 << android.hardware.radio.RadioTechnology.IS95A) /* 16 */,
+  IS95B = (1 << android.hardware.radio.RadioTechnology.IS95B) /* 32 */,
+  ONE_X_RTT = (1 << android.hardware.radio.RadioTechnology.ONE_X_RTT) /* 64 */,
+  EVDO_0 = (1 << android.hardware.radio.RadioTechnology.EVDO_0) /* 128 */,
+  EVDO_A = (1 << android.hardware.radio.RadioTechnology.EVDO_A) /* 256 */,
+  HSDPA = (1 << android.hardware.radio.RadioTechnology.HSDPA) /* 512 */,
+  HSUPA = (1 << android.hardware.radio.RadioTechnology.HSUPA) /* 1024 */,
+  HSPA = (1 << android.hardware.radio.RadioTechnology.HSPA) /* 2048 */,
+  EVDO_B = (1 << android.hardware.radio.RadioTechnology.EVDO_B) /* 4096 */,
+  EHRPD = (1 << android.hardware.radio.RadioTechnology.EHRPD) /* 8192 */,
+  LTE = (1 << android.hardware.radio.RadioTechnology.LTE) /* 16384 */,
+  HSPAP = (1 << android.hardware.radio.RadioTechnology.HSPAP) /* 32768 */,
+  GSM = (1 << android.hardware.radio.RadioTechnology.GSM) /* 65536 */,
+  TD_SCDMA = (1 << android.hardware.radio.RadioTechnology.TD_SCDMA) /* 131072 */,
+  IWLAN = (1 << android.hardware.radio.RadioTechnology.IWLAN) /* 262144 */,
+  /**
+   * @deprecated use LTE instead.
+   */
+  LTE_CA = (1 << android.hardware.radio.RadioTechnology.LTE_CA) /* 524288 */,
+  NR = (1 << android.hardware.radio.RadioTechnology.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 b91bf03..9785825 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
@@ -37,5 +37,5 @@
   const int MAX_RILDS = 3;
   const int MAX_UUID_LENGTH = 64;
   const int CARD_MAX_APPS = 8;
-  const int P2_CONSTANT_NO_P2 = -1;
+  const int P2_CONSTANT_NO_P2 = (-1) /* -1 */;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl
index 54ea3a4..58b35a5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl
@@ -34,6 +34,6 @@
 package android.hardware.radio;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioIndicationType {
-  UNSOLICITED = 0,
-  UNSOLICITED_ACK_EXP = 1,
+  UNSOLICITED,
+  UNSOLICITED_ACK_EXP,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl
index 5cd99c4..1ee62bd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl
@@ -34,7 +34,7 @@
 package android.hardware.radio;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioResponseType {
-  SOLICITED = 0,
-  SOLICITED_ACK = 1,
-  SOLICITED_ACK_EXP = 2,
+  SOLICITED,
+  SOLICITED_ACK,
+  SOLICITED_ACK_EXP,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
index 9dad0a4..b6af5aa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
@@ -34,25 +34,28 @@
 package android.hardware.radio;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioTechnology {
-  UNKNOWN = 0,
-  GPRS = 1,
-  EDGE = 2,
-  UMTS = 3,
-  IS95A = 4,
-  IS95B = 5,
-  ONE_X_RTT = 6,
-  EVDO_0 = 7,
-  EVDO_A = 8,
-  HSDPA = 9,
-  HSUPA = 10,
-  HSPA = 11,
-  EVDO_B = 12,
-  EHRPD = 13,
-  LTE = 14,
-  HSPAP = 15,
-  GSM = 16,
-  TD_SCDMA = 17,
-  IWLAN = 18,
-  LTE_CA = 19,
-  NR = 20,
+  UNKNOWN,
+  GPRS,
+  EDGE,
+  UMTS,
+  IS95A,
+  IS95B,
+  ONE_X_RTT,
+  EVDO_0,
+  EVDO_A,
+  HSDPA,
+  HSUPA,
+  HSPA,
+  EVDO_B,
+  EHRPD,
+  LTE,
+  HSPAP,
+  GSM,
+  TD_SCDMA,
+  IWLAN,
+  /**
+   * @deprecated use LTE instead and indicate carrier aggregation through multiple physical channel configurations in IRadioNetwork::currentPhysicalChannelConfigs.
+   */
+  LTE_CA,
+  NR,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
index e6fdce2..2af7e53 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
@@ -34,6 +34,6 @@
 package android.hardware.radio;
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioTechnologyFamily {
-  THREE_GPP = 0,
-  THREE_GPP2 = 1,
+  THREE_GPP,
+  THREE_GPP2,
 }
diff --git a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
index 6cd0a95..edf33ba 100644
--- a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
@@ -41,6 +41,7 @@
     GSM = 1 << RadioTechnology.GSM,
     TD_SCDMA = 1 << RadioTechnology.TD_SCDMA,
     IWLAN = 1 << RadioTechnology.IWLAN,
+    /** @deprecated use LTE instead. */
     LTE_CA = 1 << RadioTechnology.LTE_CA,
     /**
      * 5G NR. This is only use in 5G Standalone mode.
diff --git a/radio/aidl/android/hardware/radio/RadioError.aidl b/radio/aidl/android/hardware/radio/RadioError.aidl
index ae58a0e..2031399 100644
--- a/radio/aidl/android/hardware/radio/RadioError.aidl
+++ b/radio/aidl/android/hardware/radio/RadioError.aidl
@@ -41,6 +41,9 @@
      * Operation requires SIM PUK2 to be entered
      */
     SIM_PUK2 = 5,
+    /**
+     * Optional API
+     */
     REQUEST_NOT_SUPPORTED = 6,
     CANCELLED = 7,
     /**
@@ -177,7 +180,8 @@
      */
     NO_SMS_TO_ACK = 48,
     /**
-     * Received error from network
+     * Received error from network. This generic error code should be used only when the error
+     * cannot be mapped to other specific network error codes.
      */
     NETWORK_ERR = 49,
     /**
diff --git a/radio/aidl/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/android/hardware/radio/RadioTechnology.aidl
index 917cb16..4b51152 100644
--- a/radio/aidl/android/hardware/radio/RadioTechnology.aidl
+++ b/radio/aidl/android/hardware/radio/RadioTechnology.aidl
@@ -45,6 +45,10 @@
     GSM,
     TD_SCDMA,
     IWLAN,
+    /**
+     * @deprecated use LTE instead and indicate carrier aggregation through multiple
+     * physical channel configurations in IRadioNetwork::currentPhysicalChannelConfigs.
+     */
     LTE_CA,
     /**
      * 5G NR. This is only used in 5G Standalone mode.
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
index 929f02d..0d36bbd 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -54,7 +54,6 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void getNumOfLiveModemsResponse(
             in android.hardware.radio.RadioResponseInfo info, in byte numOfLiveModems);
@@ -93,7 +92,6 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
      */
     void setNumOfLiveModemsResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl b/radio/aidl/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
new file mode 100644
index 0000000..b18ea0e
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.config;
+
+/**
+ * Multiple Enabled Profiles(MEP) mode is the jointly supported MEP mode. As per section 3.4.1.1 of
+ * GSMA spec SGP.22 v3.0,there are 3 supported MEP modes: MEP-A1, MEP-A2 and MEP-B.
+ * If there is no jointly supported MEP mode, supported MEP mode is set to NONE.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum MultipleEnabledProfilesMode {
+    /**
+     * If there is no jointly supported MEP mode, set supported MEP mode to NONE.
+     */
+    NONE,
+    /**
+     * In case of MEP-A1, the ISD-R is selected on eSIM port 0 only and profiles are selected on
+     * eSIM ports 1 and higher, with the eSIM port being assigned by the LPA or platform.
+     */
+    MEP_A1,
+    /**
+     * In case of MEP-A2, the ISD-R is selected on eSIM port 0 only and profiles are selected on
+     * eSIM ports 1 and higher, with the eSIM port being assigned by the eUICC.
+     */
+    MEP_A2,
+    /**
+     * In case of MEP-B, profiles are selected on eSIM ports 0 and higher, with the ISD-R being
+     * selectable on any of these eSIM ports.
+     */
+    MEP_B,
+}
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index 748660f..6a36d5e 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.radio.config;
 
+import android.hardware.radio.config.MultipleEnabledProfilesMode;
 import android.hardware.radio.config.SimPortInfo;
 
 @VintfStability
@@ -52,4 +53,9 @@
      * active port in the slot mapping.
      */
     SimPortInfo[] portInfo;
+    /**
+     * Jointly supported Multiple Enabled Profiles(MEP) mode as per SGP.22 V3.0. Should always
+     * report proper MEP mode irrespective of whether the slot is active or inactive.
+     */
+    MultipleEnabledProfilesMode supportedMepMode = MultipleEnabledProfilesMode.NONE;
 }
diff --git a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
index 29ece76..071ce55 100644
--- a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
@@ -911,10 +911,14 @@
      */
     PDP_MODIFY_COLLISION = 0x875,
     /**
-     * Maximum size of the L2 message was exceeded.
+     * @deprecated use MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED instead.
      */
     MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
     /**
+     * Maximum size of the L2 message was exceeded.
+     */
+    MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
+    /**
      * Non-access stratum (NAS) request was rejected by the network.
      */
     NAS_REQUEST_REJECTED_BY_NETWORK = 0x877,
diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
index 88b6c1b..06c83c1 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
@@ -44,7 +44,6 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_RESOURCES- Indicates that no pdu session ids are available
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void allocatePduSessionIdResponse(in RadioResponseInfo info, in int id);
 
@@ -57,7 +56,6 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_RESOURCES
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_CALL_ID
      */
     void cancelHandoverResponse(in RadioResponseInfo info);
@@ -66,7 +64,6 @@
      * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
-     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
      *   RadioError:NONE indicates success. Any other error will remove the network from the list.
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_CALL_ID
@@ -112,7 +109,6 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_RESOURCES
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void releasePduSessionIdResponse(in RadioResponseInfo info);
 
@@ -131,7 +127,6 @@
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void setDataAllowedResponse(in RadioResponseInfo info);
 
@@ -146,7 +141,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_ABSENT
      */
     void setDataProfileResponse(in RadioResponseInfo info);
@@ -159,7 +153,6 @@
      *  RadioError:RADIO_NOT_AVAILABLE
      *  RadioError:MODEM_ERR
      *  RadioError:INVALID_ARGUMENTS
-     *  RadioError:REQUEST_NOT_SUPPORTED
      */
     void setDataThrottlingResponse(in RadioResponseInfo info);
 
@@ -176,7 +169,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NOT_PROVISIONED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -208,7 +200,6 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_RESOURCES
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_CALL_ID
      */
     void startHandoverResponse(in RadioResponseInfo info);
diff --git a/radio/aidl/android/hardware/radio/data/NrQos.aidl b/radio/aidl/android/hardware/radio/data/NrQos.aidl
index af8ab83..4078fdc 100644
--- a/radio/aidl/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/android/hardware/radio/data/NrQos.aidl
@@ -27,6 +27,8 @@
     const byte FLOW_ID_RANGE_MIN = 1;
     const byte FLOW_ID_RANGE_MAX = 63;
 
+    const int AVERAGING_WINDOW_UNKNOWN = -1;
+
     /**
      * 5G QOS Identifier (5QI), see 3GPP TS 24.501 and 23.501. The allowed values are standard
      * values (1-9, 65-68, 69-70, 75, 79-80, 82-85) defined in the spec and operator specific values
@@ -37,8 +39,15 @@
     QosBandwidth uplink;
     /**
      * QOS flow identifier of the QOS flow description in the range
-     * (FLOW_ID_RANGE_MIN, FLOW_ID_RANGE_MAX)
+     * (FLOW_ID_RANGE_MIN, FLOW_ID_RANGE_MAX).
      */
     byte qfi;
+    /**
+     * @deprecated use averagingWindowMillis;
+     */
     char averagingWindowMs;
+    /**
+     * The duration over which flow rates are calculated.
+     */
+    int averagingWindowMillis = AVERAGING_WINDOW_UNKNOWN;
 }
diff --git a/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl b/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl
new file mode 100644
index 0000000..70faa1e
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable ConnectionFailureInfo {
+
+    @VintfStability
+    @Backing(type="int")
+    enum ConnectionFailureReason {
+        /** Access class check failed */
+        REASON_ACCESS_DENIED = 1,
+        /** 3GPP Non-access stratum failure */
+        REASON_NAS_FAILURE = 2,
+        /** Random access failure */
+        REASON_RACH_FAILURE = 3,
+        /** Radio link failure */
+        REASON_RLC_FAILURE = 4,
+        /** Radio connection establishment rejected by network */
+        REASON_RRC_REJECT = 5,
+        /** Radio connection establishment timed out */
+        REASON_RRC_TIMEOUT = 6,
+        /** Device currently not in service */
+        REASON_NO_SERVICE = 7,
+        /** The PDN is no more active */
+        REASON_PDN_NOT_AVAILABLE = 8,
+        /** Radio resource is busy with another subscription */
+        REASON_RF_BUSY = 9,
+        REASON_UNSPECIFIED = 0xFFFF,
+    }
+
+    /**
+     * Values are REASON_* constants
+     */
+    ConnectionFailureReason failureReason;
+
+    /**
+     * Failure cause code from network or modem specific to the failure
+     */
+    int causeCode;
+
+    /**
+     * Retry wait time provided by network in milliseconds
+     */
+    int waitTimeMillis;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/EpsFallbackReason.aidl b/radio/aidl/android/hardware/radio/ims/EpsFallbackReason.aidl
new file mode 100644
index 0000000..670638b
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/EpsFallbackReason.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum EpsFallbackReason {
+    /**
+     * If VoNR is not supported and EPS fallback is not triggered by network then UE initiated EPS
+     * fallback would be triggered by IMS stack with this reason. The modem shall locally release
+     * the 5G NR SA RRC connection and acquire the LTE network and perform a tracking area update
+     * procedure. After the EPS fallback procedure is completed, the call setup for voice will
+     * be established.
+     */
+    NO_NETWORK_TRIGGER = 1,
+
+    /**
+     * If the UE doesn't receive any response for SIP INVITE within a certain time in 5G NR SA,
+     * UE initiated EPS fallback will be triggered with this reason. The modem shall reset its data
+     * buffer of IMS PDUs to prevent the ghost call. After the EPS fallback procedure is completed,
+     * the VoLTE call will be established.
+     */
+    NO_NETWORK_RESPONSE = 2,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/IRadioIms.aidl b/radio/aidl/android/hardware/radio/ims/IRadioIms.aidl
new file mode 100644
index 0000000..bd661a7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/IRadioIms.aidl
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.ims.EpsFallbackReason;
+import android.hardware.radio.ims.IRadioImsIndication;
+import android.hardware.radio.ims.IRadioImsResponse;
+import android.hardware.radio.ims.ImsCall;
+import android.hardware.radio.ims.ImsRegistration;
+import android.hardware.radio.ims.ImsStreamDirection;
+import android.hardware.radio.ims.ImsStreamType;
+import android.hardware.radio.ims.ImsTrafficType;
+import android.hardware.radio.ims.SrvccCall;
+
+/**
+ * This interface is used by IMS telephony layer to talk to cellular radio.
+ * All the functions have minimum one parameter:
+ * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
+ * duration of a method call. If clients provide colliding serials (including passing the same
+ * serial to different methods), multiple responses (one for each method call) must still be served.
+ * setResponseFunctions must work with IRadioImsResponse and IRadioImsIndication.
+ */
+@VintfStability
+oneway interface IRadioIms {
+    /**
+     * Provides a list of SRVCC call information to radio.
+     *
+     * @param serial Serial number of request
+     * @param srvccCalls the list of calls
+     *
+     * Response function is IRadioImsResponse.setSrvccCallInfoResponse()
+     */
+    void setSrvccCallInfo(int serial, in SrvccCall[] srvccCalls);
+
+    /**
+     * Update the IMS registration information to the radio.
+     *
+     * This information shall be used by radio to implement following carrier requirements:
+     * 1) Graceful IMS PDN disconnection on cellular when NAS is about to perform detach
+     * eg. SIM removal or SIM refresh
+     * 2) Block PLMN or RAT based on the IMS registration failure reason
+     *
+     * @param serial Serial number of request
+     * @param imsRegistration IMS registration information
+     *
+     * Response function is IRadioImsResponse.updateImsRegistrationInfoResponse()
+     */
+    void updateImsRegistrationInfo(int serial, in ImsRegistration imsRegistration);
+
+    /**
+     * IMS stack notifies the NAS and RRC layers of the radio that the upcoming IMS traffic is
+     * for the service mentioned in the ImsTrafficType. If this API is not
+     * explicitly invoked and IMS module sends traffic on IMS PDN then the radio
+     * shall treat type as background data traffic type.
+     * This API shall be used by modem
+     *  1. To set the appropriate establishment cause in RRC connection request.
+     *  2. To prioritize RF resources in case of DSDS. The service priority is
+     * EMERGENCY > EMERGENCY SMS > VOICE > VIDEO > SMS > REGISTRATION > Ut/XCAP. The RF
+     * shall be prioritized to the subscription which handles higher priority service.
+     * When both subscriptions are handling the same type of service then RF shall be
+     * prioritized to the voice preferred sub.
+     *  3. To evaluate the overall access barring in the case of ACB, ACB-Skp/SCM and UAC.
+     * The response {@link IRadioImsResponse#startImsTrafficResponse()} with success shall
+     * be sent by modem upon access class is allowed and RF resource is allotted. Otherwise
+     * the same API shall be invoked with appropriate {@link ConnectionFailureInfo}. Further
+     * if RRC connection setup fails then {@link IRadioImsIndication#onConnectionSetupFailure()}
+     * shall be invoked by modem with appropriate {@link ConnectionFailureInfo}.
+     *
+     * @param serial Serial number of request
+     * @param token A nonce to identify the request
+     * @param imsTrafficType IMS traffic type like registration, voice, and video
+     * @param accessNetworkType The type of the radio access network used
+     * @param trafficDirection Indicates whether traffic is originated by mobile originated or
+     *        mobile terminated use case eg. MO/MT call/SMS etc
+     *
+     * Response function is IRadioImsResponse.startImsTrafficResponse()
+     */
+    void startImsTraffic(int serial, int token,
+            ImsTrafficType imsTrafficType, AccessNetwork accessNetworkType,
+            ImsCall.Direction trafficDirection);
+
+    /**
+     * Indicates IMS traffic has been stopped.
+     * For all IMS traffic, notified with startImsTraffic, IMS service shall notify
+     * stopImsTraffic when it completes the traffic specified by the token.
+     *
+     * @param serial Serial number of request
+     * @param token The token assigned by startImsTraffic()
+     *
+     * Response function is IRadioImsResponse.stopImsTrafficResponse()
+     */
+    void stopImsTraffic(int serial, int token);
+
+    /**
+     * Triggers the UE initiated EPS fallback when a MO voice call failed to establish on 5G NR
+     * network and network didn't initiate a fallback.
+     *
+     * @param serial Serial number of request
+     * @param reason Specifies the reason that causes EPS fallback
+     *
+     * Response function is IRadioImsResponse.triggerEpsFallbackResponse()
+     */
+    void triggerEpsFallback(int serial, in EpsFallbackReason reason);
+
+    /**
+     * Set response functions for IMS radio requests and indications.
+     *
+     * @param radioImsResponse Object containing response functions
+     * @param radioImsIndication Object containing radio indications
+     */
+    void setResponseFunctions(in IRadioImsResponse radioImsResponse,
+            in IRadioImsIndication radioImsIndication);
+
+    /**
+     * Access Network Bitrate Recommendation Query (ANBRQ), see 3GPP TS 26.114.
+     * This API triggers radio to send ANBRQ message
+     * to the access network to query the desired bitrate.
+     *
+     * @param serial Serial number of request
+     * @param mediaType Media type is used to identify media stream such as audio or video
+     * @param direction Direction of this packet stream (e.g. uplink or downlink)
+     * @param bitsPerSecond The bit rate requested by the opponent UE
+     *
+     * Response function is IRadioImsResponse.sendAnbrQueryResponse()
+     */
+    void sendAnbrQuery(int serial, ImsStreamType mediaType, ImsStreamDirection direction, int bitsPerSecond);
+
+    /**
+     * Provides a list of IMS call information to radio.
+     *
+     * @param serial Serial number of request
+     * @param imsCalls The list of IMS calls
+     *
+     * Response function is IRadioImsResponse.updateImsCallStatusResponse()
+     */
+    void updateImsCallStatus(int serial, in ImsCall[] imsCalls);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl b/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
new file mode 100644
index 0000000..d123d07
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.RadioIndicationType;
+import android.hardware.radio.ims.ConnectionFailureInfo;
+import android.hardware.radio.ims.ImsDeregistrationReason;
+import android.hardware.radio.ims.ImsStreamDirection;
+import android.hardware.radio.ims.ImsStreamType;
+
+/**
+ * Interface declaring unsolicited radio indications for ims APIs.
+ */
+@VintfStability
+oneway interface IRadioImsIndication {
+    /**
+     * Fired by radio when any IMS traffic is not sent to network due to any failure
+     * on cellular networks. IMS service shall call stopImsTraffic when receiving
+     * this indication.
+     *
+     * @param type Type of radio indication
+     * @param token The token of startImsTraffic() associated with this indication
+     * @param info Connection failure information
+     */
+    void onConnectionSetupFailure(
+            in RadioIndicationType type, int token, in ConnectionFailureInfo info);
+
+    /**
+     * Access Network Bitrate Recommendation (ANBR), see 3GPP TS 26.114.
+     * Notifies the bit rate received from the network via ANBR message
+     *
+     * @param type Type of radio indication
+     * @param mediaType Media type is used to identify media stream such as audio or video
+     * @param direction Direction of this packet stream (e.g. uplink or downlink)
+     * @param bitsPerSecond The recommended bit rate for the UE
+     * for a specific logical channel and a specific direction by NW
+     */
+    void notifyAnbr(in RadioIndicationType type, in ImsStreamType mediaType,
+            in ImsStreamDirection direction, int bitsPerSecond);
+
+    /**
+     * Requests IMS stack to perform graceful IMS deregistration before radio performing
+     * network detach in the events of SIM remove, refresh or and so on. The radio waits for
+     * the IMS deregistration, which will be notified by telephony via
+     * {@link IRadioIms#updateImsRegistrationInfo()}, or a certain timeout interval to start
+     * the network detach procedure.
+     *
+     * @param type Type of radio indication
+     * @param reason the reason why the deregistration is triggered
+     */
+    void triggerImsDeregistration(in RadioIndicationType type, in ImsDeregistrationReason reason);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/IRadioImsResponse.aidl b/radio/aidl/android/hardware/radio/ims/IRadioImsResponse.aidl
new file mode 100644
index 0000000..ff516cc
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/IRadioImsResponse.aidl
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.RadioResponseInfo;
+import android.hardware.radio.ims.ConnectionFailureInfo;
+
+/**
+ * Interface declaring response functions to solicited radio requests for ims APIs.
+ */
+@VintfStability
+oneway interface IRadioImsResponse {
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:NO_MEMORY
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     */
+    void setSrvccCallInfoResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:NO_MEMORY
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     */
+    void updateImsRegistrationInfoResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     * @param failureInfo Information about failure in detail. If there is no error,
+     *        it should be {@code null}.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:NO_MEMORY
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     */
+    void startImsTrafficResponse(in RadioResponseInfo info,
+            in @nullable ConnectionFailureInfo failureInfo);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:NO_MEMORY
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     */
+    void stopImsTrafficResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:NO_MEMORY
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     */
+    void triggerEpsFallbackResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:NO_MEMORY
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     */
+    void sendAnbrQueryResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:NO_MEMORY
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:MODEM_ERR
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:NO_RESOURCES
+     */
+    void updateImsCallStatusResponse(in RadioResponseInfo info);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsCall.aidl b/radio/aidl/android/hardware/radio/ims/ImsCall.aidl
new file mode 100644
index 0000000..b71682f
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsCall.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.AccessNetwork;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable ImsCall {
+
+    @Backing(type="int")
+    enum CallType {
+        NORMAL,
+        EMERGENCY,
+    }
+
+    @Backing(type="int")
+    enum CallState {
+        ACTIVE,
+        HOLDING,
+        DIALING, /* Outgoing only */
+        ALERTING, /* Outgoing only */
+        INCOMING, /* Incoming only */
+        WAITING, /* Incoming only */
+        DISCONNECTING,
+        DISCONNECTED,
+    }
+
+    @Backing(type="int")
+    enum Direction {
+        INCOMING,
+        OUTGOING,
+    }
+
+    /** Call index */
+    int index;
+
+    /** The type of the call */
+    CallType callType;
+
+    /** The access network where the call is in progress */
+    AccessNetwork accessNetwork;
+
+    /** The state of the call */
+    CallState callState;
+
+    /** The direction of the call */
+    Direction direction;
+
+    /** True if the call is put on HOLD by the other party */
+    boolean isHeldByRemote;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl b/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
new file mode 100644
index 0000000..eac8db4
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum ImsDeregistrationReason {
+    /**
+     * Radio shall send this reason to IMS stack to perform graceful de-registration
+     * due to SIM card is removed.
+     */
+    REASON_SIM_REMOVED = 1,
+    /**
+     * Radio shall send this reason to IMS stack to perform graceful de-registration
+     * due to SIM refresh that needs a NAS detach and re-attach.
+     */
+    REASON_SIM_REFRESH = 2,
+    /**
+     * Radio shall send this reason to IMS stack to perform graceful de-registration
+     * due to allowed network types bitmask changed that results in NAS detach.
+     */
+    REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl b/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl
new file mode 100644
index 0000000..662f9e9
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.ims.ImsRegistrationState;
+import android.hardware.radio.ims.SuggestedAction;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable ImsRegistration {
+    /** Default value */
+    const int IMS_MMTEL_CAPABILITY_NONE = 0;
+    /** IMS voice */
+    const int IMS_MMTEL_CAPABILITY_VOICE = 1 << 0;
+    /** IMS video */
+    const int IMS_MMTEL_CAPABILITY_VIDEO = 1 << 1;
+    /** IMS SMS */
+    const int IMS_MMTEL_CAPABILITY_SMS = 1 << 2;
+    /** IMS RCS */
+    const int IMS_RCS_CAPABILITIES = 1 << 3;
+
+    /** Indicates the current IMS registration state. */
+    ImsRegistrationState regState;
+
+    /**
+     * Indicates the type of the radio access network where IMS is registered.
+     */
+    AccessNetwork accessNetworkType;
+
+    /** Indicates the expected action for the radio to do. */
+    SuggestedAction suggestedAction;
+
+    /**
+     * Values are bitwise ORs of IMS_MMTEL_CAPABILITY_* constants and IMS_RCS_CAPABILITIES.
+     * IMS capability such as VOICE, VIDEO, SMS and RCS.
+     */
+    int capabilities;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsRegistrationState.aidl b/radio/aidl/android/hardware/radio/ims/ImsRegistrationState.aidl
new file mode 100644
index 0000000..fd5c0fa
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsRegistrationState.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum ImsRegistrationState {
+    /** IMS is not registered */
+    NOT_REGISTERED,
+
+    /** IMS is successfully registered */
+    REGISTERED,
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/ims/ImsStreamDirection.aidl b/radio/aidl/android/hardware/radio/ims/ImsStreamDirection.aidl
new file mode 100644
index 0000000..c0cea32
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsStreamDirection.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum ImsStreamDirection {
+    /** DIRECTION_UPLINK - From UE to Network **/
+    UPLINK = 1,
+    /** DIRECTION_DOWNLINK - From Network to UE **/
+    DOWNLINK = 2,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsStreamType.aidl b/radio/aidl/android/hardware/radio/ims/ImsStreamType.aidl
new file mode 100644
index 0000000..c12a0c1
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsStreamType.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@Backing(type="int")
+enum ImsStreamType {
+    /** Media Stream Type - Audio **/
+    AUDIO = 1,
+    /** Media Stream Type - Video **/
+    VIDEO = 2,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsTrafficType.aidl b/radio/aidl/android/hardware/radio/ims/ImsTrafficType.aidl
new file mode 100644
index 0000000..5a824c0
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsTrafficType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum ImsTrafficType {
+    /** Emergency call */
+    EMERGENCY,
+
+    /** Emergency SMS */
+    EMERGENCY_SMS,
+
+    /** Voice call */
+    VOICE,
+
+    /** Video call */
+    VIDEO,
+
+    /** SMS over IMS */
+    SMS,
+
+    /** IMS registration and subscription for reg event package (signaling) */
+    REGISTRATION,
+
+    /** Ut/XCAP (XML Configuration Access Protocol) */
+    UT_XCAP
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl b/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl
new file mode 100644
index 0000000..38e6cdb
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable SrvccCall {
+
+    @VintfStability
+    @Backing(type="int")
+    enum CallType {
+        NORMAL,
+        EMERGENCY,
+    }
+
+    @VintfStability
+    @Backing(type="int")
+    enum CallSubState {
+        NONE,
+        /** Pre-alerting state. Applicable for MT calls only */
+        PREALERTING,
+    }
+
+    @VintfStability
+    @Backing(type="int")
+    enum ToneType {
+        NONE,
+        LOCAL,
+        NETWORK,
+    }
+
+    /** Connection index */
+    int index;
+
+    /** The type of the call */
+    CallType callType;
+
+    /** Values are android.hardware.radio.voice.Call.STATE_* constants */
+    int callState;
+
+    /** The substate of the call */
+    CallSubState callSubstate;
+
+    /** The type of the ringback tone */
+    ToneType ringbackToneType;
+
+    /** true if is mpty call */
+    boolean isMpty;
+
+    /** true if call is mobile terminated */
+    boolean isMT;
+
+    /** Remote party nummber */
+    String number;
+
+    /** Values are android.hardware.radio.voice.Call.PRESENTATION_* constants */
+    int numPresentation;
+
+    /** Remote party name */
+    String name;
+
+    /** Values are android.hardware.radio.voice.Call.PRESENTATION_* constants */
+    int namePresentation;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
new file mode 100644
index 0000000..2d12ed6
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum SuggestedAction {
+    /** Default value */
+    NONE,
+    /**
+     * Indicates that the IMS registration is failed with fatal error such as 403 or 404
+     * on all P-CSCF addresses. The radio shall block the current PLMN or disable
+     * the RAT as per the carrier requirements.
+     */
+    TRIGGER_PLMN_BLOCK,
+    /**
+     * Indicates that the IMS registration on current PLMN failed multiple times.
+     * The radio shall block the current PLMN or disable the RAT during EPS or 5GS mobility
+     * management timer value as per the carrier requirements.
+     */
+    TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/AmrMode.aidl b/radio/aidl/android/hardware/radio/ims/media/AmrMode.aidl
new file mode 100644
index 0000000..66d8ef0
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/AmrMode.aidl
@@ -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.
+ */
+
+package android.hardware.radio.ims.media;
+
+/** AMR codec mode to represent the bit rate. See 3ggp Specs 26.976 & 26.071 */
+@VintfStability
+@Backing(type="int")
+enum AmrMode {
+    /** 4.75 kbps for AMR / 6.6 kbps for AMR-WB */
+    AMR_MODE_0 = 1 << 0,
+    /** 5.15 kbps for AMR / 8.855 kbps for AMR-WB */
+    AMR_MODE_1 = 1 << 1,
+    /** 5.9 kbps for AMR / 12.65 kbps for AMR-WB */
+    AMR_MODE_2 = 1 << 2,
+    /** 6.7 kbps for AMR / 14.25 kbps for AMR-WB */
+    AMR_MODE_3 = 1 << 3,
+    /** 7.4 kbps for AMR / 15.85 kbps for AMR-WB */
+    AMR_MODE_4 = 1 << 4,
+    /** 7.95 kbps for AMR / 18.25 kbps for AMR-WB */
+    AMR_MODE_5 = 1 << 5,
+    /** 10.2 kbps for AMR / 19.85 kbps for AMR-WB */
+    AMR_MODE_6 = 1 << 6,
+    /** 12.2 kbps for AMR / 23.05 kbps for AMR-WB */
+    AMR_MODE_7 = 1 << 7,
+    /** Silence frame for AMR / 23.85 kbps for AMR-WB */
+    AMR_MODE_8 = 1 << 8,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/AmrParams.aidl b/radio/aidl/android/hardware/radio/ims/media/AmrParams.aidl
new file mode 100644
index 0000000..4ed3a24
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/AmrParams.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.ims.media;
+
+import android.hardware.radio.ims.media.AmrMode;
+
+@VintfStability
+parcelable AmrParams {
+    /** mode-set: AMR codec mode to represent the bit rate */
+    AmrMode amrMode;
+    /**
+     * octet-align: If it's set to true then all fields in the AMR/AMR-WB header
+     * shall be aligned to octet boundaries by adding padding bits.
+     */
+    boolean octetAligned;
+    /**
+     * max-red: It’s the maximum duration in milliseconds that elapses between the
+     * primary (first) transmission of a frame and any redundant transmission that
+     * the sender will use. This parameter allows a receiver to have a bounded delay
+     * when redundancy is used. Allowed values are between 0 (no redundancy will be
+     * used) and 65535. If the parameter is omitted, no limitation on the use of
+     * redundancy is present. See RFC 4867
+     */
+    int maxRedundancyMillis;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl b/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl
new file mode 100644
index 0000000..f758cd4
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.CodecMode;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable AnbrMode {
+    /**
+     * Codec mode converted from bitrate received for uplink
+     * from network or peer UE for ANBR
+     */
+    CodecMode anbrUplinkMode;
+    /**
+     * Codec mode converted from bitrate received for downlink
+     * from network or peer UE for ANBR
+     */
+    CodecMode anbrDownlinkMode;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl b/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl
new file mode 100644
index 0000000..a8f7b16
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+parcelable CallQuality {
+    /**
+     * downlink CallQualityLevel for a given ongoing call
+     * this value corresponds to the CALL_QUALITY_* constants in {@link CallQuality}
+     */
+    int downlinkCallQualityLevel;
+    /**
+     * uplink CallQualityLevel for a given ongoing call
+     * this value corresponds to the CALL_QUALITY_* constants in {@link CallQuality}
+     */
+    int uplinkCallQualityLevel;
+    /** the call duration in milliseconds */
+    int callDuration;
+    /** RTP packets sent to network */
+    int numRtpPacketsTransmitted;
+    /** RTP packets received from network */
+    int numRtpPacketsReceived;
+    /** RTP packets which were lost in network and never transmitted */
+    int numRtpPacketsTransmittedLost;
+    /** RTP packets which were lost in network and never received */
+    int numRtpPacketsNotReceived;
+    /** average relative jitter in milliseconds */
+    int averageRelativeJitter;
+    /** maximum relative jitter in milliseconds */
+    int maxRelativeJitter;
+    /** average round trip delay in milliseconds */
+    int averageRoundTripTime;
+    /**
+     * the codec type. This value corresponds to the AUDIO_QUALITY_* constants in
+     * {@link ImsStreamMediaProfile}
+     */
+    int codecType;
+    /** True if no incoming RTP is received for a continuous duration of 4 seconds */
+    boolean rtpInactivityDetected;
+    /**
+     * True if only silence RTP packets are received for 20 seconds
+     * immediately after call is connected
+     */
+    boolean rxSilenceDetected;
+    /**
+     * True if only silence RTP packets are sent for 20 seconds
+     * immediately after call is connected
+     */
+    boolean txSilenceDetected;
+    /** the number of Voice frames sent by jitter buffer to audio */
+    int numVoiceFrames;
+    /** the number of no-data frames sent by jitter buffer to audio */
+    int numNoDataFrames;
+    /** the number of RTP voice packets dropped by jitter buffer */
+    int numDroppedRtpPackets;
+    /** the minimum playout delay in the reporting interval in milliseconds */
+    long minPlayoutDelayMillis;
+    /** the maximum playout delay in the reporting interval in milliseconds */
+    long maxPlayoutDelayMillis;
+    /**
+     * the total number of RTP SID (Silence Insertion Descriptor) packets
+     * received by this device for an ongoing call
+     */
+    int numRtpSidPacketsReceived;
+    /**
+     * the total number of RTP duplicate packets received by this device
+     * for an ongoing call
+     */
+    int numRtpDuplicatePackets;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl
new file mode 100644
index 0000000..aa1b3a4
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.AmrMode;
+import android.hardware.radio.ims.media.EvsMode;
+
+@VintfStability
+@JavaDerive(toString=true)
+union CodecMode {
+    /** Default value */
+    boolean noinit;
+    /** AMR codec mode to represent the bit rate. See 3ggp Specs 26.976 & 26.071 */
+    AmrMode amr;
+    /** EVS codec mode to represent the bit rate. See 3ggp Spec 26.952 Table 5.1 */
+    EvsMode evs;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecParams.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecParams.aidl
new file mode 100644
index 0000000..0aa5505
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecParams.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.ims.media;
+
+import android.hardware.radio.ims.media.CodecSpecificParams;
+import android.hardware.radio.ims.media.CodecType;
+
+@VintfStability
+parcelable CodecParams {
+    /** Negotiated codec type */
+    CodecType codecType;
+    /**
+     * Static or dynamic payload type number negotiated through the SDP for
+     * the incoming RTP packets. This value shall be matched with the PT value
+     * of the incoming RTP header. Values 0 to 127, see RFC 3551 section 6
+     */
+    byte rxPayloadTypeNumber;
+    /**
+     * Static or dynamic payload type number negotiated through the SDP for
+     * the outgoing RTP packets. This value shall be set to the PT value
+     * of the outgoing RTP header. Values 0 to 127, see RFC 3551 section 6
+     */
+    byte txPayloadTypeNumber;
+    /** Sampling rate in kHz*/
+    byte samplingRateKHz;
+    /** dtx: Whether discontinuous transmission is enabled or not */
+    boolean dtxEnabled;
+    /** Codec specific parameters */
+    CodecSpecificParams codecSpecificParams;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl
new file mode 100644
index 0000000..4410c81
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.ims.media;
+
+import android.hardware.radio.ims.media.AmrParams;
+import android.hardware.radio.ims.media.EvsParams;
+
+@VintfStability
+union CodecSpecificParams {
+    AmrParams amr;
+    EvsParams evs;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecType.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecType.aidl
new file mode 100644
index 0000000..31218e3
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecType.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.radio.ims.media;
+
+@VintfStability
+@Backing(type="int")
+enum CodecType {
+    /** Adaptive Multi-Rate */
+    AMR = 1 << 0,
+    /** Adaptive Multi-Rate Wide Band */
+    AMR_WB = 1 << 1,
+    /** Enhanced Voice Services */
+    EVS = 1 << 2,
+    /** G.711 A-law i.e. Pulse Code Modulation using A-law */
+    PCMA = 1 << 3,
+    /** G.711 μ-law i.e. Pulse Code Modulation using μ-law */
+    PCMU = 1 << 4,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
new file mode 100644
index 0000000..a7dcb0d
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.ims.media;
+
+@VintfStability
+parcelable DtmfParams {
+    /**
+     * Dynamic payload type number to be used for DTMF RTP packets received.
+     * The values is in the range from 96 to 127 chosen during the session
+     * establishment. The PT  value of the RTP header of all DTMF packets shall be
+     * set with this value.
+     */
+    byte rxPayloadTypeNumber;
+
+    /**
+     * Dynamic payload type number to be used for DTMF RTP packets sent.
+     * The values is in the range from 96 to 127 chosen during the session
+     * establishment. The PT value of the RTP header of all DTMF packets shall be set
+     * with this value.
+     */
+    byte txPayloadTypeNumber;
+
+    /** Sampling rate in kHz */
+    byte samplingRateKHz;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/EvsBandwidth.aidl b/radio/aidl/android/hardware/radio/ims/media/EvsBandwidth.aidl
new file mode 100644
index 0000000..8278514
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/EvsBandwidth.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.ims.media;
+/** EVS Speech codec bandwidths, See 3gpp spec 26.441 Table 1 */
+@VintfStability
+@Backing(type="int")
+enum EvsBandwidth {
+    NONE = 0,
+    NARROW_BAND = 1 << 0,
+    WIDE_BAND = 1 << 1,
+    SUPER_WIDE_BAND = 1 << 2,
+    FULL_BAND = 1 << 3,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/EvsMode.aidl b/radio/aidl/android/hardware/radio/ims/media/EvsMode.aidl
new file mode 100644
index 0000000..95bd6c7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/EvsMode.aidl
@@ -0,0 +1,65 @@
+/*
+ * 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.ims.media;
+
+/** EVS codec mode to represent the bit rate. See 3ggp Spec 26.952 Table 5.1 */
+@VintfStability
+@Backing(type="int")
+enum EvsMode {
+    /** 6.6 kbps for EVS AMR-WB IO */
+    EVS_MODE_0 = 1 << 0,
+    /** 8.855 kbps for AMR-WB IO */
+    EVS_MODE_1 = 1 << 1,
+    /** 12.65 kbps for AMR-WB IO */
+    EVS_MODE_2 = 1 << 2,
+    /** 14.25 kbps for AMR-WB IO */
+    EVS_MODE_3 = 1 << 3,
+    /** 15.85 kbps for AMR-WB IO */
+    EVS_MODE_4 = 1 << 4,
+    /** 18.25 kbps for AMR-WB IO */
+    EVS_MODE_5 = 1 << 5,
+    /** 19.85 kbps for AMR-WB IO */
+    EVS_MODE_6 = 1 << 6,
+    /** 23.05 kbps for AMR-WB IO */
+    EVS_MODE_7 = 1 << 7,
+    /** 23.85 kbps for AMR-WB IO */
+    EVS_MODE_8 = 1 << 8,
+    /** 5.9 kbps for EVS primary */
+    EVS_MODE_9 = 1 << 9,
+    /** 7.2 kbps for EVS primary */
+    EVS_MODE_10 = 1 << 10,
+    /** 8.0 kbps for EVS primary */
+    EVS_MODE_11 = 1 << 11,
+    /** 9.6 kbps for EVS primary */
+    EVS_MODE_12 = 1 << 12,
+    /** 13.2 kbps for EVS primary */
+    EVS_MODE_13 = 1 << 13,
+    /** 16.4 kbps for EVS primary */
+    EVS_MODE_14 = 1 << 14,
+    /** 24.4 kbps for EVS primary */
+    EVS_MODE_15 = 1 << 15,
+    /** 32.0 kbps for EVS primary */
+    EVS_MODE_16 = 1 << 16,
+    /** 48.0 kbps for EVS primary */
+    EVS_MODE_17 = 1 << 17,
+    /** 64.0 kbps for EVS primary */
+    EVS_MODE_18 = 1 << 18,
+    /** 96.0 kbps for EVS primary */
+    EVS_MODE_19 = 1 << 19,
+    /** 128.0 kbps for EVS primary */
+    EVS_MODE_20 = 1 << 20,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl b/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl
new file mode 100644
index 0000000..d138c83
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.ims.media;
+
+import android.hardware.radio.ims.media.EvsBandwidth;
+import android.hardware.radio.ims.media.EvsMode;
+
+@VintfStability
+parcelable EvsParams {
+    /** EVS codec bandwidth */
+    EvsBandwidth bandwidth;
+
+    /** mode-set: EVS codec mode to represent the bit rate */
+    EvsMode evsMode;
+    /**
+     * ch-aw-recv: Channel aware mode for the receive direction. Permissible values
+     * are -1, 0, 2, 3, 5, and 7. If -1, channel-aware mode is disabled in the
+     * session for the receive direction. If 0 or not present, partial redundancy
+     * (channel-aware mode) is not used at the start of the session for the receive
+     * direction. If positive (2, 3, 5, or 7), partial redundancy (channel-aware
+     * mode) is used at the start of the session for the receive direction using the
+     * value as the offset, See 3GPP TS 26.445 section 4.4.5
+     */
+    byte channelAwareMode;
+    /**
+     * hf-only: Header full only is used for the outgoing and incoming packets.
+     * If it's true then the session shall support header full format only else the
+     * session could support both header full format and compact format.
+     */
+    boolean useHeaderFullOnly;
+    /**
+     * evs-mode-switch: Used for switching between EVS Primary mode and EVS AMR-WB IO mode,
+     * If this value is true, the codec operates in AMR-WB IO mode
+     */
+    boolean useEvsModeSwitch;
+    /**
+     * cmr: Codec mode request is used to request the speech codec encoder of the
+     * other party to set the frame type index of speech mode via RTP header, See
+     * 3GPP TS 26.445 section A.3. Allowed values are -1, 0 and 1.
+     */
+    byte codecModeRequest;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/IImsMedia.aidl b/radio/aidl/android/hardware/radio/ims/media/IImsMedia.aidl
new file mode 100644
index 0000000..ecf1370
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/IImsMedia.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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.ims.media;
+
+import android.hardware.radio.ims.media.IImsMediaListener;
+import android.hardware.radio.ims.media.LocalEndPoint;
+import android.hardware.radio.ims.media.RtpConfig;
+import android.hardware.radio.ims.media.RtpError;
+
+/**
+ * This interface is used by IMS media framework to talk to RTP stack located in another processor.
+ */
+@VintfStability
+oneway interface IImsMedia {
+
+    /**
+     * Set the listener functions for receiving notifications from the RTP stack.
+     *
+     * @param mediaListener Object containing listener methods
+     */
+    void setListener(in IImsMediaListener mediaListener);
+
+    /**
+     * Opens a RTP session for the local end point with the associated initial remote configuration
+     * if there is a valid RtpConfig passed. It starts the media flow if the media direction in the
+     * RtpConfig is set to any value other than NO_MEDIA_FLOW. If the open session is successful
+     * then the implementation shall return a new IImsMediaSession binder connection for this
+     * session using IImsMediaListener#onOpenSessionSuccess() API. If the open session is failed
+     * then the implementation shall return the error using IImsMediaListener#onOpenSessionFailure()
+     *
+     * @param sessionId unique identifier of the session
+     * @param localEndPoint provides IP address, port and logical modem id for local RTP endpoint
+     * @param config provides remote end point info and codec details. This could be null initially
+     *        and the application may update this later using modifySession() API.
+     */
+    void openSession(int sessionId, in LocalEndPoint localEndPoint, in RtpConfig config);
+
+    /**
+     * Close the RTP session including cleanup of all the resources associated with the session.
+     * This shall also close the session specific binder connection opened as part of openSession().
+     *
+     * @param sessionId identifier for the rtp session that needs to be closed
+     */
+    void closeSession(int sessionId);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/IImsMediaListener.aidl b/radio/aidl/android/hardware/radio/ims/media/IImsMediaListener.aidl
new file mode 100644
index 0000000..228acb7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/IImsMediaListener.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.ims.media;
+
+import android.hardware.radio.ims.media.IImsMediaSession;
+import android.hardware.radio.ims.media.RtpError;
+
+/**
+ * Interface declaring listener functions for unsolicited IMS media notifications.
+ */
+@VintfStability
+oneway interface IImsMediaListener {
+    /**
+     * Fired when a IImsMedia#openSession() API is successful.
+     *
+     * @param sessionId identifier of the session
+     * @param session new IImsMediaSession binder connection to be used for the session
+     *        specific operations
+     */
+    void onOpenSessionSuccess(int sessionId, IImsMediaSession session);
+
+    /**
+     * Fired when IImsMedia#openSession() API failed to create a new session.
+     *
+     * @param sessionId identifier of the session
+     * @param error one of the following RTP error code
+     *   RtpError :INVALID_PARAM
+     *   RtpError :INTERNAL_ERR
+     *   RtpError :NO_MEMORY
+     *   RtpError :NO_RESOURCES
+     *   RtpError :PORT_UNAVAILABLE
+     */
+    void onOpenSessionFailure(int sessionId, RtpError error);
+
+    /**
+     * Fired when IImsMedia#closeSession() API handled.
+     *
+     * @param sessionId identifier of the session
+     */
+    void onSessionClosed(int sessionId);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl
new file mode 100644
index 0000000..ec2fa2b
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl
@@ -0,0 +1,82 @@
+/*
+ * 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.ims.media;
+
+import android.hardware.radio.ims.media.IImsMediaSessionListener;
+import android.hardware.radio.ims.media.MediaQualityThreshold;
+import android.hardware.radio.ims.media.RtpConfig;
+import android.hardware.radio.ims.media.RtpError;
+import android.hardware.radio.ims.media.RtpHeaderExtension;
+
+/**
+ * Session specific interface used by IMS media framework to talk to the vendor RTP stack.
+ */
+@VintfStability
+oneway interface IImsMediaSession {
+    /**
+     * Set the listener functions to receive IMS media session specific notifications.
+     *
+     * @param sessionListener Object containing notification methods
+     */
+    void setListener(in IImsMediaSessionListener sessionListener);
+
+    /**
+     * Modifies the configuration of the RTP session. It can be used to pause/resume
+     * the media stream by changing the value of the MediaDirection.
+     *
+     * @param config provides remote end point info and codec details
+     */
+    void modifySession(in RtpConfig config);
+
+    /**
+     * Send DTMF digit until the duration expires.
+     *
+     * @param dtmfDigit single char having one of 12 values: 0-9, *, #
+     * @param duration of the key press in milliseconds.
+     */
+    void sendDtmf(char dtmfDigit, int duration);
+
+    /**
+     * Start sending DTMF digit until the stopDtmf() API is received.
+     * If the implementation is currently sending a DTMF tone for which
+     * stopDtmf() is not received yet, then that digit must be stopped first
+     *
+     * @param dtmfDigit single char having one of 12 values: 0-9, *, #
+     */
+    void startDtmf(char dtmfDigit);
+
+    /**
+     * Stop sending the last DTMF digit started by startDtmf().
+     * stopDtmf() without preceding startDtmf() must be ignored.
+     */
+    void stopDtmf();
+
+    /**
+     * Send RTP header extension to the other party in the next RTP packet.
+     *
+     * @param extensions data to be transmitted via RTP header extension
+     */
+    void sendHeaderExtension(in List<RtpHeaderExtension> extensions);
+
+    /**
+     * Sets the media quality threshold parameters of the session to get
+     * media quality notifications.
+     *
+     * @param threshold media quality thresholds for various quality parameters
+     */
+    void setMediaQualityThreshold(in MediaQualityThreshold threshold);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl
new file mode 100644
index 0000000..8341da2
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl
@@ -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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.CallQuality;
+import android.hardware.radio.ims.media.MediaQualityStatus;
+import android.hardware.radio.ims.media.RtpConfig;
+import android.hardware.radio.ims.media.RtpError;
+import android.hardware.radio.ims.media.RtpHeaderExtension;
+
+/**
+ * Interface declaring listener functions for unsolicited IMS media notifications per session.
+ */
+@VintfStability
+oneway interface IImsMediaSessionListener {
+    /**
+     * Notifies the result of IImsMediaSession#modifySession() API.
+     *
+     * @param config The RTP config passed in IImsMediaSession#modifySession() API
+     * @param error RtpError.NONE in case of success else one of the following
+     *   RtpError :INVALID_PARAM
+     *   RtpError :INTERNAL_ERR
+     *   RtpError :NO_MEMORY
+     *   RtpError :NO_RESOURCES
+     */
+    void onModifySessionResponse(in RtpConfig config, RtpError error);
+
+    /**
+     * Indicates when the first Rtp media packet is received by the UE during ring
+     * back, call hold or early media scenarios. This is sent only if the packet is
+     * received on the active remote configuration.
+     *
+     * In case of early media scenarios, the implementation shall play the RTP
+     * packets from the most recently added config.
+     *
+     * @param config The remote config where the media is received
+     */
+    void onFirstMediaPacketReceived(in RtpConfig config);
+
+    /**
+     * RTP header extension received from the other party
+     *
+     * @param extensions content of the received RTP header extension
+     */
+    void onHeaderExtensionReceived(in List<RtpHeaderExtension> extensions);
+
+    /**
+     * Notifies when the measured media quality crosses at least one of
+     * {@link MediaQualityThreshold} set by {@link IImsMediaSession#setMediaQualityThreshold()}.
+     *
+     * @param quality The object of MediaQualityStatus with the rtp and the rtcp statistics.
+     */
+    void notifyMediaQualityStatus(in MediaQualityStatus quality);
+
+    /**
+     * The modem RTP stack fires this API to query whether the desired bitrate mentioned
+     * in the RtpConfig is currently available on the NW or not using ANBRQ message.
+     * See 3GPP TS 26.114.
+     *
+     * @param config containing desired bitrate and direction
+     */
+    void triggerAnbrQuery(in RtpConfig config);
+
+    /**
+     * Notifies the received DTMF digit from the other party
+     *
+     * @param dtmfDigit single char having one of 12 values: 0-9, *, #
+     * @param durationMs The duration to play the tone in milliseconds unit
+     */
+    void onDtmfReceived(char dtmfDigit, int durationMs);
+
+    /**
+     * Notifies when a change to call quality has occurred
+     *
+     * @param CallQuality The call quality statistics of ongoing call since last report
+     */
+    void onCallQualityChanged(in CallQuality callQuality);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/LocalEndPoint.aidl b/radio/aidl/android/hardware/radio/ims/media/LocalEndPoint.aidl
new file mode 100644
index 0000000..2bd48c6
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/LocalEndPoint.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.ims.media;
+
+import android.os.ParcelFileDescriptor;
+
+@VintfStability
+parcelable LocalEndPoint {
+    /** Socket file descriptor for RTP traffic */
+    ParcelFileDescriptor rtpFd;
+    /** Socket file descriptor for RTCP traffic */
+    ParcelFileDescriptor rtcpFd;
+    /** The logical modem ID, returned by IRadioConfig.getPhoneCapability() */
+    int modemId;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/MediaDirection.aidl b/radio/aidl/android/hardware/radio/ims/media/MediaDirection.aidl
new file mode 100644
index 0000000..e5c34c7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/MediaDirection.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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.ims.media;
+
+/**
+ * Directions can be combined to meet various media direction
+ * requirements depending on the scenario.
+ *
+ * Examples:
+ *     No Flow      : NO_FLOW - eg. SRVCC.
+ *     RTCP-only    : RTCP_TX | RTCP_RX - eg. Local Hold or Dual Hold.
+ *     Receive-Only : RTP_RX | RTCP_TX | RTCP_RX - eg. Remote Hold.
+ *     Send-Receive : RTP_TX | RTP_RX | RTCP_TX | RTCP_RX - eg. Active call.
+ *     Send-Only    : RTP_TX | RTCP_TX | RTCP_RX - eg. Simplex call, voice mail, etc
+ */
+@VintfStability
+@Backing(type="int")
+enum MediaDirection {
+    /**
+     * No RTP/RTCP flow in either direction. The implementation
+     * may release the audio resource. Eg. SRVCC.
+     */
+    NO_FLOW = 0,
+
+    /** Send RTP packets */
+    RTP_TX = 1 << 0,
+
+    /** Receive and processes RTP packets */
+    RTP_RX = 1 << 1,
+
+    /** Send RTCP packets */
+    RTCP_TX = 1 << 2,
+
+    /** Receive RTCP packets */
+    RTCP_RX = 1 << 3,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.aidl b/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.aidl
new file mode 100644
index 0000000..b99e501
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+parcelable MediaQualityStatus {
+    /**
+     * Rtp inactivity observed as per threshold set by
+     * {@link IImsMediaSession#setMediaQualityThreshold()}
+     */
+    int rtpInactivityTimeMillis;
+    /**
+     * Rtcp inactivity observed as per threshold set by
+     * {@link IImsMediaSession#setMediaQualityThreshold()}
+     */
+    int rtcpInactivityTimeMillis;
+    /**
+     * Rtp packet loss rate observed as per threshold set by
+     * {@link IImsMediaSession#setMediaQualityThreshold()}
+     */
+    int rtpPacketLossRate;
+    /**
+     * Rtp jitter observed as per threshold set by
+     * {@link IImsMediaSession#setMediaQualityThreshold()}
+     */
+    int rtpJitterMillis;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl b/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
new file mode 100644
index 0000000..bf98928
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
@@ -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.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+parcelable MediaQualityThreshold {
+    /** Array including threshold values in milliseconds for monitoring RTP inactivity */
+    int[] rtpInactivityTimerMillis;
+    /** Timer in milliseconds for monitoring RTCP inactivity */
+    int rtcpInactivityTimerMillis;
+    /**
+     * This value determines the size of the time window (in milliseconds)
+     * required to calculate the packet loss rate per second for the manner of
+     * smoothly monitoring changes in the packet loss rate value.
+     */
+    int rtpPacketLossDurationMillis;
+    /**
+     * The threshold hysteresis time for packet loss and jitter. This has a goal to prevent
+     * frequent ping-pong notification. So whenever a notifier needs to report the cross of
+     * threshold in opposite direction, this hysteresis timer should be respected.
+     */
+    int rtpHysteresisTimeInMillis;
+    /**
+     * Array including threshold values of Packet loss rate in percentage of
+     * (total number of packets lost) / (total number of packets expected) calculated
+     * every one sec with the packet received in rtpPacketLossDurationMillis.
+     */
+    int[] rtpPacketLossRate;
+
+    /** Array including threshold values in milliseconds for RTP jitter */
+    int[] rtpJitterMillis;
+
+    /**
+     * A flag indicating whether the client needs to be notified the current media quality status
+     * right after the threshold is being set. True means the media stack should notify the client
+     * of the current status.
+     */
+    boolean notifyCurrentStatus;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl b/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl
new file mode 100644
index 0000000..98bbfc6
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.ims.media;
+
+@VintfStability
+parcelable RtcpConfig {
+    /** Canonical name that will be sent to all session participants */
+    String canonicalName;
+    /** Port for sending outgoing RTCP packets */
+    int transmitPort;
+    /** Transmit interval in seconds. Value 0 indicates that RTCP reports should not be reported */
+    int transmitIntervalSec;
+    /** Bitmask of RTCP-XR blocks to enable as in RtcpXrReportBlockType */
+    int rtcpXrBlocks;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl b/radio/aidl/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl
new file mode 100644
index 0000000..7f6839a
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+
+/** RTP Control Protocol Extended Reports (RTCP XR) Blocks, See RFC 3611 section 4 */
+
+@VintfStability
+@Backing(type="int")
+enum RtcpXrReportBlockType {
+    /** Disable RTCP XR */
+    RTCPXR_NONE = 0,
+    /** Loss RLE Report Block */
+    RTCPXR_LOSS_RLE_REPORT_BLOCK                  = 1 << 0,
+    /** Duplicate RLE Report Block */
+    RTCPXR_DUPLICATE_RLE_REPORT_BLOCK             = 1 << 1,
+    /** Packet Receipt Times Report Block */
+    RTCPXR_PACKET_RECEIPT_TIMES_REPORT_BLOCK      = 1 << 2,
+    /** Receiver Reference Time Report Block */
+    RTCPXR_RECEIVER_REFERENCE_TIME_REPORT_BLOCK   = 1 << 3,
+    /** DLRR Report Block */
+    RTCPXR_DLRR_REPORT_BLOCK                      = 1 << 4,
+    /** Statistics Summary Report Block */
+    RTCPXR_STATISTICS_SUMMARY_REPORT_BLOCK        = 1 << 5,
+    /** VoIP Metrics Report Block */
+    RTCPXR_VOIP_METRICS_REPORT_BLOCK              = 1 << 6,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl
new file mode 100644
index 0000000..2db73a3
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.ims.media;
+
+@VintfStability
+parcelable RtpAddress {
+    /** Point to point IP address */
+    String ipAddress;
+    /** UDP port number used for the RTP traffic */
+    int portNumber;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl
new file mode 100644
index 0000000..f93b112
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.ims.media;
+
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.ims.media.AnbrMode;
+import android.hardware.radio.ims.media.RtcpConfig;
+import android.hardware.radio.ims.media.RtpAddress;
+import android.hardware.radio.ims.media.RtpSessionParams;
+
+@VintfStability
+parcelable RtpConfig {
+    /** Media flow direction. The bitfield of MediaDirection(s) */
+    int direction;
+    /** Radio Access Network */
+    AccessNetwork accessNetwork;
+    /** IP address and port number of the other party for RTP media */
+    RtpAddress remoteAddress;
+    /** Negotiated session parameters */
+    RtpSessionParams sessionParams;
+    /** RTCP configuration */
+    RtcpConfig rtcpConfig;
+    /**
+     * ANBR Mode parameters. This is set to valid only when its triggered,
+     * otherwise it shall be set to NULL.
+     *
+     * This would be used in the following two cases
+     * - IImsMediaSession#modifySession(RtpConfig) - When RAN wants to change the bit
+     *   rate via ANBR MAC layer signaling, ImsStack converts the received bitrate
+     *   to the codec mode appropriately and passes the codec mode and direction
+     *   using modifySession(). The underlying RTP stack shall adapt to
+     *   the changed bitrate.
+     *
+     * - IImsMediaSessionListener#triggerAnbrQuery(RtpConfig) - When the vendor RTP
+     *   stack receives a request for bitrate increase from the peer terminal via CMR,
+     *   RTCP-APP or TMMBR, it triggers ANBRQ by setting the desired bitrate and the
+     *   direction of the stream.
+     */
+    AnbrMode anbrModeParams;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpError.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpError.aidl
new file mode 100644
index 0000000..11a3468
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpError.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.radio.ims.media;
+
+@VintfStability
+@Backing(type="int")
+enum RtpError {
+    /** Success */
+    NONE = 0,
+    /** Invalid parameters passed in the request */
+    INVALID_PARAM = 1,
+    /** The RTP stack is not ready to handle the request */
+    NOT_READY = 2,
+    /** Unable to handle the request due to memory allocation failure */
+    NO_MEMORY = 3,
+    /** Unable to handle the request due to no sufficient resources such as audio, codec */
+    NO_RESOURCES = 4,
+    /** The requested port number is not available */
+    PORT_UNAVAILABLE = 5,
+    /** The request is not supported by the implementation */
+    NOT_SUPPORTED = 6,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
new file mode 100644
index 0000000..76b13dc
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.ims.media;
+
+/** RTP Header Extensions, see RFC 8285 */
+@VintfStability
+parcelable RtpHeaderExtension {
+    /** Local identifier */
+    int localId;
+    /** Extension data bytes */
+    byte[] data;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.aidl
new file mode 100644
index 0000000..f93c52c
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.ims.media;
+
+import android.hardware.radio.ims.media.CodecParams;
+import android.hardware.radio.ims.media.DtmfParams;
+
+@VintfStability
+parcelable RtpSessionParams {
+    /**
+     * ptime: Recommended length of time in milliseconds represented by the media
+     * in each packet, see RFC 4566
+     */
+    byte pTimeMillis;
+    /**
+     * maxptime: Maximum amount of media that can be encapsulated in each packet
+     * represented in milliseconds, see RFC 4566
+     */
+    int maxPtimeMillis;
+    /** dscp: Differentiated Services Field Code Point value, see RFC 2474 */
+    byte dscp;
+    /** DTMF payload and clock rate */
+    DtmfParams dtmfParams;
+    /** Negotiated codec parameters */
+    CodecParams codecParams;
+}
diff --git a/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
index ee62d95..b256c9a 100644
--- a/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
@@ -27,6 +27,7 @@
     /**
      * SMS in PDU format as an ASCII hex string less the SMSC address.
      * TP-Layer-Length is be "strlen(pdu)/2
+     * TP - MessageRef field of pdu must not be modified by modem
      */
     String pdu;
 }
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
index 492755f..8cbc869 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
@@ -36,7 +36,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void acknowledgeIncomingGsmSmsWithPduResponse(in RadioResponseInfo info);
 
@@ -56,7 +55,6 @@
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -73,7 +71,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void acknowledgeLastIncomingGsmSmsResponse(in RadioResponseInfo info);
 
@@ -98,7 +95,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NO_SUCH_ENTRY
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -122,7 +118,6 @@
      *   RadioError:NO_SUCH_ENTRY
      *   RadioError:INTERNAL_ERR
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
@@ -145,7 +140,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NO_RESOURCES
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
@@ -168,7 +162,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NO_RESOURCES
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
@@ -191,7 +184,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NOT_PROVISIONED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -212,7 +204,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_STATE
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
@@ -240,7 +231,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NETWORK_ERR
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:OPERATION_NOT_ALLOWED
@@ -275,7 +265,6 @@
      *   RadioError:INVALID_SMSC_ADDRESS
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:ENCODING_ERR
      *   RadioError:NO_RESOURCES
@@ -308,7 +297,6 @@
      *   RadioError:ENCODING_ERR
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -336,7 +324,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NETWORK_ERR
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:OPERATION_NOT_ALLOWED
@@ -368,7 +355,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NETWORK_ERR
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NETWORK_NOT_READY
      *   RadioError:OPERATION_NOT_ALLOWED
@@ -393,7 +379,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -414,7 +399,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
@@ -434,7 +418,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -455,7 +438,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
@@ -476,7 +458,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NO_RESOURCES
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -502,7 +483,6 @@
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:INVALID_SMSC_ADDRESS
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -531,7 +511,6 @@
      *   RadioError:INVALID_SMSC_ADDRESS
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:SIM_ABSENT
diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl
index ba0ddb9..2011c53 100644
--- a/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl
@@ -67,6 +67,7 @@
      * @param serial Serial number of request.
      *
      * Response function is IRadioModemResponse.getDeviceIdentityResponse()
+     * @deprecated use getImei(int serial)
      */
     void getDeviceIdentity(in int serial);
 
@@ -117,6 +118,8 @@
      * @param itemId NvItem
      *
      * Response function is IRadioModemResponse.nvReadItemResponse()
+     *
+     * @deprecated NV APIs are deprecated starting from Android U.
      */
     void nvReadItem(in int serial, in NvItem itemId);
 
@@ -128,6 +131,8 @@
      * @param resetType ResetNvType
      *
      * Response function is IRadioModemResponse.nvResetConfigResponse()
+     *
+     * Note: This will be deprecated in favor of a rebootModem API in Android U.
      */
     void nvResetConfig(in int serial, in ResetNvType resetType);
 
@@ -139,6 +144,8 @@
      * @param prl PRL as a byte array
      *
      * Response function is IRadioModemResponse.nvWriteCdmaPrlResponse()
+     *
+     * @deprecated NV APIs are deprecated starting from Android U.
      */
     void nvWriteCdmaPrl(in int serial, in byte[] prl);
 
@@ -150,6 +157,8 @@
      * @param item NvWriteItem
      *
      * Response function is IRadioModemResponse.nvWriteItemResponse()
+     *
+     * @deprecated NV APIs are deprecated starting from Android U.
      */
     void nvWriteItem(in int serial, in NvWriteItem item);
 
@@ -227,4 +236,13 @@
      */
     void setResponseFunctions(in IRadioModemResponse radioModemResponse,
             in IRadioModemIndication radioModemIndication);
+
+    /**
+     * Request the IMEI associated with the radio.
+     *
+     * @param serial : Serial number of request.
+     *
+     * Response function is IRadioModemResponse.getImeiResponse()
+     */
+     void getImei(in int serial);
 }
diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
index b17cac4..fd4bffb 100644
--- a/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
+++ b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.modem.ActivityStatsInfo;
 import android.hardware.radio.modem.HardwareConfig;
 import android.hardware.radio.modem.RadioCapability;
+import android.hardware.radio.modem.ImeiInfo;
 
 /**
  * Interface declaring response functions to solicited radio requests for modem APIs.
@@ -61,7 +62,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -89,6 +89,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     * @deprecated use getImeiResponse(RadioResponseInfo responseInfo, ImeiInfo imeiInfo)
      */
     void getDeviceIdentityResponse(in RadioResponseInfo info, in String imei, in String imeisv,
             in String esn, in String meid);
@@ -100,7 +101,6 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void getHardwareConfigResponse(in RadioResponseInfo info, in HardwareConfig[] config);
 
@@ -118,7 +118,6 @@
      *   RadioError:NOT_PROVISIONED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void getModemActivityInfoResponse(in RadioResponseInfo info, in ActivityStatsInfo activityInfo);
 
@@ -141,7 +140,6 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
@@ -156,7 +154,8 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
+     *
+     * @deprecated NV APIs are deprecated starting from Android U.
      */
     void nvReadItemResponse(in RadioResponseInfo info, in String result);
 
@@ -166,7 +165,8 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
+     *
+     * Note: This will be deprecated in favor of a rebootModemResponse API in Android U.
      */
     void nvResetConfigResponse(in RadioResponseInfo info);
 
@@ -176,7 +176,8 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
+     *
+     * @deprecated NV APIs are deprecated starting from Android U.
      */
     void nvWriteCdmaPrlResponse(in RadioResponseInfo info);
 
@@ -186,7 +187,8 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
+     *
+     * @deprecated NV APIs are deprecated starting from Android U.
      */
     void nvWriteItemResponse(in RadioResponseInfo info);
 
@@ -200,7 +202,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -216,7 +217,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -237,7 +237,6 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -254,4 +253,20 @@
      *   RadioError:NO_RF_CALIBRATION_INFO
      */
     void setRadioPowerResponse(in RadioResponseInfo info);
+
+    /**
+     * ImeiInfo to encapsulate the IMEI information from modem. When the return error code
+     * is {@code RadioError:NONE}, {@code imeiInfo} must be non-null, and a valid IMEITYPE,
+     * IMEI and SVN must be filled in {@code imeiInfo}. When the error code is not
+     * {@code RadioError:NONE}, {@code imeiInfo} must be {@code null}.
+     *
+     * @param responseInfo Response info struct containing response type, serial no. and error
+     * @param imeiInfo IMEI information
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:MODEM_ERR
+     */
+    void getImeiResponse(in RadioResponseInfo responseInfo, in @nullable ImeiInfo imeiInfo);
 }
diff --git a/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl b/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl
new file mode 100644
index 0000000..2d25bb7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.modem;
+
+/**
+ * ImeiInfo to encapsulate the IMEI information from modem
+ */
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable ImeiInfo {
+
+    @VintfStability
+    @Backing(type="int")
+    /**
+     * ImeiType enum is used identify the IMEI as primary or secondary as mentioned in GSMA TS.37
+     */
+    enum ImeiType {
+       /**
+        * This is the primary IMEI of the device as mentioned in the GSMA TS.37. In a multi-SIM
+        * device the modem must set one IMEI with this type as mentioned in GSMA TS37_2.2_REQ_8.
+        * A single SIM with one IMEI must by default set that IMEI with this type.
+        */
+       PRIMARY = 1,
+       /** This is not the primary IMEI of the device */
+       SECONDARY = 2,
+    }
+
+    /** Primary or secondary IMEI as mentioned in GSMA spec TS.37 */
+    ImeiType type;
+    /**
+     * IMEI value, see 3gpp spec 23.003 section 6. Note: This primary IMEI mapping must be
+     * permanent throughout the lifetime of the device irrespective of the factory data reset,
+     * SIM activations or swaps.
+     */
+    String imei;
+   /**
+     * IMEI software version, see 3gpp spec 23.003 section 6.
+     */
+    String svn;
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/modem/NvItem.aidl b/radio/aidl/android/hardware/radio/modem/NvItem.aidl
index 649b0d2..310b1ad 100644
--- a/radio/aidl/android/hardware/radio/modem/NvItem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/NvItem.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.radio.modem;
 
+/** @deprecated NV APIs are deprecated starting from Android U. */
 @VintfStability
 @Backing(type="int")
 @JavaDerive(toString=true)
diff --git a/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
index 47fb490..6472f23 100644
--- a/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.radio.modem.NvItem;
 
+/** @deprecated NV APIs are deprecated starting from Android U. */
 @VintfStability
 @JavaDerive(toString=true)
 parcelable NvWriteItem {
diff --git a/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
index 16487f8..6476fe8 100644
--- a/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.radio.modem;
 
+/** Note: This will be deprecated along with nvResetConfig in Android U. */
 @VintfStability
 @Backing(type="int")
 @JavaDerive(toString=true)
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyMode.aidl b/radio/aidl/android/hardware/radio/network/EmergencyMode.aidl
new file mode 100644
index 0000000..25031a9
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/EmergencyMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.network;
+
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum EmergencyMode {
+    /**
+     * Mode Type Emergency WWAN, indicates that the current domain selected for the Emergency call
+     * is cellular.
+     */
+    EMERGENCY_WWAN = 1,
+
+    /**
+     * Mode Type Emergency WLAN, indicates that the current domain selected for the Emergency call
+     * is WLAN/WIFI.
+     */
+    EMERGENCY_WLAN = 2,
+
+    /**
+     * Mode Type Emergency Callback, indicates that the current mode set request is for Emergency
+     * callback.
+     */
+    EMERGENCY_CALLBACK = 3,
+}
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl b/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
new file mode 100644
index 0000000..0a22e4c
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.network;
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.network.EmergencyScanType;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable EmergencyNetworkScanTrigger{
+    /**
+     * Access network to be prioritized during emergency scan. The 1st entry has the highest
+     * priority.
+     */
+    AccessNetwork[] accessNetwork;
+
+    /**
+     * Scan type indicates the type of scans to be performed i.e. limited scan, full service scan or
+     * any scan.
+     */
+    EmergencyScanType scanType;
+}
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl b/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl
new file mode 100644
index 0000000..2215149
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.network;
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.network.Domain;
+import android.hardware.radio.network.RegState;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable EmergencyRegResult {
+    /**
+     * Indicates the cellular access network of the current emergency capable system.
+     */
+    AccessNetwork accessNetwork;
+
+    /**
+     * Registration state of the current emergency capable system.
+     */
+    RegState regState;
+
+    /**
+     * EMC domain indicates the current domain of the acquired system.
+     */
+    Domain emcDomain;
+
+    /**
+     * This indicates whether the network supports voice over PS network.
+     */
+    boolean isVopsSupported;
+
+    /**
+     * This indicates if camped network support VoLTE emergency bearers.
+     * This should only be set if the UE is in LTE mode.
+     */
+    boolean isEmcBearerSupported;
+
+    /**
+     * The value of the network provided EMC 5G Registration ACCEPT.
+     * This should be set only if  the UE is in 5G mode.
+     */
+    byte nwProvidedEmc;
+
+    /**
+     * The value of the network provided EMF ( EPS Fallback) in 5G Registration ACCEPT.
+     * This should not be set if UE is not in 5G mode.
+     */
+    byte nwProvidedEmf;
+
+    /** 3-digit Mobile Country Code, 000..999, empty string if unknown. */
+    String mcc = "";
+
+    /** 2 or 3-digit Mobile Network Code, 00..999, empty string if unknown. */
+    String mnc = "";
+}
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyScanType.aidl b/radio/aidl/android/hardware/radio/network/EmergencyScanType.aidl
new file mode 100644
index 0000000..72c5490
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/EmergencyScanType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.network;
+
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum EmergencyScanType {
+    /**
+     * Scan Type No Preference, indicates that the modem can scan for emergency
+     * service as per modem’s implementation.
+     */
+    NO_PREFERENCE = 0,
+
+    /**
+     * Scan Type limited, indicates that the modem will scan for
+     * emergency service in limited service mode.
+     */
+    LIMITED_SERVICE = 1,
+
+    /**
+     * Scan Type Full Service, indicates that the modem will scan for
+     * emergency service in Full service mode.
+     */
+    FULL_SERVICE = 2,
+}
diff --git a/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
index c9563ac..b986944 100644
--- a/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
@@ -22,6 +22,21 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable EutranRegistrationInfo {
+    enum AttachResultType {
+        /** Default value. */
+        NONE,
+        /** LTE is attached with eps only. */
+        EPS_ONLY,
+        /** LTE combined EPS and IMSI attach. */
+        COMBINED,
+    }
+
+    /** LTE combined attach with CSFB not preferred */
+    const int EXTRA_CSFB_NOT_PREFERRED = 1 << 0;
+
+    /** LTE combined attach for SMS only */
+    const int EXTRA_SMS_ONLY = 1 << 1;
+
     /**
      * Network capabilities for voice over PS services. This info is valid only on LTE network and
      * must be present when device is camped on LTE. VopsInfo must be empty when device is camped
@@ -33,4 +48,13 @@
      * be empty.
      */
     NrIndicators nrIndicators;
+
+    /**
+     * The type of network attachment. This info is valid only on LTE network and must be present
+     * when device has attached to the network.
+     */
+    AttachResultType lteAttachResultType;
+
+    /** Values are bitwise ORs of EXTRA_* constants */
+    int extraInfo;
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index cce52ff..f22cdb0 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -18,6 +18,8 @@
 
 import android.hardware.radio.AccessNetwork;
 import android.hardware.radio.network.CdmaRoamingType;
+import android.hardware.radio.network.EmergencyMode;
+import android.hardware.radio.network.EmergencyNetworkScanTrigger;
 import android.hardware.radio.network.IRadioNetworkIndication;
 import android.hardware.radio.network.IRadioNetworkResponse;
 import android.hardware.radio.network.IndicationFilter;
@@ -110,6 +112,8 @@
      * @param serial Serial number of request.
      *
      * Response function is IRadioNetworkResponse.getImsRegistrationStateResponse()
+     *
+     * @deprecated Deprecated starting from Android U.
      */
     void getImsRegistrationState(in int serial);
 
@@ -437,4 +441,118 @@
      * @param serial Serial number of request.
      */
     oneway void getUsageSetting(in int serial);
+
+    /**
+     * Set the Emergency Mode
+     *
+     * @param serial Serial number of the request.
+     * @param emcModeType Defines the radio emergency mode type/radio network required/
+     * type of service to be scanned.
+     *
+     * Response function is IRadioEmergencyResponse.setEmergencyModeResponse()
+     */
+    void setEmergencyMode(int serial, in EmergencyMode emcModeType);
+
+    /**
+     * Triggers an Emergency network scan.
+     *
+     * @param serial Serial number of the request.
+     * @param request Contains the preferred networks and type of service to be scanned.
+     *                See {@link EmergencyNetworkScanTrigger}.
+     *
+     * Response function is IRadioEmergencyResponse.triggerEmergencyNetworkScanResponse()
+     */
+    void triggerEmergencyNetworkScan(int serial, in EmergencyNetworkScanTrigger request);
+
+    /**
+     * Cancels ongoing Emergency network scan
+     *
+     * @param serial Serial number of the request.
+     * @param resetScan Indicates how the next {@link #triggerEmergencyNetworkScan} should work.
+     *        If {@code true}, then the modem shall start the new scan from the beginning,
+     *        otherwise the modem shall resume from the last search.
+     *
+     * Response function is IRadioEmergencyResponse.cancelEmergencyNetworkScan()
+     */
+    void cancelEmergencyNetworkScan(int serial, boolean resetScan);
+
+    /**
+     * Exits ongoing Emergency Mode
+     *
+     * @param serial Serial number of the request.
+     *
+     * Response function is IRadioEmergencyResponse.exitEmergencyModeResponse()
+     */
+    void exitEmergencyMode(in int serial);
+
+    /**
+     * Set if null encryption and integrity modes are enabled. If the value of enabled is false
+     * the modem must not allow any network communications with null ciphering (for both signalling
+     * and user data) or null integrity (for signalling) modes for 3G and above, even if the
+     * network only uses null algorithms. This setting must be respected even if
+     * "cipheringDisabled" (as defined in TS 38.331) is in use by the network.
+     *
+     * For 2G, which does not use integrity protection, the modem must only disallow any network
+     * communications with null ciphering.
+     *
+     * In the case when enabled is false, integrity protection for user data is optional, but
+     * ciphering for user data is required.
+     *
+     * In case of an emergency call, the modem must bypass this setting.
+     *
+     * Null ciphering and integrity modes include (but are not limited to):
+     * 2G: A5/0 and GEA0
+     * 3G: UEA0 and UIA0
+     * 4G: EEA0 and EIA0
+     * 5G: NEA0 and NIA0
+     *
+     *
+     * @param serial Serial number of the request.
+     * @param enabled To allow null encryption/integrity, set to true.
+     *                Otherwise, false.
+     *
+     * Response callback is IRadioResponse.setNullCipherAndIntegrityEnabledResponse()
+     */
+    void setNullCipherAndIntegrityEnabled(in int serial, in boolean enabled);
+
+    /**
+     * Get whether null encryption and integrity modes are enabled.
+     *
+     * Null ciphering and integrity modes include, (but are not limited to):
+     * 2G: A5/0, GAE0 (no integrity algorithm supported)
+     * 3G: UEA0 and UIA0
+     * 4G: EEA0 and EIA
+     * 5G: NEA0 and NIA0
+     *
+     * @param serial Serial number of the request.
+     *
+     * Response callback is IRadioNetworkResponse.isNullCipherAndIntegrityEnabledResponse()
+     */
+    void isNullCipherAndIntegrityEnabled(in int serial);
+
+    /**
+     * Checks whether N1 mode (access to 5G core network) is enabled or not.
+     *
+     * @param serial Serial number of request.
+     *
+     * Response function is IRadioNetworkResponse.isN1ModeEnabledResponse()
+     */
+    void isN1ModeEnabled(in int serial);
+
+    /**
+     * Enables or disables N1 mode (access to 5G core network) in accordance with
+     * 3GPP TS 24.501 4.9.
+     *
+     * Note: The default value of N1 mode shall be based on the modem's internal configuration
+     * as per device or carrier. This API may be invoked on demand first to disable N1 mode and
+     * later to re-enable for certain use case. This setting shall not be persisted by modem.
+     * This setting shall not interfere with the allowed network type bitmap set using
+     * {@link IRadioNetwork#setAllowedNetworkTypesBitmap()} API.
+     *
+     * @param serial Serial number of request.
+     * @param enable {@code true} to enable N1 mode, {@code false} to disable N1 mode.
+     *
+     * Response function is IRadioNetworkResponse.setN1ModeEnabledResponse()
+     */
+    void setN1ModeEnabled(in int serial, boolean enable);
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index f471433..47d932d 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -27,6 +27,7 @@
 import android.hardware.radio.network.PhysicalChannelConfig;
 import android.hardware.radio.network.SignalStrength;
 import android.hardware.radio.network.SuppSvcNotification;
+import android.hardware.radio.network.EmergencyRegResult;
 
 /**
  * Interface declaring unsolicited radio indications for network APIs.
@@ -190,4 +191,12 @@
      * @param rat Current new voice rat
      */
     void voiceRadioTechChanged(in RadioIndicationType type, in RadioTechnology rat);
+
+    /**
+     * Emergency Scan Results.
+     *
+     * @param type Type of radio indication
+     * @param result the result of the Emergency Network Scan
+     */
+    void emergencyNetworkScanResult(in RadioIndicationType type, in EmergencyRegResult result);
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index dcf0004..457b5b9 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -23,6 +23,7 @@
 import android.hardware.radio.network.CdmaRoamingType;
 import android.hardware.radio.network.CellIdentity;
 import android.hardware.radio.network.CellInfo;
+import android.hardware.radio.network.EmergencyRegResult;
 import android.hardware.radio.network.OperatorInfo;
 import android.hardware.radio.network.RadioAccessSpecifier;
 import android.hardware.radio.network.RadioBandMode;
@@ -56,7 +57,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      */
     void getAllowedNetworkTypesBitmapResponse(in RadioResponseInfo info, in int networkTypeBitmap);
@@ -73,7 +73,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -92,7 +91,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:CANCELLED
      *   RadioError:NO_RESOURCES
      *   RadioError:INTERNAL_ERR
@@ -125,7 +123,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
@@ -169,7 +166,8 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
+     *
+     * @deprecated Deprecated starting from Android U.
      */
     void getImsRegistrationStateResponse(
             in RadioResponseInfo info, in boolean isRegistered, in RadioTechnologyFamily ratFamily);
@@ -186,7 +184,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -204,7 +201,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -246,7 +242,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void getVoiceRadioTechnologyResponse(in RadioResponseInfo info, in RadioTechnology rat);
 
@@ -271,7 +266,6 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void isNrDualConnectivityEnabledResponse(in RadioResponseInfo info, in boolean isEnabled);
 
@@ -286,7 +280,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      */
     void setAllowedNetworkTypesBitmapResponse(in RadioResponseInfo info);
@@ -303,7 +296,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -324,7 +316,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:FDN_CHECK_FAILURE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -341,7 +332,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -361,7 +351,6 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void setCellInfoListRateResponse(in RadioResponseInfo info);
 
@@ -399,7 +388,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
@@ -419,7 +407,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *
@@ -442,7 +429,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *
@@ -458,7 +444,6 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_STATE
      */
     void setNrDualConnectivityStateResponse(in RadioResponseInfo info);
@@ -485,7 +470,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
@@ -542,7 +526,6 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_ABSENT
      */
     void supplyNetworkDepersonalizationResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -572,4 +555,116 @@
      *   RadioError:SIM_ABSENT
      */
     oneway void getUsageSettingResponse(in RadioResponseInfo info, in UsageSetting usageSetting);
+
+    /**
+     * Response of setEmergencyMode.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     * @param regState the current registration state of the modem.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:MODEM_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     */
+    void setEmergencyModeResponse(in RadioResponseInfo info, in EmergencyRegResult regState);
+
+    /**
+     * Response of triggerEmergencyNetworkScan.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:MODEM_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     */
+    void triggerEmergencyNetworkScanResponse(in RadioResponseInfo info);
+
+    /**
+     * Response of exitEmergencyMode.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:MODEM_ERR
+     */
+    void exitEmergencyModeResponse(in RadioResponseInfo info);
+
+    /**
+     * Response of cancelEmergencyNetworkScan.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:MODEM_ERR
+     */
+    void cancelEmergencyNetworkScanResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:MODEM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     */
+    void setNullCipherAndIntegrityEnabledResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     * @param enabled the last known state of null ciphering and integrity algorithms
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:MODEM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     */
+    void isNullCipherAndIntegrityEnabledResponse(in RadioResponseInfo info, in boolean isEnabled);
+
+    /**
+     * Response of isN1ModeEnabled.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     * @param isEnabled Indicates whether N1 mode is enabled or not.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     */
+    void isN1ModeEnabledResponse(in RadioResponseInfo info, boolean isEnabled);
+
+    /**
+     * Response of setN1ModeEnabled.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INVALID_STATE
+     */
+    void setN1ModeEnabledResponse(in RadioResponseInfo info);
 }
diff --git a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
index 1bb569a..30ae067 100644
--- a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
@@ -71,4 +71,11 @@
      * Range [0, 15], 0xFF means invalid/unreported.
      */
     byte[] csiCqiReport;
+    /**
+     * Timing advance in micro seconds for a one way trip from cell to device. Approximate distance
+     * is calculated using 300m/us * timingAdvance. Range: 0 to 1282 inclusive.
+     * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value.
+     * Reference: 3GPP 36.213 section 4.2.3
+     */
+    int timingAdvance = 0x7FFFFFFF;
 }
diff --git a/radio/aidl/android/hardware/radio/network/RegState.aidl b/radio/aidl/android/hardware/radio/network/RegState.aidl
index 3f13783..bdba4c4 100644
--- a/radio/aidl/android/hardware/radio/network/RegState.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegState.aidl
@@ -65,4 +65,10 @@
      * Same as UNKNOWN but indicates that emergency calls are enabled
      */
     UNKNOWN_EM = 14,
+    /**
+     * Emergency attached in EPS or in 5GS.
+     * Reference: 3GPP TS 24.301 9.9.3.11 EPS attach type.
+     * Reference: 3GPP TS 24.501 9.11.3.6 5GS registration result.
+     */
+    REG_EM = 20,
 }
diff --git a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
index 3d96b8c..f1d2972 100644
--- a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
@@ -33,9 +33,9 @@
      */
     RegState regState;
     /**
-     * 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.
+     * Indicates the radio technology, 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.
      */
diff --git a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
index 2f90180..0a8e9ce 100644
--- a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -82,7 +82,13 @@
      * Reference: 3GPP TS 38.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1.
      */
     const int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8;
-
+    /**
+     * EcNo value
+     * Range: -24 dBm to 1 dBm.
+     * Used RAN: UTRAN
+     * Reference: 3GPP TS 25.215 5.1.5
+     */
+    const int SIGNAL_MEASUREMENT_TYPE_ECNO = 9;
     /**
      * Signal Measurement Type
      * Values are SIGNAL_MEASUREMENT_TYPE_
diff --git a/radio/aidl/android/hardware/radio/sap/ISap.aidl b/radio/aidl/android/hardware/radio/sap/ISap.aidl
new file mode 100644
index 0000000..552e602
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sap/ISap.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sap;
+
+import android.hardware.radio.sap.ISapCallback;
+import android.hardware.radio.sap.SapApduType;
+import android.hardware.radio.sap.SapTransferProtocol;
+
+@VintfStability
+oneway interface ISap {
+    /**
+     * TRANSFER_APDU_REQ from SAP 1.1 spec 5.1.6
+     *
+     * @param serial Id to match req-resp. Resp must include same serial.
+     * @param type APDU command type
+     * @param command CommandAPDU/CommandAPDU7816 parameter depending on type
+     */
+    void apduReq(in int serial, in SapApduType type, in byte[] command);
+
+    /**
+     * CONNECT_REQ from SAP 1.1 spec 5.1.1
+     *
+     * @param serial Id to match req-resp. Resp must include same serial.
+     * @param maxMsgSizeBytes MaxMsgSize to be used for SIM Access Profile connection
+     */
+    void connectReq(in int serial, in int maxMsgSizeBytes);
+
+    /**
+     * DISCONNECT_REQ from SAP 1.1 spec 5.1.3
+     *
+     * @param serial Id to match req-resp. Resp must include same serial.
+     */
+    void disconnectReq(in int serial);
+
+    /**
+     * POWER_SIM_OFF_REQ and POWER_SIM_ON_REQ from SAP 1.1 spec 5.1.10 + 5.1.12
+     *
+     * @param serial Id to match req-resp. Resp must include same serial.
+     * @param powerOn true for on, false for off
+     */
+    void powerReq(in int serial, in boolean powerOn);
+
+    /**
+     * RESET_SIM_REQ from SAP 1.1 spec 5.1.14
+     *
+     * @param serial Id to match req-resp. Resp must include same serial.
+     */
+    void resetSimReq(in int serial);
+
+    /**
+     * 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 serial Id to match req-resp. Resp must include same serial.
+     * @param transferProtocol Transport Protocol
+     */
+    void setTransferProtocolReq(in int serial, in SapTransferProtocol transferProtocol);
+
+    /**
+     * TRANSFER_ATR_REQ from SAP 1.1 spec 5.1.8
+     *
+     * @param serial Id to match req-resp. Resp must include same serial.
+     */
+    void transferAtrReq(in int serial);
+
+    /**
+     * TRANSFER_CARD_READER_STATUS_REQ from SAP 1.1 spec 5.1.17
+     *
+     * @param serial Id to match req-resp. Resp must include same serial.
+     */
+    void transferCardReaderStatusReq(in int serial);
+}
diff --git a/radio/aidl/android/hardware/radio/sap/ISapCallback.aidl b/radio/aidl/android/hardware/radio/sap/ISapCallback.aidl
new file mode 100644
index 0000000..34111eb
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sap/ISapCallback.aidl
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sap;
+
+import android.hardware.radio.sap.SapConnectRsp;
+import android.hardware.radio.sap.SapDisconnectType;
+import android.hardware.radio.sap.SapResultCode;
+import android.hardware.radio.sap.SapStatus;
+
+@VintfStability
+oneway interface ISapCallback {
+    /**
+     * TRANSFER_APDU_RESP from SAP 1.1 spec 5.1.7
+     *
+     * @param serial 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 serial, in SapResultCode resultCode, in byte[] apduRsp);
+
+    /**
+     * CONNECT_RESP from SAP 1.1 spec 5.1.2
+     *
+     * @param serial Id to match req-resp. Value must match the one in req.
+     * @param sapConnectRsp Connection Status
+     * @param maxMsgSizeBytes MaxMsgSize supported by server if request cannot be fulfilled.
+     *        Valid only if connectResponse is SapConnectResponse:MSG_SIZE_TOO_LARGE.
+     */
+    void connectResponse(in int serial, in SapConnectRsp sapConnectRsp, in int maxMsgSizeBytes);
+
+    /**
+     * DISCONNECT_IND from SAP 1.1 spec 5.1.5
+     *
+     * @param serial 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 serial, in SapDisconnectType disconnectType);
+
+    /**
+     * DISCONNECT_RESP from SAP 1.1 spec 5.1.4
+     *
+     * @param serial Id to match req-resp. Value must match the one in req.
+     */
+    void disconnectResponse(in int serial);
+
+    /**
+     * ERROR_RESP from SAP 1.1 spec 5.1.19
+     *
+     * @param serial Id to match req-resp. Value must match the one in req.
+     */
+    void errorResponse(in int serial);
+
+    /**
+     * POWER_SIM_OFF_RESP and POWER_SIM_ON_RESP from SAP 1.1 spec 5.1.11 + 5.1.13
+     *
+     * @param serial 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 serial, in SapResultCode resultCode);
+
+    /**
+     * RESET_SIM_RESP from SAP 1.1 spec 5.1.15
+     *
+     * @param serial 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 serial, in SapResultCode resultCode);
+
+    /**
+     * STATUS_IND from SAP 1.1 spec 5.1.16
+     *
+     * @param serial 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 serial, in SapStatus status);
+
+    /**
+     * TRANSFER_ATR_RESP from SAP 1.1 spec 5.1.9
+     *
+     * @param serial 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 serial, in SapResultCode resultCode, in byte[] atr);
+
+    /**
+     * TRANSFER_CARD_READER_STATUS_REQ from SAP 1.1 spec 5.1.18
+     *
+     * @param serial 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 serial, in SapResultCode resultCode, in int cardReaderStatus);
+
+    /**
+     * SET_TRANSPORT_PROTOCOL_RESP from SAP 1.1 spec 5.1.21
+     *
+     * @param serial 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 serial, in SapResultCode resultCode);
+}
diff --git a/radio/aidl/android/hardware/radio/sap/SapApduType.aidl b/radio/aidl/android/hardware/radio/sap/SapApduType.aidl
new file mode 100644
index 0000000..ab8ffb9
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sap/SapApduType.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sap;
+
+@VintfStability
+@Backing(type="int")
+enum SapApduType {
+    APDU,
+    APDU7816,
+}
diff --git a/radio/aidl/android/hardware/radio/sap/SapConnectRsp.aidl b/radio/aidl/android/hardware/radio/sap/SapConnectRsp.aidl
new file mode 100644
index 0000000..0e1d528
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sap/SapConnectRsp.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sap;
+
+@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/sap/SapDisconnectType.aidl b/radio/aidl/android/hardware/radio/sap/SapDisconnectType.aidl
new file mode 100644
index 0000000..16d7cc6
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sap/SapDisconnectType.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sap;
+
+@VintfStability
+@Backing(type="int")
+enum SapDisconnectType {
+    GRACEFUL,
+    IMMEDIATE,
+}
diff --git a/radio/aidl/android/hardware/radio/sap/SapResultCode.aidl b/radio/aidl/android/hardware/radio/sap/SapResultCode.aidl
new file mode 100644
index 0000000..4728ebe
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sap/SapResultCode.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sap;
+
+@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/sap/SapStatus.aidl b/radio/aidl/android/hardware/radio/sap/SapStatus.aidl
new file mode 100644
index 0000000..309352d
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sap/SapStatus.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sap;
+
+@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/sap/SapTransferProtocol.aidl b/radio/aidl/android/hardware/radio/sap/SapTransferProtocol.aidl
new file mode 100644
index 0000000..823c5f2
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sap/SapTransferProtocol.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sap;
+
+@VintfStability
+@Backing(type="int")
+enum SapTransferProtocol {
+    T0,
+    T1,
+}
diff --git a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
index a14cf7d..1419c51 100644
--- a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.radio.sim;
 
+import android.hardware.radio.config.MultipleEnabledProfilesMode;
 import android.hardware.radio.config.SlotPortMapping;
 import android.hardware.radio.sim.AppStatus;
 import android.hardware.radio.sim.PinState;
@@ -93,4 +94,8 @@
      * PortId is the id (enumerated value) for the associated port available on the SIM.
      */
     SlotPortMapping slotMap;
+    /**
+     * Jointly supported Multiple Enabled Profiles(MEP) mode as per SGP.22 V3.0
+     */
+    MultipleEnabledProfilesMode supportedMepMode = MultipleEnabledProfilesMode.NONE;
 }
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
index 3dce907..edbec2c 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -21,6 +21,22 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable CarrierRestrictions {
+    @VintfStability
+    @Backing(type="int")
+    /** This enum defines the carrier restriction status values */
+    enum CarrierRestrictionStatus {
+       /**
+        * Carrier restriction status value is unknown, used in cases where modem is dependent on
+        * external module to know about the lock status and the module hasn’t yet provided the lock
+        * status. For example, when the lock status is maintained on a cloud server and device has
+        * just booted after out of box and not yet connected to the internet.
+        */
+        UNKNOWN = 0,
+        /** There is no carrier restriction on the device */
+        NOT_RESTRICTED = 1,
+        /** The device is restricted to a carrier */
+        RESTRICTED = 2,
+    }
     /**
      * Allowed carriers
      */
@@ -40,4 +56,6 @@
      * and not in the allowed list.
      */
     boolean allowedCarriersPrioritized;
+    /** Current restriction status as defined in CarrierRestrictionStatus enum */
+    CarrierRestrictionStatus status;
 }
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index 7923b14..3823a71 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -26,6 +26,7 @@
 import android.hardware.radio.sim.PersoSubstate;
 import android.hardware.radio.sim.PhonebookRecordInfo;
 import android.hardware.radio.sim.SelectUiccSub;
+import android.hardware.radio.sim.SessionInfo;
 import android.hardware.radio.sim.SimApdu;
 import android.hardware.radio.sim.SimLockMultiSimPolicy;
 
@@ -184,6 +185,8 @@
      * @param channelId session id of the logical channel (+CCHC).
      *
      * Response function is IRadioSimResponse.iccCloseLogicalChannelResponse()
+     *
+     * @deprecated use iccCloseLogicalChannelWithSessionInfo instead.
      */
     void iccCloseLogicalChannel(in int serial, in int channelId);
 
@@ -494,4 +497,19 @@
      * Response function is IRadioSimResponse.updateSimPhonebookRecordsResponse()
      */
     void updateSimPhonebookRecords(in int serial, in PhonebookRecordInfo recordInfo);
+
+    /**
+     * Close a previously opened logical channel. This command reflects TS 27.007
+     * "close logical channel" operation (+CCHC).
+     *
+     * Per spec SGP.22 V3.0, ES10 commands needs to be sent over command port of MEP-A. In order
+     * to close proper logical channel, should pass information about whether the logical channel
+     * was opened for sending ES10 commands or not.
+     *
+     * @param serial Serial number of request.
+     * @param sessionInfo Details of the opened logical channel info like sessionId and isEs10.
+     *
+     * Response function is IRadioSimResponse.iccCloseLogicalChannelWithSessionInfoResponse()
+     */
+    void iccCloseLogicalChannelWithSessionInfo(in int serial, in SessionInfo sessionInfo);
 }
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
index 750a29a..90f172f 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -65,7 +65,6 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SIM_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_PUK2
      */
     void changeIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -84,7 +83,6 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SIM_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void changeIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries);
 
@@ -108,7 +106,6 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void getAllowedCarriersResponse(in RadioResponseInfo info, in CarrierRestrictions carriers,
             in SimLockMultiSimPolicy multiSimPolicy);
@@ -133,7 +130,6 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
      *   RadioError:NOT_PROVISIONED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
@@ -153,7 +149,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_ABSENT
      */
     void getCdmaSubscriptionSourceResponse(
@@ -176,7 +171,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:FDN_CHECK_FAILURE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -191,7 +185,6 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_RESOURCES
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void getIccCardStatusResponse(in RadioResponseInfo info, in CardStatus cardStatus);
 
@@ -208,7 +201,6 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_SIM_STATE
      *   RadioError:SIM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void getImsiForAppResponse(in RadioResponseInfo info, in String imsi);
 
@@ -219,13 +211,10 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SIM_STATE
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
-     * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API,
-     * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM.
      */
     void getSimPhonebookCapacityResponse(in RadioResponseInfo info, in PhonebookCapacity capacity);
 
@@ -235,13 +224,10 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SIM_STATE
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
-     * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API,
-     * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM.
      */
     void getSimPhonebookRecordsResponse(in RadioResponseInfo info);
 
@@ -255,7 +241,8 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
+     *
+     * @deprecated use iccCloseLogicalChannelWithSessionInfoResponse instead.
      */
     void iccCloseLogicalChannelResponse(in RadioResponseInfo info);
 
@@ -274,7 +261,6 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_SIM_STATE
      *   RadioError:SIM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void iccIoForAppResponse(in RadioResponseInfo info, in IccIoResult iccIo);
 
@@ -296,7 +282,6 @@
      *   RadioError:SIM_ERR
      *   RadioError:INVALID_SIM_STATE
      *   RadioError:MISSING_RESOURCE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void iccOpenLogicalChannelResponse(
             in RadioResponseInfo info, in int channelId, in byte[] selectResponse);
@@ -312,7 +297,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void iccTransmitApduBasicChannelResponse(in RadioResponseInfo info, in IccIoResult result);
 
@@ -327,7 +311,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void iccTransmitApduLogicalChannelResponse(in RadioResponseInfo info, in IccIoResult result);
 
@@ -341,7 +324,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void reportStkServiceIsRunningResponse(in RadioResponseInfo info);
 
@@ -359,7 +341,6 @@
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:SIM_ERR
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void requestIccSimAuthenticationResponse(in RadioResponseInfo info, in IccIoResult result);
 
@@ -379,7 +360,6 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_ABSENT
      */
     void sendEnvelopeResponse(in RadioResponseInfo info, in String commandResponse);
@@ -397,7 +377,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_ABSENT
      */
     void sendEnvelopeWithStatusResponse(in RadioResponseInfo info, in IccIoResult iccIo);
@@ -415,7 +394,6 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_ABSENT
      */
     void sendTerminalResponseToSimResponse(in RadioResponseInfo info);
@@ -427,7 +405,6 @@
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void setAllowedCarriersResponse(in RadioResponseInfo info);
 
@@ -435,12 +412,11 @@
      * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
-     *   RadioError:RIL_E_SUCCESS
-     *   RadioError:RIL_E_RADIO_NOT_AVAILABLE
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:SIM_ABSENT
-     *   RadioError:RIL_E_REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:MODEM_INTERNAL_FAILURE
+     *   RadioError:INTERNAL_FAILURE
      */
     void setCarrierInfoForImsiEncryptionResponse(in RadioResponseInfo info);
 
@@ -456,7 +432,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void setCdmaSubscriptionSourceResponse(in RadioResponseInfo info);
 
@@ -477,7 +452,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_STATE
      *   RadioError:FDN_CHECK_FAILURE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -507,7 +481,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -527,7 +500,6 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SIM_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_PUK2
      */
     void supplyIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -546,7 +518,6 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SIM_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void supplyIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries);
 
@@ -564,7 +535,6 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SIM_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void supplyIccPuk2ForAppResponse(in RadioResponseInfo info, in int remainingRetries);
 
@@ -582,7 +552,6 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SIM_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void supplyIccPukForAppResponse(in RadioResponseInfo info, in int remainingRetries);
 
@@ -603,7 +572,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_RESOURCES
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void supplySimDepersonalizationResponse(
             in RadioResponseInfo info, in PersoSubstate persoType, in int remainingRetries);
@@ -616,7 +584,6 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INVALID_SIM_STATE
      *   RadioError:MODEM_ERR
@@ -624,8 +591,19 @@
      *   RadioError:SIM_ERR
      *   RadioError:NO_SUCH_ENTRY
      *   RadioError:NO_RESOURCES
-     * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API,
-     * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM.
      */
     void updateSimPhonebookRecordsResponse(in RadioResponseInfo info, in int updatedRecordIndex);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NO_MEMORY
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     */
+    void iccCloseLogicalChannelWithSessionInfoResponse(in RadioResponseInfo info);
 }
diff --git a/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl b/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl
new file mode 100644
index 0000000..9e3e8ed
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sim;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable SessionInfo {
+    /**
+     * Session id of the logical channel from TS 27.007 (+CCHC).
+     */
+    int sessionId;
+    /**
+     * Whether the logical channel was opened for sending ES10 commands.
+     */
+    boolean isEs10 = false;
+}
diff --git a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
index 43adbbc..9799f2b 100644
--- a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
@@ -49,4 +49,9 @@
      * In hex string format ([a-fA-F0-9]*)
      */
     String data;
+    /**
+     * isEs10 indicates that the current streaming APDU contains an ES10 command or it is a regular
+     * APDU. (As per spec SGP.22 V3.0, ES10 commands needs to be sent over command port of MEP-A1)
+     */
+    boolean isEs10 = false;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index cf1b953..39e3ace 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -42,7 +42,6 @@
      *   RadioError:INVALID_CALL_ID
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -71,7 +70,6 @@
      *   RadioError:INVALID_STATE
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -92,7 +90,6 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -122,7 +119,6 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:ABORTED
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:CANCELLED
      */
@@ -163,7 +159,6 @@
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
@@ -185,7 +180,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_CALL_ID
      *   RadioError:OPERATION_NOT_ALLOWED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -212,7 +206,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:FDN_CHECK_FAILURE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SYSTEM_ERR
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -241,7 +234,6 @@
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -260,7 +252,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:FDN_CHECK_FAILURE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -282,7 +273,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -298,7 +288,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -344,7 +333,6 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INTERNAL_ERR
      *   RadioError:MODEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -367,7 +355,6 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -386,7 +373,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -404,7 +390,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -423,7 +408,6 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_ABSENT
      */
     void handleStkCallSetupRequestFromSimResponse(in RadioResponseInfo info);
@@ -442,7 +426,6 @@
      *   RadioError:INVALID_CALL_ID
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void hangupConnectionResponse(in RadioResponseInfo info);
 
@@ -461,7 +444,6 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -482,7 +464,6 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:CANCELLED
      */
     void hangupWaitingOrBackgroundResponse(in RadioResponseInfo info);
@@ -497,7 +478,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void isVoNrEnabledResponse(in RadioResponseInfo info, in boolean enable);
 
@@ -516,7 +496,6 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -536,7 +515,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_CALL_ID
      *   RadioError:INVALID_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
@@ -557,7 +535,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_CALL_ID
      *   RadioError:INVALID_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -578,7 +555,6 @@
      *   RadioError:INVALID_CALL_ID
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
@@ -603,7 +579,6 @@
      *   RadioError:ABORTED
      *   RadioError:SYSTEM_ERR
      *   RadioError:INVALID_STATE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -625,7 +600,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_CALL_ID
      *   RadioError:OPERATION_NOT_ALLOWED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:CANCELLED
      */
@@ -647,7 +621,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_STATE
      *   RadioError:FDN_CHECK_FAILURE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -670,7 +643,6 @@
      *   RadioError:INVALID_STATE
      *   RadioError:FDN_CHECK_FAILURE
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -690,7 +662,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -707,7 +678,6 @@
      *   RadioError:REQUEST_RATE_LIMITED
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -724,7 +694,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_CALL_ID
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -742,7 +711,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -758,7 +726,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void setVoNrEnabledResponse(in RadioResponseInfo info);
 
@@ -776,7 +743,6 @@
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_CALL_ID
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
@@ -796,7 +762,6 @@
      *   RadioError:MODEM_ERR
      *   RadioError:INTERNAL_ERR
      *   RadioError:INVALID_CALL_ID
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      */
@@ -817,7 +782,6 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
index 487d91b..5cf1378 100644
--- a/radio/aidl/compat/libradiocompat/Android.bp
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -31,17 +31,20 @@
         "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
     ],
     shared_libs: [
-        "android.hardware.radio.config-V1-ndk",
+        "android.hardware.radio.config-V2-ndk",
         "android.hardware.radio.config@1.0",
         "android.hardware.radio.config@1.1",
         "android.hardware.radio.config@1.2",
         "android.hardware.radio.config@1.3",
-        "android.hardware.radio.data-V1-ndk",
-        "android.hardware.radio.messaging-V1-ndk",
-        "android.hardware.radio.modem-V1-ndk",
-        "android.hardware.radio.network-V1-ndk",
-        "android.hardware.radio.sim-V1-ndk",
-        "android.hardware.radio.voice-V1-ndk",
+        "android.hardware.radio.data-V2-ndk",
+        "android.hardware.radio.ims-V1-ndk",
+        "android.hardware.radio.ims.media-V1-ndk",
+        "android.hardware.radio.messaging-V2-ndk",
+        "android.hardware.radio.modem-V2-ndk",
+        "android.hardware.radio.network-V2-ndk",
+        "android.hardware.radio.sap-V1-ndk",
+        "android.hardware.radio.sim-V2-ndk",
+        "android.hardware.radio.voice-V2-ndk",
         "android.hardware.radio@1.0",
         "android.hardware.radio@1.1",
         "android.hardware.radio@1.2",
@@ -69,6 +72,11 @@
         "data/RadioResponse-data.cpp",
         "data/RadioData.cpp",
         "data/structs.cpp",
+        "ims/RadioIndication-ims.cpp",
+        "ims/RadioResponse-ims.cpp",
+        "ims/RadioIms.cpp",
+        "ims/media/RadioImsMediaSession.cpp",
+        "ims/media/RadioImsMedia.cpp",
         "messaging/RadioIndication-messaging.cpp",
         "messaging/RadioMessaging.cpp",
         "messaging/RadioResponse-messaging.cpp",
@@ -82,6 +90,9 @@
         "network/RadioResponse-network.cpp",
         "network/structs.cpp",
         "network/utils.cpp",
+        "sap/Sap.cpp",
+        "sap/SapCallback.cpp",
+        "sap/structs.cpp",
         "sim/RadioIndication-sim.cpp",
         "sim/RadioResponse-sim.cpp",
         "sim/RadioSim.cpp",
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.cpp b/radio/aidl/compat/libradiocompat/commonStructs.cpp
index 6e4c873..d65ed1a 100644
--- a/radio/aidl/compat/libradiocompat/commonStructs.cpp
+++ b/radio/aidl/compat/libradiocompat/commonStructs.cpp
@@ -48,6 +48,10 @@
     return v;
 }
 
+uint8_t toHidl(int8_t v) {
+    return v;
+}
+
 aidl::RadioIndicationType toAidl(V1_0::RadioIndicationType type) {
     return aidl::RadioIndicationType(type);
 }
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.h b/radio/aidl/compat/libradiocompat/commonStructs.h
index a4a4869..f43a599 100644
--- a/radio/aidl/compat/libradiocompat/commonStructs.h
+++ b/radio/aidl/compat/libradiocompat/commonStructs.h
@@ -28,6 +28,7 @@
 uint8_t toAidl(int8_t v);
 int8_t toAidl(uint8_t v);
 int32_t toAidl(uint32_t v);
+uint8_t toHidl(int8_t v);
 
 aidl::android::hardware::radio::RadioIndicationType toAidl(V1_0::RadioIndicationType type);
 aidl::android::hardware::radio::RadioResponseType toAidl(V1_0::RadioResponseType type);
diff --git a/radio/aidl/compat/libradiocompat/data/structs.cpp b/radio/aidl/compat/libradiocompat/data/structs.cpp
index 4ff89a1..47f1f86 100644
--- a/radio/aidl/compat/libradiocompat/data/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/data/structs.cpp
@@ -28,14 +28,14 @@
 
 V1_5::DataProfileInfo toHidl(const aidl::DataProfileInfo& info) {
     return {
-            .profileId = V1_0::DataProfileId{info.profileId},
+            .profileId = static_cast<V1_0::DataProfileId>(info.profileId),
             .apn = info.apn,
-            .protocol = V1_4::PdpProtocolType{info.protocol},
-            .roamingProtocol = V1_4::PdpProtocolType{info.roamingProtocol},
-            .authType = V1_0::ApnAuthType{info.authType},
+            .protocol = static_cast<V1_4::PdpProtocolType>(info.protocol),
+            .roamingProtocol = static_cast<V1_4::PdpProtocolType>(info.roamingProtocol),
+            .authType = static_cast<V1_0::ApnAuthType>(info.authType),
             .user = info.user,
             .password = info.password,
-            .type = V1_0::DataProfileInfoType{info.type},
+            .type = static_cast<V1_0::DataProfileInfoType>(info.type),
             .maxConnsTime = info.maxConnsTime,
             .maxConns = info.maxConns,
             .waitTime = info.waitTime,
@@ -74,7 +74,7 @@
             .sliceDifferentiator = info.sliceDifferentiator,
             .mappedHplmnSst = static_cast<V1_6::SliceServiceType>(info.mappedHplmnSst),
             .mappedHplmnSD = info.mappedHplmnSd,
-            .status = V1_6::SliceStatus{info.status},
+            .status = static_cast<V1_6::SliceStatus>(info.status),
     };
 }
 
@@ -106,7 +106,7 @@
 
 V1_1::KeepaliveRequest toHidl(const aidl::KeepaliveRequest& keep) {
     return {
-            .type = V1_1::KeepaliveType{keep.type},
+            .type = static_cast<V1_1::KeepaliveType>(keep.type),
             .sourceAddress = keep.sourceAddress,
             .sourcePort = keep.sourcePort,
             .destinationAddress = keep.destinationAddress,
@@ -137,7 +137,7 @@
             .downlink = toAidl(qos.downlink),
             .uplink = toAidl(qos.uplink),
             .qfi = static_cast<int8_t>(qos.qfi),
-            .averagingWindowMs = qos.averagingWindowMs,
+            .averagingWindowMillis = qos.averagingWindowMs,
     };
 }
 
diff --git a/radio/aidl/compat/libradiocompat/ims/RadioIms.cpp b/radio/aidl/compat/libradiocompat/ims/RadioIms.cpp
new file mode 100644
index 0000000..d2bdfff
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/RadioIms.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIms.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Ims"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::ims;
+constexpr auto ok = &ScopedAStatus::ok;
+
+std::shared_ptr<aidl::IRadioImsResponse> RadioIms::respond() {
+    return mCallbackManager->response().imsCb();
+}
+
+ScopedAStatus RadioIms::setSrvccCallInfo(
+        int32_t serial, const std::vector<aidl::SrvccCall>& /*srvccCalls*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " setSrvccCallInfo is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioIms::updateImsRegistrationInfo(
+        int32_t serial, const aidl::ImsRegistration& /*imsRegistration*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " updateImsRegistrationInfo is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioIms::startImsTraffic(
+        int32_t serial, int32_t /*token*/, aidl::ImsTrafficType /*imsTrafficType*/,
+        ::aidl::android::hardware::radio::AccessNetwork /*accessNetworkType*/,
+        ::aidl::android::hardware::radio::ims::ImsCall::Direction /*trafficDirection*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " startImsTraffic is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioIms::stopImsTraffic(int32_t serial, int32_t /*token*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " stopImsTraffic is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioIms::triggerEpsFallback(int32_t serial, aidl::EpsFallbackReason /*reason*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " triggerEpsFallback is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioIms::sendAnbrQuery(
+        int32_t serial, aidl::ImsStreamType /*mediaType*/, aidl::ImsStreamDirection /*direction*/,
+        int32_t /*bitsPerSecond*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " sendAnbrQuery is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioIms::updateImsCallStatus(
+        int32_t serial, const std::vector<aidl::ImsCall>& /*imsCalls*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " updateImsCallStatus is unsupported by HIDL HALs";
+    return ok();
+}
+
+ScopedAStatus RadioIms::setResponseFunctions(
+        const std::shared_ptr<aidl::IRadioImsResponse>& response,
+        const std::shared_ptr<aidl::IRadioImsIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/ims/RadioIndication-ims.cpp b/radio/aidl/compat/libradiocompat/ims/RadioIndication-ims.cpp
new file mode 100644
index 0000000..10109b8
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/RadioIndication-ims.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ImsIndication"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioTechnology;
+namespace aidl = ::aidl::android::hardware::radio::ims;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioImsIndication> imsCb) {
+    mImsCb = imsCb;
+}
+
+std::shared_ptr<aidl::IRadioImsIndication> RadioIndication::imsCb() {
+    return mImsCb.get();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/ims/RadioResponse-ims.cpp b/radio/aidl/compat/libradiocompat/ims/RadioResponse-ims.cpp
new file mode 100644
index 0000000..831a0ae
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/RadioResponse-ims.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ImsResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::ims;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioImsResponse> imsCb) {
+    mImsCb = imsCb;
+}
+
+std::shared_ptr<aidl::IRadioImsResponse> RadioResponse::imsCb() {
+    return mImsCb.get();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp
new file mode 100644
index 0000000..464a410
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioImsMedia.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ImsMedia"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioImsMedia::setListener(
+        const std::shared_ptr<::aidl::android::hardware::radio::ims::media::
+                                      IImsMediaListener>& /*in_mediaListener*/) {
+    LOG(ERROR) << " setListener is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioImsMedia::openSession(
+        int32_t /*in_sessionId*/,
+        const ::aidl::android::hardware::radio::ims::media::LocalEndPoint& /*in_localEndPoint*/,
+        const ::aidl::android::hardware::radio::ims::media::RtpConfig& /*in_config*/) {
+    LOG(ERROR) << " openSession is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioImsMedia::closeSession(int32_t /*in_sessionId*/) {
+    LOG(ERROR) << " closeSession is unsupported by HIDL HALs";
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp
new file mode 100644
index 0000000..ae86914
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioImsMediaSession.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ImsMediaSession"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::ims::media;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioImsMediaSession::setListener(
+        const std::shared_ptr<aidl::IImsMediaSessionListener>& /*in_sessionListener*/) {
+    LOG(ERROR) << " setListener is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioImsMediaSession::modifySession(const aidl::RtpConfig& /*in_config*/) {
+    LOG(ERROR) << " modifySession is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioImsMediaSession::sendDtmf(char16_t /*in_dtmfDigit*/, int32_t /*in_duration*/) {
+    LOG(ERROR) << " sendDtmf is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioImsMediaSession::startDtmf(char16_t /*in_dtmfDigit*/) {
+    LOG(ERROR) << " startDtmf is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioImsMediaSession::stopDtmf() {
+    LOG(ERROR) << " stopDtmf is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioImsMediaSession::sendHeaderExtension(
+        const std::vector<aidl::RtpHeaderExtension>& /*in_extensions*/) {
+    LOG(ERROR) << " sendHeaderExtension is unsupported by HIDL HALs";
+    return ok();
+}
+ScopedAStatus RadioImsMediaSession::setMediaQualityThreshold(
+        const aidl::MediaQualityThreshold& /*in_threshold*/) {
+    LOG(ERROR) << " setMediaQualityThreshold is unsupported by HIDL HALs";
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIms.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIms.h
new file mode 100644
index 0000000..0dbc565
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIms.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/ims/BnRadioIms.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioIms : public RadioCompatBase, public aidl::android::hardware::radio::ims::BnRadioIms {
+    ::ndk::ScopedAStatus setSrvccCallInfo(
+            int32_t serial,
+            const std::vector<::aidl::android::hardware::radio::ims::SrvccCall>& srvccCalls)
+            override;
+    ::ndk::ScopedAStatus updateImsRegistrationInfo(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::ims::ImsRegistration& imsRegistration) override;
+    ::ndk::ScopedAStatus startImsTraffic(
+            int32_t serial, int32_t token,
+            ::aidl::android::hardware::radio::ims::ImsTrafficType imsTrafficType,
+            ::aidl::android::hardware::radio::AccessNetwork accessNetworkType,
+            ::aidl::android::hardware::radio::ims::ImsCall::Direction trafficDirection) override;
+    ::ndk::ScopedAStatus stopImsTraffic(int32_t serial, int32_t token) override;
+    ::ndk::ScopedAStatus triggerEpsFallback(
+            int32_t serial,
+            ::aidl::android::hardware::radio::ims::EpsFallbackReason reason) override;
+    ::ndk::ScopedAStatus sendAnbrQuery(
+            int32_t serial, ::aidl::android::hardware::radio::ims::ImsStreamType mediaType,
+            ::aidl::android::hardware::radio::ims::ImsStreamDirection direction,
+            int32_t bitsPerSecond) override;
+    ::ndk::ScopedAStatus updateImsCallStatus(
+            int32_t serial,
+            const std::vector<::aidl::android::hardware::radio::ims::ImsCall>& imsCalls) override;
+
+    ::ndk::ScopedAStatus setResponseFunctions(
+            const std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsResponse>&
+                    radioImsResponse,
+            const std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsIndication>&
+                    radioImsIndication) override;
+
+  protected:
+    std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsResponse> respond();
+
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h
new file mode 100644
index 0000000..2ee6bf1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/ims/media/BnImsMedia.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioImsMedia : public RadioCompatBase,
+                      public aidl::android::hardware::radio::ims::media::BnImsMedia {
+    ::ndk::ScopedAStatus setListener(
+            const std::shared_ptr<::aidl::android::hardware::radio::ims::media::IImsMediaListener>&
+                    in_mediaListener) override;
+    ::ndk::ScopedAStatus openSession(
+            int32_t in_sessionId,
+            const ::aidl::android::hardware::radio::ims::media::LocalEndPoint& in_localEndPoint,
+            const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) override;
+    ::ndk::ScopedAStatus closeSession(int32_t in_sessionId) override;
+
+  protected:
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.h
new file mode 100644
index 0000000..00f21fc
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/ims/media/BnImsMediaSession.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioImsMediaSession : public RadioCompatBase,
+                             public aidl::android::hardware::radio::ims::media::BnImsMediaSession {
+    ::ndk::ScopedAStatus setListener(
+            const std::shared_ptr<
+                    ::aidl::android::hardware::radio::ims::media::IImsMediaSessionListener>&
+                    in_sessionListener) override;
+    ::ndk::ScopedAStatus modifySession(
+            const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) override;
+    ::ndk::ScopedAStatus sendDtmf(char16_t in_dtmfDigit, int32_t in_duration) override;
+    ::ndk::ScopedAStatus startDtmf(char16_t in_dtmfDigit) override;
+    ::ndk::ScopedAStatus stopDtmf() override;
+    ::ndk::ScopedAStatus sendHeaderExtension(
+            const std::vector<::aidl::android::hardware::radio::ims::media::RtpHeaderExtension>&
+                    in_extensions) override;
+    ::ndk::ScopedAStatus setMediaQualityThreshold(
+            const ::aidl::android::hardware::radio::ims::media::MediaQualityThreshold& in_threshold)
+            override;
+
+  protected:
+  public:
+    using RadioCompatBase::RadioCompatBase;
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
index 6cfd59c..f042456 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
@@ -19,6 +19,7 @@
 #include "GuaranteedCallback.h"
 
 #include <aidl/android/hardware/radio/data/IRadioDataIndication.h>
+#include <aidl/android/hardware/radio/ims/IRadioImsIndication.h>
 #include <aidl/android/hardware/radio/messaging/IRadioMessagingIndication.h>
 #include <aidl/android/hardware/radio/modem/IRadioModemIndication.h>
 #include <aidl/android/hardware/radio/network/IRadioNetworkIndication.h>
@@ -55,6 +56,10 @@
             ::aidl::android::hardware::radio::voice::IRadioVoiceIndication,
             ::aidl::android::hardware::radio::voice::IRadioVoiceIndicationDefault, true>
             mVoiceCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::ims::IRadioImsIndication,
+            ::aidl::android::hardware::radio::ims::IRadioImsIndicationDefault, true>
+            mImsCb;
 
     // IRadioIndication @ 1.0
     Return<void> radioStateChanged(V1_0::RadioIndicationType type,
@@ -220,6 +225,8 @@
             std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb);
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voicCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsIndication> imsCb);
 
     std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb();
     std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
@@ -228,6 +235,7 @@
     std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> networkCb();
     std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb();
     std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voiceCb();
+    std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsIndication> imsCb();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
index beb1fb0..54bedd8 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
@@ -26,6 +26,7 @@
     ::ndk::ScopedAStatus enableModem(int32_t serial, bool on) override;
     ::ndk::ScopedAStatus getBasebandVersion(int32_t serial) override;
     ::ndk::ScopedAStatus getDeviceIdentity(int32_t serial) override;
+    ::ndk::ScopedAStatus getImei(int32_t serial) override;
     ::ndk::ScopedAStatus getHardwareConfig(int32_t serial) override;
     ::ndk::ScopedAStatus getModemActivityInfo(int32_t serial) override;
     ::ndk::ScopedAStatus getModemStackStatus(int32_t serial) override;
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
index 9784665..d57c83d 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -18,6 +18,9 @@
 #include "RadioCompatBase.h"
 
 #include <aidl/android/hardware/radio/network/BnRadioNetwork.h>
+#include <aidl/android/hardware/radio/network/IRadioNetwork.h>
+
+// using namespace aidl::android::hardware::radio::network;
 
 namespace android::hardware::radio::compat {
 
@@ -90,6 +93,21 @@
             ::aidl::android::hardware::radio::network::UsageSetting usageSetting) override;
     ::ndk::ScopedAStatus getUsageSetting(int32_t serial) override;
 
+    ::ndk::ScopedAStatus setEmergencyMode(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::network::EmergencyMode emergencyMode) override;
+    ::ndk::ScopedAStatus triggerEmergencyNetworkScan(
+            int32_t serial,
+            const ::aidl::android::hardware::radio::network::EmergencyNetworkScanTrigger&
+                    scanTrigger) override;
+    ::ndk::ScopedAStatus cancelEmergencyNetworkScan(int32_t serial, bool resetScan) override;
+    ::ndk::ScopedAStatus exitEmergencyMode(int32_t serial) override;
+    ::ndk::ScopedAStatus isN1ModeEnabled(int32_t serial) override;
+    ::ndk::ScopedAStatus setN1ModeEnabled(int32_t serial, bool enable) override;
+
+    ::ndk::ScopedAStatus setNullCipherAndIntegrityEnabled(int32_t serial, bool enabled) override;
+    ::ndk::ScopedAStatus isNullCipherAndIntegrityEnabled(int32_t serial) override;
+
   protected:
     std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> respond();
 
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
index 1f82dd1..e20eed9 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
@@ -19,6 +19,8 @@
 #include "GuaranteedCallback.h"
 
 #include <aidl/android/hardware/radio/data/IRadioDataResponse.h>
+#include <aidl/android/hardware/radio/ims/IRadioImsResponse.h>
+#include <aidl/android/hardware/radio/ims/media/IImsMediaListener.h>
 #include <aidl/android/hardware/radio/messaging/IRadioMessagingResponse.h>
 #include <aidl/android/hardware/radio/modem/IRadioModemResponse.h>
 #include <aidl/android/hardware/radio/network/IRadioNetworkResponse.h>
@@ -49,6 +51,9 @@
     GuaranteedCallback<::aidl::android::hardware::radio::voice::IRadioVoiceResponse,
                        ::aidl::android::hardware::radio::voice::IRadioVoiceResponseDefault>
             mVoiceCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::ims::IRadioImsResponse,
+                       ::aidl::android::hardware::radio::ims::IRadioImsResponseDefault>
+            mImsCb;
 
     // IRadioResponse @ 1.0
     Return<void> getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
@@ -440,6 +445,8 @@
             std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb);
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb);
+    void setResponseFunction(
+            std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsResponse> imsCb);
 
     std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb();
     std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
@@ -448,6 +455,7 @@
     std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> networkCb();
     std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb();
     std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb();
+    std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsResponse> imsCb();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
index ff91aef..99e4b25 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
@@ -40,7 +40,8 @@
     ::ndk::ScopedAStatus getImsiForApp(int32_t serial, const std::string& aid) override;
     ::ndk::ScopedAStatus getSimPhonebookCapacity(int32_t serial) override;
     ::ndk::ScopedAStatus getSimPhonebookRecords(int32_t serial) override;
-    ::ndk::ScopedAStatus iccCloseLogicalChannel(int32_t serial, int32_t channelId) override;
+    ::ndk::ScopedAStatus iccCloseLogicalChannelWithSessionInfo(int32_t serial,
+            const ::aidl::android::hardware::radio::sim::SessionInfo& recordInfo) override;
     ::ndk::ScopedAStatus iccIoForApp(
             int32_t serial, const ::aidl::android::hardware::radio::sim::IccIo& iccIo) override;
     ::ndk::ScopedAStatus iccOpenLogicalChannel(int32_t serial, const std::string& aid,
@@ -102,6 +103,7 @@
 
   protected:
     std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> respond();
+    ::ndk::ScopedAStatus iccCloseLogicalChannel(int32_t serial, int32_t channelId) override;
 
   public:
     using RadioCompatBase::RadioCompatBase;
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/Sap.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/Sap.h
new file mode 100644
index 0000000..a293d11
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/Sap.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+#include "SapCallback.h"
+
+#include <aidl/android/hardware/radio/sap/BnSap.h>
+#include <android/hardware/radio/1.0/ISap.h>
+#include <android/hardware/radio/1.0/ISapCallback.h>
+
+namespace android::hardware::radio::compat {
+
+/**
+ * HAL translator from HIDL ISap to AIDL ISap
+ *
+ * This class wraps existing HIDL implementation (either a binder stub or real
+ * class implementing the HAL) and implements AIDL HAL. It's up to the caller to
+ * fetch source implementation and publish resulting HAL instance.
+ */
+class Sap : public aidl::android::hardware::radio::sap::BnSap {
+    const sp<radio::V1_0::ISap> mHal;
+
+    const sp<SapCallback> mSapCallback;
+
+    ::ndk::ScopedAStatus apduReq(int32_t serial,
+                                 aidl::android::hardware::radio::sap::SapApduType type,
+                                 const std::vector<uint8_t>& command) override;
+    ::ndk::ScopedAStatus connectReq(int32_t serial, int32_t maxMsgSize) override;
+    ::ndk::ScopedAStatus disconnectReq(int32_t serial) override;
+    ::ndk::ScopedAStatus powerReq(int32_t serial, bool state) override;
+    ::ndk::ScopedAStatus resetSimReq(int32_t serial) override;
+    ::ndk::ScopedAStatus setCallback(
+            const std::shared_ptr<::aidl::android::hardware::radio::sap::ISapCallback>& sapCallback)
+            override;
+    ::ndk::ScopedAStatus setTransferProtocolReq(
+            int32_t serial,
+            aidl::android::hardware::radio::sap::SapTransferProtocol transferProtocol) override;
+    ::ndk::ScopedAStatus transferAtrReq(int32_t serial) override;
+    ::ndk::ScopedAStatus transferCardReaderStatusReq(int32_t serial) override;
+
+  public:
+    /**
+     * Constructs AIDL ISap instance wrapping existing HIDL ISap instance.
+     *
+     * \param hidlHal existing HIDL ISap HAL instance
+     */
+    Sap(sp<V1_0::ISap> hidlHal);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/SapCallback.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/SapCallback.h
new file mode 100644
index 0000000..7e72106
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/SapCallback.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "GuaranteedCallback.h"
+
+#include <aidl/android/hardware/radio/sap/ISapCallback.h>
+#include <android/hardware/radio/1.0/ISapCallback.h>
+
+namespace android::hardware::radio::compat {
+
+class SapCallback : public V1_0::ISapCallback {
+    GuaranteedCallback<aidl::android::hardware::radio::sap::ISapCallback,
+                       aidl::android::hardware::radio::sap::ISapCallbackDefault>
+            mCallback;
+
+    Return<void> apduResponse(int32_t serial, V1_0::SapResultCode resultCode,
+                              const ::android::hardware::hidl_vec<uint8_t>& apduRsp) override;
+    Return<void> connectResponse(int32_t serial, V1_0::SapConnectRsp sapConnectRsp,
+                                 int32_t maxMsgSize) override;
+    Return<void> disconnectIndication(int32_t serial,
+                                      V1_0::SapDisconnectType disconnectType) override;
+    Return<void> disconnectResponse(int32_t serial) override;
+    Return<void> errorResponse(int32_t serial) override;
+    Return<void> powerResponse(int32_t serial, V1_0::SapResultCode resultCode) override;
+    Return<void> resetSimResponse(int32_t serial, V1_0::SapResultCode resultCode) override;
+    Return<void> statusIndication(int32_t serial, V1_0::SapStatus status) override;
+    Return<void> transferAtrResponse(int32_t serial, V1_0::SapResultCode resultCode,
+                                     const ::android::hardware::hidl_vec<uint8_t>& atr) override;
+    Return<void> transferCardReaderStatusResponse(int32_t serial, V1_0::SapResultCode resultCode,
+                                                  int32_t cardReaderStatus) override;
+    Return<void> transferProtocolResponse(int32_t serial, V1_0::SapResultCode resultCode) override;
+
+  public:
+    void setResponseFunction(
+            const std::shared_ptr<aidl::android::hardware::radio::sap::ISapCallback>& callback);
+
+    std::shared_ptr<aidl::android::hardware::radio::sap::ISapCallback> respond();
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/structs.cpp b/radio/aidl/compat/libradiocompat/messaging/structs.cpp
index 9019680..f30c5ce 100644
--- a/radio/aidl/compat/libradiocompat/messaging/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/structs.cpp
@@ -45,11 +45,11 @@
 
 static V1_0::CdmaSmsAddress toHidl(const aidl::CdmaSmsAddress& addr) {
     return {
-            .digitMode = V1_0::CdmaSmsDigitMode{addr.digitMode},
+            .digitMode = static_cast<V1_0::CdmaSmsDigitMode>(addr.digitMode),
             .numberMode = addr.isNumberModeDataNetwork ? V1_0::CdmaSmsNumberMode::DATA_NETWORK
                                                        : V1_0::CdmaSmsNumberMode::NOT_DATA_NETWORK,
-            .numberType = V1_0::CdmaSmsNumberType{addr.numberType},
-            .numberPlan = V1_0::CdmaSmsNumberPlan{addr.numberPlan},
+            .numberType = static_cast<V1_0::CdmaSmsNumberType>(addr.numberType),
+            .numberPlan = static_cast<V1_0::CdmaSmsNumberPlan>(addr.numberPlan),
             .digits = addr.digits,
     };
 }
@@ -64,7 +64,7 @@
 
 static V1_0::CdmaSmsSubaddress toHidl(const aidl::CdmaSmsSubaddress& addr) {
     return {
-            .subaddressType = V1_0::CdmaSmsSubaddressType{addr.subaddressType},
+            .subaddressType = static_cast<V1_0::CdmaSmsSubaddressType>(addr.subaddressType),
             .odd = addr.odd,
             .digits = addr.digits,
     };
@@ -94,7 +94,7 @@
 
 V1_0::ImsSmsMessage toHidl(const aidl::ImsSmsMessage& msg) {
     return {
-            .tech = V1_0::RadioTechnologyFamily{msg.tech},
+            .tech = static_cast<V1_0::RadioTechnologyFamily>(msg.tech),
             .retry = msg.retry,
             .messageRef = msg.messageRef,
             .cdmaMessage = toHidl(msg.cdmaMessage),
@@ -147,14 +147,14 @@
 
 V1_0::CdmaSmsWriteArgs toHidl(const aidl::CdmaSmsWriteArgs& args) {
     return {
-            .status = V1_0::CdmaSmsWriteArgsStatus{args.status},
+            .status = static_cast<V1_0::CdmaSmsWriteArgsStatus>(args.status),
             .message = toHidl(args.message),
     };
 }
 
 V1_0::SmsWriteArgs toHidl(const aidl::SmsWriteArgs& args) {
     return {
-            .status = V1_0::SmsWriteArgsStatus{args.status},
+            .status = static_cast<V1_0::SmsWriteArgsStatus>(args.status),
             .pdu = args.pdu,
             .smsc = args.smsc,
     };
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
index d28b940..f088b10 100644
--- a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
@@ -15,7 +15,7 @@
  */
 
 #include <libradiocompat/RadioModem.h>
-
+#include "commonStructs.h"
 #include "debug.h"
 #include "structs.h"
 
@@ -49,6 +49,13 @@
     return ok();
 }
 
+ScopedAStatus RadioModem::getImei(int32_t serial) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " getImei is unsupported by HIDL HALs";
+    respond()->getImeiResponse(notSupported(serial), {});
+    return ok();
+}
+
 ScopedAStatus RadioModem::getHardwareConfig(int32_t serial) {
     LOG_CALL << serial;
     mHal1_5->getHardwareConfig(serial);
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.cpp b/radio/aidl/compat/libradiocompat/modem/structs.cpp
index 69e651b..6f32cdf 100644
--- a/radio/aidl/compat/libradiocompat/modem/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/structs.cpp
@@ -30,7 +30,7 @@
 
 V1_0::NvWriteItem toHidl(const aidl::NvWriteItem& item) {
     return {
-            .itemId = V1_0::NvItem{item.itemId},
+            .itemId = static_cast<V1_0::NvItem>(item.itemId),
             .value = item.value,
     };
 }
@@ -48,10 +48,10 @@
 V1_0::RadioCapability toHidl(const aidl::RadioCapability& capa) {
     return {
             .session = capa.session,
-            .phase = V1_0::RadioCapabilityPhase{capa.phase},
+            .phase = static_cast<V1_0::RadioCapabilityPhase>(capa.phase),
             .raf = toHidlBitfield<V1_0::RadioAccessFamily>(capa.raf),
             .logicalModemUuid = capa.logicalModemUuid,
-            .status = V1_0::RadioCapabilityStatus{capa.status},
+            .status = static_cast<V1_0::RadioCapabilityStatus>(capa.status),
     };
 }
 
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
index d5e2a8d..a379eec 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -261,6 +261,11 @@
     if (infos.size() > 1) {
         LOG(WARNING) << "Multi-element reporting criteria are not supported with HIDL HAL";
     }
+    if (infos[0].signalMeasurement == aidl::SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_ECNO) {
+        LOG(WARNING) << "SIGNAL_MEASUREMENT_TYPE_ECNO are not supported with HIDL HAL";
+        respond()->setSignalStrengthReportingCriteriaResponse(notSupported(serial));
+        return ok();
+    }
     mHal1_5->setSignalStrengthReportingCriteria_1_5(serial, toHidl(infos[0]),
                                                     V1_5::AccessNetwork(infos[0].ran));
     return ok();
@@ -311,4 +316,60 @@
     return ok();
 }
 
+ScopedAStatus RadioNetwork::setEmergencyMode(int32_t serial, aidl::EmergencyMode) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " setEmergencyMode is unsupported by HIDL HALs";
+    respond()->setEmergencyModeResponse(notSupported(serial), {});
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::triggerEmergencyNetworkScan(int32_t serial,
+        const aidl::EmergencyNetworkScanTrigger&) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " triggerEmergencyNetworkScan is unsupported by HIDL HALs";
+    respond()->triggerEmergencyNetworkScanResponse(notSupported(serial));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::cancelEmergencyNetworkScan(int32_t serial, bool) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " cancelEmergencyNetworkScan is unsupported by HIDL HALs";
+    respond()->cancelEmergencyNetworkScanResponse(notSupported(serial));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::exitEmergencyMode(int32_t serial) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " exitEmergencyMode is unsupported by HIDL HALs";
+    respond()->exitEmergencyModeResponse(notSupported(serial));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setNullCipherAndIntegrityEnabled(int32_t serial, bool) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " setNullCipherAndIntegrityEnabled is unsupported by HIDL HALs";
+    respond()->setNullCipherAndIntegrityEnabledResponse(notSupported(serial));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::isNullCipherAndIntegrityEnabled(int32_t serial) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " isNullCipherAndIntegrityEnabled is unsupported by HIDL HALs";
+    respond()->isNullCipherAndIntegrityEnabledResponse(notSupported(serial), true);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::isN1ModeEnabled(int32_t serial) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " isN1ModeEnabled is unsupported by HIDL HALs";
+    respond()->isN1ModeEnabledResponse(notSupported(serial), false);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setN1ModeEnabled(int32_t serial, bool /*enable*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " setN1ModeEnabled is unsupported by HIDL HALs";
+    respond()->setN1ModeEnabledResponse(notSupported(serial));
+    return ok();
+}
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/structs.cpp b/radio/aidl/compat/libradiocompat/network/structs.cpp
index d0b3b90..30d4f6d 100644
--- a/radio/aidl/compat/libradiocompat/network/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/network/structs.cpp
@@ -66,7 +66,7 @@
 
 V1_5::SignalThresholdInfo toHidl(const aidl::SignalThresholdInfo& info) {
     return {
-            .signalMeasurement = V1_5::SignalMeasurementType{info.signalMeasurement},
+            .signalMeasurement = static_cast<V1_5::SignalMeasurementType>(info.signalMeasurement),
             .hysteresisMs = info.hysteresisMs,
             .hysteresisDb = info.hysteresisDb,
             .thresholds = info.thresholds,
@@ -155,7 +155,7 @@
 
 V1_5::NetworkScanRequest toHidl(const aidl::NetworkScanRequest& req) {
     return {
-            .type = V1_1::ScanType{req.type},
+            .type = static_cast<V1_1::ScanType>(req.type),
             .interval = req.interval,
             .specifiers = toHidl(req.specifiers),
             .maxSearchTime = req.maxSearchTime,
diff --git a/radio/aidl/compat/libradiocompat/sap/Sap.cpp b/radio/aidl/compat/libradiocompat/sap/Sap.cpp
new file mode 100644
index 0000000..1a77169
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sap/Sap.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/Sap.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Sap"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::sap;
+constexpr auto ok = &ScopedAStatus::ok;
+
+Sap::Sap(sp<V1_0::ISap> hidlHal) : mHal(hidlHal), mSapCallback(sp<SapCallback>::make()) {}
+
+ScopedAStatus Sap::apduReq(int32_t serial, aidl::SapApduType type,
+                           const std::vector<uint8_t>& command) {
+    LOG_CALL << serial;
+    mHal->apduReq(serial, toHidl(type), toHidl(command));
+    return ok();
+}
+
+ScopedAStatus Sap::connectReq(int32_t serial, int32_t maxMsgSize) {
+    LOG_CALL << serial;
+    mHal->connectReq(serial, maxMsgSize);
+    return ok();
+}
+
+ScopedAStatus Sap::disconnectReq(int32_t serial) {
+    LOG_CALL << serial;
+    mHal->disconnectReq(serial);
+    return ok();
+}
+
+ScopedAStatus Sap::powerReq(int32_t serial, bool state) {
+    LOG_CALL << serial;
+    mHal->powerReq(serial, state);
+    return ok();
+}
+
+ScopedAStatus Sap::resetSimReq(int32_t serial) {
+    LOG_CALL << serial;
+    mHal->resetSimReq(serial);
+    return ok();
+}
+
+ScopedAStatus Sap::setCallback(
+        const std::shared_ptr<::aidl::android::hardware::radio::sap::ISapCallback>& sapCallback) {
+    LOG_CALL << sapCallback;
+
+    CHECK(sapCallback);
+
+    mSapCallback->setResponseFunction(sapCallback);
+    mHal->setCallback(mSapCallback).assertOk();
+    return ok();
+}
+ScopedAStatus Sap::setTransferProtocolReq(int32_t serial,
+                                          aidl::SapTransferProtocol transferProtocol) {
+    LOG_CALL << serial;
+    mHal->setTransferProtocolReq(serial, toHidl(transferProtocol));
+    return ok();
+}
+
+ScopedAStatus Sap::transferAtrReq(int32_t serial) {
+    LOG_CALL << serial;
+    mHal->transferAtrReq(serial);
+    return ok();
+}
+ScopedAStatus Sap::transferCardReaderStatusReq(int32_t serial) {
+    LOG_CALL << serial;
+    mHal->transferCardReaderStatusReq(serial);
+    return ok();
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sap/SapCallback.cpp b/radio/aidl/compat/libradiocompat/sap/SapCallback.cpp
new file mode 100644
index 0000000..a40dff8
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sap/SapCallback.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/SapCallback.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "SapCallback"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sap;
+
+void SapCallback::setResponseFunction(const std::shared_ptr<aidl::ISapCallback>& callback) {
+    mCallback = callback;
+}
+
+std::shared_ptr<aidl::ISapCallback> SapCallback::respond() {
+    return mCallback.get();
+}
+
+Return<void> SapCallback::apduResponse(int32_t serial, V1_0::SapResultCode resultCode,
+                                       const hidl_vec<uint8_t>& apduRsp) {
+    LOG_CALL << serial;
+    respond()->apduResponse(serial, toAidl(resultCode), apduRsp);
+    return {};
+}
+
+Return<void> SapCallback::connectResponse(int32_t serial, V1_0::SapConnectRsp sapConnectRsp,
+                                          int32_t maxMsgSize) {
+    LOG_CALL << serial;
+    respond()->connectResponse(serial, toAidl(sapConnectRsp), maxMsgSize);
+    return {};
+}
+
+Return<void> SapCallback::disconnectIndication(int32_t serial,
+                                               V1_0::SapDisconnectType disconnectType) {
+    LOG_CALL << serial;
+    respond()->disconnectIndication(serial, toAidl(disconnectType));
+    return {};
+}
+
+Return<void> SapCallback::disconnectResponse(int32_t serial) {
+    LOG_CALL << serial;
+    respond()->disconnectResponse(serial);
+    return {};
+}
+
+Return<void> SapCallback::errorResponse(int32_t serial) {
+    LOG_CALL << serial;
+    respond()->errorResponse(serial);
+    return {};
+}
+
+Return<void> SapCallback::powerResponse(int32_t serial, V1_0::SapResultCode resultCode) {
+    LOG_CALL << serial;
+    respond()->powerResponse(serial, toAidl(resultCode));
+    return {};
+}
+
+Return<void> SapCallback::resetSimResponse(int32_t serial, V1_0::SapResultCode resultCode) {
+    LOG_CALL << serial;
+    respond()->resetSimResponse(serial, toAidl(resultCode));
+    return {};
+}
+
+Return<void> SapCallback::statusIndication(int32_t serial, V1_0::SapStatus status) {
+    LOG_CALL << serial;
+    respond()->statusIndication(serial, toAidl(status));
+    return {};
+}
+
+Return<void> SapCallback::transferAtrResponse(int32_t serial, V1_0::SapResultCode resultCode,
+                                              const hidl_vec<uint8_t>& atr) {
+    LOG_CALL << serial;
+    respond()->transferAtrResponse(serial, toAidl(resultCode), atr);
+    return {};
+}
+
+Return<void> SapCallback::transferCardReaderStatusResponse(int32_t serial,
+                                                           V1_0::SapResultCode resultCode,
+                                                           int32_t cardReaderStatus) {
+    LOG_CALL << serial;
+    respond()->transferCardReaderStatusResponse(serial, toAidl(resultCode), cardReaderStatus);
+    return {};
+}
+
+Return<void> SapCallback::transferProtocolResponse(int32_t serial, V1_0::SapResultCode resultCode) {
+    LOG_CALL << serial;
+    respond()->transferProtocolResponse(serial, toAidl(resultCode));
+    return {};
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sap/structs.cpp b/radio/aidl/compat/libradiocompat/sap/structs.cpp
new file mode 100644
index 0000000..522056b
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sap/structs.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "structs.h"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sap;
+
+V1_0::SapApduType toHidl(const aidl::SapApduType sapApduType) {
+    return V1_0::SapApduType(sapApduType);
+}
+
+V1_0::SapTransferProtocol toHidl(const aidl::SapTransferProtocol sapTransferProtocol) {
+    return V1_0::SapTransferProtocol(sapTransferProtocol);
+}
+
+aidl::SapResultCode toAidl(const V1_0::SapResultCode sapResultCode) {
+    return aidl::SapResultCode(sapResultCode);
+}
+
+aidl::SapConnectRsp toAidl(const V1_0::SapConnectRsp sapConnectRsp) {
+    return aidl::SapConnectRsp(sapConnectRsp);
+}
+
+aidl::SapDisconnectType toAidl(const V1_0::SapDisconnectType sapDisconnectType) {
+    return aidl::SapDisconnectType(sapDisconnectType);
+}
+
+aidl::SapStatus toAidl(const V1_0::SapStatus sapStatus) {
+    return aidl::SapStatus(sapStatus);
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sap/structs.h b/radio/aidl/compat/libradiocompat/sap/structs.h
new file mode 100644
index 0000000..d88120d
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sap/structs.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, eithe r express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/sap/ISap.h>
+#include <android/hardware/radio/1.0/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::SapApduType toHidl(aidl::android::hardware::radio::sap::SapApduType sapAdpuType);
+V1_0::SapTransferProtocol toHidl(
+        aidl::android::hardware::radio::sap::SapTransferProtocol sapTransferProtocol);
+
+aidl::android::hardware::radio::sap::SapResultCode toAidl(V1_0::SapResultCode sapResultCode);
+aidl::android::hardware::radio::sap::SapConnectRsp toAidl(V1_0::SapConnectRsp sapConnectRsp);
+aidl::android::hardware::radio::sap::SapDisconnectType toAidl(
+        V1_0::SapDisconnectType sapDisconnectType);
+aidl::android::hardware::radio::sap::SapStatus toAidl(V1_0::SapStatus sapStatus);
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
index b43f64f..490b07b 100644
--- a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
@@ -124,6 +124,14 @@
     return ok();
 }
 
+ScopedAStatus RadioSim::iccCloseLogicalChannelWithSessionInfo(int32_t serial,
+                                                        const aidl::SessionInfo& /*SessionInfo*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " iccCloseLogicalChannelWithSessionInfo is unsupported by HIDL HALs";
+    respond()->iccCloseLogicalChannelWithSessionInfoResponse(notSupported(serial));
+    return ok();
+}
+
 ScopedAStatus RadioSim::iccIoForApp(int32_t serial, const aidl::IccIo& iccIo) {
     LOG_CALL << serial;
     mHal1_5->iccIOForApp(serial, toHidl(iccIo));
@@ -289,5 +297,4 @@
     }
     return ok();
 }
-
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.cpp b/radio/aidl/compat/libradiocompat/sim/structs.cpp
index bfbff02..00db2b8 100644
--- a/radio/aidl/compat/libradiocompat/sim/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/structs.cpp
@@ -65,7 +65,7 @@
     return {
             .mcc = carrier.mcc,
             .mnc = carrier.mnc,
-            .matchType = V1_0::CarrierMatchType{carrier.matchType},
+            .matchType = static_cast<V1_0::CarrierMatchType>(carrier.matchType),
             .matchData = carrier.matchData,
     };
 }
@@ -107,7 +107,7 @@
 V1_6::ImsiEncryptionInfo toHidl_1_6(const aidl::ImsiEncryptionInfo& info) {
     return {
             .base = toHidl(info),
-            .keyType = V1_6::PublicKeyType{info.keyType},
+            .keyType = static_cast<V1_6::PublicKeyType>(info.keyType),
     };
 }
 
diff --git a/radio/aidl/compat/libradiocompat/voice/structs.cpp b/radio/aidl/compat/libradiocompat/voice/structs.cpp
index 254ea20..35c8d46 100644
--- a/radio/aidl/compat/libradiocompat/voice/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/structs.cpp
@@ -29,15 +29,15 @@
 V1_0::Dial toHidl(const aidl::Dial& info) {
     return {
             .address = info.address,
-            .clir = V1_0::Clir{info.clir},
+            .clir = static_cast<V1_0::Clir>(info.clir),
             .uusInfo = toHidl(info.uusInfo),
     };
 }
 
 V1_0::UusInfo toHidl(const aidl::UusInfo& info) {
     return {
-            .uusType = V1_0::UusType{info.uusType},
-            .uusDcs = V1_0::UusDcs{info.uusDcs},
+            .uusType = static_cast<V1_0::UusType>(info.uusType),
+            .uusDcs = static_cast<V1_0::UusDcs>(info.uusDcs),
             .uusData = info.uusData,
     };
 }
@@ -55,7 +55,7 @@
 
 V1_0::CallForwardInfo toHidl(const aidl::CallForwardInfo& info) {
     return {
-            .status = V1_0::CallForwardInfoStatus{info.status},
+            .status = static_cast<V1_0::CallForwardInfoStatus>(info.status),
             .reason = info.reason,
             .serviceClass = info.serviceClass,
             .toa = info.toa,
diff --git a/radio/aidl/compat/service/Android.bp b/radio/aidl/compat/service/Android.bp
index 52eb71f..dff0182 100644
--- a/radio/aidl/compat/service/Android.bp
+++ b/radio/aidl/compat/service/Android.bp
@@ -34,17 +34,20 @@
     ],
     shared_libs: [
         "android.hardware.radio-library.compat",
-        "android.hardware.radio.config-V1-ndk",
+        "android.hardware.radio.config-V2-ndk",
         "android.hardware.radio.config@1.0",
         "android.hardware.radio.config@1.1",
         "android.hardware.radio.config@1.2",
         "android.hardware.radio.config@1.3",
-        "android.hardware.radio.data-V1-ndk",
-        "android.hardware.radio.messaging-V1-ndk",
-        "android.hardware.radio.modem-V1-ndk",
-        "android.hardware.radio.network-V1-ndk",
-        "android.hardware.radio.sim-V1-ndk",
-        "android.hardware.radio.voice-V1-ndk",
+        "android.hardware.radio.data-V2-ndk",
+        "android.hardware.radio.ims-V1-ndk",
+        "android.hardware.radio.ims.media-V1-ndk",
+        "android.hardware.radio.messaging-V2-ndk",
+        "android.hardware.radio.modem-V2-ndk",
+        "android.hardware.radio.network-V2-ndk",
+        "android.hardware.radio.sap-V1-ndk",
+        "android.hardware.radio.sim-V2-ndk",
+        "android.hardware.radio.voice-V2-ndk",
         "android.hardware.radio@1.0",
         "android.hardware.radio@1.1",
         "android.hardware.radio@1.2",
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
index 021ee89..e79d3c0 100644
--- a/radio/aidl/vts/Android.bp
+++ b/radio/aidl/vts/Android.bp
@@ -41,6 +41,12 @@
         "radio_data_indication.cpp",
         "radio_data_response.cpp",
         "radio_data_test.cpp",
+        "radio_ims_indication.cpp",
+        "radio_ims_response.cpp",
+        "radio_ims_test.cpp",
+        "radio_imsmedia_listener.cpp",
+        "radio_imsmedia_session_listener.cpp",
+        "radio_imsmedia_test.cpp",
         "radio_messaging_indication.cpp",
         "radio_messaging_response.cpp",
         "radio_messaging_test.cpp",
@@ -50,6 +56,8 @@
         "radio_network_indication.cpp",
         "radio_network_response.cpp",
         "radio_network_test.cpp",
+        "radio_sap_callback.cpp",
+        "radio_sap_test.cpp",
         "radio_sim_indication.cpp",
         "radio_sim_response.cpp",
         "radio_sim_test.cpp",
@@ -63,14 +71,17 @@
         "libvintf",
     ],
     static_libs: [
-        "android.hardware.radio-V1-ndk",
-        "android.hardware.radio.config-V1-ndk",
-        "android.hardware.radio.data-V1-ndk",
-        "android.hardware.radio.messaging-V1-ndk",
-        "android.hardware.radio.modem-V1-ndk",
-        "android.hardware.radio.network-V1-ndk",
-        "android.hardware.radio.sim-V1-ndk",
-        "android.hardware.radio.voice-V1-ndk",
+        "android.hardware.radio-V2-ndk",
+        "android.hardware.radio.config-V2-ndk",
+        "android.hardware.radio.data-V2-ndk",
+        "android.hardware.radio.ims-V1-ndk",
+        "android.hardware.radio.ims.media-V1-ndk",
+        "android.hardware.radio.messaging-V2-ndk",
+        "android.hardware.radio.modem-V2-ndk",
+        "android.hardware.radio.network-V2-ndk",
+        "android.hardware.radio.sap-V1-ndk",
+        "android.hardware.radio.sim-V2-ndk",
+        "android.hardware.radio.voice-V2-ndk",
     ],
     test_suites: [
         "general-tests",
diff --git a/radio/aidl/vts/AndroidTest.xml b/radio/aidl/vts/AndroidTest.xml
index 36381d1..7edc072 100644
--- a/radio/aidl/vts/AndroidTest.xml
+++ b/radio/aidl/vts/AndroidTest.xml
@@ -16,6 +16,7 @@
 <configuration description="Runs VtsHalRadioTargetTest.">
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
 
     <target_preparer class="com.android.tradefed.targetprep.MultiSimPreparer" />
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
@@ -31,4 +32,4 @@
         <option name="native-test-timeout" value="300000" /> <!-- 5 min -->
         <option name="module-name" value="VtsHalRadioTargetTest" />
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/radio/aidl/vts/OWNERS b/radio/aidl/vts/OWNERS
deleted file mode 100644
index e75c6c8..0000000
--- a/radio/aidl/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 20868
-include ../../1.0/vts/OWNERS
-
diff --git a/radio/aidl/vts/VtsHalRadioTargetTest.cpp b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
index 1ebc6af..c04173b 100644
--- a/radio/aidl/vts/VtsHalRadioTargetTest.cpp
+++ b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
@@ -18,9 +18,12 @@
 
 #include "radio_config_utils.h"
 #include "radio_data_utils.h"
+#include "radio_ims_utils.h"
+#include "radio_imsmedia_utils.h"
 #include "radio_messaging_utils.h"
 #include "radio_modem_utils.h"
 #include "radio_network_utils.h"
+#include "radio_sap_utils.h"
 #include "radio_sim_utils.h"
 #include "radio_voice_utils.h"
 
@@ -54,6 +57,11 @@
         testing::ValuesIn(android::getAidlHalInstanceNames(IRadioNetwork::descriptor)),
         android::PrintInstanceNameToString);
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SapTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, SapTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ISap::descriptor)),
+                         android::PrintInstanceNameToString);
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioSimTest);
 INSTANTIATE_TEST_SUITE_P(PerInstance, RadioSimTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(IRadioSim::descriptor)),
@@ -65,6 +73,17 @@
         testing::ValuesIn(android::getAidlHalInstanceNames(IRadioVoice::descriptor)),
         android::PrintInstanceNameToString);
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioImsTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioImsTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioIms::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioImsMediaTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioImsMediaTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IImsMedia::descriptor)),
+                         android::PrintInstanceNameToString);
+
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
     ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.cpp b/radio/aidl/vts/radio_aidl_hal_utils.cpp
index 5781b42..1515201 100644
--- a/radio/aidl/vts/radio_aidl_hal_utils.cpp
+++ b/radio/aidl/vts/radio_aidl_hal_utils.cpp
@@ -16,7 +16,6 @@
 #define LOG_TAG "RadioTest"
 
 #include "radio_aidl_hal_utils.h"
-#include <iostream>
 #include "VtsCoreUtil.h"
 #include "radio_config_utils.h"
 #include "radio_sim_utils.h"
@@ -144,11 +143,25 @@
     return true;
 }
 
+void RadioServiceTest::SetUp() {
+    ALOGD("BEGIN %s#%s", ::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name(),
+          ::testing::UnitTest::GetInstance()->current_test_info()->name());
+    count_ = 0;
+    serial = -1;
+}
+
+void RadioServiceTest::TearDown() {
+    count_ = 0;
+    serial = -1;
+    ALOGD("END %s#%s", ::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name(),
+          ::testing::UnitTest::GetInstance()->current_test_info()->name());
+}
+
 /*
  * Notify that the response message is received.
  */
 void RadioServiceTest::notify(int receivedSerial) {
-    std::unique_lock<std::mutex> lock(mtx_);
+    std::lock_guard<std::mutex> lock(mtx_);
     if (serial == receivedSerial) {
         count_++;
         cv_.notify_one();
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.h b/radio/aidl/vts/radio_aidl_hal_utils.h
index e68c5c1..d8aa024 100644
--- a/radio/aidl/vts/radio_aidl_hal_utils.h
+++ b/radio/aidl/vts/radio_aidl_hal_utils.h
@@ -25,7 +25,6 @@
 #include <aidl/android/hardware/radio/sim/CardStatus.h>
 #include <aidl/android/hardware/radio/sim/IRadioSim.h>
 #include <utils/Log.h>
-#include <vector>
 
 using namespace aidl::android::hardware::radio;
 using aidl::android::hardware::radio::config::SimSlotStatus;
@@ -67,6 +66,8 @@
 
 static constexpr const char* FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
 
+static constexpr const char* FEATURE_TELEPHONY_IMS = "android.hardware.telephony.ims";
+
 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
 #define MODEM_SET_SIM_POWER_DELAY_IN_SECONDS 2
@@ -136,14 +137,15 @@
 /**
  * RadioServiceTest base class
  */
-class RadioServiceTest {
+class RadioServiceTest : public ::testing::TestWithParam<std::string> {
   protected:
-    std::mutex mtx_;
-    std::condition_variable cv_;
     std::shared_ptr<config::IRadioConfig> radio_config;
     std::shared_ptr<sim::IRadioSim> radio_sim;
 
   public:
+    void SetUp() override;
+    void TearDown() override;
+
     /* Used as a mechanism to inform the test about data/event callback */
     void notify(int receivedSerial);
 
@@ -158,4 +160,8 @@
 
     /* Update SIM slot status */
     void updateSimSlotStatus(int physicalSlotId);
+
+  private:
+    std::mutex mtx_;
+    std::condition_variable cv_;
 };
diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp
index c979d28..aed3b05 100644
--- a/radio/aidl/vts/radio_config_test.cpp
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <android-base/logging.h>
 #include <android/binder_manager.h>
 
 #include "radio_config_utils.h"
@@ -22,6 +21,7 @@
 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
 
 void RadioConfigTest::SetUp() {
+    RadioServiceTest::SetUp();
     std::string serviceName = GetParam();
 
     radio_config = IRadioConfig::fromBinder(
@@ -31,8 +31,6 @@
     radioRsp_config = ndk::SharedRefBase::make<RadioConfigResponse>(*this);
     ASSERT_NE(nullptr, radioRsp_config.get());
 
-    count_ = 0;
-
     radioInd_config = ndk::SharedRefBase::make<RadioConfigIndication>(*this);
     ASSERT_NE(nullptr, radioInd_config.get());
 
diff --git a/radio/aidl/vts/radio_config_utils.h b/radio/aidl/vts/radio_config_utils.h
index 3db430d..f79aedb 100644
--- a/radio/aidl/vts/radio_config_utils.h
+++ b/radio/aidl/vts/radio_config_utils.h
@@ -74,9 +74,10 @@
 };
 
 // The main test class for Radio AIDL Config.
-class RadioConfigTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+class RadioConfigTest : public RadioServiceTest {
   public:
-    virtual void SetUp() override;
+    void SetUp() override;
+
     ndk::ScopedAStatus updateSimCardStatus();
     /* Override updateSimSlotStatus in RadioServiceTest to not call setResponseFunctions */
     void updateSimSlotStatus();
diff --git a/radio/aidl/vts/radio_data_test.cpp b/radio/aidl/vts/radio_data_test.cpp
index 6ad3237..f31c254 100644
--- a/radio/aidl/vts/radio_data_test.cpp
+++ b/radio/aidl/vts/radio_data_test.cpp
@@ -17,7 +17,6 @@
 #include <aidl/android/hardware/radio/RadioAccessFamily.h>
 #include <aidl/android/hardware/radio/config/IRadioConfig.h>
 #include <aidl/android/hardware/radio/data/ApnTypes.h>
-#include <android-base/logging.h>
 #include <android/binder_manager.h>
 
 #include "radio_data_utils.h"
@@ -25,6 +24,7 @@
 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
 
 void RadioDataTest::SetUp() {
+    RadioServiceTest::SetUp();
     std::string serviceName = GetParam();
 
     if (!isServiceValidForDeviceConfiguration(serviceName)) {
@@ -39,8 +39,6 @@
     radioRsp_data = ndk::SharedRefBase::make<RadioDataResponse>(*this);
     ASSERT_NE(nullptr, radioRsp_data.get());
 
-    count_ = 0;
-
     radioInd_data = ndk::SharedRefBase::make<RadioDataIndication>(*this);
     ASSERT_NE(nullptr, radioInd_data.get());
 
@@ -143,7 +141,6 @@
 
     TrafficDescriptor trafficDescriptor;
     OsAppId osAppId;
-    // hardcode osAppId for ENTERPRISE
     osAppId.osAppId = {static_cast<unsigned char>(-105), static_cast<unsigned char>(-92),
                        static_cast<unsigned char>(-104), static_cast<unsigned char>(-29),
                        static_cast<unsigned char>(-4),   static_cast<unsigned char>(-110),
@@ -217,7 +214,8 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
                                      {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
                                       RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
-        if (radioRsp_data->setupDataCallResult.trafficDescriptors.size() <= 0) {
+        if (radioRsp_data->setupDataCallResult.trafficDescriptors.size() <= 0 ||
+            !radioRsp_data->setupDataCallResult.trafficDescriptors[0].osAppId.has_value()) {
             return;
         }
         EXPECT_EQ(trafficDescriptor.osAppId.value().osAppId,
@@ -234,14 +232,10 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
-    if (getRadioHalCapabilities()) {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
-                                     {RadioError::REQUEST_NOT_SUPPORTED}));
-    } else {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
-                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
-                                      RadioError::INTERNAL_ERR, RadioError::MODEM_ERR}));
-    }
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::INTERNAL_ERR, RadioError::MODEM_ERR,
+                                  RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 /*
@@ -560,7 +554,6 @@
  * Test IRadioData.getDataCallList() for the response returned.
  */
 TEST_P(RadioDataTest, getDataCallList) {
-    LOG(DEBUG) << "getDataCallList";
     serial = GetRandomSerialNumber();
 
     radio_data->getDataCallList(serial);
@@ -574,14 +567,12 @@
                 radioRsp_data->rspInfo.error,
                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ABSENT}));
     }
-    LOG(DEBUG) << "getDataCallList finished";
 }
 
 /*
  * Test IRadioData.setDataAllowed() for the response returned.
  */
 TEST_P(RadioDataTest, setDataAllowed) {
-    LOG(DEBUG) << "setDataAllowed";
     serial = GetRandomSerialNumber();
     bool allow = true;
 
@@ -594,5 +585,4 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         EXPECT_EQ(RadioError::NONE, radioRsp_data->rspInfo.error);
     }
-    LOG(DEBUG) << "setDataAllowed finished";
 }
diff --git a/radio/aidl/vts/radio_data_utils.h b/radio/aidl/vts/radio_data_utils.h
index fb91ef6..0959207 100644
--- a/radio/aidl/vts/radio_data_utils.h
+++ b/radio/aidl/vts/radio_data_utils.h
@@ -100,13 +100,13 @@
 };
 
 // The main test class for Radio AIDL Data.
-class RadioDataTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+class RadioDataTest : public RadioServiceTest {
   protected:
     /* Get current data call list */
     ndk::ScopedAStatus getDataCallList();
 
   public:
-    virtual void SetUp() override;
+    void SetUp() override;
 
     /* radio data service handle */
     std::shared_ptr<IRadioData> radio_data;
diff --git a/radio/aidl/vts/radio_ims_indication.cpp b/radio/aidl/vts/radio_ims_indication.cpp
new file mode 100644
index 0000000..988038b
--- /dev/null
+++ b/radio/aidl/vts/radio_ims_indication.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "radio_ims_utils.h"
+
+RadioImsIndication::RadioImsIndication(RadioServiceTest& parent) : parent_ims(parent) {}
+
+ndk::ScopedAStatus RadioImsIndication::onConnectionSetupFailure(RadioIndicationType /*type*/,
+        int32_t /*token*/, const ConnectionFailureInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsIndication::notifyAnbr(RadioIndicationType /*type*/,
+        ImsStreamType /*mediaType*/, ImsStreamDirection /*direction*/, int /*bitsPerSecond*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsIndication::triggerImsDeregistration(RadioIndicationType /*type*/,
+        ImsDeregistrationReason /*reason*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_ims_response.cpp b/radio/aidl/vts/radio_ims_response.cpp
new file mode 100644
index 0000000..c6d62dc
--- /dev/null
+++ b/radio/aidl/vts/radio_ims_response.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "radio_ims_utils.h"
+
+RadioImsResponse::RadioImsResponse(RadioServiceTest& parent) : parent_ims(parent) {}
+
+ndk::ScopedAStatus RadioImsResponse::setSrvccCallInfoResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_ims.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::updateImsRegistrationInfoResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_ims.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::startImsTrafficResponse(const RadioResponseInfo& info,
+        const std::optional<ConnectionFailureInfo>& response) {
+    rspInfo = info;
+    startImsTrafficResp = response;
+    parent_ims.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::stopImsTrafficResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_ims.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::triggerEpsFallbackResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_ims.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::sendAnbrQueryResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_ims.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::updateImsCallStatusResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_ims.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_ims_test.cpp b/radio/aidl/vts/radio_ims_test.cpp
new file mode 100644
index 0000000..1938e0a
--- /dev/null
+++ b/radio/aidl/vts/radio_ims_test.cpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <android/binder_manager.h>
+
+#include "radio_ims_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioImsTest::SetUp() {
+    RadioServiceTest::SetUp();
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_ims = IRadioIms::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_ims.get());
+
+    radioRsp_ims = ndk::SharedRefBase::make<RadioImsResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_ims.get());
+
+    radioInd_ims = ndk::SharedRefBase::make<RadioImsIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_ims.get());
+
+    radio_ims->setResponseFunctions(radioRsp_ims, radioInd_ims);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+/*
+ * Test IRadioIms.setSrvccCallInfo() for the response returned.
+ */
+TEST_P(RadioImsTest, setSrvccCallInfo) {
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping setSrvccCallInfo because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running setSrvccCallInfo because ims is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    SrvccCall srvccCall;
+
+    ndk::ScopedAStatus res =
+            radio_ims->setSrvccCallInfo(serial, { srvccCall });
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+    ALOGI("setSrvccCallInfo, rspInfo.error = %s\n",
+              toString(radioRsp_ims->rspInfo.error).c_str());
+
+    verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.updateImsRegistrationInfo() for the response returned.
+ */
+TEST_P(RadioImsTest, updateImsRegistrationInfo) {
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping updateImsRegistrationInfo because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running updateImsRegistrationInfo because ims is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    ImsRegistration regInfo;
+    regInfo.regState = ImsRegistrationState::NOT_REGISTERED;
+    regInfo.accessNetworkType = AccessNetwork::EUTRAN;
+    regInfo.suggestedAction = SuggestedAction::NONE;
+    regInfo.capabilities = ImsRegistration::IMS_MMTEL_CAPABILITY_NONE;
+
+    ndk::ScopedAStatus res =
+            radio_ims->updateImsRegistrationInfo(serial, regInfo);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+    ALOGI("updateImsRegistrationInfo, rspInfo.error = %s\n",
+              toString(radioRsp_ims->rspInfo.error).c_str());
+
+    verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.startImsTraffic() for the response returned.
+ */
+TEST_P(RadioImsTest, startImsTraffic) {
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping startImsTraffic because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running startImsTraffic because ims is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res =
+            radio_ims->startImsTraffic(serial, 1,
+            ImsTrafficType::REGISTRATION, AccessNetwork::EUTRAN, ImsCall::Direction::OUTGOING);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+    ALOGI("startImsTraffic, rspInfo.error = %s\n",
+              toString(radioRsp_ims->rspInfo.error).c_str());
+
+    verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.stopImsTraffic() for the response returned.
+ */
+TEST_P(RadioImsTest, stopImsTraffic) {
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping stopImsTraffic because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running stopImsTraffic because ims is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_ims->stopImsTraffic(serial, 2);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+    ALOGI("stopImsTraffic, rspInfo.error = %s\n",
+              toString(radioRsp_ims->rspInfo.error).c_str());
+
+    verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.triggerEpsFallback() for the response returned.
+ */
+TEST_P(RadioImsTest, triggerEpsFallback) {
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping triggerEpsFallback because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running triggerEpsFallback because ims is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res =
+            radio_ims->triggerEpsFallback(serial, EpsFallbackReason::NO_NETWORK_TRIGGER);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+    ALOGI("triggerEpsFallback, rspInfo.error = %s\n",
+              toString(radioRsp_ims->rspInfo.error).c_str());
+
+    verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.sendAnbrQuery() for the response returned.
+ */
+TEST_P(RadioImsTest, sendAnbrQuery) {
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping sendAnbrQuery because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running sendAnbrQuery because ims is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res =
+            radio_ims->sendAnbrQuery(serial, ImsStreamType::AUDIO, ImsStreamDirection::UPLINK, 13200);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+    ALOGI("sendAnbrQuery, rspInfo.error = %s\n",
+              toString(radioRsp_ims->rspInfo.error).c_str());
+
+    verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.updateImsCallStatus() for the response returned.
+ */
+TEST_P(RadioImsTest, updateImsCallStatus) {
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping updateImsCallStatus because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running updateImsCallStatus because ims is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    ImsCall imsCall;
+
+    ndk::ScopedAStatus res =
+            radio_ims->updateImsCallStatus(serial, { imsCall });
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+    ALOGI("updateImsCallStatus, rspInfo.error = %s\n",
+              toString(radioRsp_ims->rspInfo.error).c_str());
+
+    verifyError(radioRsp_ims->rspInfo.error);
+}
+
+void RadioImsTest::verifyError(RadioError resp) {
+    switch (resp) {
+        case RadioError::NONE:
+        case RadioError::RADIO_NOT_AVAILABLE:
+        case RadioError::INVALID_STATE:
+        case RadioError::NO_MEMORY:
+        case RadioError::SYSTEM_ERR:
+        case RadioError::MODEM_ERR:
+        case RadioError::INTERNAL_ERR:
+        case RadioError::INVALID_ARGUMENTS:
+        case RadioError::NO_RESOURCES:
+            SUCCEED();
+            break;
+        default:
+            FAIL();
+            break;
+    }
+}
diff --git a/radio/aidl/vts/radio_ims_utils.h b/radio/aidl/vts/radio_ims_utils.h
new file mode 100644
index 0000000..208c94b
--- /dev/null
+++ b/radio/aidl/vts/radio_ims_utils.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/ims/BnRadioImsIndication.h>
+#include <aidl/android/hardware/radio/ims/BnRadioImsResponse.h>
+#include <aidl/android/hardware/radio/ims/IRadioIms.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::ims;
+
+class RadioImsTest;
+
+/* Callback class for radio ims response */
+class RadioImsResponse : public BnRadioImsResponse {
+  protected:
+    RadioServiceTest& parent_ims;
+
+  public:
+    RadioImsResponse(RadioServiceTest& parent_ims);
+    virtual ~RadioImsResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    std::optional<ConnectionFailureInfo> startImsTrafficResp;
+
+    virtual ndk::ScopedAStatus setSrvccCallInfoResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus updateImsRegistrationInfoResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus startImsTrafficResponse(
+            const RadioResponseInfo& info,
+            const std::optional<ConnectionFailureInfo>& response) override;
+
+    virtual ndk::ScopedAStatus stopImsTrafficResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus triggerEpsFallbackResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendAnbrQueryResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus updateImsCallStatusResponse(const RadioResponseInfo& info) override;
+};
+
+/* Callback class for radio ims indication */
+class RadioImsIndication : public BnRadioImsIndication {
+  protected:
+    RadioServiceTest& parent_ims;
+
+  public:
+    RadioImsIndication(RadioServiceTest& parent_ims);
+    virtual ~RadioImsIndication() = default;
+
+    virtual ndk::ScopedAStatus onConnectionSetupFailure(RadioIndicationType type,
+            int32_t token, const ConnectionFailureInfo& info) override;
+
+    virtual ndk::ScopedAStatus notifyAnbr(RadioIndicationType type, ImsStreamType mediaType,
+            ImsStreamDirection direction, int bitsPerSecond) override;
+
+    virtual ndk::ScopedAStatus triggerImsDeregistration(RadioIndicationType type,
+            ImsDeregistrationReason reason) override;
+};
+
+// The main test class for Radio AIDL Ims.
+class RadioImsTest : public RadioServiceTest {
+  protected:
+    virtual void verifyError(RadioError resp);
+
+  public:
+    void SetUp() override;
+
+    /* radio ims service handle */
+    std::shared_ptr<IRadioIms> radio_ims;
+    /* radio ims response handle */
+    std::shared_ptr<RadioImsResponse> radioRsp_ims;
+    /* radio ims indication handle */
+    std::shared_ptr<RadioImsIndication> radioInd_ims;
+};
diff --git a/radio/aidl/vts/radio_imsmedia_listener.cpp b/radio/aidl/vts/radio_imsmedia_listener.cpp
new file mode 100644
index 0000000..78f66a9
--- /dev/null
+++ b/radio/aidl/vts/radio_imsmedia_listener.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "radio_imsmedia_utils.h"
+
+ImsMediaListener::ImsMediaListener(RadioServiceTest& parent) : parent_imsmedia(parent) {}
+
+ndk::ScopedAStatus ImsMediaListener::onOpenSessionSuccess(
+        int32_t in_sessionId, const std::shared_ptr<IImsMediaSession>& in_session) {
+    mSessionId = in_sessionId;
+    mSession = in_session;
+    parent_imsmedia.notify(SERIAL_OPEN_SESSION);
+    return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaListener::onOpenSessionFailure(int32_t in_sessionId, RtpError in_error) {
+    mSessionId = in_sessionId;
+    mError = in_error;
+    parent_imsmedia.notify(SERIAL_OPEN_SESSION);
+    return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaListener::onSessionClosed(int32_t in_sessionId) {
+    mSessionId = in_sessionId;
+    parent_imsmedia.notify(SERIAL_CLOSE_SESSION);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_imsmedia_session_listener.cpp b/radio/aidl/vts/radio_imsmedia_session_listener.cpp
new file mode 100644
index 0000000..986cab2
--- /dev/null
+++ b/radio/aidl/vts/radio_imsmedia_session_listener.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "radio_imsmedia_utils.h"
+
+ImsMediaSessionListener::ImsMediaSessionListener(RadioServiceTest& parent)
+    : parent_imsmedia(parent) {}
+
+ndk::ScopedAStatus ImsMediaSessionListener::onModifySessionResponse(const RtpConfig& in_config,
+                                                                    RtpError in_error) {
+    mConfig = in_config;
+    mError = in_error;
+    parent_imsmedia.notify(SERIAL_MODIFY_SESSION);
+    return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::onFirstMediaPacketReceived(
+        const RtpConfig& /*in_config*/) {
+    return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::onHeaderExtensionReceived(
+        const std::vector<RtpHeaderExtension>& /*in_extensions*/) {
+    return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::notifyMediaQualityStatus(
+        const MediaQualityStatus& /*in_quality*/) {
+    return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::triggerAnbrQuery(const RtpConfig& /*in_config*/) {
+    return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::onDtmfReceived(char16_t /*in_dtmfDigit*/,
+                                                           int32_t /*in_durationMs*/) {
+    return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::onCallQualityChanged(
+        const CallQuality& /*in_callQuality*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_imsmedia_test.cpp b/radio/aidl/vts/radio_imsmedia_test.cpp
new file mode 100644
index 0000000..425f6b4
--- /dev/null
+++ b/radio/aidl/vts/radio_imsmedia_test.cpp
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/radio/ims/media/MediaDirection.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <sys/socket.h>
+
+#include "radio_imsmedia_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioImsMediaTest::SetUp() {
+    RadioServiceTest::SetUp();
+    std::string serviceName = GetParam();
+
+    radio_imsmedia = IImsMedia::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_imsmedia.get());
+
+    radio_imsmedialistener = ndk::SharedRefBase::make<ImsMediaListener>(*this);
+    ASSERT_NE(nullptr, radio_imsmedialistener.get());
+
+    radio_imsmediasessionlistener = ndk::SharedRefBase::make<ImsMediaSessionListener>(*this);
+    ASSERT_NE(nullptr, radio_imsmediasessionlistener.get());
+}
+
+TEST_P(RadioImsMediaTest, MOCallSuccess) {
+    int32_t sessionId = 1;
+    RtpConfig modifyRtpConfig;
+
+    modifyRtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+                                static_cast<int32_t>(MediaDirection::RTP_RX) |
+                                static_cast<int32_t>(MediaDirection::RTCP_TX) |
+                                static_cast<int32_t>(MediaDirection::RTCP_RX);
+    modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33";
+    modifyRtpConfig.remoteAddress.portNumber = 1234;
+
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping setListener because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running setListener because ims is supported in device");
+    }
+
+    ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener);
+    ASSERT_OK(res);
+
+    serial = SERIAL_OPEN_SESSION;
+    res = triggerOpenSession(sessionId);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+    ASSERT_NE(nullptr, radio_imsmedialistener->mSession);
+
+    radio_imsmediasession = radio_imsmedialistener->mSession;
+    radio_imsmediasession->setListener(radio_imsmediasessionlistener);
+    ASSERT_OK(res);
+
+    serial = SERIAL_MODIFY_SESSION;
+    res = radio_imsmediasession->modifySession(modifyRtpConfig);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig);
+    verifyError(radio_imsmediasessionlistener->mError);
+
+    serial = SERIAL_CLOSE_SESSION;
+    res = radio_imsmedia->closeSession(sessionId);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+}
+
+TEST_P(RadioImsMediaTest, testDtmfOperation) {
+    int32_t sessionId = 1;
+    char16_t dtmfDight = 'a';
+    int32_t duration = 200;
+    RtpConfig modifyRtpConfig;
+
+    modifyRtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+                                static_cast<int32_t>(MediaDirection::RTP_RX) |
+                                static_cast<int32_t>(MediaDirection::RTCP_TX) |
+                                static_cast<int32_t>(MediaDirection::RTCP_RX);
+    modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33";
+    modifyRtpConfig.remoteAddress.portNumber = 1234;
+
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping setListener because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running setListener because ims is supported in device");
+    }
+
+    ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener);
+    ASSERT_OK(res);
+
+    serial = SERIAL_OPEN_SESSION;
+    res = triggerOpenSession(sessionId);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+    ASSERT_NE(nullptr, radio_imsmedialistener->mSession);
+
+    radio_imsmediasession = radio_imsmedialistener->mSession;
+    radio_imsmediasession->setListener(radio_imsmediasessionlistener);
+    ASSERT_OK(res);
+
+    serial = SERIAL_MODIFY_SESSION;
+    res = radio_imsmediasession->modifySession(modifyRtpConfig);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig);
+    verifyError(radio_imsmediasessionlistener->mError);
+
+    res = radio_imsmediasession->sendDtmf(dtmfDight, duration);
+    ASSERT_OK(res);
+
+    res = radio_imsmediasession->startDtmf(dtmfDight);
+    ASSERT_OK(res);
+
+    res = radio_imsmediasession->stopDtmf();
+    ASSERT_OK(res);
+
+    serial = SERIAL_CLOSE_SESSION;
+    res = radio_imsmedia->closeSession(sessionId);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
+
+TEST_P(RadioImsMediaTest, sendHeaderExtension) {
+    int32_t sessionId = 1;
+    std::vector<RtpHeaderExtension> extensions;
+    RtpConfig modifyRtpConfig;
+
+    modifyRtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+                                static_cast<int32_t>(MediaDirection::RTP_RX) |
+                                static_cast<int32_t>(MediaDirection::RTCP_TX) |
+                                static_cast<int32_t>(MediaDirection::RTCP_RX);
+    modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33";
+    modifyRtpConfig.remoteAddress.portNumber = 1234;
+
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping setListener because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running setListener because ims is supported in device");
+    }
+
+    ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener);
+    ASSERT_OK(res);
+
+    serial = SERIAL_OPEN_SESSION;
+    res = triggerOpenSession(sessionId);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+    ASSERT_NE(nullptr, radio_imsmedialistener->mSession);
+
+    radio_imsmediasession = radio_imsmedialistener->mSession;
+    radio_imsmediasession->setListener(radio_imsmediasessionlistener);
+    ASSERT_OK(res);
+
+    serial = SERIAL_MODIFY_SESSION;
+    res = radio_imsmediasession->modifySession(modifyRtpConfig);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig);
+    verifyError(radio_imsmediasessionlistener->mError);
+
+    res = radio_imsmediasession->sendHeaderExtension(extensions);
+    ASSERT_OK(res);
+
+    serial = SERIAL_CLOSE_SESSION;
+    res = radio_imsmedia->closeSession(sessionId);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
+
+TEST_P(RadioImsMediaTest, setMediaQualityThreshold) {
+    int32_t sessionId = 1;
+    MediaQualityThreshold threshold;
+    RtpConfig modifyRtpConfig;
+
+    modifyRtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+                                static_cast<int32_t>(MediaDirection::RTP_RX) |
+                                static_cast<int32_t>(MediaDirection::RTCP_TX) |
+                                static_cast<int32_t>(MediaDirection::RTCP_RX);
+    modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33";
+    modifyRtpConfig.remoteAddress.portNumber = 1234;
+
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        ALOGI("Skipping setListener because ims is not supported in device");
+        return;
+    } else {
+        ALOGI("Running setListener because ims is supported in device");
+    }
+
+    ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener);
+    ASSERT_OK(res);
+
+    serial = SERIAL_OPEN_SESSION;
+    res = triggerOpenSession(sessionId);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+    ASSERT_NE(nullptr, radio_imsmedialistener->mSession);
+
+    radio_imsmediasession = radio_imsmedialistener->mSession;
+    radio_imsmediasession->setListener(radio_imsmediasessionlistener);
+    ASSERT_OK(res);
+
+    serial = SERIAL_MODIFY_SESSION;
+    res = radio_imsmediasession->modifySession(modifyRtpConfig);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig);
+    verifyError(radio_imsmediasessionlistener->mError);
+
+    res = radio_imsmediasession->setMediaQualityThreshold(threshold);
+    ASSERT_OK(res);
+
+    serial = SERIAL_CLOSE_SESSION;
+    res = radio_imsmedia->closeSession(sessionId);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
+
+ndk::ScopedAStatus RadioImsMediaTest::triggerOpenSession(int32_t sessionId) {
+    LocalEndPoint localEndPoint;
+    RtpConfig rtpConfig;
+    ndk::ScopedAStatus result;
+
+    int mSocketFd = ::socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    int mRtcpSocketFd = ::socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    localEndPoint.rtpFd = ndk::ScopedFileDescriptor(mSocketFd);
+    localEndPoint.rtcpFd = ndk::ScopedFileDescriptor(mRtcpSocketFd);
+    localEndPoint.modemId = 1;
+
+    rtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+                          static_cast<int32_t>(MediaDirection::RTP_RX) |
+                          static_cast<int32_t>(MediaDirection::RTCP_TX) |
+                          static_cast<int32_t>(MediaDirection::RTCP_RX);
+    rtpConfig.remoteAddress.ipAddress = "122.22.22.22";
+    rtpConfig.remoteAddress.portNumber = 2222;
+
+    result = radio_imsmedia->openSession(sessionId, localEndPoint, rtpConfig);
+    return result;
+}
+
+void RadioImsMediaTest::verifyError(RtpError error) {
+    switch (error) {
+        case RtpError::NONE:
+        case RtpError::INVALID_PARAM:
+        case RtpError::NOT_READY:
+        case RtpError::NO_MEMORY:
+        case RtpError::NO_RESOURCES:
+        case RtpError::PORT_UNAVAILABLE:
+        case RtpError::NOT_SUPPORTED:
+            SUCCEED();
+            break;
+        default:
+            FAIL();
+            break;
+    }
+}
diff --git a/radio/aidl/vts/radio_imsmedia_utils.h b/radio/aidl/vts/radio_imsmedia_utils.h
new file mode 100644
index 0000000..87f1b00
--- /dev/null
+++ b/radio/aidl/vts/radio_imsmedia_utils.h
@@ -0,0 +1,98 @@
+
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/ims/media/BnImsMediaListener.h>
+#include <aidl/android/hardware/radio/ims/media/BnImsMediaSessionListener.h>
+#include <aidl/android/hardware/radio/ims/media/IImsMedia.h>
+#include <aidl/android/hardware/radio/ims/media/IImsMediaSession.h>
+
+#include "radio_aidl_hal_utils.h"
+
+#define SERIAL_SET_LISTENER 1
+#define SERIAL_OPEN_SESSION 2
+#define SERIAL_CLOSE_SESSION 3
+#define SERIAL_MODIFY_SESSION 4
+
+using namespace aidl::android::hardware::radio::ims::media;
+
+class RadioImsMediaTest;
+
+/* Listener class for ImsMedia. */
+class ImsMediaListener : public BnImsMediaListener {
+  protected:
+    RadioServiceTest& parent_imsmedia;
+
+  public:
+    ImsMediaListener(RadioServiceTest& parent_imsmedialistener);
+    virtual ~ImsMediaListener() = default;
+
+    int32_t mSessionId;
+    std::shared_ptr<::aidl::android::hardware::radio::ims::media::IImsMediaSession> mSession;
+    RtpError mError;
+
+    virtual ndk::ScopedAStatus onOpenSessionSuccess(
+            int32_t in_sessionId, const std::shared_ptr<IImsMediaSession>& in_session) override;
+    virtual ndk::ScopedAStatus onOpenSessionFailure(int32_t in_sessionId,
+                                                    RtpError in_error) override;
+    virtual ndk::ScopedAStatus onSessionClosed(int32_t in_sessionId) override;
+};
+
+/* Listener class for ImsMediaSession. */
+class ImsMediaSessionListener : public BnImsMediaSessionListener {
+  protected:
+    RadioServiceTest& parent_imsmedia;
+
+  public:
+    ImsMediaSessionListener(RadioServiceTest& parent_imsmediasessionlistener);
+    virtual ~ImsMediaSessionListener() = default;
+
+    RtpConfig mConfig;
+    RtpError mError;
+
+    virtual ndk::ScopedAStatus onModifySessionResponse(const RtpConfig& in_config,
+                                                       RtpError in_error) override;
+    virtual ndk::ScopedAStatus onFirstMediaPacketReceived(const RtpConfig& in_config) override;
+    virtual ndk::ScopedAStatus onHeaderExtensionReceived(
+            const std::vector<RtpHeaderExtension>& in_extensions) override;
+    virtual ndk::ScopedAStatus notifyMediaQualityStatus(
+            const MediaQualityStatus& in_quality) override;
+    virtual ndk::ScopedAStatus triggerAnbrQuery(const RtpConfig& in_config) override;
+    virtual ndk::ScopedAStatus onDtmfReceived(char16_t in_dtmfDigit,
+                                              int32_t in_durationMs) override;
+    virtual ndk::ScopedAStatus onCallQualityChanged(const CallQuality& in_callQuality) override;
+};
+
+/* The main test class for Radio AIDL ImsMedia. */
+class RadioImsMediaTest : public RadioServiceTest {
+  protected:
+    virtual void verifyError(RtpError inError);
+    virtual ndk::ScopedAStatus triggerOpenSession(int32_t sessionId);
+
+  public:
+    void SetUp() override;
+
+    /* radio imsmedia service handle */
+    std::shared_ptr<IImsMedia> radio_imsmedia;
+    /* radio imsmediasession service handle */
+    std::shared_ptr<IImsMediaSession> radio_imsmediasession;
+    /* radio imsmedia listener handle */
+    std::shared_ptr<ImsMediaListener> radio_imsmedialistener;
+    /* radio imsmediasession listener handle */
+    std::shared_ptr<ImsMediaSessionListener> radio_imsmediasessionlistener;
+};
diff --git a/radio/aidl/vts/radio_messaging_test.cpp b/radio/aidl/vts/radio_messaging_test.cpp
index 9f1718b..4ab88d2 100644
--- a/radio/aidl/vts/radio_messaging_test.cpp
+++ b/radio/aidl/vts/radio_messaging_test.cpp
@@ -15,7 +15,6 @@
  */
 
 #include <aidl/android/hardware/radio/config/IRadioConfig.h>
-#include <android-base/logging.h>
 #include <android/binder_manager.h>
 
 #include "radio_messaging_utils.h"
@@ -23,6 +22,7 @@
 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
 
 void RadioMessagingTest::SetUp() {
+    RadioServiceTest::SetUp();
     std::string serviceName = GetParam();
 
     if (!isServiceValidForDeviceConfiguration(serviceName)) {
@@ -37,8 +37,6 @@
     radioRsp_messaging = ndk::SharedRefBase::make<RadioMessagingResponse>(*this);
     ASSERT_NE(nullptr, radioRsp_messaging.get());
 
-    count_ = 0;
-
     radioInd_messaging = ndk::SharedRefBase::make<RadioMessagingIndication>(*this);
     ASSERT_NE(nullptr, radioInd_messaging.get());
 
@@ -61,7 +59,6 @@
  * Test IRadioMessaging.sendSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendSms) {
-    LOG(DEBUG) << "sendSms";
     serial = GetRandomSerialNumber();
     GsmSmsMessage msg;
     msg.smscPdu = "";
@@ -80,14 +77,12 @@
                 CHECK_GENERAL_ERROR));
         EXPECT_EQ(0, radioRsp_messaging->sendSmsResult.errorCode);
     }
-    LOG(DEBUG) << "sendSms finished";
 }
 
 /*
  * Test IRadioMessaging.sendSmsExpectMore() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendSmsExpectMore) {
-    LOG(DEBUG) << "sendSmsExpectMore";
     serial = GetRandomSerialNumber();
     GsmSmsMessage msg;
     msg.smscPdu = "";
@@ -105,14 +100,12 @@
                 {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendSmsExpectMore finished";
 }
 
 /*
  * Test IRadioMessaging.sendCdmaSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendCdmaSms) {
-    LOG(DEBUG) << "sendCdmaSms";
     serial = GetRandomSerialNumber();
 
     // Create a CdmaSmsAddress
@@ -151,7 +144,6 @@
                 {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendCdmaSms finished";
 }
 
 /*
@@ -202,7 +194,6 @@
  * Test IRadioMessaging.setGsmBroadcastConfig() for the response returned.
  */
 TEST_P(RadioMessagingTest, setGsmBroadcastConfig) {
-    LOG(DEBUG) << "setGsmBroadcastConfig";
     serial = GetRandomSerialNumber();
 
     // Create GsmBroadcastSmsConfigInfo #1
@@ -260,14 +251,12 @@
                                       RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setGsmBroadcastConfig finished";
 }
 
 /*
  * Test IRadioMessaging.getGsmBroadcastConfig() for the response returned.
  */
 TEST_P(RadioMessagingTest, getGsmBroadcastConfig) {
-    LOG(DEBUG) << "getGsmBroadcastConfig";
     serial = GetRandomSerialNumber();
 
     radio_messaging->getGsmBroadcastConfig(serial);
@@ -282,14 +271,12 @@
                 {RadioError::NONE, RadioError::INVALID_MODEM_STATE, RadioError::INVALID_STATE},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "getGsmBroadcastConfig finished";
 }
 
 /*
  * Test IRadioMessaging.setCdmaBroadcastConfig() for the response returned.
  */
 TEST_P(RadioMessagingTest, setCdmaBroadcastConfig) {
-    LOG(DEBUG) << "setCdmaBroadcastConfig";
     serial = GetRandomSerialNumber();
 
     CdmaBroadcastSmsConfigInfo cbSmsConfig;
@@ -310,14 +297,12 @@
                                      {RadioError::NONE, RadioError::INVALID_MODEM_STATE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setCdmaBroadcastConfig finished";
 }
 
 /*
  * Test IRadioMessaging.getCdmaBroadcastConfig() for the response returned.
  */
 TEST_P(RadioMessagingTest, getCdmaBroadcastConfig) {
-    LOG(DEBUG) << "getCdmaBroadcastConfig";
     serial = GetRandomSerialNumber();
 
     radio_messaging->getCdmaBroadcastConfig(serial);
@@ -330,14 +315,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error, {RadioError::NONE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "getCdmaBroadcastConfig finished";
 }
 
 /*
  * Test IRadioMessaging.setCdmaBroadcastActivation() for the response returned.
  */
 TEST_P(RadioMessagingTest, setCdmaBroadcastActivation) {
-    LOG(DEBUG) << "setCdmaBroadcastActivation";
     serial = GetRandomSerialNumber();
     bool activate = false;
 
@@ -352,14 +335,12 @@
                                      {RadioError::NONE, RadioError::INVALID_ARGUMENTS},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setCdmaBroadcastActivation finished";
 }
 
 /*
  * Test IRadioMessaging.setGsmBroadcastActivation() for the response returned.
  */
 TEST_P(RadioMessagingTest, setGsmBroadcastActivation) {
-    LOG(DEBUG) << "setGsmBroadcastActivation";
     serial = GetRandomSerialNumber();
     bool activate = false;
 
@@ -376,14 +357,12 @@
                  RadioError::INVALID_STATE, RadioError::OPERATION_NOT_ALLOWED},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setGsmBroadcastActivation finished";
 }
 
 /*
  * Test IRadioMessaging.acknowledgeLastIncomingGsmSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, acknowledgeLastIncomingGsmSms) {
-    LOG(DEBUG) << "acknowledgeLastIncomingGsmSms";
     serial = GetRandomSerialNumber();
     bool success = true;
 
@@ -399,14 +378,12 @@
                                      {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "acknowledgeLastIncomingGsmSms finished";
 }
 
 /*
  * Test IRadioMessaging.acknowledgeIncomingGsmSmsWithPdu() for the response returned.
  */
 TEST_P(RadioMessagingTest, acknowledgeIncomingGsmSmsWithPdu) {
-    LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu";
     serial = GetRandomSerialNumber();
     bool success = true;
     std::string ackPdu = "";
@@ -422,14 +399,12 @@
                                      {RadioError::INVALID_ARGUMENTS, RadioError::NO_SMS_TO_ACK},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "acknowledgeIncomingGsmSmsWithPdu finished";
 }
 
 /*
  * Test IRadioMessaging.acknowledgeLastIncomingCdmaSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, acknowledgeLastIncomingCdmaSms) {
-    LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms";
     serial = GetRandomSerialNumber();
 
     // Create a CdmaSmsAck
@@ -448,14 +423,12 @@
                                      {RadioError::INVALID_ARGUMENTS, RadioError::NO_SMS_TO_ACK},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "acknowledgeLastIncomingCdmaSms finished";
 }
 
 /*
  * Test IRadioMessaging.sendImsSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendImsSms) {
-    LOG(DEBUG) << "sendImsSms";
     serial = GetRandomSerialNumber();
 
     // Create a CdmaSmsAddress
@@ -482,7 +455,7 @@
     cdmaSmsMessage.bearerData =
             (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
 
-    // Creata an ImsSmsMessage
+    // Create an ImsSmsMessage
     ImsSmsMessage msg;
     msg.tech = RadioTechnologyFamily::THREE_GPP2;
     msg.retry = false;
@@ -500,14 +473,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
                                      {RadioError::INVALID_ARGUMENTS}, CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendImsSms finished";
 }
 
 /*
  * Test IRadioMessaging.getSmscAddress() for the response returned.
  */
 TEST_P(RadioMessagingTest, getSmscAddress) {
-    LOG(DEBUG) << "getSmscAddress";
     serial = GetRandomSerialNumber();
 
     radio_messaging->getSmscAddress(serial);
@@ -522,14 +493,12 @@
                                       RadioError::SIM_ABSENT},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "getSmscAddress finished";
 }
 
 /*
  * Test IRadioMessaging.setSmscAddress() for the response returned.
  */
 TEST_P(RadioMessagingTest, setSmscAddress) {
-    LOG(DEBUG) << "setSmscAddress";
     serial = GetRandomSerialNumber();
     std::string address = std::string("smscAddress");
 
@@ -545,14 +514,12 @@
                                       RadioError::SIM_ABSENT},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setSmscAddress finished";
 }
 
 /*
  * Test IRadioMessaging.writeSmsToSim() for the response returned.
  */
 TEST_P(RadioMessagingTest, writeSmsToSim) {
-    LOG(DEBUG) << "writeSmsToSim";
     serial = GetRandomSerialNumber();
     SmsWriteArgs smsWriteArgs;
     smsWriteArgs.status = SmsWriteArgs::STATUS_REC_UNREAD;
@@ -573,14 +540,12 @@
                  RadioError::NETWORK_NOT_READY, RadioError::NO_RESOURCES, RadioError::SIM_ABSENT},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "writeSmsToSim finished";
 }
 
 /*
  * Test IRadioMessaging.deleteSmsOnSim() for the response returned.
  */
 TEST_P(RadioMessagingTest, deleteSmsOnSim) {
-    LOG(DEBUG) << "deleteSmsOnSim";
     serial = GetRandomSerialNumber();
     int index = 1;
 
@@ -598,14 +563,12 @@
                  RadioError::SIM_ABSENT},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "deleteSmsOnSim finished";
 }
 
 /*
  * Test IRadioMessaging.writeSmsToRuim() for the response returned.
  */
 TEST_P(RadioMessagingTest, writeSmsToRuim) {
-    LOG(DEBUG) << "writeSmsToRuim";
     serial = GetRandomSerialNumber();
 
     // Create a CdmaSmsAddress
@@ -651,14 +614,12 @@
                  RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "writeSmsToRuim finished";
 }
 
 /*
  * Test IRadioMessaging.deleteSmsOnRuim() for the response returned.
  */
 TEST_P(RadioMessagingTest, deleteSmsOnRuim) {
-    LOG(DEBUG) << "deleteSmsOnRuim";
     serial = GetRandomSerialNumber();
     int index = 1;
 
@@ -704,14 +665,12 @@
                  RadioError::MODEM_ERR, RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "deleteSmsOnRuim finished";
 }
 
 /*
  * Test IRadioMessaging.reportSmsMemoryStatus() for the response returned.
  */
 TEST_P(RadioMessagingTest, reportSmsMemoryStatus) {
-    LOG(DEBUG) << "reportSmsMemoryStatus";
     serial = GetRandomSerialNumber();
     bool available = true;
 
@@ -727,5 +686,4 @@
                                       RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "reportSmsMemoryStatus finished";
 }
diff --git a/radio/aidl/vts/radio_messaging_utils.h b/radio/aidl/vts/radio_messaging_utils.h
index 7b66192..3bd8346 100644
--- a/radio/aidl/vts/radio_messaging_utils.h
+++ b/radio/aidl/vts/radio_messaging_utils.h
@@ -132,9 +132,9 @@
 };
 
 // The main test class for Radio AIDL Messaging.
-class RadioMessagingTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+class RadioMessagingTest : public RadioServiceTest {
   public:
-    virtual void SetUp() override;
+    void SetUp() override;
 
     /* radio messaging service handle */
     std::shared_ptr<IRadioMessaging> radio_messaging;
diff --git a/radio/aidl/vts/radio_modem_response.cpp b/radio/aidl/vts/radio_modem_response.cpp
index 20b44c5..050b2c8 100644
--- a/radio/aidl/vts/radio_modem_response.cpp
+++ b/radio/aidl/vts/radio_modem_response.cpp
@@ -46,6 +46,13 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus RadioModemResponse::getImeiResponse(const RadioResponseInfo& info,
+                   const std::optional<ImeiInfo>& /*imeiInfo*/) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus RadioModemResponse::getHardwareConfigResponse(
         const RadioResponseInfo& info, const std::vector<HardwareConfig>& /*config*/) {
     rspInfo = info;
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index e867378..c48a461 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -15,7 +15,6 @@
  */
 
 #include <aidl/android/hardware/radio/config/IRadioConfig.h>
-#include <android-base/logging.h>
 #include <android/binder_manager.h>
 
 #include "radio_modem_utils.h"
@@ -23,6 +22,7 @@
 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
 
 void RadioModemTest::SetUp() {
+    RadioServiceTest::SetUp();
     std::string serviceName = GetParam();
 
     if (!isServiceValidForDeviceConfiguration(serviceName)) {
@@ -37,8 +37,6 @@
     radioRsp_modem = ndk::SharedRefBase::make<RadioModemResponse>(*this);
     ASSERT_NE(nullptr, radioRsp_modem.get());
 
-    count_ = 0;
-
     radioInd_modem = ndk::SharedRefBase::make<RadioModemIndication>(*this);
     ASSERT_NE(nullptr, radioInd_modem.get());
 
@@ -154,7 +152,6 @@
  * Test IRadioModem.getBasebandVersion() for the response returned.
  */
 TEST_P(RadioModemTest, getBasebandVersion) {
-    LOG(DEBUG) << "getBasebandVersion";
     serial = GetRandomSerialNumber();
 
     radio_modem->getBasebandVersion(serial);
@@ -165,14 +162,12 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
     }
-    LOG(DEBUG) << "getBasebandVersion finished";
 }
 
 /*
  * Test IRadioModem.getDeviceIdentity() for the response returned.
  */
 TEST_P(RadioModemTest, getDeviceIdentity) {
-    LOG(DEBUG) << "getDeviceIdentity";
     serial = GetRandomSerialNumber();
 
     radio_modem->getDeviceIdentity(serial);
@@ -184,14 +179,36 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
                                      {RadioError::NONE, RadioError::EMPTY_RECORD}));
     }
-    LOG(DEBUG) << "getDeviceIdentity finished";
+}
+
+/*
+ * Test IRadioModem.getImei() for the response returned.
+ */
+TEST_P(RadioModemTest, getImei) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_modem->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since getImei is not supported on version < 2");
+        GTEST_SKIP();
+    }
+    serial = GetRandomSerialNumber();
+
+    radio_modem->getImei(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+                                     {RadioError::NONE, RadioError::EMPTY_RECORD}));
+    }
 }
 
 /*
  * Test IRadioModem.nvReadItem() for the response returned.
  */
 TEST_P(RadioModemTest, nvReadItem) {
-    LOG(DEBUG) << "nvReadItem";
     serial = GetRandomSerialNumber();
 
     radio_modem->nvReadItem(serial, NvItem::LTE_BAND_ENABLE_25);
@@ -203,14 +220,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "nvReadItem finished";
 }
 
 /*
  * Test IRadioModem.nvWriteItem() for the response returned.
  */
 TEST_P(RadioModemTest, nvWriteItem) {
-    LOG(DEBUG) << "nvWriteItem";
     serial = GetRandomSerialNumber();
     NvWriteItem item;
     memset(&item, 0, sizeof(item));
@@ -225,14 +240,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "nvWriteItem finished";
 }
 
 /*
  * Test IRadioModem.nvWriteCdmaPrl() for the response returned.
  */
 TEST_P(RadioModemTest, nvWriteCdmaPrl) {
-    LOG(DEBUG) << "nvWriteCdmaPrl";
     serial = GetRandomSerialNumber();
     std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
 
@@ -245,14 +258,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "nvWriteCdmaPrl finished";
 }
 
 /*
  * Test IRadioModem.nvResetConfig() for the response returned.
  */
 TEST_P(RadioModemTest, nvResetConfig) {
-    LOG(DEBUG) << "nvResetConfig";
     serial = GetRandomSerialNumber();
 
     radio_modem->nvResetConfig(serial, ResetNvType::FACTORY_RESET);
@@ -266,14 +277,12 @@
     }
     // wait until modem reset finishes
     sleep(10);
-    LOG(DEBUG) << "nvResetConfig finished";
 }
 
 /*
  * Test IRadioModem.getHardwareConfig() for the response returned.
  */
 TEST_P(RadioModemTest, getHardwareConfig) {
-    LOG(DEBUG) << "getHardwareConfig";
     serial = GetRandomSerialNumber();
 
     radio_modem->getHardwareConfig(serial);
@@ -285,7 +294,6 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "getHardwareConfig finished";
 }
 
 /*
@@ -311,7 +319,6 @@
  * Test IRadioModem.getRadioCapability() for the response returned.
  */
 TEST_P(RadioModemTest, getRadioCapability) {
-    LOG(DEBUG) << "getRadioCapability";
     serial = GetRandomSerialNumber();
 
     radio_modem->getRadioCapability(serial);
@@ -322,14 +329,12 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
     }
-    LOG(DEBUG) << "getRadioCapability finished";
 }
 
 /*
  * Test IRadioModem.setRadioCapability() for the response returned.
  */
 TEST_P(RadioModemTest, setRadioCapability) {
-    LOG(DEBUG) << "setRadioCapability";
     serial = GetRandomSerialNumber();
     RadioCapability rc;
     memset(&rc, 0, sizeof(rc));
@@ -345,14 +350,12 @@
                                      {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setRadioCapability finished";
 }
 
 /*
  * Test IRadioModem.getModemActivityInfo() for the response returned.
  */
 TEST_P(RadioModemTest, getModemActivityInfo) {
-    LOG(DEBUG) << "getModemActivityInfo";
     serial = GetRandomSerialNumber();
 
     radio_modem->getModemActivityInfo(serial);
@@ -364,14 +367,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
-    LOG(DEBUG) << "getModemActivityInfo finished";
 }
 
 /*
  * Test IRadioModem.sendDeviceState() for the response returned.
  */
 TEST_P(RadioModemTest, sendDeviceState) {
-    LOG(DEBUG) << "sendDeviceState";
     serial = GetRandomSerialNumber();
 
     radio_modem->sendDeviceState(serial, DeviceStateType::POWER_SAVE_MODE, true);
@@ -385,5 +386,4 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
-    LOG(DEBUG) << "sendDeviceState finished";
 }
diff --git a/radio/aidl/vts/radio_modem_utils.h b/radio/aidl/vts/radio_modem_utils.h
index 49e1891..d47bdeb 100644
--- a/radio/aidl/vts/radio_modem_utils.h
+++ b/radio/aidl/vts/radio_modem_utils.h
@@ -19,6 +19,7 @@
 #include <aidl/android/hardware/radio/modem/BnRadioModemIndication.h>
 #include <aidl/android/hardware/radio/modem/BnRadioModemResponse.h>
 #include <aidl/android/hardware/radio/modem/IRadioModem.h>
+#include <aidl/android/hardware/radio/modem/ImeiInfo.h>
 
 #include "radio_aidl_hal_utils.h"
 
@@ -52,6 +53,9 @@
                                                          const std::string& esn,
                                                          const std::string& meid) override;
 
+    virtual ndk::ScopedAStatus getImeiResponse(const RadioResponseInfo& info,
+            const std::optional<ImeiInfo>& config) override;
+
     virtual ndk::ScopedAStatus getHardwareConfigResponse(
             const RadioResponseInfo& info, const std::vector<HardwareConfig>& config) override;
 
@@ -108,9 +112,9 @@
 };
 
 // The main test class for Radio AIDL Modem.
-class RadioModemTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+class RadioModemTest : public RadioServiceTest {
   public:
-    virtual void SetUp() override;
+    void SetUp() override;
 
     /* radio modem service handle */
     std::shared_ptr<IRadioModem> radio_modem;
diff --git a/radio/aidl/vts/radio_network_indication.cpp b/radio/aidl/vts/radio_network_indication.cpp
index 7acbff4..ae3bd4b 100644
--- a/radio/aidl/vts/radio_network_indication.cpp
+++ b/radio/aidl/vts/radio_network_indication.cpp
@@ -92,3 +92,8 @@
                                                                  RadioTechnology /*rat*/) {
     return ndk::ScopedAStatus::ok();
 }
+
+ndk::ScopedAStatus RadioNetworkIndication::emergencyNetworkScanResult(
+        RadioIndicationType /*type*/, const EmergencyRegResult& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
index 2292c54..25d45a5 100644
--- a/radio/aidl/vts/radio_network_response.cpp
+++ b/radio/aidl/vts/radio_network_response.cpp
@@ -266,3 +266,57 @@
     parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
+
+ndk::ScopedAStatus RadioNetworkResponse::setEmergencyModeResponse(
+        const RadioResponseInfo& info, const EmergencyRegResult& /*regState*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::triggerEmergencyNetworkScanResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::exitEmergencyModeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::cancelEmergencyNetworkScanResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setNullCipherAndIntegrityEnabledResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::isNullCipherAndIntegrityEnabledResponse(
+        const RadioResponseInfo& info, bool /*isEnabled*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::isN1ModeEnabledResponse(
+        const RadioResponseInfo& info, bool /*isEnabled*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setN1ModeEnabledResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 00fa3fb..f316a34 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -17,7 +17,6 @@
 #include <aidl/android/hardware/radio/RadioAccessFamily.h>
 #include <aidl/android/hardware/radio/config/IRadioConfig.h>
 #include <aidl/android/hardware/radio/network/IndicationFilter.h>
-#include <android-base/logging.h>
 #include <android/binder_manager.h>
 
 #include "radio_network_utils.h"
@@ -38,6 +37,7 @@
 }  // namespace
 
 void RadioNetworkTest::SetUp() {
+    RadioServiceTest::SetUp();
     std::string serviceName = GetParam();
 
     if (!isServiceValidForDeviceConfiguration(serviceName)) {
@@ -52,8 +52,6 @@
     radioRsp_network = ndk::SharedRefBase::make<RadioNetworkResponse>(*this);
     ASSERT_NE(nullptr, radioRsp_network.get());
 
-    count_ = 0;
-
     radioInd_network = ndk::SharedRefBase::make<RadioNetworkIndication>(*this);
     ASSERT_NE(nullptr, radioInd_network.get());
 
@@ -85,11 +83,6 @@
 TEST_P(RadioNetworkTest, setGetAllowedNetworkTypesBitmap) {
     serial = GetRandomSerialNumber();
 
-    // get aidl version
-    int32_t aidl_version;
-    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
-    ASSERT_OK(aidl_status);
-
     // save current value
     radio_network->getAllowedNetworkTypesBitmap(serial);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -125,13 +118,8 @@
                  RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR,
                  RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES}));
         if (radioRsp_network->rspInfo.error == RadioError::NONE) {
-            if (aidl_version < 2) {
-                radioRsp_network->networkTypeBitmapResponse
-                    &= ~static_cast<int32_t>(RadioAccessFamily::LTE_CA);
-            }
-
             // verify we get the value we set
-            ASSERT_EQ(radioRsp_network->networkTypeBitmapResponse, allowedNetworkTypesBitmap);
+            EXPECT_EQ(radioRsp_network->networkTypeBitmapResponse, allowedNetworkTypesBitmap);
         }
     }
 
@@ -383,7 +371,7 @@
 /*
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for UTRAN
  */
-TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran) {
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran_Rscp) {
     serial = GetRandomSerialNumber();
 
     SignalThresholdInfo signalThresholdInfo;
@@ -407,6 +395,33 @@
 }
 
 /*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for UTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran_Ecno) {
+    serial = GetRandomSerialNumber();
+
+    SignalThresholdInfo signalThresholdInfo;
+    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_ECNO;
+    signalThresholdInfo.hysteresisMs = 5000;
+    signalThresholdInfo.hysteresisDb = 2;
+    signalThresholdInfo.thresholds = {-22, -18, 0};
+    signalThresholdInfo.isEnabled = true;
+    signalThresholdInfo.ran = AccessNetwork::UTRAN;
+
+    ndk::ScopedAStatus res =
+            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ALOGI("setSignalStrengthReportingCriteria_Utran, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSRP) {
@@ -718,7 +733,7 @@
 
     ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisDlKbps, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
-    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 /*
@@ -737,7 +752,7 @@
 
     ALOGI("setLinkCapacityReportingCriteria_invalidHysteresisUlKbps, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
-    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 /*
@@ -755,7 +770,7 @@
 
     ALOGI("setLinkCapacityReportingCriteria_emptyParams, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
-    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 /*
@@ -1393,21 +1408,31 @@
     }
 
     // 32 bit system might return invalid mcc and mnc string "\xff\xff..."
-    if (checkMccMnc && mcc.size() == 3 && (mnc.size() == 2 || mnc.size() == 3)) {
-        int mcc_int = stoi(mcc);
-        int mnc_int = stoi(mnc);
-        EXPECT_TRUE(mcc_int >= 0 && mcc_int <= 999);
-        EXPECT_TRUE(mnc_int >= 0 && mnc_int <= 999);
+    if (checkMccMnc) {
+        int mccSize = mcc.size();
+        EXPECT_TRUE(mccSize == 0 || mccSize == 3);
+        if (mccSize > 0) {
+            int mcc_int = stoi(mcc);
+            EXPECT_TRUE(mcc_int >= 0 && mcc_int <= 999);
+        }
+
+        int mncSize = mnc.size();
+        EXPECT_TRUE(mncSize == 0 || mncSize == 2 || mncSize == 3);
+        if (mncSize > 0) {
+            int mnc_int = stoi(mnc);
+            EXPECT_TRUE(mnc_int >= 0 && mnc_int <= 999);
+        }
     }
 
     // Check for access technology specific info
     AccessTechnologySpecificInfo info = radioRsp_network->dataRegResp.accessTechnologySpecificInfo;
     RadioTechnology rat = radioRsp_network->dataRegResp.rat;
+
     // TODO: add logic for cdmaInfo
-    if (rat == RadioTechnology::LTE || rat == RadioTechnology::LTE_CA) {
+    if (rat == RadioTechnology::LTE) {
         ASSERT_EQ(info.getTag(), AccessTechnologySpecificInfo::eutranInfo);
     } else if (rat == RadioTechnology::NR) {
-        ASSERT_EQ(info.getTag(), AccessTechnologySpecificInfo::ngranNrVopsInfo);
+        ASSERT_TRUE(info.getTag() == AccessTechnologySpecificInfo::ngranNrVopsInfo);
     }
 }
 
@@ -1524,7 +1549,6 @@
  * Test IRadioNetwork.getOperator() for the response returned.
  */
 TEST_P(RadioNetworkTest, getOperator) {
-    LOG(DEBUG) << "getOperator";
     serial = GetRandomSerialNumber();
 
     radio_network->getOperator(serial);
@@ -1535,14 +1559,12 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
     }
-    LOG(DEBUG) << "getOperator finished";
 }
 
 /*
  * Test IRadioNetwork.getNetworkSelectionMode() for the response returned.
  */
 TEST_P(RadioNetworkTest, getNetworkSelectionMode) {
-    LOG(DEBUG) << "getNetworkSelectionMode";
     serial = GetRandomSerialNumber();
 
     radio_network->getNetworkSelectionMode(serial);
@@ -1553,14 +1575,12 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
     }
-    LOG(DEBUG) << "getNetworkSelectionMode finished";
 }
 
 /*
  * Test IRadioNetwork.setNetworkSelectionModeAutomatic() for the response returned.
  */
 TEST_P(RadioNetworkTest, setNetworkSelectionModeAutomatic) {
-    LOG(DEBUG) << "setNetworkSelectionModeAutomatic";
     serial = GetRandomSerialNumber();
 
     radio_network->setNetworkSelectionModeAutomatic(serial);
@@ -1574,14 +1594,12 @@
                                       RadioError::OPERATION_NOT_ALLOWED},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setNetworkSelectionModeAutomatic finished";
 }
 
 /*
  * Test IRadioNetwork.getAvailableNetworks() for the response returned.
  */
 TEST_P(RadioNetworkTest, getAvailableNetworks) {
-    LOG(DEBUG) << "getAvailableNetworks";
     serial = GetRandomSerialNumber();
 
     radio_network->getAvailableNetworks(serial);
@@ -1597,14 +1615,12 @@
                  RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "getAvailableNetworks finished";
 }
 
 /*
  * Test IRadioNetwork.setBandMode() for the response returned.
  */
 TEST_P(RadioNetworkTest, setBandMode) {
-    LOG(DEBUG) << "setBandMode";
     serial = GetRandomSerialNumber();
 
     radio_network->setBandMode(serial, RadioBandMode::BAND_MODE_USA);
@@ -1616,14 +1632,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setBandMode finished";
 }
 
 /*
  * Test IRadioNetwork.setLocationUpdates() for the response returned.
  */
 TEST_P(RadioNetworkTest, setLocationUpdates) {
-    LOG(DEBUG) << "setLocationUpdates";
     serial = GetRandomSerialNumber();
 
     radio_network->setLocationUpdates(serial, true);
@@ -1635,14 +1649,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::NONE, RadioError::SIM_ABSENT}));
     }
-    LOG(DEBUG) << "setLocationUpdates finished";
 }
 
 /*
  * Test IRadioNetwork.setCdmaRoamingPreference() for the response returned.
  */
 TEST_P(RadioNetworkTest, setCdmaRoamingPreference) {
-    LOG(DEBUG) << "setCdmaRoamingPreference";
     serial = GetRandomSerialNumber();
 
     radio_network->setCdmaRoamingPreference(serial, CdmaRoamingType::HOME_NETWORK);
@@ -1655,14 +1667,12 @@
                 radioRsp_network->rspInfo.error,
                 {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::REQUEST_NOT_SUPPORTED}));
     }
-    LOG(DEBUG) << "setCdmaRoamingPreference finished";
 }
 
 /*
  * Test IRadioNetwork.getCdmaRoamingPreference() for the response returned.
  */
 TEST_P(RadioNetworkTest, getCdmaRoamingPreference) {
-    LOG(DEBUG) << "getCdmaRoamingPreference";
     serial = GetRandomSerialNumber();
 
     radio_network->getCdmaRoamingPreference(serial);
@@ -1676,14 +1686,12 @@
                                  {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::MODEM_ERR},
                                  CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "getCdmaRoamingPreference finished";
 }
 
 /*
  * Test IRadioNetwork.getVoiceRadioTechnology() for the response returned.
  */
 TEST_P(RadioNetworkTest, getVoiceRadioTechnology) {
-    LOG(DEBUG) << "getVoiceRadioTechnology";
     serial = GetRandomSerialNumber();
 
     radio_network->getVoiceRadioTechnology(serial);
@@ -1694,14 +1702,12 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
     }
-    LOG(DEBUG) << "getVoiceRadioTechnology finished";
 }
 
 /*
  * Test IRadioNetwork.setCellInfoListRate() for the response returned.
  */
 TEST_P(RadioNetworkTest, setCellInfoListRate) {
-    LOG(DEBUG) << "setCellInfoListRate";
     serial = GetRandomSerialNumber();
 
     radio_network->setCellInfoListRate(serial, 10);
@@ -1713,14 +1719,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
-    LOG(DEBUG) << "setCellInfoListRate finished";
 }
 
 /*
  * Test IRadioNetwork.supplyNetworkDepersonalization() for the response returned.
  */
 TEST_P(RadioNetworkTest, supplyNetworkDepersonalization) {
-    LOG(DEBUG) << "supplyNetworkDepersonalization";
     serial = GetRandomSerialNumber();
 
     radio_network->supplyNetworkDepersonalization(serial, std::string("test"));
@@ -1735,5 +1739,226 @@
                  RadioError::INVALID_SIM_STATE, RadioError::MODEM_ERR, RadioError::NO_MEMORY,
                  RadioError::PASSWORD_INCORRECT, RadioError::SIM_ABSENT, RadioError::SYSTEM_ERR}));
     }
-    LOG(DEBUG) << "supplyNetworkDepersonalization finished";
+}
+
+/*
+ * Test IRadioNetwork.setEmergencyMode() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setEmergencyMode) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since setEmergencyMode is not supported on version < 2.");
+        GTEST_SKIP();
+    }
+
+    serial = GetRandomSerialNumber();
+
+    radio_network->setEmergencyMode(serial, EmergencyMode::EMERGENCY_WWAN);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_network->rspInfo.error,
+            {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE,
+             RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS}));
+
+    // exit emergency mode for other tests
+    serial = GetRandomSerialNumber();
+    radio_network->exitEmergencyMode(serial);
+}
+
+/*
+ * Test IRadioNetwork.triggerEmergencyNetworkScan() for the response returned.
+ */
+TEST_P(RadioNetworkTest, triggerEmergencyNetworkScan) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since"
+                " triggerEmergencyNetworkScan is not supported on version < 2.");
+        GTEST_SKIP();
+    }
+
+    serial = GetRandomSerialNumber();
+
+    EmergencyNetworkScanTrigger scanRequest;
+    scanRequest.accessNetwork = {AccessNetwork::EUTRAN};
+    scanRequest.scanType = EmergencyScanType::NO_PREFERENCE;
+
+    radio_network->triggerEmergencyNetworkScan(serial, scanRequest);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_network->rspInfo.error,
+            {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE,
+             RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS}));
+}
+
+/*
+ * Test IRadioNetwork.cancelEmergencyNetworkScan() for the response returned.
+ */
+TEST_P(RadioNetworkTest, cancelEmergencyNetworkScan) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since cancelEmergencyNetworkScan is not supported on version < 2.");
+        GTEST_SKIP();
+    }
+
+    serial = GetRandomSerialNumber();
+
+    radio_network->cancelEmergencyNetworkScan(serial, true);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED,
+                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+}
+
+/*
+ * Test IRadioNetwork.exitEmergencyMode() for the response returned.
+ */
+TEST_P(RadioNetworkTest, exitEmergencyMode) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since exitEmergencyMode is not supported on version < 2.");
+        GTEST_SKIP();
+    }
+
+    serial = GetRandomSerialNumber();
+
+    radio_network->exitEmergencyMode(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED,
+                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+}
+
+/*
+ * Test IRadioNetwork.setN1ModeEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setN1ModeEnabled) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since setN1ModeEnabled is not supported on version < 2.");
+        GTEST_SKIP();
+    }
+
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res =
+            radio_network->setN1ModeEnabled(serial, false);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+                 RadioError::INVALID_STATE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.isN1ModeEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, isN1ModeEnabled) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since isN1ModeEnabled is not supported on version < 2.");
+        GTEST_SKIP();
+    }
+
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->isN1ModeEnabled(serial);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+                 RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.setNullCipherAndIntegrityEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setNullCipherAndIntegrityEnabled) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since"
+                " setNullCipherAndIntegrityEnabled is not supported on version < 2.");
+        GTEST_SKIP();
+    }
+
+    serial = GetRandomSerialNumber();
+
+    radio_network->setNullCipherAndIntegrityEnabled(serial, false);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED,
+                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+}
+
+/**
+ * Test IRadioNetwork.isNullCipherAndIntegrityEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, isNullCipherAndIntegrityEnabled) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since"
+                " isNullCipherAndIntegrityEnabled is not supported on version < 2.");
+        GTEST_SKIP();
+    }
+
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->isNullCipherAndIntegrityEnabled(serial);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
 }
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index 29f20e8..8f8f6b0 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -147,6 +147,28 @@
 
     virtual ndk::ScopedAStatus supplyNetworkDepersonalizationResponse(
             const RadioResponseInfo& info, int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus setEmergencyModeResponse(
+            const RadioResponseInfo& info, const EmergencyRegResult& regState) override;
+
+    virtual ndk::ScopedAStatus triggerEmergencyNetworkScanResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus exitEmergencyModeResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus cancelEmergencyNetworkScanResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setNullCipherAndIntegrityEnabledResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus isNullCipherAndIntegrityEnabledResponse(
+            const RadioResponseInfo& info, const bool isEnabled) override;
+
+    virtual ndk::ScopedAStatus isN1ModeEnabledResponse(
+            const RadioResponseInfo& info, bool isEnabled) override;
+
+    virtual ndk::ScopedAStatus setN1ModeEnabledResponse(const RadioResponseInfo& info) override;
 };
 
 /* Callback class for radio network indication */
@@ -201,12 +223,15 @@
 
     virtual ndk::ScopedAStatus voiceRadioTechChanged(RadioIndicationType type,
                                                      RadioTechnology rat) override;
+
+    virtual ndk::ScopedAStatus emergencyNetworkScanResult(
+            RadioIndicationType type, const EmergencyRegResult& result) override;
 };
 
 // The main test class for Radio AIDL Network.
-class RadioNetworkTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+class RadioNetworkTest : public RadioServiceTest {
   public:
-    virtual void SetUp() override;
+    void SetUp() override;
 
     /* radio network service handle */
     std::shared_ptr<IRadioNetwork> radio_network;
diff --git a/radio/aidl/vts/radio_sap_callback.cpp b/radio/aidl/vts/radio_sap_callback.cpp
new file mode 100644
index 0000000..3b21ede
--- /dev/null
+++ b/radio/aidl/vts/radio_sap_callback.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "radio_sap_utils.h"
+
+#include <android-base/logging.h>
+
+SapCallback::SapCallback(SapTest& parent) : parent_sap(parent) {}
+
+::ndk::ScopedAStatus SapCallback::apduResponse(int32_t serialNumber, SapResultCode resultCode,
+                                               const std::vector<uint8_t>& /*apduRsp*/) {
+    sapResponseSerial = serialNumber;
+    sapResultCode = resultCode;
+    parent_sap.notify(serialNumber);
+    return ndk::ScopedAStatus::ok();
+}
+::ndk::ScopedAStatus SapCallback::connectResponse(int32_t serialNumber,
+                                                  SapConnectRsp /*sapConnectRsp*/,
+                                                  int32_t /*maxMsgSize*/) {
+    sapResponseSerial = serialNumber;
+    parent_sap.notify(serialNumber);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SapCallback::disconnectIndication(int32_t /*serialNumber*/,
+                                                       SapDisconnectType /*sapDisconnectType*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SapCallback::disconnectResponse(int32_t serialNumber) {
+    sapResponseSerial = serialNumber;
+    parent_sap.notify(serialNumber);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SapCallback::errorResponse(int32_t /*serialNumber*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SapCallback::powerResponse(int32_t serialNumber, SapResultCode resultCode) {
+    sapResponseSerial = serialNumber;
+    sapResultCode = resultCode;
+    parent_sap.notify(serialNumber);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SapCallback::resetSimResponse(int32_t serialNumber, SapResultCode resultCode) {
+    sapResponseSerial = serialNumber;
+    sapResultCode = resultCode;
+    parent_sap.notify(serialNumber);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SapCallback::statusIndication(int32_t /*serialNumber*/,
+                                                   SapStatus /*sapStatus*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SapCallback::transferAtrResponse(int32_t serialNumber,
+                                                      SapResultCode resultCode,
+                                                      const std::vector<uint8_t>& /*atr*/) {
+    sapResponseSerial = serialNumber;
+    sapResultCode = resultCode;
+    parent_sap.notify(serialNumber);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SapCallback::transferCardReaderStatusResponse(int32_t serialNumber,
+                                                                   SapResultCode resultCode,
+                                                                   int32_t /*cardReaderStatus*/) {
+    sapResponseSerial = serialNumber;
+    sapResultCode = resultCode;
+    parent_sap.notify(serialNumber);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus SapCallback::transferProtocolResponse(int32_t serialNumber,
+                                                           SapResultCode resultCode) {
+    sapResponseSerial = serialNumber;
+    sapResultCode = resultCode;
+    parent_sap.notify(serialNumber);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_sap_test.cpp b/radio/aidl/vts/radio_sap_test.cpp
new file mode 100644
index 0000000..9a1c145
--- /dev/null
+++ b/radio/aidl/vts/radio_sap_test.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_manager.h>
+
+#include "radio_sap_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE((ret).isOk())
+#define TIMEOUT_PERIOD 40
+
+void SapTest::SetUp() {
+    ALOGD("BEGIN %s#%s", ::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name(),
+          ::testing::UnitTest::GetInstance()->current_test_info()->name());
+    count = 0;
+    serial = -1;
+    std::string serviceName = GetParam();
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+    sap = ISap::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+    ASSERT_NE(sap.get(), nullptr);
+
+    sapCb = ndk::SharedRefBase::make<SapCallback>(*this);
+    ASSERT_NE(sapCb.get(), nullptr);
+
+    ndk::ScopedAStatus res = sap->setCallback(sapCb);
+    ASSERT_OK(res) << res;
+}
+
+void SapTest::TearDown() {
+    count_ = 0;
+    serial = -1;
+    ALOGD("END %s#%s", ::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name(),
+          ::testing::UnitTest::GetInstance()->current_test_info()->name());
+}
+
+::testing::AssertionResult SapTest::CheckAnyOfErrors(SapResultCode err,
+                                                     std::vector<SapResultCode> errors) {
+    for (size_t i = 0; i < errors.size(); i++) {
+        if (err == errors[i]) {
+            return testing::AssertionSuccess();
+        }
+    }
+    return testing::AssertionFailure() << "SapError:" + toString(err) + " is returned";
+}
+
+void SapTest::notify(int receivedSerial) {
+    std::lock_guard<std::mutex> lock(mtx);
+    if (serial == receivedSerial) {
+        count++;
+        cv.notify_one();
+    }
+}
+
+std::cv_status SapTest::wait() {
+    std::unique_lock<std::mutex> lock(mtx);
+
+    std::cv_status status = std::cv_status::no_timeout;
+    auto now = std::chrono::system_clock::now();
+    while (count == 0) {
+        status = cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+        if (status == std::cv_status::timeout) {
+            return status;
+        }
+    }
+    count--;
+    return status;
+}
+
+/*
+ * Test ISap.connectReq() for the response returned.
+ */
+TEST_P(SapTest, connectReq) {
+    serial = GetRandomSerialNumber();
+    int32_t maxMsgSize = 100;
+
+    ndk::ScopedAStatus res = sap->connectReq(serial, maxMsgSize);
+    ASSERT_OK(res) << res;
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sapCb->sapResponseSerial, serial);
+
+    // Modem side need time for connect to finish. Adding a waiting time to prevent
+    // disconnect being requested right after connect request.
+    sleep(1);
+}
+
+/*
+ * Test ISap.disconnectReq() for the response returned
+ */
+TEST_P(SapTest, disconnectReq) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = sap->disconnectReq(serial);
+    ASSERT_OK(res) << res;
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sapCb->sapResponseSerial, serial);
+}
+
+/*
+ * Test ISap.apduReq() for the response returned.
+ */
+TEST_P(SapTest, apduReq) {
+    serial = GetRandomSerialNumber();
+    SapApduType sapApduType = SapApduType::APDU;
+    std::vector<uint8_t> command = {};
+
+    ndk::ScopedAStatus res = sap->apduReq(serial, sapApduType, command);
+    ASSERT_OK(res) << res;
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sapCb->sapResponseSerial, serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(
+            sapCb->sapResultCode,
+            {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_ALREADY_POWERED_OFF,
+             SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_REMOVED,
+             SapResultCode::SUCCESS}));
+}
+
+/*
+ * Test ISap.transferAtrReq() for the response returned.
+ */
+TEST_P(SapTest, transferAtrReq) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = sap->transferAtrReq(serial);
+    ASSERT_OK(res) << res;
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sapCb->sapResponseSerial, serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode,
+                                 {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE,
+                                  SapResultCode::CARD_ALREADY_POWERED_OFF,
+                                  SapResultCode::CARD_REMOVED, SapResultCode::SUCCESS}));
+}
+
+/*
+ * Test ISap.powerReq() for the response returned.
+ */
+TEST_P(SapTest, powerReq) {
+    serial = GetRandomSerialNumber();
+    bool state = true;
+
+    ndk::ScopedAStatus res = sap->powerReq(serial, state);
+    ASSERT_OK(res) << res;
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sapCb->sapResponseSerial, serial);
+
+    ASSERT_TRUE(
+            CheckAnyOfErrors(sapCb->sapResultCode,
+                             {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE,
+                              SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED,
+                              SapResultCode::CARD_ALREADY_POWERED_ON, SapResultCode::SUCCESS}));
+}
+
+/*
+ * Test ISap.resetSimReq() for the response returned.
+ */
+TEST_P(SapTest, resetSimReq) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = sap->resetSimReq(serial);
+    ASSERT_OK(res) << res;
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sapCb->sapResponseSerial, serial);
+
+    ASSERT_TRUE(
+            CheckAnyOfErrors(sapCb->sapResultCode,
+                             {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE,
+                              SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED,
+                              SapResultCode::SUCCESS}));
+}
+
+/*
+ * Test ISap.transferCardReaderStatusReq() for the response returned.
+ */
+TEST_P(SapTest, transferCardReaderStatusReq) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = sap->transferCardReaderStatusReq(serial);
+    ASSERT_OK(res) << res;
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sapCb->sapResponseSerial, serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode,
+                                 {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE,
+                                  SapResultCode::SUCCESS}));
+}
+
+/*
+ * Test ISap.setTransferProtocolReq() for the response returned.
+ */
+TEST_P(SapTest, setTransferProtocolReq) {
+    serial = GetRandomSerialNumber();
+    SapTransferProtocol sapTransferProtocol = SapTransferProtocol::T0;
+
+    ndk::ScopedAStatus res = sap->setTransferProtocolReq(serial, sapTransferProtocol);
+    ASSERT_OK(res) << res;
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(sapCb->sapResponseSerial, serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode,
+                                 {SapResultCode::NOT_SUPPORTED, SapResultCode::SUCCESS}));
+}
diff --git a/radio/aidl/vts/radio_sap_utils.h b/radio/aidl/vts/radio_sap_utils.h
new file mode 100644
index 0000000..bf17006
--- /dev/null
+++ b/radio/aidl/vts/radio_sap_utils.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/Gtest.h>
+#include <aidl/android/hardware/radio/sap/BnSapCallback.h>
+#include <aidl/android/hardware/radio/sap/ISap.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::sap;
+
+class SapTest;
+
+/* Callback class for radio sap response */
+class SapCallback : public BnSapCallback {
+  protected:
+    SapTest& parent_sap;
+
+  public:
+    SapCallback(SapTest& parent_config);
+    virtual ~SapCallback() = default;
+
+    int32_t sapResponseSerial;
+    SapResultCode sapResultCode;
+
+    virtual ::ndk::ScopedAStatus apduResponse(int32_t serial, SapResultCode resultCode,
+                                              const std::vector<uint8_t>& adpuRsp) override;
+
+    virtual ::ndk::ScopedAStatus connectResponse(int32_t serial, SapConnectRsp sapConnectRsp,
+                                                 int32_t maxMsgSize) override;
+
+    virtual ::ndk::ScopedAStatus disconnectIndication(int32_t serial,
+                                                      SapDisconnectType sapDisconnectType) override;
+
+    virtual ::ndk::ScopedAStatus disconnectResponse(int32_t serial) override;
+
+    virtual ::ndk::ScopedAStatus errorResponse(int32_t serial) override;
+
+    virtual ::ndk::ScopedAStatus powerResponse(int32_t serial, SapResultCode resultCode) override;
+
+    virtual ::ndk::ScopedAStatus resetSimResponse(int32_t serial,
+                                                  SapResultCode resultCode) override;
+
+    virtual ::ndk::ScopedAStatus statusIndication(int32_t serial, SapStatus sapStatus) override;
+
+    virtual ::ndk::ScopedAStatus transferAtrResponse(int32_t serial, SapResultCode resultCode,
+                                                     const std::vector<uint8_t>& atr) override;
+
+    virtual ::ndk::ScopedAStatus transferCardReaderStatusResponse(
+            int32_t serial, SapResultCode resultCode, int32_t cardReaderStatus) override;
+
+    virtual ::ndk::ScopedAStatus transferProtocolResponse(int32_t serial,
+                                                          SapResultCode resultCode) override;
+};
+
+// The main test class for  AIDL SAP.
+class SapTest : public ::testing::TestWithParam<std::string> {
+  private:
+    std::mutex mtx;
+    std::condition_variable cv;
+    int count;
+
+  public:
+    virtual void SetUp() override;
+
+    virtual void TearDown() override;
+
+    ::testing::AssertionResult CheckAnyOfErrors(SapResultCode err,
+                                                std::vector<SapResultCode> errors);
+
+    /* Used as a mechanism to inform the test about data/event callback */
+    void notify(int receivedSerial);
+
+    /* Test code calls this function to wait for response */
+    std::cv_status wait();
+
+    /* Sap service */
+    std::shared_ptr<ISap> sap;
+
+    /* Sap Callback object */
+    std::shared_ptr<SapCallback> sapCb;
+
+    /* Serial for sap request */
+    int32_t serial;
+};
diff --git a/radio/aidl/vts/radio_sim_response.cpp b/radio/aidl/vts/radio_sim_response.cpp
index 391c9cb..296c65c 100644
--- a/radio/aidl/vts/radio_sim_response.cpp
+++ b/radio/aidl/vts/radio_sim_response.cpp
@@ -118,6 +118,13 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus RadioSimResponse::iccCloseLogicalChannelWithSessionInfoResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus RadioSimResponse::iccIoForAppResponse(const RadioResponseInfo& info,
                                                          const IccIoResult& /*iccIo*/) {
     rspInfo = info;
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index e69247d..d906588 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -16,7 +16,6 @@
 
 #include <aidl/android/hardware/radio/RadioConst.h>
 #include <aidl/android/hardware/radio/config/IRadioConfig.h>
-#include <android-base/logging.h>
 #include <android/binder_manager.h>
 
 #include "radio_sim_utils.h"
@@ -24,6 +23,7 @@
 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
 
 void RadioSimTest::SetUp() {
+    RadioServiceTest::SetUp();
     std::string serviceName = GetParam();
 
     if (!isServiceValidForDeviceConfiguration(serviceName)) {
@@ -38,8 +38,6 @@
     radioRsp_sim = ndk::SharedRefBase::make<RadioSimResponse>(*this);
     ASSERT_NE(nullptr, radioRsp_sim.get());
 
-    count_ = 0;
-
     radioInd_sim = ndk::SharedRefBase::make<RadioSimIndication>(*this);
     ASSERT_NE(nullptr, radioInd_sim.get());
 
@@ -481,19 +479,16 @@
  * Test IRadioSim.getIccCardStatus() for the response returned.
  */
 TEST_P(RadioSimTest, getIccCardStatus) {
-    LOG(DEBUG) << "getIccCardStatus";
     EXPECT_LE(cardStatus.applications.size(), RadioConst::CARD_MAX_APPS);
     EXPECT_LT(cardStatus.gsmUmtsSubscriptionAppIndex, RadioConst::CARD_MAX_APPS);
     EXPECT_LT(cardStatus.cdmaSubscriptionAppIndex, RadioConst::CARD_MAX_APPS);
     EXPECT_LT(cardStatus.imsSubscriptionAppIndex, RadioConst::CARD_MAX_APPS);
-    LOG(DEBUG) << "getIccCardStatus finished";
 }
 
 /*
  * Test IRadioSim.supplyIccPinForApp() for the response returned
  */
 TEST_P(RadioSimTest, supplyIccPinForApp) {
-    LOG(DEBUG) << "supplyIccPinForApp";
     serial = GetRandomSerialNumber();
 
     // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -513,14 +508,12 @@
                     {RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED}));
         }
     }
-    LOG(DEBUG) << "supplyIccPinForApp finished";
 }
 
 /*
  * Test IRadioSim.supplyIccPukForApp() for the response returned.
  */
 TEST_P(RadioSimTest, supplyIccPukForApp) {
-    LOG(DEBUG) << "supplyIccPukForApp";
     serial = GetRandomSerialNumber();
 
     // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -540,14 +533,12 @@
                     {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE}));
         }
     }
-    LOG(DEBUG) << "supplyIccPukForApp finished";
 }
 
 /*
  * Test IRadioSim.supplyIccPin2ForApp() for the response returned.
  */
 TEST_P(RadioSimTest, supplyIccPin2ForApp) {
-    LOG(DEBUG) << "supplyIccPin2ForApp";
     serial = GetRandomSerialNumber();
 
     // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -568,14 +559,12 @@
                                       RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_PUK2}));
         }
     }
-    LOG(DEBUG) << "supplyIccPin2ForApp finished";
 }
 
 /*
  * Test IRadioSim.supplyIccPuk2ForApp() for the response returned.
  */
 TEST_P(RadioSimTest, supplyIccPuk2ForApp) {
-    LOG(DEBUG) << "supplyIccPuk2ForApp";
     serial = GetRandomSerialNumber();
 
     // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -595,14 +584,12 @@
                     {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE}));
         }
     }
-    LOG(DEBUG) << "supplyIccPuk2ForApp finished";
 }
 
 /*
  * Test IRadioSim.changeIccPinForApp() for the response returned.
  */
 TEST_P(RadioSimTest, changeIccPinForApp) {
-    LOG(DEBUG) << "changeIccPinForApp";
     serial = GetRandomSerialNumber();
 
     // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -622,14 +609,12 @@
                     {RadioError::PASSWORD_INCORRECT, RadioError::REQUEST_NOT_SUPPORTED}));
         }
     }
-    LOG(DEBUG) << "changeIccPinForApp finished";
 }
 
 /*
  * Test IRadioSim.changeIccPin2ForApp() for the response returned.
  */
 TEST_P(RadioSimTest, changeIccPin2ForApp) {
-    LOG(DEBUG) << "changeIccPin2ForApp";
     serial = GetRandomSerialNumber();
 
     // Pass wrong password and check PASSWORD_INCORRECT returned for 3GPP and
@@ -650,14 +635,12 @@
                                       RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_PUK2}));
         }
     }
-    LOG(DEBUG) << "changeIccPin2ForApp finished";
 }
 
 /*
  * Test IRadioSim.getImsiForApp() for the response returned.
  */
 TEST_P(RadioSimTest, getImsiForApp) {
-    LOG(DEBUG) << "getImsiForApp";
     serial = GetRandomSerialNumber();
 
     // Check success returned while getting imsi for 3GPP and 3GPP2 apps only
@@ -681,14 +664,12 @@
             }
         }
     }
-    LOG(DEBUG) << "getImsiForApp finished";
 }
 
 /*
  * Test IRadioSim.iccIoForApp() for the response returned.
  */
 TEST_P(RadioSimTest, iccIoForApp) {
-    LOG(DEBUG) << "iccIoForApp";
     serial = GetRandomSerialNumber();
 
     for (int i = 0; i < (int)cardStatus.applications.size(); i++) {
@@ -708,14 +689,12 @@
         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
         EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
     }
-    LOG(DEBUG) << "iccIoForApp finished";
 }
 
 /*
  * Test IRadioSim.iccTransmitApduBasicChannel() for the response returned.
  */
 TEST_P(RadioSimTest, iccTransmitApduBasicChannel) {
-    LOG(DEBUG) << "iccTransmitApduBasicChannel";
     serial = GetRandomSerialNumber();
     SimApdu msg;
     memset(&msg, 0, sizeof(msg));
@@ -725,14 +704,12 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-    LOG(DEBUG) << "iccTransmitApduBasicChannel finished";
 }
 
 /*
  * Test IRadioSim.iccOpenLogicalChannel() for the response returned.
  */
 TEST_P(RadioSimTest, iccOpenLogicalChannel) {
-    LOG(DEBUG) << "iccOpenLogicalChannel";
     serial = GetRandomSerialNumber();
     int p2 = 0x04;
     // Specified in ISO 7816-4 clause 7.1.1 0x04 means that FCP template is requested.
@@ -742,14 +719,12 @@
         EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
     }
-    LOG(DEBUG) << "iccOpenLogicalChannel finished";
 }
 
 /*
  * Test IRadioSim.iccCloseLogicalChannel() for the response returned.
  */
 TEST_P(RadioSimTest, iccCloseLogicalChannel) {
-    LOG(DEBUG) << "iccCloseLogicalChannel";
     serial = GetRandomSerialNumber();
     // Try closing invalid channel and check INVALID_ARGUMENTS returned as error
     radio_sim->iccCloseLogicalChannel(serial, 0);
@@ -758,14 +733,39 @@
     EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
 
     EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp_sim->rspInfo.error);
-    LOG(DEBUG) << "iccCloseLogicalChannel finished";
+}
+
+/*
+ * Test IRadioSim.iccCloseLogicalChannelWithSessionInfo() for the response returned.
+ */
+TEST_P(RadioSimTest, iccCloseLogicalChannelWithSessionInfo) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_sim->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 2) {
+        ALOGI("Skipped the test since"
+              " iccCloseLogicalChannelWithSessionInfo is not supported on version < 2");
+        GTEST_SKIP();
+    }
+    serial = GetRandomSerialNumber();
+    SessionInfo info;
+    memset(&info, 0, sizeof(info));
+    info.sessionId = 0;
+    info.isEs10 = false;
+
+    // Try closing invalid channel and check INVALID_ARGUMENTS returned as error
+    radio_sim->iccCloseLogicalChannelWithSessionInfo(serial, info);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+    EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp_sim->rspInfo.error);
 }
 
 /*
  * Test IRadioSim.iccTransmitApduLogicalChannel() for the response returned.
  */
 TEST_P(RadioSimTest, iccTransmitApduLogicalChannel) {
-    LOG(DEBUG) << "iccTransmitApduLogicalChannel";
     serial = GetRandomSerialNumber();
     SimApdu msg;
     memset(&msg, 0, sizeof(msg));
@@ -775,14 +775,12 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-    LOG(DEBUG) << "iccTransmitApduLogicalChannel finished";
 }
 
 /*
  * Test IRadioSim.requestIccSimAuthentication() for the response returned.
  */
 TEST_P(RadioSimTest, requestIccSimAuthentication) {
-    LOG(DEBUG) << "requestIccSimAuthentication";
     serial = GetRandomSerialNumber();
 
     // Pass wrong challenge string and check RadioError::INVALID_ARGUMENTS
@@ -797,7 +795,6 @@
                 radioRsp_sim->rspInfo.error,
                 {RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED}));
     }
-    LOG(DEBUG) << "requestIccSimAuthentication finished";
 }
 
 /*
@@ -851,7 +848,6 @@
  * Test IRadioSim.getCdmaSubscription() for the response returned.
  */
 TEST_P(RadioSimTest, getCdmaSubscription) {
-    LOG(DEBUG) << "getCdmaSubscription";
     serial = GetRandomSerialNumber();
 
     radio_sim->getCdmaSubscription(serial);
@@ -864,14 +860,12 @@
                 radioRsp_sim->rspInfo.error,
                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
     }
-    LOG(DEBUG) << "getCdmaSubscription finished";
 }
 
 /*
  * Test IRadioSim.getCdmaSubscriptionSource() for the response returned.
  */
 TEST_P(RadioSimTest, getCdmaSubscriptionSource) {
-    LOG(DEBUG) << "getCdmaSubscriptionSource";
     serial = GetRandomSerialNumber();
 
     radio_sim->getCdmaSubscriptionSource(serial);
@@ -884,14 +878,12 @@
                 radioRsp_sim->rspInfo.error,
                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
     }
-    LOG(DEBUG) << "getCdmaSubscriptionSource finished";
 }
 
 /*
  * Test IRadioSim.setCdmaSubscriptionSource() for the response returned.
  */
 TEST_P(RadioSimTest, setCdmaSubscriptionSource) {
-    LOG(DEBUG) << "setCdmaSubscriptionSource";
     serial = GetRandomSerialNumber();
 
     radio_sim->setCdmaSubscriptionSource(serial, CdmaSubscriptionSource::RUIM_SIM);
@@ -905,14 +897,12 @@
                 {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::SUBSCRIPTION_NOT_AVAILABLE},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setCdmaSubscriptionSource finished";
 }
 
 /*
  * Test IRadioSim.setUiccSubscription() for the response returned.
  */
 TEST_P(RadioSimTest, setUiccSubscription) {
-    LOG(DEBUG) << "setUiccSubscription";
     serial = GetRandomSerialNumber();
     SelectUiccSub item;
     memset(&item, 0, sizeof(item));
@@ -929,14 +919,12 @@
                                   RadioError::MODEM_ERR, RadioError::SUBSCRIPTION_NOT_SUPPORTED},
                                  CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setUiccSubscription finished";
 }
 
 /*
  * Test IRadioSim.sendEnvelope() for the response returned.
  */
 TEST_P(RadioSimTest, sendEnvelope) {
-    LOG(DEBUG) << "sendEnvelope";
     serial = GetRandomSerialNumber();
 
     // Test with sending empty string
@@ -954,14 +942,12 @@
                                       RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendEnvelope finished";
 }
 
 /*
  * Test IRadioSim.sendTerminalResponseToSim() for the response returned.
  */
 TEST_P(RadioSimTest, sendTerminalResponseToSim) {
-    LOG(DEBUG) << "sendTerminalResponseToSim";
     serial = GetRandomSerialNumber();
 
     // Test with sending empty string
@@ -979,14 +965,12 @@
                 {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::SIM_ABSENT},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendTerminalResponseToSim finished";
 }
 
 /*
  * Test IRadioSim.reportStkServiceIsRunning() for the response returned.
  */
 TEST_P(RadioSimTest, reportStkServiceIsRunning) {
-    LOG(DEBUG) << "reportStkServiceIsRunning";
     serial = GetRandomSerialNumber();
 
     radio_sim->reportStkServiceIsRunning(serial);
@@ -999,7 +983,6 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error, {RadioError::NONE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "reportStkServiceIsRunning finished";
 }
 
 /*
@@ -1007,7 +990,6 @@
  * string.
  */
 TEST_P(RadioSimTest, sendEnvelopeWithStatus) {
-    LOG(DEBUG) << "sendEnvelopeWithStatus";
     serial = GetRandomSerialNumber();
 
     // Test with sending empty string
@@ -1025,5 +1007,4 @@
                 {RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendEnvelopeWithStatus finished";
 }
diff --git a/radio/aidl/vts/radio_sim_utils.h b/radio/aidl/vts/radio_sim_utils.h
index 83f1cbc..7cbcc58 100644
--- a/radio/aidl/vts/radio_sim_utils.h
+++ b/radio/aidl/vts/radio_sim_utils.h
@@ -87,6 +87,9 @@
     virtual ndk::ScopedAStatus iccCloseLogicalChannelResponse(
             const RadioResponseInfo& info) override;
 
+    virtual ndk::ScopedAStatus iccCloseLogicalChannelWithSessionInfoResponse(
+            const RadioResponseInfo& info) override;
+
     virtual ndk::ScopedAStatus iccIoForAppResponse(const RadioResponseInfo& info,
                                                    const IccIoResult& iccIo) override;
 
@@ -191,9 +194,9 @@
 };
 
 // The main test class for Radio AIDL SIM.
-class RadioSimTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+class RadioSimTest : public RadioServiceTest {
   public:
-    virtual void SetUp() override;
+    void SetUp() override;
 
     /* Override updateSimCardStatus in RadioServiceTest to not call setResponseFunctions */
     void updateSimCardStatus();
diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp
index 249ee63..397c417 100644
--- a/radio/aidl/vts/radio_voice_test.cpp
+++ b/radio/aidl/vts/radio_voice_test.cpp
@@ -16,7 +16,6 @@
 
 #include <aidl/android/hardware/radio/config/IRadioConfig.h>
 #include <aidl/android/hardware/radio/voice/EmergencyServiceCategory.h>
-#include <android-base/logging.h>
 #include <android/binder_manager.h>
 
 #include "radio_voice_utils.h"
@@ -24,6 +23,7 @@
 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
 
 void RadioVoiceTest::SetUp() {
+    RadioServiceTest::SetUp();
     std::string serviceName = GetParam();
 
     if (!isServiceValidForDeviceConfiguration(serviceName)) {
@@ -38,8 +38,6 @@
     radioRsp_voice = ndk::SharedRefBase::make<RadioVoiceResponse>(*this);
     ASSERT_NE(nullptr, radioRsp_voice.get());
 
-    count_ = 0;
-
     radioInd_voice = ndk::SharedRefBase::make<RadioVoiceIndication>(*this);
     ASSERT_NE(nullptr, radioInd_voice.get());
 
@@ -324,7 +322,6 @@
  * Test IRadioVoice.getTtyMode() for the response returned.
  */
 TEST_P(RadioVoiceTest, getTtyMode) {
-    LOG(DEBUG) << "getTtyMode";
     serial = GetRandomSerialNumber();
 
     radio_voice->getTtyMode(serial);
@@ -335,14 +332,12 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
     }
-    LOG(DEBUG) << "getTtyMode finished";
 }
 
 /*
  * Test IRadioVoice.setTtyMode() for the response returned.
  */
 TEST_P(RadioVoiceTest, setTtyMode) {
-    LOG(DEBUG) << "setTtyMode";
     serial = GetRandomSerialNumber();
 
     radio_voice->setTtyMode(serial, TtyMode::OFF);
@@ -353,14 +348,12 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
     }
-    LOG(DEBUG) << "setTtyMode finished";
 }
 
 /*
  * Test IRadioVoice.setPreferredVoicePrivacy() for the response returned.
  */
 TEST_P(RadioVoiceTest, setPreferredVoicePrivacy) {
-    LOG(DEBUG) << "setPreferredVoicePrivacy";
     serial = GetRandomSerialNumber();
 
     radio_voice->setPreferredVoicePrivacy(serial, true);
@@ -372,14 +365,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
-    LOG(DEBUG) << "setPreferredVoicePrivacy finished";
 }
 
 /*
  * Test IRadioVoice.getPreferredVoicePrivacy() for the response returned.
  */
 TEST_P(RadioVoiceTest, getPreferredVoicePrivacy) {
-    LOG(DEBUG) << "getPreferredVoicePrivacy";
     serial = GetRandomSerialNumber();
 
     radio_voice->getPreferredVoicePrivacy(serial);
@@ -391,14 +382,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
     }
-    LOG(DEBUG) << "getPreferredVoicePrivacy finished";
 }
 
 /*
  * Test IRadioVoice.exitEmergencyCallbackMode() for the response returned.
  */
 TEST_P(RadioVoiceTest, exitEmergencyCallbackMode) {
-    LOG(DEBUG) << "exitEmergencyCallbackMode";
     serial = GetRandomSerialNumber();
 
     radio_voice->exitEmergencyCallbackMode(serial);
@@ -411,14 +400,12 @@
                 radioRsp_voice->rspInfo.error,
                 {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
     }
-    LOG(DEBUG) << "exitEmergencyCallbackMode finished";
 }
 
 /*
  * Test IRadioVoice.handleStkCallSetupRequestFromSim() for the response returned.
  */
 TEST_P(RadioVoiceTest, handleStkCallSetupRequestFromSim) {
-    LOG(DEBUG) << "handleStkCallSetupRequestFromSim";
     serial = GetRandomSerialNumber();
     bool accept = false;
 
@@ -434,14 +421,12 @@
                                       RadioError::MODEM_ERR, RadioError::SIM_ABSENT},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "handleStkCallSetupRequestFromSim finished";
 }
 
 /*
  * Test IRadioVoice.dial() for the response returned.
  */
 TEST_P(RadioVoiceTest, dial) {
-    LOG(DEBUG) << "dial";
     serial = GetRandomSerialNumber();
 
     Dial dialInfo;
@@ -463,14 +448,12 @@
                  RadioError::OPERATION_NOT_ALLOWED},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "dial finished";
 }
 
 /*
  * Test IRadioVoice.hangup() for the response returned.
  */
 TEST_P(RadioVoiceTest, hangup) {
-    LOG(DEBUG) << "hangup";
     serial = GetRandomSerialNumber();
 
     radio_voice->hangup(serial, 1);
@@ -484,14 +467,12 @@
                 {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "hangup finished";
 }
 
 /*
  * Test IRadioVoice.hangupWaitingOrBackground() for the response returned.
  */
 TEST_P(RadioVoiceTest, hangupWaitingOrBackground) {
-    LOG(DEBUG) << "hangupWaitingOrBackground";
     serial = GetRandomSerialNumber();
 
     radio_voice->hangupWaitingOrBackground(serial);
@@ -504,14 +485,12 @@
                                      {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "hangupWaitingOrBackground finished";
 }
 
 /*
  * Test IRadioVoice.hangupForegroundResumeBackground() for the response returned.
  */
 TEST_P(RadioVoiceTest, hangupForegroundResumeBackground) {
-    LOG(DEBUG) << "hangupForegroundResumeBackground";
     serial = GetRandomSerialNumber();
 
     radio_voice->hangupForegroundResumeBackground(serial);
@@ -524,14 +503,12 @@
                                      {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "hangupForegroundResumeBackground finished";
 }
 
 /*
  * Test IRadioVoice.switchWaitingOrHoldingAndActive() for the response returned.
  */
 TEST_P(RadioVoiceTest, switchWaitingOrHoldingAndActive) {
-    LOG(DEBUG) << "switchWaitingOrHoldingAndActive";
     serial = GetRandomSerialNumber();
 
     radio_voice->switchWaitingOrHoldingAndActive(serial);
@@ -544,14 +521,12 @@
                                      {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "switchWaitingOrHoldingAndActive finished";
 }
 
 /*
  * Test IRadioVoice.conference() for the response returned.
  */
 TEST_P(RadioVoiceTest, conference) {
-    LOG(DEBUG) << "conference";
     serial = GetRandomSerialNumber();
 
     radio_voice->conference(serial);
@@ -564,14 +539,12 @@
                                      {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "conference finished";
 }
 
 /*
  * Test IRadioVoice.rejectCall() for the response returned.
  */
 TEST_P(RadioVoiceTest, rejectCall) {
-    LOG(DEBUG) << "rejectCall";
     serial = GetRandomSerialNumber();
 
     radio_voice->rejectCall(serial);
@@ -584,14 +557,12 @@
                                      {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "rejectCall finished";
 }
 
 /*
  * Test IRadioVoice.getLastCallFailCause() for the response returned.
  */
 TEST_P(RadioVoiceTest, getLastCallFailCause) {
-    LOG(DEBUG) << "getLastCallFailCause";
     serial = GetRandomSerialNumber();
 
     radio_voice->getLastCallFailCause(serial);
@@ -603,14 +574,12 @@
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error, {RadioError::NONE},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "getLastCallFailCause finished";
 }
 
 /*
  * Test IRadioVoice.getCallForwardStatus() for the response returned.
  */
 TEST_P(RadioVoiceTest, getCallForwardStatus) {
-    LOG(DEBUG) << "getCallForwardStatus";
     serial = GetRandomSerialNumber();
     CallForwardInfo callInfo;
     memset(&callInfo, 0, sizeof(callInfo));
@@ -627,14 +596,12 @@
                 {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "getCallForwardStatus finished";
 }
 
 /*
  * Test IRadioVoice.setCallForward() for the response returned.
  */
 TEST_P(RadioVoiceTest, setCallForward) {
-    LOG(DEBUG) << "setCallForward";
     serial = GetRandomSerialNumber();
     CallForwardInfo callInfo;
     memset(&callInfo, 0, sizeof(callInfo));
@@ -651,14 +618,12 @@
                 {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setCallForward finished";
 }
 
 /*
  * Test IRadioVoice.getCallWaiting() for the response returned.
  */
 TEST_P(RadioVoiceTest, getCallWaiting) {
-    LOG(DEBUG) << "getCallWaiting";
     serial = GetRandomSerialNumber();
 
     radio_voice->getCallWaiting(serial, 1);
@@ -672,14 +637,12 @@
                 {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "getCallWaiting finished";
 }
 
 /*
  * Test IRadioVoice.setCallWaiting() for the response returned.
  */
 TEST_P(RadioVoiceTest, setCallWaiting) {
-    LOG(DEBUG) << "setCallWaiting";
     serial = GetRandomSerialNumber();
 
     radio_voice->setCallWaiting(serial, true, 1);
@@ -693,14 +656,12 @@
                 {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setCallWaiting finished";
 }
 
 /*
  * Test IRadioVoice.acceptCall() for the response returned.
  */
 TEST_P(RadioVoiceTest, acceptCall) {
-    LOG(DEBUG) << "acceptCall";
     serial = GetRandomSerialNumber();
 
     radio_voice->acceptCall(serial);
@@ -713,14 +674,12 @@
                                      {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "acceptCall finished";
 }
 
 /*
  * Test IRadioVoice.separateConnection() for the response returned.
  */
 TEST_P(RadioVoiceTest, separateConnection) {
-    LOG(DEBUG) << "separateConnection";
     serial = GetRandomSerialNumber();
 
     radio_voice->separateConnection(serial, 1);
@@ -734,14 +693,12 @@
                 {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "separateConnection finished";
 }
 
 /*
  * Test IRadioVoice.explicitCallTransfer() for the response returned.
  */
 TEST_P(RadioVoiceTest, explicitCallTransfer) {
-    LOG(DEBUG) << "explicitCallTransfer";
     serial = GetRandomSerialNumber();
 
     radio_voice->explicitCallTransfer(serial);
@@ -754,14 +711,12 @@
                                      {RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "explicitCallTransfer finished";
 }
 
 /*
  * Test IRadioVoice.sendCdmaFeatureCode() for the response returned.
  */
 TEST_P(RadioVoiceTest, sendCdmaFeatureCode) {
-    LOG(DEBUG) << "sendCdmaFeatureCode";
     serial = GetRandomSerialNumber();
 
     radio_voice->sendCdmaFeatureCode(serial, std::string());
@@ -776,14 +731,12 @@
                                       RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendCdmaFeatureCode finished";
 }
 
 /*
  * Test IRadioVoice.sendDtmf() for the response returned.
  */
 TEST_P(RadioVoiceTest, sendDtmf) {
-    LOG(DEBUG) << "sendDtmf";
     serial = GetRandomSerialNumber();
 
     radio_voice->sendDtmf(serial, "1");
@@ -798,14 +751,12 @@
                  RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendDtmf finished";
 }
 
 /*
  * Test IRadioVoice.startDtmf() for the response returned.
  */
 TEST_P(RadioVoiceTest, startDtmf) {
-    LOG(DEBUG) << "startDtmf";
     serial = GetRandomSerialNumber();
 
     radio_voice->startDtmf(serial, "1");
@@ -820,14 +771,12 @@
                  RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "startDtmf finished";
 }
 
 /*
  * Test IRadioVoice.stopDtmf() for the response returned.
  */
 TEST_P(RadioVoiceTest, stopDtmf) {
-    LOG(DEBUG) << "stopDtmf";
     serial = GetRandomSerialNumber();
 
     radio_voice->stopDtmf(serial);
@@ -841,14 +790,12 @@
                                       RadioError::INVALID_MODEM_STATE, RadioError::MODEM_ERR},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "stopDtmf finished";
 }
 
 /*
  * Test IRadioVoice.setMute() for the response returned.
  */
 TEST_P(RadioVoiceTest, setMute) {
-    LOG(DEBUG) << "setMute";
     serial = GetRandomSerialNumber();
 
     radio_voice->setMute(serial, true);
@@ -861,14 +808,12 @@
                                      {RadioError::NONE, RadioError::INVALID_ARGUMENTS},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "setMute finished";
 }
 
 /*
  * Test IRadioVoice.getMute() for the response returned.
  */
 TEST_P(RadioVoiceTest, getMute) {
-    LOG(DEBUG) << "getMute";
     serial = GetRandomSerialNumber();
 
     radio_voice->getMute(serial);
@@ -879,14 +824,12 @@
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
     }
-    LOG(DEBUG) << "getMute finished";
 }
 
 /*
  * Test IRadioVoice.sendBurstDtmf() for the response returned.
  */
 TEST_P(RadioVoiceTest, sendBurstDtmf) {
-    LOG(DEBUG) << "sendBurstDtmf";
     serial = GetRandomSerialNumber();
 
     radio_voice->sendBurstDtmf(serial, "1", 0, 0);
@@ -900,14 +843,12 @@
                                       RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
                                      CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendBurstDtmf finished";
 }
 
 /*
  * Test IRadioVoice.sendUssd() for the response returned.
  */
 TEST_P(RadioVoiceTest, sendUssd) {
-    LOG(DEBUG) << "sendUssd";
     serial = GetRandomSerialNumber();
     radio_voice->sendUssd(serial, std::string("test"));
     EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -920,14 +861,12 @@
                 {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendUssd finished";
 }
 
 /*
  * Test IRadioVoice.cancelPendingUssd() for the response returned.
  */
 TEST_P(RadioVoiceTest, cancelPendingUssd) {
-    LOG(DEBUG) << "cancelPendingUssd";
     serial = GetRandomSerialNumber();
 
     radio_voice->cancelPendingUssd(serial);
@@ -941,14 +880,12 @@
                 {RadioError::NONE, RadioError::INVALID_STATE, RadioError::MODEM_ERR},
                 CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "cancelPendingUssd finished";
 }
 
 /*
  * Test IRadioVoice.isVoNrEnabled() for the response returned.
  */
 TEST_P(RadioVoiceTest, isVoNrEnabled) {
-    LOG(DEBUG) << "isVoNrEnabled";
     serial = GetRandomSerialNumber();
 
     radio_voice->isVoNrEnabled(serial);
@@ -958,14 +895,12 @@
 
     ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
                                  {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
-    LOG(DEBUG) << "isVoNrEnabled finished";
 }
 
 /*
  * Test IRadioVoice.setVoNrEnabled() for the response returned.
  */
 TEST_P(RadioVoiceTest, setVoNrEnabled) {
-    LOG(DEBUG) << "setVoNrEnabled";
     serial = GetRandomSerialNumber();
 
     radio_voice->setVoNrEnabled(serial, true);
@@ -975,5 +910,4 @@
 
     ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
                                  {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
-    LOG(DEBUG) << "setVoNrEnabled finished";
 }
diff --git a/radio/aidl/vts/radio_voice_utils.h b/radio/aidl/vts/radio_voice_utils.h
index 0c3df7f..dda6c65 100644
--- a/radio/aidl/vts/radio_voice_utils.h
+++ b/radio/aidl/vts/radio_voice_utils.h
@@ -183,7 +183,7 @@
 };
 
 // The main test class for Radio AIDL Voice.
-class RadioVoiceTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+class RadioVoiceTest : public RadioServiceTest {
   protected:
     /* Clear Potential Established Calls */
     virtual ndk::ScopedAStatus clearPotentialEstablishedCalls();
@@ -192,7 +192,7 @@
     std::shared_ptr<RadioNetworkIndication> radioInd_network;
 
   public:
-    virtual void SetUp() override;
+    void SetUp() override;
 
     /* radio voice service handle */
     std::shared_ptr<IRadioVoice> radio_voice;
diff --git a/rebootescrow/aidl/Android.bp b/rebootescrow/aidl/Android.bp
index c764f86..39aaa07 100644
--- a/rebootescrow/aidl/Android.bp
+++ b/rebootescrow/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/scripts/anapic_hidl2aidl_review.sh b/scripts/anapic_hidl2aidl_review.sh
new file mode 100755
index 0000000..ce72160
--- /dev/null
+++ b/scripts/anapic_hidl2aidl_review.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# Create two CLs for the given HIDL interface to see the diff between the
+# hidl2aidl output and the source at the tip-of-tree.
+# The first CL contains the hidl2aidl output after removing all existing AIDL
+# files.
+# The second CL contains all of the changes on top of the raw hidl2aidl output
+# that can be used for review.
+
+if [[ $# -ne 1 ]]; then
+    echo "Usage: $0 INTERFACE_NAME"
+    echo "- INTERFACE_NAME fully qualified HIDL interface name with version"
+    echo "example of creating the diffs for android.hardware.boot@1.2"
+    echo "$ ./anapic_hidl2aidl_review.sh android.hardware.boot@1.2"
+    exit 1
+fi
+
+# for pathmod
+source ${ANDROID_BUILD_TOP}/build/make/envsetup.sh
+
+set -ex
+type hidl2aidl 2>/dev/null || m hidl2aidl
+
+INTERFACE_NAME_NO_VER=${1%@*}
+pushd $(pathmod $INTERFACE_NAME_NO_VER)
+rm -rf android
+hidl2aidl -o . "$1"
+rm -rf conversion.log translate include
+git add -A
+git commit -am "convert $1" --no-edit
+git revert HEAD --no-edit
+git commit --amend --no-edit
+git diff HEAD~1 --stat
+repo upload . --no-verify --wip --hashtag=anapic_release_review
+popd
diff --git a/scripts/anapic_release_diff.sh b/scripts/anapic_release_diff.sh
new file mode 100755
index 0000000..c22d9e5
--- /dev/null
+++ b/scripts/anapic_release_diff.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# Create a CL that contains the changes between this branch and a newer branch
+# for a given AIDL interface.
+# Be sure that BRANCH_BASE is the current upstream branch in order to get a CL.
+
+if [[ $# -ne 3 ]]; then
+    echo "Usage: $0 BRANCH_BASE BRANCH_NEW PACKAGE_NAME"
+    echo "- BRANCH_BASE current branch, typically a previous release's dev branch"
+    echo "- BRANCH_NEW end branch, typically goog/master as the latest branch"
+    echo "- PACKAGE_NAME this is the AIDL package name"
+    echo "example of creating the diffs for android.hardware.boot"
+    echo "$ git checkout tm-dev ; repo start review"
+    echo "$ ./anapic_release_diff.sh goog/tm-dev goog/master android.hardware.boot"
+    exit 1
+fi
+
+# for pathmod
+source ${ANDROID_BUILD_TOP}/build/make/envsetup.sh
+
+set -ex
+
+INTERFACE_NAME_NO_VER=${3%@*}
+pushd $(pathmod $INTERFACE_NAME_NO_VER)
+git diff "$1".."$2" android | git apply
+git add -A
+git commit -am "Android $1 to $2: $3" --no-edit
+git diff HEAD~1 --stat
+repo upload . --no-verify --wip --hashtag=anapic_release_review
+popd
diff --git a/secure_element/1.0/vts/OWNERS b/secure_element/1.0/vts/OWNERS
deleted file mode 100644
index c7963e7..0000000
--- a/secure_element/1.0/vts/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-alisher@google.com
-jackcwyu@google.com
-georgekgchang@google.com
-zachoverflow@google.com
diff --git a/secure_element/1.0/vts/functional/OWNERS b/secure_element/1.0/vts/functional/OWNERS
deleted file mode 100644
index a7ee7e9..0000000
--- a/secure_element/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 456592
-jackcwyu@google.com
diff --git a/secure_element/1.1/vts/OWNERS b/secure_element/1.1/vts/OWNERS
deleted file mode 100644
index c7963e7..0000000
--- a/secure_element/1.1/vts/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-alisher@google.com
-jackcwyu@google.com
-georgekgchang@google.com
-zachoverflow@google.com
diff --git a/secure_element/1.1/vts/functional/OWNERS b/secure_element/1.1/vts/functional/OWNERS
deleted file mode 100644
index a7ee7e9..0000000
--- a/secure_element/1.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 456592
-jackcwyu@google.com
diff --git a/secure_element/1.2/vts/OWNERS b/secure_element/1.2/vts/OWNERS
deleted file mode 100644
index c7963e7..0000000
--- a/secure_element/1.2/vts/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-alisher@google.com
-jackcwyu@google.com
-georgekgchang@google.com
-zachoverflow@google.com
diff --git a/secure_element/1.2/vts/functional/OWNERS b/secure_element/1.2/vts/functional/OWNERS
deleted file mode 100644
index a7ee7e9..0000000
--- a/secure_element/1.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 456592
-jackcwyu@google.com
diff --git a/secure_element/OWNERS b/secure_element/OWNERS
new file mode 100644
index 0000000..492696b
--- /dev/null
+++ b/secure_element/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 456592
+alisher@google.com
+jackcwyu@google.com
+georgekgchang@google.com
+henrichataing@google.com
diff --git a/secure_element/aidl/Android.bp b/secure_element/aidl/Android.bp
new file mode 100644
index 0000000..655487d
--- /dev/null
+++ b/secure_element/aidl/Android.bp
@@ -0,0 +1,52 @@
+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"],
+}
+
+aidl_interface {
+    name: "android.hardware.secure_element",
+    vendor_available: true,
+    host_supported: true,
+    srcs: ["android/hardware/secure_element/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "system_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
+
+cc_test {
+    name: "VtsHalSecureElementTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["vts/VtsHalSecureElementTargetTest.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.secure_element-V1-ndk",
+        "libgmock",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/1/.hash b/secure_element/aidl/aidl_api/android.hardware.secure_element/1/.hash
new file mode 100644
index 0000000..d7ad83f
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/1/.hash
@@ -0,0 +1 @@
+3430a4053a6e5f73f2d0c250cab7a8ba654efdae
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/1/android/hardware/secure_element/ISecureElement.aidl b/secure_element/aidl/aidl_api/android.hardware.secure_element/1/android/hardware/secure_element/ISecureElement.aidl
new file mode 100644
index 0000000..fba29ab
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/1/android/hardware/secure_element/ISecureElement.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.secure_element;
+@VintfStability
+interface ISecureElement {
+  void closeChannel(in byte channelNumber);
+  byte[] getAtr();
+  void init(in android.hardware.secure_element.ISecureElementCallback clientCallback);
+  boolean isCardPresent();
+  byte[] openBasicChannel(in byte[] aid, in byte p2);
+  android.hardware.secure_element.LogicalChannelResponse openLogicalChannel(in byte[] aid, in byte p2);
+  void reset();
+  byte[] transmit(in byte[] data);
+  const int FAILED = 1;
+  const int CHANNEL_NOT_AVAILABLE = 2;
+  const int NO_SUCH_ELEMENT_ERROR = 3;
+  const int UNSUPPORTED_OPERATION = 4;
+  const int IOERROR = 5;
+}
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/1/android/hardware/secure_element/ISecureElementCallback.aidl b/secure_element/aidl/aidl_api/android.hardware.secure_element/1/android/hardware/secure_element/ISecureElementCallback.aidl
new file mode 100644
index 0000000..6c2be2a
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/1/android/hardware/secure_element/ISecureElementCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.secure_element;
+@VintfStability
+interface ISecureElementCallback {
+  void onStateChange(in boolean connected, in String debugReason);
+}
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/1/android/hardware/secure_element/LogicalChannelResponse.aidl b/secure_element/aidl/aidl_api/android.hardware.secure_element/1/android/hardware/secure_element/LogicalChannelResponse.aidl
new file mode 100644
index 0000000..f2e7f04
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/1/android/hardware/secure_element/LogicalChannelResponse.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.secure_element;
+@VintfStability
+parcelable LogicalChannelResponse {
+  byte channelNumber;
+  byte[] selectResponse;
+}
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElement.aidl b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElement.aidl
new file mode 100644
index 0000000..fba29ab
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElement.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.secure_element;
+@VintfStability
+interface ISecureElement {
+  void closeChannel(in byte channelNumber);
+  byte[] getAtr();
+  void init(in android.hardware.secure_element.ISecureElementCallback clientCallback);
+  boolean isCardPresent();
+  byte[] openBasicChannel(in byte[] aid, in byte p2);
+  android.hardware.secure_element.LogicalChannelResponse openLogicalChannel(in byte[] aid, in byte p2);
+  void reset();
+  byte[] transmit(in byte[] data);
+  const int FAILED = 1;
+  const int CHANNEL_NOT_AVAILABLE = 2;
+  const int NO_SUCH_ELEMENT_ERROR = 3;
+  const int UNSUPPORTED_OPERATION = 4;
+  const int IOERROR = 5;
+}
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElementCallback.aidl b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElementCallback.aidl
new file mode 100644
index 0000000..6c2be2a
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/ISecureElementCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.secure_element;
+@VintfStability
+interface ISecureElementCallback {
+  void onStateChange(in boolean connected, in String debugReason);
+}
diff --git a/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/LogicalChannelResponse.aidl b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/LogicalChannelResponse.aidl
new file mode 100644
index 0000000..f2e7f04
--- /dev/null
+++ b/secure_element/aidl/aidl_api/android.hardware.secure_element/current/android/hardware/secure_element/LogicalChannelResponse.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.secure_element;
+@VintfStability
+parcelable LogicalChannelResponse {
+  byte channelNumber;
+  byte[] selectResponse;
+}
diff --git a/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl b/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl
new file mode 100644
index 0000000..800494a
--- /dev/null
+++ b/secure_element/aidl/android/hardware/secure_element/ISecureElement.aidl
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.secure_element;
+
+import android.hardware.secure_element.ISecureElementCallback;
+import android.hardware.secure_element.LogicalChannelResponse;
+
+@VintfStability
+interface ISecureElement {
+    const int FAILED = 1;
+    const int CHANNEL_NOT_AVAILABLE = 2;
+    const int NO_SUCH_ELEMENT_ERROR = 3;
+    const int UNSUPPORTED_OPERATION = 4;
+    const int IOERROR = 5;
+
+    /**
+     * Closes the channel indicated by the channelNumber.
+     *
+     * @throws ServiceSpecificException Closing a channel must return
+     *     FAILED on an error or if a basic channel (i.e. channel 0)
+     *     is used.
+     *
+     * @param channelNumber to be closed
+     */
+    void closeChannel(in byte channelNumber);
+
+    /**
+     * Returns Answer to Reset as per ISO/IEC 7816
+     *
+     * @return containing the response. Empty vector if Secure Element
+     *                  doesn't support ATR.
+     */
+    byte[] getAtr();
+
+    /**
+     * Initializes the Secure Element. This may include updating the applet
+     * and/or vendor-specific initialization.
+     *
+     * HAL service must send onStateChange() with connected equal to true
+     * after all the initialization has been successfully completed.
+     * Clients must wait for a onStateChange(true) before opening channels.
+     *
+     * @param clientCallback callback used to sent status of the SE back to the
+     *                       client
+     */
+    void init(in ISecureElementCallback clientCallback);
+
+    /**
+     * Returns the current state of the card.
+     *
+     * This is useful for removable Secure Elements like UICC,
+     * Secure Elements on SD cards etc.
+     *
+     * @return true if present, false otherwise
+     */
+    boolean isCardPresent();
+
+    /**
+     * Opens a basic channel with the Secure Element, selecting the applet
+     * represented by the Application ID (AID). A basic channel has channel
+     * number 0.
+     *
+     * @throws ServiceSpecificException with codes
+     *  - CHANNEL_NOT_AVAILABLE if secure element has reached the maximum
+     *    limit on the number of channels it can support.
+     *  - NO_SUCH_ELEMENT_ERROR if AID provided doesn't match any applet
+     *    on the secure element.
+     *  - UNSUPPORTED_OPERATION if operation provided by the P2 parameter
+     *    is not permitted by the applet.
+     *  - IOERROR if there was an error communicating with the Secure Element.
+     *
+     * @param aid AID to uniquely identify the applet on the Secure Element
+     * @param p2 P2 parameter of SELECT APDU as per ISO 7816-4
+     *
+     * @return On success, response to SELECT command.
+     */
+    byte[] openBasicChannel(in byte[] aid, in byte p2);
+
+    /**
+     * Opens a logical channel with the Secure Element, selecting the applet
+     * represented by the Application ID (AID).
+     *
+     * @param aid AID to uniquely identify the applet on the Secure Element
+     * @param p2 P2 parameter of SELECT APDU as per ISO 7816-4
+     * @throws ServiceSpecificException on error with the following code:
+     *  - CHANNEL_NOT_AVAILABLE if secure element has reached the maximum
+     *    limit on the number of channels it can support.
+     *  - NO_SUCH_ELEMENT_ERROR if AID provided doesn't match any applet
+     *    on the secure element.
+     *  - UNSUPPORTED_OPERATION if operation provided by the P2 parameter
+     *    is not permitted by the applet.
+     *  - IOERROR if there was an error communicating with the Secure Element.
+     *
+     * @return On success, response to SELECT command
+     */
+    LogicalChannelResponse openLogicalChannel(in byte[] aid, in byte p2);
+
+    /**
+     * Reset the Secure Element.
+     *
+     * HAL should trigger reset to the secure element. It could hardware power cycle or
+     * a soft reset depends on the hardware design. All channels opened are
+     * closed by this operation.
+     * HAL service must send onStateChange() with connected equal to true
+     * after resetting and all the re-initialization has been successfully completed.
+     *
+     * @throws ServiceSpecificException on error with the following code:
+     *  - FAILED if the service was unable to reset the secure element.
+     */
+    void reset();
+
+    /**
+     * Transmits an APDU command (as per ISO/IEC 7816) to the SE.
+     *
+     * @throws ServiceSpecificException with code CHANNEL_NOT_AVAILABLE
+     *  if there was an error in communicating with the secure element.
+     *
+     * @param data APDU command to be sent
+     * @return response to the command
+     */
+    byte[] transmit(in byte[] data);
+}
diff --git a/secure_element/aidl/android/hardware/secure_element/ISecureElementCallback.aidl b/secure_element/aidl/android/hardware/secure_element/ISecureElementCallback.aidl
new file mode 100644
index 0000000..d15a7fb
--- /dev/null
+++ b/secure_element/aidl/android/hardware/secure_element/ISecureElementCallback.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.secure_element;
+
+@VintfStability
+interface ISecureElementCallback {
+    /**
+     * Used to inform the client about changes in the state of the Secure
+     * Element.
+     *
+     * @param connected indicates the current state of the SE
+     * @param reason provides additional data why there was a change in state
+     *               ex. initialization error, SE removed etc
+     *               This is used only for debugging purpose to understand
+     *               in-field issues.
+     */
+    void onStateChange(in boolean connected, in String debugReason);
+}
diff --git a/secure_element/aidl/android/hardware/secure_element/LogicalChannelResponse.aidl b/secure_element/aidl/android/hardware/secure_element/LogicalChannelResponse.aidl
new file mode 100644
index 0000000..65ea71e
--- /dev/null
+++ b/secure_element/aidl/android/hardware/secure_element/LogicalChannelResponse.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.secure_element;
+
+@VintfStability
+parcelable LogicalChannelResponse {
+    /**
+     * Channel number to uniquely identify the channel
+     */
+    byte channelNumber;
+    /**
+     * Response to SELECT command as per ISO/IEC 7816
+     */
+    byte[] selectResponse;
+}
diff --git a/secure_element/aidl/default/Android.bp b/secure_element/aidl/default/Android.bp
new file mode 100644
index 0000000..d1bb393
--- /dev/null
+++ b/secure_element/aidl/default/Android.bp
@@ -0,0 +1,24 @@
+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_binary {
+    name: "android.hardware.secure_element-service.example",
+    relative_install_path: "hw",
+    vendor: true,
+    init_rc: ["secure_element.rc"],
+    vintf_fragments: ["secure_element.xml"],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.secure_element-V1-ndk",
+    ],
+    srcs: [
+        "main.cpp",
+    ],
+}
diff --git a/secure_element/aidl/default/main.cpp b/secure_element/aidl/default/main.cpp
new file mode 100644
index 0000000..0822402
--- /dev/null
+++ b/secure_element/aidl/default/main.cpp
@@ -0,0 +1,716 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/secure_element/BnSecureElement.h>
+#include <android-base/hex.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include <algorithm>
+
+using aidl::android::hardware::secure_element::BnSecureElement;
+using aidl::android::hardware::secure_element::ISecureElementCallback;
+using aidl::android::hardware::secure_element::LogicalChannelResponse;
+using android::base::HexString;
+using ndk::ScopedAStatus;
+
+static const std::vector<uint8_t> kIssuerSecurityDomainSelectResponse = {0x00, 0x00, 0x90, 0x00};
+
+namespace se {
+// Application identifier.
+using Aid = std::vector<uint8_t>;
+
+// ISO7816 APDU status codes.
+enum Status : uint16_t {
+    SW_WRONG_DATA = 0x6A80,
+    SW_LOGICAL_CHANNEL_NOT_SUPPORTED = 0x6881,
+    SW_CONDITIONS_NOT_SATISFIED = 0x6985,
+    SW_INCORRECT_P1P2 = 0x6A86,
+    SW_BYTES_REMAINING_00 = 0x6100,
+    SW_WRONG_LENGTH = 0x6700,
+    SW_CORRECT_LENGTH_00 = 0x6C00,
+    SW_INS_NOT_SUPPORTED = 0x6D00,
+    SW_NO_ERROR = 0x9000,
+};
+
+// Type for raw APDUs.
+using RawApdu = std::vector<uint8_t>;
+
+// Wrap a command APDU (Application Processing Data Unit) to provide
+// accessors for header fields.
+struct Apdu {
+  public:
+    // Construct a command Apdu.
+    Apdu(std::vector<uint8_t> packet) : bytes_(std::move(packet)) {
+        CHECK(bytes_.size() >= kHeaderSize) << "command APDU created with invalid length";
+        size_t payload_len = bytes_.size() - kHeaderSize;
+
+        // TODO(b/123254068) - add support for extended command APDUs.
+        // Pre compute Lc and Le.
+
+        // Case 1: CLA | INS | P1 | P2
+        if (payload_len == 0) {
+            lc_ = 0;
+            le_ = 0;
+            return;
+        }
+
+        // Case 2: CLA | INS | P1 | P2 | Le
+        // Le has a value of 1 to 255.
+        if (payload_len == 1) {
+            le_ = bytes_[kHeaderSize];
+            le_ = le_ == 0 ? 256 : le_;
+            lc_ = 0;
+            return;
+        }
+
+        // Case 3: CLA | INS | P1 | P2 | Lc | Data
+        // Lc is less than 256 bytes
+        // of data, and Le is zero.
+        lc_ = bytes_[kHeaderSize];
+        if (payload_len <= (1 + lc_)) {
+            le_ = 0;
+        }
+
+        // Case 4: CLA | INS | P1 | P2 | Lc | Data | Le
+        // The legacy Case 4. Lc and Le
+        // are less than 256 bytes of data.
+        else {
+            le_ = bytes_[bytes_.size() - 1];
+            le_ = le_ == 0 ? 256 : le_;
+        }
+    }
+
+    // Construct a response Apdu with data.
+    static RawApdu CreateResponse(std::vector<uint8_t> data, Status status) {
+        // Append status word.
+        data.push_back(status >> 8);
+        data.push_back(status);
+        return data;
+    }
+
+    // Construct a response Apdu with no data.
+    static RawApdu CreateResponse(Status status) {
+        // Append status word.
+        return std::vector<uint8_t>{static_cast<uint8_t>(status >> 8),
+                                    static_cast<uint8_t>(status)};
+    }
+
+    // Return if command APDU is extended.
+    // The ISO/IEC 7816-4:2013 specification defines an extended APDU as any APDU
+    // whose payload data, response data or expected data length exceeds the 256
+    // byte limit.
+    bool IsExtended() const { return (bytes_.size() - kHeaderSize) > 256; }
+
+    // Return if command APDU has payload bytes.
+    bool HasPayload() const { return bytes_.size() > kHeaderSize; }
+
+    uint8_t get_cla() const { return bytes_[0]; }
+    uint8_t get_ins() const { return bytes_[1]; }
+    uint8_t get_p1() const { return bytes_[2]; }
+    uint8_t get_p2() const { return bytes_[3]; }
+
+    // Return the channel number encoded in the CLA field.
+    uint8_t get_channel_number() const {
+        // Type 4 commands — Encode legacy ISO/IEC 7816-4 logical channel
+        // information. Type 16 commands — Defined by the ISO/IEC 7816-4:2013
+        // specification to
+        //   encode information for additional 16 logical channels in the card.
+        uint8_t cla = get_cla();
+        return (cla & 0x40) == 0 ? cla & 0x3 : 4 + (cla & 0xf);
+    }
+
+    // Return the length of the command data field.
+    uint16_t get_lc() const { return lc_; }
+
+    // Return the expected length of the response data field.
+    // Le should be have the same format as Lc.
+    uint16_t get_le() const { return le_; }
+
+    // Get the pointer to the APDU raw data.
+    std::vector<uint8_t> const& get_data() const { return bytes_; }
+
+  private:
+    // Size of command header, including CLA, INS, P1, P2 fields.
+    const size_t kHeaderSize = 4;
+
+    // Command or response buffer.
+    std::vector<uint8_t> bytes_{};
+
+    // Lengths of command data field and expected response data field.
+    uint16_t lc_{0};
+    uint16_t le_{0};
+};
+
+// Type of SE applets.
+class Applet {
+  public:
+    virtual ~Applet() {}
+
+    // Called to inform this applet that it has been selected.
+    virtual RawApdu Select(Aid const& aid, uint8_t p2) = 0;
+
+    // Called by the Java Card runtime environment to process an
+    // incoming APDU command. SELECT commands are processed by \ref select
+    // instead.
+    virtual RawApdu Process(Apdu const& apdu) = 0;
+};
+};  // namespace se
+
+// Implement the Google-eSE-test.cap test applet for passing OMAPI CTS tests
+// on Cuttlefish. The reference can be found here:
+// cts/tests/tests/secure_element/sample_applet/src/com/android/cts/omapi/test/CtsAndroidOmapiTestApplet.java
+class CtsAndroidOmapiTestApplet : public se::Applet {
+  public:
+    CtsAndroidOmapiTestApplet() {}
+    virtual ~CtsAndroidOmapiTestApplet() {}
+
+    se::RawApdu Select(se::Aid const& aid, uint8_t /*p2*/) override {
+        if (aid[aid.size() - 1] == 0x31) {
+            // AID: A000000476416E64726F696443545331
+            return se::Apdu::CreateResponse(se::Status::SW_NO_ERROR);
+        } else {
+            // AID: A000000476416E64726F696443545332
+            return se::Apdu::CreateResponse(GenerateBerTLVBytes(SELECT_RESPONSE_DATA_LENGTH),
+                                            se::Status::SW_NO_ERROR);
+        }
+    }
+
+    se::RawApdu ReadNextResponseChunk(uint16_t max_output_len) {
+        uint16_t output_len = static_cast<uint16_t>(response_.size() - response_offset_);
+        output_len = std::min<uint16_t>(max_output_len, output_len);
+        std::vector<uint8_t> output{
+                &response_[response_offset_],
+                &response_[response_offset_ + output_len],
+        };
+        response_offset_ += output_len;
+        uint16_t remaining_len = response_.size() - response_offset_;
+        se::Status status = se::Status::SW_NO_ERROR;
+        if (remaining_len > 0) {
+            if (remaining_len > 256) {
+                remaining_len = 0x00;
+            }
+            status = se::Status(se::Status::SW_BYTES_REMAINING_00 | remaining_len);
+        } else {
+            response_.clear();
+            response_offset_ = 0;
+        }
+        return se::Apdu::CreateResponse(output, status);
+    }
+
+    se::RawApdu Process(se::Apdu const& apdu) override {
+        uint16_t lc;
+        uint16_t le = apdu.get_le();
+        uint8_t p1 = apdu.get_p1();
+        uint8_t p2 = apdu.get_p2();
+
+        switch (apdu.get_ins()) {
+            case NO_DATA_INS_1:
+            case NO_DATA_INS_2:
+                LOG(INFO) << __func__ << ": NO_DATA_INS_1|2";
+                return se::Apdu::CreateResponse(se::Status::SW_NO_ERROR);
+
+            case DATA_INS_1:
+            case DATA_INS_2:
+                // Return 256 bytes of data.
+                LOG(INFO) << __func__ << ": DATA_INS_1|2";
+                return se::Apdu::CreateResponse(GeneratesBytes(256), se::Status::SW_NO_ERROR);
+
+            case GET_RESPONSE_INS:
+                // ISO GET_RESPONSE command.
+                LOG(INFO) << __func__ << ": GET_RESPONSE_INS";
+                if (response_.empty()) {
+                    return se::Apdu::CreateResponse(se::Status::SW_CONDITIONS_NOT_SATISFIED);
+                }
+                return ReadNextResponseChunk(apdu.get_le());
+
+            case SW_62xx_APDU_INS:
+                LOG(INFO) << __func__ << ": SW_62xx_APDU_INS";
+                if (p1 < 1 || p1 > 16) {
+                    return se::Apdu::CreateResponse(se::Status::SW_INCORRECT_P1P2);
+                }
+                if (p2 == SW_62xx_DATA_APDU_P2) {
+                    return se::Apdu::CreateResponse(GeneratesBytes(3),
+                                                    se::Status(SW_62xx_resp[p1 - 1]));
+                }
+                if (p2 == SW_62xx_VALIDATE_DATA_P2) {
+                    std::vector<uint8_t> output{SW_62xx_VALIDATE_DATA_RESP.begin(),
+                                                SW_62xx_VALIDATE_DATA_RESP.end()};
+                    output[2] = p1;
+                    return se::Apdu::CreateResponse(std::move(output),
+                                                    se::Status(SW_62xx_resp[p1 - 1]));
+                }
+                return se::Apdu::CreateResponse(se::Status(SW_62xx_resp[p1 - 1]));
+
+            case SEGMENTED_RESP_INS_1:
+            case SEGMENTED_RESP_INS_2:
+                LOG(INFO) << __func__ << ": SEGMENTED_RESP_INS_1|2";
+                response_ = GeneratesBytes((static_cast<uint16_t>(p1) << 8) | p2);
+                response_offset_ = 0;
+                return ReadNextResponseChunk(std::min<uint16_t>(apdu.get_le(), 256));
+
+            case SEGMENTED_RESP_INS_3:
+            case SEGMENTED_RESP_INS_4:
+                LOG(INFO) << __func__ << ": SEGMENTED_RESP_INS_3|4";
+                response_ = GeneratesBytes((static_cast<uint16_t>(p1) << 8) | p2);
+                response_offset_ = 0;
+                return ReadNextResponseChunk(apdu.get_le());
+
+            case SEGMENTED_RESP_INS_5:
+                LOG(INFO) << __func__ << ": SEGMENTED_RESP_INS_5";
+                if (le == 0xff) {
+                    return se::Apdu::CreateResponse(
+                            se::Status(se::Status::SW_CORRECT_LENGTH_00 | 0xff));
+                }
+                response_ = GeneratesBytes((static_cast<uint16_t>(p1) << 8) | p2);
+                response_offset_ = 0;
+                return ReadNextResponseChunk(apdu.get_le());
+
+            case CHECK_SELECT_P2_APDU:
+                LOG(INFO) << __func__ << ": CHECK_SELECT_P2_APDU";
+                return se::Apdu::CreateResponse(std::vector<uint8_t>{apdu.get_p2()},
+                                                se::Status::SW_NO_ERROR);
+
+            default:
+                // Case is not known.
+                LOG(INFO) << __func__ << ": UNKNOWN_INS";
+                return se::Apdu::CreateResponse(se::Status::SW_INS_NOT_SUPPORTED);
+        }
+    }
+
+  private:
+    std::vector<uint8_t> response_{};
+    uint16_t response_offset_{0};
+
+    static const uint8_t NO_DATA_INS_1 = 0x06;
+    static const uint8_t NO_DATA_INS_2 = 0x0A;
+    static const uint8_t DATA_INS_1 = 0x08;
+    static const uint8_t DATA_INS_2 = 0x0C;
+    static const uint8_t SW_62xx_APDU_INS = 0xF3;
+    static const uint8_t SW_62xx_DATA_APDU_P2 = 0x08;
+    static const uint8_t SW_62xx_VALIDATE_DATA_P2 = 0x0C;
+
+    static constexpr std::array<uint8_t, 7> SW_62xx_VALIDATE_DATA_RESP = {0x01, 0xF3, 0x00, 0x0C,
+                                                                          0x01, 0xAA, 0x00};
+    static constexpr uint16_t SW_62xx_resp[] = {
+            0x6200, 0x6281, 0x6282, 0x6283, 0x6285, 0x62F1, 0x62F2, 0x63F1,
+            0x63F2, 0x63C2, 0x6202, 0x6280, 0x6284, 0x6286, 0x6300, 0x6381,
+    };
+
+    static const uint8_t SEGMENTED_RESP_INS_1 = 0xC2;
+    static const uint8_t SEGMENTED_RESP_INS_2 = 0xC4;
+    static const uint8_t SEGMENTED_RESP_INS_3 = 0xC6;
+    static const uint8_t SEGMENTED_RESP_INS_4 = 0xC8;
+    static const uint8_t SEGMENTED_RESP_INS_5 = 0xCF;
+    static const uint8_t CHECK_SELECT_P2_APDU = 0xF4;
+    static const uint8_t GET_RESPONSE_INS = 0xC0;
+    static const uint8_t BER_TLV_TYPE = 0x1F;
+    static const uint16_t SELECT_RESPONSE_DATA_LENGTH = 252;
+
+    static const uint16_t LENGTH_256 = 0x0100;
+    static constexpr std::array<uint8_t, 256> resp_bytes256{
+            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+            0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
+            0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
+            0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+            0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
+            0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+            0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61,
+            0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+            0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D,
+            0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B,
+            0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
+            0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+            0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
+            0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3,
+            0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1,
+            0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+            0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED,
+            0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB,
+            0xFC, 0xFD, 0xFE, 0xFF};
+
+    // Generate a response buffer of the selected length containing valid
+    // BER TLV bytes.
+    static std::vector<uint8_t> GenerateBerTLVBytes(uint16_t le) {
+        // Support length from 0x00 - 0x7FFF.
+        uint16_t le_len = 1;
+        if (le < (uint16_t)0x80) {
+            le_len = 1;
+        } else if (le < (uint16_t)0x100) {
+            le_len = 2;
+        } else {
+            le_len = 3;
+        }
+
+        uint16_t total_len = (uint16_t)(le + 2 + le_len);
+        std::vector<uint8_t> output(total_len);
+        uint16_t i = 0;
+
+        output[i++] = BER_TLV_TYPE;
+        output[i++] = 0x00;  // second byte of Type
+        if (le < 0x80) {
+            output[i++] = le;
+        } else if (le < 0x100) {
+            output[i++] = 0x81;
+            output[i++] = le;
+        } else {
+            output[i++] = 0x82;
+            output[i++] = (le >> 8);
+            output[i++] = (le & 0xFF);
+        }
+        while (i < total_len) {
+            output[i++] = ((i - 2 - le_len) & 0xFF);
+        }
+
+        // Set the last byte to 0xFF for CTS validation.
+        output[total_len - 1] = 0xFF;
+        return output;
+    }
+
+    // Generate a response buffer of the selected length using the
+    // array resp_bytes256 as input.
+    static std::vector<uint8_t> GeneratesBytes(uint16_t total_len) {
+        std::vector<uint8_t> output(total_len);
+        uint16_t i = 0;
+
+        while (i < total_len) {
+            if ((total_len - i) >= resp_bytes256.size()) {
+                std::memcpy(&output[i], resp_bytes256.data(), resp_bytes256.size());
+                i += resp_bytes256.size();
+            } else {
+                output[i] = i & 0xFF;
+                i += 1;
+            }
+        }
+
+        // Set the last byte to 0xFF for CTS validation.
+        output[total_len - 1] = 0xFF;
+        return output;
+    }
+};
+
+class EmulatedSecureElement : public BnSecureElement {
+  public:
+    EmulatedSecureElement() {
+        std::shared_ptr<CtsAndroidOmapiTestApplet> test_applet =
+                std::make_shared<CtsAndroidOmapiTestApplet>();
+
+        applets_.push_back(std::pair{se::Aid{0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, 0x72,
+                                             0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x31},
+                                     test_applet});
+
+        applets_.push_back(std::pair{se::Aid{0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, 0x72,
+                                             0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x32},
+                                     test_applet});
+    }
+
+    ScopedAStatus init(const std::shared_ptr<ISecureElementCallback>& client_callback) override {
+        LOG(INFO) << __func__ << " callback: " << client_callback.get();
+        if (client_callback == nullptr) {
+            return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+        }
+        for (auto& channel : channels_) {
+            channel = Channel();
+        }
+        client_callback_ = client_callback;
+        client_callback_->onStateChange(true, "init");
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus getAtr(std::vector<uint8_t>* aidl_return) override {
+        LOG(INFO) << __func__;
+        if (client_callback_ == nullptr) {
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+        *aidl_return = atr_;
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus reset() override {
+        LOG(INFO) << __func__;
+        if (client_callback_ == nullptr) {
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+        client_callback_->onStateChange(false, "reset");
+        client_callback_->onStateChange(true, "reset");
+        // All channels are closed after reset.
+        for (auto& channel : channels_) {
+            channel = Channel();
+        }
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus isCardPresent(bool* aidl_return) override {
+        LOG(INFO) << __func__;
+        if (client_callback_ == nullptr) {
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+        *aidl_return = true;
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus openBasicChannel(const std::vector<uint8_t>& aid, int8_t p2,
+                                   std::vector<uint8_t>* aidl_return) override {
+        LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
+                  << ") p2 " << p2;
+        if (client_callback_ == nullptr) {
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+
+        std::vector<uint8_t> select_response;
+        std::shared_ptr<se::Applet> applet = nullptr;
+
+        // The basic channel can only be opened once, and stays opened
+        // and locked until the channel is closed.
+        if (channels_[0].opened) {
+            LOG(INFO) << __func__ << " basic channel already opened";
+            return ScopedAStatus::fromServiceSpecificError(CHANNEL_NOT_AVAILABLE);
+        }
+
+        // If the AID is defined (the AID is not Null and the length of the
+        // AID is not 0) and the channel is not locked then the corresponding
+        // applet shall be selected.
+        if (aid.size() > 0) {
+            applet = SelectApplet(aid);
+            if (applet == nullptr) {
+                // No applet registered with matching AID.
+                LOG(INFO) << __func__ << " basic channel AID not found";
+                return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
+            }
+            select_response = applet->Select(aid, p2);
+        }
+
+        // If the AID is a 0 length AID and the channel is not locked, the
+        // method will select the Issuer Security Domain of the SE by sending a
+        // SELECT command with a 0 length AID as defined in
+        // [GP Card specification].
+        if (aid.size() == 0) {
+            select_response = kIssuerSecurityDomainSelectResponse;
+        }
+
+        LOG(INFO) << __func__ << " sending response: "
+                  << HexString(select_response.data(), select_response.size());
+
+        // TODO(b/123254068) - this is not an implementation of the OMAPI protocol
+        // or APDU. The functionality here is enough to exercise the framework,
+        // but actual calls to the secure element will fail. This implementation
+        // does not model channel isolation or any other aspects important to
+        // implementing secure element.
+        channels_[0] = Channel(aid, p2, applet);
+        *aidl_return = select_response;
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus openLogicalChannel(
+            const std::vector<uint8_t>& aid, int8_t p2,
+            ::aidl::android::hardware::secure_element::LogicalChannelResponse* aidl_return)
+            override {
+        LOG(INFO) << __func__ << " aid: " << HexString(aid.data(), aid.size()) << " (" << aid.size()
+                  << ") p2 " << p2;
+
+        if (client_callback_ == nullptr) {
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+
+        size_t channel_number = 1;
+        std::vector<uint8_t> select_response;
+        std::shared_ptr<se::Applet> applet = nullptr;
+
+        // Look for an available channel number.
+        for (; channel_number < channels_.size(); channel_number++) {
+            if (channels_[channel_number].opened == false) {
+                break;
+            }
+        }
+
+        // All channels are currently allocated.
+        if (channel_number >= channels_.size()) {
+            LOG(INFO) << __func__ << " all logical channels already opened";
+            return ScopedAStatus::fromServiceSpecificError(CHANNEL_NOT_AVAILABLE);
+        }
+
+        // If the AID is defined (the AID is not Null and the length of the
+        // AID is not 0) then the corresponding applet shall be selected.
+        if (aid.size() > 0) {
+            applet = SelectApplet(aid);
+            if (applet == nullptr) {
+                // No applet registered with matching AID.
+                LOG(INFO) << __func__ << " logical channel AID not found";
+                return ScopedAStatus::fromServiceSpecificError(NO_SUCH_ELEMENT_ERROR);
+            }
+            select_response = applet->Select(aid, p2);
+        }
+
+        // If the length of the AID is 0, the method will select the
+        // Issuer Security Domain of the SE by sending a SELECT command
+        // with 0 length AID as defined in [GPCS].
+        if (aid.size() == 0) {
+            select_response = kIssuerSecurityDomainSelectResponse;
+        }
+
+        LOG(INFO) << __func__ << " sending response: "
+                  << HexString(select_response.data(), select_response.size());
+
+        // TODO(b/123254068) - this is not an implementation of the OMAPI protocol
+        // or APDU. The functionality here is enough to exercise the framework,
+        // but actual calls to the secure element will fail. This implementation
+        // does not model channel isolation or any other aspects important to
+        // implementing secure element.
+        channels_[channel_number] = Channel(aid, p2, applet);
+        *aidl_return = LogicalChannelResponse{
+                .channelNumber = static_cast<int8_t>(channel_number),
+                .selectResponse = select_response,
+        };
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus closeChannel(int8_t channel_number) override {
+        LOG(INFO) << __func__ << " channel number: " << static_cast<int>(channel_number);
+        if (client_callback_ == nullptr) {
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+
+        // The selected basic or logical channel is not opened.
+        if (channel_number >= channels_.size() || !channels_[channel_number].opened) {
+            return ScopedAStatus::fromServiceSpecificError(FAILED);
+        }
+
+        // TODO(b/123254068) - this is not an implementation of the OMAPI protocol
+        // or APDU. The functionality here is enough to exercise the framework,
+        // but actual calls to the secure element will fail. This implementation
+        // does not model channel isolation or any other aspects important to
+        // implementing secure element.
+        channels_[channel_number].opened = false;
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus transmit(const std::vector<uint8_t>& data,
+                           std::vector<uint8_t>* aidl_return) override {
+        LOG(INFO) << __func__ << " data: " << HexString(data.data(), data.size()) << " ("
+                  << data.size() << ")";
+        if (client_callback_ == nullptr) {
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+
+        se::Apdu apdu(data);
+        uint8_t channel_number = apdu.get_channel_number();
+        std::vector<uint8_t> response_apdu;
+
+        switch (apdu.get_ins()) {
+            // TODO(b/123254068) - Implement support channel management APDUs.
+            case MANAGE_CHANNEL_INS:
+                // P1 = '00' to open
+                // P1 = '80' to close
+                LOG(INFO) << __func__ << " MANAGE_CHANNEL apdu";
+                response_apdu =
+                        se::Apdu::CreateResponse(se::Status::SW_LOGICAL_CHANNEL_NOT_SUPPORTED);
+                break;
+
+            // TODO(b/123254068) - Implement support channel management APDUs.
+            case SELECT_INS:
+                LOG(INFO) << __func__ << " SELECT apdu";
+                response_apdu =
+                        se::Apdu::CreateResponse(se::Status::SW_LOGICAL_CHANNEL_NOT_SUPPORTED);
+                break;
+
+            default:
+                CHECK(channel_number < channels_.size()) << " invalid channel number";
+                if (!channels_[channel_number].opened) {
+                    LOG(INFO) << __func__ << " the channel " << static_cast<int>(channel_number)
+                              << " is not opened";
+                    response_apdu =
+                            se::Apdu::CreateResponse(se::Status::SW_LOGICAL_CHANNEL_NOT_SUPPORTED);
+                    break;
+                }
+                // Send the APDU to the applet for processing.
+                // Applet implementation is optional, default to sending
+                // SW_INS_NOT_SUPPORTED.
+                if (channels_[channel_number].applet == nullptr) {
+                    response_apdu = se::Apdu::CreateResponse(se::Status::SW_INS_NOT_SUPPORTED);
+                } else {
+                    response_apdu = channels_[channel_number].applet->Process(apdu);
+                }
+                break;
+        }
+
+        aidl_return->assign(response_apdu.begin(), response_apdu.end());
+        LOG(INFO) << __func__
+                  << " response: " << HexString(aidl_return->data(), aidl_return->size()) << " ("
+                  << aidl_return->size() << ")";
+        return ScopedAStatus::ok();
+    }
+
+  private:
+    struct Channel {
+      public:
+        Channel() = default;
+        Channel(Channel const&) = default;
+        Channel(se::Aid const& aid, uint8_t p2, std::shared_ptr<se::Applet> applet)
+            : opened(true), aid(aid), p2(p2), applet(std::move(applet)) {}
+        Channel& operator=(Channel const&) = default;
+
+        bool opened{false};
+        se::Aid aid{};
+        uint8_t p2{0};
+        std::shared_ptr<se::Applet> applet{nullptr};
+    };
+
+    // OMAPI abstraction.
+
+    // Channel 0 is the basic channel, channels 1-19 are the logical channels.
+    std::array<Channel, 20> channels_{};
+    std::shared_ptr<ISecureElementCallback> client_callback_{nullptr};
+
+    // Secure element abstraction.
+
+    static const uint8_t MANAGE_CHANNEL_INS = 0x70;
+    static const uint8_t SELECT_INS = 0xa4;
+
+    // Secure element ATR (Answer-To-Reset).
+    // The format is specified by ISO/IEC 1816-4 2020 and lists
+    // the capabilities of the card.
+    //
+    // TODO(b/123254068): encode the default SE properties in the ATR:
+    // support for extended Lc / Le fields, maximum number of logical channels.
+    // The CTS tests are *not* checking this value.
+    std::vector<uint8_t> const atr_{};
+
+    // Applet registration.
+    std::vector<std::pair<se::Aid, std::shared_ptr<se::Applet>>> applets_{};
+
+    // Return the first applet that matches the selected aid.
+    std::shared_ptr<se::Applet> SelectApplet(se::Aid const& aid) {
+        for (auto& [applet_aid, applet] : applets_) {
+            if (applet_aid == aid) {
+                return applet;
+            }
+        }
+        return nullptr;
+    }
+};
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+    auto se = ndk::SharedRefBase::make<EmulatedSecureElement>();
+    const std::string name = std::string() + BnSecureElement::descriptor + "/eSE1";
+    binder_status_t status = AServiceManager_addService(se->asBinder().get(), name.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/secure_element/aidl/default/secure_element.rc b/secure_element/aidl/default/secure_element.rc
new file mode 100644
index 0000000..7d21666
--- /dev/null
+++ b/secure_element/aidl/default/secure_element.rc
@@ -0,0 +1,4 @@
+service vendor.secure_element /vendor/bin/hw/android.hardware.secure_element-service.example
+    class hal
+    user nobody
+    group nobody
diff --git a/secure_element/aidl/default/secure_element.xml b/secure_element/aidl/default/secure_element.xml
new file mode 100644
index 0000000..96ab2e7
--- /dev/null
+++ b/secure_element/aidl/default/secure_element.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.secure_element</name>
+        <version>1</version>
+        <fqname>ISecureElement/eSE1</fqname>
+    </hal>
+</manifest>
diff --git a/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp b/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
new file mode 100644
index 0000000..9678da4
--- /dev/null
+++ b/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/secure_element/BnSecureElementCallback.h>
+#include <aidl/android/hardware/secure_element/ISecureElement.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+using namespace std::chrono_literals;
+
+using aidl::android::hardware::secure_element::BnSecureElementCallback;
+using aidl::android::hardware::secure_element::ISecureElement;
+using aidl::android::hardware::secure_element::LogicalChannelResponse;
+using ndk::ScopedAStatus;
+using ndk::SharedRefBase;
+using ndk::SpAIBinder;
+using testing::ElementsAre;
+using testing::ElementsAreArray;
+
+#define EXPECT_OK(status)                                                \
+    do {                                                                 \
+        auto status_impl = (status);                                     \
+        EXPECT_TRUE(status_impl.isOk()) << status_impl.getDescription(); \
+    } while (false)
+
+#define EXPECT_ERR(status)                                                \
+    do {                                                                  \
+        auto status_impl = (status);                                      \
+        EXPECT_FALSE(status_impl.isOk()) << status_impl.getDescription(); \
+    } while (false)
+
+// APDU defined in CTS tests.
+// The applet selected with kSelectableAid will return 256 bytes of data
+// in response.
+static const std::vector<uint8_t> kDataApdu = {
+        0x00, 0x08, 0x00, 0x00, 0x00,
+};
+
+// Selectable test AID defined in CTS tests.
+static const std::vector<uint8_t> kSelectableAid = {
+        0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
+        0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0x31,
+};
+// Non-selectable test AID defined in CTS tests.
+static const std::vector<uint8_t> kNonSelectableAid = {
+        0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64,
+        0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, 0xFF,
+};
+
+class MySecureElementCallback : public BnSecureElementCallback {
+  public:
+    ScopedAStatus onStateChange(bool state, const std::string& debugReason) override {
+        {
+            std::unique_lock<std::mutex> l(m);
+            (void)debugReason;
+            history.push_back(state);
+        }
+        cv.notify_one();
+        return ScopedAStatus::ok();
+    };
+
+    void expectCallbackHistory(std::vector<bool>&& want) {
+        std::unique_lock<std::mutex> l(m);
+        cv.wait_for(l, 5s, [&]() { return history.size() >= want.size(); });
+        EXPECT_THAT(history, ElementsAreArray(want));
+    }
+
+    void resetCallbackHistory() {
+        std::unique_lock<std::mutex> l(m);
+        history.clear();
+    }
+
+  private:
+    std::mutex m;  // guards history
+    std::condition_variable cv;
+    std::vector<bool> history;
+};
+
+class SecureElementAidl : public ::testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        SpAIBinder binder = SpAIBinder(AServiceManager_waitForService(GetParam().c_str()));
+
+        secure_element_ = ISecureElement::fromBinder(binder);
+        ASSERT_NE(secure_element_, nullptr);
+
+        secure_element_callback_ = SharedRefBase::make<MySecureElementCallback>();
+        ASSERT_NE(secure_element_callback_, nullptr);
+
+        EXPECT_OK(secure_element_->init(secure_element_callback_));
+        secure_element_callback_->expectCallbackHistory({true});
+
+        // Check if the basic channel is supported by the bound SE.
+        std::vector<uint8_t> basic_channel_response;
+        auto status =
+                secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response);
+        if (status.isOk()) {
+            basic_channel_supported_ = true;
+            secure_element_->closeChannel(0);
+        }
+    }
+
+    void TearDown() override {
+        secure_element_callback_->resetCallbackHistory();
+        EXPECT_OK(secure_element_->reset());
+        secure_element_callback_->expectCallbackHistory({false, true});
+        secure_element_ = nullptr;
+        secure_element_callback_ = nullptr;
+    }
+
+    // Call transmit with kDataApdu and the selected channel number.
+    // Return the response sstatus code.
+    uint16_t transmit(uint8_t channel_number) {
+        std::vector<uint8_t> apdu = kDataApdu;
+        std::vector<uint8_t> response;
+
+        // Edit the channel number into the CLA header byte.
+        if (channel_number < 4) {
+            apdu[0] |= channel_number;
+        } else {
+            apdu[0] |= (channel_number - 4) | 0x40;
+        }
+
+        // transmit() will return an empty response with the error
+        // code CHANNEL_NOT_AVAILABLE when the SE cannot be
+        // communicated with.
+        auto status = secure_element_->transmit(apdu, &response);
+        if (!status.isOk()) {
+            return 0x6881;
+        }
+
+        // transmit() will return a response containing at least
+        // the APDU response status otherwise.
+        EXPECT_GE(response.size(), 2u);
+        uint16_t apdu_status =
+                (response[response.size() - 2] << 8) | (response[response.size() - 1] << 0);
+
+        // When the command is successful the response
+        // must contain 256 bytes of data.
+        if (apdu_status == 0x9000) {
+            EXPECT_EQ(response.size(), 258);
+        }
+
+        return apdu_status;
+    }
+
+    std::shared_ptr<ISecureElement> secure_element_;
+    std::shared_ptr<MySecureElementCallback> secure_element_callback_;
+    bool basic_channel_supported_{false};
+};
+
+TEST_P(SecureElementAidl, init) {
+    // init(nullptr) shall fail.
+    EXPECT_ERR(secure_element_->init(nullptr));
+
+    // init with a valid callback pointer shall succeed.
+    EXPECT_OK(secure_element_->init(secure_element_callback_));
+    secure_element_callback_->expectCallbackHistory({true, true});
+}
+
+TEST_P(SecureElementAidl, reset) {
+    std::vector<uint8_t> basic_channel_response;
+    LogicalChannelResponse logical_channel_response;
+
+    // reset called after init shall succeed.
+    if (basic_channel_supported_) {
+        EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
+    }
+    EXPECT_OK(secure_element_->openLogicalChannel(kSelectableAid, 0x00, &logical_channel_response));
+
+    EXPECT_OK(secure_element_->reset());
+    secure_element_callback_->expectCallbackHistory({true, false, true});
+
+    // All opened channels must be closed.
+    if (basic_channel_supported_) {
+        EXPECT_NE(transmit(0), 0x9000);
+    }
+    EXPECT_NE(transmit(logical_channel_response.channelNumber), 0x9000);
+}
+
+TEST_P(SecureElementAidl, isCardPresent) {
+    bool res = false;
+
+    // isCardPresent called after init shall succeed.
+    EXPECT_OK(secure_element_->isCardPresent(&res));
+    EXPECT_TRUE(res);
+}
+
+TEST_P(SecureElementAidl, getAtr) {
+    std::vector<uint8_t> atr;
+
+    // getAtr called after init shall succeed.
+    // The ATR has size between 0 and 32 bytes.
+    EXPECT_OK(secure_element_->getAtr(&atr));
+    EXPECT_LE(atr.size(), 32u);
+}
+
+TEST_P(SecureElementAidl, openBasicChannel) {
+    std::vector<uint8_t> response;
+
+    if (!basic_channel_supported_) {
+        return;
+    }
+
+    // openBasicChannel called with an invalid AID shall fail.
+    EXPECT_ERR(secure_element_->openBasicChannel(kNonSelectableAid, 0x00, &response));
+
+    // openBasicChannel called after init shall succeed.
+    // The response size must be larger than 2 bytes as it includes the
+    // status code.
+    EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &response));
+    EXPECT_GE(response.size(), 2u);
+
+    // transmit called on the basic channel should succeed.
+    EXPECT_EQ(transmit(0), 0x9000);
+
+    // openBasicChannel called a second time shall fail.
+    // The basic channel can only be opened once.
+    EXPECT_ERR(secure_element_->openBasicChannel(kSelectableAid, 0x00, &response));
+
+    // openBasicChannel called after closing the basic channel shall succeed.
+    EXPECT_OK(secure_element_->closeChannel(0));
+    EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &response));
+}
+
+TEST_P(SecureElementAidl, openLogicalChannel) {
+    LogicalChannelResponse response;
+
+    // openLogicalChannel called with an invalid AID shall fail.
+    EXPECT_ERR(secure_element_->openLogicalChannel(kNonSelectableAid, 0x00, &response));
+
+    // openLogicalChannel called after init shall succeed.
+    // The response size must be larger than 2 bytes as it includes the
+    // status code. The channel number must be in the range 1-19.
+    EXPECT_OK(secure_element_->openLogicalChannel(kSelectableAid, 0x00, &response));
+    EXPECT_GE(response.selectResponse.size(), 2u);
+    EXPECT_GE(response.channelNumber, 1u);
+    EXPECT_LE(response.channelNumber, 19u);
+
+    // transmit called on the logical channel should succeed.
+    EXPECT_EQ(transmit(response.channelNumber), 0x9000);
+}
+
+TEST_P(SecureElementAidl, closeChannel) {
+    std::vector<uint8_t> basic_channel_response;
+    LogicalChannelResponse logical_channel_response;
+
+    // closeChannel called on non-existing basic or logical channel
+    // shall fail.
+    EXPECT_ERR(secure_element_->closeChannel(0));
+    EXPECT_ERR(secure_element_->closeChannel(1));
+
+    // closeChannel called on basic channel closes the basic channel.
+    if (basic_channel_supported_) {
+        EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
+        EXPECT_OK(secure_element_->closeChannel(0));
+
+        // transmit called on the basic channel should fail.
+        EXPECT_NE(transmit(0), 0x9000);
+    }
+
+    // closeChannel called on logical channel closes the logical channel.
+    EXPECT_OK(secure_element_->openLogicalChannel(kSelectableAid, 0x00, &logical_channel_response));
+    EXPECT_OK(secure_element_->closeChannel(logical_channel_response.channelNumber));
+
+    // transmit called on the logical channel should fail.
+    EXPECT_NE(transmit(logical_channel_response.channelNumber), 0x9000);
+}
+
+TEST_P(SecureElementAidl, transmit) {
+    std::vector<uint8_t> response;
+    LogicalChannelResponse logical_channel_response;
+
+    /* Temporaly disable this check to clarify Basic Channel behavior (b/300502872)
+    // Note: no channel is opened for this test
+    // transmit() will return an empty response with the error
+    // code CHANNEL_NOT_AVAILABLE when the SE cannot be
+    // communicated with.
+    EXPECT_ERR(secure_element_->transmit(kDataApdu, &response));
+    */
+
+    EXPECT_OK(secure_element_->openLogicalChannel(kSelectableAid, 0x00, &logical_channel_response));
+    EXPECT_GE(logical_channel_response.selectResponse.size(), 2u);
+    EXPECT_GE(logical_channel_response.channelNumber, 1u);
+    EXPECT_LE(logical_channel_response.channelNumber, 19u);
+
+    // transmit called on the logical channel should succeed.
+    EXPECT_EQ(transmit(logical_channel_response.channelNumber), 0x9000);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SecureElementAidl);
+INSTANTIATE_TEST_SUITE_P(
+        SecureElement, SecureElementAidl,
+        testing::ValuesIn(android::getAidlHalInstanceNames(ISecureElement::descriptor)),
+        android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/security/OWNERS b/security/OWNERS
index 54d820a..619139b 100644
--- a/security/OWNERS
+++ b/security/OWNERS
@@ -1,5 +1,16 @@
+# Bug component: 1084733
+
+# Please assign all bugs related to /hardware/interfaces/security/ to the team alias:
+#
+#    android-hardware-security@google.com
+#
+# This will get them auto-assigned to the on-call triage engineer, ensuring quickest response.
+
+ascull@google.com
 drysdale@google.com
+eranm@google.com
+hasinitg@google.com
 jbires@google.com
-jdanis@google.com
-seleneh@google.com
+sethmo@google.com
 swillden@google.com
+zeuthen@google.com
diff --git a/security/dice/aidl/Android.bp b/security/dice/aidl/Android.bp
deleted file mode 100644
index 97781b3..0000000
--- a/security/dice/aidl/Android.bp
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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 {
-    // 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"],
-}
-
-aidl_interface {
-    name: "android.hardware.security.dice",
-    vendor_available: true,
-    srcs: [
-        "android/hardware/security/dice/*.aidl",
-    ],
-    stability: "vintf",
-    backend: {
-        java: {
-            enabled: false,
-            platform_apis: false,
-        },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-            apps_enabled: false,
-            apex_available: [
-                "//apex_available:platform",
-                "com.android.compos",
-            ],
-        },
-        rust: {
-            enabled: true,
-            apex_available: [
-                "//apex_available:platform",
-                "com.android.compos",
-            ],
-        },
-    },
-    versions_with_info: [
-        {
-            version: "1",
-            imports: [],
-        },
-    ],
-
-    //     versions: ["1"],
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/.hash b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/.hash
deleted file mode 100644
index 3f08fd8..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/.hash
+++ /dev/null
@@ -1 +0,0 @@
-02994f275fd7b1b40610c10eaeb0573f4312e358
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Bcc.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Bcc.aidl
deleted file mode 100644
index 5af7358..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Bcc.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Bcc {
-  byte[] data;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/BccHandover.aidl
deleted file mode 100644
index 8baca94..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/BccHandover.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable BccHandover {
-  byte[32] cdiAttest;
-  byte[32] cdiSeal;
-  android.hardware.security.dice.Bcc bcc;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Config.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Config.aidl
deleted file mode 100644
index 78dd2f8..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Config.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Config {
-  byte[] desc;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/IDiceDevice.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/IDiceDevice.aidl
deleted file mode 100644
index 383f4d1..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/IDiceDevice.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.security.dice;
-/* @hide */
-@SensitiveData @VintfStability
-interface IDiceDevice {
-  android.hardware.security.dice.Signature sign(in android.hardware.security.dice.InputValues[] id, in byte[] payload);
-  android.hardware.security.dice.Bcc getAttestationChain(in android.hardware.security.dice.InputValues[] inputValues);
-  android.hardware.security.dice.BccHandover derive(in android.hardware.security.dice.InputValues[] inputValues);
-  void demote(in android.hardware.security.dice.InputValues[] inputValues);
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/InputValues.aidl
deleted file mode 100644
index e43c429..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/InputValues.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable InputValues {
-  byte[64] codeHash;
-  android.hardware.security.dice.Config config;
-  byte[64] authorityHash;
-  @nullable byte[] authorityDescriptor;
-  android.hardware.security.dice.Mode mode = android.hardware.security.dice.Mode.NOT_INITIALIZED;
-  byte[64] hidden;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
deleted file mode 100644
index 295c32e..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Mode.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum Mode {
-  NOT_INITIALIZED = 0,
-  NORMAL = 1,
-  DEBUG = 2,
-  RECOVERY = 3,
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/ResponseCode.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/ResponseCode.aidl
deleted file mode 100644
index c13afa6..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/ResponseCode.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 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.security.dice;
-@Backing(type="int") @VintfStability
-enum ResponseCode {
-  PERMISSION_DENIED = 1,
-  SYSTEM_ERROR = 2,
-  NOT_IMPLEMENTED = 3,
-  DEMOTION_FAILED = 4,
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
deleted file mode 100644
index 294170d..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/1/android/hardware/security/dice/Signature.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Signature {
-  byte[] data;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Bcc.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Bcc.aidl
deleted file mode 100644
index 5af7358..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Bcc.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Bcc {
-  byte[] data;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
deleted file mode 100644
index 8baca94..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable BccHandover {
-  byte[32] cdiAttest;
-  byte[32] cdiSeal;
-  android.hardware.security.dice.Bcc bcc;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Config.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Config.aidl
deleted file mode 100644
index 78dd2f8..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Config.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Config {
-  byte[] desc;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/IDiceDevice.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/IDiceDevice.aidl
deleted file mode 100644
index 383f4d1..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/IDiceDevice.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.security.dice;
-/* @hide */
-@SensitiveData @VintfStability
-interface IDiceDevice {
-  android.hardware.security.dice.Signature sign(in android.hardware.security.dice.InputValues[] id, in byte[] payload);
-  android.hardware.security.dice.Bcc getAttestationChain(in android.hardware.security.dice.InputValues[] inputValues);
-  android.hardware.security.dice.BccHandover derive(in android.hardware.security.dice.InputValues[] inputValues);
-  void demote(in android.hardware.security.dice.InputValues[] inputValues);
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
deleted file mode 100644
index e43c429..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable InputValues {
-  byte[64] codeHash;
-  android.hardware.security.dice.Config config;
-  byte[64] authorityHash;
-  @nullable byte[] authorityDescriptor;
-  android.hardware.security.dice.Mode mode = android.hardware.security.dice.Mode.NOT_INITIALIZED;
-  byte[64] hidden;
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Mode.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Mode.aidl
deleted file mode 100644
index 295c32e..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Mode.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum Mode {
-  NOT_INITIALIZED = 0,
-  NORMAL = 1,
-  DEBUG = 2,
-  RECOVERY = 3,
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/ResponseCode.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/ResponseCode.aidl
deleted file mode 100644
index c13afa6..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/ResponseCode.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 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.security.dice;
-@Backing(type="int") @VintfStability
-enum ResponseCode {
-  PERMISSION_DENIED = 1,
-  SYSTEM_ERROR = 2,
-  NOT_IMPLEMENTED = 3,
-  DEMOTION_FAILED = 4,
-}
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Signature.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Signature.aidl
deleted file mode 100644
index 294170d..0000000
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Signature.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.dice;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable Signature {
-  byte[] data;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/Bcc.aidl b/security/dice/aidl/android/hardware/security/dice/Bcc.aidl
deleted file mode 100644
index 983915e..0000000
--- a/security/dice/aidl/android/hardware/security/dice/Bcc.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.security.dice;
-
-/**
- * A DICE certificate chain following the Boot Certificate Chain (BCC) specification.
- * @hide
- */
-@VintfStability
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-parcelable Bcc {
-    /**
-     * The DICE certificate chain CBOR encoded following the BCC specification. The CDDL
-     * specification for BCC can be found here [1].
-     *
-     * @see <a
-     *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl">
-     *    BCC CDDL specification
-     * </a>
-     */
-    byte[] data;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl
deleted file mode 100644
index 6ca862c..0000000
--- a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.security.dice;
-
-import android.hardware.security.dice.Bcc;
-
-/**
- * Represents one set of DICE artifacts.
- *
- * @hide
- */
-@VintfStability
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-parcelable BccHandover {
-    /**
-     * CDI_attest. Must be exactly 32 bytes of data.
-     */
-    byte[32] cdiAttest;
-    /**
-     * CDI_seal. Must be exactly 32 bytes of data.
-     */
-    byte[32] cdiSeal;
-    /**
-     * CBOR encoded BCC.
-     *
-     * @see <a
-     *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl">
-     *    BCC CDDL specification
-     * </a>
-     */
-    Bcc bcc;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/Config.aidl b/security/dice/aidl/android/hardware/security/dice/Config.aidl
deleted file mode 100644
index 6decfc5..0000000
--- a/security/dice/aidl/android/hardware/security/dice/Config.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.security.dice;
-
-/**
- * DICE config descriptor as described in at
- * <a
- * href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#input-values">
- *     input-values
- * </a>
- * @hide
- */
-@VintfStability
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-parcelable Config {
-    /**
-     * A free form descriptor. This should follow the BCC Configuration Descriptor.
-     * @see <a
-     *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl">
-     *     BccPayload field -4670548
-     * </a>
-     */
-    byte[] desc;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/IDiceDevice.aidl b/security/dice/aidl/android/hardware/security/dice/IDiceDevice.aidl
deleted file mode 100644
index 709aede..0000000
--- a/security/dice/aidl/android/hardware/security/dice/IDiceDevice.aidl
+++ /dev/null
@@ -1,100 +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.security.dice;
-
-import android.hardware.security.dice.Bcc;
-import android.hardware.security.dice.BccHandover;
-import android.hardware.security.dice.InputValues;
-import android.hardware.security.dice.Signature;
-
-/**
- * IDiceDevice specifies an interface that allows access to the Android instance's DICE artifacts.
- *
- * <h2>Features</h2>
- *
- * The dice device provides access to the component's CDI_SEAL and CDI_ATTEST secrets as well
- * as to its attestation certificate chain. The "component" is the Android instance running this
- * HAL service and the secrets and attestation chain must include all boot stage components,
- * the kernel, and the verified boot information (VBA).
- *
- * Implementations provide the following operations:
- * <li> sign - Signing a payload with a key derived from CDI_ATTEST.
- * <li> getAttestationChain - Retrieve the component's attestation certificate chain.
- * <li> derive - Retrieve the component's DICE artifacts.
- *
- * @see <a
- *         href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md">
- *     Open-dice Specification
- * </a>
- * @see <a
- *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl">
- *     Boot Certificate Chain (BCC) CDDL specification
- * </a>
- * @hide
- */
-@SensitiveData
-@VintfStability
-interface IDiceDevice {
-    /**
-     * Uses the a key derived from the component's, or a child's given by <code>inputValues</code>,
-     * attestation secret to sign the payload using RFC 8032 Pure Ed25519 and returns the
-     * signature. The payload is limited to 1024 bytes.
-     *
-     * @see <a href="https://datatracker.ietf.org/doc/html/rfc8032">RFC 8032</a>
-     */
-    Signature sign(in InputValues[] id, in byte[] payload);
-
-    /**
-     * Returns the attestation chain of the component if <code>inputValues</code> is empty or the
-     * chain to the given child of the component identified by the <code>inputValues</code> vector.
-     *
-     * ## Error as service specific exception:
-     *     ResponseCode::PERMISSION_DENIED if the caller is not sufficiently privileged.
-     */
-    Bcc getAttestationChain(in InputValues[] inputValues);
-
-    /**
-     * This function allows a client to become a resident node. A resident node is a node that
-     * manages its own dice secrets as opposed to using them by proxy, i.e., by calling sign
-     * and getAttestationChain. Called with empty <code>inputValues</code> vectors, an
-     * implementation returns the component's DICE secrets. If the <code>inputValues</code> vector
-     * is given the appropriate derivations are performed starting from the component's level.
-     *
-     * ## Error as service specific exception:
-     *     ResponseCode::PERMISSION_DENIED if the implementation does not allow resident nodes
-     *     at the client's level.
-     */
-    BccHandover derive(in InputValues[] inputValues);
-
-    /**
-     * This demotes the implementation of this interface.
-     * When called, the implementation performs appropriate derivation steps using
-     * <code>inputValues</code>, traversing the vector in ascending order. Then it replaces its
-     * stored DICE artifacts with the newly derived ones.
-     *
-     * IMPORTANT: When the function returns, all remnants of the previous DICE artifacts must
-     * have been purged from memory.
-     *
-     * This operation is not reversible until the next reboot. Further demotion is always
-     * possible.
-     *
-     * ## Error as service specific exception:
-     *     ResponseCode::DEMOTION_FAILED if the implementation failed to demote itself
-     *     or was unable to purge previous DICE artifacts from memory.
-     */
-    void demote(in InputValues[] inputValues);
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl
deleted file mode 100644
index 711d523..0000000
--- a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.security.dice;
-
-import android.hardware.security.dice.Config;
-import android.hardware.security.dice.Mode;
-
-/**
- * DICE input values for certificate and CDI generation.
- *
- * @see <a
- *         href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#input-values">
- *     Open-dice input-values
- * </a>
- * @hide
- */
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-@VintfStability
-parcelable InputValues {
-    /**
-     * The target code hash. Must be exactly 64 bytes.
-     */
-    byte[64] codeHash;
-    /**
-     * The configuration data.
-     */
-    Config config;
-    /**
-     * The authority hash. Must be exactly 64 bytes. Must be all zero if unused.
-     */
-    byte[64] authorityHash;
-    /**
-     * Optional free form authorityDescriptor.
-     */
-    @nullable byte[] authorityDescriptor;
-    /**
-     * The mode of operation. Normal, Debug, Maintenance, or not initialized.
-     */
-    Mode mode = Mode.NOT_INITIALIZED;
-    /**
-     * Optional hidden values. Must be exactly 64 bytes. Must be all zero if unused.
-     */
-    byte[64] hidden;
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/Mode.aidl b/security/dice/aidl/android/hardware/security/dice/Mode.aidl
deleted file mode 100644
index 3b3bfdc..0000000
--- a/security/dice/aidl/android/hardware/security/dice/Mode.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.security.dice;
-
-/**
- * DICE mode values as defined at
- *
- * @see <a
- *         href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#mode-value-details">
- *     open-dice mode-value-details
- * </a>
- * @hide
- */
-@Backing(type="int")
-@VintfStability
-enum Mode {
-    NOT_INITIALIZED = 0,
-    NORMAL = 1,
-    DEBUG = 2,
-    /**
-     * The recovery mode is also referred to as "maintenance" mode.
-     */
-    RECOVERY = 3,
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/ResponseCode.aidl b/security/dice/aidl/android/hardware/security/dice/ResponseCode.aidl
deleted file mode 100644
index 3e77cf7..0000000
--- a/security/dice/aidl/android/hardware/security/dice/ResponseCode.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2020, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.dice;
-
-@Backing(type="int")
-/**
- * These response codes are used as service specific exception codes by
- * IDiceDevice.
- * @hide
- */
-@VintfStability
-enum ResponseCode {
-    /**
-     * The caller has insufficient privilege to access the DICE API.
-     */
-    PERMISSION_DENIED = 1,
-    /**
-     * An unexpected error occurred, likely with IO or IPC.
-     */
-    SYSTEM_ERROR = 2,
-    /**
-     * Returned if the called function is not implemented.
-     */
-    NOT_IMPLEMENTED = 3,
-    /**
-     * An attempt to demote the implementation failed.
-     */
-    DEMOTION_FAILED = 4,
-}
diff --git a/security/dice/aidl/android/hardware/security/dice/Signature.aidl b/security/dice/aidl/android/hardware/security/dice/Signature.aidl
deleted file mode 100644
index ea3594f..0000000
--- a/security/dice/aidl/android/hardware/security/dice/Signature.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.security.dice;
-
-/**
- * This parcelable represents a Signature. It is used as return value of IDiceNode::sign.
- *
- * @hide
- */
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-@VintfStability
-parcelable Signature {
-    /**
-     * The RFC 8032 PureEd25519 signature.
-     * @see <a href="https://datatracker.ietf.org/doc/html/rfc8032">RFC 8032</a>
-     */
-    byte[] data;
-}
diff --git a/security/dice/aidl/default/Android.bp b/security/dice/aidl/default/Android.bp
deleted file mode 100644
index b67a44a..0000000
--- a/security/dice/aidl/default/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-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"],
-}
-
-rust_binary {
-    name: "android.hardware.security.dice-service.non-secure-software",
-    srcs: ["service.rs"],
-    relative_install_path: "hw",
-    vendor: true,
-    rustlibs: [
-        "android.hardware.security.dice-V1-rust",
-        "libdiced_open_dice_cbor",
-        "libdiced_sample_inputs",
-        "libdiced_vendor",
-        "libandroid_logger",
-        "libanyhow",
-        "libbinder_rs",
-        "liblog_rust",
-        "libserde",
-    ],
-    init_rc: ["android.hardware.security.dice-service.non-secure-software.rc"],
-    vintf_fragments: [
-        "android.hardware.security.dice-service.non-secure-software.xml",
-    ],
-}
diff --git a/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.rc b/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.rc
deleted file mode 100644
index 28e43c3..0000000
--- a/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.rc
+++ /dev/null
@@ -1,9 +0,0 @@
-service vendor.dice /vendor/bin/hw/android.hardware.security.dice-service.non-secure-software
-    class early_hal
-    user nobody
-    # The diced HAL cannot be allowed to restart. When it crashes for any reason.
-    # it loses security critical state. The only remedy is to restart the device.
-    # This may be implementation depended. It is safe to restart the HAL if the
-    # state change during a call to "demote" is is preserved.
-    # see android/hardware/security/dice/IDiceDevice.aidl for details on "demote".
-    oneshot
diff --git a/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.xml b/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.xml
deleted file mode 100644
index 94ef243..0000000
--- a/security/dice/aidl/default/android.hardware.security.dice-service.non-secure-software.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<manifest version="1.0" type="device">
-    <hal format="aidl">
-        <name>android.hardware.security.dice</name>
-        <fqname>IDiceDevice/default</fqname>
-    </hal>
-</manifest>
\ No newline at end of file
diff --git a/security/dice/aidl/default/service.rs b/security/dice/aidl/default/service.rs
deleted file mode 100644
index eebf333..0000000
--- a/security/dice/aidl/default/service.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-// 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.
-
-//! Main entry point for the android.hardware.security.dice service.
-
-use anyhow::Result;
-use diced::{
-    dice,
-    hal_node::{DiceArtifacts, DiceDevice, ResidentHal, UpdatableDiceArtifacts},
-};
-use diced_sample_inputs::make_sample_bcc_and_cdis;
-use serde::{Deserialize, Serialize};
-use std::convert::TryInto;
-use std::panic;
-use std::sync::Arc;
-
-static DICE_HAL_SERVICE_NAME: &str = "android.hardware.security.dice.IDiceDevice/default";
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-struct InsecureSerializableArtifacts {
-    cdi_attest: [u8; dice::CDI_SIZE],
-    cdi_seal: [u8; dice::CDI_SIZE],
-    bcc: Vec<u8>,
-}
-
-impl DiceArtifacts for InsecureSerializableArtifacts {
-    fn cdi_attest(&self) -> &[u8; dice::CDI_SIZE] {
-        &self.cdi_attest
-    }
-    fn cdi_seal(&self) -> &[u8; dice::CDI_SIZE] {
-        &self.cdi_seal
-    }
-    fn bcc(&self) -> Vec<u8> {
-        self.bcc.clone()
-    }
-}
-
-impl UpdatableDiceArtifacts for InsecureSerializableArtifacts {
-    fn with_artifacts<F, T>(&self, f: F) -> Result<T>
-    where
-        F: FnOnce(&dyn DiceArtifacts) -> Result<T>,
-    {
-        f(self)
-    }
-    fn update(self, new_artifacts: &impl DiceArtifacts) -> Result<Self> {
-        Ok(Self {
-            cdi_attest: *new_artifacts.cdi_attest(),
-            cdi_seal: *new_artifacts.cdi_seal(),
-            bcc: new_artifacts.bcc(),
-        })
-    }
-}
-
-fn main() {
-    android_logger::init_once(
-        android_logger::Config::default()
-            .with_tag("android.hardware.security.dice")
-            .with_min_level(log::Level::Debug),
-    );
-    // Redirect panic messages to logcat.
-    panic::set_hook(Box::new(|panic_info| {
-        log::error!("{}", panic_info);
-    }));
-
-    // Saying hi.
-    log::info!("android.hardware.security.dice is starting.");
-
-    let (cdi_attest, cdi_seal, bcc) =
-        make_sample_bcc_and_cdis().expect("Failed to construct sample dice chain.");
-
-    let hal_impl = Arc::new(
-        unsafe {
-            // Safety: ResidentHal cannot be used in multi threaded processes.
-            // This service does not start a thread pool. The main thread is the only thread
-            // joining the thread pool, thereby keeping the process single threaded.
-            ResidentHal::new(InsecureSerializableArtifacts {
-                cdi_attest: cdi_attest[..]
-                    .try_into()
-                    .expect("Failed to convert cdi_attest to array reference."),
-                cdi_seal: cdi_seal[..]
-                    .try_into()
-                    .expect("Failed to convert cdi_seal to array reference."),
-                bcc,
-            })
-        }
-        .expect("Failed to create ResidentHal implementation."),
-    );
-
-    let hal = DiceDevice::new_as_binder(hal_impl).expect("Failed to construct hal service.");
-
-    binder::add_service(DICE_HAL_SERVICE_NAME, hal.as_binder())
-        .expect("Failed to register IDiceDevice Service");
-
-    log::info!("Joining thread pool now.");
-    binder::ProcessState::join_thread_pool();
-}
diff --git a/security/dice/aidl/vts/functional/Android.bp b/security/dice/aidl/vts/functional/Android.bp
deleted file mode 100644
index f5bc949..0000000
--- a/security/dice/aidl/vts/functional/Android.bp
+++ /dev/null
@@ -1,54 +0,0 @@
-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"],
-}
-
-rust_test {
-    name: "VtsAidlDiceTargetTest",
-    srcs: [
-        "dice_test.rs",
-    ],
-    require_root: true,
-    auto_gen_config: true,
-    test_suites: [
-        "general-tests",
-        "vts",
-    ],
-
-    rustlibs: [
-        "android.hardware.security.dice-V1-rust",
-        "libanyhow",
-        "libbinder_rs",
-        "libdiced_open_dice_cbor",
-        "libdiced_sample_inputs",
-        "libdiced_utils",
-        "libkeystore2_vintf_rust",
-    ],
-}
-
-rust_test {
-    name: "VtsAidlDiceDemoteTargetTest",
-    srcs: [
-        "dice_demote_test.rs",
-    ],
-
-    test_config: "VtsAidlDiceDemoteTargetTest.xml",
-    test_suites: [
-        "general-tests",
-        "vts",
-    ],
-
-    rustlibs: [
-        "android.hardware.security.dice-V1-rust",
-        "libanyhow",
-        "libbinder_rs",
-        "libdiced_open_dice_cbor",
-        "libdiced_sample_inputs",
-        "libdiced_utils",
-        "libkeystore2_vintf_rust",
-    ],
-}
diff --git a/security/dice/aidl/vts/functional/VtsAidlDiceDemoteTargetTest.xml b/security/dice/aidl/vts/functional/VtsAidlDiceDemoteTargetTest.xml
deleted file mode 100644
index 2991580..0000000
--- a/security/dice/aidl/vts/functional/VtsAidlDiceDemoteTargetTest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<configuration description="Config to run VtsAidlDiceDemoteTargetTest device tests.">
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="cleanup" value="true" />
-        <option name="push" value="VtsAidlDiceDemoteTargetTest->/data/local/tmp/VtsAidlDiceDemoteTargetTest" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
-        <option name="test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="VtsAidlDiceDemoteTargetTest" />
-    </test>
-    <target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer" />
-
-</configuration>
\ No newline at end of file
diff --git a/security/dice/aidl/vts/functional/dice_demote_test.rs b/security/dice/aidl/vts/functional/dice_demote_test.rs
deleted file mode 100644
index 02ff2a4..0000000
--- a/security/dice/aidl/vts/functional/dice_demote_test.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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.
-
-use diced_open_dice_cbor as dice;
-use diced_sample_inputs;
-use diced_utils;
-use std::convert::TryInto;
-
-mod utils;
-use utils::with_connection;
-
-// This test calls derive with an empty argument vector, then demotes the HAL using
-// a set of three input values, and then calls derive with empty argument vector again.
-// It then performs the same three derivation steps on the result of the former and compares
-// the result to the result of the latter.
-#[test]
-fn demote_test() {
-    with_connection(|device| {
-        let input_values = diced_sample_inputs::get_input_values_vector();
-        let former = device.derive(&[]).expect("Trying to call derive.");
-        device
-            .demote(&input_values)
-            .expect("Trying to call demote with input values.");
-
-        let latter = device
-            .derive(&[])
-            .expect("Trying to call derive after demote.");
-
-        let artifacts = diced_utils::ResidentArtifacts::new(
-            former.cdiAttest[..].try_into().unwrap(),
-            former.cdiSeal[..].try_into().unwrap(),
-            &former.bcc.data,
-        )
-        .unwrap();
-
-        let input_values: Vec<diced_utils::InputValues> = input_values
-            .iter()
-            .map(|v| v.into())
-            .collect();
-
-        let artifacts = artifacts
-            .execute_steps(input_values.iter().map(|v| v as &dyn dice::InputValues))
-            .unwrap();
-        let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
-        let from_former = diced_utils::make_bcc_handover(
-            cdi_attest[..].try_into().unwrap(),
-            cdi_seal[..].try_into().unwrap(),
-            &bcc,
-        )
-        .unwrap();
-        // TODO b/204938506 when we have a parser/verifier, check equivalence rather
-        // than bit by bit equality.
-        assert_eq!(latter, from_former);
-        Ok(())
-    })
-}
diff --git a/security/dice/aidl/vts/functional/dice_test.rs b/security/dice/aidl/vts/functional/dice_test.rs
deleted file mode 100644
index 574b634..0000000
--- a/security/dice/aidl/vts/functional/dice_test.rs
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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.
-
-use diced_open_dice_cbor as dice;
-use diced_sample_inputs;
-use diced_utils;
-use std::convert::{TryInto, Into};
-
-mod utils;
-use utils::with_connection;
-
-static TEST_MESSAGE: &[u8] = &[
-    // "My test message!"
-    0x4d, 0x79, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x21,
-    0x0a,
-];
-
-// This test calls derive with an empty argument vector and with a set of three input values.
-// It then performs the same three derivation steps on the result of the former and compares
-// the result to the result of the latter.
-#[test]
-fn equivalence_test() {
-    with_connection(|device| {
-        let input_values = diced_sample_inputs::get_input_values_vector();
-        let former = device.derive(&[]).expect("Trying to call derive.");
-        let latter = device
-            .derive(&input_values)
-            .expect("Trying to call derive with input values.");
-        let artifacts = diced_utils::ResidentArtifacts::new(
-            former.cdiAttest[..].try_into().unwrap(),
-            former.cdiSeal[..].try_into().unwrap(),
-            &former.bcc.data,
-        )
-        .unwrap();
-
-        let input_values: Vec<diced_utils::InputValues> = input_values
-            .iter()
-            .map(|v| v.into())
-            .collect();
-
-        let artifacts = artifacts
-            .execute_steps(input_values.iter().map(|v| v as &dyn dice::InputValues))
-            .unwrap();
-        let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
-        let from_former = diced_utils::make_bcc_handover(
-            cdi_attest[..].try_into().unwrap(),
-            cdi_seal[..].try_into().unwrap(),
-            &bcc,
-        )
-        .unwrap();
-        // TODO b/204938506 when we have a parser/verifier, check equivalence rather
-        // than bit by bit equality.
-        assert_eq!(latter, from_former);
-        Ok(())
-    })
-}
-
-#[test]
-fn sign_and_verify() {
-    with_connection(|device| {
-        let _signature = device
-            .sign(&[], TEST_MESSAGE)
-            .expect("Trying to call sign.");
-
-        let _bcc = device
-            .getAttestationChain(&[])
-            .expect("Trying to call getAttestationChain.");
-        // TODO b/204938506 check the signature with the bcc when the verifier is available.
-        Ok(())
-    })
-}
diff --git a/security/dice/aidl/vts/functional/utils.rs b/security/dice/aidl/vts/functional/utils.rs
deleted file mode 100644
index 4e6708e..0000000
--- a/security/dice/aidl/vts/functional/utils.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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.
-
-use android_hardware_security_dice::aidl::android::hardware::security::dice::IDiceDevice::IDiceDevice;
-use anyhow::Result;
-use binder::Strong;
-use keystore2_vintf::get_aidl_instances;
-use std::sync::Arc;
-
-static DICE_DEVICE_SERVICE_NAME: &str = &"android.hardware.security.dice";
-static DICE_DEVICE_INTERFACE_NAME: &str = &"IDiceDevice";
-
-/// This function iterates through all announced IDiceDevice services and runs the given test
-/// closure against connections to each of them. It also modifies the panic hook to indicate
-/// on which instance the test failed in case the test closure panics.
-pub fn with_connection<R, F>(test: F)
-where
-    F: Fn(&Strong<dyn IDiceDevice>) -> Result<R>,
-{
-    let instances = get_aidl_instances(DICE_DEVICE_SERVICE_NAME, 1, DICE_DEVICE_INTERFACE_NAME);
-    let panic_hook = Arc::new(std::panic::take_hook());
-    for i in instances.into_iter() {
-        let panic_hook_clone = panic_hook.clone();
-        let instance_clone = i.clone();
-        std::panic::set_hook(Box::new(move |v| {
-            println!("While testing instance: \"{}\"", instance_clone);
-            panic_hook_clone(v)
-        }));
-        let connection: Strong<dyn IDiceDevice> = binder::get_interface(&format!(
-            "{}.{}/{}",
-            DICE_DEVICE_SERVICE_NAME, DICE_DEVICE_INTERFACE_NAME, i
-        ))
-        .unwrap();
-        test(&connection).unwrap();
-        drop(std::panic::take_hook());
-    }
-    // Cannot call unwrap here because the panic hook is not Debug.
-    std::panic::set_hook(match Arc::try_unwrap(panic_hook) {
-        Ok(hook) => hook,
-        _ => panic!("Failed to unwrap and reset previous panic hook."),
-    })
-}
diff --git a/security/keymint/README.md b/security/keymint/README.md
new file mode 100644
index 0000000..54647af
--- /dev/null
+++ b/security/keymint/README.md
@@ -0,0 +1,10 @@
+# KeyMint HAL
+
+This directory contains the HAL definition for KeyMint. KeyMint provides
+cryptographic services in a hardware-isolated environment.
+
+Note that the `IRemotelyProvisionedComponent` HAL, and it's associated types,
+used to also be defined in this directory. As of Android U, this HAL has been
+moved to a different directory (../rkp). This move is ABI compatible, as the
+interfaces have been maintained. The build is split so that the generated
+code may be built with different options.
diff --git a/security/keymint/RKP_README.md b/security/keymint/RKP_README.md
deleted file mode 100644
index 89a2598..0000000
--- a/security/keymint/RKP_README.md
+++ /dev/null
@@ -1,374 +0,0 @@
-# Remote Provisioning HAL
-
-## Objective
-
-Design a HAL to support over-the-air provisioning of certificates for asymmetric
-keys. The HAL must interact effectively with Keystore (and other daemons) and
-protect device privacy and security.
-
-Note that this API is designed for KeyMint, but with the intention that it
-should be usable for other HALs that require certificate provisioning.
-Throughout this document we'll refer to the Keystore and KeyMint (formerly
-called Keymaster) components, but only for concreteness and convenience; those
-labels could be replaced with the names of any system and secure area
-components, respectively, that need certificates provisioned.
-
-## Key design decisions
-
-### General approach
-
-To more securely and reliably get keys and certificates to Android devices, we
-need to create a system where no party outside of the device's secure components
-is responsible for managing private keys. The strategy we've chosen is to
-deliver certificates over the air, using an asymmetric key pair created
-on-device in the factory as a root of trust to create an authenticated, secure
-channel. In this document we refer to this device-unique asymmetric key pair as
-Device Key (DK), its public half DK\_pub, its private half DK\_priv and a Device
-Key Certificate containing DK\_pub is denoted DKC.
-
-In order for the provisioning service to use DK (or a key authenticated by DK),
-it must know whether a given DK\_pub is known and trusted. To prove trust, we
-ask device OEMs to use one of two mechanisms:
-
-1.  (Preferred, recommended) The device OEM extracts DK\_pub from each device it
-    manufactures and uploads the public keys to a backend server.
-
-1.  The device OEM signs the DK\_pub to produce DKC and stores it on the device.
-    This has the advantage that they don't need to upload a DK\_pub for every
-    device immediately, but the disadvantage that they have to manage their
-    private signing keys, which means they have to have HSMs, configure and
-    secure them correctly, etc. Some backend providers may also require that the
-    OEM passes a factory security audit, and additionally promises to upload the
-    keys eventually as well.
-
-Note that in the full elaboration of this plan, DK\_pub is not the key used to
-establish a secure channel. Instead, DK\_pub is just the first public key in a
-chain of public keys which ends with the KeyMint public key, KM\_pub. All keys
-in the chain are device-unique and are joined in a certificate chain called the
-_Boot Certificate Chain_ (BCC), because in phases 2 and 3 of the remote
-provisioning project it is a chain of certificates corresponding to boot phases.
-We speak of the BCC even for phase 1, though in phase 1 it contains only a
-single self-signed DKC. This is described in more depth in the Phases section
-below.
-
-The BCC is authenticated by DK\_pub. To authenticate DK\_pub, we may have
-additional DKCs, from the SoC vendor, the device OEM, or both. Those are not
-part of the BCC but included as optional fields in the certificate request
-structure.
-
-The format of the the DK and BCC is specified within [Open Profile for DICE]
-(https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md).  To
-map phrases within this document to their equivalent terminology in the DICE
-specification, read the terms as follows: the DK corresponds to the UDS-derived
-key pair, DKC corresponds to the UDS certificate, and the BCC entries between
-DK\_pub and KM\_pub correspond to a chain of CDI certificates.
-
-Note: In addition to allowing 32 byte hash values for fields in the BCC payload,
-this spec additionally constrains some of the choices allowed in open-DICE.
-Specifically, these include which entries are required and which are optional in
-the BCC payload, and which algorithms are acceptable for use.
-
-### Phases
-
-RKP will be deployed in three phases, in terms of managing the root of trust
-binding between the device and the backend. To briefly describe them:
-
-* Phase 1: In phase 1 there is only one entry in the BCC; DK_pub and KM_pub are
-  the same key and the certificate is self-signed.
-* Phase 2: This is identical to phase 1, except it leverages the hardware root
-  of trust process described by DICE. Instead of trust being rooted in the TEE,
-  it is now rooted in the ROM by key material blown into fuses which are only
-  accessible to the ROM code.
-* Phase 3: This is identical to Phase 2, except the SoC vendor also does the
-  public key extraction or certification in their facilities, along with the OEM
-  doing it in the factory. This tightens up the "supply chain" and aims to make
-  key upload management more secure.
-
-### Privacy considerations
-
-Because DK and the DKCs are unique, immutable, unspoofable hardware-bound
-identifiers for the device, we must limit access to them to the absolute minimum
-possible. We do this in two ways:
-
-1.  We require KeyMint (which knows the BCC and either knows or at least has the
-ability to use KM\_priv) to refuse to ever divulge the BCC or additional
-signatures in plaintext. Instead, KeyMint requires the caller to provide an
-_Endpoint Encryption Key_ (EEK), with which it will encrypt the data before
-returning it. When provisioning production keys, the EEK must be signed by an
-approved authority whose public key is embedded in KeyMint. When certifying test
-keys, KeyMint will accept any EEK without checking the signature, but will
-encrypt and return a test BCC, rather than the real one.  The result is that
-only an entity in possession of an Trusted EEK (TEEK) private key can discover
-the plaintext of the production BCC.
-1.  Having thus limited access to the public keys to the trusted party only, we
-need to prevent the entity from abusing this unique device identifier.  The
-approach and mechanisms for doing that are beyond the scope of this document
-(they must be addressed in the server design), but generally involve taking care
-to ensure that we do not create any links between user IDs, IP addresses or
-issued certificates and the device pubkey.
-
-Although the details of the mechanisms for preventing the entity from abusing
-the BCC are, as stated, beyond the scope of this document, there is a subtle
-design decision here made specifically to enable abuse prevention. Specifically
-the `CertificateRequest` message sent to the server is (in
-[CDDL](https://tools.ietf.org/html/rfc8610)):
-
-```
-cddl
-CertificateRequest = [
-    DeviceInfo,
-    challenge : bstr,
-    ProtectedData,
-    MacedKeysToSign
-]
-```
-
-The public keys to be attested by the server are in `MacedKeysToSign`, which is
-a COSE\_Mac0 structure, MACed with a key that is found in `ProtectedData`. The
-MAC key is signed by DK\_pub.
-
-This structure allows the backend component that has access to EEK\_priv to
-decrypt `ProtectedData`, validate that the request is from an authorized device,
-check that the request is fresh and verify and extract the MAC key. That backend
-component never sees any data related to the keys to be signed, but can provide
-the MAC key to another backend component that can verify `MacedKeysToSign` and
-proceed to generate the certificates.
-
-In this way, we can partition the provisioning server into one component that
-knows the device identity, as represented by DK\_pub, but never sees the keys to
-be certified or certificates generated, and another component that sees the keys
-to be certified and certificates generated but does not know the device
-identity.
-
-### Key and cryptographic message formatting
-
-For simplicity of generation and parsing, compactness of wire representation,
-and flexibility and standardization, we've settled on using the CBOR Object
-Signing and Encryption (COSE) standard, defined in [RFC
-8152](https://tools.ietf.org/html/rfc8152). COSE provides compact and reasonably
-simple, yet easily-extensible, wire formats for:
-
-*   Keys,
-*   MACed messages,
-*   Signed messages, and
-*   Encrypted messages
-
-COSE enables easy layering of these message formats, such as using a COSE\_Sign
-structure to contain a COSE\_Key with a public key in it. We call this a
-"certificate".
-
-Due to the complexity of the standard, we'll spell out the COSE structures
-completely in this document and in the HAL and other documentation, so that
-although implementors will need to understand CBOR and the CBOR Data Definition
-Language ([CDDL, defined in RFC 8610](https://tools.ietf.org/html/rfc8610)),
-they shouldn't need to understand COSE.
-
-Note, however, that the certificate chains returned from the provisioning server
-are standard X.509 certificates.
-
-### Algorithm choices
-
-This document uses:
-
-*   ECDSA P-256 for attestation signing keys;
-*   Remote provisioning protocol signing keys:
-  *  Ed25519 / P-256
-*   ECDH keys:
-  *  X25519 / P-256
-*   AES-GCM for all encryption;
-*   SHA-256 for all message digesting;
-*   HMAC-SHA-256 for all MACing; and
-*   HKDF-SHA-256 for all key derivation.
-
-We believe that Curve25519 offers the best tradeoff in terms of security,
-efficiency and global trustworthiness, and that it is now sufficiently
-widely-used and widely-implemented to make it a practical choice.
-
-However, since Secure Elements (SE) do not currently offer support for curve
-25519, we are allowing implementations to instead make use of EC P-256 for
-signing and ECDH. To put it simply, the device unique key pair will be a P-256
-key pair for ECDSA instead of Ed25519, and the ProtectedData COSE\_Encrypt
-message will have its payload encrypted with P-256 ECDH key exchange instead of
-X25519.
-
-The CDDL in the rest of the document will use the '/' operator to show areas
-where either curve 25519 or P-256 may be used. Since there is no easy way to
-bind choices across different CDDL groups, it is important that the implementor
-stays consistent in which type is chosen. E.g. taking ES256 as the choice for
-algorithm implies the implementor should also choose the P256 public key group
-further down in the COSE structure.
-
-### Testability
-
-It's critical that the remote provisioning implementation be testable, to
-minimize the probability that broken devices are sold to end users. To support
-testing, the remote provisioning HAL methods take a `testMode` argument. Keys
-created in test mode are tagged to indicate this. The provisioning server will
-check for the test mode tag and issue test certificates that do not chain back
-to a trusted public key. In test mode, any EEK will be accepted, enabling
-testing tools to use EEKs for which they have the private key so they can
-validate the content of certificate requests. The BCC included in the
-`CertificateRequest` must contain freshly-generated keys, not the real BCC keys.
-
-Keystore (or similar) will need to be able to handle both testMode keys and
-production keys and keep them distinct, generating test certificate requests
-when asked with a test EEK and production certificate requests when asked with a
-production EEK. Likewise, the interface used to instruct Keystore to create keys
-will need to be able to specify whether test or production keys are desired.
-
-## Design
-
-### Certificate provisioning flow
-
-TODO(jbires): Replace this with a `.png` containing a sequence diagram.  The
-provisioning flow looks something like this:
-
-Provisioner -> Keystore: Prepare N keys
-Keystore -> KeyMint: generateKeyPair
-KeyMint -> KeyMint: Generate  key pair
-KeyMint --> Keystore: key\_blob,pubkey
-Keystore -> Keystore: Store key\_blob,pubkey
-Provisioner -> Server: Get TEEK
-Server --> Provisioner: TEEK
-Provisioner -> Keystore: genCertReq(N, TEEK)
-Keystore -> KeyMint: genCertReq(pubkeys, TEEK)
-KeyMint -> KeyMint: Sign pubkeys & encrypt BCC
-KeyMint --> Keystore: signature, encrypted BCC
-Keystore -> Keystore: Construct cert\_request
-Keystore --> Provisioner: cert\_request
-Provisioner --> Server: cert\_request
-Server -> Server: Validate cert\_request
-Server -> Server: Generate certificates
-Server --> Provisioner: certificates
-Provisioner -> Keystore: certificates
-Keystore -> Keystore: Store certificates
-
-The actors in the above diagram are:
-
-*   **Server** is the backend certificate provisioning server. It has access to
-    the uploaded device public keys and is responsible for providing encryption
-    keys, decrypting and validating requests, and generating certificates in
-    response to requests.
-*   **Provisioner** is an application that is responsible for communicating with
-    the server and all of the system components that require key certificates
-    from the server. It also implements the policy that defines how many key
-    pairs each client should keep in their pool.
-*   **Keystore** is the [Android keystore
-    daemon](https://developer.android.com/training/articles/keystore) (or, more
-    generally, whatever system component manages communications with a
-    particular secure aread component).
-*   **KeyMint** is the secure area component that manages cryptographic keys and
-    performs attestations (or perhaps some other secure area component).
-
-### `BCC`
-
-The _Boot Certificate Chain_ (BCC) is the chain of certificates that contains
-DK\_pub as well as other often device-unique certificates. The BCC is
-represented as a COSE\_Key containing DK\_pub followed by an array of
-COSE\_Sign1 "certificates" containing public keys and optional additional
-information, ordered from root to leaf, with each certificate signing the next.
-The first certificate in the array is signed by DK\_pub, the last certificate
-has the KeyMint (or whatever) signing key's public key, KM\_pub. In phase 1
-there is only one entry; DK\_pub and KM\_pub are the same key and the
-certificate is self-signed.
-
-Each COSE\_Sign1 certificate is a CBOR Web Token (CWT) as described in [RFC
-8392](https://tools.ietf.org/html/rfc8392) with additional fields as described
-in the Open Profile for DICE. Of these additional fields, only the
-_subjectPublicKey_ and _keyUsage_ fields are expected to be present for the
-KM\_pub entry (that is, the last entry) in a BCC, but all fields required by the
-Open Profile for DICE are expected for other entries (each of which corresponds
-to a particular firmware component or boot stage). The CWT fields _iss_ and
-_sub_ identify the issuer and subject of the certificate and are consistent
-along the BCC entries; the issuer of a given entry matches the subject of the
-previous entry.
-
-The BCC is designed to be constructed using the Open Profile for DICE. In this
-case the DK key pair is derived from the UDS as described by that profile and
-all BCC entries before the leaf are CBOR CDI certificates chained from DK\_pub.
-The KM key pair is not part of the derived DICE chain. It is generated (not
-derived) by the KeyMint module, certified by the last key in the DICE chain, and
-added as the leaf BCC entry. The key usage field in this leaf certificate must
-indicate the key is not used to sign certificates. If a UDS certificate is
-available on the device it should appear in the certificate request as the leaf
-of a DKCertChain in AdditionalDKSignatures (see
-[CertificateRequest](#certificaterequest)).
-
-The Open Profile for DICE allows for an arbitrary configuration descriptor. For
-BCC entries, this configuration descriptor is a CBOR map with the following
-optional fields. If no fields are relevant, an empty map should be encoded.
-Additional implementation-specific fields may be added using key values not in
-the range \[-70000, -70999\] (these are reserved for future additions here).
-
-```
-| Name              | Key    | Value type | Meaning                           |
-| ----------------- | ------ | ---------- | ----------------------------------|
-| Component name    | -70002 | tstr       | Name of firmware component / boot |
-:                   :        :            : stage                             :
-| Component version | -70003 | int        | Version of firmware component /   |
-:                   :        :            : boot stage                        :
-| Resettable        | -70004 | null       | If present, key changes on factory|
-:                   :        :            : reset                             :
-```
-
-Please see
-[ProtectedData.aidl](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl)
-for a full CDDL definition of the BCC.
-
-### `CertificateRequest`
-
-The full CBOR message that will be sent to the server to request certificates
-is:
-
-```cddl
-CertificateRequest = [
-    DeviceInfo,
-    challenge : bstr,       // Provided by the server
-    ProtectedData,          // See ProtectedData.aidl
-    MacedKeysToSign         // See IRemotelyProvisionedComponent.aidl
-]
-
-DeviceInfo = [
-    VerifiedDeviceInfo,     // See DeviceInfo.aidl
-    UnverifiedDeviceInfo
-]
-
-// Unverified info is anything provided by the HLOS. Subject to change out of
-// step with the HAL.
-UnverifiedDeviceInfo = {
-    ? "fingerprint" : tstr,
-}
-
-```
-
-It will be the responsibility of Keystore and the Provisioner to construct the
-`CertificateRequest`. The HAL provides a method to generate the elements that
-need to be constructed on the secure side, which are the tag field of
-`MacedKeysToSign`, `VerifiedDeviceInfo`, and the ciphertext field of
-`ProtectedData`.
-
-### HAL
-
-The remote provisioning HAL provides a simple interface that can be implemented
-by multiple secure components that require remote provisioning. It would be
-slightly simpler to extend the KeyMint API, but that approach would only serve
-the needs of KeyMint, this is more general.
-
-NOTE the data structures defined in this HAL may look a little bloated and
-complex. This is because the COSE data structures are fully spelled-out; we
-could make it much more compact by not re-specifying the standardized elements
-and instead just referencing the standard, but it seems better to fully specify
-them. If the apparent complexity seems daunting, consider what the same would
-look like if traditional ASN.1 DER-based structures from X.509 and related
-standards were used and also fully elaborated.
-
-Please see the related HAL documentation directly in the source code at the
-following links:
-
-*   [IRemotelyProvisionedComponent
-    HAL](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl)
-*   [ProtectedData](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl)
-*   [MacedPublicKey](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl)
-*   [RpcHardwareInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl)
-*   [DeviceInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl)
-
diff --git a/security/keymint/TEST_MAPPING b/security/keymint/TEST_MAPPING
new file mode 100644
index 0000000..4ab60b6
--- /dev/null
+++ b/security/keymint/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsAidlKeyMintTargetTest"
+    },
+    {
+      "name": "VtsHalRemotelyProvisionedComponentTargetTest"
+    }
+  ]
+}
diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp
index a233087..e346610 100644
--- a/security/keymint/aidl/Android.bp
+++ b/security/keymint/aidl/Android.bp
@@ -17,14 +17,12 @@
         "android.hardware.security.secureclock-V1",
     ],
     stability: "vintf",
+    frozen: true,
     backend: {
         java: {
             platform_apis: true,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apps_enabled: false,
         },
         rust: {
@@ -44,6 +42,10 @@
             version: "2",
             imports: ["android.hardware.security.secureclock-V1"],
         },
+        {
+            version: "3",
+            imports: ["android.hardware.security.secureclock-V1"],
+        },
 
     ],
 
@@ -55,21 +57,28 @@
 cc_defaults {
     name: "keymint_use_latest_hal_aidl_ndk_static",
     static_libs: [
-        "android.hardware.security.keymint-V2-ndk",
+        "android.hardware.security.keymint-V3-ndk",
     ],
 }
 
 cc_defaults {
     name: "keymint_use_latest_hal_aidl_ndk_shared",
     shared_libs: [
-        "android.hardware.security.keymint-V2-ndk",
+        "android.hardware.security.keymint-V3-ndk",
     ],
 }
 
 cc_defaults {
     name: "keymint_use_latest_hal_aidl_cpp_static",
     static_libs: [
-        "android.hardware.security.keymint-V2-cpp",
+        "android.hardware.security.keymint-V3-cpp",
+    ],
+}
+
+cc_defaults {
+    name: "keymint_use_latest_hal_aidl_cpp_shared",
+    shared_libs: [
+        "android.hardware.security.keymint-V3-cpp",
     ],
 }
 
@@ -79,6 +88,6 @@
 rust_defaults {
     name: "keymint_use_latest_hal_aidl_rust",
     rustlibs: [
-        "android.hardware.security.keymint-V2-rust",
+        "android.hardware.security.keymint-V3-rust",
     ],
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/.hash b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/.hash
index b712a52..3a6d415 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/.hash
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/.hash
@@ -1 +1,2 @@
 976674616001f714f4a4df49ee45f548de828524
+cd862ae2e49b54fc965dc1b99c218eb729c93bb1
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/.hash b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/.hash
index 69ba9a6..b4c2b78 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/.hash
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/.hash
@@ -1 +1,2 @@
 207c9f218b9b9e4e74ff5232eb16511eca9d7d2e
+70c734fbd5cac5b36676d66d8d9aa941967e1e7b
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/.hash b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/.hash
new file mode 100644
index 0000000..d8a0378
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/.hash
@@ -0,0 +1 @@
+74a538630d5d90f732f361a2313cbb69b09eb047
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Algorithm.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Algorithm.aidl
new file mode 100644
index 0000000..6da124f
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Algorithm.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Algorithm {
+  RSA = 1,
+  EC = 3,
+  AES = 32,
+  TRIPLE_DES = 33,
+  HMAC = 128,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/AttestationKey.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/AttestationKey.aidl
new file mode 100644
index 0000000..90f2e6e
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/AttestationKey.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.security.keymint;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable AttestationKey {
+  byte[] keyBlob;
+  android.hardware.security.keymint.KeyParameter[] attestKeyParams;
+  byte[] issuerSubjectName;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/BeginResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/BeginResult.aidl
new file mode 100644
index 0000000..c952a31
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/BeginResult.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@VintfStability
+parcelable BeginResult {
+  long challenge;
+  android.hardware.security.keymint.KeyParameter[] params;
+  android.hardware.security.keymint.IKeyMintOperation operation;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/BlockMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/BlockMode.aidl
new file mode 100644
index 0000000..0049883
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/BlockMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum BlockMode {
+  ECB = 1,
+  CBC = 2,
+  CTR = 3,
+  GCM = 32,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Certificate.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Certificate.aidl
new file mode 100644
index 0000000..645f0a7
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Certificate.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.security.keymint;
+/* @hide */
+@VintfStability
+parcelable Certificate {
+  byte[] encodedCertificate;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Digest.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Digest.aidl
new file mode 100644
index 0000000..0df7096
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Digest.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Digest {
+  NONE = 0,
+  MD5 = 1,
+  SHA1 = 2,
+  SHA_2_224 = 3,
+  SHA_2_256 = 4,
+  SHA_2_384 = 5,
+  SHA_2_512 = 6,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/EcCurve.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/EcCurve.aidl
new file mode 100644
index 0000000..ffc7efe
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/EcCurve.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum EcCurve {
+  P_224 = 0,
+  P_256 = 1,
+  P_384 = 2,
+  P_521 = 3,
+  CURVE_25519 = 4,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/ErrorCode.aidl
new file mode 100644
index 0000000..6d49c44
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/ErrorCode.aidl
@@ -0,0 +1,125 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ErrorCode {
+  OK = 0,
+  ROOT_OF_TRUST_ALREADY_SET = (-1) /* -1 */,
+  UNSUPPORTED_PURPOSE = (-2) /* -2 */,
+  INCOMPATIBLE_PURPOSE = (-3) /* -3 */,
+  UNSUPPORTED_ALGORITHM = (-4) /* -4 */,
+  INCOMPATIBLE_ALGORITHM = (-5) /* -5 */,
+  UNSUPPORTED_KEY_SIZE = (-6) /* -6 */,
+  UNSUPPORTED_BLOCK_MODE = (-7) /* -7 */,
+  INCOMPATIBLE_BLOCK_MODE = (-8) /* -8 */,
+  UNSUPPORTED_MAC_LENGTH = (-9) /* -9 */,
+  UNSUPPORTED_PADDING_MODE = (-10) /* -10 */,
+  INCOMPATIBLE_PADDING_MODE = (-11) /* -11 */,
+  UNSUPPORTED_DIGEST = (-12) /* -12 */,
+  INCOMPATIBLE_DIGEST = (-13) /* -13 */,
+  INVALID_EXPIRATION_TIME = (-14) /* -14 */,
+  INVALID_USER_ID = (-15) /* -15 */,
+  INVALID_AUTHORIZATION_TIMEOUT = (-16) /* -16 */,
+  UNSUPPORTED_KEY_FORMAT = (-17) /* -17 */,
+  INCOMPATIBLE_KEY_FORMAT = (-18) /* -18 */,
+  UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = (-19) /* -19 */,
+  UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = (-20) /* -20 */,
+  INVALID_INPUT_LENGTH = (-21) /* -21 */,
+  KEY_EXPORT_OPTIONS_INVALID = (-22) /* -22 */,
+  DELEGATION_NOT_ALLOWED = (-23) /* -23 */,
+  KEY_NOT_YET_VALID = (-24) /* -24 */,
+  KEY_EXPIRED = (-25) /* -25 */,
+  KEY_USER_NOT_AUTHENTICATED = (-26) /* -26 */,
+  OUTPUT_PARAMETER_NULL = (-27) /* -27 */,
+  INVALID_OPERATION_HANDLE = (-28) /* -28 */,
+  INSUFFICIENT_BUFFER_SPACE = (-29) /* -29 */,
+  VERIFICATION_FAILED = (-30) /* -30 */,
+  TOO_MANY_OPERATIONS = (-31) /* -31 */,
+  UNEXPECTED_NULL_POINTER = (-32) /* -32 */,
+  INVALID_KEY_BLOB = (-33) /* -33 */,
+  IMPORTED_KEY_NOT_ENCRYPTED = (-34) /* -34 */,
+  IMPORTED_KEY_DECRYPTION_FAILED = (-35) /* -35 */,
+  IMPORTED_KEY_NOT_SIGNED = (-36) /* -36 */,
+  IMPORTED_KEY_VERIFICATION_FAILED = (-37) /* -37 */,
+  INVALID_ARGUMENT = (-38) /* -38 */,
+  UNSUPPORTED_TAG = (-39) /* -39 */,
+  INVALID_TAG = (-40) /* -40 */,
+  MEMORY_ALLOCATION_FAILED = (-41) /* -41 */,
+  IMPORT_PARAMETER_MISMATCH = (-44) /* -44 */,
+  SECURE_HW_ACCESS_DENIED = (-45) /* -45 */,
+  OPERATION_CANCELLED = (-46) /* -46 */,
+  CONCURRENT_ACCESS_CONFLICT = (-47) /* -47 */,
+  SECURE_HW_BUSY = (-48) /* -48 */,
+  SECURE_HW_COMMUNICATION_FAILED = (-49) /* -49 */,
+  UNSUPPORTED_EC_FIELD = (-50) /* -50 */,
+  MISSING_NONCE = (-51) /* -51 */,
+  INVALID_NONCE = (-52) /* -52 */,
+  MISSING_MAC_LENGTH = (-53) /* -53 */,
+  KEY_RATE_LIMIT_EXCEEDED = (-54) /* -54 */,
+  CALLER_NONCE_PROHIBITED = (-55) /* -55 */,
+  KEY_MAX_OPS_EXCEEDED = (-56) /* -56 */,
+  INVALID_MAC_LENGTH = (-57) /* -57 */,
+  MISSING_MIN_MAC_LENGTH = (-58) /* -58 */,
+  UNSUPPORTED_MIN_MAC_LENGTH = (-59) /* -59 */,
+  UNSUPPORTED_KDF = (-60) /* -60 */,
+  UNSUPPORTED_EC_CURVE = (-61) /* -61 */,
+  KEY_REQUIRES_UPGRADE = (-62) /* -62 */,
+  ATTESTATION_CHALLENGE_MISSING = (-63) /* -63 */,
+  KEYMINT_NOT_CONFIGURED = (-64) /* -64 */,
+  ATTESTATION_APPLICATION_ID_MISSING = (-65) /* -65 */,
+  CANNOT_ATTEST_IDS = (-66) /* -66 */,
+  ROLLBACK_RESISTANCE_UNAVAILABLE = (-67) /* -67 */,
+  HARDWARE_TYPE_UNAVAILABLE = (-68) /* -68 */,
+  PROOF_OF_PRESENCE_REQUIRED = (-69) /* -69 */,
+  CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = (-70) /* -70 */,
+  NO_USER_CONFIRMATION = (-71) /* -71 */,
+  DEVICE_LOCKED = (-72) /* -72 */,
+  EARLY_BOOT_ENDED = (-73) /* -73 */,
+  ATTESTATION_KEYS_NOT_PROVISIONED = (-74) /* -74 */,
+  ATTESTATION_IDS_NOT_PROVISIONED = (-75) /* -75 */,
+  INVALID_OPERATION = (-76) /* -76 */,
+  STORAGE_KEY_UNSUPPORTED = (-77) /* -77 */,
+  INCOMPATIBLE_MGF_DIGEST = (-78) /* -78 */,
+  UNSUPPORTED_MGF_DIGEST = (-79) /* -79 */,
+  MISSING_NOT_BEFORE = (-80) /* -80 */,
+  MISSING_NOT_AFTER = (-81) /* -81 */,
+  MISSING_ISSUER_SUBJECT = (-82) /* -82 */,
+  INVALID_ISSUER_SUBJECT = (-83) /* -83 */,
+  BOOT_LEVEL_EXCEEDED = (-84) /* -84 */,
+  HARDWARE_NOT_YET_AVAILABLE = (-85) /* -85 */,
+  UNIMPLEMENTED = (-100) /* -100 */,
+  VERSION_MISMATCH = (-101) /* -101 */,
+  UNKNOWN_ERROR = (-1000) /* -1000 */,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/HardwareAuthToken.aidl
new file mode 100644
index 0000000..2e07924
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/HardwareAuthToken.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 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.security.keymint;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable HardwareAuthToken {
+  long challenge;
+  long userId;
+  long authenticatorId;
+  android.hardware.security.keymint.HardwareAuthenticatorType authenticatorType = android.hardware.security.keymint.HardwareAuthenticatorType.NONE;
+  android.hardware.security.secureclock.Timestamp timestamp;
+  byte[] mac;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/HardwareAuthenticatorType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/HardwareAuthenticatorType.aidl
new file mode 100644
index 0000000..eb4f621
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/HardwareAuthenticatorType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum HardwareAuthenticatorType {
+  NONE = 0,
+  PASSWORD = (1 << 0) /* 1 */,
+  FINGERPRINT = (1 << 1) /* 2 */,
+  ANY = 0xFFFFFFFF,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/IKeyMintDevice.aidl
new file mode 100644
index 0000000..dcc22c4
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@SensitiveData @VintfStability
+interface IKeyMintDevice {
+  android.hardware.security.keymint.KeyMintHardwareInfo getHardwareInfo();
+  void addRngEntropy(in byte[] data);
+  android.hardware.security.keymint.KeyCreationResult generateKey(in android.hardware.security.keymint.KeyParameter[] keyParams, in @nullable android.hardware.security.keymint.AttestationKey attestationKey);
+  android.hardware.security.keymint.KeyCreationResult importKey(in android.hardware.security.keymint.KeyParameter[] keyParams, in android.hardware.security.keymint.KeyFormat keyFormat, in byte[] keyData, in @nullable android.hardware.security.keymint.AttestationKey attestationKey);
+  android.hardware.security.keymint.KeyCreationResult importWrappedKey(in byte[] wrappedKeyData, in byte[] wrappingKeyBlob, in byte[] maskingKey, in android.hardware.security.keymint.KeyParameter[] unwrappingParams, in long passwordSid, in long biometricSid);
+  byte[] upgradeKey(in byte[] keyBlobToUpgrade, in android.hardware.security.keymint.KeyParameter[] upgradeParams);
+  void deleteKey(in byte[] keyBlob);
+  void deleteAllKeys();
+  void destroyAttestationIds();
+  android.hardware.security.keymint.BeginResult begin(in android.hardware.security.keymint.KeyPurpose purpose, in byte[] keyBlob, in android.hardware.security.keymint.KeyParameter[] params, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken);
+  void deviceLocked(in boolean passwordOnly, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken);
+  void earlyBootEnded();
+  byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob);
+  android.hardware.security.keymint.KeyCharacteristics[] getKeyCharacteristics(in byte[] keyBlob, in byte[] appId, in byte[] appData);
+  byte[16] getRootOfTrustChallenge();
+  byte[] getRootOfTrust(in byte[16] challenge);
+  void sendRootOfTrust(in byte[] rootOfTrust);
+  const int AUTH_TOKEN_MAC_LENGTH = 32;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/IKeyMintOperation.aidl
new file mode 100644
index 0000000..4ab4ffe
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@SensitiveData @VintfStability
+interface IKeyMintOperation {
+  void updateAad(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken);
+  byte[] update(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken);
+  byte[] finish(in @nullable byte[] input, in @nullable byte[] signature, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken, in @nullable byte[] confirmationToken);
+  void abort();
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyCharacteristics.aidl
new file mode 100644
index 0000000..008381f
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyCharacteristics.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@VintfStability
+parcelable KeyCharacteristics {
+  android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE;
+  android.hardware.security.keymint.KeyParameter[] authorizations;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyCreationResult.aidl
new file mode 100644
index 0000000..9f77d3e
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.security.keymint;
+/* @hide */
+@VintfStability
+parcelable KeyCreationResult {
+  byte[] keyBlob;
+  android.hardware.security.keymint.KeyCharacteristics[] keyCharacteristics;
+  android.hardware.security.keymint.Certificate[] certificateChain;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyFormat.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyFormat.aidl
new file mode 100644
index 0000000..9560d8d
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyFormat.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum KeyFormat {
+  X509 = 0,
+  PKCS8 = 1,
+  RAW = 3,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
new file mode 100644
index 0000000..2113e42a
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable KeyMintHardwareInfo {
+  int versionNumber;
+  android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE;
+  @utf8InCpp String keyMintName;
+  @utf8InCpp String keyMintAuthorName;
+  boolean timestampTokenRequired;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyOrigin.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyOrigin.aidl
new file mode 100644
index 0000000..4b3c659
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyOrigin.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum KeyOrigin {
+  GENERATED = 0,
+  DERIVED = 1,
+  IMPORTED = 2,
+  RESERVED = 3,
+  SECURELY_IMPORTED = 4,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyParameter.aidl
new file mode 100644
index 0000000..c5a1e01
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyParameter.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable KeyParameter {
+  android.hardware.security.keymint.Tag tag = android.hardware.security.keymint.Tag.INVALID;
+  android.hardware.security.keymint.KeyParameterValue value;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyParameterValue.aidl
new file mode 100644
index 0000000..7a0b074
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyParameterValue.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+union KeyParameterValue {
+  int invalid;
+  android.hardware.security.keymint.Algorithm algorithm;
+  android.hardware.security.keymint.BlockMode blockMode;
+  android.hardware.security.keymint.PaddingMode paddingMode;
+  android.hardware.security.keymint.Digest digest;
+  android.hardware.security.keymint.EcCurve ecCurve;
+  android.hardware.security.keymint.KeyOrigin origin;
+  android.hardware.security.keymint.KeyPurpose keyPurpose;
+  android.hardware.security.keymint.HardwareAuthenticatorType hardwareAuthenticatorType;
+  android.hardware.security.keymint.SecurityLevel securityLevel;
+  boolean boolValue;
+  int integer;
+  long longInteger;
+  long dateTime;
+  byte[] blob;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyPurpose.aidl
new file mode 100644
index 0000000..b84bec1
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/KeyPurpose.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum KeyPurpose {
+  ENCRYPT = 0,
+  DECRYPT = 1,
+  SIGN = 2,
+  VERIFY = 3,
+  WRAP_KEY = 5,
+  AGREE_KEY = 6,
+  ATTEST_KEY = 7,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/PaddingMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/PaddingMode.aidl
new file mode 100644
index 0000000..dba4a8a
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/PaddingMode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum PaddingMode {
+  NONE = 1,
+  RSA_OAEP = 2,
+  RSA_PSS = 3,
+  RSA_PKCS1_1_5_ENCRYPT = 4,
+  RSA_PKCS1_1_5_SIGN = 5,
+  PKCS7 = 64,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/SecurityLevel.aidl
new file mode 100644
index 0000000..0d278e0
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/SecurityLevel.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum SecurityLevel {
+  SOFTWARE = 0,
+  TRUSTED_ENVIRONMENT = 1,
+  STRONGBOX = 2,
+  KEYSTORE = 100,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Tag.aidl
new file mode 100644
index 0000000..0d30c0a
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/Tag.aidl
@@ -0,0 +1,104 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Tag {
+  INVALID = 0,
+  PURPOSE = (android.hardware.security.keymint.TagType.ENUM_REP | 1) /* 536870913 */,
+  ALGORITHM = (android.hardware.security.keymint.TagType.ENUM | 2) /* 268435458 */,
+  KEY_SIZE = (android.hardware.security.keymint.TagType.UINT | 3) /* 805306371 */,
+  BLOCK_MODE = (android.hardware.security.keymint.TagType.ENUM_REP | 4) /* 536870916 */,
+  DIGEST = (android.hardware.security.keymint.TagType.ENUM_REP | 5) /* 536870917 */,
+  PADDING = (android.hardware.security.keymint.TagType.ENUM_REP | 6) /* 536870918 */,
+  CALLER_NONCE = (android.hardware.security.keymint.TagType.BOOL | 7) /* 1879048199 */,
+  MIN_MAC_LENGTH = (android.hardware.security.keymint.TagType.UINT | 8) /* 805306376 */,
+  EC_CURVE = (android.hardware.security.keymint.TagType.ENUM | 10) /* 268435466 */,
+  RSA_PUBLIC_EXPONENT = (android.hardware.security.keymint.TagType.ULONG | 200) /* 1342177480 */,
+  INCLUDE_UNIQUE_ID = (android.hardware.security.keymint.TagType.BOOL | 202) /* 1879048394 */,
+  RSA_OAEP_MGF_DIGEST = (android.hardware.security.keymint.TagType.ENUM_REP | 203) /* 536871115 */,
+  BOOTLOADER_ONLY = (android.hardware.security.keymint.TagType.BOOL | 302) /* 1879048494 */,
+  ROLLBACK_RESISTANCE = (android.hardware.security.keymint.TagType.BOOL | 303) /* 1879048495 */,
+  HARDWARE_TYPE = (android.hardware.security.keymint.TagType.ENUM | 304) /* 268435760 */,
+  EARLY_BOOT_ONLY = (android.hardware.security.keymint.TagType.BOOL | 305) /* 1879048497 */,
+  ACTIVE_DATETIME = (android.hardware.security.keymint.TagType.DATE | 400) /* 1610613136 */,
+  ORIGINATION_EXPIRE_DATETIME = (android.hardware.security.keymint.TagType.DATE | 401) /* 1610613137 */,
+  USAGE_EXPIRE_DATETIME = (android.hardware.security.keymint.TagType.DATE | 402) /* 1610613138 */,
+  MIN_SECONDS_BETWEEN_OPS = (android.hardware.security.keymint.TagType.UINT | 403) /* 805306771 */,
+  MAX_USES_PER_BOOT = (android.hardware.security.keymint.TagType.UINT | 404) /* 805306772 */,
+  USAGE_COUNT_LIMIT = (android.hardware.security.keymint.TagType.UINT | 405) /* 805306773 */,
+  USER_ID = (android.hardware.security.keymint.TagType.UINT | 501) /* 805306869 */,
+  USER_SECURE_ID = (android.hardware.security.keymint.TagType.ULONG_REP | 502) /* -1610612234 */,
+  NO_AUTH_REQUIRED = (android.hardware.security.keymint.TagType.BOOL | 503) /* 1879048695 */,
+  USER_AUTH_TYPE = (android.hardware.security.keymint.TagType.ENUM | 504) /* 268435960 */,
+  AUTH_TIMEOUT = (android.hardware.security.keymint.TagType.UINT | 505) /* 805306873 */,
+  ALLOW_WHILE_ON_BODY = (android.hardware.security.keymint.TagType.BOOL | 506) /* 1879048698 */,
+  TRUSTED_USER_PRESENCE_REQUIRED = (android.hardware.security.keymint.TagType.BOOL | 507) /* 1879048699 */,
+  TRUSTED_CONFIRMATION_REQUIRED = (android.hardware.security.keymint.TagType.BOOL | 508) /* 1879048700 */,
+  UNLOCKED_DEVICE_REQUIRED = (android.hardware.security.keymint.TagType.BOOL | 509) /* 1879048701 */,
+  APPLICATION_ID = (android.hardware.security.keymint.TagType.BYTES | 601) /* -1879047591 */,
+  APPLICATION_DATA = (android.hardware.security.keymint.TagType.BYTES | 700) /* -1879047492 */,
+  CREATION_DATETIME = (android.hardware.security.keymint.TagType.DATE | 701) /* 1610613437 */,
+  ORIGIN = (android.hardware.security.keymint.TagType.ENUM | 702) /* 268436158 */,
+  ROOT_OF_TRUST = (android.hardware.security.keymint.TagType.BYTES | 704) /* -1879047488 */,
+  OS_VERSION = (android.hardware.security.keymint.TagType.UINT | 705) /* 805307073 */,
+  OS_PATCHLEVEL = (android.hardware.security.keymint.TagType.UINT | 706) /* 805307074 */,
+  UNIQUE_ID = (android.hardware.security.keymint.TagType.BYTES | 707) /* -1879047485 */,
+  ATTESTATION_CHALLENGE = (android.hardware.security.keymint.TagType.BYTES | 708) /* -1879047484 */,
+  ATTESTATION_APPLICATION_ID = (android.hardware.security.keymint.TagType.BYTES | 709) /* -1879047483 */,
+  ATTESTATION_ID_BRAND = (android.hardware.security.keymint.TagType.BYTES | 710) /* -1879047482 */,
+  ATTESTATION_ID_DEVICE = (android.hardware.security.keymint.TagType.BYTES | 711) /* -1879047481 */,
+  ATTESTATION_ID_PRODUCT = (android.hardware.security.keymint.TagType.BYTES | 712) /* -1879047480 */,
+  ATTESTATION_ID_SERIAL = (android.hardware.security.keymint.TagType.BYTES | 713) /* -1879047479 */,
+  ATTESTATION_ID_IMEI = (android.hardware.security.keymint.TagType.BYTES | 714) /* -1879047478 */,
+  ATTESTATION_ID_MEID = (android.hardware.security.keymint.TagType.BYTES | 715) /* -1879047477 */,
+  ATTESTATION_ID_MANUFACTURER = (android.hardware.security.keymint.TagType.BYTES | 716) /* -1879047476 */,
+  ATTESTATION_ID_MODEL = (android.hardware.security.keymint.TagType.BYTES | 717) /* -1879047475 */,
+  VENDOR_PATCHLEVEL = (android.hardware.security.keymint.TagType.UINT | 718) /* 805307086 */,
+  BOOT_PATCHLEVEL = (android.hardware.security.keymint.TagType.UINT | 719) /* 805307087 */,
+  DEVICE_UNIQUE_ATTESTATION = (android.hardware.security.keymint.TagType.BOOL | 720) /* 1879048912 */,
+  IDENTITY_CREDENTIAL_KEY = (android.hardware.security.keymint.TagType.BOOL | 721) /* 1879048913 */,
+  STORAGE_KEY = (android.hardware.security.keymint.TagType.BOOL | 722) /* 1879048914 */,
+  ATTESTATION_ID_SECOND_IMEI = (android.hardware.security.keymint.TagType.BYTES | 723) /* -1879047469 */,
+  ASSOCIATED_DATA = (android.hardware.security.keymint.TagType.BYTES | 1000) /* -1879047192 */,
+  NONCE = (android.hardware.security.keymint.TagType.BYTES | 1001) /* -1879047191 */,
+  MAC_LENGTH = (android.hardware.security.keymint.TagType.UINT | 1003) /* 805307371 */,
+  RESET_SINCE_ID_ROTATION = (android.hardware.security.keymint.TagType.BOOL | 1004) /* 1879049196 */,
+  CONFIRMATION_TOKEN = (android.hardware.security.keymint.TagType.BYTES | 1005) /* -1879047187 */,
+  CERTIFICATE_SERIAL = (android.hardware.security.keymint.TagType.BIGNUM | 1006) /* -2147482642 */,
+  CERTIFICATE_SUBJECT = (android.hardware.security.keymint.TagType.BYTES | 1007) /* -1879047185 */,
+  CERTIFICATE_NOT_BEFORE = (android.hardware.security.keymint.TagType.DATE | 1008) /* 1610613744 */,
+  CERTIFICATE_NOT_AFTER = (android.hardware.security.keymint.TagType.DATE | 1009) /* 1610613745 */,
+  MAX_BOOT_LEVEL = (android.hardware.security.keymint.TagType.UINT | 1010) /* 805307378 */,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/TagType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/TagType.aidl
new file mode 100644
index 0000000..ca19e7e
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/3/android/hardware/security/keymint/TagType.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum TagType {
+  INVALID = (0 << 28) /* 0 */,
+  ENUM = (1 << 28) /* 268435456 */,
+  ENUM_REP = (2 << 28) /* 536870912 */,
+  UINT = (3 << 28) /* 805306368 */,
+  UINT_REP = (4 << 28) /* 1073741824 */,
+  ULONG = (5 << 28) /* 1342177280 */,
+  DATE = (6 << 28) /* 1610612736 */,
+  BOOL = (7 << 28) /* 1879048192 */,
+  BIGNUM = (8 << 28) /* -2147483648 */,
+  BYTES = (9 << 28) /* -1879048192 */,
+  ULONG_REP = (10 << 28) /* -1610612736 */,
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
deleted file mode 100644
index f566462..0000000
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.security.keymint;
-/* @hide */
-@VintfStability
-interface IRemotelyProvisionedComponent {
-  android.hardware.security.keymint.RpcHardwareInfo getHardwareInfo();
-  byte[] generateEcdsaP256KeyPair(in boolean testMode, out android.hardware.security.keymint.MacedPublicKey macedPublicKey);
-  byte[] generateCertificateRequest(in boolean testMode, in android.hardware.security.keymint.MacedPublicKey[] keysToSign, in byte[] endpointEncryptionCertChain, in byte[] challenge, out android.hardware.security.keymint.DeviceInfo deviceInfo, out android.hardware.security.keymint.ProtectedData protectedData);
-  const int STATUS_FAILED = 1;
-  const int STATUS_INVALID_MAC = 2;
-  const int STATUS_PRODUCTION_KEY_IN_TEST_REQUEST = 3;
-  const int STATUS_TEST_KEY_IN_PRODUCTION_REQUEST = 4;
-  const int STATUS_INVALID_EEK = 5;
-}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl
deleted file mode 100644
index 5ff45f8..0000000
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.security.keymint;
-/* @hide */
-@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
-parcelable RpcHardwareInfo {
-  int versionNumber;
-  @utf8InCpp String rpcAuthorName;
-  int supportedEekCurve = 0;
-  @nullable @utf8InCpp String uniqueId;
-  const int CURVE_NONE = 0;
-  const int CURVE_P256 = 1;
-  const int CURVE_25519 = 2;
-}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
index e310b44..6ae2369 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
@@ -90,6 +90,7 @@
   DEVICE_UNIQUE_ATTESTATION = 1879048912,
   IDENTITY_CREDENTIAL_KEY = 1879048913,
   STORAGE_KEY = 1879048914,
+  ATTESTATION_ID_SECOND_IMEI = -1879047469,
   ASSOCIATED_DATA = -1879047192,
   NONCE = -1879047191,
   MAC_LENGTH = 805307371,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
deleted file mode 100644
index abb2a7b..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
+++ /dev/null
@@ -1,56 +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.security.keymint;
-
-/**
- * DeviceInfo contains information about the device that's fed in as AAD in the signature of the
- * device private key over the MAC key used for the bundle of public keys. These values are intended
- * to be checked by the server to verify that the certificate signing request crafted by
- * an IRemotelyProvisionedComponent HAL instance is coming from the expected device based
- * on values initially uploaded during device manufacture in the factory.
- * @hide
- */
-@VintfStability
-parcelable DeviceInfo {
-    /**
-     * DeviceInfo is a CBOR Map structure described by the following CDDL. DeviceInfo must be
-     * canonicalized according to the specification in RFC 7049. The ordering presented here is
-     * non-canonical to group similar entries semantically.
-     *
-     *     DeviceInfo = {
-     *         "brand" : tstr,
-     *         "manufacturer" : tstr,
-     *         "product" : tstr,
-     *         "model" : tstr,
-     *         "device" : tstr,
-     *         "vb_state" : "green" / "yellow" / "orange",    // Taken from the AVB values
-     *         "bootloader_state" : "locked" / "unlocked",    // Taken from the AVB values
-     *         "vbmeta_digest": bstr,                         // Taken from the AVB values
-     *         ? "os_version" : tstr,                         // Same as
-     *                                                        // android.os.Build.VERSION.release
-     *                                                        // Not optional for TEE.
-     *         "system_patch_level" : uint,                   // YYYYMMDD
-     *         "boot_patch_level" : uint,                     // YYYYMMDD
-     *         "vendor_patch_level" : uint,                   // YYYYMMDD
-     *         "version" : 2,                                 // The CDDL schema version.
-     *         "security_level" : "tee" / "strongbox",
-     *         "fused": 1 / 0,  // 1 if secure boot is enforced for the processor that the IRPC
-     *                          // implementation is contained in. 0 otherwise.
-     *     }
-     */
-    byte[] deviceInfo;
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 95a3710..2e4fc15 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -196,12 +196,12 @@
  * derive a key that is used to encrypt the private/secret key material.
  *
  * The root of trust consists of a bitstring that must be derived from the public key used by
- * Verified Boot to verify the signature on the boot image and from the lock state of the
- * device.  If the public key is changed to allow a different system image to be used or if the
- * lock state is changed, then all of the IKeyMintDevice-protected keys created by the previous
- * system state must be unusable, unless the previous state is restored.  The goal is to increase
- * the value of the software-enforced key access controls by making it impossible for an attacker-
- * installed operating system to use IKeyMintDevice keys.
+ * Verified Boot to verify the signature on the boot image, from the lock state and from the
+ * Verified Boot state of the device.  If the public key is changed to allow a different system
+ * image to be used or if the lock state is changed, then all of the IKeyMintDevice-protected keys
+ * created by the previous system state must be unusable, unless the previous state is restored.
+ * The goal is to increase the value of the software-enforced key access controls by making it
+ * impossible for an attacker-installed operating system to use IKeyMintDevice keys.
  *
  * == Version Binding ==
  *
@@ -336,6 +336,17 @@
      * Only Tag::KEY_SIZE is required to generate an 3DES key, and its value must be 168.  If
      * omitted, generateKey must return ErrorCode::UNSUPPORTED_KEY_SIZE.
      *
+     * == HMAC Keys ==
+     *
+     * Tag::KEY_SIZE must be provided to generate an HMAC key, and its value must be >= 64 and a
+     * multiple of 8.  All devices must support key sizes up to 512 bits, but StrongBox devices must
+     * not support key sizes larger than 512 bits.  If omitted or invalid, generateKey() must return
+     * ErrorCode::UNSUPPORTED_KEY_SIZE.
+     *
+     * Tag::MIN_MAC_LENGTH must be provided, and must be a multiple of 8 in the range 64 to 512
+     * bits (inclusive). If omitted, generateKey must return ErrorCode::MISSING_MIN_MAC_LENGTH; if
+     * invalid, generateKey must return ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH.
+     *
      * @param keyParams Key generation parameters are defined as KeyMintDevice tag/value pairs,
      *        provided in params.  See above for detailed specifications of which tags are required
      *        for which types of keys.
@@ -613,9 +624,15 @@
      *
      *   o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
      *
-     *   o The timestamp in the auth token plus the value of the Tag::AUTH_TIMEOUT must be less than
-     *     the current secure timestamp (which is a monotonic timer counting milliseconds since
-     *     boot.)
+     *   o If the device has a source of secure time, then the timestamp in the auth token plus the
+     *     value of the Tag::AUTH_TIMEOUT must be greater than the current secure timestamp (which
+     *     is a monotonic timer counting milliseconds since boot).
+     *
+     *   o If the device does not have a source of secure time, then the timestamp check should be
+     *     performed on the first update(), updateAad() or finish() invocation for the operation,
+     *     using the timeStampToken parameter provided on the invocation to indicate the current
+     *     timestamp. It may optionally also be performed on subsequent update() / updateAad() /
+     *     finish() invocations.
      *
      *   If any of these conditions are not met, begin() must return
      *   ErrorCode::KEY_USER_NOT_AUTHENTICATED.
@@ -661,19 +678,19 @@
      *   structure, because it cannot add the DigestInfo structure.  Instead, the IKeyMintDevice
      *   must construct 0x00 || 0x01 || PS || 0x00 || M, where M is the provided message and PS is a
      *   random padding string at least eight bytes in length.  The size of the RSA key has to be at
-     *   least 11 bytes larger than the message, otherwise begin() must return
+     *   least 11 bytes larger than the message, otherwise finish() must return
      *   ErrorCode::INVALID_INPUT_LENGTH.
      *
      * o PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT padding does not require a digest.
      *
-     * o PaddingMode::RSA_PSS padding requires a digest, which must match one of the padding values
+     * o PaddingMode::RSA_PSS padding requires a digest, which must match one of the digest values
      *   in the key authorizations, and which may not be Digest::NONE.  begin() must return
      *   ErrorCode::INCOMPATIBLE_DIGEST if this is not the case.  In addition, the size of the RSA
-     *   key must be at least 2 + D bytes larger than the output size of the digest, where D is the
-     *   size of the digest, in bytes.  Otherwise begin() must return
-     *   ErrorCode::INCOMPATIBLE_DIGEST.  The salt size must be D.
+     *   key must be at least (D + S + 9) bits, where D is the size of the digest (in bits) and
+     *   S is the size of the salt (in bits).  The salt size S must equal D, so the RSA key must
+     *   be at least (2*D + 9) bits. Otherwise begin() must return ErrorCode::INCOMPATIBLE_DIGEST.
      *
-     * o PaddingMode::RSA_OAEP padding requires a digest, which must match one of the padding values
+     * o PaddingMode::RSA_OAEP padding requires a digest, which must match one of the digest values
      *   in the key authorizations, and which may not be Digest::NONE.  begin() must return
      *   ErrorCode::INCOMPATIBLE_DIGEST if this is not the case.  RSA_OAEP padding also requires an
      *   MGF1 digest, specified with Tag::RSA_OAEP_MGF_DIGEST, which must match one of the MGF1
@@ -683,9 +700,9 @@
      *
      * -- EC Keys --
      *
-     * Private key operations (KeyPurpose::SIGN) need authorization of digest and padding, which
-     * means that the key authorizations must contain the specified values.  If not, begin() must
-     * return ErrorCode::INCOMPATIBLE_DIGEST.
+     * Private key operations (KeyPurpose::SIGN) need authorization of digest, which means that the
+     * key authorizations must contain the specified values.  If not, begin() must return
+     * ErrorCode::INCOMPATIBLE_DIGEST.
      *
      * -- AES Keys --
      *
@@ -804,7 +821,7 @@
     /**
      * Called by client to notify the IKeyMintDevice that the device has left the early boot
      * state, and that keys with the EARLY_BOOT_ONLY tag may no longer be used.  All attempts to use
-     * an EARLY_BOOT_ONLY key after this method is called must fail with Error::INVALID_KEY_BLOB.
+     * an EARLY_BOOT_ONLY key after this method is called must fail with Error::EARLY_BOOT_ENDED.
      */
     void earlyBootEnded();
 
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index c30c183..82c8a0d 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -40,31 +40,7 @@
      *
      * == Authorization Enforcement ==
      *
-     * Key authorization enforcement is performed primarily in begin().  The one exception is the
-     * case where the key has:
-     *
-     * o One or more Tag::USER_SECURE_IDs, and
-     *
-     * o Does not have a Tag::AUTH_TIMEOUT
-     *
-     * In this case, the key requires an authorization per operation, and the update method must
-     * receive a non-null and valid HardwareAuthToken.  For the auth token to be valid, all of the
-     * following has to be true:
-     *
-     *   o The HMAC field must validate correctly.
-     *
-     *   o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
-     *     the secure ID values in the token.
-     *
-     *   o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
-     *
-     *   o The challenge field in the auth token must contain the value returned from
-     *     IKeyMintDevice::begin(), given by the challenge field of the BeginResult structure.
-     *
-     *   If any of these conditions are not met, updateAad() must return
-     *   ErrorCode::KEY_USER_NOT_AUTHENTICATED.
-     *
-     * The caller must provide the auth token on every call to updateAad(), update() and finish().
+     * See the Authorization Enforcement section for the update() method.
      *
      *
      * For GCM encryption, the AEAD tag must be appended to the ciphertext by finish().  During
@@ -104,16 +80,22 @@
      *
      * == Authorization Enforcement ==
      *
-     * Key authorization enforcement is performed primarily in IKeyMintDevice::begin().  The one
-     * exception is the case where the key has:
+     * Key authorization enforcement is performed primarily in IKeyMintDevice::begin().  There are
+     * two exceptions to this:
      *
-     * o One or more Tag::USER_SECURE_IDs, and
+     *  1) Key with USER_SECURE_IDs but no AUTH_TIMEOUT
      *
-     * o Does not have a Tag::AUTH_TIMEOUT
+     *  2) Key with USER_SECURE_IDs and AUTH_TIMEOUT, but the device does not support secure time.
      *
-     * In this case, the key requires an authorization per operation, and the update method must
-     * receive a non-empty and valid HardwareAuthToken.  For the auth token to be valid, all of the
-     * following has to be true:
+     * The first exception is the case where the key:
+     *
+     *   o Has one or more Tag::USER_SECURE_IDs, and
+     *
+     *   o Does not have a Tag::AUTH_TIMEOUT
+     *
+     * In this case, the key requires an authorization per operation, and update() / updateAad() /
+     * finish() methods must receive a non-null and valid HardwareAuthToken.  For the auth token to
+     * be valid, all of the following has to be true:
      *
      *   o The HMAC field must validate correctly.
      *
@@ -125,10 +107,47 @@
      *   o The challenge field in the auth token must contain the challenge value contained in the
      *     BeginResult returned from IKeyMintDevice::begin().
      *
-     *   If any of these conditions are not met, update() must return
+     *   If any of these conditions are not met, the method must return
      *   ErrorCode::KEY_USER_NOT_AUTHENTICATED.
      *
-     * The caller must provide the auth token on every call to update() and finish().
+     * The caller must provide the auth token on every call to update(), updateAad() and finish().
+     *
+     *
+     * The second exception is the case where the key:
+     *
+     *   o Has one or more Tag::USER_SECURE_IDs, and
+     *
+     *   o Has a Tag::AUTH_TIMEOUT value, but the device does not have a source of secure time (as
+     *     indicated by the KeyMintHardwareInfo.timestampTokenRequired field).
+     *
+     * In this case, the key requires an per-operation authorization on the first call to update(),
+     * updateAad() or finish() for the operation, using the provided timeStampToken as a source of
+     * secure time.  For this timeStampToken to be valid, all of the following has to be true:
+     *
+     *   o The HMAC field must validate correctly.
+     *
+     *   o The challenge field in the auth token must contain the challenge value contained in the
+     *     BeginResult returned from IKeyMintDevice::begin().
+     *
+     * The resulting secure time value is then used to authenticate the HardwareAuthToken. For the
+     * auth token to be valid, all of the following has to be true:
+     *
+     *   o The HMAC field must validate correctly.
+     *
+     *   o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
+     *     the secure ID values in the token.
+     *
+     *   o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
+     *
+     *   o The challenge field in the auth token must contain the challenge value contained in the
+     *     BeginResult returned from IKeyMintDevice::begin().
+     *
+     *   o The timestamp in the auth token plus the value of the Tag::AUTH_TIMEOUT must be greater
+     *     than the provided secure timestamp.
+
+     *   If any of these conditions are not met, the method must return
+     *   ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+     *
      *
      * -- RSA keys --
      *
@@ -187,24 +206,7 @@
      * Key authorization enforcement is performed primarily in begin().  The exceptions are
      * authorization per operation keys and confirmation-required keys.
      *
-     * Authorization per operation keys are the case where the key has one or more
-     * Tag::USER_SECURE_IDs, and does not have a Tag::AUTH_TIMEOUT.  In this case, the key requires
-     * an authorization per operation, and the finish method must receive a non-empty and valid
-     * authToken.  For the auth token to be valid, all of the following has to be true:
-     *
-     *   o The HMAC field must validate correctly.
-     *
-     *   o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
-     *     the secure ID values in the token.
-     *
-     *   o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
-     *
-     *   o The challenge field in the auth token must contain the operation challenge.
-     *
-     *   If any of these conditions are not met, update() must return
-     *   ErrorCode::KEY_USER_NOT_AUTHENTICATED.
-     *
-     * The caller must provide the auth token on every call to update() and finish().
+     * Authorization per operation keys must be authorized as described for the update() method.
      *
      * Confirmation-required keys are keys that were generated with
      * Tag::TRUSTED_CONFIRMATION_REQUIRED.  For these keys, when doing a signing operation the
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
deleted file mode 100644
index a29fb08..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.keymint;
-
-import android.hardware.security.keymint.DeviceInfo;
-import android.hardware.security.keymint.MacedPublicKey;
-import android.hardware.security.keymint.ProtectedData;
-import android.hardware.security.keymint.RpcHardwareInfo;
-
-/**
- * An IRemotelyProvisionedComponent is a secure-side component for which certificates can be
- * remotely provisioned. It provides an interface for generating asymmetric key pairs and then
- * creating a CertificateRequest that contains the generated public keys, plus other information to
- * authenticate the request origin. The CertificateRequest can be sent to a server, which can
- * validate the request and create certificates.
- *
- * This interface does not provide any way to use the generated and certified key pairs. It's
- * intended to be implemented by a HAL service that does other things with keys (e.g. Keymint).
- *
- * The root of trust for secure provisioning is something called the "Boot Certificate Chain", or
- * BCC. The BCC is a chain of public key certificates, represented as COSE_Sign1 objects containing
- * COSE_Key representations of the public keys. The "root" of the BCC is
- * a device-unique public key, denoted DK_pub. All public keys in the BCC are device-unique. The
- * public key from each certificate in the chain is used to sign the next certificate in the
- * chain. The final, "leaf" certificate contains a public key, denoted KM_pub, whose corresponding
- * private key, denoted KM_priv, is available for use by the IRemotelyProvisionedComponent.
- *
- * BCC Design
- * ==========
- *
- * The BCC is designed to mirror the boot stages of a device, and to prove the content and integrity
- * of each firmware image. In a proper BCC, each boot stage hashes its own private key with the code
- * and any relevant configuration parameters of the next stage to produce a key pair for the next
- * stage. Each stage also uses its own private key to sign the public key of the next stage,
- * including in the certificate the hash of the next firmware stage, then loads the next stage,
- * passing the private key and certificate to it in a manner that does not leak the private key to
- * later boot stages. The BCC root key pair is generated by immutable code (e.g. ROM), from a
- * device-unique secret. After the device-unique secret is used, it must be made unavailable to any
- * later boot stage.
- *
- * In this way, booting the device incrementally builds a certificate chain that (a) identifies and
- * validates the integrity of every stage and (b) contains a set of public keys that correspond to
- * private keys, one known to each stage. Any stage can compute the secrets of all later stages
- * (given the necessary input), but no stage can compute the secret of any preceding stage. Updating
- * the firmware or configuration of any stage changes the key pair of that stage, and of all
- * subsequent stages, and no attacker who compromised the previous version of the updated firmware
- * can know or predict the post-update key pairs. It is recommended and expected that the BCC is
- * constructed using the Open Profile for DICE.
- *
- * When the provisioning server receives a message signed by KM_priv and containing a BCC that
- * chains from DK_pub to KM_pub, it can be certain that (barring vulnerabilities in some boot
- * stage), the CertificateRequest came from the device associated with DK_pub, running the specific
- * software identified by the certificates in the BCC. If the server has some mechanism for knowing
- * which the DK_pub values of "valid" devices, it can determine whether signing certificates is
- * appropriate.
- *
- * Degenerate BCCs
- * ===============
- *
- * While a proper BCC, as described above, reflects the complete boot sequence from boot ROM to the
- * secure area image of the IRemotelyProvisionedComponent, it's also possible to use a "degenerate"
- * BCC which consists only of a single, self-signed certificate containing the public key of a
- * hardware-bound key pair. This is an appopriate solution for devices which haven't implemented
- * everything necessary to produce a proper BCC, but can derive a unique key pair in the secure
- * area.  In this degenerate case, DK_pub is the same as KM_pub.
- *
- * BCC Privacy
- * ===========
- *
- * Because the BCC constitutes an unspoofable, device-unique identifier, special care is taken to
- * prevent its availability to entities who may wish to track devices. Two precautions are taken:
- *
- * 1.  The BCC is never exported from the IRemotelyProvisionedComponent except in encrypted
- *     form. The portion of the CertificateRequest that contains the BCC is encrypted using an
- *     Endpoint Encryption Key (EEK).  The EEK is provided in the form of a certificate chain whose
- *     root must be pre-provisioned into the secure area (hardcoding the roots into the secure area
- *     firmware image is a recommended approach). Multiple roots may be provisioned. If the provided
- *     EEK does not chain back to this already-known root, the IRemotelyProvisionedComponent must
- *     reject it.
- *
- * 2.  Precaution 1 above ensures that only an entity with a valid EEK private key can decrypt the
- *     BCC. To make it feasible to build a provisioning server which cannot use the BCC to track
- *     devices, the CertificateRequest is structured so that the server can be partitioned into two
- *     components.  The "decrypter" decrypts the BCC, verifies DK_pub and the device's right to
- *     receive provisioned certificates, but does not see the public keys to be signed or the
- *     resulting certificates.  The "certifier" gets informed of the results of the decrypter's
- *     validation and sees the public keys to be signed and resulting certificates, but does not see
- *     the BCC.
- *
- * Test Mode
- * =========
- *
- * The IRemotelyProvisionedComponent supports a test mode, allowing the generation of test key pairs
- * and test CertificateRequests. Test keys/requests are annotated as such, and the BCC used for test
- * CertificateRequests must contain freshly-generated keys, not the real BCC key pairs.
- * @hide
- */
-@VintfStability
-interface IRemotelyProvisionedComponent {
-    const int STATUS_FAILED = 1;
-    const int STATUS_INVALID_MAC = 2;
-    const int STATUS_PRODUCTION_KEY_IN_TEST_REQUEST = 3;
-    const int STATUS_TEST_KEY_IN_PRODUCTION_REQUEST = 4;
-    const int STATUS_INVALID_EEK = 5;
-
-    /**
-     * @return info which contains information about the underlying IRemotelyProvisionedComponent
-     *         hardware, such as version number, component name, author name, and supported curve.
-     */
-    RpcHardwareInfo getHardwareInfo();
-
-    /**
-     * generateKeyPair generates a new ECDSA P-256 key pair that can be certified.  Note that this
-     * method only generates ECDSA P-256 key pairs, but the interface can be extended to add methods
-     * for generating keys for other algorithms, if necessary.
-     *
-     * @param in boolean testMode indicates whether the generated key is for testing only. Test keys
-     *        are marked (see the definition of PublicKey in the MacedPublicKey structure) to
-     *        prevent them from being confused with production keys.
-     *
-     * @param out MacedPublicKey macedPublicKey contains the public key of the generated key pair,
-     *        MACed so that generateCertificateRequest can easily verify, without the
-     *        privateKeyHandle, that the contained public key is for remote certification.
-     *
-     * @return data representing a handle to the private key. The format is implementation-defined,
-     *         but note that specific services may define a required format. KeyMint does.
-     */
-    byte[] generateEcdsaP256KeyPair(in boolean testMode, out MacedPublicKey macedPublicKey);
-
-    /**
-     * generateCertificateRequest creates a certificate request to be sent to the provisioning
-     * server.
-     *
-     * @param in boolean testMode indicates whether the generated certificate request is for testing
-     *        only.
-     *
-     * @param in MacedPublicKey[] keysToSign contains the set of keys to certify. The
-     *        IRemotelyProvisionedComponent must validate the MACs on each key.  If any entry in the
-     *        array lacks a valid MAC, the method must return STATUS_INVALID_MAC.
-     *
-     *        If testMode is true, the keysToCertify array must contain only keys flagged as test
-     *        keys. Otherwise, the method must return STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
-     *
-     *        If testMode is false, the keysToCertify array must not contain any keys flagged as
-     *        test keys. Otherwise, the method must return STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
-     *
-     * @param in endpointEncryptionKey contains an X22519 public key which will be used to encrypt
-     *        the BCC. For flexibility, this is represented as a certificate chain, represented as a
-     *        CBOR array of COSE_Sign1 objects, ordered from root to leaf. The leaf contains the
-     *        X25519 encryption key, each other element is an Ed25519 key signing the next in the
-     *        chain. The root is self-signed. An implementor may also choose to use P256 as an
-     *        alternative curve for signing and encryption instead of Curve 25519.
-     *
-     *            EekChain = [ + SignedSignatureKey, SignedEek ]
-     *
-     *            SignedSignatureKey = [              // COSE_Sign1
-     *                protected: bstr .cbor {
-     *                    1 : AlgorithmEdDSA / AlgorithmES256,  // Algorithm
-     *                },
-     *                unprotected: {},
-     *                payload: bstr .cbor SignatureKeyEd25519 /
-     *                         bstr .cbor SignatureKeyP256,
-     *                signature: bstr PureEd25519(.cbor SignatureKeySignatureInput) /
-     *                           bstr ECDSA(.cbor SignatureKeySignatureInput)
-     *            ]
-     *
-     *            SignatureKeyEd25519 = {                    // COSE_Key
-     *                 1 : 1,                         // Key type : Octet Key Pair
-     *                 3 : AlgorithmEdDSA,            // Algorithm
-     *                 -1 : 6,                        // Curve : Ed25519
-     *                 -2 : bstr                      // Ed25519 public key
-     *            }
-     *
-     *            SignatureKeyP256 = {
-     *                 1 : 2,                         // Key type : EC2
-     *                 3 : AlgorithmES256,            // Algorithm
-     *                 -1 : 1,                        // Curve: P256
-     *                 -2 : bstr,                     // X coordinate
-     *                 -3 : bstr                      // Y coordinate
-     *            }
-     *
-     *            SignatureKeySignatureInput = [
-     *                context: "Signature1",
-     *                body_protected: bstr .cbor {
-     *                    1 : AlgorithmEdDSA / AlgorithmES256,     // Algorithm
-     *                },
-     *                external_aad: bstr .size 0,
-     *                payload: bstr .cbor SignatureKeyEd25519 /
-     *                         bstr .cbor SignatureKeyP256
-     *            ]
-     *
-     *            SignedEek = [                       // COSE_Sign1
-     *                protected: bstr .cbor {
-     *                    1 : AlgorithmEdDSA / AlgorithmES256,  // Algorithm
-     *                },
-     *                unprotected: {},
-     *                payload: bstr .cbor EekX25519 / .cbor EekP256,
-     *                signature: bstr PureEd25519(.cbor EekSignatureInput) /
-     *                           bstr ECDSA(.cbor EekSignatureInput)
-     *            ]
-     *
-     *            EekX25519 = {            // COSE_Key
-     *                1 : 1,               // Key type : Octet Key Pair
-     *                2 : bstr             // KID : EEK ID
-     *                3 : -25,             // Algorithm : ECDH-ES + HKDF-256
-     *                -1 : 4,              // Curve : X25519
-     *                -2 : bstr            // Ed25519 public key
-     *            }
-     *
-     *            EekP256 = {              // COSE_Key
-     *                1 : 2,               // Key type : EC2
-     *                2 : bstr             // KID : EEK ID
-     *                3 : -25,             // Algorithm : ECDH-ES + HKDF-256
-     *                -1 : 1,              // Curve : P256
-     *                -2 : bstr            // Sender X coordinate
-     *                -3 : bstr            // Sender Y coordinate
-     *            }
-     *
-     *            EekSignatureInput = [
-     *                context: "Signature1",
-     *                body_protected: bstr .cbor {
-     *                    1 : AlgorithmEdDSA / AlgorithmES256,     // Algorithm
-     *                },
-     *                external_aad: bstr .size 0,
-     *                payload: bstr .cbor EekX25519 / .cbor EekP256
-     *            ]
-     *
-     *            AlgorithmES256 = -7
-     *            AlgorithmEdDSA = -8
-     *
-     *        If the contents of endpointEncryptionKey do not match the SignedEek structure above,
-     *        the method must return STATUS_INVALID_EEK.
-     *
-     *        If testMode is true, the method must ignore the length and content of the signatures
-     *        in the chain, which implies that it must not attempt to validate the signature.
-     *
-     *        If testMode is false, the method must validate the chain signatures, and must verify
-     *        that the public key in the root certifictate is in its pre-configured set of
-     *        authorized EEK root keys. If the public key is not in the database, or if signature
-     *        verification fails, the method must return STATUS_INVALID_EEK.
-     *
-     * @param in challenge contains a byte string from the provisioning server that must be signed
-     *        by the secure area. See the description of the 'signature' output parameter for
-     *        details.
-     *
-     * @param out DeviceInfo contains the VerifiedDeviceInfo portion of the DeviceInfo array in
-     *        CertificateRequest. The structure is described within the DeviceInfo.aidl file.
-     *
-     * @param out ProtectedData contains the encrypted BCC and the ephemeral MAC key used to
-     *        authenticate the keysToSign (see keysToSignMac output argument).
-     *
-     * @return The of KeysToSign in the CertificateRequest structure. Specifically, it contains:
-     *
-     *            HMAC-256(EK_mac, .cbor KeysToMacStructure)
-     *
-     *        Where EK_mac is an ephemeral MAC key, found in ProtectedData (see below).  The MACed
-     *        data is the "tag" field of a COSE_Mac0 structure like:
-     *
-     *            MacedKeys = [                            // COSE_Mac0
-     *                protected : bstr .cbor {
-     *                    1 : 5,                           // Algorithm : HMAC-256
-     *                },
-     *                unprotected : {},
-     *                // Payload is PublicKeys from keysToSign argument, in provided order.
-     *                payload: bstr .cbor [ * PublicKey ],
-     *                tag: bstr
-     *            ]
-     *
-     *            KeysToMacStructure = [
-     *                context : "MAC0",
-     *                protected : bstr .cbor { 1 : 5 },    // Algorithm : HMAC-256
-     *                external_aad : bstr .size 0,
-     *                // Payload is PublicKeys from keysToSign argument, in provided order.
-     *                payload : bstr .cbor [ * PublicKey ]
-     *            ]
-     */
-    byte[] generateCertificateRequest(in boolean testMode, in MacedPublicKey[] keysToSign,
-            in byte[] endpointEncryptionCertChain, in byte[] challenge, out DeviceInfo deviceInfo,
-            out ProtectedData protectedData);
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
index 57285a3..294c205 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -99,8 +99,7 @@
      * X.509 certificates ordered such that each certificate is signed by the subsequent one, up to
      * the root which must be self-signed (or contain a fake signature in the case of case 4 above).
      * The first certificate in the chain signs the public key info of the newly-generated or
-     * newly-imported key pair.  In the attestation cases (1 and 2 above), the first certificate
-     * must also satisfy some other requirements:
+     * newly-imported key pair.  The first certificate must also satisfy some other requirements:
      *
      * o It must have the serial number provided in Tag::CERTIFICATE_SERIAL, or default to 1 if the
      *   tag is not provided.
@@ -119,15 +118,16 @@
      *    - the keyAgreement bit set iff the attested key has KeyPurpose::AGREE_KEY, and
      *    - the keyCertSignBit set iff the attested key has KeyPurpose::ATTEST_KEY.
      *
-     * o it must contain a KeyDescription attestation extension with OID 1.3.6.1.4.1.11129.2.1.17.
+     * In the attestation cases (1 and 2 above), the first certificate must contain a
+     * KeyDescription attestation extension with OID 1.3.6.1.4.1.11129.2.1.17.
      *
      * The KeyDescription content is defined by the following ASN.1 schema, which is mostly a
      * straightforward translation of the KeyMint tag/value parameter lists to ASN.1.
      *
      * KeyDescription ::= SEQUENCE {
-     *     attestationVersion         INTEGER, # Value 200
+     *     attestationVersion         INTEGER, # Value 300
      *     attestationSecurityLevel   SecurityLevel, # See below
-     *     keyMintVersion             INTEGER, # Value 200
+     *     keyMintVersion             INTEGER, # Value 300
      *     keymintSecurityLevel       SecurityLevel, # See below
      *     attestationChallenge       OCTET_STRING, # Tag::ATTESTATION_CHALLENGE from attestParams
      *     uniqueId                   OCTET_STRING, # Empty unless key has Tag::INCLUDE_UNIQUE_ID
@@ -158,12 +158,23 @@
      *     Failed                     (3),
      * }
      *
+     * -- Note that the AuthorizationList SEQUENCE is also used in IKeyMintDevice::importWrappedKey
+     * -- as a way of describing the authorizations associated with a key that is being securely
+     * -- imported.  As such, it includes the ability to describe tags that are only relevant for
+     * -- symmetric keys, and which will never appear in the attestation extension of an X.509
+     * -- certificate that holds the public key part of an asymmetric keypair. Importing a wrapped
+     * -- key also allows the use of Tag::USER_SECURE_ID, which is never included in an attestation
+     * -- extension because it has no meaning off-device.
+     *
      * AuthorizationList ::= SEQUENCE {
      *     purpose                    [1] EXPLICIT SET OF INTEGER OPTIONAL,
      *     algorithm                  [2] EXPLICIT INTEGER OPTIONAL,
      *     keySize                    [3] EXPLICIT INTEGER OPTIONAL,
+     *     blockMode                  [4] EXPLICIT SET OF INTEGER OPTIONAL, -- symmetric only
      *     digest                     [5] EXPLICIT SET OF INTEGER OPTIONAL,
      *     padding                    [6] EXPLICIT SET OF INTEGER OPTIONAL,
+     *     callerNonce                [7] EXPLICIT NULL OPTIONAL, -- symmetric only
+     *     minMacLength               [8] EXPLICIT INTEGER OPTIONAL, -- symmetric only
      *     ecCurve                    [10] EXPLICIT INTEGER OPTIONAL,
      *     rsaPublicExponent          [200] EXPLICIT INTEGER OPTIONAL,
      *     mgfDigest                  [203] EXPLICIT SET OF INTEGER OPTIONAL,
@@ -173,6 +184,7 @@
      *     originationExpireDateTime  [401] EXPLICIT INTEGER OPTIONAL,
      *     usageExpireDateTime        [402] EXPLICIT INTEGER OPTIONAL,
      *     usageCountLimit            [405] EXPLICIT INTEGER OPTIONAL,
+     *     userSecureId               [502] EXPLICIT INTEGER OPTIONAL, -- only used on import
      *     noAuthRequired             [503] EXPLICIT NULL OPTIONAL,
      *     userAuthType               [504] EXPLICIT INTEGER OPTIONAL,
      *     authTimeout                [505] EXPLICIT INTEGER OPTIONAL,
@@ -197,6 +209,7 @@
      *     vendorPatchLevel           [718] EXPLICIT INTEGER OPTIONAL,
      *     bootPatchLevel             [719] EXPLICIT INTEGER OPTIONAL,
      *     deviceUniqueAttestation    [720] EXPLICIT NULL OPTIONAL,
+     *     attestationIdSecondImei    [723] EXPLICIT OCTET_STRING OPTIONAL,
      * }
      */
     Certificate[] certificateChain;
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
index fd103ef..32e71a7 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
@@ -23,7 +23,7 @@
 @VintfStability
 @Backing(type="int")
 enum KeyPurpose {
-    /* Usable with RSA, 3DES and AES keys. */
+    /* Usable with 3DES and AES keys. */
     ENCRYPT = 0,
 
     /* Usable with RSA, 3DES and AES keys. */
@@ -32,7 +32,7 @@
     /* Usable with RSA, EC and HMAC keys. */
     SIGN = 2,
 
-    /* Usable with RSA, EC and HMAC keys. */
+    /* Usable with HMAC keys. */
     VERIFY = 3,
 
     /* 4 is reserved */
diff --git a/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl b/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
deleted file mode 100644
index ad97443..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.keymint;
-
-/**
- * MacedPublicKey contains a CBOR-encoded public key, MACed by an IRemotelyProvisionedComponent, to
- * prove that the key pair was generated by that component.
- * @hide
- */
-@VintfStability
-parcelable MacedPublicKey {
-    /**
-     * key is a COSE_Mac0 structure containing the new public key.  It's MACed by a key available
-     * only to the secure environment, as proof that the public key was generated by that
-     * environment. In CDDL, assuming the contained key is a P-256 public key:
-     *
-     *     MacedPublicKey = [                     // COSE_Mac0
-     *         protected: bstr .cbor { 1 : 5},    // Algorithm : HMAC-256
-     *         unprotected: { },
-     *         payload : bstr .cbor PublicKey,
-     *         tag : bstr HMAC-256(K_mac, MAC_structure)
-     *     ]
-     *
-     *     PublicKey = {               // COSE_Key
-     *         1 : 2,                  // Key type : EC2
-     *         3 : -7,                 // Algorithm : ES256
-     *         -1 : 1,                 // Curve : P256
-     *         -2 : bstr,              // X coordinate, little-endian
-     *         -3 : bstr,              // Y coordinate, little-endian
-     *         ? -70000 : nil          // Presence indicates this is a test key.  If set, K_mac is
-     *                                 // all zeros.
-     *     },
-     *
-     *     MAC_structure = [
-     *         context : "MAC0",
-     *         protected : bstr .cbor { 1 : 5 },
-     *         external_aad : bstr .size 0,
-     *         payload : bstr .cbor PublicKey
-     *     ]
-     *
-     * if a non-P256 public key were contained, the contents of the PublicKey map would change a
-     * little; see RFC 8152 for details.
-     */
-    byte[] macedKey;
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl b/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl
index e71a9c9..6ff4b29 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl
@@ -26,7 +26,7 @@
 @VintfStability
 @Backing(type="int")
 enum PaddingMode {
-    NONE = 1, /* deprecated */
+    NONE = 1,
     RSA_OAEP = 2,
     RSA_PSS = 3,
     RSA_PKCS1_1_5_ENCRYPT = 4,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
deleted file mode 100644
index 8b3875b..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
+++ /dev/null
@@ -1,237 +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.security.keymint;
-
-/**
- * ProtectedData contains the encrypted BCC and the ephemeral MAC key used to
- * authenticate the keysToSign (see keysToSignMac output argument of
- * IRemotelyProvisionedComponent.generateCertificateRequest).
- * @hide
- */
-@VintfStability
-parcelable ProtectedData {
-    /**
-     * ProtectedData is a COSE_Encrypt structure, encrypted with an AES key that is agreed upon
-     * using Elliptic-curve Diffie-Hellman. The contents of the structure are specified by the
-     * following CDDL [RFC8610].
-     *
-     * Notes:
-     *   - None of the CBOR in ProtectedData uses CBOR tags. If an implementation includes
-     *     tags, parsers may reject the data.
-     *
-     *     ProtectedData = [               // COSE_Encrypt
-     *         protected: bstr .cbor {
-     *             1 : 3                   // Algorithm : AES-GCM 256
-     *         },
-     *         unprotected: {
-     *             5 : bstr .size 12       // IV
-     *         },
-     *         ciphertext: bstr,           // AES-GCM-256(K, .cbor ProtectedDataPayload)
-     *                                     // Where the encryption key 'K' is derived as follows:
-     *                                     // ikm = ECDH(EEK_pub, Ephemeral_priv)
-     *                                     // salt = null
-     *                                     // info = .cbor Context (see below)
-     *                                     // K = HKDF-SHA-256(ikm, salt, info)
-     *         recipients : [
-     *             [                       // COSE_Recipient
-     *                 protected : bstr .cbor {
-     *                     1 : -25         // Algorithm : ECDH-ES + HKDF-256
-     *                 },
-     *                 unprotected : {
-     *                     -1 : PubKeyX25519 / PubKeyEcdhP256  // Ephemeral_pub
-     *                     4 : bstr,       // KID : EEK ID
-     *                 },
-     *                 ciphertext : nil
-     *             ]
-     *         ]
-     *     ]
-     *
-     *     // The COSE_KDF_Context that is used to derive the ProtectedData encryption key with
-     *     // HKDF. See details on use in ProtectedData comments above.
-     *     Context = [
-     *         AlgorithmID : 3             // AES-GCM 256
-     *         PartyUInfo : [
-     *             identity : bstr "client"
-     *             nonce : bstr .size 0,
-     *             other : bstr            // Ephemeral_pub
-     *         ],
-     *         PartyVInfo : [
-     *             identity : bstr "server",
-     *             nonce : bstr .size 0,
-     *             other : bstr            // EEK pubkey
-     *         ],
-     *         SuppPubInfo : [
-     *             256,                    // Output key length
-     *             protected : bstr .size 0
-     *         ]
-     *     ]
-     *
-     *     // The data that is encrypted and included in ProtectedData ciphertext (see above).
-     *     ProtectedDataPayload [
-     *         SignedMac,
-     *         Bcc,
-     *         ? AdditionalDKSignatures,
-     *     ]
-     *
-     *     // AdditionalDKSignatures allows the platform to provide additional certifications
-     *     // for the DK_pub. For example, this could be provided by the hardware vendor, who
-     *     // certifies all of their devices. The SignerName is a free-form string describing
-     *     // who generated the signature.
-     *     AdditionalDKSignatures = {
-     *         + SignerName => DKCertChain
-     *     }
-     *
-     *     // SignerName is a string identifier that indicates both the signing authority as
-     *     // well as the format of the DKCertChain
-     *     SignerName = tstr
-     *
-     *     DKCertChain = [
-     *         2* X509Certificate       // Root -> ... -> Leaf. "Root" is the vendor self-signed
-     *                                  // cert, "Leaf" contains DK_pub. There may also be
-     *                                  // intermediate certificates between Root and Leaf.
-     *     ]
-     *
-     *     // A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or edDSA)
-     *     X509Certificate = bstr
-     *
-     *     // The SignedMac, which authenticates the MAC key that is used to authenticate the
-     *     // keysToSign.
-     *     SignedMac = [                                // COSE_Sign1
-     *         bstr .cbor {                             // Protected params
-     *             1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm
-     *         },
-     *         {},                                      // Unprotected params
-     *         bstr .size 32,                           // Payload: MAC key
-     *         bstr // PureEd25519(KM_priv, bstr .cbor SignedMac_structure) /
-     *              // ECDSA(KM_priv, bstr .cbor SignedMac_structure)
-     *     ]
-     *
-     *     SignedMac_structure = [                      //  COSE Sig_structure
-     *         "Signature1",
-     *         bstr .cbor {                             // Protected params
-     *             1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm
-     *         },
-     *         bstr .cbor SignedMacAad,
-     *         bstr .size 32                            // MAC key
-     *     ]
-     *
-     *     SignedMacAad = [
-     *         challenge : bstr .size (32..64),   // Size between 32 - 64
-     *                                            // bytes inclusive
-     *         VerifiedDeviceInfo,
-     *         tag: bstr                 // This is the tag from COSE_Mac0 of
-     *                                   // KeysToCertify, to tie the key set to
-     *                                   // the signature.
-     *     ]
-     *
-     *     VerifiedDeviceInfo = DeviceInfo  // See DeviceInfo.aidl
-     *
-     *     // The BCC is the boot certificate chain, containing measurements about the device
-     *     // boot chain. The BCC generally follows the Open Profile for DICE specification at
-     *     // https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md.
-     *     //
-     *     // The first entry in the Bcc is the DK_pub, encoded as a COSE_key. All entries after
-     *     // the first describe a link in the boot chain (e.g. bootloaders: BL1, BL2, ... BLN).
-     *     // Note that there is no BccEntry for DK_pub, only a "bare" COSE_key.
-     *     Bcc = [
-     *         PubKeyEd25519 / PubKeyECDSA256, // DK_pub
-     *         + BccEntry,                     // Root -> leaf (KM_pub)
-     *     ]
-     *
-     *     // This is the signed payload for each entry in the Bcc. Note that the "Configuration
-     *     // Input Values" described by the Open Profile are not used here. Instead, the Bcc
-     *     // defines its own configuration values for the Configuration Descriptor field. See
-     *     // the Open Profile for DICE for more details on the fields. All hashes are SHA256.
-     *     BccPayload = {                               // CWT [RFC8392]
-     *         1 : tstr,                                // Issuer
-     *         2 : tstr,                                // Subject
-     *         -4670552 : bstr .cbor PubKeyEd25519 /
-     *                    bstr .cbor PubKeyECDSA256,    // Subject Public Key
-     *         -4670553 : bstr                          // Key Usage
-     *
-     *         // NOTE: All of the following fields may be omitted for a "Degenerate BCC", as
-     *         //       described by IRemotelyProvisionedComponent.aidl.
-     *         -4670545 : bstr,                         // Code Hash
-     *         ? -4670546 : bstr,                       // Code Descriptor
-     *         ? -4670547 : bstr,                       // Configuration Hash
-     *         -4670548 : bstr .cbor {                  // Configuration Descriptor
-     *             ? -70002 : tstr,                         // Component name
-     *             ? -70003 : int,                          // Firmware version
-     *             ? -70004 : null,                         // Resettable
-     *         },
-     *         -4670549 : bstr,                         // Authority Hash
-     *         ? -4670550 : bstr,                       // Authority Descriptor
-     *         -4670551 : bstr,                         // Mode
-     *     }
-     *
-     *     // Each entry in the Bcc is a BccPayload signed by the key from the previous entry
-     *     // in the Bcc array.
-     *     BccEntry = [                                  // COSE_Sign1 (untagged)
-     *         protected : bstr .cbor {
-     *             1 : AlgorithmEdDSA / AlgorithmES256,  // Algorithm
-     *         },
-     *         unprotected: {},
-     *         payload: bstr .cbor BccPayload,
-     *         signature: bstr // PureEd25519(SigningKey, bstr .cbor BccEntryInput) /
-     *                         // ECDSA(SigningKey, bstr .cbor BccEntryInput)
-     *         // See RFC 8032 for details of how to encode the signature value for Ed25519.
-     *     ]
-     *
-     *     BccEntryInput = [
-     *         context: "Signature1",
-     *         protected: bstr .cbor {
-     *             1 : AlgorithmEdDSA / AlgorithmES256,  // Algorithm
-     *         },
-     *         external_aad: bstr .size 0,
-     *         payload: bstr .cbor BccPayload
-     *     ]
-     *
-     *     // The following section defines some types that are reused throughout the above
-     *     // data structures.
-     *     PubKeyX25519 = {                 // COSE_Key
-     *          1 : 1,                      // Key type : Octet Key Pair
-     *         -1 : 4,                      // Curve : X25519
-     *         -2 : bstr                    // Sender X25519 public key
-     *     }
-     *
-     *     PubKeyEd25519 = {                // COSE_Key
-     *         1 : 1,                       // Key type : octet key pair
-     *         3 : AlgorithmEdDSA,          // Algorithm : EdDSA
-     *         -1 : 6,                      // Curve : Ed25519
-     *         -2 : bstr                    // X coordinate, little-endian
-     *     }
-     *
-     *     PubKeyEcdhP256 = {               // COSE_Key
-     *          1 : 2,                      // Key type : EC2
-     *          -1 : 1,                     // Curve : P256
-     *          -2 : bstr                   // Sender X coordinate
-     *          -3 : bstr                   // Sender Y coordinate
-     *     }
-     *
-     *     PubKeyECDSA256 = {               // COSE_Key
-     *         1 : 2,                       // Key type : EC2
-     *         3 : AlgorithmES256,          // Algorithm : ECDSA w/ SHA-256
-     *         -1 : 1,                      // Curve: P256
-     *         -2 : bstr,                   // X coordinate
-     *         -3 : bstr                    // Y coordinate
-     *     }
-     *
-     *     AlgorithmES256 = -7
-     *     AlgorithmEdDSA = -8
-     */
-    byte[] protectedData;
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
deleted file mode 100644
index 0cb33ce..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.keymint;
-
-/**
- * RpcHardwareInfo is the hardware information returned by calling RemotelyProvisionedComponent
- * getHardwareInfo()
- * @hide
- */
-@VintfStability
-@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
-parcelable RpcHardwareInfo {
-    const int CURVE_NONE = 0;
-    const int CURVE_P256 = 1;
-    const int CURVE_25519 = 2;
-
-    /**
-     * Implementation version of the remotely provisioned component hardware.  The version number is
-     * implementation defined, and not necessarily globally meaningful.  The version is used to
-     * distinguish between different versions of a given implementation.
-     */
-    int versionNumber;
-
-    /**
-     * rpcAuthorName is the name of the author of the IRemotelyProvisionedComponent implementation
-     * (organization name, not individual). This name is implementation defined, so it can be used
-     * to distinguish between different implementations from the same author.
-     */
-    @utf8InCpp String rpcAuthorName;
-
-    /**
-     * supportedEekCurve returns an int representing which curve is supported for validating
-     * signatures over the Endpoint Encryption Key certificate chain and for using the corresponding
-     * signed encryption key in ECDH. Only one curve should be supported, with preference for 25519
-     * if it's available. These values are defined as constants above.
-     *
-     * CURVE_NONE is made the default to help ensure that an implementor doesn't accidentally forget
-     * to provide the correct information here, as the VTS tests will check to make certain that
-     * a passing implementation does not provide CURVE_NONE.
-     */
-    int supportedEekCurve = CURVE_NONE;
-
-    /**
-     * uniqueId is an opaque identifier for this IRemotelyProvisionedComponent implementation. The
-     * client should NOT interpret the content of the identifier in any way. The client can only
-     * compare identifiers to determine if two IRemotelyProvisionedComponents share the same
-     * implementation. Each IRemotelyProvisionedComponent implementation must have a distinct
-     * identifier from all other implementations, and it must be consistent across all devices.
-     * It's critical that this identifier not be usable to uniquely identify a specific device.
-     *
-     * This identifier must be consistent across reboots, as it is used to store and track
-     * provisioned keys in a persistent, on-device database.
-     *
-     * uniqueId may not be empty, and must not be any longer than 32 characters.
-     *
-     * A recommended construction for this value is "[Vendor] [Component Name] [Major Version]",
-     * e.g. "Google Trusty KeyMint 1".
-     *
-     * This field was added in API version 2.
-     *
-     */
-    @nullable @utf8InCpp String uniqueId;
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index b28ebcb..d401247 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -186,10 +186,16 @@
      * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with RSA
      * encryption/decryption with OAEP padding.  Possible values are defined by the Digest enum.
      *
-     * This tag is repeatable for key generation/import.  RSA cipher operations with OAEP padding
-     * must specify an MGF1 digest in the params argument of begin(). If this tag is missing or the
-     * specified digest is not in the MGF1 digests associated with the key then begin operation must
-     * fail with ErrorCode::INCOMPATIBLE_MGF_DIGEST.
+     * This tag is repeatable for key generation/import.
+     *
+     * If the caller specifies an MGF1 digest in the params argument of begin(), that digest must be
+     * present as an RSA_OAEP_MGF_DIGEST value in the key characteristics (or the begin() operation
+     * must fail with ErrorCode::INCOMPATIBLE_MGF_DIGEST).
+     *
+     * If the caller does not specify an MGF1 digest in the params argument of begin(), a default
+     * MGF1 digest of SHA1 is used.  If the key characteristics have any explicitly specified values
+     * for RSA_OAEP_MGF_DIGEST, then SHA1 must be included (or the begin() operation must fail with
+     * ErrorCode::INCOMPATIBLE_MGF_DIGEST).
      *
      * Must be hardware-enforced.
      */
@@ -268,25 +274,10 @@
     USAGE_EXPIRE_DATETIME = TagType.DATE | 402,
 
     /**
-     * Tag::MIN_SECONDS_BETWEEN_OPS specifies the minimum amount of time that elapses between
-     * allowed operations using a key.  This can be used to rate-limit uses of keys in contexts
-     * where unlimited use may enable brute force attacks.
+     * OBSOLETE: Do not use.
      *
-     * The value is a 32-bit integer representing seconds between allowed operations.
-     *
-     * When a key with this tag is used in an operation, the IKeyMintDevice must start a timer
-     * during the finish() or abort() call.  Any call to begin() that is received before the timer
-     * indicates that the interval specified by Tag::MIN_SECONDS_BETWEEN_OPS has elapsed must fail
-     * with ErrorCode::KEY_RATE_LIMIT_EXCEEDED.  This implies that the IKeyMintDevice must keep a
-     * table of use counters for keys with this tag.  Because memory is often limited, this table
-     * may have a fixed maximum size and KeyMint may fail operations that attempt to use keys with
-     * this tag when the table is full.  The table must accommodate at least 8 in-use keys and
-     * aggressively reuse table slots when key minimum-usage intervals expire.  If an operation
-     * fails because the table is full, KeyMint returns ErrorCode::TOO_MANY_OPERATIONS.
-     *
-     * Must be hardware-enforced.
-     *
-     * TODO(b/191738660): Remove in KeyMint V2. Currently only used for FDE.
+     * This tag value is included for historical reason, as it was present in Keymaster.
+     * KeyMint implementations do not need to support this tag.
      */
     MIN_SECONDS_BETWEEN_OPS = TagType.UINT | 403,
 
@@ -504,7 +495,9 @@
      * that is necessary during all uses of the key.  In particular, calls to exportKey() and
      * getKeyCharacteristics() must provide the same value to the clientId parameter, and calls to
      * begin() must provide this tag and the same associated data as part of the inParams set.  If
-     * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+     * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.  Note
+     * that a key with a zero-length APPLICATION_ID cannot have its key characteristics retrieved
+     * using getKeyCharacteristics() due to a historical limitation of the API.
      *
      * The content of this tag must be bound to the key cryptographically, meaning it must not be
      * possible for an adversary who has access to all of the secure world secrets but does not have
@@ -525,7 +518,9 @@
      * that is necessary during all uses of the key.  In particular, calls to begin() and
      * exportKey() must provide the same value to the appData parameter, and calls to begin must
      * provide this tag and the same associated data as part of the inParams set.  If the correct
-     * data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+     * data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.  Note that a key
+     * with a zero-length APPLICATION_DATA cannot have its key characteristics retrieved using
+     * getKeyCharacteristics() due to a historical limitation of the API.
      *
      * The content of this tag must be bound to the key cryptographically, meaning it must not be
      * possible for an adversary who has access to all of the secure world secrets but does not have
@@ -731,9 +726,10 @@
     ATTESTATION_ID_SERIAL = TagType.BYTES | 713,
 
     /**
-     * Tag::ATTESTATION_ID_IMEI provides the IMEIs for all radios on the device to attested key
+     * Tag::ATTESTATION_ID_IMEI provides the IMEI one of the radios on the device to attested key
      * generation/import operations.  This field must be set only when requesting attestation of the
-     * device's identifiers.
+     * device's identifiers. If the device has more than one IMEI, a second IMEI may be included
+     * by using the Tag::ATTESTATION_ID_SECOND_IMEI tag.
      *
      * If the device does not support ID attestation (or destroyAttestationIds() was previously
      * called and the device can no longer attest its IDs), any key attestation request that
@@ -888,8 +884,26 @@
     STORAGE_KEY = TagType.BOOL | 722,
 
     /**
-     * OBSOLETE: Do not use. See IKeyMintOperation.updateAad instead.
-     * TODO(b/191738660): Remove in KeyMint v2.
+     * Tag::ATTESTATION_ID_SECOND_IMEI provides an additional IMEI of one of the radios on the
+     * device to attested key generation/import operations. It should be used to convey an
+     * IMEI different to the one conveyed by the Tag::ATTESTATION_ID_IMEI tag. Like all other
+     * ID attestation flags, it may be included independently of other tags.
+     *
+     * If the device does not support ID attestation (or destroyAttestationIds() was previously
+     * called and the device can no longer attest its IDs), any key attestation request that
+     * includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
+     *
+     * Must never appear in KeyCharacteristics.
+     */
+    ATTESTATION_ID_SECOND_IMEI = TagType.BYTES | 723,
+
+    /**
+     * OBSOLETE: Do not use.
+     *
+     * This tag value is included for historical reasons -- in Keymaster it was used to hold
+     * associated data for AEAD encryption, as an additional parameter to
+     * IKeymasterDevice::finish().  In KeyMint the IKeyMintOperation::updateAad() method is used for
+     * this.
      */
     ASSOCIATED_DATA = TagType.BYTES | 1000,
 
@@ -928,10 +942,12 @@
     RESET_SINCE_ID_ROTATION = TagType.BOOL | 1004,
 
     /**
-     * OBSOLETE: Do not use. See the authToken parameter for IKeyMintDevice::begin and for
-     * IKeyMintOperation methods instead.
+     * OBSOLETE: Do not use.
      *
-     * TODO(b/191738660): Delete when keystore1 is deleted.
+     * This tag value is included for historical reasons -- in Keymaster it was used to hold
+     * a confirmation token as an additional parameter to
+     * IKeymasterDevice::finish().  In KeyMint the IKeyMintOperation::finish() method includes
+     * a confirmationToken argument for this.
      */
     CONFIRMATION_TOKEN = TagType.BYTES | 1005,
 
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index 1a17fd4..953630b 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -25,6 +25,7 @@
         "keymint_use_latest_hal_aidl_ndk_shared",
     ],
     shared_libs: [
+        "android.hardware.security.rkp-V3-ndk",
         "android.hardware.security.sharedsecret-V1-ndk",
         "android.hardware.security.secureclock-V1-ndk",
         "libbase",
@@ -41,7 +42,6 @@
         "service.cpp",
     ],
     required: [
-        "RemoteProvisioner",
         "android.hardware.hardware_keystore.xml",
     ],
 }
diff --git a/security/keymint/aidl/default/android.hardware.hardware_keystore.xml b/security/keymint/aidl/default/android.hardware.hardware_keystore.xml
index 2ebf1fe..4c75596 100644
--- a/security/keymint/aidl/default/android.hardware.hardware_keystore.xml
+++ b/security/keymint/aidl/default/android.hardware.hardware_keystore.xml
@@ -14,5 +14,5 @@
      limitations under the License.
 -->
 <permissions>
-  <feature name="android.hardware.hardware_keystore" version="200" />
+  <feature name="android.hardware.hardware_keystore" version="300" />
 </permissions>
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index cfc7fb5..41b161d 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -34,9 +34,14 @@
         "libbinder",
         "libbinder_ndk",
         "libcrypto",
+        "libbase",
+        "libgatekeeper",
         "packagemanager_aidl-cpp",
     ],
     static_libs: [
+        "android.hardware.gatekeeper@1.0",
+        "android.hardware.gatekeeper-V1-ndk",
+        "android.hardware.security.rkp-V3-ndk",
         "android.hardware.security.secureclock-V1-ndk",
         "libavb_user",
         "libavb",
@@ -60,8 +65,10 @@
     ],
     srcs: [
         "AttestKeyTest.cpp",
+        "AuthTest.cpp",
         "BootloaderStateTest.cpp",
         "DeviceUniqueAttestationTest.cpp",
+        "KeyBlobUpgradeTest.cpp",
         "KeyMintTest.cpp",
         "SecureElementProvisioningTest.cpp",
     ],
@@ -95,24 +102,3 @@
         "libgmock_ndk",
     ],
 }
-
-cc_test {
-    name: "VtsHalRemotelyProvisionedComponentTargetTest",
-    defaults: [
-        "keymint_vts_defaults",
-    ],
-    srcs: [
-        "VtsRemotelyProvisionedComponentTests.cpp",
-    ],
-    static_libs: [
-        "libgmock_ndk",
-        "libkeymaster_portable",
-        "libkeymint_vts_test_utils",
-        "libpuresoftkeymasterdevice",
-    ],
-    test_config: "VtsRemotelyProvisionedComponentTests.xml",
-    test_suites: [
-        "general-tests",
-        "vts",
-    ],
-}
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 3e37a5c..6d289ec 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -15,6 +15,8 @@
  */
 
 #define LOG_TAG "keymint_1_attest_key_test"
+#include <android-base/logging.h>
+#include <android-base/strings.h>
 #include <cutils/log.h>
 #include <cutils/properties.h>
 
@@ -26,103 +28,75 @@
 namespace aidl::android::hardware::security::keymint::test {
 
 namespace {
+string TELEPHONY_CMD_GET_IMEI = "cmd phone get-imei ";
 
 bool IsSelfSigned(const vector<Certificate>& chain) {
     if (chain.size() != 1) return false;
     return ChainSignaturesAreValid(chain);
 }
 
+/*
+ * Run a shell command and collect the output of it. If any error, set an empty string as the
+ * output.
+ */
+string exec_command(string command) {
+    char buffer[128];
+    string result = "";
+
+    FILE* pipe = popen(command.c_str(), "r");
+    if (!pipe) {
+        LOG(ERROR) << "popen failed.";
+        return result;
+    }
+
+    // read till end of process:
+    while (!feof(pipe)) {
+        if (fgets(buffer, 128, pipe) != NULL) {
+            result += buffer;
+        }
+    }
+
+    pclose(pipe);
+    return result;
+}
+
+/*
+ * Get IMEI using Telephony service shell command. If any error while executing the command
+ * then empty string will be returned as output.
+ */
+string get_imei(int slot) {
+    string cmd = TELEPHONY_CMD_GET_IMEI + std::to_string(slot);
+    string output = exec_command(cmd);
+
+    if (output.empty()) {
+        LOG(ERROR) << "Command failed. Cmd: " << cmd;
+        return "";
+    }
+
+    vector<string> out = ::android::base::Tokenize(::android::base::Trim(output), "Device IMEI:");
+
+    if (out.size() != 1) {
+        LOG(ERROR) << "Error in parsing the command output. Cmd: " << cmd;
+        return "";
+    }
+
+    string imei = ::android::base::Trim(out[0]);
+    if (imei.compare("null") == 0) {
+        LOG(ERROR) << "Error in getting IMEI from Telephony service: value is null. Cmd: " << cmd;
+        return "";
+    }
+
+    return imei;
+}
+
 }  // namespace
 
 class AttestKeyTest : public KeyMintAidlTestBase {
   public:
     void SetUp() override {
-        check_skip_test();
+        skipAttestKeyTest();
         KeyMintAidlTestBase::SetUp();
     }
-
-  protected:
-    const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key";
-
-    const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
-
-    ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc,
-                                const optional<AttestationKey>& attest_key,
-                                vector<uint8_t>* key_blob,
-                                vector<KeyCharacteristics>* key_characteristics,
-                                vector<Certificate>* cert_chain) {
-        // The original specification for KeyMint v1 required ATTEST_KEY not be combined
-        // with any other key purpose, but the original VTS tests incorrectly did exactly that.
-        // This means that a device that launched prior to Android T (API level 33) may
-        // accept or even require KeyPurpose::SIGN too.
-        if (property_get_int32("ro.board.first_api_level", 0) < 33) {
-            AuthorizationSet key_desc_plus_sign = key_desc;
-            key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN);
-
-            auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics,
-                                      cert_chain);
-            if (result == ErrorCode::OK) {
-                return result;
-            }
-            // If the key generation failed, it may be because the device is (correctly)
-            // rejecting the combination of ATTEST_KEY+SIGN.  Fall through to try again with
-            // just ATTEST_KEY.
-        }
-        return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain);
-    }
-
-    // Check if ATTEST_KEY feature is disabled
-    bool is_attest_key_feature_disabled(void) const {
-        if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) {
-            GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled";
-            return true;
-        }
-
-        return false;
-    }
-
-    // Check if StrongBox KeyStore is enabled
-    bool is_strongbox_enabled(void) const {
-        if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) {
-            GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled";
-            return true;
-        }
-
-        return false;
-    }
-
-    // Check if chipset has received a waiver allowing it to be launched with
-    // Android S (or later) with Keymaster 4.0 in StrongBox
-    bool is_chipset_allowed_km4_strongbox(void) const {
-        std::array<char, PROPERTY_VALUE_MAX> buffer;
-
-        auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr);
-        if (res <= 0) return false;
-
-        const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"};
-
-        for (const string model : allowed_soc_models) {
-            if (model.compare(buffer.data()) == 0) {
-                GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0";
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    // Skip the test if all the following conditions hold:
-    // 1. ATTEST_KEY feature is disabled
-    // 2. STRONGBOX is enabled
-    // 3. The device is running one of the chipsets that have received a waiver
-    //     allowing it to be launched with Android S (or later) with Keymaster 4.0
-    //     in StrongBox
-    void check_skip_test(void) const {
-        if (is_attest_key_feature_disabled() && is_strongbox_enabled() &&
-            is_chipset_allowed_km4_strongbox()) {
-            GTEST_SKIP() << "Test is not applicable";
-        }
-    }
 };
 
 /*
@@ -858,13 +832,44 @@
 
     // Collection of valid attestation ID tags.
     auto attestation_id_tags = AuthorizationSetBuilder();
-    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
+    // Use ro.product.brand_for_attestation property for attestation if it is present else fallback
+    // to ro.product.brand
+    std::string prop_value =
+            ::android::base::GetProperty("ro.product.brand_for_attestation", /* default= */ "");
+    if (!prop_value.empty()) {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND,
+                          "ro.product.brand_for_attestation");
+    } else {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
+    }
     add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
-    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
-    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial");
+    // Use ro.product.name_for_attestation property for attestation if it is present else fallback
+    // to ro.product.name
+    prop_value = ::android::base::GetProperty("ro.product.name_for_attestation", /* default= */ "");
+    if (!prop_value.empty()) {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT,
+                          "ro.product.name_for_attestation");
+    } else {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
+    }
+    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
     add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
                       "ro.product.manufacturer");
-    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
+    // Use ro.product.model_for_attestation property for attestation if it is present else fallback
+    // to ro.product.model
+    prop_value =
+            ::android::base::GetProperty("ro.product.model_for_attestation", /* default= */ "");
+    if (!prop_value.empty()) {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL,
+                          "ro.product.model_for_attestation");
+    } else {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
+    }
+
+    string imei = get_imei(0);
+    if (!imei.empty()) {
+        attestation_id_tags.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
+    }
 
     for (const KeyParameter& tag : attestation_id_tags) {
         SCOPED_TRACE(testing::Message() << "+tag-" << tag);
@@ -932,6 +937,10 @@
                     .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid")
                     .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer")
                     .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model");
+
+    if (isSecondImeiIdAttestationRequired()) {
+        attestation_id_tags.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, "invalid-second-imei");
+    }
     vector<uint8_t> key_blob;
     vector<KeyCharacteristics> key_characteristics;
 
@@ -957,6 +966,164 @@
     CheckedDeleteKey(&attest_key.keyBlob);
 }
 
+TEST_P(AttestKeyTest, SecondIMEIAttestationIDSuccess) {
+    if (is_gsi_image()) {
+        // GSI sets up a standard set of device identifiers that may not match
+        // the device identifiers held by the device.
+        GTEST_SKIP() << "Test not applicable under GSI";
+    }
+
+    // Skip the test if there is no second IMEI exists.
+    string second_imei = get_imei(1);
+    if (second_imei.empty()) {
+        GTEST_SKIP() << "Test not applicable as there is no second IMEI";
+    }
+
+    if (!isSecondImeiIdAttestationRequired()) {
+        GTEST_SKIP() << "Test not applicable for KeyMint-Version < 3 or first-api-level < 34";
+    }
+
+    // Create attestation key.
+    AttestationKey attest_key;
+    vector<KeyCharacteristics> attest_key_characteristics;
+    vector<Certificate> attest_key_cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateAttestKey(AuthorizationSetBuilder()
+                                        .EcdsaKey(EcCurve::P_256)
+                                        .AttestKey()
+                                        .SetDefaultValidity(),
+                                {} /* attestation signing key */, &attest_key.keyBlob,
+                                &attest_key_characteristics, &attest_key_cert_chain));
+    attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
+    EXPECT_EQ(attest_key_cert_chain.size(), 1);
+    EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));
+
+    // Use attestation key to sign an ECDSA key, but include an attestation ID field.
+    AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+                                              .EcdsaSigningKey(EcCurve::P_256)
+                                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                                              .AttestationChallenge("challenge")
+                                              .AttestationApplicationId("foo")
+                                              .SetDefaultValidity();
+    // b/264979486 - second imei doesn't depend on first imei.
+    // Add second IMEI as attestation id without adding first IMEI as
+    // attestation id.
+    builder.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(), second_imei.size());
+
+    vector<uint8_t> attested_key_blob;
+    vector<KeyCharacteristics> attested_key_characteristics;
+    vector<Certificate> attested_key_cert_chain;
+    auto result = GenerateKey(builder, attest_key, &attested_key_blob,
+                              &attested_key_characteristics, &attested_key_cert_chain);
+
+    if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
+        GTEST_SKIP()
+                << "Test not applicable as device does not support SECOND-IMEI ID attestation.";
+    }
+
+    ASSERT_EQ(result, ErrorCode::OK);
+
+    CheckedDeleteKey(&attested_key_blob);
+
+    AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+    AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+
+    // The attested key characteristics will not contain APPLICATION_ID_* fields (their
+    // spec definitions all have "Must never appear in KeyCharacteristics"), but the
+    // attestation extension should contain them, so make sure the extra tag is added.
+    vector<uint8_t> imei_blob(second_imei.data(), second_imei.data() + second_imei.size());
+    KeyParameter imei_tag = Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, imei_blob);
+    hw_enforced.push_back(imei_tag);
+
+    EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
+                                          hw_enforced, SecLevel(),
+                                          attested_key_cert_chain[0].encodedCertificate));
+
+    CheckedDeleteKey(&attest_key.keyBlob);
+}
+
+TEST_P(AttestKeyTest, MultipleIMEIAttestationIDSuccess) {
+    if (is_gsi_image()) {
+        // GSI sets up a standard set of device identifiers that may not match
+        // the device identifiers held by the device.
+        GTEST_SKIP() << "Test not applicable under GSI";
+    }
+
+    // Skip the test if there is no first IMEI exists.
+    string imei = get_imei(0);
+    if (imei.empty()) {
+        GTEST_SKIP() << "Test not applicable as there is no first IMEI";
+    }
+
+    // Skip the test if there is no second IMEI exists.
+    string second_imei = get_imei(1);
+    if (second_imei.empty()) {
+        GTEST_SKIP() << "Test not applicable as there is no second IMEI";
+    }
+
+    if (!isSecondImeiIdAttestationRequired()) {
+        GTEST_SKIP() << "Test not applicable for KeyMint-Version < 3 or first-api-level < 34";
+    }
+
+    // Create attestation key.
+    AttestationKey attest_key;
+    vector<KeyCharacteristics> attest_key_characteristics;
+    vector<Certificate> attest_key_cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateAttestKey(AuthorizationSetBuilder()
+                                        .EcdsaKey(EcCurve::P_256)
+                                        .AttestKey()
+                                        .SetDefaultValidity(),
+                                {} /* attestation signing key */, &attest_key.keyBlob,
+                                &attest_key_characteristics, &attest_key_cert_chain));
+    attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
+    EXPECT_EQ(attest_key_cert_chain.size(), 1);
+    EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));
+
+    // Use attestation key to sign an ECDSA key, but include both IMEI attestation ID fields.
+    AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+                                              .EcdsaSigningKey(EcCurve::P_256)
+                                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                                              .AttestationChallenge("challenge")
+                                              .AttestationApplicationId("foo")
+                                              .SetDefaultValidity();
+    builder.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
+    builder.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(), second_imei.size());
+
+    vector<uint8_t> attested_key_blob;
+    vector<KeyCharacteristics> attested_key_characteristics;
+    vector<Certificate> attested_key_cert_chain;
+    auto result = GenerateKey(builder, attest_key, &attested_key_blob,
+                              &attested_key_characteristics, &attested_key_cert_chain);
+
+    if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
+        GTEST_SKIP() << "Test not applicable as device does not support IMEI ID attestation.";
+    }
+
+    ASSERT_EQ(result, ErrorCode::OK);
+
+    CheckedDeleteKey(&attested_key_blob);
+
+    AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+    AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+
+    // The attested key characteristics will not contain APPLICATION_ID_* fields (their
+    // spec definitions all have "Must never appear in KeyCharacteristics"), but the
+    // attestation extension should contain them, so make sure the extra tag is added.
+    vector<uint8_t> imei_blob(imei.data(), imei.data() + imei.size());
+    KeyParameter imei_tag = Authorization(TAG_ATTESTATION_ID_IMEI, imei_blob);
+    hw_enforced.push_back(imei_tag);
+    vector<uint8_t> sec_imei_blob(second_imei.data(), second_imei.data() + second_imei.size());
+    KeyParameter sec_imei_tag = Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, sec_imei_blob);
+    hw_enforced.push_back(sec_imei_tag);
+
+    EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
+                                          hw_enforced, SecLevel(),
+                                          attested_key_cert_chain[0].encodedCertificate));
+
+    CheckedDeleteKey(&attest_key.keyBlob);
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(AttestKeyTest);
 
 }  // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/AuthTest.cpp b/security/keymint/aidl/vts/functional/AuthTest.cpp
new file mode 100644
index 0000000..6499f14
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/AuthTest.cpp
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "keymint_1_test"
+#include <cutils/log.h>
+
+#include <iostream>
+#include <optional>
+
+#include "KeyMintAidlTestBase.h"
+
+#include <aidl/android/hardware/gatekeeper/GatekeeperEnrollResponse.h>
+#include <aidl/android/hardware/gatekeeper/GatekeeperVerifyResponse.h>
+#include <aidl/android/hardware/gatekeeper/IGatekeeper.h>
+#include <aidl/android/hardware/security/secureclock/ISecureClock.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+using aidl::android::hardware::gatekeeper::GatekeeperEnrollResponse;
+using aidl::android::hardware::gatekeeper::GatekeeperVerifyResponse;
+using aidl::android::hardware::gatekeeper::IGatekeeper;
+using aidl::android::hardware::security::keymint::HardwareAuthToken;
+using aidl::android::hardware::security::secureclock::ISecureClock;
+
+#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
+#include <android/hardware/gatekeeper/1.0/types.h>
+#include <gatekeeper/password_handle.h>  // for password_handle_t
+#include <hardware/hw_auth_token.h>
+
+using ::android::sp;
+using IHidlGatekeeper = ::android::hardware::gatekeeper::V1_0::IGatekeeper;
+using HidlGatekeeperResponse = ::android::hardware::gatekeeper::V1_0::GatekeeperResponse;
+using HidlGatekeeperStatusCode = ::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
+
+namespace aidl::android::hardware::security::keymint::test {
+
+class AuthTest : public KeyMintAidlTestBase {
+  public:
+    void SetUp() {
+        KeyMintAidlTestBase::SetUp();
+
+        // Find the default Gatekeeper instance.
+        string gk_name = string(IGatekeeper::descriptor) + "/default";
+        if (AServiceManager_isDeclared(gk_name.c_str())) {
+            // Enroll a user with AIDL Gatekeeper.
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(gk_name.c_str()));
+            gk_ = IGatekeeper::fromBinder(binder);
+        } else {
+            // Prior to Android U, Gatekeeper was HIDL not AIDL and so may not be present.
+            // Try to enroll user with HIDL Gatekeeper instead.
+            string gk_name = "default";
+            hidl_gk_ = IHidlGatekeeper::getService(gk_name.c_str());
+            if (hidl_gk_ == nullptr) {
+                std::cerr << "No HIDL Gatekeeper instance for '" << gk_name << "' found.\n";
+                return;
+            }
+            std::cerr << "No AIDL Gatekeeper instance for '" << gk_name << "' found, using HIDL.\n";
+        }
+
+        // If the device needs timestamps, find the default ISecureClock instance.
+        if (timestamp_token_required_) {
+            string clock_name = string(ISecureClock::descriptor) + "/default";
+            if (AServiceManager_isDeclared(clock_name.c_str())) {
+                ::ndk::SpAIBinder binder(AServiceManager_waitForService(clock_name.c_str()));
+                clock_ = ISecureClock::fromBinder(binder);
+            } else {
+                std::cerr << "No ISecureClock instance for '" << clock_name << "' found.\n";
+            }
+        }
+
+        // Enroll a password for a user.
+        uid_ = 10001;
+        password_ = "correcthorsebatterystaple";
+        std::optional<GatekeeperEnrollResponse> rsp = doEnroll(password_);
+        ASSERT_TRUE(rsp.has_value());
+        sid_ = rsp->secureUserId;
+        handle_ = rsp->data;
+    }
+
+    void TearDown() {
+        if (gk_ == nullptr) return;
+        gk_->deleteUser(uid_);
+    }
+
+    bool GatekeeperAvailable() { return (gk_ != nullptr) || (hidl_gk_ != nullptr); }
+
+    std::optional<GatekeeperEnrollResponse> doEnroll(const std::vector<uint8_t>& newPwd,
+                                                     const std::vector<uint8_t>& curHandle = {},
+                                                     const std::vector<uint8_t>& curPwd = {}) {
+        if (gk_ != nullptr) {
+            while (true) {
+                GatekeeperEnrollResponse rsp;
+                Status status = gk_->enroll(uid_, curHandle, curPwd, newPwd, &rsp);
+                if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+                    status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
+                    sleep(1);
+                    continue;
+                }
+                if (status.isOk()) {
+                    return std::move(rsp);
+                } else {
+                    GTEST_LOG_(ERROR) << "doEnroll(AIDL) failed: " << status;
+                    return std::nullopt;
+                }
+            }
+        } else if (hidl_gk_ != nullptr) {
+            while (true) {
+                HidlGatekeeperResponse rsp;
+                auto status = hidl_gk_->enroll(
+                        uid_, curHandle, curPwd, newPwd,
+                        [&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
+                if (!status.isOk()) {
+                    GTEST_LOG_(ERROR) << "doEnroll(HIDL) failed";
+                    return std::nullopt;
+                }
+                if (rsp.code == HidlGatekeeperStatusCode::ERROR_RETRY_TIMEOUT) {
+                    sleep(1);
+                    continue;
+                }
+                if (rsp.code != HidlGatekeeperStatusCode::STATUS_OK) {
+                    GTEST_LOG_(ERROR) << "doEnroll(HIDL) failed with " << int(rsp.code);
+                    return std::nullopt;
+                }
+                // "Parse" the returned data to get at the secure user ID.
+                if (rsp.data.size() != sizeof(::gatekeeper::password_handle_t)) {
+                    GTEST_LOG_(ERROR)
+                            << "HAL returned password handle of invalid length " << rsp.data.size();
+                    return std::nullopt;
+                }
+                const ::gatekeeper::password_handle_t* handle =
+                        reinterpret_cast<const ::gatekeeper::password_handle_t*>(rsp.data.data());
+
+                // Translate HIDL response to look like an AIDL response.
+                GatekeeperEnrollResponse aidl_rsp;
+                aidl_rsp.statusCode = IGatekeeper::STATUS_OK;
+                aidl_rsp.data = rsp.data;
+                aidl_rsp.secureUserId = handle->user_id;
+                return aidl_rsp;
+            }
+        } else {
+            return std::nullopt;
+        }
+    }
+
+    std::optional<GatekeeperEnrollResponse> doEnroll(const string& newPwd,
+                                                     const std::vector<uint8_t>& curHandle = {},
+                                                     const string& curPwd = {}) {
+        return doEnroll(std::vector<uint8_t>(newPwd.begin(), newPwd.end()), curHandle,
+                        std::vector<uint8_t>(curPwd.begin(), curPwd.end()));
+    }
+
+    std::optional<HardwareAuthToken> doVerify(uint64_t challenge,
+                                              const std::vector<uint8_t>& handle,
+                                              const std::vector<uint8_t>& pwd) {
+        if (gk_ != nullptr) {
+            while (true) {
+                GatekeeperVerifyResponse rsp;
+                Status status = gk_->verify(uid_, challenge, handle, pwd, &rsp);
+                if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+                    status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
+                    sleep(1);
+                    continue;
+                }
+                if (status.isOk()) {
+                    return rsp.hardwareAuthToken;
+                } else {
+                    GTEST_LOG_(ERROR) << "doVerify(AIDL) failed: " << status;
+                    return std::nullopt;
+                }
+            }
+        } else if (hidl_gk_ != nullptr) {
+            while (true) {
+                HidlGatekeeperResponse rsp;
+                auto status = hidl_gk_->verify(
+                        uid_, challenge, handle, pwd,
+                        [&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
+                if (!status.isOk()) {
+                    GTEST_LOG_(ERROR) << "doVerify(HIDL) failed";
+                    return std::nullopt;
+                }
+                if (rsp.code == HidlGatekeeperStatusCode::ERROR_RETRY_TIMEOUT) {
+                    sleep(1);
+                    continue;
+                }
+                if (rsp.code != HidlGatekeeperStatusCode::STATUS_OK) {
+                    GTEST_LOG_(ERROR) << "doVerify(HIDL) failed with " << int(rsp.code);
+                    return std::nullopt;
+                }
+                // "Parse" the returned data to get auth token contents.
+                if (rsp.data.size() != sizeof(hw_auth_token_t)) {
+                    GTEST_LOG_(ERROR) << "Incorrect size of AuthToken payload.";
+                    return std::nullopt;
+                }
+                const hw_auth_token_t* hwAuthToken =
+                        reinterpret_cast<const hw_auth_token_t*>(rsp.data.data());
+                HardwareAuthToken authToken;
+                authToken.timestamp.milliSeconds = betoh64(hwAuthToken->timestamp);
+                authToken.challenge = hwAuthToken->challenge;
+                authToken.userId = hwAuthToken->user_id;
+                authToken.authenticatorId = hwAuthToken->authenticator_id;
+                authToken.authenticatorType = static_cast<HardwareAuthenticatorType>(
+                        betoh32(hwAuthToken->authenticator_type));
+                authToken.mac.assign(&hwAuthToken->hmac[0], &hwAuthToken->hmac[32]);
+                return authToken;
+            }
+        } else {
+            return std::nullopt;
+        }
+    }
+    std::optional<HardwareAuthToken> doVerify(uint64_t challenge,
+                                              const std::vector<uint8_t>& handle,
+                                              const string& pwd) {
+        return doVerify(challenge, handle, std::vector<uint8_t>(pwd.begin(), pwd.end()));
+    }
+
+    // Variants of the base class methods but with authentication information included.
+    string ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
+                          const string& message, const AuthorizationSet& in_params,
+                          AuthorizationSet* out_params, const HardwareAuthToken& hat) {
+        AuthorizationSet begin_out_params;
+        ErrorCode result = Begin(operation, key_blob, in_params, out_params, hat);
+        EXPECT_EQ(ErrorCode::OK, result);
+        if (result != ErrorCode::OK) {
+            return "";
+        }
+
+        std::optional<secureclock::TimeStampToken> time_token = std::nullopt;
+        if (timestamp_token_required_ && clock_ != nullptr) {
+            // Ask a secure clock instance for a timestamp, including the per-op challenge.
+            secureclock::TimeStampToken token;
+            EXPECT_EQ(ErrorCode::OK,
+                      GetReturnErrorCode(clock_->generateTimeStamp(challenge_, &token)));
+            time_token = token;
+        }
+
+        string output;
+        EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &output, hat, time_token));
+        return output;
+    }
+
+    string EncryptMessage(const vector<uint8_t>& key_blob, const string& message,
+                          const AuthorizationSet& in_params, AuthorizationSet* out_params,
+                          const HardwareAuthToken& hat) {
+        SCOPED_TRACE("EncryptMessage");
+        return ProcessMessage(key_blob, KeyPurpose::ENCRYPT, message, in_params, out_params, hat);
+    }
+
+    string DecryptMessage(const vector<uint8_t>& key_blob, const string& ciphertext,
+                          const AuthorizationSet& params, const HardwareAuthToken& hat) {
+        SCOPED_TRACE("DecryptMessage");
+        AuthorizationSet out_params;
+        string plaintext =
+                ProcessMessage(key_blob, KeyPurpose::DECRYPT, ciphertext, params, &out_params, hat);
+        EXPECT_TRUE(out_params.empty());
+        return plaintext;
+    }
+
+  protected:
+    std::shared_ptr<IGatekeeper> gk_;
+    sp<IHidlGatekeeper> hidl_gk_;
+    std::shared_ptr<ISecureClock> clock_;
+    string password_;
+    uint32_t uid_;
+    int64_t sid_;
+    std::vector<uint8_t> handle_;
+};
+
+// Test use of a key that requires user-authentication within recent history.
+TEST_P(AuthTest, TimeoutAuthentication) {
+    if (!GatekeeperAvailable()) {
+        GTEST_SKIP() << "No Gatekeeper available";
+    }
+    if (timestamp_token_required_ && clock_ == nullptr) {
+        GTEST_SKIP() << "Device requires timestamps and no ISecureClock available";
+    }
+
+    // Create an AES key that requires authentication within the last 3 seconds.
+    const uint32_t timeout_secs = 3;
+    auto builder = AuthorizationSetBuilder()
+                           .AesEncryptionKey(256)
+                           .BlockMode(BlockMode::ECB)
+                           .Padding(PaddingMode::PKCS7)
+                           .Authorization(TAG_USER_SECURE_ID, sid_)
+                           .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD)
+                           .Authorization(TAG_AUTH_TIMEOUT, timeout_secs);
+    vector<uint8_t> keyblob;
+    vector<KeyCharacteristics> key_characteristics;
+    vector<Certificate> cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+    // Attempt to use the AES key without authentication.
+    const string message = "Hello World!";
+    AuthorizationSet out_params;
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+              Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+
+    // Verify to get a HAT, arbitrary challenge.
+    const uint64_t challenge = 42;
+    const std::optional<HardwareAuthToken> hat = doVerify(challenge, handle_, password_);
+    ASSERT_TRUE(hat.has_value());
+    EXPECT_EQ(hat->userId, sid_);
+
+    // Adding the auth token makes it possible to use the AES key.
+    const string ciphertext = EncryptMessage(keyblob, message, params, &out_params, hat.value());
+    const string plaintext = DecryptMessage(keyblob, ciphertext, params, hat.value());
+    EXPECT_EQ(message, plaintext);
+
+    // Altering a single bit in the MAC means no auth.
+    HardwareAuthToken dodgy_hat = hat.value();
+    ASSERT_GT(dodgy_hat.mac.size(), 0);
+    dodgy_hat.mac[0] ^= 0x01;
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+              Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, dodgy_hat));
+
+    // Wait for long enough that the hardware auth token expires.
+    sleep(timeout_secs + 1);
+
+    auto begin_result = Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, hat);
+    if (begin_result == ErrorCode::OK) {
+        // If begin() succeeds despite the out-of-date HAT, that must mean that the KeyMint
+        // device doesn't have its own clock.  In that case, it only detects timeout via a
+        // timestamp token provided on update()/finish()
+        ASSERT_TRUE(timestamp_token_required_);
+
+        secureclock::TimeStampToken time_token;
+        EXPECT_EQ(ErrorCode::OK,
+                  GetReturnErrorCode(clock_->generateTimeStamp(challenge_, &time_token)));
+
+        string output;
+        EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+                  Finish(message, {} /* signature */, &output, hat, time_token));
+    } else {
+        // The KeyMint implementation may have its own clock that can immediately detect timeout.
+        ASSERT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED, begin_result);
+    }
+}
+
+// Test use of a key that requires an auth token for each action on the operation, with
+// a per-operation challenge value included.
+TEST_P(AuthTest, AuthPerOperation) {
+    if (!GatekeeperAvailable()) {
+        GTEST_SKIP() << "No Gatekeeper available";
+    }
+
+    // Create an AES key that requires authentication per-action.
+    auto builder = AuthorizationSetBuilder()
+                           .AesEncryptionKey(256)
+                           .BlockMode(BlockMode::ECB)
+                           .Padding(PaddingMode::PKCS7)
+                           .Authorization(TAG_USER_SECURE_ID, sid_)
+                           .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD);
+    vector<uint8_t> keyblob;
+    vector<KeyCharacteristics> key_characteristics;
+    vector<Certificate> cert_chain;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+    // Attempt to use the AES key without authentication fails after begin.
+    const string message = "Hello World!";
+    AuthorizationSet out_params;
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+    string output;
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED, Finish(message, {} /* signature */, &output));
+
+    // Verify to get a HAT, but with an arbitrary challenge.
+    const uint64_t unrelated_challenge = 42;
+    const std::optional<HardwareAuthToken> unrelated_hat =
+            doVerify(unrelated_challenge, handle_, password_);
+    ASSERT_TRUE(unrelated_hat.has_value());
+    EXPECT_EQ(unrelated_hat->userId, sid_);
+
+    // Attempt to use the AES key with an unrelated authentication fails after begin.
+    EXPECT_EQ(ErrorCode::OK,
+              Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, unrelated_hat.value()));
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+              Finish(message, {} /* signature */, &output, unrelated_hat.value()));
+
+    // Now get a HAT with the challenge from an in-progress operation.
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+    const std::optional<HardwareAuthToken> hat = doVerify(challenge_, handle_, password_);
+    ASSERT_TRUE(hat.has_value());
+    EXPECT_EQ(hat->userId, sid_);
+    string ciphertext;
+    EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &ciphertext, hat.value()));
+
+    // Altering a single bit in the MAC means no auth.
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+    std::optional<HardwareAuthToken> dodgy_hat = doVerify(challenge_, handle_, password_);
+    ASSERT_TRUE(dodgy_hat.has_value());
+    EXPECT_EQ(dodgy_hat->userId, sid_);
+    ASSERT_GT(dodgy_hat->mac.size(), 0);
+    dodgy_hat->mac[0] ^= 0x01;
+    EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+              Finish(message, {} /* signature */, &ciphertext, hat.value()));
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(AuthTest);
+
+}  // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
index a709b41..54f187c 100644
--- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
+++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
@@ -38,7 +38,6 @@
 
 // Since this test needs to talk to KeyMint HAL, it can only run as root. Thus,
 // bootloader can not be locked.
-// @CddTest = 9.10/C-0-2
 class BootloaderStateTest : public KeyMintAidlTestBase {
   public:
     virtual void SetUp() override {
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index c91e4e8..8e9aded 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -249,13 +249,39 @@
 
     // Collection of valid attestation ID tags.
     auto attestation_id_tags = AuthorizationSetBuilder();
-    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
+    // Use ro.product.brand_for_attestation property for attestation if it is present else fallback
+    // to ro.product.brand
+    std::string prop_value =
+            ::android::base::GetProperty("ro.product.brand_for_attestation", /* default= */ "");
+    if (!prop_value.empty()) {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND,
+                          "ro.product.brand_for_attestation");
+    } else {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
+    }
     add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
-    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
-    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial");
+    // Use ro.product.name_for_attestation property for attestation if it is present else fallback
+    // to ro.product.name
+    prop_value = ::android::base::GetProperty("ro.product.name_for_attestation", /* default= */ "");
+    if (!prop_value.empty()) {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT,
+                          "ro.product.name_for_attestation");
+    } else {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
+    }
+    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
     add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
                       "ro.product.manufacturer");
-    add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
+    // Use ro.product.model_for_attestation property for attestation if it is present else fallback
+    // to ro.product.model
+    prop_value =
+            ::android::base::GetProperty("ro.product.model_for_attestation", /* default= */ "");
+    if (!prop_value.empty()) {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL,
+                          "ro.product.model_for_attestation");
+    } else {
+        add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
+    }
     vector<uint8_t> key_blob;
     vector<KeyCharacteristics> key_characteristics;
 
diff --git a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
new file mode 100644
index 0000000..fb014cf
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
@@ -0,0 +1,638 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// The tests in this file are intended to be run manually, to allow testing of whether
+// keyblob upgrade works correctly.  The manual procedure is roughly:
+//
+// 1) Run the "*Before*" subset of these tests with the `--keyblob_dir <dir>` command-line argument
+//    so that keyblobs are saved to a directory on the device:
+//
+//      VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest*Before*" \
+//                               --keyblob_dir /data/local/tmp/keymint-blobs
+//
+//    All tests should pass, and the `UpgradeKeyBlobs` test should indicate that no keyblob
+//    upgrades were needed.
+//
+// 2) Copy the generated keyblobs off the device into a safe place.
+//
+//      adb pull /data/local/tmp/keymint-blobs
+//
+// 3) Upgrade the device to a new version.
+//
+// 4) Push the saved keyblobs back onto the upgraded device.
+//
+//      adb push keymint-blobs /data/local/tmp/keymint-blobs
+//
+// 5) Run the "*After*" subset of these tests with the `--keyblob_dir <dir>` command-line argument
+//    pointing to the directory with the keyblobs:
+//
+//      VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest*After*" \
+//                               --keyblob_dir /data/local/tmp/keymint-blobs
+//
+//    (Note that this skips the `CreateKeyBlobs` test, which would otherwise replace the saved
+//    keyblobs with freshly generated ones.).
+//
+//    All tests should pass, and the `UpgradeKeyBlobs` test should have output that matches whether
+//    upgrade was expected or not.
+
+#define LOG_TAG "keymint_1_test"
+#include <cutils/log.h>
+
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+
+#include <unistd.h>
+
+#include <openssl/curve25519.h>
+#include <openssl/ec.h>
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+#include <openssl/x509v3.h>
+
+#include "KeyMintAidlTestBase.h"
+
+using aidl::android::hardware::security::keymint::KeyCharacteristics;
+
+namespace aidl::android::hardware::security::keymint::test {
+
+namespace {
+
+// Names for individual key types to create and use.  Note that some the names
+// induce specific behaviour, as indicated by the functions below.
+
+std::vector<std::string> keyblob_names_tee = {
+        "aes-key",        "aes-key-rr",      "des-key",           "hmac-key",
+        "rsa-key",        "p256-key",        "ed25519-key",       "x25519-key",
+        "rsa-attest-key", "p256-attest-key", "ed25519-attest-key"};
+
+std::vector<std::string> keyblob_names_tee_no_25519 = {
+        "aes-key", "aes-key-rr", "des-key",        "hmac-key",
+        "rsa-key", "p256-key",   "rsa-attest-key", "p256-attest-key"};
+
+std::vector<std::string> keyblob_names_sb = {"aes-key",        "aes-key-rr",     "des-key",
+                                             "hmac-key",       "rsa-key",        "p256-key",
+                                             "rsa-attest-key", "p256-attest-key"};
+
+// Helper functions to detect particular key types based on the name.
+bool requires_attest_key(const std::string& name) {
+    return name.find("-attest-key") != std::string::npos;
+}
+
+bool requires_rr(const std::string& name) {
+    return name.find("-rr") != std::string::npos;
+}
+
+bool is_asymmetric(const std::string& name) {
+    return (name.find("rsa") != std::string::npos || name.find("25519") != std::string::npos ||
+            name.find("p256") != std::string::npos);
+}
+
+std::string keyblob_subdir(const std::string& keyblob_dir, const std::string& full_name,
+                           bool create) {
+    if (keyblob_dir.empty()) {
+        return "";
+    }
+
+    // Use a subdirectory for the specific instance, so two different KeyMint instances won't
+    // clash with each other.
+    size_t found = full_name.find_last_of('/');
+    std::string subdir = keyblob_dir + "/" + full_name.substr(found + 1);
+
+    if (create) {
+        mkdir(keyblob_dir.c_str(), 0777);
+        mkdir(subdir.c_str(), 0777);
+    }
+    return subdir;
+}
+
+void save_keyblob(const std::string& subdir, const std::string& name,
+                  const vector<uint8_t>& keyblob,
+                  const std::vector<KeyCharacteristics>& key_characteristics) {
+    // Write the keyblob out to a file.
+    std::string blobname(subdir + "/" + name + ".keyblob");
+    std::ofstream blobfile(blobname, std::ios::out | std::ios::trunc | std::ios::binary);
+    blobfile.write(reinterpret_cast<const char*>(keyblob.data()), keyblob.size());
+    blobfile.close();
+
+    // Dump the characteristics too.
+    std::string charsname(subdir + "/" + name + ".chars");
+    std::ofstream charsfile(charsname, std::ios::out | std::ios::trunc);
+    charsfile << "{\n";
+    for (const auto& characteristic : key_characteristics) {
+        charsfile << "  " << characteristic.toString() << "\n";
+    }
+    charsfile << "}\n";
+    charsfile.close();
+
+    // Also write out a hexdump of the keyblob for convenience.
+    std::string hexname(subdir + "/" + name + ".hex");
+    std::ofstream hexfile(hexname, std::ios::out | std::ios::trunc);
+    hexfile << bin2hex(keyblob) << "\n";
+    hexfile.close();
+}
+
+void save_keyblob_and_cert(const std::string& subdir, const std::string& name,
+                           const vector<uint8_t>& keyblob,
+                           const std::vector<KeyCharacteristics>& key_characteristics,
+                           const std::vector<Certificate>& cert_chain) {
+    save_keyblob(subdir, name, keyblob, key_characteristics);
+
+    if (is_asymmetric(name)) {
+        // Dump the leaf certificate as DER.
+        if (cert_chain.empty()) {
+            FAIL() << "No cert available for " << name;
+        } else {
+            const vector<uint8_t>& certdata = cert_chain[0].encodedCertificate;
+            std::string certname(subdir + "/" + name + ".cert");
+            std::ofstream certfile(certname, std::ios::out | std::ios::trunc | std::ios::binary);
+            certfile.write(reinterpret_cast<const char*>(certdata.data()), certdata.size());
+            certfile.close();
+        }
+    }
+}
+
+void delete_keyblob(const std::string& subdir, const std::string& name) {
+    std::string blobname(subdir + "/" + name + ".keyblob");
+    unlink(blobname.c_str());
+    std::string charsname(subdir + "/" + name + ".chars");
+    unlink(charsname.c_str());
+    std::string hexname(subdir + "/" + name + ".hex");
+    unlink(hexname.c_str());
+    std::string certname(subdir + "/" + name + ".cert");
+    unlink(certname.c_str());
+}
+
+std::vector<uint8_t> load_file(const std::string& subdir, const std::string& name,
+                               const std::string& suffix) {
+    std::string blobname(subdir + "/" + name + suffix);
+    std::ifstream blobfile(blobname, std::ios::in | std::ios::binary);
+
+    std::vector<uint8_t> data((std::istreambuf_iterator<char>(blobfile)),
+                              std::istreambuf_iterator<char>());
+    return data;
+}
+
+std::vector<uint8_t> load_keyblob(const std::string& subdir, const std::string& name) {
+    return load_file(subdir, name, ".keyblob");
+}
+
+std::vector<uint8_t> load_cert(const std::string& subdir, const std::string& name) {
+    return load_file(subdir, name, ".cert");
+}
+
+}  // namespace
+
+class KeyBlobUpgradeTest : public KeyMintAidlTestBase {
+  protected:
+    const std::vector<std::string>& keyblob_names() {
+        if (SecLevel() == SecurityLevel::STRONGBOX) {
+            return keyblob_names_sb;
+        } else if (!Curve25519Supported()) {
+            return keyblob_names_tee_no_25519;
+        } else {
+            return keyblob_names_tee;
+        }
+    }
+
+    void UpgradeKeyBlobs(bool expectUpgrade) {
+        std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ false);
+        if (subdir.empty()) {
+            GTEST_SKIP() << "No keyblob directory provided";
+        }
+
+        for (std::string name : keyblob_names()) {
+            if (requires_attest_key(name) && shouldSkipAttestKeyTest()) {
+                std::cerr << "Skipping variant '" << name
+                          << "' which requires ATTEST_KEY support that has been waivered\n";
+                continue;
+            }
+            for (bool with_hidden : {false, true}) {
+                std::string app_id;
+                std::string app_data;
+                auto builder = AuthorizationSetBuilder();
+                if (with_hidden) {
+                    // Build a variant keyblob that requires app_id/app_data
+                    app_id = "appid";
+                    app_data = "appdata";
+                    builder.Authorization(TAG_APPLICATION_ID, "appid")
+                            .Authorization(TAG_APPLICATION_DATA, "appdata");
+                    name += "-hidden";
+                }
+                SCOPED_TRACE(testing::Message() << name);
+
+                // Load the old format keyblob.
+                std::vector<uint8_t> keyblob = load_keyblob(subdir, name);
+                if (keyblob.empty()) {
+                    if (requires_rr(name)) {
+                        std::cerr << "Skipping missing keyblob file '" << name
+                                  << "', assuming rollback resistance unavailable\n";
+                    } else {
+                        FAIL() << "Missing keyblob file '" << name << "'";
+                    }
+                    continue;
+                }
+
+                // An upgrade will either produce a new keyblob or no data (if upgrade isn't
+                // needed).
+                std::vector<uint8_t> upgraded_keyblob;
+                Status result =
+                        keymint_->upgradeKey(keyblob, builder.vector_data(), &upgraded_keyblob);
+                ASSERT_EQ(ErrorCode::OK, GetReturnErrorCode(result));
+
+                if (upgraded_keyblob.empty()) {
+                    std::cerr << "Keyblob '" << name << "' did not require upgrade\n";
+                    EXPECT_TRUE(!expectUpgrade) << "Keyblob '" << name << "' unexpectedly upgraded";
+                } else {
+                    // Ensure the old format keyblob is deleted (so any secure deletion data is
+                    // cleaned up).
+                    EXPECT_EQ(ErrorCode::OK, DeleteKey(&keyblob));
+
+                    std::vector<uint8_t> app_id_v(app_id.begin(), app_id.end());
+                    std::vector<uint8_t> app_data_v(app_data.begin(), app_data.end());
+                    std::vector<KeyCharacteristics> key_characteristics;
+                    result = keymint_->getKeyCharacteristics(upgraded_keyblob, app_id_v, app_data_v,
+                                                             &key_characteristics);
+                    ASSERT_EQ(ErrorCode::OK, GetReturnErrorCode(result))
+                            << "Failed getKeyCharacteristics() after upgrade";
+
+                    save_keyblob(subdir, name, upgraded_keyblob, key_characteristics);
+                    // Cert file is left unchanged.
+                    std::cerr << "Keyblob '" << name << "' upgraded\n";
+                    EXPECT_TRUE(expectUpgrade)
+                            << "Keyblob '" << name << "' unexpectedly left as-is";
+                }
+            }
+        }
+    }
+};
+
+// To save off keyblobs before upgrade, use:
+//
+//    VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.CreateKeyBlobs*" \
+//                             --keyblob_dir /data/local/tmp/keymint-blobs
+//
+// Then copy the contents of the /data/local/tmp/keymint-blobs/ directory somewhere safe:
+//
+//    adb pull /data/local/tmp/keymint-blobs/
+TEST_P(KeyBlobUpgradeTest, CreateKeyBlobsBefore) {
+    std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ true);
+
+    std::map<const std::string, AuthorizationSetBuilder> keys_info = {
+            {"aes-key", AuthorizationSetBuilder()
+                                .AesEncryptionKey(256)
+                                .BlockMode(BlockMode::ECB)
+                                .Padding(PaddingMode::PKCS7)
+                                .Authorization(TAG_NO_AUTH_REQUIRED)},
+            {"aes-key-rr", AuthorizationSetBuilder()
+                                   .AesEncryptionKey(256)
+                                   .BlockMode(BlockMode::ECB)
+                                   .Padding(PaddingMode::PKCS7)
+                                   .Authorization(TAG_ROLLBACK_RESISTANCE)
+                                   .Authorization(TAG_NO_AUTH_REQUIRED)},
+            {"des-key", AuthorizationSetBuilder()
+                                .TripleDesEncryptionKey(168)
+                                .BlockMode(BlockMode::ECB)
+                                .Padding(PaddingMode::PKCS7)
+                                .Authorization(TAG_NO_AUTH_REQUIRED)},
+            {"hmac-key", AuthorizationSetBuilder()
+                                 .HmacKey(128)
+                                 .Digest(Digest::SHA_2_256)
+                                 .Authorization(TAG_MIN_MAC_LENGTH, 128)
+                                 .Authorization(TAG_NO_AUTH_REQUIRED)},
+            {"rsa-key", AuthorizationSetBuilder()
+                                .RsaEncryptionKey(2048, 65537)
+                                .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
+                                .Digest(Digest::NONE)
+                                .Digest(Digest::SHA_2_256)
+                                .Padding(PaddingMode::NONE)
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .SetDefaultValidity()},
+            {
+                    "p256-key",
+                    AuthorizationSetBuilder()
+                            .EcdsaSigningKey(EcCurve::P_256)
+                            .Authorization(TAG_PURPOSE, KeyPurpose::AGREE_KEY)
+                            .Digest(Digest::NONE)
+                            .Digest(Digest::SHA_2_256)
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .SetDefaultValidity(),
+            },
+            {
+                    "ed25519-key",
+                    AuthorizationSetBuilder()
+                            .EcdsaSigningKey(EcCurve::CURVE_25519)
+                            .Digest(Digest::NONE)
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .SetDefaultValidity(),
+            },
+            {"x25519-key", AuthorizationSetBuilder()
+                                   .Authorization(TAG_EC_CURVE, EcCurve::CURVE_25519)
+                                   .Authorization(TAG_PURPOSE, KeyPurpose::AGREE_KEY)
+                                   .Authorization(TAG_ALGORITHM, Algorithm::EC)
+                                   .Authorization(TAG_NO_AUTH_REQUIRED)
+                                   .SetDefaultValidity()},
+            {"rsa-attest-key", AuthorizationSetBuilder()
+                                       .RsaKey(2048, 65537)
+                                       .AttestKey()
+                                       .Authorization(TAG_NO_AUTH_REQUIRED)
+                                       .SetDefaultValidity()},
+            {
+                    "p256-attest-key",
+                    AuthorizationSetBuilder()
+                            .EcdsaKey(EcCurve::P_256)
+                            .AttestKey()
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .SetDefaultValidity(),
+            },
+            {
+                    "ed25519-attest-key",
+                    AuthorizationSetBuilder()
+                            .EcdsaKey(EcCurve::CURVE_25519)
+                            .AttestKey()
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .SetDefaultValidity(),
+            }};
+
+    for (std::string name : keyblob_names()) {
+        if (requires_attest_key(name) && shouldSkipAttestKeyTest()) {
+            std::cerr << "Skipping variant '" << name
+                      << "' which requires ATTEST_KEY support that has been waivered\n";
+            continue;
+        }
+        auto entry = keys_info.find(name);
+        ASSERT_NE(entry, keys_info.end()) << "no builder for " << name;
+        auto builder = entry->second;
+        for (bool with_hidden : {false, true}) {
+            if (with_hidden) {
+                // Build a variant keyblob that requires app_id/app_data
+                builder.Authorization(TAG_APPLICATION_ID, "appid")
+                        .Authorization(TAG_APPLICATION_DATA, "appdata");
+                name += "-hidden";
+            }
+            SCOPED_TRACE(testing::Message() << name);
+
+            vector<uint8_t> keyblob;
+            vector<KeyCharacteristics> key_characteristics;
+            vector<Certificate> cert_chain;
+            auto result =
+                    GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain);
+
+            if (requires_rr(name) && result == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE) {
+                // Rollback resistance support is optional.
+                std::cerr << "Skipping '" << name << "' key as rollback resistance unavailable\n";
+                continue;
+            }
+            ASSERT_EQ(ErrorCode::OK, result) << " failed for " << name;
+
+            if (!subdir.empty()) {
+                save_keyblob_and_cert(subdir, name, keyblob, key_characteristics, cert_chain);
+            }
+        }
+    }
+
+    if (!subdir.empty()) {
+        std::cerr << "Save generated keyblobs with:\n\n    adb pull " << keyblob_dir << "\n\n";
+    }
+}
+
+TEST_P(KeyBlobUpgradeTest, UpgradeKeyBlobsBefore) {
+    // Check that attempting to upgrade valid keyblobs does nothing.
+    UpgradeKeyBlobs(/* expectUpgrade= */ false);
+}
+
+// To run this test:
+//
+// - save off some keyblobs before upgrade as per the CreateKeyBlobs test above.
+// - upgrade the device to a version that should trigger keyblob upgrade (e.g. different patchlevel)
+// - put the saved keyblobs back onto the upgraded device:
+//
+//     adb push keymint-blobs /data/local/tmp/keymint-blobs
+//
+// - run the test with:
+//
+//     VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.UpgradeKeyBlobsAfter*" \
+//                              --keyblob_dir /data/local/tmp/keymint-blobs
+//
+// - this replaces the keyblob contents in that directory; if needed, save the upgraded keyblobs
+//   with:
+//      adb pull /data/local/tmp/keymint-blobs/
+TEST_P(KeyBlobUpgradeTest, UpgradeKeyBlobsAfter) {
+    UpgradeKeyBlobs(/* expectUpgrade= */ true);
+}
+
+// To run this test:
+//
+// - save off some keyblobs before upgrade as per the CreateKeyBlobs test above
+// - if needed, upgrade the saved keyblobs as per the UpgradeKeyBlobs test above
+// - run the test with:
+//
+//     VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.UseKeyBlobs*" \
+//                              --keyblob_dir /data/local/tmp/keymint-blobs
+TEST_P(KeyBlobUpgradeTest, UseKeyBlobsBeforeOrAfter) {
+    std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ false);
+    if (subdir.empty()) {
+        GTEST_SKIP() << "No keyblob directory provided with (e.g.) --keyblob_dir "
+                        "/data/local/tmp/keymint-blobs";
+    }
+
+    for (std::string name : keyblob_names()) {
+        if (requires_attest_key(name) && shouldSkipAttestKeyTest()) {
+            std::cerr << "Skipping variant '" << name
+                      << "' which requires ATTEST_KEY support that has been waivered\n";
+            continue;
+        }
+        for (bool with_hidden : {false, true}) {
+            auto builder = AuthorizationSetBuilder();
+            if (with_hidden) {
+                // Build a variant keyblob that requires app_id/app_data
+                builder.Authorization(TAG_APPLICATION_ID, "appid")
+                        .Authorization(TAG_APPLICATION_DATA, "appdata");
+                name += "-hidden";
+            }
+            SCOPED_TRACE(testing::Message() << name);
+            std::vector<uint8_t> keyblob = load_keyblob(subdir, name);
+            if (keyblob.empty()) {
+                if (requires_rr(name)) {
+                    std::cerr << "Skipping missing keyblob file '" << name
+                              << "', assuming rollback resistance unavailable\n";
+                } else {
+                    FAIL() << "Missing keyblob file '" << name << "'";
+                }
+                continue;
+            }
+
+            std::vector<uint8_t> cert;
+            if (is_asymmetric(name)) {
+                cert = load_cert(subdir, name);
+            }
+
+            // Perform an algorithm-specific operation with the keyblob.
+            string message = "Hello World!";
+            AuthorizationSet out_params;
+            if (name.find("aes-key") != std::string::npos) {
+                builder.BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+                string ciphertext = EncryptMessage(keyblob, message, builder, &out_params);
+                string plaintext = DecryptMessage(keyblob, ciphertext, builder);
+                EXPECT_EQ(message, plaintext);
+            } else if (name.find("des-key") != std::string::npos) {
+                builder.BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+                string ciphertext = EncryptMessage(keyblob, message, builder, &out_params);
+                string plaintext = DecryptMessage(keyblob, ciphertext, builder);
+                EXPECT_EQ(message, plaintext);
+            } else if (name.find("hmac-key") != std::string::npos) {
+                builder.Digest(Digest::SHA_2_256);
+                auto sign_builder = builder;
+                sign_builder.Authorization(TAG_MAC_LENGTH, 128);
+                string tag = SignMessage(keyblob, message, sign_builder);
+                VerifyMessage(keyblob, message, tag, builder);
+            } else if (name.find("rsa-key") != std::string::npos) {
+                builder.Digest(Digest::NONE).Padding(PaddingMode::NONE);
+                string signature = SignMessage(keyblob, message, builder);
+                LocalVerifyMessage(cert, message, signature, builder);
+            } else if (name.find("p256-key") != std::string::npos) {
+                builder.Digest(Digest::SHA_2_256);
+                string signature = SignMessage(keyblob, message, builder);
+                LocalVerifyMessage(cert, message, signature, builder);
+            } else if (name.find("ed25519-key") != std::string::npos) {
+                builder.Digest(Digest::NONE);
+                string signature = SignMessage(keyblob, message, builder);
+                LocalVerifyMessage(cert, message, signature, builder);
+            } else if (name.find("x25519-key") != std::string::npos) {
+                // Generate EC key on same curve locally (with access to private key material).
+                uint8_t localPrivKeyData[32];
+                uint8_t localPubKeyData[32];
+                X25519_keypair(localPubKeyData, localPrivKeyData);
+                EVP_PKEY_Ptr localPrivKey(EVP_PKEY_new_raw_private_key(
+                        EVP_PKEY_X25519, nullptr, localPrivKeyData, sizeof(localPrivKeyData)));
+                // Get encoded form of the public part of the locally generated key.
+                unsigned char* p = nullptr;
+                int localPublicKeySize = i2d_PUBKEY(localPrivKey.get(), &p);
+                ASSERT_GT(localPublicKeySize, 0);
+                vector<uint8_t> localPublicKey(
+                        reinterpret_cast<const uint8_t*>(p),
+                        reinterpret_cast<const uint8_t*>(p + localPublicKeySize));
+                OPENSSL_free(p);
+
+                // Agree on a key between local and KeyMint.
+                string data;
+                ASSERT_EQ(ErrorCode::OK,
+                          Begin(KeyPurpose::AGREE_KEY, keyblob, builder, &out_params));
+                ASSERT_EQ(ErrorCode::OK,
+                          Finish(string(localPublicKey.begin(), localPublicKey.end()), &data));
+                vector<uint8_t> keymint_data(data.begin(), data.end());
+
+                // Extract the public key for the KeyMint key from the cert.
+                X509_Ptr kmKeyCert(parse_cert_blob(cert));
+                ASSERT_NE(kmKeyCert, nullptr);
+                EVP_PKEY_Ptr kmPubKey = EVP_PKEY_Ptr(X509_get_pubkey(kmKeyCert.get()));
+                ASSERT_NE(kmPubKey.get(), nullptr);
+
+                size_t kmPubKeySize = 32;
+                uint8_t kmPubKeyData[32];
+                ASSERT_EQ(1,
+                          EVP_PKEY_get_raw_public_key(kmPubKey.get(), kmPubKeyData, &kmPubKeySize));
+                ASSERT_EQ(kmPubKeySize, 32);
+
+                // Agree on a key between KeyMint and local.
+                uint8_t sharedKey[32];
+                ASSERT_EQ(1, X25519(sharedKey, localPrivKeyData, kmPubKeyData));
+                vector<uint8_t> local_data(sharedKey, sharedKey + 32);
+
+                // Both ways round should agree.
+                EXPECT_EQ(keymint_data, local_data);
+            } else if (requires_attest_key(name)) {
+                // Covers rsa-attest-key, p256-attest-key, ed25519-attest-key.
+
+                // Use attestation key to sign RSA signing key
+                AttestationKey attest_key;
+                attest_key.keyBlob = keyblob;
+                attest_key.attestKeyParams = builder.vector_data();
+                attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
+                vector<uint8_t> attested_key_blob;
+                vector<KeyCharacteristics> attested_key_characteristics;
+                vector<Certificate> attested_key_cert_chain;
+                EXPECT_EQ(ErrorCode::OK,
+                          GenerateKey(AuthorizationSetBuilder()
+                                              .RsaSigningKey(2048, 65537)
+                                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                                              .AttestationChallenge("challenge")
+                                              .AttestationApplicationId("app-id")
+                                              .SetDefaultValidity(),
+                                      attest_key, &attested_key_blob, &attested_key_characteristics,
+                                      &attested_key_cert_chain));
+                CheckedDeleteKey(&attested_key_blob);
+            } else {
+                FAIL() << "Unexpected name: " << name;
+            }
+        }
+    }
+}
+
+// This test target deletes any keys from the keyblob subdirectory that have rollback resistance
+// enabled.
+TEST_P(KeyBlobUpgradeTest, DeleteRRKeyBlobsAfter) {
+    std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ false);
+    if (subdir.empty()) {
+        GTEST_SKIP() << "No keyblob directory provided with (e.g.) --keyblob_dir "
+                        "/data/local/tmp/keymint-blobs";
+    }
+
+    for (std::string name : keyblob_names()) {
+        for (bool with_hidden : {false, true}) {
+            auto builder = AuthorizationSetBuilder();
+            if (with_hidden) {
+                // Build a variant keyblob that requires app_id/app_data
+                builder.Authorization(TAG_APPLICATION_ID, "appid")
+                        .Authorization(TAG_APPLICATION_DATA, "appdata");
+                name += "-hidden";
+            }
+            if (!requires_rr(name)) {
+                std::cerr << "Skipping keyblob file '" << name
+                          << "' which does not use rollback resistance\n";
+                continue;
+            }
+            SCOPED_TRACE(testing::Message() << name);
+            std::vector<uint8_t> keyblob = load_keyblob(subdir, name);
+            if (keyblob.empty()) {
+                std::cerr << "Skipping missing keyblob file '" << name
+                          << "', assuming rollback resistance unavailable\n";
+                continue;
+            }
+
+            // Delete the key
+            ASSERT_EQ(ErrorCode::OK, DeleteKey(&keyblob));
+
+            // Remove all files relating to the deleted key.
+            std::cerr << "Deleting files for deleted key '" << name << "';\n";
+            delete_keyblob(subdir, name);
+
+            // Attempting to use the keyblob after deletion should fail.
+            AuthorizationSet out_params;
+            if (name.find("aes-key") != std::string::npos) {
+                builder.BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+                EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+                          Begin(KeyPurpose::ENCRYPT, keyblob, builder, &out_params));
+            } else {
+                FAIL() << "Unexpected name: " << name;
+            }
+        }
+    }
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(KeyBlobUpgradeTest);
+
+}  // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 15693ac..433857c 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -108,6 +108,15 @@
     return true;
 }
 
+void check_crl_distribution_points_extension_not_present(X509* certificate) {
+    ASN1_OBJECT_Ptr crl_dp_oid(OBJ_txt2obj(kCrlDPOid, 1 /* dotted string format */));
+    ASSERT_TRUE(crl_dp_oid.get());
+
+    int location =
+            X509_get_ext_by_OBJ(certificate, crl_dp_oid.get(), -1 /* search from beginning */);
+    ASSERT_EQ(location, -1);
+}
+
 void check_attestation_version(uint32_t attestation_version, int32_t aidl_version) {
     // Version numbers in attestation extensions should be a multiple of 100.
     EXPECT_EQ(attestation_version % 100, 0);
@@ -164,6 +173,7 @@
 
 bool KeyMintAidlTestBase::arm_deleteAllKeys = false;
 bool KeyMintAidlTestBase::dump_Attestations = false;
+std::string KeyMintAidlTestBase::keyblob_dir;
 
 uint32_t KeyMintAidlTestBase::boot_patch_level(
         const vector<KeyCharacteristics>& key_characteristics) {
@@ -192,7 +202,15 @@
  * which is mandatory for KeyMint version 2 or first_api_level 33 or greater.
  */
 bool KeyMintAidlTestBase::isDeviceIdAttestationRequired() {
-    return AidlVersion() >= 2 || property_get_int32("ro.vendor.api_level", 0) >= 33;
+    return AidlVersion() >= 2 || property_get_int32("ro.vendor.api_level", 0) >= __ANDROID_API_T__;
+}
+
+/**
+ * An API to determine second IMEI ID attestation is required or not,
+ * which is supported for KeyMint version 3 or first_api_level greater than 33.
+ */
+bool KeyMintAidlTestBase::isSecondImeiIdAttestationRequired() {
+    return AidlVersion() >= 3 && property_get_int32("ro.vendor.api_level", 0) > __ANDROID_API_T__;
 }
 
 bool KeyMintAidlTestBase::Curve25519Supported() {
@@ -304,12 +322,13 @@
         const AuthorizationSet& attest_key_desc, const AuthorizationSet& key_desc,
         vector<uint8_t>* key_blob, vector<KeyCharacteristics>* key_characteristics,
         vector<Certificate>* cert_chain) {
+    skipAttestKeyTest();
     AttestationKey attest_key;
     vector<Certificate> attest_cert_chain;
     vector<KeyCharacteristics> attest_key_characteristics;
     // Generate a key with self signed attestation.
-    auto error = GenerateKey(attest_key_desc, std::nullopt, &attest_key.keyBlob,
-                             &attest_key_characteristics, &attest_cert_chain);
+    auto error = GenerateAttestKey(attest_key_desc, std::nullopt, &attest_key.keyBlob,
+                                   &attest_key_characteristics, &attest_cert_chain);
     if (error != ErrorCode::OK) {
         return error;
     }
@@ -522,12 +541,13 @@
 
 ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
                                      const AuthorizationSet& in_params,
-                                     AuthorizationSet* out_params) {
+                                     AuthorizationSet* out_params,
+                                     std::optional<HardwareAuthToken> hat) {
     SCOPED_TRACE("Begin");
     Status result;
     BeginResult out;
 
-    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), std::nullopt, &out);
+    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), hat, &out);
 
     if (result.isOk()) {
         *out_params = out.params;
@@ -581,8 +601,9 @@
     return GetReturnErrorCode(result);
 }
 
-ErrorCode KeyMintAidlTestBase::Finish(const string& input, const string& signature,
-                                      string* output) {
+ErrorCode KeyMintAidlTestBase::Finish(const string& input, const string& signature, string* output,
+                                      std::optional<HardwareAuthToken> hat,
+                                      std::optional<secureclock::TimeStampToken> time_token) {
     SCOPED_TRACE("Finish");
     Status result;
 
@@ -591,8 +612,8 @@
 
     vector<uint8_t> oPut;
     result = op_->finish(vector<uint8_t>(input.begin(), input.end()),
-                         vector<uint8_t>(signature.begin(), signature.end()), {} /* authToken */,
-                         {} /* timestampToken */, {} /* confirmationToken */, &oPut);
+                         vector<uint8_t>(signature.begin(), signature.end()), hat, time_token,
+                         {} /* confirmationToken */, &oPut);
 
     if (result.isOk()) output->append(oPut.begin(), oPut.end());
 
@@ -752,6 +773,100 @@
     }
 }
 
+void KeyMintAidlTestBase::AesCheckEncryptOneByteAtATime(const string& key, BlockMode block_mode,
+                                                        PaddingMode padding_mode, const string& iv,
+                                                        const string& plaintext,
+                                                        const string& exp_cipher_text) {
+    bool is_authenticated_cipher = (block_mode == BlockMode::GCM);
+    auto auth_set = AuthorizationSetBuilder()
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .AesEncryptionKey(key.size() * 8)
+                            .BlockMode(block_mode)
+                            .Padding(padding_mode);
+    if (iv.size() > 0) auth_set.Authorization(TAG_CALLER_NONCE);
+    if (is_authenticated_cipher) auth_set.Authorization(TAG_MIN_MAC_LENGTH, 128);
+    ASSERT_EQ(ErrorCode::OK, ImportKey(auth_set, KeyFormat::RAW, key));
+
+    CheckEncryptOneByteAtATime(block_mode, 16 /*block_size*/, padding_mode, iv, plaintext,
+                               exp_cipher_text);
+}
+
+void KeyMintAidlTestBase::CheckEncryptOneByteAtATime(BlockMode block_mode, const int block_size,
+                                                     PaddingMode padding_mode, const string& iv,
+                                                     const string& plaintext,
+                                                     const string& exp_cipher_text) {
+    bool is_stream_cipher = (block_mode == BlockMode::CTR || block_mode == BlockMode::GCM);
+    bool is_authenticated_cipher = (block_mode == BlockMode::GCM);
+    auto params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding_mode);
+    if (iv.size() > 0) params.Authorization(TAG_NONCE, iv.data(), iv.size());
+    if (is_authenticated_cipher) params.Authorization(TAG_MAC_LENGTH, 128);
+
+    AuthorizationSet output_params;
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &output_params));
+
+    string actual_ciphertext;
+    if (is_stream_cipher) {
+        // Assert that a 1 byte of output is produced for 1 byte of input.
+        // Every input byte produces an output byte.
+        for (int plaintext_index = 0; plaintext_index < plaintext.size(); plaintext_index++) {
+            string ciphertext;
+            EXPECT_EQ(ErrorCode::OK, Update(plaintext.substr(plaintext_index, 1), &ciphertext));
+            // Some StrongBox implementations cannot support 1:1 input:output lengths, so
+            // we relax this API restriction for them.
+            if (SecLevel() != SecurityLevel::STRONGBOX) {
+                EXPECT_EQ(1, ciphertext.size()) << "plaintext index: " << plaintext_index;
+            }
+            actual_ciphertext.append(ciphertext);
+        }
+        string ciphertext;
+        EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
+        if (SecLevel() != SecurityLevel::STRONGBOX) {
+            string expected_final_output;
+            if (is_authenticated_cipher) {
+                expected_final_output = exp_cipher_text.substr(plaintext.size());
+            }
+            EXPECT_EQ(expected_final_output, ciphertext);
+        }
+        actual_ciphertext.append(ciphertext);
+    } else {
+        // Assert that a block of output is produced once a full block of input is provided.
+        // Every input block produces an output block.
+        bool compare_output = true;
+        string additional_information;
+        int vendor_api_level = property_get_int32("ro.vendor.api_level", 0);
+        if (SecLevel() == SecurityLevel::STRONGBOX) {
+            // This is known to be broken on older vendor implementations.
+            if (vendor_api_level < __ANDROID_API_T__) {
+                compare_output = false;
+            } else {
+                additional_information = " (b/194134359) ";
+            }
+        }
+        for (int plaintext_index = 0; plaintext_index < plaintext.size(); plaintext_index++) {
+            string ciphertext;
+            EXPECT_EQ(ErrorCode::OK, Update(plaintext.substr(plaintext_index, 1), &ciphertext));
+            if (compare_output) {
+                if ((plaintext_index % block_size) == block_size - 1) {
+                    // Update is expected to have output a new block
+                    EXPECT_EQ(block_size, ciphertext.size())
+                            << "plaintext index: " << plaintext_index << additional_information;
+                } else {
+                    // Update is expected to have produced no output
+                    EXPECT_EQ(0, ciphertext.size())
+                            << "plaintext index: " << plaintext_index << additional_information;
+                }
+            }
+            actual_ciphertext.append(ciphertext);
+        }
+        string ciphertext;
+        EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
+        actual_ciphertext.append(ciphertext);
+    }
+    // Regardless of how the completed ciphertext got accumulated, it should match the expected
+    // ciphertext.
+    EXPECT_EQ(exp_cipher_text, actual_ciphertext);
+}
+
 void KeyMintAidlTestBase::CheckHmacTestVector(const string& key, const string& message,
                                               Digest digest, const string& expected_mac) {
     SCOPED_TRACE("CheckHmacTestVector");
@@ -832,9 +947,15 @@
                                              const AuthorizationSet& params) {
     SCOPED_TRACE("LocalVerifyMessage");
 
-    // Retrieve the public key from the leaf certificate.
     ASSERT_GT(cert_chain_.size(), 0);
-    X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+    LocalVerifyMessage(cert_chain_[0].encodedCertificate, message, signature, params);
+}
+
+void KeyMintAidlTestBase::LocalVerifyMessage(const vector<uint8_t>& der_cert, const string& message,
+                                             const string& signature,
+                                             const AuthorizationSet& params) {
+    // Retrieve the public key from the leaf certificate.
+    X509_Ptr key_cert(parse_cert_blob(der_cert));
     ASSERT_TRUE(key_cert.get());
     EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get()));
     ASSERT_TRUE(pub_key.get());
@@ -956,12 +1077,24 @@
         return "Failure";
     }
     X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+    if (key_cert.get() == nullptr) {
+        ADD_FAILURE() << "Failed to parse cert";
+        return "Failure";
+    }
     EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get()));
+    if (pub_key.get() == nullptr) {
+        ADD_FAILURE() << "Failed to retrieve public key";
+        return "Failure";
+    }
     RSA_Ptr rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pub_key.get())));
+    if (rsa.get() == nullptr) {
+        ADD_FAILURE() << "Failed to retrieve RSA public key";
+        return "Failure";
+    }
 
     // Retrieve relevant tags.
     Digest digest = Digest::NONE;
-    Digest mgf_digest = Digest::NONE;
+    Digest mgf_digest = Digest::SHA1;
     PaddingMode padding = PaddingMode::NONE;
 
     auto digest_tag = params.GetTagValue(TAG_DIGEST);
@@ -1160,6 +1293,16 @@
 
     return retval;
 }
+
+bool KeyMintAidlTestBase::IsRkpSupportRequired() const {
+    // This is technically not a match to the requirements for S chipsets,
+    // however when S shipped there was a bug in the test that skipped the
+    // tests if KeyMint 2 was not on the system. So we allowed many chipests
+    // to ship without RKP support. In T we hardened the requirements around
+    // support for RKP, so relax the test to match.
+    return get_vsr_api_level() >= __ANDROID_API_T__;
+}
+
 vector<uint32_t> KeyMintAidlTestBase::ValidKeySizes(Algorithm algorithm) {
     switch (algorithm) {
         case Algorithm::RSA:
@@ -1403,6 +1546,110 @@
     return result;
 }
 
+ErrorCode KeyMintAidlTestBase::GenerateAttestKey(const AuthorizationSet& key_desc,
+                                                 const optional<AttestationKey>& attest_key,
+                                                 vector<uint8_t>* key_blob,
+                                                 vector<KeyCharacteristics>* key_characteristics,
+                                                 vector<Certificate>* cert_chain) {
+    // The original specification for KeyMint v1 required ATTEST_KEY not be combined
+    // with any other key purpose, but the original VTS tests incorrectly did exactly that.
+    // This means that a device that launched prior to Android T (API level 33) may
+    // accept or even require KeyPurpose::SIGN too.
+    if (property_get_int32("ro.board.first_api_level", 0) < __ANDROID_API_T__) {
+        AuthorizationSet key_desc_plus_sign = key_desc;
+        key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN);
+
+        auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics,
+                                  cert_chain);
+        if (result == ErrorCode::OK) {
+            return result;
+        }
+        // If the key generation failed, it may be because the device is (correctly)
+        // rejecting the combination of ATTEST_KEY+SIGN.  Fall through to try again with
+        // just ATTEST_KEY.
+    }
+    return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain);
+}
+
+// Check if ATTEST_KEY feature is disabled
+bool KeyMintAidlTestBase::is_attest_key_feature_disabled(void) const {
+    if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) {
+        GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled";
+        return true;
+    }
+
+    return false;
+}
+
+// Check if StrongBox KeyStore is enabled
+bool KeyMintAidlTestBase::is_strongbox_enabled(void) const {
+    if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) {
+        GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled";
+        return true;
+    }
+
+    return false;
+}
+
+// Check if chipset has received a waiver allowing it to be launched with Android S or T with
+// Keymaster 4.0 in StrongBox.
+bool KeyMintAidlTestBase::is_chipset_allowed_km4_strongbox(void) const {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+
+    const int32_t first_api_level = property_get_int32("ro.board.first_api_level", 0);
+    if (first_api_level <= 0 || first_api_level > __ANDROID_API_T__) return false;
+
+    auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr);
+    if (res <= 0) return false;
+
+    const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"};
+
+    for (const string model : allowed_soc_models) {
+        if (model.compare(buffer.data()) == 0) {
+            GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0";
+            return true;
+        }
+    }
+
+    return false;
+}
+
+// Indicate whether a test that involves use of the ATTEST_KEY feature should be
+// skipped.
+//
+// In general, every KeyMint implementation should support ATTEST_KEY;
+// however, there is a waiver for some specific devices that ship with a
+// combination of Keymaster/StrongBox and KeyMint/TEE.  On these devices, the
+// ATTEST_KEY feature is disabled in the KeyMint/TEE implementation so that
+// the device has consistent ATTEST_KEY behavior (ie. UNIMPLEMENTED) across both
+// HAL implementations.
+//
+// This means that a test involving ATTEST_KEY test should be skipped if all of
+// the following conditions hold:
+// 1. The device is running one of the chipsets that have received a waiver
+//     allowing it to be launched with Android S or T with Keymaster 4.0
+//     in StrongBox
+// 2. The device has a STRONGBOX implementation present.
+// 3. ATTEST_KEY feature is advertised as disabled.
+//
+// Note that in this scenario, ATTEST_KEY tests should be skipped for both
+// the StrongBox implementation (which is Keymaster, therefore not tested here)
+// and for the TEE implementation (which is adjusted to return UNIMPLEMENTED
+// specifically for this waiver).
+bool KeyMintAidlTestBase::shouldSkipAttestKeyTest(void) const {
+    // Check the chipset first as that doesn't require a round-trip to Package Manager.
+    return (is_chipset_allowed_km4_strongbox() && is_strongbox_enabled() &&
+            is_attest_key_feature_disabled());
+}
+
+// Skip a test that involves use of the ATTEST_KEY feature in specific configurations
+// where ATTEST_KEY is not supported (for either StrongBox or TEE).
+void KeyMintAidlTestBase::skipAttestKeyTest(void) const {
+    if (shouldSkipAttestKeyTest()) {
+        GTEST_SKIP() << "Test using ATTEST_KEY is not applicable on waivered device";
+    }
+}
+
 void verify_serial(X509* cert, const uint64_t expected_serial) {
     BIGNUM_Ptr ser(BN_new());
     EXPECT_TRUE(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), ser.get()));
@@ -1567,6 +1814,10 @@
     EXPECT_TRUE(!!cert.get());
     if (!cert.get()) return false;
 
+    // Make sure CRL Distribution Points extension is not present in a certificate
+    // containing attestation record.
+    check_crl_distribution_points_extension_not_present(cert.get());
+
     ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
     EXPECT_TRUE(!!attest_rec);
     if (!attest_rec) return false;
@@ -1609,38 +1860,33 @@
     EXPECT_EQ(security_level, att_keymint_security_level);
     EXPECT_EQ(security_level, att_attestation_security_level);
 
-    // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed
-    // keymint implementation will report YYYYMM dates instead of YYYYMMDD
-    // for the BOOT_PATCH_LEVEL.
-    if (avb_verification_enabled()) {
-        for (int i = 0; i < att_hw_enforced.size(); i++) {
-            if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
-                att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
-                std::string date =
-                        std::to_string(att_hw_enforced[i].value.get<KeyParameterValue::integer>());
+    for (int i = 0; i < att_hw_enforced.size(); i++) {
+        if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
+            att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
+            std::string date =
+                    std::to_string(att_hw_enforced[i].value.get<KeyParameterValue::integer>());
 
-                // strptime seems to require delimiters, but the tag value will
-                // be YYYYMMDD
-                if (date.size() != 8) {
-                    ADD_FAILURE() << "Tag " << att_hw_enforced[i].tag
-                                  << " with invalid format (not YYYYMMDD): " << date;
-                    return false;
-                }
-                date.insert(6, "-");
-                date.insert(4, "-");
-                struct tm time;
-                strptime(date.c_str(), "%Y-%m-%d", &time);
-
-                // Day of the month (0-31)
-                EXPECT_GE(time.tm_mday, 0);
-                EXPECT_LT(time.tm_mday, 32);
-                // Months since Jan (0-11)
-                EXPECT_GE(time.tm_mon, 0);
-                EXPECT_LT(time.tm_mon, 12);
-                // Years since 1900
-                EXPECT_GT(time.tm_year, 110);
-                EXPECT_LT(time.tm_year, 200);
+            // strptime seems to require delimiters, but the tag value will
+            // be YYYYMMDD
+            if (date.size() != 8) {
+                ADD_FAILURE() << "Tag " << att_hw_enforced[i].tag
+                              << " with invalid format (not YYYYMMDD): " << date;
+                return false;
             }
+            date.insert(6, "-");
+            date.insert(4, "-");
+            struct tm time;
+            strptime(date.c_str(), "%Y-%m-%d", &time);
+
+            // Day of the month (0-31)
+            EXPECT_GE(time.tm_mday, 0);
+            EXPECT_LT(time.tm_mday, 32);
+            // Months since Jan (0-11)
+            EXPECT_GE(time.tm_mon, 0);
+            EXPECT_LT(time.tm_mon, 12);
+            // Years since 1900
+            EXPECT_GT(time.tm_year, 110);
+            EXPECT_LT(time.tm_year, 200);
         }
     }
 
@@ -1814,30 +2060,32 @@
 
     // The following check assumes that canonical CBOR encoding is used for the COSE_Key.
     if (testMode) {
-        EXPECT_THAT(cppbor::prettyPrint(parsedPayload.get()),
-                    MatchesRegex("{\n"
-                                 "  1 : 2,\n"   // kty: EC2
-                                 "  3 : -7,\n"  // alg: ES256
-                                 "  -1 : 1,\n"  // EC id: P256
-                                 // The regex {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}} matches a
-                                 // sequence of 32 hexadecimal bytes, enclosed in braces and
-                                 // separated by commas. In this case, some Ed25519 public key.
-                                 "  -2 : {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}},\n"  // pub_x: data
-                                 "  -3 : {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}},\n"  // pub_y: data
-                                 "  -70000 : null,\n"                              // test marker
-                                 "}"));
+        EXPECT_THAT(
+                cppbor::prettyPrint(parsedPayload.get()),
+                MatchesRegex("\\{\n"
+                             "  1 : 2,\n"   // kty: EC2
+                             "  3 : -7,\n"  // alg: ES256
+                             "  -1 : 1,\n"  // EC id: P256
+                             // The regex {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}} matches a
+                             // sequence of 32 hexadecimal bytes, enclosed in braces and
+                             // separated by commas. In this case, some Ed25519 public key.
+                             "  -2 : \\{(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}\\},\n"  // pub_x: data
+                             "  -3 : \\{(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}\\},\n"  // pub_y: data
+                             "  -70000 : null,\n"                                  // test marker
+                             "\\}"));
     } else {
-        EXPECT_THAT(cppbor::prettyPrint(parsedPayload.get()),
-                    MatchesRegex("{\n"
-                                 "  1 : 2,\n"   // kty: EC2
-                                 "  3 : -7,\n"  // alg: ES256
-                                 "  -1 : 1,\n"  // EC id: P256
-                                 // The regex {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}} matches a
-                                 // sequence of 32 hexadecimal bytes, enclosed in braces and
-                                 // separated by commas. In this case, some Ed25519 public key.
-                                 "  -2 : {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}},\n"  // pub_x: data
-                                 "  -3 : {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}},\n"  // pub_y: data
-                                 "}"));
+        EXPECT_THAT(
+                cppbor::prettyPrint(parsedPayload.get()),
+                MatchesRegex("\\{\n"
+                             "  1 : 2,\n"   // kty: EC2
+                             "  3 : -7,\n"  // alg: ES256
+                             "  -1 : 1,\n"  // EC id: P256
+                             // The regex {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}} matches a
+                             // sequence of 32 hexadecimal bytes, enclosed in braces and
+                             // separated by commas. In this case, some Ed25519 public key.
+                             "  -2 : \\{(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}\\},\n"  // pub_x: data
+                             "  -3 : \\{(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}\\},\n"  // pub_y: data
+                             "\\}"));
     }
 }
 
@@ -1931,10 +2179,16 @@
     } else if (result == ErrorCode::INVALID_TAG) {
         // Depending on the situation, other error codes may be acceptable.  First, allow older
         // implementations to use INVALID_TAG.
+        ASSERT_FALSE(get_vsr_api_level() > __ANDROID_API_T__)
+                << "It is a specification violation for INVALID_TAG to be returned due to ID "
+                << "mismatch in a Device ID Attestation call. INVALID_TAG is only intended to "
+                << "be used for a case where updateAad() is called after update(). As of "
+                << "VSR-14, this is now enforced as an error.";
     } else if (result == ErrorCode::ATTESTATION_IDS_NOT_PROVISIONED) {
         // If the device is not a phone, it will not have IMEI/MEID values available.  Allow
         // ATTESTATION_IDS_NOT_PROVISIONED in this case.
-        ASSERT_TRUE((tag == TAG_ATTESTATION_ID_IMEI || tag == TAG_ATTESTATION_ID_MEID))
+        ASSERT_TRUE((tag == TAG_ATTESTATION_ID_IMEI || tag == TAG_ATTESTATION_ID_MEID ||
+                     tag == TAG_ATTESTATION_ID_SECOND_IMEI))
                 << "incorrect error code on attestation ID mismatch";
     } else {
         ADD_FAILURE() << "Error code " << result
@@ -1945,9 +2199,10 @@
 // Check whether the given named feature is available.
 bool check_feature(const std::string& name) {
     ::android::sp<::android::IServiceManager> sm(::android::defaultServiceManager());
-    ::android::sp<::android::IBinder> binder(sm->getService(::android::String16("package_native")));
+    ::android::sp<::android::IBinder> binder(
+        sm->waitForService(::android::String16("package_native")));
     if (binder == nullptr) {
-        GTEST_LOG_(ERROR) << "getService package_native failed";
+        GTEST_LOG_(ERROR) << "waitForService package_native failed";
         return false;
     }
     ::android::sp<::android::content::pm::IPackageManagerNative> packageMgr =
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 2489ab2..d8c9f11 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -54,6 +54,9 @@
 
 constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF;
 
+const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key";
+const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
+
 class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
   public:
     struct KeyData {
@@ -64,6 +67,10 @@
     static bool arm_deleteAllKeys;
     static bool dump_Attestations;
 
+    // Directory to store/retrieve keyblobs, using subdirectories named for the
+    // KeyMint instance in question (e.g. "./default/", "./strongbox/").
+    static std::string keyblob_dir;
+
     void SetUp() override;
     void TearDown() override {
         if (key_blob_.size()) {
@@ -81,6 +88,7 @@
     uint32_t boot_patch_level(const vector<KeyCharacteristics>& key_characteristics);
     uint32_t boot_patch_level();
     bool isDeviceIdAttestationRequired();
+    bool isSecondImeiIdAttestationRequired();
 
     bool Curve25519Supported();
 
@@ -156,7 +164,8 @@
                     const AuthorizationSet& in_params, AuthorizationSet* out_params,
                     std::shared_ptr<IKeyMintOperation>& op);
     ErrorCode Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
-                    const AuthorizationSet& in_params, AuthorizationSet* out_params);
+                    const AuthorizationSet& in_params, AuthorizationSet* out_params,
+                    std::optional<HardwareAuthToken> hat = std::nullopt);
     ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params,
                     AuthorizationSet* out_params);
     ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params);
@@ -164,7 +173,9 @@
     ErrorCode UpdateAad(const string& input);
     ErrorCode Update(const string& input, string* output);
 
-    ErrorCode Finish(const string& message, const string& signature, string* output);
+    ErrorCode Finish(const string& message, const string& signature, string* output,
+                     std::optional<HardwareAuthToken> hat = std::nullopt,
+                     std::optional<secureclock::TimeStampToken> time_token = std::nullopt);
     ErrorCode Finish(const string& message, string* output) {
         return Finish(message, {} /* signature */, output);
     }
@@ -188,6 +199,10 @@
 
     void CheckAesIncrementalEncryptOperation(BlockMode block_mode, int message_size);
 
+    void AesCheckEncryptOneByteAtATime(const string& key, BlockMode block_mode,
+                                       PaddingMode padding_mode, const string& iv,
+                                       const string& plaintext, const string& exp_cipher_text);
+
     void CheckHmacTestVector(const string& key, const string& message, Digest digest,
                              const string& expected_mac);
 
@@ -202,6 +217,8 @@
                        const string& signature, const AuthorizationSet& params);
     void VerifyMessage(const string& message, const string& signature,
                        const AuthorizationSet& params);
+    void LocalVerifyMessage(const vector<uint8_t>& der_cert, const string& message,
+                            const string& signature, const AuthorizationSet& params);
     void LocalVerifyMessage(const string& message, const string& signature,
                             const AuthorizationSet& params);
 
@@ -295,6 +312,7 @@
     }
     bool IsSecure() const { return securityLevel_ != SecurityLevel::SOFTWARE; }
     SecurityLevel SecLevel() const { return securityLevel_; }
+    bool IsRkpSupportRequired() const;
 
     vector<uint32_t> ValidKeySizes(Algorithm algorithm);
     vector<uint32_t> InvalidKeySizes(Algorithm algorithm);
@@ -332,6 +350,18 @@
     ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob);
     ErrorCode UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob);
 
+    ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc,
+                                const optional<AttestationKey>& attest_key,
+                                vector<uint8_t>* key_blob,
+                                vector<KeyCharacteristics>* key_characteristics,
+                                vector<Certificate>* cert_chain);
+
+    bool is_attest_key_feature_disabled(void) const;
+    bool is_strongbox_enabled(void) const;
+    bool is_chipset_allowed_km4_strongbox(void) const;
+    bool shouldSkipAttestKeyTest(void) const;
+    void skipAttestKeyTest(void) const;
+
   protected:
     std::shared_ptr<IKeyMintDevice> keymint_;
     uint32_t os_version_;
@@ -342,7 +372,12 @@
     SecurityLevel securityLevel_;
     string name_;
     string author_;
-    long challenge_;
+    int64_t challenge_;
+
+  private:
+    void CheckEncryptOneByteAtATime(BlockMode block_mode, const int block_size,
+                                    PaddingMode padding_mode, const string& iv,
+                                    const string& plaintext, const string& exp_cipher_text);
 };
 
 // If the given property is available, add it to the tag set under the given tag ID.
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 18d49e9..2e6fa3b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -26,6 +26,7 @@
 #include <openssl/ec.h>
 #include <openssl/evp.h>
 #include <openssl/mem.h>
+#include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
 #include <cutils/properties.h>
@@ -590,8 +591,7 @@
     return name.substr(pos + 1);
 }
 
-bool matching_rp_instance(const string& km_name,
-                          std::shared_ptr<IRemotelyProvisionedComponent>* rp) {
+std::shared_ptr<IRemotelyProvisionedComponent> matching_rp_instance(const std::string& km_name) {
     string km_suffix = device_suffix(km_name);
 
     vector<string> rp_names =
@@ -601,11 +601,10 @@
         // KeyMint instance, assume they match.
         if (device_suffix(rp_name) == km_suffix && AServiceManager_isDeclared(rp_name.c_str())) {
             ::ndk::SpAIBinder binder(AServiceManager_waitForService(rp_name.c_str()));
-            *rp = IRemotelyProvisionedComponent::fromBinder(binder);
-            return true;
+            return IRemotelyProvisionedComponent::fromBinder(binder);
         }
     }
-    return false;
+    return nullptr;
 }
 
 }  // namespace
@@ -613,7 +612,7 @@
 class NewKeyGenerationTest : public KeyMintAidlTestBase {
   protected:
     void CheckBaseParams(const vector<KeyCharacteristics>& keyCharacteristics) {
-        AuthorizationSet auths = CheckCommonParams(keyCharacteristics);
+        AuthorizationSet auths = CheckCommonParams(keyCharacteristics, KeyOrigin::GENERATED);
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
 
         // Check that some unexpected tags/values are NOT present.
@@ -622,20 +621,21 @@
     }
 
     void CheckSymmetricParams(const vector<KeyCharacteristics>& keyCharacteristics) {
-        AuthorizationSet auths = CheckCommonParams(keyCharacteristics);
+        AuthorizationSet auths = CheckCommonParams(keyCharacteristics, KeyOrigin::GENERATED);
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::ENCRYPT));
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT));
 
         EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
     }
 
-    AuthorizationSet CheckCommonParams(const vector<KeyCharacteristics>& keyCharacteristics) {
+    AuthorizationSet CheckCommonParams(const vector<KeyCharacteristics>& keyCharacteristics,
+                                       const KeyOrigin expectedKeyOrigin) {
         // TODO(swillden): Distinguish which params should be in which auth list.
         AuthorizationSet auths;
         for (auto& entry : keyCharacteristics) {
             auths.push_back(AuthorizationSet(entry.authorizations));
         }
-        EXPECT_TRUE(auths.Contains(TAG_ORIGIN, KeyOrigin::GENERATED));
+        EXPECT_TRUE(auths.Contains(TAG_ORIGIN, expectedKeyOrigin));
 
         // Verify that App data, ROT and auth timeout are NOT included.
         EXPECT_FALSE(auths.Contains(TAG_ROOT_OF_TRUST));
@@ -740,6 +740,7 @@
 
     for (auto block_mode : ValidBlockModes(Algorithm::AES)) {
         for (auto padding_mode : ValidPaddingModes(Algorithm::AES, block_mode)) {
+            SCOPED_TRACE(testing::Message() << "AES-unknown-" << block_mode << "-" << padding_mode);
             vector<uint8_t> key_blob;
             vector<KeyCharacteristics> key_characteristics;
             // No key size specified
@@ -993,6 +994,7 @@
  */
 TEST_P(NewKeyGenerationTest, Rsa) {
     for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        SCOPED_TRACE(testing::Message() << "RSA-" << key_size);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -1024,6 +1026,15 @@
  * without providing NOT_BEFORE and NOT_AFTER parameters.
  */
 TEST_P(NewKeyGenerationTest, RsaWithMissingValidity) {
+    if (AidlVersion() < 3) {
+        /*
+         * The KeyMint V1 spec required that CERTIFICATE_NOT_{BEFORE,AFTER} be
+         * specified for asymmetric key generation. However, this was not
+         * checked at the time so we can only be strict about checking this for
+         * implementations of KeyMint version 2 and above.
+         */
+        GTEST_SKIP() << "Validity strict since KeyMint v2";
+    }
     // Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to
     // GeneralizedTime 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
     constexpr uint64_t kUndefinedExpirationDateTime = 253402300799000;
@@ -1049,6 +1060,42 @@
 }
 
 /*
+ * NewKeyGenerationTest.RsaWithSpecifiedValidity
+ *
+ * Verifies that KeyMint respects specified NOT_BEFORE and NOT_AFTER certificate dates.
+ */
+TEST_P(NewKeyGenerationTest, RsaWithSpecifiedValidity) {
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(AuthorizationSetBuilder()
+                                  .RsaSigningKey(2048, 65537)
+                                  .Digest(Digest::NONE)
+                                  .Padding(PaddingMode::NONE)
+                                  .Authorization(TAG_CERTIFICATE_NOT_BEFORE,
+                                                 1183806000000 /* 2007-07-07T11:00:00Z */)
+                                  .Authorization(TAG_CERTIFICATE_NOT_AFTER,
+                                                 1916049600000 /* 2030-09-19T12:00:00Z */),
+                          &key_blob, &key_characteristics));
+    ASSERT_GT(cert_chain_.size(), 0);
+
+    X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+    ASSERT_TRUE(!!cert.get());
+
+    const ASN1_TIME* not_before = X509_get0_notBefore(cert.get());
+    ASSERT_NE(not_before, nullptr);
+    time_t not_before_time;
+    ASSERT_EQ(ASN1_TIME_to_time_t(not_before, &not_before_time), 1);
+    EXPECT_EQ(not_before_time, 1183806000);
+
+    const ASN1_TIME* not_after = X509_get0_notAfter(cert.get());
+    ASSERT_NE(not_after, nullptr);
+    time_t not_after_time;
+    ASSERT_EQ(ASN1_TIME_to_time_t(not_after, &not_after_time), 1);
+    EXPECT_EQ(not_after_time, 1916049600);
+}
+
+/*
  * NewKeyGenerationTest.RsaWithAttestation
  *
  * Verifies that keymint can generate all required RSA key sizes with attestation, and that the
@@ -1065,6 +1112,7 @@
     vector<uint8_t> serial_blob(build_serial_blob(serial_int));
 
     for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        SCOPED_TRACE(testing::Message() << "RSA-" << key_size);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         auto builder = AuthorizationSetBuilder()
@@ -1102,9 +1150,9 @@
                 << "Key size " << key_size << "missing";
         EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
 
+        ASSERT_GT(cert_chain_.size(), 0);
         verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-        ASSERT_GT(cert_chain_.size(), 0);
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -1117,21 +1165,24 @@
 }
 
 /*
- * NewKeyGenerationTest.RsaWithRpkAttestation
+ * NewKeyGenerationTest.RsaWithRkpAttestation
  *
- * Verifies that keymint can generate all required RSA key sizes, using an attestation key
+ * Verifies that keymint can generate all required RSA key sizes using an attestation key
  * that has been generated using an associate IRemotelyProvisionedComponent.
- *
- * This test is disabled because the KeyMint specification does not require that implementations
- * of the first version of KeyMint have to also implement IRemotelyProvisionedComponent.
- * However, the test is kept in the code because KeyMint v2 will impose this requirement.
  */
-TEST_P(NewKeyGenerationTest, DISABLED_RsaWithRpkAttestation) {
-    // There should be an IRemotelyProvisionedComponent instance associated with the KeyMint
-    // instance.
-    std::shared_ptr<IRemotelyProvisionedComponent> rp;
-    ASSERT_TRUE(matching_rp_instance(GetParam(), &rp))
-            << "No IRemotelyProvisionedComponent found that matches KeyMint device " << GetParam();
+TEST_P(NewKeyGenerationTest, RsaWithRkpAttestation) {
+    if (!IsRkpSupportRequired()) {
+        GTEST_SKIP() << "RKP support is not required on this platform";
+    }
+
+    // Check for an IRemotelyProvisionedComponent instance associated with the
+    // KeyMint instance.
+    std::shared_ptr<IRemotelyProvisionedComponent> rp = matching_rp_instance(GetParam());
+    if (rp == nullptr && SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Encountered StrongBox implementation that does not support RKP";
+    }
+    ASSERT_NE(rp, nullptr) << "No IRemotelyProvisionedComponent found that matches KeyMint device "
+                           << GetParam();
 
     // Generate a P-256 keypair to use as an attestation key.
     MacedPublicKey macedPubKey;
@@ -1147,6 +1198,7 @@
     attestation_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
 
     for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        SCOPED_TRACE(testing::Message() << "RSA-" << key_size);
         auto challenge = "hello";
         auto app_id = "foo";
 
@@ -1178,6 +1230,85 @@
         EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_));
 
         // The signature over the attested key should correspond to the P256 public key.
+        ASSERT_GT(cert_chain_.size(), 0);
+        X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+        ASSERT_TRUE(key_cert.get());
+        EVP_PKEY_Ptr signing_pubkey;
+        p256_pub_key(coseKeyData, &signing_pubkey);
+        ASSERT_TRUE(signing_pubkey.get());
+
+        ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
+                << "Verification of attested certificate failed "
+                << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
+ * NewKeyGenerationTest.EcdsaWithRkpAttestation
+ *
+ * Verifies that keymint can generate all required ECDSA key sizes using an attestation key
+ * that has been generated using an associate IRemotelyProvisionedComponent.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaWithRkpAttestation) {
+    if (!IsRkpSupportRequired()) {
+        GTEST_SKIP() << "RKP support is not required on this platform";
+    }
+
+    // Check for an IRemotelyProvisionedComponent instance associated with the
+    // KeyMint instance.
+    std::shared_ptr<IRemotelyProvisionedComponent> rp = matching_rp_instance(GetParam());
+    if (rp == nullptr && SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Encountered StrongBox implementation that does not support RKP";
+    }
+    ASSERT_NE(rp, nullptr) << "No IRemotelyProvisionedComponent found that matches KeyMint device "
+                           << GetParam();
+
+    // Generate a P-256 keypair to use as an attestation key.
+    MacedPublicKey macedPubKey;
+    std::vector<uint8_t> privateKeyBlob;
+    auto status =
+            rp->generateEcdsaP256KeyPair(/* testMode= */ false, &macedPubKey, &privateKeyBlob);
+    ASSERT_TRUE(status.isOk());
+    vector<uint8_t> coseKeyData;
+    check_maced_pubkey(macedPubKey, /* testMode= */ false, &coseKeyData);
+
+    AttestationKey attestation_key;
+    attestation_key.keyBlob = std::move(privateKeyBlob);
+    attestation_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
+
+    for (auto curve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
+        auto challenge = "hello";
+        auto app_id = "foo";
+
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK,
+                  GenerateKey(AuthorizationSetBuilder()
+                                      .EcdsaSigningKey(curve)
+                                      .Digest(Digest::NONE)
+                                      .AttestationChallenge(challenge)
+                                      .AttestationApplicationId(app_id)
+                                      .Authorization(TAG_NO_AUTH_REQUIRED)
+                                      .SetDefaultValidity(),
+                              attestation_key, &key_blob, &key_characteristics, &cert_chain_));
+
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+        CheckCharacteristics(key_blob, key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing";
+
+        // Attestation by itself is not valid (last entry is not self-signed).
+        EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_));
+
+        // The signature over the attested key should correspond to the P256 public key.
+        ASSERT_GT(cert_chain_.size(), 0);
         X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
         ASSERT_TRUE(key_cert.get());
         EVP_PKEY_Ptr signing_pubkey;
@@ -1265,9 +1396,9 @@
             << "Key size " << key_size << "missing";
     EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
 
+    ASSERT_GT(cert_chain_.size(), 0);
     verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
     EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-    ASSERT_GT(cert_chain_.size(), 0);
 
     AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
     AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -1293,6 +1424,7 @@
     vector<uint8_t> serial_blob(build_serial_blob(serial_int));
 
     for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        SCOPED_TRACE(testing::Message() << "RSA-" << key_size);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK,
@@ -1317,9 +1449,9 @@
                 << "Key size " << key_size << "missing";
         EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
 
+        ASSERT_EQ(cert_chain_.size(), 1);
         verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-        ASSERT_EQ(cert_chain_.size(), 1);
 
         CheckedDeleteKey(&key_blob);
     }
@@ -1398,6 +1530,7 @@
             << "Key size " << key_size << "missing";
     EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
 
+    ASSERT_GT(cert_chain_.size(), 0);
     verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
     EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
     ASSERT_EQ(cert_chain_.size(), 1);
@@ -1413,6 +1546,7 @@
  */
 TEST_P(NewKeyGenerationTest, LimitedUsageRsa) {
     for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        SCOPED_TRACE(testing::Message() << "RSA-" << key_size);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -1463,6 +1597,7 @@
     vector<uint8_t> serial_blob(build_serial_blob(serial_int));
 
     for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        SCOPED_TRACE(testing::Message() << "RSA-" << key_size);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         auto builder = AuthorizationSetBuilder()
@@ -1532,6 +1667,7 @@
  */
 TEST_P(NewKeyGenerationTest, NoInvalidRsaSizes) {
     for (auto key_size : InvalidKeySizes(Algorithm::RSA)) {
+        SCOPED_TRACE(testing::Message() << "RSA-" << key_size);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
@@ -1566,6 +1702,7 @@
  */
 TEST_P(NewKeyGenerationTest, RsaMissingParams) {
     for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        SCOPED_TRACE(testing::Message() << "RSA-" << key_size);
         ASSERT_EQ(ErrorCode::OK,
                   GenerateKey(
                           AuthorizationSetBuilder().RsaKey(key_size, 65537).SetDefaultValidity()));
@@ -1581,6 +1718,7 @@
  */
 TEST_P(NewKeyGenerationTest, Ecdsa) {
     for (auto curve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -1667,6 +1805,15 @@
  * without providing NOT_BEFORE and NOT_AFTER parameters.
  */
 TEST_P(NewKeyGenerationTest, EcdsaWithMissingValidity) {
+    if (AidlVersion() < 2) {
+        /*
+         * The KeyMint V1 spec required that CERTIFICATE_NOT_{BEFORE,AFTER} be
+         * specified for asymmetric key generation. However, this was not
+         * checked at the time so we can only be strict about checking this for
+         * implementations of KeyMint version 2 and above.
+         */
+        GTEST_SKIP() << "Validity strict since KeyMint v2";
+    }
     // Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to
     // GeneralizedTime 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
     constexpr uint64_t kUndefinedExpirationDateTime = 253402300799000;
@@ -1706,6 +1853,7 @@
     vector<uint8_t> serial_blob(build_serial_blob(serial_int));
 
     for (auto curve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         auto builder = AuthorizationSetBuilder()
@@ -1974,12 +2122,38 @@
 
     // Various ATTESTATION_ID_* tags that map to fields in the attestation extension ASN.1 schema.
     auto extra_tags = AuthorizationSetBuilder();
-    add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
+    // Use ro.product.brand_for_attestation property for attestation if it is present else fallback
+    // to ro.product.brand
+    std::string prop_value =
+            ::android::base::GetProperty("ro.product.brand_for_attestation", /* default= */ "");
+    if (!prop_value.empty()) {
+        add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_BRAND,
+                          "ro.product.brand_for_attestation");
+    } else {
+        add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
+    }
     add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
-    add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
-    add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial");
+    // Use ro.product.name_for_attestation property for attestation if it is present else fallback
+    // to ro.product.name
+    prop_value = ::android::base::GetProperty("ro.product.name_for_attestation", /* default= */ "");
+    if (!prop_value.empty()) {
+        add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_PRODUCT,
+                          "ro.product.name_for_attestation");
+    } else {
+        add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
+    }
+    add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
     add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_MANUFACTURER, "ro.product.manufacturer");
-    add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
+    // Use ro.product.model_for_attestation property for attestation if it is present else fallback
+    // to ro.product.model
+    prop_value =
+            ::android::base::GetProperty("ro.product.model_for_attestation", /* default= */ "");
+    if (!prop_value.empty()) {
+        add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_MODEL,
+                          "ro.product.model_for_attestation");
+    } else {
+        add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
+    }
 
     for (const KeyParameter& tag : extra_tags) {
         SCOPED_TRACE(testing::Message() << "tag-" << tag);
@@ -2209,6 +2383,7 @@
     vector<uint8_t> serial_blob(build_serial_blob(serial_int));
 
     for (auto curve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK,
@@ -2229,8 +2404,8 @@
         EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing";
 
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-        verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
         ASSERT_EQ(cert_chain_.size(), 1);
+        verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -2280,6 +2455,7 @@
     auto app_id = "foo";
 
     for (auto curve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -2321,6 +2497,7 @@
     std::vector<uint32_t> app_id_lengths{143, 258};
 
     for (uint32_t length : app_id_lengths) {
+        SCOPED_TRACE(testing::Message() << "app_id_len=" << length);
         const string app_id(length, 'a');
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
@@ -2375,6 +2552,7 @@
  */
 TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) {
     for (auto curve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -2428,6 +2606,7 @@
  */
 TEST_P(NewKeyGenerationTest, EcdsaInvalidCurve) {
     for (auto curve : InvalidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         auto result = GenerateKey(AuthorizationSetBuilder()
@@ -2449,6 +2628,29 @@
 }
 
 /*
+ * NewKeyGenerationTest.EcdsaMissingCurve
+ *
+ * Verifies that EC key generation fails if EC_CURVE not specified after KeyMint V3.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaMissingCurve) {
+    if (AidlVersion() < 3) {
+        /*
+         * The KeyMint V1 spec required that EC_CURVE be specified for EC keys.
+         * However, this was not checked at the time so we can only be strict about checking this
+         * for implementations of KeyMint version 3 and above.
+         */
+        GTEST_SKIP() << "Requiring EC_CURVE only strict since KeyMint v3";
+    }
+    /* If EC_CURVE not provided, generateKey
+     * must return ErrorCode::UNSUPPORTED_KEY_SIZE or ErrorCode::UNSUPPORTED_EC_CURVE.
+     */
+    auto result = GenerateKey(
+            AuthorizationSetBuilder().EcdsaKey(256).Digest(Digest::NONE).SetDefaultValidity());
+    ASSERT_TRUE(result == ErrorCode::UNSUPPORTED_KEY_SIZE ||
+                result == ErrorCode::UNSUPPORTED_EC_CURVE);
+}
+
+/*
  * NewKeyGenerationTest.EcdsaMismatchKeySize
  *
  * Verifies that specifying mismatched key size and curve for EC key generation returns
@@ -2482,6 +2684,7 @@
         digest = Digest::SHA_2_512;
     }
     for (auto curve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
         EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                                      .EcdsaSigningKey(curve)
                                                      .Digest(digest)
@@ -2499,6 +2702,7 @@
  */
 TEST_P(NewKeyGenerationTest, Hmac) {
     for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) {
+        SCOPED_TRACE(testing::Message() << "Digest::" << digest);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         constexpr size_t key_size = 128;
@@ -2532,6 +2736,7 @@
     auto app_id = "foo";
 
     for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) {
+        SCOPED_TRACE(testing::Message() << "Digest::" << digest);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         constexpr size_t key_size = 128;
@@ -2565,6 +2770,7 @@
  */
 TEST_P(NewKeyGenerationTest, LimitedUsageHmac) {
     for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) {
+        SCOPED_TRACE(testing::Message() << "Digest::" << digest);
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         constexpr size_t key_size = 128;
@@ -2603,6 +2809,7 @@
  */
 TEST_P(NewKeyGenerationTest, HmacCheckKeySizes) {
     for (size_t key_size = 0; key_size <= 512; ++key_size) {
+        SCOPED_TRACE(testing::Message() << "HMAC-" << key_size);
         if (key_size < 64 || key_size % 8 != 0) {
             // To keep this test from being very slow, we only test a random fraction of
             // non-byte key sizes.  We test only ~10% of such cases. Since there are 392 of
@@ -2645,6 +2852,7 @@
  */
 TEST_P(NewKeyGenerationTest, HmacCheckMinMacLengths) {
     for (size_t min_mac_length = 0; min_mac_length <= 256; ++min_mac_length) {
+        SCOPED_TRACE(testing::Message() << "MIN_MAC_LENGTH=" << min_mac_length);
         if (min_mac_length < 64 || min_mac_length % 8 != 0) {
             // To keep this test from being very long, we only test a random fraction of
             // non-byte lengths.  We test only ~10% of such cases. Since there are 172 of them,
@@ -2801,6 +3009,7 @@
     for (auto padding :
          {PaddingMode::NONE, PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN}) {
         for (auto digest : ValidDigests(true /* withNone */, true /* withMD5 */)) {
+            SCOPED_TRACE(testing::Message() << "RSA padding=" << padding << " digest=" << digest);
             if (padding == PaddingMode::NONE && digest != Digest::NONE) {
                 // Digesting only makes sense with padding.
                 continue;
@@ -2910,11 +3119,8 @@
  * presented.
  */
 TEST_P(SigningOperationsTest, NoUserConfirmation) {
-    if (SecLevel() == SecurityLevel::STRONGBOX) {
-        GTEST_SKIP() << "Test not applicable to StrongBox device";
-    }
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .RsaSigningKey(1024, 65537)
+                                                 .RsaSigningKey(2048, 65537)
                                                  .Digest(Digest::NONE)
                                                  .Padding(PaddingMode::NONE)
                                                  .Authorization(TAG_NO_AUTH_REQUIRED)
@@ -3516,6 +3722,7 @@
  */
 TEST_P(SigningOperationsTest, HmacAllDigests) {
     for (auto digest : ValidDigests(false /* withNone */, false /* withMD5 */)) {
+        SCOPED_TRACE(testing::Message() << "Digest::" << digest);
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                                      .Authorization(TAG_NO_AUTH_REQUIRED)
                                                      .HmacKey(128)
@@ -3777,7 +3984,7 @@
 // TODO(seleneh) add ExportKey to GenerateKey
 // check result
 
-class ImportKeyTest : public KeyMintAidlTestBase {
+class ImportKeyTest : public NewKeyGenerationTest {
   public:
     template <TagType tag_type, Tag tag, typename ValueT>
     void CheckCryptoParam(TypedTag<tag_type, tag> ttag, ValueT expected) {
@@ -4366,6 +4573,7 @@
     string key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     uint32_t bitlen = key.size() * 8;
     for (uint32_t key_size : {bitlen - 1, bitlen + 1, bitlen - 8, bitlen + 8}) {
+        SCOPED_TRACE(testing::Message() << "import-key-size=" << key_size);
         // Explicit key size doesn't match that of the provided key.
         auto result = ImportKey(AuthorizationSetBuilder()
                                         .Authorization(TAG_NO_AUTH_REQUIRED)
@@ -4433,6 +4641,7 @@
     string key = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f7358");
     uint32_t bitlen = key.size() * 7;
     for (uint32_t key_size : {bitlen - 1, bitlen + 1, bitlen - 8, bitlen + 8}) {
+        SCOPED_TRACE(testing::Message() << "import-key-size=" << key_size);
         // Explicit key size doesn't match that of the provided key.
         auto result = ImportKey(AuthorizationSetBuilder()
                                         .Authorization(TAG_NO_AUTH_REQUIRED)
@@ -4487,6 +4696,65 @@
     VerifyMessage(message, signature, AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
 }
 
+/*
+ * ImportKeyTest.GetKeyCharacteristics
+ *
+ * Verifies that imported keys have the correct characteristics.
+ */
+TEST_P(ImportKeyTest, GetKeyCharacteristics) {
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+    auto base_builder = AuthorizationSetBuilder()
+                                .Padding(PaddingMode::NONE)
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .SetDefaultValidity();
+    vector<Algorithm> algorithms = {Algorithm::RSA, Algorithm::EC, Algorithm::HMAC, Algorithm::AES,
+                                    Algorithm::TRIPLE_DES};
+    ErrorCode result;
+    string symKey = hex2str("a49d7564199e97cb529d2c9d97bf2f98");                   // 128 bits
+    string tdesKey = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f7358");  // 192 bits
+    for (auto alg : algorithms) {
+        SCOPED_TRACE(testing::Message() << "Algorithm-" << alg);
+        AuthorizationSetBuilder builder(base_builder);
+        switch (alg) {
+            case Algorithm::RSA:
+                builder.RsaSigningKey(2048, 65537).Digest(Digest::NONE);
+
+                result = ImportKey(builder, KeyFormat::PKCS8, rsa_2048_key, &key_blob,
+                                   &key_characteristics);
+                break;
+            case Algorithm::EC:
+                builder.EcdsaSigningKey(EcCurve::P_256).Digest(Digest::NONE);
+                result = ImportKey(builder, KeyFormat::PKCS8, ec_256_key, &key_blob,
+                                   &key_characteristics);
+                break;
+            case Algorithm::HMAC:
+                builder.HmacKey(128)
+                        .Digest(Digest::SHA_2_256)
+                        .Authorization(TAG_MIN_MAC_LENGTH, 128);
+                result =
+                        ImportKey(builder, KeyFormat::RAW, symKey, &key_blob, &key_characteristics);
+                break;
+            case Algorithm::AES:
+                builder.AesEncryptionKey(128).BlockMode(BlockMode::ECB);
+                result =
+                        ImportKey(builder, KeyFormat::RAW, symKey, &key_blob, &key_characteristics);
+                break;
+            case Algorithm::TRIPLE_DES:
+                builder.TripleDesEncryptionKey(168).BlockMode(BlockMode::ECB);
+                result = ImportKey(builder, KeyFormat::RAW, tdesKey, &key_blob,
+                                   &key_characteristics);
+                break;
+            default:
+                ADD_FAILURE() << "Invalid Algorithm " << uint32_t(alg);
+                continue;
+        }
+        ASSERT_EQ(ErrorCode::OK, result);
+        CheckCharacteristics(key_blob, key_characteristics);
+        CheckCommonParams(key_characteristics, KeyOrigin::IMPORTED);
+    }
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(ImportKeyTest);
 
 auto wrapped_key = hex2str(
@@ -4836,15 +5104,15 @@
 TEST_P(ImportWrappedKeyTest, WrongDigest) {
     auto wrapping_key_desc = AuthorizationSetBuilder()
                                      .RsaEncryptionKey(2048, 65537)
-                                     .Digest(Digest::SHA_2_512)
                                      .Padding(PaddingMode::RSA_OAEP)
+                                     .Digest(Digest::SHA_2_256)
                                      .Authorization(TAG_PURPOSE, KeyPurpose::WRAP_KEY)
                                      .SetDefaultValidity();
 
     ASSERT_EQ(ErrorCode::INCOMPATIBLE_DIGEST,
               ImportWrappedKey(wrapped_key, wrapping_key, wrapping_key_desc, zero_masking_key,
                                AuthorizationSetBuilder()
-                                       .Digest(Digest::SHA_2_256)
+                                       .Digest(Digest::SHA_2_512)
                                        .Padding(PaddingMode::RSA_OAEP)));
 }
 
@@ -4859,6 +5127,7 @@
  */
 TEST_P(EncryptionOperationsTest, RsaNoPaddingSuccess) {
     for (uint64_t exponent : ValidExponents()) {
+        SCOPED_TRACE(testing::Message() << "RSA exponent=" << exponent);
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                                      .Authorization(TAG_NO_AUTH_REQUIRED)
                                                      .RsaEncryptionKey(2048, exponent)
@@ -5049,6 +5318,7 @@
     string message = "Hello";
 
     for (auto digest : digests) {
+        SCOPED_TRACE(testing::Message() << "digest-" << digest);
         auto params = AuthorizationSetBuilder()
                               .Authorization(TAG_RSA_OAEP_MGF_DIGEST, digest)
                               .Digest(Digest::SHA_2_256)
@@ -5085,6 +5355,79 @@
 }
 
 /*
+ * EncryptionOperationsTest.RsaOaepMGFDigestDefaultSuccess
+ *
+ * Verifies that RSA-OAEP decryption operations work when no MGF digest is
+ * specified, defaulting to SHA-1.
+ */
+TEST_P(EncryptionOperationsTest, RsaOaepMGFDigestDefaultSuccess) {
+    size_t key_size = 2048;
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .RsaEncryptionKey(key_size, 65537)
+                                                 .Padding(PaddingMode::RSA_OAEP)
+                                                 .Digest(Digest::SHA_2_256)
+                                                 .SetDefaultValidity()));
+
+    // Do local RSA encryption using the default MGF digest of SHA-1.
+    string message = "Hello";
+    auto params =
+            AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_OAEP);
+    string ciphertext = LocalRsaEncryptMessage(message, params);
+    EXPECT_EQ(key_size / 8, ciphertext.size());
+
+    // Do KeyMint RSA decryption also using the default MGF digest of SHA-1.
+    string plaintext = DecryptMessage(ciphertext, params);
+    EXPECT_EQ(message, plaintext) << "RSA-OAEP failed with default digest";
+
+    // Decrypting corrupted ciphertext should fail.
+    size_t offset_to_corrupt = random() % ciphertext.size();
+    char corrupt_byte;
+    do {
+        corrupt_byte = static_cast<char>(random() % 256);
+    } while (corrupt_byte == ciphertext[offset_to_corrupt]);
+    ciphertext[offset_to_corrupt] = corrupt_byte;
+
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+    string result;
+    EXPECT_EQ(ErrorCode::UNKNOWN_ERROR, Finish(ciphertext, &result));
+    EXPECT_EQ(0U, result.size());
+}
+
+/*
+ * EncryptionOperationsTest.RsaOaepMGFDigestDefaultFail
+ *
+ * Verifies that RSA-OAEP decryption operations fail when no MGF digest is
+ * specified on begin (thus defaulting to SHA-1), but the key characteristics
+ * has an explicit set of values for MGF_DIGEST that do not contain SHA-1.
+ */
+TEST_P(EncryptionOperationsTest, RsaOaepMGFDigestDefaultFail) {
+    size_t key_size = 2048;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(AuthorizationSetBuilder()
+                                  .Authorization(TAG_NO_AUTH_REQUIRED)
+                                  .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA_2_256)
+                                  .RsaEncryptionKey(key_size, 65537)
+                                  .Padding(PaddingMode::RSA_OAEP)
+                                  .Digest(Digest::SHA_2_256)
+                                  .SetDefaultValidity()));
+
+    // Do local RSA encryption using the default MGF digest of SHA-1.
+    string message = "Hello";
+    auto params =
+            AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_OAEP);
+    string ciphertext = LocalRsaEncryptMessage(message, params);
+    EXPECT_EQ(key_size / 8, ciphertext.size());
+
+    // begin() params do not include MGF_DIGEST, so a default of SHA1 is assumed.
+    // Key characteristics *do* include values for MGF_DIGEST, so the SHA1 value
+    // is checked against those values, and found absent.
+    auto result = Begin(KeyPurpose::DECRYPT, params);
+    EXPECT_TRUE(result == ErrorCode::UNSUPPORTED_MGF_DIGEST ||
+                result == ErrorCode::INCOMPATIBLE_MGF_DIGEST);
+}
+
+/*
  * EncryptionOperationsTest.RsaOaepWithMGFIncompatibleDigest
  *
  * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to operate
@@ -5396,6 +5739,7 @@
  */
 TEST_P(EncryptionOperationsTest, AesEcbCbcNoPaddingWrongInputSize) {
     for (BlockMode blockMode : {BlockMode::ECB, BlockMode::CBC}) {
+        SCOPED_TRACE(testing::Message() << "AES-" << blockMode);
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                                      .Authorization(TAG_NO_AUTH_REQUIRED)
                                                      .AesEncryptionKey(128)
@@ -5615,6 +5959,328 @@
     CheckAesIncrementalEncryptOperation(BlockMode::GCM, 240);
 }
 
+/*
+ * EncryptionOperationsTest.Aes128CBCNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128CBCNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("7E3D723C09A9852B24F584F9D916F6A8");
+    string kat_iv = hex2str("944AE274D983892EADE422274858A96A");
+    string kat_plaintext =
+            hex2str("044E15899A080AADEB6778F64323B64D2CBCBADB338DF93B9AC459D4F41029"
+                    "809FFF37081C22EF278F896AB213A2A631");
+    string kat_ciphertext =
+            hex2str("B419293FCBD686F2913D1CF947E510D42FAFEDE5593C98AFD6AEE272596A"
+                    "56FE42C22F2A5E3B6A02BA9D8D0DE1E9A810");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128CBCPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128CBCPKCS7PaddingOneByteAtATime) {
+    string kat_key = hex2str("F16E698472578E919D92806262C5169F");
+    string kat_iv = hex2str("EF743540F8421ACA128A3247521F3E7D");
+    string kat_plaintext =
+            hex2str("5BEBF33569D90BF5E853814E12E7C7AA5758013F755773E29F4A25EC26EEB7"
+                    "65F7F2DC251F7DC62AEFCA1E8A5A11A1DCD44F0BD8FB593A5AE3");
+    string kat_ciphertext =
+            hex2str("3197CF6DB9466188B5FED375329324EE7D6092A8C0E41DFAF49E3724271427"
+                    "896D56A6243C0D59D6639722AF93CD53449BDDABF9C5F153EBDBFED9ED98C8CC37");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::PKCS7, kat_iv,
+                                  kat_plaintext, kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128CTRNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CTR/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128CTRNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("4713a7b2f93efe809b42ecc45213ef9f");
+    string kat_iv = hex2str("ebfa19b0ebf3d57feabd4c4bd04bea01");
+    string kat_plaintext =
+            hex2str("6d2c07e1fc86f99c6e2a8f6567828b4262a9c23d0f3ed8ab32482283c79796"
+                    "f0adba1bcd3736084996452a917fae98005aebe61f9e91c3");
+    string kat_ciphertext =
+            hex2str("345deb1d67b95e600e05cad4c32ec381aadb3e2c1ec7e0fb956dc38e6860cf"
+                    "0553535566e1b12fa9f87d29266ca26df427233df035df28");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CTR, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128ECBNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128ECBNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("7DA2467F068854B3CB36E5C333A16619");
+    string kat_plaintext =
+            hex2str("9A07C9575AD9CE209DF9F3953965CEBE8208587C7AE575A1904BF25048946D"
+                    "7B6168A9A27BCE554BEA94EF26E6C742A0");
+    string kat_ciphertext =
+            hex2str("8C47E49420FC92AC4CA2C601BC3F8AC31D01B260B7B849F2B8EEDFFFED8F36"
+                    "C31CBDA0D22F95C9C2A48C347E8C77AC82");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::NONE, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128ECBPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128ECBPKCS7PaddingOneByteAtATime) {
+    string kat_key = hex2str("C3BE04BCCB3D99B85290F113FE7AF194");
+    string kat_plaintext =
+            hex2str("348C213FD8DF3F990C20C5ACBF07B34B6264AE245784A5A6176DBFB1C2E7DD"
+                    "27E52CC92B8EEE40614F05B507B355F6354A2705BD86");
+    string kat_ciphertext =
+            hex2str("07CD05C41FEDEDDC5DB4B3E35E676153184A119AA4DFDDC290616F1FA60093"
+                    "1DE6BEA9BDB90D1D733899946F8C8E5C0C4383F99F5D88E27F3EBC0C6E52759ED3");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::PKCS7, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128GCMNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/GCM/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128GCMNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("ba76354f0aed6e8d91f45c4ff5a062db");
+    string kat_iv = hex2str("b79437ae08ff355d7d8a4d0f");
+    string kat_plaintext =
+            hex2str("6d7596a8fd56ceaec61de7940984b7736fec44f572afc3c8952e4dc6541e2b"
+                    "c6a702c440a37610989543f63fedb047ca2173bc18581944");
+    string kat_ciphertext =
+            hex2str("b3f6799e8f9326f2df1e80fcd2cb16d78c9dc7cc14bb677862dc6c639b3a63"
+                    "38d24b312d3989e5920b5dbfc976765efbfe57bb385940a7a43bdf05bddae3c9d6a2fb"
+                    "bdfcc0cba0");
+
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::GCM, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192CBCNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192CBCNoPaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("be8cc4e25cce46e5d55725e2391f7d3cf59ed60062f5a43b");
+    string kat_iv = hex2str("80a199aab0eee77e7762ddf3b3a32f40");
+    string kat_plaintext =
+            hex2str("064f9200e0df37d4711af4a69d11addf9e1c345d9d8195f9f1f715019ce96a"
+                    "167f2497c994bd496eb80bfb2ba2c9d5af");
+    string kat_ciphertext =
+            hex2str("859b90becaa85e95a71e104efbd7a3b723bcbf4eb39865544a05d9e90b6fe5"
+                    "72c134552f3a138e726fbe493b3a839598");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192CBCPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192CBCPKCS7PaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("68969215ec41e4df7d23de0e806f458f52aff492bd7c5263");
+    string kat_iv = hex2str("e61d13dfbf0533289f0e7950209da418");
+    string kat_plaintext =
+            hex2str("8d4c1cac27511ee2d82409a7f378e7e402b0eb189c1eaa5c506eb72a9074"
+                    "b170");
+    string kat_ciphertext =
+            hex2str("e70bcd62c595dc1b2b8c197bb91a7447e1be2cbcf3fdc69e7e991faf0f57cf"
+                    "4e3884138ff403a41fd99818708ada301c");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::PKCS7, kat_iv,
+                                  kat_plaintext, kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192CTRNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CTR/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192CTRNoPaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("5e2036e790d38815c90beb67a1c9e5aa0e167ef082927317");
+    string kat_iv = hex2str("df0694959b89054156962d68a226965c");
+    string kat_plaintext =
+            hex2str("6ed2781c99e03e45314d6019932220c2c98130c53f9f67ad10ac519adf50e9"
+                    "28091e09cdbbd3b42b");
+    string kat_ciphertext =
+            hex2str("e427b6666502e05b82d0b20ae50e862b1936d71266fc49178ac984e71571f2"
+                    "2ae0f90f0c19f42b4a");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CTR, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192ECBNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192ECBNoPaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("3cab83fb338ba985fbfe74c5e9d2e900adb570b1d67faf92");
+    string kat_plaintext =
+            hex2str("2cc64c335a13fb838f3c6aad0a6b47297ca90bb886ddb059200f0b41740c"
+                    "44ab");
+    string kat_ciphertext =
+            hex2str("9c5c825328f5ee0aa24947e374d3f9165f484b39dd808c790d7a12964810"
+                    "2453");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::NONE, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192ECBPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192ECBPKCS7PaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("d57f4e5446f736c16476ec4db5decc7b1bf3936e4f7e4618");
+    string kat_plaintext =
+            hex2str("b115777f1ee7a43a07daa6401e59c46b7a98213a8747eabfbe3ca4ec93524d"
+                    "e2c7");
+    string kat_ciphertext =
+            hex2str("1e92cd20da08bb5fa174a7a69879d4fc25a155e6af06d75b26c5b450d273c8"
+                    "bb7e3a889dd4a9589098b44acf1056e7aa");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::PKCS7, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192GCMNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/GCM/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192GCMNoPaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("21339fc1d011abca65d50ce2365230603fd47d07e8830f6e");
+    string kat_iv = hex2str("d5fb1469a8d81dd75286a418");
+    string kat_plaintext =
+            hex2str("cf776dedf53a828d51a0073db3ef0dd1ee19e2e9e243ce97e95841bb9ad4e3"
+                    "ff52");
+    string kat_ciphertext =
+            hex2str("3a0d48278111d3296bc663df8a5dbeb2474ea47fd85b608f8d9375d9dcf7de"
+                    "1413ad70fb0e1970669095ad77ebb5974ae8");
+
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::GCM, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256CBCNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256CBCNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("dd2f20dc6b98c100bac919120ff95eb5d96003f8229987b283a1e777b0cd5c30");
+    string kat_iv = hex2str("23b4d85239fb90db93b07a981e90a170");
+    string kat_plaintext =
+            hex2str("2fbe5d46dca5cea433e550d8b291740ab9551c2a2d37680d7fb7b993225f58"
+                    "494cb53caca353e4b637ba05687be20f8d");
+    string kat_ciphertext =
+            hex2str("5aba24fc316936c8369061ee8fe463e4faed04288e204456626b988c0e376b"
+                    "6047da1e4fd7c4e1cf2656097f75ae8685");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256CBCPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256CBCPKCS7PaddingOneByteAtATime) {
+    string kat_key = hex2str("03ab2510520f5cfebfab0a17a7f8324c9634911f6fc59e586f85346bb38ac88a");
+    string kat_iv = hex2str("9af96967195bb0184f129beffa8241ae");
+    string kat_plaintext =
+            hex2str("2d6944653ac14988a772a2730b7c5bfa99a21732ae26f40cdc5b3a2874c794"
+                    "2545a82b73c48078b9dae62261c65909");
+    string kat_ciphertext =
+            hex2str("26b308f7e1668b55705a79c8b3ad10e244655f705f027f390a5c34e4536f51"
+                    "9403a71987b95124073d69f2a3cb95b0ab");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::PKCS7, kat_iv,
+                                  kat_plaintext, kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256CTRNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CTR/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256CTRNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("928b380a8fed4b4b4cfeb56e0c66a4cb0f9ff58d61ac68bcfd0e3fbd910a684f");
+    string kat_iv = hex2str("0b678a5249e6eeda461dfb4776b6c58e");
+    string kat_plaintext =
+            hex2str("f358de57543b297e997cba46fb9100553d6abd65377e55b9aac3006400ead1"
+                    "1f6db3c884");
+    string kat_ciphertext =
+            hex2str("a07a35fbd1776ad81462e1935f542337add60962bf289249476817b6ddd532"
+                    "a7be30d4c3");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CTR, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256ECBNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256ECBNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("fa4622d9cf6485075daedd33d2c4fffdf859e2edb7f7df4f04603f7e647fae90");
+    string kat_plaintext =
+            hex2str("96ccabbe0c68970d8cdee2b30ab43c2d61cc50ee68271e77571e72478d713a"
+                    "31a476d6806b8116089c6ec50bb543200f");
+    string kat_ciphertext =
+            hex2str("0e81839e9dfbfe3b503d619e676abe5ac80fac3f245d8f09b9134b1b32a67d"
+                    "c83e377faf246288931136bef2a07c0be4");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::NONE, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256ECBPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256ECBPKCS7PaddingOneByteAtATime) {
+    string kat_key = hex2str("bf3f07c68467fead0ca8e2754500ab514258abf02eb7e615a493bcaaa45d5ee1");
+    string kat_plaintext =
+            hex2str("af0757e49018dad628f16998628a407db5f28291bef3bc2e4d8a5a31fb238e"
+                    "6f");
+    string kat_ciphertext =
+            hex2str("21ec3011074bf1ef140643d47130326c5e183f61237c69bc77551ca207d71f"
+                    "c2b90cfac6c8d2d125e5cd9ff353dee0df");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::PKCS7, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256GCMNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/GCM/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256GCMNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("7972140d831eedac75d5ea515c9a4c3bb124499a90b5f317ac1a685e88fae395");
+    string kat_iv = hex2str("a66c5252808d823dd4151fed");
+    string kat_plaintext =
+            hex2str("c2b9dabf3a55adaa94e8c0d1e77a84a3435aee23b2c3c4abb587b09a9c2afb"
+                    "f0");
+    string kat_ciphertext =
+            hex2str("a960619314657b2afb96b93bebb372bffd09e19d53e351f17d1ba2611f9dc3"
+                    "3c9c92d563e8fd381254ac262aa2a4ea0d");
+
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::GCM, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
 struct AesCtrSp80038aTestVector {
     const char* key;
     const char* nonce;
@@ -5770,6 +6436,7 @@
     // Zero input message
     string message = "";
     for (auto padding : {PaddingMode::NONE, PaddingMode::PKCS7}) {
+        SCOPED_TRACE(testing::Message() << "AES padding=" << padding);
         auto params = AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(padding);
         AuthorizationSet out_params;
         string ciphertext1 = EncryptMessage(message, params, &out_params);
@@ -6164,7 +6831,7 @@
 
     // Encrypt
     AuthorizationSet begin_out_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
     string ciphertext;
     AuthorizationSet finish_out_params;
     ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
@@ -6207,7 +6874,7 @@
                                 .Authorization(TAG_MAC_LENGTH, tag_bits);
     AuthorizationSet begin_out_params;
 
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
 
     // No data, AAD only.
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
@@ -6223,7 +6890,7 @@
     begin_params.push_back(begin_out_params);
 
     // Decrypt
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foofoo"));
     string plaintext;
     EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
@@ -6250,7 +6917,7 @@
                                 .Authorization(TAG_MAC_LENGTH, 128);
     AuthorizationSet begin_out_params;
 
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
 
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
     string ciphertext;
@@ -6284,7 +6951,7 @@
 
     // Encrypt
     AuthorizationSet begin_out_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
     string ciphertext;
     EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
@@ -6293,7 +6960,7 @@
     begin_params.push_back(begin_out_params);
 
     // Decrypt.
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("barfoo"));
     string plaintext;
     EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
@@ -6320,7 +6987,7 @@
 
     // Encrypt
     AuthorizationSet begin_out_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
     string ciphertext;
     AuthorizationSet finish_out_params;
@@ -6330,7 +6997,7 @@
     begin_params.push_back(TAG_NONCE, AidlBuf("123456789012"));
 
     // Decrypt.
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
     string plaintext;
     EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
@@ -6362,7 +7029,7 @@
 
     // Encrypt
     AuthorizationSet begin_out_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
     string ciphertext;
     EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
@@ -6374,7 +7041,7 @@
     params.push_back(begin_out_params);
 
     // Decrypt.
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
     string plaintext;
     EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
@@ -6438,6 +7105,7 @@
                                                  .Padding(PaddingMode::PKCS7)));
 
     for (size_t i = 0; i < 32; ++i) {
+        SCOPED_TRACE(testing::Message() << "msg size=" << i);
         string message(i, 'a');
         auto inParams =
                 AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
@@ -6487,7 +7155,7 @@
     for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
         ++ciphertext[ciphertext.size() / 2];
 
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
         string plaintext;
         EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
         ErrorCode error = Finish(&plaintext);
@@ -6748,6 +7416,7 @@
  */
 TEST_P(EncryptionOperationsTest, TripleDesEcbCbcNoPaddingWrongInputSize) {
     for (BlockMode blockMode : {BlockMode::ECB, BlockMode::CBC}) {
+        SCOPED_TRACE(testing::Message() << "BlockMode::" << blockMode);
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
                                                      .TripleDesEncryptionKey(168)
                                                      .BlockMode(blockMode)
@@ -6759,7 +7428,7 @@
         auto begin_params =
                 AuthorizationSetBuilder().BlockMode(blockMode).Padding(PaddingMode::NONE);
         AuthorizationSet output_params;
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &output_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &output_params));
         string ciphertext;
         EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, "", &ciphertext));
 
@@ -6806,6 +7475,7 @@
 
     // Try various message lengths; all should fail.
     for (size_t i = 0; i <= 32; i++) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
         auto begin_params =
                 AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::PKCS7);
         EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, begin_params));
@@ -6838,7 +7508,7 @@
     for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
         SCOPED_TRACE(testing::Message() << "i = " << i);
         ++ciphertext[ciphertext.size() / 2];
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
         string plaintext;
         EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
         ErrorCode error = Finish(&plaintext);
@@ -6870,7 +7540,7 @@
     AuthorizationSet input_params =
             AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::NONE);
     AuthorizationSet output_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, input_params, &output_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, input_params, &output_params));
 
     string ciphertext;
     for (size_t i = 0; i < message.size(); i += increment)
@@ -6884,7 +7554,7 @@
     input_params.push_back(TAG_PADDING, PaddingMode::NONE);
     output_params.Clear();
 
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, input_params, &output_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, input_params, &output_params));
     string plaintext;
     for (size_t i = 0; i < ciphertext.size(); i += increment)
         EXPECT_EQ(ErrorCode::OK, Update(ciphertext.substr(i, increment), &plaintext));
@@ -7001,7 +7671,7 @@
     } else {
         // Usage count limit tag is enforced by keystore, keymint does nothing.
         EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U));
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
     }
 }
 
@@ -7048,7 +7718,7 @@
     } else {
         // Usage count limit tag is enforced by keystore, keymint does nothing.
         EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U));
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
     }
 }
 
@@ -7094,7 +7764,7 @@
     } else {
         // Usage count limit tag is enforced by keystore, keymint does nothing.
         EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U));
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
     }
 }
 
@@ -7141,7 +7811,7 @@
     } else {
         // Usage count limit tag is enforced by keystore, keymint does nothing.
         EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U));
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
     }
 }
 
@@ -7153,10 +7823,6 @@
  * in hardware.
  */
 TEST_P(UsageCountLimitTest, TestSingleUseKeyAndRollbackResistance) {
-    if (SecLevel() == SecurityLevel::STRONGBOX) {
-        GTEST_SKIP() << "Test not applicable to StrongBox device";
-    }
-
     auto error = GenerateKey(AuthorizationSetBuilder()
                                      .RsaSigningKey(2048, 65537)
                                      .Digest(Digest::NONE)
@@ -7454,7 +8120,7 @@
         EXPECT_EQ(ErrorCode::OK, Abort(op_handles[j]))
                 << "Aboort failed for i = " << j << std::endl;
     }
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, key_blob_, params, &out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, key_blob_, params, &out_params));
     AbortIfNeeded();
 }
 
@@ -7475,11 +8141,12 @@
                                                  .Padding(PaddingMode::NONE)));
 
     for (int msg_size = 8 /* 256 bytes */; msg_size <= 11 /* 2 KiB */; msg_size++) {
+        SCOPED_TRACE(testing::Message() << "msg_size = " << msg_size);
         auto cipher_params =
                 AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE);
 
         AuthorizationSet out_params;
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, cipher_params, &out_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, cipher_params, &out_params));
 
         string plain_message = std::string(1 << msg_size, 'x');
         string encrypted_message;
@@ -7490,7 +8157,7 @@
                 << "Encrypt finish returned OK, but did not consume all of the given input";
         cipher_params.push_back(out_params);
 
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, cipher_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, cipher_params));
 
         string decrypted_message;
         rc = Finish(encrypted_message, &decrypted_message);
@@ -7656,7 +8323,7 @@
             if (curve != localCurve) {
                 // If the keys are using different curves KeyMint should fail with
                 // ErrorCode:INVALID_ARGUMENT. Check that.
-                EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
+                ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
                 string ZabFromKeyMintStr;
                 EXPECT_EQ(ErrorCode::INVALID_ARGUMENT,
                           Finish(string(localPublicKey.begin(), localPublicKey.end()),
@@ -7788,6 +8455,7 @@
     GenerateKeyMintEcKey(curve, &kmPubKey);
 
     for (auto localCurve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "local-curve-" << localCurve);
         if (localCurve == curve) {
             continue;
         }
@@ -7796,7 +8464,7 @@
         vector<uint8_t> encodedPublicKey;
         GenerateLocalEcKey(localCurve, &privKey, &encodedPublicKey);
 
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
         string ZabFromKeyMintStr;
         EXPECT_EQ(ErrorCode::INVALID_ARGUMENT,
                   Finish(string(encodedPublicKey.begin(), encodedPublicKey.end()),
@@ -7996,12 +8664,20 @@
 
 TEST_P(VsrRequirementTest, Vsr13Test) {
     int vsr_api_level = get_vsr_api_level();
-    if (vsr_api_level < 33) {
+    if (vsr_api_level < __ANDROID_API_T__) {
         GTEST_SKIP() << "Applies only to VSR API level 33, this device is: " << vsr_api_level;
     }
     EXPECT_GE(AidlVersion(), 2) << "VSR 13+ requires KeyMint version 2";
 }
 
+TEST_P(VsrRequirementTest, Vsr14Test) {
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < __ANDROID_API_U__) {
+        GTEST_SKIP() << "Applies only to VSR API level 34, this device is: " << vsr_api_level;
+    }
+    EXPECT_GE(AidlVersion(), 3) << "VSR 14+ requires KeyMint version 3";
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(VsrRequirementTest);
 
 }  // namespace aidl::android::hardware::security::keymint::test
@@ -8034,6 +8710,15 @@
                 // interactions.
                 aidl::android::hardware::security::keymint::test::check_boot_pl = false;
             }
+            if (std::string(argv[i]) == "--keyblob_dir") {
+                if (i + 1 >= argc) {
+                    std::cerr << "Missing argument for --keyblob_dir\n";
+                    return 1;
+                }
+                aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::keyblob_dir =
+                        std::string(argv[i + 1]);
+                ++i;
+            }
         }
     }
     return RUN_ALL_TESTS();
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
deleted file mode 100644
index 7184613..0000000
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ /dev/null
@@ -1,802 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "VtsRemotelyProvisionableComponentTests"
-
-#include <AndroidRemotelyProvisionedComponentDevice.h>
-#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
-#include <aidl/android/hardware/security/keymint/SecurityLevel.h>
-#include <android/binder_manager.h>
-#include <binder/IServiceManager.h>
-#include <cppbor_parse.h>
-#include <gmock/gmock.h>
-#include <keymaster/cppcose/cppcose.h>
-#include <keymaster/keymaster_configuration.h>
-#include <keymint_support/authorization_set.h>
-#include <openssl/ec.h>
-#include <openssl/ec_key.h>
-#include <openssl/x509.h>
-#include <remote_prov/remote_prov_utils.h>
-#include <set>
-#include <vector>
-
-#include "KeyMintAidlTestBase.h"
-
-namespace aidl::android::hardware::security::keymint::test {
-
-using ::std::string;
-using ::std::vector;
-
-namespace {
-
-constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2;
-
-#define INSTANTIATE_REM_PROV_AIDL_TEST(name)                                         \
-    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);                             \
-    INSTANTIATE_TEST_SUITE_P(                                                        \
-            PerInstance, name,                                                       \
-            testing::ValuesIn(VtsRemotelyProvisionedComponentTests::build_params()), \
-            ::android::PrintInstanceNameToString)
-
-using ::android::sp;
-using bytevec = std::vector<uint8_t>;
-using testing::MatchesRegex;
-using namespace remote_prov;
-using namespace keymaster;
-
-std::set<std::string> getAllowedVbStates() {
-    return {"green", "yellow", "orange"};
-}
-
-std::set<std::string> getAllowedBootloaderStates() {
-    return {"locked", "unlocked"};
-}
-
-std::set<std::string> getAllowedSecurityLevels() {
-    return {"tee", "strongbox"};
-}
-
-std::set<std::string> getAllowedAttIdStates() {
-    return {"locked", "open"};
-}
-
-bytevec string_to_bytevec(const char* s) {
-    const uint8_t* p = reinterpret_cast<const uint8_t*>(s);
-    return bytevec(p, p + strlen(s));
-}
-
-ErrMsgOr<MacedPublicKey> corrupt_maced_key(const MacedPublicKey& macedPubKey) {
-    auto [coseMac0, _, mac0ParseErr] = cppbor::parse(macedPubKey.macedKey);
-    if (!coseMac0 || coseMac0->asArray()->size() != kCoseMac0EntryCount) {
-        return "COSE Mac0 parse failed";
-    }
-    auto protParams = coseMac0->asArray()->get(kCoseMac0ProtectedParams)->asBstr();
-    auto unprotParams = coseMac0->asArray()->get(kCoseMac0UnprotectedParams)->asMap();
-    auto payload = coseMac0->asArray()->get(kCoseMac0Payload)->asBstr();
-    auto tag = coseMac0->asArray()->get(kCoseMac0Tag)->asBstr();
-    if (!protParams || !unprotParams || !payload || !tag) {
-        return "Invalid COSE_Sign1: missing content";
-    }
-    auto corruptMac0 = cppbor::Array();
-    corruptMac0.add(protParams->clone());
-    corruptMac0.add(unprotParams->clone());
-    corruptMac0.add(payload->clone());
-    vector<uint8_t> tagData = tag->value();
-    tagData[0] ^= 0x08;
-    tagData[tagData.size() - 1] ^= 0x80;
-    corruptMac0.add(cppbor::Bstr(tagData));
-
-    return MacedPublicKey{corruptMac0.encode()};
-}
-
-ErrMsgOr<cppbor::Array> corrupt_sig(const cppbor::Array* coseSign1) {
-    if (coseSign1->size() != kCoseSign1EntryCount) {
-        return "Invalid COSE_Sign1, wrong entry count";
-    }
-    const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
-    const cppbor::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
-    const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
-    const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
-    if (!protectedParams || !unprotectedParams || !payload || !signature) {
-        return "Invalid COSE_Sign1: missing content";
-    }
-
-    auto corruptSig = cppbor::Array();
-    corruptSig.add(protectedParams->clone());
-    corruptSig.add(unprotectedParams->clone());
-    corruptSig.add(payload->clone());
-    vector<uint8_t> sigData = signature->value();
-    sigData[0] ^= 0x08;
-    corruptSig.add(cppbor::Bstr(sigData));
-
-    return std::move(corruptSig);
-}
-
-ErrMsgOr<bytevec> corrupt_sig_chain(const bytevec& encodedEekChain, int which) {
-    auto [chain, _, parseErr] = cppbor::parse(encodedEekChain);
-    if (!chain || !chain->asArray()) {
-        return "EekChain parse failed";
-    }
-
-    cppbor::Array* eekChain = chain->asArray();
-    if (which >= eekChain->size()) {
-        return "selected sig out of range";
-    }
-    auto corruptChain = cppbor::Array();
-
-    for (int ii = 0; ii < eekChain->size(); ++ii) {
-        if (ii == which) {
-            auto sig = corrupt_sig(eekChain->get(which)->asArray());
-            if (!sig) {
-                return "Failed to build corrupted signature" + sig.moveMessage();
-            }
-            corruptChain.add(sig.moveValue());
-        } else {
-            corruptChain.add(eekChain->get(ii)->clone());
-        }
-    }
-    return corruptChain.encode();
-}
-
-string device_suffix(const string& name) {
-    size_t pos = name.find('/');
-    if (pos == string::npos) {
-        return name;
-    }
-    return name.substr(pos + 1);
-}
-
-bool matching_keymint_device(const string& rp_name, std::shared_ptr<IKeyMintDevice>* keyMint) {
-    string rp_suffix = device_suffix(rp_name);
-
-    vector<string> km_names = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
-    for (const string& km_name : km_names) {
-        // If the suffix of the KeyMint instance equals the suffix of the
-        // RemotelyProvisionedComponent instance, assume they match.
-        if (device_suffix(km_name) == rp_suffix && AServiceManager_isDeclared(km_name.c_str())) {
-            ::ndk::SpAIBinder binder(AServiceManager_waitForService(km_name.c_str()));
-            *keyMint = IKeyMintDevice::fromBinder(binder);
-            return true;
-        }
-    }
-    return false;
-}
-
-}  // namespace
-
-class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std::string> {
-  public:
-    virtual void SetUp() override {
-        if (AServiceManager_isDeclared(GetParam().c_str())) {
-            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
-            provisionable_ = IRemotelyProvisionedComponent::fromBinder(binder);
-        }
-        ASSERT_NE(provisionable_, nullptr);
-        ASSERT_TRUE(provisionable_->getHardwareInfo(&rpcHardwareInfo).isOk());
-    }
-
-    static vector<string> build_params() {
-        auto params = ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor);
-        return params;
-    }
-
-  protected:
-    std::shared_ptr<IRemotelyProvisionedComponent> provisionable_;
-    RpcHardwareInfo rpcHardwareInfo;
-};
-
-/**
- * Verify that every implementation reports a different unique id.
- */
-TEST(NonParameterizedTests, eachRpcHasAUniqueId) {
-    std::set<std::string> uniqueIds;
-    for (auto hal : ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor)) {
-        ASSERT_TRUE(AServiceManager_isDeclared(hal.c_str()));
-        ::ndk::SpAIBinder binder(AServiceManager_waitForService(hal.c_str()));
-        std::shared_ptr<IRemotelyProvisionedComponent> rpc =
-                IRemotelyProvisionedComponent::fromBinder(binder);
-        ASSERT_NE(rpc, nullptr);
-
-        RpcHardwareInfo hwInfo;
-        ASSERT_TRUE(rpc->getHardwareInfo(&hwInfo).isOk());
-
-        int32_t version;
-        ASSERT_TRUE(rpc->getInterfaceVersion(&version).isOk());
-        if (version >= VERSION_WITH_UNIQUE_ID_SUPPORT) {
-            ASSERT_TRUE(hwInfo.uniqueId);
-            auto [_, wasInserted] = uniqueIds.insert(*hwInfo.uniqueId);
-            EXPECT_TRUE(wasInserted);
-        } else {
-            ASSERT_FALSE(hwInfo.uniqueId);
-        }
-    }
-}
-
-using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests;
-
-INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);
-
-/**
- * Verify that a valid curve is reported by the implementation.
- */
-TEST_P(GetHardwareInfoTests, supportsValidCurve) {
-    RpcHardwareInfo hwInfo;
-    ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
-
-    const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
-    ASSERT_EQ(validCurves.count(hwInfo.supportedEekCurve), 1)
-            << "Invalid curve: " << hwInfo.supportedEekCurve;
-}
-
-/**
- * Verify that the unique id is within the length limits as described in RpcHardwareInfo.aidl.
- */
-TEST_P(GetHardwareInfoTests, uniqueId) {
-    int32_t version;
-    ASSERT_TRUE(provisionable_->getInterfaceVersion(&version).isOk());
-
-    if (version < VERSION_WITH_UNIQUE_ID_SUPPORT) {
-        return;
-    }
-
-    RpcHardwareInfo hwInfo;
-    ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
-    ASSERT_TRUE(hwInfo.uniqueId);
-    EXPECT_GE(hwInfo.uniqueId->size(), 1);
-    EXPECT_LE(hwInfo.uniqueId->size(), 32);
-}
-
-using GenerateKeyTests = VtsRemotelyProvisionedComponentTests;
-
-INSTANTIATE_REM_PROV_AIDL_TEST(GenerateKeyTests);
-
-/**
- * Generate and validate a production-mode key.  MAC tag can't be verified, but
- * the private key blob should be usable in KeyMint operations.
- */
-TEST_P(GenerateKeyTests, generateEcdsaP256Key_prodMode) {
-    MacedPublicKey macedPubKey;
-    bytevec privateKeyBlob;
-    bool testMode = false;
-    auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
-    ASSERT_TRUE(status.isOk());
-    vector<uint8_t> coseKeyData;
-    check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
-}
-
-/**
- * Generate and validate a production-mode key, then use it as a KeyMint attestation key.
- */
-TEST_P(GenerateKeyTests, generateAndUseEcdsaP256Key_prodMode) {
-    // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
-    std::shared_ptr<IKeyMintDevice> keyMint;
-    if (!matching_keymint_device(GetParam(), &keyMint)) {
-        // No matching IKeyMintDevice.
-        GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
-        return;
-    }
-    KeyMintHardwareInfo info;
-    ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
-
-    MacedPublicKey macedPubKey;
-    bytevec privateKeyBlob;
-    bool testMode = false;
-    auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
-    ASSERT_TRUE(status.isOk());
-    vector<uint8_t> coseKeyData;
-    check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
-
-    AttestationKey attestKey;
-    attestKey.keyBlob = std::move(privateKeyBlob);
-    attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
-
-    // Generate an ECDSA key that is attested by the generated P256 keypair.
-    AuthorizationSet keyDesc = AuthorizationSetBuilder()
-                                       .Authorization(TAG_NO_AUTH_REQUIRED)
-                                       .EcdsaSigningKey(EcCurve::P_256)
-                                       .AttestationChallenge("foo")
-                                       .AttestationApplicationId("bar")
-                                       .Digest(Digest::NONE)
-                                       .SetDefaultValidity();
-    KeyCreationResult creationResult;
-    auto result = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
-    ASSERT_TRUE(result.isOk());
-    vector<uint8_t> attested_key_blob = std::move(creationResult.keyBlob);
-    vector<KeyCharacteristics> attested_key_characteristics =
-            std::move(creationResult.keyCharacteristics);
-    vector<Certificate> attested_key_cert_chain = std::move(creationResult.certificateChain);
-    EXPECT_EQ(attested_key_cert_chain.size(), 1);
-
-    int32_t aidl_version = 0;
-    ASSERT_TRUE(keyMint->getInterfaceVersion(&aidl_version).isOk());
-    AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
-    AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
-    EXPECT_TRUE(verify_attestation_record(aidl_version, "foo", "bar", sw_enforced, hw_enforced,
-                                          info.securityLevel,
-                                          attested_key_cert_chain[0].encodedCertificate));
-
-    // Attestation by itself is not valid (last entry is not self-signed).
-    EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
-
-    // The signature over the attested key should correspond to the P256 public key.
-    X509_Ptr key_cert(parse_cert_blob(attested_key_cert_chain[0].encodedCertificate));
-    ASSERT_TRUE(key_cert.get());
-    EVP_PKEY_Ptr signing_pubkey;
-    p256_pub_key(coseKeyData, &signing_pubkey);
-    ASSERT_TRUE(signing_pubkey.get());
-
-    ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
-            << "Verification of attested certificate failed "
-            << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
-}
-
-/**
- * Generate and validate a test-mode key.
- */
-TEST_P(GenerateKeyTests, generateEcdsaP256Key_testMode) {
-    MacedPublicKey macedPubKey;
-    bytevec privateKeyBlob;
-    bool testMode = true;
-    auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
-    ASSERT_TRUE(status.isOk());
-
-    check_maced_pubkey(macedPubKey, testMode, nullptr);
-}
-
-class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests {
-  protected:
-    CertificateRequestTest() : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(64)) {}
-
-    void generateTestEekChain(size_t eekLength) {
-        auto chain = generateEekChain(rpcHardwareInfo.supportedEekCurve, eekLength, eekId_);
-        ASSERT_TRUE(chain) << chain.message();
-        if (chain) testEekChain_ = chain.moveValue();
-        testEekLength_ = eekLength;
-    }
-
-    void generateKeys(bool testMode, size_t numKeys) {
-        keysToSign_ = std::vector<MacedPublicKey>(numKeys);
-        cborKeysToSign_ = cppbor::Array();
-
-        for (auto& key : keysToSign_) {
-            bytevec privateKeyBlob;
-            auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &key, &privateKeyBlob);
-            ASSERT_TRUE(status.isOk()) << status.getMessage();
-
-            vector<uint8_t> payload_value;
-            check_maced_pubkey(key, testMode, &payload_value);
-            cborKeysToSign_.add(cppbor::EncodedItem(payload_value));
-        }
-    }
-
-    ErrMsgOr<bytevec> getSessionKey(ErrMsgOr<std::pair<bytevec, bytevec>>& senderPubkey) {
-        if (rpcHardwareInfo.supportedEekCurve == RpcHardwareInfo::CURVE_25519 ||
-            rpcHardwareInfo.supportedEekCurve == RpcHardwareInfo::CURVE_NONE) {
-            return x25519_HKDF_DeriveKey(testEekChain_.last_pubkey, testEekChain_.last_privkey,
-                                         senderPubkey->first, false /* senderIsA */);
-        } else {
-            return ECDH_HKDF_DeriveKey(testEekChain_.last_pubkey, testEekChain_.last_privkey,
-                                       senderPubkey->first, false /* senderIsA */);
-        }
-    }
-
-    void checkProtectedData(const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
-                            const bytevec& keysToSignMac, const ProtectedData& protectedData,
-                            std::vector<BccEntryData>* bccOutput = nullptr) {
-        auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData);
-        ASSERT_TRUE(parsedProtectedData) << protDataErrMsg;
-        ASSERT_TRUE(parsedProtectedData->asArray());
-        ASSERT_EQ(parsedProtectedData->asArray()->size(), kCoseEncryptEntryCount);
-
-        auto senderPubkey = getSenderPubKeyFromCoseEncrypt(parsedProtectedData);
-        ASSERT_TRUE(senderPubkey) << senderPubkey.message();
-        EXPECT_EQ(senderPubkey->second, eekId_);
-
-        auto sessionKey = getSessionKey(senderPubkey);
-        ASSERT_TRUE(sessionKey) << sessionKey.message();
-
-        auto protectedDataPayload =
-                decryptCoseEncrypt(*sessionKey, parsedProtectedData.get(), bytevec{} /* aad */);
-        ASSERT_TRUE(protectedDataPayload) << protectedDataPayload.message();
-
-        auto [parsedPayload, __, payloadErrMsg] = cppbor::parse(*protectedDataPayload);
-        ASSERT_TRUE(parsedPayload) << "Failed to parse payload: " << payloadErrMsg;
-        ASSERT_TRUE(parsedPayload->asArray());
-        // Strongbox may contain additional certificate chain.
-        EXPECT_LE(parsedPayload->asArray()->size(), 3U);
-
-        auto& signedMac = parsedPayload->asArray()->get(0);
-        auto& bcc = parsedPayload->asArray()->get(1);
-        ASSERT_TRUE(signedMac && signedMac->asArray());
-        ASSERT_TRUE(bcc && bcc->asArray());
-
-        // BCC is [ pubkey, + BccEntry]
-        auto bccContents = validateBcc(bcc->asArray());
-        ASSERT_TRUE(bccContents) << "\n" << bccContents.message() << "\n" << prettyPrint(bcc.get());
-        ASSERT_GT(bccContents->size(), 0U);
-
-        auto [deviceInfoMap, __2, deviceInfoErrMsg] = cppbor::parse(deviceInfo.deviceInfo);
-        ASSERT_TRUE(deviceInfoMap) << "Failed to parse deviceInfo: " << deviceInfoErrMsg;
-        ASSERT_TRUE(deviceInfoMap->asMap());
-        checkDeviceInfo(deviceInfoMap->asMap(), deviceInfo.deviceInfo);
-        auto& signingKey = bccContents->back().pubKey;
-        deviceInfoMap->asMap()->canonicalize();
-        auto macKey = verifyAndParseCoseSign1(signedMac->asArray(), signingKey,
-                                              cppbor::Array()  // SignedMacAad
-                                                      .add(challenge_)
-                                                      .add(std::move(deviceInfoMap))
-                                                      .add(keysToSignMac)
-                                                      .encode());
-        ASSERT_TRUE(macKey) << macKey.message();
-
-        auto coseMac0 = cppbor::Array()
-                                .add(cppbor::Map()  // protected
-                                             .add(ALGORITHM, HMAC_256)
-                                             .canonicalize()
-                                             .encode())
-                                .add(cppbor::Map())        // unprotected
-                                .add(keysToSign.encode())  // payload (keysToSign)
-                                .add(keysToSignMac);       // tag
-
-        auto macPayload = verifyAndParseCoseMac0(&coseMac0, *macKey);
-        ASSERT_TRUE(macPayload) << macPayload.message();
-
-        if (bccOutput) {
-            *bccOutput = std::move(*bccContents);
-        }
-    }
-
-    void checkType(const cppbor::Map* devInfo, uint8_t majorType, std::string entryName) {
-        const auto& val = devInfo->get(entryName);
-        ASSERT_TRUE(val) << entryName << " does not exist";
-        ASSERT_EQ(val->type(), majorType) << entryName << " has the wrong type.";
-        switch (majorType) {
-            case cppbor::TSTR:
-                EXPECT_GT(val->asTstr()->value().size(), 0);
-                break;
-            case cppbor::BSTR:
-                EXPECT_GT(val->asBstr()->value().size(), 0);
-                break;
-            default:
-                break;
-        }
-    }
-
-    void checkDeviceInfo(const cppbor::Map* deviceInfo, bytevec deviceInfoBytes) {
-        EXPECT_EQ(deviceInfo->clone()->asMap()->canonicalize().encode(), deviceInfoBytes)
-                << "DeviceInfo ordering is non-canonical.";
-        const auto& version = deviceInfo->get("version");
-        ASSERT_TRUE(version);
-        ASSERT_TRUE(version->asUint());
-        RpcHardwareInfo info;
-        provisionable_->getHardwareInfo(&info);
-        ASSERT_EQ(version->asUint()->value(), info.versionNumber);
-        std::set<std::string> allowList;
-        switch (version->asUint()->value()) {
-            // These fields became mandated in version 2.
-            case 2:
-                checkType(deviceInfo, cppbor::TSTR, "brand");
-                checkType(deviceInfo, cppbor::TSTR, "manufacturer");
-                checkType(deviceInfo, cppbor::TSTR, "product");
-                checkType(deviceInfo, cppbor::TSTR, "model");
-                checkType(deviceInfo, cppbor::TSTR, "device");
-                // TODO: Refactor the KeyMint code that validates these fields and include it here.
-                checkType(deviceInfo, cppbor::TSTR, "vb_state");
-                allowList = getAllowedVbStates();
-                EXPECT_NE(allowList.find(deviceInfo->get("vb_state")->asTstr()->value()),
-                          allowList.end());
-                checkType(deviceInfo, cppbor::TSTR, "bootloader_state");
-                allowList = getAllowedBootloaderStates();
-                EXPECT_NE(allowList.find(deviceInfo->get("bootloader_state")->asTstr()->value()),
-                          allowList.end());
-                checkType(deviceInfo, cppbor::BSTR, "vbmeta_digest");
-                checkType(deviceInfo, cppbor::UINT, "system_patch_level");
-                checkType(deviceInfo, cppbor::UINT, "boot_patch_level");
-                checkType(deviceInfo, cppbor::UINT, "vendor_patch_level");
-                checkType(deviceInfo, cppbor::UINT, "fused");
-                EXPECT_LT(deviceInfo->get("fused")->asUint()->value(), 2);  // Must be 0 or 1.
-                checkType(deviceInfo, cppbor::TSTR, "security_level");
-                allowList = getAllowedSecurityLevels();
-                EXPECT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()),
-                          allowList.end());
-                if (deviceInfo->get("security_level")->asTstr()->value() == "tee") {
-                    checkType(deviceInfo, cppbor::TSTR, "os_version");
-                }
-                break;
-            case 1:
-                checkType(deviceInfo, cppbor::TSTR, "security_level");
-                allowList = getAllowedSecurityLevels();
-                EXPECT_NE(allowList.find(deviceInfo->get("security_level")->asTstr()->value()),
-                          allowList.end());
-                if (version->asUint()->value() == 1) {
-                    checkType(deviceInfo, cppbor::TSTR, "att_id_state");
-                    allowList = getAllowedAttIdStates();
-                    EXPECT_NE(allowList.find(deviceInfo->get("att_id_state")->asTstr()->value()),
-                              allowList.end());
-                }
-                break;
-            default:
-                FAIL() << "Unrecognized version: " << version->asUint()->value();
-        }
-    }
-
-    bytevec eekId_;
-    size_t testEekLength_;
-    EekChain testEekChain_;
-    bytevec challenge_;
-    std::vector<MacedPublicKey> keysToSign_;
-    cppbor::Array cborKeysToSign_;
-};
-
-/**
- * Generate an empty certificate request in test mode, and decrypt and verify the structure and
- * content.
- */
-TEST_P(CertificateRequestTest, EmptyRequest_testMode) {
-    bool testMode = true;
-    for (size_t eekLength : {2, 3, 7}) {
-        SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateTestEekChain(eekLength);
-
-        bytevec keysToSignMac;
-        DeviceInfo deviceInfo;
-        ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(
-                testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
-                &protectedData, &keysToSignMac);
-        ASSERT_TRUE(status.isOk()) << status.getMessage();
-
-        checkProtectedData(deviceInfo, cppbor::Array(), keysToSignMac, protectedData);
-    }
-}
-
-/**
- * Ensure that test mode outputs a unique BCC root key every time we request a
- * certificate request. Else, it's possible that the test mode API could be used
- * to fingerprint devices. Only the GEEK should be allowed to decrypt the same
- * device public key multiple times.
- */
-TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) {
-    constexpr bool testMode = true;
-
-    bytevec keysToSignMac;
-    DeviceInfo deviceInfo;
-    ProtectedData protectedData;
-    generateTestEekChain(3);
-    auto status = provisionable_->generateCertificateRequest(
-            testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
-            &protectedData, &keysToSignMac);
-    ASSERT_TRUE(status.isOk()) << status.getMessage();
-
-    std::vector<BccEntryData> firstBcc;
-    checkProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData,
-                       &firstBcc);
-
-    status = provisionable_->generateCertificateRequest(
-            testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
-            &protectedData, &keysToSignMac);
-    ASSERT_TRUE(status.isOk()) << status.getMessage();
-
-    std::vector<BccEntryData> secondBcc;
-    checkProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData,
-                       &secondBcc);
-
-    // Verify that none of the keys in the first BCC are repeated in the second one.
-    for (const auto& i : firstBcc) {
-        for (auto& j : secondBcc) {
-            ASSERT_THAT(i.pubKey, testing::Not(testing::ElementsAreArray(j.pubKey)))
-                    << "Found a repeated pubkey in two generateCertificateRequest test mode calls";
-        }
-    }
-}
-
-/**
- * Generate an empty certificate request in prod mode. This test must be run explicitly, and
- * is not run by default. Not all devices are GMS devices, and therefore they do not all
- * trust the Google EEK root.
- */
-TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
-    bool testMode = false;
-
-    bytevec keysToSignMac;
-    DeviceInfo deviceInfo;
-    ProtectedData protectedData;
-    auto status = provisionable_->generateCertificateRequest(
-            testMode, {} /* keysToSign */, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
-            challenge_, &deviceInfo, &protectedData, &keysToSignMac);
-    EXPECT_TRUE(status.isOk());
-}
-
-/**
- * Generate a non-empty certificate request in test mode.  Decrypt, parse and validate the contents.
- */
-TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) {
-    bool testMode = true;
-    generateKeys(testMode, 4 /* numKeys */);
-
-    for (size_t eekLength : {2, 3, 7}) {
-        SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateTestEekChain(eekLength);
-
-        bytevec keysToSignMac;
-        DeviceInfo deviceInfo;
-        ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(
-                testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
-                &keysToSignMac);
-        ASSERT_TRUE(status.isOk()) << status.getMessage();
-
-        checkProtectedData(deviceInfo, cborKeysToSign_, keysToSignMac, protectedData);
-    }
-}
-
-/**
- * Generate a non-empty certificate request in prod mode. This test must be run explicitly, and
- * is not run by default. Not all devices are GMS devices, and therefore they do not all
- * trust the Google EEK root.
- */
-TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
-    bool testMode = false;
-    generateKeys(testMode, 4 /* numKeys */);
-
-    bytevec keysToSignMac;
-    DeviceInfo deviceInfo;
-    ProtectedData protectedData;
-    auto status = provisionable_->generateCertificateRequest(
-            testMode, keysToSign_, getProdEekChain(rpcHardwareInfo.supportedEekCurve), challenge_,
-            &deviceInfo, &protectedData, &keysToSignMac);
-    EXPECT_TRUE(status.isOk());
-}
-
-/**
- * Generate a non-empty certificate request in test mode, but with the MAC corrupted on the keypair.
- */
-TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_testMode) {
-    bool testMode = true;
-    generateKeys(testMode, 1 /* numKeys */);
-    auto result = corrupt_maced_key(keysToSign_[0]);
-    ASSERT_TRUE(result) << result.moveMessage();
-    MacedPublicKey keyWithCorruptMac = result.moveValue();
-
-    bytevec keysToSignMac;
-    DeviceInfo deviceInfo;
-    ProtectedData protectedData;
-    generateTestEekChain(3);
-    auto status = provisionable_->generateCertificateRequest(
-            testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
-            &protectedData, &keysToSignMac);
-    ASSERT_FALSE(status.isOk()) << status.getMessage();
-    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
-}
-
-/**
- * Generate a non-empty certificate request in prod mode, but with the MAC corrupted on the keypair.
- */
-TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) {
-    bool testMode = false;
-    generateKeys(testMode, 1 /* numKeys */);
-    auto result = corrupt_maced_key(keysToSign_[0]);
-    ASSERT_TRUE(result) << result.moveMessage();
-    MacedPublicKey keyWithCorruptMac = result.moveValue();
-
-    bytevec keysToSignMac;
-    DeviceInfo deviceInfo;
-    ProtectedData protectedData;
-    auto status = provisionable_->generateCertificateRequest(
-            testMode, {keyWithCorruptMac}, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
-            challenge_, &deviceInfo, &protectedData, &keysToSignMac);
-    ASSERT_FALSE(status.isOk()) << status.getMessage();
-    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
-}
-
-/**
- * Generate a non-empty certificate request in prod mode that has a corrupt EEK chain.
- * Confirm that the request is rejected.
- */
-TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) {
-    bool testMode = false;
-    generateKeys(testMode, 4 /* numKeys */);
-
-    auto prodEekChain = getProdEekChain(rpcHardwareInfo.supportedEekCurve);
-    auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain);
-    ASSERT_NE(parsedChain, nullptr) << parseErr;
-    ASSERT_NE(parsedChain->asArray(), nullptr);
-
-    for (int ii = 0; ii < parsedChain->asArray()->size(); ++ii) {
-        auto chain = corrupt_sig_chain(prodEekChain, ii);
-        ASSERT_TRUE(chain) << chain.message();
-
-        bytevec keysToSignMac;
-        DeviceInfo deviceInfo;
-        ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, *chain,
-                                                                 challenge_, &deviceInfo,
-                                                                 &protectedData, &keysToSignMac);
-        ASSERT_FALSE(status.isOk());
-        ASSERT_EQ(status.getServiceSpecificError(),
-                  BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
-    }
-}
-
-/**
- * Generate a non-empty certificate request in prod mode that has an incomplete EEK chain.
- * Confirm that the request is rejected.
- */
-TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) {
-    bool testMode = false;
-    generateKeys(testMode, 4 /* numKeys */);
-
-    // Build an EEK chain that omits the first self-signed cert.
-    auto truncatedChain = cppbor::Array();
-    auto [chain, _, parseErr] = cppbor::parse(getProdEekChain(rpcHardwareInfo.supportedEekCurve));
-    ASSERT_TRUE(chain);
-    auto eekChain = chain->asArray();
-    ASSERT_NE(eekChain, nullptr);
-    for (size_t ii = 1; ii < eekChain->size(); ii++) {
-        truncatedChain.add(eekChain->get(ii)->clone());
-    }
-
-    bytevec keysToSignMac;
-    DeviceInfo deviceInfo;
-    ProtectedData protectedData;
-    auto status = provisionable_->generateCertificateRequest(
-            testMode, keysToSign_, truncatedChain.encode(), challenge_, &deviceInfo, &protectedData,
-            &keysToSignMac);
-    ASSERT_FALSE(status.isOk());
-    ASSERT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
-}
-
-/**
- * Generate a non-empty certificate request in test mode, with prod keys.  Must fail with
- * STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
- */
-TEST_P(CertificateRequestTest, NonEmptyRequest_prodKeyInTestCert) {
-    generateKeys(false /* testMode */, 2 /* numKeys */);
-
-    bytevec keysToSignMac;
-    DeviceInfo deviceInfo;
-    ProtectedData protectedData;
-    generateTestEekChain(3);
-    auto status = provisionable_->generateCertificateRequest(
-            true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
-            &protectedData, &keysToSignMac);
-    ASSERT_FALSE(status.isOk());
-    ASSERT_EQ(status.getServiceSpecificError(),
-              BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST);
-}
-
-/**
- * Generate a non-empty certificate request in prod mode, with test keys.  Must fail with
- * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
- */
-TEST_P(CertificateRequestTest, NonEmptyRequest_testKeyInProdCert) {
-    generateKeys(true /* testMode */, 2 /* numKeys */);
-
-    bytevec keysToSignMac;
-    DeviceInfo deviceInfo;
-    ProtectedData protectedData;
-    generateTestEekChain(3);
-    auto status = provisionable_->generateCertificateRequest(
-            false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
-            &protectedData, &keysToSignMac);
-    ASSERT_FALSE(status.isOk());
-    ASSERT_EQ(status.getServiceSpecificError(),
-              BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
-}
-
-INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestTest);
-
-}  // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
index 54b6fdc..49fd0c9 100644
--- a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
+++ b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
@@ -16,16 +16,21 @@
 
 #define LOG_TAG "keymint_benchmark"
 
+#include <iostream>
+
 #include <base/command_line.h>
 #include <benchmark/benchmark.h>
-#include <iostream>
 
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/security/keymint/ErrorCode.h>
 #include <aidl/android/hardware/security/keymint/IKeyMintDevice.h>
 #include <android/binder_manager.h>
 #include <binder/IServiceManager.h>
+
 #include <keymint_support/authorization_set.h>
+#include <keymint_support/openssl_utils.h>
+#include <openssl/curve25519.h>
+#include <openssl/x509.h>
 
 #define SMALL_MESSAGE_SIZE 64
 #define MEDIUM_MESSAGE_SIZE 1024
@@ -63,7 +68,7 @@
 
     int getError() { return static_cast<int>(error_); }
 
-    const string& GenerateMessage(int size) {
+    const string GenerateMessage(int size) {
         for (const string& message : message_cache_) {
             if (message.size() == size) {
                 return message;
@@ -71,7 +76,7 @@
         }
         string message = string(size, 'x');
         message_cache_.push_back(message);
-        return std::move(message);
+        return message;
     }
 
     optional<BlockMode> getBlockMode(string transform) {
@@ -119,6 +124,22 @@
         return {};
     }
 
+    string getAlgorithmString(string transform) {
+        if (transform.find("AES") != string::npos) {
+            return "AES";
+        } else if (transform.find("Hmac") != string::npos) {
+            return "HMAC";
+        } else if (transform.find("DESede") != string::npos) {
+            return "TRIPLE_DES";
+        } else if (transform.find("RSA") != string::npos) {
+            return "RSA";
+        } else if (transform.find("EC") != string::npos) {
+            return "EC";
+        }
+        std::cerr << "Can't find algorithm for " << transform << std::endl;
+        return "";
+    }
+
     Digest getDigest(string transform) {
         if (transform.find("MD5") != string::npos) {
             return Digest::MD5;
@@ -135,13 +156,59 @@
             return Digest::SHA_2_512;
         } else if (transform.find("RSA") != string::npos &&
                    transform.find("OAEP") != string::npos) {
-            return Digest::SHA1;
+            if (securityLevel_ == SecurityLevel::STRONGBOX) {
+                return Digest::SHA_2_256;
+            } else {
+                return Digest::SHA1;
+            }
         } else if (transform.find("Hmac") != string::npos) {
             return Digest::SHA_2_256;
         }
         return Digest::NONE;
     }
 
+    string getDigestString(string transform) {
+        if (transform.find("MD5") != string::npos) {
+            return "MD5";
+        } else if (transform.find("SHA1") != string::npos ||
+                   transform.find("SHA-1") != string::npos) {
+            return "SHA1";
+        } else if (transform.find("SHA224") != string::npos) {
+            return "SHA_2_224";
+        } else if (transform.find("SHA256") != string::npos) {
+            return "SHA_2_256";
+        } else if (transform.find("SHA384") != string::npos) {
+            return "SHA_2_384";
+        } else if (transform.find("SHA512") != string::npos) {
+            return "SHA_2_512";
+        } else if (transform.find("RSA") != string::npos &&
+                   transform.find("OAEP") != string::npos) {
+            if (securityLevel_ == SecurityLevel::STRONGBOX) {
+                return "SHA_2_256";
+            } else {
+                return "SHA1";
+            }
+        } else if (transform.find("Hmac") != string::npos) {
+            return "SHA_2_256";
+        }
+        return "";
+    }
+
+    optional<EcCurve> getCurveFromLength(int keySize) {
+        switch (keySize) {
+            case 224:
+                return EcCurve::P_224;
+            case 256:
+                return EcCurve::P_256;
+            case 384:
+                return EcCurve::P_384;
+            case 521:
+                return EcCurve::P_521;
+            default:
+                return std::nullopt;
+        }
+    }
+
     bool GenerateKey(string transform, int keySize, bool sign = false) {
         if (transform == key_transform_) {
             return true;
@@ -184,6 +251,12 @@
         }
         if (algorithm == Algorithm::EC) {
             authSet.SetDefaultValidity();
+            std::optional<EcCurve> curve = getCurveFromLength(keySize);
+            if (!curve) {
+                std::cerr << "Error: invalid EC-Curve from size " << keySize << std::endl;
+                return false;
+            }
+            authSet.Authorization(TAG_EC_CURVE, curve.value());
         }
         error_ = GenerateKey(authSet);
         return error_ == ErrorCode::OK;
@@ -236,6 +309,109 @@
         return GetReturnErrorCode(result);
     }
 
+    /* Copied the function LocalRsaEncryptMessage from
+     * hardware/interfaces/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp in VTS.
+     * Replaced asserts with the condition check and return false in case of failure condition.
+     * Require return value to skip the benchmark test case from further execution in case
+     * LocalRsaEncryptMessage fails.
+     */
+    optional<string> LocalRsaEncryptMessage(const string& message, const AuthorizationSet& params) {
+        // Retrieve the public key from the leaf certificate.
+        if (cert_chain_.empty()) {
+            std::cerr << "Local RSA encrypt Error: invalid cert_chain_" << std::endl;
+            return "Failure";
+        }
+        X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+        EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get()));
+        RSA_Ptr rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pub_key.get())));
+
+        // Retrieve relevant tags.
+        Digest digest = Digest::NONE;
+        Digest mgf_digest = Digest::SHA1;
+        PaddingMode padding = PaddingMode::NONE;
+
+        auto digest_tag = params.GetTagValue(TAG_DIGEST);
+        if (digest_tag.has_value()) digest = digest_tag.value();
+        auto pad_tag = params.GetTagValue(TAG_PADDING);
+        if (pad_tag.has_value()) padding = pad_tag.value();
+        auto mgf_tag = params.GetTagValue(TAG_RSA_OAEP_MGF_DIGEST);
+        if (mgf_tag.has_value()) mgf_digest = mgf_tag.value();
+
+        const EVP_MD* md = openssl_digest(digest);
+        const EVP_MD* mgf_md = openssl_digest(mgf_digest);
+
+        // Set up encryption context.
+        EVP_PKEY_CTX_Ptr ctx(EVP_PKEY_CTX_new(pub_key.get(), /* engine= */ nullptr));
+        if (EVP_PKEY_encrypt_init(ctx.get()) <= 0) {
+            std::cerr << "Local RSA encrypt Error: Encryption init failed" << std::endl;
+            return "Failure";
+        }
+
+        int rc = -1;
+        switch (padding) {
+            case PaddingMode::NONE:
+                rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_NO_PADDING);
+                break;
+            case PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
+                rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING);
+                break;
+            case PaddingMode::RSA_OAEP:
+                rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_OAEP_PADDING);
+                break;
+            default:
+                break;
+        }
+        if (rc <= 0) {
+            std::cerr << "Local RSA encrypt Error: Set padding failed" << std::endl;
+            return "Failure";
+        }
+        if (padding == PaddingMode::RSA_OAEP) {
+            if (!EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), md)) {
+                std::cerr << "Local RSA encrypt Error: Set digest failed: " << ERR_peek_last_error()
+                          << std::endl;
+                return "Failure";
+            }
+            if (!EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), mgf_md)) {
+                std::cerr << "Local RSA encrypt Error: Set digest failed: " << ERR_peek_last_error()
+                          << std::endl;
+                return "Failure";
+            }
+        }
+
+        // Determine output size.
+        size_t outlen;
+        if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen,
+                             reinterpret_cast<const uint8_t*>(message.data()),
+                             message.size()) <= 0) {
+            std::cerr << "Local RSA encrypt Error: Determine output size failed: "
+                      << ERR_peek_last_error() << std::endl;
+            return "Failure";
+        }
+
+        // Left-zero-pad the input if necessary.
+        const uint8_t* to_encrypt = reinterpret_cast<const uint8_t*>(message.data());
+        size_t to_encrypt_len = message.size();
+
+        std::unique_ptr<string> zero_padded_message;
+        if (padding == PaddingMode::NONE && to_encrypt_len < outlen) {
+            zero_padded_message.reset(new string(outlen, '\0'));
+            memcpy(zero_padded_message->data() + (outlen - to_encrypt_len), message.data(),
+                   message.size());
+            to_encrypt = reinterpret_cast<const uint8_t*>(zero_padded_message->data());
+            to_encrypt_len = outlen;
+        }
+
+        // Do the encryption.
+        string output(outlen, '\0');
+        if (EVP_PKEY_encrypt(ctx.get(), reinterpret_cast<uint8_t*>(output.data()), &outlen,
+                             to_encrypt, to_encrypt_len) <= 0) {
+            std::cerr << "Local RSA encrypt Error: Encryption failed: " << ERR_peek_last_error()
+                      << std::endl;
+            return "Failure";
+        }
+        return output;
+    }
+
     SecurityLevel securityLevel_;
     string name_;
 
@@ -243,12 +419,13 @@
     ErrorCode GenerateKey(const AuthorizationSet& key_desc,
                           const optional<AttestationKey>& attest_key = std::nullopt) {
         key_blob_.clear();
+        cert_chain_.clear();
         KeyCreationResult creationResult;
         Status result = keymint_->generateKey(key_desc.vector_data(), attest_key, &creationResult);
         if (result.isOk()) {
             key_blob_ = std::move(creationResult.keyBlob);
+            cert_chain_ = std::move(creationResult.certificateChain);
             creationResult.keyCharacteristics.clear();
-            creationResult.certificateChain.clear();
         }
         return GetReturnErrorCode(result);
     }
@@ -313,6 +490,11 @@
         return ErrorCode::UNKNOWN_ERROR;
     }
 
+    X509_Ptr parse_cert_blob(const vector<uint8_t>& blob) {
+        const uint8_t* p = blob.data();
+        return X509_Ptr(d2i_X509(nullptr /* allocate new */, &p, blob.size()));
+    }
+
     std::shared_ptr<IKeyMintOperation> op_;
     vector<Certificate> cert_chain_;
     vector<uint8_t> key_blob_;
@@ -365,6 +547,10 @@
     BENCHMARK_KM_MSG(encrypt, transform, keySize, msgSize) \
     BENCHMARK_KM_MSG(decrypt, transform, keySize, msgSize)
 
+// Skip public key operations as they are not supported in KeyMint.
+#define BENCHMARK_KM_ASYM_CIPHER(transform, keySize, msgSize)   \
+    BENCHMARK_KM_MSG(decrypt, transform, keySize, msgSize)
+
 #define BENCHMARK_KM_CIPHER_ALL_MSGS(transform, keySize) \
     BENCHMARK_KM_ALL_MSGS(encrypt, transform, keySize)   \
     BENCHMARK_KM_ALL_MSGS(decrypt, transform, keySize)
@@ -372,12 +558,43 @@
 #define BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, keySize) \
     BENCHMARK_KM_ALL_MSGS(sign, transform, keySize)         \
     BENCHMARK_KM_ALL_MSGS(verify, transform, keySize)
-// clang-format on
+
+// Skip public key operations as they are not supported in KeyMint.
+#define BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, keySize) \
+    BENCHMARK_KM_ALL_MSGS(sign, transform, keySize) \
+    // clang-format on
 
 /*
  * ============= KeyGen TESTS ==================
  */
+
+static bool isValidSBKeySize(string transform, int keySize) {
+    std::optional<Algorithm> algorithm = keymintTest->getAlgorithm(transform);
+    switch (algorithm.value()) {
+        case Algorithm::AES:
+            return (keySize == 128 || keySize == 256);
+        case Algorithm::HMAC:
+            return (keySize % 8 == 0 && keySize >= 64 && keySize <= 512);
+        case Algorithm::TRIPLE_DES:
+            return (keySize == 168);
+        case Algorithm::RSA:
+            return (keySize == 2048);
+        case Algorithm::EC:
+            return (keySize == 256);
+    }
+    return false;
+}
+
 static void keygen(benchmark::State& state, string transform, int keySize) {
+    // Skip the test for unsupported key size in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX &&
+        !isValidSBKeySize(transform, keySize)) {
+        state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                             " is not supported in StrongBox for algorithm: " +
+                             keymintTest->getAlgorithmString(transform))
+                                    .c_str());
+        return;
+    }
     addDefaultLabel(state);
     for (auto _ : state) {
         if (!keymintTest->GenerateKey(transform, keySize)) {
@@ -413,8 +630,24 @@
 /*
  * ============= SIGNATURE TESTS ==================
  */
-
 static void sign(benchmark::State& state, string transform, int keySize, int msgSize) {
+    // Skip the test for unsupported key size or unsupported digest in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX) {
+        if (!isValidSBKeySize(transform, keySize)) {
+            state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                                 " is not supported in StrongBox for algorithm: " +
+                                 keymintTest->getAlgorithmString(transform))
+                                        .c_str());
+            return;
+        }
+        if (keymintTest->getDigest(transform) != Digest::SHA_2_256) {
+            state.SkipWithError(
+                    ("Skipped for STRONGBOX: Digest: " + keymintTest->getDigestString(transform) +
+                     " is not supported in StrongBox")
+                            .c_str());
+            return;
+        }
+    }
     addDefaultLabel(state);
     if (!keymintTest->GenerateKey(transform, keySize, true)) {
         state.SkipWithError(
@@ -444,6 +677,23 @@
 }
 
 static void verify(benchmark::State& state, string transform, int keySize, int msgSize) {
+    // Skip the test for unsupported key size or unsupported digest in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX) {
+        if (!isValidSBKeySize(transform, keySize)) {
+            state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                                 " is not supported in StrongBox for algorithm: " +
+                                 keymintTest->getAlgorithmString(transform))
+                                        .c_str());
+            return;
+        }
+        if (keymintTest->getDigest(transform) != Digest::SHA_2_256) {
+            state.SkipWithError(
+                    ("Skipped for STRONGBOX: Digest: " + keymintTest->getDigestString(transform) +
+                     " is not supported in StrongBox")
+                            .c_str());
+            return;
+        }
+    }
     addDefaultLabel(state);
     if (!keymintTest->GenerateKey(transform, keySize, true)) {
         state.SkipWithError(
@@ -500,10 +750,10 @@
 BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA512)
 
 #define BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(transform) \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 224)      \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256)      \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 384)      \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 521)
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 224)      \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 256)      \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 384)      \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 521)
 
 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(NONEwithECDSA);
 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA1withECDSA);
@@ -513,13 +763,14 @@
 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA512withECDSA);
 
 #define BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(transform) \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2048)   \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 3072)   \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096)
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 2048)   \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 3072)   \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 4096)
 
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA256withRSA);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA);
 
@@ -528,6 +779,7 @@
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA/PSS);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA/PSS);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA/PSS);
+
 // clang-format on
 
 /*
@@ -535,6 +787,15 @@
  */
 
 static void encrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
+    // Skip the test for unsupported key size in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX &&
+        (!isValidSBKeySize(transform, keySize))) {
+        state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                             " is not supported in StrongBox for algorithm: " +
+                             keymintTest->getAlgorithmString(transform))
+                                    .c_str());
+        return;
+    }
     addDefaultLabel(state);
     if (!keymintTest->GenerateKey(transform, keySize)) {
         state.SkipWithError(
@@ -564,6 +825,15 @@
 }
 
 static void decrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
+    // Skip the test for unsupported key size in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX &&
+        (!isValidSBKeySize(transform, keySize))) {
+        state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                             " is not supported in StrongBox for algorithm: " +
+                             keymintTest->getAlgorithmString(transform))
+                                    .c_str());
+        return;
+    }
     addDefaultLabel(state);
     if (!keymintTest->GenerateKey(transform, keySize)) {
         state.SkipWithError(
@@ -573,23 +843,34 @@
     AuthorizationSet out_params;
     AuthorizationSet in_params = keymintTest->getOperationParams(transform);
     string message = keymintTest->GenerateMessage(msgSize);
-    auto error = keymintTest->Begin(KeyPurpose::ENCRYPT, in_params, &out_params);
-    if (error != ErrorCode::OK) {
-        state.SkipWithError(
-                ("Encryption begin error, " + std::to_string(keymintTest->getError())).c_str());
-        return;
+    optional<string> encryptedMessage;
+
+    if (keymintTest->getAlgorithm(transform).value() == Algorithm::RSA) {
+        // Public key operation not supported, doing local Encryption
+        encryptedMessage = keymintTest->LocalRsaEncryptMessage(message, in_params);
+        if ((keySize / 8) != (*encryptedMessage).size()) {
+            state.SkipWithError("Local Encryption falied");
+            return;
+        }
+    } else {
+        auto error = keymintTest->Begin(KeyPurpose::ENCRYPT, in_params, &out_params);
+        if (error != ErrorCode::OK) {
+            state.SkipWithError(
+                    ("Encryption begin error, " + std::to_string(keymintTest->getError())).c_str());
+            return;
+        }
+        encryptedMessage = keymintTest->Process(message);
+        if (!encryptedMessage) {
+            state.SkipWithError(
+                    ("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
+            return;
+        }
+        in_params.push_back(out_params);
+        out_params.Clear();
     }
-    auto encryptedMessage = keymintTest->Process(message);
-    if (!encryptedMessage) {
-        state.SkipWithError(
-                ("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
-        return;
-    }
-    in_params.push_back(out_params);
-    out_params.Clear();
     for (auto _ : state) {
         state.PauseTiming();
-        error = keymintTest->Begin(KeyPurpose::DECRYPT, in_params, &out_params);
+        auto error = keymintTest->Begin(KeyPurpose::DECRYPT, in_params, &out_params);
         if (error != ErrorCode::OK) {
             state.SkipWithError(
                     ("Decryption begin error, " + std::to_string(keymintTest->getError())).c_str());
@@ -624,9 +905,9 @@
 BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/PKCS7Padding, 168);
 
 #define BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(transform, msgSize) \
-    BENCHMARK_KM_CIPHER(transform, 2048, msgSize)            \
-    BENCHMARK_KM_CIPHER(transform, 3072, msgSize)            \
-    BENCHMARK_KM_CIPHER(transform, 4096, msgSize)
+    BENCHMARK_KM_ASYM_CIPHER(transform, 2048, msgSize)            \
+    BENCHMARK_KM_ASYM_CIPHER(transform, 3072, msgSize)            \
+    BENCHMARK_KM_ASYM_CIPHER(transform, 4096, msgSize)
 
 BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/NoPadding, SMALL_MESSAGE_SIZE);
 BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/PKCS1Padding, SMALL_MESSAGE_SIZE);
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index bf2ab02..1a8695b 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -63,8 +63,15 @@
     defaults: [
         "keymint_use_latest_hal_aidl_ndk_shared",
     ],
+    static_libs: [
+        "android.hardware.security.rkp-V3-ndk",
+    ],
+    whole_static_libs: [
+        "libhwtrust_cxx",
+    ],
     shared_libs: [
         "libbase",
+        "libbinder_ndk",
         "libcppbor_external",
         "libcppcose_rkp",
         "libcrypto",
@@ -77,8 +84,10 @@
     name: "libkeymint_remote_prov_support_test",
     srcs: ["remote_prov_utils_test.cpp"],
     static_libs: [
+        "android.hardware.security.rkp-V3-ndk",
         "libgmock",
         "libgtest_main",
+        "libkeymint_remote_prov_support",
     ],
     defaults: [
         "keymint_use_latest_hal_aidl_ndk_shared",
@@ -90,6 +99,5 @@
         "libcrypto",
         "libjsoncpp",
         "libkeymaster_portable",
-        "libkeymint_remote_prov_support",
     ],
 }
diff --git a/security/keymint/support/attestation_record.cpp b/security/keymint/support/attestation_record.cpp
index 2462228..5a26611 100644
--- a/security/keymint/support/attestation_record.cpp
+++ b/security/keymint/support/attestation_record.cpp
@@ -105,6 +105,7 @@
     ASN1_INTEGER* boot_patchlevel;
     ASN1_NULL* device_unique_attestation;
     ASN1_NULL* identity_credential;
+    ASN1_OCTET_STRING* attestation_id_second_imei;
 } KM_AUTH_LIST;
 
 ASN1_SEQUENCE(KM_AUTH_LIST) = {
@@ -170,6 +171,8 @@
                      TAG_DEVICE_UNIQUE_ATTESTATION.maskedTag()),
         ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential, ASN1_NULL,
                      TAG_IDENTITY_CREDENTIAL_KEY.maskedTag()),
+        ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_second_imei, ASN1_OCTET_STRING,
+                     TAG_ATTESTATION_ID_SECOND_IMEI.maskedTag()),
 } ASN1_SEQUENCE_END(KM_AUTH_LIST);
 IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST);
 
@@ -323,6 +326,7 @@
     copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list);
     copyAuthTag(record->device_unique_attestation, TAG_DEVICE_UNIQUE_ATTESTATION, auth_list);
     copyAuthTag(record->identity_credential, TAG_IDENTITY_CREDENTIAL_KEY, auth_list);
+    copyAuthTag(record->attestation_id_second_imei, TAG_ATTESTATION_ID_SECOND_IMEI, auth_list);
 
     return ErrorCode::OK;
 }
diff --git a/security/keymint/support/include/keymint_support/attestation_record.h b/security/keymint/support/include/keymint_support/attestation_record.h
index bc76c93..f280f48 100644
--- a/security/keymint/support/include/keymint_support/attestation_record.h
+++ b/security/keymint/support/include/keymint_support/attestation_record.h
@@ -43,6 +43,8 @@
  */
 static const char kAttestionRecordOid[] = "1.3.6.1.4.1.11129.2.1.17";
 
+static const char kCrlDPOid[] = "2.5.29.31";  // Standard CRL Distribution Points extension.
+
 enum class VerifiedBoot : uint8_t {
     VERIFIED = 0,
     SELF_SIGNED = 1,
diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h
index 5b2a6f3..823899a 100644
--- a/security/keymint/support/include/keymint_support/keymint_tags.h
+++ b/security/keymint/support/include/keymint_support/keymint_tags.h
@@ -77,6 +77,7 @@
 DECLARE_TYPED_TAG(ATTESTATION_ID_BRAND);
 DECLARE_TYPED_TAG(ATTESTATION_ID_DEVICE);
 DECLARE_TYPED_TAG(ATTESTATION_ID_IMEI);
+DECLARE_TYPED_TAG(ATTESTATION_ID_SECOND_IMEI);
 DECLARE_TYPED_TAG(ATTESTATION_ID_MANUFACTURER);
 DECLARE_TYPED_TAG(ATTESTATION_ID_MEID);
 DECLARE_TYPED_TAG(ATTESTATION_ID_PRODUCT);
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index f3b8608..79189a1 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -16,7 +16,9 @@
 
 #pragma once
 
+#include <memory>
 #include <vector>
+#include "aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h"
 
 #include <keymaster/cppcose/cppcose.h>
 
@@ -106,15 +108,6 @@
     bytevec pubKey;
 };
 
-/**
- * Validates the provided CBOR-encoded BCC, returning a vector of BccEntryData
- * structs containing the BCC entry contents.  If an entry contains no firmware
- * digest, the corresponding BccEntryData.firmwareDigest will have length zero
- * (there's no way to distinguish between an empty and missing firmware digest,
- * which seems fine).
- */
-ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc);
-
 struct JsonOutput {
     static JsonOutput Ok(std::string json) { return {std::move(json), ""}; }
     static JsonOutput Error(std::string error) { return {"", std::move(error)}; }
@@ -139,4 +132,54 @@
 JsonOutput jsonEncodeCsrWithBuild(const std::string instance_name,
                                   const cppbor::Array& csr);
 
+/**
+ * Parses a DeviceInfo structure from the given CBOR data. The parsed data is then validated to
+ * ensure it contains the minimum required data at the time of manufacturing. This is only a
+ * partial validation, as some fields may not be provisioned yet at the time this information
+ * is parsed in the manufacturing process.
+ */
+ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo(
+        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable);
+
+/**
+ * Parses a DeviceInfo structure from the given CBOR data. The parsed data is then validated to
+ * ensure it is formatted correctly and that it contains the required values for Remote Key
+ * Provisioning. This is a full validation, and assumes the device is provisioned as if it is
+ * suitable for the end user.
+ */
+ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo(
+        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable);
+
+/**
+ * Verify the protected data as if the device is still early in the factory process and may not
+ * have all device identifiers provisioned yet.
+ */
+ErrMsgOr<std::vector<BccEntryData>> verifyFactoryProtectedData(
+        const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
+        const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
+        IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
+/**
+ * Verify the protected data as if the device is a final production sample.
+ */
+ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData(
+        const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
+        const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
+        IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
+
+/**
+ * Verify the CSR as if the device is still early in the factory process and may not
+ * have all device identifiers provisioned yet.
+ */
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(
+        const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
+        IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
+/**
+ * Verify the CSR as if the device is a final production sample.
+ */
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
+        const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
+        IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge);
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 0dbea5b..c9c3e4d 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -15,11 +15,17 @@
  */
 
 #include <iterator>
+#include <memory>
+#include <set>
+#include <string>
 #include <tuple>
+#include "aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h"
 
 #include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h>
+#include <android-base/macros.h>
 #include <android-base/properties.h>
 #include <cppbor.h>
+#include <hwtrust/hwtrust.h>
 #include <json/json.h>
 #include <keymaster/km_openssl/ec_key.h>
 #include <keymaster/km_openssl/ecdsa_operation.h>
@@ -28,6 +34,7 @@
 #include <openssl/base64.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
+#include <openssl/x509.h>
 #include <remote_prov/remote_prov_utils.h>
 
 namespace aidl::android::hardware::security::keymint::remote_prov {
@@ -37,10 +44,13 @@
 constexpr int32_t kBccPayloadSubjPubKey = -4670552;
 constexpr int32_t kBccPayloadKeyUsage = -4670553;
 constexpr int kP256AffinePointSize = 32;
+constexpr uint32_t kNumTeeDeviceInfoEntries = 14;
 
 using EC_KEY_Ptr = bssl::UniquePtr<EC_KEY>;
 using EVP_PKEY_Ptr = bssl::UniquePtr<EVP_PKEY>;
 using EVP_PKEY_CTX_Ptr = bssl::UniquePtr<EVP_PKEY_CTX>;
+using X509_Ptr = bssl::UniquePtr<X509>;
+using CRYPTO_BUFFER_Ptr = bssl::UniquePtr<CRYPTO_BUFFER>;
 
 ErrMsgOr<bytevec> ecKeyGetPrivateKey(const EC_KEY* ecKey) {
     // Extract private key.
@@ -105,6 +115,36 @@
     return std::make_tuple(std::move(pubX), std::move(pubY));
 }
 
+ErrMsgOr<bytevec> getRawPublicKey(const EVP_PKEY_Ptr& pubKey) {
+    if (pubKey.get() == nullptr) {
+        return "pkey is null.";
+    }
+    int keyType = EVP_PKEY_base_id(pubKey.get());
+    switch (keyType) {
+        case EVP_PKEY_EC: {
+            auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pubKey.get()));
+            if (ecKey.get() == nullptr) {
+                return "Failed to get ec key";
+            }
+            return ecKeyGetPublicKey(ecKey.get());
+        }
+        case EVP_PKEY_ED25519: {
+            bytevec rawPubKey;
+            size_t rawKeySize = 0;
+            if (!EVP_PKEY_get_raw_public_key(pubKey.get(), NULL, &rawKeySize)) {
+                return "Failed to get raw public key.";
+            }
+            rawPubKey.resize(rawKeySize);
+            if (!EVP_PKEY_get_raw_public_key(pubKey.get(), rawPubKey.data(), &rawKeySize)) {
+                return "Failed to get raw public key.";
+            }
+            return rawPubKey;
+        }
+        default:
+            return "Unknown key type.";
+    }
+}
+
 ErrMsgOr<std::tuple<bytevec, bytevec>> generateEc256KeyPair() {
     auto ec_key = EC_KEY_Ptr(EC_KEY_new());
     if (ec_key.get() == nullptr) {
@@ -282,134 +322,23 @@
     return chain.encode();
 }
 
-ErrMsgOr<bytevec> validatePayloadAndFetchPubKey(const cppbor::Map* payload) {
-    const auto& issuer = payload->get(kBccPayloadIssuer);
-    if (!issuer || !issuer->asTstr()) return "Issuer is not present or not a tstr.";
-    const auto& subject = payload->get(kBccPayloadSubject);
-    if (!subject || !subject->asTstr()) return "Subject is not present or not a tstr.";
-    const auto& keyUsage = payload->get(kBccPayloadKeyUsage);
-    if (!keyUsage || !keyUsage->asBstr()) return "Key usage is not present or not a bstr.";
-    const auto& serializedKey = payload->get(kBccPayloadSubjPubKey);
-    if (!serializedKey || !serializedKey->asBstr()) return "Key is not present or not a bstr.";
-    return serializedKey->asBstr()->value();
-}
-
-ErrMsgOr<bytevec> verifyAndParseCoseSign1Cwt(const cppbor::Array* coseSign1,
-                                             const bytevec& signingCoseKey, const bytevec& aad) {
-    if (!coseSign1 || coseSign1->size() != kCoseSign1EntryCount) {
-        return "Invalid COSE_Sign1";
-    }
-
-    const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
-    const cppbor::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
-    const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
-    const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
-
-    if (!protectedParams || !unprotectedParams || !payload || !signature) {
-        return "Invalid COSE_Sign1";
-    }
-
-    auto [parsedProtParams, _, errMsg] = cppbor::parse(protectedParams);
-    if (!parsedProtParams) {
-        return errMsg + " when parsing protected params.";
-    }
-    if (!parsedProtParams->asMap()) {
-        return "Protected params must be a map";
-    }
-
-    auto& algorithm = parsedProtParams->asMap()->get(ALGORITHM);
-    if (!algorithm || !algorithm->asInt() ||
-        (algorithm->asInt()->value() != EDDSA && algorithm->asInt()->value() != ES256)) {
-        return "Unsupported signature algorithm";
-    }
-
-    auto [parsedPayload, __, payloadErrMsg] = cppbor::parse(payload);
-    if (!parsedPayload) return payloadErrMsg + " when parsing key";
-    if (!parsedPayload->asMap()) return "CWT must be a map";
-    auto serializedKey = validatePayloadAndFetchPubKey(parsedPayload->asMap());
-    if (!serializedKey) {
-        return "CWT validation failed: " + serializedKey.moveMessage();
-    }
-
-    bool selfSigned = signingCoseKey.empty();
-    bytevec signatureInput =
-        cppbor::Array().add("Signature1").add(*protectedParams).add(aad).add(*payload).encode();
-
-    if (algorithm->asInt()->value() == EDDSA) {
-        auto key = CoseKey::parseEd25519(selfSigned ? *serializedKey : signingCoseKey);
-
-        if (!key) return "Bad signing key: " + key.moveMessage();
-
-        if (!ED25519_verify(signatureInput.data(), signatureInput.size(), signature->value().data(),
-                            key->getBstrValue(CoseKey::PUBKEY_X)->data())) {
-            return "Signature verification failed";
-        }
-    } else {  // P256
-        auto key = CoseKey::parseP256(selfSigned ? *serializedKey : signingCoseKey);
-        if (!key || key->getBstrValue(CoseKey::PUBKEY_X)->empty() ||
-            key->getBstrValue(CoseKey::PUBKEY_Y)->empty()) {
-            return "Bad signing key: " + key.moveMessage();
-        }
-        auto publicKey = key->getEcPublicKey();
-        if (!publicKey) return publicKey.moveMessage();
-
-        auto ecdsaDerSignature = ecdsaCoseSignatureToDer(signature->value());
-        if (!ecdsaDerSignature) return ecdsaDerSignature.moveMessage();
-
-        // convert public key to uncompressed form.
-        publicKey->insert(publicKey->begin(), 0x04);
-
-        if (!verifyEcdsaDigest(publicKey.moveValue(), sha256(signatureInput), *ecdsaDerSignature)) {
-            return "Signature verification failed";
-        }
-    }
-
-    return serializedKey.moveValue();
-}
-
-ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc) {
-    if (!bcc || bcc->size() == 0) return "Invalid BCC";
-
+ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc,
+                                                hwtrust::DiceChain::Kind kind) {
+    auto encodedBcc = bcc->encode();
+    auto chain = hwtrust::DiceChain::Verify(encodedBcc, kind);
+    if (!chain.ok()) return chain.error().message();
+    auto keys = chain->CosePublicKeys();
+    if (!keys.ok()) return keys.error().message();
     std::vector<BccEntryData> result;
-
-    const auto& devicePubKey = bcc->get(0);
-    if (!devicePubKey->asMap()) return "Invalid device public key at the 1st entry in the BCC";
-
-    bytevec prevKey;
-
-    for (size_t i = 1; i < bcc->size(); ++i) {
-        const cppbor::Array* entry = bcc->get(i)->asArray();
-        if (!entry || entry->size() != kCoseSign1EntryCount) {
-            return "Invalid BCC entry " + std::to_string(i) + ": " + prettyPrint(entry);
-        }
-        auto payload = verifyAndParseCoseSign1Cwt(entry, std::move(prevKey), bytevec{} /* AAD */);
-        if (!payload) {
-            return "Failed to verify entry " + std::to_string(i) + ": " + payload.moveMessage();
-        }
-
-        auto& certProtParms = entry->get(kCoseSign1ProtectedParams);
-        if (!certProtParms || !certProtParms->asBstr()) return "Invalid prot params";
-        auto [parsedProtParms, _, errMsg] = cppbor::parse(certProtParms->asBstr()->value());
-        if (!parsedProtParms || !parsedProtParms->asMap()) return "Invalid prot params";
-
-        result.push_back(BccEntryData{*payload});
-
-        // This entry's public key is the signing key for the next entry.
-        prevKey = payload.moveValue();
-        if (i == 1) {
-            auto [parsedRootKey, _, errMsg] = cppbor::parse(prevKey);
-            if (!parsedRootKey || !parsedRootKey->asMap()) return "Invalid payload entry in BCC.";
-            if (*parsedRootKey != *devicePubKey) {
-                return "Device public key doesn't match BCC root.";
-            }
-        }
+    for (auto& key : *keys) {
+        result.push_back({std::move(key)});
     }
-
     return result;
 }
 
 JsonOutput jsonEncodeCsrWithBuild(const std::string instance_name, const cppbor::Array& csr) {
     const std::string kFingerprintProp = "ro.build.fingerprint";
+    const std::string kSerialNoProp = "ro.serialno";
 
     if (!::android::base::WaitForPropertyCreation(kFingerprintProp)) {
         return JsonOutput::Error("Unable to read build fingerprint");
@@ -434,6 +363,7 @@
     Json::Value json(Json::objectValue);
     json["name"] = instance_name;
     json["build_fingerprint"] = ::android::base::GetProperty(kFingerprintProp, /*default=*/"");
+    json["serialno"] = ::android::base::GetProperty(kSerialNoProp, /*default=*/"");
     json["csr"] = base64.data();  // Boring writes a NUL-terminated c-string
 
     Json::StreamWriterBuilder factory;
@@ -441,4 +371,651 @@
     return JsonOutput::Ok(Json::writeString(factory, json));
 }
 
+std::string checkMapEntry(bool isFactory, const cppbor::Map& devInfo, cppbor::MajorType majorType,
+                          const std::string& entryName) {
+    const std::unique_ptr<cppbor::Item>& val = devInfo.get(entryName);
+    if (!val) {
+        return entryName + " is missing.\n";
+    }
+    if (val->type() != majorType) {
+        return entryName + " has the wrong type.\n";
+    }
+    if (isFactory) {
+        return "";
+    }
+    switch (majorType) {
+        case cppbor::TSTR:
+            if (val->asTstr()->value().size() <= 0) {
+                return entryName + " is present but the value is empty.\n";
+            }
+            break;
+        case cppbor::BSTR:
+            if (val->asBstr()->value().size() <= 0) {
+                return entryName + " is present but the value is empty.\n";
+            }
+            break;
+        default:
+            break;
+    }
+    return "";
+}
+
+std::string checkMapEntry(bool isFactory, const cppbor::Map& devInfo, cppbor::MajorType majorType,
+                          const std::string& entryName, const cppbor::Array& allowList) {
+    std::string error = checkMapEntry(isFactory, devInfo, majorType, entryName);
+    if (!error.empty()) {
+        return error;
+    }
+
+    if (isFactory) {
+        return "";
+    }
+
+    const std::unique_ptr<cppbor::Item>& val = devInfo.get(entryName);
+    for (auto i = allowList.begin(); i != allowList.end(); ++i) {
+        if (**i == *val) {
+            return "";
+        }
+    }
+    return entryName + " has an invalid value.\n";
+}
+
+bool isTeeDeviceInfo(const cppbor::Map& devInfo) {
+    return devInfo.get("security_level") && devInfo.get("security_level")->asTstr() &&
+           devInfo.get("security_level")->asTstr()->value() == "tee";
+}
+
+ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo(
+        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable,
+        bool isFactory) {
+    const cppbor::Array kValidVbStates = {"green", "yellow", "orange"};
+    const cppbor::Array kValidBootloaderStates = {"locked", "unlocked"};
+    const cppbor::Array kValidSecurityLevels = {"tee", "strongbox"};
+    const cppbor::Array kValidAttIdStates = {"locked", "open"};
+    const cppbor::Array kValidFused = {0, 1};
+    constexpr std::array<std::string_view, kNumTeeDeviceInfoEntries> kDeviceInfoKeys = {
+            "brand",
+            "manufacturer",
+            "product",
+            "model",
+            "device",
+            "vb_state",
+            "bootloader_state",
+            "vbmeta_digest",
+            "os_version",
+            "system_patch_level",
+            "boot_patch_level",
+            "vendor_patch_level",
+            "security_level",
+            "fused"};
+
+    struct AttestationIdEntry {
+        const char* id;
+        bool alwaysValidate;
+    };
+    constexpr AttestationIdEntry kAttestationIdEntrySet[] = {{"brand", false},
+                                                             {"manufacturer", true},
+                                                             {"product", false},
+                                                             {"model", false},
+                                                             {"device", false}};
+
+    auto [parsedVerifiedDeviceInfo, ignore1, errMsg] = cppbor::parse(deviceInfoBytes);
+    if (!parsedVerifiedDeviceInfo) {
+        return errMsg;
+    }
+
+    std::unique_ptr<cppbor::Map> parsed(parsedVerifiedDeviceInfo.release()->asMap());
+    if (!parsed) {
+        return "DeviceInfo must be a CBOR map.";
+    }
+
+    if (parsed->clone()->asMap()->canonicalize().encode() != deviceInfoBytes) {
+        return "DeviceInfo ordering is non-canonical.";
+    }
+
+    RpcHardwareInfo info;
+    provisionable->getHardwareInfo(&info);
+    if (info.versionNumber < 3) {
+        const std::unique_ptr<cppbor::Item>& version = parsed->get("version");
+        if (!version) {
+            return "Device info is missing version";
+        }
+        if (!version->asUint()) {
+            return "version must be an unsigned integer";
+        }
+        if (version->asUint()->value() != info.versionNumber) {
+            return "DeviceInfo version (" + std::to_string(version->asUint()->value()) +
+                   ") does not match the remotely provisioned component version (" +
+                   std::to_string(info.versionNumber) + ").";
+        }
+    }
+
+    std::string error;
+    std::string tmp;
+    std::set<std::string_view> previousKeys;
+    switch (info.versionNumber) {
+        case 3:
+            if (isTeeDeviceInfo(*parsed) && parsed->size() != kNumTeeDeviceInfoEntries) {
+                error += fmt::format(
+                        "Err: Incorrect number of device info entries. Expected {} but got "
+                        "{}\n",
+                        kNumTeeDeviceInfoEntries, parsed->size());
+            }
+            // TEE IRPC instances require all entries to be present in DeviceInfo. Non-TEE instances
+            // may omit `os_version`
+            if (!isTeeDeviceInfo(*parsed) && (parsed->size() != kNumTeeDeviceInfoEntries &&
+                                              parsed->size() != kNumTeeDeviceInfoEntries - 1)) {
+                error += fmt::format(
+                        "Err: Incorrect number of device info entries. Expected {} or {} but got "
+                        "{}\n",
+                        kNumTeeDeviceInfoEntries - 1, kNumTeeDeviceInfoEntries, parsed->size());
+            }
+            for (auto& [key, _] : *parsed) {
+                const std::string& keyValue = key->asTstr()->value();
+                if (!previousKeys.insert(keyValue).second) {
+                    error += "Err: Duplicate device info entry: <" + keyValue + ">,\n";
+                }
+                if (std::find(kDeviceInfoKeys.begin(), kDeviceInfoKeys.end(), keyValue) ==
+                    kDeviceInfoKeys.end()) {
+                    error += "Err: Unrecognized key entry: <" + key->asTstr()->value() + ">,\n";
+                }
+            }
+            FALLTHROUGH_INTENDED;
+        case 2:
+            for (const auto& entry : kAttestationIdEntrySet) {
+                tmp = checkMapEntry(isFactory && !entry.alwaysValidate, *parsed, cppbor::TSTR,
+                                    entry.id);
+            }
+            if (!tmp.empty()) {
+                error += tmp +
+                         "Attestation IDs are missing or malprovisioned. If this test is being\n"
+                         "run against an early proto or EVT build, this error is probably WAI\n"
+                         "and indicates that Device IDs were not provisioned in the factory. If\n"
+                         "this error is returned on a DVT or later build revision, then\n"
+                         "something is likely wrong with the factory provisioning process.";
+            }
+            // TODO: Refactor the KeyMint code that validates these fields and include it here.
+            error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "vb_state", kValidVbStates);
+            error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "bootloader_state",
+                                   kValidBootloaderStates);
+            error += checkMapEntry(isFactory, *parsed, cppbor::BSTR, "vbmeta_digest");
+            error += checkMapEntry(isFactory, *parsed, cppbor::UINT, "system_patch_level");
+            error += checkMapEntry(isFactory, *parsed, cppbor::UINT, "boot_patch_level");
+            error += checkMapEntry(isFactory, *parsed, cppbor::UINT, "vendor_patch_level");
+            error += checkMapEntry(isFactory, *parsed, cppbor::UINT, "fused", kValidFused);
+            error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "security_level",
+                                   kValidSecurityLevels);
+            if (isTeeDeviceInfo(*parsed)) {
+                error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "os_version");
+            }
+            break;
+        case 1:
+            error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "security_level",
+                                   kValidSecurityLevels);
+            error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "att_id_state",
+                                   kValidAttIdStates);
+            break;
+        default:
+            return "Unrecognized version: " + std::to_string(info.versionNumber);
+    }
+
+    if (!error.empty()) {
+        return error;
+    }
+
+    return std::move(parsed);
+}
+
+ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo(
+        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) {
+    return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/true);
+}
+
+ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo(
+        const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) {
+    return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/false);
+}
+
+ErrMsgOr<bytevec> getSessionKey(ErrMsgOr<std::pair<bytevec, bytevec>>& senderPubkey,
+                                const EekChain& eekChain, int32_t supportedEekCurve) {
+    if (supportedEekCurve == RpcHardwareInfo::CURVE_25519 ||
+        supportedEekCurve == RpcHardwareInfo::CURVE_NONE) {
+        return x25519_HKDF_DeriveKey(eekChain.last_pubkey, eekChain.last_privkey,
+                                     senderPubkey->first, false /* senderIsA */);
+    } else {
+        return ECDH_HKDF_DeriveKey(eekChain.last_pubkey, eekChain.last_privkey, senderPubkey->first,
+                                   false /* senderIsA */);
+    }
+}
+
+ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData(
+        const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
+        const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
+        IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge,
+        bool isFactory) {
+    auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData);
+    if (!parsedProtectedData) {
+        return protDataErrMsg;
+    }
+    if (!parsedProtectedData->asArray()) {
+        return "Protected data is not a CBOR array.";
+    }
+    if (parsedProtectedData->asArray()->size() != kCoseEncryptEntryCount) {
+        return "The protected data COSE_encrypt structure must have " +
+               std::to_string(kCoseEncryptEntryCount) + " entries, but it only has " +
+               std::to_string(parsedProtectedData->asArray()->size());
+    }
+
+    auto senderPubkey = getSenderPubKeyFromCoseEncrypt(parsedProtectedData);
+    if (!senderPubkey) {
+        return senderPubkey.message();
+    }
+    if (senderPubkey->second != eekId) {
+        return "The COSE_encrypt recipient does not match the expected EEK identifier";
+    }
+
+    auto sessionKey = getSessionKey(senderPubkey, eekChain, supportedEekCurve);
+    if (!sessionKey) {
+        return sessionKey.message();
+    }
+
+    auto protectedDataPayload =
+            decryptCoseEncrypt(*sessionKey, parsedProtectedData.get(), bytevec{} /* aad */);
+    if (!protectedDataPayload) {
+        return protectedDataPayload.message();
+    }
+
+    auto [parsedPayload, __, payloadErrMsg] = cppbor::parse(*protectedDataPayload);
+    if (!parsedPayload) {
+        return "Failed to parse payload: " + payloadErrMsg;
+    }
+    if (!parsedPayload->asArray()) {
+        return "The protected data payload must be an Array.";
+    }
+    if (parsedPayload->asArray()->size() != 3U && parsedPayload->asArray()->size() != 2U) {
+        return "The protected data payload must contain SignedMAC and BCC. It may optionally "
+               "contain AdditionalDKSignatures. However, the parsed payload has " +
+               std::to_string(parsedPayload->asArray()->size()) + " entries.";
+    }
+
+    auto& signedMac = parsedPayload->asArray()->get(0);
+    auto& bcc = parsedPayload->asArray()->get(1);
+    if (!signedMac->asArray()) {
+        return "The SignedMAC in the protected data payload is not an Array.";
+    }
+    if (!bcc->asArray()) {
+        return "The BCC in the protected data payload is not an Array.";
+    }
+
+    // BCC is [ pubkey, + BccEntry]
+    auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13);
+    if (!bccContents) {
+        return bccContents.message() + "\n" + prettyPrint(bcc.get());
+    }
+
+    auto deviceInfoResult =
+            parseAndValidateDeviceInfo(deviceInfo.deviceInfo, provisionable, isFactory);
+    if (!deviceInfoResult) {
+        return deviceInfoResult.message();
+    }
+    std::unique_ptr<cppbor::Map> deviceInfoMap = deviceInfoResult.moveValue();
+    auto& signingKey = bccContents->back().pubKey;
+    auto macKey = verifyAndParseCoseSign1(signedMac->asArray(), signingKey,
+                                          cppbor::Array()  // SignedMacAad
+                                                  .add(challenge)
+                                                  .add(std::move(deviceInfoMap))
+                                                  .add(keysToSignMac)
+                                                  .encode());
+    if (!macKey) {
+        return macKey.message();
+    }
+
+    auto coseMac0 = cppbor::Array()
+                            .add(cppbor::Map()  // protected
+                                         .add(ALGORITHM, HMAC_256)
+                                         .canonicalize()
+                                         .encode())
+                            .add(cppbor::Map())        // unprotected
+                            .add(keysToSign.encode())  // payload (keysToSign)
+                            .add(keysToSignMac);       // tag
+
+    auto macPayload = verifyAndParseCoseMac0(&coseMac0, *macKey);
+    if (!macPayload) {
+        return macPayload.message();
+    }
+
+    return *bccContents;
+}
+
+ErrMsgOr<std::vector<BccEntryData>> verifyFactoryProtectedData(
+        const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
+        const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
+        IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
+    return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain,
+                               eekId, supportedEekCurve, provisionable, challenge,
+                               /*isFactory=*/true);
+}
+
+ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData(
+        const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
+        const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
+        const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
+        IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
+    return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain,
+                               eekId, supportedEekCurve, provisionable, challenge,
+                               /*isFactory=*/false);
+}
+
+ErrMsgOr<X509_Ptr> parseX509Cert(const std::vector<uint8_t>& cert) {
+    CRYPTO_BUFFER_Ptr certBuf(CRYPTO_BUFFER_new(cert.data(), cert.size(), nullptr));
+    if (!certBuf.get()) {
+        return "Failed to create crypto buffer.";
+    }
+    X509_Ptr result(X509_parse_from_buffer(certBuf.get()));
+    if (!result.get()) {
+        return "Failed to parse certificate.";
+    }
+    return result;
+}
+
+std::string getX509IssuerName(const X509_Ptr& cert) {
+    char* name = X509_NAME_oneline(X509_get_issuer_name(cert.get()), nullptr, 0);
+    std::string result(name);
+    OPENSSL_free(name);
+    return result;
+}
+
+std::string getX509SubjectName(const X509_Ptr& cert) {
+    char* name = X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0);
+    std::string result(name);
+    OPENSSL_free(name);
+    return result;
+}
+
+// Validates the certificate chain and returns the leaf public key.
+ErrMsgOr<bytevec> validateCertChain(const cppbor::Array& chain) {
+    bytevec rawPubKey;
+    for (size_t i = 0; i < chain.size(); ++i) {
+        // Root must be self-signed.
+        size_t signingCertIndex = (i > 0) ? i - 1 : i;
+        auto& keyCertItem = chain[i];
+        auto& signingCertItem = chain[signingCertIndex];
+        if (!keyCertItem || !keyCertItem->asBstr()) {
+            return "Key certificate must be a Bstr.";
+        }
+        if (!signingCertItem || !signingCertItem->asBstr()) {
+            return "Signing certificate must be a Bstr.";
+        }
+
+        auto keyCert = parseX509Cert(keyCertItem->asBstr()->value());
+        if (!keyCert) {
+            return keyCert.message();
+        }
+        auto signingCert = parseX509Cert(signingCertItem->asBstr()->value());
+        if (!signingCert) {
+            return signingCert.message();
+        }
+
+        EVP_PKEY_Ptr pubKey(X509_get_pubkey(keyCert->get()));
+        if (!pubKey.get()) {
+            return "Failed to get public key.";
+        }
+        EVP_PKEY_Ptr signingPubKey(X509_get_pubkey(signingCert->get()));
+        if (!signingPubKey.get()) {
+            return "Failed to get signing public key.";
+        }
+
+        if (!X509_verify(keyCert->get(), signingPubKey.get())) {
+            return "Verification of certificate " + std::to_string(i) +
+                   " faile. OpenSSL error string: " + ERR_error_string(ERR_get_error(), NULL);
+        }
+
+        auto certIssuer = getX509IssuerName(*keyCert);
+        auto signerSubj = getX509SubjectName(*signingCert);
+        if (certIssuer != signerSubj) {
+            return "Certificate " + std::to_string(i) + " has wrong issuer. Signer subject is " +
+                   signerSubj + " Issuer subject is " + certIssuer;
+        }
+        if (i == chain.size() - 1) {
+            auto key = getRawPublicKey(pubKey);
+            if (!key) key.moveMessage();
+            rawPubKey = key.moveValue();
+        }
+    }
+    return rawPubKey;
+}
+
+std::string validateUdsCerts(const cppbor::Map& udsCerts, const bytevec& udsCoseKeyBytes) {
+    for (const auto& [signerName, udsCertChain] : udsCerts) {
+        if (!signerName || !signerName->asTstr()) {
+            return "Signer Name must be a Tstr.";
+        }
+        if (!udsCertChain || !udsCertChain->asArray()) {
+            return "UDS certificate chain must be an Array.";
+        }
+        if (udsCertChain->asArray()->size() < 2) {
+            return "UDS certificate chain must have at least two entries: root and leaf.";
+        }
+
+        auto leafPubKey = validateCertChain(*udsCertChain->asArray());
+        if (!leafPubKey) {
+            return leafPubKey.message();
+        }
+        auto coseKey = CoseKey::parse(udsCoseKeyBytes);
+        if (!coseKey) return coseKey.moveMessage();
+
+        auto curve = coseKey->getIntValue(CoseKey::CURVE);
+        if (!curve) {
+            return "CoseKey must contain curve.";
+        }
+        bytevec udsPub;
+        if (curve == CoseKeyCurve::P256 || curve == CoseKeyCurve::P384) {
+            auto pubKey = coseKey->getEcPublicKey();
+            if (!pubKey) return pubKey.moveMessage();
+            // convert public key to uncompressed form by prepending 0x04 at begin.
+            pubKey->insert(pubKey->begin(), 0x04);
+            udsPub = pubKey.moveValue();
+        } else if (curve == CoseKeyCurve::ED25519) {
+            auto& pubkey = coseKey->getMap().get(cppcose::CoseKey::PUBKEY_X);
+            if (!pubkey || !pubkey->asBstr()) {
+                return "Invalid public key.";
+            }
+            udsPub = pubkey->asBstr()->value();
+        } else {
+            return "Unknown curve.";
+        }
+        if (*leafPubKey != udsPub) {
+            return "Leaf public key in UDS certificate chain doesn't match UDS public key.";
+        }
+    }
+    return "";
+}
+
+ErrMsgOr<std::unique_ptr<cppbor::Array>> parseAndValidateCsrPayload(
+        const cppbor::Array& keysToSign, const std::vector<uint8_t>& csrPayload,
+        IRemotelyProvisionedComponent* provisionable, bool isFactory) {
+    auto [parsedCsrPayload, _, errMsg] = cppbor::parse(csrPayload);
+    if (!parsedCsrPayload) {
+        return errMsg;
+    }
+
+    std::unique_ptr<cppbor::Array> parsed(parsedCsrPayload.release()->asArray());
+    if (!parsed) {
+        return "CSR payload is not a CBOR array.";
+    }
+
+    if (parsed->size() != 4U) {
+        return "CSR payload must contain version, certificate type, device info, keys. "
+               "However, the parsed CSR payload has " +
+               std::to_string(parsed->size()) + " entries.";
+    }
+
+    auto signedVersion = parsed->get(0)->asUint();
+    auto signedCertificateType = parsed->get(1)->asTstr();
+    auto signedDeviceInfo = parsed->get(2)->asMap();
+    auto signedKeys = parsed->get(3)->asArray();
+
+    if (!signedVersion || signedVersion->value() != 3U) {
+        return "CSR payload version must be an unsigned integer and must be equal to 3.";
+    }
+    if (!signedCertificateType) {
+        // Certificate type is allowed to be extendend by vendor, i.e. we can't
+        // enforce its value.
+        return "Certificate type must be a Tstr.";
+    }
+    if (!signedDeviceInfo) {
+        return "Device info must be an Map.";
+    }
+    if (!signedKeys) {
+        return "Keys must be an Array.";
+    }
+
+    auto result = parseAndValidateDeviceInfo(signedDeviceInfo->encode(), provisionable, isFactory);
+    if (!result) {
+        return result.message();
+    }
+
+    if (signedKeys->encode() != keysToSign.encode()) {
+        return "Signed keys do not match.";
+    }
+
+    return std::move(parsed);
+}
+
+ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequestSignedPayload(
+        const std::vector<uint8_t>& signedPayload, const std::vector<uint8_t>& challenge) {
+    auto [parsedSignedPayload, _, errMsg] = cppbor::parse(signedPayload);
+    if (!parsedSignedPayload) {
+        return errMsg;
+    }
+    if (!parsedSignedPayload->asArray()) {
+        return "SignedData payload is not a CBOR array.";
+    }
+    if (parsedSignedPayload->asArray()->size() != 2U) {
+        return "SignedData payload must contain the challenge and request. However, the parsed "
+               "SignedData payload has " +
+               std::to_string(parsedSignedPayload->asArray()->size()) + " entries.";
+    }
+
+    auto signedChallenge = parsedSignedPayload->asArray()->get(0)->asBstr();
+    auto signedRequest = parsedSignedPayload->asArray()->get(1)->asBstr();
+
+    if (!signedChallenge) {
+        return "Challenge must be a Bstr.";
+    }
+
+    if (challenge.size() > 64) {
+        return "Challenge size must be between 0 and 64 bytes inclusive. "
+               "However, challenge is " +
+               std::to_string(challenge.size()) + " bytes long.";
+    }
+
+    auto challengeBstr = cppbor::Bstr(challenge);
+    if (*signedChallenge != challengeBstr) {
+        return "Signed challenge does not match."
+               "\n  Actual: " +
+               cppbor::prettyPrint(signedChallenge->asBstr(), 64 /* maxBStrSize */) +
+               "\nExpected: " + cppbor::prettyPrint(&challengeBstr, 64 /* maxBStrSize */);
+    }
+
+    if (!signedRequest) {
+        return "Request must be a Bstr.";
+    }
+
+    return signedRequest->value();
+}
+
+ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t>& request,
+                                                       const std::vector<uint8_t>& challenge) {
+    auto [parsedRequest, _, csrErrMsg] = cppbor::parse(request);
+    if (!parsedRequest) {
+        return csrErrMsg;
+    }
+    if (!parsedRequest->asArray()) {
+        return "AuthenticatedRequest is not a CBOR array.";
+    }
+    if (parsedRequest->asArray()->size() != 4U) {
+        return "AuthenticatedRequest must contain version, UDS certificates, DICE chain, and "
+               "signed data. However, the parsed AuthenticatedRequest has " +
+               std::to_string(parsedRequest->asArray()->size()) + " entries.";
+    }
+
+    auto version = parsedRequest->asArray()->get(0)->asUint();
+    auto udsCerts = parsedRequest->asArray()->get(1)->asMap();
+    auto diceCertChain = parsedRequest->asArray()->get(2)->asArray();
+    auto signedData = parsedRequest->asArray()->get(3)->asArray();
+
+    if (!version || version->value() != 1U) {
+        return "AuthenticatedRequest version must be an unsigned integer and must be equal to 1.";
+    }
+    if (!udsCerts) {
+        return "AuthenticatedRequest UdsCerts must be an Map.";
+    }
+    if (!diceCertChain) {
+        return "AuthenticatedRequest DiceCertChain must be an Array.";
+    }
+    if (!signedData) {
+        return "AuthenticatedRequest SignedData must be an Array.";
+    }
+
+    // DICE chain is [ pubkey, + DiceChainEntry ].
+    auto diceContents = validateBcc(diceCertChain, hwtrust::DiceChain::Kind::kVsr14);
+    if (!diceContents) {
+        return diceContents.message() + "\n" + prettyPrint(diceCertChain);
+    }
+
+    auto& udsPub = diceContents->back().pubKey;
+
+    auto error = validateUdsCerts(*udsCerts, udsPub);
+    if (!error.empty()) {
+        return error;
+    }
+
+    auto signedPayload = verifyAndParseCoseSign1(signedData, udsPub, {} /* aad */);
+    if (!signedPayload) {
+        return signedPayload.message();
+    }
+
+    auto payload = parseAndValidateAuthenticatedRequestSignedPayload(*signedPayload, challenge);
+    if (!payload) {
+        return payload.message();
+    }
+
+    return payload;
+}
+
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr(const cppbor::Array& keysToSign,
+                                                   const std::vector<uint8_t>& csr,
+                                                   IRemotelyProvisionedComponent* provisionable,
+                                                   const std::vector<uint8_t>& challenge,
+                                                   bool isFactory) {
+    RpcHardwareInfo info;
+    provisionable->getHardwareInfo(&info);
+    if (info.versionNumber != 3) {
+        return "Remotely provisioned component version (" + std::to_string(info.versionNumber) +
+               ") does not match expected version (3).";
+    }
+
+    auto csrPayload = parseAndValidateAuthenticatedRequest(csr, challenge);
+    if (!csrPayload) {
+        return csrPayload.message();
+    }
+
+    return parseAndValidateCsrPayload(keysToSign, *csrPayload, provisionable, isFactory);
+}
+
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(
+        const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
+        IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
+    return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/true);
+}
+
+ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
+        const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
+        IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
+    return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false);
+}
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp
index 0250cd6..eaaba45 100644
--- a/security/keymint/support/remote_prov_utils_test.cpp
+++ b/security/keymint/support/remote_prov_utils_test.cpp
@@ -191,7 +191,8 @@
 
     std::string expected = R"({"build_fingerprint":")" +
                            ::android::base::GetProperty("ro.build.fingerprint", /*default=*/"") +
-                           R"(","csr":"gQE=","name":"test"})";
+                           R"(","csr":"gQE=","name":"test","serialno":")" +
+                           ::android::base::GetProperty("ro.serialno", /*default=*/"") + R"("})";
 
     ASSERT_EQ(json, expected);
 }
diff --git a/security/rkp/CHANGELOG.md b/security/rkp/CHANGELOG.md
new file mode 100644
index 0000000..6593ab2
--- /dev/null
+++ b/security/rkp/CHANGELOG.md
@@ -0,0 +1,48 @@
+# Remote Provisioning Changelog
+
+This document provides an exact description of which changes have occurred in the
+`IRemotelyProvisionedComponent` HAL interface in each Android release.
+
+## Releases
+* **Android S (12):** IRemotelyProvisionedComponent v1
+* **Android T (13):** IRemotelyProvisionedComponent v2
+* **Android U (14):** IRemotelyProvisionedComponent v3
+
+## IRemotelyProvisionedComponent 1 -> 2
+* DeviceInfo
+  * Most entries are no longer optional.
+  * `att_id_state` is now `fused`. `fused` is used to indicate if SecureBoot is enabled.
+  * `version` is now `2`.
+  * `board` has been removed.
+  * `device` has been added.
+* RpcHardwareInfo
+  * `uniqueId` String added as a field in order to differentiate IRPC instances on device.
+
+## IRemotelyProvisionedComponent 2 -> 3
+* The RKP HAL now builds separately from KeyMint.
+  * The HAL remains under the `android.hardware.security.keymint` package for
+    compatibility with previous releases. ABI compatibility requires this.
+  * Dependencies on the RKP HAL must add a dependency on
+    `"android.hardware.security.rkp"` generated code (instead of
+    `"android.hardward.security.keymint"`).
+* ProtectedData has been removed.
+* DeviceInfo
+  * `version` has moved to a top-level field within the CSR generated by the HAL.
+* IRemotelyProvisionedComponent
+  * The need for an EEK has been removed. There is no longer an encrypted portion of the CSR.
+  * Keys for new CSR format must be generated with test mode set to false, effectively removing test
+    mode in the new CSR flow.
+  * The schema for the CSR itself has been significantly simplified, please see
+    IRemotelyProvisionedComponent.aidl for more details. Notably,
+    * the chain of signing, MACing, and encryption operations has been replaced with a single
+      COSE_Sign1 object.
+    * CertificateType has been added to identify the type of certificate being requested.
+    * The structure has been composed to enable a clear split between what is required to validate a
+      payload and the implementation-defined payload itself. This is done by creating a typed
+      `AuthenticatedRequest<T>` object representing the top level data required to authenticate
+      the data provided in the payload, `T`.
+  * The new CSR format supports P-384 signing keys and SHA-384 hashes in the DICE chain.
+  * The component version can now be either an int or a string.
+* RpcHardwareInfo
+  * `supportedNumKeysInCsr` added to report the maximum number of keys supported in a CSR.
+  * `supportedEekCurve` is no longer used, due to the removal of the EEK from the scheme.
diff --git a/security/rkp/OWNERS b/security/rkp/OWNERS
new file mode 100644
index 0000000..d25977f
--- /dev/null
+++ b/security/rkp/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 1084908
+
+jbires@google.com
+sethmo@google.com
+trong@google.com
diff --git a/security/rkp/README.md b/security/rkp/README.md
new file mode 100644
index 0000000..5a93734
--- /dev/null
+++ b/security/rkp/README.md
@@ -0,0 +1,394 @@
+# Remote Provisioning HAL
+
+## Objective
+
+Design a HAL to support over-the-air provisioning of certificates for asymmetric
+keys. The HAL must interact effectively with Keystore (and other daemons) and
+protect device privacy and security.
+
+Note that this API was originally designed for KeyMint, with the intention that
+it should be usable for other HALs that require certificate provisioning.
+Throughout this document we'll refer to the Keystore and KeyMint (formerly
+called Keymaster) components, but only for concreteness and convenience; those
+labels could be replaced with the names of any system and secure area
+components, respectively, that need certificates provisioned.
+
+## Key design decisions
+
+### General approach
+
+To more securely and reliably get keys and certificates to Android devices, we
+need to create a system where no party outside of the device's secure components
+is responsible for managing private keys. The strategy we've chosen is to
+deliver certificates over the air, using an asymmetric key pair created
+on-device in the factory as a root of trust to create an authenticated, secure
+channel. In this document we refer to this device-unique asymmetric key pair as
+Device Key (DK), its public half DK\_pub, its private half DK\_priv and a Device
+Key Certificate containing DK\_pub is denoted DKC.
+
+In order for the provisioning service to use DK (or a key authenticated by DK),
+it must know whether a given DK\_pub is known and trusted. To prove trust, we
+ask device OEMs to use one of two mechanisms:
+
+1.  (Preferred, recommended) The device OEM extracts DK\_pub from each device it
+    manufactures and uploads the public keys to a backend server.
+
+1.  The device OEM signs the DK\_pub to produce DKC and stores it on the device.
+    This has the advantage that they don't need to upload a DK\_pub for every
+    device immediately, but the disadvantage that they have to manage their
+    private signing keys, which means they have to have HSMs, configure and
+    secure them correctly, etc. Some backend providers may also require that the
+    OEM passes a factory security audit, and additionally promises to upload the
+    keys eventually as well.
+
+Note that in the full elaboration of this plan, DK\_pub is not the key used to
+establish a secure channel. Instead, DK\_pub is just the first public key in a
+chain of public keys which ends with the KeyMint public key, KM\_pub. All keys
+in the chain are device-unique and are joined in a certificate chain called the
+_Boot Certificate Chain_ (BCC), because in phases 2 and 3 of the remote
+provisioning project it is a chain of certificates corresponding to boot phases.
+We speak of the BCC even for phase 1, though in phase 1 it contains only a
+single self-signed DKC. This is described in more depth in the Phases section
+below.
+
+The BCC is authenticated by DK\_pub. To authenticate DK\_pub, we may have
+additional DKCs, from the SoC vendor, the device OEM, or both. Those are not
+part of the BCC but included as optional fields in the certificate request
+structure.
+
+The format of the the DK and BCC is specified within [Open Profile for DICE]
+(https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md).  To
+map phrases within this document to their equivalent terminology in the DICE
+specification, read the terms as follows: the DK corresponds to the UDS-derived
+key pair, DKC corresponds to the UDS certificate, and the BCC entries between
+DK\_pub and KM\_pub correspond to a chain of CDI certificates.
+
+Note: In addition to allowing 32 byte hash values for fields in the BCC payload,
+this spec additionally constrains some of the choices allowed in open-DICE.
+Specifically, these include which entries are required and which are optional in
+the BCC payload, and which algorithms are acceptable for use.
+
+### Phases
+
+RKP will be deployed in three phases, in terms of managing the root of trust
+binding between the device and the backend. To briefly describe them:
+
+* Phase 1: In phase 1 there is only one entry in the BCC; DK_pub and KM_pub are
+  the same key and the certificate is self-signed.
+* Phase 2: This is identical to phase 1, except it leverages the hardware root
+  of trust process described by DICE. Instead of trust being rooted in the TEE,
+  it is now rooted in the ROM by key material blown into fuses which are only
+  accessible to the ROM code.
+* Phase 3: This is identical to Phase 2, except the SoC vendor also does the
+  public key extraction or certification in their facilities, along with the OEM
+  doing it in the factory. This tightens up the "supply chain" and aims to make
+  key upload management more secure.
+
+### Privacy considerations
+
+Because DK and the DKCs are unique, immutable, unspoofable hardware-bound
+identifiers for the device, we must limit access to them to the absolute minimum
+possible. We do this in two ways:
+
+1.  We require KeyMint (which knows the BCC and either knows or at least has the
+ability to use KM\_priv) to refuse to ever divulge the BCC or additional
+signatures in plaintext. Instead, KeyMint requires the caller to provide an
+_Endpoint Encryption Key_ (EEK), with which it will encrypt the data before
+returning it. When provisioning production keys, the EEK must be signed by an
+approved authority whose public key is embedded in KeyMint. When certifying test
+keys, KeyMint will accept any EEK without checking the signature, but will
+encrypt and return a test BCC, rather than the real one.  The result is that
+only an entity in possession of an Trusted EEK (TEEK) private key can discover
+the plaintext of the production BCC.
+1.  Having thus limited access to the public keys to the trusted party only, we
+need to prevent the entity from abusing this unique device identifier.  The
+approach and mechanisms for doing that are beyond the scope of this document
+(they must be addressed in the server design), but generally involve taking care
+to ensure that we do not create any links between user IDs, IP addresses or
+issued certificates and the device pubkey.
+
+Although the details of the mechanisms for preventing the entity from abusing
+the BCC are, as stated, beyond the scope of this document, there is a subtle
+design decision here made specifically to enable abuse prevention. Specifically
+the `CertificateRequest` message sent to the server is (in
+[CDDL](https://tools.ietf.org/html/rfc8610)):
+
+```
+cddl
+CertificateRequest = [
+    DeviceInfo,
+    challenge : bstr,
+    ProtectedData,
+    MacedKeysToSign
+]
+```
+
+The public keys to be attested by the server are in `MacedKeysToSign`, which is
+a COSE\_Mac0 structure, MACed with a key that is found in `ProtectedData`. The
+MAC key is signed by DK\_pub.
+
+This structure allows the backend component that has access to EEK\_priv to
+decrypt `ProtectedData`, validate that the request is from an authorized device,
+check that the request is fresh and verify and extract the MAC key. That backend
+component never sees any data related to the keys to be signed, but can provide
+the MAC key to another backend component that can verify `MacedKeysToSign` and
+proceed to generate the certificates.
+
+In this way, we can partition the provisioning server into one component that
+knows the device identity, as represented by DK\_pub, but never sees the keys to
+be certified or certificates generated, and another component that sees the keys
+to be certified and certificates generated but does not know the device
+identity.
+
+### Key and cryptographic message formatting
+
+For simplicity of generation and parsing, compactness of wire representation,
+and flexibility and standardization, we've settled on using the CBOR Object
+Signing and Encryption (COSE) standard, defined in [RFC
+8152](https://tools.ietf.org/html/rfc8152). COSE provides compact and reasonably
+simple, yet easily-extensible, wire formats for:
+
+*   Keys,
+*   MACed messages,
+*   Signed messages, and
+*   Encrypted messages
+
+COSE enables easy layering of these message formats, such as using a COSE\_Sign
+structure to contain a COSE\_Key with a public key in it. We call this a
+"certificate".
+
+Due to the complexity of the standard, we'll spell out the COSE structures
+completely in this document and in the HAL and other documentation, so that
+although implementors will need to understand CBOR and the CBOR Data Definition
+Language ([CDDL, defined in RFC 8610](https://tools.ietf.org/html/rfc8610)),
+they shouldn't need to understand COSE.
+
+Note, however, that the certificate chains returned from the provisioning server
+are standard X.509 certificates.
+
+### Algorithm choices
+
+This document uses:
+
+*   ECDSA P-256 for attestation signing keys;
+*   Remote provisioning protocol signing keys:
+  *  Ed25519 / P-256 / P-384
+*   ECDH keys:
+  *  X25519 / P-256
+*   AES-GCM for all encryption;
+*   SHA-256 / SHA-384 / SHA-512 for message digesting;
+*   HMAC with a supported message digest for all MACing; and
+*   HKDF with a supported message digest for all key derivation.
+
+We believe that Curve25519 offers the best tradeoff in terms of security,
+efficiency and global trustworthiness, and that it is now sufficiently
+widely-used and widely-implemented to make it a practical choice.
+
+However, since hardware such as Secure Elements (SE) do not currently offer
+support for curve 25519, we are allowing implementations to instead make use of
+ECDSA and ECDH.
+
+The CDDL in the rest of the document will use the '/' operator to show areas
+where either curve 25519, P-256 or P-384 may be used. Since there is no easy way
+to bind choices across different CDDL groups, it is important that the
+implementor stays consistent in which type is chosen. E.g. taking ES256 as the
+choice for algorithm implies the implementor should also choose the P256 public
+key group further down in the COSE structure.
+
+### Testability
+
+It's critical that the remote provisioning implementation be testable, to
+minimize the probability that broken devices are sold to end users. To support
+testing, the remote provisioning HAL methods take a `testMode` argument. Keys
+created in test mode are tagged to indicate this. The provisioning server will
+check for the test mode tag and issue test certificates that do not chain back
+to a trusted public key. In test mode, any EEK will be accepted, enabling
+testing tools to use EEKs for which they have the private key so they can
+validate the content of certificate requests. The BCC included in the
+`CertificateRequest` must contain freshly-generated keys, not the real BCC keys.
+
+Keystore (or similar) will need to be able to handle both testMode keys and
+production keys and keep them distinct, generating test certificate requests
+when asked with a test EEK and production certificate requests when asked with a
+production EEK. Likewise, the interface used to instruct Keystore to create keys
+will need to be able to specify whether test or production keys are desired.
+
+## Design
+
+### Certificate provisioning flow
+
+TODO(jbires): Replace this with a `.png` containing a sequence diagram.  The
+provisioning flow looks something like this:
+
+Provisioner -> Keystore: Prepare N keys
+Keystore -> KeyMint: generateKeyPair
+KeyMint -> KeyMint: Generate  key pair
+KeyMint --> Keystore: key\_blob,pubkey
+Keystore -> Keystore: Store key\_blob,pubkey
+Provisioner -> Server: Get TEEK
+Server --> Provisioner: TEEK
+Provisioner -> Keystore: genCertReq(N, TEEK)
+Keystore -> KeyMint: genCertReq(pubkeys, TEEK)
+KeyMint -> KeyMint: Sign pubkeys & encrypt BCC
+KeyMint --> Keystore: signature, encrypted BCC
+Keystore -> Keystore: Construct cert\_request
+Keystore --> Provisioner: cert\_request
+Provisioner --> Server: cert\_request
+Server -> Server: Validate cert\_request
+Server -> Server: Generate certificates
+Server --> Provisioner: certificates
+Provisioner -> Keystore: certificates
+Keystore -> Keystore: Store certificates
+
+The actors in the above diagram are:
+
+*   **Server** is the backend certificate provisioning server. It has access to
+    the uploaded device public keys and is responsible for providing encryption
+    keys, decrypting and validating requests, and generating certificates in
+    response to requests.
+*   **Provisioner** is an application that is responsible for communicating with
+    the server and all of the system components that require key certificates
+    from the server. It also implements the policy that defines how many key
+    pairs each client should keep in their pool.
+*   **Keystore** is the [Android keystore
+    daemon](https://developer.android.com/training/articles/keystore) (or, more
+    generally, whatever system component manages communications with a
+    particular secure aread component).
+*   **KeyMint** is the secure area component that manages cryptographic keys and
+    performs attestations (or perhaps some other secure area component).
+
+### `BCC`
+
+The _Boot Certificate Chain_ (BCC) is the chain of certificates that contains
+DK\_pub as well as other often device-unique certificates. The BCC is
+represented as a COSE\_Key containing DK\_pub followed by an array of
+COSE\_Sign1 "certificates" containing public keys and optional additional
+information, ordered from root to leaf, with each certificate signing the next.
+The first certificate in the array is signed by DK\_pub, the last certificate
+has the KeyMint (or whatever) signing key's public key, KM\_pub. In phase 1
+there is only one entry; DK\_pub and KM\_pub are the same key and the
+certificate is self-signed.
+
+Each COSE\_Sign1 certificate is a CBOR Web Token (CWT) as described in [RFC
+8392](https://tools.ietf.org/html/rfc8392) with additional fields as described
+in the Open Profile for DICE. Of these additional fields, only the
+_subjectPublicKey_ and _keyUsage_ fields are expected to be present for the
+KM\_pub entry (that is, the last entry) in a BCC, but all fields required by the
+Open Profile for DICE are expected for other entries (each of which corresponds
+to a particular firmware component or boot stage). The CWT fields _iss_ and
+_sub_ identify the issuer and subject of the certificate and are consistent
+along the BCC entries; the issuer of a given entry matches the subject of the
+previous entry.
+
+The BCC is designed to be constructed using the Open Profile for DICE. In this
+case the DK key pair is derived from the UDS as described by that profile and
+all BCC entries before the leaf are CBOR CDI certificates chained from DK\_pub.
+The KM key pair is not part of the derived DICE chain. It is generated (not
+derived) by the KeyMint module, certified by the last key in the DICE chain, and
+added as the leaf BCC entry. The key usage field in this leaf certificate must
+indicate the key is not used to sign certificates. If a UDS certificate is
+available on the device it should appear in the certificate request as the leaf
+of a DKCertChain in AdditionalDKSignatures (see
+[CertificateRequest](#certificaterequest)).
+
+#### Mode
+
+The Open Profile for DICE specifies four possible modes with the most important
+mode being `normal`. A certificate must only set the mode to `normal` when all
+of the following conditions are met when loading and verifying the software
+component that is being described by the certificate:
+
+*   verified boot with anti-rollback protection is enabled
+*   only the verified boot authorities for production images are enabled
+*   debug ports, fuses or other debug facilities are disabled
+*   device booted software from the normal primary source e.g. internal flash
+
+If any of these conditions are not met then it is recommended to explicitly
+acknowledge this fact by using the `debug` mode. The mode should never be `not
+configured`.
+
+#### Configuration descriptor
+
+The Open Profile for DICE allows for an arbitrary configuration descriptor. For
+BCC entries, this configuration descriptor is a CBOR map with the following
+optional fields. If no fields are relevant, an empty map should be encoded.
+Additional implementation-specific fields may be added using key values not in
+the range \[-70000, -70999\] (these are reserved for future additions here).
+
+```
+| Name              | Key    | Value type | Meaning                           |
+| ----------------- | ------ | ---------- | ----------------------------------|
+| Component name    | -70002 | tstr       | Name of firmware component / boot |
+:                   :        :            : stage                             :
+| Component version | -70003 | int / tstr | Version of firmware component /   |
+:                   :        :            : boot stage                        :
+| Resettable        | -70004 | null       | If present, key changes on factory|
+:                   :        :            : reset                             :
+| Security version  | -70005 | uint       | Machine-comparable, monotonically |
+:                   :        :            : increasing version of the firmware:
+:                   :        :            : component / boot stage where a    :
+:                   :        :            : greater value indicates a newer   :
+:                   :        :            : version                           :
+```
+
+Please see
+[ProtectedData.aidl](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl)
+for a full CDDL definition of the BCC.
+
+### `CertificateRequest`
+
+The full CBOR message that will be sent to the server to request certificates
+is:
+
+```cddl
+CertificateRequest = [
+    DeviceInfo,
+    challenge : bstr,       // Provided by the server
+    ProtectedData,          // See ProtectedData.aidl
+    MacedKeysToSign         // See IRemotelyProvisionedComponent.aidl
+]
+
+DeviceInfo = [
+    VerifiedDeviceInfo,     // See DeviceInfo.aidl
+    UnverifiedDeviceInfo
+]
+
+// Unverified info is anything provided by the HLOS. Subject to change out of
+// step with the HAL.
+UnverifiedDeviceInfo = {
+    ? "fingerprint" : tstr,
+}
+
+```
+
+It will be the responsibility of Keystore and the Provisioner to construct the
+`CertificateRequest`. The HAL provides a method to generate the elements that
+need to be constructed on the secure side, which are the tag field of
+`MacedKeysToSign`, `VerifiedDeviceInfo`, and the ciphertext field of
+`ProtectedData`.
+
+### HAL
+
+The remote provisioning HAL provides a simple interface that can be implemented
+by multiple secure components that require remote provisioning. It would be
+slightly simpler to extend the KeyMint API, but that approach would only serve
+the needs of KeyMint, this is more general.
+
+NOTE the data structures defined in this HAL may look a little bloated and
+complex. This is because the COSE data structures are fully spelled-out; we
+could make it much more compact by not re-specifying the standardized elements
+and instead just referencing the standard, but it seems better to fully specify
+them. If the apparent complexity seems daunting, consider what the same would
+look like if traditional ASN.1 DER-based structures from X.509 and related
+standards were used and also fully elaborated.
+
+Please see the related HAL documentation directly in the source code at the
+following links:
+
+*   [IRemotelyProvisionedComponent
+    HAL](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl)
+*   [ProtectedData](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl)
+*   [MacedPublicKey](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/MacedPublicKey.aidl)
+*   [RpcHardwareInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl)
+*   [DeviceInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl)
+
diff --git a/security/rkp/TEST_MAPPING b/security/rkp/TEST_MAPPING
new file mode 100644
index 0000000..9ce5e9b
--- /dev/null
+++ b/security/rkp/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalRemotelyProvisionedComponentTargetTest"
+    }
+  ]
+}
diff --git a/security/rkp/aidl/Android.bp b/security/rkp/aidl/Android.bp
new file mode 100644
index 0000000..e2ce649
--- /dev/null
+++ b/security/rkp/aidl/Android.bp
@@ -0,0 +1,47 @@
+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"],
+}
+
+aidl_interface {
+    name: "android.hardware.security.rkp",
+    vendor_available: true,
+    srcs: [
+        // This HAL was originally part of keymint.
+        "android/hardware/security/keymint/*.aidl",
+
+        // in the future
+        // "android/hardware/security/rkp/*.aidl",
+    ],
+    stability: "vintf",
+    backend: {
+        java: {
+            min_sdk_version: "33",
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.rkpd",
+            ],
+        },
+        rust: {
+            enabled: true,
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+        },
+        {
+            version: "2",
+        },
+        {
+            version: "3",
+            imports: [],
+        },
+
+    ],
+    frozen: true,
+}
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash
new file mode 100644
index 0000000..1397c05
--- /dev/null
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash
@@ -0,0 +1,2 @@
+976674616001f714f4a4df49ee45f548de828524
+d285480d2e0002adc0ace80edf34aa725679512e
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/DeviceInfo.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/DeviceInfo.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/DeviceInfo.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/DeviceInfo.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/MacedPublicKey.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/MacedPublicKey.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/MacedPublicKey.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/MacedPublicKey.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ProtectedData.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/ProtectedData.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ProtectedData.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/ProtectedData.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/RpcHardwareInfo.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/RpcHardwareInfo.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/android/hardware/security/keymint/RpcHardwareInfo.aidl
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/.hash b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/.hash
new file mode 100644
index 0000000..4b3b2a6
--- /dev/null
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/.hash
@@ -0,0 +1,2 @@
+207c9f218b9b9e4e74ff5232eb16511eca9d7d2e
+c8d34e56ae0807b61f028019622d8b60a37e0a8b
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/DeviceInfo.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/DeviceInfo.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/DeviceInfo.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/DeviceInfo.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/MacedPublicKey.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/MacedPublicKey.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/MacedPublicKey.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/MacedPublicKey.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/ProtectedData.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/ProtectedData.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/ProtectedData.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/ProtectedData.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/RpcHardwareInfo.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/2/android/hardware/security/keymint/RpcHardwareInfo.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/2/android/hardware/security/keymint/RpcHardwareInfo.aidl
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/.hash b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/.hash
new file mode 100644
index 0000000..85cefd9
--- /dev/null
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/.hash
@@ -0,0 +1 @@
+7d14edbfab5c490efa407ba55fa80614bb48ae8e
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/DeviceInfo.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/DeviceInfo.aidl
similarity index 100%
copy from security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/DeviceInfo.aidl
copy to security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/DeviceInfo.aidl
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
new file mode 100644
index 0000000..626ece8
--- /dev/null
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@VintfStability
+interface IRemotelyProvisionedComponent {
+  android.hardware.security.keymint.RpcHardwareInfo getHardwareInfo();
+  byte[] generateEcdsaP256KeyPair(in boolean testMode, out android.hardware.security.keymint.MacedPublicKey macedPublicKey);
+  byte[] generateCertificateRequest(in boolean testMode, in android.hardware.security.keymint.MacedPublicKey[] keysToSign, in byte[] endpointEncryptionCertChain, in byte[] challenge, out android.hardware.security.keymint.DeviceInfo deviceInfo, out android.hardware.security.keymint.ProtectedData protectedData);
+  byte[] generateCertificateRequestV2(in android.hardware.security.keymint.MacedPublicKey[] keysToSign, in byte[] challenge);
+  const int STATUS_FAILED = 1;
+  const int STATUS_INVALID_MAC = 2;
+  const int STATUS_PRODUCTION_KEY_IN_TEST_REQUEST = 3;
+  const int STATUS_TEST_KEY_IN_PRODUCTION_REQUEST = 4;
+  const int STATUS_INVALID_EEK = 5;
+  const int STATUS_REMOVED = 6;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/MacedPublicKey.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/MacedPublicKey.aidl
similarity index 100%
copy from security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/MacedPublicKey.aidl
copy to security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/MacedPublicKey.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ProtectedData.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/ProtectedData.aidl
similarity index 100%
copy from security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ProtectedData.aidl
copy to security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/ProtectedData.aidl
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/RpcHardwareInfo.aidl
new file mode 100644
index 0000000..147331c
--- /dev/null
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/3/android/hardware/security/keymint/RpcHardwareInfo.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable RpcHardwareInfo {
+  int versionNumber;
+  @utf8InCpp String rpcAuthorName;
+  int supportedEekCurve = CURVE_NONE /* 0 */;
+  @nullable @utf8InCpp String uniqueId;
+  int supportedNumKeysInCsr = 4;
+  const int CURVE_NONE = 0;
+  const int CURVE_P256 = 1;
+  const int CURVE_25519 = 2;
+  const int MIN_SUPPORTED_NUM_KEYS_IN_CSR = 20;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/DeviceInfo.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/DeviceInfo.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/DeviceInfo.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/DeviceInfo.aidl
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
new file mode 100644
index 0000000..626ece8
--- /dev/null
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@VintfStability
+interface IRemotelyProvisionedComponent {
+  android.hardware.security.keymint.RpcHardwareInfo getHardwareInfo();
+  byte[] generateEcdsaP256KeyPair(in boolean testMode, out android.hardware.security.keymint.MacedPublicKey macedPublicKey);
+  byte[] generateCertificateRequest(in boolean testMode, in android.hardware.security.keymint.MacedPublicKey[] keysToSign, in byte[] endpointEncryptionCertChain, in byte[] challenge, out android.hardware.security.keymint.DeviceInfo deviceInfo, out android.hardware.security.keymint.ProtectedData protectedData);
+  byte[] generateCertificateRequestV2(in android.hardware.security.keymint.MacedPublicKey[] keysToSign, in byte[] challenge);
+  const int STATUS_FAILED = 1;
+  const int STATUS_INVALID_MAC = 2;
+  const int STATUS_PRODUCTION_KEY_IN_TEST_REQUEST = 3;
+  const int STATUS_TEST_KEY_IN_PRODUCTION_REQUEST = 4;
+  const int STATUS_INVALID_EEK = 5;
+  const int STATUS_REMOVED = 6;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/MacedPublicKey.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/MacedPublicKey.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/MacedPublicKey.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/MacedPublicKey.aidl
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ProtectedData.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/ProtectedData.aidl
similarity index 100%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ProtectedData.aidl
rename to security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/ProtectedData.aidl
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/RpcHardwareInfo.aidl
new file mode 100644
index 0000000..b1f99e1
--- /dev/null
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/current/android/hardware/security/keymint/RpcHardwareInfo.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.security.keymint;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable RpcHardwareInfo {
+  int versionNumber;
+  @utf8InCpp String rpcAuthorName;
+  int supportedEekCurve = 0;
+  @nullable @utf8InCpp String uniqueId;
+  int supportedNumKeysInCsr = 4;
+  const int CURVE_NONE = 0;
+  const int CURVE_P256 = 1;
+  const int CURVE_25519 = 2;
+  const int MIN_SUPPORTED_NUM_KEYS_IN_CSR = 20;
+}
diff --git a/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl
new file mode 100644
index 0000000..8456148
--- /dev/null
+++ b/security/rkp/aidl/android/hardware/security/keymint/DeviceInfo.aidl
@@ -0,0 +1,110 @@
+/*
+ * 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.security.keymint;
+
+/**
+ * DeviceInfo contains information about the device that's signed by the
+ * IRemotelyProvisionedComponent HAL. These values are intended to be checked by the server to
+ * verify that the certificate signing request crafted by an IRemotelyProvisionedComponent HAL
+ * instance is coming from the expected device based on values initially uploaded during device
+ * manufacture in the factory.
+ * @hide
+ */
+@VintfStability
+parcelable DeviceInfo {
+    /**
+     * DeviceInfo is a CBOR Map structure described by the following CDDL. DeviceInfo must be
+     * canonicalized according to the specification in RFC 7049. The ordering presented here is
+     * non-canonical to group similar entries semantically.
+     *
+     * The DeviceInfo has changed across versions 1, 2, and 3 of the HAL. All versions of the
+     * DeviceInfo CDDL are described as follows. Please refer to the CDDL structure version
+     * that corresponds to the HAL version you are working with:
+     *
+     * Version 3, introduced in Android 14:
+     *     DeviceInfo = {
+     *         "brand" : tstr,
+     *         "manufacturer" : tstr,
+     *         "product" : tstr,
+     *         "model" : tstr,
+     *         "device" : tstr,
+     *         "vb_state" : "green" / "yellow" / "orange",    ; Taken from the AVB values
+     *         "bootloader_state" : "locked" / "unlocked",    ; Taken from the AVB values
+     *         "vbmeta_digest": bstr,                         ; Taken from the AVB values
+     *         ? "os_version" : tstr,                         ; Same as
+     *                                                        ; android.os.Build.VERSION.release
+     *                                                        ; Not optional for TEE.
+     *         "system_patch_level" : uint,     ; YYYYMM, must match KeyMint OS_PATCHLEVEL
+     *         "boot_patch_level" : uint,       ; YYYYMMDD, must match KeyMint BOOT_PATCHLEVEL
+     *         "vendor_patch_level" : uint,     ; YYYYMMDD, must match KeyMint VENDOR_PATCHLEVEL
+     *         "security_level" : "tee" / "strongbox",
+     *         "fused": 1 / 0,  ; 1 if secure boot is enforced for the processor that the IRPC
+     *                          ; implementation is contained in. 0 otherwise.
+     *     }
+     *
+     * ---------------------------------------------------------------------------------------------
+     *
+     * Version 2, introduced in Android 13:
+     *     DeviceInfo = {
+     *         "brand" : tstr,
+     *         "manufacturer" : tstr,
+     *         "product" : tstr,
+     *         "model" : tstr,
+     *         "device" : tstr,
+     *         "vb_state" : "green" / "yellow" / "orange",    ; Taken from the AVB values
+     *         "bootloader_state" : "locked" / "unlocked",    ; Taken from the AVB values
+     *         "vbmeta_digest": bstr,                         ; Taken from the AVB values
+     *         ? "os_version" : tstr,                         ; Same as
+     *                                                        ; android.os.Build.VERSION.release
+     *                                                        ; Not optional for TEE.
+     *         "system_patch_level" : uint,     ; YYYYMM, must match KeyMint OS_PATCHLEVEL
+     *         "boot_patch_level" : uint,       ; YYYYMMDD, must match KeyMint BOOT_PATCHLEVEL
+     *         "vendor_patch_level" : uint,     ; YYYYMMDD, must match KeyMint VENDOR_PATCHLEVEL
+     *         "version" : 2,                                 ; The CDDL schema version.
+     *         "security_level" : "tee" / "strongbox",
+     *         "fused": 1 / 0,  ; 1 if secure boot is enforced for the processor that the IRPC
+     *                          ; implementation is contained in. 0 otherwise.
+     *
+     * ---------------------------------------------------------------------------------------------
+     *
+     * Version 1, introduced in Android 12:
+     *     DeviceInfo = {
+     *         ? "brand" : tstr,
+     *         ? "manufacturer" : tstr,
+     *         ? "product" : tstr,
+     *         ? "model" : tstr,
+     *         ? "board" : tstr,
+     *         ? "vb_state" : "green" / "yellow" / "orange",  ; Taken from the AVB values
+     *         ? "bootloader_state" : "locked" / "unlocked",  ; Taken from the AVB values
+     *         ? "vbmeta_digest": bstr,                       ; Taken from the AVB values
+     *         ? "os_version" : tstr,                         ; Same as
+     *                                                        ; android.os.Build.VERSION.release
+     *         ? "system_patch_level" : uint,     ; YYYYMM, must match KeyMint OS_PATCHLEVEL
+     *         ? "boot_patch_level" : uint,       ; YYYYMMDD, must match KeyMint BOOT_PATCHLEVEL
+     *         ? "vendor_patch_level" : uint,     ; YYYYMMDD, must match KeyMint VENDOR_PATCHLEVEL
+     *         "version" : 1,                                 ; The CDDL schema version.
+     *         "security_level" : "tee" / "strongbox"
+     *         "att_id_state": "locked" / "open",  ; Attestation IDs State. If "locked", this
+     *                                             ; indicates a device's attestable IDs are
+     *                                             ; factory-locked and immutable. If "open",
+     *                                             ; this indicates the device is still in a
+     *                                             ; provisionable state and the attestable IDs
+     *                                             ; are not yet frozen.
+     *     }
+     */
+    byte[] deviceInfo;
+}
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
new file mode 100644
index 0000000..7fed363
--- /dev/null
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -0,0 +1,489 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.keymint;
+
+import android.hardware.security.keymint.DeviceInfo;
+import android.hardware.security.keymint.MacedPublicKey;
+import android.hardware.security.keymint.ProtectedData;
+import android.hardware.security.keymint.RpcHardwareInfo;
+
+/**
+ * An IRemotelyProvisionedComponent is a secure-side component for which certificates can be
+ * remotely provisioned. It provides an interface for generating asymmetric key pairs and then
+ * creating a CertificateRequest that contains the generated public keys, plus other information to
+ * authenticate the request origin. The CertificateRequest can be sent to a server, which can
+ * validate the request and create certificates.
+ *
+ * This interface does not provide any way to use the generated and certified key pairs. It's
+ * intended to be implemented by a HAL service that does other things with keys (e.g. KeyMint).
+ *
+ * The root of trust for secure provisioning is something called the Device Identifier Composition
+ * Engine (DICE) Chain. The DICE Chain is a chain of certificates, represented as COSE_Sign1 objects
+ * containing CBOR Web Tokens (CWT) which have descriptions about the stage of firmware being
+ * signed, including a COSE_Key representation of that stage's public key.
+ *
+ * DICE Chain Design
+ * =================
+ *
+ * For a more exhaustive and thorough look at DICE and the implementation used within this protocol,
+ * please see: https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md
+ *
+ * The DICE Chain is designed to mirror the boot stages of a device, and to prove the content and
+ * integrity of each firmware image. In a proper DICE Chain, each boot stage hashes its own private
+ * key material with the code and any relevant configuration parameters of the next stage to produce
+ * a Compound Device Identifier, or CDI, which is used as the secret key material for the next
+ * stage. From the CDI, a key pair - CDI_*_Pub and CDI_*_Priv - is derived and certified for the
+ * next stage by the current stages CDI_*_Priv. The next stage is then loaded and given its CDI and
+ * the DICE certificate chain generated so far in a manner that does not leak the previous stage's
+ * CDI_*_Priv or CDI to later boot stages. The final, "leaf" CDI certificate contains a public key,
+ * denoted CDI_Leaf_Pub, whose corresponding private key, denoted CDI_Leaf_Priv, is available for
+ * use by the IRemotelyProvisionedComponent.
+ *
+ * The root keypair is generated by immutable code (e.g. ROM), from a Unique Device Secret (UDS).
+ * The keypair that is generated from it can be referred to as the UDS_Pub/UDS_Priv keys. After the
+ * device-unique secret is used, it must be made unavailable to any later boot stage.
+ *
+ * In this way, booting the device incrementally builds a certificate chain that (a) identifies and
+ * validates the integrity of every stage and (b) contains a set of public keys that correspond to
+ * private keys, one known to each stage. Any stage can compute the secrets of all later stages
+ * (given the necessary input), but no stage can compute the secret of any preceding stage. Updating
+ * the firmware or configuration of any stage changes the key pair of that stage, and of all
+ * subsequent stages, and no attacker who compromised the previous version of the updated firmware
+ * can know or predict the post-update key pairs. It is recommended and expected that the DICE Chain
+ * is constructed using the Open Profile for DICE.
+ *
+ * When the provisioning server receives a message signed by CDI_Leaf_Priv and containing a DICE
+ * chain that chains from UDS_Pub to CDI_Leaf_Pub, it can be certain that (barring vulnerabilities
+ * in some boot stage), the CertificateRequest came from the device associated with UDS_Pub, running
+ * the specific software identified by the certificates in the chain. If the server has some
+ * mechanism for knowing the hash values of compromised stages, it can determine whether signing
+ * certificates is appropriate.
+ *
+ * Degenerate DICE Chains
+ * ======================
+ *
+ * While a proper DICE Chain, as described above, reflects the complete boot sequence from boot ROM
+ * to the secure area image of the IRemotelyProvisionedComponent, it's also possible to use a
+ * "degenerate" DICE Chain which consists only of a single, self-signed certificate containing the
+ * public key of a hardware-bound key pair. This is an appropriate solution for devices which
+ * haven't implemented everything necessary to produce a proper DICE Chain, but can derive a unique
+ * key pair in the secure area. In this degenerate case, UDS_Pub is the same as CDI_Leaf_Pub.
+ *
+ * DICE Chain Privacy
+ * ==================
+ *
+ * Because the DICE Chain constitutes an unspoofable, device-unique identifier, special care is
+ * taken to prevent its availability to entities who may wish to track devices. Three precautions
+ * are taken:
+ *
+ * 1) The DICE chain is only handled by the native Remote Key Provisioning Daemon (RKPD) service on
+ *    the HLOS and is not exposed to apps running on device.
+ *
+ * 2) The CDI_Leaf_Priv key cannot be used to sign arbitrary data.
+ *
+ * 3) Backend infrastructure does not correlate UDS_Pub with the certificates signed and sent back
+ *    to the device.
+ *
+ * Versioning
+ * ==========
+ * Versions 1 and 2 of the schema, as previously defined in DeviceInfo.aidl, diverge in
+ * functionality from Version 3. Version 3 removes the need to have testMode in function calls and
+ * deprecates the Endpoint Encryption Key (EEK) as well. Vendors implementing Version 1
+ * (Android S/12) or Version 2 (Android T/13) do not need to implement generateCertificateRequestV2.
+ * Vendors implementing Version 3 (Android U/14) need to implement generateCertificateRequestV2.
+ *
+ * For better coverage of changes from version to version, please see RKP_CHANGELOG.md in the root
+ * of the keymint interface directory.
+ *
+ * @hide
+ */
+@VintfStability
+interface IRemotelyProvisionedComponent {
+    const int STATUS_FAILED = 1;
+    const int STATUS_INVALID_MAC = 2;
+    const int STATUS_PRODUCTION_KEY_IN_TEST_REQUEST = 3; // Versions 1 and 2 Only
+    const int STATUS_TEST_KEY_IN_PRODUCTION_REQUEST = 4;
+    const int STATUS_INVALID_EEK = 5; // Versions 1 and 2 Only
+    const int STATUS_REMOVED = 6;
+
+    /**
+     * @return info which contains information about the underlying IRemotelyProvisionedComponent
+     *         hardware, such as version number, component name, author name, and supported curve.
+     */
+    RpcHardwareInfo getHardwareInfo();
+
+    /**
+     * generateKeyPair generates a new ECDSA P-256 key pair that can be attested by the remote
+     * server.
+     *
+     * @param in boolean testMode indicates whether the generated key is for testing only. Test keys
+     *        are marked (see the definition of PublicKey in the MacedPublicKey structure) to
+     *        prevent them from being confused with production keys.
+     *
+     *        This parameter has been deprecated since version 3 of the HAL and will always be
+     *        false. From v3, if this parameter is true, the method must raise a
+     *        ServiceSpecificException with an error of code of STATUS_REMOVED.
+     *
+     * @param out MacedPublicKey macedPublicKey contains the public key of the generated key pair,
+     *        MACed so that generateCertificateRequest can easily verify, without the
+     *        privateKeyHandle, that the contained public key is for remote certification.
+     *
+     * @return data representing a handle to the private key. The format is implementation-defined,
+     *         but note that specific services may define a required format. KeyMint does.
+     */
+    byte[] generateEcdsaP256KeyPair(in boolean testMode, out MacedPublicKey macedPublicKey);
+
+    /**
+     * This method has been deprecated since version 3 of the HAL. The header is kept around for
+     * backwards compatibility purposes. From v3, this method must raise a ServiceSpecificException
+     * with an error code of STATUS_REMOVED.
+     *
+     * For v1 and v2 implementations:
+     * generateCertificateRequest creates a certificate request to be sent to the provisioning
+     * server.
+     *
+     * @param in boolean testMode indicates whether the generated certificate request is for testing
+     *        only.
+     *
+     * @param in MacedPublicKey[] keysToSign contains the set of keys to certify. The
+     *        IRemotelyProvisionedComponent must validate the MACs on each key.  If any entry in the
+     *        array lacks a valid MAC, the method must return STATUS_INVALID_MAC.
+     *
+     *        If testMode is true, the keysToSign array must contain only keys flagged as test
+     *        keys. Otherwise, the method must return STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
+     *
+     *        If testMode is false, the keysToSign array must not contain any keys flagged as
+     *        test keys. Otherwise, the method must return STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
+     *
+     * @param in endpointEncryptionKey contains an X25519 or P-256 public key which will be used to
+     *        encrypt the BCC. For flexibility, this is represented as a certificate chain
+     *        in the form of a CBOR array of COSE_Sign1 objects, ordered from root to leaf.  An
+     *        implementor may also choose to use P256 as an alternative curve for signing and
+     *        encryption instead of Curve 25519, as indicated by the supportedEekCurve field in
+     *        RpcHardwareInfo; the contents of the EEK chain will match the specified
+     *        supportedEekCurve.
+     *
+     *        - For CURVE_25519 the leaf contains the X25519 agreement key, each other element is an
+     *          Ed25519 key signing the next in the chain.
+     *
+     *        - For CURVE_P256 the leaf contains the P-256 agreement key, each other element is a
+     *          P-256 key signing the next in the chain.
+     *
+     *        In either case, the root is self-signed.
+     *
+     *            EekChain = [ + SignedSignatureKey, SignedEek ]
+     *
+     *            SignedSignatureKey = [              ; COSE_Sign1
+     *                protected: bstr .cbor {
+     *                    1 : AlgorithmEdDSA / AlgorithmES256,  ; Algorithm
+     *                },
+     *                unprotected: {},
+     *                payload: bstr .cbor SignatureKeyEd25519 /
+     *                         bstr .cbor SignatureKeyP256,
+     *                signature: bstr PureEd25519(.cbor SignatureKeySignatureInput) /
+     *                           bstr ECDSA(.cbor SignatureKeySignatureInput)
+     *            ]
+     *
+     *            SignatureKeyEd25519 = {             ; COSE_Key
+     *                 1 : 1,                         ; Key type : Octet Key Pair
+     *                 3 : AlgorithmEdDSA,            ; Algorithm
+     *                 -1 : 6,                        ; Curve : Ed25519
+     *                 -2 : bstr                      ; Ed25519 public key
+     *            }
+     *
+     *            SignatureKeyP256 = {                ; COSE_Key
+     *                 1 : 2,                         ; Key type : EC2
+     *                 3 : AlgorithmES256,            ; Algorithm
+     *                 -1 : 1,                        ; Curve: P256
+     *                 -2 : bstr,                     ; X coordinate
+     *                 -3 : bstr                      ; Y coordinate
+     *            }
+     *
+     *            SignatureKeySignatureInput = [
+     *                context: "Signature1",
+     *                body_protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+     *                external_aad: bstr .size 0,
+     *                payload: bstr .cbor SignatureKeyEd25519 /
+     *                         bstr .cbor SignatureKeyP256
+     *            ]
+     *
+     *            ; COSE_Sign1
+     *            SignedEek = [
+     *                protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+     *                unprotected: {},
+     *                payload: bstr .cbor EekX25519 / .cbor EekP256,
+     *                signature: bstr PureEd25519(.cbor EekSignatureInput) /
+     *                           bstr ECDSA(.cbor EekSignatureInput)
+     *            ]
+     *
+     *            EekX25519 = {            ; COSE_Key
+     *                1 : 1,               ; Key type : Octet Key Pair
+     *                2 : bstr             ; KID : EEK ID
+     *                3 : -25,             ; Algorithm : ECDH-ES + HKDF-256
+     *                -1 : 4,              ; Curve : X25519
+     *                -2 : bstr            ; X25519 public key, little-endian
+     *            }
+     *
+     *            EekP256 = {              ; COSE_Key
+     *                1 : 2,               ; Key type : EC2
+     *                2 : bstr             ; KID : EEK ID
+     *                3 : -25,             ; Algorithm : ECDH-ES + HKDF-256
+     *                -1 : 1,              ; Curve : P256
+     *                -2 : bstr            ; Sender X coordinate
+     *                -3 : bstr            ; Sender Y coordinate
+     *            }
+     *
+     *            EekSignatureInput = [
+     *                context: "Signature1",
+     *                body_protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 },
+     *                external_aad: bstr .size 0,
+     *                payload: bstr .cbor EekX25519 / .cbor EekP256
+     *            ]
+     *
+     *            AlgorithmES256 = -7      ; RFC 8152 section 8.1
+     *            AlgorithmEdDSA = -8      ; RFC 8152 section 8.2
+     *
+     *        If the contents of endpointEncryptionKey do not match the SignedEek structure above,
+     *        the method must return STATUS_INVALID_EEK.
+     *
+     *        If testMode is true, the method must ignore the length and content of the signatures
+     *        in the chain, which implies that it must not attempt to validate the signature.
+     *
+     *        If testMode is false, the method must validate the chain signatures, and must verify
+     *        that the public key in the root certificate is in its pre-configured set of
+     *        authorized EEK root keys. If the public key is not in the database, or if signature
+     *        verification fails, the method must return STATUS_INVALID_EEK.
+     *
+     * @param in challenge contains a byte string from the provisioning server that must be signed
+     *        by the secure area. See the description of the 'signature' output parameter for
+     *        details.
+     *
+     * @param out DeviceInfo contains the VerifiedDeviceInfo portion of the DeviceInfo array in
+     *        CertificateRequest. The structure is described within the DeviceInfo.aidl file.
+     *
+     * @param out ProtectedData contains the encrypted BCC and the ephemeral MAC key used to
+     *        authenticate the keysToSign (see keysToSignMac output argument).
+     *
+     * @return The MAC of KeysToSign in the CertificateRequest structure. Specifically, it contains:
+     *
+     *            HMAC-256(EK_mac, .cbor KeysToMacStructure)
+     *
+     *        Where EK_mac is an ephemeral MAC key, found in ProtectedData (see below).  The MACed
+     *        data is the "tag" field of a COSE_Mac0 structure like:
+     *
+     *            MacedKeys = [                            ; COSE_Mac0
+     *                protected : bstr .cbor {
+     *                    1 : 5,                           ; Algorithm : HMAC-256
+     *                },
+     *                unprotected : {},
+     *                ; Payload is PublicKeys from keysToSign argument, in provided order.
+     *                payload: bstr .cbor [ * PublicKey ],
+     *                tag: bstr
+     *            ]
+     *
+     *            KeysToMacStructure = [
+     *                context : "MAC0",
+     *                protected : bstr .cbor { 1 : 5 },    ; Algorithm : HMAC-256
+     *                external_aad : bstr .size 0,
+     *                ; Payload is PublicKeys from keysToSign argument, in provided order.
+     *                payload : bstr .cbor [ * PublicKey ]
+     *            ]
+     */
+    byte[] generateCertificateRequest(in boolean testMode, in MacedPublicKey[] keysToSign,
+            in byte[] endpointEncryptionCertChain, in byte[] challenge, out DeviceInfo deviceInfo,
+            out ProtectedData protectedData);
+
+    /**
+     * generateCertificateRequestV2 creates a certificate signing request to be sent to the
+     * provisioning server.
+     *
+     * @param in MacedPublicKey[] keysToSign contains the set of keys to certify. The
+     *        IRemotelyProvisionedComponent must validate the MACs on each key.  If any entry in the
+     *        array lacks a valid MAC, the method must return STATUS_INVALID_MAC.  This method must
+     *        not accept test keys. If any entry in the array is a test key, the method must return
+     *        STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
+     *
+     * @param in challenge contains a byte string from the provisioning server which will be
+     *        included in the signed data of the CSR structure. Different provisioned backends may
+     *        use different semantic data for this field, but the supported sizes must be between 0
+     *        and 64 bytes, inclusive.
+     *
+     * @return the following CBOR Certificate Signing Request (Csr) serialized into a byte array:
+     *
+     * Csr = AuthenticatedRequest<CsrPayload>
+     *
+     * CsrPayload = [                      ; CBOR Array defining the payload for Csr
+     *     version: 3,                     ; The CsrPayload CDDL Schema version.
+     *     CertificateType,                ; The type of certificate being requested.
+     *     DeviceInfo,                     ; Defined in DeviceInfo.aidl
+     *     KeysToSign,                     ; Provided by the method parameters
+     * ]
+     *
+     *  ; A tstr identifying the type of certificate. The set of supported certificate types may
+     *  ; be extended without requiring a version bump of the HAL. Custom certificate types may
+     *  ; be used, but the provisioning server may reject the request for an unknown certificate
+     *  ; type. The currently defined certificate types are:
+     *  ;  - "widevine"
+     *  ;  - "keymint"
+     *  CertificateType = tstr
+     *
+     * KeysToSign = [ * PublicKey ]   ; Please see MacedPublicKey.aidl for the PublicKey definition.
+     *
+     * AuthenticatedRequest<T> = [
+     *     version: 1,              ; The AuthenticatedRequest CDDL Schema version.
+     *     UdsCerts,
+     *     DiceCertChain,
+     *     SignedData<[
+     *         challenge: bstr .size (0..64), ; Provided by the method parameters
+     *         bstr .cbor T,
+     *     ]>,
+     * ]
+     *
+     * ; COSE_Sign1 (untagged)
+     * SignedData<Data> = [
+     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
+     *     unprotected: {},
+     *     payload: bstr .cbor Data / nil,
+     *     signature: bstr      ; PureEd25519(CDI_Leaf_Priv, SignedDataSigStruct<Data>) /
+     *                          ; ECDSA(CDI_Leaf_Priv, SignedDataSigStruct<Data>)
+     * ]
+     *
+     * ; Sig_structure for SignedData
+     * SignedDataSigStruct<Data> = [
+     *     context: "Signature1",
+     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
+     *     external_aad: bstr .size 0,
+     *     payload: bstr .cbor Data / nil,
+     * ]
+     *
+     * ; UdsCerts allows the platform to provide additional certifications for the UDS_Pub. For
+     * ; example, this could be provided by the hardware vendor, who certifies all of their chips.
+     * ; The SignerName is a free-form string describing who generated the signature. The root
+     * ; certificate will need to be communicated to the verifier out of band, along with the
+     * ; SignerName that is expected for the given root certificate.
+     * UdsCerts = {
+     *     * SignerName => UdsCertChain
+     * }
+     *
+     * ; SignerName is a string identifier that indicates both the signing authority as
+     * ; well as the format of the UdsCertChain
+     * SignerName = tstr
+     *
+     * UdsCertChain = [
+     *     2* X509Certificate       ; Root -> ... -> Leaf. "Root" is the vendor self-signed
+     *                              ; cert, "Leaf" contains UDS_Public. There may also be
+     *                              ; intermediate certificates between Root and Leaf.
+     * ]
+     *
+     * ; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or EdDSA)
+     * X509Certificate = bstr
+     *
+     * ; The DICE Chain contains measurements about the device firmware.
+     * ; The first entry in the DICE Chain is the UDS_Pub, encoded as a COSE_key. All entries
+     * ; after the first describe a link in the boot chain (e.g. bootloaders: BL1, BL2, ... BLN)
+     * ; Note that there is no DiceChainEntry for UDS_pub, only a "bare" COSE_key.
+     * DiceCertChain = [
+     *     PubKeyEd25519 / PubKeyECDSA256 / PubKeyECDSA384,  ; UDS_Pub
+     *     + DiceChainEntry,                ; First CDI_Certificate -> Last CDI_Certificate
+     *                                      ; Last certificate corresponds to KeyMint's DICE key.
+     * ]
+     *
+     * ; This is the signed payload for each entry in the DICE chain. Note that the "Configuration
+     * ; Input Values" described by the Open Profile are not used here. Instead, the DICE chain
+     * ; defines its own configuration values for the Configuration Descriptor field. See
+     * ; the Open Profile for DICE for more details on the fields. SHA256, SHA384 and SHA512 are
+     * ; acceptable hash algorithms. The digest bstr values in the payload are the digest values
+     * ; without any padding. Note that this implies that the digest is a 32-byte bstr for SHA256
+     * ; and a 48-byte bstr for SHA384. This is an intentional, minor deviation from Open Profile
+     * ; for DICE, which specifies all digests are 64 bytes.
+     * DiceChainEntryPayload = {                    ; CWT [RFC8392]
+     *     1 : tstr,                                ; Issuer
+     *     2 : tstr,                                ; Subject
+     *     -4670552 : bstr .cbor PubKeyEd25519 /
+     *                bstr .cbor PubKeyECDSA256,
+     *                bstr .cbor PubKeyECDSA384,    ; Subject Public Key
+     *     -4670553 : bstr                          ; Key Usage
+     *
+     *     ; NOTE: All of the following fields may be omitted for a "Degenerate DICE Chain", as
+     *     ;       described above.
+     *     -4670545 : bstr,                         ; Code Hash
+     *     ? -4670546 : bstr,                       ; Code Descriptor
+     *     ? -4670547 : bstr,                       ; Configuration Hash
+     *     -4670548 : bstr .cbor {                  ; Configuration Descriptor
+     *         ? -70002 : tstr,                         ; Component name
+     *         ? -70003 : int / tstr,                   ; Component version
+     *         ? -70004 : null,                         ; Resettable
+     *         ? -70005 : uint,                         ; Security version
+     *     },
+     *     -4670549 : bstr,                         ; Authority Hash
+     *     ? -4670550 : bstr,                       ; Authority Descriptor
+     *     -4670551 : bstr,                         ; Mode
+     * }
+     *
+     * ; Each entry in the DICE chain is a DiceChainEntryPayload signed by the key from the previous
+     * ; entry in the DICE chain array.
+     * DiceChainEntry = [                            ; COSE_Sign1 (untagged)
+     *     protected : bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
+     *     unprotected: {},
+     *     payload: bstr .cbor DiceChainEntryPayload,
+     *     signature: bstr ; PureEd25519(SigningKey, DiceChainEntryInput) /
+     *                     ; ECDSA(SigningKey, DiceChainEntryInput)
+     *                     ; See RFC 8032 for details of how to encode the signature value
+     *                     ; for Ed25519.
+     * ]
+     *
+     * DiceChainEntryInput = [
+     *     context: "Signature1",
+     *     protected: bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
+     *     external_aad: bstr .size 0,
+     *     payload: bstr .cbor DiceChainEntryPayload
+     * ]
+     *
+     * ; The following section defines some types that are reused throughout the above
+     * ; data structures.
+     * ; NOTE: Integer encoding is different for Ed25519 and P256 keys:
+     * ;       - Ed25519 is LE: https://www.rfc-editor.org/rfc/rfc8032#section-3.1
+     * ;       - P256 is BE: https://www.secg.org/sec1-v2.pdf#page=19 (section 2.3.7)
+     * PubKeyEd25519 = {                ; COSE_Key
+     *     1 : 1,                       ; Key type : octet key pair
+     *     3 : AlgorithmEdDSA,          ; Algorithm : EdDSA
+     *     -1 : 6,                      ; Curve : Ed25519
+     *     -2 : bstr                    ; X coordinate, little-endian
+     * }
+     *
+     * PubKeyECDSA256 = {               ; COSE_Key
+     *     1 : 2,                       ; Key type : EC2
+     *     3 : AlgorithmES256,          ; Algorithm : ECDSA w/ SHA-256
+     *     -1 : 1,                      ; Curve: P256
+     *     -2 : bstr,                   ; X coordinate, big-endian
+     *     -3 : bstr                    ; Y coordinate, big-endian
+     * }
+     *
+     * PubKeyECDSA384 = {               ; COSE_Key
+     *     1 : 2,                       ; Key type : EC2
+     *     3 : AlgorithmES384,          ; Algorithm : ECDSA w/ SHA-384
+     *     -1 : 2,                      ; Curve: P384
+     *     -2 : bstr,                   ; X coordinate
+     *     -3 : bstr                    ; Y coordinate
+     * }
+     *
+     * AlgorithmES256 = -7
+     * AlgorithmES384 = -35
+     * AlgorithmEdDSA = -8
+     */
+    byte[] generateCertificateRequestV2(in MacedPublicKey[] keysToSign, in byte[] challenge);
+}
diff --git a/security/rkp/aidl/android/hardware/security/keymint/MacedPublicKey.aidl b/security/rkp/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
new file mode 100644
index 0000000..1e41d1b
--- /dev/null
+++ b/security/rkp/aidl/android/hardware/security/keymint/MacedPublicKey.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.keymint;
+
+/**
+ * MacedPublicKey contains a CBOR-encoded public key, MACed by an IRemotelyProvisionedComponent, to
+ * prove that the key pair was generated by that component.
+ * @hide
+ */
+@VintfStability
+parcelable MacedPublicKey {
+    /**
+     * key is a COSE_Mac0 structure containing the new public key.  It's MACed by a key available
+     * only to the secure environment, as proof that the public key was generated by that
+     * environment. In CDDL, assuming the contained key is a P-256 public key:
+     *
+     *     MacedPublicKey = [                     ; COSE_Mac0
+     *         protected: bstr .cbor { 1 : 5},    ; Algorithm : HMAC-256
+     *         unprotected: { },
+     *         payload : bstr .cbor PublicKey,
+     *         tag : bstr HMAC-256(K_mac, MAC_structure)
+     *     ]
+     *
+     *     ; NOTE: -70000 is deprecated for v3 HAL implementations.
+     *     ; NOTE: Integer encoding is different for Ed25519 and P256 keys:
+     *     ;       - Ed25519 is LE: https://www.rfc-editor.org/rfc/rfc8032#section-3.1
+     *     ;       - P256 is BE: https://www.secg.org/sec1-v2.pdf#page=19 (section 2.3.7)
+     *     PublicKey = {               ; COSE_Key
+     *         1 : 2,                  ; Key type : EC2
+     *         3 : -7,                 ; Algorithm : ES256
+     *         -1 : 1,                 ; Curve : P256
+     *         -2 : bstr,              ; X coordinate, big-endian
+     *         -3 : bstr,              ; Y coordinate, big-endian
+     *         -70000 : nil            ; Presence indicates this is a test key. If set, K_mac is
+     *                                 ; all zeros.
+     *     },
+     *
+     *     MAC_structure = [
+     *         context : "MAC0",
+     *         protected : bstr .cbor { 1 : 5 },
+     *         external_aad : bstr .size 0,
+     *         payload : bstr .cbor PublicKey
+     *     ]
+     */
+    byte[] macedKey;
+}
diff --git a/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl
new file mode 100644
index 0000000..de94264
--- /dev/null
+++ b/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl
@@ -0,0 +1,246 @@
+/*
+ * 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.security.keymint;
+
+/**
+ * NOTE: ProtectedData has been removed as of version 3, but is kept around for backwards
+ * compatibility reasons. For versions 1 and 2:
+ *
+ * ProtectedData contains the encrypted BCC and the ephemeral MAC key used to
+ * authenticate the keysToSign (see keysToSignMac output argument of
+ * IRemotelyProvisionedComponent.generateCertificateRequest).
+ *
+ * @hide
+ */
+@VintfStability
+parcelable ProtectedData {
+    /**
+     * ProtectedData is a COSE_Encrypt structure, encrypted with an AES key that is agreed upon
+     * using Elliptic-curve Diffie-Hellman. The contents of the structure are specified by the
+     * following CDDL [RFC8610].
+     *
+     * Notes:
+     *   - None of the CBOR in ProtectedData uses CBOR tags. If an implementation includes
+     *     tags, parsers may reject the data.
+     *
+     *     ProtectedData = [               ; COSE_Encrypt
+     *         protected: bstr .cbor {
+     *             1 : 3                   ; Algorithm : AES-GCM 256
+     *         },
+     *         unprotected: {
+     *             5 : bstr .size 12       ; IV
+     *         },
+     *         ciphertext: bstr,           ; AES-GCM-256(K, .cbor ProtectedDataPayload)
+     *                                     ; Where the encryption key 'K' is derived as follows:
+     *                                     ; ikm = ECDH(EEK_pub, Ephemeral_priv)
+     *                                     ; salt = null
+     *                                     ; info = .cbor Context (see below)
+     *                                     ; K = HKDF-SHA-256(ikm, salt, info)
+     *                                     ; AAD for the encryption is a CBOR-serialized
+     *                                     ; Enc_structure (RFC 8152 s5.3) with empty external_aad.
+     *         recipients : [
+     *             [                       ; COSE_Recipient
+     *                 protected : bstr .cbor {
+     *                     1 : -25         ; Algorithm : ECDH-ES + HKDF-256
+     *                 },
+     *                 unprotected : {
+     *                     -1 : PubKeyX25519 / PubKeyEcdhP256  ; Ephemeral_pub
+     *                     4 : bstr,       ; KID : EEK ID
+     *                 },
+     *                 ciphertext : nil
+     *             ]
+     *         ]
+     *     ]
+     *
+     *     ; The COSE_KDF_Context that is used to derive the ProtectedData encryption key with
+     *     ; HKDF. See details on use in ProtectedData comments above. The public key data
+     *     ; included in the other field of PartyUInfo / PartyVInfo is encoded as:
+     *     ;  - a raw 32-byte public key for X25519
+     *     ;  - raw coordinate data (x || y) for P-256
+     *     Context = [
+     *         AlgorithmID : 3             ; AES-GCM 256
+     *         PartyUInfo : [
+     *             identity : bstr "client"
+     *             nonce : bstr .size 0,
+     *             other : bstr            ; Ephemeral_pub
+     *         ],
+     *         PartyVInfo : [
+     *             identity : bstr "server",
+     *             nonce : bstr .size 0,
+     *             other : bstr            ; EEK pubkey
+     *         ],
+     *         SuppPubInfo : [
+     *             256,                    ; Output key length
+     *             protected : bstr .size 0
+     *         ]
+     *     ]
+     *
+     *     ; The data that is encrypted and included in ProtectedData ciphertext (see above).
+     *     ProtectedDataPayload [
+     *         SignedMac,
+     *         Bcc,
+     *         ? AdditionalDKSignatures,
+     *     ]
+     *
+     *     ; AdditionalDKSignatures allows the platform to provide additional certifications
+     *     ; for the DK_pub. For example, this could be provided by the hardware vendor, who
+     *     ; certifies all of their devices. The SignerName is a free-form string describing
+     *     ; who generated the signature.
+     *     AdditionalDKSignatures = {
+     *         + SignerName => DKCertChain
+     *     }
+     *
+     *     ; SignerName is a string identifier that indicates both the signing authority as
+     *     ; well as the format of the DKCertChain
+     *     SignerName = tstr
+     *
+     *     DKCertChain = [
+     *         2* X509Certificate       ; Root -> ... -> Leaf. "Root" is the vendor self-signed
+     *                                  ; cert, "Leaf" contains DK_pub. There may also be
+     *                                  ; intermediate certificates between Root and Leaf.
+     *     ]
+     *
+     *     ; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or edDSA)
+     *     X509Certificate = bstr
+     *
+     *     ; The SignedMac, which authenticates the MAC key that is used to authenticate the
+     *     ; keysToSign.
+     *     SignedMac = [                                ; COSE_Sign1
+     *         bstr .cbor {                             ; Protected params
+     *             1 : AlgorithmEdDSA / AlgorithmES256, ; Algorithm
+     *         },
+     *         {},                                      ; Unprotected params
+     *         bstr .size 32,                           ; Payload: MAC key
+     *         bstr ; PureEd25519(KM_priv, bstr .cbor SignedMac_structure) /
+     *              ; ECDSA(KM_priv, bstr .cbor SignedMac_structure)
+     *     ]
+     *
+     *     SignedMac_structure = [                      ;  COSE Sig_structure
+     *         "Signature1",
+     *         bstr .cbor {                             ; Protected params
+     *             1 : AlgorithmEdDSA / AlgorithmES256, ; Algorithm
+     *         },
+     *         bstr .cbor SignedMacAad,
+     *         bstr .size 32                            ; MAC key
+     *     ]
+     *
+     *     SignedMacAad = [
+     *         challenge : bstr .size (16..64),   ; Size between 16 - 64
+     *                                            ; bytes inclusive
+     *         VerifiedDeviceInfo,
+     *         tag: bstr                 ; This is the tag from COSE_Mac0 of
+     *                                   ; KeysToSign, to tie the key set to
+     *                                   ; the signature.
+     *     ]
+     *
+     *     VerifiedDeviceInfo = DeviceInfo  ; See DeviceInfo.aidl
+     *
+     *     ; The BCC is the boot certificate chain, containing measurements about the device
+     *     ; boot chain. The BCC generally follows the Open Profile for DICE specification at
+     *     ; https:;pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md.
+     *     ;
+     *     ; The first entry in the Bcc is the DK_pub, encoded as a COSE_key. All entries after
+     *     ; the first describe a link in the boot chain (e.g. bootloaders: BL1, BL2, ... BLN).
+     *     ; Note that there is no BccEntry for DK_pub, only a "bare" COSE_key.
+     *     Bcc = [
+     *         PubKeyEd25519 / PubKeyECDSA256, ; DK_pub
+     *         + BccEntry,                     ; Root -> leaf (KM_pub)
+     *     ]
+     *
+     *     ; This is the signed payload for each entry in the Bcc. Note that the "Configuration
+     *     ; Input Values" described by the Open Profile are not used here. Instead, the Bcc
+     *     ; defines its own configuration values for the Configuration Descriptor field. See
+     *     ; the Open Profile for DICE for more details on the fields. All hashes are SHA256.
+     *     BccPayload = {                               ; CWT [RFC8392]
+     *         1 : tstr,                                ; Issuer
+     *         2 : tstr,                                ; Subject
+     *         -4670552 : bstr .cbor PubKeyEd25519 /
+     *                    bstr .cbor PubKeyECDSA256,    ; Subject Public Key
+     *         -4670553 : bstr                          ; Key Usage
+     *
+     *         ; NOTE: All of the following fields may be omitted for a "Degenerate BCC", as
+     *         ;       described by IRemotelyProvisionedComponent.aidl.
+     *         -4670545 : bstr,                         ; Code Hash
+     *         ? -4670546 : bstr,                       ; Code Descriptor
+     *         ? -4670547 : bstr,                       ; Configuration Hash
+     *         -4670548 : bstr .cbor {                  ; Configuration Descriptor
+     *             ? -70002 : tstr,                         ; Component name
+     *             ? -70003 : int,                          ; Firmware version
+     *             ? -70004 : null,                         ; Resettable
+     *         },
+     *         -4670549 : bstr,                         ; Authority Hash
+     *         ? -4670550 : bstr,                       ; Authority Descriptor
+     *         -4670551 : bstr,                         ; Mode
+     *     }
+     *
+     *     ; Each entry in the Bcc is a BccPayload signed by the key from the previous entry
+     *     ; in the Bcc array.
+     *     BccEntry = [                                  ; COSE_Sign1 (untagged)
+     *         protected : bstr .cbor {
+     *             1 : AlgorithmEdDSA / AlgorithmES256,  ; Algorithm
+     *         },
+     *         unprotected: {},
+     *         payload: bstr .cbor BccPayload,
+     *         signature: bstr ; PureEd25519(SigningKey, bstr .cbor BccEntryInput) /
+     *                         ; ECDSA(SigningKey, bstr .cbor BccEntryInput)
+     *         ; See RFC 8032 for details of how to encode the signature value for Ed25519.
+     *     ]
+     *
+     *     BccEntryInput = [
+     *         context: "Signature1",
+     *         protected: bstr .cbor {
+     *             1 : AlgorithmEdDSA / AlgorithmES256,  ; Algorithm
+     *         },
+     *         external_aad: bstr .size 0,
+     *         payload: bstr .cbor BccPayload
+     *     ]
+     *
+     *     ; The following section defines some types that are reused throughout the above
+     *     ; data structures.
+     *     PubKeyX25519 = {                 ; COSE_Key
+     *          1 : 1,                      ; Key type : Octet Key Pair
+     *         -1 : 4,                      ; Curve : X25519
+     *         -2 : bstr                    ; Sender X25519 public key, little-endian
+     *     }
+     *
+     *     PubKeyEd25519 = {                ; COSE_Key
+     *         1 : 1,                       ; Key type : octet key pair
+     *         3 : AlgorithmEdDSA,          ; Algorithm : EdDSA
+     *         -1 : 6,                      ; Curve : Ed25519
+     *         -2 : bstr                    ; X coordinate, little-endian
+     *     }
+     *
+     *     PubKeyEcdhP256 = {               ; COSE_Key
+     *          1 : 2,                      ; Key type : EC2
+     *          -1 : 1,                     ; Curve : P256
+     *          -2 : bstr                   ; Sender X coordinate, big-endian
+     *          -3 : bstr                   ; Sender Y coordinate, big-endian
+     *     }
+     *
+     *     PubKeyECDSA256 = {               ; COSE_Key
+     *         1 : 2,                       ; Key type : EC2
+     *         3 : AlgorithmES256,          ; Algorithm : ECDSA w/ SHA-256
+     *         -1 : 1,                      ; Curve: P256
+     *         -2 : bstr,                   ; X coordinate, big-endian
+     *         -3 : bstr                    ; Y coordinate, big-endian
+     *     }
+     *
+     *     AlgorithmES256 = -7
+     *     AlgorithmEdDSA = -8
+     */
+    byte[] protectedData;
+}
diff --git a/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
new file mode 100644
index 0000000..d0b059d
--- /dev/null
+++ b/security/rkp/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.keymint;
+
+/**
+ * RpcHardwareInfo is the hardware information returned by calling RemotelyProvisionedComponent
+ * getHardwareInfo()
+ * @hide
+ */
+@VintfStability
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable RpcHardwareInfo {
+    const int CURVE_NONE = 0;
+    const int CURVE_P256 = 1;
+    const int CURVE_25519 = 2;
+
+    /**
+     * Implementation version of the remotely provisioned component hardware. The version provided
+     * here must match the version reported in the CsrPayload produced by the HAL interface. This
+     * field primarily acts as a convenience for the system components interacting with the HALs.
+     */
+    int versionNumber;
+
+    /**
+     * rpcAuthorName is the name of the author of the IRemotelyProvisionedComponent implementation
+     * (organization name, not individual). This name is implementation defined, so it can be used
+     * to distinguish between different implementations from the same author.
+     */
+    @utf8InCpp String rpcAuthorName;
+
+    /**
+     * NOTE: This field is no longer used as of version 3 of the HAL interface. This is because the
+     *       Endpoint Encryption Key is no longer used in the provisioning scheme.
+     *
+     * supportedEekCurve returns an int representing which curve is supported for validating
+     * signatures over the Endpoint Encryption Key certificate chain and for using the corresponding
+     * signed encryption key in ECDH. Only one curve should be supported, with preference for 25519
+     * if it's available. These values are defined as constants above.
+     *
+     * CURVE_NONE is made the default to help ensure that an implementor doesn't accidentally forget
+     * to provide the correct information here, as the VTS tests will check to make certain that
+     * a passing implementation does not provide CURVE_NONE.
+     */
+    int supportedEekCurve = CURVE_NONE;
+
+    /**
+     * uniqueId is an opaque identifier for this IRemotelyProvisionedComponent implementation. The
+     * client should NOT interpret the content of the identifier in any way. The client can only
+     * compare identifiers to determine if two IRemotelyProvisionedComponents share the same
+     * implementation. Each IRemotelyProvisionedComponent implementation must have a distinct
+     * identifier from all other implementations, and it must be consistent across all devices.
+     * It's critical that this identifier not be usable to uniquely identify a specific device.
+     *
+     * This identifier must be consistent across reboots, as it is used to store and track
+     * provisioned keys in a persistent, on-device database.
+     *
+     * uniqueId may not be empty, and must not be any longer than 32 characters.
+     *
+     * A recommended construction for this value is "[Vendor] [Component Name] [Major Version]",
+     * e.g. "Google Trusty KeyMint 1".
+     *
+     * This field was added in API version 2.
+     *
+     */
+    @nullable @utf8InCpp String uniqueId;
+
+    /**
+     * supportedNumKeysInCsr is the maximum number of keys in a CSR that this implementation can
+     * support. This value is implementation defined.
+     *
+     * From version 3 onwards, supportedNumKeysInCsr must be larger or equal to
+     * MIN_SUPPORTED_NUM_KEYS_IN_CSR.
+     *
+     * The default value was chosen as the value enforced by the VTS test in versions 1 and 2 of
+     * this interface.
+     */
+    const int MIN_SUPPORTED_NUM_KEYS_IN_CSR = 20;
+    int supportedNumKeysInCsr = 4;
+}
diff --git a/security/rkp/aidl/lint-baseline.xml b/security/rkp/aidl/lint-baseline.xml
new file mode 100644
index 0000000..d25d383
--- /dev/null
+++ b/security/rkp/aidl/lint-baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 34 (current min is 33): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V1-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+            line="50"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 34 (current min is 33): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V2-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+            line="50"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 34 (current min is 33): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V3-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+            line="495"
+            column="12"/>
+    </issue>
+
+</issues>
\ No newline at end of file
diff --git a/security/rkp/aidl/vts/functional/Android.bp b/security/rkp/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..9c2b6e1
--- /dev/null
+++ b/security/rkp/aidl/vts/functional/Android.bp
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalRemotelyProvisionedComponentTargetTest",
+    defaults: [
+        "keymint_vts_defaults",
+    ],
+    srcs: [
+        "VtsRemotelyProvisionedComponentTests.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcrypto",
+    ],
+    static_libs: [
+        "libcppbor_external",
+        "libgmock_ndk",
+        "libkeymint_vts_test_utils",
+    ],
+    test_config: "VtsRemotelyProvisionedComponentTests.xml",
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml b/security/rkp/aidl/vts/functional/AndroidTest.xml
similarity index 100%
copy from security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
copy to security/rkp/aidl/vts/functional/AndroidTest.xml
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
new file mode 100644
index 0000000..62463eb
--- /dev/null
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -0,0 +1,980 @@
+/*
+ * 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.
+ */
+
+#include <memory>
+#include <string>
+#define LOG_TAG "VtsRemotelyProvisionableComponentTests"
+
+#include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
+#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
+#include <aidl/android/hardware/security/keymint/SecurityLevel.h>
+#include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <gmock/gmock.h>
+#include <keymaster/cppcose/cppcose.h>
+#include <keymaster/keymaster_configuration.h>
+#include <keymint_support/authorization_set.h>
+#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/x509.h>
+#include <remote_prov/remote_prov_utils.h>
+#include <optional>
+#include <set>
+#include <vector>
+
+#include "KeyMintAidlTestBase.h"
+
+namespace aidl::android::hardware::security::keymint::test {
+
+using ::std::string;
+using ::std::vector;
+
+namespace {
+
+constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2;
+
+constexpr int32_t VERSION_WITHOUT_EEK = 3;
+constexpr int32_t VERSION_WITHOUT_TEST_MODE = 3;
+constexpr int32_t VERSION_WITH_CERTIFICATE_REQUEST_V2 = 3;
+constexpr int32_t VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR = 3;
+
+constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
+constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
+
+#define INSTANTIATE_REM_PROV_AIDL_TEST(name)                                         \
+    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);                             \
+    INSTANTIATE_TEST_SUITE_P(                                                        \
+            PerInstance, name,                                                       \
+            testing::ValuesIn(VtsRemotelyProvisionedComponentTests::build_params()), \
+            ::android::PrintInstanceNameToString)
+
+using ::android::sp;
+using bytevec = std::vector<uint8_t>;
+using testing::MatchesRegex;
+using namespace remote_prov;
+using namespace keymaster;
+
+bytevec string_to_bytevec(const char* s) {
+    const uint8_t* p = reinterpret_cast<const uint8_t*>(s);
+    return bytevec(p, p + strlen(s));
+}
+
+ErrMsgOr<MacedPublicKey> corrupt_maced_key(const MacedPublicKey& macedPubKey) {
+    auto [coseMac0, _, mac0ParseErr] = cppbor::parse(macedPubKey.macedKey);
+    if (!coseMac0 || coseMac0->asArray()->size() != kCoseMac0EntryCount) {
+        return "COSE Mac0 parse failed";
+    }
+    auto protParams = coseMac0->asArray()->get(kCoseMac0ProtectedParams)->asBstr();
+    auto unprotParams = coseMac0->asArray()->get(kCoseMac0UnprotectedParams)->asMap();
+    auto payload = coseMac0->asArray()->get(kCoseMac0Payload)->asBstr();
+    auto tag = coseMac0->asArray()->get(kCoseMac0Tag)->asBstr();
+    if (!protParams || !unprotParams || !payload || !tag) {
+        return "Invalid COSE_Sign1: missing content";
+    }
+    auto corruptMac0 = cppbor::Array();
+    corruptMac0.add(protParams->clone());
+    corruptMac0.add(unprotParams->clone());
+    corruptMac0.add(payload->clone());
+    vector<uint8_t> tagData = tag->value();
+    tagData[0] ^= 0x08;
+    tagData[tagData.size() - 1] ^= 0x80;
+    corruptMac0.add(cppbor::Bstr(tagData));
+
+    return MacedPublicKey{corruptMac0.encode()};
+}
+
+ErrMsgOr<cppbor::Array> corrupt_sig(const cppbor::Array* coseSign1) {
+    if (coseSign1->size() != kCoseSign1EntryCount) {
+        return "Invalid COSE_Sign1, wrong entry count";
+    }
+    const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
+    const cppbor::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
+    const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
+    const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
+    if (!protectedParams || !unprotectedParams || !payload || !signature) {
+        return "Invalid COSE_Sign1: missing content";
+    }
+
+    auto corruptSig = cppbor::Array();
+    corruptSig.add(protectedParams->clone());
+    corruptSig.add(unprotectedParams->clone());
+    corruptSig.add(payload->clone());
+    vector<uint8_t> sigData = signature->value();
+    sigData[0] ^= 0x08;
+    corruptSig.add(cppbor::Bstr(sigData));
+
+    return std::move(corruptSig);
+}
+
+ErrMsgOr<bytevec> corrupt_sig_chain(const bytevec& encodedEekChain, int which) {
+    auto [chain, _, parseErr] = cppbor::parse(encodedEekChain);
+    if (!chain || !chain->asArray()) {
+        return "EekChain parse failed";
+    }
+
+    cppbor::Array* eekChain = chain->asArray();
+    if (which >= eekChain->size()) {
+        return "selected sig out of range";
+    }
+    auto corruptChain = cppbor::Array();
+
+    for (int ii = 0; ii < eekChain->size(); ++ii) {
+        if (ii == which) {
+            auto sig = corrupt_sig(eekChain->get(which)->asArray());
+            if (!sig) {
+                return "Failed to build corrupted signature" + sig.moveMessage();
+            }
+            corruptChain.add(sig.moveValue());
+        } else {
+            corruptChain.add(eekChain->get(ii)->clone());
+        }
+    }
+    return corruptChain.encode();
+}
+
+string device_suffix(const string& name) {
+    size_t pos = name.find('/');
+    if (pos == string::npos) {
+        return name;
+    }
+    return name.substr(pos + 1);
+}
+
+bool matching_keymint_device(const string& rp_name, std::shared_ptr<IKeyMintDevice>* keyMint) {
+    string rp_suffix = device_suffix(rp_name);
+
+    vector<string> km_names = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
+    for (const string& km_name : km_names) {
+        // If the suffix of the KeyMint instance equals the suffix of the
+        // RemotelyProvisionedComponent instance, assume they match.
+        if (device_suffix(km_name) == rp_suffix && AServiceManager_isDeclared(km_name.c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(km_name.c_str()));
+            *keyMint = IKeyMintDevice::fromBinder(binder);
+            return true;
+        }
+    }
+    return false;
+}
+
+}  // namespace
+
+class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            provisionable_ = IRemotelyProvisionedComponent::fromBinder(binder);
+        }
+        ASSERT_NE(provisionable_, nullptr);
+        ASSERT_TRUE(provisionable_->getHardwareInfo(&rpcHardwareInfo).isOk());
+    }
+
+    static vector<string> build_params() {
+        auto params = ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor);
+        return params;
+    }
+
+  protected:
+    std::shared_ptr<IRemotelyProvisionedComponent> provisionable_;
+    RpcHardwareInfo rpcHardwareInfo;
+};
+
+/**
+ * Verify that every implementation reports a different unique id.
+ */
+TEST(NonParameterizedTests, eachRpcHasAUniqueId) {
+    std::set<std::string> uniqueIds;
+    for (auto hal : ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor)) {
+        ASSERT_TRUE(AServiceManager_isDeclared(hal.c_str()));
+        ::ndk::SpAIBinder binder(AServiceManager_waitForService(hal.c_str()));
+        std::shared_ptr<IRemotelyProvisionedComponent> rpc =
+                IRemotelyProvisionedComponent::fromBinder(binder);
+        ASSERT_NE(rpc, nullptr);
+
+        RpcHardwareInfo hwInfo;
+        ASSERT_TRUE(rpc->getHardwareInfo(&hwInfo).isOk());
+
+        if (hwInfo.versionNumber >= VERSION_WITH_UNIQUE_ID_SUPPORT) {
+            ASSERT_TRUE(hwInfo.uniqueId);
+            auto [_, wasInserted] = uniqueIds.insert(*hwInfo.uniqueId);
+            EXPECT_TRUE(wasInserted);
+        } else {
+            ASSERT_FALSE(hwInfo.uniqueId);
+        }
+    }
+}
+
+using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests;
+
+INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);
+
+/**
+ * Verify that a valid curve is reported by the implementation.
+ */
+TEST_P(GetHardwareInfoTests, supportsValidCurve) {
+    RpcHardwareInfo hwInfo;
+    ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
+
+    if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_EEK) {
+        ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE)
+                << "Invalid curve: " << hwInfo.supportedEekCurve;
+        return;
+    }
+
+    const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
+    ASSERT_EQ(validCurves.count(hwInfo.supportedEekCurve), 1)
+            << "Invalid curve: " << hwInfo.supportedEekCurve;
+}
+
+/**
+ * Verify that the unique id is within the length limits as described in RpcHardwareInfo.aidl.
+ */
+TEST_P(GetHardwareInfoTests, uniqueId) {
+    if (rpcHardwareInfo.versionNumber < VERSION_WITH_UNIQUE_ID_SUPPORT) {
+        return;
+    }
+
+    RpcHardwareInfo hwInfo;
+    ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
+    ASSERT_TRUE(hwInfo.uniqueId);
+    EXPECT_GE(hwInfo.uniqueId->size(), 1);
+    EXPECT_LE(hwInfo.uniqueId->size(), 32);
+}
+
+/**
+ * Verify implementation supports at least MIN_SUPPORTED_NUM_KEYS_IN_CSR keys in a CSR.
+ */
+TEST_P(GetHardwareInfoTests, supportedNumKeysInCsr) {
+    if (rpcHardwareInfo.versionNumber < VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR) {
+        return;
+    }
+
+    RpcHardwareInfo hwInfo;
+    ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
+    ASSERT_GE(hwInfo.supportedNumKeysInCsr, RpcHardwareInfo::MIN_SUPPORTED_NUM_KEYS_IN_CSR);
+}
+
+using GenerateKeyTests = VtsRemotelyProvisionedComponentTests;
+
+INSTANTIATE_REM_PROV_AIDL_TEST(GenerateKeyTests);
+
+/**
+ * Generate and validate a production-mode key.  MAC tag can't be verified, but
+ * the private key blob should be usable in KeyMint operations.
+ */
+TEST_P(GenerateKeyTests, generateEcdsaP256Key_prodMode) {
+    MacedPublicKey macedPubKey;
+    bytevec privateKeyBlob;
+    bool testMode = false;
+    auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
+    ASSERT_TRUE(status.isOk());
+    vector<uint8_t> coseKeyData;
+    check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
+}
+
+/**
+ * Generate and validate a production-mode key, then use it as a KeyMint attestation key.
+ */
+TEST_P(GenerateKeyTests, generateAndUseEcdsaP256Key_prodMode) {
+    // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
+    std::shared_ptr<IKeyMintDevice> keyMint;
+    if (!matching_keymint_device(GetParam(), &keyMint)) {
+        // No matching IKeyMintDevice.
+        GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
+        return;
+    }
+    KeyMintHardwareInfo info;
+    ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
+
+    MacedPublicKey macedPubKey;
+    bytevec privateKeyBlob;
+    bool testMode = false;
+    auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
+    ASSERT_TRUE(status.isOk());
+    vector<uint8_t> coseKeyData;
+    check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
+
+    AttestationKey attestKey;
+    attestKey.keyBlob = std::move(privateKeyBlob);
+    attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
+
+    // Generate an ECDSA key that is attested by the generated P256 keypair.
+    AuthorizationSet keyDesc = AuthorizationSetBuilder()
+                                       .Authorization(TAG_NO_AUTH_REQUIRED)
+                                       .EcdsaSigningKey(EcCurve::P_256)
+                                       .AttestationChallenge("foo")
+                                       .AttestationApplicationId("bar")
+                                       .Digest(Digest::NONE)
+                                       .SetDefaultValidity();
+    KeyCreationResult creationResult;
+    auto result = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
+    ASSERT_TRUE(result.isOk());
+    vector<uint8_t> attested_key_blob = std::move(creationResult.keyBlob);
+    vector<KeyCharacteristics> attested_key_characteristics =
+            std::move(creationResult.keyCharacteristics);
+    vector<Certificate> attested_key_cert_chain = std::move(creationResult.certificateChain);
+    EXPECT_EQ(attested_key_cert_chain.size(), 1);
+
+    int32_t aidl_version = 0;
+    ASSERT_TRUE(keyMint->getInterfaceVersion(&aidl_version).isOk());
+    AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+    AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+    EXPECT_TRUE(verify_attestation_record(aidl_version, "foo", "bar", sw_enforced, hw_enforced,
+                                          info.securityLevel,
+                                          attested_key_cert_chain[0].encodedCertificate));
+
+    // Attestation by itself is not valid (last entry is not self-signed).
+    EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
+
+    // The signature over the attested key should correspond to the P256 public key.
+    X509_Ptr key_cert(parse_cert_blob(attested_key_cert_chain[0].encodedCertificate));
+    ASSERT_TRUE(key_cert.get());
+    EVP_PKEY_Ptr signing_pubkey;
+    p256_pub_key(coseKeyData, &signing_pubkey);
+    ASSERT_TRUE(signing_pubkey.get());
+
+    ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
+            << "Verification of attested certificate failed "
+            << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
+}
+
+/**
+ * Generate and validate a test-mode key.
+ */
+TEST_P(GenerateKeyTests, generateEcdsaP256Key_testMode) {
+    MacedPublicKey macedPubKey;
+    bytevec privateKeyBlob;
+    bool testMode = true;
+    auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
+
+    if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
+        ASSERT_FALSE(status.isOk());
+        EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
+        return;
+    }
+
+    ASSERT_TRUE(status.isOk());
+    check_maced_pubkey(macedPubKey, testMode, nullptr);
+}
+
+class CertificateRequestTestBase : public VtsRemotelyProvisionedComponentTests {
+  protected:
+    CertificateRequestTestBase()
+        : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(64)) {}
+
+    void generateTestEekChain(size_t eekLength) {
+        auto chain = generateEekChain(rpcHardwareInfo.supportedEekCurve, eekLength, eekId_);
+        ASSERT_TRUE(chain) << chain.message();
+        if (chain) testEekChain_ = chain.moveValue();
+        testEekLength_ = eekLength;
+    }
+
+    void generateKeys(bool testMode, size_t numKeys) {
+        keysToSign_ = std::vector<MacedPublicKey>(numKeys);
+        cborKeysToSign_ = cppbor::Array();
+
+        for (auto& key : keysToSign_) {
+            bytevec privateKeyBlob;
+            auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &key, &privateKeyBlob);
+            ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+            vector<uint8_t> payload_value;
+            check_maced_pubkey(key, testMode, &payload_value);
+            cborKeysToSign_.add(cppbor::EncodedItem(payload_value));
+        }
+    }
+
+    bytevec eekId_;
+    size_t testEekLength_;
+    EekChain testEekChain_;
+    bytevec challenge_;
+    std::vector<MacedPublicKey> keysToSign_;
+    cppbor::Array cborKeysToSign_;
+};
+
+class CertificateRequestTest : public CertificateRequestTestBase {
+  protected:
+    void SetUp() override {
+        CertificateRequestTestBase::SetUp();
+        ASSERT_FALSE(HasFatalFailure());
+
+        if (rpcHardwareInfo.versionNumber >= VERSION_WITH_CERTIFICATE_REQUEST_V2) {
+            GTEST_SKIP() << "This test case only applies to RKP v1 and v2. "
+                         << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
+        }
+    }
+};
+
+/**
+ * Generate an empty certificate request in test mode, and decrypt and verify the structure and
+ * content.
+ */
+TEST_P(CertificateRequestTest, EmptyRequest_testMode) {
+    bool testMode = true;
+    for (size_t eekLength : {2, 3, 7}) {
+        SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
+        generateTestEekChain(eekLength);
+
+        bytevec keysToSignMac;
+        DeviceInfo deviceInfo;
+        ProtectedData protectedData;
+        auto status = provisionable_->generateCertificateRequest(
+                testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
+                &protectedData, &keysToSignMac);
+        ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+        auto result = verifyProductionProtectedData(
+                deviceInfo, cppbor::Array(), keysToSignMac, protectedData, testEekChain_, eekId_,
+                rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
+        ASSERT_TRUE(result) << result.message();
+    }
+}
+
+/**
+ * Ensure that test mode outputs a unique BCC root key every time we request a
+ * certificate request. Else, it's possible that the test mode API could be used
+ * to fingerprint devices. Only the GEEK should be allowed to decrypt the same
+ * device public key multiple times.
+ */
+TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) {
+    constexpr bool testMode = true;
+
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    generateTestEekChain(3);
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+    auto firstBcc = verifyProductionProtectedData(
+            deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
+            eekId_, rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
+    ASSERT_TRUE(firstBcc) << firstBcc.message();
+
+    status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+    auto secondBcc = verifyProductionProtectedData(
+            deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
+            eekId_, rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
+    ASSERT_TRUE(secondBcc) << secondBcc.message();
+
+    // Verify that none of the keys in the first BCC are repeated in the second one.
+    for (const auto& i : *firstBcc) {
+        for (auto& j : *secondBcc) {
+            ASSERT_THAT(i.pubKey, testing::Not(testing::ElementsAreArray(j.pubKey)))
+                    << "Found a repeated pubkey in two generateCertificateRequest test mode calls";
+        }
+    }
+}
+
+/**
+ * Generate an empty certificate request in prod mode. This test must be run explicitly, and
+ * is not run by default. Not all devices are GMS devices, and therefore they do not all
+ * trust the Google EEK root.
+ */
+TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
+    bool testMode = false;
+
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
+            challenge_, &deviceInfo, &protectedData, &keysToSignMac);
+    EXPECT_TRUE(status.isOk());
+}
+
+/**
+ * Generate a non-empty certificate request in test mode.  Decrypt, parse and validate the contents.
+ */
+TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) {
+    bool testMode = true;
+    generateKeys(testMode, 4 /* numKeys */);
+
+    for (size_t eekLength : {2, 3, 7}) {
+        SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
+        generateTestEekChain(eekLength);
+
+        bytevec keysToSignMac;
+        DeviceInfo deviceInfo;
+        ProtectedData protectedData;
+        auto status = provisionable_->generateCertificateRequest(
+                testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
+                &keysToSignMac);
+        ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+        auto result = verifyProductionProtectedData(
+                deviceInfo, cborKeysToSign_, keysToSignMac, protectedData, testEekChain_, eekId_,
+                rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
+        ASSERT_TRUE(result) << result.message();
+    }
+}
+
+/**
+ * Generate a non-empty certificate request in prod mode. This test must be run explicitly, and
+ * is not run by default. Not all devices are GMS devices, and therefore they do not all
+ * trust the Google EEK root.
+ */
+TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
+    bool testMode = false;
+    generateKeys(testMode, 4 /* numKeys */);
+
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, keysToSign_, getProdEekChain(rpcHardwareInfo.supportedEekCurve), challenge_,
+            &deviceInfo, &protectedData, &keysToSignMac);
+    EXPECT_TRUE(status.isOk());
+}
+
+/**
+ * Generate a non-empty certificate request in test mode, but with the MAC corrupted on the keypair.
+ */
+TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_testMode) {
+    bool testMode = true;
+    generateKeys(testMode, 1 /* numKeys */);
+    auto result = corrupt_maced_key(keysToSign_[0]);
+    ASSERT_TRUE(result) << result.moveMessage();
+    MacedPublicKey keyWithCorruptMac = result.moveValue();
+
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    generateTestEekChain(3);
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
+}
+
+/**
+ * Generate a non-empty certificate request in prod mode, but with the MAC corrupted on the keypair.
+ */
+TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) {
+    bool testMode = false;
+    generateKeys(testMode, 1 /* numKeys */);
+    auto result = corrupt_maced_key(keysToSign_[0]);
+    ASSERT_TRUE(result) << result.moveMessage();
+    MacedPublicKey keyWithCorruptMac = result.moveValue();
+
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, {keyWithCorruptMac}, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
+            challenge_, &deviceInfo, &protectedData, &keysToSignMac);
+    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
+}
+
+/**
+ * Generate a non-empty certificate request in prod mode that has a corrupt EEK chain.
+ * Confirm that the request is rejected.
+ */
+TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) {
+    bool testMode = false;
+    generateKeys(testMode, 4 /* numKeys */);
+
+    auto prodEekChain = getProdEekChain(rpcHardwareInfo.supportedEekCurve);
+    auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain);
+    ASSERT_NE(parsedChain, nullptr) << parseErr;
+    ASSERT_NE(parsedChain->asArray(), nullptr);
+
+    for (int ii = 0; ii < parsedChain->asArray()->size(); ++ii) {
+        auto chain = corrupt_sig_chain(prodEekChain, ii);
+        ASSERT_TRUE(chain) << chain.message();
+
+        bytevec keysToSignMac;
+        DeviceInfo deviceInfo;
+        ProtectedData protectedData;
+        auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, *chain,
+                                                                 challenge_, &deviceInfo,
+                                                                 &protectedData, &keysToSignMac);
+        ASSERT_FALSE(status.isOk());
+        ASSERT_EQ(status.getServiceSpecificError(),
+                  BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
+    }
+}
+
+/**
+ * Generate a non-empty certificate request in prod mode that has an incomplete EEK chain.
+ * Confirm that the request is rejected.
+ */
+TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) {
+    bool testMode = false;
+    generateKeys(testMode, 4 /* numKeys */);
+
+    // Build an EEK chain that omits the first self-signed cert.
+    auto truncatedChain = cppbor::Array();
+    auto [chain, _, parseErr] = cppbor::parse(getProdEekChain(rpcHardwareInfo.supportedEekCurve));
+    ASSERT_TRUE(chain);
+    auto eekChain = chain->asArray();
+    ASSERT_NE(eekChain, nullptr);
+    for (size_t ii = 1; ii < eekChain->size(); ii++) {
+        truncatedChain.add(eekChain->get(ii)->clone());
+    }
+
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, keysToSign_, truncatedChain.encode(), challenge_, &deviceInfo, &protectedData,
+            &keysToSignMac);
+    ASSERT_FALSE(status.isOk());
+    ASSERT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
+}
+
+/**
+ * Generate a non-empty certificate request in test mode, with prod keys.  Must fail with
+ * STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
+ */
+TEST_P(CertificateRequestTest, NonEmptyRequest_prodKeyInTestCert) {
+    generateKeys(false /* testMode */, 2 /* numKeys */);
+
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    generateTestEekChain(3);
+    auto status = provisionable_->generateCertificateRequest(
+            true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_FALSE(status.isOk());
+    ASSERT_EQ(status.getServiceSpecificError(),
+              BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST);
+}
+
+/**
+ * Generate a non-empty certificate request in prod mode, with test keys.  Must fail with
+ * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
+ */
+TEST_P(CertificateRequestTest, NonEmptyRequest_testKeyInProdCert) {
+    generateKeys(true /* testMode */, 2 /* numKeys */);
+
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    generateTestEekChain(3);
+    auto status = provisionable_->generateCertificateRequest(
+            false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_FALSE(status.isOk());
+    ASSERT_EQ(status.getServiceSpecificError(),
+              BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
+}
+
+INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestTest);
+
+class CertificateRequestV2Test : public CertificateRequestTestBase {
+    void SetUp() override {
+        CertificateRequestTestBase::SetUp();
+        ASSERT_FALSE(HasFatalFailure());
+
+        if (rpcHardwareInfo.versionNumber < VERSION_WITH_CERTIFICATE_REQUEST_V2) {
+            GTEST_SKIP() << "This test case only applies to RKP v3 and above. "
+                         << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
+        }
+    }
+};
+
+/**
+ * Generate an empty certificate request with all possible length of challenge, and decrypt and
+ * verify the structure and content.
+ */
+// @VsrTest = 3.10-015
+TEST_P(CertificateRequestV2Test, EmptyRequest) {
+    bytevec csr;
+
+    for (auto size = MIN_CHALLENGE_SIZE; size <= MAX_CHALLENGE_SIZE; size++) {
+        SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
+        auto challenge = randomBytes(size);
+        auto status =
+                provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
+        ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+        auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge);
+        ASSERT_TRUE(result) << result.message();
+    }
+}
+
+/**
+ * Generate a non-empty certificate request with all possible length of challenge.  Decrypt, parse
+ * and validate the contents.
+ */
+// @VsrTest = 3.10-015
+TEST_P(CertificateRequestV2Test, NonEmptyRequest) {
+    generateKeys(false /* testMode */, 1 /* numKeys */);
+
+    bytevec csr;
+
+    for (auto size = MIN_CHALLENGE_SIZE; size <= MAX_CHALLENGE_SIZE; size++) {
+        SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
+        auto challenge = randomBytes(size);
+        auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge, &csr);
+        ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+        auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge);
+        ASSERT_TRUE(result) << result.message();
+    }
+}
+
+/**
+ * Generate an empty certificate request with invalid size of challenge
+ */
+TEST_P(CertificateRequestV2Test, EmptyRequestWithInvalidChallengeFail) {
+    bytevec csr;
+
+    auto status = provisionable_->generateCertificateRequestV2(
+            /* keysToSign */ {}, randomBytes(MAX_CHALLENGE_SIZE + 1), &csr);
+    EXPECT_FALSE(status.isOk()) << status.getMessage();
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_FAILED);
+}
+
+/**
+ * Generate a non-empty certificate request.  Make sure contents are reproducible but allow for the
+ * signature to be different since algorithms including ECDSA P-256 can include a random value.
+ */
+// @VsrTest = 3.10-015
+TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) {
+    generateKeys(false /* testMode */, 1 /* numKeys */);
+
+    bytevec csr;
+
+    auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+    auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
+    ASSERT_TRUE(firstCsr) << firstCsr.message();
+
+    status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+    auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
+    ASSERT_TRUE(secondCsr) << secondCsr.message();
+
+    ASSERT_EQ(**firstCsr, **secondCsr);
+}
+
+/**
+ * Generate a non-empty certificate request with multiple keys.
+ */
+// @VsrTest = 3.10-015
+TEST_P(CertificateRequestV2Test, NonEmptyRequestMultipleKeys) {
+    generateKeys(false /* testMode */, rpcHardwareInfo.supportedNumKeysInCsr /* numKeys */);
+
+    bytevec csr;
+
+    auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+    auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
+    ASSERT_TRUE(result) << result.message();
+}
+
+/**
+ * Generate a non-empty certificate request, but with the MAC corrupted on the keypair.
+ */
+TEST_P(CertificateRequestV2Test, NonEmptyRequestCorruptMac) {
+    generateKeys(false /* testMode */, 1 /* numKeys */);
+    auto result = corrupt_maced_key(keysToSign_[0]);
+    ASSERT_TRUE(result) << result.moveMessage();
+    MacedPublicKey keyWithCorruptMac = result.moveValue();
+
+    bytevec csr;
+    auto status =
+            provisionable_->generateCertificateRequestV2({keyWithCorruptMac}, challenge_, &csr);
+    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
+}
+
+/**
+ * Call generateCertificateRequest(). Make sure it's removed.
+ */
+TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_prodMode) {
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            false /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
+}
+
+/**
+ * Call generateCertificateRequest() in test mode. Make sure it's removed.
+ */
+TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_testMode) {
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            true /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
+}
+
+void parse_root_of_trust(const vector<uint8_t>& attestation_cert,
+                         vector<uint8_t>* verified_boot_key, VerifiedBoot* verified_boot_state,
+                         bool* device_locked, vector<uint8_t>* verified_boot_hash) {
+    X509_Ptr cert(parse_cert_blob(attestation_cert));
+    ASSERT_TRUE(cert.get());
+
+    ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
+    ASSERT_TRUE(attest_rec);
+
+    auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, verified_boot_key,
+                                     verified_boot_state, device_locked, verified_boot_hash);
+    ASSERT_EQ(error, ErrorCode::OK);
+}
+
+/**
+ * Generate a CSR and verify DeviceInfo against IDs attested by KeyMint.
+ */
+// @VsrTest = 3.10-015
+TEST_P(CertificateRequestV2Test, DeviceInfo) {
+    // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
+    std::shared_ptr<IKeyMintDevice> keyMint;
+    if (!matching_keymint_device(GetParam(), &keyMint)) {
+        // No matching IKeyMintDevice.
+        GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
+        return;
+    }
+    KeyMintHardwareInfo info;
+    ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
+
+    // Get IDs attested by KeyMint.
+    MacedPublicKey macedPubKey;
+    bytevec privateKeyBlob;
+    auto irpcStatus =
+            provisionable_->generateEcdsaP256KeyPair(false, &macedPubKey, &privateKeyBlob);
+    ASSERT_TRUE(irpcStatus.isOk());
+
+    AttestationKey attestKey;
+    attestKey.keyBlob = std::move(privateKeyBlob);
+    attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
+
+    // Generate an ECDSA key that is attested by the generated P256 keypair.
+    AuthorizationSet keyDesc = AuthorizationSetBuilder()
+                                       .Authorization(TAG_NO_AUTH_REQUIRED)
+                                       .EcdsaSigningKey(EcCurve::P_256)
+                                       .AttestationChallenge("foo")
+                                       .AttestationApplicationId("bar")
+                                       .Digest(Digest::NONE)
+                                       .SetDefaultValidity();
+    KeyCreationResult creationResult;
+    auto kmStatus = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
+    ASSERT_TRUE(kmStatus.isOk());
+
+    vector<KeyCharacteristics> key_characteristics = std::move(creationResult.keyCharacteristics);
+    vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
+    // We didn't provision the attestation key.
+    ASSERT_EQ(key_cert_chain.size(), 1);
+
+    // Parse attested patch levels.
+    auto auths = HwEnforcedAuthorizations(key_characteristics);
+
+    auto attestedSystemPatchLevel = auths.GetTagValue(TAG_OS_PATCHLEVEL);
+    auto attestedVendorPatchLevel = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
+    auto attestedBootPatchLevel = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
+
+    ASSERT_TRUE(attestedSystemPatchLevel.has_value());
+    ASSERT_TRUE(attestedVendorPatchLevel.has_value());
+    ASSERT_TRUE(attestedBootPatchLevel.has_value());
+
+    // Parse attested AVB values.
+    vector<uint8_t> key;
+    VerifiedBoot attestedVbState;
+    bool attestedBootloaderState;
+    vector<uint8_t> attestedVbmetaDigest;
+    parse_root_of_trust(key_cert_chain[0].encodedCertificate, &key, &attestedVbState,
+                        &attestedBootloaderState, &attestedVbmetaDigest);
+
+    // Get IDs from DeviceInfo.
+    bytevec csr;
+    irpcStatus =
+            provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
+    ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getMessage();
+
+    auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge_);
+    ASSERT_TRUE(result) << result.message();
+
+    std::unique_ptr<cppbor::Array> csrPayload = std::move(*result);
+    ASSERT_TRUE(csrPayload);
+
+    auto deviceInfo = csrPayload->get(2)->asMap();
+    ASSERT_TRUE(deviceInfo);
+
+    auto vbState = deviceInfo->get("vb_state")->asTstr();
+    auto bootloaderState = deviceInfo->get("bootloader_state")->asTstr();
+    auto vbmetaDigest = deviceInfo->get("vbmeta_digest")->asBstr();
+    auto systemPatchLevel = deviceInfo->get("system_patch_level")->asUint();
+    auto vendorPatchLevel = deviceInfo->get("vendor_patch_level")->asUint();
+    auto bootPatchLevel = deviceInfo->get("boot_patch_level")->asUint();
+    auto securityLevel = deviceInfo->get("security_level")->asTstr();
+
+    ASSERT_TRUE(vbState);
+    ASSERT_TRUE(bootloaderState);
+    ASSERT_TRUE(vbmetaDigest);
+    ASSERT_TRUE(systemPatchLevel);
+    ASSERT_TRUE(vendorPatchLevel);
+    ASSERT_TRUE(bootPatchLevel);
+    ASSERT_TRUE(securityLevel);
+
+    auto kmDeviceName = device_suffix(GetParam());
+
+    // Compare DeviceInfo against IDs attested by KeyMint.
+    ASSERT_TRUE((securityLevel->value() == "tee" && kmDeviceName == "default") ||
+                (securityLevel->value() == "strongbox" && kmDeviceName == "strongbox"));
+    ASSERT_TRUE((vbState->value() == "green" && attestedVbState == VerifiedBoot::VERIFIED) ||
+                (vbState->value() == "yellow" && attestedVbState == VerifiedBoot::SELF_SIGNED) ||
+                (vbState->value() == "orange" && attestedVbState == VerifiedBoot::UNVERIFIED));
+    ASSERT_TRUE((bootloaderState->value() == "locked" && attestedBootloaderState) ||
+                (bootloaderState->value() == "unlocked" && !attestedBootloaderState));
+    ASSERT_EQ(vbmetaDigest->value(), attestedVbmetaDigest);
+    ASSERT_EQ(systemPatchLevel->value(), attestedSystemPatchLevel.value());
+    ASSERT_EQ(vendorPatchLevel->value(), attestedVendorPatchLevel.value());
+    ASSERT_EQ(bootPatchLevel->value(), attestedBootPatchLevel.value());
+}
+
+INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestV2Test);
+
+using VsrRequirementTest = VtsRemotelyProvisionedComponentTests;
+
+INSTANTIATE_REM_PROV_AIDL_TEST(VsrRequirementTest);
+
+TEST_P(VsrRequirementTest, VsrEnforcementTest) {
+    RpcHardwareInfo hwInfo;
+    ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < 34) {
+        GTEST_SKIP() << "Applies only to VSR API level 34 or newer, this device is: "
+                     << vsr_api_level;
+    }
+    EXPECT_GE(hwInfo.versionNumber, 3)
+            << "VSR 14+ requires IRemotelyProvisionedComponent v3 or newer.";
+}
+
+}  // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
similarity index 100%
rename from security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
rename to security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
diff --git a/security/secureclock/aidl/Android.bp b/security/secureclock/aidl/Android.bp
index 00a6ba3..853ad89 100644
--- a/security/secureclock/aidl/Android.bp
+++ b/security/secureclock/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
         rust: {
             enabled: true,
             apex_available: [
diff --git a/security/sharedsecret/aidl/Android.bp b/security/sharedsecret/aidl/Android.bp
index f1fce74..fe77c10 100644
--- a/security/sharedsecret/aidl/Android.bp
+++ b/security/sharedsecret/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
         rust: {
             enabled: true,
         },
diff --git a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
index 8144699..b72f0de 100644
--- a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
+++ b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
@@ -33,9 +33,9 @@
     byte[] seed;
 
     /**
-     * A 32-byte value which is guaranteed to be different each time
-     * getSharedSecretParameters() is called.  Probabilistic uniqueness (i.e. random) is acceptable,
-     * though a stronger uniqueness guarantee (e.g. counter) is recommended where possible.
+     * A 32-byte value which is guaranteed to be different each time getSharedSecretParameters() is
+     * called after a restart.  Probabilistic uniqueness (i.e. random) is acceptable, though a
+     * stronger uniqueness guarantee (e.g. counter) is recommended where possible.
      */
     byte[] nonce;
 }
diff --git a/sensors/1.0/default/Android.bp b/sensors/1.0/default/Android.bp
index 2e4e1b0..bb31050 100644
--- a/sensors/1.0/default/Android.bp
+++ b/sensors/1.0/default/Android.bp
@@ -44,6 +44,12 @@
         "libhidlbase",
         "android.hardware.sensors@1.0",
     ],
+    whole_static_libs: [
+        "sensors_common_convert",
+    ],
+    export_static_lib_headers: [
+        "sensors_common_convert",
+    ],
     local_include_dirs: ["include/sensors"],
     export_shared_lib_headers: [
         "libhardware",
diff --git a/sensors/1.0/default/OWNERS b/sensors/1.0/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/1.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/1.0/default/convert.cpp b/sensors/1.0/default/convert.cpp
index 43ee327..ae71a97 100644
--- a/sensors/1.0/default/convert.cpp
+++ b/sensors/1.0/default/convert.cpp
@@ -196,6 +196,11 @@
     }
 }
 
+void convertFromASensorEvent(const ASensorEvent& src, Event* dst) {
+    convertFromSensorEvent(
+            android::hardware::sensors::implementation::common::convertASensorEvent(src), dst);
+}
+
 void convertToSensorEvent(const Event &src, sensors_event_t *dst) {
     *dst = {.version = sizeof(sensors_event_t),
             .sensor = src.sensorHandle,
diff --git a/sensors/1.0/default/include/sensors/convert.h b/sensors/1.0/default/include/sensors/convert.h
index c3a0125..ae773df 100644
--- a/sensors/1.0/default/include/sensors/convert.h
+++ b/sensors/1.0/default/include/sensors/convert.h
@@ -20,6 +20,7 @@
 
 #include <android/hardware/sensors/1.0/ISensors.h>
 #include <hardware/sensors.h>
+#include <sensors/common_convert.h>
 
 namespace android {
 namespace hardware {
@@ -31,6 +32,7 @@
 void convertToSensor(const SensorInfo &src, sensor_t *dst);
 
 void convertFromSensorEvent(const sensors_event_t &src, Event *dst);
+void convertFromASensorEvent(const ASensorEvent& src, Event* dst);
 void convertToSensorEvent(const Event &src, sensors_event_t *dst);
 
 bool convertFromSharedMemInfo(const SharedMemInfo& memIn, sensors_direct_mem_t *memOut);
diff --git a/sensors/1.0/vts/functional/OWNERS b/sensors/1.0/vts/functional/OWNERS
deleted file mode 100644
index e20125b..0000000
--- a/sensors/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 62965
-include ../../../common/vts/OWNERS
diff --git a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
index b802e6c..a4e4457 100644
--- a/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
+++ b/sensors/1.0/vts/functional/SensorsHidlEnvironmentV1_0.h
@@ -46,8 +46,6 @@
     bool resetHal() override;
     void startPollingThread() override;
     static void pollingThread(SensorsHidlEnvironmentV1_0* env, std::atomic_bool& stop);
-
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentV1_0);
 };
 
 #endif  // ANDROID_SENSORS_HIDL_ENVIRONMENT_V1_0_H
\ No newline at end of file
diff --git a/sensors/2.0/default/OWNERS b/sensors/2.0/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/2.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/2.0/multihal/OWNERS b/sensors/2.0/multihal/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/2.0/multihal/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc b/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc
index 8867a1a..c874604 100644
--- a/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc
+++ b/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc
@@ -1,7 +1,7 @@
 service vendor.sensors-hal-2-0-multihal /vendor/bin/hw/android.hardware.sensors@2.0-service.multihal
     class hal
     user system
-    group system wakelock context_hub
+    group system wakelock context_hub input
     task_profiles ServiceCapacityLow
     capabilities BLOCK_SUSPEND
     rlimit rtprio 10 10
diff --git a/sensors/2.0/vts/functional/OWNERS b/sensors/2.0/vts/functional/OWNERS
deleted file mode 100644
index e20125b..0000000
--- a/sensors/2.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 62965
-include ../../../common/vts/OWNERS
diff --git a/sensors/2.1/default/OWNERS b/sensors/2.1/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/2.1/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/2.1/default/apex/Android.bp b/sensors/2.1/default/apex/Android.bp
deleted file mode 100644
index 3345b92..0000000
--- a/sensors/2.1/default/apex/Android.bp
+++ /dev/null
@@ -1,46 +0,0 @@
-package {
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-apex_key {
-    name: "com.android.hardware.sensors.key",
-    public_key: "com.android.hardware.sensors.avbpubkey",
-    private_key: "com.android.hardware.sensors.pem",
-}
-
-android_app_certificate {
-    name: "com.android.hardware.sensors.certificate",
-    certificate: "com.android.hardware.sensors",
-}
-
-prebuilt_etc {
-    name: "com.android.hardware.sensors.rc",
-    src: "com.android.hardware.sensors.rc",
-    installable: false,
-}
-
-// Default vendor APEX for android.hardware.sensors.
-// Custom implementations may use override_apex based on this APEX.
-apex {
-    name: "com.android.hardware.sensors",
-    manifest: "apex_manifest.json",
-    key: "com.android.hardware.sensors.key",
-    certificate: ":com.android.hardware.sensors.certificate",
-    file_contexts: "file_contexts",
-    use_vndk_as_stable: true,
-    updatable: false,
-    // Install the apex in /vendor/apex
-    soc_specific: true,
-    binaries: ["android.hardware.sensors@2.1-service.mock"],
-    prebuilts: [
-        "com.android.hardware.sensors.rc",
-        "android.hardware.sensor.ambient_temperature.prebuilt.xml",
-        "android.hardware.sensor.barometer.prebuilt.xml",
-        "android.hardware.sensor.gyroscope.prebuilt.xml",
-        "android.hardware.sensor.hinge_angle.prebuilt.xml",
-        "android.hardware.sensor.light.prebuilt.xml",
-        "android.hardware.sensor.proximity.prebuilt.xml",
-        "android.hardware.sensor.relative_humidity.prebuilt.xml",
-    ],
-    vintf_fragments: [":android.hardware.sensors@2.1.xml"],
-}
diff --git a/sensors/2.1/default/apex/apex_manifest.json b/sensors/2.1/default/apex/apex_manifest.json
deleted file mode 100644
index 47e45ee..0000000
--- a/sensors/2.1/default/apex/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.hardware.sensors",
-  "version": 1
-}
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.rc b/sensors/2.1/default/apex/com.android.hardware.sensors.rc
deleted file mode 100644
index bd245b4..0000000
--- a/sensors/2.1/default/apex/com.android.hardware.sensors.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-service vendor.sensors-hal-2-1-mock /apex/com.android.hardware.sensors/bin/hw/android.hardware.sensors@2.1-service.mock
-    interface android.hardware.sensors@2.0::ISensors default
-    interface android.hardware.sensors@2.1::ISensors default
-    class hal
-    user system
-    group system
-    rlimit rtprio 10 10
diff --git a/sensors/2.1/default/apex/file_contexts b/sensors/2.1/default/apex/file_contexts
deleted file mode 100644
index d0095c0..0000000
--- a/sensors/2.1/default/apex/file_contexts
+++ /dev/null
@@ -1,5 +0,0 @@
-(/.*)?							u:object_r:vendor_file:s0
-# Permission XMLs
-/etc/permissions(/.*)?					u:object_r:vendor_configs_file:s0
-# Service binary
-/bin/hw/android\.hardware\.sensors@2\.1-service\.mock	u:object_r:hal_sensors_default_exec:s0
diff --git a/sensors/2.1/multihal/OWNERS b/sensors/2.1/multihal/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/2.1/multihal/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc b/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc
index f47e060..deea16e 100644
--- a/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc
+++ b/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc
@@ -1,7 +1,7 @@
 service vendor.sensors-hal-2-1-multihal /vendor/bin/hw/android.hardware.sensors@2.1-service.multihal
     class hal
     user system
-    group system wakelock context_hub
+    group system wakelock context_hub input
     task_profiles ServiceCapacityLow
     capabilities BLOCK_SUSPEND
     rlimit rtprio 10 10
diff --git a/sensors/2.1/vts/functional/OWNERS b/sensors/2.1/vts/functional/OWNERS
deleted file mode 100644
index e20125b..0000000
--- a/sensors/2.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 62965
-include ../../../common/vts/OWNERS
diff --git a/sensors/OWNERS b/sensors/OWNERS
new file mode 100644
index 0000000..e7ebd3e
--- /dev/null
+++ b/sensors/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 62965
+
+arthuri@google.com
+bduddie@google.com
+stange@google.com
diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp
index 1c2d83f..3914ec1 100644
--- a/sensors/aidl/Android.bp
+++ b/sensors/aidl/Android.bp
@@ -11,6 +11,7 @@
     name: "android.hardware.sensors",
     vendor_available: true,
     srcs: ["android/hardware/sensors/*.aidl"],
+    host_supported: true,
     imports: [
         "android.hardware.common-V2",
         "android.hardware.common.fmq-V1",
@@ -23,11 +24,6 @@
         java: {
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
@@ -37,6 +33,15 @@
                 "android.hardware.common.fmq-V1",
             ],
         },
+        {
+            version: "2",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.common.fmq-V1",
+            ],
+        },
+
     ],
+    frozen: true,
 
 }
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/2/.hash b/sensors/aidl/aidl_api/android.hardware.sensors/2/.hash
new file mode 100644
index 0000000..f04da9f
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/2/.hash
@@ -0,0 +1 @@
+8cdc9f2ea08fd57e6c60a600fea28a51a2ff12f9
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/AdditionalInfo.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/AdditionalInfo.aidl
new file mode 100644
index 0000000..a35b54c
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/AdditionalInfo.aidl
@@ -0,0 +1,76 @@
+/*
+ * 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.sensors;
+@FixedSize @VintfStability
+parcelable AdditionalInfo {
+  android.hardware.sensors.AdditionalInfo.AdditionalInfoType type;
+  int serial;
+  android.hardware.sensors.AdditionalInfo.AdditionalInfoPayload payload;
+  @FixedSize @VintfStability
+  union AdditionalInfoPayload {
+    android.hardware.sensors.AdditionalInfo.AdditionalInfoPayload.Int32Values dataInt32;
+    android.hardware.sensors.AdditionalInfo.AdditionalInfoPayload.FloatValues dataFloat;
+    @FixedSize @VintfStability
+    parcelable Int32Values {
+      int[14] values;
+    }
+    @FixedSize @VintfStability
+    parcelable FloatValues {
+      float[14] values;
+    }
+  }
+  @Backing(type="int") @VintfStability
+  enum AdditionalInfoType {
+    AINFO_BEGIN = 0,
+    AINFO_END = 1,
+    AINFO_UNTRACKED_DELAY = 0x10000,
+    AINFO_INTERNAL_TEMPERATURE,
+    AINFO_VEC3_CALIBRATION,
+    AINFO_SENSOR_PLACEMENT,
+    AINFO_SAMPLING,
+    AINFO_CHANNEL_NOISE = 0x20000,
+    AINFO_CHANNEL_SAMPLER,
+    AINFO_CHANNEL_FILTER,
+    AINFO_CHANNEL_LINEAR_TRANSFORM,
+    AINFO_CHANNEL_NONLINEAR_MAP,
+    AINFO_CHANNEL_RESAMPLER,
+    AINFO_LOCAL_GEOMAGNETIC_FIELD = 0x30000,
+    AINFO_LOCAL_GRAVITY,
+    AINFO_DOCK_STATE,
+    AINFO_HIGH_PERFORMANCE_MODE,
+    AINFO_MAGNETIC_FIELD_CALIBRATION,
+    AINFO_CUSTOM_START = 0x10000000,
+    AINFO_DEBUGGING_START = 0x40000000,
+  }
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/DynamicSensorInfo.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/DynamicSensorInfo.aidl
new file mode 100644
index 0000000..0c9a493
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/DynamicSensorInfo.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.sensors;
+@FixedSize @VintfStability
+parcelable DynamicSensorInfo {
+  boolean connected;
+  int sensorHandle;
+  android.hardware.sensors.DynamicSensorInfo.Uuid uuid;
+  @FixedSize @VintfStability
+  parcelable Uuid {
+    byte[16] values;
+  }
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/Event.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/Event.aidl
new file mode 100644
index 0000000..4f49002
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/Event.aidl
@@ -0,0 +1,139 @@
+/*
+ * 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.sensors;
+@FixedSize @VintfStability
+parcelable Event {
+  long timestamp;
+  int sensorHandle;
+  android.hardware.sensors.SensorType sensorType;
+  android.hardware.sensors.Event.EventPayload payload;
+  @FixedSize @VintfStability
+  union EventPayload {
+    android.hardware.sensors.Event.EventPayload.Vec3 vec3;
+    android.hardware.sensors.Event.EventPayload.Vec4 vec4;
+    android.hardware.sensors.Event.EventPayload.Uncal uncal;
+    android.hardware.sensors.Event.EventPayload.MetaData meta;
+    float scalar;
+    long stepCount;
+    android.hardware.sensors.Event.EventPayload.HeartRate heartRate;
+    android.hardware.sensors.Event.EventPayload.Pose6Dof pose6DOF;
+    android.hardware.sensors.DynamicSensorInfo dynamic;
+    android.hardware.sensors.AdditionalInfo additional;
+    android.hardware.sensors.Event.EventPayload.Data data;
+    android.hardware.sensors.Event.EventPayload.HeadTracker headTracker;
+    android.hardware.sensors.Event.EventPayload.LimitedAxesImu limitedAxesImu;
+    android.hardware.sensors.Event.EventPayload.LimitedAxesImuUncal limitedAxesImuUncal;
+    android.hardware.sensors.Event.EventPayload.Heading heading;
+    @FixedSize @VintfStability
+    parcelable Vec4 {
+      float x;
+      float y;
+      float z;
+      float w;
+    }
+    @FixedSize @VintfStability
+    parcelable Vec3 {
+      float x;
+      float y;
+      float z;
+      android.hardware.sensors.SensorStatus status;
+    }
+    @FixedSize @VintfStability
+    parcelable Uncal {
+      float x;
+      float y;
+      float z;
+      float xBias;
+      float yBias;
+      float zBias;
+    }
+    @FixedSize @VintfStability
+    parcelable HeadTracker {
+      float rx;
+      float ry;
+      float rz;
+      float vx;
+      float vy;
+      float vz;
+      int discontinuityCount;
+    }
+    @FixedSize @VintfStability
+    parcelable LimitedAxesImu {
+      float x;
+      float y;
+      float z;
+      float xSupported;
+      float ySupported;
+      float zSupported;
+    }
+    @FixedSize @VintfStability
+    parcelable LimitedAxesImuUncal {
+      float x;
+      float y;
+      float z;
+      float xBias;
+      float yBias;
+      float zBias;
+      float xSupported;
+      float ySupported;
+      float zSupported;
+    }
+    @FixedSize @VintfStability
+    parcelable HeartRate {
+      float bpm;
+      android.hardware.sensors.SensorStatus status;
+    }
+    @FixedSize @VintfStability
+    parcelable Heading {
+      float heading;
+      float accuracy;
+    }
+    @FixedSize @VintfStability
+    parcelable MetaData {
+      android.hardware.sensors.Event.EventPayload.MetaData.MetaDataEventType what;
+      @Backing(type="int") @VintfStability
+      enum MetaDataEventType {
+        META_DATA_FLUSH_COMPLETE = 1,
+      }
+    }
+    @FixedSize @VintfStability
+    parcelable Pose6Dof {
+      float[15] values;
+    }
+    @FixedSize @VintfStability
+    parcelable Data {
+      float[16] values;
+    }
+  }
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/ISensors.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/ISensors.aidl
new file mode 100644
index 0000000..0566a64
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/ISensors.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.sensors;
+@VintfStability
+interface ISensors {
+  void activate(in int sensorHandle, in boolean enabled);
+  void batch(in int sensorHandle, in long samplingPeriodNs, in long maxReportLatencyNs);
+  int configDirectReport(in int sensorHandle, in int channelHandle, in android.hardware.sensors.ISensors.RateLevel rate);
+  void flush(in int sensorHandle);
+  android.hardware.sensors.SensorInfo[] getSensorsList();
+  void initialize(in android.hardware.common.fmq.MQDescriptor<android.hardware.sensors.Event,android.hardware.common.fmq.SynchronizedReadWrite> eventQueueDescriptor, in android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> wakeLockDescriptor, in android.hardware.sensors.ISensorsCallback sensorsCallback);
+  void injectSensorData(in android.hardware.sensors.Event event);
+  int registerDirectChannel(in android.hardware.sensors.ISensors.SharedMemInfo mem);
+  void setOperationMode(in android.hardware.sensors.ISensors.OperationMode mode);
+  void unregisterDirectChannel(in int channelHandle);
+  const int ERROR_NO_MEMORY = (-12) /* -12 */;
+  const int ERROR_BAD_VALUE = (-22) /* -22 */;
+  const int WAKE_LOCK_TIMEOUT_SECONDS = 1;
+  const int EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS = (1 << 0) /* 1 */;
+  const int EVENT_QUEUE_FLAG_BITS_EVENTS_READ = (1 << 1) /* 2 */;
+  const int WAKE_LOCK_QUEUE_FLAG_BITS_DATA_WRITTEN = (1 << 0) /* 1 */;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD = 0x0;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN = 0x4;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE = 0x8;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER = 0xC;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP = 0x10;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 0x18;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 0x58;
+  const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
+  const int RUNTIME_SENSORS_HANDLE_BASE = 0x5F000000;
+  const int RUNTIME_SENSORS_HANDLE_END = 0x5FFFFFFF;
+  @Backing(type="int") @VintfStability
+  enum RateLevel {
+    STOP,
+    NORMAL,
+    FAST,
+    VERY_FAST,
+  }
+  @Backing(type="int") @VintfStability
+  enum OperationMode {
+    NORMAL = 0,
+    DATA_INJECTION = 1,
+  }
+  @VintfStability
+  parcelable SharedMemInfo {
+    android.hardware.sensors.ISensors.SharedMemInfo.SharedMemType type;
+    android.hardware.sensors.ISensors.SharedMemInfo.SharedMemFormat format;
+    int size;
+    android.hardware.common.NativeHandle memoryHandle;
+    @Backing(type="int") @VintfStability
+    enum SharedMemFormat {
+      SENSORS_EVENT = 1,
+    }
+    @Backing(type="int") @VintfStability
+    enum SharedMemType {
+      ASHMEM = 1,
+      GRALLOC,
+    }
+  }
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/ISensorsCallback.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/ISensorsCallback.aidl
new file mode 100644
index 0000000..78ab567
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/ISensorsCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.sensors;
+@VintfStability
+interface ISensorsCallback {
+  void onDynamicSensorsConnected(in android.hardware.sensors.SensorInfo[] sensorInfos);
+  void onDynamicSensorsDisconnected(in int[] sensorHandles);
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/SensorInfo.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/SensorInfo.aidl
new file mode 100644
index 0000000..677e6c4
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/SensorInfo.aidl
@@ -0,0 +1,71 @@
+/*
+ * 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.sensors;
+@VintfStability
+parcelable SensorInfo {
+  int sensorHandle;
+  String name;
+  String vendor;
+  int version;
+  android.hardware.sensors.SensorType type;
+  String typeAsString;
+  float maxRange;
+  float resolution;
+  float power;
+  int minDelayUs;
+  int fifoReservedEventCount;
+  int fifoMaxEventCount;
+  String requiredPermission;
+  int maxDelayUs;
+  int flags;
+  const int SENSOR_FLAG_BITS_WAKE_UP = 1;
+  const int SENSOR_FLAG_BITS_CONTINUOUS_MODE = 0;
+  const int SENSOR_FLAG_BITS_ON_CHANGE_MODE = 2;
+  const int SENSOR_FLAG_BITS_ONE_SHOT_MODE = 4;
+  const int SENSOR_FLAG_BITS_SPECIAL_REPORTING_MODE = 6;
+  const int SENSOR_FLAG_BITS_DATA_INJECTION = 0x10;
+  const int SENSOR_FLAG_BITS_DYNAMIC_SENSOR = 0x20;
+  const int SENSOR_FLAG_BITS_ADDITIONAL_INFO = 0x40;
+  const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_ASHMEM = 0x400;
+  const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_GRALLOC = 0x800;
+  const int SENSOR_FLAG_BITS_MASK_REPORTING_MODE = 0xE;
+  const int SENSOR_FLAG_BITS_MASK_DIRECT_REPORT = 0x380;
+  const int SENSOR_FLAG_BITS_MASK_DIRECT_CHANNEL = 0xC00;
+  const int SENSOR_FLAG_SHIFT_REPORTING_MODE = 1;
+  const int SENSOR_FLAG_SHIFT_DATA_INJECTION = 4;
+  const int SENSOR_FLAG_SHIFT_DYNAMIC_SENSOR = 5;
+  const int SENSOR_FLAG_SHIFT_ADDITIONAL_INFO = 6;
+  const int SENSOR_FLAG_SHIFT_DIRECT_REPORT = 7;
+  const int SENSOR_FLAG_SHIFT_DIRECT_CHANNEL = 10;
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/SensorStatus.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/SensorStatus.aidl
new file mode 100644
index 0000000..f401dac
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/SensorStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.sensors;
+@Backing(type="byte") @VintfStability
+enum SensorStatus {
+  NO_CONTACT = (-1) /* -1 */,
+  UNRELIABLE = 0,
+  ACCURACY_LOW = 1,
+  ACCURACY_MEDIUM = 2,
+  ACCURACY_HIGH = 3,
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/SensorType.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/SensorType.aidl
new file mode 100644
index 0000000..0639f13
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/2/android/hardware/sensors/SensorType.aidl
@@ -0,0 +1,80 @@
+/*
+ * 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.sensors;
+@Backing(type="int") @VintfStability
+enum SensorType {
+  META_DATA = 0,
+  ACCELEROMETER = 1,
+  MAGNETIC_FIELD = 2,
+  ORIENTATION = 3,
+  GYROSCOPE = 4,
+  LIGHT = 5,
+  PRESSURE = 6,
+  PROXIMITY = 8,
+  GRAVITY = 9,
+  LINEAR_ACCELERATION = 10,
+  ROTATION_VECTOR = 11,
+  RELATIVE_HUMIDITY = 12,
+  AMBIENT_TEMPERATURE = 13,
+  MAGNETIC_FIELD_UNCALIBRATED = 14,
+  GAME_ROTATION_VECTOR = 15,
+  GYROSCOPE_UNCALIBRATED = 16,
+  SIGNIFICANT_MOTION = 17,
+  STEP_DETECTOR = 18,
+  STEP_COUNTER = 19,
+  GEOMAGNETIC_ROTATION_VECTOR = 20,
+  HEART_RATE = 21,
+  TILT_DETECTOR = 22,
+  WAKE_GESTURE = 23,
+  GLANCE_GESTURE = 24,
+  PICK_UP_GESTURE = 25,
+  WRIST_TILT_GESTURE = 26,
+  DEVICE_ORIENTATION = 27,
+  POSE_6DOF = 28,
+  STATIONARY_DETECT = 29,
+  MOTION_DETECT = 30,
+  HEART_BEAT = 31,
+  DYNAMIC_SENSOR_META = 32,
+  ADDITIONAL_INFO = 33,
+  LOW_LATENCY_OFFBODY_DETECT = 34,
+  ACCELEROMETER_UNCALIBRATED = 35,
+  HINGE_ANGLE = 36,
+  HEAD_TRACKER = 37,
+  ACCELEROMETER_LIMITED_AXES = 38,
+  GYROSCOPE_LIMITED_AXES = 39,
+  ACCELEROMETER_LIMITED_AXES_UNCALIBRATED = 40,
+  GYROSCOPE_LIMITED_AXES_UNCALIBRATED = 41,
+  HEADING = 42,
+  DEVICE_PRIVATE_BASE = 0x10000,
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
index f60f5bb..b26040b 100644
--- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
@@ -58,6 +58,8 @@
   const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 24;
   const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 88;
   const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
+  const int RUNTIME_SENSORS_HANDLE_BASE = 1593835520;
+  const int RUNTIME_SENSORS_HANDLE_END = 1610612735;
   @Backing(type="int") @VintfStability
   enum RateLevel {
     STOP = 0,
diff --git a/sensors/aidl/android/hardware/sensors/ISensors.aidl b/sensors/aidl/android/hardware/sensors/ISensors.aidl
index 2c68489..5e276dd 100644
--- a/sensors/aidl/android/hardware/sensors/ISensors.aidl
+++ b/sensors/aidl/android/hardware/sensors/ISensors.aidl
@@ -371,4 +371,13 @@
     const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 0x18;
     const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 0x58;
     const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
+
+    /**
+     * Constants related to reserved sensor handle ranges.
+     *
+     * The following range (inclusive) is reserved for usage by the system for
+     * runtime sensors.
+     */
+    const int RUNTIME_SENSORS_HANDLE_BASE = 0x5F000000;
+    const int RUNTIME_SENSORS_HANDLE_END = 0x5FFFFFFF;
 }
diff --git a/sensors/aidl/convert/Android.bp b/sensors/aidl/convert/Android.bp
new file mode 100644
index 0000000..53060b9
--- /dev/null
+++ b/sensors/aidl/convert/Android.bp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    // 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_static {
+    name: "android.hardware.sensors-V1-convert",
+    vendor_available: true,
+    host_supported: true,
+    srcs: ["convert.cpp"],
+    export_include_dirs: ["include"],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libhardware",
+        "libbase",
+        "libutils",
+        "android.hardware.sensors-V2-ndk",
+    ],
+    whole_static_libs: [
+        "sensors_common_convert",
+    ],
+    export_static_lib_headers: [
+        "sensors_common_convert",
+    ],
+    local_include_dirs: ["include/aidl/sensors"],
+    export_shared_lib_headers: [
+        "libhardware",
+    ],
+}
diff --git a/sensors/aidl/convert/convert.cpp b/sensors/aidl/convert/convert.cpp
new file mode 100644
index 0000000..2dc7a17
--- /dev/null
+++ b/sensors/aidl/convert/convert.cpp
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "aidl/sensors/convert.h"
+#include "android-base/logging.h"
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+using aidl::android::hardware::sensors::AdditionalInfo;
+using aidl::android::hardware::sensors::DynamicSensorInfo;
+using aidl::android::hardware::sensors::Event;
+using aidl::android::hardware::sensors::ISensors;
+using aidl::android::hardware::sensors::SensorInfo;
+using aidl::android::hardware::sensors::SensorStatus;
+using aidl::android::hardware::sensors::SensorType;
+
+status_t convertToStatus(ndk::ScopedAStatus status) {
+    if (status.isOk()) {
+        return OK;
+    } else {
+        switch (status.getExceptionCode()) {
+            case EX_ILLEGAL_ARGUMENT: {
+                return BAD_VALUE;
+            }
+            case EX_SECURITY: {
+                return PERMISSION_DENIED;
+            }
+            case EX_UNSUPPORTED_OPERATION: {
+                return INVALID_OPERATION;
+            }
+            case EX_SERVICE_SPECIFIC: {
+                switch (status.getServiceSpecificError()) {
+                    case ISensors::ERROR_BAD_VALUE: {
+                        return BAD_VALUE;
+                    }
+                    case ISensors::ERROR_NO_MEMORY: {
+                        return NO_MEMORY;
+                    }
+                    default: {
+                        return UNKNOWN_ERROR;
+                    }
+                }
+            }
+            default: {
+                return UNKNOWN_ERROR;
+            }
+        }
+    }
+}
+
+void convertToSensor(const 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.minDelayUs;
+    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.maxDelayUs;
+    dst->flags = src.flags;
+    dst->reserved[0] = dst->reserved[1] = 0;
+}
+
+void convertToSensorEvent(const Event& src, sensors_event_t* dst) {
+    *dst = {.version = sizeof(sensors_event_t),
+            .sensor = src.sensorHandle,
+            .type = (int32_t)src.sensorType,
+            .reserved0 = 0,
+            .timestamp = src.timestamp};
+
+    switch (src.sensorType) {
+        case SensorType::META_DATA: {
+            // Legacy HALs expect the handle reference in the meta data field.
+            // Copy it over from the handle of the event.
+            dst->meta_data.what = (int32_t)src.payload.get<Event::EventPayload::meta>().what;
+            dst->meta_data.sensor = src.sensorHandle;
+            // Set the sensor handle to 0 to maintain compatibility.
+            dst->sensor = 0;
+            break;
+        }
+
+        case SensorType::ACCELEROMETER:
+        case SensorType::MAGNETIC_FIELD:
+        case SensorType::ORIENTATION:
+        case SensorType::GYROSCOPE:
+        case SensorType::GRAVITY:
+        case SensorType::LINEAR_ACCELERATION: {
+            dst->acceleration.x = src.payload.get<Event::EventPayload::vec3>().x;
+            dst->acceleration.y = src.payload.get<Event::EventPayload::vec3>().y;
+            dst->acceleration.z = src.payload.get<Event::EventPayload::vec3>().z;
+            dst->acceleration.status = (int32_t)src.payload.get<Event::EventPayload::vec3>().status;
+            break;
+        }
+
+        case SensorType::GAME_ROTATION_VECTOR: {
+            dst->data[0] = src.payload.get<Event::EventPayload::vec4>().x;
+            dst->data[1] = src.payload.get<Event::EventPayload::vec4>().y;
+            dst->data[2] = src.payload.get<Event::EventPayload::vec4>().z;
+            dst->data[3] = src.payload.get<Event::EventPayload::vec4>().w;
+            break;
+        }
+
+        case SensorType::ROTATION_VECTOR:
+        case SensorType::GEOMAGNETIC_ROTATION_VECTOR: {
+            dst->data[0] = src.payload.get<Event::EventPayload::data>().values[0];
+            dst->data[1] = src.payload.get<Event::EventPayload::data>().values[1];
+            dst->data[2] = src.payload.get<Event::EventPayload::data>().values[2];
+            dst->data[3] = src.payload.get<Event::EventPayload::data>().values[3];
+            dst->data[4] = src.payload.get<Event::EventPayload::data>().values[4];
+            break;
+        }
+
+        case SensorType::MAGNETIC_FIELD_UNCALIBRATED:
+        case SensorType::GYROSCOPE_UNCALIBRATED:
+        case SensorType::ACCELEROMETER_UNCALIBRATED: {
+            dst->uncalibrated_gyro.x_uncalib = src.payload.get<Event::EventPayload::uncal>().x;
+            dst->uncalibrated_gyro.y_uncalib = src.payload.get<Event::EventPayload::uncal>().y;
+            dst->uncalibrated_gyro.z_uncalib = src.payload.get<Event::EventPayload::uncal>().z;
+            dst->uncalibrated_gyro.x_bias = src.payload.get<Event::EventPayload::uncal>().xBias;
+            dst->uncalibrated_gyro.y_bias = src.payload.get<Event::EventPayload::uncal>().yBias;
+            dst->uncalibrated_gyro.z_bias = src.payload.get<Event::EventPayload::uncal>().zBias;
+            break;
+        }
+
+        case SensorType::HINGE_ANGLE:
+        case SensorType::DEVICE_ORIENTATION:
+        case SensorType::LIGHT:
+        case SensorType::PRESSURE:
+        case SensorType::PROXIMITY:
+        case SensorType::RELATIVE_HUMIDITY:
+        case SensorType::AMBIENT_TEMPERATURE:
+        case SensorType::SIGNIFICANT_MOTION:
+        case SensorType::STEP_DETECTOR:
+        case SensorType::TILT_DETECTOR:
+        case SensorType::WAKE_GESTURE:
+        case SensorType::GLANCE_GESTURE:
+        case SensorType::PICK_UP_GESTURE:
+        case SensorType::WRIST_TILT_GESTURE:
+        case SensorType::STATIONARY_DETECT:
+        case SensorType::MOTION_DETECT:
+        case SensorType::HEART_BEAT:
+        case SensorType::LOW_LATENCY_OFFBODY_DETECT: {
+            dst->data[0] = src.payload.get<Event::EventPayload::scalar>();
+            break;
+        }
+
+        case SensorType::STEP_COUNTER: {
+            dst->u64.step_counter = src.payload.get<Event::EventPayload::stepCount>();
+            break;
+        }
+
+        case SensorType::HEART_RATE: {
+            dst->heart_rate.bpm = src.payload.get<Event::EventPayload::heartRate>().bpm;
+            dst->heart_rate.status =
+                    (int8_t)src.payload.get<Event::EventPayload::heartRate>().status;
+            break;
+        }
+
+        case SensorType::POSE_6DOF: {  // 15 floats
+            for (size_t i = 0; i < 15; ++i) {
+                dst->data[i] = src.payload.get<Event::EventPayload::pose6DOF>().values[i];
+            }
+            break;
+        }
+
+        case SensorType::DYNAMIC_SENSOR_META: {
+            dst->dynamic_sensor_meta.connected =
+                    src.payload.get<Event::EventPayload::dynamic>().connected;
+            dst->dynamic_sensor_meta.handle =
+                    src.payload.get<Event::EventPayload::dynamic>().sensorHandle;
+            dst->dynamic_sensor_meta.sensor = NULL;  // to be filled in later
+
+            memcpy(dst->dynamic_sensor_meta.uuid,
+                   src.payload.get<Event::EventPayload::dynamic>().uuid.values.data(), 16);
+
+            break;
+        }
+
+        case SensorType::ADDITIONAL_INFO: {
+            const AdditionalInfo& srcInfo = src.payload.get<Event::EventPayload::additional>();
+
+            additional_info_event_t* dstInfo = &dst->additional_info;
+            dstInfo->type = (int32_t)srcInfo.type;
+            dstInfo->serial = srcInfo.serial;
+
+            switch (srcInfo.payload.getTag()) {
+                case AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32: {
+                    const auto& values =
+                            srcInfo.payload.get<AdditionalInfo::AdditionalInfoPayload::dataInt32>()
+                                    .values;
+                    CHECK_EQ(values.size() * sizeof(int32_t), sizeof(dstInfo->data_int32));
+                    memcpy(dstInfo->data_int32, values.data(), sizeof(dstInfo->data_int32));
+                    break;
+                }
+                case AdditionalInfo::AdditionalInfoPayload::Tag::dataFloat: {
+                    const auto& values =
+                            srcInfo.payload.get<AdditionalInfo::AdditionalInfoPayload::dataFloat>()
+                                    .values;
+                    CHECK_EQ(values.size() * sizeof(float), sizeof(dstInfo->data_float));
+                    memcpy(dstInfo->data_float, values.data(), sizeof(dstInfo->data_float));
+                    break;
+                }
+                default: {
+                    LOG(ERROR) << "Invalid sensor additional info tag: ",
+                            (int)srcInfo.payload.getTag();
+                }
+            }
+            break;
+        }
+
+        case SensorType::HEAD_TRACKER: {
+            const auto& ht = src.payload.get<Event::EventPayload::headTracker>();
+            dst->head_tracker.rx = ht.rx;
+            dst->head_tracker.ry = ht.ry;
+            dst->head_tracker.rz = ht.rz;
+            dst->head_tracker.vx = ht.vx;
+            dst->head_tracker.vy = ht.vy;
+            dst->head_tracker.vz = ht.vz;
+            dst->head_tracker.discontinuity_count = ht.discontinuityCount;
+            break;
+        }
+
+        case SensorType::ACCELEROMETER_LIMITED_AXES:
+        case SensorType::GYROSCOPE_LIMITED_AXES:
+            dst->limited_axes_imu.x = src.payload.get<Event::EventPayload::limitedAxesImu>().x;
+            dst->limited_axes_imu.y = src.payload.get<Event::EventPayload::limitedAxesImu>().y;
+            dst->limited_axes_imu.z = src.payload.get<Event::EventPayload::limitedAxesImu>().z;
+            dst->limited_axes_imu.x_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImu>().xSupported;
+            dst->limited_axes_imu.y_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImu>().ySupported;
+            dst->limited_axes_imu.z_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImu>().zSupported;
+            break;
+
+        case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+        case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
+            dst->limited_axes_imu_uncalibrated.x_uncalib =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().x;
+            dst->limited_axes_imu_uncalibrated.y_uncalib =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().y;
+            dst->limited_axes_imu_uncalibrated.z_uncalib =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().z;
+            dst->limited_axes_imu_uncalibrated.x_bias =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xBias;
+            dst->limited_axes_imu_uncalibrated.y_bias =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().yBias;
+            dst->limited_axes_imu_uncalibrated.z_bias =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zBias;
+            dst->limited_axes_imu_uncalibrated.x_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xSupported;
+            dst->limited_axes_imu_uncalibrated.y_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().ySupported;
+            dst->limited_axes_imu_uncalibrated.z_supported =
+                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zSupported;
+            break;
+
+        case SensorType::HEADING:
+            dst->heading.heading = src.payload.get<Event::EventPayload::heading>().heading;
+            dst->heading.accuracy = src.payload.get<Event::EventPayload::heading>().accuracy;
+            break;
+
+        default: {
+            CHECK_GE((int32_t)src.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
+
+            memcpy(dst->data, src.payload.get<Event::EventPayload::data>().values.data(),
+                   16 * sizeof(float));
+            break;
+        }
+    }
+}
+
+void convertFromSensorEvent(const sensors_event_t& src, Event* dst) {
+    *dst = {
+            .timestamp = src.timestamp,
+            .sensorHandle = src.sensor,
+            .sensorType = (SensorType)src.type,
+    };
+
+    switch (dst->sensorType) {
+        case SensorType::META_DATA: {
+            Event::EventPayload::MetaData meta;
+            meta.what = (Event::EventPayload::MetaData::MetaDataEventType)src.meta_data.what;
+            // Legacy HALs contain the handle reference in the meta data field.
+            // Copy that over to the handle of the event. In legacy HALs this
+            // field was expected to be 0.
+            dst->sensorHandle = src.meta_data.sensor;
+            dst->payload.set<Event::EventPayload::Tag::meta>(meta);
+            break;
+        }
+
+        case SensorType::ACCELEROMETER:
+        case SensorType::MAGNETIC_FIELD:
+        case SensorType::ORIENTATION:
+        case SensorType::GYROSCOPE:
+        case SensorType::GRAVITY:
+        case SensorType::LINEAR_ACCELERATION: {
+            Event::EventPayload::Vec3 vec3;
+            vec3.x = src.acceleration.x;
+            vec3.y = src.acceleration.y;
+            vec3.z = src.acceleration.z;
+            vec3.status = (SensorStatus)src.acceleration.status;
+            dst->payload.set<Event::EventPayload::Tag::vec3>(vec3);
+            break;
+        }
+
+        case SensorType::GAME_ROTATION_VECTOR: {
+            Event::EventPayload::Vec4 vec4;
+            vec4.x = src.data[0];
+            vec4.y = src.data[1];
+            vec4.z = src.data[2];
+            vec4.w = src.data[3];
+            dst->payload.set<Event::EventPayload::Tag::vec4>(vec4);
+            break;
+        }
+
+        case SensorType::ROTATION_VECTOR:
+        case SensorType::GEOMAGNETIC_ROTATION_VECTOR: {
+            Event::EventPayload::Data data;
+            memcpy(data.values.data(), src.data, 5 * sizeof(float));
+            dst->payload.set<Event::EventPayload::Tag::data>(data);
+            break;
+        }
+
+        case SensorType::MAGNETIC_FIELD_UNCALIBRATED:
+        case SensorType::GYROSCOPE_UNCALIBRATED:
+        case SensorType::ACCELEROMETER_UNCALIBRATED: {
+            Event::EventPayload::Uncal uncal;
+            uncal.x = src.uncalibrated_gyro.x_uncalib;
+            uncal.y = src.uncalibrated_gyro.y_uncalib;
+            uncal.z = src.uncalibrated_gyro.z_uncalib;
+            uncal.xBias = src.uncalibrated_gyro.x_bias;
+            uncal.yBias = src.uncalibrated_gyro.y_bias;
+            uncal.zBias = src.uncalibrated_gyro.z_bias;
+            dst->payload.set<Event::EventPayload::Tag::uncal>(uncal);
+            break;
+        }
+
+        case SensorType::DEVICE_ORIENTATION:
+        case SensorType::LIGHT:
+        case SensorType::PRESSURE:
+        case SensorType::PROXIMITY:
+        case SensorType::RELATIVE_HUMIDITY:
+        case SensorType::AMBIENT_TEMPERATURE:
+        case SensorType::SIGNIFICANT_MOTION:
+        case SensorType::STEP_DETECTOR:
+        case SensorType::TILT_DETECTOR:
+        case SensorType::WAKE_GESTURE:
+        case SensorType::GLANCE_GESTURE:
+        case SensorType::PICK_UP_GESTURE:
+        case SensorType::WRIST_TILT_GESTURE:
+        case SensorType::STATIONARY_DETECT:
+        case SensorType::MOTION_DETECT:
+        case SensorType::HEART_BEAT:
+        case SensorType::LOW_LATENCY_OFFBODY_DETECT:
+        case SensorType::HINGE_ANGLE: {
+            dst->payload.set<Event::EventPayload::Tag::scalar>((float)src.data[0]);
+            break;
+        }
+
+        case SensorType::STEP_COUNTER: {
+            dst->payload.set<Event::EventPayload::Tag::stepCount>(src.u64.step_counter);
+            break;
+        }
+
+        case SensorType::HEART_RATE: {
+            Event::EventPayload::HeartRate heartRate;
+            heartRate.bpm = src.heart_rate.bpm;
+            heartRate.status = (SensorStatus)src.heart_rate.status;
+            dst->payload.set<Event::EventPayload::Tag::heartRate>(heartRate);
+            break;
+        }
+
+        case SensorType::POSE_6DOF: {  // 15 floats
+            Event::EventPayload::Pose6Dof pose6DOF;
+            for (size_t i = 0; i < 15; ++i) {
+                pose6DOF.values[i] = src.data[i];
+            }
+            dst->payload.set<Event::EventPayload::Tag::pose6DOF>(pose6DOF);
+            break;
+        }
+
+        case SensorType::DYNAMIC_SENSOR_META: {
+            DynamicSensorInfo dynamic;
+            dynamic.connected = src.dynamic_sensor_meta.connected;
+            dynamic.sensorHandle = src.dynamic_sensor_meta.handle;
+
+            memcpy(dynamic.uuid.values.data(), src.dynamic_sensor_meta.uuid, 16);
+            dst->payload.set<Event::EventPayload::Tag::dynamic>(dynamic);
+            break;
+        }
+
+        case SensorType::ADDITIONAL_INFO: {
+            AdditionalInfo info;
+            const additional_info_event_t& srcInfo = src.additional_info;
+            info.type = (AdditionalInfo::AdditionalInfoType)srcInfo.type;
+            info.serial = srcInfo.serial;
+
+            AdditionalInfo::AdditionalInfoPayload::Int32Values data;
+            CHECK_EQ(data.values.size() * sizeof(int32_t), sizeof(srcInfo.data_int32));
+            memcpy(data.values.data(), srcInfo.data_int32, sizeof(srcInfo.data_int32));
+            info.payload.set<AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32>(data);
+
+            dst->payload.set<Event::EventPayload::Tag::additional>(info);
+            break;
+        }
+
+        case SensorType::HEAD_TRACKER: {
+            Event::EventPayload::HeadTracker headTracker;
+            headTracker.rx = src.head_tracker.rx;
+            headTracker.ry = src.head_tracker.ry;
+            headTracker.rz = src.head_tracker.rz;
+            headTracker.vx = src.head_tracker.vx;
+            headTracker.vy = src.head_tracker.vy;
+            headTracker.vz = src.head_tracker.vz;
+            headTracker.discontinuityCount = src.head_tracker.discontinuity_count;
+
+            dst->payload.set<Event::EventPayload::Tag::headTracker>(headTracker);
+            break;
+        }
+
+        case SensorType::ACCELEROMETER_LIMITED_AXES:
+        case SensorType::GYROSCOPE_LIMITED_AXES: {
+            Event::EventPayload::LimitedAxesImu limitedAxesImu;
+            limitedAxesImu.x = src.limited_axes_imu.x;
+            limitedAxesImu.y = src.limited_axes_imu.y;
+            limitedAxesImu.z = src.limited_axes_imu.z;
+            limitedAxesImu.xSupported = src.limited_axes_imu.x_supported;
+            limitedAxesImu.ySupported = src.limited_axes_imu.y_supported;
+            limitedAxesImu.zSupported = src.limited_axes_imu.z_supported;
+            dst->payload.set<Event::EventPayload::Tag::limitedAxesImu>(limitedAxesImu);
+            break;
+        }
+
+        case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
+        case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED: {
+            Event::EventPayload::LimitedAxesImuUncal limitedAxesImuUncal;
+            limitedAxesImuUncal.x = src.limited_axes_imu_uncalibrated.x_uncalib;
+            limitedAxesImuUncal.y = src.limited_axes_imu_uncalibrated.y_uncalib;
+            limitedAxesImuUncal.z = src.limited_axes_imu_uncalibrated.z_uncalib;
+            limitedAxesImuUncal.xBias = src.limited_axes_imu_uncalibrated.x_bias;
+            limitedAxesImuUncal.yBias = src.limited_axes_imu_uncalibrated.y_bias;
+            limitedAxesImuUncal.zBias = src.limited_axes_imu_uncalibrated.z_bias;
+            limitedAxesImuUncal.xSupported = src.limited_axes_imu_uncalibrated.x_supported;
+            limitedAxesImuUncal.ySupported = src.limited_axes_imu_uncalibrated.y_supported;
+            limitedAxesImuUncal.zSupported = src.limited_axes_imu_uncalibrated.z_supported;
+            dst->payload.set<Event::EventPayload::Tag::limitedAxesImuUncal>(limitedAxesImuUncal);
+            break;
+        }
+
+        case SensorType::HEADING: {
+            Event::EventPayload::Heading heading;
+            heading.heading = src.heading.heading;
+            heading.accuracy = src.heading.accuracy;
+            dst->payload.set<Event::EventPayload::heading>(heading);
+            break;
+        }
+
+        default: {
+            CHECK_GE((int32_t)dst->sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
+
+            Event::EventPayload::Data data;
+            memcpy(data.values.data(), src.data, 16 * sizeof(float));
+            dst->payload.set<Event::EventPayload::Tag::data>(data);
+            break;
+        }
+    }
+}
+
+void convertFromASensorEvent(const ASensorEvent& src, Event* dst) {
+    convertFromSensorEvent(common::convertASensorEvent(src), dst);
+}
+
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
diff --git a/sensors/aidl/convert/include/aidl/sensors/convert.h b/sensors/aidl/convert/include/aidl/sensors/convert.h
new file mode 100644
index 0000000..44504fe
--- /dev/null
+++ b/sensors/aidl/convert/include/aidl/sensors/convert.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/sensors/ISensors.h>
+#include <hardware/sensors.h>
+#include <sensors/common_convert.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+status_t convertToStatus(ndk::ScopedAStatus status);
+void convertToSensor(const aidl::android::hardware::sensors::SensorInfo& src, sensor_t* dst);
+void convertToSensorEvent(const aidl::android::hardware::sensors::Event& src, sensors_event_t* dst);
+void convertFromSensorEvent(const sensors_event_t& src,
+                            aidl::android::hardware::sensors::Event* dst);
+void convertFromASensorEvent(const ASensorEvent& src, aidl::android::hardware::sensors::Event* dst);
+
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
index 49841a4..16b4d35 100644
--- a/sensors/aidl/default/Android.bp
+++ b/sensors/aidl/default/Android.bp
@@ -23,6 +23,16 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+filegroup {
+    name: "sensors-default.rc",
+    srcs: ["sensors-default.rc"],
+}
+
+filegroup {
+    name: "sensors-default.xml",
+    srcs: ["sensors-default.xml"],
+}
+
 cc_library_static {
     name: "libsensorsexampleimpl",
     vendor: true,
@@ -31,7 +41,7 @@
         "libfmq",
         "libpower",
         "libbinder_ndk",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
     ],
     export_include_dirs: ["include"],
     srcs: [
@@ -47,8 +57,8 @@
 cc_binary {
     name: "android.hardware.sensors-service.example",
     relative_install_path: "hw",
-    init_rc: ["sensors-default.rc"],
-    vintf_fragments: ["sensors-default.xml"],
+    init_rc: [":sensors-default.rc"],
+    vintf_fragments: [":sensors-default.xml"],
     vendor: true,
     shared_libs: [
         "libbase",
@@ -58,7 +68,7 @@
         "libcutils",
         "liblog",
         "libutils",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
     ],
     static_libs: [
         "libsensorsexampleimpl",
diff --git a/sensors/aidl/default/OWNERS b/sensors/aidl/default/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/aidl/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/aidl/default/Sensor.cpp b/sensors/aidl/default/Sensor.cpp
index 62193d6..3bdd8b6 100644
--- a/sensors/aidl/default/Sensor.cpp
+++ b/sensors/aidl/default/Sensor.cpp
@@ -223,7 +223,7 @@
     EventPayload::Vec3 vec3 = {
             .x = 0,
             .y = 0,
-            .z = -9.8,
+            .z = 9.8,
             .status = SensorStatus::ACCURACY_HIGH,
     };
     payload.set<EventPayload::Tag::vec3>(vec3);
diff --git a/sensors/aidl/default/apex/Android.bp b/sensors/aidl/default/apex/Android.bp
new file mode 100644
index 0000000..ceb428b
--- /dev/null
+++ b/sensors/aidl/default/apex/Android.bp
@@ -0,0 +1,53 @@
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex_key {
+    name: "com.android.hardware.sensors.key",
+    public_key: "com.android.hardware.sensors.avbpubkey",
+    private_key: "com.android.hardware.sensors.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.sensors.certificate",
+    certificate: "com.android.hardware.sensors",
+}
+
+genrule {
+    name: "com.android.hardware.sensors.rc-gen",
+    srcs: [":sensors-default.rc"],
+    out: ["com.android.hardware.sensors.rc"],
+    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.sensors/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "com.android.hardware.sensors.rc",
+    src: ":com.android.hardware.sensors.rc-gen",
+    installable: false,
+}
+
+// Default vendor APEX for android.hardware.sensors.
+// Custom implementations may use override_apex based on this APEX.
+apex {
+    name: "com.android.hardware.sensors",
+    manifest: "apex_manifest.json",
+    key: "com.android.hardware.sensors.key",
+    certificate: ":com.android.hardware.sensors.certificate",
+    file_contexts: "file_contexts",
+    use_vndk_as_stable: true,
+    updatable: false,
+    // Install the apex in /vendor/apex
+    soc_specific: true,
+    binaries: ["android.hardware.sensors-service.example"],
+    prebuilts: [
+        "com.android.hardware.sensors.rc",
+        "android.hardware.sensor.ambient_temperature.prebuilt.xml",
+        "android.hardware.sensor.barometer.prebuilt.xml",
+        "android.hardware.sensor.gyroscope.prebuilt.xml",
+        "android.hardware.sensor.hinge_angle.prebuilt.xml",
+        "android.hardware.sensor.light.prebuilt.xml",
+        "android.hardware.sensor.proximity.prebuilt.xml",
+        "android.hardware.sensor.relative_humidity.prebuilt.xml",
+    ],
+    vintf_fragments: [":sensors-default.xml"],
+}
diff --git a/sensors/aidl/default/apex/apex_manifest.json b/sensors/aidl/default/apex/apex_manifest.json
new file mode 100644
index 0000000..659e739
--- /dev/null
+++ b/sensors/aidl/default/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+    "name": "com.android.hardware.sensors",
+    "version": 1
+}
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.avbpubkey b/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.avbpubkey
rename to sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
Binary files differ
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.pem
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.pem
rename to sensors/aidl/default/apex/com.android.hardware.sensors.pem
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.pk8 b/sensors/aidl/default/apex/com.android.hardware.sensors.pk8
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.pk8
rename to sensors/aidl/default/apex/com.android.hardware.sensors.pk8
Binary files differ
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.x509.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.x509.pem
rename to sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
diff --git a/sensors/aidl/default/apex/file_contexts b/sensors/aidl/default/apex/file_contexts
new file mode 100644
index 0000000..27be16b
--- /dev/null
+++ b/sensors/aidl/default/apex/file_contexts
@@ -0,0 +1,5 @@
+(/.*)?							u:object_r:vendor_file:s0
+# Permission XMLs
+/etc/permissions(/.*)?					u:object_r:vendor_configs_file:s0
+# Service binary
+/bin/hw/android\.hardware\.sensors-service\.example	u:object_r:hal_sensors_default_exec:s0
\ No newline at end of file
diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp
index eee1062..a20d6d7 100644
--- a/sensors/aidl/default/multihal/Android.bp
+++ b/sensors/aidl/default/multihal/Android.bp
@@ -38,7 +38,7 @@
         "android.hardware.sensors@1.0",
         "android.hardware.sensors@2.0",
         "android.hardware.sensors@2.1",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
     ],
     export_include_dirs: ["include"],
     srcs: [
diff --git a/sensors/aidl/default/multihal/HalProxyAidl.cpp b/sensors/aidl/default/multihal/HalProxyAidl.cpp
index e6bcdad..dbef030 100644
--- a/sensors/aidl/default/multihal/HalProxyAidl.cpp
+++ b/sensors/aidl/default/multihal/HalProxyAidl.cpp
@@ -17,6 +17,7 @@
 #include "HalProxyAidl.h"
 #include <aidlcommonsupport/NativeHandle.h>
 #include <fmq/AidlMessageQueue.h>
+#include <hidl/HidlSupport.h>
 #include <hidl/Status.h>
 #include "ConvertUtils.h"
 #include "EventMessageQueueWrapperAidl.h"
@@ -28,6 +29,8 @@
 using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using ::aidl::android::hardware::sensors::ISensors;
 using ::aidl::android::hardware::sensors::ISensorsCallback;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
 using ::android::hardware::sensors::V2_1::implementation::convertToOldEvent;
 using ::ndk::ScopedAStatus;
 
@@ -225,13 +228,18 @@
   return resultToAStatus(HalProxy::unregisterDirectChannel(in_channelHandle));
 }
 
-binder_status_t HalProxyAidl::dump(int fd, const char ** /* args */,
-                                   uint32_t /* numArgs */) {
+binder_status_t HalProxyAidl::dump(int fd, const char ** args,
+                                   uint32_t numArgs) {
   native_handle_t *nativeHandle =
       native_handle_create(1 /* numFds */, 0 /* numInts */);
   nativeHandle->data[0] = fd;
 
-  HalProxy::debug(nativeHandle, {} /* args */);
+  hidl_vec<hidl_string> hidl_args;
+  hidl_args.resize(numArgs);
+  for (size_t i = 0; i < numArgs; ++i) {
+    hidl_args[i] = args[i];
+  }
+  HalProxy::debug(nativeHandle, hidl_args);
 
   native_handle_delete(nativeHandle);
   return STATUS_OK;
@@ -241,4 +249,4 @@
 }  // namespace sensors
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/sensors/aidl/default/sensors-default.xml b/sensors/aidl/default/sensors-default.xml
index 7898a6b..36b28ed 100644
--- a/sensors/aidl/default/sensors-default.xml
+++ b/sensors/aidl/default/sensors-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.sensors</name>
-        <version>1</version>
+        <version>2</version>
         <fqname>ISensors/default</fqname>
     </hal>
 </manifest>
diff --git a/sensors/aidl/multihal/Android.bp b/sensors/aidl/multihal/Android.bp
index 6d35daf..522d305 100644
--- a/sensors/aidl/multihal/Android.bp
+++ b/sensors/aidl/multihal/Android.bp
@@ -40,7 +40,7 @@
         "android.hardware.sensors@2.0-ScopedWakelock",
         "android.hardware.sensors@2.0",
         "android.hardware.sensors@2.1",
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
         "libbase",
         "libcutils",
         "libfmq",
diff --git a/sensors/aidl/multihal/OWNERS b/sensors/aidl/multihal/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/aidl/multihal/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
index d78edff..5da4fbd 100644
--- a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
+++ b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
@@ -17,7 +17,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.sensors</name>
-        <version>1</version>
+        <version>2</version>
         <fqname>ISensors/default</fqname>
     </hal>
 </manifest>
diff --git a/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
index 3f91a0a..5aecc54 100644
--- a/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
+++ b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
@@ -1,7 +1,7 @@
 service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.multihal
     class hal
     user system
-    group system wakelock context_hub
+    group system wakelock context_hub input uhid
     task_profiles ServiceCapacityLow
     capabilities BLOCK_SUSPEND
-    rlimit rtprio 10 10
\ No newline at end of file
+    rlimit rtprio 10 10
diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp
index f3972ec..c17a558 100644
--- a/sensors/aidl/vts/Android.bp
+++ b/sensors/aidl/vts/Android.bp
@@ -41,7 +41,7 @@
         "android.hardware.common.fmq-V1-ndk",
     ],
     static_libs: [
-        "android.hardware.sensors-V1-ndk",
+        "android.hardware.sensors-V2-ndk",
         "VtsHalSensorsTargetTestUtils",
         "libaidlcommonsupport",
     ],
diff --git a/sensors/aidl/vts/OWNERS b/sensors/aidl/vts/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/aidl/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/aidl/vts/SensorsAidlEnvironment.h b/sensors/aidl/vts/SensorsAidlEnvironment.h
index 2f5f287..a852e91 100644
--- a/sensors/aidl/vts/SensorsAidlEnvironment.h
+++ b/sensors/aidl/vts/SensorsAidlEnvironment.h
@@ -69,8 +69,6 @@
      */
     void readEvents();
 
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsAidlEnvironment);
-
     /**
      * Pointer to the Sensors HAL Interface that allows the test to call HAL functions.
      */
diff --git a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
index 35220a2..be11b87 100644
--- a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
+++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
@@ -41,6 +41,7 @@
 using aidl::android::hardware::sensors::SensorInfo;
 using aidl::android::hardware::sensors::SensorStatus;
 using aidl::android::hardware::sensors::SensorType;
+using aidl::android::hardware::sensors::AdditionalInfo;
 using android::ProcessState;
 using std::chrono::duration_cast;
 
@@ -561,10 +562,15 @@
             EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(info.type, info.typeAsString));
         }
 
-        // Test if all sensor has name and vendor
+        // Test if all sensors have name and vendor
         EXPECT_FALSE(info.name.empty());
         EXPECT_FALSE(info.vendor.empty());
 
+        // Make sure that the sensor handle is not within the reserved range for runtime
+        // sensors.
+        EXPECT_FALSE(ISensors::RUNTIME_SENSORS_HANDLE_BASE <= info.sensorHandle &&
+                     info.sensorHandle <= ISensors::RUNTIME_SENSORS_HANDLE_END);
+
         // Make sure that sensors of the same type have a unique name.
         std::vector<std::string>& v = sensorTypeNameMap[static_cast<int32_t>(info.type)];
         bool isUniqueName = std::find(v.begin(), v.end(), info.name) == v.end();
@@ -624,6 +630,15 @@
     Event additionalInfoEvent;
     additionalInfoEvent.sensorType = SensorType::ADDITIONAL_INFO;
     additionalInfoEvent.timestamp = android::elapsedRealtimeNano();
+    AdditionalInfo info;
+    info.type = AdditionalInfo::AdditionalInfoType::AINFO_BEGIN;
+    info.serial = 1;
+    AdditionalInfo::AdditionalInfoPayload::Int32Values infoData;
+    for (int32_t i = 0; i < 14; i++) {
+        infoData.values[i] = i;
+    }
+    info.payload.set<AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32>(infoData);
+    additionalInfoEvent.payload.set<Event::EventPayload::Tag::additional>(info);
 
     Event injectedEvent;
     injectedEvent.timestamp = android::elapsedRealtimeNano();
diff --git a/sensors/common/convert/Android.bp b/sensors/common/convert/Android.bp
new file mode 100644
index 0000000..230665e
--- /dev/null
+++ b/sensors/common/convert/Android.bp
@@ -0,0 +1,42 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "sensors_common_convert",
+    srcs: [
+        "convert.cpp",
+    ],
+    vendor_available: true,
+    host_supported: true,
+    local_include_dirs: ["include"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    shared_libs: [
+        "libhardware",
+    ],
+    header_libs: [
+        "libandroid_sensor_headers",
+    ],
+
+    export_include_dirs: ["include"],
+    export_header_lib_headers: [
+        "libandroid_sensor_headers",
+    ],
+}
diff --git a/sensors/common/convert/convert.cpp b/sensors/common/convert/convert.cpp
new file mode 100644
index 0000000..27de32c
--- /dev/null
+++ b/sensors/common/convert/convert.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sensors/common_convert.h>
+#include <cstring>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+namespace common {
+
+sensors_event_t convertASensorEvent(const ASensorEvent& src) {
+    // Attempt to ensure these types are compatible.
+    static_assert(sizeof(sensors_event_t) == sizeof(ASensorEvent));
+    static_assert(offsetof(sensors_event_t, timestamp) == offsetof(ASensorEvent, timestamp));
+    static_assert(offsetof(sensors_event_t, flags) == offsetof(ASensorEvent, flags));
+
+    // TODO(b/259711109) Follow up work to handle this in a safer way.
+    return *reinterpret_cast<const sensors_event_t*>(&src);
+}
+
+}  // namespace common
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
diff --git a/sensors/common/convert/include/sensors/common_convert.h b/sensors/common/convert/include/sensors/common_convert.h
new file mode 100644
index 0000000..a281369
--- /dev/null
+++ b/sensors/common/convert/include/sensors/common_convert.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/sensor.h>
+#include <hardware/sensors.h>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+namespace common {
+
+sensors_event_t convertASensorEvent(const ASensorEvent& aEvent);
+
+}  // namespace common
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
diff --git a/sensors/common/default/2.X/OWNERS b/sensors/common/default/2.X/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/common/default/2.X/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/common/default/2.X/Sensor.cpp b/sensors/common/default/2.X/Sensor.cpp
index fd701fd..2c1cdfb 100644
--- a/sensors/common/default/2.X/Sensor.cpp
+++ b/sensors/common/default/2.X/Sensor.cpp
@@ -218,7 +218,7 @@
 void AccelSensor::readEventPayload(EventPayload& payload) {
     payload.vec3.x = 0;
     payload.vec3.y = 0;
-    payload.vec3.z = -9.8;
+    payload.vec3.z = 9.8;
     payload.vec3.status = SensorStatus::ACCURACY_HIGH;
 }
 
diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp
index f44f5c4..305383e 100644
--- a/sensors/common/default/2.X/multihal/HalProxy.cpp
+++ b/sensors/common/default/2.X/multihal/HalProxy.cpp
@@ -82,8 +82,11 @@
 }
 
 HalProxy::HalProxy() {
-    const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf";
-    initializeSubHalListFromConfigFile(kMultiHalConfigFile);
+    static const std::string kMultiHalConfigFiles[] = {"/vendor/etc/sensors/hals.conf",
+                                                       "/odm/etc/sensors/hals.conf"};
+    for (const std::string& configFile : kMultiHalConfigFiles) {
+        initializeSubHalListFromConfigFile(configFile.c_str());
+    }
     init();
 }
 
@@ -348,7 +351,7 @@
     return Return<void>();
 }
 
-Return<void> HalProxy::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /*args*/) {
+Return<void> HalProxy::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
     if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
         ALOGE("%s: missing fd for writing", __FUNCTION__);
         return Void();
@@ -382,7 +385,7 @@
         stream << "  Name: " << subHal->getName() << std::endl;
         stream << "  Debug dump: " << std::endl;
         android::base::WriteStringToFd(stream.str(), writeFd);
-        subHal->debug(fd, {});
+        subHal->debug(fd, args);
         stream.str("");
         stream << std::endl;
     }
diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
index f5745c5..d8e292a 100644
--- a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
+++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp
@@ -76,6 +76,7 @@
                                   static_cast<int64_t>(mSensorInfo.minDelay) * 1000,
                                   static_cast<int64_t>(mSensorInfo.maxDelay) * 1000);
 
+    std::unique_lock<std::mutex> lock(mRunMutex);
     if (mSamplingPeriodNs != samplingPeriodNs) {
         mSamplingPeriodNs = samplingPeriodNs;
         // Wake up the 'run' thread to check if a new event should be generated now
@@ -237,7 +238,7 @@
     event.timestamp = ::android::elapsedRealtimeNano();
     event.u.vec3.x = 0;
     event.u.vec3.y = 0;
-    event.u.vec3.z = -9.815;
+    event.u.vec3.z = 9.815;
     event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
     events.push_back(event);
     return events;
diff --git a/sensors/common/utils/OWNERS b/sensors/common/utils/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/common/utils/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
index 5fe4d8b..796de2f 100644
--- a/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
+++ b/sensors/common/vts/2_X/SensorsHidlEnvironmentV2_X.h
@@ -79,8 +79,6 @@
      */
     void readEvents();
 
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentV2_X);
-
     /**
      * Pointer to the Sensors HAL Interface that allows the test to call HAL functions.
      */
diff --git a/sensors/common/vts/OWNERS b/sensors/common/vts/OWNERS
deleted file mode 100644
index 1b9a2f8..0000000
--- a/sensors/common/vts/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 62965
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/common/vts/utils/Android.bp b/sensors/common/vts/utils/Android.bp
index 08b6afa..b35280a 100644
--- a/sensors/common/vts/utils/Android.bp
+++ b/sensors/common/vts/utils/Android.bp
@@ -27,9 +27,11 @@
 // dependencies
 cc_defaults {
     name: "VtsHalSensorsDefaults",
+    defaults: [
+        "android.hardware.graphics.allocator-ndk_shared",
+        "android.hardware.graphics.common-ndk_shared",
+    ],
     shared_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
-        "android.hardware.graphics.common-V3-ndk",
         "libbinder_ndk",
         "libutils",
         "libvndksupport",
@@ -42,7 +44,11 @@
 
 cc_library_static {
     name: "VtsHalSensorsTargetTestUtils",
-    defaults: ["VtsHalTargetTestDefaults"],
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "android.hardware.graphics.allocator-ndk_shared",
+        "android.hardware.graphics.common-ndk_shared",
+    ],
     cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
     srcs: [
         "GrallocWrapper.cpp",
@@ -55,8 +61,6 @@
     ],
     // Targets that depend on us need to also include these
     shared_libs: [
-        "android.hardware.graphics.allocator-V1-ndk",
-        "android.hardware.graphics.common-V3-ndk",
         "libbinder_ndk",
         "libutils",
         "libvndksupport",
diff --git a/sensors/common/vts/utils/OWNERS b/sensors/common/vts/utils/OWNERS
deleted file mode 100644
index 892da15..0000000
--- a/sensors/common/vts/utils/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
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 f3cbd78..ec7c906 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
@@ -225,7 +225,9 @@
 
         ASSERT_EQ(batch(handle, samplingPeriodInNs, batchingPeriodInNs), Result::OK);
         ASSERT_EQ(activate(handle, 1), Result::OK);
-        events = getEnvironment()->collectEvents(minTimeUs, minNEvent, true /*clearBeforeStart*/);
+        events = getEnvironment()->collectEvents(
+                minTimeUs, minNEvent, true /* clearBeforeStart */, true /* changeCollection */,
+                [&type](const EventType& event) { return event.sensorType == type; });
         ASSERT_EQ(activate(handle, 0), Result::OK);
 
         ALOGI("Collected %zu samples", events.size());
@@ -233,24 +235,14 @@
         ASSERT_GT(events.size(), 0u);
 
         bool handleMismatchReported = false;
-        bool metaSensorTypeErrorReported = false;
         for (auto& e : events) {
-            if (e.sensorType == type) {
-                // avoid generating hundreds of error
-                if (!handleMismatchReported) {
-                    EXPECT_EQ(e.sensorHandle, handle)
-                            << (handleMismatchReported = true,
-                                "Event of the same type must come from the sensor registered");
-                }
-                sensorEvents.push_back(e);
-            } else {
-                // avoid generating hundreds of error
-                if (!metaSensorTypeErrorReported) {
-                    EXPECT_TRUE(isMetaSensorType(e.sensorType))
-                            << (metaSensorTypeErrorReported = true,
-                                "Only meta types are allowed besides the type registered");
-                }
+            // avoid generating hundreds of error
+            if (!handleMismatchReported) {
+                EXPECT_EQ(e.sensorHandle, handle)
+                        << (handleMismatchReported = true,
+                            "Event of the same type must come from the sensor registered");
             }
+            sensorEvents.push_back(e);
         }
 
         std::string s;
@@ -351,11 +343,11 @@
                   minDelayAverageInterval / 10);
 
         // fastest rate sampling time is close to spec
-        EXPECT_LT(std::abs(minDelayAverageInterval - minSamplingPeriodInNs),
+        EXPECT_LE(std::abs(minDelayAverageInterval - minSamplingPeriodInNs),
                   minSamplingPeriodInNs / 10);
 
         // slowest rate sampling time is close to spec
-        EXPECT_LT(std::abs(maxDelayAverageInterval - maxSamplingPeriodInNs),
+        EXPECT_LE(std::abs(maxDelayAverageInterval - maxSamplingPeriodInNs),
                   maxSamplingPeriodInNs / 10);
     }
 
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
index 17a96ed..c061a75 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
@@ -20,6 +20,7 @@
 #include <gtest/gtest.h>
 
 #include <atomic>
+#include <functional>
 #include <memory>
 #include <mutex>
 #include <thread>
@@ -61,9 +62,16 @@
     }
 
     // set sensor event collection status
-    void setCollection(bool enable) {
+    void setCollection(bool enable, const std::optional<std::function<bool(const Event&)>>& filter =
+                                            std::nullopt) {
         std::lock_guard<std::mutex> lock(mEventsMutex);
         mCollectionEnabled = enable;
+
+        if (enable && filter.has_value()) {
+            mEventFilter = *filter;
+        } else {
+            mEventFilter.reset();
+        }
     }
 
     void registerCallback(IEventCallback<Event>* callback) {
@@ -76,8 +84,10 @@
         mCallback = nullptr;
     }
 
-    std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
-                                     bool clearBeforeStart = true, bool changeCollection = true) {
+    std::vector<Event> collectEvents(
+            useconds_t timeLimitUs, size_t nEventLimit, bool clearBeforeStart = true,
+            bool changeCollection = true,
+            const std::optional<std::function<bool(const Event&)>>& filter = std::nullopt) {
         std::vector<Event> events;
         constexpr useconds_t SLEEP_GRANULARITY = 100 * 1000;  // granularity 100 ms
 
@@ -85,7 +95,7 @@
               clearBeforeStart);
 
         if (changeCollection) {
-            setCollection(true);
+            setCollection(true, filter);
         }
         if (clearBeforeStart) {
             catEvents(nullptr);
@@ -115,11 +125,13 @@
         : mCollectionEnabled(false), mCallback(nullptr) {
         mServiceName = service_name;
     }
+    SensorsVtsEnvironmentBase(const SensorsVtsEnvironmentBase&) = delete;
+    SensorsVtsEnvironmentBase& operator=(const SensorsVtsEnvironmentBase&) = delete;
     virtual ~SensorsVtsEnvironmentBase(){};
 
     void addEvent(const Event& ev) {
         std::lock_guard<std::mutex> lock(mEventsMutex);
-        if (mCollectionEnabled) {
+        if (mCollectionEnabled && (!mEventFilter.has_value() || (*mEventFilter)(ev))) {
             mEvents.push_back(ev);
         }
 
@@ -136,11 +148,10 @@
     std::atomic_bool mStopThread;
     std::thread mPollThread;
     std::vector<Event> mEvents;
+    std::optional<std::function<bool(const Event&)>> mEventFilter;
     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/soundtrigger/2.3/cli/Android.bp b/soundtrigger/2.3/cli/Android.bp
index 27d7b30..883bf2b 100644
--- a/soundtrigger/2.3/cli/Android.bp
+++ b/soundtrigger/2.3/cli/Android.bp
@@ -9,7 +9,7 @@
 
 java_binary {
     name: "sthal_cli_2.3",
-    wrapper: "sthal_cli_2.3",
+    wrapper: "sthal_cli_2.3.sh",
     srcs: ["java/**/*.java"],
     static_libs: [
         "android.hardware.soundtrigger-V2.3-java",
diff --git a/soundtrigger/2.3/cli/sthal_cli_2.3 b/soundtrigger/2.3/cli/sthal_cli_2.3.sh
similarity index 100%
rename from soundtrigger/2.3/cli/sthal_cli_2.3
rename to soundtrigger/2.3/cli/sthal_cli_2.3.sh
diff --git a/soundtrigger/aidl/Android.bp b/soundtrigger/aidl/Android.bp
index 448895c..27d43d3 100644
--- a/soundtrigger/aidl/Android.bp
+++ b/soundtrigger/aidl/Android.bp
@@ -33,17 +33,26 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: ["android.media.soundtrigger.types-V1"],
         },
+        // IMPORTANT: Update latest_android_hardware_soundtrigger3 every time
+        // you add the latest frozen version to versions_with_info
     ],
+}
 
+// Note: This should always be one version ahead of the last frozen version
+latest_android_hardware_soundtrigger3 = "android.hardware.soundtrigger3-V1"
+
+// Modules that depend on android.hardware.soundtrigger3 directly can include
+// the following java_defaults to avoid explicitly managing dependency versions
+// across many scattered files.
+java_defaults {
+    name: "latest_android_hardware_soundtrigger3_java_static",
+    static_libs: [
+        latest_android_hardware_soundtrigger3 + "-java",
+    ],
 }
diff --git a/soundtrigger/aidl/cli/Android.bp b/soundtrigger/aidl/cli/Android.bp
index e8999ff..935e438 100644
--- a/soundtrigger/aidl/cli/Android.bp
+++ b/soundtrigger/aidl/cli/Android.bp
@@ -9,7 +9,7 @@
 
 java_binary {
     name: "sthal_cli_3",
-    wrapper: "sthal_cli_3",
+    wrapper: "sthal_cli_3.sh",
     srcs: ["java/**/*.java"],
     static_libs: [
         "android.hardware.soundtrigger3-V1-java",
diff --git a/soundtrigger/aidl/cli/sthal_cli_3 b/soundtrigger/aidl/cli/sthal_cli_3.sh
similarity index 100%
rename from soundtrigger/aidl/cli/sthal_cli_3
rename to soundtrigger/aidl/cli/sthal_cli_3.sh
diff --git a/staging/c2/aidl/Android.bp b/staging/c2/aidl/Android.bp
new file mode 100644
index 0000000..b9da7ad
--- /dev/null
+++ b/staging/c2/aidl/Android.bp
@@ -0,0 +1,39 @@
+// This is the expected build file, but it may not be right in all cases
+
+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"],
+}
+
+aidl_interface {
+    name: "android.hardware.media.c2",
+    vendor_available: true,
+    double_loadable: true,
+    unstable: true,
+    srcs: ["android/hardware/media/c2/*.aidl"],
+    include_dirs: [
+        "frameworks/native/aidl/gui",
+    ],
+    imports: [
+        "android.hardware.common-V2",
+        "android.hardware.media.bufferpool2-V1",
+    ],
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            enabled: false,
+        },
+        ndk: {
+            enabled: true,
+            additional_shared_libraries: [
+                "libnativewindow",
+            ],
+        },
+    },
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/BaseBlock.aidl b/staging/c2/aidl/android/hardware/media/c2/BaseBlock.aidl
new file mode 100644
index 0000000..16e7653
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/BaseBlock.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+
+/**
+ * Storage type for `BaseBlock`.
+ *
+ * A `BaseBlock` is a representation of a codec memory block. Coded data,
+ * decoded data, codec-specific data, and other codec-related data are all sent
+ * in the form of BaseBlocks.
+ */
+union BaseBlock {
+    /**
+     * #nativeBlock is the opaque representation of a buffer.
+     */
+    NativeHandle nativeBlock;
+    /**
+     * #pooledBlock is a reference to a buffer handled by a BufferPool.
+     */
+    android.hardware.media.bufferpool2.BufferStatusMessage pooledBlock;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Block.aidl b/staging/c2/aidl/android/hardware/media/c2/Block.aidl
new file mode 100644
index 0000000..4da8490
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Block.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.media.c2.Params;
+
+/**
+ * Reference to a @ref BaseBlock within a @ref WorkBundle.
+ *
+ * `Block` contains additional attributes that `BaseBlock` does not. These
+ * attributes may differ among `Block` objects that refer to the same
+ * `BaseBlock` in the same `WorkBundle`.
+ */
+parcelable Block {
+    /**
+     * Identity of a `BaseBlock` within a `WorkBundle`. This is an index into
+     * #WorkBundle.baseBlocks.
+     */
+    int index;
+    /**
+     * Metadata associated with this `Block`.
+     */
+    Params meta;
+    /**
+     * Fence for synchronizing `Block` access.
+     */
+    NativeHandle fence;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Buffer.aidl b/staging/c2/aidl/android/hardware/media/c2/Buffer.aidl
new file mode 100644
index 0000000..fe01b64
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Buffer.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.Block;
+import android.hardware.media.c2.Params;
+
+/**
+ * A codec buffer, which is a collection of @ref Block objects and metadata.
+ *
+ * This is a part of @ref FrameData.
+ */
+parcelable Buffer {
+    /**
+     * Metadata associated with the buffer.
+     */
+    Params info;
+    /**
+     * Blocks contained in the buffer.
+     */
+    Block[] blocks;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl
new file mode 100644
index 0000000..3dd14cd
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldId;
+
+/**
+ * Description of a field inside a C2Param structure.
+ */
+parcelable FieldDescriptor {
+    /**
+     * Possible types of the field.
+     */
+    @Backing(type="int")
+    enum Type {
+        NO_INIT = 0,
+        INT32,
+        UINT32,
+        CNTR32,
+        INT64,
+        UINT64,
+        CNTR64,
+        FLOAT,
+        /**
+         * Fixed-size string (POD).
+         */
+        STRING = 0x100,
+        /**
+         * A blob has no sub-elements and can be thought of as an array of
+         * bytes. However, bytes cannot be individually addressed by clients.
+         */
+        BLOB,
+        /**
+         * The field is a structure that may contain other fields.
+         */
+        STRUCT = 0x20000,
+    }
+    /**
+     * Named value type. This is used for defining an enum value for a numeric
+     * type.
+     */
+    parcelable NamedValue {
+        /**
+         * Name of the enum value. This must be unique for each enum value in
+         * the same field.
+         */
+        String name;
+        /**
+         * Underlying value of the enum value. Multiple enum names may have the
+         * same underlying value.
+         */
+        long value;
+    }
+    /**
+     * Location of the field in the C2Param structure
+     */
+    FieldId fieldId;
+    /**
+     * Type of the field.
+     */
+    Type type;
+    /**
+     * If #type is #Type.STRUCT, #structIndex is the C2Param structure index;
+     * otherwise, #structIndex is not used.
+     */
+    int structIndex;
+    /**
+     * Extent of the field.
+     * - For a non-array field, #extent is 1.
+     * - For a fixed-length array field, #extent is the length. An array field
+     *   of length 1 is indistinguishable from a non-array field.
+     * - For a variable-length array field, #extent is 0. This can only occur as
+     *   the last member of a C2Param structure.
+     */
+    int extent;
+    /**
+     * Name of the field. This must be unique for each field in the same
+     * structure.
+     */
+    String name;
+    /**
+     * List of enum values. This is not used when #type is not one of the
+     * numeric types.
+     */
+    NamedValue[] namedValues;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldId.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldId.aidl
new file mode 100644
index 0000000..c53f7a5
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldId.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Identifying information of a field relative to a known C2Param structure.
+ *
+ * Within a given C2Param structure, each field is uniquely identified by @ref
+ * FieldId.
+ */
+parcelable FieldId {
+    /**
+     * Offset of the field in bytes.
+     */
+    int offset;
+    /**
+     * Size of the field in bytes.
+     */
+    int sizeBytes;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl
new file mode 100644
index 0000000..5f4ad2a
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.ValueRange;
+
+/*
+ * Description of supported values for a field of C2Param.
+ *
+ * This can be a continuous range or a discrete set of values.
+ *
+ * The intended type of values must be made clear in the context where
+ * `FieldSupportedValues` is used.
+ */
+union FieldSupportedValues {
+    /**
+     * No supported values
+     */
+    boolean empty;
+    /**
+     * Numeric range, described in a #ValueRange structure
+     */
+    ValueRange range;
+    /**
+     * List of values
+     */
+    long[] values;
+    /**
+     * List of flags that can be OR-ed.
+     *
+     * The list contains { min-mask, flag1, flag2... }. Basically, the first
+     * value is the required set of flags to be set, and the rest of the values are flags that can
+     * be set independently. FLAGS is only supported for integral types. Supported flags should
+     * not overlap, as it can make validation non-deterministic. The standard validation method
+     * is that starting from the original value, if each flag is removed when fully present (the
+     * min-mask must be fully present), we shall arrive at 0.
+     */
+    long[] flags;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
new file mode 100644
index 0000000..33a8170
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.ParamField;
+
+/**
+ * Query information for supported values of a field. This is used as input to
+ * IConfigurable::querySupportedValues().
+ */
+parcelable FieldSupportedValuesQuery {
+    @Backing(type="int")
+    enum Type {
+        /**
+         * Query all possible values regardless of other settings.
+         */
+        POSSIBLE = 0,
+        /**
+         * Query currently possible values given dependent settings.
+         */
+        CURRENT,
+    }
+    /**
+     * Identity of the field to query.
+     */
+    ParamField field;
+    /**
+     * Type of the query. See #Type for more information.
+     */
+    Type type;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
new file mode 100644
index 0000000..133712a
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldSupportedValues;
+import android.hardware.media.c2.Status;
+
+/**
+ * This structure is used to hold the result from
+ * IConfigurable::querySupportedValues().
+ */
+parcelable FieldSupportedValuesQueryResult {
+    /**
+     * Result of the query. Possible values are
+     * - `Status::OK`: The query was successful.
+     * - `Status::BAD_STATE`: The query was requested when the `IConfigurable` instance
+     *   was in a bad state.
+     * - `Status::BAD_INDEX`: The requested field was not recognized.
+     * - `Status::TIMED_OUT`: The query could not be completed in a timely manner.
+     * - `Status::BLOCKING`: The query must block, but the parameter `mayBlock` in the
+     *   call to `querySupportedValues()` was `false`.
+     * - `Status::CORRUPTED`: Some unknown error occurred.
+     */
+    Status status;
+    /**
+     * Supported values. This is meaningful only when #status is `OK`.
+     */
+    FieldSupportedValues values;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FrameData.aidl b/staging/c2/aidl/android/hardware/media/c2/FrameData.aidl
new file mode 100644
index 0000000..81c76be
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FrameData.aidl
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.Buffer;
+import android.hardware.media.c2.InfoBuffer;
+import android.hardware.media.c2.Params;
+import android.hardware.media.c2.WorkOrdinal;
+
+/**
+ * Data for an input frame or an output frame.
+ *
+ * This structure represents a @e frame with its metadata. A @e frame consists
+ * of an ordered set of buffers, configuration changes, and info buffers along
+ * with some non-configuration metadata.
+ *
+ * @note `FrameData` is the HIDL counterpart of `C2FrameData` in the Codec 2.0
+ * standard.
+ */
+parcelable FrameData {
+    /** List of frame flags */
+    /**
+     * For input frames: no output frame shall be generated when processing
+     * this frame, but metadata must still be processed.
+     *
+     * For output frames: this frame must be discarded but metadata is still
+     * valid.
+     */
+    const int DROP_FRAME = (1 << 0);
+    /**
+     * This frame is the last frame of the current stream. Further frames
+     * are part of a new stream.
+     */
+    const int END_OF_STREAM = (1 << 1);
+    /**
+     * This frame must be discarded with its metadata.
+     *
+     * This flag is only set by components, e.g. as a response to the flush
+     * command.
+     */
+    const int DISCARD_FRAME = (1 << 2);
+    /**
+     * This frame is not the last frame produced for the input.
+     *
+     * This flag is normally set by the component - e.g. when an input frame
+     * results in multiple output frames, this flag is set on all but the
+     * last output frame.
+     *
+     * Also, when components are chained, this flag should be propagated
+     * down the work chain. That is, if set on an earlier frame of a
+     * work-chain, it should be propagated to all later frames in that
+     * chain. Additionally, components down the chain could set this flag
+     * even if not set earlier, e.g. if multiple output frames are generated
+     * at that component for the input frame.
+     */
+    const int FLAG_INCOMPLETE = (1 << 3);
+    /**
+     * This frame contains only codec-specific configuration data, and no
+     * actual access unit.
+     */
+    const int CODEC_CONFIG = (1 << 31);
+    /**
+     * Frame flags, as described above.
+     */
+    int flags;
+    /**
+     * @ref WorkOrdinal of the frame.
+     */
+    WorkOrdinal ordinal;
+    /**
+     * List of frame buffers.
+     */
+    Buffer[] buffers;
+    /**
+     * List of configuration updates.
+     */
+    Params configUpdate;
+    /**
+     * List of info buffers.
+     */
+    InfoBuffer[] infoBuffers;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IComponent.aidl b/staging/c2/aidl/android/hardware/media/c2/IComponent.aidl
new file mode 100644
index 0000000..bea4b70
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IComponent.aidl
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+import android.view.Surface;
+
+import android.hardware.media.c2.IComponentInterface;
+import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.WorkBundle;
+import android.hardware.media.c2.SurfaceSyncObj;
+
+/**
+ * Interface for an AIDL Codec2 component.
+ * Components have two states: stopped and running. The running state has three
+ * sub-states: executing, tripped and error.
+ *
+ * All methods in `IComponent` must not block. If a method call cannot be
+ * completed in a timely manner, it must throw `Status::TIMED_OUT`.
+ */
+interface IComponent {
+    /**
+     * The reference object from framwork to HAL C2BlockPool.
+     *
+     * The object will be returned when C2BlockPool is created by a framework
+     * request. The object also can be destroyed using blockPoolId.
+     * Using configurable framework can query/config the object in HAL(IComponent).
+     */
+    parcelable BlockPool {
+        long blockPoolId;
+        IConfigurable configurable;
+    }
+    /**
+     * Configures a component for a tunneled playback mode.
+     *
+     * A successful call to this method puts the component in the *tunneled*
+     * mode. In this mode, the output `Worklet`s returned in
+     * IComponentListener::onWorkDone() may not contain any buffers. The output
+     * buffers are passed directly to the consumer end of a buffer queue whose
+     * producer side is configured with the returned @p sidebandStream passed
+     * to IGraphicBufferProducer::setSidebandStream().
+     *
+     * The component is initially in the non-tunneled mode by default. The
+     * tunneled mode can be toggled on only before the component starts
+     * processing. Once the component is put into the tunneled mode, it shall
+     * stay in the tunneled mode until and only until reset() is called.
+     *
+     * @param avSyncHwId A resource ID for hardware sync. The generator of sync
+     *     IDs must ensure that this number is unique among all services at any
+     *     given time. For example, if both the audio HAL and the tuner HAL
+     *     support this feature, sync IDs from the audio HAL must not clash
+     *     with sync IDs from the tuner HAL.
+     * @return Codec-allocated sideband stream NativeHandle. This can
+     *     be passed to IGraphicBufferProducer::setSidebandStream() to
+     *     establish a direct channel to the consumer.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::OMITTED`   - The component does not support video tunneling.
+     *   - `Status::BAD_STATE` - The component is already running.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    NativeHandle configureVideoTunnel(in int avSyncHwId);
+
+    /**
+     * Creates a local `C2BlockPool` backed by the given allocator and returns
+     * its id.
+     *
+     * The returned @p blockPoolId is the only way the client can refer to a
+     * `C2BlockPool` object in the component. The id can be passed to
+     * setOutputSurface() or used in some C2Param objects later.
+     *
+     * The created `C2BlockPool` object can be destroyed by calling
+     * destroyBlockPool(), reset() or release(). reset() and release() must
+     * destroy all `C2BlockPool` objects that have been created.
+     *
+     * @param allocatorId Id of a `C2Allocator`.
+     * @param out configurable Configuration interface for the created pool. This
+     *     must not be null.
+     * @return Created block pool information. This could be used to config/query and
+     * also be used in setOutputSurface() if the allocator
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::NO_MEMORY` - Not enough memory to create the pool.
+     *   - `Status::BAD_VALUE` - @p allocatorId is not recognized.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    BlockPool createBlockPool(in int allocatorId);
+
+    /**
+     * Destroys a local block pool previously created by createBlockPool().
+     *
+     * @param blockPoolId Id of a `C2BlockPool` that was previously returned by
+     *      createBlockPool().
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::NOT_FOUND` - The supplied blockPoolId is not valid.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    void destroyBlockPool(in long blockPoolId);
+
+    /**
+     * Drains the component, and optionally downstream components. This is a
+     * signalling method; as such it does not wait for any work completion.
+     *
+     * The last `Work` item is marked as "drain-till-here", so the component is
+     * notified not to wait for further `Work` before it processes what is
+     * already queued. This method can also be used to set the end-of-stream
+     * flag after `Work` has been queued. Client can continue to queue further
+     * `Work` immediately after this method returns.
+     *
+     * This method must be supported in running (including tripped) states.
+     *
+     * `Work` that is completed must be returned via
+     * IComponentListener::onWorkDone().
+     *
+     * @param withEos Whether to drain the component with marking end-of-stream.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    void drain(in boolean withEos);
+
+    /**
+     * Discards and abandons any pending `Work` items for the component.
+     *
+     * This method must be supported in running (including tripped) states.
+     *
+     * `Work` that could be immediately abandoned/discarded must be returned in
+     * @p flushedWorkBundle. The order in which queued `Work` items are
+     * discarded can be arbitrary.
+     *
+     * `Work` that could not be abandoned or discarded immediately must be
+     * marked to be discarded at the earliest opportunity, and must be returned
+     * via IComponentListener::onWorkDone(). This must be completed within
+     * 500ms.
+     *
+     * @return `WorkBundle` object containing flushed `Work` items.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    WorkBundle flush();
+
+    /**
+     * Returns the @ref IComponentInterface instance associated to this
+     * component.
+     *
+     * An @ref IConfigurable instance for the component can be obtained by calling
+     * IComponentInterface::getConfigurable() on the returned @p intf.
+     *
+     * @return `IComponentInterface` instance. This must not be null.
+     */
+    IComponentInterface getInterface();
+
+    /**
+     * Queues up work for the component.
+     *
+     * This method must be supported in running (including tripped) states.
+     *
+     * It is acceptable for this method to return `OK` and return an error value
+     * using the IComponentListener::onWorkDone() callback.
+     *
+     * @param workBundle `WorkBundle` object containing a list of `Work` objects
+     *     to queue to the component.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::BAD_INDEX` - Some component id in some `Worklet` is not valid.
+     *   - `Status::CANNOT_DO` - The components are not tunneled but some `Work` object
+     *                   contains tunneling information.
+     *   - `Status::NO_MEMORY` - Not enough memory to queue @p workBundle.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    void queue(in WorkBundle workBundle);
+
+    /**
+     * Releases the component.
+     *
+     * This method must be supported in stopped state.
+     *
+     * This method destroys the component. Upon return, if @p status is `OK` or
+     * `DUPLICATE`, all resources must have been released.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::BAD_STATE` - The component is running.
+     *   - `Status::DUPLICATE` - The component is already released.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    void release();
+
+    /**
+     * Resets the component.
+     *
+     * This method must be supported in all (including tripped) states other
+     * than released.
+     *
+     * This method must be supported during any other blocking call.
+     *
+     * This method must return within 500ms.
+     *
+     * When this call returns, if @p status is `OK`, all `Work` items must
+     * have been abandoned, and all resources (including `C2BlockPool` objects
+     * previously created by createBlockPool()) must have been released.
+     *
+     * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
+     * expected as a response to this call. For all other return values, the
+     * component must be in the stopped state.
+     *
+     * This brings settings back to their default, "guaranteeing" no tripped
+     * state.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::BAD_STATE` - Component is in released state.
+     *   - `Status::DUPLICATE` - When called during another reset call from another
+     *                   thread.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    void reset();
+
+    /**
+     * Starts using a surface for output with a synchronization object
+     *
+     * This method must not block.
+     *
+     * @param blockPoolId Id of the `C2BlockPool` to be associated with the
+     *     output surface.
+     * @param surface Output surface.
+     * @param syncObject synchronization object for buffer allocation between
+     *     Framework and Component.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::CANNOT_DO` - The component does not support an output surface.
+     *   - `Status::REFUSED`   - The output surface cannot be accessed.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    void setOutputSurface(in long blockPoolId, in Surface surface,
+        in SurfaceSyncObj syncObject);
+
+    /**
+     * Starts the component.
+     *
+     * This method must be supported in stopped state as well as tripped state.
+     *
+     * If the return value is `OK`, the component must be in the running state.
+     * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
+     * expected as a response to this call. Otherwise, the component must be in
+     * the stopped state.
+     *
+     * If a component is in the tripped state and start() is called while the
+     * component configuration still results in a trip, start() must succeed and
+     * a new onTripped() callback must be used to communicate the configuration
+     * conflict that results in the new trip.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::BAD_STATE` - Component is not in stopped or tripped state.
+     *   - `Status::DUPLICATE` - When called during another start call from another
+     *                   thread.
+     *   - `Status::NO_MEMORY` - Not enough memory to start the component.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    void start();
+
+    /**
+     * Stops the component.
+     *
+     * This method must be supported in running (including tripped) state.
+     *
+     * This method must return within 500ms.
+     *
+     * Upon this call, all pending `Work` must be abandoned.
+     *
+     * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
+     * expected as a response to this call. For all other return values, the
+     * component must be in the stopped state.
+     *
+     * This does not alter any settings and tunings that may have resulted in a
+     * tripped state.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::BAD_STATE` - Component is not in running state.
+     *   - `Status::DUPLICATE` - When called during another stop call from another
+     *                   thread.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    void stop();
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl b/staging/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl
new file mode 100644
index 0000000..4589115
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.IConfigurable;
+
+/**
+ * Component interface object. This object contains all of the configurations of
+ * a potential or actual component. It can be created and used independently of
+ * an actual Codec2 component to query supported parameters for various
+ * component settings, and configurations for a potential component.
+ *
+ * An actual component exposes this interface via IComponent::getInterface().
+ */
+interface IComponentInterface {
+    /**
+     * Returns the @ref IConfigurable instance associated to this component
+     * interface.
+     *
+     * @return `IConfigurable` instance. This must not be null.
+     */
+    IConfigurable getConfigurable();
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IComponentListener.aidl b/staging/c2/aidl/android/hardware/media/c2/IComponentListener.aidl
new file mode 100644
index 0000000..786c8f1
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IComponentListener.aidl
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.SettingResult;
+import android.hardware.media.c2.Status;
+import android.hardware.media.c2.WorkBundle;
+
+/**
+ * Callback interface for handling notifications from @ref IComponent.
+ */
+oneway interface IComponentListener {
+    /**
+     * Identifying information for an input buffer previously queued to the
+     * component via IComponent::queue().
+     */
+    parcelable InputBuffer {
+        /**
+         * This value comes from `Work::input.ordinal.frameIndex` in a `Work`
+         * object that was previously queued.
+         */
+        long frameIndex;
+        /**
+         * This value is an index into `Work::input.buffers` (which is an array)
+         * in a `Work` object that was previously queued.
+         */
+        int arrayIndex;
+    }
+    /**
+     * Information about rendering of a frame to a `Surface`.
+     */
+    parcelable RenderedFrame {
+        /**
+         * Id of the `BufferQueue` containing the rendered buffer.
+         *
+         * This value must have been obtained by an earlier call to
+         * IGraphicBufferProducer::getUniqueId().
+         */
+        long bufferQueueId;
+        /**
+         * Id of the slot of the rendered buffer.
+         *
+         * This value must have been obtained by an earlier call to
+         * IGraphicBufferProducer::dequeueBuffer() or
+         * IGraphicBufferProducer::attachBuffer().
+         */
+        int slotId;
+        /**
+         * Timestamp the rendering happened.
+         *
+         * The reference point for the timestamp is determined by the
+         * `BufferQueue` that performed the rendering.
+         */
+        long timestampNs;
+    }
+    /**
+     * Notify the listener of an error.
+     *
+     * @param status Error type. @p status may be `OK`, which means that an
+     *     error has occurred, but the error type does not fit into the type
+     *     `Status`. In this case, additional information is provided by
+     *     @p errorCode.
+     * @param errorCode Additional error information. The framework may not
+     *     recognize the meaning of this value.
+     */
+    void onError(in Status status, in int errorCode);
+
+    /**
+     * Notify the listener that frames have been rendered.
+     *
+     * @param renderedFrames List of @ref RenderedFrame objects.
+     */
+    void onFramesRendered(in RenderedFrame[] renderedFrames);
+
+    /**
+     * Notify the listener that some input buffers are no longer needed by the
+     * component, and hence can be released or reused by the client.
+     *
+     * Input buffers that are contained in a `Work` object returned by an
+     * earlier onWorkDone() call are assumed released, so they must not appear
+     * in any onInputBuffersReleased() calls. That means
+     * onInputBuffersReleased() must only report input buffers that are released
+     * before the output in the same `Work` item is produced. However, it is
+     * possible for an input buffer to be returned by onWorkDone() after it has
+     * been reported by onInputBuffersReleased().
+     *
+     * @note onWorkDone() and onInputBuffersReleased() both notify the client
+     * that input buffers are no longer needed. However, in order to minimize
+     * IPC calls, onInputBuffersReleased() should be called only when
+     * onWorkDone() cannot be called, e.g., the component needs more input
+     * before an output can be produced.
+     *
+     * @param inputBuffers List of `InputBuffer` objects, identifying input
+     * buffers that are no longer needed by the component.
+     */
+    void onInputBuffersReleased(in InputBuffer[] inputBuffers);
+
+    /**
+     * Notify the listener that the component is tripped.
+     *
+     * @param settingResults List of failures.
+     */
+    void onTripped(in SettingResult[] settingResults);
+
+    /**
+     * Notify the listener that some `Work` items have been completed.
+     *
+     * All the input buffers in the returned `Work` objects must not be used by
+     * the component after onWorkDone() is called.
+     *
+     * @param workBundle List of completed `Work` objects.
+     */
+    void onWorkDone(in WorkBundle workBundle);
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IComponentStore.aidl b/staging/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
new file mode 100644
index 0000000..d332bd3
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.Buffer;
+import android.hardware.media.c2.IComponent;
+import android.hardware.media.c2.IComponentInterface;
+import android.hardware.media.c2.IComponentListener;
+import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.StructDescriptor;
+
+/**
+ * Entry point for Codec2 HAL.
+ *
+ * All methods in `IComponentStore` must not block. If a method call cannot be
+ * completed in a timely manner, it must throw `Status::TIMED_OUT`. The only
+ * exceptions are getPoolClientManager() and getConfigurable(),  which must
+ * always return immediately.
+ *
+ * @note This is an extension of version 1.1 of `IComponentStore`. The purpose
+ * of the extension is to add support for blocking output buffer allocator.
+ */
+interface IComponentStore {
+    /**
+     * Component traits.
+     */
+    parcelable ComponentTraits {
+        @Backing(type="int")
+        enum Kind {
+            OTHER = 0,
+            DECODER,
+            ENCODER,
+        }
+        @Backing(type="int")
+        enum Domain {
+            OTHER = 0,
+            VIDEO,
+            AUDIO,
+            IMAGE,
+        }
+        /**
+         * Name of the component. This must be unique for each component.
+         *
+         * This name is use to identify the component to create in
+         * createComponent() and createComponentInterface().
+         */
+        String name;
+        /**
+         * Component domain.
+         */
+        Domain domain;
+        /**
+         * Component kind.
+         */
+        Kind kind;
+        /**
+         * Rank used by `MediaCodecList` to determine component ordering. Lower
+         * value means higher priority.
+         */
+        int rank;
+        /**
+         * MIME type.
+         */
+        String mediaType;
+        /**
+         * Aliases for component name for backward compatibility.
+         *
+         * Multiple components can have the same alias (but not the same
+         * component name) as long as their media types differ.
+         */
+        String[] aliases;
+    }
+
+    /**
+     * Copies the contents of @p src into @p dst without changing the format of
+     * @p dst.
+     *
+     * @param src Source buffer.
+     * @param dst Destination buffer.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::CANNOT_DO` - @p src and @p dst are not compatible.
+     *   - `Status::REFUSED`   - No permission to copy.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    void copyBuffer(in Buffer src, in Buffer dst);
+
+    /**
+     * Creates a component by name.
+     *
+     * @param name Name of the component to create. This must match one of the
+     *     names returned by listComponents().
+     * @param listener Callback receiver.
+     * @param pool `IClientManager` object of the BufferPool in the client
+     *     process. This may be null if the client does not own a BufferPool.
+     * @return The created component.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::NOT_FOUND` - There is no component with the given name.
+     *   - `Status::NO_MEMORY` - Not enough memory to create the component.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     *
+     * @sa IComponentListener.
+     */
+    IComponent createComponent(in String name, in IComponentListener listener,
+        in android.hardware.media.bufferpool2.IClientManager pool);
+
+    /**
+     * Creates a component interface by name.
+     *
+     * @param name Name of the component interface to create. This should match
+     *     one of the names returned by listComponents().
+     * @return The created component interface.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::NOT_FOUND` - There is no component interface with the given name.
+     *   - `Status::NO_MEMORY` - Not enough memory to create the component interface.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    IComponentInterface createInterface(in String name);
+
+    /**
+     * Returns the @ref IConfigurable instance associated to this component
+     * store.
+     *
+     * @return `IConfigurable` instance. This must not be null.
+     */
+    IConfigurable getConfigurable();
+
+    /**
+     * Returns the `IClientManager` object for the component's BufferPool.
+     *
+     * @return If the component store supports receiving buffers via
+     *     BufferPool API, @p pool must be a valid `IClientManager` instance.
+     *     Otherwise, @p pool must be null.
+     */
+    android.hardware.media.bufferpool2.IClientManager getPoolClientManager();
+
+    /**
+     * Returns a list of `StructDescriptor` objects for a set of requested
+     * C2Param structure indices that this store is aware of.
+     *
+     * This operation must be performed at best effort, e.g. the component
+     * store must simply ignore all struct indices that it is not aware of.
+     *
+     * @param indices Indices of C2Param structures to describe.
+     * @return List of `StructDescriptor` objects.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::NOT_FOUND` - Some indices were not known.
+     *   - `Status::NO_MEMORY` - Not enough memory to complete this method.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    StructDescriptor[] getStructDescriptors(in int[] indices);
+
+    /**
+     * Returns the list of components supported by this component store.
+     *
+     * @return traits List of component traits for all components supported by
+     *     this store (in no particular order).
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::NO_MEMORY` - Not enough memory to complete this method.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    ComponentTraits[] listComponents();
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IConfigurable.aidl b/staging/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
new file mode 100644
index 0000000..9f79576
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldSupportedValuesQuery;
+import android.hardware.media.c2.FieldSupportedValuesQueryResult;
+import android.hardware.media.c2.ParamDescriptor;
+import android.hardware.media.c2.Params;
+import android.hardware.media.c2.SettingResult;
+
+/**
+ * Generic configuration interface presented by all configurable Codec2 objects.
+ *
+ * This interface must be supported in all states of the owning object, and must
+ * not change the state of the owning object.
+ */
+interface IConfigurable {
+    /**
+     * Return parcelable for config() interface.
+     *
+     * This includes the successful config settings along with the failure reasons of
+     * the specified setting.
+     */
+    parcelable ConfigResult {
+        Params params;
+        SettingResult[] failures;
+    }
+
+    /**
+     * Sets a set of parameters for the object.
+     *
+     * Tuning is performed at best effort: the object must update all supported
+     * configurations at best effort and skip unsupported parameters. Any errors
+     * are communicated in the return value along with the failures.
+     *
+     * A non-strict parameter update with an unsupported value shall cause an
+     * update to the closest supported value. A strict parameter update with an
+     * unsupported value shall be skipped and a failure shall be returned.
+     *
+     * If @p mayBlock is false, this method must not block. An update that
+     * requires blocking shall be skipped and a failure shall be returned.
+     *
+     * If @p mayBlock is true, an update may block, but the whole method call
+     * has to complete in a timely manner, or `Status::TIMED_OUT` is thrown.
+     *
+     * The final values for all parameters set are propagated back to the caller
+     * in @p params.
+     *
+     * \par For IComponent
+     *
+     * When the object type is @ref IComponent, this method must be supported in
+     * any state except released.
+     *
+     * The blocking behavior of this method differs among states:
+     *   - In the stopped state, this must be non-blocking. @p mayBlock is
+     *     ignored. (The method operates as if @p mayBlock was false.)
+     *   - In any of the running states, this method may block momentarily if
+     *     @p mayBlock is true. However, if the call cannot be completed in a
+     *     timely manner, `Status::TIMED_OUT` is thrown.
+     *
+     * @note Parameter tuning @e does depend on the order of the tuning
+     * parameters, e.g., some parameter update may enable some subsequent
+     * parameter update.
+     *
+     * @param inParams Requested parameter updates.
+     * @param mayBlock Whether this call may block or not.
+     * @return result of config. Params in the result should be in same order
+     *     with @p inParams.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::NO_MEMORY` - Some supported parameters could not be updated
+     *                   successfully because they contained unsupported values.
+     *                   These are returned in @p failures.
+     *   - `Status::BLOCKING`  - Setting some parameters requires blocking, but
+     *                   @p mayBlock is false.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    ConfigResult config(in Params inParams, in boolean mayBlock);
+
+    /**
+     * Returns the id of the object. This must be unique among all objects of
+     * the same type hosted by the same store.
+     *
+     * @return Id of the object.
+     */
+    int getId();
+
+    /**
+     * Returns the name of the object.
+     *
+     * This must match the name that was supplied during the creation of the
+     * object.
+     *
+     * @return Name of the object.
+     */
+    String getName();
+
+    /**
+     * Queries a set of parameters from the object.
+     *
+     * Querying is performed at best effort: the object must query all supported
+     * parameters and skip unsupported ones (which may include parameters that
+     * could not be allocated).
+     *
+     * If @p mayBlock is true, a query may block, but the whole method call
+     * has to complete in a timely manner, or `Status::TIMED_OUT` is thrown.
+     *
+     * If @p mayBlock is false, this method must not block(All parameter queries
+     * that require blocking must be skipped). Otherwise, this
+     * method is allowed to block for a certain period of time before completing
+     * the operation. If the operation is not completed in a timely manner,
+     * `Status::TIMED_OUT` is thrown.
+     *
+     * @note Since unsupported parameters will be skipped, the returned results
+     *     does not have every settings from @p indices, but the result will preserve
+     *     the original order from @p indices though unsupported settings are skipped.
+     *
+     * \par For IComponent
+     *
+     * When the object type is @ref IComponent, this method must be supported in
+     * any state except released. This call must not change the state nor the
+     * internal configuration of the component.
+     *
+     * The blocking behavior of this method differs among states:
+     *   - In the stopped state, this must be non-blocking. @p mayBlock is
+     *     ignored. (The method operates as if @p mayBlock was false.)
+     *   - In any of the running states, this method may block momentarily if
+     *     @p mayBlock is true. However, if the call cannot be completed in a
+     *     timely manner, `Status::status` is thrown.
+     *
+     * @param indices List of C2Param structure indices to query.
+     * @param mayBlock Whether this call may block or not.
+     * @return Flattened representation of std::vector<C2Param> object.
+     *     Unsupported settings are skipped in the results. The order in @p indices
+     *     still be preserved except skipped settings.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::NO_MEMORY` - Could not allocate memory for a supported parameter.
+     *   - `Status::BLOCKING`  - Querying some parameters requires blocking, but
+     *                   @p mayBlock is false.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    Params query(in int[] indices, in boolean mayBlock);
+
+    /**
+     * Returns a list of supported parameters within a selected range of C2Param
+     * structure indices.
+     *
+     * @param start The first index of the selected range.
+     * @param count The length of the selected range.
+     * @return List of supported parameters in the selected range. This
+     *     list may have fewer than @p count elements if some indices in the
+     *     range are not supported.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::NO_MEMORY` - Not enough memory to complete this method.
+     *
+     */
+    ParamDescriptor[] querySupportedParams(in int start, in int count);
+
+    /**
+     * Retrieves the supported values for the queried fields.
+     *
+     * The object must process all fields queried even if some queries fail.
+     *
+     * If @p mayBlock is false, this method must not block. Otherwise, this
+     * method is allowed to block for a certain period of time before completing
+     * the operation. If the operation cannot be completed in a timely manner,
+     * `Status::TIMED_OUT` is thrown.
+     *
+     * \par For IComponent
+     *
+     * When the object type is @ref IComponent, this method must be supported in
+     * any state except released.
+     *
+     * The blocking behavior of this method differs among states:
+     *   - In the stopped state, this must be non-blocking. @p mayBlock is
+     *     ignored. (The method operates as if @p mayBlock was false.)
+     *   - In any of the running states, this method may block momentarily if
+     *     @p mayBlock is true. However, if the call cannot be completed in a
+     *     timely manner, `Status::TIMED_OUT` is thrown.
+     *
+     * @param inFields List of field queries.
+     * @param mayBlock Whether this call may block or not.
+     * @return List of supported values and results for the
+     *     supplied queries.
+     * @throws ServiceSpecificException with one of the following values:
+     *   - `Status::BLOCKING`  - Querying some parameters requires blocking, but
+     *                   @p mayBlock is false.
+     *   - `Status::NO_MEMORY` - Not enough memory to complete this method.
+     *   - `Status::BLOCKING`  - Querying some fields requires blocking, but @p mayblock
+     *                   is false.
+     *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+     *   - `Status::CORRUPTED` - Some unknown error occurred.
+     */
+    FieldSupportedValuesQueryResult[] querySupportedValues(
+            in FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl b/staging/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl
new file mode 100644
index 0000000..7cfabcb
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.Buffer;
+
+/**
+ * An extension of @ref Buffer that also contains a C2Param structure index.
+ *
+ * This is a part of @ref FrameData.
+ */
+parcelable InfoBuffer {
+    /**
+     * A C2Param structure index.
+     */
+    int index;
+    /**
+     * Associated @ref Buffer object.
+     */
+    Buffer buffer;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl b/staging/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl
new file mode 100644
index 0000000..716c07e
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Usage description of a C2Param structure.
+ *
+ * @ref ParamDescriptor is returned by IConfigurable::querySupportedParams().
+ */
+parcelable ParamDescriptor {
+    /** The list of bit flags for attrib */
+    /**
+     * The parameter is required to be specified.
+     */
+    const int ATTRIBUTE_REQUIRED = 1 << 0;
+    /**
+     * The parameter retains its value.
+     */
+    const int ATTRIBUTE_PERSISTENT = 1 << 1;
+    /**
+     * The parameter is strict.
+     */
+    const int ATTRIBUTE_STRICT = 1 << 2;
+    /**
+     * The parameter is publicly read-only.
+     */
+    const int ATTRIBUTE_READ_ONLY = 1 << 3;
+    /**
+     * The parameter must not be visible to clients.
+     */
+    const int ATTRIBUTE_HIDDEN = 1 << 4;
+    /**
+     * The parameter must not be used by framework (other than testing).
+     */
+    const int ATTRIBUTE_INTERNAL = 1 << 5;
+    /**
+     * The parameter is publicly constant (hence read-only).
+     */
+    const int ATTRIBUTE_CONST = 1 << 6;
+
+    /**
+     * Index of the C2Param structure being described.
+     */
+    int index;
+    /**
+     * bit flag for attribute defined in the above.
+     */
+    int attrib;
+    /**
+     * Name of the structure. This must be unique for each structure.
+     */
+    String name;
+    /**
+     * Indices of other C2Param structures that this C2Param structure depends
+     * on.
+     */
+    int[] dependencies;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/ParamField.aidl b/staging/c2/aidl/android/hardware/media/c2/ParamField.aidl
new file mode 100644
index 0000000..94f737d
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/ParamField.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldId;
+
+/**
+ * Reference to a field in a C2Param structure.
+ */
+parcelable ParamField {
+    /**
+     * Index of the C2Param structure.
+     */
+    int index;
+    /**
+     * Identifier of the field inside the C2Param structure.
+     */
+    FieldId fieldId;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl b/staging/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl
new file mode 100644
index 0000000..4bb9a91
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldSupportedValues;
+import android.hardware.media.c2.ParamField;
+
+/**
+ * Supported values for a field.
+ *
+ * This is a pair of the field specifier together with an optional supported
+ * values object. This structure is used when reporting parameter configuration
+ * failures and conflicts.
+ */
+parcelable ParamFieldValues {
+    /**
+     * Reference to a field or a C2Param structure.
+     */
+    ParamField paramOrField;
+    /**
+     * Optional supported values for the field if #paramOrField specifies an
+     * actual field that is numeric (non struct, blob or string). Supported
+     * values for arrays (including string and blobs) describe the supported
+     * values for each element (character for string, and bytes for blobs). It
+     * is optional for read-only strings and blobs.
+     */
+    FieldSupportedValues[] values;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Params.aidl b/staging/c2/aidl/android/hardware/media/c2/Params.aidl
new file mode 100644
index 0000000..3c1a321
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Params.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Flattened representation of std::vector<C2Param> object.
+ *
+ * The `Params` type is an array of bytes made up by concatenating a list of
+ * C2Param objects. The start index (offset into @ref Params) of each C2Param
+ * object in the list is divisible by 8. Up to 7 padding bytes may be added
+ * after each C2Param object to achieve this 64-bit alignment.
+ *
+ * Each C2Param object has the following layout:
+ * - 4 bytes: C2Param structure index (of type @ref ParamIndex) identifying the
+ *   type of the C2Param object.
+ * - 4 bytes: size of the C2Param object (unsigned 4-byte integer).
+ * - (size - 8) bytes: data of the C2Param object.
+ */
+parcelable Params {
+    byte[] params;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/SettingResult.aidl b/staging/c2/aidl/android/hardware/media/c2/SettingResult.aidl
new file mode 100644
index 0000000..a270146
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/SettingResult.aidl
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.ParamFieldValues;
+
+/**
+ * Information describing the reason the parameter settings may fail, or may be
+ * overridden.
+ */
+parcelable SettingResult {
+    /**
+     * Failure code
+     */
+    @Backing(type="int")
+    enum Failure {
+        /**
+         * Parameter is not supported.
+         */
+        BAD_TYPE,
+        /**
+         * Parameter is not supported on the specific port.
+         */
+        BAD_PORT,
+        /**
+         * Parameter is not supported on the specific stream.
+         */
+        BAD_INDEX,
+        /**
+         * Parameter is read-only and cannot be set.
+         */
+        READ_ONLY,
+        /**
+         * Parameter mismatches input data.
+         */
+        MISMATCH,
+        /**
+         * Strict parameter does not accept value for the field at all.
+         */
+        BAD_VALUE,
+        /**
+         * Strict parameter field value is in conflict with an/other
+         * setting(s).
+         */
+        CONFLICT,
+        /**
+         * Parameter field is out of range due to other settings. (This failure
+         * mode can only be used for strict calculated parameters.)
+         */
+        UNSUPPORTED,
+        /**
+         * Field does not access the requested parameter value at all. It has
+         * been corrected to the closest supported value. This failure mode is
+         * provided to give guidance as to what are the currently supported
+         * values for this field (which may be a subset of the at-all-potential
+         * values).
+         */
+        INFO_BAD_VALUE,
+        /**
+         * Requested parameter value is in conflict with an/other setting(s)
+         * and has been corrected to the closest supported value. This failure
+         * mode is given to provide guidance as to what are the currently
+         * supported values as well as to optionally provide suggestion to the
+         * client as to how to enable the requested parameter value.
+         */
+        INFO_CONFLICT,
+    }
+    Failure failure;
+    /**
+     * Failing (or corrected) field or parameter and optionally, currently
+     * supported values for the field. Values must only be set for field
+     * failures other than `BAD_VALUE`, and only if they are different from the
+     * globally supported values (e.g. due to restrictions by another parameter
+     * or input data).
+     */
+    ParamFieldValues field;
+    /**
+     * Conflicting parameters or fields with (optional) suggested values for any
+     * conflicting fields to avoid the conflict. Values must only be set for
+     * `CONFLICT`, `UNSUPPORTED` or `INFO_CONFLICT` failure code.
+     */
+    ParamFieldValues[] conflicts;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Status.aidl b/staging/c2/aidl/android/hardware/media/c2/Status.aidl
new file mode 100644
index 0000000..660db57
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Status.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Common return values for Codec2 operations.
+ */
+parcelable Status {
+    /**
+     * Operation completed successfully.
+     */
+    const int OK = 0;
+    /**
+     * Argument has invalid value (user error).
+     */
+    const int BAD_VALUE = -22;
+    /**
+     * Argument uses invalid index (user error).
+     */
+    const int BAD_INDEX = -75;
+    /**
+     * Argument/Index is valid but not possible.
+     */
+    const int CANNOT_DO = -2147483646;
+    /**
+     * Object already exists.
+     */
+    const int DUPLICATE = -17;
+    /**
+     * Object not found.
+     */
+    const int NOT_FOUND = -2;
+    /**
+     * Operation is not permitted in the current state.
+     */
+    const int BAD_STATE = -38;
+    /**
+     * Operation would block but blocking is not permitted.
+     */
+    const int BLOCKING = -9930;
+    /**
+     * Not enough memory to complete operation.
+     */
+    const int NO_MEMORY = -12;
+    /**
+     * Missing permission to complete operation.
+     */
+    const int REFUSED = -1;
+    /**
+     * Operation did not complete within timeout.
+     */
+    const int TIMED_OUT = -110;
+    /**
+     * Operation is not implemented/supported (optional only).
+     */
+    const int OMITTED = -74;
+    /**
+     * Some unexpected error prevented the operation.
+     */
+    const int CORRUPTED = -2147483648;
+    /**
+     * Status has not been initialized.
+     */
+    const int NO_INIT = -19;
+
+    int status;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl b/staging/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl
new file mode 100644
index 0000000..5d6d2eb
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldDescriptor;
+
+/**
+ * Description of a C2Param structure. It consists of an index and a list of
+ * `FieldDescriptor`s.
+ */
+parcelable StructDescriptor {
+    /**
+     * Index of the structure.
+     *
+     * Actually C2Param::CoreIndex
+     * Core index is the underlying parameter type for a parameter. It is used to describe the
+     * layout of the parameter structure regardless of the component or parameter kind/scope.
+     *
+     * It is used to identify and distinguish global parameters, and also parameters on a given
+     * port or stream. They must be unique for the set of global parameters, as well as for the
+     * set of parameters on each port or each stream, but the same core index can be used for
+     * parameters on different streams or ports, as well as for global parameters and port/stream
+     * parameters.
+     */
+    int type;
+    /**
+     * List of fields in the structure.
+     *
+     * Fields are ordered by their offsets. A field that is a structure is
+     * ordered before its members.
+     */
+    FieldDescriptor[] fields;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl b/staging/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
new file mode 100644
index 0000000..2e7330e
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+/**
+ * Surface(BufferQueue/IGBP) synchronization object regarding # of dequeued
+ * output buffers. This keeps # of dequeued buffers from Surface less than
+ * configured max # of dequeued buffers all the time.
+ */
+parcelable SurfaceSyncObj {
+    /**
+     * ASharedMemory for synchronization data. Layout is below
+     *
+     * |lock(futex)                               4bytes|
+     * |conditional_variable(futex)               4bytes|
+     * |# of max dequeable buffer                 4bytes|
+     * |# of dequeued buffer                      4bytes|
+     * |Status of the surface                     4bytes|
+     *      INIT        = 0, Configuring surface is not finished.
+     *      ACTIVE      = 1, Surface is ready to allocate(dequeue).
+     *      SWITCHING   = 2, Switching to the new surface. It is blocked
+     *                       to allocate(dequeue) a buffer until switching
+     *                       completes.
+     */
+    NativeHandle syncMemory;
+    /**
+     * BufferQueue id.
+     */
+    long bqId;
+    /**
+     * Generation id.
+     */
+    int generationId;
+    /**
+     * Consumer usage flags. See +ndk
+     * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
+     */
+    long consumerUsage;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/ValueRange.aidl b/staging/c2/aidl/android/hardware/media/c2/ValueRange.aidl
new file mode 100644
index 0000000..6707a25
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/ValueRange.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Description of a set of values.
+ *
+ * If the `step` member is 0, and `num` and `denom` are both 1, the `Range`
+ * structure represents a closed interval bounded by `min` and `max`.
+ *
+ * Otherwise, the #ValueRange structure represents a finite sequence of numbers
+ * produced from the following recurrence relation:
+ *
+ * @code
+ * v[0] = min
+ * v[i] = v[i - 1] * num / denom + step ; i >= 1
+ * @endcode
+ *
+ * Both the ratio `num / denom` and the value `step` must be positive. The
+ * last number in the sequence described by this #Range structure is the
+ * largest number in the sequence that is smaller than or equal to `max`.
+ *
+ * @note
+ * The division in the formula may truncate the result if the data type of
+ * these values is an integral type.
+ */
+parcelable ValueRange {
+    /**
+     * Lower end of the range (inclusive).
+     */
+    long min;
+    /**
+     * Upper end of the range (inclusive).
+     */
+    long max;
+    /**
+     * The non-homogeneous term in the recurrence relation.
+     */
+    long step;
+    /**
+     * The numerator of the scale coefficient in the recurrence relation.
+     */
+    long num;
+    /**
+     * The denominator of the scale coefficient in the recurrence relation.
+     */
+    long denom;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Work.aidl b/staging/c2/aidl/android/hardware/media/c2/Work.aidl
new file mode 100644
index 0000000..0732479
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Work.aidl
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FrameData;
+import android.hardware.media.c2.Status;
+import android.hardware.media.c2.Worklet;
+
+/**
+ * A collection of input data to and output data from the component.
+ *
+ * A `Work` object holds information about a single work item. It is created by
+ * the client and passed to the component via IComponent::queue(). The component
+ * has two ways of returning a `Work` object to the client:
+ *   1. If the queued `Work` object has been successfully processed,
+ *      IComponentListener::onWorkDone() shall be called to notify the listener,
+ *      and the output shall be included in the returned `Work` object.
+ *   2. If the client calls IComponent::flush(), a `Work` object that has not
+ *      been processed shall be returned.
+ *
+ * `Work` is a part of @ref WorkBundle.
+ */
+parcelable Work {
+    /**
+     * Additional work chain info not part of this work.
+     */
+    byte[] chainInfo;
+    /**
+     * @ref FrameData for the input.
+     */
+    FrameData input;
+    /**
+     * The chain of `Worklet`s.
+     *
+     * The length of #worklets is 1 when tunneling is not enabled.
+     *
+     * If #worklets has more than a single element, the tunnels between
+     * successive components of the work chain must have been successfully
+     * pre-registered at the time that the `Work` is submitted. Allocating the
+     * output buffers in the `Worklet`s is the responsibility of each component
+     * in the chain.
+     *
+     * Upon `Work` submission, #worklets must be an appropriately sized vector
+     * containing `Worklet`s with @ref Worklet.hasOutput set to `false`. After a
+     * successful processing, all but the final `Worklet` in the returned
+     * #worklets must have @ref Worklet.hasOutput set to `false`.
+     */
+    Worklet[] worklets;
+    /**
+     * The number of `Worklet`s successfully processed in this chain.
+     *
+     * This must be initialized to 0 by the client when the `Work` is submitted,
+     * and it must contain the number of `Worklet`s that were successfully
+     * processed when the `Work` is returned to the client.
+     *
+     * #workletsProcessed cannot exceed the length of #worklets. If
+     * #workletsProcessed is smaller than the length of #worklets, #result
+     * cannot be `OK`.
+     */
+    int workletsProcessed;
+    /**
+     * The final outcome of the `Work` (corresponding to #workletsProcessed).
+     *
+     * The value of @ref Status.OK implies that all `Worklet`s have been
+     * successfully processed.
+     */
+    Status result;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/WorkBundle.aidl b/staging/c2/aidl/android/hardware/media/c2/WorkBundle.aidl
new file mode 100644
index 0000000..79b4cdb
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/WorkBundle.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.BaseBlock;
+import android.hardware.media.c2.Work;
+
+/**
+ * List of `Work` objects.
+ *
+ * `WorkBundle` is used in IComponent::queue(), IComponent::flush() and
+ * IComponentListener::onWorkDone(). A `WorkBundle` object consists of a list of
+ * `Work` objects and a list of `BaseBlock` objects. Bundling multiple `Work`
+ * objects together provides two benefits:
+ *   1. Batching of `Work` objects can reduce the number of IPC calls.
+ *   2. If multiple `Work` objects contain `Block`s that refer to the same
+ *      `BaseBlock`, the number of `BaseBlock`s that is sent between processes
+ *      is also reduced.
+ *
+ * @note `WorkBundle` is the AIDL counterpart of the vector of `C2Work` in the
+ * Codec 2.0 standard. The presence of #baseBlocks helps with minimizing the
+ * data transferred over an IPC.
+ */
+parcelable WorkBundle {
+    /**
+     * A list of Work items.
+     */
+    Work[] works;
+    /**
+     * A list of blocks indexed by elements of #works.
+     */
+    BaseBlock[] baseBlocks;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl b/staging/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl
new file mode 100644
index 0000000..eb8b244
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Ordering information of @ref FrameData objects. Each member is used for
+ * comparing urgency: a smaller difference from a reference value indicates that
+ * the associated Work object is more urgent. The reference value for each
+ * member is initialized the first time it is communicated between the client
+ * and the codec, and it may be updated to later values that are communicated.
+ *
+ * Each member of `WorkOrdinal` is stored as an unsigned integer, but the actual
+ * order it represents is derived by subtracting the reference value, then
+ * interpreting the result as a signed number with the same storage size (using
+ * two's complement).
+ *
+ * @note `WorkOrdinal` is the HIDL counterpart of `C2WorkOrdinalStruct` in the
+ * Codec 2.0 standard.
+ */
+parcelable WorkOrdinal {
+    /**
+     * Timestamp in microseconds.
+     */
+    long timestampUs;
+    /**
+     * Frame index.
+     */
+    long frameIndex;
+    /**
+     * Component specific frame ordinal.
+     */
+    long customOrdinal;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Worklet.aidl b/staging/c2/aidl/android/hardware/media/c2/Worklet.aidl
new file mode 100644
index 0000000..04c59c1
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Worklet.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FrameData;
+import android.hardware.media.c2.SettingResult;
+
+/**
+ * In/out structure containing some instructions for and results from output
+ * processing.
+ *
+ * This is a part of @ref Work. One `Worklet` corresponds to one output
+ * @ref FrameData. The client must construct an original `Worklet` object inside
+ * a @ref Work object for each expected output before calling
+ * IComponent::queue().
+ */
+parcelable Worklet {
+    /**
+     * Component id. (Input)
+     *
+     * This is used only when tunneling is enabled.
+     *
+     * When used, this must match the return value from IConfigurable::getId().
+     */
+    int componentId;
+    /**
+     * List of C2Param objects describing tunings to be applied before
+     * processing this `Worklet`. (Input)
+     */
+    byte[] tunings;
+    /**
+     * List of failures. (Output)
+     */
+    SettingResult[] failures;
+    /**
+     * Output frame data. (Output)
+     */
+    FrameData output;
+}
diff --git a/staging/threadnetwork/OWNERS b/staging/threadnetwork/OWNERS
new file mode 100644
index 0000000..037215d
--- /dev/null
+++ b/staging/threadnetwork/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 1203089
+
+wgtdkp@google.com
+xyk@google.com
+zhanglongxia@google.com
diff --git a/staging/threadnetwork/README.md b/staging/threadnetwork/README.md
new file mode 100644
index 0000000..12104e5
--- /dev/null
+++ b/staging/threadnetwork/README.md
@@ -0,0 +1,12 @@
+# Staging threadnetwork HAL interface
+
+The directory includes the unstable/unreleased version of `hardware/interfaces/threadnetwork`
+code which should **NOT** be used in production. But vendors may start verifying their hardware
+with the HAL interface.
+
+This directory will be cleaned up when the stable Thread HAL interface is added in
+`hardware/interfaces/threadnetwork` by version `V` or later.
+
+More information about _Thread_:
+- https://www.threadgroup.org
+- https://openthread.io
diff --git a/staging/threadnetwork/aidl/Android.bp b/staging/threadnetwork/aidl/Android.bp
new file mode 100644
index 0000000..b59d6da
--- /dev/null
+++ b/staging/threadnetwork/aidl/Android.bp
@@ -0,0 +1,26 @@
+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"],
+}
+
+aidl_interface {
+    name: "android.hardware.threadnetwork",
+    host_supported: true,
+    vendor_available: true,
+
+    srcs: [
+        "android/hardware/threadnetwork/*.aidl",
+    ],
+
+    unstable: true,
+
+    backend: {
+        ndk: {
+            enabled: true,
+        },
+    },
+}
diff --git a/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChip.aidl b/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChip.aidl
new file mode 100644
index 0000000..3c57149
--- /dev/null
+++ b/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChip.aidl
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.threadnetwork;
+
+import android.hardware.threadnetwork.IThreadChipCallback;
+
+/**
+ * Controls a Thread radio chip on the device.
+ */
+
+interface IThreadChip {
+    /**
+     * The operation failed for the internal error.
+     */
+    const int ERROR_FAILED = 1;
+
+    /**
+     * Insufficient buffers available to send frames.
+     */
+    const int ERROR_NO_BUFS = 2;
+
+    /**
+     * Service is busy and could not service the operation.
+     */
+    const int ERROR_BUSY = 3;
+
+    /**
+     * This method initializes the Thread HAL instance. If open completes
+     * successfully, then the Thread HAL instance is ready to accept spinel
+     * messages through sendSpinelFrame() API.
+     *
+     * @param callback  A IThreadChipCallback callback instance. If multiple
+     *                  callbacks are passed in, the open() will return ERROR_BUSY.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT  if the callback handle is invalid (for example, it is null).
+     * @throws ServiceSpecificException with one of the following values:
+     *     - ERROR_FAILED        The interface cannot be opened due to an internal error.
+     *     - ERROR_BUSY          This interface is in use.
+     */
+    void open(in IThreadChipCallback callback);
+
+    /**
+     * Close the Thread HAL instance. Must free all resources.
+     *
+     * @throws EX_ILLEGAL_STATE  if the Thread HAL instance is not opened.
+     *
+     */
+    void close();
+
+    /**
+     * This method resets the Thread HAL internal state. The callback registered by
+     * `open()` won’t be reset and the resource allocated by `open()` won’t be free.
+     *
+     */
+    void reset();
+
+    /**
+     * This method sends a spinel frame to the Thread HAL.
+     *
+     * This method should block until the frame is sent out successfully or
+     * the method throws errors immediately.
+     *
+     * Spinel Protocol:
+     *     https://github.com/openthread/openthread/blob/main/src/lib/spinel/spinel.h
+     *
+     * @param frame  The spinel frame to be sent.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         - ERROR_FAILED The Thread HAL failed to send the frame for an internal reason.
+     *         - ERROR_NO_BUFS Insufficient buffer space to send the frame.
+     *         - ERROR_BUSY The Thread HAL is busy.
+     */
+    void sendSpinelFrame(in byte[] frame);
+}
diff --git a/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChipCallback.aidl b/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChipCallback.aidl
new file mode 100644
index 0000000..a0fe88c
--- /dev/null
+++ b/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChipCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.threadnetwork;
+
+interface IThreadChipCallback {
+    /**
+     * This method is called when a spinel frame is received. Thread network
+     * will process the received spinel frame.
+     *
+     * Spinel Protocol:
+     *     https://github.com/openthread/openthread/blob/main/src/lib/spinel/spinel.h
+     *
+     * @param frame  The received spinel frame.
+     */
+    oneway void onReceiveSpinelFrame(in byte[] frame);
+}
diff --git a/staging/threadnetwork/aidl/default/Android.bp b/staging/threadnetwork/aidl/default/Android.bp
new file mode 100644
index 0000000..8fc22ad
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/Android.bp
@@ -0,0 +1,63 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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_defaults {
+    name: "threadnetwork_service_default",
+    vendor: true,
+    relative_install_path: "hw",
+
+    shared_libs: [
+        "android.hardware.threadnetwork-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "liblog",
+        "libutils",
+    ],
+
+    static_libs: [
+        "openthread-common",
+        "openthread-hdlc",
+        "openthread-platform",
+        "openthread-posix",
+        "openthread-url",
+    ],
+
+    srcs: [
+        "main.cpp",
+        "service.cpp",
+        "thread_chip.cpp",
+        "utils.cpp",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.threadnetwork-service.sim",
+    defaults: ["threadnetwork_service_default"],
+    init_rc: ["android.hardware.threadnetwork-service.sim.rc"],
+}
+
+cc_binary {
+    name: "android.hardware.threadnetwork-service",
+    defaults: ["threadnetwork_service_default"],
+}
diff --git a/staging/threadnetwork/aidl/default/android.hardware.threadnetwork-service.sim.rc b/staging/threadnetwork/aidl/default/android.hardware.threadnetwork-service.sim.rc
new file mode 100644
index 0000000..2fb409c
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/android.hardware.threadnetwork-service.sim.rc
@@ -0,0 +1,3 @@
+service vendor.threadnetwork_hal /vendor/bin/hw/android.hardware.threadnetwork-service.sim spinel+hdlc+forkpty:///vendor/bin/ot-rcp?forkpty-arg=1
+    class hal
+    user thread_network
diff --git a/staging/threadnetwork/aidl/default/main.cpp b/staging/threadnetwork/aidl/default/main.cpp
new file mode 100644
index 0000000..b6c8bbb
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/main.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <utils/Log.h>
+
+#include "service.hpp"
+
+int main(int argc, char* argv[]) {
+    CHECK_GT(argc, 1);
+    aidl::android::hardware::threadnetwork::Service service(&argv[1], argc - 1);
+
+    ALOGI("Thread Network HAL is running");
+
+    service.startLoop();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/staging/threadnetwork/aidl/default/service.cpp b/staging/threadnetwork/aidl/default/service.cpp
new file mode 100644
index 0000000..8047214
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/service.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "service.hpp"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "thread_chip.hpp"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+Service::Service(char* urls[], int numUrls) : mBinderFd(-1) {
+    int fd;
+
+    CHECK_NE(urls, nullptr);
+    CHECK_GT(numUrls, 0);
+
+    for (int i = 0; i < numUrls; i++) {
+        auto threadChip = ndk::SharedRefBase::make<ThreadChip>(i, urls[i]);
+        CHECK_NE(threadChip, nullptr);
+        mThreadChips.push_back(std::move(threadChip));
+    }
+
+    binder_status_t status = ABinderProcess_setupPolling(&fd);
+    CHECK_EQ(status, ::STATUS_OK);
+    CHECK_GE(fd, 0);
+    mBinderFd.reset(fd);
+}
+
+void Service::Update(otSysMainloopContext& context) {
+    FD_SET(mBinderFd.get(), &context.mReadFdSet);
+    context.mMaxFd = std::max(context.mMaxFd, mBinderFd.get());
+}
+
+void Service::Process(const otSysMainloopContext& context) {
+    if (FD_ISSET(mBinderFd.get(), &context.mReadFdSet)) {
+        ABinderProcess_handlePolledCommands();
+    }
+}
+
+void Service::startLoop(void) {
+    const struct timeval kPollTimeout = {1, 0};
+    otSysMainloopContext context;
+    int rval;
+
+    ot::Posix::Mainloop::Manager::Get().Add(*this);
+
+    while (true) {
+        context.mMaxFd = -1;
+        context.mTimeout = kPollTimeout;
+
+        FD_ZERO(&context.mReadFdSet);
+        FD_ZERO(&context.mWriteFdSet);
+        FD_ZERO(&context.mErrorFdSet);
+
+        ot::Posix::Mainloop::Manager::Get().Update(context);
+
+        rval = select(context.mMaxFd + 1, &context.mReadFdSet, &context.mWriteFdSet,
+                      &context.mErrorFdSet, &context.mTimeout);
+
+        if (rval >= 0) {
+            ot::Posix::Mainloop::Manager::Get().Process(context);
+        } else if (errno != EINTR) {
+            ALOGE("select() failed: %s", strerror(errno));
+            break;
+        }
+    }
+}
+}  // namespace threadnetwork
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/staging/threadnetwork/aidl/default/service.hpp b/staging/threadnetwork/aidl/default/service.hpp
new file mode 100644
index 0000000..6e6e868
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/service.hpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/unique_fd.h>
+
+#include "mainloop.hpp"
+#include "thread_chip.hpp"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+class Service : public ot::Posix::Mainloop::Source {
+  public:
+    Service(char* urls[], int numUrls);
+
+    void Update(otSysMainloopContext& context) override;
+    void Process(const otSysMainloopContext& context) override;
+    void startLoop(void);
+
+  private:
+    ::android::base::unique_fd mBinderFd;
+    std::vector<std::shared_ptr<ThreadChip>> mThreadChips;
+};
+}  // namespace threadnetwork
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/staging/threadnetwork/aidl/default/thread_chip.cpp b/staging/threadnetwork/aidl/default/thread_chip.cpp
new file mode 100644
index 0000000..38abad4
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/thread_chip.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "thread_chip.hpp"
+
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+static ndk::ScopedAStatus errorStatus(int32_t error, const char* message) {
+    return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(error, message));
+}
+
+ThreadChip::ThreadChip(uint8_t id, char* url)
+    : mUrl(),
+      mInterface(handleReceivedFrame, this, mRxFrameBuffer),
+      mRxFrameBuffer(),
+      mCallback(nullptr) {
+    const std::string name(std::string() + IThreadChip::descriptor + "/chip" + std::to_string(id));
+    binder_status_t status;
+
+    ALOGI("ServiceName: %s, Url: %s", name.c_str(), url);
+    CHECK_EQ(mUrl.Init(url), 0);
+    status = AServiceManager_addService(asBinder().get(), name.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(
+            AIBinder_DeathRecipient_new(ThreadChip::onBinderDied));
+    AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(), ThreadChip::onBinderUnlinked);
+}
+
+ThreadChip::~ThreadChip() {
+    AIBinder_DeathRecipient_delete(mDeathRecipient.get());
+}
+
+void ThreadChip::onBinderDied(void* context) {
+    reinterpret_cast<ThreadChip*>(context)->onBinderDied();
+}
+
+void ThreadChip::onBinderDied(void) {
+    ALOGW("Thread Network HAL client is dead.");
+}
+
+void ThreadChip::onBinderUnlinked(void* context) {
+    reinterpret_cast<ThreadChip*>(context)->onBinderUnlinked();
+}
+
+void ThreadChip::onBinderUnlinked(void) {
+    ALOGW("ThreadChip binder is unlinked.");
+    deinitChip();
+}
+
+void ThreadChip::handleReceivedFrame(void* context) {
+    reinterpret_cast<ThreadChip*>(context)->handleReceivedFrame();
+}
+
+void ThreadChip::handleReceivedFrame(void) {
+    if (mCallback != nullptr) {
+        mCallback->onReceiveSpinelFrame(std::vector<uint8_t>(
+                mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetFrame() + mRxFrameBuffer.GetLength()));
+    }
+
+    mRxFrameBuffer.DiscardFrame();
+}
+
+ndk::ScopedAStatus ThreadChip::open(const std::shared_ptr<IThreadChipCallback>& in_callback) {
+    ndk::ScopedAStatus status = initChip(in_callback);
+
+    if (status.isOk()) {
+        AIBinder_linkToDeath(in_callback->asBinder().get(), mDeathRecipient.get(), this);
+        ALOGI("Open IThreadChip successfully.");
+    } else {
+        ALOGW("Open IThreadChip failed, error: %s", status.getDescription().c_str());
+    }
+
+    return status;
+}
+
+ndk::ScopedAStatus ThreadChip::initChip(const std::shared_ptr<IThreadChipCallback>& in_callback) {
+    if (in_callback == nullptr) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    } else if (mCallback == nullptr) {
+        if (mInterface.Init(mUrl) != OT_ERROR_NONE) {
+            return errorStatus(ERROR_FAILED, "Failed to initialize the interface");
+        }
+
+        mCallback = in_callback;
+        ot::Posix::Mainloop::Manager::Get().Add(*this);
+        return ndk::ScopedAStatus::ok();
+    } else {
+        return errorStatus(ERROR_BUSY, "Interface is already opened");
+    }
+}
+
+ndk::ScopedAStatus ThreadChip::close() {
+    ndk::ScopedAStatus status;
+    std::shared_ptr<IThreadChipCallback> callback = mCallback;
+
+    status = deinitChip();
+    if (status.isOk()) {
+        if (callback != nullptr) {
+            AIBinder_unlinkToDeath(callback->asBinder().get(), mDeathRecipient.get(), this);
+        }
+
+        ALOGI("Close IThreadChip successfully");
+    } else {
+        ALOGW("Close IThreadChip failed, error: %s", status.getDescription().c_str());
+    }
+
+    return status;
+}
+
+ndk::ScopedAStatus ThreadChip::deinitChip() {
+    if (mCallback != nullptr) {
+        mInterface.Deinit();
+        ot::Posix::Mainloop::Manager::Get().Remove(*this);
+        mCallback = nullptr;
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+}
+
+ndk::ScopedAStatus ThreadChip::sendSpinelFrame(const std::vector<uint8_t>& in_frame) {
+    ndk::ScopedAStatus status;
+    otError error;
+
+    if (mCallback == nullptr) {
+        status = errorStatus(ERROR_FAILED, "The interface is not open");
+    } else {
+        error = mInterface.SendFrame(reinterpret_cast<const uint8_t*>(in_frame.data()),
+                                     in_frame.size());
+        if (error == OT_ERROR_NONE) {
+            status = ndk::ScopedAStatus::ok();
+        } else if (error == OT_ERROR_NO_BUFS) {
+            status = errorStatus(ERROR_NO_BUFS, "Insufficient buffer space to send");
+        } else if (error == OT_ERROR_BUSY) {
+            status = errorStatus(ERROR_BUSY, "The interface is busy");
+        } else {
+            status = errorStatus(ERROR_FAILED, "Failed to send the spinel frame");
+        }
+    }
+
+    if (!status.isOk()) {
+        ALOGW("Send spinel frame failed, error: %s", status.getDescription().c_str());
+    }
+
+    return status;
+}
+
+ndk::ScopedAStatus ThreadChip::reset() {
+    mInterface.OnRcpReset();
+    ALOGI("reset()");
+    return ndk::ScopedAStatus::ok();
+}
+
+void ThreadChip::Update(otSysMainloopContext& context) {
+    if (mCallback != nullptr) {
+        mInterface.UpdateFdSet(context.mReadFdSet, context.mWriteFdSet, context.mMaxFd,
+                               context.mTimeout);
+    }
+}
+
+void ThreadChip::Process(const otSysMainloopContext& context) {
+    struct RadioProcessContext radioContext;
+
+    if (mCallback != nullptr) {
+        radioContext.mReadFdSet = &context.mReadFdSet;
+        radioContext.mWriteFdSet = &context.mWriteFdSet;
+        mInterface.Process(radioContext);
+    }
+}
+}  // namespace threadnetwork
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/staging/threadnetwork/aidl/default/thread_chip.hpp b/staging/threadnetwork/aidl/default/thread_chip.hpp
new file mode 100644
index 0000000..da5cba7
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/thread_chip.hpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/threadnetwork/BnThreadChip.h>
+#include <aidl/android/hardware/threadnetwork/IThreadChipCallback.h>
+
+#include "hdlc_interface.hpp"
+#include "lib/spinel/spinel_interface.hpp"
+#include "mainloop.hpp"
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder.h>
+#include <utils/Mutex.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+class ThreadChip : public BnThreadChip, ot::Posix::Mainloop::Source {
+  public:
+    ThreadChip(uint8_t id, char* url);
+    ~ThreadChip();
+
+    ndk::ScopedAStatus open(const std::shared_ptr<IThreadChipCallback>& in_callback) override;
+    ndk::ScopedAStatus close() override;
+    ndk::ScopedAStatus sendSpinelFrame(const std::vector<uint8_t>& in_frame) override;
+    ndk::ScopedAStatus reset() override;
+    void Update(otSysMainloopContext& context) override;
+    void Process(const otSysMainloopContext& context) override;
+
+  private:
+    static void onBinderDied(void* context);
+    void onBinderDied(void);
+    static void onBinderUnlinked(void* context);
+    void onBinderUnlinked(void);
+    static void handleReceivedFrame(void* context);
+    void handleReceivedFrame(void);
+
+    ndk::ScopedAStatus initChip(const std::shared_ptr<IThreadChipCallback>& in_callback);
+    ndk::ScopedAStatus deinitChip();
+
+    ot::Url::Url mUrl;
+    ot::Posix::HdlcInterface mInterface;
+    ot::Spinel::SpinelInterface::RxFrameBuffer mRxFrameBuffer;
+    std::shared_ptr<IThreadChipCallback> mCallback;
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+};
+
+}  // namespace threadnetwork
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/staging/threadnetwork/aidl/default/utils.cpp b/staging/threadnetwork/aidl/default/utils.cpp
new file mode 100644
index 0000000..d3b4062
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/utils.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <openthread/logging.h>
+#include <utils/Log.h>
+
+void otLogCritPlat(const char* format, ...) {
+    va_list args;
+
+    va_start(args, format);
+    __android_log_vprint(ANDROID_LOG_FATAL, LOG_TAG, format, args);
+    va_end(args);
+}
+
+void otLogWarnPlat(const char* format, ...) {
+    va_list args;
+
+    va_start(args, format);
+    __android_log_vprint(ANDROID_LOG_WARN, LOG_TAG, format, args);
+    va_end(args);
+}
diff --git a/staging/threadnetwork/aidl/vts/Android.bp b/staging/threadnetwork/aidl/vts/Android.bp
new file mode 100644
index 0000000..e2609ed
--- /dev/null
+++ b/staging/threadnetwork/aidl/vts/Android.bp
@@ -0,0 +1,47 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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_test {
+    name: "VtsHalThreadNetworkTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "VtsHalThreadNetworkTargetTest.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.threadnetwork-ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/staging/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp b/staging/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
new file mode 100644
index 0000000..14c5b06
--- /dev/null
+++ b/staging/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ThreadNetworkHalTargetTest"
+
+#include <future>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <log/log.h>
+
+#include <aidl/android/hardware/threadnetwork/BnThreadChipCallback.h>
+#include <aidl/android/hardware/threadnetwork/IThreadChip.h>
+
+using aidl::android::hardware::threadnetwork::BnThreadChipCallback;
+using aidl::android::hardware::threadnetwork::IThreadChip;
+using android::ProcessState;
+using ndk::ScopedAStatus;
+using ndk::SpAIBinder;
+
+namespace {
+constexpr static int kCallbackTimeoutMs = 5000;
+}  // namespace
+
+class ThreadChipCallback : public BnThreadChipCallback {
+  public:
+    ThreadChipCallback(const std::function<void(const std::vector<uint8_t>&)>& on_spinel_message_cb)
+        : on_spinel_message_cb_(on_spinel_message_cb) {}
+
+    ScopedAStatus onReceiveSpinelFrame(const std::vector<uint8_t>& in_aFrame) {
+        on_spinel_message_cb_(in_aFrame);
+        return ScopedAStatus::ok();
+    }
+
+  private:
+    std::function<void(const std::vector<uint8_t>&)> on_spinel_message_cb_;
+};
+
+class ThreadNetworkAidl : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        std::string serviceName = GetParam();
+
+        ALOGI("serviceName: %s", serviceName.c_str());
+
+        thread_chip = IThreadChip::fromBinder(
+                SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+        ASSERT_NE(thread_chip, nullptr);
+    }
+
+    virtual void TearDown() override { thread_chip->close(); }
+    bool DeviceSupportsFeature(const char* feature);
+
+    static constexpr char kTvFeatureName[] = "android.software.leanback";
+    std::shared_ptr<IThreadChip> thread_chip;
+};
+
+bool ThreadNetworkAidl::DeviceSupportsFeature(const char* feature) {
+    bool device_supports_feature = false;
+    FILE* p = popen("pm list features", "re");
+    char* line = nullptr;
+    size_t len = 0;
+
+    if (!p) {
+        return false;
+    }
+
+    while (getline(&line, &len, p) > 0) {
+        if (strstr(line, feature)) {
+            device_supports_feature = true;
+            break;
+        }
+    }
+    pclose(p);
+
+    return device_supports_feature;
+}
+
+TEST_P(ThreadNetworkAidl, Open) {
+    std::shared_ptr<ThreadChipCallback> callback =
+            ndk::SharedRefBase::make<ThreadChipCallback>([](auto /* data */) {});
+
+    EXPECT_TRUE(thread_chip->open(callback).isOk());
+    EXPECT_EQ(thread_chip->open(callback).getServiceSpecificError(), IThreadChip::ERROR_BUSY);
+}
+
+TEST_P(ThreadNetworkAidl, Close) {
+    std::shared_ptr<ThreadChipCallback> callback =
+            ndk::SharedRefBase::make<ThreadChipCallback>([](auto /* data */) {});
+
+    EXPECT_TRUE(thread_chip->open(callback).isOk());
+    EXPECT_TRUE(thread_chip->close().isOk());
+    EXPECT_EQ(thread_chip->close().getExceptionCode(), EX_ILLEGAL_STATE);
+}
+
+TEST_P(ThreadNetworkAidl, Reset) {
+    std::shared_ptr<ThreadChipCallback> callback =
+            ndk::SharedRefBase::make<ThreadChipCallback>([](auto /* data */) {});
+
+    EXPECT_TRUE(thread_chip->open(callback).isOk());
+    EXPECT_TRUE(thread_chip->reset().isOk());
+}
+
+TEST_P(ThreadNetworkAidl, SendSpinelFrame) {
+    const uint8_t kCmdOffset = 2;
+    const uint8_t kMajorVersionOffset = 3;
+    const uint8_t kMinorVersionOffset = 4;
+    const std::vector<uint8_t> kGetSpinelProtocolVersion({0x81, 0x02, 0x01});
+    const std::vector<uint8_t> kGetSpinelProtocolVersionResponse({0x81, 0x06, 0x01, 0x04, 0x03});
+    uint8_t min_major_version = kGetSpinelProtocolVersionResponse[kMajorVersionOffset];
+    uint8_t min_minor_version = kGetSpinelProtocolVersionResponse[kMinorVersionOffset];
+    uint8_t major_version;
+    uint8_t minor_version;
+    std::promise<void> open_cb_promise;
+    std::future<void> open_cb_future{open_cb_promise.get_future()};
+    std::shared_ptr<ThreadChipCallback> callback;
+    std::vector<uint8_t> received_frame;
+    std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+
+    callback = ndk::SharedRefBase::make<ThreadChipCallback>(
+            [&](const std::vector<uint8_t>& in_aFrame) {
+                if (in_aFrame.size() == kGetSpinelProtocolVersionResponse.size() &&
+                    in_aFrame[kCmdOffset] == kGetSpinelProtocolVersionResponse[kCmdOffset]) {
+                    major_version = in_aFrame[kMajorVersionOffset];
+                    minor_version = in_aFrame[kMinorVersionOffset];
+                    open_cb_promise.set_value();
+                }
+            });
+
+    if (DeviceSupportsFeature(kTvFeatureName)) {
+        GTEST_SKIP() << "SendSpinelFrame test is bypassed on TV devices";
+    }
+
+    ASSERT_NE(callback, nullptr);
+
+    EXPECT_TRUE(thread_chip->open(callback).isOk());
+
+    EXPECT_TRUE(thread_chip->sendSpinelFrame(kGetSpinelProtocolVersion).isOk());
+    EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+    EXPECT_GE(major_version, min_major_version);
+    if (major_version == min_major_version) {
+        EXPECT_GE(minor_version, min_minor_version);
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThreadNetworkAidl);
+INSTANTIATE_TEST_SUITE_P(
+        Thread, ThreadNetworkAidl,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IThreadChip::descriptor)),
+        android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp
index 20df5bb..0306dca 100644
--- a/tests/extension/vibrator/aidl/Android.bp
+++ b/tests/extension/vibrator/aidl/Android.bp
@@ -38,5 +38,11 @@
             enabled: false,
         },
     },
-    versions: ["1"],
+    frozen: true,
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.vibrator-V2"],
+        },
+    ],
 }
diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp
index 0f3895f..5e156af 100644
--- a/tests/extension/vibrator/aidl/default/Android.bp
+++ b/tests/extension/vibrator/aidl/default/Android.bp
@@ -29,6 +29,6 @@
         "libbase",
         "libbinder_ndk",
         "android.hardware.vibrator-V2-ndk",
-        "android.hardware.tests.extension.vibrator-V2-ndk",
+        "android.hardware.tests.extension.vibrator-V1-ndk",
     ],
 }
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
index 2f3dfcb..7a7c58b 100644
--- a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
@@ -57,4 +57,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::SpAIBinder CustomVibrator::createBinder() {
+    auto binder = BnCustomVibrator::createBinder();
+    // e.g. AIBinder_setInheritRt(binder.get(), true);
+    // e.g. AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, 20);
+    // e.g. AIBinder_setRequestingSid(binder.get(), true);
+    return binder;
+}
+
 }  // namespace aidl::android::hardware::tests::extension::vibrator
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.h b/tests/extension/vibrator/aidl/default/CustomVibrator.h
index 6dc5743..084a557 100644
--- a/tests/extension/vibrator/aidl/default/CustomVibrator.h
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.h
@@ -29,6 +29,12 @@
     ndk::ScopedAStatus perform(VendorEffect effect,
                                const std::shared_ptr<IVibratorCallback>& callback,
                                int32_t* _aidl_return) override;
+
+  private:
+    // override for AIBinder_setInheritRt, AIBinder_setMinSchedulerPolicy, or
+    // AIBinder_setRequestingSid calling this in the constructor or elsewhere, the binder would
+    // immediately be destroyed.
+    ndk::SpAIBinder createBinder() override;
 };
 
 }  // namespace aidl::android::hardware::tests::extension::vibrator
diff --git a/tetheroffload/aidl/Android.bp b/tetheroffload/aidl/Android.bp
new file mode 100644
index 0000000..6de27c3
--- /dev/null
+++ b/tetheroffload/aidl/Android.bp
@@ -0,0 +1,34 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+    name: "android.hardware.tetheroffload",
+    vendor_available: true,
+    srcs: ["android/hardware/tetheroffload/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+            apex_available: [
+                "com.android.tethering",
+            ],
+            min_sdk_version: "30",
+            enabled: true,
+        },
+        ndk: {
+            apps_enabled: false,
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/tetheroffload/aidl/TEST_MAPPING b/tetheroffload/aidl/TEST_MAPPING
new file mode 100644
index 0000000..c6d4c07
--- /dev/null
+++ b/tetheroffload/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit" : [
+    {
+      "name": "VtsHalTetheroffloadTargetTest"
+    }
+  ]
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/.hash b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/.hash
new file mode 100644
index 0000000..e7b452e
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/.hash
@@ -0,0 +1 @@
+ba3f0342e13af942628a6c00e920d55ce8ad1ea3
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ForwardedStats.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ForwardedStats.aidl
new file mode 100644
index 0000000..493a698
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ForwardedStats.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+parcelable ForwardedStats {
+  long rxBytes;
+  long txBytes;
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IOffload.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IOffload.aidl
new file mode 100644
index 0000000..9a58b1f
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IOffload.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+interface IOffload {
+  void initOffload(in ParcelFileDescriptor fd1, in ParcelFileDescriptor fd2, in android.hardware.tetheroffload.ITetheringOffloadCallback cb);
+  void stopOffload();
+  void setLocalPrefixes(in String[] prefixes);
+  android.hardware.tetheroffload.ForwardedStats getForwardedStats(in String upstream);
+  void setDataWarningAndLimit(in String upstream, in long warningBytes, in long limitBytes);
+  void setUpstreamParameters(in String iface, in String v4Addr, in String v4Gw, in String[] v6Gws);
+  void addDownstream(in String iface, in String prefix);
+  void removeDownstream(in String iface, in String prefix);
+  const int ERROR_CODE_UNUSED = 0;
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IPv4AddrPortPair.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IPv4AddrPortPair.aidl
new file mode 100644
index 0000000..2b42f0c
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/IPv4AddrPortPair.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+parcelable IPv4AddrPortPair {
+  String addr;
+  int port;
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl
new file mode 100644
index 0000000..4eb7d04
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+interface ITetheringOffloadCallback {
+  oneway void onEvent(in android.hardware.tetheroffload.OffloadCallbackEvent event);
+  oneway void updateTimeout(in android.hardware.tetheroffload.NatTimeoutUpdate params);
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NatTimeoutUpdate.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NatTimeoutUpdate.aidl
new file mode 100644
index 0000000..9eddaa2
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NatTimeoutUpdate.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+parcelable NatTimeoutUpdate {
+  android.hardware.tetheroffload.IPv4AddrPortPair src;
+  android.hardware.tetheroffload.IPv4AddrPortPair dst;
+  android.hardware.tetheroffload.NetworkProtocol proto;
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NetworkProtocol.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NetworkProtocol.aidl
new file mode 100644
index 0000000..52bd2a6
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/NetworkProtocol.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@Backing(type="int") @VintfStability
+enum NetworkProtocol {
+  TCP = 6,
+  UDP = 17,
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/OffloadCallbackEvent.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/OffloadCallbackEvent.aidl
new file mode 100644
index 0000000..026e18e
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/1/android/hardware/tetheroffload/OffloadCallbackEvent.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@Backing(type="int") @VintfStability
+enum OffloadCallbackEvent {
+  OFFLOAD_STARTED = 1,
+  OFFLOAD_STOPPED_ERROR = 2,
+  OFFLOAD_STOPPED_UNSUPPORTED = 3,
+  OFFLOAD_SUPPORT_AVAILABLE = 4,
+  OFFLOAD_STOPPED_LIMIT_REACHED = 5,
+  OFFLOAD_WARNING_REACHED = 6,
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/ForwardedStats.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/ForwardedStats.aidl
new file mode 100644
index 0000000..493a698
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/ForwardedStats.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+parcelable ForwardedStats {
+  long rxBytes;
+  long txBytes;
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/IOffload.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/IOffload.aidl
new file mode 100644
index 0000000..9a58b1f
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/IOffload.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+interface IOffload {
+  void initOffload(in ParcelFileDescriptor fd1, in ParcelFileDescriptor fd2, in android.hardware.tetheroffload.ITetheringOffloadCallback cb);
+  void stopOffload();
+  void setLocalPrefixes(in String[] prefixes);
+  android.hardware.tetheroffload.ForwardedStats getForwardedStats(in String upstream);
+  void setDataWarningAndLimit(in String upstream, in long warningBytes, in long limitBytes);
+  void setUpstreamParameters(in String iface, in String v4Addr, in String v4Gw, in String[] v6Gws);
+  void addDownstream(in String iface, in String prefix);
+  void removeDownstream(in String iface, in String prefix);
+  const int ERROR_CODE_UNUSED = 0;
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/IPv4AddrPortPair.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/IPv4AddrPortPair.aidl
new file mode 100644
index 0000000..2b42f0c
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/IPv4AddrPortPair.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+parcelable IPv4AddrPortPair {
+  String addr;
+  int port;
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl
new file mode 100644
index 0000000..4eb7d04
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+interface ITetheringOffloadCallback {
+  oneway void onEvent(in android.hardware.tetheroffload.OffloadCallbackEvent event);
+  oneway void updateTimeout(in android.hardware.tetheroffload.NatTimeoutUpdate params);
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/NatTimeoutUpdate.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/NatTimeoutUpdate.aidl
new file mode 100644
index 0000000..9eddaa2
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/NatTimeoutUpdate.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@VintfStability
+parcelable NatTimeoutUpdate {
+  android.hardware.tetheroffload.IPv4AddrPortPair src;
+  android.hardware.tetheroffload.IPv4AddrPortPair dst;
+  android.hardware.tetheroffload.NetworkProtocol proto;
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/NetworkProtocol.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/NetworkProtocol.aidl
new file mode 100644
index 0000000..52bd2a6
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/NetworkProtocol.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@Backing(type="int") @VintfStability
+enum NetworkProtocol {
+  TCP = 6,
+  UDP = 17,
+}
diff --git a/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/OffloadCallbackEvent.aidl b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/OffloadCallbackEvent.aidl
new file mode 100644
index 0000000..026e18e
--- /dev/null
+++ b/tetheroffload/aidl/aidl_api/android.hardware.tetheroffload/current/android/hardware/tetheroffload/OffloadCallbackEvent.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tetheroffload;
+@Backing(type="int") @VintfStability
+enum OffloadCallbackEvent {
+  OFFLOAD_STARTED = 1,
+  OFFLOAD_STOPPED_ERROR = 2,
+  OFFLOAD_STOPPED_UNSUPPORTED = 3,
+  OFFLOAD_SUPPORT_AVAILABLE = 4,
+  OFFLOAD_STOPPED_LIMIT_REACHED = 5,
+  OFFLOAD_WARNING_REACHED = 6,
+}
diff --git a/tetheroffload/aidl/android/hardware/tetheroffload/ForwardedStats.aidl b/tetheroffload/aidl/android/hardware/tetheroffload/ForwardedStats.aidl
new file mode 100644
index 0000000..d2fe49b
--- /dev/null
+++ b/tetheroffload/aidl/android/hardware/tetheroffload/ForwardedStats.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tetheroffload;
+
+@VintfStability
+parcelable ForwardedStats {
+    /**
+     * Tx/Rx forwarded bytes
+     */
+    long rxBytes;
+    long txBytes;
+}
diff --git a/tetheroffload/aidl/android/hardware/tetheroffload/IOffload.aidl b/tetheroffload/aidl/android/hardware/tetheroffload/IOffload.aidl
new file mode 100644
index 0000000..984f2a5
--- /dev/null
+++ b/tetheroffload/aidl/android/hardware/tetheroffload/IOffload.aidl
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tetheroffload;
+
+import android.hardware.tetheroffload.ForwardedStats;
+import android.hardware.tetheroffload.ITetheringOffloadCallback;
+
+/**
+ * Interface used to control tethering offload.
+ */
+@VintfStability
+interface IOffload {
+    /**
+     * Error code for all {@code ServiceSpecificException}s thrown by this interface.
+     */
+    const int ERROR_CODE_UNUSED = 0;
+
+    /**
+     * Indicates intent to start offload for tethering in immediate future.
+     *
+     * This API must be called exactly once when Tethering is requested by the user.
+     *
+     * If this API is called multiple times without first calling stopOffload, then the subsequent
+     * calls must fail without changing the state of the server.
+     *
+     * If for some reason, the hardware is currently unable to support offload, this call must fail.
+     *
+     * @param fd1 A file descriptor bound to the following netlink groups
+     *            (NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY).
+     * @param fd2 A file descriptor bound to the following netlink groups
+     *            (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
+     * @param cb Assuming success, this callback must provide unsolicited updates of offload status.
+     *           It is assumed to be valid until stopOffload is called.
+     *
+     * @throws:
+     *         - EX_ILLEGAL_ARGUMENT if any file descriptors are invalid.
+     *         - EX_ILLEGAL_STATE if this method previously succeeded and stopOffload() was not
+     *           later called.
+     *         - EX_SERVICE_SPECIFIC with the error message set to a human-readable reason for the
+     *           error.
+     *
+     * Remarks: Initializing offload does not imply that any upstreams or downstreams have yet been,
+     * or even will be, chosen.  This API is symmetrical with stopOffload.
+     */
+    void initOffload(in ParcelFileDescriptor fd1, in ParcelFileDescriptor fd2,
+            in ITetheringOffloadCallback cb);
+
+    /**
+     * Indicate desire to tear down all tethering offload.
+     *
+     * Called after tethering is no longer requested by the user. Any remaining offload must
+     * be subsequently torn down by the management process.  Upon success, the callback registered
+     * in initOffload must be released, and offload must be stopped.
+     *
+     * @throws:
+     *         - EX_ILLEGAL_STATE if initOffload() was not called, or if stopOffload() was already
+     *           called.
+     *         - EX_SERVICE_SPECIFIC with the error message set to a human-readable reason for the
+     *           error.
+     *
+     * Remarks: Statistics must be reset by this API.
+     */
+    void stopOffload();
+
+    /**
+     * Instruct management process not to forward traffic destined to or from the specified
+     * prefixes.
+     *
+     * This API may only be called after initOffload and before stopOffload.
+     *
+     * @param prefixes List containing fully specified prefixes. For e.g. 192.168.1.0/24
+     * or 2001:4860:684::/64
+     *
+     * @throws:
+     *         - EX_ILLEGAL_ARGUMENT if the IP prefixes are invalid.
+     *         - EX_ILLEGAL_STATE if this method is called before initOffload(), or if this method
+     *           is called after stopOffload().
+     *         - EX_SERVICE_SPECIFIC with the error message set to a human-readable reason for the
+     *           error.
+     *
+     * Remarks: This list overrides any previously specified list
+     */
+    void setLocalPrefixes(in String[] prefixes);
+
+    /**
+     * Query offloaded traffic statistics forwarded to an upstream address.
+     *
+     * Return statistics that have transpired since the last query.  This would include
+     * statistics from all offloaded downstream tether interfaces that have been forwarded to this
+     * upstream interface.  After returning the statistics, the counters are reset to zero.
+     *
+     * Only offloaded statistics must be returned by this API, software stats must not be
+     * returned.
+     *
+     * @param upstream Upstream interface on which traffic exited/entered
+     *
+     * @return ForwardedStats depicting the received and transmitted bytes
+     *
+     * @throws:
+     *         - EX_SERVICE_SPECIFIC with the error message set to a human-readable reason for the
+     *           error.
+     */
+    ForwardedStats getForwardedStats(in String upstream);
+
+    /**
+     * Instruct hardware to send callbacks, and possibly stop offload, after certain number of bytes
+     * have been transferred in either direction on this upstream interface.
+     *
+     * The specified quota bytes must be applied to all traffic on the given upstream interface.
+     * This includes hardware forwarded traffic, software forwarded traffic, and AP-originated
+     * traffic. IPv4 and IPv6 traffic both count towards the same quota. IP headers are included
+     * in the byte count quota, but, link-layer headers are not.
+     *
+     * This API may only be called while offload is occurring on this upstream. The hardware
+     * management process MUST NOT store the values when offload is not started and apply them
+     * once offload is started. This is because the quota values would likely become stale over
+     * time and would not reflect any new traffic that has occurred.
+     *
+     * The specified quota bytes MUST replace any previous quotas set by
+     * {@code setDataWarningAndLimit} specified on the same interface. It may be interpreted as
+     * "tell me when either <warningBytes> or <limitBytes> bytes have been transferred
+     * (in either direction), and stop offload when <limitBytes> bytes have been transferred,
+     * starting now and counting from zero on <upstream>."
+     *
+     * Once the {@code warningBytes} is reached, the callback registered in initOffload must be
+     * called with {@code OFFLOAD_WARNING_REACHED} to indicate this event. Once the event fires
+     * for this upstream, no further {@code OFFLOAD_WARNING_REACHED} event will be fired for this
+     * upstream unless this method is called again with the same interface. Note that there is
+     * no need to call initOffload again to resume offload if stopOffload was not called by the
+     * client.
+     *
+     * Similarly, Once the {@code limitBytes} is reached, the callback registered in initOffload
+     * must be called with {@code OFFLOAD_STOPPED_LIMIT_REACHED} to indicate this event. Once
+     * the event fires for this upstream, no further {@code OFFLOAD_STOPPED_LIMIT_REACHED}
+     * event will be fired for this upstream unless this method is called again with the same
+     * interface. However, unlike {@code warningBytes}, when {@code limitBytes} is reached,
+     * all offload must be stopped. If offload is desired again, the hardware management
+     * process must be completely reprogrammed by calling setUpstreamParameters and
+     * addDownstream again.
+     *
+     * Note that {@code warningBytes} must always be less than or equal to {@code limitBytes},
+     * when {@code warningBytes} is reached, {@code limitBytes} may still valid unless this method
+     * is called again with the same interface.
+     *
+     * @param upstream Upstream interface name that quota must apply to.
+     * @param warningBytes The quota of warning, defined as the number of bytes, starting from
+     *                     zero and counting from now.
+     * @param limitBytes The quota of limit, defined as the number of bytes, starting from zero
+     *                   and counting from now.
+     *
+     * @throws:
+     *         - EX_ILLEGAL_ARGUMENT if any parameters are invalid (such as invalid upstream
+     *           or negative number of bytes).
+     *         - EX_ILLEGAL_STATE if this method is called before initOffload(), or if this method
+     *           is called after stopOffload().
+     *         - EX_SERVICE_SPECIFIC with the error message set to a human-readable reason for the
+     *           error.
+     */
+    void setDataWarningAndLimit(in String upstream, in long warningBytes, in long limitBytes);
+
+    /**
+     * Instruct hardware to start forwarding traffic to the specified upstream.
+     *
+     * When iface, v4Addr, and v4Gw are all non-null, the management process may begin forwarding
+     * any currently configured or future configured IPv4 downstreams to this upstream interface.
+     *
+     * If any of the previously three mentioned parameters are null, then any current IPv4 offload
+     * must be stopped.
+     *
+     * When iface and v6Gws are both non-null, and in the case of v6Gws, are not empty, the
+     * management process may begin forwarding any currently configured or future configured IPv6
+     * downstreams to this upstream interface.
+     *
+     * If either of the two above parameters are null, or no V6 Gateways are provided, then IPv6
+     * offload must be stopped.
+     *
+     * This API may only be called after initOffload and before stopOffload.
+     *
+     * @param iface  Upstream interface name.  Note that only one is needed because IPv4 and IPv6
+     *               interfaces cannot be different (only known that this can occur during software
+     *               xlat, which cannot be offloaded through hardware anyways).  If the iface is
+     *               null, offload must be stopped.
+     * @param v4Addr The local IPv4 address assigned to the provided upstream interface, i.e. the
+     *               IPv4 address the packets are NATed to. For e.g. 192.168.0.12.
+     * @param v4Gw   The IPv4 address of the IPv4 gateway on the upstream interface.
+     *               For e.g. 192.168.1.1
+     * @param v6Gws  A list of IPv6 addresses (for e.g. fe80::97be:9de7:b24b:9194) for possible IPv6
+     *               gateways on the upstream interface.
+     *
+     * @throws:
+     *         - EX_ILLEGAL_ARGUMENT if any parameters are invalid (such as invalid upstream
+     *           or IP addresses).
+     *         - EX_ILLEGAL_STATE if this method is called before initOffload(), or if this method
+     *           is called after stopOffload().
+     *         - EX_SERVICE_SPECIFIC with the error message set to a human-readable reason for the
+     *           error.
+     *
+     * Remarks: This overrides any previously configured parameters.
+     */
+    void setUpstreamParameters(
+            in String iface, in String v4Addr, in String v4Gw, in String[] v6Gws);
+
+    /**
+     * Configure a downstream interface and prefix in the hardware management process that may be
+     * forwarded.
+     *
+     * The prefix may be an IPv4 or an IPv6 prefix to signify which family can be offloaded from
+     * the specified tether interface.  The list of IPv4 and IPv6 downstreams that are configured
+     * may differ.
+     *
+     * If the given protocol, as determined by the prefix, has an upstream set,
+     * the hardware may begin forwarding traffic between the upstream and any devices on the
+     * downstream interface that have IP addresses within the specified prefix. Other traffic from
+     * the same downstream interfaces is unaffected and must be forwarded if and only if it was
+     * already being forwarded.
+     *
+     * If no upstream is currently configured, then these downstream interface and prefixes must be
+     * preserved so that offload may begin in the future when an upstream is set.
+     *
+     * This API does not replace any previously configured downstreams and any such downstreams must
+     * be explicitly removed by calling removeDownstream.
+     *
+     * This API may only be called after initOffload and before stopOffload.
+     *
+     * @param iface  Downstream interface
+     * @param prefix Downstream prefix depicting addresses that may be offloaded.
+     *               For e.g. 192.168.1.0/24 or 2001:4860:684::/64)
+     *
+     * @throws:
+     *         - EX_ILLEGAL_ARGUMENT if any parameters are invalid (such as invalid downstream
+     *           or IP prefix).
+     *         - EX_ILLEGAL_STATE if this method is called before initOffload(), or if this method
+     *           is called after stopOffload().
+     *         - EX_SERVICE_SPECIFIC with the error message set to a human-readable reason for the
+     *           error.
+     *
+     * Remarks: The hardware management process may fail this call in a normal situation.  This can
+     *          happen because the hardware cannot support the current number of prefixes, the
+     *          hardware cannot support concurrent offload on multiple interfaces, the hardware
+     *          cannot currently support offload on the tether interface for some reason, or any
+     *          other dynamic configuration issues which may occur.  In this case,
+     *          traffic must remain unaffected and must be forwarded if and only if it was already
+     *          being forwarded.
+     */
+    void addDownstream(in String iface, in String prefix);
+
+    /**
+     * Remove a downstream prefix that may be forwarded from the hardware management process.
+     *
+     * The prefix may be an IPv4 or an IPv6 prefix. If it was not previously configured using
+     * addDownstream, then this must be a no-op.
+     *
+     * This API may only be called after initOffload and before stopOffload.
+     *
+     * @param iface  Downstream interface
+     * @param prefix Downstream prefix depicting prefix that must no longer be offloaded
+     *               For e.g. 192.168.1.0/24 or 2001:4860:684::/64)
+     *
+     * @throws:
+     *         - EX_ILLEGAL_ARGUMENT if any parameters are invalid (such as invalid downstream
+     *           or IP prefix).
+     *         - EX_ILLEGAL_STATE if this method is called before initOffload(), or if this method
+     *           is called after stopOffload().
+     *         - EX_SERVICE_SPECIFIC with the error message set to a human-readable reason for the
+     *           error.
+     */
+    void removeDownstream(in String iface, in String prefix);
+}
diff --git a/tetheroffload/aidl/android/hardware/tetheroffload/IPv4AddrPortPair.aidl b/tetheroffload/aidl/android/hardware/tetheroffload/IPv4AddrPortPair.aidl
new file mode 100644
index 0000000..16d7d85
--- /dev/null
+++ b/tetheroffload/aidl/android/hardware/tetheroffload/IPv4AddrPortPair.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tetheroffload;
+
+@VintfStability
+parcelable IPv4AddrPortPair {
+    /**
+     * IPv4 Address and Port
+     */
+    String addr;
+    int port;
+}
diff --git a/tetheroffload/aidl/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl b/tetheroffload/aidl/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl
new file mode 100644
index 0000000..5ee819b
--- /dev/null
+++ b/tetheroffload/aidl/android/hardware/tetheroffload/ITetheringOffloadCallback.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tetheroffload;
+
+import android.hardware.tetheroffload.NatTimeoutUpdate;
+import android.hardware.tetheroffload.OffloadCallbackEvent;
+
+/**
+ * Callback providing information about status of hardware management process
+ * as well as providing a way to keep offloaded connections from timing out.
+ */
+@VintfStability
+oneway interface ITetheringOffloadCallback {
+    /**
+     * Called when an asynchronous event is generated by the hardware
+     * management process.
+     */
+    void onEvent(in OffloadCallbackEvent event);
+
+    /**
+     *  Provide a way for the management process to request that a connections
+     *  timeout be updated in kernel.
+     *
+     *  This is necessary to ensure that offloaded traffic is not cleaned up
+     *  by the kernel connection tracking module for IPv4.
+     */
+    void updateTimeout(in NatTimeoutUpdate params);
+}
diff --git a/tetheroffload/aidl/android/hardware/tetheroffload/NatTimeoutUpdate.aidl b/tetheroffload/aidl/android/hardware/tetheroffload/NatTimeoutUpdate.aidl
new file mode 100644
index 0000000..50805ef
--- /dev/null
+++ b/tetheroffload/aidl/android/hardware/tetheroffload/NatTimeoutUpdate.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tetheroffload;
+
+import android.hardware.tetheroffload.IPv4AddrPortPair;
+import android.hardware.tetheroffload.NetworkProtocol;
+
+@VintfStability
+parcelable NatTimeoutUpdate {
+    IPv4AddrPortPair src;
+    IPv4AddrPortPair dst;
+    NetworkProtocol proto;
+}
diff --git a/tetheroffload/aidl/android/hardware/tetheroffload/NetworkProtocol.aidl b/tetheroffload/aidl/android/hardware/tetheroffload/NetworkProtocol.aidl
new file mode 100644
index 0000000..cc4f7ac
--- /dev/null
+++ b/tetheroffload/aidl/android/hardware/tetheroffload/NetworkProtocol.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tetheroffload;
+
+@VintfStability
+@Backing(type="int")
+enum NetworkProtocol {
+    TCP = 6,
+    UDP = 17,
+}
diff --git a/tetheroffload/aidl/android/hardware/tetheroffload/OffloadCallbackEvent.aidl b/tetheroffload/aidl/android/hardware/tetheroffload/OffloadCallbackEvent.aidl
new file mode 100644
index 0000000..15a1f93
--- /dev/null
+++ b/tetheroffload/aidl/android/hardware/tetheroffload/OffloadCallbackEvent.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tetheroffload;
+
+@VintfStability
+@Backing(type="int")
+enum OffloadCallbackEvent {
+    /**
+     * Indicate that a working configuration has been programmed and the
+     * hardware management process has begun forwarding traffic.
+     */
+    OFFLOAD_STARTED = 1,
+    /**
+     * Indicate that an error has occurred which has disrupted hardware
+     * acceleration.  Software routing may still be attempted; however,
+     * statistics may be temporarily unavailable.  Statistics may be recovered
+     * after OFFLOAD_SUPPORT_AVAILABLE event is fired.
+     */
+    OFFLOAD_STOPPED_ERROR = 2,
+    /**
+     * Indicate that the device has moved to a RAT on which hardware
+     * acceleration is not supported.  Subsequent calls to setUpstreamParameters
+     * and add/removeDownstream will likely fail and cannot be presumed to be
+     * saved inside of the hardware management process.  Upon receiving
+     * OFFLOAD_SUPPORT_AVAILABLE, the client may reprogram the hardware
+     * management process to begin offload again.
+     */
+    OFFLOAD_STOPPED_UNSUPPORTED = 3,
+    /**
+     * Indicate that the hardware management process is willing and able to
+     * provide support for hardware acceleration at this time.  If applicable,
+     * the client may query for statistics.  If offload is desired, the client
+     * must reprogram the hardware management process.
+     */
+    OFFLOAD_SUPPORT_AVAILABLE = 4,
+    /**
+     * Hardware acceleration is no longer in effect and must be reprogrammed
+     * in order to resume.  This event is fired when the limit, applied in
+     * setDataLimit, has expired.  It is recommended that the client query for
+     * statistics immediately after receiving this event.
+     */
+    OFFLOAD_STOPPED_LIMIT_REACHED = 5,
+    /**
+     * This event is fired when the quota, applied in setDataWarningAndLimit, has expired. It is
+     * recommended that the client query for statistics immediately after receiving this event.
+     * Any offloaded traffic will continue to be offloaded until offload is stopped or
+     * OFFLOAD_STOPPED_LIMIT_REACHED is sent.
+     */
+    OFFLOAD_WARNING_REACHED = 6,
+}
diff --git a/tetheroffload/aidl/default/Android.bp b/tetheroffload/aidl/default/Android.bp
new file mode 100644
index 0000000..8f0739c
--- /dev/null
+++ b/tetheroffload/aidl/default/Android.bp
@@ -0,0 +1,36 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+    name: "android.hardware.tetheroffload-service.example",
+    relative_install_path: "hw",
+    init_rc: ["tetheroffload-example.rc"],
+    vintf_fragments: ["tetheroffload-example.xml"],
+    vendor: true,
+    shared_libs: [
+        "android.hardware.tetheroffload-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libutils",
+    ],
+    srcs: [
+        "main.cpp",
+        "Offload.cpp",
+    ],
+}
diff --git a/tetheroffload/aidl/default/Offload.cpp b/tetheroffload/aidl/default/Offload.cpp
new file mode 100644
index 0000000..8aa6916
--- /dev/null
+++ b/tetheroffload/aidl/default/Offload.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <numeric>
+#include <string>
+
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <netdb.h>
+
+#include "Offload.h"
+
+namespace aidl::android::hardware::tetheroffload::impl::example {
+
+using ::android::base::Join;
+
+ndk::ScopedAStatus Offload::addDownstream(const std::string& in_iface,
+                                          const std::string& in_prefix) {
+    LOG(VERBOSE) << __func__ << " Interface: " << in_iface << ", Prefix: " << in_prefix;
+    if (!isInitialized()) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                EX_ILLEGAL_STATE, "Tetheroffload HAL not initialized");
+    }
+    if (!isValidInterface(in_iface)) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid interface name");
+    }
+    if (!isValidIpPrefix(in_prefix)) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid IP prefix");
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Offload::getForwardedStats(const std::string& in_upstream,
+                                              ForwardedStats* _aidl_return) {
+    LOG(VERBOSE) << __func__ << " Upstream: " << in_upstream;
+    ForwardedStats stats;
+    stats.rxBytes = 0;
+    stats.txBytes = 0;
+    *_aidl_return = std::move(stats);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Offload::initOffload(const ndk::ScopedFileDescriptor& in_fd1,
+                                        const ndk::ScopedFileDescriptor& in_fd2,
+                                        const std::shared_ptr<ITetheringOffloadCallback>& in_cb) {
+    LOG(VERBOSE) << __func__ << " FileDescriptor1: " << std::to_string(in_fd1.get())
+                 << ", FileDescriptor2: " << std::to_string(in_fd2.get())
+                 << ", ITetheringOffloadCallback: " << in_cb;
+    if (isInitialized()) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                EX_ILLEGAL_STATE, "Tetheroffload HAL already initialized");
+    }
+    int fd1 = in_fd1.get();
+    int fd2 = in_fd2.get();
+    if (fd1 < 0 || fd2 < 0) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid file descriptors");
+    }
+    mFd1 = ndk::ScopedFileDescriptor(dup(fd1));
+    mFd2 = ndk::ScopedFileDescriptor(dup(fd2));
+    mInitialized = true;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Offload::removeDownstream(const std::string& in_iface,
+                                             const std::string& in_prefix) {
+    LOG(VERBOSE) << __func__ << " Interface: " << in_iface << ", Prefix: " << in_prefix;
+    if (!isInitialized()) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                EX_ILLEGAL_STATE, "Tetheroffload HAL not initialized");
+    }
+    if (!isValidIpPrefix(in_prefix)) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid IP prefix");
+    }
+    if (!isValidInterface(in_iface)) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid interface name");
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Offload::setDataWarningAndLimit(const std::string& in_upstream,
+                                                   int64_t in_warningBytes, int64_t in_limitBytes) {
+    LOG(VERBOSE) << __func__ << " Upstream: " << in_upstream
+                 << ", WarningBytes: " << in_warningBytes << ", LimitBytes: " << in_limitBytes;
+    if (!isInitialized()) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                EX_ILLEGAL_STATE, "Tetheroffload HAL not initialized");
+    }
+    if (!isValidInterface(in_upstream)) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid interface name");
+    }
+    if (in_warningBytes < 0 || in_limitBytes < 0) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Threshold must be non-negative");
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Offload::setLocalPrefixes(const std::vector<std::string>& in_prefixes) {
+    LOG(VERBOSE) << __func__ << " Prefixes: " << Join(in_prefixes, ',');
+    if (!isInitialized()) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                EX_ILLEGAL_STATE, "Tetheroffload HAL not initialized");
+    }
+    if (in_prefixes.empty()) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "No IP prefix");
+    }
+    for (std::string prefix : in_prefixes) {
+        if (!isValidIpPrefix(prefix)) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Invalid IP prefix");
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Offload::setUpstreamParameters(const std::string& in_iface,
+                                                  const std::string& in_v4Addr,
+                                                  const std::string& in_v4Gw,
+                                                  const std::vector<std::string>& in_v6Gws) {
+    LOG(VERBOSE) << __func__ << " Interface: " << in_iface << ", IPv4Address: " << in_v4Addr
+                 << ", IPv4Gateway: " << in_v4Gw << ", IPv6Gateways: " << Join(in_v6Gws, ',');
+    if (!isInitialized()) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                EX_ILLEGAL_STATE, "Tetheroffload HAL not initialized");
+    }
+    if (!isValidInterface(in_iface)) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid interface name");
+    }
+    if (in_v4Addr.empty() && in_v4Gw.empty() && in_v6Gws.empty()) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "No upstream IP address");
+    }
+    if (!in_v4Addr.empty() && !in_v4Gw.empty()) {
+        if (!isValidIpv4Address(in_v4Addr) || !isValidIpv4Address(in_v4Gw)) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Invalid IP address");
+        }
+    }
+    for (std::string ip : in_v6Gws) {
+        if (!isValidIpv6Address(ip)) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Invalid IP address");
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Offload::stopOffload() {
+    LOG(VERBOSE) << __func__;
+    if (!isInitialized()) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                EX_ILLEGAL_STATE, "Tetheroffload HAL not initialized");
+    }
+    mInitialized = false;
+    return ndk::ScopedAStatus::ok();
+};
+
+bool Offload::isInitialized() {
+    return (mInitialized == true);
+}
+
+bool Offload::isValidInterface(const std::string& iface) {
+    return !iface.empty() && iface != "invalid";
+}
+
+bool Offload::isValidIpv4Address(const std::string& repr) {
+    return validateIpAddressOrPrefix(repr, AF_INET, false);
+}
+
+bool Offload::isValidIpv4Prefix(const std::string& repr) {
+    return validateIpAddressOrPrefix(repr, AF_INET, true);
+}
+
+bool Offload::isValidIpv6Address(const std::string& repr) {
+    return validateIpAddressOrPrefix(repr, AF_INET6, false);
+}
+
+bool Offload::isValidIpv6Prefix(const std::string& repr) {
+    return validateIpAddressOrPrefix(repr, AF_INET6, true);
+}
+
+bool Offload::isValidIpAddress(const std::string& repr) {
+    return isValidIpv4Address(repr) || isValidIpv6Address(repr);
+}
+
+bool Offload::isValidIpPrefix(const std::string& repr) {
+    return isValidIpv4Prefix(repr) || isValidIpv6Prefix(repr);
+}
+
+// Refer to libnetdutils's IPAddress and IPPrefix classes.
+// Can't use them directly because libnetdutils is not "vendor_available".
+bool Offload::validateIpAddressOrPrefix(const std::string& repr, const int expectedFamily,
+                                        const bool isPrefix) {
+    const addrinfo hints = {
+            .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV,
+    };
+    addrinfo* res;
+    size_t index = repr.find('/');
+    if (isPrefix && index == std::string::npos) return false;
+
+    // Parse the IP address.
+    const std::string ipAddress = isPrefix ? repr.substr(0, index) : repr;
+    const int ret = getaddrinfo(ipAddress.c_str(), nullptr, &hints, &res);
+    if (ret != 0) return false;
+
+    // Check the address family.
+    int family = res[0].ai_family;
+    freeaddrinfo(res);
+    if (family != expectedFamily) return false;
+    if (!isPrefix) return true;
+
+    // Parse the prefix length.
+    const char* prefixString = repr.c_str() + index + 1;
+    if (!isdigit(*prefixString)) return false;
+    char* endptr;
+    unsigned long prefixlen = strtoul(prefixString, &endptr, 10);
+    if (*endptr != '\0') return false;
+
+    uint8_t maxlen = (family == AF_INET) ? 32 : 128;
+    if (prefixlen > maxlen) return false;
+
+    return true;
+}
+
+}  // namespace aidl::android::hardware::tetheroffload::impl::example
diff --git a/tetheroffload/aidl/default/Offload.h b/tetheroffload/aidl/default/Offload.h
new file mode 100644
index 0000000..a1f6bce
--- /dev/null
+++ b/tetheroffload/aidl/default/Offload.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/tetheroffload/BnOffload.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tetheroffload {
+namespace impl {
+namespace example {
+
+using aidl::android::hardware::tetheroffload::ForwardedStats;
+using aidl::android::hardware::tetheroffload::ITetheringOffloadCallback;
+
+class Offload : public BnOffload {
+  public:
+    ndk::ScopedAStatus addDownstream(const std::string& in_iface,
+                                     const std::string& in_prefix) override;
+    ndk::ScopedAStatus getForwardedStats(const std::string& in_upstream,
+                                         ForwardedStats* _aidl_return) override;
+    ndk::ScopedAStatus initOffload(
+            const ndk::ScopedFileDescriptor& in_fd1, const ndk::ScopedFileDescriptor& in_fd2,
+            const std::shared_ptr<ITetheringOffloadCallback>& in_cb) override;
+    ndk::ScopedAStatus removeDownstream(const std::string& in_iface,
+                                        const std::string& in_prefix) override;
+    ndk::ScopedAStatus setDataWarningAndLimit(const std::string& in_upstream,
+                                              int64_t in_warningBytes,
+                                              int64_t in_limitBytes) override;
+    ndk::ScopedAStatus setLocalPrefixes(const std::vector<std::string>& in_prefixes) override;
+    ndk::ScopedAStatus setUpstreamParameters(const std::string& in_iface,
+                                             const std::string& in_v4Addr,
+                                             const std::string& in_v4Gw,
+                                             const std::vector<std::string>& in_v6Gws) override;
+    ndk::ScopedAStatus stopOffload() override;
+
+  private:
+    bool isInitialized();
+    bool isValidInterface(const std::string& iface);
+    bool isValidIpv4Address(const std::string& repr);
+    bool isValidIpv4Prefix(const std::string& repr);
+    bool isValidIpv6Address(const std::string& repr);
+    bool isValidIpv6Prefix(const std::string& repr);
+    bool isValidIpAddress(const std::string& repr);
+    bool isValidIpPrefix(const std::string& repr);
+    bool validateIpAddressOrPrefix(const std::string& repr, const int expectedFamily,
+                                   const bool isPrefix);
+
+    bool mInitialized = false;
+    ndk::ScopedFileDescriptor mFd1;
+    ndk::ScopedFileDescriptor mFd2;
+};
+
+}  // namespace example
+}  // namespace impl
+}  // namespace tetheroffload
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tetheroffload/aidl/default/main.cpp b/tetheroffload/aidl/default/main.cpp
new file mode 100644
index 0000000..6633630
--- /dev/null
+++ b/tetheroffload/aidl/default/main.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Offload.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::tetheroffload::impl::example::Offload;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<Offload> offload = ndk::SharedRefBase::make<Offload>();
+
+    binder_status_t status = AServiceManager_addService(
+            offload->asBinder().get(), Offload::makeServiceName("default").c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/tetheroffload/aidl/default/tetheroffload-example.rc b/tetheroffload/aidl/default/tetheroffload-example.rc
new file mode 100644
index 0000000..46cda61
--- /dev/null
+++ b/tetheroffload/aidl/default/tetheroffload-example.rc
@@ -0,0 +1,4 @@
+service vendor.tetheroffload-example /vendor/bin/hw/android.hardware.tetheroffload-service.example
+    class hal
+    user nobody
+    group nobody
diff --git a/tetheroffload/aidl/default/tetheroffload-example.xml b/tetheroffload/aidl/default/tetheroffload-example.xml
new file mode 100644
index 0000000..9fe83f6
--- /dev/null
+++ b/tetheroffload/aidl/default/tetheroffload-example.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.tetheroffload</name>
+        <version>1</version>
+        <fqname>IOffload/default</fqname>
+    </hal>
+</manifest>
diff --git a/tetheroffload/aidl/vts/functional/Android.bp b/tetheroffload/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..74edab0
--- /dev/null
+++ b/tetheroffload/aidl/vts/functional/Android.bp
@@ -0,0 +1,25 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "VtsHalTetheroffloadTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "VtsHalTetheroffloadTargetTest.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.tetheroffload-V1-ndk",
+        "libgmock_ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp b/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp
new file mode 100644
index 0000000..1049ea2
--- /dev/null
+++ b/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp
@@ -0,0 +1,700 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "tetheroffload_aidl_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/tetheroffload/BnOffload.h>
+#include <aidl/android/hardware/tetheroffload/BnTetheringOffloadCallback.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <log/log.h>
+#include <net/if.h>
+#include <sys/socket.h>
+
+namespace aidl::android::hardware::tetheroffload {
+
+namespace {
+
+using ::android::base::unique_fd;
+using android::hardware::tetheroffload::ForwardedStats;
+using android::hardware::tetheroffload::IOffload;
+using android::hardware::tetheroffload::NatTimeoutUpdate;
+using android::hardware::tetheroffload::OffloadCallbackEvent;
+using ::testing::AnyOf;
+using ::testing::Eq;
+
+const std::string TEST_IFACE = "rmnet_data0";
+const unsigned kFd1Groups = NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY;
+const unsigned kFd2Groups = NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY;
+
+enum class ExpectBoolean {
+    Ignored = -1,
+    False = 0,
+    True = 1,
+};
+
+inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
+    return reinterpret_cast<const sockaddr*>(nladdr);
+}
+
+int netlinkSocket(int protocol, unsigned groups) {
+    unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, protocol));
+    if (s.get() < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl bind_addr = {
+            .nl_family = AF_NETLINK,
+            .nl_pad = 0,
+            .nl_pid = 0,
+            .nl_groups = groups,
+    };
+    if (bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) != 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl kernel_addr = {
+            .nl_family = AF_NETLINK,
+            .nl_pad = 0,
+            .nl_pid = 0,
+            .nl_groups = groups,
+    };
+    if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+        return -errno;
+    }
+
+    return s.release();
+}
+
+int netlinkSocket(unsigned groups) {
+    return netlinkSocket(NETLINK_NETFILTER, groups);
+}
+
+// Check whether the specified interface is up.
+bool interfaceIsUp(const std::string name) {
+    struct ifreq ifr = {};
+    strlcpy(ifr.ifr_name, name.c_str(), sizeof(ifr.ifr_name));
+    int sock = socket(AF_INET6, SOCK_DGRAM, 0);
+    if (sock == -1) return false;
+    int ret = ioctl(sock, SIOCGIFFLAGS, &ifr, sizeof(ifr));
+    close(sock);
+    return (ret == 0) && (ifr.ifr_flags & IFF_UP);
+}
+
+// Callback class for both events and NAT timeout updates.
+class TetheringOffloadCallback : public BnTetheringOffloadCallback {
+  public:
+    ndk::ScopedAStatus onEvent(OffloadCallbackEvent in_event) override {
+        auto lock = std::lock_guard{mMutex};
+        mOnEventInvoked = true;
+        mLastEvent = in_event;
+        mNotifyCv.notify_all();
+        return ndk::ScopedAStatus::ok();
+    }
+
+    ndk::ScopedAStatus updateTimeout(const NatTimeoutUpdate& in_params) override {
+        auto lock = std::lock_guard{mMutex};
+        mOnUpdateTimeoutInvoked = true;
+        mNatTimeout = in_params;
+        mNotifyCv.notify_all();
+        return ndk::ScopedAStatus::ok();
+    }
+
+  private:
+    std::mutex mMutex;
+    std::condition_variable mNotifyCv;
+    OffloadCallbackEvent mLastEvent;
+    NatTimeoutUpdate mNatTimeout;
+    bool mOnEventInvoked = false;
+    bool mOnUpdateTimeoutInvoked = false;
+};
+
+// The common base class for tetheroffload AIDL HAL tests.
+class TetheroffloadAidlTestBase : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override { getService(); }
+    virtual void TearDown() override {
+        // For good measure, the teardown should try stopOffload() once more, since
+        // different HAL call test cycles might enter this function. Also the
+        // return code cannot be actually expected for all cases, hence ignore it.
+        stopOffload(ExpectBoolean::Ignored);
+    };
+
+  protected:
+    void getService() {
+        AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+        ASSERT_NE(binder, nullptr);
+        mOffload = IOffload::fromBinder(ndk::SpAIBinder(binder));
+    }
+
+    void initOffload(const bool expectedResult) {
+        unique_fd ufd1(netlinkSocket(kFd1Groups));
+        if (ufd1.get() < 0) {
+            FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
+        }
+        ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(ufd1.release());
+
+        unique_fd ufd2(netlinkSocket(kFd2Groups));
+        if (ufd2.get() < 0) {
+            FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
+        }
+        ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(ufd2.release());
+
+        mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
+        ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
+
+        ASSERT_EQ(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
+                  expectedResult ? EX_NONE : EX_ILLEGAL_STATE);
+    }
+
+    void stopOffload(const ExpectBoolean expectedResult) {
+        ndk::ScopedAStatus status = mOffload->stopOffload();
+        if (expectedResult == ExpectBoolean::Ignored) return;
+        ASSERT_EQ(status.getExceptionCode(),
+                  expectedResult == ExpectBoolean::True ? EX_NONE : EX_ILLEGAL_STATE);
+    }
+
+    std::shared_ptr<IOffload> mOffload;
+    std::shared_ptr<TetheringOffloadCallback> mTetheringOffloadCallback;
+};
+
+// The test class for tetheroffload before initialization.
+class TetheroffloadAidlPreInitTest : public TetheroffloadAidlTestBase {
+  public:
+    virtual void SetUp() override { getService(); }
+};
+
+// The main test class for tetheroffload AIDL HAL.
+class TetheroffloadAidlGeneralTest : public TetheroffloadAidlTestBase {
+  public:
+    virtual void SetUp() override {
+        getService();
+        initOffload(true);
+    }
+};
+
+// Passing invalid file descriptor to initOffload() should return an error.
+// Check that this occurs when both FDs are empty.
+TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFdsReturnsError) {
+    ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(-1);
+    ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(-1);
+    mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
+    ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
+    EXPECT_THAT(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
+                AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_TRANSACTION_FAILED)));
+}
+
+// Passing invalid file descriptor to initOffload() should return an error.
+// Check that this occurs when FD1 is empty.
+TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFd1ReturnsError) {
+    ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(-1);
+    unique_fd ufd2(netlinkSocket(kFd2Groups));
+    if (ufd2.get() < 0) {
+        FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
+    }
+    ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(ufd2.release());
+    mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
+    ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
+    EXPECT_THAT(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
+                AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_TRANSACTION_FAILED)));
+}
+
+// Passing invalid file descriptor to initOffload() should return an error.
+// Check that this occurs when FD2 is empty.
+TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFd2ReturnsError) {
+    unique_fd ufd1(netlinkSocket(kFd1Groups));
+    if (ufd1.get() < 0) {
+        FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
+    }
+    ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(ufd1.release());
+    ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(-1);
+    mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
+    ASSERT_NE(mTetheringOffloadCallback, nullptr) << "Could not get offload callback";
+    EXPECT_THAT(mOffload->initOffload(fd1, fd2, mTetheringOffloadCallback).getExceptionCode(),
+                AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_TRANSACTION_FAILED)));
+}
+
+// Call initOffload() multiple times. Check that non-first initOffload() calls return error.
+TEST_P(TetheroffloadAidlPreInitTest, AdditionalInitsWithoutStopReturnError) {
+    initOffload(true);
+    initOffload(false);
+    initOffload(false);
+    initOffload(false);
+}
+
+// Check that calling stopOffload() without first having called initOffload() returns error.
+TEST_P(TetheroffloadAidlPreInitTest, MultipleStopsWithoutInitReturnError) {
+    stopOffload(ExpectBoolean::False);
+    stopOffload(ExpectBoolean::False);
+    stopOffload(ExpectBoolean::False);
+}
+
+// Check that calling stopOffload() after a complete init/stop cycle returns error.
+TEST_P(TetheroffloadAidlPreInitTest, AdditionalStopsWithInitReturnError) {
+    initOffload(true);
+    // Call setUpstreamParameters() so that "offload" can be reasonably said
+    // to be both requested and operational.
+    const std::string iface(TEST_IFACE);
+    const std::string v4Addr("192.0.0.2");
+    const std::string v4Gw("192.0.0.1");
+    const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
+    auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+    EXPECT_TRUE(ret.isOk()) << ret;
+    if (!interfaceIsUp(TEST_IFACE)) {
+        return;
+    }
+    SCOPED_TRACE("Expecting stopOffload to succeed");
+    stopOffload(ExpectBoolean::True);  // balance out initOffload(true)
+    SCOPED_TRACE("Expecting stopOffload to fail the first time");
+    stopOffload(ExpectBoolean::False);
+    SCOPED_TRACE("Expecting stopOffload to fail the second time");
+    stopOffload(ExpectBoolean::False);
+}
+
+// Check that calling setLocalPrefixes() without first having called initOffload() returns error.
+TEST_P(TetheroffloadAidlPreInitTest, SetLocalPrefixesWithoutInitReturnsError) {
+    const std::vector<std::string> prefixes{std::string("2001:db8::/64")};
+    EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
+}
+
+// Check that calling getForwardedStats() without first having called initOffload()
+// returns zero bytes statistics.
+TEST_P(TetheroffloadAidlPreInitTest, GetForwardedStatsWithoutInitReturnsZeroValues) {
+    const std::string upstream(TEST_IFACE);
+    ForwardedStats stats;
+    auto ret = mOffload->getForwardedStats(upstream, &stats);
+    EXPECT_TRUE(ret.isOk()) << ret;
+    EXPECT_EQ(0ULL, stats.rxBytes);
+    EXPECT_EQ(0ULL, stats.txBytes);
+}
+
+// Check that calling setDataWarningAndLimit() without first having called initOffload() returns
+// error.
+TEST_P(TetheroffloadAidlPreInitTest, SetDataWarningAndLimitWithoutInitReturnsError) {
+    const std::string upstream(TEST_IFACE);
+    const int64_t warning = 5000LL;
+    const int64_t limit = 5000LL;
+    EXPECT_EQ(EX_ILLEGAL_STATE,
+              mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode());
+}
+
+// Check that calling setUpstreamParameters() without first having called initOffload()
+// returns error.
+TEST_P(TetheroffloadAidlPreInitTest, SetUpstreamParametersWithoutInitReturnsError) {
+    const std::string iface(TEST_IFACE);
+    const std::string v4Addr("192.0.2.0/24");
+    const std::string v4Gw("192.0.2.1");
+    const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
+    EXPECT_EQ(EX_ILLEGAL_STATE,
+              mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
+}
+
+// Check that calling addDownstream() with an IPv4 prefix without first having called
+// initOffload() returns error.
+TEST_P(TetheroffloadAidlPreInitTest, AddIPv4DownstreamWithoutInitReturnsError) {
+    const std::string iface(TEST_IFACE);
+    const std::string prefix("192.0.2.0/24");
+    EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->addDownstream(iface, prefix).getExceptionCode());
+}
+
+// Check that calling addDownstream() with an IPv6 prefix without first having called
+// initOffload() returns error.
+TEST_P(TetheroffloadAidlPreInitTest, AddIPv6DownstreamWithoutInitReturnsError) {
+    const std::string iface(TEST_IFACE);
+    const std::string prefix("2001:db8::/64");
+    EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->addDownstream(iface, prefix).getExceptionCode());
+}
+
+// Check that calling removeDownstream() with an IPv4 prefix without first having called
+// initOffload() returns error.
+TEST_P(TetheroffloadAidlPreInitTest, RemoveIPv4DownstreamWithoutInitReturnsError) {
+    const std::string iface(TEST_IFACE);
+    const std::string prefix("192.0.2.0/24");
+    EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->removeDownstream(iface, prefix).getExceptionCode());
+}
+
+// Check that calling removeDownstream() with an IPv6 prefix without first having called
+// initOffload() returns error.
+TEST_P(TetheroffloadAidlPreInitTest, RemoveIPv6DownstreamWithoutInitReturnsError) {
+    const std::string iface(TEST_IFACE);
+    const std::string prefix("2001:db8::/64");
+    EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->removeDownstream(iface, prefix).getExceptionCode());
+}
+
+/*
+ * Tests for IOffload::setLocalPrefixes().
+ */
+
+// Test setLocalPrefixes() rejects an IPv4 address.
+TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv4AddressFails) {
+    const std::vector<std::string> prefixes{std::string("192.0.2.1")};
+    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
+}
+
+// Test setLocalPrefixes() rejects an IPv6 address.
+TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv6AddressFails) {
+    const std::vector<std::string> prefixes{std::string("fe80::1")};
+    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
+}
+
+// Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
+TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv4v6PrefixesOk) {
+    const std::vector<std::string> prefixes{std::string("192.0.2.0/24"), std::string("fe80::/64")};
+    auto ret = mOffload->setLocalPrefixes(prefixes);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// Test that setLocalPrefixes() fails given empty input. There is always
+// a non-empty set of local prefixes; when all networking interfaces are down
+// we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
+TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesEmptyFails) {
+    const std::vector<std::string> prefixes{};
+    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
+}
+
+// Test setLocalPrefixes() fails on incorrectly formed input strings.
+TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesInvalidFails) {
+    const std::vector<std::string> prefixes{std::string("192.0.2.0/24"), std::string("invalid")};
+    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
+}
+
+/*
+ * Tests for IOffload::getForwardedStats().
+ */
+
+// Test that getForwardedStats() for a non-existent upstream yields zero bytes statistics.
+TEST_P(TetheroffloadAidlGeneralTest, GetForwardedStatsInvalidUpstreamIface) {
+    const std::string upstream("invalid");
+    ForwardedStats stats;
+    auto ret = mOffload->getForwardedStats(upstream, &stats);
+    EXPECT_TRUE(ret.isOk()) << ret;
+    EXPECT_EQ(0ULL, stats.rxBytes);
+    EXPECT_EQ(0ULL, stats.txBytes);
+}
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(TetheroffloadAidlGeneralTest, GetForwardedStatsDummyIface) {
+    const std::string upstream(TEST_IFACE);
+    ForwardedStats stats;
+    auto ret = mOffload->getForwardedStats(upstream, &stats);
+    EXPECT_TRUE(ret.isOk()) << ret;
+    EXPECT_EQ(0ULL, stats.rxBytes);
+    EXPECT_EQ(0ULL, stats.txBytes);
+}
+
+/*
+ * Tests for IOffload::setDataWarningAndLimit().
+ */
+
+// Test that setDataWarningAndLimit() for an empty interface name fails.
+TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitEmptyUpstreamIfaceFails) {
+    const std::string upstream("");
+    const int64_t warning = 12345LL;
+    const int64_t limit = 67890LL;
+    EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+              mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode());
+}
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitNonZeroOk) {
+    const std::string upstream(TEST_IFACE);
+    const int64_t warning = 4000LL;
+    const int64_t limit = 5000LL;
+    auto ret = mOffload->setDataWarningAndLimit(upstream, warning, limit);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitZeroOk) {
+    const std::string upstream(TEST_IFACE);
+    const int64_t warning = 0LL;
+    const int64_t limit = 0LL;
+    auto ret = mOffload->setDataWarningAndLimit(upstream, warning, limit);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitUnlimitedWarningOk) {
+    const std::string upstream(TEST_IFACE);
+    const int64_t warning = LLONG_MAX;
+    const int64_t limit = 5000LL;
+    auto ret = mOffload->setDataWarningAndLimit(upstream, warning, limit);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// Test that setDataWarningAndLimit() with negative thresholds fails.
+TEST_P(TetheroffloadAidlGeneralTest, SetDataWarningAndLimitNegativeFails) {
+    const std::string upstream(TEST_IFACE);
+    const int64_t warning = -1LL;
+    const int64_t limit = -1LL;
+    EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+              mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode());
+}
+
+/*
+ * Tests for IOffload::setUpstreamParameters().
+ */
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersIPv6OnlyOk) {
+    const std::string iface(TEST_IFACE);
+    const std::string v4Addr("");
+    const std::string v4Gw("");
+    const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
+    auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
+    const std::string iface(TEST_IFACE);
+    const std::string v4Addr("");
+    const std::string v4Gw("");
+    const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:3")};
+    auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersIPv4OnlyOk) {
+    const std::string iface(TEST_IFACE);
+    const std::string v4Addr("192.0.2.2");
+    const std::string v4Gw("192.0.2.1");
+    const std::vector<std::string> v6Gws{};
+    auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// TEST_IFACE is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersIPv4v6Ok) {
+    const std::string iface(TEST_IFACE);
+    const std::string v4Addr("192.0.2.2");
+    const std::string v4Gw("192.0.2.1");
+    const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
+    auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// Test that setUpstreamParameters() fails when all parameters are empty.
+TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersEmptyFails) {
+    const std::string iface("");
+    const std::string v4Addr("");
+    const std::string v4Gw("");
+    const std::vector<std::string> v6Gws{};
+    EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+              mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
+}
+
+// Test that setUpstreamParameters() fails when given empty or non-existent interface names.
+TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersBogusIfaceFails) {
+    const std::string v4Addr("192.0.2.2");
+    const std::string v4Gw("192.0.2.1");
+    const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(testing::Message() << "upstream: " << bogus);
+        const std::string iface(bogus);
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+                  mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 addresses.
+TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersInvalidIPv4AddrFails) {
+    const std::string iface(TEST_IFACE);
+    const std::string v4Gw("192.0.2.1");
+    const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
+    for (const auto& bogus : {"invalid", "192.0.2"}) {
+        SCOPED_TRACE(testing::Message() << "v4addr: " << bogus);
+        const std::string v4Addr(bogus);
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+                  mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 gateways.
+TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
+    const std::string iface(TEST_IFACE);
+    const std::string v4Addr("192.0.2.2");
+    const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
+    for (const auto& bogus : {"invalid", "192.0.2"}) {
+        SCOPED_TRACE(testing::Message() << "v4gateway: " << bogus);
+        const std::string v4Gw(bogus);
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+                  mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv6 gateways.
+TEST_P(TetheroffloadAidlGeneralTest, SetUpstreamParametersBadIPv6GatewaysFail) {
+    const std::string iface(TEST_IFACE);
+    const std::string v4Addr("192.0.2.2");
+    const std::string v4Gw("192.0.2.1");
+    for (const auto& bogus : {"", "invalid", "fe80::bogus", "192.0.2.66"}) {
+        SCOPED_TRACE(testing::Message() << "v6gateway: " << bogus);
+        const std::vector<std::string> v6Gws{std::string("fe80::1"), std::string(bogus)};
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+                  mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
+    }
+}
+
+/*
+ * Tests for IOffload::addDownstream().
+ */
+
+// Test addDownstream() works given an IPv4 prefix.
+TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamIPv4) {
+    const std::string iface("dummy0");
+    const std::string prefix("192.0.2.0/24");
+    auto ret = mOffload->addDownstream(iface, prefix);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// Test addDownstream() works given an IPv6 prefix.
+TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamIPv6) {
+    const std::string iface("dummy0");
+    const std::string prefix("2001:db8::/64");
+    auto ret = mOffload->addDownstream(iface, prefix);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// Test addDownstream() fails given all empty parameters.
+TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamEmptyFails) {
+    const std::string iface("");
+    const std::string prefix("");
+    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->addDownstream(iface, prefix).getExceptionCode());
+}
+
+// Test addDownstream() fails given empty or non-existent interface names.
+TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamInvalidIfaceFails) {
+    const std::string prefix("192.0.2.0/24");
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(testing::Message() << "iface: " << bogus);
+        const std::string iface(bogus);
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->addDownstream(iface, prefix).getExceptionCode());
+    }
+}
+
+// Test addDownstream() fails given unparseable prefix arguments.
+TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamBogusPrefixFails) {
+    const std::string iface("dummy0");
+    for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+        SCOPED_TRACE(testing::Message() << "prefix: " << bogus);
+        const std::string prefix(bogus);
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->addDownstream(iface, prefix).getExceptionCode());
+    }
+}
+
+/*
+ * Tests for IOffload::removeDownstream().
+ */
+
+// Test removeDownstream() works given an IPv4 prefix.
+TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamIPv4) {
+    const std::string iface("dummy0");
+    const std::string prefix("192.0.2.0/24");
+    // First add the downstream, otherwise removeDownstream logic can reasonably
+    // return error for downstreams not previously added.
+    auto ret = mOffload->addDownstream(iface, prefix);
+    EXPECT_TRUE(ret.isOk()) << ret;
+    ret = mOffload->removeDownstream(iface, prefix);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// Test removeDownstream() works given an IPv6 prefix.
+TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamIPv6) {
+    const std::string iface("dummy0");
+    const std::string prefix("2001:db8::/64");
+    // First add the downstream, otherwise removeDownstream logic can reasonably
+    // return error for downstreams not previously added.
+    auto ret = mOffload->addDownstream(iface, prefix);
+    EXPECT_TRUE(ret.isOk()) << ret;
+    ret = mOffload->removeDownstream(iface, prefix);
+    EXPECT_TRUE(ret.isOk()) << ret;
+}
+
+// Test removeDownstream() fails given all empty parameters.
+TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamEmptyFails) {
+    const std::string iface("");
+    const std::string prefix("");
+    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->removeDownstream(iface, prefix).getExceptionCode());
+}
+
+// Test removeDownstream() fails given empty or non-existent interface names.
+TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamBogusIfaceFails) {
+    const std::string prefix("192.0.2.0/24");
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(testing::Message() << "iface: " << bogus);
+        const std::string iface(bogus);
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+                  mOffload->removeDownstream(iface, prefix).getExceptionCode());
+    }
+}
+
+// Test removeDownstream() fails given unparseable prefix arguments.
+TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamBogusPrefixFails) {
+    const std::string iface("dummy0");
+    for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+        SCOPED_TRACE(testing::Message() << "prefix: " << bogus);
+        const std::string prefix(bogus);
+        EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+                  mOffload->removeDownstream(iface, prefix).getExceptionCode());
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TetheroffloadAidlTestBase);
+INSTANTIATE_TEST_SUITE_P(
+        IOffload, TetheroffloadAidlTestBase,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IOffload::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TetheroffloadAidlPreInitTest);
+INSTANTIATE_TEST_SUITE_P(
+        IOffload, TetheroffloadAidlPreInitTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IOffload::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TetheroffloadAidlGeneralTest);
+INSTANTIATE_TEST_SUITE_P(
+        IOffload, TetheroffloadAidlGeneralTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IOffload::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+}  // namespace
+}  // namespace aidl::android::hardware::tetheroffload
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/thermal/OWNERS b/thermal/OWNERS
new file mode 100644
index 0000000..7229b22
--- /dev/null
+++ b/thermal/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 826709
+
+# ADPF virtual team
+lpy@google.com
+wvw@google.com
diff --git a/thermal/aidl/Android.bp b/thermal/aidl/Android.bp
new file mode 100644
index 0000000..efc763c
--- /dev/null
+++ b/thermal/aidl/Android.bp
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.thermal",
+    vendor_available: true,
+    srcs: [
+        "android/hardware/thermal/*.aidl",
+    ],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: true,
+        },
+        java: {
+            platform_apis: true,
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/1/.hash b/thermal/aidl/aidl_api/android.hardware.thermal/1/.hash
new file mode 100644
index 0000000..1a9e33b
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/1/.hash
@@ -0,0 +1 @@
+76e77ca374a7860f09aeac48e98b2ec61f576767
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/CoolingDevice.aidl
new file mode 100644
index 0000000..dff3c4c
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/CoolingDevice.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+1 *      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.thermal;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable CoolingDevice {
+  android.hardware.thermal.CoolingType type;
+  String name;
+  long value;
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/CoolingType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/CoolingType.aidl
new file mode 100644
index 0000000..1f87cf2
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/CoolingType.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum CoolingType {
+  FAN,
+  BATTERY,
+  CPU,
+  GPU,
+  MODEM,
+  NPU,
+  COMPONENT,
+  TPU,
+  POWER_AMPLIFIER,
+  DISPLAY,
+  SPEAKER,
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/IThermal.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/IThermal.aidl
new file mode 100644
index 0000000..c9b6cab
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/IThermal.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@VintfStability
+interface IThermal {
+  android.hardware.thermal.CoolingDevice[] getCoolingDevices();
+  android.hardware.thermal.CoolingDevice[] getCoolingDevicesWithType(in android.hardware.thermal.CoolingType type);
+  android.hardware.thermal.Temperature[] getTemperatures();
+  android.hardware.thermal.Temperature[] getTemperaturesWithType(in android.hardware.thermal.TemperatureType type);
+  android.hardware.thermal.TemperatureThreshold[] getTemperatureThresholds();
+  android.hardware.thermal.TemperatureThreshold[] getTemperatureThresholdsWithType(in android.hardware.thermal.TemperatureType type);
+  void registerThermalChangedCallback(in android.hardware.thermal.IThermalChangedCallback callback);
+  void registerThermalChangedCallbackWithType(in android.hardware.thermal.IThermalChangedCallback callback, in android.hardware.thermal.TemperatureType type);
+  void unregisterThermalChangedCallback(in android.hardware.thermal.IThermalChangedCallback callback);
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/IThermalChangedCallback.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/IThermalChangedCallback.aidl
new file mode 100644
index 0000000..5e1d753
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/IThermalChangedCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@VintfStability
+interface IThermalChangedCallback {
+  oneway void notifyThrottling(in android.hardware.thermal.Temperature temperature);
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/Temperature.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/Temperature.aidl
new file mode 100644
index 0000000..ce70ab8
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/Temperature.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable Temperature {
+  android.hardware.thermal.TemperatureType type;
+  String name;
+  float value;
+  android.hardware.thermal.ThrottlingSeverity throttlingStatus;
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/TemperatureThreshold.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/TemperatureThreshold.aidl
new file mode 100644
index 0000000..a384d19
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/TemperatureThreshold.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable TemperatureThreshold {
+  android.hardware.thermal.TemperatureType type;
+  String name;
+  float[] hotThrottlingThresholds;
+  float[] coldThrottlingThresholds;
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/TemperatureType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/TemperatureType.aidl
new file mode 100644
index 0000000..fb0b0b3
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/TemperatureType.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum TemperatureType {
+  UNKNOWN = (-1) /* -1 */,
+  CPU = 0,
+  GPU = 1,
+  BATTERY = 2,
+  SKIN = 3,
+  USB_PORT = 4,
+  POWER_AMPLIFIER = 5,
+  BCL_VOLTAGE = 6,
+  BCL_CURRENT = 7,
+  BCL_PERCENTAGE = 8,
+  NPU = 9,
+  TPU = 10,
+  DISPLAY = 11,
+  MODEM = 12,
+  SOC = 13,
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/ThrottlingSeverity.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/ThrottlingSeverity.aidl
new file mode 100644
index 0000000..183344d
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/1/android/hardware/thermal/ThrottlingSeverity.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ThrottlingSeverity {
+  NONE = 0,
+  LIGHT,
+  MODERATE,
+  SEVERE,
+  CRITICAL,
+  EMERGENCY,
+  SHUTDOWN,
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
new file mode 100644
index 0000000..dff3c4c
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+1 *      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.thermal;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable CoolingDevice {
+  android.hardware.thermal.CoolingType type;
+  String name;
+  long value;
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
new file mode 100644
index 0000000..1f87cf2
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum CoolingType {
+  FAN,
+  BATTERY,
+  CPU,
+  GPU,
+  MODEM,
+  NPU,
+  COMPONENT,
+  TPU,
+  POWER_AMPLIFIER,
+  DISPLAY,
+  SPEAKER,
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl
new file mode 100644
index 0000000..c9b6cab
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@VintfStability
+interface IThermal {
+  android.hardware.thermal.CoolingDevice[] getCoolingDevices();
+  android.hardware.thermal.CoolingDevice[] getCoolingDevicesWithType(in android.hardware.thermal.CoolingType type);
+  android.hardware.thermal.Temperature[] getTemperatures();
+  android.hardware.thermal.Temperature[] getTemperaturesWithType(in android.hardware.thermal.TemperatureType type);
+  android.hardware.thermal.TemperatureThreshold[] getTemperatureThresholds();
+  android.hardware.thermal.TemperatureThreshold[] getTemperatureThresholdsWithType(in android.hardware.thermal.TemperatureType type);
+  void registerThermalChangedCallback(in android.hardware.thermal.IThermalChangedCallback callback);
+  void registerThermalChangedCallbackWithType(in android.hardware.thermal.IThermalChangedCallback callback, in android.hardware.thermal.TemperatureType type);
+  void unregisterThermalChangedCallback(in android.hardware.thermal.IThermalChangedCallback callback);
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermalChangedCallback.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermalChangedCallback.aidl
new file mode 100644
index 0000000..5e1d753
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermalChangedCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@VintfStability
+interface IThermalChangedCallback {
+  oneway void notifyThrottling(in android.hardware.thermal.Temperature temperature);
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl
new file mode 100644
index 0000000..ce70ab8
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable Temperature {
+  android.hardware.thermal.TemperatureType type;
+  String name;
+  float value;
+  android.hardware.thermal.ThrottlingSeverity throttlingStatus;
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl
new file mode 100644
index 0000000..a384d19
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable TemperatureThreshold {
+  android.hardware.thermal.TemperatureType type;
+  String name;
+  float[] hotThrottlingThresholds;
+  float[] coldThrottlingThresholds;
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
new file mode 100644
index 0000000..e9710a7
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum TemperatureType {
+  UNKNOWN = (-1),
+  CPU = 0,
+  GPU = 1,
+  BATTERY = 2,
+  SKIN = 3,
+  USB_PORT = 4,
+  POWER_AMPLIFIER = 5,
+  BCL_VOLTAGE = 6,
+  BCL_CURRENT = 7,
+  BCL_PERCENTAGE = 8,
+  NPU = 9,
+  TPU = 10,
+  DISPLAY = 11,
+  MODEM = 12,
+  SOC = 13,
+}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/ThrottlingSeverity.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/ThrottlingSeverity.aidl
new file mode 100644
index 0000000..183344d
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/ThrottlingSeverity.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.thermal;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ThrottlingSeverity {
+  NONE = 0,
+  LIGHT,
+  MODERATE,
+  SEVERE,
+  CRITICAL,
+  EMERGENCY,
+  SHUTDOWN,
+}
diff --git a/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
new file mode 100644
index 0000000..0c5c17d
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+1 *      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.thermal;
+
+import android.hardware.thermal.CoolingType;
+
+/* @hide */
+@VintfStability
+@JavaDerive(toString=true)
+parcelable CoolingDevice {
+    /**
+     * This cooling device type, CPU, GPU, BATTERY, and etc.
+     */
+    CoolingType type;
+    /**
+     * Name of this cooling device.
+     * All cooling devices of the same "type" must have a different "name".
+     * The name is usually defined in kernel device tree, and this is for client
+     * logging purpose.
+     */
+    String name;
+    /**
+     * Current throttle state of the cooling device. The value can any unsigned integer
+     * numbers between 0 and max_state defined in its driver, usually representing the
+     * associated device's power state. 0 means device is not in throttling, higher value
+     * means deeper throttling.
+     */
+    long value;
+}
diff --git a/thermal/aidl/android/hardware/thermal/CoolingType.aidl b/thermal/aidl/android/hardware/thermal/CoolingType.aidl
new file mode 100644
index 0000000..08beb55
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/CoolingType.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal;
+
+/**
+ * Device cooling device types
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum CoolingType {
+    FAN,
+    BATTERY,
+    CPU,
+    GPU,
+    MODEM,
+    NPU,
+    COMPONENT,
+    TPU,
+    POWER_AMPLIFIER,
+    DISPLAY,
+    SPEAKER,
+}
diff --git a/thermal/aidl/android/hardware/thermal/IThermal.aidl b/thermal/aidl/android/hardware/thermal/IThermal.aidl
new file mode 100644
index 0000000..c94edcd
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/IThermal.aidl
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal;
+
+import android.hardware.thermal.CoolingDevice;
+import android.hardware.thermal.CoolingType;
+import android.hardware.thermal.IThermalChangedCallback;
+import android.hardware.thermal.Temperature;
+import android.hardware.thermal.TemperatureThreshold;
+import android.hardware.thermal.TemperatureType;
+
+/* @hide */
+@VintfStability
+interface IThermal {
+    /**
+     * Retrieves the cooling devices information.
+     *
+     * @return devices If succeed, it's filled with the
+     *    current cooling device information. The order of built-in cooling
+     *    devices in the list must be kept the same regardless the number
+     *    of calls to this method even if they go offline, if these devices
+     *    exist on boot. The method always returns and never removes from
+     *    the list such cooling devices.
+     *
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    CoolingDevice[] getCoolingDevices();
+
+    /**
+     * Retrieves the cooling devices information of a given CoolingType.
+     *
+     * @param type the CoolingDevice such as CPU/GPU.
+     *
+     * @return devices If succeed, it's filled with the current
+     *    cooling device information. The order of built-in cooling
+     *    devices in the list must be kept the same regardless of the number
+     *    of calls to this method even if they go offline, if these devices
+     *    exist on boot. The method always returns and never removes from
+     *    the list such cooling devices.
+     *
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    CoolingDevice[] getCoolingDevicesWithType(in CoolingType type);
+
+    /**
+     * Retrieves temperatures in Celsius.
+     *
+     * @return temperatures If succeed, it's filled with the
+     *    current temperatures. The order of temperatures of built-in
+     *    devices (such as CPUs, GPUs and etc.) in the list must be kept
+     *    the same regardless the number of calls to this method even if
+     *    they go offline, if these devices exist on boot. The method
+     *    always returns and never removes such temperatures.
+     *
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    Temperature[] getTemperatures();
+
+    /**
+     * Retrieves temperatures in Celsius with a given TemperatureType.
+     *
+     * @param type the TemperatureType such as battery or skin.
+     *
+     * @return temperatures If succeed, it's filled with the
+     *    current temperatures. The order of temperatures of built-in
+     *    devices (such as CPUs, GPUs and etc.) in the list must be kept
+     *    the same regardless of the number of calls to this method even if
+     *    they go offline, if these devices exist on boot. The method
+     *    always returns and never removes such temperatures.
+     *
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    Temperature[] getTemperaturesWithType(in TemperatureType type);
+
+    /**
+     * Retrieves static temperature thresholds in Celsius.
+     *
+     * @return temperatureThresholds If succeed, it's filled with the
+     *    temperatures thresholds. The order of temperatures of built-in
+     *    devices (such as CPUs, GPUs and etc.) in the list must be kept
+     *    the same regardless of the number of calls to this method even if
+     *    they go offline, if these devices exist on boot. The method
+     *    always returns and never removes such temperatures. The thresholds
+     *    are returned as static values and must not change across calls. The actual
+     *    throttling state is determined in device thermal mitigation policy/algorithm
+     *    which might not be simple thresholds so these values Thermal HAL provided
+     *    may not be accurate to determine the throttling status. To get accurate
+     *    throttling status, use getTemperatures or registerThermalChangedCallback
+     *    and listen to the callback.
+     *
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    TemperatureThreshold[] getTemperatureThresholds();
+
+    /**
+     * Retrieves static temperature thresholds in Celsius of a given temperature
+     * type.
+     *
+     * @param type the TemperatureType such as battery or skin.
+     *
+     * @return temperatureThresholds If succeed, it's filled with the
+     *    temperatures thresholds. The order of temperatures of built-in
+     *    devices (such as CPUs, GPUs and etc.) in the list must be kept
+     *    the same regardless of the number of calls to this method even if
+     *    they go offline, if these devices exist on boot. The method
+     *    always returns and never removes such temperatures. The thresholds
+     *    are returned as static values and must not change across calls. The actual
+     *    throttling state is determined in device thermal mitigation policy/algorithm
+     *    which might not be simple thresholds so these values Thermal HAL provided
+     *    may not be accurate to determine the throttling status. To get accurate
+     *    throttling status, use getTemperatures or registerThermalChangedCallback
+     *    and listen to the callback.
+     *
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    TemperatureThreshold[] getTemperatureThresholdsWithType(in TemperatureType type);
+
+    /**
+     * Register an IThermalChangedCallback, used by the Thermal HAL to receive
+     * thermal events when thermal mitigation status changed.
+     * Multiple registrations with different IThermalChangedCallback must be allowed.
+     * Multiple registrations with same IThermalChangedCallback is not allowed, client
+     * should unregister the given IThermalChangedCallback first.
+     *
+     * @param callback the IThermalChangedCallback to use for receiving
+     *    thermal events. if nullptr callback is given, the status code will be
+     *    STATUS_BAD_VALUE and the operation will fail.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or already registered. And the
+     *         getMessage() must be populated with human-readable error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    void registerThermalChangedCallback(in IThermalChangedCallback callback);
+
+    /**
+     * Register an IThermalChangedCallback for a given TemperatureType, used by
+     * the Thermal HAL to receive thermal events when thermal mitigation status
+     * changed.
+     * Multiple registrations with different IThermalChangedCallback must be allowed.
+     * Multiple registrations with same IThermalChangedCallback is not allowed, client
+     * should unregister the given IThermalChangedCallback first.
+     *
+     * @param callback the IThermalChangedCallback to use for receiving
+     *    thermal events. if nullptr callback is given, the status code will be
+     *    STATUS_BAD_VALUE and the operation will fail.
+     * @param type the type to be filtered.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or already registered. And the
+     *         getMessage() must be populated with human-readable error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    void registerThermalChangedCallbackWithType(
+            in IThermalChangedCallback callback, in TemperatureType type);
+
+    /**
+     * Unregister an IThermalChangedCallback, used by the Thermal HAL
+     * to receive thermal events when thermal mitigation status changed.
+     *
+     * @param callback the IThermalChangedCallback to use for receiving
+     *    thermal events. if nullptr callback is given, the status code will be
+     *    STATUS_BAD_VALUE and the operation will fail.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or not previously registered.
+     *         And the getMessage() must be populated with human-readable error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    void unregisterThermalChangedCallback(in IThermalChangedCallback callback);
+}
diff --git a/thermal/aidl/android/hardware/thermal/IThermalChangedCallback.aidl b/thermal/aidl/android/hardware/thermal/IThermalChangedCallback.aidl
new file mode 100644
index 0000000..105f085
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/IThermalChangedCallback.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal;
+
+import android.hardware.thermal.Temperature;
+
+/**
+ * IThermalChangedCallback send throttling notification to clients.
+ * @hide
+ */
+@VintfStability
+interface IThermalChangedCallback {
+    /**
+     * Send a thermal throttling event to all ThermalHAL
+     * thermal event listeners.
+     *
+     * @param temperature The temperature associated with the
+     *    throttling event.
+     */
+    oneway void notifyThrottling(in Temperature temperature);
+}
diff --git a/thermal/aidl/android/hardware/thermal/Temperature.aidl b/thermal/aidl/android/hardware/thermal/Temperature.aidl
new file mode 100644
index 0000000..b3f6700
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/Temperature.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal;
+
+import android.hardware.thermal.TemperatureType;
+import android.hardware.thermal.ThrottlingSeverity;
+
+/* @hide */
+@VintfStability
+@JavaDerive(toString=true)
+parcelable Temperature {
+    /**
+     * This temperature's type.
+     */
+    TemperatureType type;
+    /**
+     * Name of this temperature matching the TemperatureThreshold.
+     * All temperatures of the same "type" must have a different "name",
+     * e.g., cpu0, battery. Clients use it to match with TemperatureThreshold
+     * struct.
+     */
+    String name;
+    /**
+     * For BCL, this is the current reading of the virtual sensor and the unit is
+     * millivolt, milliamp, percentage for BCL_VOLTAGE, BCL_CURRENT and BCL_PERCENTAGE
+     * respectively. For everything else, this is the current temperature in Celsius.
+     * If not available set by HAL to NAN.
+     */
+    float value;
+    /**
+     * The current throttling level of the sensor.
+     */
+    ThrottlingSeverity throttlingStatus;
+}
diff --git a/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl b/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl
new file mode 100644
index 0000000..94991ae
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal;
+
+import android.hardware.thermal.TemperatureType;
+
+/* @hide */
+@VintfStability
+@JavaDerive(toString=true)
+parcelable TemperatureThreshold {
+    /**
+     * This temperature's type.
+     */
+    TemperatureType type;
+    /**
+     * Name of this temperature matching the Temperature struct.
+     * All temperatures of the same "type" must have a different "name",
+     * e.g., cpu0, battery. Clients use it to match Temperature struct.
+     */
+    String name;
+    /**
+     * Hot throttling temperature constant for this temperature sensor in
+     * level defined in ThrottlingSeverity including shutdown. Throttling
+     * happens when temperature >= threshold. If not available, set to NAN.
+     * Unit is same as Temperature's value.
+     * The array size must be the same as ThrottlingSeverity's enum cardinality.
+     */
+    float[] hotThrottlingThresholds;
+    /**
+     * Cold throttling temperature constant for this temperature sensor in
+     * level defined in ThrottlingSeverity including shutdown. Throttling
+     * happens when temperature <= threshold. If not available, set to NAN.
+     * Unit is same as Temperature's value.
+     * The array size must be the same as ThrottlingSeverity's enum cardinality.
+     */
+    float[] coldThrottlingThresholds;
+}
diff --git a/thermal/aidl/android/hardware/thermal/TemperatureType.aidl b/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
new file mode 100644
index 0000000..467d096
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal;
+
+/**
+ * Device temperature types
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum TemperatureType {
+    UNKNOWN = -1,
+    CPU = 0,
+    GPU = 1,
+    BATTERY = 2,
+    SKIN = 3,
+    USB_PORT = 4,
+    POWER_AMPLIFIER = 5,
+    /**
+     * Battery Current Limit - virtual sensors
+     */
+    BCL_VOLTAGE = 6,
+    BCL_CURRENT = 7,
+    BCL_PERCENTAGE = 8,
+    /**
+     * Neural Processing Unit
+     */
+    NPU = 9,
+    TPU = 10,
+    DISPLAY = 11,
+    MODEM = 12,
+    SOC = 13,
+}
diff --git a/thermal/aidl/android/hardware/thermal/ThrottlingSeverity.aidl b/thermal/aidl/android/hardware/thermal/ThrottlingSeverity.aidl
new file mode 100644
index 0000000..c66e6c2
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/ThrottlingSeverity.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal;
+
+/**
+ * Device throttling severity
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum ThrottlingSeverity {
+    /**
+     * Not under throttling.
+     */
+    NONE = 0,
+    /**
+     * Light throttling where UX is not impacted.
+     */
+    LIGHT,
+    /**
+     * Moderate throttling where UX is not largely impacted.
+     */
+    MODERATE,
+    /**
+     * Severe throttling where UX is largely impacted.
+     * Similar to 1.0 throttlingThreshold.
+     */
+    SEVERE,
+    /**
+     * Platform has done everything to reduce power.
+     */
+    CRITICAL,
+    /**
+     * Key components in platform are shutting down due to thermal condition.
+     * Device functionalities will be limited.
+     */
+    EMERGENCY,
+    /**
+     * Need shutdown immediately.
+     */
+    SHUTDOWN,
+}
diff --git a/thermal/aidl/default/Android.bp b/thermal/aidl/default/Android.bp
new file mode 100644
index 0000000..49a578b
--- /dev/null
+++ b/thermal/aidl/default/Android.bp
@@ -0,0 +1,49 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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_binary {
+    name: "android.hardware.thermal-service.example",
+    relative_install_path: "hw",
+    init_rc: [":android.hardware.thermal.example.rc"],
+    vintf_fragments: [":android.hardware.thermal.example.xml"],
+    vendor: true,
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.thermal-V1-ndk",
+    ],
+    srcs: [
+        "main.cpp",
+        "Thermal.cpp",
+    ],
+}
+
+filegroup {
+    name: "android.hardware.thermal.example.xml",
+    srcs: ["thermal-example.xml"],
+}
+
+filegroup {
+    name: "android.hardware.thermal.example.rc",
+    srcs: ["thermal-example.rc"],
+}
diff --git a/thermal/aidl/default/Thermal.cpp b/thermal/aidl/default/Thermal.cpp
new file mode 100644
index 0000000..f643d22
--- /dev/null
+++ b/thermal/aidl/default/Thermal.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "thermal_service_example"
+
+#include "Thermal.h"
+
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::thermal::impl::example {
+
+using ndk::ScopedAStatus;
+
+namespace {
+
+bool interfacesEqual(const std::shared_ptr<::ndk::ICInterface>& left,
+                     const std::shared_ptr<::ndk::ICInterface>& right) {
+    if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) {
+        return left == right;
+    }
+    return left->asBinder() == right->asBinder();
+}
+
+}  // namespace
+
+ScopedAStatus Thermal::getCoolingDevices(std::vector<CoolingDevice>* /* out_devices */) {
+    LOG(VERBOSE) << __func__;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::getCoolingDevicesWithType(CoolingType in_type,
+                                                 std::vector<CoolingDevice>* /* out_devices */) {
+    LOG(VERBOSE) << __func__ << " CoolingType: " << static_cast<int32_t>(in_type);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::getTemperatures(std::vector<Temperature>* /* out_temperatures */) {
+    LOG(VERBOSE) << __func__;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::getTemperaturesWithType(TemperatureType in_type,
+                                               std::vector<Temperature>* /* out_temperatures */) {
+    LOG(VERBOSE) << __func__ << " TemperatureType: " << static_cast<int32_t>(in_type);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::getTemperatureThresholds(
+        std::vector<TemperatureThreshold>* /* out_temperatureThresholds */) {
+    LOG(VERBOSE) << __func__;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::getTemperatureThresholdsWithType(
+        TemperatureType in_type,
+        std::vector<TemperatureThreshold>* /* out_temperatureThresholds */) {
+    LOG(VERBOSE) << __func__ << " TemperatureType: " << static_cast<int32_t>(in_type);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::registerThermalChangedCallback(
+        const std::shared_ptr<IThermalChangedCallback>& in_callback) {
+    LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback;
+    if (in_callback == nullptr) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid nullptr callback");
+    }
+    {
+        std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
+        if (std::any_of(thermal_callbacks_.begin(), thermal_callbacks_.end(),
+                        [&](const std::shared_ptr<IThermalChangedCallback>& c) {
+                            return interfacesEqual(c, in_callback);
+                        })) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Callback already registered");
+        }
+        thermal_callbacks_.push_back(in_callback);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::registerThermalChangedCallbackWithType(
+        const std::shared_ptr<IThermalChangedCallback>& in_callback, TemperatureType in_type) {
+    LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback
+                 << ", TemperatureType: " << static_cast<int32_t>(in_type);
+    if (in_callback == nullptr) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid nullptr callback");
+    }
+    {
+        std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
+        if (std::any_of(thermal_callbacks_.begin(), thermal_callbacks_.end(),
+                        [&](const std::shared_ptr<IThermalChangedCallback>& c) {
+                            return interfacesEqual(c, in_callback);
+                        })) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Callback already registered");
+        }
+        thermal_callbacks_.push_back(in_callback);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::unregisterThermalChangedCallback(
+        const std::shared_ptr<IThermalChangedCallback>& in_callback) {
+    LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback;
+    if (in_callback == nullptr) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid nullptr callback");
+    }
+    {
+        std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
+        bool removed = false;
+        thermal_callbacks_.erase(
+                std::remove_if(thermal_callbacks_.begin(), thermal_callbacks_.end(),
+                               [&](const std::shared_ptr<IThermalChangedCallback>& c) {
+                                   if (interfacesEqual(c, in_callback)) {
+                                       removed = true;
+                                       return true;
+                                   }
+                                   return false;
+                               }),
+                thermal_callbacks_.end());
+        if (!removed) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Callback wasn't registered");
+        }
+    }
+    return ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::thermal::impl::example
diff --git a/thermal/aidl/default/Thermal.h b/thermal/aidl/default/Thermal.h
new file mode 100644
index 0000000..8885e63
--- /dev/null
+++ b/thermal/aidl/default/Thermal.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <set>
+
+#include <aidl/android/hardware/thermal/BnThermal.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace thermal {
+namespace impl {
+namespace example {
+
+class Thermal : public BnThermal {
+  public:
+    ndk::ScopedAStatus getCoolingDevices(std::vector<CoolingDevice>* out_devices) override;
+    ndk::ScopedAStatus getCoolingDevicesWithType(CoolingType in_type,
+                                                 std::vector<CoolingDevice>* out_devices) override;
+
+    ndk::ScopedAStatus getTemperatures(std::vector<Temperature>* out_temperatures) override;
+    ndk::ScopedAStatus getTemperaturesWithType(TemperatureType in_type,
+                                               std::vector<Temperature>* out_temperatures) override;
+
+    ndk::ScopedAStatus getTemperatureThresholds(
+            std::vector<TemperatureThreshold>* out_temperatureThresholds) override;
+
+    ndk::ScopedAStatus getTemperatureThresholdsWithType(
+            TemperatureType in_type,
+            std::vector<TemperatureThreshold>* out_temperatureThresholds) override;
+
+    ndk::ScopedAStatus registerThermalChangedCallback(
+            const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
+    ndk::ScopedAStatus registerThermalChangedCallbackWithType(
+            const std::shared_ptr<IThermalChangedCallback>& in_callback,
+            TemperatureType in_type) override;
+
+    ndk::ScopedAStatus unregisterThermalChangedCallback(
+            const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
+
+  private:
+    std::mutex thermal_callback_mutex_;
+    std::vector<std::shared_ptr<IThermalChangedCallback>> thermal_callbacks_;
+};
+
+}  // namespace example
+}  // namespace impl
+}  // namespace thermal
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/thermal/aidl/default/main.cpp b/thermal/aidl/default/main.cpp
new file mode 100644
index 0000000..9f4ddb8
--- /dev/null
+++ b/thermal/aidl/default/main.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "thermal_service_example"
+
+#include "Thermal.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::thermal::impl::example::Thermal;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<Thermal> thermal = ndk::SharedRefBase::make<Thermal>();
+
+    const std::string instance = std::string() + Thermal::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(thermal->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/thermal/aidl/default/thermal-example.rc b/thermal/aidl/default/thermal-example.rc
new file mode 100644
index 0000000..591ca03
--- /dev/null
+++ b/thermal/aidl/default/thermal-example.rc
@@ -0,0 +1,4 @@
+service vendor.thermal-example /vendor/bin/hw/android.hardware.thermal-service.example
+    class hal
+    user nobody
+    group system
diff --git a/thermal/aidl/default/thermal-example.xml b/thermal/aidl/default/thermal-example.xml
new file mode 100644
index 0000000..bdee744
--- /dev/null
+++ b/thermal/aidl/default/thermal-example.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.thermal</name>
+        <version>1</version>
+        <fqname>IThermal/default</fqname>
+    </hal>
+</manifest>
diff --git a/thermal/aidl/vts/Android.bp b/thermal/aidl/vts/Android.bp
new file mode 100644
index 0000000..b00eb33
--- /dev/null
+++ b/thermal/aidl/vts/Android.bp
@@ -0,0 +1,40 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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_test {
+    name: "VtsHalThermalTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalThermalTargetTest.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.thermal-V1-ndk",
+    ],
+    test_suites: [
+        "vts",
+    ],
+}
diff --git a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
new file mode 100644
index 0000000..835fbfa
--- /dev/null
+++ b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <chrono>
+#include <cmath>
+#include <memory>
+#include <string>
+#include <thread>
+#include <vector>
+
+#define LOG_TAG "thermal_aidl_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/thermal/BnThermal.h>
+#include <aidl/android/hardware/thermal/BnThermalChangedCallback.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_status.h>
+#include <gtest/gtest.h>
+
+#include <unistd.h>
+
+namespace aidl::android::hardware::thermal {
+
+namespace {
+
+using ::android::sp;
+using android::hardware::thermal::CoolingDevice;
+using android::hardware::thermal::IThermal;
+using android::hardware::thermal::Temperature;
+using android::hardware::thermal::TemperatureType;
+
+using namespace std::string_literals;
+using namespace std::chrono_literals;
+
+static const Temperature kThrottleTemp = {
+        .type = TemperatureType::SKIN,
+        .name = "test temperature sensor",
+        .value = 98.6,
+        .throttlingStatus = ThrottlingSeverity::CRITICAL,
+};
+
+// Callback class for receiving thermal event notifications from main class
+class ThermalCallback : public BnThermalChangedCallback {
+  public:
+    ndk::ScopedAStatus notifyThrottling(const Temperature&) override {
+        {
+            std::lock_guard<std::mutex> lock(mMutex);
+            mInvoke = true;
+        }
+        mNotifyThrottling.notify_all();
+        return ndk::ScopedAStatus::ok();
+    }
+
+    template <typename R, typename P>
+    [[nodiscard]] bool waitForCallback(std::chrono::duration<R, P> duration) {
+        std::unique_lock<std::mutex> lock(mMutex);
+        bool r = mNotifyThrottling.wait_for(lock, duration, [this] { return this->mInvoke; });
+        mInvoke = false;
+        return r;
+    }
+
+  private:
+    std::mutex mMutex;
+    std::condition_variable mNotifyThrottling;
+    bool mInvoke = false;
+};
+
+// The main test class for THERMAL HIDL HAL.
+class ThermalAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+        ASSERT_NE(binder, nullptr);
+        mThermal = IThermal::fromBinder(ndk::SpAIBinder(binder));
+
+        mThermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
+        ASSERT_NE(mThermalCallback, nullptr);
+        ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
+        ASSERT_TRUE(status.isOk()) << status.getMessage();
+    }
+
+    void TearDown() override {
+        ::ndk::ScopedAStatus status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
+        ASSERT_TRUE(status.isOk()) << status.getMessage();
+        // Expect to fail if unregister again
+        status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
+        ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+    }
+
+  protected:
+    std::shared_ptr<IThermal> mThermal;
+    std::shared_ptr<ThermalCallback> mThermalCallback;
+};
+
+// Test ThermalChangedCallback::notifyThrottling().
+// This just calls into and back from our local ThermalChangedCallback impl.
+TEST_P(ThermalAidlTest, NotifyThrottlingTest) {
+    std::shared_ptr<ThermalCallback> thermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
+    ::ndk::ScopedAStatus status = thermalCallback->notifyThrottling(kThrottleTemp);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    ASSERT_TRUE(thermalCallback->waitForCallback(200ms));
+}
+
+// Test Thermal->registerThermalChangedCallback.
+TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackTest) {
+    // Expect to fail with same callback
+    ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
+    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+    // Expect to fail with null callback
+    status = mThermal->registerThermalChangedCallback(nullptr);
+    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+    std::shared_ptr<ThermalCallback> localThermalCallback =
+            ndk::SharedRefBase::make<ThermalCallback>();
+    // Expect to succeed with different callback
+    status = mThermal->registerThermalChangedCallback(localThermalCallback);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    // Remove the local callback
+    status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    // Expect to fail with null callback
+    status = mThermal->unregisterThermalChangedCallback(nullptr);
+    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+}
+
+// Test Thermal->registerThermalChangedCallbackWithType.
+TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackWithTypeTest) {
+    // Expect to fail with same callback
+    ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallbackWithType(
+            mThermalCallback, TemperatureType::SKIN);
+    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+    // Expect to fail with null callback
+    status = mThermal->registerThermalChangedCallbackWithType(nullptr, TemperatureType::SKIN);
+    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+    std::shared_ptr<ThermalCallback> localThermalCallback =
+            ndk::SharedRefBase::make<ThermalCallback>();
+    // Expect to succeed with different callback
+    status = mThermal->registerThermalChangedCallbackWithType(localThermalCallback,
+                                                              TemperatureType::SKIN);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    // Remove the local callback
+    status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    // Expect to fail with null callback
+    status = mThermal->unregisterThermalChangedCallback(nullptr);
+    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+}
+
+// Test Thermal->getCurrentTemperatures().
+TEST_P(ThermalAidlTest, TemperatureTest) {
+    std::vector<Temperature> ret;
+    ::ndk::ScopedAStatus status = mThermal->getTemperatures(&ret);
+    if (status.isOk()) {
+        for (auto& i : ret) {
+            EXPECT_LT(0u, i.name.size());
+            LOG(INFO) << i.name + " " + toString(i.type) << "\n";
+        }
+    } else {
+        ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+    }
+
+    auto types = ::ndk::enum_range<TemperatureType>();
+    for (const auto& type : types) {
+        status = mThermal->getTemperaturesWithType(type, &ret);
+
+        if (status.isOk()) {
+            for (auto& i : ret) {
+                EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
+                                                   toString(i.type) + " for " + i.name;
+                EXPECT_LT(0u, i.name.size());
+            }
+        } else {
+            ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+        }
+    }
+}
+
+// Test Thermal->getTemperatureThresholds().
+TEST_P(ThermalAidlTest, TemperatureThresholdTest) {
+    std::vector<TemperatureThreshold> ret;
+    ::ndk::ScopedAStatus status = mThermal->getTemperatureThresholds(&ret);
+    if (status.isOk()) {
+        for (auto& i : ret) {
+            EXPECT_LT(0u, i.name.size());
+            LOG(INFO) << i.name + " " + toString(i.type) << "\n";
+        }
+    } else {
+        ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+    }
+
+    auto types = ::ndk::enum_range<TemperatureType>();
+    for (const auto& type : types) {
+        status = mThermal->getTemperatureThresholdsWithType(type, &ret);
+
+        if (status.isOk()) {
+            for (auto& i : ret) {
+                EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
+                                                   toString(i.type) + " for " + i.name;
+                EXPECT_LT(0u, i.name.size());
+            }
+        } else {
+            ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+        }
+    }
+}
+
+// Test Thermal->getCoolingDevices().
+TEST_P(ThermalAidlTest, CoolingDeviceTest) {
+    std::vector<CoolingDevice> ret;
+    ::ndk::ScopedAStatus status = mThermal->getCoolingDevices(&ret);
+    if (status.isOk()) {
+        for (auto& i : ret) {
+            EXPECT_LT(0u, i.name.size());
+            LOG(INFO) << i.name + " " + toString(i.type) << "\n";
+        }
+    } else {
+        ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+    }
+
+    auto types = ::ndk::enum_range<CoolingType>();
+    for (const auto& type : types) {
+        status = mThermal->getCoolingDevicesWithType(type, &ret);
+        if (status.isOk()) {
+            ASSERT_TRUE(status.isOk());
+            for (auto& i : ret) {
+                EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
+                                                   toString(i.type) + " for " + i.name;
+                EXPECT_LT(0u, i.name.size());
+            }
+        } else {
+            ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+        }
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThermalAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+        Thermal, ThermalAidlTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IThermal::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+}  // namespace
+}  // namespace aidl::android::hardware::thermal
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/thermal/utils/Android.bp b/thermal/utils/Android.bp
new file mode 100644
index 0000000..72e1e34
--- /dev/null
+++ b/thermal/utils/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_static {
+    name: "libthermalutils",
+    vendor_available: true,
+    export_include_dirs: ["include"],
+    srcs: [
+        "ThermalHidlWrapper.cpp",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+    shared_libs: [
+        "android.hardware.thermal@2.0",
+        "android.hardware.thermal-V1-ndk",
+    ],
+}
diff --git a/thermal/utils/ThermalHidlWrapper.cpp b/thermal/utils/ThermalHidlWrapper.cpp
new file mode 100644
index 0000000..05a992a
--- /dev/null
+++ b/thermal/utils/ThermalHidlWrapper.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/thermalutils/ThermalHidlWrapper.h"
+
+#include <hidl/HidlTransportSupport.h>
+
+#include <cmath>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace thermal {
+
+using ::android::hardware::Void;
+
+namespace {
+
+template <typename T, typename U>
+Return<void> setFailureAndCallback(T _hidl_cb, hidl_vec<U> data, std::string_view debug_msg) {
+    ThermalStatus status;
+    status.code = ThermalStatusCode::FAILURE;
+    status.debugMessage = debug_msg.data();
+    _hidl_cb(status, data);
+    return Void();
+}
+
+template <typename T>
+Return<void> setFailureAndCallback(T _hidl_cb, std::string_view debug_msg) {
+    ThermalStatus status;
+    status.code = ThermalStatusCode::FAILURE;
+    status.debugMessage = debug_msg.data();
+    _hidl_cb(status);
+    return Void();
+}
+
+template <typename T, typename U>
+Return<void> setInitFailureAndCallback(T _hidl_cb, hidl_vec<U> data) {
+    return setFailureAndCallback(
+            _hidl_cb, data, "Thermal AIDL HAL client used by HIDL wrapper was not initialized");
+}
+
+template <typename T>
+Return<void> setInitFailureAndCallback(T _hidl_cb) {
+    return setFailureAndCallback(
+            _hidl_cb, "Thermal AIDL HAL client used by HIDL wrapper was not initialized");
+}
+
+template <typename T, typename U>
+Return<void> setUnsupportedFailureAndCallback(T _hidl_cb, hidl_vec<U> data) {
+    return setFailureAndCallback(_hidl_cb, data, "Operation unsupported by Thermal HIDL wrapper");
+}
+
+TemperatureType_2_0 convertAidlTemperatureType(const TemperatureType& type) {
+    if (type < TemperatureType::CPU || type > TemperatureType::NPU) {
+        return TemperatureType_2_0::UNKNOWN;
+    }
+    return static_cast<TemperatureType_2_0>(type);
+}
+
+CoolingType_2_0 convertAidlCoolingType(const CoolingType& type) {
+    if (type < CoolingType::FAN || type > CoolingType::COMPONENT) {
+        return CoolingType_2_0::COMPONENT;
+    }
+    return static_cast<CoolingType_2_0>(type);
+}
+
+Temperature_2_0 convertAidlTemperature(const Temperature& temperature) {
+    Temperature_2_0 t = Temperature_2_0{
+            convertAidlTemperatureType(temperature.type), temperature.name, temperature.value,
+            static_cast<ThrottlingSeverity_2_0>(temperature.throttlingStatus)};
+    return t;
+}
+
+CoolingDevice_2_0 convertAidlCoolingDevice(const CoolingDevice& cooling_device) {
+    CoolingDevice_2_0 t =
+            CoolingDevice_2_0{convertAidlCoolingType(cooling_device.type), cooling_device.name,
+                              static_cast<uint64_t>(cooling_device.value)};
+    return t;
+}
+TemperatureThreshold_2_0 convertAidlTemperatureThreshold(const TemperatureThreshold& threshold) {
+    TemperatureThreshold_2_0 t =
+            TemperatureThreshold_2_0{convertAidlTemperatureType(threshold.type), threshold.name,
+                                     threshold.hotThrottlingThresholds.data(),
+                                     threshold.coldThrottlingThresholds.data(), NAN};
+    return t;
+}
+
+}  // namespace
+
+// Methods from ::android::hardware::thermal::V1_0::IThermal follow.
+Return<void> ThermalHidlWrapper::getTemperatures(getTemperatures_cb _hidl_cb) {
+    hidl_vec<Temperature_1_0> ret_1_0;
+    setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
+    return Void();
+}
+
+Return<void> ThermalHidlWrapper::getCpuUsages(
+        std::function<void(const ThermalStatus&, const hidl_vec<CpuUsage>&)> _hidl_cb) {
+    hidl_vec<CpuUsage> ret_1_0;
+    setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
+    return Void();
+}
+
+Return<void> ThermalHidlWrapper::getCoolingDevices(
+        std::function<void(const ThermalStatus&, const hidl_vec<CoolingDevice_1_0>&)> _hidl_cb) {
+    hidl_vec<CoolingDevice_1_0> ret_1_0;
+    setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
+    return Void();
+}
+
+// Methods from ::android::hardware::thermal::V2_0::IThermal follow.
+Return<void> ThermalHidlWrapper::getCurrentTemperatures(
+        bool filterType, TemperatureType_2_0 type,
+        std::function<void(const ThermalStatus&, const hidl_vec<Temperature_2_0>&)> _hidl_cb) {
+    hidl_vec<Temperature_2_0> ret_2_0;
+    if (!thermal_service_) {
+        setInitFailureAndCallback(_hidl_cb, ret_2_0);
+    }
+
+    std::vector<Temperature> ret_aidl;
+    ThermalStatus status;
+    ::ndk::ScopedAStatus a_status;
+    if (filterType) {
+        a_status = thermal_service_->getTemperaturesWithType(static_cast<TemperatureType>(type),
+                                                             &ret_aidl);
+    } else {
+        a_status = thermal_service_->getTemperatures(&ret_aidl);
+    }
+    if (a_status.isOk()) {
+        std::vector<Temperature_2_0> ret;
+        for (const auto& temperature : ret_aidl) {
+            ret.push_back(convertAidlTemperature(temperature));
+        }
+        _hidl_cb(status, hidl_vec<Temperature_2_0>(ret));
+    } else {
+        setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
+    }
+    return Void();
+}
+
+Return<void> ThermalHidlWrapper::getTemperatureThresholds(
+        bool filterType, TemperatureType_2_0 type,
+        std::function<void(const ThermalStatus&, const hidl_vec<TemperatureThreshold_2_0>&)>
+                _hidl_cb) {
+    hidl_vec<TemperatureThreshold_2_0> ret_2_0;
+    if (!thermal_service_) {
+        setInitFailureAndCallback(_hidl_cb, ret_2_0);
+    }
+
+    std::vector<TemperatureThreshold> ret_aidl;
+    ThermalStatus status;
+    ::ndk::ScopedAStatus a_status;
+    if (filterType) {
+        a_status = thermal_service_->getTemperatureThresholdsWithType(
+                static_cast<TemperatureType>(type), &ret_aidl);
+    } else {
+        a_status = thermal_service_->getTemperatureThresholds(&ret_aidl);
+    }
+    if (a_status.isOk()) {
+        std::vector<TemperatureThreshold_2_0> ret;
+        for (const auto& threshold : ret_aidl) {
+            ret.push_back(convertAidlTemperatureThreshold(threshold));
+        }
+        _hidl_cb(status, hidl_vec<TemperatureThreshold_2_0>(ret));
+    } else {
+        setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
+    }
+    return Void();
+}
+
+Return<void> ThermalHidlWrapper::registerThermalChangedCallback(
+        const sp<IThermalChangedCallback_2_0>& callback, bool filterType, TemperatureType_2_0 type,
+        std::function<void(const ThermalStatus&)> _hidl_cb) {
+    if (!thermal_service_) {
+        setInitFailureAndCallback(_hidl_cb);
+    }
+    if (callback == nullptr) {
+        setFailureAndCallback(_hidl_cb, "Invalid nullptr callback");
+        return Void();
+    }
+    std::lock_guard<std::mutex> _lock(callback_wrappers_mutex_);
+    for (const auto& callback_wrapper : callback_wrappers_) {
+        if (::android::hardware::interfacesEqual(callback_wrapper->callback_2_0_.get(),
+                                                 callback.get())) {
+            setFailureAndCallback(_hidl_cb, "The callback was already registered through wrapper");
+            return Void();
+        }
+    }
+    std::shared_ptr<IThermalChangedCallbackWrapper> callback_wrapper =
+            ndk::SharedRefBase::make<IThermalChangedCallbackWrapper>(callback);
+    ::ndk::ScopedAStatus a_status;
+    ThermalStatus status;
+    if (filterType) {
+        a_status = thermal_service_->registerThermalChangedCallbackWithType(
+                callback_wrapper, static_cast<TemperatureType>(type));
+    } else {
+        a_status = thermal_service_->registerThermalChangedCallback(callback_wrapper);
+    }
+    if (a_status.isOk()) {
+        callback_wrappers_.push_back(callback_wrapper);
+        _hidl_cb(status);
+    } else {
+        setFailureAndCallback(_hidl_cb, a_status.getMessage());
+    }
+    return Void();
+}
+
+Return<void> ThermalHidlWrapper::unregisterThermalChangedCallback(
+        const sp<IThermalChangedCallback_2_0>& callback,
+        std::function<void(const ThermalStatus&)> _hidl_cb) {
+    if (!thermal_service_) {
+        setInitFailureAndCallback(_hidl_cb);
+    }
+    if (callback == nullptr) {
+        setFailureAndCallback(_hidl_cb, "Invalid nullptr callback");
+        return Void();
+    }
+    std::lock_guard<std::mutex> _lock(callback_wrappers_mutex_);
+    for (auto it = callback_wrappers_.begin(); it != callback_wrappers_.end(); it++) {
+        auto callback_wrapper = *it;
+        if (::android::hardware::interfacesEqual(callback_wrapper->callback_2_0_.get(),
+                                                 callback.get())) {
+            ::ndk::ScopedAStatus a_status;
+            ThermalStatus status;
+            a_status = thermal_service_->unregisterThermalChangedCallback(callback_wrapper);
+            if (a_status.isOk()) {
+                callback_wrappers_.erase(it);
+                _hidl_cb(status);
+            } else {
+                setFailureAndCallback(_hidl_cb, a_status.getMessage());
+            }
+            return Void();
+        }
+    }
+    setFailureAndCallback(_hidl_cb, "The callback was not registered through wrapper before");
+    return Void();
+}
+
+Return<void> ThermalHidlWrapper::getCurrentCoolingDevices(
+        bool filterType, CoolingType_2_0 type,
+        std::function<void(const ThermalStatus&, const hidl_vec<CoolingDevice_2_0>&)> _hidl_cb) {
+    hidl_vec<CoolingDevice_2_0> ret_2_0;
+    if (!thermal_service_) {
+        setInitFailureAndCallback(_hidl_cb, ret_2_0);
+    }
+
+    std::vector<CoolingDevice> ret_aidl;
+    ThermalStatus status;
+    ::ndk::ScopedAStatus a_status;
+    if (filterType) {
+        a_status = thermal_service_->getCoolingDevicesWithType(static_cast<CoolingType>(type),
+                                                               &ret_aidl);
+    } else {
+        a_status = thermal_service_->getCoolingDevices(&ret_aidl);
+    }
+    if (a_status.isOk()) {
+        std::vector<CoolingDevice_2_0> ret;
+        for (const auto& cooling_device : ret_aidl) {
+            ret.push_back(convertAidlCoolingDevice(cooling_device));
+        }
+        _hidl_cb(status, hidl_vec<CoolingDevice_2_0>(ret));
+    } else {
+        setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
+    }
+    return Void();
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+Return<void> ThermalHidlWrapper::debug(const hidl_handle& handle,
+                                       const hidl_vec<hidl_string>& args) {
+    if (handle != nullptr && handle->numFds >= 1) {
+        int fd = handle->data[0];
+        char** arr = new char*[args.size()];
+        for (size_t i = 0; i < args.size(); i++) {
+            arr[i] = strdup(args[i].c_str());
+        }
+        thermal_service_->dump(fd, (const char**)arr, args.size());
+    }
+    return Void();
+}
+
+::ndk::ScopedAStatus ThermalHidlWrapper::IThermalChangedCallbackWrapper::notifyThrottling(
+        const Temperature& temperature) {
+    callback_2_0_->notifyThrottling(convertAidlTemperature(temperature));
+    return ::ndk::ScopedAStatus::ok();
+}
+
+}  // namespace thermal
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/thermal/utils/include/thermalutils/ThermalHidlWrapper.h b/thermal/utils/include/thermalutils/ThermalHidlWrapper.h
new file mode 100644
index 0000000..1fec100
--- /dev/null
+++ b/thermal/utils/include/thermalutils/ThermalHidlWrapper.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/thermal/BnThermalChangedCallback.h>
+#include <aidl/android/hardware/thermal/IThermal.h>
+#include <android/hardware/thermal/2.0/IThermal.h>
+#include <android/hardware/thermal/2.0/IThermalChangedCallback.h>
+#include <android/hardware/thermal/2.0/types.h>
+#include <hidl/Status.h>
+
+#include <utility>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace thermal {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+
+using IThermal_Aidl = ::aidl::android::hardware::thermal::IThermal;
+using ::android::hardware::thermal::V1_0::CpuUsage;
+using CoolingType_2_0 = ::android::hardware::thermal::V2_0::CoolingType;
+using CoolingDevice_1_0 = ::android::hardware::thermal::V1_0::CoolingDevice;
+using CoolingDevice_2_0 = ::android::hardware::thermal::V2_0::CoolingDevice;
+using IThermal_2_0 = ::android::hardware::thermal::V2_0::IThermal;
+using IThermalChangedCallback_2_0 = ::android::hardware::thermal::V2_0::IThermalChangedCallback;
+using Temperature_1_0 = ::android::hardware::thermal::V1_0::Temperature;
+using Temperature_2_0 = ::android::hardware::thermal::V2_0::Temperature;
+using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType;
+
+using ::android::hardware::thermal::V1_0::ThermalStatus;
+using ::android::hardware::thermal::V1_0::ThermalStatusCode;
+
+using TemperatureThreshold_2_0 = ::android::hardware::thermal::V2_0::TemperatureThreshold;
+using ThrottlingSeverity_2_0 = ::android::hardware::thermal::V2_0::ThrottlingSeverity;
+
+// This wrapper converts all Thermal HIDL 2.0 calls to AIDL calls and converts AIDL response to
+// HIDL 2.0 response.
+//
+// For Thermal HIDL 1.0 calls, it returns unsupported error.
+class ThermalHidlWrapper : public IThermal_2_0 {
+  public:
+    explicit ThermalHidlWrapper(::std::shared_ptr<IThermal_Aidl> thermal_service)
+        : thermal_service_(std::move(thermal_service)) {}
+
+    // Methods from ::android::hardware::thermal::V1_0::IThermal follow.
+    Return<void> getTemperatures(getTemperatures_cb _hidl_cb) override;
+    Return<void> getCpuUsages(getCpuUsages_cb _hidl_cb) override;
+    Return<void> getCoolingDevices(getCoolingDevices_cb _hidl_cb) override;
+
+    // Methods from ::android::hardware::thermal::V2_0::IThermal follow.
+    Return<void> getCurrentTemperatures(bool filterType, TemperatureType_2_0 type,
+                                        getCurrentTemperatures_cb _hidl_cb) override;
+    Return<void> getTemperatureThresholds(bool filterType, TemperatureType_2_0 type,
+                                          getTemperatureThresholds_cb _hidl_cb) override;
+    Return<void> registerThermalChangedCallback(
+            const sp<IThermalChangedCallback_2_0>& callback, bool filterType,
+            TemperatureType_2_0 type, registerThermalChangedCallback_cb _hidl_cb) override;
+    Return<void> unregisterThermalChangedCallback(
+            const sp<IThermalChangedCallback_2_0>& callback,
+            unregisterThermalChangedCallback_cb _hidl_cb) override;
+    Return<void> getCurrentCoolingDevices(bool filterType, CoolingType_2_0 type,
+                                          getCurrentCoolingDevices_cb _hidl_cb) override;
+
+    // Methods from ::android::hidl::base::V1_0::IBase follow.
+    Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& args) override;
+
+  private:
+    class IThermalChangedCallbackWrapper : public BnThermalChangedCallback {
+      public:
+        explicit IThermalChangedCallbackWrapper(const sp<IThermalChangedCallback_2_0>& callback_2_0)
+            : callback_2_0_(callback_2_0) {}
+        ::ndk::ScopedAStatus notifyThrottling(const Temperature& temperature) override;
+        sp<IThermalChangedCallback_2_0> callback_2_0_;
+    };
+
+    // Reference to thermal service.
+    ::std::shared_ptr<IThermal_Aidl> thermal_service_;
+    // Mutex lock for read/write on callback wrappers.
+    std::mutex callback_wrappers_mutex_;
+    // All thermal changed callback wrappers registered.
+    ::std::vector<std::shared_ptr<IThermalChangedCallbackWrapper>> callback_wrappers_;
+};
+
+}  // namespace thermal
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/thermal/utils/tests/Android.bp b/thermal/utils/tests/Android.bp
new file mode 100644
index 0000000..fd74e8b
--- /dev/null
+++ b/thermal/utils/tests/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "ThermalHidlWrapperTest",
+    srcs: ["ThermalHidlWrapperTest.cpp"],
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "android.hardware.thermal@1.0",
+        "android.hardware.thermal@2.0",
+        "android.hardware.thermal-V1-ndk",
+    ],
+    static_libs: [
+        "libthermalutils",
+        "libgtest",
+    ],
+    test_suites: [
+        "device-tests",
+    ],
+}
diff --git a/thermal/utils/tests/ThermalHidlWrapperTest.cpp b/thermal/utils/tests/ThermalHidlWrapperTest.cpp
new file mode 100644
index 0000000..1723a1a
--- /dev/null
+++ b/thermal/utils/tests/ThermalHidlWrapperTest.cpp
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "thermal_hidl_wrapper_test"
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/thermal/BnThermal.h>
+#include <aidl/android/hardware/thermal/BnThermalChangedCallback.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_status.h>
+#include <android/hardware/thermal/2.0/IThermal.h>
+#include <android/hardware/thermal/2.0/IThermalChangedCallback.h>
+#include <android/hardware/thermal/2.0/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <thermalutils/ThermalHidlWrapper.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <chrono>
+#include <cmath>
+#include <memory>
+#include <string>
+#include <thread>
+#include <vector>
+
+namespace aidl::android::hardware::thermal {
+
+namespace {
+
+using ::android::sp;
+using ::android::hardware::hidl_enum_range;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using ::android::hardware::thermal::V1_0::ThermalStatus;
+using ::android::hardware::thermal::V1_0::ThermalStatusCode;
+using ::android::hardware::thermal::V2_0::CoolingDevice;
+using ::android::hardware::thermal::V2_0::CoolingType;
+using IThermal_2_0 = ::android::hardware::thermal::V2_0::IThermal;
+using ::android::hardware::thermal::V2_0::IThermalChangedCallback;
+using ::android::hardware::thermal::V2_0::Temperature;
+using ::android::hardware::thermal::V2_0::TemperatureThreshold;
+using ::android::hardware::thermal::V2_0::TemperatureType;
+using ::android::hardware::thermal::V2_0::ThrottlingSeverity;
+
+constexpr char kCallbackNameNotifyThrottling[] = "notifyThrottling";
+static const Temperature kThrottleTemp = {
+        .type = TemperatureType::SKIN,
+        .name = "test temperature sensor",
+        .value = 98.6,
+        .throttlingStatus = ThrottlingSeverity::CRITICAL,
+};
+
+class ThermalCallbackArgs {
+  public:
+    Temperature temperature;
+};
+
+// Callback class for receiving thermal event notifications from main class
+class ThermalCallback : public ::testing::VtsHalHidlTargetCallbackBase<ThermalCallbackArgs>,
+                        public IThermalChangedCallback {
+  public:
+    Return<void> notifyThrottling(const Temperature& temperature) override {
+        ThermalCallbackArgs args;
+        args.temperature = temperature;
+        NotifyFromCallback(kCallbackNameNotifyThrottling, args);
+        return Void();
+    }
+};
+
+// The main test class for THERMAL HIDL HAL 2.0.
+class ThermalHidlWrapperTest : public ::testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+        ASSERT_NE(binder, nullptr);
+        mThermal = sp<ThermalHidlWrapper>::make(IThermal::fromBinder(ndk::SpAIBinder(binder)));
+        ASSERT_NE(mThermal, nullptr);
+        mThermalCallback = new (std::nothrow) ThermalCallback();
+        ASSERT_NE(mThermalCallback, nullptr);
+        auto ret = mThermal->registerThermalChangedCallback(
+                mThermalCallback, false, TemperatureType::SKIN,
+                [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+        ASSERT_TRUE(ret.isOk());
+        // Expect to fail if register again
+        ret = mThermal->registerThermalChangedCallback(
+                mThermalCallback, false, TemperatureType::SKIN,
+                [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    void TearDown() override {
+        auto ret = mThermal->unregisterThermalChangedCallback(
+                mThermalCallback,
+                [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+        ASSERT_TRUE(ret.isOk());
+        // Expect to fail if unregister again
+        ret = mThermal->unregisterThermalChangedCallback(
+                mThermalCallback,
+                [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+        ASSERT_TRUE(ret.isOk());
+    }
+
+  protected:
+    sp<IThermal_2_0> mThermal;
+    sp<ThermalCallback> mThermalCallback;
+};  // class ThermalHidlWrapperTest
+
+// Test ThermalChangedCallback::notifyThrottling().
+// This just calls into and back from our local ThermalChangedCallback impl.
+TEST_P(ThermalHidlWrapperTest, NotifyThrottlingTest) {
+    sp<ThermalCallback> thermalCallback = new (std::nothrow) ThermalCallback();
+    auto ret = thermalCallback->notifyThrottling(kThrottleTemp);
+    ASSERT_TRUE(ret.isOk());
+    auto res = thermalCallback->WaitForCallback(kCallbackNameNotifyThrottling);
+    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.args);
+    EXPECT_EQ(kThrottleTemp, res.args->temperature);
+}
+
+// Test Thermal->registerThermalChangedCallback.
+TEST_P(ThermalHidlWrapperTest, RegisterThermalChangedCallbackTest) {
+    // Expect to fail with same callback
+    auto ret = mThermal->registerThermalChangedCallback(
+            mThermalCallback, false, TemperatureType::SKIN,
+            [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); });
+    ASSERT_TRUE(ret.isOk());
+    // Expect to fail with null callback
+    ret = mThermal->registerThermalChangedCallback(
+            nullptr, false, TemperatureType::SKIN,
+            [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); });
+    ASSERT_TRUE(ret.isOk());
+    sp<ThermalCallback> localThermalCallback = new (std::nothrow) ThermalCallback();
+    // Expect to succeed with different callback
+    ret = mThermal->registerThermalChangedCallback(
+            localThermalCallback, false, TemperatureType::SKIN,
+            [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+    ASSERT_TRUE(ret.isOk());
+    // Remove the local callback
+    ret = mThermal->unregisterThermalChangedCallback(
+            localThermalCallback,
+            [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+    ASSERT_TRUE(ret.isOk());
+    // Expect to fail with null callback
+    ret = mThermal->unregisterThermalChangedCallback(nullptr, [](ThermalStatus status) {
+        EXPECT_EQ(ThermalStatusCode::FAILURE, status.code);
+    });
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Test Thermal->unregisterThermalChangedCallback.
+TEST_P(ThermalHidlWrapperTest, UnregisterThermalChangedCallbackTest) {
+    sp<ThermalCallback> localThermalCallback = new (std::nothrow) ThermalCallback();
+    // Expect to fail as the callback was not registered before
+    auto ret = mThermal->unregisterThermalChangedCallback(
+            localThermalCallback,
+            [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+    ASSERT_TRUE(ret.isOk());
+    // Register a local callback
+    ret = mThermal->registerThermalChangedCallback(
+            localThermalCallback, false, TemperatureType::SKIN,
+            [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+    ASSERT_TRUE(ret.isOk());
+    // Expect to succeed with callback removed
+    ret = mThermal->unregisterThermalChangedCallback(
+            localThermalCallback,
+            [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+    ASSERT_TRUE(ret.isOk());
+    // Expect to fail as the callback has been unregistered already
+    ret = mThermal->unregisterThermalChangedCallback(
+            localThermalCallback,
+            [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Sanity test for Thermal::getCurrentTemperatures().
+TEST_P(ThermalHidlWrapperTest, TemperatureTest) {
+    mThermal->getCurrentTemperatures(false, TemperatureType::SKIN,
+                                     [](ThermalStatus status, hidl_vec<Temperature> temperatures) {
+                                         if (temperatures.size()) {
+                                             EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+                                         } else {
+                                             EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+                                         }
+                                         for (int i = 0; i < temperatures.size(); ++i) {
+                                             EXPECT_LT(0u, temperatures[i].name.size());
+                                         }
+                                     });
+    auto types = hidl_enum_range<TemperatureType>();
+    for (const auto& type : types) {
+        mThermal->getCurrentTemperatures(
+                true, type, [&type](ThermalStatus status, hidl_vec<Temperature> temperatures) {
+                    if (temperatures.size()) {
+                        EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+                    } else {
+                        EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+                    }
+                    for (int i = 0; i < temperatures.size(); ++i) {
+                        EXPECT_EQ(type, temperatures[i].type);
+                        EXPECT_LT(0u, temperatures[i].name.size());
+                    }
+                });
+    }
+}
+
+// Sanity test for Thermal::getTemperatureThresholds().
+TEST_P(ThermalHidlWrapperTest, TemperatureThresholdTest) {
+    mThermal->getTemperatureThresholds(
+            false, TemperatureType::SKIN,
+            [](ThermalStatus status, hidl_vec<TemperatureThreshold> temperatures) {
+                if (temperatures.size()) {
+                    EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+                } else {
+                    EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+                }
+            });
+    for (int i = static_cast<int>(TemperatureType::UNKNOWN);
+         i <= static_cast<int>(TemperatureType::POWER_AMPLIFIER); ++i) {
+        auto type = static_cast<TemperatureType>(i);
+        mThermal->getTemperatureThresholds(
+                true, type,
+                [&type](ThermalStatus status, hidl_vec<TemperatureThreshold> temperatures) {
+                    if (temperatures.size()) {
+                        EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+                    } else {
+                        EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+                    }
+                    for (int i = 0; i < temperatures.size(); ++i) {
+                        EXPECT_EQ(type, temperatures[i].type);
+                    }
+                });
+    }
+}
+
+// Sanity test for Thermal::getCurrentCoolingDevices().
+TEST_P(ThermalHidlWrapperTest, CoolingDeviceTest) {
+    mThermal->getCurrentCoolingDevices(
+            false, CoolingType::CPU,
+            [](ThermalStatus status, hidl_vec<CoolingDevice> cooling_devices) {
+                if (cooling_devices.size()) {
+                    EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+                } else {
+                    EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+                }
+                for (int i = 0; i < cooling_devices.size(); ++i) {
+                    EXPECT_LT(0u, cooling_devices[i].name.size());
+                }
+            });
+    for (int i = 0; i <= static_cast<int>(CoolingType::COMPONENT); ++i) {
+        auto type = static_cast<CoolingType>(i);
+        mThermal->getCurrentCoolingDevices(
+                true, type, [&type](ThermalStatus status, hidl_vec<CoolingDevice> cooling_devices) {
+                    if (cooling_devices.size()) {
+                        EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+                    } else {
+                        EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+                    }
+                    for (int i = 0; i < cooling_devices.size(); ++i) {
+                        EXPECT_EQ(type, cooling_devices[i].type);
+                        EXPECT_LT(0u, cooling_devices[i].name.size());
+                    }
+                });
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThermalHidlWrapperTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, ThermalHidlWrapperTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IThermal::descriptor)),
+        ::android::hardware::PrintInstanceNameToString);
+
+}  // namespace
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
+
+}  // namespace aidl::android::hardware::thermal
diff --git a/threadnetwork/OWNERS b/threadnetwork/OWNERS
new file mode 100644
index 0000000..54fd66d
--- /dev/null
+++ b/threadnetwork/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1288834
+
+include platform/packages/modules/ThreadNetwork:/OWNERS
diff --git a/tv/README.md b/tv/README.md
new file mode 100644
index 0000000..9a1c381
--- /dev/null
+++ b/tv/README.md
@@ -0,0 +1,8 @@
+# TV-related HIDL and AIDL HALs
+
+This directory bundles TV-related HALs in HIDL (legacy) and AIDL.
+
+- The 'tuner' directory contains the Tuner HIDL and AIDL HALs.
+- The 'input' directory contains the TV Input HIDL and AIDL HALs.
+- The 'cec' directory contains the CEC HIDL HAL.
+- The 'hdmi' directory contains the HDMI-related AIDL HALs, which includes the CEC AIDL HAL.
diff --git a/tv/cec/1.0/default/HdmiCec.cpp b/tv/cec/1.0/default/HdmiCec.cpp
index 74de785..f05f610 100644
--- a/tv/cec/1.0/default/HdmiCec.cpp
+++ b/tv/cec/1.0/default/HdmiCec.cpp
@@ -307,6 +307,9 @@
 }
 
 Return<SendMessageResult> HdmiCec::sendMessage(const CecMessage& message) {
+    if (message.body.size() > CEC_MESSAGE_BODY_MAX_LENGTH) {
+        return SendMessageResult::FAIL;
+    }
     cec_message_t legacyMessage {
         .initiator = static_cast<cec_logical_address_t>(message.initiator),
         .destination = static_cast<cec_logical_address_t>(message.destination),
diff --git a/tv/cec/1.0/default/HdmiCecDefault.cpp b/tv/cec/1.0/default/HdmiCecDefault.cpp
index 26ccb7d..2a5197c 100644
--- a/tv/cec/1.0/default/HdmiCecDefault.cpp
+++ b/tv/cec/1.0/default/HdmiCecDefault.cpp
@@ -278,6 +278,10 @@
 
 Return<bool> HdmiCecDefault::isConnected(int32_t portId) {
     uint16_t addr;
+    if (portId < 0 || portId >= mHdmiCecPorts.size()) {
+        LOG(ERROR) << "Port id is out of bounds, portId = " << portId;
+        return false;
+    }
     int ret = ioctl(mHdmiCecPorts[portId]->mCecFd, CEC_ADAP_G_PHYS_ADDR, &addr);
     if (ret) {
         LOG(ERROR) << "Is connected failed, Error = " << strerror(errno);
diff --git a/tv/hdmi/OWNERS b/tv/hdmi/OWNERS
new file mode 100644
index 0000000..d9c6783
--- /dev/null
+++ b/tv/hdmi/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 826094
+include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS
\ No newline at end of file
diff --git a/tv/hdmi/README.md b/tv/hdmi/README.md
new file mode 100644
index 0000000..183a3d0
--- /dev/null
+++ b/tv/hdmi/README.md
@@ -0,0 +1,11 @@
+# HDMI-related AIDL HALs for Android devices
+
+This directory bundles 3 HDMI-related AIDL HALs: HDMI Connection HAL, CEC HAL and eARC HAL.
+
+The HDMI Connection HAL contains general APIs for the HDMI Connection. These methods are required by
+the CEC and the eARC implementation. Therefore, devices that implement CEC need to support the HDMI
+Connection HAL and the CEC HAL. Devices that implement eARC need to support the HDMI Connection HAL
+and the eARC HAL.
+
+Other Android HALs are related to HDMI as well, but not included in this directory for historical
+reasons, e.g. Display HAL and TV Input HAL.
diff --git a/tv/hdmi/cec/aidl/Android.bp b/tv/hdmi/cec/aidl/Android.bp
new file mode 100644
index 0000000..53cb5a9
--- /dev/null
+++ b/tv/hdmi/cec/aidl/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.tv.hdmi.cec",
+    vendor_available: true,
+    srcs: ["android/hardware/tv/hdmi/cec/*.aidl"],
+    stability: "vintf",
+    backend: {
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/tv/hdmi/cec/aidl/TEST_MAPPING b/tv/hdmi/cec/aidl/TEST_MAPPING
new file mode 100644
index 0000000..17d6bca
--- /dev/null
+++ b/tv/hdmi/cec/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalTvHdmiCecAidlTargetTest"
+    }
+  ]
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/.hash b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/.hash
new file mode 100644
index 0000000..8a30199
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/.hash
@@ -0,0 +1 @@
+cd956e3a0c2e6ade71693c85e9f0aeffa221ea26
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/AbortReason.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/AbortReason.aidl
new file mode 100644
index 0000000..45b973a
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/AbortReason.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="int") @VintfStability
+enum AbortReason {
+  UNRECOGNIZED_MODE = 0,
+  NOT_IN_CORRECT_MODE = 1,
+  CANNOT_PROVIDE_SOURCE = 2,
+  INVALID_OPERAND = 3,
+  REFUSED = 4,
+  UNABLE_TO_DETERMINE = 5,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecDeviceType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
new file mode 100644
index 0000000..4f7e247
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="byte") @VintfStability
+enum CecDeviceType {
+  INACTIVE = (-1) /* -1 */,
+  TV = 0,
+  RECORDER = 1,
+  TUNER = 3,
+  PLAYBACK = 4,
+  AUDIO_SYSTEM = 5,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
new file mode 100644
index 0000000..1fc9fb7
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="byte") @VintfStability
+enum CecLogicalAddress {
+  TV = 0,
+  RECORDER_1 = 1,
+  RECORDER_2 = 2,
+  TUNER_1 = 3,
+  PLAYBACK_1 = 4,
+  AUDIO_SYSTEM = 5,
+  TUNER_2 = 6,
+  TUNER_3 = 7,
+  PLAYBACK_2 = 8,
+  RECORDER_3 = 9,
+  TUNER_4 = 10,
+  PLAYBACK_3 = 11,
+  BACKUP_1 = 12,
+  BACKUP_2 = 13,
+  FREE_USE = 14,
+  BROADCAST = 15,
+  UNREGISTERED = 15,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecMessage.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecMessage.aidl
new file mode 100644
index 0000000..9de07ec
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecMessage.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@VintfStability
+parcelable CecMessage {
+  android.hardware.tv.hdmi.cec.CecLogicalAddress initiator;
+  android.hardware.tv.hdmi.cec.CecLogicalAddress destination;
+  byte[] body;
+  const int MAX_MESSAGE_BODY_LENGTH = 15;
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecMessageType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecMessageType.aidl
new file mode 100644
index 0000000..20472f0
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/CecMessageType.aidl
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="int") @VintfStability
+enum CecMessageType {
+  FEATURE_ABORT = 0x00,
+  IMAGE_VIEW_ON = 0x04,
+  TUNER_STEP_INCREMENT = 0x05,
+  TUNER_STEP_DECREMENT = 0x06,
+  TUNER_DEVICE_STATUS = 0x07,
+  GIVE_TUNER_DEVICE_STATUS = 0x08,
+  RECORD_ON = 0x09,
+  RECORD_STATUS = 0x0A,
+  RECORD_OFF = 0x0B,
+  TEXT_VIEW_ON = 0x0D,
+  RECORD_TV_SCREEN = 0x0F,
+  GIVE_DECK_STATUS = 0x1A,
+  DECK_STATUS = 0x1B,
+  SET_MENU_LANGUAGE = 0x32,
+  CLEAR_ANALOG_TIMER = 0x33,
+  SET_ANALOG_TIMER = 0x34,
+  TIMER_STATUS = 0x35,
+  STANDBY = 0x36,
+  PLAY = 0x41,
+  DECK_CONTROL = 0x42,
+  TIMER_CLEARED_STATUS = 0x43,
+  USER_CONTROL_PRESSED = 0x44,
+  USER_CONTROL_RELEASED = 0x45,
+  GIVE_OSD_NAME = 0x46,
+  SET_OSD_NAME = 0x47,
+  SET_OSD_STRING = 0x64,
+  SET_TIMER_PROGRAM_TITLE = 0x67,
+  SYSTEM_AUDIO_MODE_REQUEST = 0x70,
+  GIVE_AUDIO_STATUS = 0x71,
+  SET_SYSTEM_AUDIO_MODE = 0x72,
+  REPORT_AUDIO_STATUS = 0x7A,
+  GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D,
+  SYSTEM_AUDIO_MODE_STATUS = 0x7E,
+  ROUTING_CHANGE = 0x80,
+  ROUTING_INFORMATION = 0x81,
+  ACTIVE_SOURCE = 0x82,
+  GIVE_PHYSICAL_ADDRESS = 0x83,
+  REPORT_PHYSICAL_ADDRESS = 0x84,
+  REQUEST_ACTIVE_SOURCE = 0x85,
+  SET_STREAM_PATH = 0x86,
+  DEVICE_VENDOR_ID = 0x87,
+  VENDOR_COMMAND = 0x89,
+  VENDOR_REMOTE_BUTTON_DOWN = 0x8A,
+  VENDOR_REMOTE_BUTTON_UP = 0x8B,
+  GIVE_DEVICE_VENDOR_ID = 0x8C,
+  MENU_REQUEST = 0x8D,
+  MENU_STATUS = 0x8E,
+  GIVE_DEVICE_POWER_STATUS = 0x8F,
+  REPORT_POWER_STATUS = 0x90,
+  GET_MENU_LANGUAGE = 0x91,
+  SELECT_ANALOG_SERVICE = 0x92,
+  SELECT_DIGITAL_SERVICE = 0x93,
+  SET_DIGITAL_TIMER = 0x97,
+  CLEAR_DIGITAL_TIMER = 0x99,
+  SET_AUDIO_RATE = 0x9A,
+  INACTIVE_SOURCE = 0x9D,
+  CEC_VERSION = 0x9E,
+  GET_CEC_VERSION = 0x9F,
+  VENDOR_COMMAND_WITH_ID = 0xA0,
+  CLEAR_EXTERNAL_TIMER = 0xA1,
+  SET_EXTERNAL_TIMER = 0xA2,
+  REPORT_SHORT_AUDIO_DESCRIPTOR = 0xA3,
+  REQUEST_SHORT_AUDIO_DESCRIPTOR = 0xA4,
+  INITIATE_ARC = 0xC0,
+  REPORT_ARC_INITIATED = 0xC1,
+  REPORT_ARC_TERMINATED = 0xC2,
+  REQUEST_ARC_INITIATION = 0xC3,
+  REQUEST_ARC_TERMINATION = 0xC4,
+  TERMINATE_ARC = 0xC5,
+  ABORT = 0xFF,
+  GIVE_FEATURES = 0xA5,
+  REPORT_FEATURES = 0xA6,
+  REQUEST_CURRENT_LATENCY = 0xA7,
+  REPORT_CURRENT_LATENCY = 0xA8,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/IHdmiCec.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
new file mode 100644
index 0000000..c6060d1
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@VintfStability
+interface IHdmiCec {
+  android.hardware.tv.hdmi.cec.Result addLogicalAddress(in android.hardware.tv.hdmi.cec.CecLogicalAddress addr);
+  void clearLogicalAddress();
+  void enableAudioReturnChannel(in int portId, in boolean enable);
+  int getCecVersion();
+  int getPhysicalAddress();
+  int getVendorId();
+  android.hardware.tv.hdmi.cec.SendMessageResult sendMessage(in android.hardware.tv.hdmi.cec.CecMessage message);
+  void setCallback(in @nullable android.hardware.tv.hdmi.cec.IHdmiCecCallback callback);
+  void setLanguage(in String language);
+  void enableWakeupByOtp(in boolean value);
+  void enableCec(in boolean value);
+  void enableSystemCecControl(in boolean value);
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
new file mode 100644
index 0000000..43fdfbd
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@VintfStability
+interface IHdmiCecCallback {
+  oneway void onCecMessage(in android.hardware.tv.hdmi.cec.CecMessage message);
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/Result.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/Result.aidl
new file mode 100644
index 0000000..c6828ef
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/Result.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="byte") @VintfStability
+enum Result {
+  SUCCESS = 0,
+  FAILURE_UNKNOWN = 1,
+  FAILURE_INVALID_ARGS = 2,
+  FAILURE_INVALID_STATE = 3,
+  FAILURE_NOT_SUPPORTED = 4,
+  FAILURE_BUSY = 5,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/SendMessageResult.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
new file mode 100644
index 0000000..87b50c9
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/1/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="byte") @VintfStability
+enum SendMessageResult {
+  SUCCESS = 0,
+  NACK = 1,
+  BUSY = 2,
+  FAIL = 3,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/AbortReason.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/AbortReason.aidl
new file mode 100644
index 0000000..45b973a
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/AbortReason.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="int") @VintfStability
+enum AbortReason {
+  UNRECOGNIZED_MODE = 0,
+  NOT_IN_CORRECT_MODE = 1,
+  CANNOT_PROVIDE_SOURCE = 2,
+  INVALID_OPERAND = 3,
+  REFUSED = 4,
+  UNABLE_TO_DETERMINE = 5,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
new file mode 100644
index 0000000..4f7e247
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="byte") @VintfStability
+enum CecDeviceType {
+  INACTIVE = (-1) /* -1 */,
+  TV = 0,
+  RECORDER = 1,
+  TUNER = 3,
+  PLAYBACK = 4,
+  AUDIO_SYSTEM = 5,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
new file mode 100644
index 0000000..1fc9fb7
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="byte") @VintfStability
+enum CecLogicalAddress {
+  TV = 0,
+  RECORDER_1 = 1,
+  RECORDER_2 = 2,
+  TUNER_1 = 3,
+  PLAYBACK_1 = 4,
+  AUDIO_SYSTEM = 5,
+  TUNER_2 = 6,
+  TUNER_3 = 7,
+  PLAYBACK_2 = 8,
+  RECORDER_3 = 9,
+  TUNER_4 = 10,
+  PLAYBACK_3 = 11,
+  BACKUP_1 = 12,
+  BACKUP_2 = 13,
+  FREE_USE = 14,
+  BROADCAST = 15,
+  UNREGISTERED = 15,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessage.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessage.aidl
new file mode 100644
index 0000000..9de07ec
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessage.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@VintfStability
+parcelable CecMessage {
+  android.hardware.tv.hdmi.cec.CecLogicalAddress initiator;
+  android.hardware.tv.hdmi.cec.CecLogicalAddress destination;
+  byte[] body;
+  const int MAX_MESSAGE_BODY_LENGTH = 15;
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
new file mode 100644
index 0000000..20472f0
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/CecMessageType.aidl
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="int") @VintfStability
+enum CecMessageType {
+  FEATURE_ABORT = 0x00,
+  IMAGE_VIEW_ON = 0x04,
+  TUNER_STEP_INCREMENT = 0x05,
+  TUNER_STEP_DECREMENT = 0x06,
+  TUNER_DEVICE_STATUS = 0x07,
+  GIVE_TUNER_DEVICE_STATUS = 0x08,
+  RECORD_ON = 0x09,
+  RECORD_STATUS = 0x0A,
+  RECORD_OFF = 0x0B,
+  TEXT_VIEW_ON = 0x0D,
+  RECORD_TV_SCREEN = 0x0F,
+  GIVE_DECK_STATUS = 0x1A,
+  DECK_STATUS = 0x1B,
+  SET_MENU_LANGUAGE = 0x32,
+  CLEAR_ANALOG_TIMER = 0x33,
+  SET_ANALOG_TIMER = 0x34,
+  TIMER_STATUS = 0x35,
+  STANDBY = 0x36,
+  PLAY = 0x41,
+  DECK_CONTROL = 0x42,
+  TIMER_CLEARED_STATUS = 0x43,
+  USER_CONTROL_PRESSED = 0x44,
+  USER_CONTROL_RELEASED = 0x45,
+  GIVE_OSD_NAME = 0x46,
+  SET_OSD_NAME = 0x47,
+  SET_OSD_STRING = 0x64,
+  SET_TIMER_PROGRAM_TITLE = 0x67,
+  SYSTEM_AUDIO_MODE_REQUEST = 0x70,
+  GIVE_AUDIO_STATUS = 0x71,
+  SET_SYSTEM_AUDIO_MODE = 0x72,
+  REPORT_AUDIO_STATUS = 0x7A,
+  GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D,
+  SYSTEM_AUDIO_MODE_STATUS = 0x7E,
+  ROUTING_CHANGE = 0x80,
+  ROUTING_INFORMATION = 0x81,
+  ACTIVE_SOURCE = 0x82,
+  GIVE_PHYSICAL_ADDRESS = 0x83,
+  REPORT_PHYSICAL_ADDRESS = 0x84,
+  REQUEST_ACTIVE_SOURCE = 0x85,
+  SET_STREAM_PATH = 0x86,
+  DEVICE_VENDOR_ID = 0x87,
+  VENDOR_COMMAND = 0x89,
+  VENDOR_REMOTE_BUTTON_DOWN = 0x8A,
+  VENDOR_REMOTE_BUTTON_UP = 0x8B,
+  GIVE_DEVICE_VENDOR_ID = 0x8C,
+  MENU_REQUEST = 0x8D,
+  MENU_STATUS = 0x8E,
+  GIVE_DEVICE_POWER_STATUS = 0x8F,
+  REPORT_POWER_STATUS = 0x90,
+  GET_MENU_LANGUAGE = 0x91,
+  SELECT_ANALOG_SERVICE = 0x92,
+  SELECT_DIGITAL_SERVICE = 0x93,
+  SET_DIGITAL_TIMER = 0x97,
+  CLEAR_DIGITAL_TIMER = 0x99,
+  SET_AUDIO_RATE = 0x9A,
+  INACTIVE_SOURCE = 0x9D,
+  CEC_VERSION = 0x9E,
+  GET_CEC_VERSION = 0x9F,
+  VENDOR_COMMAND_WITH_ID = 0xA0,
+  CLEAR_EXTERNAL_TIMER = 0xA1,
+  SET_EXTERNAL_TIMER = 0xA2,
+  REPORT_SHORT_AUDIO_DESCRIPTOR = 0xA3,
+  REQUEST_SHORT_AUDIO_DESCRIPTOR = 0xA4,
+  INITIATE_ARC = 0xC0,
+  REPORT_ARC_INITIATED = 0xC1,
+  REPORT_ARC_TERMINATED = 0xC2,
+  REQUEST_ARC_INITIATION = 0xC3,
+  REQUEST_ARC_TERMINATION = 0xC4,
+  TERMINATE_ARC = 0xC5,
+  ABORT = 0xFF,
+  GIVE_FEATURES = 0xA5,
+  REPORT_FEATURES = 0xA6,
+  REQUEST_CURRENT_LATENCY = 0xA7,
+  REPORT_CURRENT_LATENCY = 0xA8,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
new file mode 100644
index 0000000..c6060d1
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@VintfStability
+interface IHdmiCec {
+  android.hardware.tv.hdmi.cec.Result addLogicalAddress(in android.hardware.tv.hdmi.cec.CecLogicalAddress addr);
+  void clearLogicalAddress();
+  void enableAudioReturnChannel(in int portId, in boolean enable);
+  int getCecVersion();
+  int getPhysicalAddress();
+  int getVendorId();
+  android.hardware.tv.hdmi.cec.SendMessageResult sendMessage(in android.hardware.tv.hdmi.cec.CecMessage message);
+  void setCallback(in @nullable android.hardware.tv.hdmi.cec.IHdmiCecCallback callback);
+  void setLanguage(in String language);
+  void enableWakeupByOtp(in boolean value);
+  void enableCec(in boolean value);
+  void enableSystemCecControl(in boolean value);
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
new file mode 100644
index 0000000..43fdfbd
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@VintfStability
+interface IHdmiCecCallback {
+  oneway void onCecMessage(in android.hardware.tv.hdmi.cec.CecMessage message);
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/Result.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/Result.aidl
new file mode 100644
index 0000000..c6828ef
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/Result.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="byte") @VintfStability
+enum Result {
+  SUCCESS = 0,
+  FAILURE_UNKNOWN = 1,
+  FAILURE_INVALID_ARGS = 2,
+  FAILURE_INVALID_STATE = 3,
+  FAILURE_NOT_SUPPORTED = 4,
+  FAILURE_BUSY = 5,
+}
diff --git a/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/SendMessageResult.aidl b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
new file mode 100644
index 0000000..87b50c9
--- /dev/null
+++ b/tv/hdmi/cec/aidl/aidl_api/android.hardware.tv.hdmi.cec/current/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.cec;
+@Backing(type="byte") @VintfStability
+enum SendMessageResult {
+  SUCCESS = 0,
+  NACK = 1,
+  BUSY = 2,
+  FAIL = 3,
+}
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/AbortReason.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/AbortReason.aidl
new file mode 100644
index 0000000..297094d
--- /dev/null
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/AbortReason.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.cec;
+
+/**
+ * Operand description [Abort Reason]
+ */
+@VintfStability
+@Backing(type="int")
+enum AbortReason {
+    UNRECOGNIZED_MODE = 0,
+    NOT_IN_CORRECT_MODE = 1,
+    CANNOT_PROVIDE_SOURCE = 2,
+    INVALID_OPERAND = 3,
+    REFUSED = 4,
+    UNABLE_TO_DETERMINE = 5,
+}
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecDeviceType.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
new file mode 100644
index 0000000..8727a1d
--- /dev/null
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecDeviceType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.cec;
+
+@VintfStability
+@Backing(type="byte")
+enum CecDeviceType {
+    INACTIVE = -1,
+    TV = 0,
+    RECORDER = 1,
+    TUNER = 3,
+    PLAYBACK = 4,
+    AUDIO_SYSTEM = 5,
+}
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
new file mode 100644
index 0000000..e7e08a6
--- /dev/null
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecLogicalAddress.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.cec;
+
+@VintfStability
+@Backing(type="byte")
+enum CecLogicalAddress {
+    TV = 0,
+    RECORDER_1 = 1,
+    RECORDER_2 = 2,
+    TUNER_1 = 3,
+    PLAYBACK_1 = 4,
+    AUDIO_SYSTEM = 5,
+    TUNER_2 = 6,
+    TUNER_3 = 7,
+    PLAYBACK_2 = 8,
+    RECORDER_3 = 9,
+    TUNER_4 = 10,
+    PLAYBACK_3 = 11,
+    BACKUP_1 = 12,
+    BACKUP_2 = 13,
+    FREE_USE = 14,
+    BROADCAST = 15,
+    UNREGISTERED = 15,
+}
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessage.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessage.aidl
new file mode 100644
index 0000000..14a1bc7
--- /dev/null
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessage.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.cec;
+
+import android.hardware.tv.hdmi.cec.CecLogicalAddress;
+
+@VintfStability
+parcelable CecMessage {
+    /**
+     * Maximum length of the message body
+     */
+    const int MAX_MESSAGE_BODY_LENGTH = 15;
+    /**
+     * logical address of the initiator
+     */
+    CecLogicalAddress initiator;
+    /**
+     * logical address of destination
+     */
+    CecLogicalAddress destination;
+    /**
+     * The maximum size of body is 15 (MAX_MESSAGE_BODY_LENGTH) as specified in
+     * the section 6 of the CEC Spec 1.4b. Overflowed data must be ignored.
+     */
+    byte[] body;
+}
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessageType.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessageType.aidl
new file mode 100644
index 0000000..becfea1
--- /dev/null
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/CecMessageType.aidl
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.cec;
+
+@VintfStability
+@Backing(type="int")
+enum CecMessageType {
+    FEATURE_ABORT = 0x00,
+    IMAGE_VIEW_ON = 0x04,
+    TUNER_STEP_INCREMENT = 0x05,
+    TUNER_STEP_DECREMENT = 0x06,
+    TUNER_DEVICE_STATUS = 0x07,
+    GIVE_TUNER_DEVICE_STATUS = 0x08,
+    RECORD_ON = 0x09,
+    RECORD_STATUS = 0x0A,
+    RECORD_OFF = 0x0B,
+    TEXT_VIEW_ON = 0x0D,
+    RECORD_TV_SCREEN = 0x0F,
+    GIVE_DECK_STATUS = 0x1A,
+    DECK_STATUS = 0x1B,
+    SET_MENU_LANGUAGE = 0x32,
+    CLEAR_ANALOG_TIMER = 0x33,
+    SET_ANALOG_TIMER = 0x34,
+    TIMER_STATUS = 0x35,
+    STANDBY = 0x36,
+    PLAY = 0x41,
+    DECK_CONTROL = 0x42,
+    TIMER_CLEARED_STATUS = 0x43,
+    USER_CONTROL_PRESSED = 0x44,
+    USER_CONTROL_RELEASED = 0x45,
+    GIVE_OSD_NAME = 0x46,
+    SET_OSD_NAME = 0x47,
+    SET_OSD_STRING = 0x64,
+    SET_TIMER_PROGRAM_TITLE = 0x67,
+    SYSTEM_AUDIO_MODE_REQUEST = 0x70,
+    GIVE_AUDIO_STATUS = 0x71,
+    SET_SYSTEM_AUDIO_MODE = 0x72,
+    REPORT_AUDIO_STATUS = 0x7A,
+    GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D,
+    SYSTEM_AUDIO_MODE_STATUS = 0x7E,
+    ROUTING_CHANGE = 0x80,
+    ROUTING_INFORMATION = 0x81,
+    ACTIVE_SOURCE = 0x82,
+    GIVE_PHYSICAL_ADDRESS = 0x83,
+    REPORT_PHYSICAL_ADDRESS = 0x84,
+    REQUEST_ACTIVE_SOURCE = 0x85,
+    SET_STREAM_PATH = 0x86,
+    DEVICE_VENDOR_ID = 0x87,
+    VENDOR_COMMAND = 0x89,
+    VENDOR_REMOTE_BUTTON_DOWN = 0x8A,
+    VENDOR_REMOTE_BUTTON_UP = 0x8B,
+    GIVE_DEVICE_VENDOR_ID = 0x8C,
+    MENU_REQUEST = 0x8D,
+    MENU_STATUS = 0x8E,
+    GIVE_DEVICE_POWER_STATUS = 0x8F,
+    REPORT_POWER_STATUS = 0x90,
+    GET_MENU_LANGUAGE = 0x91,
+    SELECT_ANALOG_SERVICE = 0x92,
+    SELECT_DIGITAL_SERVICE = 0x93,
+    SET_DIGITAL_TIMER = 0x97,
+    CLEAR_DIGITAL_TIMER = 0x99,
+    SET_AUDIO_RATE = 0x9A,
+    INACTIVE_SOURCE = 0x9D,
+    CEC_VERSION = 0x9E,
+    GET_CEC_VERSION = 0x9F,
+    VENDOR_COMMAND_WITH_ID = 0xA0,
+    CLEAR_EXTERNAL_TIMER = 0xA1,
+    SET_EXTERNAL_TIMER = 0xA2,
+    REPORT_SHORT_AUDIO_DESCRIPTOR = 0xA3,
+    REQUEST_SHORT_AUDIO_DESCRIPTOR = 0xA4,
+    INITIATE_ARC = 0xC0,
+    REPORT_ARC_INITIATED = 0xC1,
+    REPORT_ARC_TERMINATED = 0xC2,
+    REQUEST_ARC_INITIATION = 0xC3,
+    REQUEST_ARC_TERMINATION = 0xC4,
+    TERMINATE_ARC = 0xC5,
+    ABORT = 0xFF,
+    GIVE_FEATURES = 0xA5,
+    REPORT_FEATURES = 0xA6,
+    REQUEST_CURRENT_LATENCY = 0xA7,
+    REPORT_CURRENT_LATENCY = 0xA8,
+}
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
new file mode 100644
index 0000000..578d924
--- /dev/null
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCec.aidl
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.cec;
+
+import android.hardware.tv.hdmi.cec.CecLogicalAddress;
+import android.hardware.tv.hdmi.cec.CecMessage;
+import android.hardware.tv.hdmi.cec.IHdmiCecCallback;
+import android.hardware.tv.hdmi.cec.Result;
+import android.hardware.tv.hdmi.cec.SendMessageResult;
+
+/**
+ * HDMI-CEC HAL interface definition.
+ */
+@VintfStability
+interface IHdmiCec {
+    /**
+     * Passes the logical address that must be used in this system.
+     *
+     * HAL must use it to configure the hardware so that the CEC commands
+     * addressed the given logical address can be filtered in. This method must
+     * be able to be called as many times as necessary in order to support
+     * multiple logical devices.
+     *
+     * @param addr Logical address that must be used in this system. It must be
+     *        in the range of valid logical addresses for the call to succeed.
+     * @return Result status of the operation. SUCCESS if successful,
+     *         FAILURE_INVALID_ARGS if the given logical address is invalid,
+     *         FAILURE_BUSY if device or resource is busy
+     */
+    Result addLogicalAddress(in CecLogicalAddress addr);
+
+    /**
+     * Clears all the logical addresses.
+     *
+     * It is used when the system doesn't need to process CEC command any more,
+     * hence to tell HAL to stop receiving commands from the CEC bus, and change
+     * the state back to the beginning.
+     */
+    void clearLogicalAddress();
+
+    /**
+     * Configures ARC circuit in the hardware logic to start or stop the
+     * feature.
+     *
+     * @param portId Port id to be configured.
+     * @param enable Flag must be either true to start the feature or false to
+     *        stop it.
+     */
+    void enableAudioReturnChannel(in int portId, in boolean enable);
+
+    /**
+     * Returns the CEC version supported by underlying hardware.
+     *
+     * @return the CEC version supported by underlying hardware.
+     */
+    int getCecVersion();
+
+    /**
+     * Gets the CEC physical address.
+     *
+     * The physical address depends on the topology of the network formed by
+     * connected HDMI devices. It is therefore likely to change if the cable is
+     * plugged off and on again. It is advised to call getPhysicalAddress to get
+     * the updated address when hot plug event takes place.
+     *
+     * @return Physical address of this device.
+     */
+    int getPhysicalAddress();
+
+    /**
+     * Gets the identifier of the vendor.
+     *
+     * @return Identifier of the vendor that is the 24-bit unique
+     *         company ID obtained from the IEEE Registration Authority
+     *         Committee (RAC). The upper 8 bits must be 0.
+     */
+    int getVendorId();
+
+    /**
+     * Transmits HDMI-CEC message to other HDMI device.
+     *
+     * The method must be designed to return in a certain amount of time and not
+     * hanging forever which may happen if CEC signal line is pulled low for
+     * some reason.
+     *
+     * It must try retransmission at least once as specified in the section '7.1
+     * Frame Re-transmissions' of the CEC Spec 1.4b.
+     *
+     * @param message CEC message to be sent to other HDMI device.
+     * @return Result status of the operation. SUCCESS if successful,
+     *         NACK if the sent message is not acknowledged,
+     *         BUSY if the CEC bus is busy,
+     *         FAIL if the message could not be sent.
+     */
+    SendMessageResult sendMessage(in CecMessage message);
+
+    /**
+     * Sets a callback that HDMI-CEC HAL must later use for incoming CEC
+     * messages.
+     *
+     * @param callback Callback object to pass hdmi events to the system. The
+     *        previously registered callback must be replaced with this one.
+     *        setCallback(null) should deregister the callback.
+     */
+    void setCallback(in @nullable IHdmiCecCallback callback);
+
+    /**
+     * Passes the updated language information of Android system. Contains
+     * three-letter code as defined in ISO/FDIS 639-2. Must be used for HAL to
+     * respond to <Get Menu Language> while in standby mode.
+     *
+     * @param language Three-letter code defined in ISO/FDIS 639-2. Must be
+     *        lowercase letters. (e.g., eng for English)
+     */
+    void setLanguage(in String language);
+
+    /**
+     * Determines whether a TV panel device in standby mode should wake up when
+     * it receives an OTP (One Touch Play) from a source device.
+     *
+     * @param value If true, the TV device will wake up when OTP is received
+     *              and if false, the TV device will not wake up for an OTP.
+     */
+    void enableWakeupByOtp(in boolean value);
+
+    /**
+     * Switch to enable or disable CEC on the device.
+     *
+     * @param value If true, the device will have all CEC functionalities
+     *              and if false, the device will not perform any CEC functions.
+     */
+    void enableCec(in boolean value);
+
+    /**
+     * Determines which module processes CEC messages - the Android framework or
+     * the HAL.
+     *
+     * @param value If true, the Android framework will actively process CEC
+     *        messages and if false, only the HAL will process the CEC messages.
+     */
+    void enableSystemCecControl(in boolean value);
+}
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
new file mode 100644
index 0000000..ef73dd7
--- /dev/null
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/IHdmiCecCallback.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.cec;
+
+import android.hardware.tv.hdmi.cec.CecMessage;
+
+/**
+ * Callbacks from the HAL implementation to notify the system of new events.
+ */
+@VintfStability
+oneway interface IHdmiCecCallback {
+    /**
+     * The callback function that must be called by HAL implementation to notify
+     * the system of new CEC message arrival.
+     */
+    void onCecMessage(in CecMessage message);
+}
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/Result.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/Result.aidl
new file mode 100644
index 0000000..1b1cd08
--- /dev/null
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/Result.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.cec;
+
+@VintfStability
+@Backing(type="byte")
+enum Result {
+    SUCCESS = 0,
+    FAILURE_UNKNOWN = 1,
+    FAILURE_INVALID_ARGS = 2,
+    FAILURE_INVALID_STATE = 3,
+    FAILURE_NOT_SUPPORTED = 4,
+    FAILURE_BUSY = 5,
+}
diff --git a/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/SendMessageResult.aidl b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
new file mode 100644
index 0000000..8f609d5
--- /dev/null
+++ b/tv/hdmi/cec/aidl/android/hardware/tv/hdmi/cec/SendMessageResult.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.cec;
+
+/**
+ * error code used for send_message.
+ */
+@VintfStability
+@Backing(type="byte")
+enum SendMessageResult {
+    SUCCESS = 0,
+    NACK = 1,
+    BUSY = 2,
+    FAIL = 3,
+}
diff --git a/tv/hdmi/cec/aidl/default/Android.bp b/tv/hdmi/cec/aidl/default/Android.bp
new file mode 100644
index 0000000..ea4bb94
--- /dev/null
+++ b/tv/hdmi/cec/aidl/default/Android.bp
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+    name: "android.hardware.tv.hdmi.cec-service",
+    vintf_fragments: ["android.hardware.tv.hdmi.cec-service.xml"],
+    relative_install_path: "hw",
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+    ],
+    init_rc: ["android.hardware.tv.hdmi.cec-service.rc"],
+    srcs: [
+        "serviceMock.cpp",
+        "HdmiCecMock.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "liblog",
+        "libbase",
+        "libutils",
+        "libhardware",
+        "libhidlbase",
+        "android.hardware.tv.hdmi.cec-V1-ndk",
+    ],
+}
+
+cc_fuzz {
+    name: "android.hardware.tv.hdmi.cec-service_fuzzer",
+    defaults: ["service_fuzzer_defaults"],
+    static_libs: [
+        "android.hardware.tv.hdmi.cec-V1-ndk",
+        "liblog",
+    ],
+    srcs: [
+        "fuzzer.cpp",
+        "HdmiCecMock.cpp",
+    ],
+    fuzz_config: {
+        componentid: 826094,
+    },
+}
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
new file mode 100644
index 0000000..0212e7e
--- /dev/null
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.hdmi.cec"
+#include <android-base/logging.h>
+#include <fcntl.h>
+#include <utils/Log.h>
+
+#include <hardware/hardware.h>
+#include <hardware/hdmi_cec.h>
+#include "HdmiCecMock.h"
+
+using ndk::ScopedAStatus;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace hdmi {
+namespace cec {
+namespace implementation {
+
+void HdmiCecMock::serviceDied(void* cookie) {
+    ALOGE("HdmiCecMock died");
+    auto hdmiCecMock = static_cast<HdmiCecMock*>(cookie);
+    hdmiCecMock->mCecThreadRun = false;
+}
+
+ScopedAStatus HdmiCecMock::addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) {
+    // Have a list to maintain logical addresses
+    mLogicalAddresses.push_back(addr);
+    *_aidl_return = Result::SUCCESS;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::clearLogicalAddress() {
+    // Remove logical address from the list
+    mLogicalAddresses = {};
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::enableAudioReturnChannel(int32_t portId __unused, bool enable __unused) {
+    // Maintain ARC status
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::getCecVersion(int32_t* _aidl_return) {
+    // Maintain a cec version and return it
+    *_aidl_return = mCecVersion;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::getPhysicalAddress(int32_t* _aidl_return) {
+    // Maintain a physical address and return it
+    // Default 0xFFFF, update on hotplug event
+    *_aidl_return = mPhysicalAddress;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::getVendorId(int32_t* _aidl_return) {
+    *_aidl_return = mCecVendorId;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::sendMessage(const CecMessage& message, SendMessageResult* _aidl_return) {
+    if (message.body.size() == 0) {
+        *_aidl_return = SendMessageResult::NACK;
+    } else {
+        sendMessageToFifo(message);
+        *_aidl_return = SendMessageResult::SUCCESS;
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::setCallback(const std::shared_ptr<IHdmiCecCallback>& callback) {
+    // If callback is null, mCallback is also set to null so we do not call the old callback.
+    mCallback = callback;
+
+    if (callback != nullptr) {
+        AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+
+        mInputFile = open(CEC_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
+        mOutputFile = open(CEC_MSG_OUT_FIFO, O_RDWR | O_CLOEXEC);
+        pthread_create(&mThreadId, NULL, __threadLoop, this);
+        pthread_setname_np(mThreadId, "hdmi_cec_loop");
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::setLanguage(const std::string& language) {
+    if (language.size() != 3) {
+        LOG(ERROR) << "Wrong language code: expected 3 letters, but it was " << language.size()
+                   << ".";
+        return ScopedAStatus::ok();
+    }
+    // TODO Validate if language is a valid language code
+    const char* languageStr = language.c_str();
+    int convertedLanguage = ((languageStr[0] & 0xFF) << 16) | ((languageStr[1] & 0xFF) << 8) |
+                            (languageStr[2] & 0xFF);
+    mOptionLanguage = convertedLanguage;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::enableWakeupByOtp(bool value) {
+    mOptionWakeUp = value;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::enableCec(bool value) {
+    mOptionEnableCec = value;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiCecMock::enableSystemCecControl(bool value) {
+    mOptionSystemCecControl = value;
+    return ScopedAStatus::ok();
+}
+
+void* HdmiCecMock::__threadLoop(void* user) {
+    HdmiCecMock* const self = static_cast<HdmiCecMock*>(user);
+    self->threadLoop();
+    return 0;
+}
+
+int HdmiCecMock::readMessageFromFifo(unsigned char* buf, int msgCount) {
+    if (msgCount <= 0 || !buf) {
+        return 0;
+    }
+
+    int ret = -1;
+    // Maybe blocked at driver
+    ret = read(mInputFile, buf, msgCount);
+    if (ret < 0) {
+        ALOGE("[halimp_aidl] read :%s failed, ret:%d\n", CEC_MSG_IN_FIFO, ret);
+        return -1;
+    }
+
+    return ret;
+}
+
+int HdmiCecMock::sendMessageToFifo(const CecMessage& message) {
+    unsigned char msgBuf[CEC_MESSAGE_BODY_MAX_LENGTH + 1] = {0};
+    int ret = -1;
+
+    msgBuf[0] = ((static_cast<uint8_t>(message.initiator) & 0xf) << 4) |
+                (static_cast<uint8_t>(message.destination) & 0xf);
+
+    size_t length = std::min(static_cast<size_t>(message.body.size()),
+                             static_cast<size_t>(CEC_MESSAGE_BODY_MAX_LENGTH));
+    for (size_t i = 0; i < length; ++i) {
+        msgBuf[i + 1] = static_cast<unsigned char>(message.body[i]);
+    }
+
+    // Open the output pipe for writing outgoing cec message
+    mOutputFile = open(CEC_MSG_OUT_FIFO, O_WRONLY | O_CLOEXEC);
+    if (mOutputFile < 0) {
+        ALOGD("[halimp_aidl] file open failed for writing");
+        return -1;
+    }
+
+    // Write message into the output pipe
+    ret = write(mOutputFile, msgBuf, length + 1);
+    close(mOutputFile);
+    if (ret < 0) {
+        ALOGE("[halimp_aidl] write :%s failed, ret:%d\n", CEC_MSG_OUT_FIFO, ret);
+        return -1;
+    }
+    return ret;
+}
+
+void HdmiCecMock::printCecMsgBuf(const char* msg_buf, int len) {
+    int i, size = 0;
+    const int bufSize = CEC_MESSAGE_BODY_MAX_LENGTH * 3;
+    // Use 2 characters for each byte in the message plus 1 space
+    char buf[bufSize] = {0};
+
+    // Messages longer than max length will be truncated.
+    for (i = 0; i < len && size < bufSize; i++) {
+        size += sprintf(buf + size, " %02x", msg_buf[i]);
+    }
+    ALOGD("[halimp_aidl] %s, msg:%.*s", __FUNCTION__, size, buf);
+}
+
+void HdmiCecMock::handleCecMessage(unsigned char* msgBuf, int msgSize) {
+    CecMessage message;
+    size_t length = std::min(static_cast<size_t>(msgSize - 1),
+                             static_cast<size_t>(CEC_MESSAGE_BODY_MAX_LENGTH));
+    message.body.resize(length);
+
+    for (size_t i = 0; i < length; ++i) {
+        message.body[i] = static_cast<uint8_t>(msgBuf[i + 1]);
+        ALOGD("[halimp_aidl] msg body %x", message.body[i]);
+    }
+
+    message.initiator = static_cast<CecLogicalAddress>((msgBuf[0] >> 4) & 0xf);
+    ALOGD("[halimp_aidl] msg init %hhd", message.initiator);
+    message.destination = static_cast<CecLogicalAddress>((msgBuf[0] >> 0) & 0xf);
+    ALOGD("[halimp_aidl] msg dest %hhd", message.destination);
+
+    if (mCallback != nullptr) {
+        mCallback->onCecMessage(message);
+    }
+}
+
+void HdmiCecMock::threadLoop() {
+    ALOGD("[halimp_aidl] threadLoop start.");
+    unsigned char msgBuf[CEC_MESSAGE_BODY_MAX_LENGTH];
+    int r = -1;
+
+    // Open the input pipe
+    while (mInputFile < 0) {
+        usleep(1000 * 1000);
+        mInputFile = open(CEC_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
+    }
+    ALOGD("[halimp_aidl] file open ok, fd = %d.", mInputFile);
+
+    while (mCecThreadRun) {
+        if (!mOptionSystemCecControl) {
+            usleep(1000 * 1000);
+            continue;
+        }
+
+        memset(msgBuf, 0, sizeof(msgBuf));
+        // Try to get a message from dev.
+        // echo -n -e '\x04\x83' >> /dev/cec
+        r = readMessageFromFifo(msgBuf, CEC_MESSAGE_BODY_MAX_LENGTH);
+        if (r <= 1) {
+            // Ignore received ping messages
+            continue;
+        }
+
+        printCecMsgBuf((const char*)msgBuf, r);
+
+        if (((msgBuf[0] >> 4) & 0xf) == 0xf) {
+            // The message is a hotplug event, handled by HDMI HAL.
+            continue;
+        }
+
+        handleCecMessage(msgBuf, r);
+    }
+
+    ALOGD("[halimp_aidl] thread end.");
+}
+
+HdmiCecMock::HdmiCecMock() {
+    ALOGE("[halimp_aidl] Opening a virtual CEC HAL for testing and virtual machine.");
+    mCallback = nullptr;
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+}
+
+}  // namespace implementation
+}  // namespace cec
+}  // namespace hdmi
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.h b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
new file mode 100644
index 0000000..aca0581
--- /dev/null
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/tv/hdmi/cec/BnHdmiCec.h>
+#include <algorithm>
+#include <vector>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace hdmi {
+namespace cec {
+namespace implementation {
+
+using ::aidl::android::hardware::tv::hdmi::cec::BnHdmiCec;
+using ::aidl::android::hardware::tv::hdmi::cec::CecLogicalAddress;
+using ::aidl::android::hardware::tv::hdmi::cec::CecMessage;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCec;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCecCallback;
+using ::aidl::android::hardware::tv::hdmi::cec::Result;
+using ::aidl::android::hardware::tv::hdmi::cec::SendMessageResult;
+
+#define CEC_MSG_IN_FIFO "/dev/cec_aidl_in_pipe"
+#define CEC_MSG_OUT_FIFO "/dev/cec_aidl_out_pipe"
+
+struct HdmiCecMock : public BnHdmiCec {
+    HdmiCecMock();
+    ::ndk::ScopedAStatus addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) override;
+    ::ndk::ScopedAStatus clearLogicalAddress() override;
+    ::ndk::ScopedAStatus enableAudioReturnChannel(int32_t portId, bool enable) override;
+    ::ndk::ScopedAStatus getCecVersion(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getPhysicalAddress(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getVendorId(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus sendMessage(const CecMessage& message,
+                                     SendMessageResult* _aidl_return) override;
+    ::ndk::ScopedAStatus setCallback(const std::shared_ptr<IHdmiCecCallback>& callback) override;
+    ::ndk::ScopedAStatus setLanguage(const std::string& language) override;
+    ::ndk::ScopedAStatus enableWakeupByOtp(bool value) override;
+    ::ndk::ScopedAStatus enableCec(bool value) override;
+    ::ndk::ScopedAStatus enableSystemCecControl(bool value) override;
+    void printCecMsgBuf(const char* msg_buf, int len);
+
+  private:
+    static void* __threadLoop(void* data);
+    void threadLoop();
+    int readMessageFromFifo(unsigned char* buf, int msgCount);
+    int sendMessageToFifo(const CecMessage& message);
+    void handleCecMessage(unsigned char* msgBuf, int length);
+
+  private:
+    static void serviceDied(void* cookie);
+    std::shared_ptr<IHdmiCecCallback> mCallback;
+
+    // Variables for the virtual cec hal impl
+    uint16_t mPhysicalAddress = 0xFFFF;
+    vector<CecLogicalAddress> mLogicalAddresses;
+    int32_t mCecVersion = 0x06;
+    uint32_t mCecVendorId = 0x01;
+
+    // CEC Option value
+    bool mOptionWakeUp = 0;
+    bool mOptionEnableCec = 0;
+    bool mOptionSystemCecControl = 0;
+    int mOptionLanguage;
+
+    // Testing variables
+    // Input file descriptor
+    int mInputFile;
+    // Output file descriptor
+    int mOutputFile;
+    bool mCecThreadRun = true;
+    pthread_t mThreadId = 0;
+
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+};
+}  // namespace implementation
+}  // namespace cec
+}  // namespace hdmi
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.rc b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.rc
new file mode 100644
index 0000000..f4c9fcf
--- /dev/null
+++ b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.rc
@@ -0,0 +1,5 @@
+service vendor.cec-default /vendor/bin/hw/android.hardware.tv.hdmi.cec-service
+    interface aidl android.hardware.tv.hdmi.cec.IHdmiCec/default
+    class hal
+    user system
+    group system
diff --git a/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.xml b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.xml
new file mode 100644
index 0000000..d48565c
--- /dev/null
+++ b/tv/hdmi/cec/aidl/default/android.hardware.tv.hdmi.cec-service.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.tv.hdmi.cec</name>
+        <version>1</version>
+        <interface>
+            <name>IHdmiCec</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/tv/hdmi/cec/aidl/default/fuzzer.cpp b/tv/hdmi/cec/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..33453dc
--- /dev/null
+++ b/tv/hdmi/cec/aidl/default/fuzzer.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <HdmiCecMock.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using android::fuzzService;
+using android::hardware::tv::hdmi::cec::implementation::HdmiCecMock;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto hdmiCecAidl = SharedRefBase::make<HdmiCecMock>();
+
+    fuzzService(hdmiCecAidl->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/tv/hdmi/cec/aidl/default/serviceMock.cpp b/tv/hdmi/cec/aidl/default/serviceMock.cpp
new file mode 100644
index 0000000..cbf85e5
--- /dev/null
+++ b/tv/hdmi/cec/aidl/default/serviceMock.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.hdmi.cec-service-shim"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <hidl/HidlTransportSupport.h>
+#include <utils/Log.h>
+#include "HdmiCecMock.h"
+
+using android::hardware::tv::hdmi::cec::implementation::HdmiCecMock;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+
+    std::shared_ptr<HdmiCecMock> hdmiCecAidl = ndk::SharedRefBase::make<HdmiCecMock>();
+    const std::string instance = std::string() + HdmiCecMock::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(hdmiCecAidl->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return 0;
+}
diff --git a/tv/hdmi/cec/aidl/vts/functional/Android.bp b/tv/hdmi/cec/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..5c86d3f
--- /dev/null
+++ b/tv/hdmi/cec/aidl/vts/functional/Android.bp
@@ -0,0 +1,38 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalTvHdmiCecAidlTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalTvHdmiCecAidlTargetTest.cpp"],
+    static_libs: [
+        "android.hardware.tv.hdmi.cec-V1-ndk",
+        "android.hardware.tv.hdmi.connection-V1-ndk",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    disable_framework: true,
+}
diff --git a/tv/hdmi/cec/aidl/vts/functional/AndroidTest.xml b/tv/hdmi/cec/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..63e7763
--- /dev/null
+++ b/tv/hdmi/cec/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalTvHdmiCecAidlTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalTvHdmiCecAidlTargetTest->/data/local/tmp/VtsHalTvHdmiCecAidlTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalTvHdmiCecAidlTargetTest" />
+        <option name="native-test-timeout" value="30m" />
+    </test>
+</configuration>
diff --git a/tv/hdmi/cec/aidl/vts/functional/VtsHalTvHdmiCecAidlTargetTest.cpp b/tv/hdmi/cec/aidl/vts/functional/VtsHalTvHdmiCecAidlTargetTest.cpp
new file mode 100644
index 0000000..a2fb0f8
--- /dev/null
+++ b/tv/hdmi/cec/aidl/vts/functional/VtsHalTvHdmiCecAidlTargetTest.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "HdmiCec_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/tv/hdmi/cec/BnHdmiCec.h>
+#include <aidl/android/hardware/tv/hdmi/cec/BnHdmiCecCallback.h>
+#include <aidl/android/hardware/tv/hdmi/cec/CecDeviceType.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <sstream>
+#include <vector>
+
+using ::aidl::android::hardware::tv::hdmi::cec::BnHdmiCecCallback;
+using ::aidl::android::hardware::tv::hdmi::cec::CecDeviceType;
+using ::aidl::android::hardware::tv::hdmi::cec::CecLogicalAddress;
+using ::aidl::android::hardware::tv::hdmi::cec::CecMessage;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCec;
+using ::aidl::android::hardware::tv::hdmi::cec::IHdmiCecCallback;
+using ::aidl::android::hardware::tv::hdmi::cec::Result;
+using ::aidl::android::hardware::tv::hdmi::cec::SendMessageResult;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo;
+using ::ndk::SpAIBinder;
+
+#define CEC_VERSION 0x05
+#define INCORRECT_VENDOR_ID 0x00
+#define TV_PHYSICAL_ADDRESS 0x0000
+
+// The main test class for TV CEC HAL.
+class HdmiCecTest : public ::testing::TestWithParam<std::string> {
+    static void serviceDied(void* /* cookie */) { ALOGE("VtsHalTvCecAidlTargetTest died"); }
+
+  public:
+    void SetUp() override {
+        hdmiCec = IHdmiCec::fromBinder(
+                SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(hdmiCec, nullptr);
+        ALOGI("%s: getService() for hdmiCec is %s", __func__,
+              hdmiCec->isRemote() ? "remote" : "local");
+
+        hdmiCecCallback = ::ndk::SharedRefBase::make<CecCallback>();
+        ASSERT_NE(hdmiCecCallback, nullptr);
+        hdmiCecDeathRecipient =
+                ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(&serviceDied));
+        ASSERT_EQ(AIBinder_linkToDeath(hdmiCec->asBinder().get(), hdmiCecDeathRecipient.get(), 0),
+                  STATUS_OK);
+    }
+
+    std::vector<int> getDeviceTypes() {
+        std::vector<int> deviceTypes;
+        FILE* p = popen("getprop ro.hdmi.device_type", "re");
+        if (p) {
+            char* line = NULL;
+            size_t len = 0;
+            if (getline(&line, &len, p) > 0) {
+                std::istringstream stream(line);
+                std::string number{};
+                while (std::getline(stream, number, ',')) {
+                    deviceTypes.push_back(stoi(number));
+                }
+            }
+            pclose(p);
+        }
+        return deviceTypes;
+    }
+
+    bool hasDeviceType(CecDeviceType type) {
+        std::vector<int> deviceTypes = getDeviceTypes();
+        return std::find(deviceTypes.begin(), deviceTypes.end(), (int)type) != deviceTypes.end();
+    }
+
+    class CecCallback : public BnHdmiCecCallback {
+      public:
+        ::ndk::ScopedAStatus onCecMessage(const CecMessage& message __unused) {
+            return ::ndk::ScopedAStatus::ok();
+        };
+    };
+
+    std::shared_ptr<IHdmiCec> hdmiCec;
+    std::shared_ptr<IHdmiCecCallback> hdmiCecCallback;
+    ::ndk::ScopedAIBinder_DeathRecipient hdmiCecDeathRecipient;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HdmiCecTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, HdmiCecTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IHdmiCec::descriptor)),
+                         android::PrintInstanceNameToString);
+
+TEST_P(HdmiCecTest, ClearAddLogicalAddress) {
+    Result addLaResult;
+    ASSERT_TRUE(hdmiCec->clearLogicalAddress().isOk());
+    ASSERT_TRUE(hdmiCec->addLogicalAddress(CecLogicalAddress::PLAYBACK_3, &addLaResult).isOk());
+    EXPECT_EQ(addLaResult, Result::SUCCESS);
+}
+
+TEST_P(HdmiCecTest, PhysicalAddress) {
+    int32_t addr;
+    ASSERT_TRUE(hdmiCec->getPhysicalAddress(&addr).isOk());
+    if (!hasDeviceType(CecDeviceType::TV)) {
+        EXPECT_NE(addr, TV_PHYSICAL_ADDRESS);
+    }
+}
+
+TEST_P(HdmiCecTest, SendMessage) {
+    CecMessage message;
+    message.initiator = CecLogicalAddress::PLAYBACK_1;
+    message.destination = CecLogicalAddress::BROADCAST;
+    message.body.resize(1);
+    message.body[0] = 131;
+    SendMessageResult result;
+    ASSERT_TRUE(hdmiCec->sendMessage(message, &result).isOk());
+    EXPECT_EQ(result, SendMessageResult::SUCCESS);
+}
+
+TEST_P(HdmiCecTest, CecVersion) {
+    int32_t version;
+    ASSERT_TRUE(hdmiCec->getCecVersion(&version).isOk());
+    EXPECT_GE(version, CEC_VERSION);
+}
+
+TEST_P(HdmiCecTest, SetCallback) {
+    ASSERT_TRUE(hdmiCec->setCallback(::ndk::SharedRefBase::make<CecCallback>()).isOk());
+}
+
+TEST_P(HdmiCecTest, VendorId) {
+    int32_t vendorId;
+    ASSERT_TRUE(hdmiCec->getVendorId(&vendorId).isOk());
+    EXPECT_NE(vendorId, INCORRECT_VENDOR_ID);
+}
+
+TEST_P(HdmiCecTest, EnableWakeupByOtp) {
+    ASSERT_TRUE(hdmiCec->enableWakeupByOtp(false).isOk());
+    // Restore option to its default value
+    ASSERT_TRUE(hdmiCec->enableWakeupByOtp(true).isOk());
+}
+
+TEST_P(HdmiCecTest, EnableCec) {
+    ASSERT_TRUE(hdmiCec->enableCec(false).isOk());
+    // Restore option to its default value
+    ASSERT_TRUE(hdmiCec->enableCec(true).isOk());
+}
+
+TEST_P(HdmiCecTest, EnableSystemCecControl) {
+    ASSERT_TRUE(hdmiCec->enableSystemCecControl(true).isOk());
+    // Restore option to its default value
+    ASSERT_TRUE(hdmiCec->enableSystemCecControl(false).isOk());
+}
+
+TEST_P(HdmiCecTest, SetLanguage) {
+    ASSERT_TRUE(hdmiCec->setLanguage("eng").isOk());
+}
diff --git a/tv/hdmi/connection/aidl/Android.bp b/tv/hdmi/connection/aidl/Android.bp
new file mode 100644
index 0000000..ff7e166
--- /dev/null
+++ b/tv/hdmi/connection/aidl/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.tv.hdmi.connection",
+    vendor_available: true,
+    srcs: ["android/hardware/tv/hdmi/connection/*.aidl"],
+    stability: "vintf",
+    backend: {
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/tv/hdmi/connection/aidl/TEST_MAPPING b/tv/hdmi/connection/aidl/TEST_MAPPING
new file mode 100644
index 0000000..13cf0c2
--- /dev/null
+++ b/tv/hdmi/connection/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalTvHdmiConnectionAidlTargetTest"
+    }
+  ]
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/.hash b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/.hash
new file mode 100644
index 0000000..e11a015
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/.hash
@@ -0,0 +1 @@
+85c26fa47f3c3062aa93ffc8bb0897a85c8cb118
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
new file mode 100644
index 0000000..ac35c99
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@VintfStability
+parcelable HdmiPortInfo {
+  android.hardware.tv.hdmi.connection.HdmiPortType type;
+  int portId;
+  boolean cecSupported;
+  boolean arcSupported;
+  boolean eArcSupported;
+  int physicalAddress;
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/HdmiPortType.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
new file mode 100644
index 0000000..fc2d7e5
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@Backing(type="byte") @VintfStability
+enum HdmiPortType {
+  INPUT = 0,
+  OUTPUT = 1,
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/HpdSignal.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/HpdSignal.aidl
new file mode 100644
index 0000000..697da29
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/HpdSignal.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@Backing(type="byte") @VintfStability
+enum HpdSignal {
+  HDMI_HPD_PHYSICAL = 0,
+  HDMI_HPD_STATUS_BIT = 1,
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
new file mode 100644
index 0000000..cf7c4bd
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@VintfStability
+interface IHdmiConnection {
+  android.hardware.tv.hdmi.connection.HdmiPortInfo[] getPortInfo();
+  boolean isConnected(in int portId);
+  void setCallback(in android.hardware.tv.hdmi.connection.IHdmiConnectionCallback callback);
+  void setHpdSignal(android.hardware.tv.hdmi.connection.HpdSignal signal, in int portId);
+  android.hardware.tv.hdmi.connection.HpdSignal getHpdSignal(in int portId);
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
new file mode 100644
index 0000000..f9f6856
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@VintfStability
+interface IHdmiConnectionCallback {
+  oneway void onHotplugEvent(in boolean connected, in int portId);
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/Result.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/Result.aidl
new file mode 100644
index 0000000..93182c5
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/1/android/hardware/tv/hdmi/connection/Result.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@VintfStability
+enum Result {
+  SUCCESS = 0,
+  FAILURE_UNKNOWN = 1,
+  FAILURE_INVALID_ARGS = 2,
+  FAILURE_INVALID_STATE = 3,
+  FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
new file mode 100644
index 0000000..ac35c99
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@VintfStability
+parcelable HdmiPortInfo {
+  android.hardware.tv.hdmi.connection.HdmiPortType type;
+  int portId;
+  boolean cecSupported;
+  boolean arcSupported;
+  boolean eArcSupported;
+  int physicalAddress;
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortType.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
new file mode 100644
index 0000000..fc2d7e5
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@Backing(type="byte") @VintfStability
+enum HdmiPortType {
+  INPUT = 0,
+  OUTPUT = 1,
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HpdSignal.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HpdSignal.aidl
new file mode 100644
index 0000000..697da29
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/HpdSignal.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@Backing(type="byte") @VintfStability
+enum HpdSignal {
+  HDMI_HPD_PHYSICAL = 0,
+  HDMI_HPD_STATUS_BIT = 1,
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
new file mode 100644
index 0000000..cf7c4bd
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@VintfStability
+interface IHdmiConnection {
+  android.hardware.tv.hdmi.connection.HdmiPortInfo[] getPortInfo();
+  boolean isConnected(in int portId);
+  void setCallback(in android.hardware.tv.hdmi.connection.IHdmiConnectionCallback callback);
+  void setHpdSignal(android.hardware.tv.hdmi.connection.HpdSignal signal, in int portId);
+  android.hardware.tv.hdmi.connection.HpdSignal getHpdSignal(in int portId);
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
new file mode 100644
index 0000000..f9f6856
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@VintfStability
+interface IHdmiConnectionCallback {
+  oneway void onHotplugEvent(in boolean connected, in int portId);
+}
diff --git a/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/Result.aidl b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/Result.aidl
new file mode 100644
index 0000000..93182c5
--- /dev/null
+++ b/tv/hdmi/connection/aidl/aidl_api/android.hardware.tv.hdmi.connection/current/android/hardware/tv/hdmi/connection/Result.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.connection;
+@VintfStability
+enum Result {
+  SUCCESS = 0,
+  FAILURE_UNKNOWN = 1,
+  FAILURE_INVALID_ARGS = 2,
+  FAILURE_INVALID_STATE = 3,
+  FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
new file mode 100644
index 0000000..6bec7e5
--- /dev/null
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.connection;
+
+import android.hardware.tv.hdmi.connection.HdmiPortType;
+
+/**
+ * HDMI port descriptor
+ */
+@VintfStability
+parcelable HdmiPortInfo {
+    HdmiPortType type;
+    int portId; // For devices with input ports (e.g. TV Panels), input ports should start from 1
+                // which corresponds to HDMI "port 1".
+
+    // In the following, 'supported' refers to having the necessary hardware and firmware on the
+    // device to support CEC/ARC/eARC on this port.
+    boolean cecSupported;
+    boolean arcSupported; // If true, cecSupported has to be true as well. ARC cannot be supported
+                          // without CEC support.
+    boolean eArcSupported;
+
+    // The physical address of the device connected to this port, valid range is 0x0000 to 0xFFFF
+    // (ref Sec 8.7.2 of HDMI 1.4b).
+    int physicalAddress;
+}
diff --git a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortType.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
new file mode 100644
index 0000000..4ec58ee
--- /dev/null
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HdmiPortType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.connection;
+
+/**
+ * HDMI port type.
+ */
+@VintfStability
+@Backing(type="byte")
+enum HdmiPortType {
+    INPUT = 0,
+    OUTPUT = 1,
+}
diff --git a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HpdSignal.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HpdSignal.aidl
new file mode 100644
index 0000000..554dcf6
--- /dev/null
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/HpdSignal.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.connection;
+
+/**
+ * HPD (Hotplug Detection) Signal Types
+ */
+@VintfStability
+@Backing(type="byte")
+enum HpdSignal {
+    HDMI_HPD_PHYSICAL = 0,
+    HDMI_HPD_STATUS_BIT = 1,
+}
diff --git a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
new file mode 100644
index 0000000..ee6cc89
--- /dev/null
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnection.aidl
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.connection;
+
+import android.hardware.tv.hdmi.connection.HdmiPortInfo;
+import android.hardware.tv.hdmi.connection.HpdSignal;
+import android.hardware.tv.hdmi.connection.IHdmiConnectionCallback;
+
+/**
+ * HDMI Connection HAL interface definition.
+ */
+@VintfStability
+interface IHdmiConnection {
+    /**
+     * Gets the hdmi port information of underlying hardware.
+     *
+     * @return The list of HDMI port information
+     */
+    HdmiPortInfo[] getPortInfo();
+
+    /**
+     * Gets the connection status of the specified port.
+     *
+     * @param portId Port id to be inspected for the connection status.
+     * @return True if a device is connected, otherwise false. The HAL
+     *         must watch for +5V power signal to determine the status.
+     */
+    boolean isConnected(in int portId);
+
+    /**
+     * Sets a callback that HDMI HAL must later use for internal HDMI events
+     *
+     * @param callback Callback object to pass hdmi events to the system. The
+     *        previously registered callback must be replaced with this one.
+     *        setCallback(null) should deregister the callback.
+     */
+    void setCallback(in IHdmiConnectionCallback callback);
+
+    /**
+     * Method to set the HPD (Hot Plug Detection) signal the HAL should use for HPD signaling (e.g.
+     * signaling EDID updates). By default, the HAL will use {@code HDMI_HPD_PHYSICAL} (the physical
+     * hotplug signal). When set to {@code HDMI_HPD_STATUS_BIT} the HAL should use the HDP status
+     * bit.
+     *
+     * This is only relevant to TV Panel devices that support eARC TX. While eARC TX is connected,
+     * the framework calls this method to set the HPD signal to {@code HDMI_HPD_STATUS_BIT}.
+     *
+     * For all other device types, this method can be stubbed.
+     *
+     * @param signal The HPD signal type to use.
+     * @param portId id of the port on which the HPD signal should be set.
+     *
+     * @throws ServiceSpecificException with error code set to
+     *         {@code Result::FAILURE_NOT_SUPPORTED} if the signal type is not supported.
+     *         {@code Result::FAILURE_INVALID_ARGS} if the signal type is invalid.
+     *         {@code Result::FAILURE_UNKNOWN} if the signal type could not be set because of an
+     *                                         unknown failure.
+     */
+    void setHpdSignal(HpdSignal signal, in int portId);
+
+    /**
+     * Get the current signal the HAL is using for HPD
+     *
+     * This is only relevant to TV Panel devices that support eARC TX. While eARC TX is connected,
+     * this method returns {@code HDMI_HPD_STATUS_BIT}.
+     *
+     * For all other device types, this method can be stubbed by always returning
+     * {@code HDMI_HPD_PHYSICAL}.
+     *
+     * @param portId id of the port of which the current HPD signal is queried.
+     */
+    HpdSignal getHpdSignal(in int portId);
+}
diff --git a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
new file mode 100644
index 0000000..8b001fb
--- /dev/null
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/IHdmiConnectionCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.connection;
+
+/**
+ * Callbacks from the HDMI HAL implementation to notify the system of new events.
+ */
+@VintfStability
+oneway interface IHdmiConnectionCallback {
+    /**
+     * The callback function that must be called by HAL implementation to notify
+     * the system of new hotplug event.
+     */
+    void onHotplugEvent(in boolean connected, in int portId);
+}
diff --git a/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/Result.aidl b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/Result.aidl
new file mode 100644
index 0000000..edaa0a0
--- /dev/null
+++ b/tv/hdmi/connection/aidl/android/hardware/tv/hdmi/connection/Result.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.connection;
+
+/**
+ * Result enum for return values. Used by the HDMI related AIDL.
+ */
+@VintfStability
+enum Result {
+    /**
+     * The HPD Signal type was set successfully.
+     */
+    SUCCESS = 0,
+
+    /**
+     * The HPD Signal type could not be set because of an unknown failure.
+     */
+    FAILURE_UNKNOWN = 1,
+
+    /**
+     * The HPD Signal type could not be set because the arguments were invalid.
+     */
+    FAILURE_INVALID_ARGS = 2,
+
+    /**
+     * The HPD Signal type could not be set because the HAL is in an invalid state.
+     */
+    FAILURE_INVALID_STATE = 3,
+
+    /**
+     * The HPD Signal type could not be set as the signal type is not supported.
+     */
+    FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/hdmi/connection/aidl/default/Android.bp b/tv/hdmi/connection/aidl/default/Android.bp
new file mode 100644
index 0000000..5e7e330
--- /dev/null
+++ b/tv/hdmi/connection/aidl/default/Android.bp
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+    name: "android.hardware.tv.hdmi.connection-service",
+    vintf_fragments: ["android.hardware.tv.hdmi.connection-service.xml"],
+    relative_install_path: "hw",
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+    ],
+    init_rc: ["android.hardware.tv.hdmi.connection-service.rc"],
+    srcs: [
+        "serviceMock.cpp",
+        "HdmiConnectionMock.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "liblog",
+        "libbase",
+        "libutils",
+        "libhardware",
+        "libhidlbase",
+        "android.hardware.tv.hdmi.connection-V1-ndk",
+    ],
+}
+
+cc_fuzz {
+    name: "android.hardware.tv.hdmi.connection-service_fuzzer",
+    defaults: ["service_fuzzer_defaults"],
+    static_libs: [
+        "android.hardware.tv.hdmi.connection-V1-ndk",
+        "liblog",
+    ],
+    srcs: [
+        "fuzzer.cpp",
+        "HdmiConnectionMock.cpp",
+    ],
+    fuzz_config: {
+        componentid: 826094,
+    },
+}
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
new file mode 100644
index 0000000..8f4411b
--- /dev/null
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.hdmi.connection"
+#include <android-base/logging.h>
+#include <fcntl.h>
+#include <utils/Log.h>
+
+#include "HdmiConnectionMock.h"
+
+using ndk::ScopedAStatus;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace hdmi {
+namespace connection {
+namespace implementation {
+
+void HdmiConnectionMock::serviceDied(void* cookie) {
+    ALOGE("HdmiConnectionMock died");
+    auto hdmi = static_cast<HdmiConnectionMock*>(cookie);
+    hdmi->mHdmiThreadRun = false;
+}
+
+ScopedAStatus HdmiConnectionMock::getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) {
+    *_aidl_return = mPortInfos;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiConnectionMock::isConnected(int32_t portId, bool* _aidl_return) {
+    // Maintain port connection status and update on hotplug event
+    if (portId <= mTotalPorts && portId >= 1) {
+        *_aidl_return = mPortConnectionStatus.at(portId - 1);
+    } else {
+        *_aidl_return = false;
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiConnectionMock::setCallback(
+        const std::shared_ptr<IHdmiConnectionCallback>& callback) {
+    if (mCallback != nullptr) {
+        mCallback = nullptr;
+    }
+
+    if (callback != nullptr) {
+        mCallback = callback;
+        AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+
+        mInputFile = open(HDMI_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
+        pthread_create(&mThreadId, NULL, __threadLoop, this);
+        pthread_setname_np(mThreadId, "hdmi_loop");
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiConnectionMock::setHpdSignal(HpdSignal signal, int32_t portId) {
+    if (portId > mTotalPorts || portId < 1) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    if (!mHdmiThreadRun) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::FAILURE_INVALID_STATE));
+    }
+    mHpdSignal.at(portId - 1) = signal;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus HdmiConnectionMock::getHpdSignal(int32_t portId, HpdSignal* _aidl_return) {
+    if (portId > mTotalPorts || portId < 1) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    *_aidl_return = mHpdSignal.at(portId - 1);
+    return ScopedAStatus::ok();
+}
+
+void* HdmiConnectionMock::__threadLoop(void* user) {
+    HdmiConnectionMock* const self = static_cast<HdmiConnectionMock*>(user);
+    self->threadLoop();
+    return 0;
+}
+
+int HdmiConnectionMock::readMessageFromFifo(unsigned char* buf, int msgCount) {
+    if (msgCount <= 0 || !buf) {
+        return 0;
+    }
+
+    int ret = -1;
+    // Maybe blocked at driver
+    ret = read(mInputFile, buf, msgCount);
+    if (ret < 0) {
+        ALOGE("[halimp_aidl] read :%s failed, ret:%d\n", HDMI_MSG_IN_FIFO, ret);
+        return -1;
+    }
+
+    return ret;
+}
+
+void HdmiConnectionMock::printEventBuf(const char* msg_buf, int len) {
+    int i, size = 0;
+    const int bufSize = MESSAGE_BODY_MAX_LENGTH * 3;
+    // Use 2 characters for each byte in the message plus 1 space
+    char buf[bufSize] = {0};
+
+    // Messages longer than max length will be truncated.
+    for (i = 0; i < len && size < bufSize; i++) {
+        size += sprintf(buf + size, " %02x", msg_buf[i]);
+    }
+    ALOGD("[halimp_aidl] %s, msg:%.*s", __FUNCTION__, size, buf);
+}
+
+void HdmiConnectionMock::handleHotplugMessage(unsigned char* msgBuf) {
+    bool connected = ((msgBuf[3]) & 0xf) > 0;
+    int32_t portId = static_cast<uint32_t>(msgBuf[0] & 0xf);
+
+    if (portId > static_cast<int32_t>(mPortInfos.size()) || portId < 1) {
+        ALOGD("[halimp_aidl] ignore hot plug message, id %x does not exist", portId);
+        return;
+    }
+
+    ALOGD("[halimp_aidl] hot plug port id %x, is connected %x", (msgBuf[0] & 0xf),
+          (msgBuf[3] & 0xf));
+    mPortConnectionStatus.at(portId - 1) = connected;
+    if (mPortInfos.at(portId - 1).type == HdmiPortType::OUTPUT) {
+        mPhysicalAddress = (connected ? 0xffff : ((msgBuf[1] << 8) | (msgBuf[2])));
+        mPortInfos.at(portId - 1).physicalAddress = mPhysicalAddress;
+        ALOGD("[halimp_aidl] hot plug physical address %x", mPhysicalAddress);
+    }
+
+    if (mCallback != nullptr) {
+        mCallback->onHotplugEvent(connected, portId);
+    }
+}
+
+void HdmiConnectionMock::threadLoop() {
+    ALOGD("[halimp_aidl] threadLoop start.");
+    unsigned char msgBuf[MESSAGE_BODY_MAX_LENGTH];
+    int r = -1;
+
+    // Open the input pipe
+    while (mInputFile < 0) {
+        usleep(1000 * 1000);
+        mInputFile = open(HDMI_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
+    }
+    ALOGD("[halimp_aidl] file open ok, fd = %d.", mInputFile);
+
+    while (mHdmiThreadRun) {
+        memset(msgBuf, 0, sizeof(msgBuf));
+        // Try to get a message from dev.
+        // echo -n -e '\x04\x83' >> /dev/cec
+        r = readMessageFromFifo(msgBuf, MESSAGE_BODY_MAX_LENGTH);
+        if (r <= 1) {
+            // Ignore received ping messages
+            continue;
+        }
+
+        printEventBuf((const char*)msgBuf, r);
+
+        if (((msgBuf[0] >> 4) & 0xf) == 0xf) {
+            handleHotplugMessage(msgBuf);
+        }
+    }
+
+    ALOGD("[halimp_aidl] thread end.");
+}
+
+HdmiConnectionMock::HdmiConnectionMock() {
+    ALOGE("[halimp_aidl] Opening a virtual HDMI HAL for testing and virtual machine.");
+    mCallback = nullptr;
+    mPortInfos.resize(mTotalPorts);
+    mPortConnectionStatus.resize(mTotalPorts);
+    mHpdSignal.resize(mTotalPorts);
+    mPortInfos[0] = {.type = HdmiPortType::OUTPUT,
+                     .portId = static_cast<uint32_t>(1),
+                     .cecSupported = true,
+                     .arcSupported = false,
+                     .eArcSupported = false,
+                     .physicalAddress = mPhysicalAddress};
+    mPortConnectionStatus[0] = false;
+    mHpdSignal[0] = HpdSignal::HDMI_HPD_PHYSICAL;
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+}
+
+}  // namespace implementation
+}  // namespace connection
+}  // namespace hdmi
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
new file mode 100644
index 0000000..c013fdd
--- /dev/null
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
+#include <aidl/android/hardware/tv/hdmi/connection/Result.h>
+#include <algorithm>
+#include <vector>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace hdmi {
+namespace connection {
+namespace implementation {
+
+using ::aidl::android::hardware::tv::hdmi::connection::BnHdmiConnection;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::connection::HpdSignal;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnection;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnectionCallback;
+using ::aidl::android::hardware::tv::hdmi::connection::Result;
+
+#define HDMI_MSG_IN_FIFO "/dev/hdmi_in_pipe"
+#define MESSAGE_BODY_MAX_LENGTH 4
+
+struct HdmiConnectionMock : public BnHdmiConnection {
+    HdmiConnectionMock();
+
+    ::ndk::ScopedAStatus getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) override;
+    ::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
+    ::ndk::ScopedAStatus setCallback(
+            const std::shared_ptr<IHdmiConnectionCallback>& callback) override;
+    ::ndk::ScopedAStatus setHpdSignal(HpdSignal signal, int32_t portId) override;
+    ::ndk::ScopedAStatus getHpdSignal(int32_t portId, HpdSignal* _aidl_return) override;
+
+    void printEventBuf(const char* msg_buf, int len);
+
+  private:
+    static void* __threadLoop(void* data);
+    void threadLoop();
+    int readMessageFromFifo(unsigned char* buf, int msgCount);
+    void handleHotplugMessage(unsigned char* msgBuf);
+
+  private:
+    static void serviceDied(void* cookie);
+    std::shared_ptr<IHdmiConnectionCallback> mCallback;
+
+    // Variables for the virtual HDMI hal impl
+    std::vector<HdmiPortInfo> mPortInfos;
+    std::vector<bool> mPortConnectionStatus;
+
+    // Port configuration
+    uint16_t mPhysicalAddress = 0xFFFF;
+    int mTotalPorts = 1;
+
+    // HPD Signal being used
+    std::vector<HpdSignal> mHpdSignal;
+
+    // Testing variables
+    // Input file descriptor
+    int mInputFile;
+    bool mHdmiThreadRun = true;
+    pthread_t mThreadId = 0;
+
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+};
+}  // namespace implementation
+}  // namespace connection
+}  // namespace hdmi
+}  // Namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.rc b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.rc
new file mode 100644
index 0000000..9e37e61
--- /dev/null
+++ b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.rc
@@ -0,0 +1,5 @@
+service vendor.hdmi-default /vendor/bin/hw/android.hardware.tv.hdmi.connection-service
+    interface aidl android.hardware.tv.hdmi.connection.IHdmiConnection/default
+    class hal
+    user system
+    group system
diff --git a/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.xml b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.xml
new file mode 100644
index 0000000..144fef1
--- /dev/null
+++ b/tv/hdmi/connection/aidl/default/android.hardware.tv.hdmi.connection-service.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.tv.hdmi.connection</name>
+        <version>1</version>
+        <interface>
+            <name>IHdmiConnection</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/tv/hdmi/connection/aidl/default/fuzzer.cpp b/tv/hdmi/connection/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..c5e33fa
--- /dev/null
+++ b/tv/hdmi/connection/aidl/default/fuzzer.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <HdmiConnectionMock.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using android::fuzzService;
+using android::hardware::tv::hdmi::connection::implementation::HdmiConnectionMock;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto hdmiAidl = SharedRefBase::make<HdmiConnectionMock>();
+
+    fuzzService(hdmiAidl->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/tv/hdmi/connection/aidl/default/serviceMock.cpp b/tv/hdmi/connection/aidl/default/serviceMock.cpp
new file mode 100644
index 0000000..223c578
--- /dev/null
+++ b/tv/hdmi/connection/aidl/default/serviceMock.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.hdmi.connection-service-shim"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <hidl/HidlTransportSupport.h>
+#include <utils/Log.h>
+#include "HdmiConnectionMock.h"
+
+using android::hardware::tv::hdmi::connection::implementation::HdmiConnectionMock;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+
+    std::shared_ptr<HdmiConnectionMock> hdmiAidl = ndk::SharedRefBase::make<HdmiConnectionMock>();
+    const std::string instance = std::string() + HdmiConnectionMock::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(hdmiAidl->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return 0;
+}
diff --git a/tv/hdmi/connection/aidl/vts/functional/Android.bp b/tv/hdmi/connection/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..fc8e2f7
--- /dev/null
+++ b/tv/hdmi/connection/aidl/vts/functional/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalTvHdmiConnectionAidlTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalTvHdmiConnectionAidlTargetTest.cpp"],
+    static_libs: [
+        "android.hardware.tv.hdmi.connection-V1-ndk",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    disable_framework: true,
+}
diff --git a/tv/hdmi/connection/aidl/vts/functional/AndroidTest.xml b/tv/hdmi/connection/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..5a7fed0
--- /dev/null
+++ b/tv/hdmi/connection/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalTvHdmiConnectionAidlTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalTvHdmiConnectionAidlTargetTest->/data/local/tmp/VtsHalTvHdmiConnectionAidlTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalTvHdmiConnectionAidlTargetTest" />
+        <option name="native-test-timeout" value="30m" />
+    </test>
+</configuration>
diff --git a/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp b/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp
new file mode 100644
index 0000000..a9b288b
--- /dev/null
+++ b/tv/hdmi/connection/aidl/vts/functional/VtsHalTvHdmiConnectionAidlTargetTest.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Hdmi_Connection_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
+#include <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnectionCallback.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <sstream>
+#include <vector>
+
+using ::aidl::android::hardware::tv::hdmi::connection::BnHdmiConnectionCallback;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo;
+using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::connection::HpdSignal;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnection;
+using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnectionCallback;
+using ::ndk::SpAIBinder;
+
+#define INCORRECT_VENDOR_ID 0x00
+#define TV_PHYSICAL_ADDRESS 0x0000
+
+// The main test class for TV HDMI Connection HAL.
+class HdmiConnectionTest : public ::testing::TestWithParam<std::string> {
+    static void serviceDied(void* /* cookie */) {
+        ALOGE("VtsHalTvHdmiConnectionAidlTargetTest died");
+    }
+
+  public:
+    void SetUp() override {
+        hdmiConnection = IHdmiConnection::fromBinder(
+                SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(hdmiConnection, nullptr);
+        ALOGI("%s: getService() for hdmiConnection is %s", __func__,
+              hdmiConnection->isRemote() ? "remote" : "local");
+
+        hdmiConnectionCallback = ::ndk::SharedRefBase::make<HdmiConnectionCallback>();
+        ASSERT_NE(hdmiConnectionCallback, nullptr);
+        hdmiConnectionDeathRecipient =
+                ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(&serviceDied));
+        ASSERT_EQ(AIBinder_linkToDeath(hdmiConnection->asBinder().get(),
+                                       hdmiConnectionDeathRecipient.get(), 0),
+                  STATUS_OK);
+    }
+
+    class HdmiConnectionCallback : public BnHdmiConnectionCallback {
+      public:
+        ::ndk::ScopedAStatus onHotplugEvent(bool connected __unused, int32_t portId __unused) {
+            return ::ndk::ScopedAStatus::ok();
+        };
+    };
+
+    std::shared_ptr<IHdmiConnection> hdmiConnection;
+    std::shared_ptr<IHdmiConnectionCallback> hdmiConnectionCallback;
+    ::ndk::ScopedAIBinder_DeathRecipient hdmiConnectionDeathRecipient;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HdmiConnectionTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, HdmiConnectionTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IHdmiConnection::descriptor)),
+        android::PrintInstanceNameToString);
+
+TEST_P(HdmiConnectionTest, SetCallback) {
+    ASSERT_TRUE(hdmiConnection->setCallback(::ndk::SharedRefBase::make<HdmiConnectionCallback>())
+                        .isOk());
+}
+
+TEST_P(HdmiConnectionTest, GetPortInfo) {
+    std::vector<HdmiPortInfo> ports;
+    ASSERT_TRUE(hdmiConnection->getPortInfo(&ports).isOk());
+
+    bool cecSupportedOnDevice = false;
+    for (size_t i = 0; i < ports.size(); ++i) {
+        EXPECT_TRUE((ports[i].type == HdmiPortType::OUTPUT) ||
+                    (ports[i].type == HdmiPortType::INPUT));
+        if (ports[i].type == HdmiPortType::OUTPUT && ports[i].portId <= 0) {
+            ALOGW("%s: Port id for output ports should start from 1", __func__);
+        }
+        cecSupportedOnDevice = cecSupportedOnDevice | ports[i].cecSupported;
+    }
+    EXPECT_NE(cecSupportedOnDevice, false) << "At least one port should support CEC";
+}
+
+TEST_P(HdmiConnectionTest, IsConnected) {
+    std::vector<HdmiPortInfo> ports;
+    ASSERT_TRUE(hdmiConnection->getPortInfo(&ports).isOk());
+    for (size_t i = 0; i < ports.size(); ++i) {
+        bool connected;
+        ASSERT_TRUE(hdmiConnection->isConnected(ports[i].portId, &connected).isOk());
+    }
+}
+
+TEST_P(HdmiConnectionTest, HdpSignal) {
+    std::vector<HdmiPortInfo> ports;
+    ASSERT_TRUE(hdmiConnection->getPortInfo(&ports).isOk());
+    HpdSignal originalSignal;
+    HpdSignal signal = HpdSignal::HDMI_HPD_STATUS_BIT;
+    for (size_t i = 0; i < ports.size(); ++i) {
+        int32_t portId = ports[i].portId;
+        HpdSignal readSignal;
+        ASSERT_TRUE(hdmiConnection->getHpdSignal(portId, &originalSignal).isOk());
+        ASSERT_TRUE(hdmiConnection->setHpdSignal(signal, portId).isOk());
+        ASSERT_TRUE(hdmiConnection->getHpdSignal(portId, &readSignal).isOk());
+        EXPECT_EQ(readSignal, signal);
+        signal = HpdSignal::HDMI_HPD_PHYSICAL;
+        ASSERT_TRUE(hdmiConnection->setHpdSignal(signal, portId).isOk());
+        ASSERT_TRUE(hdmiConnection->getHpdSignal(portId, &readSignal).isOk());
+        EXPECT_EQ(readSignal, signal);
+        ASSERT_TRUE(hdmiConnection->setHpdSignal(originalSignal, portId).isOk());
+    }
+}
diff --git a/tv/hdmi/earc/aidl/Android.bp b/tv/hdmi/earc/aidl/Android.bp
new file mode 100644
index 0000000..d08e46d
--- /dev/null
+++ b/tv/hdmi/earc/aidl/Android.bp
@@ -0,0 +1,38 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.tv.hdmi.earc",
+    vendor_available: true,
+    srcs: ["android/hardware/tv/hdmi/earc/*.aidl"],
+    imports: ["android.hardware.tv.hdmi.connection-V1"],
+    stability: "vintf",
+    backend: {
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: ["android.hardware.tv.hdmi.connection-V1"],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/tv/hdmi/earc/aidl/TEST_MAPPING b/tv/hdmi/earc/aidl/TEST_MAPPING
new file mode 100644
index 0000000..ccc48fc
--- /dev/null
+++ b/tv/hdmi/earc/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalTvHdmiEArcAidlTargetTest"
+    }
+  ]
+}
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/.hash b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/.hash
new file mode 100644
index 0000000..856086e
--- /dev/null
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/.hash
@@ -0,0 +1 @@
+101230f18c7b8438921e517e80eea4ccc7c1e463
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/IEArc.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/IEArc.aidl
new file mode 100644
index 0000000..1ea7df7
--- /dev/null
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/IEArc.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.earc;
+@VintfStability
+interface IEArc {
+  void setEArcEnabled(in boolean enabled);
+  boolean isEArcEnabled();
+  void setCallback(in android.hardware.tv.hdmi.earc.IEArcCallback callback);
+  android.hardware.tv.hdmi.earc.IEArcStatus getState(in int portId);
+  byte[] getLastReportedAudioCapabilities(in int portId);
+}
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/IEArcCallback.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
new file mode 100644
index 0000000..1730dcf
--- /dev/null
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.earc;
+@VintfStability
+interface IEArcCallback {
+  oneway void onStateChange(in android.hardware.tv.hdmi.earc.IEArcStatus status, in int portId);
+  oneway void onCapabilitiesReported(in byte[] rawCapabilities, in int portId);
+}
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/IEArcStatus.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
new file mode 100644
index 0000000..6dcbd8d
--- /dev/null
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.earc;
+@Backing(type="byte") @VintfStability
+enum IEArcStatus {
+  IDLE = 0,
+  EARC_PENDING = 1,
+  ARC_PENDING = 2,
+  EARC_CONNECTED = 3,
+}
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/Result.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/Result.aidl
new file mode 100644
index 0000000..b248f41
--- /dev/null
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/1/android/hardware/tv/hdmi/earc/Result.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.earc;
+@VintfStability
+enum Result {
+  SUCCESS = 0,
+  FAILURE_UNKNOWN = 1,
+  FAILURE_INVALID_ARGS = 2,
+  FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArc.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArc.aidl
new file mode 100644
index 0000000..1ea7df7
--- /dev/null
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArc.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.earc;
+@VintfStability
+interface IEArc {
+  void setEArcEnabled(in boolean enabled);
+  boolean isEArcEnabled();
+  void setCallback(in android.hardware.tv.hdmi.earc.IEArcCallback callback);
+  android.hardware.tv.hdmi.earc.IEArcStatus getState(in int portId);
+  byte[] getLastReportedAudioCapabilities(in int portId);
+}
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcCallback.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
new file mode 100644
index 0000000..1730dcf
--- /dev/null
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.earc;
+@VintfStability
+interface IEArcCallback {
+  oneway void onStateChange(in android.hardware.tv.hdmi.earc.IEArcStatus status, in int portId);
+  oneway void onCapabilitiesReported(in byte[] rawCapabilities, in int portId);
+}
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
new file mode 100644
index 0000000..6dcbd8d
--- /dev/null
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.earc;
+@Backing(type="byte") @VintfStability
+enum IEArcStatus {
+  IDLE = 0,
+  EARC_PENDING = 1,
+  ARC_PENDING = 2,
+  EARC_CONNECTED = 3,
+}
diff --git a/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/Result.aidl b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/Result.aidl
new file mode 100644
index 0000000..b248f41
--- /dev/null
+++ b/tv/hdmi/earc/aidl/aidl_api/android.hardware.tv.hdmi.earc/current/android/hardware/tv/hdmi/earc/Result.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.hdmi.earc;
+@VintfStability
+enum Result {
+  SUCCESS = 0,
+  FAILURE_UNKNOWN = 1,
+  FAILURE_INVALID_ARGS = 2,
+  FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
new file mode 100644
index 0000000..d9fb29c
--- /dev/null
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArc.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.earc;
+
+import android.hardware.tv.hdmi.earc.IEArcCallback;
+import android.hardware.tv.hdmi.earc.IEArcStatus;
+
+/**
+ * eARC HAL interface definition. This is only relevant to TV Panels that implement eARC TX.
+ */
+@VintfStability
+interface IEArc {
+    /**
+     * Function to enable or disable eARC in the device's driver and HAL. If enabled, the driver and
+     * HAL shall attempt to establish an eARC connection and inform the Android framework about
+     * updates with IEArcCallback callbacks. If disabled, the driver and HAL shall not attempt to
+     * establish an eARC connection and shall not send any IEArcCallback callbacks to the Android
+     * framework.
+     * @throws ServiceSpecificException with error code set to
+     *         {@code Result::FAILURE_NOT_SUPPORTED} if the eARC enabled setting could not be set
+     *                                               because this is not supported.
+     *         {@code Result::FAILURE_INVALID_ARGS} if the eARC enabled setting could not be set
+     *                                              because the method argument is invalid.
+     *         {@code Result::FAILURE_UNKNOWN} if the eARC enabled setting could not be set because
+     *                                         there was an unknown failure.
+     */
+    void setEArcEnabled(in boolean enabled);
+
+    /**
+     * Function to check if eARC is enabled in the device's driver and HAL.
+     */
+    boolean isEArcEnabled();
+
+    /**
+     * Function to set callback that the HAL will use to notify the system of connection state
+     * changes and capabilities of connected devices.
+     *
+     * @param callback The callback object to pass the events to the system. A previously registered
+     *        callback should be replaced by this new object. If callback is {@code null} the
+     *        previously registered callback should be deregistered.
+     */
+    void setCallback(in IEArcCallback callback);
+
+    /**
+     * Getter for the current eARC state of a port.
+     *
+     * @param portId The port ID for which the state is to be reported.
+     * @return The state of the port.
+     */
+    IEArcStatus getState(in int portId);
+
+    /**
+     * Getter for the most recent audio capabilities reported by the device connected to port.
+     *
+     * @param portId The port ID on which the device is connected.
+     * @return a byte array containing the raw, unparsed audio capabilities (Ref "Section 9.5.3.6 -
+     * eARC RX Capabilities Data Structure" in HDMI 2.1 specification).
+     */
+    byte[] getLastReportedAudioCapabilities(in int portId);
+}
diff --git a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
new file mode 100644
index 0000000..ea77c54
--- /dev/null
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcCallback.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.earc;
+
+import android.hardware.tv.hdmi.earc.IEArcStatus;
+
+/**
+ * eARC HAL callback methods
+ */
+@VintfStability
+oneway interface IEArcCallback {
+    /**
+     * The callback function that must be called by the eARC driver and HAL implementation to notify
+     * the Android framework of an eARC status change.
+     * @param status The new status of the port
+     * @param portId The port ID for which the state change is being reported
+     */
+    void onStateChange(in IEArcStatus status, in int portId);
+
+    /**
+     * The callback function that must be called by the eARC driver and HAL implementation to
+     * notify the Android framework of the audio capabilities reported by the connected device. On
+     * every state change to {@code IEArcStatus::EARC_CONNECTED}, the driver shall read the
+     * capabilities reported by the eARC RX. The onStateChange callback shall always be invoked
+     * first and the onCapabilitiesReported callback shall be invoked second.
+     * @param rawCapabilities The raw unparsed audio capabilities (Ref "Section 9.5.3.6 - eARC RX
+     *         Capabilities Data Structure" in HDMI 2.1 specification).
+     * @param portId The port ID for which the audio capabilities are being reported
+     */
+    void onCapabilitiesReported(in byte[] rawCapabilities, in int portId);
+}
diff --git a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
new file mode 100644
index 0000000..5407434
--- /dev/null
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/IEArcStatus.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.earc;
+
+/**
+ * eARC HAL connection states
+ */
+@VintfStability
+@Backing(type="byte")
+enum IEArcStatus {
+    IDLE = 0,
+    EARC_PENDING = 1,
+    ARC_PENDING = 2,
+    EARC_CONNECTED = 3,
+}
diff --git a/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/Result.aidl b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/Result.aidl
new file mode 100644
index 0000000..268610d
--- /dev/null
+++ b/tv/hdmi/earc/aidl/android/hardware/tv/hdmi/earc/Result.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.hdmi.earc;
+
+/**
+ * Result enum for return values. Used by the HDMI related AIDL.
+ */
+@VintfStability
+enum Result {
+    /**
+     * The eARC enabled setting was set successfully.
+     */
+    SUCCESS = 0,
+
+    /**
+     * The eARC enabled setting could not be set because of an unknown failure.
+     */
+    FAILURE_UNKNOWN = 1,
+
+    /**
+     * The eARC enabled setting could not be set because the arguments were invalid.
+     */
+    FAILURE_INVALID_ARGS = 2,
+
+    /**
+     * The eARC enabled setting could not be set because eARC feature is not supported.
+     */
+    FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/hdmi/earc/aidl/default/Android.bp b/tv/hdmi/earc/aidl/default/Android.bp
new file mode 100644
index 0000000..5d56c2a
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/Android.bp
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+    name: "android.hardware.tv.hdmi.earc-service",
+    vintf_fragments: ["android.hardware.tv.hdmi.earc-service.xml"],
+    relative_install_path: "hw",
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+    ],
+    init_rc: ["android.hardware.tv.hdmi.earc-service.rc"],
+    srcs: [
+        "serviceMock.cpp",
+        "EArcMock.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "liblog",
+        "libbase",
+        "libutils",
+        "libhardware",
+        "libhidlbase",
+        "android.hardware.tv.hdmi.earc-V1-ndk",
+    ],
+}
+
+cc_fuzz {
+    name: "android.hardware.tv.hdmi.earc-service_fuzzer",
+    defaults: ["service_fuzzer_defaults"],
+    static_libs: [
+        "android.hardware.tv.hdmi.earc-V1-ndk",
+        "liblog",
+    ],
+    srcs: [
+        "fuzzer.cpp",
+        "EArcMock.cpp",
+    ],
+    fuzz_config: {
+        componentid: 826094,
+    },
+}
diff --git a/tv/hdmi/earc/aidl/default/EArcMock.cpp b/tv/hdmi/earc/aidl/default/EArcMock.cpp
new file mode 100644
index 0000000..0e92fbd
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/EArcMock.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.hdmi.earc"
+#include <android-base/logging.h>
+#include <fcntl.h>
+#include <utils/Log.h>
+
+#include "EArcMock.h"
+
+using ndk::ScopedAStatus;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace hdmi {
+namespace earc {
+namespace implementation {
+
+void EArcMock::serviceDied(void* cookie) {
+    ALOGE("EArcMock died");
+    auto eArc = static_cast<EArcMock*>(cookie);
+    eArc->mEArcEnabled = false;
+}
+
+ScopedAStatus EArcMock::setEArcEnabled(bool in_enabled) {
+    mEArcEnabled = in_enabled;
+    if (mEArcEnabled != in_enabled) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::FAILURE_UNKNOWN));
+    } else {
+        return ScopedAStatus::ok();
+    }
+}
+
+ScopedAStatus EArcMock::isEArcEnabled(bool* _aidl_return) {
+    *_aidl_return = mEArcEnabled;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::getState(int32_t portId, IEArcStatus* _aidl_return) {
+    // Maintain port connection status and update on hotplug event
+    if (portId <= mTotalPorts && portId >= 1) {
+        *_aidl_return = mPortStatus.at(portId - 1);
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::getLastReportedAudioCapabilities(int32_t portId,
+                                                         std::vector<uint8_t>* _aidl_return) {
+    if (portId <= mTotalPorts && portId >= 1) {
+        *_aidl_return = mCapabilities.at(portId - 1);
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::setCallback(const std::shared_ptr<IEArcCallback>& callback) {
+    if (mCallback != nullptr) {
+        mCallback = nullptr;
+    }
+
+    if (callback != nullptr) {
+        mCallback = callback;
+        AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::reportCapabilities(const std::vector<uint8_t>& capabilities,
+                                           int32_t portId) {
+    if (mCallback != nullptr) {
+        mCallback->onCapabilitiesReported(capabilities, portId);
+        return ScopedAStatus::ok();
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
+}
+
+ScopedAStatus EArcMock::changeState(const IEArcStatus status, int32_t portId) {
+    if (mCallback != nullptr) {
+        mCallback->onStateChange(status, portId);
+        return ScopedAStatus::ok();
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
+}
+
+EArcMock::EArcMock() {
+    ALOGE("[halimp_aidl] Opening a virtual eARC HAL for testing and virtual machine.");
+    mCallback = nullptr;
+    mCapabilities.resize(mTotalPorts);
+    mPortStatus.resize(mTotalPorts);
+    mPortStatus[0] = IEArcStatus::IDLE;
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+}
+
+}  // namespace implementation
+}  // namespace earc
+}  // namespace hdmi
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/hdmi/earc/aidl/default/EArcMock.h b/tv/hdmi/earc/aidl/default/EArcMock.h
new file mode 100644
index 0000000..8af9706
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/EArcMock.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/tv/hdmi/earc/BnEArc.h>
+#include <aidl/android/hardware/tv/hdmi/earc/Result.h>
+#include <algorithm>
+#include <vector>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace hdmi {
+namespace earc {
+namespace implementation {
+
+using ::aidl::android::hardware::tv::hdmi::earc::BnEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcStatus;
+using ::aidl::android::hardware::tv::hdmi::earc::Result;
+
+struct EArcMock : public BnEArc {
+    EArcMock();
+
+    ::ndk::ScopedAStatus setEArcEnabled(bool in_enabled) override;
+    ::ndk::ScopedAStatus isEArcEnabled(bool* _aidl_return) override;
+    ::ndk::ScopedAStatus setCallback(const std::shared_ptr<IEArcCallback>& in_callback) override;
+    ::ndk::ScopedAStatus getState(int32_t in_portId, IEArcStatus* _aidl_return) override;
+    ::ndk::ScopedAStatus getLastReportedAudioCapabilities(
+            int32_t in_portId, std::vector<uint8_t>* _aidl_return) override;
+    ::ndk::ScopedAStatus reportCapabilities(const std::vector<uint8_t>& capabilities,
+                                            int32_t portId);
+    ::ndk::ScopedAStatus changeState(const IEArcStatus status, int32_t portId);
+
+  private:
+    static void* __threadLoop(void* data);
+    void threadLoop();
+
+  private:
+    static void serviceDied(void* cookie);
+    std::shared_ptr<IEArcCallback> mCallback;
+
+    // Variables for the virtual EARC hal impl
+    std::vector<std::vector<uint8_t>> mCapabilities;
+    std::vector<IEArcStatus> mPortStatus;
+    bool mEArcEnabled = true;
+
+    // Port configuration
+    int mTotalPorts = 1;
+
+    // Testing variables
+    pthread_t mThreadId = 0;
+
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+};
+}  // namespace implementation
+}  // namespace earc
+}  // Namespace hdmi
+}  // Namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc
new file mode 100644
index 0000000..53bec04
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc
@@ -0,0 +1,5 @@
+service vendor.earc-default /vendor/bin/hw/android.hardware.tv.hdmi.earc-service
+    interface aidl android.hardware.tv.hdmi.earc.IEArc/default
+    class hal
+    user system
+    group system
diff --git a/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
new file mode 100644
index 0000000..6f8d03d
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.tv.hdmi.earc</name>
+        <version>1</version>
+        <interface>
+            <name>IEArc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/tv/hdmi/earc/aidl/default/fuzzer.cpp b/tv/hdmi/earc/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..25264ae
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/fuzzer.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <EArcMock.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using android::fuzzService;
+using android::hardware::tv::hdmi::earc::implementation::EArcMock;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto earcAidl = SharedRefBase::make<EArcMock>();
+
+    fuzzService(earcAidl->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/tv/hdmi/earc/aidl/default/serviceMock.cpp b/tv/hdmi/earc/aidl/default/serviceMock.cpp
new file mode 100644
index 0000000..0878e76
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/serviceMock.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.hdmi.earc-service-shim"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <hidl/HidlTransportSupport.h>
+#include <utils/Log.h>
+#include "EArcMock.h"
+
+using android::hardware::tv::hdmi::earc::implementation::EArcMock;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+
+    std::shared_ptr<EArcMock> earcAidl = ndk::SharedRefBase::make<EArcMock>();
+    const std::string instance = std::string() + EArcMock::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(earcAidl->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return 0;
+}
diff --git a/tv/hdmi/earc/aidl/vts/functional/Android.bp b/tv/hdmi/earc/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..36fbf56
--- /dev/null
+++ b/tv/hdmi/earc/aidl/vts/functional/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalTvHdmiEArcAidlTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalTvHdmiEArcAidlTargetTest.cpp"],
+    static_libs: [
+        "android.hardware.tv.hdmi.earc-V1-ndk",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    disable_framework: true,
+}
diff --git a/tv/hdmi/earc/aidl/vts/functional/AndroidTest.xml b/tv/hdmi/earc/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..12dd1e4
--- /dev/null
+++ b/tv/hdmi/earc/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalTvHdmiEArcAidlTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalTvHdmiEArcAidlTargetTest->/data/local/tmp/VtsHalTvHdmiEArcAidlTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalTvHdmiEArcAidlTargetTest" />
+        <option name="native-test-timeout" value="30m" />
+    </test>
+</configuration>
diff --git a/tv/hdmi/earc/aidl/vts/functional/VtsHalTvHdmiEArcAidlTargetTest.cpp b/tv/hdmi/earc/aidl/vts/functional/VtsHalTvHdmiEArcAidlTargetTest.cpp
new file mode 100644
index 0000000..3cd8577
--- /dev/null
+++ b/tv/hdmi/earc/aidl/vts/functional/VtsHalTvHdmiEArcAidlTargetTest.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "EArc_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/tv/hdmi/earc/BnEArcCallback.h>
+#include <aidl/android/hardware/tv/hdmi/earc/IEArc.h>
+#include <aidl/android/hardware/tv/hdmi/earc/IEArcStatus.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <sstream>
+#include <vector>
+
+using ::aidl::android::hardware::tv::hdmi::earc::BnEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcStatus;
+using ::ndk::SpAIBinder;
+
+// The main test class for TV EARC HAL.
+class EArcTest : public ::testing::TestWithParam<std::string> {
+    static void serviceDied(void* /* cookie */) { ALOGE("VtsHalTvCecAidlTargetTest died"); }
+
+  public:
+    void SetUp() override {
+        eArc = IEArc::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(eArc, nullptr);
+        ALOGI("%s: getService() for eArc is %s", __func__, eArc->isRemote() ? "remote" : "local");
+
+        eArcCallback = ::ndk::SharedRefBase::make<EArcCallback>();
+        ASSERT_NE(eArcCallback, nullptr);
+        eArcDeathRecipient =
+                ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(&serviceDied));
+        ASSERT_EQ(AIBinder_linkToDeath(eArc->asBinder().get(), eArcDeathRecipient.get(), 0),
+                  STATUS_OK);
+    }
+
+    class EArcCallback : public BnEArcCallback {
+      public:
+        ::ndk::ScopedAStatus onStateChange(IEArcStatus connected __unused,
+                                           int32_t portId __unused) {
+            return ::ndk::ScopedAStatus::ok();
+        };
+        ::ndk::ScopedAStatus onCapabilitiesReported(
+                const std::vector<uint8_t>& capabilities __unused, int32_t portId __unused) {
+            return ::ndk::ScopedAStatus::ok();
+        };
+    };
+
+    std::shared_ptr<IEArc> eArc;
+    std::shared_ptr<IEArcCallback> eArcCallback;
+    ::ndk::ScopedAIBinder_DeathRecipient eArcDeathRecipient;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EArcTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, EArcTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IEArc::descriptor)),
+                         android::PrintInstanceNameToString);
+
+TEST_P(EArcTest, setGetEArcEnabled) {
+    bool initial_state;
+    bool changed_state;
+    ASSERT_TRUE(eArc->isEArcEnabled(&initial_state).isOk());
+    ASSERT_TRUE(eArc->setEArcEnabled(!initial_state).isOk());
+    ASSERT_TRUE(eArc->isEArcEnabled(&changed_state).isOk());
+    ASSERT_TRUE(initial_state != changed_state);
+    ASSERT_TRUE(eArc->setEArcEnabled(initial_state).isOk());
+}
+
+TEST_P(EArcTest, SetCallback) {
+    ASSERT_TRUE(eArc->setCallback(eArcCallback).isOk());
+}
+
+TEST_P(EArcTest, GetState) {
+    IEArcStatus connectionStatus;
+    ASSERT_TRUE(eArc->getState(1, &connectionStatus).isOk());
+}
+
+TEST_P(EArcTest, GetLastReportedAudioCapabilities) {
+    std::vector<uint8_t> capabilities;
+    ASSERT_TRUE(eArc->getLastReportedAudioCapabilities(1, &capabilities).isOk());
+}
diff --git a/tv/input/OWNERS b/tv/input/OWNERS
new file mode 100644
index 0000000..ae65f67
--- /dev/null
+++ b/tv/input/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 105688
+hgchen@google.com
+shubang@google.com
+quxiangfang@google.com
+yixiaoluo@google.com
diff --git a/tv/input/aidl/Android.bp b/tv/input/aidl/Android.bp
new file mode 100644
index 0000000..35f510a
--- /dev/null
+++ b/tv/input/aidl/Android.bp
@@ -0,0 +1,40 @@
+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"],
+}
+
+aidl_interface {
+    name: "android.hardware.tv.input",
+    vendor_available: true,
+    srcs: ["android/hardware/tv/input/*.aidl"],
+    imports: [
+        "android.hardware.common-V2",
+        "android.media.audio.common.types-V1",
+        "android.hardware.common.fmq-V1",
+    ],
+    stability: "vintf",
+    backend: {
+        java: {
+            sdk_version: "module_current",
+        },
+        cpp: {
+            enabled: false,
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [
+                "android.hardware.common-V2",
+                "android.media.audio.common.types-V1",
+                "android.hardware.common.fmq-V1",
+            ],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/tv/input/aidl/TEST_MAPPING b/tv/input/aidl/TEST_MAPPING
new file mode 100644
index 0000000..981e46f
--- /dev/null
+++ b/tv/input/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalTvInputTargetTest"
+    }
+  ]
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/.hash b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/.hash
new file mode 100644
index 0000000..0bd248b
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/.hash
@@ -0,0 +1 @@
+b247370748c1e172b1279ecdc6d23d14b225bbdc
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/CableConnectionStatus.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/CableConnectionStatus.aidl
new file mode 100644
index 0000000..a48bdb1
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/CableConnectionStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum CableConnectionStatus {
+  UNKNOWN = 0,
+  CONNECTED = 1,
+  DISCONNECTED = 2,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/ITvInput.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/ITvInput.aidl
new file mode 100644
index 0000000..84fe2fb
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/ITvInput.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+interface ITvInput {
+  void closeStream(in int deviceId, in int streamId);
+  android.hardware.tv.input.TvStreamConfig[] getStreamConfigurations(in int deviceId);
+  android.hardware.common.NativeHandle openStream(in int deviceId, in int streamId);
+  void setCallback(in android.hardware.tv.input.ITvInputCallback callback);
+  void setTvMessageEnabled(int deviceId, int streamId, in android.hardware.tv.input.TvMessageEventType type, boolean enabled);
+  void getTvMessageQueueDesc(out android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> queue, int deviceId, int streamId);
+  const int STATUS_UNKNOWN = 1;
+  const int STATUS_NO_RESOURCE = 2;
+  const int STATUS_INVALID_ARGUMENTS = 3;
+  const int STATUS_INVALID_STATE = 4;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/ITvInputCallback.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/ITvInputCallback.aidl
new file mode 100644
index 0000000..9747013
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/ITvInputCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+interface ITvInputCallback {
+  void notify(in android.hardware.tv.input.TvInputEvent event);
+  void notifyTvMessageEvent(in android.hardware.tv.input.TvMessageEvent event);
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputDeviceInfo.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputDeviceInfo.aidl
new file mode 100644
index 0000000..d095146
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputDeviceInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvInputDeviceInfo {
+  int deviceId;
+  android.hardware.tv.input.TvInputType type;
+  int portId;
+  android.hardware.tv.input.CableConnectionStatus cableConnectionStatus;
+  android.media.audio.common.AudioDevice audioDevice;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputEvent.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputEvent.aidl
new file mode 100644
index 0000000..cfa8a34
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputEvent.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvInputEvent {
+  android.hardware.tv.input.TvInputEventType type;
+  android.hardware.tv.input.TvInputDeviceInfo deviceInfo;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputEventType.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputEventType.aidl
new file mode 100644
index 0000000..a9f518a
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum TvInputEventType {
+  DEVICE_AVAILABLE = 1,
+  DEVICE_UNAVAILABLE = 2,
+  STREAM_CONFIGURATIONS_CHANGED = 3,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputType.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputType.aidl
new file mode 100644
index 0000000..7e44a7d
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvInputType.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum TvInputType {
+  OTHER = 1,
+  TUNER = 2,
+  COMPOSITE = 3,
+  SVIDEO = 4,
+  SCART = 5,
+  COMPONENT = 6,
+  VGA = 7,
+  DVI = 8,
+  HDMI = 9,
+  DISPLAY_PORT = 10,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvMessage.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvMessage.aidl
new file mode 100644
index 0000000..04cb099
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvMessage.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvMessage {
+  String subType;
+  long groupId;
+  int dataLengthBytes;
+  const long NO_GROUP_ID = (-1) /* -1 */;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvMessageEvent.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvMessageEvent.aidl
new file mode 100644
index 0000000..94fe665
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvMessageEvent.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvMessageEvent {
+  android.hardware.tv.input.TvMessageEventType type;
+  int streamId;
+  android.hardware.tv.input.TvMessage[] messages;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvMessageEventType.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvMessageEventType.aidl
new file mode 100644
index 0000000..3006198
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvMessageEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum TvMessageEventType {
+  WATERMARK = 1,
+  CLOSED_CAPTION = 2,
+  OTHER = 1000,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvStreamConfig.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvStreamConfig.aidl
new file mode 100644
index 0000000..8378ff3
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/1/android/hardware/tv/input/TvStreamConfig.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvStreamConfig {
+  int streamId;
+  int maxVideoWidth;
+  int maxVideoHeight;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/CableConnectionStatus.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/CableConnectionStatus.aidl
new file mode 100644
index 0000000..a48bdb1
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/CableConnectionStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum CableConnectionStatus {
+  UNKNOWN = 0,
+  CONNECTED = 1,
+  DISCONNECTED = 2,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
new file mode 100644
index 0000000..84fe2fb
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+interface ITvInput {
+  void closeStream(in int deviceId, in int streamId);
+  android.hardware.tv.input.TvStreamConfig[] getStreamConfigurations(in int deviceId);
+  android.hardware.common.NativeHandle openStream(in int deviceId, in int streamId);
+  void setCallback(in android.hardware.tv.input.ITvInputCallback callback);
+  void setTvMessageEnabled(int deviceId, int streamId, in android.hardware.tv.input.TvMessageEventType type, boolean enabled);
+  void getTvMessageQueueDesc(out android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> queue, int deviceId, int streamId);
+  const int STATUS_UNKNOWN = 1;
+  const int STATUS_NO_RESOURCE = 2;
+  const int STATUS_INVALID_ARGUMENTS = 3;
+  const int STATUS_INVALID_STATE = 4;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInputCallback.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInputCallback.aidl
new file mode 100644
index 0000000..9747013
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInputCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+interface ITvInputCallback {
+  void notify(in android.hardware.tv.input.TvInputEvent event);
+  void notifyTvMessageEvent(in android.hardware.tv.input.TvMessageEvent event);
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputDeviceInfo.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputDeviceInfo.aidl
new file mode 100644
index 0000000..d095146
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputDeviceInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvInputDeviceInfo {
+  int deviceId;
+  android.hardware.tv.input.TvInputType type;
+  int portId;
+  android.hardware.tv.input.CableConnectionStatus cableConnectionStatus;
+  android.media.audio.common.AudioDevice audioDevice;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEvent.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEvent.aidl
new file mode 100644
index 0000000..cfa8a34
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEvent.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvInputEvent {
+  android.hardware.tv.input.TvInputEventType type;
+  android.hardware.tv.input.TvInputDeviceInfo deviceInfo;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEventType.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEventType.aidl
new file mode 100644
index 0000000..a9f518a
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum TvInputEventType {
+  DEVICE_AVAILABLE = 1,
+  DEVICE_UNAVAILABLE = 2,
+  STREAM_CONFIGURATIONS_CHANGED = 3,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputType.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputType.aidl
new file mode 100644
index 0000000..7e44a7d
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputType.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum TvInputType {
+  OTHER = 1,
+  TUNER = 2,
+  COMPOSITE = 3,
+  SVIDEO = 4,
+  SCART = 5,
+  COMPONENT = 6,
+  VGA = 7,
+  DVI = 8,
+  HDMI = 9,
+  DISPLAY_PORT = 10,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessage.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessage.aidl
new file mode 100644
index 0000000..04cb099
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessage.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvMessage {
+  String subType;
+  long groupId;
+  int dataLengthBytes;
+  const long NO_GROUP_ID = (-1) /* -1 */;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEvent.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEvent.aidl
new file mode 100644
index 0000000..94fe665
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEvent.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvMessageEvent {
+  android.hardware.tv.input.TvMessageEventType type;
+  int streamId;
+  android.hardware.tv.input.TvMessage[] messages;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEventType.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEventType.aidl
new file mode 100644
index 0000000..3006198
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum TvMessageEventType {
+  WATERMARK = 1,
+  CLOSED_CAPTION = 2,
+  OTHER = 1000,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvStreamConfig.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvStreamConfig.aidl
new file mode 100644
index 0000000..8378ff3
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvStreamConfig.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvStreamConfig {
+  int streamId;
+  int maxVideoWidth;
+  int maxVideoHeight;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/CableConnectionStatus.aidl b/tv/input/aidl/android/hardware/tv/input/CableConnectionStatus.aidl
new file mode 100644
index 0000000..64b79dd
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/CableConnectionStatus.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+/**
+ * Status of cable connection.
+ * This status is for devices having availability to detect the cable in a mechanical way,
+ * regardless of whether the connected external device is electrically on or not.
+ * If the device does not have such capability, you must use UNKNOWN.
+ */
+@VintfStability
+@Backing(type="int")
+enum CableConnectionStatus {
+    UNKNOWN = 0,
+    CONNECTED = 1,
+    DISCONNECTED = 2,
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl b/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
new file mode 100644
index 0000000..c63e0ac
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.hardware.tv.input.ITvInputCallback;
+import android.hardware.tv.input.TvMessageEventType;
+import android.hardware.tv.input.TvStreamConfig;
+
+@VintfStability
+interface ITvInput {
+    /**
+     * ServiceSpecificException values for ITvInput requests
+     */
+    const int STATUS_UNKNOWN = 1;
+    const int STATUS_NO_RESOURCE = 2;
+    const int STATUS_INVALID_ARGUMENTS = 3;
+    const int STATUS_INVALID_STATE = 4;
+
+    /**
+     * Closes a specific stream in a device.
+     *
+     * @param deviceId Device ID for the stream to close.
+     * @param streamId Stream ID for the stream to close.
+     * @throws ServiceSpecificException with values from the ITvInput::STATUS_* constants
+     */
+    void closeStream(in int deviceId, in int streamId);
+
+    /**
+     * Gets stream configurations for a specific device.
+     *
+     * The configs object is valid only until the next
+     * STREAM_CONFIGURATIONS_CHANGED event.
+     *
+     * @param deviceId Device ID for the configurations.
+     * @return the array of available configurations.
+     * @throws ServiceSpecificException with values from the ITvInput::STATUS_* constants
+     */
+    TvStreamConfig[] getStreamConfigurations(in int deviceId);
+
+    /**
+     * Opens a specific stream in a device.
+     *
+     * @param deviceId Device ID for the stream to open.
+     * @param streamId Stream ID for the stream to open. Must be one of the
+     *         stream IDs returned from getStreamConfigurations().
+     * @return the handle for sideband stream.
+     * @throws ServiceSpecificException with values from the ITvInput::STATUS_* constants
+     */
+    NativeHandle openStream(in int deviceId, in int streamId);
+
+    /**
+     * Sets a callback for events.
+     *
+     * Note that initially no device is available in the client side, so the
+     * implementation must notify all the currently available devices including
+     * static devices via callback once callback is set.
+     *
+     * @param callback Callback object to pass events.
+     * @throws ServiceSpecificException with values from the ITvInput::STATUS_* constants
+     */
+    void setCallback(in ITvInputCallback callback);
+
+    /**
+     * Enables or disables TV message detection for the specified stream on the device.
+     *
+     * @param deviceId The ID of the device that contains the stream to set the flag for.
+     * @param streamId The ID of the stream to set the flag for.
+     * @param type The type of {@link android.hardware.tv.input.TvMessageEventType}.
+     * @param enabled {@code true} if you want to enable TV message detection
+     *                {@code false} otherwise.
+     */
+    void setTvMessageEnabled(
+            int deviceId, int streamId, in TvMessageEventType type, boolean enabled);
+
+    /**
+     * Gets the TV message queue for the specified stream on the device.
+     *
+     * The FMQ is used to relay events that are parsed from the specified stream to the
+     * app or service responsible for processing the message. The HAL implementation
+     * is expected to parse these messages and add them to the queue as new events are
+     * detected from the stream based on whether or not they are enabled by
+     * {@link #setTvMessageEnabled(int, int, TvMessageEventType, boolean)}.
+     *
+     * This queue is expected to already contain the message data before calling
+     * {@link android.hardware.tv.input.ITvInputCallback#notifyTvMessageEvent}.
+     * The HAL implementation is expected to have already created the queue
+     * before the notification callback is called for the first time.
+     *
+     * @param deviceId The ID of the device that contains the stream to get the queue for.
+     * @param streamId THe ID of the stream to get the queue for.
+     * @return The descriptor of the TV message queue.
+     */
+    void getTvMessageQueueDesc(
+            out MQDescriptor<byte, SynchronizedReadWrite> queue, int deviceId, int streamId);
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl b/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl
new file mode 100644
index 0000000..a3afd41
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.tv.input.TvInputEvent;
+import android.hardware.tv.input.TvMessageEvent;
+
+@VintfStability
+interface ITvInputCallback {
+    /**
+     * Notifies the client that an event has occurred. For possible event types,
+     * check TvInputEventType.
+     *
+     * @param event Event passed to the client.
+     */
+    void notify(in TvInputEvent event);
+    /**
+     * Notifies the client that an TV message event has occurred. For possible event types,
+     * check {@link android.hardware.tv.input.TvMessageEventType}.
+     *
+     * The first message in a list of messages contained in a
+     * {@link android.hardware.tv.input.TvMessageEvent} should always have a
+     * {@link android.hardware.tv.input.TvMessage#subType} of "device_id",
+     * otherwise the event is discarded. When the subType of a message is "device_id", the ID of
+     * the device that sent the message should be contained in
+     * {@link android.hardware.tv.input.TvMessage#groupId}
+     *
+     * Invoking this callback for the first time immediately triggers
+     * {@link android.hardware.tv.input.ITvInput#getTvMessageQueueDesc}. It is
+     * expected for the queue to be ready with
+     * the relevant messages for the event before this callback is called.
+     *
+     * @param event Event passed to the client.
+     */
+    void notifyTvMessageEvent(in TvMessageEvent event);
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvInputDeviceInfo.aidl b/tv/input/aidl/android/hardware/tv/input/TvInputDeviceInfo.aidl
new file mode 100644
index 0000000..2782e90
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvInputDeviceInfo.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.tv.input.CableConnectionStatus;
+import android.hardware.tv.input.TvInputType;
+import android.media.audio.common.AudioDevice;
+
+@VintfStability
+parcelable TvInputDeviceInfo {
+    int deviceId;
+    TvInputType type;
+
+    /* HDMI port ID number. e.g. 2 for HDMI 2. */
+    int portId;
+
+    /* Cable connection status. */
+    CableConnectionStatus cableConnectionStatus;
+
+    /* Audio device info. */
+    AudioDevice audioDevice;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvInputEvent.aidl b/tv/input/aidl/android/hardware/tv/input/TvInputEvent.aidl
new file mode 100644
index 0000000..66ca7aa
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvInputEvent.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.tv.input.TvInputDeviceInfo;
+import android.hardware.tv.input.TvInputEventType;
+
+@VintfStability
+parcelable TvInputEvent {
+    TvInputEventType type;
+
+    /**
+     * TvInputEventType::DEVICE_AVAILABLE: all fields are relevant.
+     * TvInputEventType::DEVICE_UNAVAILABLE: only deviceId is relevant.
+     * TvInputEventType::STREAM_CONFIGURATIONS_CHANGED: only deviceId is relevant.
+     */
+    TvInputDeviceInfo deviceInfo;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvInputEventType.aidl b/tv/input/aidl/android/hardware/tv/input/TvInputEventType.aidl
new file mode 100644
index 0000000..fcbc3c2
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvInputEventType.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+@VintfStability
+@Backing(type="int")
+enum TvInputEventType {
+    /**
+     * Hardware notifies the framework that a device is available.
+     *
+     * Note that DEVICE_AVAILABLE and DEVICE_UNAVAILABLE events do not represent
+     * hotplug events (i.e. plugging cable into or out of the physical port).
+     * These events notify the framework whether the port is available or not.
+     * For a concrete example, when a user plugs in or pulls out the HDMI cable
+     * from a HDMI port, it does not generate DEVICE_AVAILABLE and/or
+     * DEVICE_UNAVAILABLE events. However, if a user inserts a pluggable USB
+     * tuner into the Android device, it must generate a DEVICE_AVAILABLE event
+     * and when the port is removed, it must generate a DEVICE_UNAVAILABLE
+     * event.
+     *
+     * For hotplug events, please see STREAM_CONFIGURATION_CHANGED for more
+     * details.
+     *
+     * HAL implementation must register devices by using this event when the
+     * device boots up. The framework must recognize device reported via this
+     * event only.
+     */
+    DEVICE_AVAILABLE = 1,
+
+    /**
+     * Hardware notifies the framework that a device is unavailable.
+     *
+     * HAL implementation must generate this event when a device registered
+     * by DEVICE_AVAILABLE is no longer available. For example,
+     * the event can indicate that a USB tuner is plugged out from the Android
+     * device.
+     *
+     * Note that this event is not for indicating cable plugged out of the port;
+     * for that purpose, the implementation must use
+     * STREAM_CONFIGURATION_CHANGED event. This event represents the port itself
+     * being no longer available.
+     */
+    DEVICE_UNAVAILABLE = 2,
+
+    /**
+     * Stream configurations are changed. Client must regard all open streams
+     * at the specific device are closed, and must call
+     * getStreamConfigurations() again, opening some of them if necessary.
+     *
+     * HAL implementation must generate this event when the available stream
+     * configurations change for any reason. A typical use case of this event
+     * is to notify the framework that the input signal has changed resolution,
+     * or that the cable is plugged out so that the number of available streams
+     * is 0.
+     *
+     * The implementation must use this event to indicate hotplug status of the
+     * port. the framework regards input devices with no available streams as
+     * disconnected, so the implementation can generate this event with no
+     * available streams to indicate that this device is disconnected, and vice
+     * versa.
+     */
+    STREAM_CONFIGURATIONS_CHANGED = 3,
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvInputType.aidl b/tv/input/aidl/android/hardware/tv/input/TvInputType.aidl
new file mode 100644
index 0000000..a0f8270
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvInputType.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+/**
+ * Type of physical TV input.
+ */
+@VintfStability
+@Backing(type="int")
+enum TvInputType {
+    OTHER = 1,
+    TUNER = 2,
+    COMPOSITE = 3,
+    SVIDEO = 4,
+    SCART = 5,
+    COMPONENT = 6,
+    VGA = 7,
+    DVI = 8,
+    HDMI = 9,
+    DISPLAY_PORT = 10,
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl b/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl
new file mode 100644
index 0000000..afa48a9
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+@VintfStability
+parcelable TvMessage {
+    /**
+     * This value for TvMessage.groupId denotes that the message doesn't belong to any group.
+     */
+    const long NO_GROUP_ID = -1;
+    /**
+     * Extended data type, like “ATSC A/336 Watermark”, “ATSC_CC”, etc. This type is opaque to the
+     * framework except when the subtype is "device_id". If the subtype is "device_id", the ID of
+     * device that sent the message should be contained in {@link #groupId}.
+     *
+     * The first message in a list of messages contained in
+     * {@link android.hardware.tv.input.TvMessageEvent} should always have the subtype "device_id",
+     * otherwise the event is discarded.
+     */
+    String subType;
+    /**
+     * This group id is used to optionally identify messages that belong together, such as
+     * headers and bodies of the same event. For messages that do not have a group, this value
+     * should be -1.
+     *
+     * If {@link #subType} is "device_id", this value should contain the ID of the device that sent
+     * this message.
+     *
+     * As -1 is a reserved value, -1 should not be used as a valid groupId.
+     */
+    long groupId;
+    int dataLengthBytes;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvMessageEvent.aidl b/tv/input/aidl/android/hardware/tv/input/TvMessageEvent.aidl
new file mode 100644
index 0000000..74a078a
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvMessageEvent.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.tv.input.TvMessage;
+import android.hardware.tv.input.TvMessageEventType;
+
+@VintfStability
+parcelable TvMessageEvent {
+    TvMessageEventType type;
+
+    int streamId;
+    TvMessage[] messages;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvMessageEventType.aidl b/tv/input/aidl/android/hardware/tv/input/TvMessageEventType.aidl
new file mode 100644
index 0000000..518c7fc
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvMessageEventType.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+@VintfStability
+@Backing(type="int")
+enum TvMessageEventType {
+    WATERMARK = 1,
+    CLOSED_CAPTION = 2,
+    OTHER = 1000,
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvStreamConfig.aidl b/tv/input/aidl/android/hardware/tv/input/TvStreamConfig.aidl
new file mode 100644
index 0000000..af86953
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvStreamConfig.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+@VintfStability
+parcelable TvStreamConfig {
+    int streamId;
+
+    /* Maximum video width in pixel. */
+    int maxVideoWidth;
+
+    /* Maximum video height in pixel. */
+    int maxVideoHeight;
+}
diff --git a/tv/input/aidl/default/Android.bp b/tv/input/aidl/default/Android.bp
new file mode 100644
index 0000000..05af6a9
--- /dev/null
+++ b/tv/input/aidl/default/Android.bp
@@ -0,0 +1,37 @@
+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_binary {
+    name: "android.hardware.tv.input-service.example",
+    relative_install_path: "hw",
+    init_rc: ["input-default.rc"],
+    vintf_fragments: ["input-default.xml"],
+    vendor: true,
+    cflags: [
+        "-Werror",
+        "-Wno-unused-parameter",
+    ],
+    srcs: [
+        "TvInput.cpp",
+        "service.cpp",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libfmq",
+        "libutils",
+        "libcutils",
+        "libbinder_ndk",
+        "android.hardware.tv.input-V1-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+    ],
+}
diff --git a/tv/input/aidl/default/TvInput.cpp b/tv/input/aidl/default/TvInput.cpp
new file mode 100644
index 0000000..2ee8bcf
--- /dev/null
+++ b/tv/input/aidl/default/TvInput.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.input-service.example"
+
+#include <utils/Log.h>
+
+#include "TvInput.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace input {
+
+TvInput::TvInput() {}
+
+void TvInput::init() {
+    // Set up TvInputDeviceInfo and TvStreamConfig
+    mDeviceInfos[0] = shared_ptr<TvInputDeviceInfoWrapper>(
+            new TvInputDeviceInfoWrapper(0, TvInputType::TUNER, true));
+    mDeviceInfos[1] = shared_ptr<TvInputDeviceInfoWrapper>(
+            new TvInputDeviceInfoWrapper(1, TvInputType::HDMI, true));
+    mDeviceInfos[3] = shared_ptr<TvInputDeviceInfoWrapper>(
+            new TvInputDeviceInfoWrapper(3, TvInputType::DISPLAY_PORT, true));
+
+    mStreamConfigs[0] = {
+            {1, shared_ptr<TvStreamConfigWrapper>(new TvStreamConfigWrapper(1, 720, 1080, false))}};
+    mStreamConfigs[1] = {{11, shared_ptr<TvStreamConfigWrapper>(
+                                      new TvStreamConfigWrapper(11, 360, 480, false))}};
+    mStreamConfigs[3] = {{5, shared_ptr<TvStreamConfigWrapper>(
+                                     new TvStreamConfigWrapper(5, 1080, 1920, false))}};
+}
+
+::ndk::ScopedAStatus TvInput::setCallback(const shared_ptr<ITvInputCallback>& in_callback) {
+    ALOGV("%s", __FUNCTION__);
+
+    mCallback = in_callback;
+
+    TvInputEvent event;
+    event.type = TvInputEventType::DEVICE_AVAILABLE;
+
+    event.deviceInfo = mDeviceInfos[0]->deviceInfo;
+    mCallback->notify(event);
+
+    event.deviceInfo = mDeviceInfos[1]->deviceInfo;
+    mCallback->notify(event);
+
+    event.deviceInfo = mDeviceInfos[3]->deviceInfo;
+    mCallback->notify(event);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::setTvMessageEnabled(int32_t deviceId, int32_t streamId,
+                                                  TvMessageEventType in_type, bool enabled) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mStreamConfigs.count(deviceId) == 0) {
+        ALOGW("Device with id %d isn't available", deviceId);
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
+    }
+
+    mTvMessageEventEnabled[deviceId][streamId][in_type] = enabled;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::getTvMessageQueueDesc(
+        MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue, int32_t in_deviceId,
+        int32_t in_streamId) {
+    ALOGV("%s", __FUNCTION__);
+    if (mStreamConfigs.count(in_deviceId) == 0) {
+        ALOGW("Device with id %d isn't available", in_deviceId);
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::getStreamConfigurations(int32_t in_deviceId,
+                                                      vector<TvStreamConfig>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mStreamConfigs.count(in_deviceId) == 0) {
+        ALOGW("Device with id %d isn't available", in_deviceId);
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
+    }
+
+    for (auto const& iconfig : mStreamConfigs[in_deviceId]) {
+        _aidl_return->push_back(iconfig.second->streamConfig);
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::openStream(int32_t in_deviceId, int32_t in_streamId,
+                                         NativeHandle* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mStreamConfigs.count(in_deviceId) == 0 ||
+        mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
+        ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
+    }
+    if (mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
+        ALOGW("Stream with device id %d, stream id %d is already opened", in_deviceId, in_streamId);
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
+    }
+    mStreamConfigs[in_deviceId][in_streamId]->handle = createNativeHandle(in_streamId);
+    *_aidl_return = makeToAidl(mStreamConfigs[in_deviceId][in_streamId]->handle);
+    mStreamConfigs[in_deviceId][in_streamId]->isOpen = true;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::closeStream(int32_t in_deviceId, int32_t in_streamId) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mStreamConfigs.count(in_deviceId) == 0 ||
+        mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
+        ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
+    }
+    if (!mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
+        ALOGW("Stream with device id %d, stream id %d is already closed", in_deviceId, in_streamId);
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
+    }
+    native_handle_delete(mStreamConfigs[in_deviceId][in_streamId]->handle);
+    mStreamConfigs[in_deviceId][in_streamId]->handle = nullptr;
+    mStreamConfigs[in_deviceId][in_streamId]->isOpen = false;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+native_handle_t* TvInput::createNativeHandle(int fd) {
+    native_handle_t* handle = native_handle_create(1, 1);
+    if (handle == nullptr) {
+        ALOGE("[TVInput] Failed to create native_handle %d", errno);
+        return nullptr;
+    }
+    handle->data[0] = dup(0);
+    handle->data[1] = fd;
+    return handle;
+}
+
+}  // namespace input
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/input/aidl/default/TvInput.h b/tv/input/aidl/default/TvInput.h
new file mode 100644
index 0000000..5776961
--- /dev/null
+++ b/tv/input/aidl/default/TvInput.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/tv/input/BnTvInput.h>
+#include <utils/KeyedVector.h>
+
+#include <aidl/android/hardware/tv/input/TvMessageEventType.h>
+#include <fmq/AidlMessageQueue.h>
+#include <map>
+#include <unordered_map>
+#include "TvInputDeviceInfoWrapper.h"
+#include "TvStreamConfigWrapper.h"
+
+using namespace android;
+using namespace std;
+using ::aidl::android::hardware::common::NativeHandle;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace input {
+
+using TvMessageEnabledMap = std::unordered_map<
+        int32_t, std::unordered_map<int32_t, std::unordered_map<TvMessageEventType, bool>>>;
+
+class TvInput : public BnTvInput {
+  public:
+    TvInput();
+
+    ::ndk::ScopedAStatus setCallback(const shared_ptr<ITvInputCallback>& in_callback) override;
+    ::ndk::ScopedAStatus setTvMessageEnabled(int32_t deviceId, int32_t streamId,
+                                             TvMessageEventType in_type, bool enabled) override;
+    ::ndk::ScopedAStatus getTvMessageQueueDesc(
+            MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue, int32_t in_deviceId,
+            int32_t in_streamId) override;
+    ::ndk::ScopedAStatus getStreamConfigurations(int32_t in_deviceId,
+                                                 vector<TvStreamConfig>* _aidl_return) override;
+    ::ndk::ScopedAStatus openStream(int32_t in_deviceId, int32_t in_streamId,
+                                    NativeHandle* _aidl_return) override;
+    ::ndk::ScopedAStatus closeStream(int32_t in_deviceId, int32_t in_streamId) override;
+    void init();
+
+  private:
+    native_handle_t* createNativeHandle(int fd);
+
+    shared_ptr<ITvInputCallback> mCallback;
+    map<int32_t, shared_ptr<TvInputDeviceInfoWrapper>> mDeviceInfos;
+    map<int32_t, map<int32_t, shared_ptr<TvStreamConfigWrapper>>> mStreamConfigs;
+    TvMessageEnabledMap mTvMessageEventEnabled;
+};
+
+}  // namespace input
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/input/aidl/default/TvInputDeviceInfoWrapper.h b/tv/input/aidl/default/TvInputDeviceInfoWrapper.h
new file mode 100644
index 0000000..d844cc8
--- /dev/null
+++ b/tv/input/aidl/default/TvInputDeviceInfoWrapper.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/tv/input/TvInputDeviceInfo.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace input {
+
+class TvInputDeviceInfoWrapper {
+  public:
+    TvInputDeviceInfoWrapper() {}
+    TvInputDeviceInfoWrapper(int32_t deviceId_, TvInputType type_, bool isAvailable_) {
+        deviceInfo.deviceId = deviceId_;
+        deviceInfo.type = type_;
+        isAvailable = isAvailable_;
+    }
+
+    TvInputDeviceInfo deviceInfo;
+    bool isAvailable;
+};
+}  // namespace input
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/input/aidl/default/TvStreamConfigWrapper.h b/tv/input/aidl/default/TvStreamConfigWrapper.h
new file mode 100644
index 0000000..05c7ca3
--- /dev/null
+++ b/tv/input/aidl/default/TvStreamConfigWrapper.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/tv/input/TvStreamConfig.h>
+#include <aidlcommonsupport/NativeHandle.h>
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace input {
+
+class TvStreamConfigWrapper {
+  public:
+    TvStreamConfigWrapper() {}
+    TvStreamConfigWrapper(int32_t streamId_, int32_t maxVideoWidth_, int32_t maxVideoHeight_,
+                          bool isOpen_) {
+        streamConfig.streamId = streamId_;
+        streamConfig.maxVideoWidth = maxVideoWidth_;
+        streamConfig.maxVideoHeight = maxVideoHeight_;
+        isOpen = isOpen_;
+        handle = nullptr;
+    }
+
+    TvStreamConfig streamConfig;
+    bool isOpen;
+    native_handle_t* handle;
+};
+}  // namespace input
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/input/aidl/default/input-default.rc b/tv/input/aidl/default/input-default.rc
new file mode 100644
index 0000000..1958b5c
--- /dev/null
+++ b/tv/input/aidl/default/input-default.rc
@@ -0,0 +1,5 @@
+service vendor.input-default /vendor/bin/hw/android.hardware.tv.input-service.example
+    interface aidl android.hardware.tv.input.ITvInput/default
+    class hal
+    user system
+    group system
diff --git a/tv/input/aidl/default/input-default.xml b/tv/input/aidl/default/input-default.xml
new file mode 100644
index 0000000..38ba151
--- /dev/null
+++ b/tv/input/aidl/default/input-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.tv.input</name>
+        <fqname>ITvInput/default</fqname>
+    </hal>
+</manifest>
\ No newline at end of file
diff --git a/tv/input/aidl/default/service.cpp b/tv/input/aidl/default/service.cpp
new file mode 100644
index 0000000..1021206
--- /dev/null
+++ b/tv/input/aidl/default/service.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.input-service.example"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "TvInput.h"
+
+using ::aidl::android::hardware::tv::input::TvInput;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(8);
+    std::shared_ptr<TvInput> tvInput = ndk::SharedRefBase::make<TvInput>();
+    tvInput->init();
+
+    const std::string instance = std::string() + TvInput::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(tvInput->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reached
+}
diff --git a/tv/input/aidl/vts/functional/Android.bp b/tv/input/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..22487ea
--- /dev/null
+++ b/tv/input/aidl/vts/functional/Android.bp
@@ -0,0 +1,38 @@
+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_test {
+    name: "VtsHalTvInputTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wno-unused-parameter",
+    ],
+    srcs: ["VtsHalTvInputTargetTest.cpp"],
+    static_libs: [
+        "android.media.audio.common.types-V1-ndk",
+        "android.hardware.common-V2-ndk",
+        "libaidlcommonsupport",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libvndksupport",
+        "libfmq",
+        "android.hardware.common.fmq-V1-ndk",
+        "android.hardware.tv.input-V1-ndk",
+    ],
+    require_root: true,
+}
diff --git a/tv/input/aidl/vts/functional/AndroidTest.xml b/tv/input/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..5549102
--- /dev/null
+++ b/tv/input/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs VtsHalTvInputTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalTvInputTargetTest->/data/local/tmp/VtsHalTvInputTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalTvInputTargetTest" />
+        <option name="native-test-timeout" value="30m" />
+    </test>
+</configuration>
diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
new file mode 100644
index 0000000..8d3395b
--- /dev/null
+++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
@@ -0,0 +1,367 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VtsHalTvInputTargetTest.h"
+
+#include <android-base/properties.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_process.h>
+#include <android/binder_status.h>
+
+using namespace VtsHalTvInputTargetTest;
+
+TvInputAidlTest::TvInputCallback::TvInputCallback(shared_ptr<TvInputAidlTest> parent)
+    : parent_(parent) {}
+
+::ndk::ScopedAStatus TvInputAidlTest::TvInputCallback::notify(const TvInputEvent& in_event) {
+    unique_lock<mutex> lock(parent_->mutex_);
+
+    switch (in_event.type) {
+        case TvInputEventType::DEVICE_AVAILABLE:
+            parent_->onDeviceAvailable(in_event.deviceInfo);
+            break;
+        case TvInputEventType::DEVICE_UNAVAILABLE:
+            parent_->onDeviceUnavailable(in_event.deviceInfo.deviceId);
+            break;
+        case TvInputEventType::STREAM_CONFIGURATIONS_CHANGED:
+            parent_->onStreamConfigurationsChanged(in_event.deviceInfo.deviceId);
+            break;
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInputAidlTest::TvInputCallback::notifyTvMessageEvent(
+        const TvMessageEvent& in_event) {
+    return ::ndk::ScopedAStatus::ok();
+}
+
+void TvInputAidlTest::SetUp() {
+    if (AServiceManager_isDeclared(GetParam().c_str())) {
+        ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+        tv_input_ = ITvInput::fromBinder(binder);
+    } else {
+        tv_input_ = nullptr;
+    }
+    ASSERT_NE(tv_input_, nullptr);
+
+    tv_input_callback_ =
+            ::ndk::SharedRefBase::make<TvInputCallback>(shared_ptr<TvInputAidlTest>(this));
+    ASSERT_NE(tv_input_callback_, nullptr);
+
+    tv_input_->setCallback(tv_input_callback_);
+    // All events received within the timeout should be handled.
+    sleep(WAIT_FOR_EVENT_TIMEOUT);
+}
+
+void TvInputAidlTest::TearDown() {
+    tv_input_ = nullptr;
+}
+
+void TvInputAidlTest::onDeviceAvailable(const TvInputDeviceInfo& deviceInfo) {
+    ALOGD("onDeviceAvailable for device id %d", deviceInfo.deviceId);
+    device_info_.add(deviceInfo.deviceId, deviceInfo);
+}
+
+void TvInputAidlTest::onDeviceUnavailable(int32_t deviceId) {
+    ALOGD("onDeviceUnavailable for device id %d", deviceId);
+    device_info_.removeItem(deviceId);
+    stream_config_.removeItem(deviceId);
+}
+
+::ndk::ScopedAStatus TvInputAidlTest::onStreamConfigurationsChanged(int32_t deviceId) {
+    ALOGD("onStreamConfigurationsChanged for device id %d", deviceId);
+    return updateStreamConfigurations(deviceId);
+}
+
+::ndk::ScopedAStatus TvInputAidlTest::updateStreamConfigurations(int32_t deviceId) {
+    stream_config_.removeItem(deviceId);
+    vector<TvStreamConfig> list;
+    ::ndk::ScopedAStatus status = tv_input_->getStreamConfigurations(deviceId, &list);
+    if (status.isOk()) {
+        stream_config_.add(deviceId, list);
+    }
+    return status;
+}
+
+void TvInputAidlTest::updateAllStreamConfigurations() {
+    for (size_t i = 0; i < device_info_.size(); i++) {
+        int32_t device_id = device_info_.keyAt(i);
+        updateStreamConfigurations(device_id);
+    }
+}
+
+vector<size_t> TvInputAidlTest::getConfigIndices() {
+    vector<size_t> indices;
+    for (size_t i = 0; i < stream_config_.size(); i++) {
+        if (stream_config_.valueAt(i).size() != 0) {
+            indices.push_back(i);
+        }
+    }
+    return indices;
+}
+
+int32_t TvInputAidlTest::getNumNotIn(vector<int32_t>& nums) {
+    int32_t result = DEFAULT_ID;
+    int32_t size = static_cast<int32_t>(nums.size());
+    for (int32_t i = 0; i < size; i++) {
+        // Put every element to its target position, if possible.
+        int32_t target_pos = nums[i];
+        while (target_pos >= 0 && target_pos < size && i != target_pos &&
+               nums[i] != nums[target_pos]) {
+            swap(nums[i], nums[target_pos]);
+            target_pos = nums[i];
+        }
+    }
+
+    for (int32_t i = 0; i < size; i++) {
+        if (nums[i] != i) {
+            return i;
+        }
+    }
+    return result;
+}
+
+bool TvInputAidlTest::isValidHandle(NativeHandle& handle) {
+    if (handle.fds.empty()) {
+        return false;
+    }
+    for (size_t i = 0; i < handle.fds.size(); i++) {
+        int fd = handle.fds[i].get();
+        if (fcntl(fd, F_GETFL) < 0) {
+            return false;
+        }
+    }
+    return true;
+}
+
+/*
+ * GetStreamConfigTest:
+ * Calls updateStreamConfigurations() for each existing device
+ * Checks returned results
+ */
+TEST_P(TvInputAidlTest, GetStreamConfigTest) {
+    unique_lock<mutex> lock(mutex_);
+
+    for (size_t i = 0; i < device_info_.size(); i++) {
+        int32_t device_id = device_info_.keyAt(i);
+        ALOGD("GetStreamConfigTest: device_id=%d", device_id);
+        ASSERT_TRUE(updateStreamConfigurations(device_id).isOk());
+    }
+}
+
+/*
+ * OpenAndCloseStreamTest:
+ * Calls openStream() and then closeStream() for each existing stream
+ * Checks returned results
+ */
+TEST_P(TvInputAidlTest, OpenAndCloseStreamTest) {
+    unique_lock<mutex> lock(mutex_);
+
+    updateAllStreamConfigurations();
+
+    for (size_t j = 0; j < stream_config_.size(); j++) {
+        int32_t device_id = stream_config_.keyAt(j);
+        vector<TvStreamConfig> config = stream_config_.valueAt(j);
+        for (size_t i = 0; i < config.size(); i++) {
+            NativeHandle handle;
+            int32_t stream_id = config[i].streamId;
+            ALOGD("OpenAndCloseStreamTest: open stream, device_id=%d, stream_id=%d", device_id,
+                  stream_id);
+            ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).isOk());
+            ASSERT_TRUE(isValidHandle(handle));
+
+            ALOGD("OpenAndCloseStreamTest: close stream, device_id=%d, stream_id=%d", device_id,
+                  stream_id);
+            ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).isOk());
+        }
+    }
+}
+
+/*
+ * InvalidDeviceIdTest:
+ * Calls updateStreamConfigurations(), openStream(), and closeStream()
+ * for a non-existing device
+ * Checks returned results
+ * The results should be ITvInput::STATUS_INVALID_ARGUMENTS
+ */
+TEST_P(TvInputAidlTest, InvalidDeviceIdTest) {
+    unique_lock<mutex> lock(mutex_);
+
+    vector<int32_t> device_ids;
+    for (size_t i = 0; i < device_info_.size(); i++) {
+        device_ids.push_back(device_info_.keyAt(i));
+    }
+    // Get a non-existing device ID.
+    int32_t id = getNumNotIn(device_ids);
+    ALOGD("InvalidDeviceIdTest: update stream config, device_id=%d", id);
+    ASSERT_TRUE(updateStreamConfigurations(id).getServiceSpecificError() ==
+                ITvInput::STATUS_INVALID_ARGUMENTS);
+
+    int32_t stream_id = 0;
+    NativeHandle handle;
+
+    ALOGD("InvalidDeviceIdTest: open stream, device_id=%d, stream_id=%d", id, stream_id);
+    ASSERT_TRUE(tv_input_->openStream(id, stream_id, &handle).getServiceSpecificError() ==
+                ITvInput::STATUS_INVALID_ARGUMENTS);
+
+    ALOGD("InvalidDeviceIdTest: close stream, device_id=%d, stream_id=%d", id, stream_id);
+    ASSERT_TRUE(tv_input_->closeStream(id, stream_id).getServiceSpecificError() ==
+                ITvInput::STATUS_INVALID_ARGUMENTS);
+}
+
+/*
+ * InvalidStreamIdTest:
+ * Calls openStream(), and closeStream() for a non-existing stream
+ * Checks returned results
+ * The results should be ITvInput::STATUS_INVALID_ARGUMENTS
+ */
+TEST_P(TvInputAidlTest, InvalidStreamIdTest) {
+    unique_lock<mutex> lock(mutex_);
+
+    if (device_info_.isEmpty()) {
+        return;
+    }
+    updateAllStreamConfigurations();
+
+    int32_t device_id = device_info_.keyAt(0);
+    // Get a non-existing stream ID.
+    int32_t id = DEFAULT_ID;
+    if (stream_config_.indexOfKey(device_id) >= 0) {
+        vector<int32_t> stream_ids;
+        vector<TvStreamConfig> config = stream_config_.valueFor(device_id);
+        for (size_t i = 0; i < config.size(); i++) {
+            stream_ids.push_back(config[i].streamId);
+        }
+        id = getNumNotIn(stream_ids);
+    }
+
+    NativeHandle handle;
+
+    ALOGD("InvalidStreamIdTest: open stream, device_id=%d, stream_id=%d", device_id, id);
+    ASSERT_TRUE(tv_input_->openStream(device_id, id, &handle).getServiceSpecificError() ==
+                ITvInput::STATUS_INVALID_ARGUMENTS);
+
+    ALOGD("InvalidStreamIdTest: close stream, device_id=%d, stream_id=%d", device_id, id);
+    ASSERT_TRUE(tv_input_->closeStream(device_id, id).getServiceSpecificError() ==
+                ITvInput::STATUS_INVALID_ARGUMENTS);
+}
+
+/*
+ * OpenAnOpenedStreamsTest:
+ * Calls openStream() twice for a stream (if any)
+ * Checks returned results
+ * The result of the second call should be ITvInput::STATUS_INVALID_STATE
+ */
+TEST_P(TvInputAidlTest, OpenAnOpenedStreamsTest) {
+    unique_lock<mutex> lock(mutex_);
+
+    updateAllStreamConfigurations();
+    vector<size_t> indices = getConfigIndices();
+    if (indices.empty()) {
+        return;
+    }
+    int32_t device_id = stream_config_.keyAt(indices[0]);
+    vector<TvStreamConfig> streamConfigs = stream_config_.valueAt(indices[0]);
+    if (streamConfigs.empty()) {
+        return;
+    }
+    int32_t stream_id = streamConfigs[0].streamId;
+    NativeHandle handle;
+
+    ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id);
+    ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).isOk());
+    ASSERT_TRUE(isValidHandle(handle));
+
+    ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id);
+    ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).getServiceSpecificError() ==
+                ITvInput::STATUS_INVALID_STATE);
+
+    // close stream as subsequent tests assume no open streams
+    ALOGD("OpenAnOpenedStreamsTest: close stream, device_id=%d, stream_id=%d", device_id,
+          stream_id);
+    ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).isOk());
+}
+
+/*
+ * CloseStreamBeforeOpenTest:
+ * Calls closeStream() without calling openStream() for a stream (if any)
+ * Checks the returned result
+ * The result should be ITvInput::STATUS_INVALID_STATE
+ */
+TEST_P(TvInputAidlTest, CloseStreamBeforeOpenTest) {
+    unique_lock<mutex> lock(mutex_);
+
+    updateAllStreamConfigurations();
+    vector<size_t> indices = getConfigIndices();
+    if (indices.empty()) {
+        return;
+    }
+    int32_t device_id = stream_config_.keyAt(indices[0]);
+    vector<TvStreamConfig> streamConfigs = stream_config_.valueAt(indices[0]);
+    if (streamConfigs.empty()) {
+        return;
+    }
+    int32_t stream_id = streamConfigs[0].streamId;
+
+    ALOGD("CloseStreamBeforeOpenTest: close stream, device_id=%d, stream_id=%d", device_id,
+          stream_id);
+    ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).getServiceSpecificError() ==
+                ITvInput::STATUS_INVALID_STATE);
+}
+
+TEST_P(TvInputAidlTest, SetTvMessageEnabledTest) {
+    unique_lock<mutex> lock(mutex_);
+
+    updateAllStreamConfigurations();
+    vector<size_t> indices = getConfigIndices();
+    if (indices.empty()) {
+        return;
+    }
+    int32_t device_id = stream_config_.keyAt(indices[0]);
+    vector<TvStreamConfig> streamConfigs = stream_config_.valueAt(indices[0]);
+    if (streamConfigs.empty()) {
+        return;
+    }
+    int32_t stream_id = streamConfigs[0].streamId;
+    ALOGD("SetTvMessageEnabledTest: device_id=%d, stream_id=%d", device_id, stream_id);
+    tv_input_->setTvMessageEnabled(device_id, stream_id, TvMessageEventType::WATERMARK, true);
+}
+
+TEST_P(TvInputAidlTest, GetTvMessageQueueTest) {
+    unique_lock<mutex> lock(mutex_);
+
+    updateAllStreamConfigurations();
+    vector<size_t> indices = getConfigIndices();
+    if (indices.empty()) {
+        return;
+    }
+    int32_t device_id = stream_config_.keyAt(indices[0]);
+    vector<TvStreamConfig> streamConfigs = stream_config_.valueAt(indices[0]);
+    if (streamConfigs.empty()) {
+        return;
+    }
+    int32_t stream_id = streamConfigs[0].streamId;
+    ALOGD("GetTvMessageQueueTest: device_id=%d, stream_id=%d", device_id, stream_id);
+    MQDescriptor<int8_t, SynchronizedReadWrite> queue;
+    tv_input_->getTvMessageQueueDesc(&queue, device_id, stream_id);
+}
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TvInputAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ITvInput::descriptor)),
+                         android::PrintInstanceNameToString);
+
+// TODO remove from the allow list once the cf tv target is enabled for testing
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TvInputAidlTest);
diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
new file mode 100644
index 0000000..7e66a88
--- /dev/null
+++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_manager.h>
+#include <fcntl.h>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <aidl/android/hardware/tv/input/BnTvInputCallback.h>
+#include <aidl/android/hardware/tv/input/ITvInput.h>
+#include <aidl/android/hardware/tv/input/TvInputDeviceInfo.h>
+#include <aidl/android/hardware/tv/input/TvInputEvent.h>
+#include <aidl/android/hardware/tv/input/TvMessageEvent.h>
+#include <aidl/android/hardware/tv/input/TvMessageEventType.h>
+#include <aidl/android/hardware/tv/input/TvStreamConfig.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include <log/log.h>
+#include <utils/KeyedVector.h>
+
+using namespace aidl::android::hardware::tv::input;
+using namespace std;
+using ::aidl::android::hardware::common::NativeHandle;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+
+#define WAIT_FOR_EVENT_TIMEOUT 5
+#define DEFAULT_ID INT32_MIN
+
+namespace VtsHalTvInputTargetTest {
+
+class TvInputAidlTest : public testing::TestWithParam<string> {
+  public:
+    class TvInputCallback : public BnTvInputCallback {
+      public:
+        TvInputCallback(shared_ptr<TvInputAidlTest> parent);
+        ::ndk::ScopedAStatus notify(const TvInputEvent& in_event) override;
+        ::ndk::ScopedAStatus notifyTvMessageEvent(const TvMessageEvent& in_event) override;
+
+      private:
+        shared_ptr<TvInputAidlTest> parent_;
+    };
+
+    virtual void SetUp() override;
+    virtual void TearDown() override;
+
+    /* Called when a DEVICE_AVAILABLE event is received. */
+    void onDeviceAvailable(const TvInputDeviceInfo& deviceInfo);
+
+    /* Called when a DEVICE_UNAVAILABLE event is received. */
+    void onDeviceUnavailable(int32_t deviceId);
+
+    /* Called when a STREAM_CONFIGURATIONS_CHANGED event is received. */
+    ::ndk::ScopedAStatus onStreamConfigurationsChanged(int32_t deviceId);
+
+    /* Gets and updates the stream configurations for a device. */
+    ::ndk::ScopedAStatus updateStreamConfigurations(int32_t deviceId);
+
+    /* Gets and updates the stream configurations for all existing devices. */
+    void updateAllStreamConfigurations();
+
+    /* Returns a list of indices of stream_config_ whose corresponding values are not empty. */
+    vector<size_t> getConfigIndices();
+
+    /*
+     * Returns DEFAULT_ID if there is no missing integer in the range [0, the size of nums).
+     * Otherwise, returns the smallest missing non-negative integer.
+     */
+    int32_t getNumNotIn(vector<int32_t>& nums);
+
+    /* Checks if a native handle contains valid file descriptor(s). */
+    bool isValidHandle(NativeHandle& handle);
+
+  protected:
+    shared_ptr<ITvInput> tv_input_;
+    shared_ptr<TvInputCallback> tv_input_callback_;
+    android::KeyedVector<int32_t, TvInputDeviceInfo> device_info_;
+    android::KeyedVector<int32_t, vector<TvStreamConfig>> stream_config_;
+    mutex mutex_;
+};
+
+}  // namespace VtsHalTvInputTargetTest
diff --git a/tv/tuner/1.0/default/Dvr.cpp b/tv/tuner/1.0/default/Dvr.cpp
index 40879f2..9d6d86d 100644
--- a/tv/tuner/1.0/default/Dvr.cpp
+++ b/tv/tuner/1.0/default/Dvr.cpp
@@ -164,7 +164,7 @@
         return false;
     }
 
-    mDvrMQ = move(tmpDvrMQ);
+    mDvrMQ = std::move(tmpDvrMQ);
 
     if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != OK) {
         return false;
diff --git a/tv/tuner/1.0/vts/OWNERS b/tv/tuner/1.0/vts/OWNERS
index 1b3d095..9bdafca 100644
--- a/tv/tuner/1.0/vts/OWNERS
+++ b/tv/tuner/1.0/vts/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 136752
 nchalko@google.com
 amyjojo@google.com
 shubang@google.com
diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp
index fdb66c1..8262b4d 100644
--- a/tv/tuner/1.1/default/Dvr.cpp
+++ b/tv/tuner/1.1/default/Dvr.cpp
@@ -183,7 +183,7 @@
         return false;
     }
 
-    mDvrMQ = move(tmpDvrMQ);
+    mDvrMQ = std::move(tmpDvrMQ);
 
     if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != OK) {
         return false;
diff --git a/tv/tuner/1.1/vts/OWNERS b/tv/tuner/1.1/vts/OWNERS
index 1b3d095..9bdafca 100644
--- a/tv/tuner/1.1/vts/OWNERS
+++ b/tv/tuner/1.1/vts/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 136752
 nchalko@google.com
 amyjojo@google.com
 shubang@google.com
diff --git a/tv/tuner/OWNERS b/tv/tuner/OWNERS
new file mode 100644
index 0000000..83e090d
--- /dev/null
+++ b/tv/tuner/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 136752
+
+quxiangfang@google.com
+shubang@google.com
+hgchen@google.com
+raychin@google.com
diff --git a/tv/tuner/aidl/Android.bp b/tv/tuner/aidl/Android.bp
index ecb744c..6cbf362 100644
--- a/tv/tuner/aidl/Android.bp
+++ b/tv/tuner/aidl/Android.bp
@@ -32,6 +32,15 @@
                 "android.hardware.common.fmq-V1",
             ],
         },
+        {
+            version: "2",
+            imports: [
+                "android.hardware.common-V2",
+                "android.hardware.common.fmq-V1",
+            ],
+        },
+
     ],
+    frozen: true,
 
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/.hash b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/.hash
new file mode 100644
index 0000000..59f22f4
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/.hash
@@ -0,0 +1 @@
+f8d74c149f04e76b6d622db2bd8e465dae24b08c
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioExtraMetaData.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioExtraMetaData.aidl
new file mode 100644
index 0000000..9db9609
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioExtraMetaData.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioExtraMetaData {
+  byte adFade;
+  byte adPan;
+  char versionTextTag;
+  byte adGainCenter;
+  byte adGainFront;
+  byte adGainSurround;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPreselection.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPreselection.aidl
new file mode 100644
index 0000000..ab0404e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPreselection.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioPreselection {
+  int preselectionId;
+  android.hardware.tv.tuner.AudioPreselectionLabel[] labels;
+  String language;
+  android.hardware.tv.tuner.AudioPreselectionRenderingIndicationType renderingIndication;
+  boolean hasAudioDescription;
+  boolean hasSpokenSubtitles;
+  boolean hasDialogueEnhancement;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPreselectionLabel.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
new file mode 100644
index 0000000..79f3b6f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioPreselectionLabel {
+  String language;
+  String text;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
new file mode 100644
index 0000000..2977ff6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioPreselectionRenderingIndicationType {
+  NOT_INDICATED,
+  STEREO,
+  TWO_DIMENSIONAL,
+  THREE_DIMENSIONAL,
+  HEADPHONE,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPresentation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPresentation.aidl
new file mode 100644
index 0000000..eba820c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioPresentation.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioPresentation {
+  android.hardware.tv.tuner.AudioPreselection preselection;
+  int ac4ShortProgramId = (-1) /* -1 */;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioStreamType.aidl
new file mode 100644
index 0000000..4754bb1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AudioStreamType.aidl
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioStreamType {
+  UNDEFINED,
+  PCM,
+  MP3,
+  MPEG1,
+  MPEG2,
+  MPEGH,
+  AAC,
+  AC3,
+  EAC3,
+  AC4,
+  DTS,
+  DTS_HD,
+  WMA,
+  OPUS,
+  VORBIS,
+  DRA,
+  AAC_ADTS,
+  AAC_LATM,
+  AAC_HE_ADTS,
+  AAC_HE_LATM,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AvStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AvStreamType.aidl
new file mode 100644
index 0000000..4d6acff
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/AvStreamType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union AvStreamType {
+  android.hardware.tv.tuner.VideoStreamType video = android.hardware.tv.tuner.VideoStreamType.UNDEFINED;
+  android.hardware.tv.tuner.AudioStreamType audio;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/Constant.aidl
new file mode 100644
index 0000000..1f7153b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/Constant.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Constant {
+  INVALID_TS_PID = 0xFFFF,
+  INVALID_STREAM_ID = 0xFFFF,
+  INVALID_FILTER_ID = 0xFFFFFFFF,
+  INVALID_AV_SYNC_ID = 0xFFFFFFFF,
+  INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = 0xFFFFFFFF,
+  INVALID_FIRST_MACROBLOCK_IN_SLICE = 0xFFFFFFFF,
+  INVALID_FRONTEND_SETTING_FREQUENCY = 0xFFFFFFFF,
+  INVALID_IP_FILTER_CONTEXT_ID = 0xFFFFFFFF,
+  INVALID_LTS_ID = 0xFFFFFFFF,
+  INVALID_FRONTEND_ID = 0xFFFFFFFF,
+  INVALID_LNB_ID = 0xFFFFFFFF,
+  INVALID_KEYTOKEN = 0x00,
+  INVALID_TABINFO_VERSION = 0xFFFFFFFF,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/Constant64Bit.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/Constant64Bit.aidl
new file mode 100644
index 0000000..ccbfd1a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/Constant64Bit.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum Constant64Bit {
+  INVALID_FILTER_ID_64BIT = 0xFFFFFFFFFFFFFFFF,
+  INVALID_AV_SYNC_ID_64BIT = 0xFFFFFFFFFFFFFFFF,
+  INVALID_PRESENTATION_TIME_STAMP = 0xFFFFFFFFFFFFFFFF,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DataFormat.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DataFormat.aidl
new file mode 100644
index 0000000..5fb34ba
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DataFormat.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DataFormat {
+  TS,
+  PES,
+  ES,
+  SHV_TLV,
+  UNDEFINED,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpFilterSettings.aidl
new file mode 100644
index 0000000..91a04a4
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpFilterSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxAlpFilterSettings {
+  int packetType;
+  android.hardware.tv.tuner.DemuxAlpLengthType lengthType = android.hardware.tv.tuner.DemuxAlpLengthType.UNDEFINED;
+  android.hardware.tv.tuner.DemuxAlpFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..6b15492
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpFilterSettingsFilterSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxAlpFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpFilterType.aidl
new file mode 100644
index 0000000..c164f19
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpFilterType.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxAlpFilterType {
+  UNDEFINED,
+  SECTION,
+  PTP,
+  PAYLOAD_THROUGH,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpLengthType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpLengthType.aidl
new file mode 100644
index 0000000..59edc34
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxAlpLengthType.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum DemuxAlpLengthType {
+  UNDEFINED = 0,
+  WITHOUT_ADDITIONAL_HEADER,
+  WITH_ADDITIONAL_HEADER,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxCapabilities.aidl
new file mode 100644
index 0000000..49afb94
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxCapabilities.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxCapabilities {
+  int numDemux;
+  int numRecord;
+  int numPlayback;
+  int numTsFilter;
+  int numSectionFilter;
+  int numAudioFilter;
+  int numVideoFilter;
+  int numPesFilter;
+  int numPcrFilter;
+  long numBytesInSectionFilter;
+  int filterCaps;
+  int[] linkCaps;
+  boolean bTimeFilter;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
new file mode 100644
index 0000000..3e5df2d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterAvSettings {
+  boolean isPassthrough;
+  boolean isSecureMemory;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
new file mode 100644
index 0000000..8a05dbd
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterDownloadEvent {
+  int itemId;
+  int downloadId;
+  int mpuSequenceNumber;
+  int itemFragmentIndex;
+  int lastItemFragmentIndex;
+  int dataLength;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
new file mode 100644
index 0000000..86ce646
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterDownloadSettings {
+  boolean useDownloadId;
+  int downloadId;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterEvent.aidl
new file mode 100644
index 0000000..617f71c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterEvent.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterEvent {
+  android.hardware.tv.tuner.DemuxFilterSectionEvent section;
+  android.hardware.tv.tuner.DemuxFilterMediaEvent media;
+  android.hardware.tv.tuner.DemuxFilterPesEvent pes;
+  android.hardware.tv.tuner.DemuxFilterTsRecordEvent tsRecord;
+  android.hardware.tv.tuner.DemuxFilterMmtpRecordEvent mmtpRecord;
+  android.hardware.tv.tuner.DemuxFilterDownloadEvent download;
+  android.hardware.tv.tuner.DemuxFilterIpPayloadEvent ipPayload;
+  android.hardware.tv.tuner.DemuxFilterTemiEvent temi;
+  android.hardware.tv.tuner.DemuxFilterMonitorEvent monitorEvent;
+  int startId;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterIpPayloadEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterIpPayloadEvent.aidl
new file mode 100644
index 0000000..9134df3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterIpPayloadEvent.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterIpPayloadEvent {
+  int dataLength;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMainType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMainType.aidl
new file mode 100644
index 0000000..b78965d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMainType.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxFilterMainType {
+  UNDEFINED = 0,
+  TS = (1 << 0) /* 1 */,
+  MMTP = (1 << 1) /* 2 */,
+  IP = (1 << 2) /* 4 */,
+  TLV = (1 << 3) /* 8 */,
+  ALP = (1 << 4) /* 16 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
new file mode 100644
index 0000000..61a9555
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterMediaEvent {
+  int streamId;
+  boolean isPtsPresent;
+  long pts;
+  boolean isDtsPresent;
+  long dts;
+  long dataLength;
+  long offset;
+  android.hardware.common.NativeHandle avMemory;
+  boolean isSecureMemory;
+  long avDataId;
+  int mpuSequenceNumber;
+  boolean isPesPrivateData;
+  android.hardware.tv.tuner.DemuxFilterMediaEventExtraMetaData extraMetaData;
+  android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
new file mode 100644
index 0000000..28caf19
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterMediaEventExtraMetaData {
+  boolean noinit;
+  android.hardware.tv.tuner.AudioExtraMetaData audio;
+  android.hardware.tv.tuner.AudioPresentation[] audioPresentations = {};
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMmtpRecordEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMmtpRecordEvent.aidl
new file mode 100644
index 0000000..4e31ba8
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMmtpRecordEvent.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterMmtpRecordEvent {
+  int scHevcIndexMask;
+  long byteNumber;
+  long pts;
+  int mpuSequenceNumber;
+  int firstMbInSlice;
+  int tsIndexMask;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMonitorEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMonitorEvent.aidl
new file mode 100644
index 0000000..177de7a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMonitorEvent.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterMonitorEvent {
+  android.hardware.tv.tuner.ScramblingStatus scramblingStatus = android.hardware.tv.tuner.ScramblingStatus.UNKNOWN;
+  int cid;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl
new file mode 100644
index 0000000..062650b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxFilterMonitorEventType {
+  SCRAMBLING_STATUS = (1 << 0) /* 1 */,
+  IP_CID_CHANGE = (1 << 1) /* 2 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterPesDataSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterPesDataSettings.aidl
new file mode 100644
index 0000000..2420142
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterPesDataSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterPesDataSettings {
+  int streamId;
+  boolean isRaw;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterPesEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterPesEvent.aidl
new file mode 100644
index 0000000..3ddd5e0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterPesEvent.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterPesEvent {
+  int streamId;
+  int dataLength;
+  int mpuSequenceNumber;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
new file mode 100644
index 0000000..02c478f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterRecordSettings {
+  int tsIndexMask;
+  android.hardware.tv.tuner.DemuxRecordScIndexType scIndexType = android.hardware.tv.tuner.DemuxRecordScIndexType.NONE;
+  android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
new file mode 100644
index 0000000..8dfc60e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterScIndexMask {
+  int scIndex;
+  int scAvc;
+  int scHevc;
+  int scVvc;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionBits.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionBits.aidl
new file mode 100644
index 0000000..b666c7b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionBits.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterSectionBits {
+  byte[] filter;
+  byte[] mask;
+  byte[] mode;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
new file mode 100644
index 0000000..199a09c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterSectionEvent {
+  int tableId;
+  int version;
+  int sectionNum;
+  long dataLength;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
new file mode 100644
index 0000000..7936e59
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterSectionSettings {
+  android.hardware.tv.tuner.DemuxFilterSectionSettingsCondition condition;
+  boolean isCheckCrc;
+  boolean isRepeat;
+  boolean isRaw;
+  int bitWidthOfLengthField;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionSettingsCondition.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionSettingsCondition.aidl
new file mode 100644
index 0000000..0b101de
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionSettingsCondition.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterSectionSettingsCondition {
+  android.hardware.tv.tuner.DemuxFilterSectionBits sectionBits;
+  android.hardware.tv.tuner.DemuxFilterSectionSettingsConditionTableInfo tableInfo;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
new file mode 100644
index 0000000..82d30cb
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterSectionSettingsConditionTableInfo {
+  int tableId;
+  int version;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSettings.aidl
new file mode 100644
index 0000000..c12fde2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterSettings {
+  android.hardware.tv.tuner.DemuxTsFilterSettings ts;
+  android.hardware.tv.tuner.DemuxMmtpFilterSettings mmtp;
+  android.hardware.tv.tuner.DemuxIpFilterSettings ip;
+  android.hardware.tv.tuner.DemuxTlvFilterSettings tlv;
+  android.hardware.tv.tuner.DemuxAlpFilterSettings alp;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterStatus.aidl
new file mode 100644
index 0000000..cfc5838
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum DemuxFilterStatus {
+  DATA_READY = (1 << 0) /* 1 */,
+  LOW_WATER = (1 << 1) /* 2 */,
+  HIGH_WATER = (1 << 2) /* 4 */,
+  OVERFLOW = (1 << 3) /* 8 */,
+  NO_DATA = (1 << 4) /* 16 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSubType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSubType.aidl
new file mode 100644
index 0000000..2e2a774
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterSubType.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterSubType {
+  android.hardware.tv.tuner.DemuxTsFilterType tsFilterType = android.hardware.tv.tuner.DemuxTsFilterType.UNDEFINED;
+  android.hardware.tv.tuner.DemuxMmtpFilterType mmtpFilterType;
+  android.hardware.tv.tuner.DemuxIpFilterType ipFilterType;
+  android.hardware.tv.tuner.DemuxTlvFilterType tlvFilterType;
+  android.hardware.tv.tuner.DemuxAlpFilterType alpFilterType;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterTemiEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterTemiEvent.aidl
new file mode 100644
index 0000000..ce15861
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterTemiEvent.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterTemiEvent {
+  long pts;
+  byte descrTag;
+  byte[] descrData;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterTsRecordEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterTsRecordEvent.aidl
new file mode 100644
index 0000000..5c27faf
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterTsRecordEvent.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterTsRecordEvent {
+  android.hardware.tv.tuner.DemuxPid pid;
+  int tsIndexMask;
+  android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
+  long byteNumber;
+  long pts;
+  int firstMbInSlice;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterType.aidl
new file mode 100644
index 0000000..b2f499d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxFilterType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterType {
+  android.hardware.tv.tuner.DemuxFilterMainType mainType = android.hardware.tv.tuner.DemuxFilterMainType.UNDEFINED;
+  android.hardware.tv.tuner.DemuxFilterSubType subType;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxInfo.aidl
new file mode 100644
index 0000000..12f9dc8
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxInfo.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxInfo {
+  int filterTypes = android.hardware.tv.tuner.DemuxFilterMainType.UNDEFINED /* 0 */;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpAddress.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpAddress.aidl
new file mode 100644
index 0000000..a044a19
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpAddress.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxIpAddress {
+  android.hardware.tv.tuner.DemuxIpAddressIpAddress srcIpAddress;
+  android.hardware.tv.tuner.DemuxIpAddressIpAddress dstIpAddress;
+  int srcPort;
+  int dstPort;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpAddressIpAddress.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpAddressIpAddress.aidl
new file mode 100644
index 0000000..62de088
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpAddressIpAddress.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxIpAddressIpAddress {
+  byte[] v4 = {};
+  byte[] v6;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpFilterSettings.aidl
new file mode 100644
index 0000000..2b0610b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpFilterSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxIpFilterSettings {
+  android.hardware.tv.tuner.DemuxIpAddress ipAddr;
+  android.hardware.tv.tuner.DemuxIpFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..daac284
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpFilterSettingsFilterSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxIpFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+  boolean bPassthrough;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpFilterType.aidl
new file mode 100644
index 0000000..7320aec
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxIpFilterType.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxIpFilterType {
+  UNDEFINED,
+  SECTION,
+  NTP,
+  IP_PAYLOAD,
+  IP,
+  PAYLOAD_THROUGH,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxMmtpFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxMmtpFilterSettings.aidl
new file mode 100644
index 0000000..b22c564
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxMmtpFilterSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxMmtpFilterSettings {
+  int mmtpPid;
+  android.hardware.tv.tuner.DemuxMmtpFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxMmtpFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxMmtpFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..4b23306
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxMmtpFilterSettingsFilterSettings.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxMmtpFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+  android.hardware.tv.tuner.DemuxFilterAvSettings av;
+  android.hardware.tv.tuner.DemuxFilterPesDataSettings pesData;
+  android.hardware.tv.tuner.DemuxFilterRecordSettings record;
+  android.hardware.tv.tuner.DemuxFilterDownloadSettings download;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl
new file mode 100644
index 0000000..a89c5b1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxMmtpFilterType {
+  UNDEFINED,
+  SECTION,
+  PES,
+  MMTP,
+  AUDIO,
+  VIDEO,
+  RECORD,
+  DOWNLOAD,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxPid.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxPid.aidl
new file mode 100644
index 0000000..c452f35
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxPid.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxPid {
+  int tPid;
+  int mmtpPid;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl
new file mode 100644
index 0000000..ecb4e8b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxQueueNotifyBits {
+  DATA_READY = (1 << 0) /* 1 */,
+  DATA_CONSUMED = (1 << 1) /* 2 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
new file mode 100644
index 0000000..5556bb2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxRecordScIndexType {
+  NONE,
+  SC,
+  SC_HEVC,
+  SC_AVC,
+  SC_VVC,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScAvcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
new file mode 100644
index 0000000..5c51793
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxScAvcIndex {
+  UNDEFINED = 0,
+  I_SLICE = (1 << 0) /* 1 */,
+  P_SLICE = (1 << 1) /* 2 */,
+  B_SLICE = (1 << 2) /* 4 */,
+  SI_SLICE = (1 << 3) /* 8 */,
+  SP_SLICE = (1 << 4) /* 16 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
new file mode 100644
index 0000000..d07bcb7
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxScHevcIndex {
+  UNDEFINED = 0,
+  SPS = (1 << 0) /* 1 */,
+  AUD = (1 << 1) /* 2 */,
+  SLICE_CE_BLA_W_LP = (1 << 2) /* 4 */,
+  SLICE_BLA_W_RADL = (1 << 3) /* 8 */,
+  SLICE_BLA_N_LP = (1 << 4) /* 16 */,
+  SLICE_IDR_W_RADL = (1 << 5) /* 32 */,
+  SLICE_IDR_N_LP = (1 << 6) /* 64 */,
+  SLICE_TRAIL_CRA = (1 << 7) /* 128 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScIndex.aidl
new file mode 100644
index 0000000..509c1ab
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxScIndex {
+  UNDEFINED = 0,
+  I_FRAME = (1 << 0) /* 1 */,
+  P_FRAME = (1 << 1) /* 2 */,
+  B_FRAME = (1 << 2) /* 4 */,
+  SEQUENCE = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScVvcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
new file mode 100644
index 0000000..ac3a5e6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxScVvcIndex {
+  UNDEFINED = 0,
+  SLICE_IDR_W_RADL = (1 << 0) /* 1 */,
+  SLICE_IDR_N_LP = (1 << 1) /* 2 */,
+  SLICE_CRA = (1 << 2) /* 4 */,
+  SLICE_GDR = (1 << 3) /* 8 */,
+  VPS = (1 << 4) /* 16 */,
+  SPS = (1 << 5) /* 32 */,
+  AUD = (1 << 6) /* 64 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTlvFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTlvFilterSettings.aidl
new file mode 100644
index 0000000..ddb61ce
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTlvFilterSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxTlvFilterSettings {
+  int packetType;
+  boolean isCompressedIpPacket;
+  android.hardware.tv.tuner.DemuxTlvFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTlvFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTlvFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..a9d3198
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTlvFilterSettingsFilterSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxTlvFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+  boolean bPassthrough;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTlvFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTlvFilterType.aidl
new file mode 100644
index 0000000..bd9e583
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTlvFilterType.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxTlvFilterType {
+  UNDEFINED,
+  SECTION,
+  TLV,
+  PAYLOAD_THROUGH,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsFilterSettings.aidl
new file mode 100644
index 0000000..d8d424f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsFilterSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxTsFilterSettings {
+  int tpid;
+  android.hardware.tv.tuner.DemuxTsFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..5d81bb6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsFilterSettingsFilterSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxTsFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+  android.hardware.tv.tuner.DemuxFilterAvSettings av;
+  android.hardware.tv.tuner.DemuxFilterPesDataSettings pesData;
+  android.hardware.tv.tuner.DemuxFilterRecordSettings record;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsFilterType.aidl
new file mode 100644
index 0000000..8be0e95
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsFilterType.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxTsFilterType {
+  UNDEFINED,
+  SECTION,
+  PES,
+  TS,
+  AUDIO,
+  VIDEO,
+  PCR,
+  RECORD,
+  TEMI,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsIndex.aidl
new file mode 100644
index 0000000..9ca684f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DemuxTsIndex.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxTsIndex {
+  FIRST_PACKET = (1 << 0) /* 1 */,
+  PAYLOAD_UNIT_START_INDICATOR = (1 << 1) /* 2 */,
+  CHANGE_TO_NOT_SCRAMBLED = (1 << 2) /* 4 */,
+  CHANGE_TO_EVEN_SCRAMBLED = (1 << 3) /* 8 */,
+  CHANGE_TO_ODD_SCRAMBLED = (1 << 4) /* 16 */,
+  DISCONTINUITY_INDICATOR = (1 << 5) /* 32 */,
+  RANDOM_ACCESS_INDICATOR = (1 << 6) /* 64 */,
+  PRIORITY_INDICATOR = (1 << 7) /* 128 */,
+  PCR_FLAG = (1 << 8) /* 256 */,
+  OPCR_FLAG = (1 << 9) /* 512 */,
+  SPLICING_POINT_FLAG = (1 << 10) /* 1024 */,
+  PRIVATE_DATA = (1 << 11) /* 2048 */,
+  ADAPTATION_EXTENSION_FLAG = (1 << 12) /* 4096 */,
+  MPT_INDEX_MPT = (1 << 16) /* 65536 */,
+  MPT_INDEX_VIDEO = (1 << 17) /* 131072 */,
+  MPT_INDEX_AUDIO = (1 << 18) /* 262144 */,
+  MPT_INDEX_TIMESTAMP_TARGET_VIDEO = (1 << 19) /* 524288 */,
+  MPT_INDEX_TIMESTAMP_TARGET_AUDIO = (1 << 20) /* 1048576 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DvrSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DvrSettings.aidl
new file mode 100644
index 0000000..26f864a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DvrSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union DvrSettings {
+  android.hardware.tv.tuner.RecordSettings record;
+  android.hardware.tv.tuner.PlaybackSettings playback;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DvrType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DvrType.aidl
new file mode 100644
index 0000000..6dab74b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/DvrType.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum DvrType {
+  RECORD,
+  PLAYBACK,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FilterDelayHint.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FilterDelayHint.aidl
new file mode 100644
index 0000000..1fdafd2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FilterDelayHint.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FilterDelayHint {
+  android.hardware.tv.tuner.FilterDelayHintType hintType = android.hardware.tv.tuner.FilterDelayHintType.INVALID;
+  int hintValue;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FilterDelayHintType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FilterDelayHintType.aidl
new file mode 100644
index 0000000..af35c70
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FilterDelayHintType.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FilterDelayHintType {
+  INVALID,
+  TIME_DELAY_IN_MS,
+  DATA_SIZE_DELAY_IN_BYTES,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl
new file mode 100644
index 0000000..45aa2af
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAnalogAftFlag {
+  UNDEFINED,
+  AFT_TRUE,
+  AFT_FALSE,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogCapabilities.aidl
new file mode 100644
index 0000000..46131be
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAnalogCapabilities {
+  int typeCap;
+  int sifStandardCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogSettings.aidl
new file mode 100644
index 0000000..33e9347
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogSettings.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAnalogSettings {
+  long frequency;
+  long endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAnalogType type = android.hardware.tv.tuner.FrontendAnalogType.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAnalogAftFlag aftFlag = android.hardware.tv.tuner.FrontendAnalogAftFlag.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAnalogSifStandard sifStandard = android.hardware.tv.tuner.FrontendAnalogSifStandard.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl
new file mode 100644
index 0000000..8d19461
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAnalogSifStandard {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  BG = (1 << 1) /* 2 */,
+  BG_A2 = (1 << 2) /* 4 */,
+  BG_NICAM = (1 << 3) /* 8 */,
+  I = (1 << 4) /* 16 */,
+  DK = (1 << 5) /* 32 */,
+  DK1_A2 = (1 << 6) /* 64 */,
+  DK2_A2 = (1 << 7) /* 128 */,
+  DK3_A2 = (1 << 8) /* 256 */,
+  DK_NICAM = (1 << 9) /* 512 */,
+  L = (1 << 10) /* 1024 */,
+  M = (1 << 11) /* 2048 */,
+  M_BTSC = (1 << 12) /* 4096 */,
+  M_A2 = (1 << 13) /* 8192 */,
+  M_EIAJ = (1 << 14) /* 16384 */,
+  I_NICAM = (1 << 15) /* 32768 */,
+  L_NICAM = (1 << 16) /* 65536 */,
+  L_PRIME = (1 << 17) /* 131072 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogType.aidl
new file mode 100644
index 0000000..bf8b000
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAnalogType.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAnalogType {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  PAL = (1 << 1) /* 2 */,
+  PAL_M = (1 << 2) /* 4 */,
+  PAL_N = (1 << 3) /* 8 */,
+  PAL_60 = (1 << 4) /* 16 */,
+  NTSC = (1 << 5) /* 32 */,
+  NTSC_443 = (1 << 6) /* 64 */,
+  SECAM = (1 << 7) /* 128 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl
new file mode 100644
index 0000000..9704f40
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3Bandwidth {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  BANDWIDTH_6MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_7MHZ = (1 << 2) /* 4 */,
+  BANDWIDTH_8MHZ = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Capabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Capabilities.aidl
new file mode 100644
index 0000000..b2a25c7
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Capabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtsc3Capabilities {
+  int bandwidthCap;
+  int modulationCap;
+  int timeInterleaveModeCap;
+  int codeRateCap;
+  int fecCap;
+  byte demodOutputFormatCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl
new file mode 100644
index 0000000..2d09271
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3CodeRate {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_2_15 = (1 << 1) /* 2 */,
+  CODERATE_3_15 = (1 << 2) /* 4 */,
+  CODERATE_4_15 = (1 << 3) /* 8 */,
+  CODERATE_5_15 = (1 << 4) /* 16 */,
+  CODERATE_6_15 = (1 << 5) /* 32 */,
+  CODERATE_7_15 = (1 << 6) /* 64 */,
+  CODERATE_8_15 = (1 << 7) /* 128 */,
+  CODERATE_9_15 = (1 << 8) /* 256 */,
+  CODERATE_10_15 = (1 << 9) /* 512 */,
+  CODERATE_11_15 = (1 << 10) /* 1024 */,
+  CODERATE_12_15 = (1 << 11) /* 2048 */,
+  CODERATE_13_15 = (1 << 12) /* 4096 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl
new file mode 100644
index 0000000..22267e7
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FrontendAtsc3DemodOutputFormat {
+  UNDEFINED = 0,
+  ATSC3_LINKLAYER_PACKET = (1 << 0) /* 1 */,
+  BASEBAND_PACKET = (1 << 1) /* 2 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl
new file mode 100644
index 0000000..2e229c0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3Fec {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  BCH_LDPC_16K = (1 << 1) /* 2 */,
+  BCH_LDPC_64K = (1 << 2) /* 4 */,
+  CRC_LDPC_16K = (1 << 3) /* 8 */,
+  CRC_LDPC_64K = (1 << 4) /* 16 */,
+  LDPC_16K = (1 << 5) /* 32 */,
+  LDPC_64K = (1 << 6) /* 64 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl
new file mode 100644
index 0000000..cbe8c1f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3Modulation {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_QPSK = (1 << 1) /* 2 */,
+  MOD_16QAM = (1 << 2) /* 4 */,
+  MOD_64QAM = (1 << 3) /* 8 */,
+  MOD_256QAM = (1 << 4) /* 16 */,
+  MOD_1024QAM = (1 << 5) /* 32 */,
+  MOD_4096QAM = (1 << 6) /* 64 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3PlpSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3PlpSettings.aidl
new file mode 100644
index 0000000..6301f96
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3PlpSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtsc3PlpSettings {
+  int plpId;
+  android.hardware.tv.tuner.FrontendAtsc3Modulation modulation = android.hardware.tv.tuner.FrontendAtsc3Modulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode interleaveMode = android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3CodeRate codeRate = android.hardware.tv.tuner.FrontendAtsc3CodeRate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3Fec fec = android.hardware.tv.tuner.FrontendAtsc3Fec.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Settings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Settings.aidl
new file mode 100644
index 0000000..3cbb0d0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3Settings.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtsc3Settings {
+  long frequency;
+  long endFrequency;
+  android.hardware.tv.tuner.FrontendAtsc3Bandwidth bandwidth = android.hardware.tv.tuner.FrontendAtsc3Bandwidth.UNDEFINED;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3DemodOutputFormat demodOutputFormat = android.hardware.tv.tuner.FrontendAtsc3DemodOutputFormat.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3PlpSettings[] plpSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl
new file mode 100644
index 0000000..4e70641
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3TimeInterleaveMode {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  CTI = (1 << 1) /* 2 */,
+  HTI = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtscCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtscCapabilities.aidl
new file mode 100644
index 0000000..c24afae
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtscCapabilities.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtscCapabilities {
+  int modulationCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtscModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtscModulation.aidl
new file mode 100644
index 0000000..7da48f1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtscModulation.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtscModulation {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_8VSB = (1 << 2) /* 4 */,
+  MOD_16VSB = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtscSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtscSettings.aidl
new file mode 100644
index 0000000..9121c12
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendAtscSettings.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtscSettings {
+  long frequency;
+  long endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtscModulation modulation = android.hardware.tv.tuner.FrontendAtscModulation.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendBandwidth.aidl
new file mode 100644
index 0000000..5355637
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendBandwidth.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendBandwidth {
+  android.hardware.tv.tuner.FrontendAtsc3Bandwidth atsc3 = android.hardware.tv.tuner.FrontendAtsc3Bandwidth.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbcBandwidth dvbc;
+  android.hardware.tv.tuner.FrontendDvbtBandwidth dvbt;
+  android.hardware.tv.tuner.FrontendIsdbtBandwidth isdbt;
+  android.hardware.tv.tuner.FrontendDtmbBandwidth dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl
new file mode 100644
index 0000000..61cbf12
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendCableTimeInterleaveMode {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  INTERLEAVING_128_1_0 = (1 << 1) /* 2 */,
+  INTERLEAVING_128_1_1 = (1 << 2) /* 4 */,
+  INTERLEAVING_64_2 = (1 << 3) /* 8 */,
+  INTERLEAVING_32_4 = (1 << 4) /* 16 */,
+  INTERLEAVING_16_8 = (1 << 5) /* 32 */,
+  INTERLEAVING_8_16 = (1 << 6) /* 64 */,
+  INTERLEAVING_128_2 = (1 << 7) /* 128 */,
+  INTERLEAVING_128_3 = (1 << 8) /* 256 */,
+  INTERLEAVING_128_4 = (1 << 9) /* 512 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendCapabilities.aidl
new file mode 100644
index 0000000..c9443b1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendCapabilities.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendCapabilities {
+  android.hardware.tv.tuner.FrontendAnalogCapabilities analogCaps;
+  android.hardware.tv.tuner.FrontendAtscCapabilities atscCaps;
+  android.hardware.tv.tuner.FrontendAtsc3Capabilities atsc3Caps;
+  android.hardware.tv.tuner.FrontendDtmbCapabilities dtmbCaps;
+  android.hardware.tv.tuner.FrontendDvbsCapabilities dvbsCaps;
+  android.hardware.tv.tuner.FrontendDvbcCapabilities dvbcCaps;
+  android.hardware.tv.tuner.FrontendDvbtCapabilities dvbtCaps;
+  android.hardware.tv.tuner.FrontendIsdbsCapabilities isdbsCaps;
+  android.hardware.tv.tuner.FrontendIsdbs3Capabilities isdbs3Caps;
+  android.hardware.tv.tuner.FrontendIsdbtCapabilities isdbtCaps;
+  @nullable android.hardware.tv.tuner.FrontendIptvCapabilities iptvCaps;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl
new file mode 100644
index 0000000..6f62d91
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbBandwidth {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  BANDWIDTH_8MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_6MHZ = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbCapabilities.aidl
new file mode 100644
index 0000000..8d35104
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbCapabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDtmbCapabilities {
+  int transmissionModeCap;
+  int bandwidthCap;
+  int modulationCap;
+  int codeRateCap;
+  int guardIntervalCap;
+  int interleaveModeCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl
new file mode 100644
index 0000000..d6be639
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbCodeRate {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_2_5 = (1 << 1) /* 2 */,
+  CODERATE_3_5 = (1 << 2) /* 4 */,
+  CODERATE_4_5 = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl
new file mode 100644
index 0000000..5626064
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbGuardInterval {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  PN_420_VARIOUS = (1 << 1) /* 2 */,
+  PN_595_CONST = (1 << 2) /* 4 */,
+  PN_945_VARIOUS = (1 << 3) /* 8 */,
+  PN_420_CONST = (1 << 4) /* 16 */,
+  PN_945_CONST = (1 << 5) /* 32 */,
+  PN_RESERVED = (1 << 6) /* 64 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbModulation.aidl
new file mode 100644
index 0000000..036e64b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbModulation.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbModulation {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  CONSTELLATION_4QAM = (1 << 1) /* 2 */,
+  CONSTELLATION_4QAM_NR = (1 << 2) /* 4 */,
+  CONSTELLATION_16QAM = (1 << 3) /* 8 */,
+  CONSTELLATION_32QAM = (1 << 4) /* 16 */,
+  CONSTELLATION_64QAM = (1 << 5) /* 32 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbSettings.aidl
new file mode 100644
index 0000000..5f9b775
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbSettings.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDtmbSettings {
+  long frequency;
+  long endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbTransmissionMode transmissionMode = android.hardware.tv.tuner.FrontendDtmbTransmissionMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbBandwidth bandwidth = android.hardware.tv.tuner.FrontendDtmbBandwidth.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbModulation modulation = android.hardware.tv.tuner.FrontendDtmbModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbCodeRate codeRate = android.hardware.tv.tuner.FrontendDtmbCodeRate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbGuardInterval guardInterval = android.hardware.tv.tuner.FrontendDtmbGuardInterval.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode interleaveMode = android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl
new file mode 100644
index 0000000..1223887
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbTimeInterleaveMode {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  TIMER_INT_240 = (1 << 1) /* 2 */,
+  TIMER_INT_720 = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl
new file mode 100644
index 0000000..0498825
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbTransmissionMode {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  C1 = (1 << 1) /* 2 */,
+  C3780 = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl
new file mode 100644
index 0000000..985add1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FrontendDvbcAnnex {
+  UNDEFINED = 0,
+  A = (1 << 0) /* 1 */,
+  B = (1 << 1) /* 2 */,
+  C = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl
new file mode 100644
index 0000000..c253cfe
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbcBandwidth {
+  UNDEFINED = 0,
+  BANDWIDTH_5MHZ = (1 << 0) /* 1 */,
+  BANDWIDTH_6MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_7MHZ = (1 << 2) /* 4 */,
+  BANDWIDTH_8MHZ = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcCapabilities.aidl
new file mode 100644
index 0000000..0c0e3ee
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbcCapabilities {
+  int modulationCap;
+  long fecCap;
+  byte annexCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcModulation.aidl
new file mode 100644
index 0000000..c18e83e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcModulation.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbcModulation {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_16QAM = (1 << 1) /* 2 */,
+  MOD_32QAM = (1 << 2) /* 4 */,
+  MOD_64QAM = (1 << 3) /* 8 */,
+  MOD_128QAM = (1 << 4) /* 16 */,
+  MOD_256QAM = (1 << 5) /* 32 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl
new file mode 100644
index 0000000..a6fbc6d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbcOuterFec {
+  UNDEFINED = 0,
+  OUTER_FEC_NONE,
+  OUTER_FEC_RS,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcSettings.aidl
new file mode 100644
index 0000000..6b2caed
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbcSettings.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbcSettings {
+  long frequency;
+  long endFrequency;
+  android.hardware.tv.tuner.FrontendDvbcModulation modulation = android.hardware.tv.tuner.FrontendDvbcModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendInnerFec fec = android.hardware.tv.tuner.FrontendInnerFec.FEC_UNDEFINED;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendDvbcOuterFec outerFec = android.hardware.tv.tuner.FrontendDvbcOuterFec.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbcAnnex annex = android.hardware.tv.tuner.FrontendDvbcAnnex.UNDEFINED;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendCableTimeInterleaveMode interleaveMode = android.hardware.tv.tuner.FrontendCableTimeInterleaveMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbcBandwidth bandwidth = android.hardware.tv.tuner.FrontendDvbcBandwidth.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsCapabilities.aidl
new file mode 100644
index 0000000..43e8aee
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbsCapabilities {
+  int modulationCap;
+  long innerfecCap;
+  byte standard;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsCodeRate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsCodeRate.aidl
new file mode 100644
index 0000000..4c3d4e4
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsCodeRate.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbsCodeRate {
+  android.hardware.tv.tuner.FrontendInnerFec fec = android.hardware.tv.tuner.FrontendInnerFec.FEC_UNDEFINED;
+  boolean isLinear;
+  boolean isShortFrames;
+  int bitsPer1000Symbol;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsModulation.aidl
new file mode 100644
index 0000000..71957d5
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsModulation.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsModulation {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_QPSK = (1 << 1) /* 2 */,
+  MOD_8PSK = (1 << 2) /* 4 */,
+  MOD_16QAM = (1 << 3) /* 8 */,
+  MOD_16PSK = (1 << 4) /* 16 */,
+  MOD_32PSK = (1 << 5) /* 32 */,
+  MOD_ACM = (1 << 6) /* 64 */,
+  MOD_8APSK = (1 << 7) /* 128 */,
+  MOD_16APSK = (1 << 8) /* 256 */,
+  MOD_32APSK = (1 << 9) /* 512 */,
+  MOD_64APSK = (1 << 10) /* 1024 */,
+  MOD_128APSK = (1 << 11) /* 2048 */,
+  MOD_256APSK = (1 << 12) /* 4096 */,
+  MOD_RESERVED = (1 << 13) /* 8192 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsPilot.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsPilot.aidl
new file mode 100644
index 0000000..e3543b3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsPilot.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsPilot {
+  UNDEFINED,
+  ON,
+  OFF,
+  AUTO,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl
new file mode 100644
index 0000000..2181abf
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsRolloff {
+  UNDEFINED,
+  ROLLOFF_0_35,
+  ROLLOFF_0_25,
+  ROLLOFF_0_20,
+  ROLLOFF_0_15,
+  ROLLOFF_0_10,
+  ROLLOFF_0_5,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsScanType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsScanType.aidl
new file mode 100644
index 0000000..46edb56
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsScanType.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsScanType {
+  UNDEFINED = 0,
+  DIRECT,
+  DISEQC,
+  UNICABLE,
+  JESS,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsSettings.aidl
new file mode 100644
index 0000000..dab8888
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsSettings.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbsSettings {
+  long frequency;
+  long endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsModulation modulation = android.hardware.tv.tuner.FrontendDvbsModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsCodeRate coderate;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendDvbsRolloff rolloff = android.hardware.tv.tuner.FrontendDvbsRolloff.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsPilot pilot = android.hardware.tv.tuner.FrontendDvbsPilot.UNDEFINED;
+  int inputStreamId;
+  android.hardware.tv.tuner.FrontendDvbsStandard standard = android.hardware.tv.tuner.FrontendDvbsStandard.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsVcmMode vcmMode = android.hardware.tv.tuner.FrontendDvbsVcmMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsScanType scanType = android.hardware.tv.tuner.FrontendDvbsScanType.UNDEFINED;
+  boolean isDiseqcRxMessage;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsStandard.aidl
new file mode 100644
index 0000000..bcb1c6d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsStandard.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FrontendDvbsStandard {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  S = (1 << 1) /* 2 */,
+  S2 = (1 << 2) /* 4 */,
+  S2X = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl
new file mode 100644
index 0000000..af87423
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsVcmMode {
+  UNDEFINED,
+  AUTO,
+  MANUAL,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl
new file mode 100644
index 0000000..ff2d9e4
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtBandwidth {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  BANDWIDTH_8MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_7MHZ = (1 << 2) /* 4 */,
+  BANDWIDTH_6MHZ = (1 << 3) /* 8 */,
+  BANDWIDTH_5MHZ = (1 << 4) /* 16 */,
+  BANDWIDTH_1_7MHZ = (1 << 5) /* 32 */,
+  BANDWIDTH_10MHZ = (1 << 6) /* 64 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtCapabilities.aidl
new file mode 100644
index 0000000..a0e6ce2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtCapabilities.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbtCapabilities {
+  int transmissionModeCap;
+  int bandwidthCap;
+  int constellationCap;
+  int coderateCap;
+  int hierarchyCap;
+  int guardIntervalCap;
+  boolean isT2Supported;
+  boolean isMisoSupported;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl
new file mode 100644
index 0000000..8d2df06
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtCoderate {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_1_2 = (1 << 1) /* 2 */,
+  CODERATE_2_3 = (1 << 2) /* 4 */,
+  CODERATE_3_4 = (1 << 3) /* 8 */,
+  CODERATE_5_6 = (1 << 4) /* 16 */,
+  CODERATE_7_8 = (1 << 5) /* 32 */,
+  CODERATE_3_5 = (1 << 6) /* 64 */,
+  CODERATE_4_5 = (1 << 7) /* 128 */,
+  CODERATE_6_7 = (1 << 8) /* 256 */,
+  CODERATE_8_9 = (1 << 9) /* 512 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl
new file mode 100644
index 0000000..4bd5691
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtConstellation {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  CONSTELLATION_QPSK = (1 << 1) /* 2 */,
+  CONSTELLATION_16QAM = (1 << 2) /* 4 */,
+  CONSTELLATION_64QAM = (1 << 3) /* 8 */,
+  CONSTELLATION_256QAM = (1 << 4) /* 16 */,
+  CONSTELLATION_QPSK_R = (1 << 5) /* 32 */,
+  CONSTELLATION_16QAM_R = (1 << 6) /* 64 */,
+  CONSTELLATION_64QAM_R = (1 << 7) /* 128 */,
+  CONSTELLATION_256QAM_R = (1 << 8) /* 256 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl
new file mode 100644
index 0000000..01c2b66
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtGuardInterval {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  INTERVAL_1_32 = (1 << 1) /* 2 */,
+  INTERVAL_1_16 = (1 << 2) /* 4 */,
+  INTERVAL_1_8 = (1 << 3) /* 8 */,
+  INTERVAL_1_4 = (1 << 4) /* 16 */,
+  INTERVAL_1_128 = (1 << 5) /* 32 */,
+  INTERVAL_19_128 = (1 << 6) /* 64 */,
+  INTERVAL_19_256 = (1 << 7) /* 128 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl
new file mode 100644
index 0000000..bd86479
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtHierarchy {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  HIERARCHY_NON_NATIVE = (1 << 1) /* 2 */,
+  HIERARCHY_1_NATIVE = (1 << 2) /* 4 */,
+  HIERARCHY_2_NATIVE = (1 << 3) /* 8 */,
+  HIERARCHY_4_NATIVE = (1 << 4) /* 16 */,
+  HIERARCHY_NON_INDEPTH = (1 << 5) /* 32 */,
+  HIERARCHY_1_INDEPTH = (1 << 6) /* 64 */,
+  HIERARCHY_2_INDEPTH = (1 << 7) /* 128 */,
+  HIERARCHY_4_INDEPTH = (1 << 8) /* 256 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl
new file mode 100644
index 0000000..dc8e12c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtPlpMode {
+  UNDEFINED,
+  AUTO,
+  MANUAL,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtSettings.aidl
new file mode 100644
index 0000000..ec1277a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtSettings.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbtSettings {
+  long frequency;
+  long endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtTransmissionMode transmissionMode = android.hardware.tv.tuner.FrontendDvbtTransmissionMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtBandwidth bandwidth = android.hardware.tv.tuner.FrontendDvbtBandwidth.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtConstellation constellation = android.hardware.tv.tuner.FrontendDvbtConstellation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtHierarchy hierarchy = android.hardware.tv.tuner.FrontendDvbtHierarchy.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtCoderate hpCoderate = android.hardware.tv.tuner.FrontendDvbtCoderate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtCoderate lpCoderate = android.hardware.tv.tuner.FrontendDvbtCoderate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtGuardInterval guardInterval = android.hardware.tv.tuner.FrontendDvbtGuardInterval.UNDEFINED;
+  boolean isHighPriority;
+  android.hardware.tv.tuner.FrontendDvbtStandard standard = android.hardware.tv.tuner.FrontendDvbtStandard.UNDEFINED;
+  boolean isMiso;
+  android.hardware.tv.tuner.FrontendDvbtPlpMode plpMode = android.hardware.tv.tuner.FrontendDvbtPlpMode.UNDEFINED;
+  int plpId;
+  int plpGroupId;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtStandard.aidl
new file mode 100644
index 0000000..080cc5c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtStandard.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FrontendDvbtStandard {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  T = (1 << 1) /* 2 */,
+  T2 = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl
new file mode 100644
index 0000000..3731f86
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtTransmissionMode {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  MODE_2K = (1 << 1) /* 2 */,
+  MODE_8K = (1 << 2) /* 4 */,
+  MODE_4K = (1 << 3) /* 8 */,
+  MODE_1K = (1 << 4) /* 16 */,
+  MODE_16K = (1 << 5) /* 32 */,
+  MODE_32K = (1 << 6) /* 64 */,
+  MODE_8K_E = (1 << 7) /* 128 */,
+  MODE_16K_E = (1 << 8) /* 256 */,
+  MODE_32K_E = (1 << 9) /* 512 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendEventType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendEventType.aidl
new file mode 100644
index 0000000..101e347
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendEventType.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendEventType {
+  LOCKED,
+  NO_SIGNAL,
+  LOST_LOCK,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendGuardInterval.aidl
new file mode 100644
index 0000000..15c738a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendGuardInterval.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendGuardInterval {
+  android.hardware.tv.tuner.FrontendDvbtGuardInterval dvbt = android.hardware.tv.tuner.FrontendDvbtGuardInterval.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtGuardInterval isdbt;
+  android.hardware.tv.tuner.FrontendDtmbGuardInterval dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendInfo.aidl
new file mode 100644
index 0000000..d5bdd58
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendInfo.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendInfo {
+  android.hardware.tv.tuner.FrontendType type = android.hardware.tv.tuner.FrontendType.UNDEFINED;
+  long minFrequency;
+  long maxFrequency;
+  int minSymbolRate;
+  int maxSymbolRate;
+  long acquireRange;
+  int exclusiveGroupId;
+  android.hardware.tv.tuner.FrontendStatusType[] statusCaps;
+  android.hardware.tv.tuner.FrontendCapabilities frontendCaps;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendInnerFec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendInnerFec.aidl
new file mode 100644
index 0000000..da91888
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendInnerFec.aidl
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum FrontendInnerFec {
+  FEC_UNDEFINED = 0,
+  AUTO = (1L << 0) /* 1 */,
+  FEC_1_2 = (1L << 1) /* 2 */,
+  FEC_1_3 = (1L << 2) /* 4 */,
+  FEC_1_4 = (1L << 3) /* 8 */,
+  FEC_1_5 = (1L << 4) /* 16 */,
+  FEC_2_3 = (1L << 5) /* 32 */,
+  FEC_2_5 = (1L << 6) /* 64 */,
+  FEC_2_9 = (1L << 7) /* 128 */,
+  FEC_3_4 = (1L << 8) /* 256 */,
+  FEC_3_5 = (1L << 9) /* 512 */,
+  FEC_4_5 = (1L << 10) /* 1024 */,
+  FEC_4_15 = (1L << 11) /* 2048 */,
+  FEC_5_6 = (1L << 12) /* 4096 */,
+  FEC_5_9 = (1L << 13) /* 8192 */,
+  FEC_6_7 = (1L << 14) /* 16384 */,
+  FEC_7_8 = (1L << 15) /* 32768 */,
+  FEC_7_9 = (1L << 16) /* 65536 */,
+  FEC_7_15 = (1L << 17) /* 131072 */,
+  FEC_8_9 = (1L << 18) /* 262144 */,
+  FEC_8_15 = (1L << 19) /* 524288 */,
+  FEC_9_10 = (1L << 20) /* 1048576 */,
+  FEC_9_20 = (1L << 21) /* 2097152 */,
+  FEC_11_15 = (1L << 22) /* 4194304 */,
+  FEC_11_20 = (1L << 23) /* 8388608 */,
+  FEC_11_45 = (1L << 24) /* 16777216 */,
+  FEC_13_18 = (1L << 25) /* 33554432 */,
+  FEC_13_45 = (1L << 26) /* 67108864 */,
+  FEC_14_45 = (1L << 27) /* 134217728 */,
+  FEC_23_36 = (1L << 28) /* 268435456 */,
+  FEC_25_36 = (1L << 29) /* 536870912 */,
+  FEC_26_45 = (1L << 30) /* 1073741824 */,
+  FEC_28_45 = (1L << 31) /* 2147483648 */,
+  FEC_29_45 = (1L << 32) /* 4294967296 */,
+  FEC_31_45 = (1L << 33) /* 8589934592 */,
+  FEC_32_45 = (1L << 34) /* 17179869184 */,
+  FEC_77_90 = (1L << 35) /* 34359738368 */,
+  FEC_2_15 = (1L << 36) /* 68719476736 */,
+  FEC_3_15 = (1L << 37) /* 137438953472 */,
+  FEC_5_15 = (1L << 38) /* 274877906944 */,
+  FEC_6_15 = (1L << 39) /* 549755813888 */,
+  FEC_9_15 = (1L << 40) /* 1099511627776 */,
+  FEC_10_15 = (1L << 41) /* 2199023255552 */,
+  FEC_12_15 = (1L << 42) /* 4398046511104 */,
+  FEC_13_15 = (1L << 43) /* 8796093022208 */,
+  FEC_18_30 = (1L << 44) /* 17592186044416 */,
+  FEC_20_30 = (1L << 45) /* 35184372088832 */,
+  FEC_90_180 = (1L << 46) /* 70368744177664 */,
+  FEC_96_180 = (1L << 47) /* 140737488355328 */,
+  FEC_104_180 = (1L << 48) /* 281474976710656 */,
+  FEC_128_180 = (1L << 49) /* 562949953421312 */,
+  FEC_132_180 = (1L << 50) /* 1125899906842624 */,
+  FEC_135_180 = (1L << 51) /* 2251799813685248 */,
+  FEC_140_180 = (1L << 52) /* 4503599627370496 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
new file mode 100644
index 0000000..ac38731
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendInterleaveMode {
+  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/2/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl
new file mode 100644
index 0000000..543543d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIptvCapabilities {
+  int protocolCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettings.aidl
new file mode 100644
index 0000000..73582f3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettings.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIptvSettings {
+  android.hardware.tv.tuner.FrontendIptvSettingsProtocol protocol = android.hardware.tv.tuner.FrontendIptvSettingsProtocol.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIptvSettingsFec fec;
+  android.hardware.tv.tuner.FrontendIptvSettingsIgmp igmp = android.hardware.tv.tuner.FrontendIptvSettingsIgmp.UNDEFINED;
+  long bitrate;
+  android.hardware.tv.tuner.DemuxIpAddress ipAddr;
+  String contentUrl;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl
new file mode 100644
index 0000000..c361377
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIptvSettingsFec {
+  android.hardware.tv.tuner.FrontendIptvSettingsFecType type;
+  int fecColNum;
+  int fecRowNum;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
new file mode 100644
index 0000000..5806cc5
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIptvSettingsFecType {
+  UNDEFINED = 0,
+  COLUMN = (1 << 0) /* 1 */,
+  ROW = (1 << 1) /* 2 */,
+  COLUMN_ROW = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
new file mode 100644
index 0000000..43ae523
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIptvSettingsIgmp {
+  UNDEFINED = 0,
+  V1 = (1 << 0) /* 1 */,
+  V2 = (1 << 1) /* 2 */,
+  V3 = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
new file mode 100644
index 0000000..2e4c478
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIptvSettingsProtocol {
+  UNDEFINED = 0,
+  UDP = (1 << 0) /* 1 */,
+  RTP = (1 << 1) /* 2 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Capabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Capabilities.aidl
new file mode 100644
index 0000000..4be37c2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Capabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbs3Capabilities {
+  int modulationCap;
+  int coderateCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl
new file mode 100644
index 0000000..de865ca
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbs3Coderate {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_1_3 = (1 << 1) /* 2 */,
+  CODERATE_2_5 = (1 << 2) /* 4 */,
+  CODERATE_1_2 = (1 << 3) /* 8 */,
+  CODERATE_3_5 = (1 << 4) /* 16 */,
+  CODERATE_2_3 = (1 << 5) /* 32 */,
+  CODERATE_3_4 = (1 << 6) /* 64 */,
+  CODERATE_7_9 = (1 << 7) /* 128 */,
+  CODERATE_4_5 = (1 << 8) /* 256 */,
+  CODERATE_5_6 = (1 << 9) /* 512 */,
+  CODERATE_7_8 = (1 << 10) /* 1024 */,
+  CODERATE_9_10 = (1 << 11) /* 2048 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl
new file mode 100644
index 0000000..adc902d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbs3Modulation {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_BPSK = (1 << 1) /* 2 */,
+  MOD_QPSK = (1 << 2) /* 4 */,
+  MOD_8PSK = (1 << 3) /* 8 */,
+  MOD_16APSK = (1 << 4) /* 16 */,
+  MOD_32APSK = (1 << 5) /* 32 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl
new file mode 100644
index 0000000..c93cf20
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbs3Rolloff {
+  UNDEFINED,
+  ROLLOFF_0_03,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Settings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Settings.aidl
new file mode 100644
index 0000000..8c491d6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbs3Settings.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbs3Settings {
+  long frequency;
+  long endFrequency;
+  int streamId;
+  android.hardware.tv.tuner.FrontendIsdbsStreamIdType streamIdType = android.hardware.tv.tuner.FrontendIsdbsStreamIdType.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbs3Modulation modulation = android.hardware.tv.tuner.FrontendIsdbs3Modulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbs3Coderate coderate = android.hardware.tv.tuner.FrontendIsdbs3Coderate.UNDEFINED;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendIsdbs3Rolloff rolloff = android.hardware.tv.tuner.FrontendIsdbs3Rolloff.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsCapabilities.aidl
new file mode 100644
index 0000000..2cb892c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbsCapabilities {
+  int modulationCap;
+  int coderateCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl
new file mode 100644
index 0000000..a0e436f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbsCoderate {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_1_2 = (1 << 1) /* 2 */,
+  CODERATE_2_3 = (1 << 2) /* 4 */,
+  CODERATE_3_4 = (1 << 3) /* 8 */,
+  CODERATE_5_6 = (1 << 4) /* 16 */,
+  CODERATE_7_8 = (1 << 5) /* 32 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl
new file mode 100644
index 0000000..61a21c3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbsModulation {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_BPSK = (1 << 1) /* 2 */,
+  MOD_QPSK = (1 << 2) /* 4 */,
+  MOD_TC8PSK = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl
new file mode 100644
index 0000000..b769231
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbsRolloff {
+  UNDEFINED,
+  ROLLOFF_0_35,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsSettings.aidl
new file mode 100644
index 0000000..324fb6f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsSettings.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbsSettings {
+  long frequency;
+  long endFrequency;
+  int streamId;
+  android.hardware.tv.tuner.FrontendIsdbsStreamIdType streamIdType = android.hardware.tv.tuner.FrontendIsdbsStreamIdType.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbsModulation modulation = android.hardware.tv.tuner.FrontendIsdbsModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbsCoderate coderate = android.hardware.tv.tuner.FrontendIsdbsCoderate.UNDEFINED;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendIsdbsRolloff rolloff = android.hardware.tv.tuner.FrontendIsdbsRolloff.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl
new file mode 100644
index 0000000..77956b6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbsStreamIdType {
+  STREAM_ID,
+  RELATIVE_STREAM_NUMBER,
+  UNDEFINED,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl
new file mode 100644
index 0000000..209620f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtBandwidth {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  BANDWIDTH_8MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_7MHZ = (1 << 2) /* 4 */,
+  BANDWIDTH_6MHZ = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
new file mode 100644
index 0000000..dbf631b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbtCapabilities {
+  int modeCap;
+  int bandwidthCap;
+  int modulationCap;
+  int coderateCap;
+  int guardIntervalCap;
+  int timeInterleaveCap;
+  boolean isSegmentAuto;
+  boolean isFullSegment;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl
new file mode 100644
index 0000000..4236b7c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtCoderate {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_1_2 = (1 << 1) /* 2 */,
+  CODERATE_2_3 = (1 << 2) /* 4 */,
+  CODERATE_3_4 = (1 << 3) /* 8 */,
+  CODERATE_5_6 = (1 << 4) /* 16 */,
+  CODERATE_7_8 = (1 << 5) /* 32 */,
+  CODERATE_3_5 = (1 << 6) /* 64 */,
+  CODERATE_4_5 = (1 << 7) /* 128 */,
+  CODERATE_6_7 = (1 << 8) /* 256 */,
+  CODERATE_8_9 = (1 << 9) /* 512 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl
new file mode 100644
index 0000000..86225e2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtGuardInterval {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  INTERVAL_1_32 = (1 << 1) /* 2 */,
+  INTERVAL_1_16 = (1 << 2) /* 4 */,
+  INTERVAL_1_8 = (1 << 3) /* 8 */,
+  INTERVAL_1_4 = (1 << 4) /* 16 */,
+  INTERVAL_1_128 = (1 << 5) /* 32 */,
+  INTERVAL_19_128 = (1 << 6) /* 64 */,
+  INTERVAL_19_256 = (1 << 7) /* 128 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
new file mode 100644
index 0000000..0055793
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+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/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtMode.aidl
new file mode 100644
index 0000000..0e38c26
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtMode {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  MODE_1 = (1 << 1) /* 2 */,
+  MODE_2 = (1 << 2) /* 4 */,
+  MODE_3 = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl
new file mode 100644
index 0000000..4474c83
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtModulation {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_DQPSK = (1 << 1) /* 2 */,
+  MOD_QPSK = (1 << 2) /* 4 */,
+  MOD_16QAM = (1 << 3) /* 8 */,
+  MOD_64QAM = (1 << 4) /* 16 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
new file mode 100644
index 0000000..1387e66
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtPartialReceptionFlag {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  FALSE = (1 << 1) /* 2 */,
+  TRUE = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
new file mode 100644
index 0000000..605bc21
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbtSettings {
+  long frequency;
+  long endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.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.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/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
new file mode 100644
index 0000000..b9d76ee
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtTimeInterleaveMode {
+  UNDEFINED = 0,
+  AUTO = (1 << 0) /* 1 */,
+  INTERLEAVE_1_0 = (1 << 1) /* 2 */,
+  INTERLEAVE_1_4 = (1 << 2) /* 4 */,
+  INTERLEAVE_1_8 = (1 << 3) /* 8 */,
+  INTERLEAVE_1_16 = (1 << 4) /* 16 */,
+  INTERLEAVE_2_0 = (1 << 5) /* 32 */,
+  INTERLEAVE_2_2 = (1 << 6) /* 64 */,
+  INTERLEAVE_2_4 = (1 << 7) /* 128 */,
+  INTERLEAVE_2_8 = (1 << 8) /* 256 */,
+  INTERLEAVE_3_0 = (1 << 9) /* 512 */,
+  INTERLEAVE_3_1 = (1 << 10) /* 1024 */,
+  INTERLEAVE_3_2 = (1 << 11) /* 2048 */,
+  INTERLEAVE_3_4 = (1 << 12) /* 4096 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendModulation.aidl
new file mode 100644
index 0000000..6e396b0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendModulation.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendModulation {
+  android.hardware.tv.tuner.FrontendDvbcModulation dvbc = android.hardware.tv.tuner.FrontendDvbcModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsModulation dvbs;
+  android.hardware.tv.tuner.FrontendDvbtConstellation dvbt;
+  android.hardware.tv.tuner.FrontendIsdbsModulation isdbs;
+  android.hardware.tv.tuner.FrontendIsdbs3Modulation isdbs3;
+  android.hardware.tv.tuner.FrontendIsdbtModulation isdbt;
+  android.hardware.tv.tuner.FrontendAtscModulation atsc;
+  android.hardware.tv.tuner.FrontendAtsc3Modulation atsc3;
+  android.hardware.tv.tuner.FrontendDtmbModulation dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendModulationStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendModulationStatus.aidl
new file mode 100644
index 0000000..723fdd0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendModulationStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendModulationStatus {
+  android.hardware.tv.tuner.FrontendDvbcModulation dvbc = android.hardware.tv.tuner.FrontendDvbcModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsModulation dvbs;
+  android.hardware.tv.tuner.FrontendIsdbsModulation isdbs;
+  android.hardware.tv.tuner.FrontendIsdbs3Modulation isdbs3;
+  android.hardware.tv.tuner.FrontendIsdbtModulation isdbt;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendRollOff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendRollOff.aidl
new file mode 100644
index 0000000..c5f8b8e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendRollOff.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendRollOff {
+  android.hardware.tv.tuner.FrontendDvbsRolloff dvbs = android.hardware.tv.tuner.FrontendDvbsRolloff.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbsRolloff isdbs;
+  android.hardware.tv.tuner.FrontendIsdbs3Rolloff isdbs3;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.aidl
new file mode 100644
index 0000000..56ef3e3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendScanAtsc3PlpInfo {
+  int plpId;
+  boolean bLlsFlag;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanMessage.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanMessage.aidl
new file mode 100644
index 0000000..e763cfb
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanMessage.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendScanMessage {
+  boolean isLocked;
+  boolean isEnd;
+  int progressPercent;
+  long[] frequencies;
+  int[] symbolRates;
+  android.hardware.tv.tuner.FrontendDvbtHierarchy hierarchy;
+  android.hardware.tv.tuner.FrontendAnalogType analogType;
+  int[] plpIds;
+  int[] groupIds;
+  int[] inputStreamIds;
+  android.hardware.tv.tuner.FrontendScanMessageStandard std;
+  android.hardware.tv.tuner.FrontendScanAtsc3PlpInfo[] atsc3PlpInfos;
+  android.hardware.tv.tuner.FrontendModulation modulation;
+  android.hardware.tv.tuner.FrontendDvbcAnnex annex;
+  boolean isHighPriority;
+  int[] dvbtCellIds;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanMessageStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanMessageStandard.aidl
new file mode 100644
index 0000000..e163fc6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanMessageStandard.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendScanMessageStandard {
+  android.hardware.tv.tuner.FrontendDvbsStandard sStd = android.hardware.tv.tuner.FrontendDvbsStandard.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtStandard tStd;
+  android.hardware.tv.tuner.FrontendAnalogSifStandard sifStd;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanMessageType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanMessageType.aidl
new file mode 100644
index 0000000..186dbd7
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanMessageType.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendScanMessageType {
+  LOCKED,
+  END,
+  PROGRESS_PERCENT,
+  FREQUENCY,
+  SYMBOL_RATE,
+  HIERARCHY,
+  ANALOG_TYPE,
+  PLP_IDS,
+  GROUP_IDS,
+  INPUT_STREAM_IDS,
+  STANDARD,
+  ATSC3_PLP_INFO,
+  MODULATION,
+  DVBC_ANNEX,
+  HIGH_PRIORITY,
+  DVBT_CELL_IDS,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanType.aidl
new file mode 100644
index 0000000..cef02cc
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendScanType.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendScanType {
+  SCAN_UNDEFINED = 0,
+  SCAN_AUTO = (1 << 0) /* 1 */,
+  SCAN_BLIND = (1 << 1) /* 2 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendSettings.aidl
new file mode 100644
index 0000000..9810ba6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendSettings.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendSettings {
+  android.hardware.tv.tuner.FrontendAnalogSettings analog;
+  android.hardware.tv.tuner.FrontendAtscSettings atsc;
+  android.hardware.tv.tuner.FrontendAtsc3Settings atsc3;
+  android.hardware.tv.tuner.FrontendDvbsSettings dvbs;
+  android.hardware.tv.tuner.FrontendDvbcSettings dvbc;
+  android.hardware.tv.tuner.FrontendDvbtSettings dvbt;
+  android.hardware.tv.tuner.FrontendIsdbsSettings isdbs;
+  android.hardware.tv.tuner.FrontendIsdbs3Settings isdbs3;
+  android.hardware.tv.tuner.FrontendIsdbtSettings isdbt;
+  android.hardware.tv.tuner.FrontendDtmbSettings dtmb;
+  @nullable android.hardware.tv.tuner.FrontendIptvSettings iptv;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendSpectralInversion.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendSpectralInversion.aidl
new file mode 100644
index 0000000..14ec2fd
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendSpectralInversion.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendSpectralInversion {
+  UNDEFINED,
+  NORMAL,
+  INVERTED,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatus.aidl
new file mode 100644
index 0000000..b991ab6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendStatus {
+  boolean isDemodLocked;
+  int snr;
+  int ber;
+  int per;
+  int preBer;
+  int signalQuality;
+  int signalStrength;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendInnerFec innerFec;
+  android.hardware.tv.tuner.FrontendModulationStatus modulationStatus;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion;
+  android.hardware.tv.tuner.LnbVoltage lnbVoltage;
+  int plpId;
+  boolean isEWBS;
+  int agc;
+  boolean isLnaOn;
+  boolean[] isLayerError;
+  int mer;
+  long freqOffset;
+  android.hardware.tv.tuner.FrontendDvbtHierarchy hierarchy;
+  boolean isRfLocked;
+  android.hardware.tv.tuner.FrontendStatusAtsc3PlpInfo[] plpInfo;
+  android.hardware.tv.tuner.FrontendModulation[] modulations;
+  int[] bers;
+  android.hardware.tv.tuner.FrontendInnerFec[] codeRates;
+  android.hardware.tv.tuner.FrontendBandwidth bandwidth;
+  android.hardware.tv.tuner.FrontendGuardInterval interval;
+  android.hardware.tv.tuner.FrontendTransmissionMode transmissionMode;
+  int uec;
+  int systemId;
+  android.hardware.tv.tuner.FrontendInterleaveMode[] interleaving;
+  int[] isdbtSegment;
+  int[] tsDataRate;
+  android.hardware.tv.tuner.FrontendRollOff rollOff;
+  boolean isMiso;
+  boolean isLinear;
+  boolean isShortFrames;
+  android.hardware.tv.tuner.FrontendIsdbtMode isdbtMode;
+  android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
+  int[] streamIdList;
+  int[] dvbtCellIds;
+  android.hardware.tv.tuner.FrontendScanAtsc3PlpInfo[] allPlpInfo;
+  String iptvContentUrl = "";
+  long iptvPacketsReceived;
+  long iptvPacketsLost;
+  int iptvWorstJitterMs;
+  int iptvAverageJitterMs;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.aidl
new file mode 100644
index 0000000..8f65925
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendStatusAtsc3PlpInfo {
+  int plpId;
+  boolean isLocked;
+  int uec;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatusReadiness.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatusReadiness.aidl
new file mode 100644
index 0000000..13735fa
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatusReadiness.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendStatusReadiness {
+  UNDEFINED,
+  UNAVAILABLE,
+  UNSTABLE,
+  STABLE,
+  UNSUPPORTED,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatusType.aidl
new file mode 100644
index 0000000..9f34e8d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendStatusType {
+  DEMOD_LOCK,
+  SNR,
+  BER,
+  PER,
+  PRE_BER,
+  SIGNAL_QUALITY,
+  SIGNAL_STRENGTH,
+  SYMBOL_RATE,
+  FEC,
+  MODULATION,
+  SPECTRAL,
+  LNB_VOLTAGE,
+  PLP_ID,
+  EWBS,
+  AGC,
+  LNA,
+  LAYER_ERROR,
+  MER,
+  FREQ_OFFSET,
+  HIERARCHY,
+  RF_LOCK,
+  ATSC3_PLP_INFO,
+  MODULATIONS,
+  BERS,
+  CODERATES,
+  BANDWIDTH,
+  GUARD_INTERVAL,
+  TRANSMISSION_MODE,
+  UEC,
+  T2_SYSTEM_ID,
+  INTERLEAVINGS,
+  ISDBT_SEGMENTS,
+  TS_DATA_RATES,
+  ROLL_OFF,
+  IS_MISO,
+  IS_LINEAR,
+  IS_SHORT_FRAMES,
+  ISDBT_MODE,
+  ISDBT_PARTIAL_RECEPTION_FLAG,
+  STREAM_ID_LIST,
+  DVBT_CELL_IDS,
+  ATSC3_ALL_PLP_INFO,
+  IPTV_CONTENT_URL,
+  IPTV_PACKETS_LOST,
+  IPTV_PACKETS_RECEIVED,
+  IPTV_WORST_JITTER_MS,
+  IPTV_AVERAGE_JITTER_MS,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendTransmissionMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendTransmissionMode.aidl
new file mode 100644
index 0000000..72c3641
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendTransmissionMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendTransmissionMode {
+  android.hardware.tv.tuner.FrontendDvbtTransmissionMode dvbt = android.hardware.tv.tuner.FrontendDvbtTransmissionMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtMode isdbt;
+  android.hardware.tv.tuner.FrontendDtmbTransmissionMode dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendType.aidl
new file mode 100644
index 0000000..455bbc0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/FrontendType.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendType {
+  UNDEFINED = 0,
+  ANALOG,
+  ATSC,
+  ATSC3,
+  DVBC,
+  DVBS,
+  DVBT,
+  ISDBS,
+  ISDBS3,
+  ISDBT,
+  DTMB,
+  IPTV,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDemux.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDemux.aidl
new file mode 100644
index 0000000..59ec92b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDemux.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface IDemux {
+  void setFrontendDataSource(in int frontendId);
+  android.hardware.tv.tuner.IFilter openFilter(in android.hardware.tv.tuner.DemuxFilterType type, in int bufferSize, in android.hardware.tv.tuner.IFilterCallback cb);
+  android.hardware.tv.tuner.ITimeFilter openTimeFilter();
+  int getAvSyncHwId(in android.hardware.tv.tuner.IFilter filter);
+  long getAvSyncTime(in int avSyncHwId);
+  void close();
+  android.hardware.tv.tuner.IDvr openDvr(in android.hardware.tv.tuner.DvrType type, in int bufferSize, in android.hardware.tv.tuner.IDvrCallback cb);
+  void connectCiCam(in int ciCamId);
+  void disconnectCiCam();
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDescrambler.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDescrambler.aidl
new file mode 100644
index 0000000..3cf3c04
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDescrambler.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface IDescrambler {
+  void setDemuxSource(in int demuxId);
+  void setKeyToken(in byte[] keyToken);
+  void addPid(in android.hardware.tv.tuner.DemuxPid pid, in android.hardware.tv.tuner.IFilter optionalSourceFilter);
+  void removePid(in android.hardware.tv.tuner.DemuxPid pid, in android.hardware.tv.tuner.IFilter optionalSourceFilter);
+  void close();
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDvr.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDvr.aidl
new file mode 100644
index 0000000..4648712
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDvr.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface IDvr {
+  void getQueueDesc(out android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> queue);
+  void configure(in android.hardware.tv.tuner.DvrSettings settings);
+  void attachFilter(in android.hardware.tv.tuner.IFilter filter);
+  void detachFilter(in android.hardware.tv.tuner.IFilter filter);
+  void start();
+  void stop();
+  void flush();
+  void close();
+  void setStatusCheckIntervalHint(in long milliseconds);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDvrCallback.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDvrCallback.aidl
new file mode 100644
index 0000000..13c8644
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IDvrCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface IDvrCallback {
+  oneway void onPlaybackStatus(in android.hardware.tv.tuner.PlaybackStatus status);
+  oneway void onRecordStatus(in android.hardware.tv.tuner.RecordStatus status);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFilter.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFilter.aidl
new file mode 100644
index 0000000..32d9d64
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFilter.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface IFilter {
+  void getQueueDesc(out android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> queue);
+  void close();
+  void configure(in android.hardware.tv.tuner.DemuxFilterSettings settings);
+  void configureAvStreamType(in android.hardware.tv.tuner.AvStreamType avStreamType);
+  void configureIpCid(in int ipCid);
+  void configureMonitorEvent(in int monitorEventTypes);
+  void start();
+  void stop();
+  void flush();
+  long getAvSharedHandle(out android.hardware.common.NativeHandle avMemory);
+  int getId();
+  long getId64Bit();
+  void releaseAvHandle(in android.hardware.common.NativeHandle avMemory, in long avDataId);
+  void setDataSource(in android.hardware.tv.tuner.IFilter filter);
+  void setDelayHint(in android.hardware.tv.tuner.FilterDelayHint hint);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFilterCallback.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFilterCallback.aidl
new file mode 100644
index 0000000..d8bedba
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFilterCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface IFilterCallback {
+  oneway void onFilterEvent(in android.hardware.tv.tuner.DemuxFilterEvent[] events);
+  oneway void onFilterStatus(in android.hardware.tv.tuner.DemuxFilterStatus status);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFrontend.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFrontend.aidl
new file mode 100644
index 0000000..3e3ff4f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFrontend.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface IFrontend {
+  void setCallback(in android.hardware.tv.tuner.IFrontendCallback callback);
+  void tune(in android.hardware.tv.tuner.FrontendSettings settings);
+  void stopTune();
+  void close();
+  void scan(in android.hardware.tv.tuner.FrontendSettings settings, in android.hardware.tv.tuner.FrontendScanType type);
+  void stopScan();
+  android.hardware.tv.tuner.FrontendStatus[] getStatus(in android.hardware.tv.tuner.FrontendStatusType[] statusTypes);
+  void setLnb(in int lnbId);
+  int linkCiCam(in int ciCamId);
+  void unlinkCiCam(in int ciCamId);
+  String getHardwareInfo();
+  void removeOutputPid(int pid);
+  android.hardware.tv.tuner.FrontendStatusReadiness[] getFrontendStatusReadiness(in android.hardware.tv.tuner.FrontendStatusType[] statusTypes);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFrontendCallback.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFrontendCallback.aidl
new file mode 100644
index 0000000..c22d280
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/IFrontendCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface IFrontendCallback {
+  oneway void onEvent(in android.hardware.tv.tuner.FrontendEventType frontendEventType);
+  oneway void onScanMessage(in android.hardware.tv.tuner.FrontendScanMessageType type, in android.hardware.tv.tuner.FrontendScanMessage message);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ILnb.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ILnb.aidl
new file mode 100644
index 0000000..c3fdd87
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ILnb.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface ILnb {
+  void setCallback(in android.hardware.tv.tuner.ILnbCallback callback);
+  void setVoltage(in android.hardware.tv.tuner.LnbVoltage voltage);
+  void setTone(in android.hardware.tv.tuner.LnbTone tone);
+  void setSatellitePosition(in android.hardware.tv.tuner.LnbPosition position);
+  void sendDiseqcMessage(in byte[] diseqcMessage);
+  void close();
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ILnbCallback.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ILnbCallback.aidl
new file mode 100644
index 0000000..42e84da
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ILnbCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface ILnbCallback {
+  oneway void onDiseqcMessage(in byte[] diseqcMessage);
+  oneway void onEvent(in android.hardware.tv.tuner.LnbEventType lnbEventType);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ITimeFilter.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ITimeFilter.aidl
new file mode 100644
index 0000000..838eeba
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ITimeFilter.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+interface ITimeFilter {
+  void setTimeStamp(in long timeStamp);
+  void clearTimeStamp();
+  long getTimeStamp();
+  long getSourceTime();
+  void close();
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ITuner.aidl
new file mode 100644
index 0000000..732f3fd
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ITuner.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@SuppressWarnings(value={"out-array"}) @VintfStability
+interface ITuner {
+  int[] getFrontendIds();
+  android.hardware.tv.tuner.IFrontend openFrontendById(in int frontendId);
+  android.hardware.tv.tuner.IDemux openDemux(out int[] demuxId);
+  android.hardware.tv.tuner.DemuxCapabilities getDemuxCaps();
+  android.hardware.tv.tuner.IDescrambler openDescrambler();
+  android.hardware.tv.tuner.FrontendInfo getFrontendInfo(in int frontendId);
+  int[] getLnbIds();
+  android.hardware.tv.tuner.ILnb openLnbById(in int lnbId);
+  android.hardware.tv.tuner.ILnb openLnbByName(in String lnbName, out int[] lnbId);
+  void setLna(in boolean bEnable);
+  void setMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType, in int maxNumber);
+  int getMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType);
+  boolean isLnaSupported();
+  int[] getDemuxIds();
+  android.hardware.tv.tuner.IDemux openDemuxById(in int demuxId);
+  android.hardware.tv.tuner.DemuxInfo getDemuxInfo(in int demuxId);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbEventType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbEventType.aidl
new file mode 100644
index 0000000..7bec809
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbEventType.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum LnbEventType {
+  DISEQC_RX_OVERFLOW,
+  DISEQC_RX_TIMEOUT,
+  DISEQC_RX_PARITY_ERROR,
+  LNB_OVERLOAD,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbPosition.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbPosition.aidl
new file mode 100644
index 0000000..a4a5740
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbPosition.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum LnbPosition {
+  UNDEFINED,
+  POSITION_A,
+  POSITION_B,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbTone.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbTone.aidl
new file mode 100644
index 0000000..0628354
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbTone.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum LnbTone {
+  NONE,
+  CONTINUOUS,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbVoltage.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbVoltage.aidl
new file mode 100644
index 0000000..b18ff0e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/LnbVoltage.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum LnbVoltage {
+  NONE,
+  VOLTAGE_5V,
+  VOLTAGE_11V,
+  VOLTAGE_12V,
+  VOLTAGE_13V,
+  VOLTAGE_14V,
+  VOLTAGE_15V,
+  VOLTAGE_18V,
+  VOLTAGE_19V,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/PlaybackSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/PlaybackSettings.aidl
new file mode 100644
index 0000000..e0dd5db
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/PlaybackSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable PlaybackSettings {
+  int statusMask;
+  long lowThreshold;
+  long highThreshold;
+  android.hardware.tv.tuner.DataFormat dataFormat = android.hardware.tv.tuner.DataFormat.UNDEFINED;
+  long packetSize;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/PlaybackStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/PlaybackStatus.aidl
new file mode 100644
index 0000000..a8b6378
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/PlaybackStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum PlaybackStatus {
+  SPACE_EMPTY = (1 << 0) /* 1 */,
+  SPACE_ALMOST_EMPTY = (1 << 1) /* 2 */,
+  SPACE_ALMOST_FULL = (1 << 2) /* 4 */,
+  SPACE_FULL = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/RecordSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/RecordSettings.aidl
new file mode 100644
index 0000000..de693cd
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/RecordSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable RecordSettings {
+  int statusMask;
+  long lowThreshold;
+  long highThreshold;
+  android.hardware.tv.tuner.DataFormat dataFormat = android.hardware.tv.tuner.DataFormat.UNDEFINED;
+  long packetSize;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/RecordStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/RecordStatus.aidl
new file mode 100644
index 0000000..e06b616
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/RecordStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum RecordStatus {
+  DATA_READY = (1 << 0) /* 1 */,
+  LOW_WATER = (1 << 1) /* 2 */,
+  HIGH_WATER = (1 << 2) /* 4 */,
+  OVERFLOW = (1 << 3) /* 8 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/Result.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/Result.aidl
new file mode 100644
index 0000000..ae43350
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/Result.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Result {
+  SUCCESS,
+  UNAVAILABLE,
+  NOT_INITIALIZED,
+  INVALID_STATE,
+  INVALID_ARGUMENT,
+  OUT_OF_MEMORY,
+  UNKNOWN_ERROR,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ScramblingStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ScramblingStatus.aidl
new file mode 100644
index 0000000..4d52de1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/ScramblingStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ScramblingStatus {
+  UNKNOWN = (1 << 0) /* 1 */,
+  NOT_SCRAMBLED = (1 << 1) /* 2 */,
+  SCRAMBLED = (1 << 2) /* 4 */,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/VideoStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/VideoStreamType.aidl
new file mode 100644
index 0000000..530f454
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/2/android/hardware/tv/tuner/VideoStreamType.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum VideoStreamType {
+  UNDEFINED,
+  RESERVED,
+  MPEG1,
+  MPEG2,
+  MPEG4P2,
+  AVC,
+  HEVC,
+  VC1,
+  VP8,
+  VP9,
+  AV1,
+  AVS,
+  AVS2,
+  VVC,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselection.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselection.aidl
new file mode 100644
index 0000000..ab0404e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselection.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioPreselection {
+  int preselectionId;
+  android.hardware.tv.tuner.AudioPreselectionLabel[] labels;
+  String language;
+  android.hardware.tv.tuner.AudioPreselectionRenderingIndicationType renderingIndication;
+  boolean hasAudioDescription;
+  boolean hasSpokenSubtitles;
+  boolean hasDialogueEnhancement;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionLabel.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
new file mode 100644
index 0000000..79f3b6f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioPreselectionLabel {
+  String language;
+  String text;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
new file mode 100644
index 0000000..783511f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioPreselectionRenderingIndicationType {
+  NOT_INDICATED = 0,
+  STEREO = 1,
+  TWO_DIMENSIONAL = 2,
+  THREE_DIMENSIONAL = 3,
+  HEADPHONE = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl
new file mode 100644
index 0000000..96a6d98
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioPresentation {
+  android.hardware.tv.tuner.AudioPreselection preselection;
+  int ac4ShortProgramId = -1;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
index ab36188..28caf19 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
@@ -37,4 +37,5 @@
 union DemuxFilterMediaEventExtraMetaData {
   boolean noinit;
   android.hardware.tv.tuner.AudioExtraMetaData audio;
+  android.hardware.tv.tuner.AudioPresentation[] audioPresentations = {};
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
index 371e075..8dfc60e 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -38,4 +38,5 @@
   int scIndex;
   int scAvc;
   int scHevc;
+  int scVvc;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
index 36b40ea..1dc593a 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
@@ -39,4 +39,5 @@
   LOW_WATER = 2,
   HIGH_WATER = 4,
   OVERFLOW = 8,
+  NO_DATA = 16,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.aidl
new file mode 100644
index 0000000..872d963
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxInfo {
+  int filterTypes = 0;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index 30ec29a..fb4430b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -39,4 +39,5 @@
   SC = 1,
   SC_HEVC = 2,
   SC_AVC = 3,
+  SC_VVC = 4,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
new file mode 100644
index 0000000..3e08d26
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxScVvcIndex {
+  UNDEFINED = 0,
+  SLICE_IDR_W_RADL = 1,
+  SLICE_IDR_N_LP = 2,
+  SLICE_CRA = 4,
+  SLICE_GDR = 8,
+  VPS = 16,
+  SPS = 32,
+  AUD = 64,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl
index c013cd1..c9443b1 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl
@@ -45,4 +45,5 @@
   android.hardware.tv.tuner.FrontendIsdbsCapabilities isdbsCaps;
   android.hardware.tv.tuner.FrontendIsdbs3Capabilities isdbs3Caps;
   android.hardware.tv.tuner.FrontendIsdbtCapabilities isdbtCaps;
+  @nullable android.hardware.tv.tuner.FrontendIptvCapabilities iptvCaps;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl
new file mode 100644
index 0000000..543543d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIptvCapabilities {
+  int protocolCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettings.aidl
new file mode 100644
index 0000000..73582f3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettings.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIptvSettings {
+  android.hardware.tv.tuner.FrontendIptvSettingsProtocol protocol = android.hardware.tv.tuner.FrontendIptvSettingsProtocol.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIptvSettingsFec fec;
+  android.hardware.tv.tuner.FrontendIptvSettingsIgmp igmp = android.hardware.tv.tuner.FrontendIptvSettingsIgmp.UNDEFINED;
+  long bitrate;
+  android.hardware.tv.tuner.DemuxIpAddress ipAddr;
+  String contentUrl;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl
new file mode 100644
index 0000000..c361377
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIptvSettingsFec {
+  android.hardware.tv.tuner.FrontendIptvSettingsFecType type;
+  int fecColNum;
+  int fecRowNum;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
new file mode 100644
index 0000000..50a1208
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIptvSettingsFecType {
+  UNDEFINED = 0,
+  COLUMN = 1,
+  ROW = 2,
+  COLUMN_ROW = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
new file mode 100644
index 0000000..aa08496
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIptvSettingsIgmp {
+  UNDEFINED = 0,
+  V1 = 1,
+  V2 = 2,
+  V3 = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
new file mode 100644
index 0000000..08a01f1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIptvSettingsProtocol {
+  UNDEFINED = 0,
+  UDP = 1,
+  RTP = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl
index 7eae9df..9810ba6 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl
@@ -45,4 +45,5 @@
   android.hardware.tv.tuner.FrontendIsdbs3Settings isdbs3;
   android.hardware.tv.tuner.FrontendIsdbtSettings isdbt;
   android.hardware.tv.tuner.FrontendDtmbSettings dtmb;
+  @nullable android.hardware.tv.tuner.FrontendIptvSettings iptv;
 }
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 1e0f5f0..b991ab6 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
@@ -77,4 +77,9 @@
   int[] streamIdList;
   int[] dvbtCellIds;
   android.hardware.tv.tuner.FrontendScanAtsc3PlpInfo[] allPlpInfo;
+  String iptvContentUrl = "";
+  long iptvPacketsReceived;
+  long iptvPacketsLost;
+  int iptvWorstJitterMs;
+  int iptvAverageJitterMs;
 }
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 cd6ccb3..3791299 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
@@ -77,4 +77,9 @@
   STREAM_ID_LIST = 39,
   DVBT_CELL_IDS = 40,
   ATSC3_ALL_PLP_INFO = 41,
+  IPTV_CONTENT_URL = 42,
+  IPTV_PACKETS_LOST = 43,
+  IPTV_PACKETS_RECEIVED = 44,
+  IPTV_WORST_JITTER_MS = 45,
+  IPTV_AVERAGE_JITTER_MS = 46,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
index 99a120b..cbf5b47 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -46,4 +46,5 @@
   ISDBS3 = 8,
   ISDBT = 9,
   DTMB = 10,
+  IPTV = 11,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl
index 450cd79..4648712 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl
@@ -43,4 +43,5 @@
   void stop();
   void flush();
   void close();
+  void setStatusCheckIntervalHint(in long milliseconds);
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
index 0ff2da9..732f3fd 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
@@ -47,4 +47,8 @@
   void setLna(in boolean bEnable);
   void setMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType, in int maxNumber);
   int getMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType);
+  boolean isLnaSupported();
+  int[] getDemuxIds();
+  android.hardware.tv.tuner.IDemux openDemuxById(in int demuxId);
+  android.hardware.tv.tuner.DemuxInfo getDemuxInfo(in int demuxId);
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
index 9dfd686..dbb6033 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
@@ -48,4 +48,5 @@
   AV1 = 10,
   AVS = 11,
   AVS2 = 12,
+  VVC = 13,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselection.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselection.aidl
new file mode 100644
index 0000000..16ef0dd
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselection.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.AudioPreselectionLabel;
+import android.hardware.tv.tuner.AudioPreselectionRenderingIndicationType;
+
+/**
+ * Audio preselection metadata according to ETSI EN 300 468 V1.17.1.
+ * @hide
+ */
+@VintfStability
+parcelable AudioPreselection {
+    /**
+     * Identifies this audio preselection. The value of this field shall match the corresponding
+     * field in the elementary stream.
+     */
+    int preselectionId;
+
+    /**
+     * Collection of audio preselection labels.
+     */
+    AudioPreselectionLabel[] labels;
+
+    /**
+     * ISO 639-2 3-character code.
+     */
+    String language;
+
+    /**
+     * A hint for a preferred reproduction channel layout.
+     */
+    AudioPreselectionRenderingIndicationType renderingIndication;
+
+    /**
+     * Audio preselection contains audio description for the visually impaired.
+     */
+    boolean hasAudioDescription;
+
+    /**
+     * Audio preselection contains spoken subtitles.
+     */
+    boolean hasSpokenSubtitles;
+
+    /**
+     * Audio preselection provides support for dialogue enhancement.
+     */
+    boolean hasDialogueEnhancement;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionLabel.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
new file mode 100644
index 0000000..429b026
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Audio preselection label according to ETSI EN 300 468 V1.17.1.
+ * @hide
+ */
+@VintfStability
+parcelable AudioPreselectionLabel {
+    /**
+     * ISO 639-2 3-character code.
+     */
+    String language;
+
+    /**
+     * Text information, written in the language specified, pertaining to the preselection.
+     */
+    String text;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
new file mode 100644
index 0000000..963c55a
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Audio preselection audio rendering indication according to ETSI EN 300 468 V1.17.1.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum AudioPreselectionRenderingIndicationType {
+    /**
+     * No preference given for the reproduction channel layout.
+     */
+    NOT_INDICATED,
+
+    /**
+     * Preferred reproduction channel layout is stereo.
+     */
+    STEREO,
+
+    /**
+     * Preferred reproduction channel layout is two-dimensional (e.g. 5.1 multi-channel).
+     */
+    TWO_DIMENSIONAL,
+
+    /**
+     * Preferred reproduction channel layout is three-dimensional.
+     */
+    THREE_DIMENSIONAL,
+
+    /**
+     * Content is pre-rendered for consumption with headphones.
+     */
+    HEADPHONE,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioPresentation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPresentation.aidl
new file mode 100644
index 0000000..50f9d90
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPresentation.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.AudioPreselection;
+
+/**
+ * Audio presentation metadata.
+ * @hide
+ */
+@VintfStability
+parcelable AudioPresentation {
+    /**
+     * Audio preselection.
+     */
+    AudioPreselection preselection;
+
+    /**
+     * Dolby AC-4 short program id specified in ETSI TS 103 190-2. For use in conjunction with
+     * an audio preselection to ensure contininuity of personalized experience during program
+     * transitions.
+     */
+    int ac4ShortProgramId = -1;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
index f01952b..4ff33a2 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
@@ -17,6 +17,7 @@
 package android.hardware.tv.tuner;
 
 import android.hardware.tv.tuner.AudioExtraMetaData;
+import android.hardware.tv.tuner.AudioPresentation;
 
 /**
  * Extra Meta Data for DemuxFilterMediaEvent.
@@ -30,4 +31,9 @@
     boolean noinit;
 
     AudioExtraMetaData audio;
+
+    /**
+     * Audio presentations available for user selection.
+     */
+    AudioPresentation[] audioPresentations = {};
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
index 4036b06..d53bc5b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -39,4 +39,9 @@
      * Indexes defined by DemuxScHevcIndex.
      */
     int scHevc;
+
+    /**
+     * Indexes defined by DemuxScVvcIndex.
+     */
+    int scVvc;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
index e6f3b63..45a473e 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
@@ -46,4 +46,9 @@
      * discarded.
      */
     OVERFLOW = 1 << 3,
+
+    /**
+     * Indicating there is no data coming to the filter.
+     */
+    NO_DATA = 1 << 4,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxInfo.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxInfo.aidl
new file mode 100644
index 0000000..2720e21
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxInfo.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.DemuxFilterMainType;
+
+/**
+ * Information for the Demux.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxInfo {
+    /**
+     * Bitwise OR of DemuxFilterMainTypes
+     */
+    int filterTypes = DemuxFilterMainType.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index 98427f7..265b978 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -42,4 +42,9 @@
      * Use Start Code index for AVC
      */
     SC_AVC,
+
+    /**
+     * Use Start Code index for VVC
+     */
+    SC_VVC,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScVvcIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
new file mode 100644
index 0000000..8b47f62
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Indexes can be tagged by start point of slice groups according to ISO/IEC 23090-3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxScVvcIndex {
+    UNDEFINED = 0,
+
+    /**
+     * Coded slice of an IDR picture or subpicture with RADL pictures.
+     */
+    SLICE_IDR_W_RADL = 1 << 0,
+
+    /**
+     * Coded slice of an IDR picture or subpicture without leading pictures.
+     */
+    SLICE_IDR_N_LP = 1 << 1,
+
+    /**
+     * Coded slice of a CRA (clean random access) picture or subpicture.
+     */
+    SLICE_CRA = 1 << 2,
+
+    /**
+     * Coded slice of a GDR (gradual decoder refresh) picture or subpicture.
+     */
+    SLICE_GDR = 1 << 3,
+
+    /**
+     * Video parameter set (non-VCL NALU).
+     */
+    VPS = 1 << 4,
+
+    /**
+     * Sequence parameter set (non-VCL NALU).
+     */
+    SPS = 1 << 5,
+
+    /**
+     * Access unit delimiter (non-VCL NALU).
+     */
+    AUD = 1 << 6,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl
index a6f1490..cfa1763 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl
@@ -23,6 +23,7 @@
 import android.hardware.tv.tuner.FrontendDvbcCapabilities;
 import android.hardware.tv.tuner.FrontendDvbsCapabilities;
 import android.hardware.tv.tuner.FrontendDvbtCapabilities;
+import android.hardware.tv.tuner.FrontendIptvCapabilities;
 import android.hardware.tv.tuner.FrontendIsdbs3Capabilities;
 import android.hardware.tv.tuner.FrontendIsdbsCapabilities;
 import android.hardware.tv.tuner.FrontendIsdbtCapabilities;
@@ -51,4 +52,6 @@
     FrontendIsdbs3Capabilities isdbs3Caps;
 
     FrontendIsdbtCapabilities isdbtCaps;
+
+    @nullable FrontendIptvCapabilities iptvCaps;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl
new file mode 100644
index 0000000..438492b
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Capabilities for IPTV Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIptvCapabilities {
+    /**
+     * Transmission protocols for IPTV (UDP / RTP) defined in FrontendIptvSettingsProtocol.
+     */
+    int protocolCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettings.aidl
new file mode 100644
index 0000000..782695a
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettings.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.DemuxIpAddress;
+import android.hardware.tv.tuner.FrontendIptvSettingsFec;
+import android.hardware.tv.tuner.FrontendIptvSettingsFecType;
+import android.hardware.tv.tuner.FrontendIptvSettingsIgmp;
+import android.hardware.tv.tuner.FrontendIptvSettingsProtocol;
+
+/**
+ * Frontend Settings for IPTV.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIptvSettings {
+    FrontendIptvSettingsProtocol protocol = FrontendIptvSettingsProtocol.UNDEFINED;
+
+    FrontendIptvSettingsFec fec;
+
+    FrontendIptvSettingsIgmp igmp = FrontendIptvSettingsIgmp.UNDEFINED;
+
+    long bitrate;
+
+    /**
+     * Source and destination IP Address.
+     */
+    DemuxIpAddress ipAddr;
+
+    String contentUrl;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl
new file mode 100644
index 0000000..e12f06f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.FrontendIptvSettingsFecType;
+
+/**
+ * Configuration details for IPTV FEC.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIptvSettingsFec {
+    FrontendIptvSettingsFecType type;
+
+    /**
+     * The number of columns in the source block as well as the type of the repair packet.
+     */
+    int fecColNum;
+
+    /**
+     * The number of rows in the source block as well as the type of the repair packet.
+     */
+    int fecRowNum;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
new file mode 100644
index 0000000..421cbf8
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * FEC type for IPTV.
+ * TS 102 542-3-2 - V1.3.2
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIptvSettingsFecType {
+    UNDEFINED = 0,
+
+    COLUMN = 1 << 0,
+
+    ROW = 1 << 1,
+
+    COLUMN_ROW = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
new file mode 100644
index 0000000..f6e39c8
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * IGMP type for IPTV.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIptvSettingsIgmp {
+    UNDEFINED = 0,
+
+    V1 = 1 << 0,
+
+    V2 = 1 << 1,
+
+    V3 = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
new file mode 100644
index 0000000..0283445
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Protocol for IPTV.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIptvSettingsProtocol {
+    UNDEFINED = 0,
+
+    UDP = 1 << 0,
+
+    RTP = 1 << 1,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl
index f78b2ae..e5a99e1 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl
@@ -19,13 +19,14 @@
 import android.hardware.tv.tuner.FrontendAnalogSettings;
 import android.hardware.tv.tuner.FrontendAtsc3Settings;
 import android.hardware.tv.tuner.FrontendAtscSettings;
+import android.hardware.tv.tuner.FrontendDtmbSettings;
 import android.hardware.tv.tuner.FrontendDvbcSettings;
 import android.hardware.tv.tuner.FrontendDvbsSettings;
 import android.hardware.tv.tuner.FrontendDvbtSettings;
+import android.hardware.tv.tuner.FrontendIptvSettings;
 import android.hardware.tv.tuner.FrontendIsdbs3Settings;
 import android.hardware.tv.tuner.FrontendIsdbsSettings;
 import android.hardware.tv.tuner.FrontendIsdbtSettings;
-import android.hardware.tv.tuner.FrontendDtmbSettings;
 
 /**
  * Signal Settings for Frontend.
@@ -52,4 +53,6 @@
     FrontendIsdbtSettings isdbt;
 
     FrontendDtmbSettings dtmb;
+
+    @nullable FrontendIptvSettings iptv;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
index b5d0201..391f29b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -26,8 +26,8 @@
 import android.hardware.tv.tuner.FrontendModulation;
 import android.hardware.tv.tuner.FrontendModulationStatus;
 import android.hardware.tv.tuner.FrontendRollOff;
-import android.hardware.tv.tuner.FrontendSpectralInversion;
 import android.hardware.tv.tuner.FrontendScanAtsc3PlpInfo;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
 import android.hardware.tv.tuner.FrontendStatusAtsc3PlpInfo;
 import android.hardware.tv.tuner.FrontendTransmissionMode;
 import android.hardware.tv.tuner.LnbVoltage;
@@ -247,4 +247,29 @@
      * and not tuned PLPs for currently watching service.
      */
     FrontendScanAtsc3PlpInfo[] allPlpInfo;
+
+    /**
+     * IPTV Content URL
+     */
+    String iptvContentUrl = "";
+
+    /**
+     * Packets Received (IPTV - UDP/RTP).
+     */
+    long iptvPacketsReceived;
+
+    /**
+     * Packets Lost (IPTV - RTP).
+     */
+    long iptvPacketsLost;
+
+    /**
+     * Worst jitter (milliseconds).
+     */
+    int iptvWorstJitterMs;
+
+    /**
+     * Average jitter (milliseconds).
+     */
+    int iptvAverageJitterMs;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
index 8f3f2c5..6804b2d 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -234,4 +234,29 @@
      * and not tuned PLPs for currently watching service.
      */
     ATSC3_ALL_PLP_INFO,
+
+    /**
+     * IPTV Content URL.
+     */
+    IPTV_CONTENT_URL,
+
+    /**
+     * Number of packets lost.
+     */
+    IPTV_PACKETS_LOST,
+
+    /**
+     * Number of packets received.
+     */
+    IPTV_PACKETS_RECEIVED,
+
+    /**
+     * Worst jitter (milliseconds).
+     */
+    IPTV_WORST_JITTER_MS,
+
+    /**
+     * Average jitter (milliseconds).
+     */
+    IPTV_AVERAGE_JITTER_MS,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl
index 8ade389..e8d343e 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -79,4 +79,9 @@
      * DTMB (Digital Terrestrial Multimedia Broadcast) standard.
      */
     DTMB,
+
+    /**
+     * ITU IPTV (ITU-T FG IPTV)
+     */
+    IPTV,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl
index 0534f9d..4cb5b15 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl
@@ -18,7 +18,6 @@
 
 import android.hardware.common.fmq.MQDescriptor;
 import android.hardware.common.fmq.SynchronizedReadWrite;
-
 import android.hardware.tv.tuner.DvrSettings;
 import android.hardware.tv.tuner.IFilter;
 
@@ -101,4 +100,12 @@
      * instance any more and all methods should return a failure.
      */
     void close();
+
+    /**
+     * Set status check time interval.
+     *
+     * This time interval hint will be used by the Dvr to decide how often
+     * to evaluate data.
+     */
+    void setStatusCheckIntervalHint(in long milliseconds);
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
index 03def33..9ead7dd 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
@@ -17,6 +17,7 @@
 package android.hardware.tv.tuner;
 
 import android.hardware.tv.tuner.DemuxCapabilities;
+import android.hardware.tv.tuner.DemuxInfo;
 import android.hardware.tv.tuner.FrontendInfo;
 import android.hardware.tv.tuner.FrontendType;
 import android.hardware.tv.tuner.IDemux;
@@ -65,7 +66,7 @@
     IDemux openDemux(out int[] demuxId);
 
     /**
-     * Retrieve the Demux's Capabilities.
+     * Retrieve the system wide Demux's Capabilities
      *
      * @return the Demux's Capabilities.
      */
@@ -125,6 +126,9 @@
     /**
      * Enable or Disable Low Noise Amplifier (LNA).
      *
+     * If the device doesn't support LNA, the HAL implement should set {@link Result#UNAVAILABLE}
+     * to EX_SERVICE_SPECIFIC as the service specific error.
+     *
      * @param bEnable true if activate LNA module; false if deactivate LNA
      */
     void setLna(in boolean bEnable);
@@ -148,4 +152,39 @@
      * @return the maximum usable number of the queried frontend type.
      */
     int getMaxNumberOfFrontends(in FrontendType frontendType);
+
+    /**
+     * Is Low Noise Amplifier (LNA) supported.
+     *
+     * @return true if supported, otherwise false
+     */
+    boolean isLnaSupported();
+
+    /**
+     * Get Demux IDs
+     *
+     * It is used by the client to get all available demuxes' IDs.
+     *
+     * @return an array of IDs for the available Demuxes.
+     */
+    int[] getDemuxIds();
+
+    /**
+     * Create a new instance of Demux given a demuxId.
+     *
+     * It is used by the client to create a demux instance.
+     *
+     * @param demuxId the id of the demux to be opened.
+     *
+     * @return the newly created demux interface.
+     */
+    IDemux openDemuxById(in int demuxId);
+
+    /**
+     * Retrieve the DemuxInfo of the specified Demux.
+     *
+     * @param demuxId the demux ID to query the DemuxInfo for.
+     * @return the DemuxInfo of the specified Demux by demuxId.
+     */
+    DemuxInfo getDemuxInfo(in int demuxId);
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl
index 108d986..bd000d2 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl
@@ -84,4 +84,9 @@
      * New Chinese Standard
      */
     AVS2,
+
+    /*
+     * ITU-T Rec. H.266 and ISO/IEC 23090-3
+     */
+    VVC,
 }
diff --git a/tv/tuner/aidl/default/Android.bp b/tv/tuner/aidl/default/Android.bp
index cb8f87b..65fa821 100644
--- a/tv/tuner/aidl/default/Android.bp
+++ b/tv/tuner/aidl/default/Android.bp
@@ -7,10 +7,9 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-cc_binary {
-    name: "android.hardware.tv.tuner-service.example",
+cc_defaults {
+    name: "tuner_hal_example_defaults",
     relative_install_path: "hw",
-    init_rc: ["tuner-default.rc"],
     vintf_fragments: ["tuner-default.xml"],
     vendor: true,
     compile_multilib: "first",
@@ -30,7 +29,7 @@
     ],
     shared_libs: [
         "android.hardware.common.fmq-V1-ndk",
-        "android.hardware.tv.tuner-V1-ndk",
+        "android.hardware.tv.tuner-V2-ndk",
         "libbase",
         "libbinder_ndk",
         "libcutils",
@@ -44,3 +43,18 @@
         "media_plugin_headers",
     ],
 }
+
+cc_binary {
+    name: "android.hardware.tv.tuner-service.example",
+    defaults: ["tuner_hal_example_defaults"],
+    init_rc: ["tuner-default.rc"],
+}
+
+cc_binary {
+    name: "android.hardware.tv.tuner-service.example-lazy",
+    defaults: ["tuner_hal_example_defaults"],
+    init_rc: ["tuner-default-lazy.rc"],
+    cflags: [
+        "-DLAZY_HAL",
+    ],
+}
diff --git a/tv/tuner/aidl/default/Demux.cpp b/tv/tuner/aidl/default/Demux.cpp
index a94b4ad..11e7131 100644
--- a/tv/tuner/aidl/default/Demux.cpp
+++ b/tv/tuner/aidl/default/Demux.cpp
@@ -31,12 +31,17 @@
 
 #define WAIT_TIMEOUT 3000000000
 
-Demux::Demux(int32_t demuxId, std::shared_ptr<Tuner> tuner) {
+Demux::Demux(int32_t demuxId, uint32_t filterTypes) {
     mDemuxId = demuxId;
+    mFilterTypes = filterTypes;
+}
+
+void Demux::setTunerService(std::shared_ptr<Tuner> tuner) {
     mTuner = tuner;
 }
 
 Demux::~Demux() {
+    ALOGV("%s", __FUNCTION__);
     close();
 }
 
@@ -180,7 +185,10 @@
     mRecordFilterIds.clear();
     mFilters.clear();
     mLastUsedFilterId = -1;
-    mTuner->removeDemux(mDemuxId);
+    if (mTuner != nullptr) {
+        mTuner->removeDemux(mDemuxId);
+        mTuner = nullptr;
+    }
 
     return ::ndk::ScopedAStatus::ok();
 }
@@ -342,6 +350,22 @@
     return mFilters[filterId]->getTpid();
 }
 
+int32_t Demux::getDemuxId() {
+    return mDemuxId;
+}
+
+bool Demux::isInUse() {
+    return mInUse;
+}
+
+void Demux::setInUse(bool inUse) {
+    mInUse = inUse;
+}
+
+void Demux::getDemuxInfo(DemuxInfo* demuxInfo) {
+    *demuxInfo = {.filterTypes = mFilterTypes};
+}
+
 void Demux::startFrontendInputLoop() {
     ALOGD("[Demux] start frontend on demux");
     // Stop current Frontend thread loop first, in case the user starts a new
diff --git a/tv/tuner/aidl/default/Demux.h b/tv/tuner/aidl/default/Demux.h
index 7f0b0a7..7d7aee4 100644
--- a/tv/tuner/aidl/default/Demux.h
+++ b/tv/tuner/aidl/default/Demux.h
@@ -53,7 +53,7 @@
 
 class Demux : public BnDemux {
   public:
-    Demux(int32_t demuxId, std::shared_ptr<Tuner> tuner);
+    Demux(int32_t demuxId, uint32_t filterTypes);
     ~Demux();
 
     ::ndk::ScopedAStatus setFrontendDataSource(int32_t in_frontendId) override;
@@ -98,6 +98,12 @@
     void sendFrontendInputToRecord(vector<int8_t> data, uint16_t pid, uint64_t pts);
     bool startRecordFilterDispatcher();
 
+    void getDemuxInfo(DemuxInfo* demuxInfo);
+    int32_t getDemuxId();
+    bool isInUse();
+    void setInUse(bool inUse);
+    void setTunerService(std::shared_ptr<Tuner> tuner);
+
   private:
     // Tuner service
     std::shared_ptr<Tuner> mTuner;
@@ -183,6 +189,9 @@
     vector<uint8_t> mPesOutput;
 
     const bool DEBUG_DEMUX = false;
+
+    int32_t mFilterTypes;
+    bool mInUse = false;
 };
 
 }  // namespace tuner
diff --git a/tv/tuner/aidl/default/Dvr.cpp b/tv/tuner/aidl/default/Dvr.cpp
index c591d07..c046ae3 100644
--- a/tv/tuner/aidl/default/Dvr.cpp
+++ b/tv/tuner/aidl/default/Dvr.cpp
@@ -154,6 +154,14 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus Dvr::setStatusCheckIntervalHint(int64_t /* in_milliseconds */) {
+    ALOGV("%s", __FUNCTION__);
+
+    // There is no active polling in this default implementation,
+    // so directly return ok here.
+    return ::ndk::ScopedAStatus::ok();
+}
+
 bool Dvr::createDvrMQ() {
     ALOGV("%s", __FUNCTION__);
 
@@ -164,7 +172,7 @@
         return false;
     }
 
-    mDvrMQ = move(tmpDvrMQ);
+    mDvrMQ = std::move(tmpDvrMQ);
 
     if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != ::android::OK) {
         return false;
@@ -427,7 +435,7 @@
     map<int64_t, std::shared_ptr<IFilter>>::iterator it;
     // Handle the output data per filter type
     for (it = mFilters.begin(); it != mFilters.end(); it++) {
-        if (mDemux->startFilterHandler(it->first).isOk()) {
+        if (!mDemux->startFilterHandler(it->first).isOk()) {
             return false;
         }
     }
diff --git a/tv/tuner/aidl/default/Dvr.h b/tv/tuner/aidl/default/Dvr.h
index 6ff71cd..293c533 100644
--- a/tv/tuner/aidl/default/Dvr.h
+++ b/tv/tuner/aidl/default/Dvr.h
@@ -70,6 +70,7 @@
     ::ndk::ScopedAStatus stop() override;
     ::ndk::ScopedAStatus flush() override;
     ::ndk::ScopedAStatus close() override;
+    ::ndk::ScopedAStatus setStatusCheckIntervalHint(int64_t in_milliseconds) override;
 
     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
 
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index 769ebe2..ba9602e 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -329,7 +329,8 @@
     // All the filter event callbacks in start are for testing purpose.
     switch (mType.mainType) {
         case DemuxFilterMainType::TS:
-            createMediaEvent(events);
+            createMediaEvent(events, false);
+            createMediaEvent(events, true);
             createTsRecordEvent(events);
             createTemiEvent(events);
             break;
@@ -432,12 +433,12 @@
 
     if (mSharedAvMemHandle != nullptr) {
         *out_avMemory = ::android::dupToAidl(mSharedAvMemHandle);
-        *_aidl_return = BUFFER_SIZE_16M;
+        *_aidl_return = BUFFER_SIZE;
         mUsingSharedAvMem = true;
         return ::ndk::ScopedAStatus::ok();
     }
 
-    int av_fd = createAvIonFd(BUFFER_SIZE_16M);
+    int av_fd = createAvIonFd(BUFFER_SIZE);
     if (av_fd < 0) {
         return ::ndk::ScopedAStatus::fromServiceSpecificError(
                 static_cast<int32_t>(Result::OUT_OF_MEMORY));
@@ -454,7 +455,7 @@
     mUsingSharedAvMem = true;
 
     *out_avMemory = ::android::dupToAidl(mSharedAvMemHandle);
-    *_aidl_return = BUFFER_SIZE_16M;
+    *_aidl_return = BUFFER_SIZE;
     return ::ndk::ScopedAStatus::ok();
 }
 
@@ -691,6 +692,8 @@
         return DemuxFilterStatus::OVERFLOW;
     } else if (availableToRead > highThreshold) {
         return DemuxFilterStatus::HIGH_WATER;
+    } else if (availableToRead == 0) {
+        return DemuxFilterStatus::NO_DATA;
     } else if (availableToRead < lowThreshold) {
         return DemuxFilterStatus::LOW_WATER;
     }
@@ -793,7 +796,8 @@
             }
             if (prefix == 0x000001) {
                 // TODO handle mulptiple Pes filters
-                mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
+                mPesSizeLeft = (static_cast<uint8_t>(mFilterOutput[i + 8]) << 8) |
+                               static_cast<uint8_t>(mFilterOutput[i + 9]);
                 mPesSizeLeft += 6;
                 if (DEBUG_FILTER) {
                     ALOGD("[Filter] pes data length %d", mPesSizeLeft);
@@ -803,7 +807,7 @@
             }
         }
 
-        int endPoint = min(184, mPesSizeLeft);
+        uint32_t endPoint = min(184u, mPesSizeLeft);
         // append data and check size
         vector<int8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
         vector<int8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
@@ -852,11 +856,17 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+// Read PES (Packetized Elementary Stream) Packets from TransportStreams
+// as defined in ISO/IEC 13818-1 Section 2.4.3.6. Create MediaEvents
+// containing only their data without TS or PES headers.
 ::ndk::ScopedAStatus Filter::startMediaFilterHandler() {
     if (mFilterOutput.empty()) {
         return ::ndk::ScopedAStatus::ok();
     }
 
+    // mPts being set before our MediaFilterHandler begins indicates that all
+    // metadata has already been handled. We can therefore create an event
+    // with the existing data. This method is used when processing ES files.
     ::ndk::ScopedAStatus result;
     if (mPts) {
         result = createMediaFilterEventWithIon(mFilterOutput);
@@ -867,16 +877,38 @@
     }
 
     for (int i = 0; i < mFilterOutput.size(); i += 188) {
+        // Every packet has a 4 Byte TS Header preceding it
+        uint32_t headerSize = 4;
+
         if (mPesSizeLeft == 0) {
-            uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) |
-                              mFilterOutput[i + 6];
+            // Packet Start Code Prefix is defined as the first 3 bytes of
+            // the PES Header and should always have the value 0x000001
+            uint32_t prefix = (static_cast<uint8_t>(mFilterOutput[i + 4]) << 16) |
+                              (static_cast<uint8_t>(mFilterOutput[i + 5]) << 8) |
+                              static_cast<uint8_t>(mFilterOutput[i + 6]);
             if (DEBUG_FILTER) {
                 ALOGD("[Filter] prefix %d", prefix);
             }
             if (prefix == 0x000001) {
-                // TODO handle mulptiple Pes filters
-                mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
-                mPesSizeLeft += 6;
+                // TODO handle multiple Pes filters
+                // Location of PES fields from ISO/IEC 13818-1 Section 2.4.3.6
+                mPesSizeLeft = (static_cast<uint8_t>(mFilterOutput[i + 8]) << 8) |
+                               static_cast<uint8_t>(mFilterOutput[i + 9]);
+                bool hasPts = static_cast<uint8_t>(mFilterOutput[i + 11]) & 0x80;
+                uint8_t optionalFieldsLength = static_cast<uint8_t>(mFilterOutput[i + 12]);
+                headerSize += 9 + optionalFieldsLength;
+
+                if (hasPts) {
+                    // Pts is a 33-bit field which is stored across 5 bytes, with
+                    // bits in between as reserved fields which must be ignored
+                    mPts = 0;
+                    mPts |= (static_cast<uint8_t>(mFilterOutput[i + 13]) & 0x0e) << 29;
+                    mPts |= (static_cast<uint8_t>(mFilterOutput[i + 14]) & 0xff) << 22;
+                    mPts |= (static_cast<uint8_t>(mFilterOutput[i + 15]) & 0xfe) << 14;
+                    mPts |= (static_cast<uint8_t>(mFilterOutput[i + 16]) & 0xff) << 7;
+                    mPts |= (static_cast<uint8_t>(mFilterOutput[i + 17]) & 0xfe) >> 1;
+                }
+
                 if (DEBUG_FILTER) {
                     ALOGD("[Filter] pes data length %d", mPesSizeLeft);
                 }
@@ -885,10 +917,10 @@
             }
         }
 
-        int endPoint = min(184, mPesSizeLeft);
+        uint32_t endPoint = min(188u - headerSize, mPesSizeLeft);
         // append data and check size
-        vector<int8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
-        vector<int8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
+        vector<int8_t>::const_iterator first = mFilterOutput.begin() + i + headerSize;
+        vector<int8_t>::const_iterator last = mFilterOutput.begin() + i + headerSize + endPoint;
         mPesOutput.insert(mPesOutput.end(), first, last);
         // size does not match then continue
         mPesSizeLeft -= endPoint;
@@ -900,7 +932,8 @@
         }
 
         result = createMediaFilterEventWithIon(mPesOutput);
-        if (result.isOk()) {
+        if (!result.isOk()) {
+            mFilterOutput.clear();
             return result;
         }
     }
@@ -961,24 +994,65 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+// Read PSI (Program Specific Information) Sections from TransportStreams
+// as defined in ISO/IEC 13818-1 Section 2.4.4
 bool Filter::writeSectionsAndCreateEvent(vector<int8_t>& data) {
     // TODO check how many sections has been read
     ALOGD("[Filter] section handler");
-    if (!writeDataToFilterMQ(data)) {
-        return false;
-    }
-    DemuxFilterSectionEvent secEvent;
-    secEvent = {
-            // temp dump meta data
-            .tableId = 0,
-            .version = 1,
-            .sectionNum = 1,
-            .dataLength = static_cast<int32_t>(data.size()),
-    };
 
-    {
-        std::lock_guard<std::mutex> lock(mFilterEventsLock);
-        mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
+    // Transport Stream Packets are 188 bytes long, as defined in the
+    // Introduction of ISO/IEC 13818-1
+    for (int i = 0; i < data.size(); i += 188) {
+        if (mSectionSizeLeft == 0) {
+            // Location for sectionSize as defined by Section 2.4.4
+            // Note that the first 4 bytes skipped are the TsHeader
+            mSectionSizeLeft = ((static_cast<uint8_t>(data[i + 5]) & 0x0f) << 8) |
+                               static_cast<uint8_t>(data[i + 6]);
+            mSectionSizeLeft += 3;
+            if (DEBUG_FILTER) {
+                ALOGD("[Filter] section data length %d", mSectionSizeLeft);
+            }
+        }
+
+        // 184 bytes per packet is derived by subtracting the 4 byte length of
+        // the TsHeader from its 188 byte packet size
+        uint32_t endPoint = min(184u, mSectionSizeLeft);
+        // append data and check size
+        vector<int8_t>::const_iterator first = data.begin() + i + 4;
+        vector<int8_t>::const_iterator last = data.begin() + i + 4 + endPoint;
+        mSectionOutput.insert(mSectionOutput.end(), first, last);
+        // size does not match then continue
+        mSectionSizeLeft -= endPoint;
+        if (DEBUG_FILTER) {
+            ALOGD("[Filter] section data left %d", mSectionSizeLeft);
+        }
+        if (mSectionSizeLeft > 0) {
+            continue;
+        }
+
+        if (!writeDataToFilterMQ(mSectionOutput)) {
+            mSectionOutput.clear();
+            return false;
+        }
+
+        DemuxFilterSectionEvent secEvent;
+        secEvent = {
+                // temp dump meta data
+                .tableId = 0,
+                .version = 1,
+                .sectionNum = 1,
+                .dataLength = static_cast<int32_t>(mSectionOutput.size()),
+        };
+        if (DEBUG_FILTER) {
+            ALOGD("[Filter] assembled section data length %" PRIu64, secEvent.dataLength);
+        }
+
+        {
+            std::lock_guard<std::mutex> lock(mFilterEventsLock);
+            mFilterEvents.push_back(
+                    DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
+        }
+        mSectionOutput.clear();
     }
 
     return true;
@@ -1148,15 +1222,7 @@
     return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
 }
 
-void Filter::createMediaEvent(vector<DemuxFilterEvent>& events) {
-    AudioExtraMetaData audio;
-    audio.adFade = 1;
-    audio.adPan = 2;
-    audio.versionTextTag = 3;
-    audio.adGainCenter = 4;
-    audio.adGainFront = 5;
-    audio.adGainSurround = 6;
-
+void Filter::createMediaEvent(vector<DemuxFilterEvent>& events, bool isAudioPresentation) {
     DemuxFilterMediaEvent mediaEvent;
     mediaEvent.streamId = 1;
     mediaEvent.isPtsPresent = true;
@@ -1166,9 +1232,45 @@
     mediaEvent.isSecureMemory = true;
     mediaEvent.mpuSequenceNumber = 6;
     mediaEvent.isPesPrivateData = true;
-    mediaEvent.extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audio>(audio);
 
-    int av_fd = createAvIonFd(BUFFER_SIZE_16M);
+    if (isAudioPresentation) {
+        AudioPresentation audioPresentation0{
+                .preselection.preselectionId = 0,
+                .preselection.labels = {{"en", "Commentator"}, {"es", "Comentarista"}},
+                .preselection.language = "en",
+                .preselection.renderingIndication =
+                        AudioPreselectionRenderingIndicationType::THREE_DIMENSIONAL,
+                .preselection.hasAudioDescription = false,
+                .preselection.hasSpokenSubtitles = false,
+                .preselection.hasDialogueEnhancement = true,
+                .ac4ShortProgramId = 42};
+        AudioPresentation audioPresentation1{
+                .preselection.preselectionId = 1,
+                .preselection.labels = {{"en", "Crowd"}, {"es", "Multitud"}},
+                .preselection.language = "en",
+                .preselection.renderingIndication =
+                        AudioPreselectionRenderingIndicationType::THREE_DIMENSIONAL,
+                .preselection.hasAudioDescription = false,
+                .preselection.hasSpokenSubtitles = false,
+                .preselection.hasDialogueEnhancement = false,
+                .ac4ShortProgramId = 42};
+        vector<AudioPresentation> audioPresentations;
+        audioPresentations.push_back(audioPresentation0);
+        audioPresentations.push_back(audioPresentation1);
+        mediaEvent.extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audioPresentations>(
+                audioPresentations);
+    } else {
+        AudioExtraMetaData audio;
+        audio.adFade = 1;
+        audio.adPan = 2;
+        audio.versionTextTag = 3;
+        audio.adGainCenter = 4;
+        audio.adGainFront = 5;
+        audio.adGainSurround = 6;
+        mediaEvent.extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audio>(audio);
+    }
+
+    int av_fd = createAvIonFd(BUFFER_SIZE);
     if (av_fd == -1) {
         return;
     }
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
index e301249..0985296 100644
--- a/tv/tuner/aidl/default/Filter.h
+++ b/tv/tuner/aidl/default/Filter.h
@@ -50,7 +50,8 @@
 using ::android::hardware::EventFlag;
 
 using FilterMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
-const uint32_t BUFFER_SIZE_16M = 0x1000000;
+
+const uint32_t BUFFER_SIZE = 0x800000;  // 8 MB
 
 class Demux;
 class Dvr;
@@ -229,7 +230,7 @@
     ::ndk::ScopedAStatus createShareMemMediaEvents(vector<int8_t>& output);
     bool sameFile(int fd1, int fd2);
 
-    void createMediaEvent(vector<DemuxFilterEvent>&);
+    void createMediaEvent(vector<DemuxFilterEvent>&, bool isAudioPresentation);
     void createTsRecordEvent(vector<DemuxFilterEvent>&);
     void createMmtpRecordEvent(vector<DemuxFilterEvent>&);
     void createSectionEvent(vector<DemuxFilterEvent>&);
@@ -256,9 +257,13 @@
     std::mutex mFilterOutputLock;
     std::mutex mRecordFilterOutputLock;
 
+    // handle single Section filter
+    uint32_t mSectionSizeLeft = 0;
+    vector<int8_t> mSectionOutput;
+
     // temp handle single PES filter
     // TODO handle mulptiple Pes filters
-    int mPesSizeLeft = 0;
+    uint32_t mPesSizeLeft = 0;
     vector<int8_t> mPesOutput;
 
     // A map from data id to ion handle
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index 3f7797c..cd072bf 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -28,10 +28,10 @@
 namespace tv {
 namespace tuner {
 
-Frontend::Frontend(FrontendType type, int32_t id, std::shared_ptr<Tuner> tuner) {
+Frontend::Frontend(FrontendType type, int32_t id) {
     mType = type;
     mId = id;
-    mTuner = tuner;
+    mTuner = nullptr;
     // Init callback to nullptr
     mCallback = nullptr;
 
@@ -164,20 +164,39 @@
             };
             break;
         }
+        case FrontendType::IPTV: {
+            mFrontendCaps.set<FrontendCapabilities::Tag::iptvCaps>(FrontendIptvCapabilities());
+            mFrontendStatusCaps = {
+                    FrontendStatusType::IPTV_CONTENT_URL,
+                    FrontendStatusType::IPTV_PACKETS_LOST,
+                    FrontendStatusType::IPTV_PACKETS_RECEIVED,
+                    FrontendStatusType::IPTV_AVERAGE_JITTER_MS,
+                    FrontendStatusType::IPTV_WORST_JITTER_MS,
+            };
+            break;
+        }
         default: {
             break;
         }
     }
 }
 
-Frontend::~Frontend() {}
+Frontend::~Frontend() {
+    ALOGV("%s", __FUNCTION__);
+    mCallback = nullptr;
+    mIsLocked = false;
+    mTuner = nullptr;
+}
 
 ::ndk::ScopedAStatus Frontend::close() {
     ALOGV("%s", __FUNCTION__);
     // Reset callback
     mCallback = nullptr;
     mIsLocked = false;
-    mTuner->removeFrontend(mId);
+    if (mTuner != nullptr) {
+        mTuner->removeFrontend(mId);
+    }
+    mTuner = nullptr;
 
     return ::ndk::ScopedAStatus::ok();
 }
@@ -202,7 +221,10 @@
                 static_cast<int32_t>(Result::INVALID_STATE));
     }
 
-    mTuner->frontendStartTune(mId);
+    if (mType != FrontendType::IPTV) {
+        mTuner->frontendStartTune(mId);
+    }
+
     mCallback->onEvent(FrontendEventType::LOCKED);
     mIsLocked = true;
 
@@ -233,6 +255,10 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+void Frontend::setTunerService(std::shared_ptr<Tuner> tuner) {
+    mTuner = tuner;
+}
+
 void Frontend::scanThreadLoop() {
     if (mIsLocked) {
         FrontendScanMessage msg;
@@ -863,6 +889,26 @@
                 status.set<FrontendStatus::allPlpInfo>(infos);
                 break;
             }
+            case FrontendStatusType::IPTV_CONTENT_URL: {
+                status.set<FrontendStatus::iptvContentUrl>("");
+                break;
+            }
+            case FrontendStatusType::IPTV_PACKETS_LOST: {
+                status.set<FrontendStatus::iptvPacketsLost>(5);
+                break;
+            }
+            case FrontendStatusType::IPTV_PACKETS_RECEIVED: {
+                status.set<FrontendStatus::iptvPacketsReceived>(5);
+                break;
+            }
+            case FrontendStatusType::IPTV_WORST_JITTER_MS: {
+                status.set<FrontendStatus::iptvWorstJitterMs>(5);
+                break;
+            }
+            case FrontendStatusType::IPTV_AVERAGE_JITTER_MS: {
+                status.set<FrontendStatus::iptvAverageJitterMs>(5);
+                break;
+            }
             default: {
                 continue;
             }
diff --git a/tv/tuner/aidl/default/Frontend.h b/tv/tuner/aidl/default/Frontend.h
index 1d9ab53..85bd636 100644
--- a/tv/tuner/aidl/default/Frontend.h
+++ b/tv/tuner/aidl/default/Frontend.h
@@ -34,7 +34,7 @@
 
 class Frontend : public BnFrontend {
   public:
-    Frontend(FrontendType type, int32_t id, std::shared_ptr<Tuner> tuner);
+    Frontend(FrontendType type, int32_t id);
 
     ::ndk::ScopedAStatus setCallback(
             const std::shared_ptr<IFrontendCallback>& in_callback) override;
@@ -62,6 +62,7 @@
     string getSourceFile();
     bool isLocked();
     void getFrontendInfo(FrontendInfo* _aidl_return);
+    void setTunerService(std::shared_ptr<Tuner> tuner);
 
   private:
     virtual ~Frontend();
diff --git a/tv/tuner/aidl/default/Tuner.cpp b/tv/tuner/aidl/default/Tuner.cpp
index fa74288..197d866 100644
--- a/tv/tuner/aidl/default/Tuner.cpp
+++ b/tv/tuner/aidl/default/Tuner.cpp
@@ -17,6 +17,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "android.hardware.tv.tuner-service.example-Tuner"
 
+#include <aidl/android/hardware/tv/tuner/DemuxFilterMainType.h>
 #include <aidl/android/hardware/tv/tuner/Result.h>
 #include <utils/Log.h>
 
@@ -37,17 +38,18 @@
 void Tuner::init() {
     // Static Frontends array to maintain local frontends information
     // Array index matches their FrontendId in the default impl
-    mFrontendSize = 10;
-    mFrontends[0] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS, 0, this->ref<Tuner>());
-    mFrontends[1] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC3, 1, this->ref<Tuner>());
-    mFrontends[2] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBC, 2, this->ref<Tuner>());
-    mFrontends[3] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBS, 3, this->ref<Tuner>());
-    mFrontends[4] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBT, 4, this->ref<Tuner>());
-    mFrontends[5] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBT, 5, this->ref<Tuner>());
-    mFrontends[6] = ndk::SharedRefBase::make<Frontend>(FrontendType::ANALOG, 6, this->ref<Tuner>());
-    mFrontends[7] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC, 7, this->ref<Tuner>());
-    mFrontends[8] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS3, 8, this->ref<Tuner>());
-    mFrontends[9] = ndk::SharedRefBase::make<Frontend>(FrontendType::DTMB, 9, this->ref<Tuner>());
+    mFrontendSize = 11;
+    mFrontends[0] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS, 0);
+    mFrontends[1] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC3, 1);
+    mFrontends[2] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBC, 2);
+    mFrontends[3] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBS, 3);
+    mFrontends[4] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBT, 4);
+    mFrontends[5] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBT, 5);
+    mFrontends[6] = ndk::SharedRefBase::make<Frontend>(FrontendType::ANALOG, 6);
+    mFrontends[7] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC, 7);
+    mFrontends[8] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS3, 8);
+    mFrontends[9] = ndk::SharedRefBase::make<Frontend>(FrontendType::DTMB, 9);
+    mFrontends[10] = ndk::SharedRefBase::make<Frontend>(FrontendType::IPTV, 10);
 
     mMaxUsableFrontends[FrontendType::ISDBS] = 1;
     mMaxUsableFrontends[FrontendType::ATSC3] = 1;
@@ -59,6 +61,17 @@
     mMaxUsableFrontends[FrontendType::ATSC] = 1;
     mMaxUsableFrontends[FrontendType::ISDBS3] = 1;
     mMaxUsableFrontends[FrontendType::DTMB] = 1;
+    mMaxUsableFrontends[FrontendType::IPTV] = 1;
+
+    mDemuxes[0] =
+            ndk::SharedRefBase::make<Demux>(0, (static_cast<int32_t>(DemuxFilterMainType::TS) |
+                                                static_cast<int32_t>(DemuxFilterMainType::MMTP) |
+                                                static_cast<int32_t>(DemuxFilterMainType::TLV)));
+    mDemuxes[1] =
+            ndk::SharedRefBase::make<Demux>(1, (static_cast<int32_t>(DemuxFilterMainType::MMTP) |
+                                                static_cast<int32_t>(DemuxFilterMainType::TLV)));
+    mDemuxes[2] = ndk::SharedRefBase::make<Demux>(2, static_cast<int32_t>(DemuxFilterMainType::IP));
+    mDemuxes[3] = ndk::SharedRefBase::make<Demux>(3, static_cast<int32_t>(DemuxFilterMainType::TS));
 
     mLnbs.resize(2);
     mLnbs[0] = ndk::SharedRefBase::make<Lnb>(0);
@@ -78,6 +91,28 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus Tuner::getDemuxInfo(int32_t in_demuxId, DemuxInfo* _aidl_return) {
+    if (mDemuxes.find(in_demuxId) == mDemuxes.end()) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::INVALID_ARGUMENT));
+    } else {
+        mDemuxes[in_demuxId]->getDemuxInfo(_aidl_return);
+        return ::ndk::ScopedAStatus::ok();
+    }
+}
+
+::ndk::ScopedAStatus Tuner::getDemuxIds(std::vector<int32_t>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    int numOfDemuxes = mDemuxes.size();
+    _aidl_return->resize(numOfDemuxes);
+    int i = 0;
+    for (auto e = mDemuxes.begin(); e != mDemuxes.end(); e++) {
+        (*_aidl_return)[i++] = e->first;
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
 ::ndk::ScopedAStatus Tuner::openFrontendById(int32_t in_frontendId,
                                              std::shared_ptr<IFrontend>* _aidl_return) {
     ALOGV("%s", __FUNCTION__);
@@ -89,21 +124,54 @@
                 static_cast<int32_t>(Result::INVALID_ARGUMENT));
     }
 
+    mFrontends[in_frontendId]->setTunerService(this->ref<Tuner>());
     *_aidl_return = mFrontends[in_frontendId];
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus Tuner::openDemuxById(int32_t in_demuxId,
+                                          std::shared_ptr<IDemux>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mDemuxes.find(in_demuxId) == mDemuxes.end()) {
+        ALOGW("[   WARN   ] Demux with id %d isn't available", in_demuxId);
+        *_aidl_return = nullptr;
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::INVALID_ARGUMENT));
+    }
+
+    if (mDemuxes[in_demuxId]->isInUse()) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
+    } else {
+        mDemuxes[in_demuxId]->setTunerService(this->ref<Tuner>());
+        mDemuxes[in_demuxId]->setInUse(true);
+
+        *_aidl_return = mDemuxes[in_demuxId];
+        return ::ndk::ScopedAStatus::ok();
+    }
+}
+
 ::ndk::ScopedAStatus Tuner::openDemux(std::vector<int32_t>* out_demuxId,
                                       std::shared_ptr<IDemux>* _aidl_return) {
     ALOGV("%s", __FUNCTION__);
 
-    mLastUsedId += 1;
-    mDemuxes[mLastUsedId] = ndk::SharedRefBase::make<Demux>(mLastUsedId, this->ref<Tuner>());
+    bool found = false;
+    int32_t demuxId = 0;
+    for (auto e = mDemuxes.begin(); e != mDemuxes.end(); e++) {
+        if (!e->second->isInUse()) {
+            found = true;
+            demuxId = e->second->getDemuxId();
+        }
+    }
 
-    out_demuxId->push_back(mLastUsedId);
-    *_aidl_return = mDemuxes[mLastUsedId];
-
-    return ::ndk::ScopedAStatus::ok();
+    if (found) {
+        out_demuxId->push_back(demuxId);
+        return openDemuxById(demuxId, _aidl_return);
+    } else {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
+    }
 }
 
 ::ndk::ScopedAStatus Tuner::getDemuxCaps(DemuxCapabilities* _aidl_return) {
@@ -114,6 +182,18 @@
     // Support time filter testing
     _aidl_return->bTimeFilter = true;
 
+    // set filterCaps as the bitwize OR of all the demux' caps
+    std::vector<int32_t> demuxIds;
+    getDemuxIds(&demuxIds);
+    int32_t filterCaps = 0;
+
+    for (int i = 0; i < demuxIds.size(); i++) {
+        DemuxInfo demuxInfo;
+        getDemuxInfo(demuxIds[i], &demuxInfo);
+        filterCaps |= demuxInfo.filterTypes;
+    }
+    _aidl_return->filterCaps = filterCaps;
+
     return ::ndk::ScopedAStatus::ok();
 }
 
@@ -203,6 +283,13 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus Tuner::isLnaSupported(bool* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    *_aidl_return = true;
+    return ::ndk::ScopedAStatus::ok();
+}
+
 binder_status_t Tuner::dump(int fd, const char** args, uint32_t numArgs) {
     ALOGV("%s", __FUNCTION__);
     {
@@ -242,13 +329,13 @@
             break;
         }
     }
-    mDemuxes.erase(demuxId);
+    mDemuxes[demuxId]->setInUse(false);
 }
 
 void Tuner::removeFrontend(int32_t frontendId) {
     map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
     if (it != mFrontendToDemux.end()) {
-        mDemuxes.erase(it->second);
+        mDemuxes[it->second]->setInUse(false);
     }
     mFrontendToDemux.erase(frontendId);
 }
diff --git a/tv/tuner/aidl/default/Tuner.h b/tv/tuner/aidl/default/Tuner.h
index ad73003..2656933 100644
--- a/tv/tuner/aidl/default/Tuner.h
+++ b/tv/tuner/aidl/default/Tuner.h
@@ -46,7 +46,11 @@
                                           std::shared_ptr<IFrontend>* _aidl_return) override;
     ::ndk::ScopedAStatus openDemux(std::vector<int32_t>* out_demuxId,
                                    std::shared_ptr<IDemux>* _aidl_return) override;
+    ::ndk::ScopedAStatus openDemuxById(int32_t in_demuxId,
+                                       std::shared_ptr<IDemux>* _aidl_return) override;
     ::ndk::ScopedAStatus getDemuxCaps(DemuxCapabilities* _aidl_return) override;
+    ::ndk::ScopedAStatus getDemuxInfo(int32_t in_demuxId, DemuxInfo* _aidl_return) override;
+    ::ndk::ScopedAStatus getDemuxIds(std::vector<int32_t>* _aidl_return) override;
     ::ndk::ScopedAStatus openDescrambler(std::shared_ptr<IDescrambler>* _aidl_return) override;
     ::ndk::ScopedAStatus getFrontendInfo(int32_t in_frontendId,
                                          FrontendInfo* _aidl_return) override;
@@ -61,6 +65,7 @@
                                                  int32_t in_maxNumber) override;
     ::ndk::ScopedAStatus getMaxNumberOfFrontends(FrontendType in_frontendType,
                                                  int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus isLnaSupported(bool* _aidl_return) override;
 
     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
 
@@ -76,12 +81,10 @@
     // Static mFrontends array to maintain local frontends information
     map<int32_t, std::shared_ptr<Frontend>> mFrontends;
     map<int32_t, int32_t> mFrontendToDemux;
-    map<int32_t, std::shared_ptr<Demux>> mDemuxes;
+    map<int32_t, std::shared_ptr<Demux>> mDemuxes;  // use demuxId as the key in
+                                                    // this sample implementation
     // To maintain how many Frontends we have
     int mFrontendSize;
-    // The last used demux id. Initial value is -1.
-    // First used id will be 0.
-    int32_t mLastUsedId = -1;
     vector<std::shared_ptr<Lnb>> mLnbs;
     map<FrontendType, int32_t> mMaxUsableFrontends;
 };
diff --git a/tv/tuner/aidl/default/service.cpp b/tv/tuner/aidl/default/service.cpp
index ac8d779..aa9f796 100644
--- a/tv/tuner/aidl/default/service.cpp
+++ b/tv/tuner/aidl/default/service.cpp
@@ -26,12 +26,19 @@
 using ::aidl::android::hardware::tv::tuner::Tuner;
 
 int main() {
-    ABinderProcess_setThreadPoolMaxThreadCount(8);
+    ABinderProcess_setThreadPoolMaxThreadCount(16);
     std::shared_ptr<Tuner> tuner = ndk::SharedRefBase::make<Tuner>();
     tuner->init();
 
+    binder_status_t status;
     const std::string instance = std::string() + Tuner::descriptor + "/default";
-    binder_status_t status = AServiceManager_addService(tuner->asBinder().get(), instance.c_str());
+#ifdef LAZY_HAL
+    ALOGD("Start as a lazy HAL");
+    status = AServiceManager_registerLazyService(tuner->asBinder().get(), instance.c_str());
+#else
+    ALOGD("Start as a normal HAL");
+    status = AServiceManager_addService(tuner->asBinder().get(), instance.c_str());
+#endif
     CHECK(status == STATUS_OK);
 
     ABinderProcess_joinThreadPool();
diff --git a/tv/tuner/aidl/default/tuner-default-lazy.rc b/tv/tuner/aidl/default/tuner-default-lazy.rc
new file mode 100644
index 0000000..6b3b183
--- /dev/null
+++ b/tv/tuner/aidl/default/tuner-default-lazy.rc
@@ -0,0 +1,9 @@
+service vendor.tuner-default-lazy /vendor/bin/hw/android.hardware.tv.tuner-service.example-lazy
+    class hal
+    user media
+    group mediadrm drmrpc
+    ioprio rt 4
+    task_profiles ProcessCapacityHigh
+    interface aidl android.hardware.tv.tuner.ITuner/default
+    oneshot
+    disabled
diff --git a/tv/tuner/aidl/default/tuner-default.rc b/tv/tuner/aidl/default/tuner-default.rc
index d0248c2..f9315ae 100644
--- a/tv/tuner/aidl/default/tuner-default.rc
+++ b/tv/tuner/aidl/default/tuner-default.rc
@@ -3,5 +3,6 @@
     user media
     group mediadrm drmrpc
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
     onrestart restart media.tuner
+    interface aidl android.hardware.tv.tuner.ITuner/default
diff --git a/tv/tuner/aidl/default/tuner-default.xml b/tv/tuner/aidl/default/tuner-default.xml
index f0d03ad..bff8ff0 100644
--- a/tv/tuner/aidl/default/tuner-default.xml
+++ b/tv/tuner/aidl/default/tuner-default.xml
@@ -2,5 +2,6 @@
     <hal format="aidl">
         <name>android.hardware.tv.tuner</name>
         <fqname>ITuner/default</fqname>
+        <version>2</version>
     </hal>
 </manifest>
diff --git a/tv/tuner/aidl/vts/OWNERS b/tv/tuner/aidl/vts/OWNERS
index bf2b609..5b33bf2 100644
--- a/tv/tuner/aidl/vts/OWNERS
+++ b/tv/tuner/aidl/vts/OWNERS
@@ -1,3 +1,5 @@
+# Bug component: 136752
+
 hgchen@google.com
 shubang@google.com
 quxiangfang@google.com
diff --git a/tv/tuner/aidl/vts/functional/Android.bp b/tv/tuner/aidl/vts/functional/Android.bp
index e5fb1e6..513007b 100644
--- a/tv/tuner/aidl/vts/functional/Android.bp
+++ b/tv/tuner/aidl/vts/functional/Android.bp
@@ -51,9 +51,10 @@
         "android.hardware.cas@1.0",
         "android.hardware.cas@1.1",
         "android.hardware.cas@1.2",
+        "android.hardware.cas-V1-ndk",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
-        "android.hardware.tv.tuner-V1-ndk",
+        "android.hardware.tv.tuner-V2-ndk",
         "libaidlcommonsupport",
         "libfmq",
         "libcutils",
diff --git a/tv/tuner/aidl/vts/functional/DemuxTests.cpp b/tv/tuner/aidl/vts/functional/DemuxTests.cpp
index 9de01e1..b2fca6f 100644
--- a/tv/tuner/aidl/vts/functional/DemuxTests.cpp
+++ b/tv/tuner/aidl/vts/functional/DemuxTests.cpp
@@ -16,6 +16,12 @@
 
 #include "DemuxTests.h"
 
+AssertionResult DemuxTests::getDemuxIds(std::vector<int32_t>& demuxIds) {
+    ndk::ScopedAStatus status;
+    status = mService->getDemuxIds(&demuxIds);
+    return AssertionResult(status.isOk());
+}
+
 AssertionResult DemuxTests::openDemux(std::shared_ptr<IDemux>& demux, int32_t& demuxId) {
     std::vector<int32_t> id;
     auto status = mService->openDemux(&id, &mDemux);
@@ -26,6 +32,14 @@
     return AssertionResult(status.isOk());
 }
 
+AssertionResult DemuxTests::openDemuxById(int32_t demuxId, std::shared_ptr<IDemux>& demux) {
+    auto status = mService->openDemuxById(demuxId, &mDemux);
+    if (status.isOk()) {
+        demux = mDemux;
+    }
+    return AssertionResult(status.isOk());
+}
+
 AssertionResult DemuxTests::setDemuxFrontendDataSource(int32_t frontendId) {
     EXPECT_TRUE(mDemux) << "Test with openDemux first.";
     auto status = mDemux->setFrontendDataSource(frontendId);
@@ -33,14 +47,15 @@
 }
 
 AssertionResult DemuxTests::getDemuxCaps(DemuxCapabilities& demuxCaps) {
-    if (!mDemux) {
-        ALOGW("[vts] Test with openDemux first.");
-        return failure();
-    }
     auto status = mService->getDemuxCaps(&demuxCaps);
     return AssertionResult(status.isOk());
 }
 
+AssertionResult DemuxTests::getDemuxInfo(int32_t demuxId, DemuxInfo& demuxInfo) {
+    auto status = mService->getDemuxInfo(demuxId, &demuxInfo);
+    return AssertionResult(status.isOk());
+}
+
 AssertionResult DemuxTests::getAvSyncId(std::shared_ptr<IFilter> filter, int32_t& avSyncHwId) {
     EXPECT_TRUE(mDemux) << "Demux is not opened yet.";
 
diff --git a/tv/tuner/aidl/vts/functional/DemuxTests.h b/tv/tuner/aidl/vts/functional/DemuxTests.h
index 7698de3..b58cf70 100644
--- a/tv/tuner/aidl/vts/functional/DemuxTests.h
+++ b/tv/tuner/aidl/vts/functional/DemuxTests.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <aidl/android/hardware/tv/tuner/DemuxCapabilities.h>
+#include <aidl/android/hardware/tv/tuner/DemuxInfo.h>
 #include <aidl/android/hardware/tv/tuner/IDemux.h>
 #include <aidl/android/hardware/tv/tuner/IFilter.h>
 #include <aidl/android/hardware/tv/tuner/ITuner.h>
@@ -32,11 +33,14 @@
   public:
     void setService(std::shared_ptr<ITuner> tuner) { mService = tuner; }
 
+    AssertionResult getDemuxIds(std::vector<int32_t>& demuxIds);
     AssertionResult openDemux(std::shared_ptr<IDemux>& demux, int32_t& demuxId);
+    AssertionResult openDemuxById(int32_t demuxId, std::shared_ptr<IDemux>& demux);
     AssertionResult setDemuxFrontendDataSource(int32_t frontendId);
     AssertionResult getAvSyncId(std::shared_ptr<IFilter> filter, int32_t& avSyncHwId);
     AssertionResult getAvSyncTime(int32_t avSyncId);
     AssertionResult getDemuxCaps(DemuxCapabilities& demuxCaps);
+    AssertionResult getDemuxInfo(int32_t demuxId, DemuxInfo& demuxInfo);
     AssertionResult closeDemux();
 
   protected:
diff --git a/tv/tuner/aidl/vts/functional/DescramblerTests.cpp b/tv/tuner/aidl/vts/functional/DescramblerTests.cpp
index 157fa04..f4855c2 100644
--- a/tv/tuner/aidl/vts/functional/DescramblerTests.cpp
+++ b/tv/tuner/aidl/vts/functional/DescramblerTests.cpp
@@ -19,71 +19,115 @@
 using namespace std;
 
 AssertionResult DescramblerTests::createCasPlugin(int32_t caSystemId) {
-    auto status = mMediaCasService->isSystemIdSupported(caSystemId);
-    if (!status.isOk() || !status) {
-        ALOGW("[vts] Failed to check isSystemIdSupported.");
-        return failure();
+    mCasListener = ::ndk::SharedRefBase::make<MediaCasListener>();
+
+    if (mMediaCasServiceAidl != nullptr) {
+        bool rst = false;
+        ScopedAStatus status = mMediaCasServiceAidl->isSystemIdSupported(caSystemId, &rst);
+        if (!status.isOk() || !rst) {
+            ALOGW("[vts] Failed to check isSystemIdSupported for AIDL service.");
+            return failure();
+        }
+        status = mMediaCasServiceAidl->createPlugin(caSystemId, mCasListener, &mCasAidl);
+        if (!status.isOk()) {
+            ALOGW("[vts] Failed to createPlugin for AIDL service.");
+            return failure();
+        }
+    } else {
+        auto status = mMediaCasServiceHidl->isSystemIdSupported(caSystemId);
+        if (!status.isOk() || !status) {
+            ALOGW("[vts] Failed to check isSystemIdSupported for HIDL service.");
+            return failure();
+        }
+        auto pluginStatus = mMediaCasServiceHidl->createPluginExt(
+                caSystemId, sp<ICasListenerHidl>(mCasListener.get()));
+        if (!pluginStatus.isOk()) {
+            ALOGW("[vts] Failed to createPluginExt for HIDL service.");
+            return failure();
+        }
+        mCasHidl = ICasHidl::castFrom(pluginStatus);
+        if (mCasHidl == nullptr) {
+            ALOGW("[vts] Failed to get ICas for HIDL service.");
+            return failure();
+        }
     }
 
-    mCasListener = new MediaCasListener();
-    auto pluginStatus = mMediaCasService->createPluginExt(caSystemId, mCasListener);
-    if (!pluginStatus.isOk()) {
-        ALOGW("[vts] Failed to createPluginExt.");
-        return failure();
-    }
-    mCas = ICas::castFrom(pluginStatus);
-    if (mCas == nullptr) {
-        ALOGW("[vts] Failed to get ICas.");
-        return failure();
-    }
     return success();
 }
 
 AssertionResult DescramblerTests::openCasSession(vector<uint8_t>& sessionId,
-                                                 vector<uint8_t>& hidlPvtData) {
-    Status sessionStatus;
-    SessionIntent intent = SessionIntent::LIVE;
-    ScramblingMode mode = ScramblingMode::RESERVED;
-    auto returnVoid =
-            mCas->openSession_1_2(intent, mode, [&](Status status, const hidl_vec<uint8_t>& id) {
-                sessionStatus = status;
-                sessionId = id;
-            });
-    if (!returnVoid.isOk() || (sessionStatus != Status::OK)) {
-        ALOGW("[vts] Failed to open cas session.");
-        mCas->closeSession(sessionId);
-        return failure();
-    }
-
-    if (hidlPvtData.size() > 0) {
-        auto status = mCas->setSessionPrivateData(sessionId, hidlPvtData);
-        if (status != android::hardware::cas::V1_0::Status::OK) {
-            ALOGW("[vts] Failed to set session private data");
-            mCas->closeSession(sessionId);
+                                                 vector<uint8_t>& pvtData) {
+    if (mMediaCasServiceAidl != nullptr) {
+        SessionIntentAidl intent = SessionIntentAidl::LIVE;
+        ScramblingModeAidl mode = ScramblingModeAidl::RESERVED;
+        std::vector<uint8_t> sessionId;
+        ScopedAStatus status = mCasAidl->openSession(intent, mode, &sessionId);
+        if (!status.isOk()) {
+            ALOGW("[vts] Failed to open cas session for AIDL service.");
+            mCasAidl->closeSession(sessionId);
             return failure();
         }
+
+        if (pvtData.size() > 0) {
+            ScopedAStatus status = mCasAidl->setSessionPrivateData(sessionId, pvtData);
+            if (!status.isOk()) {
+                ALOGW("[vts] Failed to set session private data for AIDL service.");
+                mCasAidl->closeSession(sessionId);
+                return failure();
+            }
+        }
+    } else {
+        Status sessionStatus;
+        SessionIntentHidl intent = SessionIntentHidl::LIVE;
+        ScramblingModeHidl mode = ScramblingModeHidl::RESERVED;
+        auto returnVoid = mCasHidl->openSession_1_2(
+                intent, mode, [&](Status status, const hidl_vec<uint8_t>& id) {
+                    sessionStatus = status;
+                    sessionId = id;
+                });
+        if (!returnVoid.isOk() || (sessionStatus != Status::OK)) {
+            ALOGW("[vts] Failed to open cas session for HIDL service.");
+            mCasHidl->closeSession(sessionId);
+            return failure();
+        }
+
+        if (pvtData.size() > 0) {
+            auto status = mCasHidl->setSessionPrivateData(sessionId, pvtData);
+            if (status != android::hardware::cas::V1_0::Status::OK) {
+                ALOGW("[vts] Failed to set session private data for HIDL service.");
+                mCasHidl->closeSession(sessionId);
+                return failure();
+            }
+        }
     }
 
     return success();
 }
 
 AssertionResult DescramblerTests::getKeyToken(int32_t caSystemId, string& provisonStr,
-                                              vector<uint8_t>& hidlPvtData,
-                                              vector<uint8_t>& token) {
+                                              vector<uint8_t>& pvtData, vector<uint8_t>& token) {
     if (createCasPlugin(caSystemId) != success()) {
         ALOGW("[vts] createCasPlugin failed.");
         return failure();
     }
 
     if (provisonStr.size() > 0) {
-        auto returnStatus = mCas->provision(hidl_string(provisonStr));
-        if (returnStatus != android::hardware::cas::V1_0::Status::OK) {
-            ALOGW("[vts] provision failed.");
-            return failure();
+        if (mMediaCasServiceAidl != nullptr) {
+            ScopedAStatus status = mCasAidl->provision(provisonStr);
+            if (!status.isOk()) {
+                ALOGW("[vts] provision failed for AIDL service.");
+                return failure();
+            }
+        } else {
+            auto returnStatus = mCasHidl->provision(hidl_string(provisonStr));
+            if (returnStatus != android::hardware::cas::V1_0::Status::OK) {
+                ALOGW("[vts] provision failed for HIDL service.");
+                return failure();
+            }
         }
     }
 
-    return openCasSession(token, hidlPvtData);
+    return openCasSession(token, pvtData);
 }
 
 AssertionResult DescramblerTests::openDescrambler(int32_t demuxId) {
diff --git a/tv/tuner/aidl/vts/functional/DescramblerTests.h b/tv/tuner/aidl/vts/functional/DescramblerTests.h
index f0b7691..bab1a88 100644
--- a/tv/tuner/aidl/vts/functional/DescramblerTests.h
+++ b/tv/tuner/aidl/vts/functional/DescramblerTests.h
@@ -30,11 +30,17 @@
 #include <android/hardware/cas/1.2/IMediaCasService.h>
 #include <android/hardware/cas/1.2/types.h>
 
+#include <aidl/android/hardware/cas/BnCasListener.h>
+#include <aidl/android/hardware/cas/ICas.h>
+#include <aidl/android/hardware/cas/IMediaCasService.h>
+#include <aidl/android/hardware/cas/ScramblingMode.h>
+#include <aidl/android/hardware/cas/SessionIntent.h>
 #include <aidl/android/hardware/tv/tuner/IDescrambler.h>
 #include <aidl/android/hardware/tv/tuner/IDvr.h>
 #include <aidl/android/hardware/tv/tuner/IDvrCallback.h>
 #include <aidl/android/hardware/tv/tuner/ITuner.h>
 
+using ::aidl::android::hardware::cas::BnCasListener;
 using android::Condition;
 using android::Mutex;
 using android::sp;
@@ -42,19 +48,26 @@
 using android::hardware::hidl_vec;
 using android::hardware::Return;
 using android::hardware::Void;
-using android::hardware::cas::V1_2::ICas;
-using android::hardware::cas::V1_2::ICasListener;
-using android::hardware::cas::V1_2::IMediaCasService;
-using android::hardware::cas::V1_2::ScramblingMode;
-using android::hardware::cas::V1_2::SessionIntent;
 using android::hardware::cas::V1_2::Status;
 using android::hardware::cas::V1_2::StatusEvent;
+using ICasAidl = ::aidl::android::hardware::cas::ICas;
+using ICasHidl = android::hardware::cas::V1_2::ICas;
+using ICasListenerHidl = android::hardware::cas::V1_2::ICasListener;
+using IMediaCasServiceAidl = ::aidl::android::hardware::cas::IMediaCasService;
+using IMediaCasServiceHidl = android::hardware::cas::V1_2::IMediaCasService;
+using ScramblingModeAidl = ::aidl::android::hardware::cas::ScramblingMode;
+using ScramblingModeHidl = android::hardware::cas::V1_2::ScramblingMode;
+using SessionIntentAidl = ::aidl::android::hardware::cas::SessionIntent;
+using SessionIntentHidl = android::hardware::cas::V1_2::SessionIntent;
 
+using ::ndk::ScopedAStatus;
 using ::testing::AssertionResult;
 
 using namespace aidl::android::hardware::tv::tuner;
 
-class MediaCasListener : public ICasListener {
+const std::string MEDIA_CAS_AIDL_SERVICE_NAME = "android.hardware.cas.IMediaCasService/default";
+
+class MediaCasListener : public ICasListenerHidl, public BnCasListener {
   public:
     virtual Return<void> onEvent(int32_t /*event*/, int32_t /*arg*/,
                                  const hidl_vec<uint8_t>& /*data*/) override {
@@ -70,12 +83,33 @@
     virtual Return<void> onStatusUpdate(StatusEvent /*event*/, int32_t /*arg*/) override {
         return Void();
     }
+
+    ScopedAStatus onEvent(int32_t /*in_event*/, int32_t /*in_arg*/,
+                          const std::vector<uint8_t>& /*in_data*/) override {
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onSessionEvent(const std::vector<uint8_t>& /*in_sessionId*/, int32_t /*in_event*/,
+                                 int32_t /*in_arg*/,
+                                 const std::vector<uint8_t>& /*in_data*/) override {
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onStatusUpdate(::aidl::android::hardware::cas::StatusEvent /*in_event*/,
+                                 int32_t /*in_number*/) override {
+        return ScopedAStatus::ok();
+    }
 };
 
 class DescramblerTests {
   public:
     void setService(std::shared_ptr<ITuner> tuner) { mService = tuner; }
-    void setCasService(sp<IMediaCasService> casService) { mMediaCasService = casService; }
+    void setCasServiceHidl(sp<IMediaCasServiceHidl> casService) {
+        mMediaCasServiceHidl = casService;
+    }
+    void setCasServiceAidl(std::shared_ptr<IMediaCasServiceAidl> casService) {
+        mMediaCasServiceAidl = casService;
+    }
 
     AssertionResult setKeyToken(std::vector<uint8_t>& token);
     AssertionResult openDescrambler(int32_t demuxId);
@@ -95,12 +129,13 @@
 
     std::shared_ptr<ITuner> mService;
     std::shared_ptr<IDescrambler> mDescrambler;
-    android::sp<ICas> mCas;
-    android::sp<IMediaCasService> mMediaCasService;
-    android::sp<MediaCasListener> mCasListener;
+    std::shared_ptr<ICasAidl> mCasAidl;
+    android::sp<ICasHidl> mCasHidl;
+    std::shared_ptr<IMediaCasServiceAidl> mMediaCasServiceAidl;
+    android::sp<IMediaCasServiceHidl> mMediaCasServiceHidl;
+    std::shared_ptr<MediaCasListener> mCasListener;
 
   private:
-    AssertionResult openCasSession(std::vector<uint8_t>& sessionId,
-                                   std::vector<uint8_t>& hidlPvtData);
+    AssertionResult openCasSession(std::vector<uint8_t>& sessionId, std::vector<uint8_t>& pvtData);
     AssertionResult createCasPlugin(int32_t caSystemId);
 };
diff --git a/tv/tuner/aidl/vts/functional/DvrTests.cpp b/tv/tuner/aidl/vts/functional/DvrTests.cpp
index a9c3b51..50f4de2 100644
--- a/tv/tuner/aidl/vts/functional/DvrTests.cpp
+++ b/tv/tuner/aidl/vts/functional/DvrTests.cpp
@@ -323,3 +323,41 @@
     ASSERT_TRUE(mDvrRecord);
     ASSERT_TRUE(mDvrRecord->close().isOk());
 }
+
+AssertionResult DvrTests::setPlaybackStatusCheckIntervalHint(int64_t milliseconds) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first.";
+
+    status = mDvrPlayback->setStatusCheckIntervalHint(milliseconds);
+
+    if (getDvrPlaybackInterfaceVersion() < 2) {
+        return AssertionResult(status.getStatus() == STATUS_UNKNOWN_TRANSACTION);
+    }
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::setRecordStatusCheckIntervalHint(int64_t milliseconds) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
+
+    status = mDvrRecord->setStatusCheckIntervalHint(milliseconds);
+
+    if (getDvrRecordInterfaceVersion() < 2) {
+        return AssertionResult(status.getStatus() == STATUS_UNKNOWN_TRANSACTION);
+    }
+    return AssertionResult(status.isOk());
+}
+
+int32_t DvrTests::getDvrPlaybackInterfaceVersion() {
+    int32_t version;
+    mDvrPlayback->getInterfaceVersion(&version);
+    return version;
+}
+
+int32_t DvrTests::getDvrRecordInterfaceVersion() {
+    int32_t version;
+    mDvrRecord->getInterfaceVersion(&version);
+    return version;
+}
diff --git a/tv/tuner/aidl/vts/functional/DvrTests.h b/tv/tuner/aidl/vts/functional/DvrTests.h
index 6662637..a88ba24 100644
--- a/tv/tuner/aidl/vts/functional/DvrTests.h
+++ b/tv/tuner/aidl/vts/functional/DvrTests.h
@@ -162,8 +162,12 @@
     AssertionResult startDvrPlayback();
     AssertionResult stopDvrRecord();
     AssertionResult startDvrRecord();
+    AssertionResult setPlaybackStatusCheckIntervalHint(int64_t milliseconds);
+    AssertionResult setRecordStatusCheckIntervalHint(int64_t milliseconds);
     void closeDvrPlayback();
     void closeDvrRecord();
+    int32_t getDvrPlaybackInterfaceVersion();
+    int32_t getDvrRecordInterfaceVersion();
 
   protected:
     static AssertionResult failure() { return ::testing::AssertionFailure(); }
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.cpp b/tv/tuner/aidl/vts/functional/FilterTests.cpp
index 53afef7..533d0e6 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FilterTests.cpp
@@ -305,13 +305,18 @@
     ndk::ScopedAStatus status;
 
     status = mFilters[filterId]->configureMonitorEvent(monitorEventTypes);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::testMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes) {
+    EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
     if (monitorEventTypes & static_cast<int32_t>(DemuxFilterMonitorEventType::SCRAMBLING_STATUS)) {
         mFilterCallbacks[filterId]->testFilterScramblingEvent();
     }
     if (monitorEventTypes & static_cast<int32_t>(DemuxFilterMonitorEventType::IP_CID_CHANGE)) {
         mFilterCallbacks[filterId]->testFilterIpCidEvent();
     }
-    return AssertionResult(status.isOk());
+    return AssertionResult(true);
 }
 
 AssertionResult FilterTests::startIdTest(int64_t filterId) {
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.h b/tv/tuner/aidl/vts/functional/FilterTests.h
index f579441..f57093e 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.h
+++ b/tv/tuner/aidl/vts/functional/FilterTests.h
@@ -124,6 +124,7 @@
     AssertionResult configAvFilterStreamType(AvStreamType type, int64_t filterId);
     AssertionResult configIpFilterCid(int32_t ipCid, int64_t filterId);
     AssertionResult configureMonitorEvent(int64_t filterId, int32_t monitorEventTypes);
+    AssertionResult testMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes);
     AssertionResult getFilterMQDescriptor(int64_t filterId, bool getMqDesc);
     AssertionResult startFilter(int64_t filterId);
     AssertionResult stopFilter(int64_t filterId);
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index a1f51df..b0f614e 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#include <aidl/android/hardware/tv/tuner/Result.h>
-
 #include "FrontendTests.h"
 
+#include <aidl/android/hardware/tv/tuner/Result.h>
+
 ndk::ScopedAStatus FrontendCallback::onEvent(FrontendEventType frontendEventType) {
     android::Mutex::Autolock autoLock(mMsgLock);
     ALOGD("[vts] frontend event received. Type: %d", frontendEventType);
@@ -323,7 +323,10 @@
         FrontendStatusType type = statusTypes[i];
         switch (type) {
             case FrontendStatusType::MODULATIONS: {
-                // TODO: verify modulations
+                ASSERT_TRUE(std::equal(
+                        realStatuses[i].get<FrontendStatus::Tag::modulations>().begin(),
+                        realStatuses[i].get<FrontendStatus::Tag::modulations>().end(),
+                        expectStatuses[i].get<FrontendStatus::Tag::modulations>().begin()));
                 break;
             }
             case FrontendStatusType::BERS: {
@@ -340,11 +343,13 @@
                 break;
             }
             case FrontendStatusType::GUARD_INTERVAL: {
-                // TODO: verify interval
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::interval>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::interval>());
                 break;
             }
             case FrontendStatusType::TRANSMISSION_MODE: {
-                // TODO: verify tranmission mode
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::transmissionMode>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::transmissionMode>());
                 break;
             }
             case FrontendStatusType::UEC: {
@@ -379,7 +384,8 @@
                 break;
             }
             case FrontendStatusType::ROLL_OFF: {
-                // TODO: verify roll off
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::rollOff>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::rollOff>());
                 break;
             }
             case FrontendStatusType::IS_MISO: {
@@ -428,6 +434,31 @@
                         expectStatuses[i].get<FrontendStatus::Tag::allPlpInfo>().begin()));
                 break;
             }
+            case FrontendStatusType::IPTV_CONTENT_URL: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvContentUrl>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::iptvContentUrl>());
+                break;
+            }
+            case FrontendStatusType::IPTV_PACKETS_LOST: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvPacketsLost>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::iptvPacketsLost>());
+                break;
+            }
+            case FrontendStatusType::IPTV_PACKETS_RECEIVED: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvPacketsReceived>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::iptvPacketsReceived>());
+                break;
+            }
+            case FrontendStatusType::IPTV_WORST_JITTER_MS: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvWorstJitterMs>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::iptvWorstJitterMs>());
+                break;
+            }
+            case FrontendStatusType::IPTV_AVERAGE_JITTER_MS: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvAverageJitterMs>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::iptvAverageJitterMs>());
+                break;
+            }
             default: {
                 continue;
             }
@@ -599,9 +630,10 @@
     ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
 
     // TODO: find a better way to push all frontend status types
-    for (int32_t i = 0; i < static_cast<int32_t>(FrontendStatusType::ATSC3_ALL_PLP_INFO); i++) {
+    for (int32_t i = 0; i <= static_cast<int32_t>(FrontendStatusType::ATSC3_ALL_PLP_INFO); i++) {
         allTypes.push_back(static_cast<FrontendStatusType>(i));
     }
+
     ndk::ScopedAStatus status = mFrontend->getFrontendStatusReadiness(allTypes, &readiness);
     ASSERT_TRUE(status.isOk());
     ASSERT_TRUE(readiness.size() == allTypes.size());
diff --git a/tv/tuner/aidl/vts/functional/LnbTests.h b/tv/tuner/aidl/vts/functional/LnbTests.h
index d6b5a25..a21e68d 100644
--- a/tv/tuner/aidl/vts/functional/LnbTests.h
+++ b/tv/tuner/aidl/vts/functional/LnbTests.h
@@ -25,6 +25,8 @@
 #include <utils/Mutex.h>
 #include <map>
 
+#define INVALID_LNB_ID -1
+
 using android::Condition;
 using android::Mutex;
 
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 07e3e3c..766814f 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -48,6 +48,7 @@
     ASSERT_TRUE(mFrontendTests.setFrontendCallback());
     ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
     ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFrontendTests.setDemux(demux);
     mFilterTests.setDemux(demux);
     ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
@@ -60,6 +61,11 @@
     }
     ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+    if (filterConf.monitorEventTypes > 0) {
+        ASSERT_TRUE(mFilterTests.testMonitorEvent(filterId, filterConf.monitorEventTypes));
+    }
+    ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
     ASSERT_TRUE(mFilterTests.stopFilter(filterId));
     ASSERT_TRUE(mFilterTests.closeFilter(filterId));
     ASSERT_TRUE(mDemuxTests.closeDemux());
@@ -129,8 +135,8 @@
     mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
     ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
     ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-    if (mLnbId) {
-        ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId));
+    if (mLnbId != INVALID_LNB_ID) {
+        ASSERT_TRUE(mFrontendTests.setLnb(mLnbId));
     }
     if (frontendConf.isSoftwareFe) {
         mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]);
@@ -162,18 +168,19 @@
         ASSERT_TRUE(mLnbTests.getLnbIds(ids));
         ASSERT_TRUE(ids.size() > 0);
         ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
-        mLnbId = &ids[0];
+        mLnbId = ids[0];
     } else {
-        mLnbId = (int32_t*)malloc(sizeof(int32_t));
-        ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId));
+        ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, mLnbId));
     }
     ASSERT_TRUE(mLnbTests.setLnbCallback());
     ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage));
     ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone));
     ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConf.position));
-    broadcastSingleFilterTest(filterConf, frontendConf);
+    if (!frontendConf.isSoftwareFe) {
+        broadcastSingleFilterTest(filterConf, frontendConf);
+    }
     ASSERT_TRUE(mLnbTests.closeLnb());
-    mLnbId = nullptr;
+    mLnbId = INVALID_LNB_ID;
 }
 
 void TunerBroadcastAidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf,
@@ -240,6 +247,28 @@
     ASSERT_TRUE(mDemuxTests.closeDemux());
 }
 
+void TunerPlaybackAidlTest::setStatusCheckIntervalHintTest(int64_t statusCheckIntervalHint,
+                                                           DvrConfig dvrConf) {
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    mDvrTests.setDemux(demux);
+    ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
+    ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrConf.settings));
+    ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+
+    ASSERT_TRUE(mDvrTests.setPlaybackStatusCheckIntervalHint(statusCheckIntervalHint));
+
+    mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile,
+                                       dvrConf.settings.get<DvrSettings::Tag::playback>());
+    ASSERT_TRUE(mDvrTests.startDvrPlayback());
+    mDvrTests.stopPlaybackThread();
+    ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+    mDvrTests.closeDvrPlayback();
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+}
+
 void TunerRecordAidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf,
                                                         FrontendConfig frontendConf,
                                                         DvrConfig dvrConf, LnbConfig lnbConf) {
@@ -248,10 +277,9 @@
         ASSERT_TRUE(mLnbTests.getLnbIds(ids));
         ASSERT_TRUE(ids.size() > 0);
         ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
-        mLnbId = &ids[0];
+        mLnbId = ids[0];
     } else {
-        mLnbId = (int32_t*)malloc(sizeof(int32_t));
-        ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId));
+        ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, mLnbId));
     }
     ASSERT_TRUE(mLnbTests.setLnbCallback());
     ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage));
@@ -260,9 +288,11 @@
     for (auto msgName : lnbRecord.diseqcMsgs) {
         ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
     }
-    recordSingleFilterTest(filterConf, frontendConf, dvrConf);
+    if (!frontendConf.isSoftwareFe) {
+        recordSingleFilterTest(filterConf, frontendConf, dvrConf, Dataflow_Context::LNBRECORD);
+    }
     ASSERT_TRUE(mLnbTests.closeLnb());
-    mLnbId = nullptr;
+    mLnbId = INVALID_LNB_ID;
 }
 
 void TunerRecordAidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterConf,
@@ -318,29 +348,47 @@
 }
 
 void TunerRecordAidlTest::recordSingleFilterTest(FilterConfig filterConf,
-                                                 FrontendConfig frontendConf, DvrConfig dvrConf) {
+                                                 FrontendConfig frontendConf, DvrConfig dvrConf,
+                                                 Dataflow_Context context) {
     int32_t demuxId;
     std::shared_ptr<IDemux> demux;
     ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
     mDvrTests.setDemux(demux);
 
     DvrConfig dvrSourceConfig;
-    if (record.hasFrontendConnection) {
+    if (context == Dataflow_Context::RECORD) {
+        if (record.hasFrontendConnection) {
+            int32_t feId;
+            mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+            ASSERT_TRUE(feId != INVALID_ID);
+            ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+            ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+            if (frontendConf.isSoftwareFe) {
+                mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
+            }
+            ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+            mFrontendTests.setDvrTests(&mDvrTests);
+        } else {
+            dvrSourceConfig = dvrMap[record.dvrSourceId];
+            ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+            ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+            ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+        }
+    } else if (context == Dataflow_Context::LNBRECORD) {
+        // If function arrives here, frontend should not be software, so no need to configure a dvr
+        // source or dvr fe connection that might be used for recording without an Lnb
         int32_t feId;
         mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
         ASSERT_TRUE(feId != INVALID_ID);
         ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
         ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-        if (frontendConf.isSoftwareFe) {
-            mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
+        if (mLnbId != INVALID_LNB_ID) {
+            ASSERT_TRUE(mFrontendTests.setLnb(mLnbId));
+        } else {
+            FAIL();
         }
         ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
         mFrontendTests.setDvrTests(&mDvrTests);
-    } else {
-        dvrSourceConfig = dvrMap[record.dvrSourceId];
-        ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
-        ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
-        ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
     }
 
     int64_t filterId;
@@ -360,24 +408,31 @@
     ASSERT_TRUE(mDvrTests.startDvrRecord());
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
 
-    if (record.hasFrontendConnection) {
+    if (context == Dataflow_Context::RECORD) {
+        if (record.hasFrontendConnection) {
+            ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+        } else {
+            // Start DVR Source
+            mDvrTests.startPlaybackInputThread(
+                    dvrSourceConfig.playbackInputFile,
+                    dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
+            ASSERT_TRUE(mDvrTests.startDvrPlayback());
+        }
+    } else if (context == Dataflow_Context::LNBRECORD) {
         ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
-    } else {
-        // Start DVR Source
-        mDvrTests.startPlaybackInputThread(
-                dvrSourceConfig.playbackInputFile,
-                dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
-        ASSERT_TRUE(mDvrTests.startDvrPlayback());
     }
-
     mDvrTests.testRecordOutput();
     mDvrTests.stopRecordThread();
 
-    if (record.hasFrontendConnection) {
+    if (context == Dataflow_Context::RECORD) {
+        if (record.hasFrontendConnection) {
+            ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+        } else {
+            mDvrTests.stopPlaybackThread();
+            ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+        }
+    } else if (context == Dataflow_Context::LNBRECORD) {
         ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
-    } else {
-        mDvrTests.stopPlaybackThread();
-        ASSERT_TRUE(mDvrTests.stopDvrPlayback());
     }
 
     ASSERT_TRUE(mFilterTests.stopFilter(filterId));
@@ -386,39 +441,99 @@
     ASSERT_TRUE(mFilterTests.closeFilter(filterId));
     mDvrTests.closeDvrRecord();
 
-    if (record.hasFrontendConnection) {
+    if (context == Dataflow_Context::RECORD) {
+        if (record.hasFrontendConnection) {
+            ASSERT_TRUE(mFrontendTests.closeFrontend());
+        } else {
+            mDvrTests.closeDvrPlayback();
+        }
+    } else if (context == Dataflow_Context::LNBRECORD) {
         ASSERT_TRUE(mFrontendTests.closeFrontend());
-    } else {
-        mDvrTests.closeDvrPlayback();
     }
 
     ASSERT_TRUE(mDemuxTests.closeDemux());
 }
 
+void TunerRecordAidlTest::setStatusCheckIntervalHintTest(int64_t statusCheckIntervalHint,
+                                                         FrontendConfig frontendConf,
+                                                         DvrConfig dvrConf) {
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    mDvrTests.setDemux(demux);
+
+    DvrConfig dvrSourceConfig;
+    if (record.hasFrontendConnection) {
+        int32_t feId;
+        mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+        ASSERT_TRUE(feId != INVALID_ID);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    } else {
+        dvrSourceConfig = dvrMap[record.dvrSourceId];
+        ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+        ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+        ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+    }
+
+    ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
+    ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
+    ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
+
+    ASSERT_TRUE(mDvrTests.setRecordStatusCheckIntervalHint(statusCheckIntervalHint));
+
+    ASSERT_TRUE(mDvrTests.startDvrRecord());
+    ASSERT_TRUE(mDvrTests.stopDvrRecord());
+    mDvrTests.closeDvrRecord();
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+
+    if (record.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    }
+}
+
 void TunerDescramblerAidlTest::scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
                                                       FrontendConfig frontendConf,
-                                                      DescramblerConfig descConfig) {
+                                                      DescramblerConfig descConfig,
+                                                      Dataflow_Context context) {
     int32_t demuxId;
     std::shared_ptr<IDemux> demux;
     ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
 
     DvrConfig dvrSourceConfig;
-    if (descrambling.hasFrontendConnection) {
+    if (context == Dataflow_Context::DESCRAMBLING) {
+        if (descrambling.hasFrontendConnection) {
+            int32_t feId;
+            mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+            ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+            ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+            if (frontendConf.isSoftwareFe) {
+                mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]);
+            }
+            ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+            mFrontendTests.setDemux(demux);
+        } else {
+            dvrSourceConfig = dvrMap[descrambling.dvrSourceId];
+            mDvrTests.setDemux(demux);
+            ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+            ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+            ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+        }
+    } else if (context == Dataflow_Context::LNBDESCRAMBLING) {
         int32_t feId;
         mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
         ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
         ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-        if (frontendConf.isSoftwareFe) {
-            mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]);
+        if (mLnbId != INVALID_LNB_ID) {
+            ASSERT_TRUE(mFrontendTests.setLnb(mLnbId));
+        } else {
+            // If, for some reason, the test got here without failing. We fail it here.
+            ALOGD("mLnbId is null. Something went wrong. Exiting ScrambledBroadcastWithLnbId.");
+            FAIL();
         }
         ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
         mFrontendTests.setDemux(demux);
-    } else {
-        dvrSourceConfig = dvrMap[descrambling.dvrSourceId];
-        mDvrTests.setDemux(demux);
-        ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
-        ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
-        ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
     }
 
     set<int64_t> filterIds;
@@ -449,24 +564,32 @@
         ASSERT_TRUE(mFilterTests.startFilter(*id));
     }
 
-    if (descrambling.hasFrontendConnection) {
-        // tune test
+    if (context == Dataflow_Context::DESCRAMBLING) {
+        if (descrambling.hasFrontendConnection) {
+            // tune test
+            ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+        } else {
+            // Start DVR Source
+            mDvrTests.startPlaybackInputThread(
+                    dvrSourceConfig.playbackInputFile,
+                    dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
+            ASSERT_TRUE(mDvrTests.startDvrPlayback());
+        }
+    } else if (context == Dataflow_Context::LNBDESCRAMBLING) {
         ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
-    } else {
-        // Start DVR Source
-        mDvrTests.startPlaybackInputThread(
-                dvrSourceConfig.playbackInputFile,
-                dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
-        ASSERT_TRUE(mDvrTests.startDvrPlayback());
     }
 
     ASSERT_TRUE(filterDataOutputTest());
 
-    if (descrambling.hasFrontendConnection) {
+    if (context == Dataflow_Context::DESCRAMBLING) {
+        if (descrambling.hasFrontendConnection) {
+            ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+        } else {
+            mDvrTests.stopPlaybackThread();
+            ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+        }
+    } else if (context == Dataflow_Context::LNBDESCRAMBLING) {
         ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
-    } else {
-        mDvrTests.stopPlaybackThread();
-        ASSERT_TRUE(mDvrTests.stopDvrPlayback());
     }
 
     for (id = filterIds.begin(); id != filterIds.end(); id++) {
@@ -480,37 +603,80 @@
         ASSERT_TRUE(mFilterTests.closeFilter(*id));
     }
 
-    if (descrambling.hasFrontendConnection) {
+    if (context == Dataflow_Context::DESCRAMBLING) {
+        if (descrambling.hasFrontendConnection) {
+            ASSERT_TRUE(mFrontendTests.closeFrontend());
+        } else {
+            mDvrTests.closeDvrPlayback();
+        }
+    } else if (context == Dataflow_Context::LNBDESCRAMBLING) {
         ASSERT_TRUE(mFrontendTests.closeFrontend());
-    } else {
-        mDvrTests.closeDvrPlayback();
     }
 
     ASSERT_TRUE(mDemuxTests.closeDemux());
 }
 
+void TunerDescramblerAidlTest::scrambledBroadcastTestWithLnb(
+        set<struct FilterConfig>& mediaFilterConfs, FrontendConfig& frontendConf,
+        DescramblerConfig& descConfig, LnbConfig& lnbConfig) {
+    // We can test the Lnb individually and make sure it functions properly. If the frontend is
+    // software, we cannot test the whole dataflow. If the frontend is hardware, we can
+    if (lnbConfig.name.compare(emptyHardwareId) == 0) {
+        vector<int32_t> ids;
+        ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+        ASSERT_TRUE(ids.size() > 0);
+        ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+        mLnbId = ids[0];
+    } else {
+        ASSERT_TRUE(mLnbTests.openLnbByName(lnbConfig.name, mLnbId));
+    }
+    // Once Lnb is opened, test some of its basic functionality
+    ASSERT_TRUE(mLnbTests.setLnbCallback());
+    ASSERT_TRUE(mLnbTests.setVoltage(lnbConfig.voltage));
+    ASSERT_TRUE(mLnbTests.setTone(lnbConfig.tone));
+    ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConfig.position));
+    if (!frontendConf.isSoftwareFe) {
+        ALOGD("Frontend is not software, testing entire dataflow.");
+        scrambledBroadcastTest(mediaFilterConfs, frontendConf, descConfig,
+                               Dataflow_Context::LNBDESCRAMBLING);
+    } else {
+        ALOGD("Frontend is software, did not test the entire dataflow, but tested the Lnb "
+              "individually.");
+    }
+    ASSERT_TRUE(mLnbTests.closeLnb());
+    mLnbId = INVALID_LNB_ID;
+}
+
 TEST_P(TunerLnbAidlTest, SendDiseqcMessageToLnb) {
     description("Open and configure an Lnb with specific settings then send a diseqc msg to it.");
     if (!lnbLive.support) {
         return;
     }
-    if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) {
-        vector<int32_t> ids;
-        ASSERT_TRUE(mLnbTests.getLnbIds(ids));
-        ASSERT_TRUE(ids.size() > 0);
-        ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
-    } else {
-        int32_t id;
-        ASSERT_TRUE(mLnbTests.openLnbByName(lnbMap[lnbLive.lnbId].name, id));
+    vector<LnbLiveHardwareConnections> lnbLive_configs = generateLnbLiveConfigurations();
+    if (lnbLive_configs.empty()) {
+        ALOGD("No frontends that support satellites.");
+        return;
     }
-    ASSERT_TRUE(mLnbTests.setLnbCallback());
-    ASSERT_TRUE(mLnbTests.setVoltage(lnbMap[lnbLive.lnbId].voltage));
-    ASSERT_TRUE(mLnbTests.setTone(lnbMap[lnbLive.lnbId].tone));
-    ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbMap[lnbLive.lnbId].position));
-    for (auto msgName : lnbLive.diseqcMsgs) {
-        ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
+    for (auto& combination : lnbLive_configs) {
+        lnbLive = combination;
+        if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) {
+            vector<int32_t> ids;
+            ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+            ASSERT_TRUE(ids.size() > 0);
+            ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+        } else {
+            int32_t id;
+            ASSERT_TRUE(mLnbTests.openLnbByName(lnbMap[lnbLive.lnbId].name, id));
+        }
+        ASSERT_TRUE(mLnbTests.setLnbCallback());
+        ASSERT_TRUE(mLnbTests.setVoltage(lnbMap[lnbLive.lnbId].voltage));
+        ASSERT_TRUE(mLnbTests.setTone(lnbMap[lnbLive.lnbId].tone));
+        ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbMap[lnbLive.lnbId].position));
+        for (auto msgName : lnbLive.diseqcMsgs) {
+            ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
+        }
+        ASSERT_TRUE(mLnbTests.closeLnb());
     }
-    ASSERT_TRUE(mLnbTests.closeLnb());
 }
 
 TEST_P(TunerDemuxAidlTest, openDemux) {
@@ -518,17 +684,49 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    int32_t feId;
-    int32_t demuxId;
-    std::shared_ptr<IDemux> demux;
-    mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
-    ASSERT_TRUE(feId != INVALID_ID);
-    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
-    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
-    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
-    ASSERT_TRUE(mDemuxTests.closeDemux());
-    ASSERT_TRUE(mFrontendTests.closeFrontend());
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        int32_t feId;
+        int32_t demuxId;
+        std::shared_ptr<IDemux> demux;
+        mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
+        ASSERT_TRUE(feId != INVALID_ID);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+        ASSERT_TRUE(mDemuxTests.closeDemux());
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    }
+}
+
+TEST_P(TunerDemuxAidlTest, openDemuxById) {
+    description("Open (with id) and close a Demux.");
+    std::vector<int32_t> demuxIds;
+    ASSERT_TRUE(mDemuxTests.getDemuxIds(demuxIds));
+    for (int i = 0; i < demuxIds.size(); i++) {
+        std::shared_ptr<IDemux> demux;
+        ASSERT_TRUE(mDemuxTests.openDemuxById(demuxIds[i], demux));
+        ASSERT_TRUE(mDemuxTests.closeDemux());
+    }
+}
+
+TEST_P(TunerDemuxAidlTest, getDemuxInfo) {
+    description("Check getDemuxInfo against demux caps");
+    std::vector<int32_t> demuxIds;
+    ASSERT_TRUE(mDemuxTests.getDemuxIds(demuxIds));
+    int32_t combinedFilterTypes = 0;
+    for (int i = 0; i < demuxIds.size(); i++) {
+        DemuxInfo demuxInfo;
+        ASSERT_TRUE(mDemuxTests.getDemuxInfo(demuxIds[i], demuxInfo));
+        combinedFilterTypes |= demuxInfo.filterTypes;
+    }
+    if (demuxIds.size() > 0) {
+        DemuxCapabilities demuxCaps;
+        ASSERT_TRUE(mDemuxTests.getDemuxCaps(demuxCaps));
+        ASSERT_TRUE(demuxCaps.filterCaps == combinedFilterTypes);
+    }
 }
 
 TEST_P(TunerDemuxAidlTest, getAvSyncTime) {
@@ -536,40 +734,45 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    if (live.pcrFilterId.compare(emptyHardwareId) == 0) {
-        return;
-    }
-    int32_t feId;
-    int32_t demuxId;
-    std::shared_ptr<IDemux> demux;
-    int64_t mediaFilterId;
-    int64_t pcrFilterId;
-    int32_t avSyncHwId;
-    std::shared_ptr<IFilter> mediaFilter;
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        if (live.pcrFilterId.compare(emptyHardwareId) == 0) {
+            continue;
+        }
+        int32_t feId;
+        int32_t demuxId;
+        std::shared_ptr<IDemux> demux;
+        int64_t mediaFilterId;
+        int64_t pcrFilterId;
+        int32_t avSyncHwId;
+        std::shared_ptr<IFilter> mediaFilter;
 
-    mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
-    ASSERT_TRUE(feId != INVALID_ID);
-    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
-    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
-    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
-    mFilterTests.setDemux(demux);
-    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.videoFilterId].type,
-                                               filterMap[live.videoFilterId].bufferSize));
-    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.videoFilterId].settings, mediaFilterId));
-    mediaFilter = mFilterTests.getFilterById(mediaFilterId);
-    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.pcrFilterId].type,
-                                               filterMap[live.pcrFilterId].bufferSize));
-    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.pcrFilterId].settings, pcrFilterId));
-    ASSERT_TRUE(mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId));
-    ASSERT_TRUE(pcrFilterId == avSyncHwId);
-    ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId));
-    ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId));
-    ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId));
-    ASSERT_TRUE(mDemuxTests.closeDemux());
-    ASSERT_TRUE(mFrontendTests.closeFrontend());
+        mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
+        ASSERT_TRUE(feId != INVALID_ID);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+        mFilterTests.setDemux(demux);
+        ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.videoFilterId].type,
+                                                   filterMap[live.videoFilterId].bufferSize));
+        ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId));
+        ASSERT_TRUE(
+                mFilterTests.configFilter(filterMap[live.videoFilterId].settings, mediaFilterId));
+        mediaFilter = mFilterTests.getFilterById(mediaFilterId);
+        ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.pcrFilterId].type,
+                                                   filterMap[live.pcrFilterId].bufferSize));
+        ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId));
+        ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.pcrFilterId].settings, pcrFilterId));
+        ASSERT_TRUE(mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId));
+        ASSERT_TRUE(pcrFilterId == avSyncHwId);
+        ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId));
+        ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId));
+        ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId));
+        ASSERT_TRUE(mDemuxTests.closeDemux());
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    }
 }
 
 TEST_P(TunerFilterAidlTest, StartFilterInDemux) {
@@ -578,7 +781,11 @@
         return;
     }
     // TODO use parameterized tests
-    configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFilterAidlTest, ConfigIpFilterInDemuxWithCid) {
@@ -587,10 +794,14 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    if (live.ipFilterId.compare(emptyHardwareId) == 0) {
-        return;
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        if (live.ipFilterId.compare(emptyHardwareId) == 0) {
+            continue;
+        }
+        configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]);
     }
-    configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerFilterAidlTest, ReconfigFilterToReceiveStartId) {
@@ -599,8 +810,13 @@
         return;
     }
     // TODO use parameterized tests
-    reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId], filterMap[live.videoFilterId],
-                                    frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId],
+                                        filterMap[live.videoFilterId],
+                                        frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFilterAidlTest, SetFilterLinkage) {
@@ -637,7 +853,11 @@
         return;
     }
     // TODO use parameterized tests
-    testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
+    auto timeFilter_configs = generateTimeFilterConfigurations();
+    for (auto& configuration : timeFilter_configs) {
+        timeFilter = configuration;
+        testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
+    }
 }
 
 static bool isEventProducingFilter(const FilterConfig& filterConfig) {
@@ -839,10 +1059,16 @@
 
 TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) {
     description("Feed ts data from playback and configure Ts section filter to get output");
-    if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) {
+    if (!playback.support) {
         return;
     }
-    playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]);
+    vector<DvrPlaybackHardwareConnections> playback_configs = generatePlaybackConfigs();
+    for (auto& configuration : playback_configs) {
+        if (configuration.sectionFilterId.compare(emptyHardwareId) != 0) {
+            playback = configuration;
+            playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]);
+        }
+    }
 }
 
 TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsAudioFilterTest) {
@@ -850,7 +1076,11 @@
     if (!playback.support) {
         return;
     }
-    playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]);
+    vector<DvrPlaybackHardwareConnections> playback_configs = generatePlaybackConfigs();
+    for (auto& configuration : playback_configs) {
+        playback = configuration;
+        playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]);
+    }
 }
 
 TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsVideoFilterTest) {
@@ -858,7 +1088,23 @@
     if (!playback.support) {
         return;
     }
-    playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]);
+    vector<DvrPlaybackHardwareConnections> playback_configs = generatePlaybackConfigs();
+    for (auto& configuration : playback_configs) {
+        playback = configuration;
+        playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]);
+    }
+}
+
+TEST_P(TunerPlaybackAidlTest, SetStatusCheckIntervalHintToPlaybackTest) {
+    description("Set status check interval hint to playback test.");
+    if (!playback.support) {
+        return;
+    }
+    vector<DvrPlaybackHardwareConnections> playback_configs = generatePlaybackConfigs();
+    for (auto& configuration : playback_configs) {
+        playback = configuration;
+        setStatusCheckIntervalHintTest(STATUS_CHECK_INTERVAL_MS, dvrMap[playback.dvrId]);
+    }
 }
 
 TEST_P(TunerRecordAidlTest, RecordDataFlowWithTsRecordFilterTest) {
@@ -866,8 +1112,12 @@
     if (!record.support) {
         return;
     }
-    recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
-                           dvrMap[record.dvrRecordId]);
+    auto record_configs = generateRecordConfigurations();
+    for (auto& configuration : record_configs) {
+        record = configuration;
+        recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
+                               dvrMap[record.dvrRecordId], Dataflow_Context::RECORD);
+    }
 }
 
 TEST_P(TunerRecordAidlTest, AttachFiltersToRecordTest) {
@@ -876,8 +1126,13 @@
     if (!record.support) {
         return;
     }
-    attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
-                                      frontendMap[record.frontendId], dvrMap[record.dvrRecordId]);
+    auto record_configs = generateRecordConfigurations();
+    for (auto& configuration : record_configs) {
+        record = configuration;
+        attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
+                                          frontendMap[record.frontendId],
+                                          dvrMap[record.dvrRecordId]);
+    }
 }
 
 TEST_P(TunerRecordAidlTest, LnbRecordDataFlowWithTsRecordFilterTest) {
@@ -885,9 +1140,30 @@
     if (!lnbRecord.support) {
         return;
     }
-    recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId],
-                                  frontendMap[lnbRecord.frontendId], dvrMap[lnbRecord.dvrRecordId],
-                                  lnbMap[lnbRecord.lnbId]);
+    vector<LnbRecordHardwareConnections> lnbRecord_configs = generateLnbRecordConfigurations();
+    if (lnbRecord_configs.empty()) {
+        ALOGD("No frontends that support satellites.");
+        return;
+    }
+    for (auto& configuration : lnbRecord_configs) {
+        lnbRecord = configuration;
+        recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId],
+                                      frontendMap[lnbRecord.frontendId],
+                                      dvrMap[lnbRecord.dvrRecordId], lnbMap[lnbRecord.lnbId]);
+    }
+}
+
+TEST_P(TunerRecordAidlTest, SetStatusCheckIntervalHintToRecordTest) {
+    description("Set status check interval hint to record test.");
+    if (!record.support) {
+        return;
+    }
+    auto record_configs = generateRecordConfigurations();
+    for (auto& configuration : record_configs) {
+        record = configuration;
+        setStatusCheckIntervalHintTest(STATUS_CHECK_INTERVAL_MS, frontendMap[record.frontendId],
+                                       dvrMap[record.dvrRecordId]);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, TuneFrontend) {
@@ -895,7 +1171,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, AutoScanFrontend) {
@@ -903,7 +1183,11 @@
     if (!scan.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO);
+    vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
+    for (auto& configuration : scan_configs) {
+        scan = configuration;
+        mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, BlindScanFrontend) {
@@ -911,7 +1195,15 @@
     if (!scan.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+    vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
+    for (auto& configuration : scan_configs) {
+        scan = configuration;
+        // Skip test if the frontend implementation doesn't support blind scan
+        if (!frontendMap[scan.frontendId].supportBlindScan) {
+            continue;
+        }
+        mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, TuneFrontendWithFrontendSettings) {
@@ -919,7 +1211,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, BlindScanFrontendWithEndFrequency) {
@@ -927,7 +1223,15 @@
     if (!scan.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+    vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
+    for (auto& configuration : scan_configs) {
+        scan = configuration;
+        // Skip test if the frontend implementation doesn't support blind scan
+        if (!frontendMap[scan.frontendId].supportBlindScan) {
+            continue;
+        }
+        mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, LinkToCiCam) {
@@ -935,10 +1239,14 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    if (!frontendMap[live.frontendId].canConnectToCiCam) {
-        return;
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        if (!frontendMap[live.frontendId].canConnectToCiCam) {
+            continue;
+        }
+        mFrontendTests.tuneTest(frontendMap[live.frontendId]);
     }
-    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerFrontendAidlTest, getHardwareInfo) {
@@ -946,7 +1254,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.debugInfoTest(frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mFrontendTests.debugInfoTest(frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, maxNumberOfFrontends) {
@@ -962,7 +1274,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.statusReadinessTest(frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mFrontendTests.statusReadinessTest(frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowVideoFilterTest) {
@@ -970,7 +1286,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowAudioFilterTest) {
@@ -978,7 +1298,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowSectionFilterTest) {
@@ -986,10 +1310,14 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    if (live.sectionFilterId.compare(emptyHardwareId) == 0) {
-        return;
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        if (live.sectionFilterId.compare(emptyHardwareId) == 0) {
+            continue;
+        }
+        broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]);
     }
-    broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerBroadcastAidlTest, IonBufferTest) {
@@ -997,7 +1325,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, LnbBroadcastDataFlowVideoFilterTest) {
@@ -1005,8 +1337,16 @@
     if (!lnbLive.support) {
         return;
     }
-    broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId],
-                                     frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]);
+    vector<LnbLiveHardwareConnections> lnbLive_configs = generateLnbLiveConfigurations();
+    if (lnbLive_configs.empty()) {
+        ALOGD("No frontends that support satellites.");
+        return;
+    }
+    for (auto& combination : lnbLive_configs) {
+        lnbLive = combination;
+        broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId],
+                                         frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, MediaFilterWithSharedMemoryHandle) {
@@ -1014,7 +1354,12 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId],
+                                         frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerDescramblerAidlTest, CreateDescrambler) {
@@ -1022,25 +1367,34 @@
     if (!descrambling.support) {
         return;
     }
-    int32_t demuxId;
-    std::shared_ptr<IDemux> demux;
-    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
-
-    if (descrambling.hasFrontendConnection) {
-        int32_t feId;
-        mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId);
-        ASSERT_TRUE(feId != INVALID_ID);
-        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
-        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    vector<DescramblingHardwareConnections> descrambling_configs =
+            generateDescramblingConfigurations();
+    if (descrambling_configs.empty()) {
+        ALOGD("No valid descrambling combinations in the configuration file.");
+        return;
     }
+    for (auto& combination : descrambling_configs) {
+        descrambling = combination;
+        int32_t demuxId;
+        std::shared_ptr<IDemux> demux;
+        ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
 
-    ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId));
-    ASSERT_TRUE(mDescramblerTests.closeDescrambler());
-    ASSERT_TRUE(mDemuxTests.closeDemux());
+        if (descrambling.hasFrontendConnection) {
+            int32_t feId;
+            mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId);
+            ASSERT_TRUE(feId != INVALID_ID);
+            ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+            ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+            ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+        }
 
-    if (descrambling.hasFrontendConnection) {
-        ASSERT_TRUE(mFrontendTests.closeFrontend());
+        ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId));
+        ASSERT_TRUE(mDescramblerTests.closeDescrambler());
+        ASSERT_TRUE(mDemuxTests.closeDemux());
+
+        if (descrambling.hasFrontendConnection) {
+            ASSERT_TRUE(mFrontendTests.closeFrontend());
+        }
     }
 }
 
@@ -1049,11 +1403,42 @@
     if (!descrambling.support) {
         return;
     }
-    set<FilterConfig> filterConfs;
-    filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.audioFilterId]));
-    filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.videoFilterId]));
-    scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId],
-                           descramblerMap[descrambling.descramblerId]);
+    vector<DescramblingHardwareConnections> descrambling_configs =
+            generateDescramblingConfigurations();
+    if (descrambling_configs.empty()) {
+        ALOGD("No valid descrambling combinations in the configuration file.");
+        return;
+    }
+    for (auto& combination : descrambling_configs) {
+        descrambling = combination;
+        set<FilterConfig> filterConfs;
+        filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.audioFilterId]));
+        filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.videoFilterId]));
+        scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId],
+                               descramblerMap[descrambling.descramblerId],
+                               Dataflow_Context::DESCRAMBLING);
+    }
+}
+
+TEST_P(TunerDescramblerAidlTest, ScrambledBroadcastDataFlowMediaFiltersTestWithLnb) {
+    description("Test media filters in scrambled broadcast use case with Lnb");
+    if (!lnbDescrambling.support) {
+        return;
+    }
+    auto lnbDescrambling_configs = generateLnbDescramblingConfigurations();
+    if (lnbDescrambling_configs.empty()) {
+        ALOGD("No frontends that support satellites.");
+        return;
+    }
+    for (auto& configuration : lnbDescrambling_configs) {
+        lnbDescrambling = configuration;
+        set<FilterConfig> filterConfs;
+        filterConfs.insert(static_cast<FilterConfig>(filterMap[lnbDescrambling.audioFilterId]));
+        filterConfs.insert(static_cast<FilterConfig>(filterMap[lnbDescrambling.videoFilterId]));
+        scrambledBroadcastTestWithLnb(filterConfs, frontendMap[lnbDescrambling.frontendId],
+                                      descramblerMap[lnbDescrambling.descramblerId],
+                                      lnbMap[lnbDescrambling.lnbId]);
+    }
 }
 
 INSTANTIATE_TEST_SUITE_P(PerInstance, TunerBroadcastAidlTest,
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
index 7f80d90..8ad6ee0 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -36,11 +36,17 @@
     initFrontendConfig();
     initFilterConfig();
     initDvrConfig();
+    initTimeFilterConfig();
+    initDescramblerConfig();
+    initLnbConfig();
+    initDiseqcMsgsConfig();
     connectHardwaresToTestCases();
     if (!validateConnections()) {
         ALOGW("[vts] failed to validate connections.");
         return false;
     }
+    determineDataFlows();
+
     return true;
 }
 
@@ -58,6 +64,24 @@
     return success();
 }
 
+void clearIds() {
+    lnbIds.clear();
+    diseqcMsgs.clear();
+    frontendIds.clear();
+    ipFilterIds.clear();
+    pcrFilterIds.clear();
+    recordDvrIds.clear();
+    timeFilterIds.clear();
+    descramblerIds.clear();
+    audioFilterIds.clear();
+    videoFilterIds.clear();
+    playbackDvrIds.clear();
+    recordFilterIds.clear();
+    sectionFilterIds.clear();
+}
+
+enum class Dataflow_Context { LNBRECORD, RECORD, DESCRAMBLING, LNBDESCRAMBLING };
+
 class TunerLnbAidlTest : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
@@ -73,6 +97,11 @@
         mLnbTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -101,6 +130,11 @@
         mFilterTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -124,13 +158,18 @@
             mService = nullptr;
         }
         ASSERT_NE(mService, nullptr);
-        initConfiguration();
+        ASSERT_TRUE(initConfiguration());
 
         mFrontendTests.setService(mService);
         mDemuxTests.setService(mService);
         mFilterTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -197,6 +236,11 @@
         mDvrTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -211,6 +255,8 @@
     AssertionResult filterDataOutputTest();
 
     void playbackSingleFilterTest(FilterConfig filterConf, DvrConfig dvrConf);
+
+    void setStatusCheckIntervalHintTest(int64_t milliseconds, DvrConfig dvrConf);
 };
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerPlaybackAidlTest);
@@ -225,7 +271,7 @@
             mService = nullptr;
         }
         ASSERT_NE(mService, nullptr);
-        initConfiguration();
+        ASSERT_TRUE(initConfiguration());
 
         mFrontendTests.setService(mService);
         mDemuxTests.setService(mService);
@@ -234,6 +280,11 @@
         mLnbTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -244,7 +295,9 @@
     void recordSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf,
                                        DvrConfig dvrConf, LnbConfig lnbConf);
     void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf,
-                                DvrConfig dvrConf);
+                                DvrConfig dvrConf, Dataflow_Context context);
+    void setStatusCheckIntervalHintTest(int64_t milliseconds, FrontendConfig frontendConf,
+                                        DvrConfig dvrConf);
 
     std::shared_ptr<ITuner> mService;
     FrontendTests mFrontendTests;
@@ -254,7 +307,7 @@
     LnbTests mLnbTests;
 
   private:
-    int32_t* mLnbId = nullptr;
+    int32_t mLnbId = INVALID_LNB_ID;
 };
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerRecordAidlTest);
@@ -269,11 +322,16 @@
             mService = nullptr;
         }
         ASSERT_NE(mService, nullptr);
-        initConfiguration();
+        ASSERT_TRUE(initConfiguration());
 
         mFrontendTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -295,7 +353,7 @@
             mService = nullptr;
         }
         ASSERT_NE(mService, nullptr);
-        initConfiguration();
+        ASSERT_TRUE(initConfiguration());
 
         mFrontendTests.setService(mService);
         mDemuxTests.setService(mService);
@@ -304,6 +362,11 @@
         mDvrTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -324,7 +387,7 @@
     void mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf);
 
   private:
-    int32_t* mLnbId = nullptr;
+    int32_t mLnbId = INVALID_LNB_ID;
 };
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerBroadcastAidlTest);
@@ -338,16 +401,37 @@
         } else {
             mService = nullptr;
         }
-        mCasService = IMediaCasService::getService();
         ASSERT_NE(mService, nullptr);
-        ASSERT_NE(mCasService, nullptr);
+
+        // Get IMediaCasService. Try getting AIDL service first, if AIDL does not exist, try HIDL.
+        if (AServiceManager_isDeclared(MEDIA_CAS_AIDL_SERVICE_NAME.c_str())) {
+            ::ndk::SpAIBinder binder(
+                    AServiceManager_waitForService(MEDIA_CAS_AIDL_SERVICE_NAME.c_str()));
+            mCasServiceAidl = IMediaCasServiceAidl::fromBinder(binder);
+        } else {
+            mCasServiceAidl = nullptr;
+        }
+        if (mCasServiceAidl == nullptr) {
+            mCasServiceHidl = IMediaCasServiceHidl::getService();
+        }
+        ASSERT_TRUE(mCasServiceAidl != nullptr || mCasServiceHidl != nullptr);
         ASSERT_TRUE(initConfiguration());
 
         mFrontendTests.setService(mService);
         mDemuxTests.setService(mService);
         mDvrTests.setService(mService);
         mDescramblerTests.setService(mService);
-        mDescramblerTests.setCasService(mCasService);
+        if (mCasServiceAidl != nullptr) {
+            mDescramblerTests.setCasServiceAidl(mCasServiceAidl);
+        } else {
+            mDescramblerTests.setCasServiceHidl(mCasServiceHidl);
+        }
+        mLnbTests.setService(mService);
+    }
+
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
     }
 
   protected:
@@ -356,16 +440,25 @@
     }
 
     void scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
-                                FrontendConfig frontendConf, DescramblerConfig descConfig);
+                                FrontendConfig frontendConf, DescramblerConfig descConfig,
+                                Dataflow_Context context);
+    void scrambledBroadcastTestWithLnb(set<struct FilterConfig>& mediaFilterConfs,
+                                       FrontendConfig& frontendConf, DescramblerConfig& descConfig,
+                                       LnbConfig& lnbConfig);
     AssertionResult filterDataOutputTest();
 
     std::shared_ptr<ITuner> mService;
-    android::sp<IMediaCasService> mCasService;
+    sp<IMediaCasServiceHidl> mCasServiceHidl;
+    std::shared_ptr<IMediaCasServiceAidl> mCasServiceAidl;
     FrontendTests mFrontendTests;
     DemuxTests mDemuxTests;
     FilterTests mFilterTests;
     DescramblerTests mDescramblerTests;
     DvrTests mDvrTests;
+    LnbTests mLnbTests;
+
+  private:
+    int32_t mLnbId = INVALID_LNB_ID;
 };
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDescramblerAidlTest);
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index 5f1f9c5..ff94639 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -55,6 +55,7 @@
 const string configFilePath = "/vendor/etc/tuner_vts_config_aidl_V1.xml";
 
 #define FILTER_MAIN_TYPE_BIT_COUNT 5
+#define STATUS_CHECK_INTERVAL_MS 100L
 
 // Hardware configs
 static map<string, FrontendConfig> frontendMap;
@@ -74,6 +75,512 @@
 static LnbLiveHardwareConnections lnbLive;
 static LnbRecordHardwareConnections lnbRecord;
 static TimeFilterHardwareConnections timeFilter;
+static LnbDescramblingHardwareConnections lnbDescrambling;
+
+/*
+ * This function takes in a 2d vector of device Id's
+ * The n vectors correlate to the ids for n different devices (eg frontends, filters)
+ * The resultant 2d vector is every combination of id's with 1 id from each vector
+ */
+inline vector<vector<string>> generateIdCombinations(vector<vector<string>>& ids) {
+    vector<vector<string>> combinations;
+
+    // The index of each vector in ids that will be used in the next combination
+    // EG {0, 2} means combo {ids[0][0] ids[1][2]} will be next
+    const int size = static_cast<int>(ids.size());
+    vector<int> indexes_used_in_combination(size, 0);
+
+    // The vector number from ids whose elements we will cycle through to make combinations.
+    // First, start at the right most vector
+    int cycled_vector = size - 1;
+
+    while (cycled_vector >= 0) {
+        // Make a combination (one at a time)
+        vector<string> combo;
+        for (size_t i = 0; i < indexes_used_in_combination.size(); ++i) {
+            const int combo_index = indexes_used_in_combination[i];
+            combo.push_back(ids[i][combo_index]);
+        }
+        combinations.push_back(combo);
+
+        // Find the right most vector that still has space [elements left] to cycle through and
+        // create a combination
+        while (cycled_vector >= 0 &&
+               indexes_used_in_combination[cycled_vector] == ids[cycled_vector].size() - 1) {
+            cycled_vector--;
+        }
+
+        // Use this check to avoid segmentation faults
+        if (cycled_vector >= 0) {
+            // Once found, we have a vector we can cycle through, so increase to its next element
+            indexes_used_in_combination[cycled_vector]++;
+
+            // Reset the other vectors to the right to their first element so we can cycle through
+            // them again with the new element from cycled vector
+            for (size_t i = cycled_vector + 1; i < indexes_used_in_combination.size(); ++i) {
+                indexes_used_in_combination[i] = 0;
+            }
+
+            // all the vectors to the right were reset, so we can cycle through them again
+            // Start at the furthest right vector
+            cycled_vector = size - 1;
+        }
+    }
+
+    return combinations;
+}
+
+/*
+ * index 0 - playback dvr
+ * index 1 - audio filters
+ * index 2 - optional section filters
+ */
+static inline vector<DvrPlaybackHardwareConnections> generatePlaybackCombinations() {
+    vector<DvrPlaybackHardwareConnections> combinations;
+    vector<string> sectionFilterIds_optional = sectionFilterIds;
+    sectionFilterIds_optional.push_back(emptyHardwareId);
+    vector<vector<string>> deviceIds{playbackDvrIds, audioFilterIds, sectionFilterIds_optional};
+
+    const int dvrIndex = 0;
+    const int audioFilterIndex = 1;
+    const int sectionFilterIndex = 2;
+
+    auto idCombinations = generateIdCombinations(deviceIds);
+    for (auto& combo : idCombinations) {
+        DvrPlaybackHardwareConnections mPlayback;
+        mPlayback.dvrId = combo[dvrIndex];
+        mPlayback.audioFilterId = combo[audioFilterIndex];
+        mPlayback.sectionFilterId = combo[sectionFilterIndex];
+        const int videoFilterIndex =
+                find(audioFilterIds.begin(), audioFilterIds.end(), mPlayback.audioFilterId) -
+                audioFilterIds.begin();
+        mPlayback.videoFilterId = videoFilterIds[videoFilterIndex];
+        combinations.push_back(mPlayback);
+    }
+
+    return combinations;
+}
+
+static inline vector<DvrPlaybackHardwareConnections> generatePlaybackConfigs() {
+    vector<DvrPlaybackHardwareConnections> playback_configs;
+    if (configuredPlayback) {
+        ALOGD("Using DVR playback configuration provided.");
+        playback_configs = {playback};
+    } else {
+        ALOGD("Dvr playback not provided. Generating possible combinations. Consider adding it to "
+              "the configuration file.");
+        playback_configs = generatePlaybackCombinations();
+    }
+
+    return playback_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - audio filters
+ * index 2 - lnbs
+ */
+static inline vector<LnbLiveHardwareConnections> generateLnbLiveCombinations() {
+    vector<LnbLiveHardwareConnections> combinations;
+    vector<vector<string>> deviceIds{frontendIds, audioFilterIds, lnbIds};
+
+    const int frontendIndex = 0;
+    const int audioFilterIndex = 1;
+    const int lnbIndex = 2;
+
+    // TODO: Find a better way to vary diseqcMsgs, if at all
+    auto idCombinations = generateIdCombinations(deviceIds);
+    for (auto& combo : idCombinations) {
+        const string feId = combo[frontendIndex];
+        auto type = frontendMap[feId].type;
+        if (type == FrontendType::DVBS || type == FrontendType::ISDBS ||
+            type == FrontendType::ISDBS3) {
+            LnbLiveHardwareConnections mLnbLive;
+            mLnbLive.frontendId = feId;
+            mLnbLive.audioFilterId = combo[audioFilterIndex];
+            const int videoFilterIndex =
+                    find(audioFilterIds.begin(), audioFilterIds.end(), mLnbLive.audioFilterId) -
+                    audioFilterIds.begin();
+            mLnbLive.videoFilterId = videoFilterIds[videoFilterIndex];
+            mLnbLive.lnbId = combo[lnbIndex];
+            mLnbLive.diseqcMsgs = diseqcMsgs;
+            combinations.push_back(mLnbLive);
+        }
+    }
+
+    return combinations;
+}
+
+static inline vector<LnbLiveHardwareConnections> generateLnbLiveConfigurations() {
+    vector<LnbLiveHardwareConnections> lnbLive_configs;
+    if (configuredLnbLive) {
+        ALOGD("Using LnbLive configuration provided.");
+        lnbLive_configs = {lnbLive};
+    } else {
+        ALOGD("LnbLive not provided. Generating possible combinations. Consider adding it to the "
+              "configuration file.");
+        lnbLive_configs = generateLnbLiveCombinations();
+    }
+
+    return lnbLive_configs;
+}
+
+static inline vector<ScanHardwareConnections> generateScanCombinations() {
+    vector<ScanHardwareConnections> combinations;
+
+    for (auto& id : frontendIds) {
+        ScanHardwareConnections mScan;
+        mScan.frontendId = id;
+        combinations.push_back(mScan);
+    }
+
+    return combinations;
+}
+
+static inline vector<ScanHardwareConnections> generateScanConfigurations() {
+    vector<ScanHardwareConnections> scan_configs;
+    if (configuredScan) {
+        ALOGD("Using scan configuration provided.");
+        scan_configs = {scan};
+    } else {
+        ALOGD("Scan not provided. Generating possible combinations. Consider adding it to "
+              "the configuration file.");
+        scan_configs = generateScanCombinations();
+    }
+
+    return scan_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - record filter
+ * index 2 - Record Dvr
+ * index 3 - Lnb
+ */
+static inline vector<LnbRecordHardwareConnections> generateLnbRecordCombinations() {
+    vector<LnbRecordHardwareConnections> combinations;
+    vector<vector<string>> deviceIds{frontendIds, recordFilterIds, recordDvrIds, lnbIds};
+
+    const int frontendIndex = 0;
+    const int recordFilterIndex = 1;
+    const int dvrIndex = 2;
+    const int lnbIndex = 3;
+
+    auto idCombinations = generateIdCombinations(deviceIds);
+    // TODO : Find a better way to vary diseqcMsgs, if at all
+    for (auto& combo : idCombinations) {
+        const string feId = combo[frontendIndex];
+        auto type = frontendMap[feId].type;
+        if (type == FrontendType::DVBS || type == FrontendType::ISDBS ||
+            type == FrontendType::ISDBS3) {
+            LnbRecordHardwareConnections mLnbRecord;
+            mLnbRecord.frontendId = feId;
+            mLnbRecord.recordFilterId = combo[recordFilterIndex];
+            mLnbRecord.dvrRecordId = combo[dvrIndex];
+            mLnbRecord.lnbId = combo[lnbIndex];
+            mLnbRecord.diseqcMsgs = diseqcMsgs;
+            combinations.push_back(mLnbRecord);
+        }
+    }
+
+    return combinations;
+}
+
+static inline vector<LnbRecordHardwareConnections> generateLnbRecordConfigurations() {
+    vector<LnbRecordHardwareConnections> lnbRecord_configs;
+    if (configuredLnbRecord) {
+        ALOGD("Using LnbRecord configuration provided.");
+        lnbRecord_configs = {lnbRecord};
+    } else {
+        ALOGD("LnbRecord not provided. Generating possible combinations. Consider adding it to "
+              "the configuration file.");
+        lnbRecord_configs = generateLnbRecordCombinations();
+    }
+
+    return lnbRecord_configs;
+}
+
+/*
+ * index 0 - decramblers
+ * index 1 - frontends
+ * index 2 - audio filters
+ * index 3 - Dvr SW Fe Connections
+ * index 4 - DVR Source Connections
+ */
+static inline vector<DescramblingHardwareConnections> generateDescramblingCombinations() {
+    vector<DescramblingHardwareConnections> combinations;
+    vector<string> mfrontendIds = frontendIds;
+    vector<string> mDvrFeConnectionIds = playbackDvrIds;
+    vector<string> mDvrSourceConnectionIds = playbackDvrIds;
+
+    // Add the empty hardware id to each vector to include combinations where these 3 fields might
+    // be optional
+    mfrontendIds.push_back(emptyHardwareId);
+    mDvrFeConnectionIds.push_back(emptyHardwareId);
+    mDvrSourceConnectionIds.push_back(emptyHardwareId);
+
+    const int descramblerIndex = 0;
+    const int frontendIndex = 1;
+    const int audioFilterIndex = 2;
+    const int dvrFeIdIndex = 3;
+    const int dvrSourceIdIndex = 4;
+
+    vector<vector<string>> deviceIds{descramblerIds, mfrontendIds, audioFilterIds,
+                                     mDvrFeConnectionIds, mDvrSourceConnectionIds};
+    auto idCombinations = generateIdCombinations(deviceIds);
+    for (auto& combo : idCombinations) {
+        DescramblingHardwareConnections mDescrambling;
+        const string feId = combo[frontendIndex];
+        const string dvrSwFeId = combo[dvrFeIdIndex];
+        const string dvrSourceId = combo[dvrSourceIdIndex];
+        mDescrambling.hasFrontendConnection = feId.compare(emptyHardwareId) == 0 ? false : true;
+        if (!mDescrambling.hasFrontendConnection) {
+            if (dvrSourceId.compare(emptyHardwareId) == 0) {
+                // If combination does not have a frontend or dvr source connection, do not include
+                // it
+                continue;
+            }
+        } else {
+            if (frontendMap[feId].isSoftwareFe && dvrSwFeId.compare(emptyHardwareId) == 0) {
+                // If combination has a software frontend and no dvr->software frontend connection,
+                // do not include it
+                continue;
+            }
+        }
+        if (dvrSwFeId.compare(dvrSourceId) == 0) {
+            // If dvr->software frontend connection is the same as dvr source input to tuner, do not
+            // include it.
+            continue;
+        }
+        mDescrambling.frontendId = feId;
+        mDescrambling.audioFilterId = combo[audioFilterIndex];
+        const int videoFilterIndex =
+                find(audioFilterIds.begin(), audioFilterIds.end(), mDescrambling.audioFilterId) -
+                audioFilterIds.begin();
+        mDescrambling.videoFilterId = videoFilterIds[videoFilterIndex];
+        mDescrambling.dvrSoftwareFeId = dvrSwFeId;
+        mDescrambling.dvrSourceId = dvrSourceId;
+        mDescrambling.descramblerId = combo[descramblerIndex];
+        combinations.push_back(mDescrambling);
+    }
+
+    return combinations;
+}
+
+static inline vector<DescramblingHardwareConnections> generateDescramblingConfigurations() {
+    vector<DescramblingHardwareConnections> descrambling_configs;
+    if (configuredDescrambling) {
+        ALOGD("Using Descrambling configuration provided.");
+        descrambling_configs = {descrambling};
+    } else {
+        ALOGD("Descrambling not provided. Generating possible combinations. Consider adding it to "
+              "the "
+              "configuration file.");
+        descrambling_configs = generateDescramblingCombinations();
+    }
+
+    return descrambling_configs;
+}
+
+static inline vector<TimeFilterHardwareConnections> generateTimeFilterCombinations() {
+    vector<TimeFilterHardwareConnections> combinations;
+
+    for (auto& id : timeFilterIds) {
+        TimeFilterHardwareConnections mTimeFilter;
+        mTimeFilter.timeFilterId = id;
+        combinations.push_back(mTimeFilter);
+    }
+
+    return combinations;
+}
+
+static inline vector<TimeFilterHardwareConnections> generateTimeFilterConfigurations() {
+    vector<TimeFilterHardwareConnections> timeFilter_configs;
+    if (configuredTimeFilter) {
+        ALOGD("Using TimeFilter configuration provided.");
+        timeFilter_configs = {timeFilter};
+    } else {
+        ALOGD("TimeFilter not provided. Generating possible combinations. Consider adding it to "
+              "the "
+              "configuration file.");
+        timeFilter_configs = generateTimeFilterCombinations();
+    }
+
+    return timeFilter_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - record dvrs
+ * index 2 - record filters
+ */
+static inline vector<DvrRecordHardwareConnections> generateRecordCombinations() {
+    vector<DvrRecordHardwareConnections> combinations;
+
+    const int frontendIdIndex = 0;
+    const int recordDvrIndex = 1;
+    const int recordFilterIndex = 2;
+
+    vector<vector<string>> deviceIds{frontendIds, recordDvrIds, recordFilterIds};
+
+    auto idCombinations = generateIdCombinations(deviceIds);
+    for (auto& combo : idCombinations) {
+        DvrRecordHardwareConnections mRecord;
+        const string feId = combo[frontendIdIndex];
+        mRecord.hasFrontendConnection = true;
+        if (frontendMap[feId].isSoftwareFe) {
+            // If we have a software frontend, do not include configuration for testing.
+            continue;
+        }
+        mRecord.frontendId = feId;
+        mRecord.support = true;
+        mRecord.dvrSourceId = emptyHardwareId;
+        mRecord.dvrSoftwareFeId = emptyHardwareId;
+        mRecord.recordFilterId = combo[recordFilterIndex];
+        mRecord.dvrRecordId = combo[recordDvrIndex];
+        combinations.push_back(mRecord);
+    }
+
+    return combinations;
+}
+
+static inline vector<DvrRecordHardwareConnections> generateRecordConfigurations() {
+    vector<DvrRecordHardwareConnections> record_configs;
+    if (configuredRecord) {
+        ALOGD("Using Record configuration provided.");
+        record_configs = {record};
+    } else {
+        ALOGD("Record not provided. Generating possible combinations. Consider adding it to "
+              "the "
+              "configuration file.");
+        record_configs = generateRecordCombinations();
+    }
+
+    return record_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - audio filters
+ * index 2 - playback dvrs
+ * index 3 - section Filters
+ */
+static inline vector<LiveBroadcastHardwareConnections> generateLiveCombinations() {
+    vector<LiveBroadcastHardwareConnections> combinations;
+    vector<string> mSectionFilterIds = sectionFilterIds;
+    vector<string> mDvrSwConnectionIds = playbackDvrIds;
+
+    // Adding the empty hardware id to cover cases where fields are optional
+    mSectionFilterIds.push_back(emptyHardwareId);
+    mDvrSwConnectionIds.push_back(emptyHardwareId);
+
+    const int frontendIdIndex = 0;
+    const int audioFilterIdIndex = 1;
+    const int dvrSwConnectionIdIndex = 2;
+    const int sectionFilterIdIndex = 3;
+
+    vector<vector<string>> deviceIds{frontendIds, audioFilterIds, mDvrSwConnectionIds,
+                                     mSectionFilterIds};
+
+    auto idCombinations = generateIdCombinations(deviceIds);
+    for (auto& combo : idCombinations) {
+        LiveBroadcastHardwareConnections mLive;
+        const string feId = combo[frontendIdIndex];
+        const string dvrSwConnectionId = combo[dvrSwConnectionIdIndex];
+        mLive.hasFrontendConnection = true;
+
+        if (frontendMap[feId].isSoftwareFe && dvrSwConnectionId.compare(emptyHardwareId) == 0) {
+            // If the frontend is a software frontend and there is no dvr playback connected, do not
+            // include configuration
+            continue;
+        }
+        mLive.frontendId = feId;
+        mLive.dvrSoftwareFeId = dvrSwConnectionId;
+        mLive.audioFilterId = combo[audioFilterIdIndex];
+        const int videoFilterIdIndex =
+                find(audioFilterIds.begin(), audioFilterIds.end(), mLive.audioFilterId) -
+                audioFilterIds.begin();
+        mLive.videoFilterId = videoFilterIds[videoFilterIdIndex];
+        mLive.sectionFilterId = combo[sectionFilterIdIndex];
+
+        if (pcrFilterIds.empty()) {
+            // If pcr Filters have not been provided, set it to empty hardware id
+            mLive.pcrFilterId = emptyHardwareId;
+        } else {
+            // If pcr Filters have been provided, use the first index if there is only 1, or choose
+            // the filter that corresponds to the correct audio and video filter pair
+            const int pcrFilterIdIndex = pcrFilterIds.size() == 1 ? 0 : videoFilterIdIndex;
+            mLive.pcrFilterId = pcrFilterIds[pcrFilterIdIndex];
+        }
+
+        combinations.push_back(mLive);
+    }
+
+    return combinations;
+}
+
+static inline vector<LiveBroadcastHardwareConnections> generateLiveConfigurations() {
+    vector<LiveBroadcastHardwareConnections> live_configs;
+    if (configuredLive) {
+        ALOGD("Using Live configuration provided.");
+        live_configs = {live};
+    } else {
+        ALOGD("Live not provided. Generating possible combinations. Consider adding it to "
+              "the "
+              "configuration file.");
+        live_configs = generateLiveCombinations();
+    }
+
+    return live_configs;
+}
+
+static inline vector<LnbDescramblingHardwareConnections> generateLnbDescramblingCombinations() {
+    vector<LnbDescramblingHardwareConnections> combinations;
+    vector<vector<string>> deviceIds{frontendIds, audioFilterIds, lnbIds, descramblerIds};
+
+    const int frontendIdIndex = 0;
+    const int audioFilterIdIndex = 1;
+    const int lnbIdIndex = 2;
+    const int descramblerIdIndex = 3;
+
+    auto idCombinations = generateIdCombinations(deviceIds);
+    // TODO : Find a better way to vary diseqcMsgs, if at all
+    for (auto& combo : idCombinations) {
+        const string feId = combo[frontendIdIndex];
+        auto type = frontendMap[feId].type;
+        if (type == FrontendType::DVBS || type == FrontendType::ISDBS ||
+            type == FrontendType::ISDBS3) {
+            LnbDescramblingHardwareConnections mLnbDescrambling;
+            mLnbDescrambling.support = true;
+            mLnbDescrambling.frontendId = feId;
+            mLnbDescrambling.audioFilterId = combo[audioFilterIdIndex];
+            const int videoFilterIdIndex = find(audioFilterIds.begin(), audioFilterIds.end(),
+                                                mLnbDescrambling.audioFilterId) -
+                                           audioFilterIds.begin();
+            mLnbDescrambling.videoFilterId = videoFilterIds[videoFilterIdIndex];
+            mLnbDescrambling.lnbId = combo[lnbIdIndex];
+            mLnbDescrambling.descramblerId = combo[descramblerIdIndex];
+            mLnbDescrambling.diseqcMsgs = diseqcMsgs;
+            combinations.push_back(mLnbDescrambling);
+        }
+    }
+
+    return combinations;
+}
+
+static inline vector<LnbDescramblingHardwareConnections> generateLnbDescramblingConfigurations() {
+    vector<LnbDescramblingHardwareConnections> lnbDescrambling_configs;
+    if (configuredLnbDescrambling) {
+        ALOGD("Using LnbDescrambling configuration provided");
+        lnbDescrambling_configs = {lnbDescrambling};
+    } else {
+        ALOGD("LnbDescrambling not provided. Generating possible combinations. Consider adding it "
+              "to the configuration file.");
+        lnbDescrambling_configs = generateLnbDescramblingCombinations();
+    }
+
+    return lnbDescrambling_configs;
+}
 
 /** Config all the frontends that would be used in the tests */
 inline void initFrontendConfig() {
@@ -105,6 +612,7 @@
     frontendMap[defaultFeId].isSoftwareFe = true;
     frontendMap[defaultFeId].canConnectToCiCam = true;
     frontendMap[defaultFeId].ciCamId = 0;
+    frontendMap[defaultFeId].supportBlindScan = true;
     FrontendDvbtSettings dvbt;
     dvbt.transmissionMode = FrontendDvbtTransmissionMode::MODE_8K_E;
     frontendMap[defaultFeId].settings.set<FrontendSettings::Tag::dvbt>(dvbt);
@@ -162,13 +670,152 @@
     TunerTestingConfigAidlReader1_0::readDvrConfig1_0(dvrMap);
 };
 
+inline void initTimeFilterConfig() {
+    // Read customized config
+    TunerTestingConfigAidlReader1_0::readTimeFilterConfig1_0(timeFilterMap);
+};
+
+inline void initDescramblerConfig() {
+    // Read customized config
+    TunerTestingConfigAidlReader1_0::readDescramblerConfig1_0(descramblerMap);
+}
+
+inline void initLnbConfig() {
+    // Read customized config
+    TunerTestingConfigAidlReader1_0::readLnbConfig1_0(lnbMap);
+};
+
+inline void initDiseqcMsgsConfig() {
+    // Read customized config
+    TunerTestingConfigAidlReader1_0::readDiseqcMessages(diseqcMsgMap);
+};
+
+inline void determineScan() {
+    if (!frontendMap.empty()) {
+        scan.hasFrontendConnection = true;
+        ALOGD("Can support scan");
+    }
+}
+
+inline void determineTimeFilter() {
+    if (!timeFilterMap.empty()) {
+        timeFilter.support = true;
+        ALOGD("Can support time filter");
+    }
+}
+
+inline void determineDvrPlayback() {
+    if (!playbackDvrIds.empty() && !audioFilterIds.empty() && !videoFilterIds.empty()) {
+        playback.support = true;
+        ALOGD("Can support dvr playback");
+    }
+}
+
+inline void determineLnbLive() {
+    if (!audioFilterIds.empty() && !videoFilterIds.empty() && !frontendMap.empty() &&
+        !lnbMap.empty()) {
+        lnbLive.support = true;
+        ALOGD("Can support lnb live");
+    }
+}
+
+inline void determineLnbRecord() {
+    if (!frontendMap.empty() && !recordFilterIds.empty() && !recordDvrIds.empty() &&
+        !lnbMap.empty()) {
+        lnbRecord.support = true;
+        ALOGD("Can support lnb record");
+    }
+}
+
+inline void determineLive() {
+    if (videoFilterIds.empty() || audioFilterIds.empty() || frontendMap.empty()) {
+        return;
+    }
+    if (!hasHwFe) {
+        if (hasSwFe) {
+            if (dvrMap.empty()) {
+                ALOGD("Cannot configure Live. Only software frontends and no dvr connections.");
+                return;
+            }
+            // Live is available if there is SW FE and some DVR is attached.
+        } else {
+            // We will arrive here because frontendMap won't be empty since
+            // there will be at least a default frontend declared. But the
+            // default frontend doesn't count as "hasSwFe".
+            ALOGD("Cannot configure Live. No frontend declared at all.");
+            return;
+        }
+    }
+    ALOGD("Can support live");
+    live.hasFrontendConnection = true;
+}
+
+inline void determineDescrambling() {
+    if (descramblerMap.empty() || audioFilterIds.empty() || videoFilterIds.empty()) {
+        return;
+    }
+    if (frontendMap.empty() && playbackDvrIds.empty()) {
+        ALOGD("Cannot configure descrambling. No frontends or playback dvr's");
+        return;
+    }
+    if (hasSwFe && !hasHwFe && playbackDvrIds.empty()) {
+        ALOGD("cannot configure descrambling. Only SW frontends and no playback dvr's");
+        return;
+    }
+    ALOGD("Can support descrambling");
+    descrambling.support = true;
+}
+
+inline void determineDvrRecord() {
+    if (recordDvrIds.empty() || recordFilterIds.empty()) {
+        return;
+    }
+    if (frontendMap.empty() && playbackDvrIds.empty()) {
+        ALOGD("Cannot support dvr record. No frontends and no playback dvr's");
+        return;
+    }
+    if (hasSwFe && !hasHwFe && playbackDvrIds.empty()) {
+        ALOGD("Cannot support dvr record. Only SW frontends and no playback dvr's");
+        return;
+    }
+    ALOGD("Can support dvr record.");
+    record.support = true;
+}
+
+inline void determineLnbDescrambling() {
+    if (frontendIds.empty() || audioFilterIds.empty() || videoFilterIds.empty() || lnbIds.empty() ||
+        descramblerIds.empty()) {
+        return;
+    }
+    ALOGD("Can support LnbDescrambling.");
+    lnbDescrambling.support = true;
+}
+
 /** Read the vendor configurations of which hardware to use for each test cases/data flows */
 inline void connectHardwaresToTestCases() {
     TunerTestingConfigAidlReader1_0::connectLiveBroadcast(live);
     TunerTestingConfigAidlReader1_0::connectScan(scan);
     TunerTestingConfigAidlReader1_0::connectDvrRecord(record);
+    TunerTestingConfigAidlReader1_0::connectTimeFilter(timeFilter);
+    TunerTestingConfigAidlReader1_0::connectDescrambling(descrambling);
+    TunerTestingConfigAidlReader1_0::connectLnbLive(lnbLive);
+    TunerTestingConfigAidlReader1_0::connectLnbRecord(lnbRecord);
+    TunerTestingConfigAidlReader1_0::connectDvrPlayback(playback);
+    TunerTestingConfigAidlReader1_0::connectLnbDescrambling(lnbDescrambling);
 };
 
+inline void determineDataFlows() {
+    determineScan();
+    determineTimeFilter();
+    determineDvrPlayback();
+    determineLnbLive();
+    determineLnbRecord();
+    determineLive();
+    determineDescrambling();
+    determineDvrRecord();
+    determineLnbDescrambling();
+}
+
 inline bool validateConnections() {
     if (record.support && !record.hasFrontendConnection &&
         record.dvrSourceId.compare(emptyHardwareId) == 0) {
@@ -183,6 +830,18 @@
     feIsValid &= record.support && record.hasFrontendConnection
                          ? frontendMap.find(record.frontendId) != frontendMap.end()
                          : true;
+    feIsValid &= descrambling.support && descrambling.hasFrontendConnection
+                         ? frontendMap.find(descrambling.frontendId) != frontendMap.end()
+                         : true;
+
+    feIsValid &= lnbLive.support ? frontendMap.find(lnbLive.frontendId) != frontendMap.end() : true;
+
+    feIsValid &=
+            lnbRecord.support ? frontendMap.find(lnbRecord.frontendId) != frontendMap.end() : true;
+
+    feIsValid &= lnbDescrambling.support
+                         ? frontendMap.find(lnbDescrambling.frontendId) != frontendMap.end()
+                         : true;
 
     if (!feIsValid) {
         ALOGW("[vts config] dynamic config fe connection is invalid.");
@@ -204,6 +863,20 @@
         dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end();
     }
 
+    if (descrambling.support) {
+        if (descrambling.hasFrontendConnection) {
+            if (frontendMap[descrambling.frontendId].isSoftwareFe) {
+                dvrIsValid &= dvrMap.find(descrambling.dvrSoftwareFeId) != dvrMap.end();
+            }
+        } else {
+            dvrIsValid &= dvrMap.find(descrambling.dvrSourceId) != dvrMap.end();
+        }
+    }
+
+    dvrIsValid &= lnbRecord.support ? dvrMap.find(lnbRecord.dvrRecordId) != dvrMap.end() : true;
+
+    dvrIsValid &= playback.support ? dvrMap.find(playback.dvrId) != dvrMap.end() : true;
+
     if (!dvrIsValid) {
         ALOGW("[vts config] dynamic config dvr connection is invalid.");
         return false;
@@ -216,10 +889,120 @@
     filterIsValid &=
             record.support ? filterMap.find(record.recordFilterId) != filterMap.end() : true;
 
+    filterIsValid &= descrambling.support
+                             ? filterMap.find(descrambling.videoFilterId) != filterMap.end() &&
+                                       filterMap.find(descrambling.audioFilterId) != filterMap.end()
+                             : true;
+
+    for (auto& filterId : descrambling.extraFilters) {
+        filterIsValid &= filterMap.find(filterId) != filterMap.end();
+    }
+
+    filterIsValid &= lnbLive.support
+                             ? filterMap.find(lnbLive.audioFilterId) != filterMap.end() &&
+                                       filterMap.find(lnbLive.videoFilterId) != filterMap.end()
+                             : true;
+
+    filterIsValid &=
+            lnbRecord.support ? filterMap.find(lnbRecord.recordFilterId) != filterMap.end() : true;
+
+    for (auto& filterId : lnbRecord.extraFilters) {
+        filterIsValid &= filterMap.find(filterId) != filterMap.end();
+    }
+
+    for (auto& filterId : lnbLive.extraFilters) {
+        filterIsValid &= filterMap.find(filterId) != filterMap.end();
+    }
+
+    filterIsValid &= playback.support
+                             ? filterMap.find(playback.audioFilterId) != filterMap.end() &&
+                                       filterMap.find(playback.videoFilterId) != filterMap.end()
+                             : true;
+    filterIsValid &= playback.sectionFilterId.compare(emptyHardwareId) == 0
+                             ? true
+                             : filterMap.find(playback.sectionFilterId) != filterMap.end();
+
+    for (auto& filterId : playback.extraFilters) {
+        filterIsValid &=
+                playback.hasExtraFilters ? filterMap.find(filterId) != filterMap.end() : true;
+    }
+
+    filterIsValid &=
+            lnbDescrambling.support
+                    ? filterMap.find(lnbDescrambling.audioFilterId) != filterMap.end() &&
+                              filterMap.find(lnbDescrambling.videoFilterId) != filterMap.end()
+                    : true;
+
     if (!filterIsValid) {
         ALOGW("[vts config] dynamic config filter connection is invalid.");
         return false;
     }
 
+    if (audioFilterIds.size() != videoFilterIds.size()) {
+        ALOGW("[vts config] the number of audio and video filters should be equal");
+        return false;
+    }
+
+    if (!pcrFilterIds.empty() && pcrFilterIds.size() != 1 &&
+        pcrFilterIds.size() != audioFilterIds.size()) {
+        ALOGW("[vts config] When more than 1 pcr filter is configured, the number of pcr filters "
+              "must equal the number of audio and video filters.");
+        return false;
+    }
+
+    bool timeFilterIsValid =
+            timeFilter.support ? timeFilterMap.find(timeFilter.timeFilterId) != timeFilterMap.end()
+                               : true;
+
+    if (!timeFilterIsValid) {
+        ALOGW("[vts config] dynamic config time filter connection is invalid.");
+    }
+
+    bool descramblerIsValid =
+            descrambling.support
+                    ? descramblerMap.find(descrambling.descramblerId) != descramblerMap.end()
+                    : true;
+
+    descramblerIsValid &=
+            lnbDescrambling.support
+                    ? descramblerMap.find(lnbDescrambling.descramblerId) != descramblerMap.end()
+                    : true;
+
+    if (!descramblerIsValid) {
+        ALOGW("[vts config] dynamic config descrambler connection is invalid.");
+        return false;
+    }
+
+    bool lnbIsValid = lnbLive.support ? lnbMap.find(lnbLive.lnbId) != lnbMap.end() : true;
+
+    lnbIsValid &= lnbRecord.support ? lnbMap.find(lnbRecord.lnbId) != lnbMap.end() : true;
+
+    lnbIsValid &=
+            lnbDescrambling.support ? lnbMap.find(lnbDescrambling.lnbId) != lnbMap.end() : true;
+
+    if (!lnbIsValid) {
+        ALOGW("[vts config] dynamic config lnb connection is invalid.");
+        return false;
+    }
+
+    bool diseqcMsgsIsValid = true;
+
+    for (auto& msg : lnbRecord.diseqcMsgs) {
+        diseqcMsgsIsValid &= diseqcMsgMap.find(msg) != diseqcMsgMap.end();
+    }
+
+    for (auto& msg : lnbLive.diseqcMsgs) {
+        diseqcMsgsIsValid &= diseqcMsgMap.find(msg) != diseqcMsgMap.end();
+    }
+
+    for (auto& msg : lnbDescrambling.diseqcMsgs) {
+        diseqcMsgsIsValid &= diseqcMsgMap.find(msg) != diseqcMsgMap.end();
+    }
+
+    if (!diseqcMsgsIsValid) {
+        ALOGW("[vts config] dynamic config diseqcMsg is invalid.");
+        return false;
+    }
+
     return true;
 }
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 189f5fd..5ffb38f 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -62,10 +62,37 @@
 using namespace aidl::android::hardware::tv::tuner;
 using namespace android::media::tuner::testing::configuration::V1_0;
 
+static bool hasHwFe = false;
+static bool hasSwFe = false;
+static bool configFileRead = false;
+static bool configuredLive = false;
+static bool configuredScan = false;
+static bool configuredRecord = false;
+static bool configuredLnbLive = false;
+static bool configuredPlayback = false;
+static bool configuredLnbRecord = false;
+static bool configuredTimeFilter = false;
+static bool configuredDescrambling = false;
+static bool configuredLnbDescrambling = false;
+
 const string emptyHardwareId = "";
 
 static string mConfigFilePath;
 
+static vector<string> playbackDvrIds;
+static vector<string> ipFilterIds;
+static vector<string> recordDvrIds;
+static vector<string> pcrFilterIds;
+static vector<string> timeFilterIds;
+static vector<string> audioFilterIds;
+static vector<string> videoFilterIds;
+static vector<string> recordFilterIds;
+static vector<string> sectionFilterIds;
+static vector<string> frontendIds;
+static vector<string> lnbIds;
+static vector<string> diseqcMsgs;
+static vector<string> descramblerIds;
+
 #define PROVISION_STR                                      \
     "{                                                   " \
     "  \"id\": 21140844,                                 " \
@@ -87,6 +114,7 @@
     FrontendSettings settings;
     vector<FrontendStatusType> tuneStatusTypes;
     vector<FrontendStatus> expectTuneStatuses;
+    bool supportBlindScan;
 };
 
 struct FilterConfig {
@@ -137,6 +165,7 @@
     string ipFilterId;
     string pcrFilterId;
     /* list string of extra filters; */
+    vector<string> extraFilters;
 };
 
 struct ScanHardwareConnections {
@@ -146,12 +175,13 @@
 
 struct DvrPlaybackHardwareConnections {
     bool support;
+    bool hasExtraFilters = false;
     string frontendId;
     string dvrId;
     string audioFilterId;
     string videoFilterId;
     string sectionFilterId;
-    /* list string of extra filters; */
+    vector<string> extraFilters;
 };
 
 struct DvrRecordHardwareConnections {
@@ -173,7 +203,7 @@
     string videoFilterId;
     string descramblerId;
     string dvrSourceId;
-    /* list string of extra filters; */
+    vector<string> extraFilters;
 };
 
 struct LnbLiveHardwareConnections {
@@ -183,7 +213,7 @@
     string videoFilterId;
     string lnbId;
     vector<string> diseqcMsgs;
-    /* list string of extra filters; */
+    vector<string> extraFilters;
 };
 
 struct LnbRecordHardwareConnections {
@@ -193,7 +223,7 @@
     string recordFilterId;
     string lnbId;
     vector<string> diseqcMsgs;
-    /* list string of extra filters; */
+    vector<string> extraFilters;
 };
 
 struct TimeFilterHardwareConnections {
@@ -201,6 +231,16 @@
     string timeFilterId;
 };
 
+struct LnbDescramblingHardwareConnections {
+    bool support;
+    string frontendId;
+    string audioFilterId;
+    string videoFilterId;
+    string lnbId;
+    string descramblerId;
+    vector<string> diseqcMsgs;
+};
+
 struct TunerTestingConfigAidlReader1_0 {
   public:
     static void setConfigFilePath(string path) { mConfigFilePath = path; }
@@ -248,6 +288,7 @@
             auto frontends = *hardwareConfig.getFirstFrontends();
             for (auto feConfig : frontends.getFrontend()) {
                 string id = feConfig.getId();
+                frontendIds.push_back(id);
                 if (id.compare(string("FE_DEFAULT")) == 0) {
                     // overrid default
                     frontendMap.erase(string("FE_DEFAULT"));
@@ -263,6 +304,9 @@
                         break;
                     case FrontendTypeEnum::ATSC:
                         type = FrontendType::ATSC;
+                        frontendMap[id].settings.set<
+                            FrontendSettings::Tag::atsc>(
+                                readAtscFrontendSettings(feConfig));
                         break;
                     case FrontendTypeEnum::ATSC3:
                         type = FrontendType::ATSC3;
@@ -283,12 +327,16 @@
                     }
                     case FrontendTypeEnum::ISDBS:
                         type = FrontendType::ISDBS;
+                        frontendMap[id].settings.set<FrontendSettings::Tag::isdbs>(
+                                readIsdbsFrontendSettings(feConfig));
                         break;
                     case FrontendTypeEnum::ISDBS3:
                         type = FrontendType::ISDBS3;
                         break;
                     case FrontendTypeEnum::ISDBT:
                         type = FrontendType::ISDBT;
+                        frontendMap[id].settings.set<FrontendSettings::Tag::isdbt>(
+                                readIsdbtFrontendSettings(feConfig));
                         break;
                     case FrontendTypeEnum::DTMB:
                         type = FrontendType::DTMB;
@@ -302,6 +350,16 @@
                 }
                 frontendMap[id].type = type;
                 frontendMap[id].isSoftwareFe = feConfig.getIsSoftwareFrontend();
+                if (frontendMap[id].isSoftwareFe) {
+                    hasSwFe = true;
+                } else {
+                    hasHwFe = true;
+                }
+                if (feConfig.hasSupportBlindScan()) {
+                    frontendMap[id].supportBlindScan = feConfig.getSupportBlindScan();
+                } else {
+                    frontendMap[id].supportBlindScan = true;
+                }
                 // TODO: b/182519645 complete the tune status config
                 frontendMap[id].tuneStatusTypes = types;
                 frontendMap[id].expectTuneStatuses = statuses;
@@ -376,11 +434,13 @@
                 DvrType type;
                 switch (dvrConfig.getType()) {
                     case DvrTypeEnum::PLAYBACK:
+                        playbackDvrIds.push_back(id);
                         type = DvrType::PLAYBACK;
                         dvrMap[id].settings.set<DvrSettings::Tag::playback>(
                                 readPlaybackSettings(dvrConfig));
                         break;
                     case DvrTypeEnum::RECORD:
+                        recordDvrIds.push_back(id);
                         type = DvrType::RECORD;
                         dvrMap[id].settings.set<DvrSettings::Tag::record>(
                                 readRecordSettings(dvrConfig));
@@ -404,6 +464,7 @@
             auto lnbs = *hardwareConfig.getFirstLnbs();
             for (auto lnbConfig : lnbs.getLnb()) {
                 string id = lnbConfig.getId();
+                lnbIds.push_back(id);
                 if (lnbConfig.hasName()) {
                     lnbMap[id].name = lnbConfig.getName();
                 } else {
@@ -422,6 +483,7 @@
             auto descramblers = *hardwareConfig.getFirstDescramblers();
             for (auto descramblerConfig : descramblers.getDescrambler()) {
                 string id = descramblerConfig.getId();
+                descramblerIds.push_back(id);
                 descramblerMap[id].casSystemId =
                         static_cast<int32_t>(descramblerConfig.getCasSystemId());
                 if (descramblerConfig.hasProvisionStr()) {
@@ -447,6 +509,7 @@
             auto msgs = *hardwareConfig.getFirstDiseqcMessages();
             for (auto msgConfig : msgs.getDiseqcMessage()) {
                 string name = msgConfig.getMsgName();
+                diseqcMsgs.push_back(name);
                 for (uint8_t atom : msgConfig.getMsgBody()) {
                     diseqcMsgMap[name].push_back(atom);
                 }
@@ -460,6 +523,7 @@
             auto timeFilters = *hardwareConfig.getFirstTimeFilters();
             for (auto timeFilterConfig : timeFilters.getTimeFilter()) {
                 string id = timeFilterConfig.getId();
+                timeFilterIds.push_back(id);
                 timeFilterMap[id].timeStamp = static_cast<int64_t>(timeFilterConfig.getTimeStamp());
             }
         }
@@ -469,6 +533,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasClearLiveBroadcast()) {
             live.hasFrontendConnection = true;
+            configuredLive = true;
         } else {
             live.hasFrontendConnection = false;
             return;
@@ -496,12 +561,17 @@
         } else {
             live.ipFilterId = emptyHardwareId;
         }
+        if (liveConfig.hasOptionalFilters()) {
+            auto optionalFilters = liveConfig.getOptionalFilters();
+            live.extraFilters = optionalFilters;
+        }
     }
 
     static void connectScan(ScanHardwareConnections& scan) {
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasScan()) {
             scan.hasFrontendConnection = true;
+            configuredScan = true;
         } else {
             scan.hasFrontendConnection = false;
             return;
@@ -514,6 +584,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasDvrPlayback()) {
             playback.support = true;
+            configuredPlayback = true;
         } else {
             playback.support = false;
             return;
@@ -527,12 +598,17 @@
         } else {
             playback.sectionFilterId = emptyHardwareId;
         }
+        if (playbackConfig.hasOptionalFilters()) {
+            auto optionalFilters = playbackConfig.getOptionalFilters();
+            playback.extraFilters = optionalFilters;
+        }
     }
 
     static void connectDvrRecord(DvrRecordHardwareConnections& record) {
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasDvrRecord()) {
             record.support = true;
+            configuredRecord = true;
         } else {
             record.support = false;
             return;
@@ -557,6 +633,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasDescrambling()) {
             descrambling.support = true;
+            configuredDescrambling = true;
         } else {
             descrambling.support = false;
             return;
@@ -576,12 +653,17 @@
             descrambling.hasFrontendConnection = false;
             descrambling.dvrSourceId = descConfig.getDvrSourceConnection();
         }
+        if (descConfig.hasOptionalFilters()) {
+            auto optionalFilters = descConfig.getOptionalFilters();
+            descrambling.extraFilters = optionalFilters;
+        }
     }
 
     static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) {
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasLnbLive()) {
             lnbLive.support = true;
+            configuredLnbLive = true;
         } else {
             lnbLive.support = false;
             return;
@@ -596,12 +678,17 @@
                 lnbLive.diseqcMsgs.push_back(msgName);
             }
         }
+        if (lnbLiveConfig.hasOptionalFilters()) {
+            auto optionalFilters = lnbLiveConfig.getOptionalFilters();
+            lnbLive.extraFilters = optionalFilters;
+        }
     }
 
     static void connectLnbRecord(LnbRecordHardwareConnections& lnbRecord) {
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasLnbRecord()) {
             lnbRecord.support = true;
+            configuredLnbRecord = true;
         } else {
             lnbRecord.support = false;
             return;
@@ -616,12 +703,17 @@
                 lnbRecord.diseqcMsgs.push_back(msgName);
             }
         }
+        if (lnbRecordConfig.hasOptionalFilters()) {
+            auto optionalFilters = lnbRecordConfig.getOptionalFilters();
+            lnbRecord.extraFilters = optionalFilters;
+        }
     }
 
     static void connectTimeFilter(TimeFilterHardwareConnections& timeFilter) {
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasTimeFilter()) {
             timeFilter.support = true;
+            configuredTimeFilter = true;
         } else {
             timeFilter.support = false;
             return;
@@ -630,6 +722,28 @@
         timeFilter.timeFilterId = timeFilterConfig.getTimeFilterConnection();
     }
 
+    static void connectLnbDescrambling(LnbDescramblingHardwareConnections& lnbDescrambling) {
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasLnbDescrambling()) {
+            lnbDescrambling.support = true;
+            configuredLnbDescrambling = true;
+        } else {
+            lnbDescrambling.support = false;
+            return;
+        }
+        auto lnbDescramblingConfig = *dataFlow.getFirstLnbDescrambling();
+        lnbDescrambling.frontendId = lnbDescramblingConfig.getFrontendConnection();
+        lnbDescrambling.audioFilterId = lnbDescramblingConfig.getAudioFilterConnection();
+        lnbDescrambling.videoFilterId = lnbDescramblingConfig.getVideoFilterConnection();
+        lnbDescrambling.lnbId = lnbDescramblingConfig.getLnbConnection();
+        lnbDescrambling.descramblerId = lnbDescramblingConfig.getDescramblerConnection();
+        if (lnbDescramblingConfig.hasDiseqcMsgSender()) {
+            for (auto& msgName : lnbDescramblingConfig.getDiseqcMsgSender()) {
+                lnbDescrambling.diseqcMsgs.push_back(msgName);
+            }
+        }
+    }
+
   private:
     static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) {
         ALOGW("[ConfigReader] fe type is dvbt");
@@ -677,25 +791,115 @@
             ALOGW("[ConfigReader] no more dvbs settings");
             return dvbsSettings;
         }
-        dvbsSettings.symbolRate = static_cast<int32_t>(
-                feConfig.getFirstDvbsFrontendSettings_optional()->getSymbolRate());
-        dvbsSettings.inputStreamId = static_cast<int32_t>(
-                feConfig.getFirstDvbsFrontendSettings_optional()->getInputStreamId());
         auto dvbs = feConfig.getFirstDvbsFrontendSettings_optional();
-        if (dvbs->hasScanType()) {
-            dvbsSettings.scanType = static_cast<FrontendDvbsScanType>(dvbs->getScanType());
-        }
-        if (dvbs->hasIsDiseqcRxMessage()) {
-            dvbsSettings.isDiseqcRxMessage = dvbs->getIsDiseqcRxMessage();
-        }
+        dvbsSettings.symbolRate = static_cast<int32_t>(dvbs->getSymbolRate());
+        dvbsSettings.inputStreamId = static_cast<int32_t>(dvbs->getInputStreamId());
+        dvbsSettings.scanType = static_cast<FrontendDvbsScanType>(dvbs->getScanType());
+        dvbsSettings.isDiseqcRxMessage = dvbs->getIsDiseqcRxMessage();
+        dvbsSettings.inversion = static_cast<FrontendSpectralInversion>(dvbs->getInversion());
+        dvbsSettings.modulation = static_cast<FrontendDvbsModulation>(dvbs->getModulation());
+        dvbsSettings.rolloff = static_cast<FrontendDvbsRolloff>(dvbs->getRolloff());
+        dvbsSettings.pilot = static_cast<FrontendDvbsPilot>(dvbs->getPilot());
+        dvbsSettings.standard = static_cast<FrontendDvbsStandard>(dvbs->getStandard());
+        dvbsSettings.vcmMode = static_cast<FrontendDvbsVcmMode>(dvbs->getVcmMode());
         return dvbsSettings;
     }
 
+    static FrontendAtscSettings readAtscFrontendSettings(Frontend& feConfig) {
+        ALOGW("[ConfigReader] fe type is atsc");
+        FrontendAtscSettings atscSettings{
+                .frequency = (int64_t)feConfig.getFrequency(),
+        };
+        if (feConfig.hasEndFrequency()) {
+            atscSettings.endFrequency = (int64_t)feConfig.getEndFrequency();
+        }
+        if (!feConfig.hasAtscFrontendSettings_optional()) {
+            ALOGW("[ConfigReader] no more atsc settings");
+            return atscSettings;
+        }
+        auto atsc = feConfig.getFirstAtscFrontendSettings_optional();
+        atscSettings.inversion = static_cast<FrontendSpectralInversion>(atsc->getInversion());
+        atscSettings.modulation = static_cast<FrontendAtscModulation>(atsc->getModulation());
+        return atscSettings;
+    }
+
+    static FrontendIsdbsSettings readIsdbsFrontendSettings(Frontend& feConfig) {
+        ALOGW("[ConfigReader] fe type is isdbs");
+        FrontendIsdbsSettings isdbsSettings{.frequency = (int64_t)feConfig.getFrequency()};
+        if (feConfig.hasEndFrequency()) {
+            isdbsSettings.endFrequency = (int64_t)feConfig.getEndFrequency();
+        }
+        if (!feConfig.hasIsdbsFrontendSettings_optional()) {
+            ALOGW("[ConfigReader] no more isdbs settings");
+            return isdbsSettings;
+        }
+        auto isdbs = feConfig.getFirstIsdbsFrontendSettings_optional();
+        isdbsSettings.streamId = (int32_t)isdbs->getStreamId();
+        isdbsSettings.symbolRate = (int32_t)isdbs->getSymbolRate();
+        isdbsSettings.modulation = static_cast<FrontendIsdbsModulation>(isdbs->getModulation());
+        isdbsSettings.coderate = static_cast<FrontendIsdbsCoderate>(isdbs->getCoderate());
+        isdbsSettings.rolloff = static_cast<FrontendIsdbsRolloff>(isdbs->getRolloff());
+        isdbsSettings.streamIdType =
+                static_cast<FrontendIsdbsStreamIdType>(isdbs->getStreamIdType());
+        return isdbsSettings;
+    }
+
+    static FrontendIsdbtSettings readIsdbtFrontendSettings(Frontend& feConfig) {
+        ALOGW("[ConfigReader] fe type is isdbt");
+        FrontendIsdbtSettings isdbtSettings{
+                .frequency = (int64_t)feConfig.getFrequency(),
+        };
+        if (feConfig.hasEndFrequency()) {
+            isdbtSettings.endFrequency = (int64_t)feConfig.getEndFrequency();
+        }
+        if (!feConfig.hasIsdbtFrontendSettings_optional()) {
+            ALOGW("[ConfigReader] no more isdbt settings");
+            return isdbtSettings;
+        }
+        auto isdbt = feConfig.getFirstIsdbtFrontendSettings_optional();
+        isdbtSettings.inversion = static_cast<FrontendSpectralInversion>(isdbt->getInversion());
+        isdbtSettings.bandwidth = static_cast<FrontendIsdbtBandwidth>(isdbt->getBandwidth());
+        isdbtSettings.mode = static_cast<FrontendIsdbtMode>(isdbt->getMode());
+        isdbtSettings.guardInterval =
+                static_cast<FrontendIsdbtGuardInterval>(isdbt->getGuardInterval());
+        isdbtSettings.serviceAreaId = (int32_t)isdbt->getServiceAreaId();
+        isdbtSettings.partialReceptionFlag =
+                static_cast<FrontendIsdbtPartialReceptionFlag>(isdbt->getPartialReceptionFlag());
+        if (!isdbt->hasFrontendIsdbtLayerSettings()) {
+            ALOGW("[ConfigReader] no isdbt layer settings");
+            return isdbtSettings;
+        }
+        auto layerSettings = isdbt->getFirstFrontendIsdbtLayerSettings();
+        ::aidl::android::hardware::tv::tuner::FrontendIsdbtLayerSettings mLayerSettings;
+        mLayerSettings.modulation =
+                static_cast<FrontendIsdbtModulation>(layerSettings->getModulation());
+        mLayerSettings.coderate = static_cast<FrontendIsdbtCoderate>(layerSettings->getCoderate());
+        mLayerSettings.timeInterleave =
+                static_cast<FrontendIsdbtTimeInterleaveMode>(layerSettings->getTimeInterleave());
+        mLayerSettings.numOfSegment = (int32_t)layerSettings->getNumOfSegment();
+        isdbtSettings.layerSettings.push_back(mLayerSettings);
+        return isdbtSettings;
+    }
+
     static bool readFilterTypeAndSettings(Filter filterConfig, DemuxFilterType& type,
                                           DemuxFilterSettings& settings) {
         auto mainType = filterConfig.getMainType();
         auto subType = filterConfig.getSubType();
 
+        if (subType == FilterSubTypeEnum::AUDIO) {
+            audioFilterIds.push_back(filterConfig.getId());
+        } else if (subType == FilterSubTypeEnum::VIDEO) {
+            videoFilterIds.push_back(filterConfig.getId());
+        } else if (subType == FilterSubTypeEnum::RECORD) {
+            recordFilterIds.push_back(filterConfig.getId());
+        } else if (subType == FilterSubTypeEnum::SECTION) {
+            sectionFilterIds.push_back(filterConfig.getId());
+        } else if (subType == FilterSubTypeEnum::PCR) {
+            pcrFilterIds.push_back(filterConfig.getId());
+        } else if (subType == FilterSubTypeEnum::IP) {
+            ipFilterIds.push_back(filterConfig.getId());
+        }
+
         switch (mainType) {
             case FilterMainTypeEnum::TS: {
                 ALOGW("[ConfigReader] filter main type is ts");
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index 383d49f..ff2df90 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -1,6 +1,14 @@
 // Signature format: 2.0
 package android.media.tuner.testing.configuration.V1_0 {
 
+  public class AtscFrontendSettings {
+    ctor public AtscFrontendSettings();
+    method @Nullable public java.math.BigInteger getInversion();
+    method @Nullable public java.math.BigInteger getModulation();
+    method public void setInversion(@Nullable java.math.BigInteger);
+    method public void setModulation(@Nullable java.math.BigInteger);
+  }
+
   public class AvFilterSettings {
     ctor public AvFilterSettings();
     method @Nullable public short getAudioStreamType_optional();
@@ -19,6 +27,7 @@
     method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling getDescrambling();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback getDvrPlayback();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord getDvrRecord();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbDescrambling getLnbDescrambling();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive getLnbLive();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord getLnbRecord();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan getScan();
@@ -27,6 +36,7 @@
     method public void setDescrambling(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling);
     method public void setDvrPlayback(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback);
     method public void setDvrRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord);
+    method public void setLnbDescrambling(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbDescrambling);
     method public void setLnbLive(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive);
     method public void setLnbRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord);
     method public void setScan(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan);
@@ -39,6 +49,7 @@
     method @Nullable public String getDvrSoftwareFeConnection();
     method @Nullable public String getFrontendConnection();
     method @Nullable public String getIpFilterConnection();
+    method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
     method @Nullable public String getPcrFilterConnection();
     method @Nullable public String getSectionFilterConnection();
     method @Nullable public String getVideoFilterConnection();
@@ -46,6 +57,7 @@
     method public void setDvrSoftwareFeConnection(@Nullable String);
     method public void setFrontendConnection(@Nullable String);
     method public void setIpFilterConnection(@Nullable String);
+    method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
     method public void setPcrFilterConnection(@Nullable String);
     method public void setSectionFilterConnection(@Nullable String);
     method public void setVideoFilterConnection(@Nullable String);
@@ -59,6 +71,7 @@
     method @Nullable public String getDvrSourceConnection();
     method @Nullable public String getFrontendConnection();
     method @Nullable public boolean getHasFrontendConnection();
+    method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
     method @Nullable public String getVideoFilterConnection();
     method public void setAudioFilterConnection(@Nullable String);
     method public void setDescramblerConnection(@Nullable String);
@@ -66,6 +79,7 @@
     method public void setDvrSourceConnection(@Nullable String);
     method public void setFrontendConnection(@Nullable String);
     method public void setHasFrontendConnection(@Nullable boolean);
+    method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
     method public void setVideoFilterConnection(@Nullable String);
   }
 
@@ -73,10 +87,12 @@
     ctor public DataFlowConfiguration.DvrPlayback();
     method @Nullable public String getAudioFilterConnection();
     method @Nullable public String getDvrConnection();
+    method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
     method @Nullable public String getSectionFilterConnection();
     method @Nullable public String getVideoFilterConnection();
     method public void setAudioFilterConnection(@Nullable String);
     method public void setDvrConnection(@Nullable String);
+    method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
     method public void setSectionFilterConnection(@Nullable String);
     method public void setVideoFilterConnection(@Nullable String);
   }
@@ -97,17 +113,35 @@
     method public void setRecordFilterConnection(@Nullable String);
   }
 
+  public static class DataFlowConfiguration.LnbDescrambling {
+    ctor public DataFlowConfiguration.LnbDescrambling();
+    method @Nullable public String getAudioFilterConnection();
+    method @Nullable public String getDescramblerConnection();
+    method @Nullable public java.util.List<java.lang.String> getDiseqcMsgSender();
+    method @Nullable public String getFrontendConnection();
+    method @Nullable public String getLnbConnection();
+    method @Nullable public String getVideoFilterConnection();
+    method public void setAudioFilterConnection(@Nullable String);
+    method public void setDescramblerConnection(@Nullable String);
+    method public void setDiseqcMsgSender(@Nullable java.util.List<java.lang.String>);
+    method public void setFrontendConnection(@Nullable String);
+    method public void setLnbConnection(@Nullable String);
+    method public void setVideoFilterConnection(@Nullable String);
+  }
+
   public static class DataFlowConfiguration.LnbLive {
     ctor public DataFlowConfiguration.LnbLive();
     method @Nullable public String getAudioFilterConnection();
     method @Nullable public java.util.List<java.lang.String> getDiseqcMsgSender();
     method @Nullable public String getFrontendConnection();
     method @Nullable public String getLnbConnection();
+    method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
     method @Nullable public String getVideoFilterConnection();
     method public void setAudioFilterConnection(@Nullable String);
     method public void setDiseqcMsgSender(@Nullable java.util.List<java.lang.String>);
     method public void setFrontendConnection(@Nullable String);
     method public void setLnbConnection(@Nullable String);
+    method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
     method public void setVideoFilterConnection(@Nullable String);
   }
 
@@ -117,11 +151,13 @@
     method @Nullable public String getDvrRecordConnection();
     method @Nullable public String getFrontendConnection();
     method @Nullable public String getLnbConnection();
+    method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
     method @Nullable public String getRecordFilterConnection();
     method public void setDiseqcMsgSender(@Nullable java.util.List<java.lang.String>);
     method public void setDvrRecordConnection(@Nullable String);
     method public void setFrontendConnection(@Nullable String);
     method public void setLnbConnection(@Nullable String);
+    method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
     method public void setRecordFilterConnection(@Nullable String);
   }
 
@@ -160,13 +196,25 @@
   public class DvbsFrontendSettings {
     ctor public DvbsFrontendSettings();
     method @Nullable public java.math.BigInteger getInputStreamId();
+    method @Nullable public java.math.BigInteger getInversion();
     method @Nullable public boolean getIsDiseqcRxMessage();
+    method @Nullable public java.math.BigInteger getModulation();
+    method @Nullable public java.math.BigInteger getPilot();
+    method @Nullable public java.math.BigInteger getRolloff();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbsScanType getScanType();
+    method @Nullable public java.math.BigInteger getStandard();
     method @Nullable public java.math.BigInteger getSymbolRate();
+    method @Nullable public java.math.BigInteger getVcmMode();
     method public void setInputStreamId(@Nullable java.math.BigInteger);
+    method public void setInversion(@Nullable java.math.BigInteger);
     method public void setIsDiseqcRxMessage(@Nullable boolean);
+    method public void setModulation(@Nullable java.math.BigInteger);
+    method public void setPilot(@Nullable java.math.BigInteger);
+    method public void setRolloff(@Nullable java.math.BigInteger);
     method public void setScanType(@Nullable android.media.tuner.testing.configuration.V1_0.DvbsScanType);
+    method public void setStandard(@Nullable java.math.BigInteger);
     method public void setSymbolRate(@Nullable java.math.BigInteger);
+    method public void setVcmMode(@Nullable java.math.BigInteger);
   }
 
   public enum DvbsScanType {
@@ -310,6 +358,7 @@
 
   public class Frontend {
     ctor public Frontend();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.AtscFrontendSettings getAtscFrontendSettings_optional();
     method @Nullable public java.math.BigInteger getConnectToCicamId();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbsFrontendSettings getDvbsFrontendSettings_optional();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbtFrontendSettings getDvbtFrontendSettings_optional();
@@ -317,8 +366,12 @@
     method @Nullable public java.math.BigInteger getFrequency();
     method @Nullable public String getId();
     method @Nullable public boolean getIsSoftwareFrontend();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.IsdbsFrontendSettings getIsdbsFrontendSettings_optional();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.IsdbtFrontendSettings getIsdbtFrontendSettings_optional();
     method @Nullable public java.math.BigInteger getRemoveOutputPid();
+    method @Nullable public boolean getSupportBlindScan();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum getType();
+    method public void setAtscFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AtscFrontendSettings);
     method public void setConnectToCicamId(@Nullable java.math.BigInteger);
     method public void setDvbsFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.DvbsFrontendSettings);
     method public void setDvbtFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.DvbtFrontendSettings);
@@ -326,10 +379,25 @@
     method public void setFrequency(@Nullable java.math.BigInteger);
     method public void setId(@Nullable String);
     method public void setIsSoftwareFrontend(@Nullable boolean);
+    method public void setIsdbsFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IsdbsFrontendSettings);
+    method public void setIsdbtFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IsdbtFrontendSettings);
     method public void setRemoveOutputPid(@Nullable java.math.BigInteger);
+    method public void setSupportBlindScan(@Nullable boolean);
     method public void setType(@Nullable android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum);
   }
 
+  public class FrontendIsdbtLayerSettings {
+    ctor public FrontendIsdbtLayerSettings();
+    method @Nullable public java.math.BigInteger getCoderate();
+    method @Nullable public java.math.BigInteger getModulation();
+    method @Nullable public java.math.BigInteger getNumOfSegment();
+    method @Nullable public java.math.BigInteger getTimeInterleave();
+    method public void setCoderate(@Nullable java.math.BigInteger);
+    method public void setModulation(@Nullable java.math.BigInteger);
+    method public void setNumOfSegment(@Nullable java.math.BigInteger);
+    method public void setTimeInterleave(@Nullable java.math.BigInteger);
+  }
+
   public enum FrontendTypeEnum {
     method @NonNull public String getRawName();
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ANALOG;
@@ -422,6 +490,40 @@
     method public void setSrcPort(@Nullable long);
   }
 
+  public class IsdbsFrontendSettings {
+    ctor public IsdbsFrontendSettings();
+    method @Nullable public java.math.BigInteger getCoderate();
+    method @Nullable public java.math.BigInteger getModulation();
+    method @Nullable public java.math.BigInteger getRolloff();
+    method @Nullable public java.math.BigInteger getStreamId();
+    method @Nullable public java.math.BigInteger getStreamIdType();
+    method @Nullable public java.math.BigInteger getSymbolRate();
+    method public void setCoderate(@Nullable java.math.BigInteger);
+    method public void setModulation(@Nullable java.math.BigInteger);
+    method public void setRolloff(@Nullable java.math.BigInteger);
+    method public void setStreamId(@Nullable java.math.BigInteger);
+    method public void setStreamIdType(@Nullable java.math.BigInteger);
+    method public void setSymbolRate(@Nullable java.math.BigInteger);
+  }
+
+  public class IsdbtFrontendSettings {
+    ctor public IsdbtFrontendSettings();
+    method @Nullable public java.math.BigInteger getBandwidth();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.FrontendIsdbtLayerSettings getFrontendIsdbtLayerSettings();
+    method @Nullable public java.math.BigInteger getGuardInterval();
+    method @Nullable public java.math.BigInteger getInversion();
+    method @Nullable public java.math.BigInteger getMode();
+    method @Nullable public java.math.BigInteger getPartialReceptionFlag();
+    method @Nullable public java.math.BigInteger getServiceAreaId();
+    method public void setBandwidth(@Nullable java.math.BigInteger);
+    method public void setFrontendIsdbtLayerSettings(@Nullable android.media.tuner.testing.configuration.V1_0.FrontendIsdbtLayerSettings);
+    method public void setGuardInterval(@Nullable java.math.BigInteger);
+    method public void setInversion(@Nullable java.math.BigInteger);
+    method public void setMode(@Nullable java.math.BigInteger);
+    method public void setPartialReceptionFlag(@Nullable java.math.BigInteger);
+    method public void setServiceAreaId(@Nullable java.math.BigInteger);
+  }
+
   public class Lnb {
     ctor public Lnb();
     method @Nullable public String getId();
@@ -462,6 +564,12 @@
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_5V;
   }
 
+  public class OptionalFilter {
+    ctor public OptionalFilter();
+    method @Nullable public String getFilterId();
+    method public void setFilterId(@Nullable String);
+  }
+
   public class RecordFilterSettings {
     ctor public RecordFilterSettings();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum getScIndexType();
diff --git a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
index fefe86e..f74af7e 100644
--- a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
+++ b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
@@ -1,19 +1,15 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <!-- 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.
 -->
-
 <!-- The Sample Tuner Testing Configuration.
     Name the customized xml with "tuner_vts_config.xml" and push into the device
     "/vendor/etc" path. Please use "tuner_testing_dynamic_configuration.xsd" to verify the xml.
@@ -32,7 +28,6 @@
                 - The default settings can be found in the sample_tuner_vts_configurations.xml.
                 - The users can also override the default frontend settings using id="FE_DEFAULT".
                 - The users can configure 1 or more frontend elements in the frontends sections.
-
             Each frontend element contain the following attributes:
                 "id": unique id of the frontend that could be used to connect to the test the
                     "dataFlowConfiguration"
@@ -46,7 +41,6 @@
                     output. Supported in Tuner 2.0 or higher.
                 "frequency": the frequency used to configure tune and scan.
                 "endFrequency": the end frequency of scan. Supported in Tuner 1.1 or higher.
-
             Each frontend element also contains one and only one type-related "frontendSettings".
                 - The settings type should match the frontend "type" attribute.
                 - For example, when frontend type="DVBT", dvbtFrontendSettings can be configured.
@@ -54,14 +48,36 @@
                     config only to the hal.
         -->
         <frontends>
-            <frontend id="FE_DEFAULT" type="DVBT" isSoftwareFrontend="true"
+            <frontend id="FE_DEFAULT" type="ISDBS" isSoftwareFrontend="true"
                       connectToCicamId="0" removeOutputPid="10" frequency="578000000"
                       endFrequency="800000000">
-                <dvbtFrontendSettings bandwidth="8" transmissionMode="128" isHighPriority="1"/>
+              <isdbsFrontendSettings streamId="0" symbolRate="0" streamIdType="0" modulation="0" coderate="0" rolloff="0"/>
+            </frontend>
+            <frontend id="FE_ATSC_0" type="ATSC" isSoftwareFrontend="true"
+                      connectToCicamId="0" removeOutputPid="10" frequency="578000000"
+                      endFrequency="800000000">
+              <atscFrontendSettings inversion="0" modulation="0"/>
+            </frontend>
+            <frontend id="FE_ISDBT_0" type="ISDBT" isSoftwareFrontend="true"
+                      connectToCicamId="0" removeOutputPid="10" frequency="578000000"
+                      endFrequency="800000000">
+              <isdbtFrontendSettings serviceAreaId="0" inversion="0" bandwidth="0" mode="0" guardInterval="0" partialReceptionFlag="0">
+                <FrontendIsdbtLayerSettings modulation="0" coderate="0" timeInterleave="0" numOfSegment="0"/>
+              </isdbtFrontendSettings>
             </frontend>
             <frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
                       connectToCicamId="0" removeOutputPid="10" frequency="578000000"
                       endFrequency="800000000">
+              <dvbsFrontendSettings inputStreamId="0" symbolRate="0" inversion="0" modulation="0" coderate="0"
+                                    rolloff="0" pilot="0" standard="0" vcmMode="0" scanType="0" isDiseqcRxMessage="true"/>
+            </frontend>
+            <frontend id="FE_DVBT_0" type="DVBT" isSoftwareFrontend="true"
+                      connectToCicamId="0" removeOutputPid="10" frequency="578000000"
+                      endFrequency="800000000">
+              <dvbtFrontendSettings bandwidth="8" transmissionMode="1" isHighPriority="1"
+                                    constellation="1" hierarchy="1" hpCoderate="1" lpCoderate="1"
+                                    guardInterval="1" standard="1" isMiso="0" plpMode="1"
+                                    plpId="0" plpGroupId="0"/>
             </frontend>
         </frontends>
         <!-- Filter section:
@@ -71,7 +87,6 @@
                 - The users can also override the default filter settings using
                 - id="FILTER_AUDIO_DEFAULT" or "FILTER_VIDEO_DEFAULT".
                 - The users can configure 1 or more filter elements in the filters sections.
-
             Each filter element contain the following attributes:
                 "id": unique id of the filter that could be used to connect to the test the
                     "dataFlowConfiguration"
@@ -80,7 +95,6 @@
                 "bufferSize": the buffer size of the filter in hex.
                 "pid": the pid that would be used to configure the filter.
                 "useFMQ": if the filter uses FMQ.
-
             Each filter element also contains at most one type-related "filterSettings".
                 - The settings type should match the filter "subType" attribute.
                 - For example, when filter subType is audio or video, the avFilterSettings can be
@@ -89,6 +103,9 @@
                     only to the hal.
         -->
         <filters>
+            <filter id="FILTER_SECTION_DEFAULT" mainType="TS" subType="SECTION"
+              bufferSize="16777216" pid="257" useFMQ="false" monitorEventTypes="3">
+          </filter>
             <filter id="FILTER_AUDIO_DEFAULT" mainType="TS" subType="AUDIO"
                     bufferSize="16777216" pid="257" useFMQ="false" monitorEventTypes="3">
                 <avFilterSettings isPassthrough="false" isSecureMemory="false">
@@ -116,7 +133,6 @@
             This section contains configurations of all the dvrs that would be used in the tests.
                 - This section is optional and can be skipped if DVR is not supported.
                 - The users can configure 1 or more dvr elements in the dvrs sections.
-
             Each dvr element contain the following attributes:
                 "id": unique id of the dvr that could be used to connect to the test the
                     "dataFlowConfiguration"
@@ -140,8 +156,21 @@
                  statusMask="15" lowThreshold="4096" highThreshold="32767"
                  dataFormat="ES" packetSize="188" inputFilePath="/data/local/tmp/test.es"/>
         </dvrs>
+        <descramblers>
+            <descrambler id="DESCRAMBLER_0" casSystemId="63192"/>
+        </descramblers>
+        <timeFilters>
+            <timeFilter id="TIME_FILTER_0" timeStamp="1"/>
+        </timeFilters>
+        <diseqcMessages>
+            <diseqcMessage msgName="DISEQC_POWER_ON" msgBody="14 0 0 0 0 3"/>
+        </diseqcMessages>
+        <lnbs>
+            <lnb id="LNB_0" voltage="VOLTAGE_12V" tone="NONE" position="UNDEFINED"/>
+            <lnb id="LNB_1" name="default_lnb_external" voltage="VOLTAGE_5V"
+                            tone="NONE" position="UNDEFINED"/>
+        </lnbs>
     </hardwareConfiguration>
-
     <!-- Data flow configuration section connects each data flow under test to the ids of the
         hardwares that would be used during the tests. -->
     <dataFlowConfiguration>
@@ -151,13 +180,39 @@
                             ipFilterConnection="FILTER_IP_IP_0"
                             dvrSoftwareFeConnection="DVR_PLAYBACK_1"/>
         <scan frontendConnection="FE_DEFAULT"/>
-        <dvrPlayback dvrConnection="DVR_PLAYBACK_1"
-                     audioFilterConnection="FILTER_AUDIO_DEFAULT"
-                     videoFilterConnection="FILTER_VIDEO_DEFAULT"/>
         <dvrRecord hasFrontendConnection="true"
                    frontendConnection="FE_DEFAULT"
                    recordFilterConnection="FILTER_TS_RECORD_0"
                    dvrRecordConnection="DVR_RECORD_0"
                    dvrSoftwareFeConnection="DVR_PLAYBACK_1"/>
+        <dvrPlayback dvrConnection="DVR_PLAYBACK_1"
+                     audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                     videoFilterConnection="FILTER_VIDEO_DEFAULT"
+                     sectionFilterConnection="FILTER_SECTION_DEFAULT"/>
+        <descrambling hasFrontendConnection="true"
+                      frontendConnection="FE_DEFAULT"
+                      descramblerConnection="DESCRAMBLER_0"
+                      audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                      videoFilterConnection="FILTER_VIDEO_DEFAULT"
+                      dvrSoftwareFeConnection="DVR_PLAYBACK_0"
+                      dvrSourceConnection="DVR_PLAYBACK_1">
+        </descrambling>
+        <timeFilter timeFilterConnection="TIME_FILTER_0"/>
+        <lnbLive frontendConnection="FE_DVBS_0"
+                 audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                 videoFilterConnection="FILTER_VIDEO_DEFAULT"
+                 lnbConnection="LNB_1"
+                 diseqcMsgSender="DISEQC_POWER_ON"/>
+        <lnbRecord frontendConnection="FE_DVBS_0"
+                   recordFilterConnection="FILTER_TS_RECORD_0"
+                   dvrRecordConnection="DVR_RECORD_0"
+                   lnbConnection="LNB_0"
+                   diseqcMsgSender="DISEQC_POWER_ON"/>
+        <lnbDescrambling frontendConnection="FE_DVBS_0"
+                        audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                        videoFilterConnection="FILTER_VIDEO_DEFAULT"
+                        lnbConnection="LNB_1"
+                        descramblerConnection="DESCRAMBLER_0"/>
+
     </dataFlowConfiguration>
 </TunerConfiguration>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 59abd9a..eafaca9 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -77,8 +77,41 @@
     <xs:complexType name="dvbsFrontendSettings">
         <xs:attribute name="inputStreamId" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="symbolRate" type="xs:nonNegativeInteger" use="required"/>
-        <xs:attribute name="scanType" type="dvbsScanType" use="optional"/>
-        <xs:attribute name="isDiseqcRxMessage" type="xs:boolean" use="optional"/>
+        <xs:attribute name="scanType" type="dvbsScanType" use="required"/>
+        <xs:attribute name="isDiseqcRxMessage" type="xs:boolean" use="required"/>
+        <xs:attribute name="inversion" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="modulation" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="pilot" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="standard" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="vcmMode" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="rolloff" type="xs:nonNegativeInteger" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="atscFrontendSettings">
+        <xs:attribute name="inversion" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="modulation" type="xs:nonNegativeInteger" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="isdbsFrontendSettings">
+        <xs:attribute name="streamId" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="symbolRate" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="streamIdType" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="modulation" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="coderate" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="rolloff" type="xs:nonNegativeInteger" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="isdbtFrontendSettings">
+        <xs:attribute name="serviceAreaId" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="inversion" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="bandwidth" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="mode" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="guardInterval" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="partialReceptionFlag" type="xs:nonNegativeInteger" use="required"/>
+        <xs:element name="FrontendIsdbtLayerSettings" type="FrontendIsdbtLayerSettings"/>
+    </xs:complexType>
+    <xs:complexType name="FrontendIsdbtLayerSettings">
+        <xs:attribute name="modulation" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="coderate" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="timeInterleave" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="numOfSegment" type="xs:nonNegativeInteger" use="required"/>
     </xs:complexType>
 
     <xs:complexType name="frontend">
@@ -109,16 +142,16 @@
         </xs:annotation>
         <xs:choice minOccurs="0" maxOccurs="1">
             <!-- TODO: b/182519645 finish all the frontend settings structures. -->
-            <!--xs:element name="analog" type="analogSettings"/>
-            <xs:element name="atsc" type="atscSettings"/>
-            <xs:element name="atsc3" type="atsc3Settings"/>
+            <!--xs:element name="analog" type="analogSettings"/-->
+            <xs:element name="atscFrontendSettings" type="atscFrontendSettings"/>
+            <!--xs:element name="atsc3" type="atsc3Settings"/>
             <xs:element name="dvbc" type="dvbcSettings"/-->
             <xs:element name="dvbsFrontendSettings" type="dvbsFrontendSettings"/>
             <xs:element name="dvbtFrontendSettings" type="dvbtFrontendSettings"/>
-            <!--xs:element name="isdbs" type="isdbsSettings"/>
-            <xs:element name="isdbs3" type="isdbs3Settings"/>
-            <xs:element name="isdbt" type="isdbtSettings"/>
-            <xs:element name="dtmb" type="dtmbSettings"/-->
+            <xs:element name="isdbsFrontendSettings" type="isdbsFrontendSettings"/>
+            <!--xs:element name="isdbs3" type="isdbs3Settings"/-->
+            <xs:element name="isdbtFrontendSettings" type="isdbtFrontendSettings"/>
+            <!--xs:element name="dtmb" type="dtmbSettings"/-->
         </xs:choice>
         <xs:attribute name="id" type="frontendId" use="required"/>
         <xs:attribute name="type" type="frontendTypeEnum" use="required"/>
@@ -129,6 +162,7 @@
         <xs:attribute name="connectToCicamId" type="xs:nonNegativeInteger" use="optional"/>
         <xs:attribute name="removeOutputPid" type="xs:nonNegativeInteger" use="optional"/>
         <xs:attribute name="endFrequency" type="xs:nonNegativeInteger" use="optional"/>
+        <xs:attribute name="supportBlindScan" type="xs:boolean" use="optional"/>
     </xs:complexType>
 
     <!-- FILTER SESSION -->
@@ -617,7 +651,7 @@
                     <xs:attribute name="pcrFilterConnection" type="filterId" use="optional"/>
                     <xs:attribute name="sectionFilterConnection" type="filterId" use="optional"/>
                     <xs:attribute name="ipFilterConnection" type="filterId" use="optional"/>
-                    <!-- TODO: b/182519645 allow the users to insert extra filters -->
+                    <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
                     <!-- DVR is only required when the frontend is using the software input -->
                     <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
                 </xs:complexType>
@@ -638,7 +672,7 @@
                     <xs:attribute name="descramblerConnection" type="descramblerId" use="required"/>
                     <xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
                     <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
-                    <!-- TODO: b/182519645 allow the users to insert extra filters -->
+                    <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
                     <!-- This DVR is only required when the frontend is using the software input -->
                     <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
                     <!-- This Dvr is only required when there's no frontend(sw or hw) connection -->
@@ -651,7 +685,7 @@
                     <xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
                     <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
                     <xs:attribute name="sectionFilterConnection" type="filterId" use="optional"/>
-                    <!-- TODO: b/182519645 allow the users to insert extra filters -->
+                    <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
                 </xs:complexType>
             </xs:element>
             <xs:element name="dvrRecord" minOccurs="0" maxOccurs="1">
@@ -675,7 +709,7 @@
                     <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
                     <xs:attribute name="lnbConnection" type="lnbId" use="required"/>
                     <xs:attribute name="diseqcMsgSender" type="diseqcMsgSender" use="optional"/>
-                    <!-- TODO: b/182519645 allow the users to insert extra filters -->
+                    <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
                 </xs:complexType>
             </xs:element>
             <xs:element name="lnbRecord" minOccurs="0" maxOccurs="1">
@@ -685,6 +719,7 @@
                     <xs:attribute name="dvrRecordConnection" type="dvrId" use="required"/>
                     <xs:attribute name="lnbConnection" type="lnbId" use="required"/>
                     <xs:attribute name="diseqcMsgSender" type="diseqcMsgSender" use="optional"/>
+                    <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
                 </xs:complexType>
             </xs:element>
             <xs:element name="timeFilter" minOccurs="0" maxOccurs="1">
@@ -692,6 +727,16 @@
                     <xs:attribute name="timeFilterConnection" type="timeFilterId" use="required"/>
                 </xs:complexType>
             </xs:element>
+            <xs:element name="lnbDescrambling" minOccurs="0" maxOccurs="1">
+                <xs:complexType>
+                    <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+                    <xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
+                    <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
+                    <xs:attribute name="lnbConnection" type="lnbId" use="required"/>
+                    <xs:attribute name="descramblerConnection" type="descramblerId" use="required"/>
+                    <xs:attribute name="diseqcMsgSender" type="diseqcMsgSender" use="optional"/>
+                </xs:complexType>
+            </xs:element>
         </xs:sequence>
     </xs:complexType>
 
@@ -729,4 +774,7 @@
             <xs:field xpath="@id"/>
         </xs:key>
     </xs:element>
+    <xs:complexType name="optionalFilter">
+        <xs:attribute name="filterId" type="filterId" use="required"/>
+    </xs:complexType>
 </xs:schema>
diff --git a/usb/1.0/default/Android.bp b/usb/1.0/default/Android.bp
index 4bed2c7..5f56fe0 100644
--- a/usb/1.0/default/Android.bp
+++ b/usb/1.0/default/Android.bp
@@ -21,21 +21,11 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-filegroup {
-    name: "android.hardware.usb@1.0-service.xml",
-    srcs: ["android.hardware.usb@1.0-service.xml"],
-}
-
-filegroup {
-    name: "android.hardware.usb@1.0-service.rc",
-    srcs: ["android.hardware.usb@1.0-service.rc"],
-}
-
 cc_binary {
     name: "android.hardware.usb@1.0-service",
     defaults: ["hidl_defaults"],
-    init_rc: [":android.hardware.usb@1.0-service.rc"],
-    vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
+    init_rc: ["android.hardware.usb@1.0-service.rc"],
+    vintf_fragments: ["android.hardware.usb@1.0-service.xml"],
     relative_install_path: "hw",
     vendor: true,
     srcs: [
diff --git a/usb/1.0/default/OWNERS b/usb/1.0/default/OWNERS
deleted file mode 100644
index fefae56..0000000
--- a/usb/1.0/default/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-badhri@google.com
diff --git a/usb/1.0/default/Usb.cpp b/usb/1.0/default/Usb.cpp
index 6eb8842..573e0e3 100644
--- a/usb/1.0/default/Usb.cpp
+++ b/usb/1.0/default/Usb.cpp
@@ -234,7 +234,7 @@
     else
         return Status::UNRECOGNIZED_ROLE;
 
-        return Status::SUCCESS;
+    return Status::SUCCESS;
 }
 
 Status getPortStatusHelper (hidl_vec<PortStatus>& currentPortStatus) {
diff --git a/usb/1.0/default/apex/Android.bp b/usb/1.0/default/apex/Android.bp
deleted file mode 100644
index ee50fdf..0000000
--- a/usb/1.0/default/apex/Android.bp
+++ /dev/null
@@ -1,59 +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 {
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-apex_key {
-    name: "com.android.hardware.usb.key",
-    public_key: "com.android.hardware.usb.avbpubkey",
-    private_key: "com.android.hardware.usb.pem",
-}
-
-android_app_certificate {
-    name: "com.android.hardware.usb.certificate",
-    certificate: "com.android.hardware.usb",
-}
-
-genrule {
-    name: "com.android.hardware.usb.rc-gen",
-    srcs: [":android.hardware.usb@1.0-service.rc"],
-    out: ["com.android.hardware.usb.rc"],
-    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.usb/' $(in) > $(out)",
-}
-
-prebuilt_etc {
-    name: "com.android.hardware.usb.rc",
-    src: ":com.android.hardware.usb.rc-gen",
-    installable: false,
-}
-
-apex {
-    name: "com.android.hardware.usb",
-    manifest: "manifest.json",
-    file_contexts: "file_contexts",
-    key: "com.android.hardware.usb.key",
-    certificate: ":com.android.hardware.usb.certificate",
-    updatable: false,
-    soc_specific: true,
-    use_vndk_as_stable: true,
-    binaries: ["android.hardware.usb@1.0-service"],
-    prebuilts: [
-        "com.android.hardware.usb.rc",
-        "android.hardware.usb.accessory.prebuilt.xml",
-        "android.hardware.usb.host.prebuilt.xml",
-    ],
-    vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
-}
diff --git a/usb/1.0/default/apex/file_contexts b/usb/1.0/default/apex/file_contexts
deleted file mode 100644
index bc84ac4..0000000
--- a/usb/1.0/default/apex/file_contexts
+++ /dev/null
@@ -1,5 +0,0 @@
-(/.*)?                                         u:object_r:vendor_file:s0
-# Permission XMLs
-/etc/permissions(/.*)?                         u:object_r:vendor_configs_file:s0
-# binary
-/bin/hw/android\.hardware\.usb@1\.0-service    u:object_r:hal_usb_default_exec:s0
\ No newline at end of file
diff --git a/usb/1.0/default/apex/manifest.json b/usb/1.0/default/apex/manifest.json
deleted file mode 100644
index 6a1095f..0000000
--- a/usb/1.0/default/apex/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.hardware.usb",
-  "version": 1
-}
diff --git a/usb/1.0/vts/OWNERS b/usb/1.0/vts/OWNERS
deleted file mode 100644
index 54f268f..0000000
--- a/usb/1.0/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-badhri@google.com
-yim@google.com
-trong@google.com
diff --git a/usb/1.1/vts/OWNERS b/usb/1.1/vts/OWNERS
deleted file mode 100644
index 54f268f..0000000
--- a/usb/1.1/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-badhri@google.com
-yim@google.com
-trong@google.com
diff --git a/usb/1.2/vts/OWNERS b/usb/1.2/vts/OWNERS
deleted file mode 100644
index f60d39a..0000000
--- a/usb/1.2/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-badhri@google.com
-yim@google.com
diff --git a/usb/1.3/vts/OWNERS b/usb/1.3/vts/OWNERS
deleted file mode 100644
index a6a1e54..0000000
--- a/usb/1.3/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-albertccwang@google.com
-badhri@google.com
diff --git a/usb/OWNERS b/usb/OWNERS
new file mode 100644
index 0000000..2b1d34d
--- /dev/null
+++ b/usb/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 175220
+
+albertccwang@google.com
+badhri@google.com
diff --git a/usb/aidl/Android.bp b/usb/aidl/Android.bp
index 7eb6020..b82f6d5 100644
--- a/usb/aidl/Android.bp
+++ b/usb/aidl/Android.bp
@@ -33,17 +33,18 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions_with_info: [
         {
             version: "1",
             imports: [],
         },
+        {
+            version: "2",
+            imports: [],
+        },
+
     ],
+    frozen: true,
 
 }
diff --git a/usb/aidl/OWNERS b/usb/aidl/OWNERS
deleted file mode 100644
index fefae56..0000000
--- a/usb/aidl/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-badhri@google.com
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/.hash b/usb/aidl/aidl_api/android.hardware.usb/2/.hash
new file mode 100644
index 0000000..ce43da6
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/.hash
@@ -0,0 +1 @@
+6c1263ce61606107f41a9edb66be1783d5881f00
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/AltModeData.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/AltModeData.aidl
new file mode 100644
index 0000000..d25ee84
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/AltModeData.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not us e 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.usb;
+@VintfStability
+union AltModeData {
+  android.hardware.usb.AltModeData.DisplayPortAltModeData displayPortAltModeData;
+  @VintfStability
+  parcelable DisplayPortAltModeData {
+    android.hardware.usb.DisplayPortAltModeStatus partnerSinkStatus = android.hardware.usb.DisplayPortAltModeStatus.UNKNOWN;
+    android.hardware.usb.DisplayPortAltModeStatus cableStatus = android.hardware.usb.DisplayPortAltModeStatus.UNKNOWN;
+    android.hardware.usb.DisplayPortAltModePinAssignment pinAssignment = android.hardware.usb.DisplayPortAltModePinAssignment.NONE;
+    boolean hpd = false;
+    android.hardware.usb.LinkTrainingStatus linkTrainingStatus = android.hardware.usb.LinkTrainingStatus.UNKNOWN;
+  }
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ComplianceWarning.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ComplianceWarning.aidl
new file mode 100644
index 0000000..8b67070
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ComplianceWarning.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum ComplianceWarning {
+  OTHER = 1,
+  DEBUG_ACCESSORY = 2,
+  BC_1_2 = 3,
+  MISSING_RP = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ContaminantDetectionStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ContaminantDetectionStatus.aidl
new file mode 100644
index 0000000..24c6966
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ContaminantDetectionStatus.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@VintfStability
+enum ContaminantDetectionStatus {
+  NOT_SUPPORTED = 0,
+  DISABLED = 1,
+  NOT_DETECTED = 2,
+  DETECTED = 3,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ContaminantProtectionMode.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ContaminantProtectionMode.aidl
new file mode 100644
index 0000000..9979869
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ContaminantProtectionMode.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@VintfStability
+enum ContaminantProtectionMode {
+  NONE = 0,
+  FORCE_SINK = 1,
+  FORCE_SOURCE = 2,
+  FORCE_DISABLE = 3,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ContaminantProtectionStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ContaminantProtectionStatus.aidl
new file mode 100644
index 0000000..9642261
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/ContaminantProtectionStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.usb;
+@VintfStability
+enum ContaminantProtectionStatus {
+  NONE = 0,
+  FORCE_SINK = 1,
+  FORCE_SOURCE = 2,
+  FORCE_DISABLE = 3,
+  DISABLED = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/DisplayPortAltModePinAssignment.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
new file mode 100644
index 0000000..5908117
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum DisplayPortAltModePinAssignment {
+  NONE = 0,
+  A = 1,
+  B = 2,
+  C = 3,
+  D = 4,
+  E = 5,
+  F = 6,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/DisplayPortAltModeStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/DisplayPortAltModeStatus.aidl
new file mode 100644
index 0000000..dc69b98
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/DisplayPortAltModeStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum DisplayPortAltModeStatus {
+  UNKNOWN = 0,
+  NOT_CAPABLE = 1,
+  CAPABLE = 2,
+  ENABLED = 3,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/IUsb.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/IUsb.aidl
new file mode 100644
index 0000000..859f526
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/IUsb.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.usb;
+@VintfStability
+interface IUsb {
+  oneway void enableContaminantPresenceDetection(in String portName, in boolean enable, long transactionId);
+  oneway void enableUsbData(in String portName, boolean enable, long transactionId);
+  oneway void enableUsbDataWhileDocked(in String portName, long transactionId);
+  oneway void queryPortStatus(long transactionId);
+  oneway void setCallback(in android.hardware.usb.IUsbCallback callback);
+  oneway void switchRole(in String portName, in android.hardware.usb.PortRole role, long transactionId);
+  oneway void limitPowerTransfer(in String portName, boolean limit, long transactionId);
+  oneway void resetUsbPort(in String portName, long transactionId);
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/IUsbCallback.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/IUsbCallback.aidl
new file mode 100644
index 0000000..4abfaec
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/IUsbCallback.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.usb;
+@VintfStability
+interface IUsbCallback {
+  oneway void notifyPortStatusChange(in android.hardware.usb.PortStatus[] currentPortStatus, in android.hardware.usb.Status retval);
+  oneway void notifyRoleSwitchStatus(in String portName, in android.hardware.usb.PortRole newRole, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyEnableUsbDataStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyEnableUsbDataWhileDockedStatus(in String portName, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyContaminantEnabledStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyQueryPortStatus(in String portName, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyLimitPowerTransferStatus(in String portName, boolean limit, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyResetUsbPortStatus(in String portName, in android.hardware.usb.Status retval, long transactionId);
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/LinkTrainingStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/LinkTrainingStatus.aidl
new file mode 100644
index 0000000..1f0b2dc
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/LinkTrainingStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@Backing(type="int") @VintfStability
+enum LinkTrainingStatus {
+  UNKNOWN = 0,
+  SUCCESS = 1,
+  FAILURE = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PlugOrientation.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PlugOrientation.aidl
new file mode 100644
index 0000000..e218544
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PlugOrientation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum PlugOrientation {
+  UNKNOWN = 0,
+  UNPLUGGED = 1,
+  PLUGGED_UNKNOWN = 2,
+  PLUGGED_NORMAL = 3,
+  PLUGGED_FLIPPED = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortDataRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortDataRole.aidl
new file mode 100644
index 0000000..105b316
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortDataRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.usb;
+@VintfStability
+enum PortDataRole {
+  NONE = 0,
+  HOST = 1,
+  DEVICE = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortMode.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortMode.aidl
new file mode 100644
index 0000000..34e4334
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.usb;
+@VintfStability
+enum PortMode {
+  NONE = 0,
+  UFP = 1,
+  DFP = 2,
+  DRP = 3,
+  AUDIO_ACCESSORY = 4,
+  DEBUG_ACCESSORY = 5,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortPowerRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortPowerRole.aidl
new file mode 100644
index 0000000..0e6f3fb
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortPowerRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.usb;
+@VintfStability
+enum PortPowerRole {
+  NONE = 0,
+  SOURCE = 1,
+  SINK = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortRole.aidl
new file mode 100644
index 0000000..c66aecc
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.usb;
+@VintfStability
+union PortRole {
+  android.hardware.usb.PortPowerRole powerRole = android.hardware.usb.PortPowerRole.NONE;
+  android.hardware.usb.PortDataRole dataRole;
+  android.hardware.usb.PortMode mode;
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortStatus.aidl
new file mode 100644
index 0000000..cefddba
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PortStatus.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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.usb;
+@VintfStability
+parcelable PortStatus {
+  String portName;
+  android.hardware.usb.PortDataRole currentDataRole = android.hardware.usb.PortDataRole.NONE;
+  android.hardware.usb.PortPowerRole currentPowerRole = android.hardware.usb.PortPowerRole.NONE;
+  android.hardware.usb.PortMode currentMode = android.hardware.usb.PortMode.NONE;
+  boolean canChangeMode;
+  boolean canChangeDataRole;
+  boolean canChangePowerRole;
+  android.hardware.usb.PortMode[] supportedModes;
+  android.hardware.usb.ContaminantProtectionMode[] supportedContaminantProtectionModes;
+  boolean supportsEnableContaminantPresenceProtection;
+  android.hardware.usb.ContaminantProtectionStatus contaminantProtectionStatus = android.hardware.usb.ContaminantProtectionStatus.NONE;
+  boolean supportsEnableContaminantPresenceDetection;
+  android.hardware.usb.ContaminantDetectionStatus contaminantDetectionStatus = android.hardware.usb.ContaminantDetectionStatus.NOT_SUPPORTED;
+  android.hardware.usb.UsbDataStatus[] usbDataStatus;
+  boolean powerTransferLimited;
+  android.hardware.usb.PowerBrickStatus powerBrickStatus;
+  boolean supportsComplianceWarnings = false;
+  android.hardware.usb.ComplianceWarning[] complianceWarnings = {};
+  android.hardware.usb.PlugOrientation plugOrientation = android.hardware.usb.PlugOrientation.UNKNOWN;
+  android.hardware.usb.AltModeData[] supportedAltModes = {};
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PowerBrickStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PowerBrickStatus.aidl
new file mode 100644
index 0000000..01d2fdd
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/PowerBrickStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.usb;
+@VintfStability
+enum PowerBrickStatus {
+  UNKNOWN = 0,
+  CONNECTED = 1,
+  NOT_CONNECTED = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/Status.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/Status.aidl
new file mode 100644
index 0000000..f28fc2a
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/Status.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.usb;
+@Backing(type="int") @VintfStability
+enum Status {
+  SUCCESS = 0,
+  ERROR = 1,
+  INVALID_ARGUMENT = 2,
+  UNRECOGNIZED_ROLE = 3,
+  NOT_SUPPORTED = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/UsbDataStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/UsbDataStatus.aidl
new file mode 100644
index 0000000..b976852
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/2/android/hardware/usb/UsbDataStatus.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.usb;
+@VintfStability
+enum UsbDataStatus {
+  UNKNOWN = 0,
+  ENABLED = 1,
+  DISABLED_OVERHEAT = 2,
+  DISABLED_CONTAMINANT = 3,
+  DISABLED_DOCK = 4,
+  DISABLED_FORCE = 5,
+  DISABLED_DEBUG = 6,
+  DISABLED_DOCK_HOST_MODE = 7,
+  DISABLED_DOCK_DEVICE_MODE = 8,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/AltModeData.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/AltModeData.aidl
new file mode 100644
index 0000000..d25ee84
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/AltModeData.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not us e 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.usb;
+@VintfStability
+union AltModeData {
+  android.hardware.usb.AltModeData.DisplayPortAltModeData displayPortAltModeData;
+  @VintfStability
+  parcelable DisplayPortAltModeData {
+    android.hardware.usb.DisplayPortAltModeStatus partnerSinkStatus = android.hardware.usb.DisplayPortAltModeStatus.UNKNOWN;
+    android.hardware.usb.DisplayPortAltModeStatus cableStatus = android.hardware.usb.DisplayPortAltModeStatus.UNKNOWN;
+    android.hardware.usb.DisplayPortAltModePinAssignment pinAssignment = android.hardware.usb.DisplayPortAltModePinAssignment.NONE;
+    boolean hpd = false;
+    android.hardware.usb.LinkTrainingStatus linkTrainingStatus = android.hardware.usb.LinkTrainingStatus.UNKNOWN;
+  }
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ComplianceWarning.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ComplianceWarning.aidl
new file mode 100644
index 0000000..8b67070
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ComplianceWarning.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum ComplianceWarning {
+  OTHER = 1,
+  DEBUG_ACCESSORY = 2,
+  BC_1_2 = 3,
+  MISSING_RP = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModePinAssignment.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
new file mode 100644
index 0000000..5908117
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum DisplayPortAltModePinAssignment {
+  NONE = 0,
+  A = 1,
+  B = 2,
+  C = 3,
+  D = 4,
+  E = 5,
+  F = 6,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModeStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModeStatus.aidl
new file mode 100644
index 0000000..dc69b98
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModeStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum DisplayPortAltModeStatus {
+  UNKNOWN = 0,
+  NOT_CAPABLE = 1,
+  CAPABLE = 2,
+  ENABLED = 3,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
index f866c1e..859f526 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
@@ -41,5 +41,5 @@
   oneway void setCallback(in android.hardware.usb.IUsbCallback callback);
   oneway void switchRole(in String portName, in android.hardware.usb.PortRole role, long transactionId);
   oneway void limitPowerTransfer(in String portName, boolean limit, long transactionId);
-  oneway void resetUsbPort(in String portName,long transactionId);
+  oneway void resetUsbPort(in String portName, long transactionId);
 }
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/LinkTrainingStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/LinkTrainingStatus.aidl
new file mode 100644
index 0000000..1f0b2dc
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/LinkTrainingStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.usb;
+@Backing(type="int") @VintfStability
+enum LinkTrainingStatus {
+  UNKNOWN = 0,
+  SUCCESS = 1,
+  FAILURE = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PlugOrientation.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PlugOrientation.aidl
new file mode 100644
index 0000000..e218544
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PlugOrientation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum PlugOrientation {
+  UNKNOWN = 0,
+  UNPLUGGED = 1,
+  PLUGGED_UNKNOWN = 2,
+  PLUGGED_NORMAL = 3,
+  PLUGGED_FLIPPED = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
index dfd99fb..cefddba 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
@@ -50,4 +50,8 @@
   android.hardware.usb.UsbDataStatus[] usbDataStatus;
   boolean powerTransferLimited;
   android.hardware.usb.PowerBrickStatus powerBrickStatus;
+  boolean supportsComplianceWarnings = false;
+  android.hardware.usb.ComplianceWarning[] complianceWarnings = {};
+  android.hardware.usb.PlugOrientation plugOrientation = android.hardware.usb.PlugOrientation.UNKNOWN;
+  android.hardware.usb.AltModeData[] supportedAltModes = {};
 }
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl
index e2c0cfb..b976852 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl
@@ -41,4 +41,6 @@
   DISABLED_DOCK = 4,
   DISABLED_FORCE = 5,
   DISABLED_DEBUG = 6,
+  DISABLED_DOCK_HOST_MODE = 7,
+  DISABLED_DOCK_DEVICE_MODE = 8,
 }
diff --git a/usb/aidl/android/hardware/usb/AltModeData.aidl b/usb/aidl/android/hardware/usb/AltModeData.aidl
new file mode 100644
index 0000000..0b1e06a
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/AltModeData.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not us e 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.usb;
+
+import android.hardware.usb.DisplayPortAltModePinAssignment;
+import android.hardware.usb.DisplayPortAltModeStatus;
+import android.hardware.usb.LinkTrainingStatus;
+
+@VintfStability
+union AltModeData {
+    /**
+     * Holds data necessary to communicate the current DisplayPort
+     * Alt Mode status.
+     */
+    @VintfStability
+    parcelable DisplayPortAltModeData {
+        /**
+         * Indicates the current DisplayPort Alt Mode Status of
+         * the port partner acting as a DisplayPort sink.
+         */
+        DisplayPortAltModeStatus partnerSinkStatus = DisplayPortAltModeStatus.UNKNOWN;
+        /**
+         * Indicates the current status of the attached DisplayPort
+         * Alt Mode cable/adapter.
+         */
+        DisplayPortAltModeStatus cableStatus = DisplayPortAltModeStatus.UNKNOWN;
+        /**
+         * Indicates the DisplayPort Alt Mode pin assignment
+         * negotiated between the device, port partner, and cable.
+         */
+        DisplayPortAltModePinAssignment pinAssignment = DisplayPortAltModePinAssignment.NONE;
+        /**
+         * Indicates DisplayPort Hot Plug Detection (HPD) status for a partner
+         * sink device. If true, then a DisplayPort Alt Mode partner sink is
+         * connected and powered on, and if false, the partner sink is not
+         * powered or no partner sink is connected.
+         */
+        boolean hpd = false;
+        /**
+         * Indicates the current status of DisplayPort link training over USB-C
+         * for the attached DisplayPort Alt Mode partner sink.
+         */
+        LinkTrainingStatus linkTrainingStatus = LinkTrainingStatus.UNKNOWN;
+    }
+    DisplayPortAltModeData displayPortAltModeData;
+}
diff --git a/usb/aidl/android/hardware/usb/ComplianceWarning.aidl b/usb/aidl/android/hardware/usb/ComplianceWarning.aidl
new file mode 100644
index 0000000..4c18a31
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/ComplianceWarning.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Indicates the potential non-compliance reasons for the
+ * connected USB Type-C port partner which could be a power
+ * source, accessory or cable. Applicable for USB-C receptacles
+ * in Android devices.
+ */
+enum ComplianceWarning {
+    /**
+     * Used to indicate Type-C sources/cables/accessories/ports
+     * whose issue is not listed below but do not meet
+     * specification requirements from including but not limited to
+     * USB Type-C Cable and Connector Specification, Universal Serial Bus
+     * Power Delivery Specification, and Universal Serial Bus
+     * 1.x/2.0/3.x/4.0.
+     */
+    OTHER = 1,
+    /**
+     * Used to indicate Type-C port partner
+     * (cable/accessory/source) that identifies itself as debug
+     * accessory source as defined in USB Type-C Cable and
+     * Connector Specification. However, the specification
+     * states that this is meant for debug only and shall not
+     * be used for with commercial products.
+     */
+    DEBUG_ACCESSORY = 2,
+    /**
+     * Used to indicate Type-C port partner that does not
+     * identify itself as one of the charging port types
+     * (SDP/CDP/DCP etc) as defined by Battery Charging v1.2
+     * Specification.
+     */
+    BC_1_2 = 3,
+    /**
+     * Used to indicate Type-C sources/cables that are missing
+     * pull up resistors on the CC pins as required by USB
+     * Type-C Cable and Connector Specification.
+     */
+    MISSING_RP = 4,
+}
diff --git a/usb/aidl/android/hardware/usb/DisplayPortAltModePinAssignment.aidl b/usb/aidl/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
new file mode 100644
index 0000000..d3284e5
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Indicates DisplayPort Alt Mode pin assignments whose port
+ * pin configurations are as defined by DisplayPort Alt Mode
+ * v1.0 for deprecated pin assignments A, B, and F and
+ * DisplayPort Alt Mode v2.x for pin assignments C, D, and E.
+ *
+ */
+enum DisplayPortAltModePinAssignment {
+    /**
+     * Indicates that the pin assignment has not yet been
+     * configured, the attached cable/adapter does not support
+     * DisplayPort Alt Mode, or no cable/adapter is attached.
+     */
+    NONE = 0,
+    /**
+     * Intended for use with USB-C-to-USB-C cables and with
+     * adapters from USB-C to other video formats using
+     * four lanes for DisplayPort transmission, and is
+     * restricted by the USB Type-C r1.0 Active Cable
+     * definition.
+     */
+    A = 1,
+    /**
+     * Intended for use with USB-C-to-USB-C cables and with
+     * adapters from USB-C to other video formats using
+     * two lanes for DisplayPort transmission and two for
+     * USB SuperSpeed,and is restricted by the USB Type-C
+     * r1.0 Active Cable definition.
+     */
+    B = 2,
+    /**
+     * Intended for use with USB-C-to-USB-C cables and with
+     * adapters from USB-C to other video formats using
+     * four lanes for DisplayPort transmission.
+     */
+    C = 3,
+    /**
+     * Intended for use with USB-C-to-USB-C cables and with
+     * adapters from USB-C to other video formats using
+     * two lanes for DisplayPort transmission and two for
+     * USB SuperSpeed.
+     */
+    D = 4,
+    /**
+     * Intended for use with adapters from USB-C-to-DP plugs
+     * or receptacles.
+     */
+    E = 5,
+    /**
+     * Intended for use with adapters from USB-C-to-DP plugs
+     * or receptacles that also support two lanes of USB
+     * SuperSpeed.
+     */
+    F = 6,
+}
diff --git a/usb/aidl/android/hardware/usb/DisplayPortAltModeStatus.aidl b/usb/aidl/android/hardware/usb/DisplayPortAltModeStatus.aidl
new file mode 100644
index 0000000..275ed15
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/DisplayPortAltModeStatus.aidl
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Port Partners:
+ * Indicates the current status of the of DisplayPort Alt Mode
+ * partner, which can either be a DisplayPort Alt Mode source
+ * (ex. computer, tablet, phone) or DisplayPort Alt Mode sink
+ * (monitor, hub, adapter).
+ *
+ * Cables:
+ * Indicates the current status of the Type-C cable/adapter
+ * connected to the local Android device.
+ *
+ */
+enum DisplayPortAltModeStatus {
+    /**
+     * Port Partners:
+     * The port partner status is currently unknown for one of
+     * the following reasons:
+     *     1. No port partner is connected to the device
+     *     2. The USB Power Delivery Discover Identity command
+     *        has not been issued to the port partner via SOP
+     *        messaging.
+     *
+     * Cables:
+     * The cable’s capabilities are not yet known to the
+     * device, or no cable is plugged in.
+     */
+    UNKNOWN = 0,
+    /**
+     * Port Partners:
+     * The current port partner does not list DisplayPort as
+     * one of its Alt Modes,does not list the capability to
+     * act as a DisplayPort Source or Sink device, or a compatible
+     * configuration could not be established.
+     *
+     * Cables:
+     * The cable/adapter’s capabilities do not list DisplayPort
+     * as one of its Alt Modes, or a compatible configuration could
+     * not be established.
+     */
+    NOT_CAPABLE = 1,
+    /**
+     * Port Partners:
+     * The current port partner lists compatible DisplayPort
+     * capabilities with the device, however may not yet have
+     * entered DisplayPort Alt Mode or has configured its
+     * port for data transmission.
+     *
+     * Cables:
+     * The Type-C cable/adapter’s capabilities have been
+     * discovered and list DisplayPort Alt Mode as one of its
+     * capabilities, however may not yet have entered DisplayPort
+     * Alt Mode or has been configured for data transmission.
+     */
+    CAPABLE = 2,
+    /**
+     * Port Partners:
+     * The port partner and device are both configured for
+     * DisplayPort Alt Mode.
+     *
+     * Cables:
+     * The Type-C cable/adapter is configured for DisplayPort
+     * Alt Mode.
+     */
+    ENABLED = 3,
+}
diff --git a/usb/aidl/android/hardware/usb/LinkTrainingStatus.aidl b/usb/aidl/android/hardware/usb/LinkTrainingStatus.aidl
new file mode 100644
index 0000000..9f3b3c3
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/LinkTrainingStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Indicates the current status of DisplayPort link training over USB-C for the
+ * attached DisplayPort Alt Mode partner sink as described in DisplayPort
+ * v1.4/2.1.
+ */
+enum LinkTrainingStatus {
+    /*
+     * Indicates the link training result is not available because link training
+     * has not completed or initiated yet.
+     */
+    UNKNOWN = 0,
+    /*
+     * Indicates that link training has completed and optimal settings for data
+     * transmission between the sink and source device have successfully been
+     * negotiated.
+     */
+    SUCCESS = 1,
+    /*
+     * Indicates that link training has failed and the link initialization has
+     * terminated.
+     */
+    FAILURE = 2,
+}
diff --git a/usb/aidl/android/hardware/usb/PlugOrientation.aidl b/usb/aidl/android/hardware/usb/PlugOrientation.aidl
new file mode 100644
index 0000000..3c09cfe
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PlugOrientation.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Used to indicate plug orientation as defined by USB Type-C
+ * Cable and Connector Specification.
+ */
+enum PlugOrientation {
+    UNKNOWN = 0,
+    UNPLUGGED = 1,
+    /**
+     * The device can detect that a plug is inserted, but
+     * the plug may not present a normal or flipped orientation.
+     */
+    PLUGGED_UNKNOWN = 2,
+    PLUGGED_NORMAL = 3,
+    PLUGGED_FLIPPED = 4,
+}
diff --git a/usb/aidl/android/hardware/usb/PortStatus.aidl b/usb/aidl/android/hardware/usb/PortStatus.aidl
index 51bee71..daed13c 100644
--- a/usb/aidl/android/hardware/usb/PortStatus.aidl
+++ b/usb/aidl/android/hardware/usb/PortStatus.aidl
@@ -16,9 +16,12 @@
 
 package android.hardware.usb;
 
+import android.hardware.usb.AltModeData;
+import android.hardware.usb.ComplianceWarning;
 import android.hardware.usb.ContaminantDetectionStatus;
 import android.hardware.usb.ContaminantProtectionMode;
 import android.hardware.usb.ContaminantProtectionStatus;
+import android.hardware.usb.PlugOrientation;
 import android.hardware.usb.PortDataRole;
 import android.hardware.usb.PortMode;
 import android.hardware.usb.PortPowerRole;
@@ -101,7 +104,8 @@
     /**
      * Current status of contaminant detection algorithm.
      */
-    ContaminantDetectionStatus contaminantDetectionStatus = ContaminantDetectionStatus.NOT_SUPPORTED;
+    ContaminantDetectionStatus contaminantDetectionStatus =
+            ContaminantDetectionStatus.NOT_SUPPORTED;
     /**
      * UsbData status of the port.
      * Lists reasons for USB data being disabled.
@@ -115,4 +119,25 @@
      * Denotes whether Power brick is connected.
      */
     PowerBrickStatus powerBrickStatus;
+    /**
+     * True if the hal implementation can support identifying
+     * non compliant USB power source/cable/accessory. False other
+     * otherwise.
+     */
+    boolean supportsComplianceWarnings = false;
+    /**
+     * List of reasons as to why the attached USB
+     * power source/cable/accessory is non compliant.
+     */
+    ComplianceWarning[] complianceWarnings = {};
+    /**
+     * Indicates the current orientation of the cable/adapter
+     * plugged into the device.
+     */
+    PlugOrientation plugOrientation = PlugOrientation.UNKNOWN;
+    /**
+     * Lists Alt Modes supported by the device and holds their
+     * current information.
+     */
+    AltModeData[] supportedAltModes = {};
 }
diff --git a/usb/aidl/android/hardware/usb/UsbDataStatus.aidl b/usb/aidl/android/hardware/usb/UsbDataStatus.aidl
index 4b6a41a..e6b5f55 100644
--- a/usb/aidl/android/hardware/usb/UsbDataStatus.aidl
+++ b/usb/aidl/android/hardware/usb/UsbDataStatus.aidl
@@ -35,7 +35,8 @@
      */
     DISABLED_CONTAMINANT = 3,
     /**
-     * USB data is disabled due to dock.
+     * DISABLED_DOCK implies both DISABLED_DOCK_HOST_MODE
+     * and DISABLED_DOCK_DEVICE_MODE.
      */
     DISABLED_DOCK = 4,
     /**
@@ -45,5 +46,13 @@
     /**
      * USB data disabled for debug.
      */
-    DISABLED_DEBUG = 6
+    DISABLED_DEBUG = 6,
+    /**
+     * USB Host mode is disabled due to a docking event.
+     */
+    DISABLED_DOCK_HOST_MODE = 7,
+    /**
+     * USB device mode disabled due to a docking event.
+     */
+    DISABLED_DOCK_DEVICE_MODE = 8,
 }
diff --git a/usb/aidl/default/Android.bp b/usb/aidl/default/Android.bp
index 7cb2822..472e732 100644
--- a/usb/aidl/default/Android.bp
+++ b/usb/aidl/default/Android.bp
@@ -34,11 +34,21 @@
         "Usb.cpp",
     ],
     shared_libs: [
-        "android.hardware.usb-V1-ndk",
+        "android.hardware.usb-V2-ndk",
         "libbase",
         "libbinder_ndk",
-	"libcutils",
+        "libcutils",
         "liblog",
         "libutils",
     ],
 }
+
+filegroup {
+    name: "android.hardware.usb-service.example.xml",
+    srcs: ["android.hardware.usb-service.example.xml"],
+}
+
+filegroup {
+    name: "android.hardware.usb-service.example.rc",
+    srcs: ["android.hardware.usb-service.example.rc"],
+}
diff --git a/usb/aidl/default/Usb.cpp b/usb/aidl/default/Usb.cpp
index 7e738c4..593dd4f 100644
--- a/usb/aidl/default/Usb.cpp
+++ b/usb/aidl/default/Usb.cpp
@@ -123,6 +123,15 @@
     return Status::SUCCESS;
 }
 
+Status queryNonCompliantChargerStatus(std::vector<PortStatus> *currentPortStatus) {
+    string reasons, path;
+
+    for (int i = 0; i < currentPortStatus->size(); i++) {
+        (*currentPortStatus)[i].supportsComplianceWarnings = false;
+    }
+    return Status::SUCCESS;
+}
+
 string appendRoleNodeHelper(const string &portName, PortRole::Tag tag) {
     string node(kTypecPath + portName);
 
@@ -508,11 +517,11 @@
             (*currentPortStatus)[i].usbDataStatus.push_back(UsbDataStatus::ENABLED);
 
             ALOGI("%d:%s connected:%d canChangeMode:%d canChagedata:%d canChangePower:%d "
-                "usbDataEnabled:%d",
-                i, port.first.c_str(), port.second,
-                (*currentPortStatus)[i].canChangeMode,
-                (*currentPortStatus)[i].canChangeDataRole,
-                (*currentPortStatus)[i].canChangePowerRole, 0);
+                  "usbDataEnabled:%d plugOrientation:%d",
+                  i, port.first.c_str(), port.second, (*currentPortStatus)[i].canChangeMode,
+                  (*currentPortStatus)[i].canChangeDataRole,
+                  (*currentPortStatus)[i].canChangePowerRole, 0,
+                  (*currentPortStatus)[i].plugOrientation);
         }
 
         return Status::SUCCESS;
@@ -527,6 +536,7 @@
     pthread_mutex_lock(&usb->mLock);
     status = getPortStatusHelper(currentPortStatus);
     queryMoistureDetectionStatus(currentPortStatus);
+    queryNonCompliantChargerStatus(currentPortStatus);
     if (usb->mCallback != NULL) {
         ScopedAStatus ret = usb->mCallback->notifyPortStatusChange(*currentPortStatus,
             status);
diff --git a/usb/aidl/default/android.hardware.usb-service.example.xml b/usb/aidl/default/android.hardware.usb-service.example.xml
index 6088194..c3f07f5 100644
--- a/usb/aidl/default/android.hardware.usb-service.example.xml
+++ b/usb/aidl/default/android.hardware.usb-service.example.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.usb</name>
-        <version>1</version>
+        <version>2</version>
         <interface>
             <name>IUsb</name>
             <instance>default</instance>
diff --git a/usb/aidl/vts/Android.bp b/usb/aidl/vts/Android.bp
index 00a7c93..d0e0eec 100644
--- a/usb/aidl/vts/Android.bp
+++ b/usb/aidl/vts/Android.bp
@@ -34,7 +34,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.usb-V1-ndk",
+        "android.hardware.usb-V2-ndk",
     ],
     test_suites: [
         "general-tests",
diff --git a/usb/aidl/vts/VtsAidlUsbTargetTest.cpp b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
index ea2f985..e9aa65b 100644
--- a/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
+++ b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
@@ -42,15 +42,22 @@
 
 #define TIMEOUT_PERIOD 10
 
+using ::aidl::android::hardware::usb::AltModeData;
 using ::aidl::android::hardware::usb::BnUsbCallback;
+using ::aidl::android::hardware::usb::ComplianceWarning;
+using ::aidl::android::hardware::usb::DisplayPortAltModePinAssignment;
+using ::aidl::android::hardware::usb::DisplayPortAltModeStatus;
 using ::aidl::android::hardware::usb::IUsb;
 using ::aidl::android::hardware::usb::IUsbCallback;
+using ::aidl::android::hardware::usb::LinkTrainingStatus;
+using ::aidl::android::hardware::usb::PlugOrientation;
 using ::aidl::android::hardware::usb::PortDataRole;
 using ::aidl::android::hardware::usb::PortMode;
 using ::aidl::android::hardware::usb::PortPowerRole;
 using ::aidl::android::hardware::usb::PortRole;
 using ::aidl::android::hardware::usb::PortStatus;
 using ::aidl::android::hardware::usb::Status;
+using ::aidl::android::hardware::usb::UsbDataStatus;
 
 using ::ndk::ScopedAStatus;
 using ::ndk::SpAIBinder;
@@ -247,6 +254,9 @@
   std::mutex usb_mtx;
   std::condition_variable usb_cv;
   int usb_count = 0;
+
+  // Stores usb version
+  int32_t usb_version;
 };
 
 /*
@@ -280,6 +290,42 @@
 }
 
 /*
+ * Query port status to Check to see whether only one of DISABLED_DOCK,
+ * DISABLED_DOCK_DEVICE_MODE, DISABLED_DOCK_HOST_MODE is set at the most.
+ * The callback parameters are checked to see if the transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, DisabledDataStatusCheck) {
+  int disabledCount = 0;
+
+  ALOGI("UsbAidlTest DataStatusCheck  start");
+  auto retVersion = usb->getInterfaceVersion(&usb_version);
+  ASSERT_TRUE(retVersion.isOk()) << retVersion;
+  if (usb_version < 2) {
+    ALOGI("UsbAidlTest skipping DataStatusCheck on older interface versions");
+    GTEST_SKIP();
+  }
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+  ALOGI("UsbAidlTest DataStatusCheck portName: %s", usb_last_port_status.portName.c_str());
+  if (usb_last_port_status.usbDataStatus.size() > 1) {
+    for (UsbDataStatus dataStatus : usb_last_port_status.usbDataStatus) {
+      if (dataStatus == UsbDataStatus::DISABLED_DOCK ||
+          dataStatus == UsbDataStatus::DISABLED_DOCK_DEVICE_MODE ||
+          dataStatus == UsbDataStatus::DISABLED_DOCK_HOST_MODE) {
+        disabledCount++;
+      }
+    }
+  }
+  EXPECT_GE(1, disabledCount);
+  ALOGI("UsbAidlTest DataStatusCheck end");
+}
+
+/*
  * Trying to switch a non-existent port should fail.
  * This test case tried to switch the port with empty
  * name which is expected to fail.
@@ -560,6 +606,135 @@
   ALOGI("UsbAidlTest resetUsbPort end");
 }
 
+/*
+ * Test charger compliance warning
+ * The test asserts that complianceWarnings is
+ * empty when the feature is not supported. i.e.
+ * supportsComplianceWarning is false.
+ */
+TEST_P(UsbAidlTest, nonCompliantChargerStatus) {
+  ALOGI("UsbAidlTest nonCompliantChargerStatus start");
+  auto retVersion = usb->getInterfaceVersion(&usb_version);
+  ASSERT_TRUE(retVersion.isOk()) << retVersion;
+  if (usb_version < 2) {
+    ALOGI("UsbAidlTest skipping nonCompliantChargerStatus on older interface versions");
+    GTEST_SKIP();
+  }
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  if (!usb_last_port_status.supportsComplianceWarnings) {
+    EXPECT_TRUE(usb_last_port_status.complianceWarnings.empty());
+  }
+
+  ALOGI("UsbAidlTest nonCompliantChargerStatus end");
+}
+
+/*
+ * Test charger compliance warning values
+ * The test asserts that complianceWarning values
+ * are valid.
+ */
+TEST_P(UsbAidlTest, nonCompliantChargerValues) {
+  ALOGI("UsbAidlTest nonCompliantChargerValues start");
+  auto retVersion = usb->getInterfaceVersion(&usb_version);
+  ASSERT_TRUE(retVersion.isOk()) << retVersion;
+  if (usb_version < 2) {
+    ALOGI("UsbAidlTest skipping nonCompliantChargerValues on older interface versions");
+    GTEST_SKIP();
+  }
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  // Current compliance values range from [1, 4]
+  if (usb_last_port_status.supportsComplianceWarnings) {
+    for (auto warning : usb_last_port_status.complianceWarnings) {
+      EXPECT_TRUE((int)warning >= (int)ComplianceWarning::OTHER);
+      EXPECT_TRUE((int)warning <= (int)ComplianceWarning::MISSING_RP);
+    }
+  }
+
+  ALOGI("UsbAidlTest nonCompliantChargerValues end");
+}
+
+/*
+ * Test PlugOrientation Values are within range in PortStatus
+ */
+TEST_P(UsbAidlTest, plugOrientationValues) {
+  ALOGI("UsbAidlTest plugOrientationValues start");
+  auto retVersion = usb->getInterfaceVersion(&usb_version);
+  ASSERT_TRUE(retVersion.isOk()) << retVersion;
+  if (usb_version < 2) {
+    ALOGI("UsbAidlTest skipping plugOrientationValues on older interface versions");
+    GTEST_SKIP();
+  }
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  EXPECT_TRUE((int)usb_last_port_status.plugOrientation >= (int)PlugOrientation::UNKNOWN);
+  EXPECT_TRUE((int)usb_last_port_status.plugOrientation <= (int)PlugOrientation::PLUGGED_FLIPPED);
+}
+
+/*
+ * Test DisplayPortAltMode Values when DisplayPort Alt Mode
+ * is active.
+ */
+TEST_P(UsbAidlTest, dpAltModeValues) {
+  ALOGI("UsbAidlTest dpAltModeValues start");
+  auto retVersion = usb->getInterfaceVersion(&usb_version);
+  ASSERT_TRUE(retVersion.isOk()) << retVersion;
+  if (usb_version < 2) {
+    ALOGI("UsbAidlTest skipping dpAltModeValues on older interface versions");
+    GTEST_SKIP();
+  }
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  // Discover DisplayPort Alt Mode
+  for (AltModeData altMode : usb_last_port_status.supportedAltModes) {
+    if (altMode.getTag() == AltModeData::displayPortAltModeData) {
+      AltModeData::DisplayPortAltModeData displayPortAltModeData =
+              altMode.get<AltModeData::displayPortAltModeData>();
+      EXPECT_TRUE((int)displayPortAltModeData.partnerSinkStatus >=
+                  (int)DisplayPortAltModeStatus::UNKNOWN);
+      EXPECT_TRUE((int)displayPortAltModeData.partnerSinkStatus <=
+                  (int)DisplayPortAltModeStatus::ENABLED);
+
+      EXPECT_TRUE((int)displayPortAltModeData.cableStatus >=
+                  (int)DisplayPortAltModeStatus::UNKNOWN);
+      EXPECT_TRUE((int)displayPortAltModeData.cableStatus <=
+                  (int)DisplayPortAltModeStatus::ENABLED);
+
+      EXPECT_TRUE((int)displayPortAltModeData.pinAssignment >=
+                  (int)DisplayPortAltModePinAssignment::NONE);
+      EXPECT_TRUE((int)displayPortAltModeData.pinAssignment <=
+                  (int)DisplayPortAltModePinAssignment::F);
+
+      EXPECT_TRUE((int)displayPortAltModeData.linkTrainingStatus >=
+                  (int)LinkTrainingStatus::UNKNOWN);
+      EXPECT_TRUE((int)displayPortAltModeData.pinAssignment <= (int)LinkTrainingStatus::FAILURE);
+    }
+  }
+
+  ALOGI("UsbAidlTest dpAltModeValues end");
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbAidlTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, UsbAidlTest,
diff --git a/usb/apex/Android.bp b/usb/apex/Android.bp
new file mode 100644
index 0000000..765aa21
--- /dev/null
+++ b/usb/apex/Android.bp
@@ -0,0 +1,60 @@
+// 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: ["hardware_interfaces_license"],
+}
+
+apex_key {
+    name: "com.android.hardware.usb.key",
+    public_key: "com.android.hardware.usb.avbpubkey",
+    private_key: "com.android.hardware.usb.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.usb.certificate",
+    certificate: "com.android.hardware.usb",
+}
+
+apex {
+    name: "com.android.hardware.usb",
+    manifest: "manifest.json",
+    file_contexts: "file_contexts",
+    key: "com.android.hardware.usb.key",
+    certificate: ":com.android.hardware.usb.certificate",
+    updatable: false,
+    soc_specific: true,
+    use_vndk_as_stable: true,
+    binaries: ["android.hardware.usb-service.example"],
+    prebuilts: [
+        "com.android.hardware.usb.rc", // init .rc
+        "android.hardware.usb.accessory.prebuilt.xml",
+        "android.hardware.usb.host.prebuilt.xml",
+    ],
+    vintf_fragments: [":android.hardware.usb-service.example.xml"],
+}
+
+// Replace the binary path from /vendor/bin to /apex/{name}/bin in the init .rc file
+genrule {
+    name: "com.android.hardware.usb.rc-gen",
+    srcs: [":android.hardware.usb-service.example.rc"],
+    out: ["com.android.hardware.usb.rc"],
+    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.usb/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "com.android.hardware.usb.rc",
+    src: ":com.android.hardware.usb.rc-gen",
+    installable: false,
+}
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey b/usb/apex/com.android.hardware.usb.avbpubkey
similarity index 100%
rename from usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
rename to usb/apex/com.android.hardware.usb.avbpubkey
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pem b/usb/apex/com.android.hardware.usb.pem
similarity index 100%
rename from usb/1.0/default/apex/com.android.hardware.usb.pem
rename to usb/apex/com.android.hardware.usb.pem
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pk8 b/usb/apex/com.android.hardware.usb.pk8
similarity index 100%
rename from usb/1.0/default/apex/com.android.hardware.usb.pk8
rename to usb/apex/com.android.hardware.usb.pk8
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.x509.pem b/usb/apex/com.android.hardware.usb.x509.pem
similarity index 100%
rename from usb/1.0/default/apex/com.android.hardware.usb.x509.pem
rename to usb/apex/com.android.hardware.usb.x509.pem
diff --git a/usb/apex/file_contexts b/usb/apex/file_contexts
new file mode 100644
index 0000000..f223a56
--- /dev/null
+++ b/usb/apex/file_contexts
@@ -0,0 +1,5 @@
+(/.*)?                                         u:object_r:vendor_file:s0
+# Permission XMLs
+/etc/permissions(/.*)?                         u:object_r:vendor_configs_file:s0
+# binary
+/bin/hw/android\.hardware\.usb-service\.example        u:object_r:hal_usb_default_exec:s0
\ No newline at end of file
diff --git a/usb/apex/manifest.json b/usb/apex/manifest.json
new file mode 100644
index 0000000..1a41b90
--- /dev/null
+++ b/usb/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+    "name": "com.android.hardware.usb",
+    "version": 1
+}
diff --git a/usb/gadget/1.1/default/lib/MonitorFfs.cpp b/usb/gadget/1.1/default/lib/MonitorFfs.cpp
index 0cdf038..6d09a8a 100644
--- a/usb/gadget/1.1/default/lib/MonitorFfs.cpp
+++ b/usb/gadget/1.1/default/lib/MonitorFfs.cpp
@@ -59,9 +59,9 @@
 
     if (addEpollFd(epollFd, eventFd) == -1) abort();
 
-    mEpollFd = move(epollFd);
-    mInotifyFd = move(inotifyFd);
-    mEventFd = move(eventFd);
+    mEpollFd = std::move(epollFd);
+    mInotifyFd = std::move(inotifyFd);
+    mEventFd = std::move(eventFd);
     gadgetPullup = false;
 }
 
diff --git a/usb/gadget/1.2/default/lib/MonitorFfs.cpp b/usb/gadget/1.2/default/lib/MonitorFfs.cpp
index 0cdf038..6d09a8a 100644
--- a/usb/gadget/1.2/default/lib/MonitorFfs.cpp
+++ b/usb/gadget/1.2/default/lib/MonitorFfs.cpp
@@ -59,9 +59,9 @@
 
     if (addEpollFd(epollFd, eventFd) == -1) abort();
 
-    mEpollFd = move(epollFd);
-    mInotifyFd = move(inotifyFd);
-    mEventFd = move(eventFd);
+    mEpollFd = std::move(epollFd);
+    mInotifyFd = std::move(inotifyFd);
+    mEventFd = std::move(eventFd);
     gadgetPullup = false;
 }
 
diff --git a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
index fa50821..0924da7 100644
--- a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
+++ b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
@@ -170,7 +170,6 @@
 
     if ((functions & GadgetFunction::RNDIS) != 0) {
         ALOGI("setCurrentUsbFunctions rndis");
-        if (linkFunction("gsi.rndis", (*functionCount)++)) return Status::ERROR;
         std::string rndisFunction = GetProperty(kVendorRndisConfig, "");
         if (rndisFunction != "") {
             if (linkFunction(rndisFunction.c_str(), (*functionCount)++)) return Status::ERROR;
diff --git a/usb/gadget/aidl/Android.bp b/usb/gadget/aidl/Android.bp
new file mode 100644
index 0000000..eb1996b
--- /dev/null
+++ b/usb/gadget/aidl/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.usb.gadget",
+    vendor_available: true,
+    srcs: ["android/hardware/usb/gadget/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/.hash b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/.hash
new file mode 100644
index 0000000..ea51eec
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/.hash
@@ -0,0 +1 @@
+cb628c69682659911bca5c1d04042adba7f0de4b
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/GadgetFunction.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/GadgetFunction.aidl
new file mode 100644
index 0000000..0cf5844
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/GadgetFunction.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@VintfStability
+parcelable GadgetFunction {
+  const long NONE = 0;
+  const long ADB = 1;
+  const long ACCESSORY = (1 << 1) /* 2 */;
+  const long MTP = (1 << 2) /* 4 */;
+  const long MIDI = (1 << 3) /* 8 */;
+  const long PTP = (1 << 4) /* 16 */;
+  const long RNDIS = (1 << 5) /* 32 */;
+  const long AUDIO_SOURCE = (1 << 6) /* 64 */;
+  const long UVC = (1 << 7) /* 128 */;
+  const long NCM = (1 << 10) /* 1024 */;
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/IUsbGadget.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/IUsbGadget.aidl
new file mode 100644
index 0000000..b5c0b5c
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/IUsbGadget.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@VintfStability
+interface IUsbGadget {
+  oneway void setCurrentUsbFunctions(in long functions, in android.hardware.usb.gadget.IUsbGadgetCallback callback, in long timeoutMs, long transactionId);
+  oneway void getCurrentUsbFunctions(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
+  oneway void getUsbSpeed(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
+  oneway void reset(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/IUsbGadgetCallback.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
new file mode 100644
index 0000000..b2b0e5a
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@VintfStability
+interface IUsbGadgetCallback {
+  oneway void setCurrentUsbFunctionsCb(in long functions, in android.hardware.usb.gadget.Status status, long transactionId);
+  oneway void getCurrentUsbFunctionsCb(in long functions, in android.hardware.usb.gadget.Status status, long transactionId);
+  oneway void getUsbSpeedCb(in android.hardware.usb.gadget.UsbSpeed speed, long transactionId);
+  oneway void resetCb(in android.hardware.usb.gadget.Status status, long transactionId);
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/Status.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/Status.aidl
new file mode 100644
index 0000000..bdcf685
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/Status.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@Backing(type="int") @VintfStability
+enum Status {
+  SUCCESS = 0,
+  ERROR = 1,
+  FUNCTIONS_APPLIED = 2,
+  FUNCTIONS_NOT_APPLIED = 3,
+  CONFIGURATION_NOT_SUPPORTED = 4,
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/UsbSpeed.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/UsbSpeed.aidl
new file mode 100644
index 0000000..fea3509
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/1/android/hardware/usb/gadget/UsbSpeed.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@Backing(type="int") @VintfStability
+enum UsbSpeed {
+  UNKNOWN = (-1) /* -1 */,
+  LOWSPEED = 0,
+  FULLSPEED = 1,
+  HIGHSPEED = 2,
+  SUPERSPEED = 3,
+  SUPERSPEED_10Gb = 4,
+  SUPERSPEED_20Gb = 5,
+  USB4_GEN2_10Gb = 6,
+  USB4_GEN2_20Gb = 7,
+  USB4_GEN3_20Gb = 8,
+  USB4_GEN3_40Gb = 9,
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl
new file mode 100644
index 0000000..78b79e4
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@VintfStability
+parcelable GadgetFunction {
+  const long NONE = 0;
+  const long ADB = 1;
+  const long ACCESSORY = (1 << 1);
+  const long MTP = (1 << 2);
+  const long MIDI = (1 << 3);
+  const long PTP = (1 << 4);
+  const long RNDIS = (1 << 5);
+  const long AUDIO_SOURCE = (1 << 6);
+  const long UVC = (1 << 7);
+  const long NCM = (1 << 10);
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl
new file mode 100644
index 0000000..b5c0b5c
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@VintfStability
+interface IUsbGadget {
+  oneway void setCurrentUsbFunctions(in long functions, in android.hardware.usb.gadget.IUsbGadgetCallback callback, in long timeoutMs, long transactionId);
+  oneway void getCurrentUsbFunctions(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
+  oneway void getUsbSpeed(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
+  oneway void reset(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
new file mode 100644
index 0000000..b2b0e5a
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@VintfStability
+interface IUsbGadgetCallback {
+  oneway void setCurrentUsbFunctionsCb(in long functions, in android.hardware.usb.gadget.Status status, long transactionId);
+  oneway void getCurrentUsbFunctionsCb(in long functions, in android.hardware.usb.gadget.Status status, long transactionId);
+  oneway void getUsbSpeedCb(in android.hardware.usb.gadget.UsbSpeed speed, long transactionId);
+  oneway void resetCb(in android.hardware.usb.gadget.Status status, long transactionId);
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/Status.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/Status.aidl
new file mode 100644
index 0000000..bdcf685
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/Status.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@Backing(type="int") @VintfStability
+enum Status {
+  SUCCESS = 0,
+  ERROR = 1,
+  FUNCTIONS_APPLIED = 2,
+  FUNCTIONS_NOT_APPLIED = 3,
+  CONFIGURATION_NOT_SUPPORTED = 4,
+}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl
new file mode 100644
index 0000000..7d4fa17
--- /dev/null
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb.gadget;
+@Backing(type="int") @VintfStability
+enum UsbSpeed {
+  UNKNOWN = (-1),
+  LOWSPEED = 0,
+  FULLSPEED = 1,
+  HIGHSPEED = 2,
+  SUPERSPEED = 3,
+  SUPERSPEED_10Gb = 4,
+  SUPERSPEED_20Gb = 5,
+  USB4_GEN2_10Gb = 6,
+  USB4_GEN2_20Gb = 7,
+  USB4_GEN3_20Gb = 8,
+  USB4_GEN3_40Gb = 9,
+}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl
new file mode 100644
index 0000000..dd7ee37
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb.gadget;
+
+@VintfStability
+parcelable GadgetFunction {
+    /**
+     * Removes all the functions and pulls down the gadget.
+     */
+    const long NONE = 0;
+    /**
+     * Android Debug Bridge function.
+     */
+    const long ADB = 1;
+    /**
+     * Android open accessory protocol function.
+     */
+    const long ACCESSORY = 1 << 1;
+    /**
+     * Media Transfer protocol function.
+     */
+    const long MTP = 1 << 2;
+    /**
+     * Peripheral mode USB Midi function.
+     */
+    const long MIDI = 1 << 3;
+    /**
+     * Picture transfer protocol function.
+     */
+    const long PTP = 1 << 4;
+    /**
+     * Tethering function.
+     */
+    const long RNDIS = 1 << 5;
+    /**
+     * AOAv2.0 - Audio Source function.
+     */
+    const long AUDIO_SOURCE = 1 << 6;
+    /**
+     * UVC - Universal Video Class function.
+     */
+    const long UVC = 1 << 7;
+    /**
+     * NCM - NCM function.
+     */
+    const long NCM = 1 << 10;
+}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl
new file mode 100644
index 0000000..a0c61ae
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb.gadget;
+
+import android.hardware.usb.gadget.IUsbGadgetCallback;
+
+@VintfStability
+oneway interface IUsbGadget {
+    /**
+     * This function is used to set the current USB gadget configuration.
+     * Usb gadget needs to be reset if an USB configuration is already.
+     *
+     * @param functions The GadgetFunction bitmap. See GadgetFunction for
+     *                  the value of each bit.
+     * @param callback IUsbGadgetCallback::setCurrentUsbFunctionsCb used to
+     *                 propagate back the status.
+     * @param timeoutMs The maximum time (in milliseconds) within which the
+     *                IUsbGadgetCallback needs to be returned.
+     * @param transactionId ID to be used when invoking the callback.
+     *
+     */
+    void setCurrentUsbFunctions(in long functions, in IUsbGadgetCallback callback,
+            in long timeoutMs, long transactionId);
+
+    /**
+     * This function is used to query the USB functions included in the
+     * current USB configuration.
+     *
+     * @param callback IUsbGadgetCallback::getCurrentUsbFunctionsCb used to
+     *                 propagate the current functions list.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void getCurrentUsbFunctions(in IUsbGadgetCallback callback, long transactionId);
+
+    /**
+     * The function is used to query current USB speed.
+     *
+     * @param callback IUsbGadgetCallback::getUsbSpeedCb used to propagate
+     *                 current USB speed.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void getUsbSpeed(in IUsbGadgetCallback callback, long transactionId);
+
+    /**
+     * This function is used to reset USB gadget driver.
+     * Performs USB data connection reset. The connection will disconnect and
+     * reconnect.
+     *
+     * @param callback IUsbGadgetCallback::resetCb used to propagate
+     *                 the result of requesting resetUsbGadget.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void reset(in IUsbGadgetCallback callback, long transactionId);
+}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
new file mode 100644
index 0000000..cd9a662
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb.gadget;
+
+import android.hardware.usb.gadget.Status;
+import android.hardware.usb.gadget.UsbSpeed;
+
+@VintfStability
+oneway interface IUsbGadgetCallback {
+    /**
+     * Callback function used to propagate the status of configuration
+     * switch to the caller.
+     *
+     * @param functions list of functions defined by GadgetFunction
+     *                  included in the current USB gadget composition.
+     * @param status SUCCESS when the functions are applied.
+     *               FUNCTIONS_NOT_SUPPORTED when the configuration is
+     *                                       not supported.
+     *               ERROR otherwise.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void setCurrentUsbFunctionsCb(in long functions, in Status status, long transactionId);
+
+    /**
+     * Callback function used to propagate the current USB gadget
+     * configuration.
+     * @param functions The GadgetFunction bitmap. See GadgetFunction for
+     *                  the value of each bit.
+     * @param status FUNCTIONS_APPLIED when list of functions have been
+     *                                 applied.
+     *               FUNCTIONS_NOT_APPLIED when the functions have not
+     *                                     been applied.
+     *               ERROR otherwise.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void getCurrentUsbFunctionsCb(in long functions, in Status status, long transactionId);
+
+    /**
+     * Used to convey the current USB speed to the caller.
+     * Must be called either when USB state changes due to USB enumeration or
+     * when caller requested for USB speed through getUsbSpeed.
+     *
+     * @param speed USB Speed defined by UsbSpeed showed current USB
+     *              connection speed.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void getUsbSpeedCb(in UsbSpeed speed, long transactionId);
+
+    /**
+     * Callback function used to propagate the result of requesting
+     * resetUsbGadget.
+     * @param status SUCCESS if current request succeeded. FAILURE otherwise.
+     * @param transactionId current transactionId sent during reset request.
+     */
+    void resetCb(in Status status, long transactionId);
+}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/Status.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/Status.aidl
new file mode 100644
index 0000000..8d8c3e3
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/Status.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb.gadget;
+
+@VintfStability
+@Backing(type="int")
+enum Status {
+    SUCCESS = 0,
+    /**
+     * Error value when the HAL operation fails for reasons not listed here.
+     */
+    ERROR = 1,
+    /**
+     * USB configuration applied successfully.
+     */
+    FUNCTIONS_APPLIED = 2,
+    /**
+     * USB confgiuration failed to apply.
+     */
+    FUNCTIONS_NOT_APPLIED = 3,
+    /**
+     * USB configuration not supported.
+     */
+    CONFIGURATION_NOT_SUPPORTED = 4,
+}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl
new file mode 100644
index 0000000..2a3fb93
--- /dev/null
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb.gadget;
+
+@VintfStability
+@Backing(type="int")
+enum UsbSpeed {
+    /**
+     * UNKNOWN - Not Connected or Unsupported Speed
+     */
+    UNKNOWN = -1,
+
+    /**
+     * USB Low Speed
+     */
+    LOWSPEED = 0,
+
+    /**
+     * USB Full Speed
+     */
+    FULLSPEED = 1,
+
+    /**
+     * USB High Speed
+     */
+    HIGHSPEED = 2,
+
+    /**
+     * USB Super Speed
+     */
+    SUPERSPEED = 3,
+
+    /**
+     * USB Super Speed 10Gbps
+     */
+    SUPERSPEED_10Gb = 4,
+
+    /**
+     * USB Super Speed 20Gbps
+     */
+    SUPERSPEED_20Gb = 5,
+
+    /**
+     * USB4 Gen2 x 1 (10Gbps)
+     */
+    USB4_GEN2_10Gb = 6,
+
+    /**
+     * USB4 Gen2 x 2 (20Gbps)
+     */
+    USB4_GEN2_20Gb = 7,
+
+    /**
+     * USB4 Gen3 x 1 (20Gbps)
+     */
+    USB4_GEN3_20Gb = 8,
+
+    /**
+     * USB4 Gen3 x 2 (40Gbps)
+     */
+    USB4_GEN3_40Gb = 9,
+}
diff --git a/usb/gadget/aidl/default/Android.bp b/usb/gadget/aidl/default/Android.bp
new file mode 100644
index 0000000..2ea0e12
--- /dev/null
+++ b/usb/gadget/aidl/default/Android.bp
@@ -0,0 +1,47 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package {
+    // 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_binary {
+    name: "android.hardware.usb.gadget-service.example",
+    relative_install_path: "hw",
+    init_rc: ["android.hardware.usb.gadget-service.example.rc"],
+    vintf_fragments: [
+        "android.hardware.usb.gadget-service.example.xml",
+    ],
+    vendor: true,
+    srcs: ["service_gadget.cpp", "UsbGadget.cpp"],
+    cflags: ["-Wall", "-Werror"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+        "libhardware",
+	"android.hardware.usb.gadget-V1-ndk",
+	"android.frameworks.stats-V1-ndk",
+        "libcutils",
+	"libbinder_ndk",
+    ],
+}
diff --git a/usb/gadget/aidl/default/UsbGadget.cpp b/usb/gadget/aidl/default/UsbGadget.cpp
new file mode 100644
index 0000000..72d59c1
--- /dev/null
+++ b/usb/gadget/aidl/default/UsbGadget.cpp
@@ -0,0 +1,306 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.usb.gadget.aidl-service"
+
+#include "UsbGadget.h"
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/inotify.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <aidl/android/frameworks/stats/IStats.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+string enabledPath;
+constexpr char kHsi2cPath[] = "/sys/devices/platform/10d50000.hsi2c";
+constexpr char kI2CPath[] = "/sys/devices/platform/10d50000.hsi2c/i2c-";
+constexpr char kAccessoryLimitCurrent[] = "i2c-max77759tcpc/usb_limit_accessory_current";
+constexpr char kAccessoryLimitCurrentEnable[] = "i2c-max77759tcpc/usb_limit_accessory_enable";
+
+UsbGadget::UsbGadget() : mGadgetIrqPath("") {
+}
+
+Status UsbGadget::getUsbGadgetIrqPath() {
+    std::string irqs;
+    size_t read_pos = 0;
+    size_t found_pos = 0;
+
+    if (!ReadFileToString(kProcInterruptsPath, &irqs)) {
+        ALOGE("cannot read all interrupts");
+        return Status::ERROR;
+    }
+
+    while (true) {
+        found_pos = irqs.find_first_of("\n", read_pos);
+        if (found_pos == std::string::npos) {
+            ALOGI("the string of all interrupts is unexpected");
+            return Status::ERROR;
+        }
+
+        std::string single_irq = irqs.substr(read_pos, found_pos - read_pos);
+
+        if (single_irq.find("dwc3", 0) != std::string::npos) {
+            unsigned int dwc3_irq_number;
+            size_t dwc3_pos = single_irq.find_first_of(":");
+            if (!ParseUint(single_irq.substr(0, dwc3_pos), &dwc3_irq_number)) {
+                ALOGI("unknown IRQ strings");
+                return Status::ERROR;
+            }
+
+            mGadgetIrqPath = kProcIrqPath + single_irq.substr(0, dwc3_pos) + kSmpAffinityList;
+            break;
+        }
+
+        if (found_pos == irqs.npos) {
+            ALOGI("USB gadget doesn't start");
+            return Status::ERROR;
+        }
+
+        read_pos = found_pos + 1;
+    }
+
+    return Status::SUCCESS;
+}
+
+void currentFunctionsAppliedCallback(bool functionsApplied, void *payload) {
+    UsbGadget *gadget = (UsbGadget *)payload;
+    gadget->mCurrentUsbFunctionsApplied = functionsApplied;
+}
+
+ScopedAStatus UsbGadget::getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback>& callback,
+                                                int64_t in_transactionId) {
+    if (callback == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
+    ScopedAStatus ret = callback->getCurrentUsbFunctionsCb(
+        mCurrentUsbFunctions,
+        mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED,
+	in_transactionId);
+    if (!ret.isOk())
+        ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.getDescription().c_str());
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus UsbGadget::getUsbSpeed(const shared_ptr<IUsbGadgetCallback> &callback,
+	int64_t in_transactionId) {
+    std::string current_speed;
+    if (ReadFileToString(SPEED_PATH, &current_speed)) {
+        current_speed = Trim(current_speed);
+        ALOGI("current USB speed is %s", current_speed.c_str());
+        if (current_speed == "low-speed")
+            mUsbSpeed = UsbSpeed::LOWSPEED;
+        else if (current_speed == "full-speed")
+            mUsbSpeed = UsbSpeed::FULLSPEED;
+        else if (current_speed == "high-speed")
+            mUsbSpeed = UsbSpeed::HIGHSPEED;
+        else if (current_speed == "super-speed")
+            mUsbSpeed = UsbSpeed::SUPERSPEED;
+        else if (current_speed == "super-speed-plus")
+            mUsbSpeed = UsbSpeed::SUPERSPEED_10Gb;
+        else if (current_speed == "UNKNOWN")
+            mUsbSpeed = UsbSpeed::UNKNOWN;
+        else
+            mUsbSpeed = UsbSpeed::UNKNOWN;
+    } else {
+        ALOGE("Fail to read current speed");
+        mUsbSpeed = UsbSpeed::UNKNOWN;
+    }
+
+    if (callback) {
+        ScopedAStatus ret = callback->getUsbSpeedCb(mUsbSpeed, in_transactionId);
+
+        if (!ret.isOk())
+            ALOGE("Call to getUsbSpeedCb failed %s", ret.getDescription().c_str());
+    }
+
+    return ScopedAStatus::ok();
+}
+
+Status UsbGadget::tearDownGadget() {
+    return Status::SUCCESS;
+}
+
+ScopedAStatus UsbGadget::reset(const shared_ptr<IUsbGadgetCallback> &callback,
+        int64_t in_transactionId) {
+    if (callback)
+        callback->resetCb(Status::SUCCESS, in_transactionId);
+    return ScopedAStatus::ok();
+}
+
+Status UsbGadget::setupFunctions(long functions,
+	const shared_ptr<IUsbGadgetCallback> &callback, uint64_t timeout,
+	int64_t in_transactionId) {
+    bool ffsEnabled = false;
+    if (timeout == 0) {
+	ALOGI("timeout not setup");
+    }
+
+    if ((functions & GadgetFunction::ADB) != 0) {
+        ffsEnabled = true;
+    }
+
+    if ((functions & GadgetFunction::NCM) != 0) {
+        ALOGI("setCurrentUsbFunctions ncm");
+    }
+
+    // Pull up the gadget right away when there are no ffs functions.
+    if (!ffsEnabled) {
+        mCurrentUsbFunctionsApplied = true;
+        if (callback)
+            callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
+        return Status::SUCCESS;
+    }
+
+    return Status::SUCCESS;
+}
+
+Status getI2cBusHelper(string *name) {
+    DIR *dp;
+
+    dp = opendir(kHsi2cPath);
+    if (dp != NULL) {
+        struct dirent *ep;
+
+        while ((ep = readdir(dp))) {
+            if (ep->d_type == DT_DIR) {
+                if (string::npos != string(ep->d_name).find("i2c-")) {
+                    std::strtok(ep->d_name, "-");
+                    *name = std::strtok(NULL, "-");
+                }
+            }
+        }
+        closedir(dp);
+        return Status::SUCCESS;
+    }
+
+    ALOGE("Failed to open %s", kHsi2cPath);
+    return Status::ERROR;
+}
+
+ScopedAStatus UsbGadget::setCurrentUsbFunctions(int64_t functions,
+                                               const shared_ptr<IUsbGadgetCallback> &callback,
+					       int64_t timeoutMs,
+					       int64_t in_transactionId) {
+    std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
+    std::string current_usb_power_operation_mode, current_usb_type;
+    std::string usb_limit_sink_enable;
+
+    string accessoryCurrentLimitEnablePath, accessoryCurrentLimitPath, path;
+
+    mCurrentUsbFunctions = functions;
+    mCurrentUsbFunctionsApplied = false;
+
+    getI2cBusHelper(&path);
+    accessoryCurrentLimitPath = kI2CPath + path + "/" + kAccessoryLimitCurrent;
+    accessoryCurrentLimitEnablePath = kI2CPath + path + "/" + kAccessoryLimitCurrentEnable;
+
+    // Get the gadget IRQ number before tearDownGadget()
+    if (mGadgetIrqPath.empty())
+        getUsbGadgetIrqPath();
+
+    // Unlink the gadget and stop the monitor if running.
+    Status status = tearDownGadget();
+    if (status != Status::SUCCESS) {
+        goto error;
+    }
+
+    ALOGI("Returned from tearDown gadget");
+
+    // Leave the gadget pulled down to give time for the host to sense disconnect.
+    //usleep(kDisconnectWaitUs);
+
+    if (functions == GadgetFunction::NONE) {
+        if (callback == NULL)
+            return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                -1, "callback == NULL");
+        ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                -1, "Error while calling setCurrentUsbFunctionsCb");
+    }
+
+    status = setupFunctions(functions, callback, timeoutMs, in_transactionId);
+    if (status != Status::SUCCESS) {
+        goto error;
+    }
+
+    if (functions & GadgetFunction::NCM) {
+        if (!mGadgetIrqPath.empty()) {
+            if (!WriteStringToFile(BIG_CORE, mGadgetIrqPath))
+                ALOGI("Cannot move gadget IRQ to big core, path:%s", mGadgetIrqPath.c_str());
+        }
+    } else {
+        if (!mGadgetIrqPath.empty()) {
+            if (!WriteStringToFile(MEDIUM_CORE, mGadgetIrqPath))
+                ALOGI("Cannot move gadget IRQ to medium core, path:%s", mGadgetIrqPath.c_str());
+        }
+    }
+
+    if (ReadFileToString(CURRENT_USB_TYPE_PATH, &current_usb_type))
+        current_usb_type = Trim(current_usb_type);
+
+    if (ReadFileToString(CURRENT_USB_POWER_OPERATION_MODE_PATH, &current_usb_power_operation_mode))
+        current_usb_power_operation_mode = Trim(current_usb_power_operation_mode);
+
+    if (functions & GadgetFunction::ACCESSORY &&
+        current_usb_type == "Unknown SDP [CDP] DCP" &&
+        (current_usb_power_operation_mode == "default" ||
+        current_usb_power_operation_mode == "1.5A")) {
+        if (!WriteStringToFile("1300000", accessoryCurrentLimitPath)) {
+            ALOGI("Write 1.3A to limit current fail");
+        } else {
+            if (!WriteStringToFile("1", accessoryCurrentLimitEnablePath)) {
+                ALOGI("Enable limit current fail");
+            }
+        }
+    } else {
+        if (!WriteStringToFile("0", accessoryCurrentLimitEnablePath))
+            ALOGI("unvote accessory limit current failed");
+    }
+
+    ALOGI("Usb Gadget setcurrent functions called successfully");
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                -1, "Usb Gadget setcurrent functions called successfully");
+
+
+error:
+    ALOGI("Usb Gadget setcurrent functions failed");
+    if (callback == NULL)
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                -1, "Usb Gadget setcurrent functions failed");
+    ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(functions, status, in_transactionId);
+    if (!ret.isOk())
+        ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                -1, "Error while calling setCurrentUsbFunctionsCb");
+}
+}  // namespace gadget
+}  // namespace usb
+}  // namespace hardware
+}  // namespace android
+}  // aidl
diff --git a/usb/gadget/aidl/default/UsbGadget.h b/usb/gadget/aidl/default/UsbGadget.h
new file mode 100644
index 0000000..5eaaa48
--- /dev/null
+++ b/usb/gadget/aidl/default/UsbGadget.h
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android-base/file.h>
+#include <android-base/properties.h>
+#include <android-base/unique_fd.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+#include <aidl/android/hardware/usb/gadget/BnUsbGadget.h>
+#include <aidl/android/hardware/usb/gadget/BnUsbGadgetCallback.h>
+#include <aidl/android/hardware/usb/gadget/GadgetFunction.h>
+#include <aidl/android/hardware/usb/gadget/IUsbGadget.h>
+#include <aidl/android/hardware/usb/gadget/IUsbGadgetCallback.h>
+#include <sched.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <utils/Log.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <string>
+#include <thread>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace usb {
+namespace gadget {
+
+using ::aidl::android::hardware::usb::gadget::GadgetFunction;
+using ::aidl::android::hardware::usb::gadget::IUsbGadgetCallback;
+using ::aidl::android::hardware::usb::gadget::IUsbGadget;
+using ::aidl::android::hardware::usb::gadget::Status;
+using ::aidl::android::hardware::usb::gadget::UsbSpeed;
+using ::android::base::GetProperty;
+using ::android::base::SetProperty;
+using ::android::base::ParseUint;
+using ::android::base::unique_fd;
+using ::android::base::ReadFileToString;
+using ::android::base::Trim;
+using ::android::base::WriteStringToFile;
+using ::ndk::ScopedAStatus;
+using ::std::shared_ptr;
+using ::std::string;
+
+constexpr char kGadgetName[] = "11110000.dwc3";
+constexpr char kProcInterruptsPath[] = "/proc/interrupts";
+constexpr char kProcIrqPath[] = "/proc/irq/";
+constexpr char kSmpAffinityList[] = "/smp_affinity_list";
+#ifndef UDC_PATH
+#define UDC_PATH "/sys/class/udc/11110000.dwc3/"
+#endif
+//static MonitorFfs monitorFfs(kGadgetName);
+
+#define SPEED_PATH UDC_PATH "current_speed"
+
+#define BIG_CORE "6"
+#define MEDIUM_CORE "4"
+
+#define POWER_SUPPLY_PATH	"/sys/class/power_supply/usb/"
+#define USB_PORT0_PATH		"/sys/class/typec/port0/"
+
+#define CURRENT_MAX_PATH			POWER_SUPPLY_PATH	"current_max"
+#define CURRENT_USB_TYPE_PATH			POWER_SUPPLY_PATH	"usb_type"
+#define CURRENT_USB_POWER_OPERATION_MODE_PATH	USB_PORT0_PATH		"power_operation_mode"
+
+struct UsbGadget : public BnUsbGadget {
+    UsbGadget();
+
+    // Makes sure that only one request is processed at a time.
+    std::mutex mLockSetCurrentFunction;
+    std::string mGadgetIrqPath;
+    long mCurrentUsbFunctions;
+    bool mCurrentUsbFunctionsApplied;
+    UsbSpeed mUsbSpeed;
+
+    ScopedAStatus setCurrentUsbFunctions(int64_t functions,
+            const shared_ptr<IUsbGadgetCallback> &callback,
+            int64_t timeoutMs, int64_t in_transactionId) override;
+
+    ScopedAStatus getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback> &callback,
+	    int64_t in_transactionId) override;
+
+    ScopedAStatus reset(const shared_ptr<IUsbGadgetCallback> &callback,
+            int64_t in_transactionId) override;
+
+    ScopedAStatus getUsbSpeed(const shared_ptr<IUsbGadgetCallback> &callback,
+	    int64_t in_transactionId) override;
+
+  private:
+    Status tearDownGadget();
+    Status getUsbGadgetIrqPath();
+    Status setupFunctions(long functions, const shared_ptr<IUsbGadgetCallback> &callback,
+            uint64_t timeout, int64_t in_transactionId);
+};
+
+}  // namespace gadget
+}  // namespace usb
+}  // namespace hardware
+}  // namespace android
+}  // aidl
diff --git a/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.rc b/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.rc
new file mode 100644
index 0000000..b2a8cc0
--- /dev/null
+++ b/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.rc
@@ -0,0 +1,4 @@
+service vendor.usb_gadget_default /vendor/bin/hw/android.hardware.usb.gadget-service.example
+    class hal
+    user system
+    group system
diff --git a/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.xml b/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.xml
new file mode 100644
index 0000000..e7eebc3
--- /dev/null
+++ b/usb/gadget/aidl/default/android.hardware.usb.gadget-service.example.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.usb.gadget</name>
+        <version>1</version>
+        <interface>
+            <name>IUsbGadget</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/usb/gadget/aidl/default/service_gadget.cpp b/usb/gadget/aidl/default/service_gadget.cpp
new file mode 100644
index 0000000..7efbadd
--- /dev/null
+++ b/usb/gadget/aidl/default/service_gadget.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include "UsbGadget.h"
+using ::aidl::android::hardware::usb::gadget::UsbGadget;
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<UsbGadget> usbgadget = ndk::SharedRefBase::make<UsbGadget>();
+    const std::string instance = std::string() + UsbGadget::descriptor + "/default";
+    binder_status_t status = AServiceManager_addService(usbgadget->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+    ABinderProcess_joinThreadPool();
+    return -1;
+}
diff --git a/uwb/aidl/Android.bp b/uwb/aidl/Android.bp
index cc61046..3e71913 100755
--- a/uwb/aidl/Android.bp
+++ b/uwb/aidl/Android.bp
@@ -18,12 +18,13 @@
     backend: {
         java: {
             sdk_version: "module_Tiramisu",
-            enabled: false,
+            enabled: true,
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.uwb",
+            ],
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apex_available: [
                 "//apex_available:platform",
                 "com.android.uwb",
@@ -50,6 +51,7 @@
 
 aidl_interface {
     name: "android.hardware.uwb.fira_android",
+    owner: "google",
     vendor_available: true,
     srcs: ["android/hardware/uwb/fira_android/*.aidl"],
     stability: "vintf",
@@ -74,6 +76,11 @@
             version: "1",
             imports: [],
         },
+        {
+            version: "2",
+            imports: [],
+        },
+
     ],
 
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/.hash b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/.hash
new file mode 100644
index 0000000..42772bb
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/.hash
@@ -0,0 +1 @@
+590d9f45625a2c353011cf85f18d1d08593b8a0a
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
new file mode 100644
index 0000000..0cc01c5
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorCapabilityTlvTypes {
+  SUPPORTED_POWER_STATS_QUERY = 192,
+  CCC_SUPPORTED_CHAPS_PER_SLOT = 160,
+  CCC_SUPPORTED_SYNC_CODES = 161,
+  CCC_SUPPORTED_HOPPING_CONFIG_MODES_AND_SEQUENCES = 162,
+  CCC_SUPPORTED_CHANNELS = 163,
+  CCC_SUPPORTED_VERSIONS = 164,
+  CCC_SUPPORTED_UWB_CONFIGS = 165,
+  CCC_SUPPORTED_PULSE_SHAPE_COMBOS = 166,
+  CCC_SUPPORTED_RAN_MULTIPLIER = 167,
+  CCC_SUPPORTED_MAX_RANGING_SESSION_NUMBER = 168,
+  SUPPORTED_AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 227,
+  SUPPORTED_MIN_RANGING_INTERVAL_MS = 228,
+  SUPPORTED_RANGE_DATA_NTF_CONFIG = 229,
+  SUPPORTED_RSSI_REPORTING = 230,
+  SUPPORTED_DIAGNOSTICS = 231,
+  SUPPORTED_MIN_SLOT_DURATION_RSTU = 232,
+  SUPPORTED_MAX_RANGING_SESSION_NUMBER = 233,
+  SUPPORTED_CHANNELS_AOA = 234,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
new file mode 100644
index 0000000..0e33f70
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.uwb.fira_android;
+@Backing(type="long") @VintfStability
+enum UwbVendorCapabilityTlvValues {
+  UWB_CONFIG_0 = 0,
+  UWB_CONFIG_1 = 1,
+  PULSE_SHAPE_SYMMETRICAL_ROOT_RAISED_COSINE = 0,
+  PULSE_SHAPE_PRECURSOR_FREE = 1,
+  PULSE_SHAPE_PRECURSOR_FREE_SPECIAL = 2,
+  CHAPS_PER_SLOT_3 = 1,
+  CHAPS_PER_SLOT_4 = 2,
+  CHAPS_PER_SLOT_6 = 4,
+  CHAPS_PER_SLOT_8 = 8,
+  CHAPS_PER_SLOT_9 = 16,
+  CHAPS_PER_SLOT_12 = 32,
+  CHAPS_PER_SLOT_24 = 64,
+  HOPPING_SEQUENCE_DEFAULT = 16,
+  HOPPING_SEQUENCE_AES = 8,
+  HOPPING_CONFIG_MODE_NONE = 128,
+  HOPPING_CONFIG_MODE_CONTINUOUS = 64,
+  HOPPING_CONFIG_MODE_ADAPTIVE = 32,
+  CCC_CHANNEL_5 = 1,
+  CCC_CHANNEL_9 = 2,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
new file mode 100644
index 0000000..fbcfbff
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorGidAndroidOids {
+  ANDROID_GET_POWER_STATS = 0,
+  ANDROID_SET_COUNTRY_CODE = 1,
+  ANDROID_RANGE_DIAGNOSTICS = 2,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGids.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGids.aidl
new file mode 100644
index 0000000..5515c67
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGids.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorGids {
+  ANDROID = 12,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
new file mode 100644
index 0000000..dc2252b
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorReasonCodes {
+  REASON_ERROR_INVALID_CHANNEL_WITH_AOA = 128,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
new file mode 100644
index 0000000..8413f06
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorSessionAppConfigTlvTypes {
+  CCC_HOP_MODE_KEY = 160,
+  CCC_UWB_TIME0 = 161,
+  CCC_RANGING_PROTOCOL_VER = 163,
+  CCC_UWB_CONFIG_ID = 164,
+  CCC_PULSESHAPE_COMBO = 165,
+  CCC_URSK_TTL = 166,
+  NB_OF_RANGE_MEASUREMENTS = 227,
+  NB_OF_AZIMUTH_MEASUREMENTS = 228,
+  NB_OF_ELEVATION_MEASUREMENTS = 229,
+  ENABLE_DIAGNOSTICS = 232,
+  DIAGRAMS_FRAME_REPORTS_FIELDS = 233,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvValues.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvValues.aidl
new file mode 100644
index 0000000..a7f487b
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvValues.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorSessionAppConfigTlvValues {
+  AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 240,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
new file mode 100644
index 0000000..30a0a1b
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorSessionInitSessionType {
+  CCC = 160,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
new file mode 100644
index 0000000..2f534df
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorStatusCodes {
+  STATUS_ERROR_CCC_SE_BUSY = 80,
+  STATUS_ERROR_CCC_LIFECYCLE = 81,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index cbe2068..25d704e 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -43,5 +43,14 @@
   CCC_SUPPORTED_UWB_CONFIGS = 165,
   CCC_SUPPORTED_PULSE_SHAPE_COMBOS = 166,
   CCC_SUPPORTED_RAN_MULTIPLIER = 167,
+  CCC_SUPPORTED_MAX_RANGING_SESSION_NUMBER = 168,
+  CCC_SUPPORTED_MIN_UWB_INITIATION_TIME_MS = 169,
   SUPPORTED_AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 227,
+  SUPPORTED_MIN_RANGING_INTERVAL_MS = 228,
+  SUPPORTED_RANGE_DATA_NTF_CONFIG = 229,
+  SUPPORTED_RSSI_REPORTING = 230,
+  SUPPORTED_DIAGNOSTICS = 231,
+  SUPPORTED_MIN_SLOT_DURATION_RSTU = 232,
+  SUPPORTED_MAX_RANGING_SESSION_NUMBER = 233,
+  SUPPORTED_CHANNELS_AOA = 234,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
index cd2e122..fbcfbff 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -36,4 +36,5 @@
 enum UwbVendorGidAndroidOids {
   ANDROID_GET_POWER_STATS = 0,
   ANDROID_SET_COUNTRY_CODE = 1,
+  ANDROID_RANGE_DIAGNOSTICS = 2,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
new file mode 100644
index 0000000..a438cbe
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorReasonCodes {
+  REASON_ERROR_INVALID_CHANNEL_WITH_AOA = 128,
+  REASON_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 129,
+  REASON_REGULATION_UWB_OFF = 130,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index d35728f..c3ac401 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -40,7 +40,10 @@
   CCC_UWB_CONFIG_ID = 164,
   CCC_PULSESHAPE_COMBO = 165,
   CCC_URSK_TTL = 166,
+  CCC_LAST_INDEX_USED = 168,
   NB_OF_RANGE_MEASUREMENTS = 227,
   NB_OF_AZIMUTH_MEASUREMENTS = 228,
   NB_OF_ELEVATION_MEASUREMENTS = 229,
+  ENABLE_DIAGNOSTICS = 232,
+  DIAGRAMS_FRAME_REPORTS_FIELDS = 233,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
index 2f534df..28cf7fe 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
@@ -36,4 +36,6 @@
 enum UwbVendorStatusCodes {
   STATUS_ERROR_CCC_SE_BUSY = 80,
   STATUS_ERROR_CCC_LIFECYCLE = 81,
+  STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 82,
+  STATUS_REGULATION_UWB_OFF = 83,
 }
diff --git a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
index 00cb8e0..6ee5799 100644
--- a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
@@ -71,8 +71,8 @@
      * The UCI message format is as per UCI  protocol and it is
      * defined in "FiRa Consortium - UCI Generic Specification_v1.0" specification at FiRa
      * consortium.
-     * WIP doc link: https://groups.firaconsortium.org/wg/Technical/document/folder/127.
-     * TODO(b/196004116): Link to the published specification.
+     *
+     * UCI 1.1 specification: https://groups.firaconsortium.org/wg/members/document/1949.
      *
      * This method may queue writes and return immediately, or it may block until data is written.
      * Implementation must guarantee that writes are executed in order.
diff --git a/uwb/aidl/android/hardware/uwb/IUwbClientCallback.aidl b/uwb/aidl/android/hardware/uwb/IUwbClientCallback.aidl
index 75853cd..f31aeba 100755
--- a/uwb/aidl/android/hardware/uwb/IUwbClientCallback.aidl
+++ b/uwb/aidl/android/hardware/uwb/IUwbClientCallback.aidl
@@ -28,8 +28,7 @@
      * can use to pass incoming data to the stack.  These include UCI
      * responses and notifications from the UWB subsystem.
      *
-     * WIP doc link: https://groups.firaconsortium.org/wg/Technical/document/folder/127.
-     * TODO(b/196004116): Link to the published specification.
+     * UCI 1.1 specification: https://groups.firaconsortium.org/wg/members/document/1949.
      *
      * @param data UCI packet sent.
      */
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index 0140fdd..22b7bfe 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -139,6 +139,16 @@
     /** Int value for indicating supported ran multiplier */
     CCC_SUPPORTED_RAN_MULTIPLIER = 0xA7,
 
+    /**
+     * Int value to indicate supported max number of ccc ranging sessions
+     */
+    CCC_SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xA8,
+
+    /**
+     * Int value to indicate the smallest supported CCC uwb initiation time in ms
+     */
+    CCC_SUPPORTED_MIN_UWB_INITIATION_TIME_MS = 0xA9,
+
     /*********************************************
      * FIRA specific
      ********************************************/
@@ -150,4 +160,57 @@
      *  0 - Feature not supported.
      */
     SUPPORTED_AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 0xE3,
+
+    /**
+     * 4 byte value to indicate supported min ranging interval in ms.
+     */
+    SUPPORTED_MIN_RANGING_INTERVAL_MS = 0xE4,
+
+    /**
+     * 4 byte bitmask to indicate the supported RANGE_DATA_NTF_CONFIG values
+     *
+     * Bitmask where each bit corresponds to values used in
+     * RANGE_DATA_NTF_CONFIG in SET_APP_CFG_CMD
+     */
+    SUPPORTED_RANGE_DATA_NTF_CONFIG = 0xE5,
+
+    /**
+     * 1 byte bitmask to indicate the supported RSSI_REPORTING values
+     * Values:
+     * 1 - Feature supported.
+     * 0 - Feature not supported.
+     */
+    SUPPORTED_RSSI_REPORTING = 0xE6,
+
+    /**
+     * 1 byte value to indicate support for diagnostics feature.
+     * Values:
+     *  1 - Feature supported.
+     *  0 - Feature not supported.
+     */
+    SUPPORTED_DIAGNOSTICS = 0xE7,
+
+    /**
+     * 4 byte value to indicate supported min slot duration in rstu.
+     */
+    SUPPORTED_MIN_SLOT_DURATION_RSTU = 0xE8,
+
+    /**
+     * Int value to indicate supported max number of fira ranging sessions
+     */
+    SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xE9,
+
+    /**
+     * 2 byte bitmask to indicate the channels that support AoA.
+     * Each "1" in this bitmap corresponds to a specific UWB channel where:
+     *  0x01 = "Channel 5",
+     *  0x02 = "Channel 6",
+     *  0x04 = "Channel 8",
+     *  0x08 = "Channel 9",
+     *  0x10 = "Channel 10",
+     *  0x20 = "Channel 12",
+     *  0x40 = "Channel 13",
+     *  0x80 = "Channel 14"
+     */
+    SUPPORTED_CHANNELS_AOA = 0xEA,
 }
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
index e389a2d..4768f55 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -30,5 +30,11 @@
     ANDROID_GET_POWER_STATS = 0x0,
     // Used to set the current regulatory country code (determined usinag
     // SIM or hardcoded by OEM).
+    // Country code is sent as a 2 byte value corresponding to ISO-3166 country code.
+    // Note: "00" is used to indicate that the country code is unknown.
     ANDROID_SET_COUNTRY_CODE = 0x1,
+    // Used by the notification to get UWB ranging diagnostics stats.
+    // Supported only if the UwbVendorCapabilityTlvTypes.SUPPORTED_DIAGNOSTICS set
+    // to 1.
+    ANDROID_RANGE_DIAGNOSTICS = 0x2,
 }
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
new file mode 100644
index 0000000..4207574
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.uwb.fira_android;
+
+/**
+ * Android specific vendor reason codes should be defined here.
+ *
+ */
+@VintfStability
+@Backing(type="int")
+enum UwbVendorReasonCodes {
+    /**
+     * Use values from the vendor specific reason code range: 0x80 – 0xFF defined in
+     * Table 15 (state change with reason codes) of UCI specification.
+     */
+
+    /** Fira specific */
+    /** The channel requested is not available for AoA */
+    REASON_ERROR_INVALID_CHANNEL_WITH_AOA = 0x80,
+    /** UWB stopped caused by other session conflict */
+    REASON_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x81,
+    /** UWB has been disabled (eg: country code change leads to UWB unsupported) */
+    REASON_REGULATION_UWB_OFF = 0x82,
+}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index f43b249..65bb1c9 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -46,6 +46,8 @@
     CCC_PULSESHAPE_COMBO = 0xA5,
     /** 2 byte data */
     CCC_URSK_TTL = 0xA6,
+    /** 4 byte data */
+    CCC_LAST_INDEX_USED = 0xA8,
 
     /**
      * Range 0xE3 - 0xFF is reserved for proprietary use in the FIRA spec.
@@ -66,4 +68,23 @@
     NB_OF_AZIMUTH_MEASUREMENTS = 0xE4,
     /** 1 byte data */
     NB_OF_ELEVATION_MEASUREMENTS = 0xE5,
+
+    /**
+     * Supported only if the UwbVendorCapabilityTlvTypes
+     * .SUPPORTED_DIAGNOSTICS set to 1.
+     */
+    /**
+     * 1 byte data
+     * 1 - Enable,
+     * 0 - Disable
+     */
+    ENABLE_DIAGNOSTICS = 0xE8,
+    /**
+     * 1 byte bitmask
+     * b0: Activate RSSIs field,
+     * b1: Activate AoAs field,
+     * b2: Activate CIRs field,
+     * b3 - b7: RFU
+     */
+    DIAGRAMS_FRAME_REPORTS_FIELDS = 0xE9,
 }
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
index 8505b8a..f952334 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
@@ -33,4 +33,8 @@
     STATUS_ERROR_CCC_SE_BUSY = 0x50,
     /** CCC Lifecycle error */
     STATUS_ERROR_CCC_LIFECYCLE = 0x51,
+    /** Other session conflict */
+    STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x52,
+    /** UWB Regulation Off */
+    STATUS_REGULATION_UWB_OFF = 0x53,
 }
diff --git a/uwb/aidl/default/Android.bp b/uwb/aidl/default/Android.bp
index 8c2b60e..9621f2c 100644
--- a/uwb/aidl/default/Android.bp
+++ b/uwb/aidl/default/Android.bp
@@ -7,29 +7,26 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-cc_binary {
+rust_binary {
     name: "android.hardware.uwb-service",
+    crate_name: "uwb_default_hal",
     relative_install_path: "hw",
-    init_rc: ["uwb-service.rc"],
     vintf_fragments: ["uwb-service.xml"],
     vendor: true,
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-g",
+    rustlibs: [
+        "android.hardware.uwb-V1-rust",
+        "liblogger",
+        "liblog_rust",
+        "libbinder_rs",
+        "libbinder_tokio_rs",
+        "libtokio",
+        "libnix",
+        "libanyhow",
     ],
-    shared_libs: [
-        "liblog",
-        "libbinder_ndk",
-    ],
-    static_libs: [
-        "libbase",
-        "libutils",
-        "android.hardware.uwb-V1-ndk",
+    proc_macros: [
+        "libasync_trait",
     ],
     srcs: [
-        "service.cpp",
-        "uwb.cpp",
-        "uwb_chip.cpp",
+        "src/service.rs",
     ],
 }
diff --git a/uwb/aidl/default/service.cpp b/uwb/aidl/default/service.cpp
deleted file mode 100644
index 007637f..0000000
--- a/uwb/aidl/default/service.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.
- */
-
-#include <android-base/logging.h>
-#include <android/binder_manager.h>
-#include <android/binder_process.h>
-#include <utils/StrongPointer.h>
-
-#include "uwb.h"
-
-using ::aidl::android::hardware::uwb::IUwb;
-using ::android::sp;
-using ::android::base::InitLogging;
-using ::android::base::StderrLogger;
-using ::android::hardware::uwb::impl::Uwb;
-
-int main(int /*argc*/, char* argv[]) {
-    InitLogging(argv, StderrLogger);
-    LOG(INFO) << "UWB HAL starting up";
-
-    ABinderProcess_setThreadPoolMaxThreadCount(0);
-    std::shared_ptr<IUwb> uwb = ndk::SharedRefBase::make<Uwb>();
-    const std::string instance = std::string() + IUwb::descriptor + "/default";
-    binder_status_t status = AServiceManager_addService(uwb->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
-
-    ABinderProcess_joinThreadPool();
-    return EXIT_FAILURE;  // should not reach
-}
diff --git a/uwb/aidl/default/src/service.rs b/uwb/aidl/default/src/service.rs
new file mode 100644
index 0000000..7d5c073
--- /dev/null
+++ b/uwb/aidl/default/src/service.rs
@@ -0,0 +1,47 @@
+use android_hardware_uwb::aidl::android::hardware::uwb::IUwb::{self, IUwb as _};
+use android_hardware_uwb::binder;
+
+use tokio::runtime::Runtime;
+
+use std::env;
+use std::panic;
+
+use log::Level;
+
+mod uwb;
+mod uwb_chip;
+
+fn main() -> anyhow::Result<()> {
+    logger::init(
+        logger::Config::default()
+            .with_min_level(Level::Debug)
+            .with_tag_on_device("android.hardware.uwb"),
+    );
+
+    // Redirect panic messages to logcat.
+    panic::set_hook(Box::new(|panic_info| {
+        log::error!("{}", panic_info);
+    }));
+
+    log::info!("UWB HAL starting up");
+
+    // Create the tokio runtime
+    let rt = Runtime::new()?;
+
+    let chips = env::args()
+        .skip(1) // Skip binary name
+        .enumerate()
+        .map(|(i, arg)| uwb_chip::UwbChip::new(i.to_string(), arg));
+
+    binder::add_service(
+        &format!("{}/default", IUwb::BpUwb::get_descriptor()),
+        IUwb::BnUwb::new_binder(
+            uwb::Uwb::from_chips(chips, rt.handle().clone()),
+            binder::BinderFeatures::default(),
+        )
+        .as_binder(),
+    )?;
+
+    binder::ProcessState::join_thread_pool();
+    Ok(())
+}
diff --git a/uwb/aidl/default/src/uwb.rs b/uwb/aidl/default/src/uwb.rs
new file mode 100644
index 0000000..428f08f
--- /dev/null
+++ b/uwb/aidl/default/src/uwb.rs
@@ -0,0 +1,53 @@
+use android_hardware_uwb::aidl::android::hardware::uwb::{IUwb, IUwbChip};
+use android_hardware_uwb::binder;
+use binder::{Result, Strong};
+use binder_tokio::TokioRuntime;
+use tokio::runtime::Handle as TokioHandle;
+
+use crate::uwb_chip;
+
+pub struct Uwb {
+    chips: Vec<Strong<dyn IUwbChip::IUwbChip>>,
+}
+
+impl Uwb {
+    pub fn from_chips(
+        chips: impl IntoIterator<Item = uwb_chip::UwbChip>,
+        handle: TokioHandle,
+    ) -> Self {
+        Self {
+            chips: chips
+                .into_iter()
+                .map(|chip| {
+                    IUwbChip::BnUwbChip::new_async_binder(
+                        chip,
+                        TokioRuntime(handle.clone()),
+                        binder::BinderFeatures::default(),
+                    )
+                })
+                .collect(),
+        }
+    }
+}
+
+impl binder::Interface for Uwb {}
+
+impl IUwb::IUwb for Uwb {
+    fn getChips(&self) -> Result<Vec<String>> {
+        log::debug!("getChips");
+        self.chips.iter().map(|chip| chip.getName()).collect()
+    }
+
+    fn getChip(&self, name: &str) -> Result<Strong<dyn IUwbChip::IUwbChip>> {
+        log::debug!("getChip {}", name);
+        let chip = self
+            .chips
+            .iter()
+            .find(|chip| chip.getName().as_deref() == Ok(name));
+        if let Some(chip) = chip {
+            Ok(chip.clone())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_ARGUMENT.into())
+        }
+    }
+}
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
new file mode 100644
index 0000000..7c2c300
--- /dev/null
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -0,0 +1,168 @@
+use android_hardware_uwb::aidl::android::hardware::uwb::{
+    IUwbChip::IUwbChipAsyncServer, IUwbClientCallback::IUwbClientCallback, UwbEvent::UwbEvent,
+    UwbStatus::UwbStatus,
+};
+use android_hardware_uwb::binder;
+use async_trait::async_trait;
+use binder::{Result, Strong};
+
+use tokio::fs::File;
+use tokio::io::{AsyncReadExt, AsyncWriteExt};
+use tokio::sync::Mutex;
+
+use std::os::fd::AsRawFd;
+
+use std::io;
+
+use nix::sys::termios;
+
+enum State {
+    Closed,
+    Opened {
+        callbacks: Strong<dyn IUwbClientCallback>,
+        #[allow(dead_code)]
+        tasks: tokio::task::JoinSet<()>,
+        write: File,
+    },
+}
+
+pub struct UwbChip {
+    name: String,
+    path: String,
+    state: Mutex<State>,
+}
+
+impl UwbChip {
+    pub fn new(name: String, path: String) -> Self {
+        Self {
+            name,
+            path,
+            state: Mutex::new(State::Closed),
+        }
+    }
+}
+
+pub fn makeraw(file: File) -> io::Result<File> {
+    let fd = file.as_raw_fd();
+
+    let mut attrs = termios::tcgetattr(fd)?;
+
+    termios::cfmakeraw(&mut attrs);
+
+    termios::tcsetattr(fd, termios::SetArg::TCSANOW, &attrs)?;
+
+    Ok(file)
+}
+
+impl binder::Interface for UwbChip {}
+
+#[async_trait]
+impl IUwbChipAsyncServer for UwbChip {
+    async fn getName(&self) -> Result<String> {
+        Ok(self.name.clone())
+    }
+
+    async fn open(&self, callbacks: &Strong<dyn IUwbClientCallback>) -> Result<()> {
+        log::debug!("open: {:?}", &self.path);
+
+        let serial = File::open(&self.path)
+            .await
+            .and_then(makeraw)
+            .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
+
+        let mut read = serial
+            .try_clone()
+            .await
+            .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
+        let write = serial;
+
+        let mut state = self.state.lock().await;
+
+        if let State::Closed = *state {
+            let client_callbacks = callbacks.clone();
+
+            let mut tasks = tokio::task::JoinSet::new();
+
+            tasks.spawn(async move {
+                loop {
+                    const UWB_HEADER_SIZE: usize = 4;
+
+                    let mut buffer = vec![0; UWB_HEADER_SIZE];
+                    read.read_exact(&mut buffer[0..UWB_HEADER_SIZE])
+                        .await
+                        .unwrap();
+
+                    let length = buffer[3] as usize + UWB_HEADER_SIZE;
+
+                    buffer.resize(length, 0);
+                    read.read_exact(&mut buffer[UWB_HEADER_SIZE..length])
+                        .await
+                        .unwrap();
+
+                    client_callbacks.onUciMessage(&buffer[..]).unwrap();
+                }
+            });
+
+            callbacks.onHalEvent(UwbEvent::OPEN_CPLT, UwbStatus::OK)?;
+
+            *state = State::Opened {
+                callbacks: callbacks.clone(),
+                tasks,
+                write,
+            };
+
+            Ok(())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+        }
+    }
+
+    async fn close(&self) -> Result<()> {
+        log::debug!("close");
+
+        let mut state = self.state.lock().await;
+
+        if let State::Opened { ref callbacks, .. } = *state {
+            callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?;
+            *state = State::Closed;
+            Ok(())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+        }
+    }
+
+    async fn coreInit(&self) -> Result<()> {
+        log::debug!("coreInit");
+
+        if let State::Opened { ref callbacks, .. } = *self.state.lock().await {
+            callbacks.onHalEvent(UwbEvent::POST_INIT_CPLT, UwbStatus::OK)?;
+            Ok(())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+        }
+    }
+
+    async fn sessionInit(&self, _id: i32) -> Result<()> {
+        log::debug!("sessionInit");
+
+        Ok(())
+    }
+
+    async fn getSupportedAndroidUciVersion(&self) -> Result<i32> {
+        Ok(1)
+    }
+
+    async fn sendUciMessage(&self, data: &[u8]) -> Result<i32> {
+        log::debug!("sendUciMessage");
+
+        if let State::Opened { write, .. } = &mut *self.state.lock().await {
+            write
+                .write(data)
+                .await
+                .map(|written| written as i32)
+                .map_err(|_| binder::StatusCode::UNKNOWN_ERROR.into())
+        } else {
+            Err(binder::ExceptionCode::ILLEGAL_STATE.into())
+        }
+    }
+}
diff --git a/uwb/aidl/default/uwb-service.rc b/uwb/aidl/default/uwb-service.rc
deleted file mode 100644
index e2c3825..0000000
--- a/uwb/aidl/default/uwb-service.rc
+++ /dev/null
@@ -1,3 +0,0 @@
-service vendor.uwb_hal /vendor/bin/hw/android.hardware.uwb-service
-    class hal
-    user uwb
diff --git a/uwb/aidl/default/uwb.cpp b/uwb/aidl/default/uwb.cpp
deleted file mode 100644
index 1e2ef4e..0000000
--- a/uwb/aidl/default/uwb.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-#include <android-base/logging.h>
-
-#include "uwb.h"
-
-namespace {
-static constexpr char kDefaultChipName[] = "default";
-
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace uwb {
-namespace impl {
-using namespace ::aidl::android::hardware::uwb;
-
-// The default implementation of the HAL assumes 1 chip on the device.
-Uwb::Uwb() : chips_({{kDefaultChipName, ndk::SharedRefBase::make<UwbChip>(kDefaultChipName)}}) {}
-
-Uwb::~Uwb() {}
-
-::ndk::ScopedAStatus Uwb::getChips(std::vector<std::string>* names) {
-    for (const auto& chip : chips_) {
-        names->push_back(chip.first);
-    }
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus Uwb::getChip(const std::string& name, std::shared_ptr<IUwbChip>* chip) {
-    const auto chip_found = chips_.find(name);
-    if (chip_found == chips_.end()) {
-        LOG(ERROR) << "Unknown chip name" << name;
-        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
-    }
-    *chip = chip_found->second;
-    return ndk::ScopedAStatus::ok();
-}
-}  // namespace impl
-}  // namespace uwb
-}  // namespace hardware
-}  // namespace android
diff --git a/uwb/aidl/default/uwb.h b/uwb/aidl/default/uwb.h
deleted file mode 100644
index ec51fd8..0000000
--- a/uwb/aidl/default/uwb.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-#ifndef ANDROID_HARDWARE_UWB_UWB
-#define ANDROID_HARDWARE_UWB_UWB
-
-#include <map>
-#include <vector>
-
-#include <aidl/android/hardware/uwb/BnUwb.h>
-#include <aidl/android/hardware/uwb/IUwbChip.h>
-
-#include "uwb_chip.h"
-
-namespace android {
-namespace hardware {
-namespace uwb {
-namespace impl {
-using namespace ::aidl::android::hardware::uwb;
-// Default implementation mean't to be used on simulator targets.
-class Uwb : public BnUwb {
-  public:
-    Uwb();
-    virtual ~Uwb();
-
-    ::ndk::ScopedAStatus getChips(std::vector<std::string>* names) override;
-    ::ndk::ScopedAStatus getChip(const std::string& name, std::shared_ptr<IUwbChip>* chip) override;
-
-  private:
-    std::map<std::string, std::shared_ptr<UwbChip>> chips_;
-};
-}  // namespace impl
-}  // namespace uwb
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_UWB_UWB
\ No newline at end of file
diff --git a/uwb/aidl/default/uwb_chip.cpp b/uwb/aidl/default/uwb_chip.cpp
deleted file mode 100644
index 41f14fd..0000000
--- a/uwb/aidl/default/uwb_chip.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.
- */
-
-#include "uwb.h"
-
-namespace {
-constexpr static int32_t kAndroidUciVersion = 1;
-}
-
-namespace android {
-namespace hardware {
-namespace uwb {
-namespace impl {
-using namespace ::aidl::android::hardware::uwb;
-
-UwbChip::UwbChip(const std::string& name) : name_(name), mClientCallback(nullptr) {}
-UwbChip::~UwbChip() {}
-
-::ndk::ScopedAStatus UwbChip::getName(std::string* name) {
-    *name = name_;
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus UwbChip::open(const std::shared_ptr<IUwbClientCallback>& clientCallback) {
-    mClientCallback = clientCallback;
-    mClientCallback->onHalEvent(UwbEvent::OPEN_CPLT, UwbStatus::OK);
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus UwbChip::close() {
-    mClientCallback->onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK);
-    mClientCallback = nullptr;
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus UwbChip::coreInit() {
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus UwbChip::sessionInit(int /* sessionId */) {
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus UwbChip::getSupportedAndroidUciVersion(int32_t* version) {
-    *version = kAndroidUciVersion;
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus UwbChip::sendUciMessage(const std::vector<uint8_t>& /* data */,
-                                             int32_t* /* bytes_written */) {
-    // TODO(b/195992658): Need emulator support for UCI stack.
-    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-}  // namespace impl
-}  // namespace uwb
-}  // namespace hardware
-}  // namespace android
diff --git a/uwb/aidl/default/uwb_chip.h b/uwb/aidl/default/uwb_chip.h
deleted file mode 100644
index e900cbe..0000000
--- a/uwb/aidl/default/uwb_chip.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_HARDWARE_UWB_UWBCHIP
-#define ANDROID_HARDWARE_UWB_UWBCHIP
-
-#include <vector>
-
-#include <aidl/android/hardware/uwb/BnUwbChip.h>
-#include <aidl/android/hardware/uwb/IUwbClientCallback.h>
-
-namespace android {
-namespace hardware {
-namespace uwb {
-namespace impl {
-using namespace ::aidl::android::hardware::uwb;
-// Default implementation mean't to be used on simulator targets.
-class UwbChip : public BnUwbChip {
-  public:
-    UwbChip(const std::string& name);
-    virtual ~UwbChip();
-
-    ::ndk::ScopedAStatus getName(std::string* name) override;
-    ::ndk::ScopedAStatus open(const std::shared_ptr<IUwbClientCallback>& clientCallback) override;
-    ::ndk::ScopedAStatus close() override;
-    ::ndk::ScopedAStatus coreInit() override;
-    ::ndk::ScopedAStatus sessionInit(int sesionId) override;
-    ::ndk::ScopedAStatus getSupportedAndroidUciVersion(int32_t* version) override;
-    ::ndk::ScopedAStatus sendUciMessage(const std::vector<uint8_t>& data,
-                                        int32_t* bytes_written) override;
-
-  private:
-    std::string name_;
-    std::shared_ptr<IUwbClientCallback> mClientCallback;
-};
-}  // namespace impl
-}  // namespace uwb
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_UWB_UWBCHIP
diff --git a/vibrator/1.0/vts/OWNERS b/vibrator/1.0/vts/OWNERS
deleted file mode 100644
index 75b9a4b..0000000
--- a/vibrator/1.0/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 345036
-michaelwr@google.com
-leungv@google.com
diff --git a/vibrator/1.1/vts/OWNERS b/vibrator/1.1/vts/OWNERS
deleted file mode 100644
index 44bfe56..0000000
--- a/vibrator/1.1/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 345036
-include ../../1.0/vts/OWNERS
diff --git a/vibrator/1.2/vts/OWNERS b/vibrator/1.2/vts/OWNERS
deleted file mode 100644
index 44bfe56..0000000
--- a/vibrator/1.2/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 345036
-include ../../1.0/vts/OWNERS
diff --git a/vibrator/1.3/example/OWNERS b/vibrator/1.3/example/OWNERS
deleted file mode 100644
index 4b34968..0000000
--- a/vibrator/1.3/example/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-eliptus@google.com
-michaelwr@google.com
diff --git a/vibrator/1.3/vts/OWNERS b/vibrator/1.3/vts/OWNERS
deleted file mode 100644
index 44bfe56..0000000
--- a/vibrator/1.3/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 345036
-include ../../1.0/vts/OWNERS
diff --git a/vibrator/OWNERS b/vibrator/OWNERS
new file mode 100644
index 0000000..62a567e
--- /dev/null
+++ b/vibrator/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 345036
+
+include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
+
+chrispaulo@google.com
+michaelwr@google.com
+nathankulczak@google.com
+taikuo@google.com
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index d4d5857..c5936e3 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -17,12 +17,7 @@
     stability: "vintf",
     backend: {
         java: {
-            sdk_version: "module_current",
-        },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
+            sdk_version: "system_current",
         },
     },
     versions: [
diff --git a/vibrator/aidl/OWNERS b/vibrator/aidl/OWNERS
deleted file mode 100644
index 3982c7b..0000000
--- a/vibrator/aidl/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# Bug component: 345036
-include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
-chasewu@google.com
-taikuo@google.com
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index c4140be..78bb4ed 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -57,33 +57,12 @@
 cc_fuzz {
     name: "android.hardware.vibrator-service.example_fuzzer",
     host_supported: true,
+    defaults: ["service_fuzzer_defaults"],
     static_libs: [
         "android.hardware.vibrator-V2-ndk",
-        "libbase",
-        "libbinder_random_parcel",
-        "libcutils",
         "liblog",
         "libvibratorexampleimpl",
     ],
-    target: {
-        android: {
-            shared_libs: [
-                "libbinder_ndk",
-                "libbinder",
-                "libutils",
-            ],
-        },
-        host: {
-            static_libs: [
-                "libbinder_ndk",
-                "libbinder",
-                "libutils",
-            ],
-        },
-        darwin: {
-            enabled: false,
-        },
-    },
     srcs: ["fuzzer.cpp"],
     fuzz_config: {
         cc: [
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index ddc6ee0..01602ab 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -59,7 +59,10 @@
                                 const std::shared_ptr<IVibratorCallback>& callback) {
     LOG(VERBOSE) << "Vibrator on for timeoutMs: " << timeoutMs;
     if (callback != nullptr) {
-        std::thread([=] {
+        // Note that thread lambdas aren't using implicit capture [=], to avoid capturing "this",
+        // which may be asynchronously destructed.
+        // If "this" is needed, use [sharedThis = this->ref<Vibrator>()].
+        std::thread([timeoutMs, callback] {
             LOG(VERBOSE) << "Starting on on another thread";
             usleep(timeoutMs * 1000);
             LOG(VERBOSE) << "Notifying on complete";
@@ -87,7 +90,7 @@
     constexpr size_t kEffectMillis = 100;
 
     if (callback != nullptr) {
-        std::thread([=] {
+        std::thread([callback] {
             LOG(VERBOSE) << "Starting perform on another thread";
             usleep(kEffectMillis * 1000);
             LOG(VERBOSE) << "Notifying perform complete";
@@ -174,7 +177,8 @@
         }
     }
 
-    std::thread([=] {
+    // The thread may theoretically outlive the vibrator, so take a proper reference to it.
+    std::thread([sharedThis = this->ref<Vibrator>(), composite, callback] {
         LOG(VERBOSE) << "Starting compose on another thread";
 
         for (auto& e : composite) {
@@ -185,7 +189,7 @@
                          << e.scale;
 
             int32_t durationMs;
-            getPrimitiveDuration(e.primitive, &durationMs);
+            sharedThis->getPrimitiveDuration(e.primitive, &durationMs);
             usleep(durationMs * 1000);
         }
 
@@ -396,7 +400,7 @@
         }
     }
 
-    std::thread([=] {
+    std::thread([totalDuration, callback] {
         LOG(VERBOSE) << "Starting composePwle on another thread";
         usleep(totalDuration * 1000);
         if (callback != nullptr) {
diff --git a/vibrator/aidl/default/VibratorManager.cpp b/vibrator/aidl/default/VibratorManager.cpp
index 7cf9e6a..26edf5a 100644
--- a/vibrator/aidl/default/VibratorManager.cpp
+++ b/vibrator/aidl/default/VibratorManager.cpp
@@ -66,7 +66,7 @@
 ndk::ScopedAStatus VibratorManager::triggerSynced(
         const std::shared_ptr<IVibratorCallback>& callback) {
     LOG(INFO) << "Vibrator Manager trigger synced";
-    std::thread([=] {
+    std::thread([callback] {
         if (callback != nullptr) {
             LOG(INFO) << "Notifying perform complete";
             callback->onComplete();
diff --git a/vibrator/aidl/default/example_java_client/Android.bp b/vibrator/aidl/default/example_java_client/Android.bp
new file mode 100644
index 0000000..17a649c
--- /dev/null
+++ b/vibrator/aidl/default/example_java_client/Android.bp
@@ -0,0 +1,54 @@
+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 {
+    name: "libexample_vib_getter",
+    srcs: ["getter.cpp"],
+    product_available: true,
+    vendor_available: true,
+    shared_libs: [
+        "liblog",
+        "libbinder_ndk",
+    ],
+    header_libs: ["jni_headers"],
+    stl: "c++_shared",
+    visibility: [":__subpackages__"],
+}
+
+android_app {
+    name: "ExampleVibratorJavaVendorClient",
+    vendor: true,
+    static_libs: ["android.hardware.vibrator-V1-java"],
+    jni_libs: ["libexample_vib_getter"],
+    use_embedded_native_libs: true,
+    jarjar_rules: "jarjar.txt",
+    stl: "c++_shared",
+    srcs: ["example/vib/MyActivity.java"],
+    sdk_version: "system_current",
+    visibility: [":__subpackages__"],
+}
+
+android_app {
+    name: "ExampleVibratorJavaProductClient",
+    product_specific: true,
+    static_libs: ["android.hardware.vibrator-V1-java"],
+    jni_libs: ["libexample_vib_getter"],
+    use_embedded_native_libs: true,
+    jarjar_rules: "jarjar.txt",
+    stl: "c++_shared",
+    srcs: ["example/vib/MyActivity.java"],
+    sdk_version: "system_current",
+    visibility: [":__subpackages__"],
+    // If PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is not true, product apps
+    // may use unstable APIs. jni_uses_platform_apis must set to use the
+    // non-SDK jni libs in this case.
+    // This is not required if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is
+    // set to true.
+    jni_uses_platform_apis: true,
+}
diff --git a/vibrator/aidl/default/example_java_client/AndroidManifest.xml b/vibrator/aidl/default/example_java_client/AndroidManifest.xml
new file mode 100644
index 0000000..0561066
--- /dev/null
+++ b/vibrator/aidl/default/example_java_client/AndroidManifest.xml
@@ -0,0 +1,7 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:tools="http://schemas.android.com/tools"
+          package="example.vib">
+    <application>
+        <activity android:name=".MyActivity"/>
+    </application>
+</manifest>
diff --git a/vibrator/aidl/default/example_java_client/example/vib/MyActivity.java b/vibrator/aidl/default/example_java_client/example/vib/MyActivity.java
new file mode 100644
index 0000000..aadce8e
--- /dev/null
+++ b/vibrator/aidl/default/example_java_client/example/vib/MyActivity.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package example.vib;
+
+import android.app.Activity;
+import android.hardware.vibrator.IVibrator;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+public class MyActivity extends Activity {
+    private static native IBinder gimme(String name);
+
+    @Override
+    public void onCreate(Bundle b) {
+        super.onCreate(b);
+        System.loadLibrary("example_vib_getter");
+
+        // There is no API to get ahold of a Stable AIDL service from a vendor app
+        // in Java. This is because this is not the recommended way to get ahold
+        // of functionality in Android. The Android API Council recommendation is to
+        // implement uses-library APIs in the system/system_ext partition which add
+        // new APIs. AIDL as an API in Java is not recommended or supported way to
+        // communicate by apps - the recommendation is to use Java APIs. However,
+        // there also exists a large number of vendor apps which are coupled with
+        // hardware-specific code, and are therefore on the vendor partition. A
+        // large number of these use HIDL, and this is how they can continue to
+        // use that structure with AIDL.
+        IVibrator v =
+                IVibrator.Stub.asInterface(gimme("android.hardware.vibrator.IVibrator/default"));
+
+        try {
+            v.on(100 /*ms*/, null /*cb*/);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+
+        finish();
+    }
+}
diff --git a/vibrator/aidl/default/example_java_client/getter.cpp b/vibrator/aidl/default/example_java_client/getter.cpp
new file mode 100644
index 0000000..6115445
--- /dev/null
+++ b/vibrator/aidl/default/example_java_client/getter.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder_jni.h>
+#include <android/binder_manager.h>
+#include <jni.h>
+#include <log/log.h>
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_example_vib_MyActivity_gimme__Ljava_lang_String_2(JNIEnv* env, jclass /**/, jstring str) {
+    ALOGI("%s", __func__);
+
+    // Best practice is probably libnativehelper ScopedUtfChars or
+    // libbase ScopeGuard (for platform code), but this is with minimal
+    // dependencies.
+    const char* name = env->GetStringUTFChars(str, nullptr);
+
+    ALOGI("example vib gimme %s", name);
+
+    jobject jbinder = nullptr;
+
+    // Java does not have vendor variants. It's only safe to pass a service when
+    // 'vendor: true' if it is @VintfStability.
+    if (AServiceManager_isDeclared(name)) {
+        ndk::SpAIBinder binder = ndk::SpAIBinder(AServiceManager_waitForService(name));
+        jbinder = AIBinder_toJavaBinder(env, binder.get());
+    } else {
+        ALOGI("not declared");
+    }
+
+    env->ReleaseStringUTFChars(str, name);
+
+    return jbinder;
+}
diff --git a/vibrator/aidl/default/example_java_client/jarjar.txt b/vibrator/aidl/default/example_java_client/jarjar.txt
new file mode 100644
index 0000000..e7613a0
--- /dev/null
+++ b/vibrator/aidl/default/example_java_client/jarjar.txt
@@ -0,0 +1,2 @@
+rule android.hardware.** example.vib.ah.@1
+
diff --git a/vibrator/aidl/default/main.cpp b/vibrator/aidl/default/main.cpp
index feba2c7..7375889 100644
--- a/vibrator/aidl/default/main.cpp
+++ b/vibrator/aidl/default/main.cpp
@@ -29,15 +29,15 @@
 
     // make a default vibrator service
     auto vib = ndk::SharedRefBase::make<Vibrator>();
-    const std::string vibName = std::string() + Vibrator::descriptor + "/default";
-    binder_status_t status = AServiceManager_addService(vib->asBinder().get(), vibName.c_str());
+    binder_status_t status = AServiceManager_addService(
+            vib->asBinder().get(), Vibrator::makeServiceName("default").c_str());
     CHECK_EQ(status, STATUS_OK);
 
     // make the vibrator manager service with a different vibrator
     auto managedVib = ndk::SharedRefBase::make<Vibrator>();
     auto vibManager = ndk::SharedRefBase::make<VibratorManager>(std::move(managedVib));
-    const std::string vibManagerName = std::string() + VibratorManager::descriptor + "/default";
-    status = AServiceManager_addService(vibManager->asBinder().get(), vibManagerName.c_str());
+    status = AServiceManager_addService(vibManager->asBinder().get(),
+                                        VibratorManager::makeServiceName("default").c_str());
     CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
index 44fa3be..e8ed26a 100644
--- a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
@@ -96,6 +96,7 @@
     if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
     if (vibratorIds.empty()) return;
     EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+    EXPECT_TRUE(manager->cancelSynced().isOk());
 }
 
 TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) {
@@ -208,6 +209,7 @@
         EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
         Status status = manager->triggerSynced(callback);
         EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+        EXPECT_TRUE(manager->cancelSynced().isOk());
     }
 }
 
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 3841715..c88cb59 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -332,6 +332,7 @@
         sleep(1);
         EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
         sleep(1);
+        EXPECT_TRUE(vibrator->off().isOk());
     }
 }
 
@@ -443,7 +444,7 @@
 
             effect.delayMs = std::rand() % (maxDelay + 1);
             effect.primitive = primitive;
-            effect.scale = static_cast<float>(std::rand()) / RAND_MAX;
+            effect.scale = static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX);
             composite.emplace_back(effect);
 
             if (composite.size() == maxSize) {
@@ -601,10 +602,11 @@
             EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
                 << toString(primitive);
 
-            //TODO(b/187207798): revert back to conservative timeout values once
-            //latencies have been fixed
-            EXPECT_EQ(completionFuture.wait_for(duration * 4), std::future_status::ready)
-                << toString(primitive);
+            // TODO(b/261130361): Investigate why latency from driver and hardware will cause test
+            // to fail when wait duration is ~40ms or less.
+            EXPECT_EQ(completionFuture.wait_for(duration + std::chrono::milliseconds(50)),
+                      std::future_status::ready)
+                    << toString(primitive);
             end = high_resolution_clock::now();
 
             elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
diff --git a/weaver/1.0/vts/functional/Android.bp b/weaver/1.0/vts/functional/Android.bp
deleted file mode 100644
index cc1d284..0000000
--- a/weaver/1.0/vts/functional/Android.bp
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
-    // See: http://go/android-license-faq
-    // 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_test {
-    name: "VtsHalWeaverV1_0TargetTest",
-    defaults: ["VtsHalTargetTestDefaults"],
-    srcs: ["VtsHalWeaverV1_0TargetTest.cpp"],
-    static_libs: ["android.hardware.weaver@1.0"],
-    test_suites: ["general-tests", "vts"],
-}
diff --git a/weaver/1.0/vts/functional/OWNERS b/weaver/1.0/vts/functional/OWNERS
deleted file mode 100644
index ec8c304..0000000
--- a/weaver/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 186411
-chengyouho@google.com
-frankwoo@google.com
diff --git a/weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp b/weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp
deleted file mode 100644
index 66465a9..0000000
--- a/weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2017 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/hardware/weaver/1.0/IWeaver.h>
-#include <gtest/gtest.h>
-#include <hidl/GtestPrinter.h>
-#include <hidl/ServiceManagement.h>
-
-#include <limits>
-
-using ::android::hardware::weaver::V1_0::IWeaver;
-using ::android::hardware::weaver::V1_0::WeaverConfig;
-using ::android::hardware::weaver::V1_0::WeaverReadStatus;
-using ::android::hardware::weaver::V1_0::WeaverReadResponse;
-using ::android::hardware::weaver::V1_0::WeaverStatus;
-using ::android::hardware::Return;
-using ::android::sp;
-
-const std::vector<uint8_t> KEY{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
-const std::vector<uint8_t> WRONG_KEY{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-const std::vector<uint8_t> VALUE{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
-const std::vector<uint8_t> OTHER_VALUE{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 255, 255};
-
-struct WeaverHidlTest : public ::testing::TestWithParam<std::string> {
-    virtual void SetUp() override {
-        weaver = IWeaver::getService(GetParam());
-        ASSERT_NE(weaver, nullptr);
-    }
-
-    virtual void TearDown() override {}
-
-    sp<IWeaver> weaver;
-};
-
-/*
- * Checks config values are suitably large
- */
-TEST_P(WeaverHidlTest, GetConfig) {
-    WeaverStatus status;
-    WeaverConfig config;
-
-    bool callbackCalled = false;
-    auto ret = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
-        callbackCalled = true;
-        status = s;
-        config = c;
-    });
-    ASSERT_TRUE(ret.isOk());
-    ASSERT_TRUE(callbackCalled);
-    ASSERT_EQ(status, WeaverStatus::OK);
-
-    EXPECT_GE(config.slots, 16u);
-    EXPECT_GE(config.keySize, 16u);
-    EXPECT_GE(config.valueSize, 16u);
-}
-
-/*
- * Gets the config twice and checks they are the same
- */
-TEST_P(WeaverHidlTest, GettingConfigMultipleTimesGivesSameResult) {
-    WeaverConfig config1;
-    WeaverConfig config2;
-
-    WeaverStatus status;
-    bool callbackCalled = false;
-    auto ret = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
-        callbackCalled = true;
-        status = s;
-        config1 = c;
-    });
-    ASSERT_TRUE(ret.isOk());
-    ASSERT_TRUE(callbackCalled);
-    ASSERT_EQ(status, WeaverStatus::OK);
-
-    callbackCalled = false;
-    ret = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
-        callbackCalled = true;
-        status = s;
-        config2 = c;
-    });
-    ASSERT_TRUE(ret.isOk());
-    ASSERT_TRUE(callbackCalled);
-    ASSERT_EQ(status, WeaverStatus::OK);
-
-    EXPECT_EQ(config1, config2);
-}
-
-/*
- * Gets the number of slots from the config and writes a key and value to the last one
- */
-TEST_P(WeaverHidlTest, WriteToLastSlot) {
-    WeaverStatus status;
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
-        status = s;
-        config = c;
-    });
-    ASSERT_TRUE(configRet.isOk());
-    ASSERT_EQ(status, WeaverStatus::OK);
-
-    const uint32_t lastSlot = config.slots - 1;
-    const auto writeRet = weaver->write(lastSlot, KEY, VALUE);
-    ASSERT_TRUE(writeRet.isOk());
-    ASSERT_EQ(writeRet, WeaverStatus::OK);
-}
-
-/*
- * Writes a key and value to a slot
- * Reads the slot with the same key and receives the value that was previously written
- */
-TEST_P(WeaverHidlTest, WriteFollowedByReadGivesTheSameValue) {
-    constexpr uint32_t slotId = 0;
-    const auto ret = weaver->write(slotId, KEY, VALUE);
-    ASSERT_TRUE(ret.isOk());
-    ASSERT_EQ(ret, WeaverStatus::OK);
-
-    bool callbackCalled = false;
-    WeaverReadStatus status;
-    std::vector<uint8_t> readValue;
-    uint32_t timeout;
-    const auto readRet = weaver->read(slotId, KEY, [&](WeaverReadStatus s, WeaverReadResponse r) {
-        callbackCalled = true;
-        status = s;
-        readValue = r.value;
-        timeout = r.timeout;
-    });
-    ASSERT_TRUE(readRet.isOk());
-    ASSERT_TRUE(callbackCalled);
-    ASSERT_EQ(status, WeaverReadStatus::OK);
-    EXPECT_EQ(readValue, VALUE);
-    EXPECT_EQ(timeout, 0u);
-}
-
-/*
- * Writes a key and value to a slot
- * Overwrites the slot with a new key and value
- * Reads the slot with the new key and receives the new value
- */
-TEST_P(WeaverHidlTest, OverwritingSlotUpdatesTheValue) {
-    constexpr uint32_t slotId = 0;
-    const auto initialWriteRet = weaver->write(slotId, WRONG_KEY, VALUE);
-    ASSERT_TRUE(initialWriteRet.isOk());
-    ASSERT_EQ(initialWriteRet, WeaverStatus::OK);
-
-    const auto overwriteRet = weaver->write(slotId, KEY, OTHER_VALUE);
-    ASSERT_TRUE(overwriteRet.isOk());
-    ASSERT_EQ(overwriteRet, WeaverStatus::OK);
-
-    bool callbackCalled = false;
-    WeaverReadStatus status;
-    std::vector<uint8_t> readValue;
-    uint32_t timeout;
-    const auto readRet = weaver->read(slotId, KEY, [&](WeaverReadStatus s, WeaverReadResponse r) {
-        callbackCalled = true;
-        status = s;
-        readValue = r.value;
-        timeout = r.timeout;
-    });
-    ASSERT_TRUE(readRet.isOk());
-    ASSERT_TRUE(callbackCalled);
-    ASSERT_EQ(status, WeaverReadStatus::OK);
-    EXPECT_EQ(readValue, OTHER_VALUE);
-    EXPECT_EQ(timeout, 0u);
-}
-
-/*
- * Writes a key and value to a slot
- * Reads the slot with a different key so does not receive the value
- */
-TEST_P(WeaverHidlTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
-    constexpr uint32_t slotId = 0;
-    const auto ret = weaver->write(slotId, KEY, VALUE);
-    ASSERT_TRUE(ret.isOk());
-    ASSERT_EQ(ret, WeaverStatus::OK);
-
-    bool callbackCalled = false;
-    WeaverReadStatus status;
-    std::vector<uint8_t> readValue;
-    const auto readRet =
-        weaver->read(slotId, WRONG_KEY, [&](WeaverReadStatus s, WeaverReadResponse r) {
-            callbackCalled = true;
-            status = s;
-            readValue = r.value;
-        });
-    ASSERT_TRUE(callbackCalled);
-    ASSERT_TRUE(readRet.isOk());
-    ASSERT_EQ(status, WeaverReadStatus::INCORRECT_KEY);
-    EXPECT_TRUE(readValue.empty());
-}
-
-/*
- * Writing to an invalid slot fails
- */
-TEST_P(WeaverHidlTest, WritingToInvalidSlotFails) {
-    WeaverStatus status;
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
-        status = s;
-        config = c;
-    });
-    ASSERT_TRUE(configRet.isOk());
-    ASSERT_EQ(status, WeaverStatus::OK);
-
-    if (config.slots == std::numeric_limits<uint32_t>::max()) {
-        // If there are no invalid slots then pass
-        return;
-    }
-
-    const auto writeRet = weaver->write(config.slots, KEY, VALUE);
-    ASSERT_TRUE(writeRet.isOk());
-    ASSERT_EQ(writeRet, WeaverStatus::FAILED);
-}
-
-/*
- * Reading from an invalid slot fails rather than incorrect key
- */
-TEST_P(WeaverHidlTest, ReadingFromInvalidSlotFails) {
-    WeaverStatus status;
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
-        status = s;
-        config = c;
-    });
-    ASSERT_TRUE(configRet.isOk());
-    ASSERT_EQ(status, WeaverStatus::OK);
-
-    if (config.slots == std::numeric_limits<uint32_t>::max()) {
-        // If there are no invalid slots then pass
-        return;
-    }
-
-    bool callbackCalled = false;
-    WeaverReadStatus readStatus;
-    std::vector<uint8_t> readValue;
-    uint32_t timeout;
-    const auto readRet =
-        weaver->read(config.slots, KEY, [&](WeaverReadStatus s, WeaverReadResponse r) {
-            callbackCalled = true;
-            readStatus = s;
-            readValue = r.value;
-            timeout = r.timeout;
-        });
-    ASSERT_TRUE(callbackCalled);
-    ASSERT_TRUE(readRet.isOk());
-    ASSERT_EQ(readStatus, WeaverReadStatus::FAILED);
-    EXPECT_TRUE(readValue.empty());
-    EXPECT_EQ(timeout, 0u);
-}
-
-/*
- * Writing a key that is too large fails
- */
-TEST_P(WeaverHidlTest, WriteWithTooLargeKeyFails) {
-    WeaverStatus status;
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
-        status = s;
-        config = c;
-    });
-    ASSERT_TRUE(configRet.isOk());
-    ASSERT_EQ(status, WeaverStatus::OK);
-
-    std::vector<uint8_t> bigKey(config.keySize + 1);
-
-    constexpr uint32_t slotId = 0;
-    const auto writeRet = weaver->write(slotId, bigKey, VALUE);
-    ASSERT_TRUE(writeRet.isOk());
-    ASSERT_EQ(writeRet, WeaverStatus::FAILED);
-}
-
-/*
- * Writing a value that is too large fails
- */
-TEST_P(WeaverHidlTest, WriteWithTooLargeValueFails) {
-    WeaverStatus status;
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
-        status = s;
-        config = c;
-    });
-    ASSERT_TRUE(configRet.isOk());
-    ASSERT_EQ(status, WeaverStatus::OK);
-
-    std::vector<uint8_t> bigValue(config.valueSize + 1);
-
-    constexpr uint32_t slotId = 0;
-    const auto writeRet = weaver->write(slotId, KEY, bigValue);
-    ASSERT_TRUE(writeRet.isOk());
-    ASSERT_EQ(writeRet, WeaverStatus::FAILED);
-}
-
-/*
- * Reading with a key that is loo large fails
- */
-TEST_P(WeaverHidlTest, ReadWithTooLargeKeyFails) {
-    WeaverStatus status;
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
-        status = s;
-        config = c;
-    });
-    ASSERT_TRUE(configRet.isOk());
-    ASSERT_EQ(status, WeaverStatus::OK);
-
-    std::vector<uint8_t> bigKey(config.keySize + 1);
-
-    constexpr uint32_t slotId = 0;
-    bool callbackCalled = false;
-    WeaverReadStatus readStatus;
-    std::vector<uint8_t> readValue;
-    uint32_t timeout;
-    const auto readRet =
-        weaver->read(slotId, bigKey, [&](WeaverReadStatus s, WeaverReadResponse r) {
-            callbackCalled = true;
-            readStatus = s;
-            readValue = r.value;
-            timeout = r.timeout;
-        });
-    ASSERT_TRUE(callbackCalled);
-    ASSERT_TRUE(readRet.isOk());
-    ASSERT_EQ(readStatus, WeaverReadStatus::FAILED);
-    EXPECT_TRUE(readValue.empty());
-    EXPECT_EQ(timeout, 0u);
-}
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WeaverHidlTest);
-INSTANTIATE_TEST_SUITE_P(
-        PerInstance, WeaverHidlTest,
-        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IWeaver::descriptor)),
-        android::hardware::PrintInstanceNameToString);
diff --git a/weaver/OWNERS b/weaver/OWNERS
new file mode 100644
index 0000000..7e579f6
--- /dev/null
+++ b/weaver/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 1081729
+ebiggers@google.com
+paulcrowley@google.com
+swillden@google.com
+wfrichar@google.com
+chengyouho@google.com
diff --git a/weaver/aidl/Android.bp b/weaver/aidl/Android.bp
index 8b4306f..38d017f 100644
--- a/weaver/aidl/Android.bp
+++ b/weaver/aidl/Android.bp
@@ -16,11 +16,17 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
-    versions: ["1"],
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+        {
+            version: "2",
+            imports: [],
+        },
+
+    ],
+    frozen: true,
 }
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/2/.hash b/weaver/aidl/aidl_api/android.hardware.weaver/2/.hash
new file mode 100644
index 0000000..0d204c9
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/2/.hash
@@ -0,0 +1 @@
+0d60d74c2704ad281e219244514516db8482ef3d
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/IWeaver.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/IWeaver.aidl
new file mode 100644
index 0000000..61627d9
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/IWeaver.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 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.weaver;
+@VintfStability
+interface IWeaver {
+  android.hardware.weaver.WeaverConfig getConfig();
+  android.hardware.weaver.WeaverReadResponse read(in int slotId, in byte[] key);
+  void write(in int slotId, in byte[] key, in byte[] value);
+  const int STATUS_FAILED = 1;
+  const int STATUS_INCORRECT_KEY = 2;
+  const int STATUS_THROTTLE = 3;
+}
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/WeaverConfig.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/WeaverConfig.aidl
new file mode 100644
index 0000000..7491f32
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/WeaverConfig.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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.weaver;
+@VintfStability
+parcelable WeaverConfig {
+  int slots;
+  int keySize;
+  int valueSize;
+}
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/WeaverReadResponse.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/WeaverReadResponse.aidl
new file mode 100644
index 0000000..96e528f
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/WeaverReadResponse.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.weaver;
+@VintfStability
+parcelable WeaverReadResponse {
+  long timeout;
+  byte[] value;
+  android.hardware.weaver.WeaverReadStatus status = android.hardware.weaver.WeaverReadStatus.FAILED;
+}
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/WeaverReadStatus.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/WeaverReadStatus.aidl
new file mode 100644
index 0000000..e0be80e
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/2/android/hardware/weaver/WeaverReadStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.weaver;
+@Backing(type="int") @VintfStability
+enum WeaverReadStatus {
+  OK,
+  FAILED,
+  INCORRECT_KEY,
+  THROTTLE,
+}
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl
index 47ee4c8..96e528f 100644
--- a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,4 +36,5 @@
 parcelable WeaverReadResponse {
   long timeout;
   byte[] value;
+  android.hardware.weaver.WeaverReadStatus status = android.hardware.weaver.WeaverReadStatus.FAILED;
 }
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadStatus.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadStatus.aidl
new file mode 100644
index 0000000..fce9758
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.weaver;
+@Backing(type="int") @VintfStability
+enum WeaverReadStatus {
+  OK = 0,
+  FAILED = 1,
+  INCORRECT_KEY = 2,
+  THROTTLE = 3,
+}
diff --git a/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl b/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl
index ec006e8..17ea718 100644
--- a/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl
+++ b/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,15 +16,22 @@
 
 package android.hardware.weaver;
 
+import android.hardware.weaver.WeaverReadStatus;
+
 @VintfStability
 parcelable WeaverReadResponse {
     /**
-     * The time to wait, in milliseconds, before making the next request.
+     * The time to wait, in milliseconds, before making the next request,
+     * must be greater than or equal to zero and less than INT_MAX.
      */
     long timeout;
     /**
      * The value read from the slot or empty if the value was not read.
      */
     byte[] value;
+    /**
+     * Status from WeaverReadStatus
+     */
+    WeaverReadStatus status = WeaverReadStatus.FAILED;
 }
 
diff --git a/weaver/aidl/android/hardware/weaver/WeaverReadStatus.aidl b/weaver/aidl/android/hardware/weaver/WeaverReadStatus.aidl
new file mode 100644
index 0000000..36e731f
--- /dev/null
+++ b/weaver/aidl/android/hardware/weaver/WeaverReadStatus.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.weaver;
+
+@VintfStability
+@Backing(type="int")
+enum WeaverReadStatus {
+    OK,
+    FAILED,
+    INCORRECT_KEY,
+    THROTTLE,
+}
diff --git a/weaver/aidl/default/Android.bp b/weaver/aidl/default/Android.bp
index 70d9171..494cb1b 100644
--- a/weaver/aidl/default/Android.bp
+++ b/weaver/aidl/default/Android.bp
@@ -34,7 +34,7 @@
         "Weaver.cpp",
     ],
     shared_libs: [
-        "android.hardware.weaver-V1-ndk",
+        "android.hardware.weaver-V2-ndk",
         "libbase",
         "libbinder_ndk",
     ],
diff --git a/weaver/aidl/default/Weaver.cpp b/weaver/aidl/default/Weaver.cpp
index 6b77924..c9ffe85 100644
--- a/weaver/aidl/default/Weaver.cpp
+++ b/weaver/aidl/default/Weaver.cpp
@@ -37,18 +37,19 @@
 }
 
 ::ndk::ScopedAStatus Weaver::read(int32_t in_slotId, const std::vector<uint8_t>& in_key, WeaverReadResponse* out_response) {
+    using ::aidl::android::hardware::weaver::WeaverReadStatus;
 
     if (in_slotId > 15 || in_key.size() > 16) {
-        *out_response = {0, {}};
-        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_FAILED));
+        *out_response = {0, {}, WeaverReadStatus::FAILED};
+        return ndk::ScopedAStatus::ok();
     }
 
     if (slot_array[in_slotId].key != in_key) {
-        *out_response = {0, {}};
-        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_INCORRECT_KEY));
+        *out_response = {0, {}, WeaverReadStatus::INCORRECT_KEY};
+        return ndk::ScopedAStatus::ok();
     }
 
-    *out_response = {0, slot_array[in_slotId].value};
+    *out_response = {0, slot_array[in_slotId].value, WeaverReadStatus::OK};
 
     return ::ndk::ScopedAStatus::ok();
 }
diff --git a/weaver/aidl/default/android.hardware.weaver-service.example.xml b/weaver/aidl/default/android.hardware.weaver-service.example.xml
index ed291cd..bfe4396 100644
--- a/weaver/aidl/default/android.hardware.weaver-service.example.xml
+++ b/weaver/aidl/default/android.hardware.weaver-service.example.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.weaver</name>
-        <version>1</version>
+        <version>2</version>
         <interface>
             <name>IWeaver</name>
             <instance>default</instance>
diff --git a/weaver/aidl/vts/Android.bp b/weaver/aidl/vts/Android.bp
deleted file mode 100644
index cf1661c..0000000
--- a/weaver/aidl/vts/Android.bp
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
-    // See: http://go/android-license-faq
-    // 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_test {
-    name: "VtsHalWeaverTargetTest",
-    defaults: [
-        "VtsHalTargetTestDefaults",
-        "use_libaidlvintf_gtest_helper_static",
-    ],
-    srcs: ["VtsHalWeaverTargetTest.cpp"],
-    shared_libs: [
-        "libbinder_ndk",
-        "libbase",
-    ],
-    static_libs: ["android.hardware.weaver-V1-ndk"],
-    test_suites: [
-        "general-tests",
-        "vts",
-    ],
-}
diff --git a/weaver/aidl/vts/OWNERS b/weaver/aidl/vts/OWNERS
deleted file mode 100644
index 40d95e4..0000000
--- a/weaver/aidl/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-chengyouho@google.com
-frankwoo@google.com
diff --git a/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp b/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp
deleted file mode 100644
index 878c762..0000000
--- a/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * 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.
- */
-#include <aidl/Gtest.h>
-#include <aidl/Vintf.h>
-
-#include <aidl/android/hardware/weaver/IWeaver.h>
-#include <android/binder_manager.h>
-#include <android/binder_process.h>
-
-#include <limits>
-
-using ::aidl::android::hardware::weaver::IWeaver;
-using ::aidl::android::hardware::weaver::WeaverConfig;
-using ::aidl::android::hardware::weaver::WeaverReadResponse;
-
-using ::ndk::SpAIBinder;
-
-const std::vector<uint8_t> KEY{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
-const std::vector<uint8_t> WRONG_KEY{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-const std::vector<uint8_t> VALUE{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
-const std::vector<uint8_t> OTHER_VALUE{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 255, 255};
-
-struct WeaverAidlTest : public ::testing::TestWithParam<std::string> {
-    virtual void SetUp() override {
-        weaver = IWeaver::fromBinder(
-            SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
-        ASSERT_NE(weaver, nullptr);
-    }
-
-    virtual void TearDown() override {}
-
-    std::shared_ptr<IWeaver> weaver;
-};
-
-/*
- * Checks config values are suitably large
- */
-TEST_P(WeaverAidlTest, GetConfig) {
-    WeaverConfig config;
-
-    auto ret = weaver->getConfig(&config);
-
-    ASSERT_TRUE(ret.isOk());
-
-    EXPECT_GE(config.slots, 16u);
-    EXPECT_GE(config.keySize, 16u);
-    EXPECT_GE(config.valueSize, 16u);
-}
-
-/*
- * Gets the config twice and checks they are the same
- */
-TEST_P(WeaverAidlTest, GettingConfigMultipleTimesGivesSameResult) {
-    WeaverConfig config1;
-    WeaverConfig config2;
-
-    auto ret = weaver->getConfig(&config1);
-    ASSERT_TRUE(ret.isOk());
-
-    ret = weaver->getConfig(&config2);
-    ASSERT_TRUE(ret.isOk());
-
-    EXPECT_EQ(config1, config2);
-}
-
-/*
- * Gets the number of slots from the config and writes a key and value to the last one
- */
-TEST_P(WeaverAidlTest, WriteToLastSlot) {
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig(&config);
-
-    ASSERT_TRUE(configRet.isOk());
-
-    const uint32_t lastSlot = config.slots - 1;
-    const auto writeRet = weaver->write(lastSlot, KEY, VALUE);
-    ASSERT_TRUE(writeRet.isOk());
-}
-
-/*
- * Writes a key and value to a slot
- * Reads the slot with the same key and receives the value that was previously written
- */
-TEST_P(WeaverAidlTest, WriteFollowedByReadGivesTheSameValue) {
-    constexpr uint32_t slotId = 0;
-    const auto ret = weaver->write(slotId, KEY, VALUE);
-    ASSERT_TRUE(ret.isOk());
-
-    WeaverReadResponse response;
-    std::vector<uint8_t> readValue;
-    uint32_t timeout;
-    const auto readRet = weaver->read(slotId, KEY, &response);
-
-    readValue = response.value;
-    timeout = response.timeout;
-
-    ASSERT_TRUE(readRet.isOk());
-    EXPECT_EQ(readValue, VALUE);
-    EXPECT_EQ(timeout, 0u);
-}
-
-/*
- * Writes a key and value to a slot
- * Overwrites the slot with a new key and value
- * Reads the slot with the new key and receives the new value
- */
-TEST_P(WeaverAidlTest, OverwritingSlotUpdatesTheValue) {
-    constexpr uint32_t slotId = 0;
-    const auto initialWriteRet = weaver->write(slotId, WRONG_KEY, VALUE);
-    ASSERT_TRUE(initialWriteRet.isOk());
-
-    const auto overwriteRet = weaver->write(slotId, KEY, OTHER_VALUE);
-    ASSERT_TRUE(overwriteRet.isOk());
-
-    WeaverReadResponse response;
-    std::vector<uint8_t> readValue;
-    uint32_t timeout;
-    const auto readRet = weaver->read(slotId, KEY, &response);
-
-    readValue = response.value;
-    timeout = response.timeout;
-
-    ASSERT_TRUE(readRet.isOk());
-    EXPECT_EQ(readValue, OTHER_VALUE);
-    EXPECT_EQ(timeout, 0u);
-}
-
-/*
- * Writes a key and value to a slot
- * Reads the slot with a different key so does not receive the value
- */
-TEST_P(WeaverAidlTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
-    constexpr uint32_t slotId = 0;
-    const auto ret = weaver->write(slotId, KEY, VALUE);
-    ASSERT_TRUE(ret.isOk());
-
-    WeaverReadResponse response;
-    std::vector<uint8_t> readValue;
-    const auto readRet =
-        weaver->read(slotId, WRONG_KEY, &response);
-
-    readValue = response.value;
-
-    ASSERT_FALSE(readRet.isOk());
-    ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
-    ASSERT_EQ(IWeaver::STATUS_INCORRECT_KEY, readRet.getServiceSpecificError());
-    EXPECT_TRUE(readValue.empty());
-}
-
-/*
- * Writing to an invalid slot fails
- */
-TEST_P(WeaverAidlTest, WritingToInvalidSlotFails) {
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig(&config);
-    ASSERT_TRUE(configRet.isOk());
-
-    if (config.slots == std::numeric_limits<uint32_t>::max()) {
-        // If there are no invalid slots then pass
-        return;
-    }
-
-    const auto writeRet = weaver->write(config.slots, KEY, VALUE);
-    ASSERT_FALSE(writeRet.isOk());
-}
-
-/*
- * Reading from an invalid slot fails rather than incorrect key
- */
-TEST_P(WeaverAidlTest, ReadingFromInvalidSlotFails) {
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig(&config);
-    ASSERT_TRUE(configRet.isOk());
-
-    if (config.slots == std::numeric_limits<uint32_t>::max()) {
-        // If there are no invalid slots then pass
-        return;
-    }
-
-    WeaverReadResponse response;
-    std::vector<uint8_t> readValue;
-    uint32_t timeout;
-    const auto readRet =
-        weaver->read(config.slots, KEY, &response);
-
-    readValue = response.value;
-    timeout = response.timeout;
-
-    ASSERT_FALSE(readRet.isOk());
-    ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
-    ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError());
-    EXPECT_TRUE(readValue.empty());
-    EXPECT_EQ(timeout, 0u);
-}
-
-/*
- * Writing a key that is too large fails
- */
-TEST_P(WeaverAidlTest, WriteWithTooLargeKeyFails) {
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig(&config);
-    ASSERT_TRUE(configRet.isOk());
-
-    std::vector<uint8_t> bigKey(config.keySize + 1);
-
-    constexpr uint32_t slotId = 0;
-    const auto writeRet = weaver->write(slotId, bigKey, VALUE);
-    ASSERT_FALSE(writeRet.isOk());
-}
-
-/*
- * Writing a value that is too large fails
- */
-TEST_P(WeaverAidlTest, WriteWithTooLargeValueFails) {
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig(&config);
-    ASSERT_TRUE(configRet.isOk());
-
-    std::vector<uint8_t> bigValue(config.valueSize + 1);
-
-    constexpr uint32_t slotId = 0;
-    const auto writeRet = weaver->write(slotId, KEY, bigValue);
-    ASSERT_FALSE(writeRet.isOk());
-}
-
-/*
- * Reading with a key that is loo large fails
- */
-TEST_P(WeaverAidlTest, ReadWithTooLargeKeyFails) {
-    WeaverConfig config;
-    const auto configRet = weaver->getConfig(&config);
-    ASSERT_TRUE(configRet.isOk());
-
-    std::vector<uint8_t> bigKey(config.keySize + 1);
-
-    constexpr uint32_t slotId = 0;
-    WeaverReadResponse response;
-    std::vector<uint8_t> readValue;
-    uint32_t timeout;
-    const auto readRet =
-        weaver->read(slotId, bigKey, &response);
-
-    readValue = response.value;
-    timeout = response.timeout;
-
-    ASSERT_FALSE(readRet.isOk());
-    ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
-    ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError());
-    EXPECT_TRUE(readValue.empty());
-    EXPECT_EQ(timeout, 0u);
-}
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WeaverAidlTest);
-INSTANTIATE_TEST_SUITE_P(
-        PerInstance, WeaverAidlTest,
-        testing::ValuesIn(android::getAidlHalInstanceNames(IWeaver::descriptor)),
-        android::PrintInstanceNameToString);
-
-int main(int argc, char** argv) {
-    ::testing::InitGoogleTest(&argc, argv);
-    ABinderProcess_setThreadPoolMaxThreadCount(1);
-    ABinderProcess_startThreadPool();
-    return RUN_ALL_TESTS();
-}
diff --git a/weaver/vts/Android.bp b/weaver/vts/Android.bp
new file mode 100644
index 0000000..ee03b28
--- /dev/null
+++ b/weaver/vts/Android.bp
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // 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_test {
+    name: "VtsHalWeaverTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalWeaverTargetTest.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+        "libbase",
+    ],
+    static_libs: [
+        "android.hardware.weaver-V2-ndk",
+        "android.hardware.weaver@1.0",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/weaver/vts/VtsHalWeaverTargetTest.cpp b/weaver/vts/VtsHalWeaverTargetTest.cpp
new file mode 100644
index 0000000..754d467
--- /dev/null
+++ b/weaver/vts/VtsHalWeaverTargetTest.cpp
@@ -0,0 +1,427 @@
+/*
+ * 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.
+ */
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <aidl/android/hardware/weaver/IWeaver.h>
+#include <android-base/file.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/hardware/weaver/1.0/IWeaver.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include <limits>
+
+using ::aidl::android::hardware::weaver::IWeaver;
+using ::aidl::android::hardware::weaver::WeaverConfig;
+using ::aidl::android::hardware::weaver::WeaverReadResponse;
+using ::aidl::android::hardware::weaver::WeaverReadStatus;
+
+using HidlIWeaver = ::android::hardware::weaver::V1_0::IWeaver;
+using HidlWeaverConfig = ::android::hardware::weaver::V1_0::WeaverConfig;
+using HidlWeaverReadStatus = ::android::hardware::weaver::V1_0::WeaverReadStatus;
+using HidlWeaverReadResponse = ::android::hardware::weaver::V1_0::WeaverReadResponse;
+using HidlWeaverStatus = ::android::hardware::weaver::V1_0::WeaverStatus;
+
+const std::string kSlotMapFile = "/metadata/password_slots/slot_map";
+const std::vector<uint8_t> KEY{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+const std::vector<uint8_t> WRONG_KEY{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const std::vector<uint8_t> VALUE{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
+const std::vector<uint8_t> OTHER_VALUE{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 255, 255};
+
+class WeaverAdapter {
+  public:
+    virtual ~WeaverAdapter() {}
+    virtual bool isReady() = 0;
+    virtual ::ndk::ScopedAStatus getConfig(WeaverConfig* _aidl_return) = 0;
+    virtual ::ndk::ScopedAStatus read(int32_t in_slotId, const std::vector<uint8_t>& in_key,
+                                      WeaverReadResponse* _aidl_return) = 0;
+    virtual ::ndk::ScopedAStatus write(int32_t in_slotId, const std::vector<uint8_t>& in_key,
+                                       const std::vector<uint8_t>& in_value) = 0;
+};
+
+class WeaverAidlAdapter : public WeaverAdapter {
+  public:
+    WeaverAidlAdapter(const std::string& param)
+        : aidl_weaver_(IWeaver::fromBinder(
+                  ::ndk::SpAIBinder(AServiceManager_waitForService(param.c_str())))) {}
+    ~WeaverAidlAdapter() {}
+
+    bool isReady() { return aidl_weaver_ != nullptr; }
+
+    ::ndk::ScopedAStatus getConfig(WeaverConfig* _aidl_return) {
+        return aidl_weaver_->getConfig(_aidl_return);
+    }
+
+    ::ndk::ScopedAStatus read(int32_t in_slotId, const std::vector<uint8_t>& in_key,
+                              WeaverReadResponse* _aidl_return) {
+        return aidl_weaver_->read(in_slotId, in_key, _aidl_return);
+    }
+
+    ::ndk::ScopedAStatus write(int32_t in_slotId, const std::vector<uint8_t>& in_key,
+                               const std::vector<uint8_t>& in_value) {
+        return aidl_weaver_->write(in_slotId, in_key, in_value);
+    }
+
+  private:
+    std::shared_ptr<IWeaver> aidl_weaver_;
+};
+
+class WeaverHidlAdapter : public WeaverAdapter {
+  public:
+    WeaverHidlAdapter(const std::string& param) : hidl_weaver_(HidlIWeaver::getService(param)) {}
+    ~WeaverHidlAdapter() {}
+
+    bool isReady() { return hidl_weaver_ != nullptr; }
+
+    ::ndk::ScopedAStatus getConfig(WeaverConfig* _aidl_return) {
+        bool callbackCalled = false;
+        HidlWeaverStatus status;
+        HidlWeaverConfig config;
+        auto ret = hidl_weaver_->getConfig([&](HidlWeaverStatus s, HidlWeaverConfig c) {
+            callbackCalled = true;
+            status = s;
+            config = c;
+        });
+        if (!ret.isOk() || !callbackCalled || status != HidlWeaverStatus::OK) {
+            return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
+        }
+        _aidl_return->slots = config.slots;
+        _aidl_return->keySize = config.keySize;
+        _aidl_return->valueSize = config.valueSize;
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    ::ndk::ScopedAStatus read(int32_t in_slotId, const std::vector<uint8_t>& in_key,
+                              WeaverReadResponse* _aidl_return) {
+        bool callbackCalled = false;
+        HidlWeaverReadStatus status;
+        std::vector<uint8_t> value;
+        uint32_t timeout;
+        auto ret = hidl_weaver_->read(in_slotId, in_key,
+                                      [&](HidlWeaverReadStatus s, HidlWeaverReadResponse r) {
+                                          callbackCalled = true;
+                                          status = s;
+                                          value = r.value;
+                                          timeout = r.timeout;
+                                      });
+        if (!ret.isOk() || !callbackCalled) {
+            return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
+        }
+        switch (status) {
+            case HidlWeaverReadStatus::OK:
+                _aidl_return->status = WeaverReadStatus::OK;
+                break;
+            case HidlWeaverReadStatus::FAILED:
+                _aidl_return->status = WeaverReadStatus::FAILED;
+                break;
+            case HidlWeaverReadStatus::INCORRECT_KEY:
+                _aidl_return->status = WeaverReadStatus::INCORRECT_KEY;
+                break;
+            case HidlWeaverReadStatus::THROTTLE:
+                _aidl_return->status = WeaverReadStatus::THROTTLE;
+                break;
+            default:
+                ADD_FAILURE() << "Unknown HIDL read status: " << static_cast<uint32_t>(status);
+                _aidl_return->status = WeaverReadStatus::FAILED;
+                break;
+        }
+        _aidl_return->value = value;
+        _aidl_return->timeout = timeout;
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    ::ndk::ScopedAStatus write(int32_t in_slotId, const std::vector<uint8_t>& in_key,
+                               const std::vector<uint8_t>& in_value) {
+        auto status = hidl_weaver_->write(in_slotId, in_key, in_value);
+        switch (status) {
+            case HidlWeaverStatus::OK:
+                return ::ndk::ScopedAStatus::ok();
+            case HidlWeaverStatus::FAILED:
+                return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
+            default:
+                ADD_FAILURE() << "Unknown HIDL write status: " << status.description();
+                return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
+        }
+    }
+
+  private:
+    android::sp<HidlIWeaver> hidl_weaver_;
+};
+
+class WeaverTest : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+  protected:
+    void SetUp() override;
+    void TearDown() override {}
+    void FindFreeSlots();
+
+    std::unique_ptr<WeaverAdapter> weaver_;
+    WeaverConfig config_;
+    uint32_t first_free_slot_;
+    uint32_t last_free_slot_;
+};
+
+void WeaverTest::SetUp() {
+    std::string api, instance_name;
+    std::tie(api, instance_name) = GetParam();
+    if (api == "hidl") {
+        weaver_.reset(new WeaverHidlAdapter(instance_name));
+    } else if (api == "aidl") {
+        weaver_.reset(new WeaverAidlAdapter(instance_name));
+    } else {
+        FAIL() << "Bad test parameterization";
+    }
+    ASSERT_TRUE(weaver_->isReady());
+
+    auto ret = weaver_->getConfig(&config_);
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_GT(config_.slots, 0);
+    GTEST_LOG_(INFO) << "WeaverConfig: slots=" << config_.slots << ", keySize=" << config_.keySize
+                     << ", valueSize=" << config_.valueSize;
+
+    FindFreeSlots();
+    GTEST_LOG_(INFO) << "First free slot is " << first_free_slot_ << ", last free slot is "
+                     << last_free_slot_;
+}
+
+void WeaverTest::FindFreeSlots() {
+    // Determine which Weaver slots are in use by the system. These slots can't be used by the test.
+    std::set<uint32_t> used_slots;
+    if (access(kSlotMapFile.c_str(), F_OK) == 0) {
+        std::string contents;
+        ASSERT_TRUE(android::base::ReadFileToString(kSlotMapFile, &contents))
+                << "Failed to read " << kSlotMapFile;
+        for (const auto& line : android::base::Split(contents, "\n")) {
+            auto trimmed_line = android::base::Trim(line);
+            if (trimmed_line[0] == '#' || trimmed_line[0] == '\0') continue;
+            auto slot_and_user = android::base::Split(trimmed_line, "=");
+            uint32_t slot;
+            ASSERT_TRUE(slot_and_user.size() == 2 &&
+                        android::base::ParseUint(slot_and_user[0], &slot))
+                    << "Error parsing " << kSlotMapFile << " at \"" << line << "\"";
+            GTEST_LOG_(INFO) << "Slot " << slot << " is in use by " << slot_and_user[1];
+            ASSERT_LT(slot, config_.slots);
+            used_slots.insert(slot);
+        }
+    }
+    // Starting in Android 14, the system will always use at least one Weaver slot if Weaver is
+    // supported at all.  Make sure we saw at least one.
+    // TODO: uncomment after Android 14 is merged into AOSP
+    // ASSERT_FALSE(used_slots.empty())
+    //<< "Could not determine which Weaver slots are in use by the system";
+
+    // Find the first free slot.
+    int found = 0;
+    for (uint32_t i = 0; i < config_.slots; i++) {
+        if (used_slots.find(i) == used_slots.end()) {
+            first_free_slot_ = i;
+            found++;
+            break;
+        }
+    }
+    // Find the last free slot.
+    for (uint32_t i = config_.slots; i > 0; i--) {
+        if (used_slots.find(i - 1) == used_slots.end()) {
+            last_free_slot_ = i - 1;
+            found++;
+            break;
+        }
+    }
+    ASSERT_EQ(found, 2) << "All Weaver slots are already in use by the system";
+}
+
+/*
+ * Checks config values are suitably large
+ */
+TEST_P(WeaverTest, GetConfig) {
+    EXPECT_GE(config_.slots, 16u);
+    EXPECT_GE(config_.keySize, 16u);
+    EXPECT_GE(config_.valueSize, 16u);
+}
+
+/*
+ * Gets the config twice and checks they are the same
+ */
+TEST_P(WeaverTest, GettingConfigMultipleTimesGivesSameResult) {
+    WeaverConfig config2;
+
+    auto ret = weaver_->getConfig(&config2);
+    ASSERT_TRUE(ret.isOk());
+
+    EXPECT_EQ(config_, config2);
+}
+
+/*
+ * Writes a key and value to the last free slot
+ */
+TEST_P(WeaverTest, WriteToLastSlot) {
+    const auto writeRet = weaver_->write(last_free_slot_, KEY, VALUE);
+    ASSERT_TRUE(writeRet.isOk());
+}
+
+/*
+ * Writes a key and value to a slot
+ * Reads the slot with the same key and receives the value that was previously written
+ */
+TEST_P(WeaverTest, WriteFollowedByReadGivesTheSameValue) {
+    const uint32_t slotId = first_free_slot_;
+    const auto ret = weaver_->write(slotId, KEY, VALUE);
+    ASSERT_TRUE(ret.isOk());
+
+    WeaverReadResponse response;
+    const auto readRet = weaver_->read(slotId, KEY, &response);
+    ASSERT_TRUE(readRet.isOk());
+    EXPECT_EQ(response.value, VALUE);
+    EXPECT_EQ(response.timeout, 0u);
+    EXPECT_EQ(response.status, WeaverReadStatus::OK);
+}
+
+/*
+ * Writes a key and value to a slot
+ * Overwrites the slot with a new key and value
+ * Reads the slot with the new key and receives the new value
+ */
+TEST_P(WeaverTest, OverwritingSlotUpdatesTheValue) {
+    const uint32_t slotId = first_free_slot_;
+    const auto initialWriteRet = weaver_->write(slotId, WRONG_KEY, VALUE);
+    ASSERT_TRUE(initialWriteRet.isOk());
+
+    const auto overwriteRet = weaver_->write(slotId, KEY, OTHER_VALUE);
+    ASSERT_TRUE(overwriteRet.isOk());
+
+    WeaverReadResponse response;
+    const auto readRet = weaver_->read(slotId, KEY, &response);
+    ASSERT_TRUE(readRet.isOk());
+    EXPECT_EQ(response.value, OTHER_VALUE);
+    EXPECT_EQ(response.timeout, 0u);
+    EXPECT_EQ(response.status, WeaverReadStatus::OK);
+}
+
+/*
+ * Writes a key and value to a slot
+ * Reads the slot with a different key so does not receive the value
+ */
+TEST_P(WeaverTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
+    const uint32_t slotId = first_free_slot_;
+    const auto writeRet = weaver_->write(slotId, KEY, VALUE);
+    ASSERT_TRUE(writeRet.isOk());
+
+    WeaverReadResponse response;
+    const auto readRet = weaver_->read(slotId, WRONG_KEY, &response);
+    ASSERT_TRUE(readRet.isOk());
+    EXPECT_TRUE(response.value.empty());
+    EXPECT_EQ(response.status, WeaverReadStatus::INCORRECT_KEY);
+}
+
+/*
+ * Writing to an invalid slot fails
+ */
+TEST_P(WeaverTest, WritingToInvalidSlotFails) {
+    if (config_.slots == std::numeric_limits<uint32_t>::max()) {
+        // If there are no invalid slots then pass
+        return;
+    }
+
+    const auto writeRet = weaver_->write(config_.slots, KEY, VALUE);
+    ASSERT_FALSE(writeRet.isOk());
+}
+
+/*
+ * Reading from an invalid slot fails rather than incorrect key
+ */
+TEST_P(WeaverTest, ReadingFromInvalidSlotFails) {
+    if (config_.slots == std::numeric_limits<uint32_t>::max()) {
+        // If there are no invalid slots then pass
+        return;
+    }
+
+    WeaverReadResponse response;
+    const auto readRet = weaver_->read(config_.slots, KEY, &response);
+    ASSERT_TRUE(readRet.isOk());
+    EXPECT_TRUE(response.value.empty());
+    EXPECT_EQ(response.timeout, 0u);
+    EXPECT_EQ(response.status, WeaverReadStatus::FAILED);
+}
+
+/*
+ * Writing a key that is too large fails
+ */
+TEST_P(WeaverTest, WriteWithTooLargeKeyFails) {
+    std::vector<uint8_t> bigKey(config_.keySize + 1);
+
+    const auto writeRet = weaver_->write(first_free_slot_, bigKey, VALUE);
+    ASSERT_FALSE(writeRet.isOk());
+}
+
+/*
+ * Writing a value that is too large fails
+ */
+TEST_P(WeaverTest, WriteWithTooLargeValueFails) {
+    std::vector<uint8_t> bigValue(config_.valueSize + 1);
+
+    const auto writeRet = weaver_->write(first_free_slot_, KEY, bigValue);
+    ASSERT_FALSE(writeRet.isOk());
+}
+
+/*
+ * Reading with a key that is too large fails
+ */
+TEST_P(WeaverTest, ReadWithTooLargeKeyFails) {
+    std::vector<uint8_t> bigKey(config_.keySize + 1);
+
+    WeaverReadResponse response;
+    const auto readRet = weaver_->read(first_free_slot_, bigKey, &response);
+    ASSERT_TRUE(readRet.isOk());
+    EXPECT_TRUE(response.value.empty());
+    EXPECT_EQ(response.timeout, 0u);
+    EXPECT_EQ(response.status, WeaverReadStatus::FAILED);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WeaverTest);
+
+// Instantiate the test for each HIDL Weaver service.
+INSTANTIATE_TEST_SUITE_P(
+        PerHidlInstance, WeaverTest,
+        testing::Combine(testing::Values("hidl"),
+                         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+                                 HidlIWeaver::descriptor))),
+        [](const testing::TestParamInfo<std::tuple<std::string, std::string>>& info) {
+            return android::hardware::PrintInstanceNameToString(
+                    testing::TestParamInfo<std::string>{std::get<1>(info.param), info.index});
+        });
+
+// Instantiate the test for each AIDL Weaver service.
+INSTANTIATE_TEST_SUITE_P(
+        PerAidlInstance, WeaverTest,
+        testing::Combine(testing::Values("aidl"),
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IWeaver::descriptor))),
+        [](const testing::TestParamInfo<std::tuple<std::string, std::string>>& info) {
+            // This name_generator makes the instance name be included in the test case names, e.g.
+            // "PerAidlInstance/WeaverTest#GetConfig/0_android_hardware_weaver_IWeaver_default"
+            // instead of "PerAidlInstance/WeaverTest#GetConfig/0".
+            return android::PrintInstanceNameToString(
+                    testing::TestParamInfo<std::string>{std::get<1>(info.param), info.index});
+        });
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/1.0/vts/OWNERS b/wifi/1.0/vts/OWNERS
deleted file mode 100644
index 287152d..0000000
--- a/wifi/1.0/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 33618
-arabawy@google.com
-etancohen@google.com
diff --git a/wifi/1.1/vts/OWNERS b/wifi/1.1/vts/OWNERS
deleted file mode 100644
index 294fc82..0000000
--- a/wifi/1.1/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.0/vts/OWNERS
diff --git a/wifi/1.2/vts/OWNERS b/wifi/1.2/vts/OWNERS
deleted file mode 100644
index 294fc82..0000000
--- a/wifi/1.2/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.0/vts/OWNERS
diff --git a/wifi/1.3/vts/OWNERS b/wifi/1.3/vts/OWNERS
deleted file mode 100644
index 294fc82..0000000
--- a/wifi/1.3/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.0/vts/OWNERS
diff --git a/wifi/1.4/vts/OWNERS b/wifi/1.4/vts/OWNERS
deleted file mode 100644
index 294fc82..0000000
--- a/wifi/1.4/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.0/vts/OWNERS
diff --git a/wifi/1.5/vts/OWNERS b/wifi/1.5/vts/OWNERS
deleted file mode 100644
index 294fc82..0000000
--- a/wifi/1.5/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.0/vts/OWNERS
diff --git a/wifi/1.6/default/Android.bp b/wifi/1.6/default/Android.bp
deleted file mode 100644
index d48d183..0000000
--- a/wifi/1.6/default/Android.bp
+++ /dev/null
@@ -1,107 +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 {
-    default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-filegroup {
-    name: "android.hardware.wifi@1.0-service_srcs",
-    srcs: ["service.cpp"],
-}
-
-cc_defaults {
-    name: "android.hardware.wifi@1.0-service_default",
-    srcs: [":android.hardware.wifi@1.0-service_srcs"],
-    relative_install_path: "hw",
-    soc_specific: true,
-    shared_libs: [
-        "android.hardware.wifi@1.0",
-        "android.hardware.wifi@1.1",
-        "android.hardware.wifi@1.2",
-        "android.hardware.wifi@1.3",
-        "android.hardware.wifi@1.4",
-        "android.hardware.wifi@1.5",
-        "android.hardware.wifi@1.6",
-        "libbase",
-        "libcutils",
-        "libhidlbase",
-        "liblog",
-        "libnl",
-        "libutils",
-        "libwifi-system-iface",
-        "libxml2",
-    ],
-    cppflags: [
-        "-Wall",
-        "-Werror",
-        "-Wextra",
-    ],
-}
-
-filegroup {
-    name: "android.hardware.wifi@1.0-service-lib_srcs",
-    srcs: [
-        "hidl_struct_util.cpp",
-        "hidl_sync_util.cpp",
-        "ringbuffer.cpp",
-        "wifi.cpp",
-        "wifi_ap_iface.cpp",
-        "wifi_chip.cpp",
-        "wifi_feature_flags.cpp",
-        "wifi_iface_util.cpp",
-        "wifi_legacy_hal.cpp",
-        "wifi_legacy_hal_factory.cpp",
-        "wifi_legacy_hal_stubs.cpp",
-        "wifi_mode_controller.cpp",
-        "wifi_nan_iface.cpp",
-        "wifi_p2p_iface.cpp",
-        "wifi_rtt_controller.cpp",
-        "wifi_sta_iface.cpp",
-        "wifi_status_util.cpp",
-    ],
-}
-
-cc_defaults {
-    name: "android.hardware.wifi@1.0-service-lib_defaults",
-    srcs: [":android.hardware.wifi@1.0-service-lib_srcs"],
-    relative_install_path: "hw",
-    soc_specific: true,
-    shared_libs: [
-        "android.hardware.wifi@1.0",
-        "android.hardware.wifi@1.1",
-        "android.hardware.wifi@1.2",
-        "android.hardware.wifi@1.3",
-        "android.hardware.wifi@1.4",
-        "android.hardware.wifi@1.5",
-        "android.hardware.wifi@1.6",
-        "libbase",
-        "libcutils",
-        "libhidlbase",
-        "liblog",
-        "libnl",
-        "libutils",
-        "libwifi-system-iface",
-        "libxml2",
-    ],
-    // Generated by building android.hardware.wifi@1.0-service-lib and printing LOCAL_CPPFLAGS.
-    cppflags: [
-        "-Wall",
-        "-Werror",
-        "-Wextra",
-        "-DWIFI_HIDL_FEATURE_DUAL_INTERFACE",
-    ],
-    export_include_dirs: ["."],
-    include_dirs: ["external/libxml2/include"],
-}
diff --git a/wifi/1.6/default/Android.mk b/wifi/1.6/default/Android.mk
deleted file mode 100644
index ca1c022..0000000
--- a/wifi/1.6/default/Android.mk
+++ /dev/null
@@ -1,202 +0,0 @@
-# Copyright (C) 2016 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.
-LOCAL_PATH := $(call my-dir)
-
-###
-### android.hardware.wifi static library
-###
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.wifi@1.0-service-lib
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_CPPFLAGS := -Wall -Werror -Wextra
-ifdef WIFI_HAL_INTERFACE_COMBINATIONS
-LOCAL_CPPFLAGS += -DWIFI_HAL_INTERFACE_COMBINATIONS="$(WIFI_HAL_INTERFACE_COMBINATIONS)"
-endif
-ifdef WIFI_HIDL_FEATURE_AWARE
-LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_AWARE
-endif
-ifdef WIFI_HIDL_FEATURE_DUAL_INTERFACE
-LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DUAL_INTERFACE
-endif
-ifdef WIFI_HIDL_FEATURE_DISABLE_AP
-LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP
-endif
-ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
-LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
-endif
-ifdef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
-LOCAL_CPPFLAGS += -DWIFI_AVOID_IFACE_RESET_MAC_CHANGE
-endif
-# Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed.
-LOCAL_CFLAGS += -Wno-error=implicit-fallthrough
-LOCAL_SRC_FILES := \
-    hidl_struct_util.cpp \
-    hidl_sync_util.cpp \
-    ringbuffer.cpp \
-    wifi.cpp \
-    wifi_ap_iface.cpp \
-    wifi_chip.cpp \
-    wifi_feature_flags.cpp \
-    wifi_iface_util.cpp \
-    wifi_legacy_hal.cpp \
-    wifi_legacy_hal_factory.cpp \
-    wifi_legacy_hal_stubs.cpp \
-    wifi_mode_controller.cpp \
-    wifi_nan_iface.cpp \
-    wifi_p2p_iface.cpp \
-    wifi_rtt_controller.cpp \
-    wifi_sta_iface.cpp \
-    wifi_status_util.cpp
-LOCAL_SHARED_LIBRARIES := \
-    libbase \
-    libcutils \
-    libhidlbase \
-    liblog \
-    libnl \
-    libutils \
-    libwifi-hal \
-    libwifi-system-iface \
-    libxml2 \
-    android.hardware.wifi@1.0 \
-    android.hardware.wifi@1.1 \
-    android.hardware.wifi@1.2 \
-    android.hardware.wifi@1.3 \
-    android.hardware.wifi@1.4 \
-    android.hardware.wifi@1.5 \
-    android.hardware.wifi@1.6
-LOCAL_C_INCLUDES += $(TOP)/external/libxml2/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-include $(BUILD_STATIC_LIBRARY)
-
-###
-### android.hardware.wifi daemon
-###
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.wifi@1.0-service
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_CPPFLAGS := -Wall -Werror -Wextra
-LOCAL_SRC_FILES := \
-    service.cpp
-LOCAL_SHARED_LIBRARIES := \
-    libbase \
-    libcutils \
-    libhidlbase \
-    liblog \
-    libnl \
-    libutils \
-    libwifi-hal \
-    libwifi-system-iface \
-    libxml2 \
-    android.hardware.wifi@1.0 \
-    android.hardware.wifi@1.1 \
-    android.hardware.wifi@1.2 \
-    android.hardware.wifi@1.3 \
-    android.hardware.wifi@1.4 \
-    android.hardware.wifi@1.5 \
-    android.hardware.wifi@1.6
-LOCAL_STATIC_LIBRARIES := \
-    android.hardware.wifi@1.0-service-lib
-LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc
-include $(BUILD_EXECUTABLE)
-
-###
-### android.hardware.wifi daemon
-###
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.wifi@1.0-service-lazy
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml
-LOCAL_OVERRIDES_MODULES := android.hardware.wifi@1.0-service
-LOCAL_CFLAGS := -DLAZY_SERVICE
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_CPPFLAGS := -Wall -Werror -Wextra
-LOCAL_SRC_FILES := \
-    service.cpp
-LOCAL_SHARED_LIBRARIES := \
-    libbase \
-    libcutils \
-    libhidlbase \
-    liblog \
-    libnl \
-    libutils \
-    libwifi-hal \
-    libwifi-system-iface \
-    libxml2 \
-    android.hardware.wifi@1.0 \
-    android.hardware.wifi@1.1 \
-    android.hardware.wifi@1.2 \
-    android.hardware.wifi@1.3 \
-    android.hardware.wifi@1.4 \
-    android.hardware.wifi@1.5 \
-    android.hardware.wifi@1.6
-LOCAL_STATIC_LIBRARIES := \
-    android.hardware.wifi@1.0-service-lib
-LOCAL_INIT_RC := android.hardware.wifi@1.0-service-lazy.rc
-include $(BUILD_EXECUTABLE)
-
-###
-### android.hardware.wifi unit tests.
-###
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.wifi@1.0-service-tests
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_CPPFLAGS := -Wall -Werror -Wextra
-LOCAL_SRC_FILES := \
-    tests/hidl_struct_util_unit_tests.cpp \
-    tests/main.cpp \
-    tests/mock_interface_tool.cpp \
-    tests/mock_wifi_feature_flags.cpp \
-    tests/mock_wifi_iface_util.cpp \
-    tests/mock_wifi_legacy_hal.cpp \
-    tests/mock_wifi_mode_controller.cpp \
-    tests/ringbuffer_unit_tests.cpp \
-    tests/wifi_nan_iface_unit_tests.cpp \
-    tests/wifi_chip_unit_tests.cpp \
-    tests/wifi_iface_util_unit_tests.cpp
-LOCAL_STATIC_LIBRARIES := \
-    libgmock \
-    libgtest \
-    android.hardware.wifi@1.0 \
-    android.hardware.wifi@1.1 \
-    android.hardware.wifi@1.2 \
-    android.hardware.wifi@1.3 \
-    android.hardware.wifi@1.4 \
-    android.hardware.wifi@1.5 \
-    android.hardware.wifi@1.6 \
-    android.hardware.wifi@1.0-service-lib
-LOCAL_SHARED_LIBRARIES := \
-    libbase \
-    libcutils \
-    libhidlbase \
-    liblog \
-    libnl \
-    libutils \
-    libwifi-hal \
-    libwifi-system-iface
-include $(BUILD_NATIVE_TEST)
diff --git a/wifi/1.6/default/OWNERS b/wifi/1.6/default/OWNERS
deleted file mode 100644
index cf81c79..0000000
--- a/wifi/1.6/default/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-arabawy@google.com
-etancohen@google.com
diff --git a/wifi/1.6/default/THREADING.README b/wifi/1.6/default/THREADING.README
deleted file mode 100644
index 8366ca0..0000000
--- a/wifi/1.6/default/THREADING.README
+++ /dev/null
@@ -1,35 +0,0 @@
-Vendor HAL Threading Model
-==========================
-The vendor HAL service has two threads:
-1. HIDL thread: This is the main thread which processes all the incoming HIDL
-RPC's.
-2. Legacy HAL event loop thread: This is the thread forked off for processing
-the legacy HAL event loop (wifi_event_loop()). This thread is used to process
-any asynchronous netlink events posted by the driver. Any asynchronous
-callbacks passed to the legacy HAL API's are invoked on this thread.
-
-Synchronization Concerns
-========================
-wifi_legacy_hal.cpp has a bunch of global "C" style functions to handle the
-legacy callbacks. Each of these "C" style function invokes a corresponding
-"std::function" version of the callback which does the actual processing.
-The variables holding these "std::function" callbacks are reset from the HIDL
-thread when they are no longer used. For example: stopGscan() will reset the
-corresponding "on_gscan_*" callback variables which were set when startGscan()
-was invoked. This is not thread safe since these callback variables are
-accesed from the legacy hal event loop thread as well.
-
-Synchronization Solution
-========================
-Adding a global lock seems to be the most trivial solution to the problem.
-a) All of the asynchronous "C" style callbacks will acquire the global lock
-before invoking the corresponding "std::function" callback variables.
-b) All of the HIDL methods will also acquire the global lock before processing
-(in hidl_return_util::validateAndCall()).
-
-Note: It's important that we only acquire the global lock for asynchronous
-callbacks, because there is no guarantee (or documentation to clarify) that the
-synchronous callbacks are invoked on the same invocation thread. If that is not
-the case in some implementation, we will end up deadlocking the system since the
-HIDL thread would have acquired the global lock which is needed by the
-synchronous callback executed on the legacy hal event loop thread.
diff --git a/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc
deleted file mode 100644
index ee8c818..0000000
--- a/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc
+++ /dev/null
@@ -1,14 +0,0 @@
-service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service-lazy
-    interface android.hardware.wifi@1.0::IWifi default
-    interface android.hardware.wifi@1.1::IWifi default
-    interface android.hardware.wifi@1.2::IWifi default
-    interface android.hardware.wifi@1.3::IWifi default
-    interface android.hardware.wifi@1.4::IWifi default
-    interface android.hardware.wifi@1.5::IWifi default
-    interface android.hardware.wifi@1.6::IWifi default
-    oneshot
-    disabled
-    class hal
-    capabilities NET_ADMIN NET_RAW SYS_MODULE
-    user wifi
-    group wifi gps
diff --git a/wifi/1.6/default/android.hardware.wifi@1.0-service.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service.rc
deleted file mode 100644
index 18f40d0..0000000
--- a/wifi/1.6/default/android.hardware.wifi@1.0-service.rc
+++ /dev/null
@@ -1,12 +0,0 @@
-service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service
-    interface android.hardware.wifi@1.0::IWifi default
-    interface android.hardware.wifi@1.1::IWifi default
-    interface android.hardware.wifi@1.2::IWifi default
-    interface android.hardware.wifi@1.3::IWifi default
-    interface android.hardware.wifi@1.4::IWifi default
-    interface android.hardware.wifi@1.5::IWifi default
-    interface android.hardware.wifi@1.6::IWifi default
-    class hal
-    capabilities NET_ADMIN NET_RAW SYS_MODULE
-    user wifi
-    group wifi gps
diff --git a/wifi/1.6/default/android.hardware.wifi@1.0-service.xml b/wifi/1.6/default/android.hardware.wifi@1.0-service.xml
deleted file mode 100644
index 771fbaa..0000000
--- a/wifi/1.6/default/android.hardware.wifi@1.0-service.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest version="1.0" type="device">
-    <hal format="hidl">
-        <name>android.hardware.wifi</name>
-        <transport>hwbinder</transport>
-        <version>1.6</version>
-        <interface>
-            <name>IWifi</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-</manifest>
diff --git a/wifi/1.6/default/hidl_callback_util.h b/wifi/1.6/default/hidl_callback_util.h
deleted file mode 100644
index aab0ae5..0000000
--- a/wifi/1.6/default/hidl_callback_util.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2017 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 HIDL_CALLBACK_UTIL_H_
-#define HIDL_CALLBACK_UTIL_H_
-
-#include <set>
-
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-
-namespace {
-// Type of callback invoked by the death handler.
-using on_death_cb_function = std::function<void(uint64_t)>;
-
-// Private class used to keep track of death of individual
-// callbacks stored in HidlCallbackHandler.
-template <typename CallbackType>
-class HidlDeathHandler : public android::hardware::hidl_death_recipient {
-  public:
-    HidlDeathHandler(const on_death_cb_function& user_cb_function)
-        : cb_function_(user_cb_function) {}
-    ~HidlDeathHandler() = default;
-
-    // Death notification for callbacks.
-    void serviceDied(uint64_t cookie,
-                     const android::wp<android::hidl::base::V1_0::IBase>& /* who */) override {
-        cb_function_(cookie);
-    }
-
-  private:
-    on_death_cb_function cb_function_;
-
-    DISALLOW_COPY_AND_ASSIGN(HidlDeathHandler);
-};
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace hidl_callback_util {
-template <typename CallbackType>
-// Provides a class to manage callbacks for the various HIDL interfaces and
-// handle the death of the process hosting each callback.
-class HidlCallbackHandler {
-  public:
-    HidlCallbackHandler()
-        : death_handler_(new HidlDeathHandler<CallbackType>(
-                  std::bind(&HidlCallbackHandler::onObjectDeath, this, std::placeholders::_1))) {}
-    ~HidlCallbackHandler() = default;
-
-    bool addCallback(const sp<CallbackType>& cb) {
-        // TODO(b/33818800): Can't compare proxies yet. So, use the cookie
-        // (callback proxy's raw pointer) to track the death of individual
-        // clients.
-        uint64_t cookie = reinterpret_cast<uint64_t>(cb.get());
-        for (const auto& s : cb_set_) {
-            if (interfacesEqual(cb, s)) {
-                LOG(ERROR) << "Duplicate death notification registration";
-                return true;
-            }
-        }
-        if (!cb->linkToDeath(death_handler_, cookie)) {
-            LOG(ERROR) << "Failed to register death notification";
-            return false;
-        }
-        cb_set_.insert(cb);
-        return true;
-    }
-
-    const std::set<android::sp<CallbackType>>& getCallbacks() { return cb_set_; }
-
-    // Death notification for callbacks.
-    void onObjectDeath(uint64_t cookie) {
-        CallbackType* cb = reinterpret_cast<CallbackType*>(cookie);
-        const auto& iter = cb_set_.find(cb);
-        if (iter == cb_set_.end()) {
-            LOG(ERROR) << "Unknown callback death notification received";
-            return;
-        }
-        cb_set_.erase(iter);
-        LOG(DEBUG) << "Dead callback removed from list";
-    }
-
-    void invalidate() {
-        for (const sp<CallbackType>& cb : cb_set_) {
-            if (!cb->unlinkToDeath(death_handler_)) {
-                LOG(ERROR) << "Failed to deregister death notification";
-            }
-        }
-        cb_set_.clear();
-    }
-
-  private:
-    std::set<sp<CallbackType>> cb_set_;
-    sp<HidlDeathHandler<CallbackType>> death_handler_;
-
-    DISALLOW_COPY_AND_ASSIGN(HidlCallbackHandler);
-};
-
-}  // namespace hidl_callback_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-#endif  // HIDL_CALLBACK_UTIL_H_
diff --git a/wifi/1.6/default/hidl_return_util.h b/wifi/1.6/default/hidl_return_util.h
deleted file mode 100644
index a0efac2..0000000
--- a/wifi/1.6/default/hidl_return_util.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2016 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 HIDL_RETURN_UTIL_H_
-#define HIDL_RETURN_UTIL_H_
-
-#include "hidl_sync_util.h"
-#include "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace hidl_return_util {
-using namespace android::hardware::wifi::V1_0;
-
-/**
- * These utility functions are used to invoke a method on the provided
- * HIDL interface object.
- * These functions checks if the provided HIDL interface object is valid.
- * a) if valid, Invokes the corresponding internal implementation function of
- * the HIDL method. It then invokes the HIDL continuation callback with
- * the status and any returned values.
- * b) if invalid, invokes the HIDL continuation callback with the
- * provided error status and default values.
- */
-// Use for HIDL methods which return only an instance of WifiStatus.
-template <typename ObjT, typename WorkFuncT, typename... Args>
-Return<void> validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
-                             const std::function<void(const WifiStatus&)>& hidl_cb,
-                             Args&&... args) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (obj->isValid()) {
-        hidl_cb((obj->*work)(std::forward<Args>(args)...));
-    } else {
-        hidl_cb(createWifiStatus(status_code_if_invalid));
-    }
-    return Void();
-}
-
-// Use for HIDL methods which return only an instance of WifiStatus.
-// This version passes the global lock acquired to the body of the method.
-// Note: Only used by IWifi::stop() currently.
-template <typename ObjT, typename WorkFuncT, typename... Args>
-Return<void> validateAndCallWithLock(ObjT* obj, WifiStatusCode status_code_if_invalid,
-                                     WorkFuncT&& work,
-                                     const std::function<void(const WifiStatus&)>& hidl_cb,
-                                     Args&&... args) {
-    auto lock = hidl_sync_util::acquireGlobalLock();
-    if (obj->isValid()) {
-        hidl_cb((obj->*work)(&lock, std::forward<Args>(args)...));
-    } else {
-        hidl_cb(createWifiStatus(status_code_if_invalid));
-    }
-    return Void();
-}
-
-// Use for HIDL methods which return instance of WifiStatus and a single return
-// value.
-template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
-Return<void> validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
-                             const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb,
-                             Args&&... args) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (obj->isValid()) {
-        const auto& ret_pair = (obj->*work)(std::forward<Args>(args)...);
-        const WifiStatus& status = std::get<0>(ret_pair);
-        const auto& ret_value = std::get<1>(ret_pair);
-        hidl_cb(status, ret_value);
-    } else {
-        hidl_cb(createWifiStatus(status_code_if_invalid),
-                typename std::remove_reference<ReturnT>::type());
-    }
-    return Void();
-}
-
-// Use for HIDL methods which return instance of WifiStatus and 2 return
-// values.
-template <typename ObjT, typename WorkFuncT, typename ReturnT1, typename ReturnT2, typename... Args>
-Return<void> validateAndCall(
-        ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
-        const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb, Args&&... args) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (obj->isValid()) {
-        const auto& ret_tuple = (obj->*work)(std::forward<Args>(args)...);
-        const WifiStatus& status = std::get<0>(ret_tuple);
-        const auto& ret_value1 = std::get<1>(ret_tuple);
-        const auto& ret_value2 = std::get<2>(ret_tuple);
-        hidl_cb(status, ret_value1, ret_value2);
-    } else {
-        hidl_cb(createWifiStatus(status_code_if_invalid),
-                typename std::remove_reference<ReturnT1>::type(),
-                typename std::remove_reference<ReturnT2>::type());
-    }
-    return Void();
-}
-
-}  // namespace hidl_return_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-#endif  // HIDL_RETURN_UTIL_H_
diff --git a/wifi/1.6/default/hidl_struct_util.cpp b/wifi/1.6/default/hidl_struct_util.cpp
deleted file mode 100644
index 2112b26..0000000
--- a/wifi/1.6/default/hidl_struct_util.cpp
+++ /dev/null
@@ -1,3007 +0,0 @@
-/*
- * Copyright (C) 2016 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 <utils/SystemClock.h>
-
-#include "hidl_struct_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace hidl_struct_util {
-
-using V1_6::NanConfigRequestSupplemental;
-
-WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(legacy_hal::wifi_channel_width type);
-
-hidl_string safeConvertChar(const char* str, size_t max_len) {
-    const char* c = str;
-    size_t size = 0;
-    while (*c && (unsigned char)*c < 128 && size < max_len) {
-        ++size;
-        ++c;
-    }
-    return hidl_string(str, size);
-}
-
-IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability(uint32_t feature) {
-    using HidlChipCaps = IWifiChip::ChipCapabilityMask;
-    switch (feature) {
-        case legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED:
-            return HidlChipCaps::DEBUG_MEMORY_FIRMWARE_DUMP;
-        case legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED:
-            return HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP;
-        case legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED:
-            return HidlChipCaps::DEBUG_RING_BUFFER_CONNECT_EVENT;
-        case legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED:
-            return HidlChipCaps::DEBUG_RING_BUFFER_POWER_EVENT;
-        case legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED:
-            return HidlChipCaps::DEBUG_RING_BUFFER_WAKELOCK_EVENT;
-    };
-    CHECK(false) << "Unknown legacy feature: " << feature;
-    return {};
-}
-
-IWifiStaIface::StaIfaceCapabilityMask convertLegacyLoggerFeatureToHidlStaIfaceCapability(
-        uint32_t feature) {
-    using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
-    switch (feature) {
-        case legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED:
-            return HidlStaIfaceCaps::DEBUG_PACKET_FATE;
-    };
-    CHECK(false) << "Unknown legacy feature: " << feature;
-    return {};
-}
-
-V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability(uint64_t feature) {
-    using HidlChipCaps = V1_5::IWifiChip::ChipCapabilityMask;
-    switch (feature) {
-        case WIFI_FEATURE_SET_TX_POWER_LIMIT:
-            return HidlChipCaps::SET_TX_POWER_LIMIT;
-        case WIFI_FEATURE_USE_BODY_HEAD_SAR:
-            return HidlChipCaps::USE_BODY_HEAD_SAR;
-        case WIFI_FEATURE_D2D_RTT:
-            return HidlChipCaps::D2D_RTT;
-        case WIFI_FEATURE_D2AP_RTT:
-            return HidlChipCaps::D2AP_RTT;
-        case WIFI_FEATURE_INFRA_60G:
-            return HidlChipCaps::WIGIG;
-        case WIFI_FEATURE_SET_LATENCY_MODE:
-            return HidlChipCaps::SET_LATENCY_MODE;
-        case WIFI_FEATURE_P2P_RAND_MAC:
-            return HidlChipCaps::P2P_RAND_MAC;
-    };
-    CHECK(false) << "Unknown legacy feature: " << feature;
-    return {};
-}
-
-IWifiStaIface::StaIfaceCapabilityMask convertLegacyFeatureToHidlStaIfaceCapability(
-        uint64_t feature) {
-    using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
-    switch (feature) {
-        case WIFI_FEATURE_GSCAN:
-            return HidlStaIfaceCaps::BACKGROUND_SCAN;
-        case WIFI_FEATURE_LINK_LAYER_STATS:
-            return HidlStaIfaceCaps::LINK_LAYER_STATS;
-        case WIFI_FEATURE_RSSI_MONITOR:
-            return HidlStaIfaceCaps::RSSI_MONITOR;
-        case WIFI_FEATURE_CONTROL_ROAMING:
-            return HidlStaIfaceCaps::CONTROL_ROAMING;
-        case WIFI_FEATURE_IE_WHITELIST:
-            return HidlStaIfaceCaps::PROBE_IE_WHITELIST;
-        case WIFI_FEATURE_SCAN_RAND:
-            return HidlStaIfaceCaps::SCAN_RAND;
-        case WIFI_FEATURE_INFRA_5G:
-            return HidlStaIfaceCaps::STA_5G;
-        case WIFI_FEATURE_HOTSPOT:
-            return HidlStaIfaceCaps::HOTSPOT;
-        case WIFI_FEATURE_PNO:
-            return HidlStaIfaceCaps::PNO;
-        case WIFI_FEATURE_TDLS:
-            return HidlStaIfaceCaps::TDLS;
-        case WIFI_FEATURE_TDLS_OFFCHANNEL:
-            return HidlStaIfaceCaps::TDLS_OFFCHANNEL;
-        case WIFI_FEATURE_CONFIG_NDO:
-            return HidlStaIfaceCaps::ND_OFFLOAD;
-        case WIFI_FEATURE_MKEEP_ALIVE:
-            return HidlStaIfaceCaps::KEEP_ALIVE;
-    };
-    CHECK(false) << "Unknown legacy feature: " << feature;
-    return {};
-}
-
-bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set,
-                                                 uint32_t legacy_logger_feature_set,
-                                                 uint32_t* hidl_caps) {
-    if (!hidl_caps) {
-        return false;
-    }
-    *hidl_caps = {};
-    using HidlChipCaps = IWifiChip::ChipCapabilityMask;
-    for (const auto feature : {legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED,
-                               legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED,
-                               legacy_hal::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED,
-                               legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED,
-                               legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED}) {
-        if (feature & legacy_logger_feature_set) {
-            *hidl_caps |= convertLegacyLoggerFeatureToHidlChipCapability(feature);
-        }
-    }
-    std::vector<uint64_t> features = {WIFI_FEATURE_SET_TX_POWER_LIMIT,
-                                      WIFI_FEATURE_USE_BODY_HEAD_SAR,
-                                      WIFI_FEATURE_D2D_RTT,
-                                      WIFI_FEATURE_D2AP_RTT,
-                                      WIFI_FEATURE_INFRA_60G,
-                                      WIFI_FEATURE_SET_LATENCY_MODE,
-                                      WIFI_FEATURE_P2P_RAND_MAC};
-    for (const auto feature : features) {
-        if (feature & legacy_feature_set) {
-            *hidl_caps |= convertLegacyFeatureToHidlChipCapability(feature);
-        }
-    }
-
-    // There are no flags for these 3 in the legacy feature set. Adding them to
-    // the set because all the current devices support it.
-    *hidl_caps |= HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA;
-    *hidl_caps |= HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS;
-    *hidl_caps |= HidlChipCaps::DEBUG_ERROR_ALERTS;
-    return true;
-}
-
-WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToHidl(uint32_t flag) {
-    switch (flag) {
-        case WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES:
-            return WifiDebugRingBufferFlags::HAS_BINARY_ENTRIES;
-        case WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES:
-            return WifiDebugRingBufferFlags::HAS_ASCII_ENTRIES;
-    };
-    CHECK(false) << "Unknown legacy flag: " << flag;
-    return {};
-}
-
-bool convertLegacyDebugRingBufferStatusToHidl(
-        const legacy_hal::wifi_ring_buffer_status& legacy_status,
-        WifiDebugRingBufferStatus* hidl_status) {
-    if (!hidl_status) {
-        return false;
-    }
-    *hidl_status = {};
-    hidl_status->ringName = safeConvertChar(reinterpret_cast<const char*>(legacy_status.name),
-                                            sizeof(legacy_status.name));
-    hidl_status->flags = 0;
-    for (const auto flag :
-         {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES, WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) {
-        if (flag & legacy_status.flags) {
-            hidl_status->flags |= static_cast<std::underlying_type<WifiDebugRingBufferFlags>::type>(
-                    convertLegacyDebugRingBufferFlagsToHidl(flag));
-        }
-    }
-    hidl_status->ringId = legacy_status.ring_id;
-    hidl_status->sizeInBytes = legacy_status.ring_buffer_byte_size;
-    // Calculate free size of the ring the buffer. We don't need to send the
-    // exact read/write pointers that were there in the legacy HAL interface.
-    if (legacy_status.written_bytes >= legacy_status.read_bytes) {
-        hidl_status->freeSizeInBytes = legacy_status.ring_buffer_byte_size -
-                                       (legacy_status.written_bytes - legacy_status.read_bytes);
-    } else {
-        hidl_status->freeSizeInBytes = legacy_status.read_bytes - legacy_status.written_bytes;
-    }
-    hidl_status->verboseLevel = legacy_status.verbose_level;
-    return true;
-}
-
-bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
-        const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
-        std::vector<WifiDebugRingBufferStatus>* hidl_status_vec) {
-    if (!hidl_status_vec) {
-        return false;
-    }
-    *hidl_status_vec = {};
-    for (const auto& legacy_status : legacy_status_vec) {
-        WifiDebugRingBufferStatus hidl_status;
-        if (!convertLegacyDebugRingBufferStatusToHidl(legacy_status, &hidl_status)) {
-            return false;
-        }
-        hidl_status_vec->push_back(hidl_status);
-    }
-    return true;
-}
-
-bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats,
-                                        WifiDebugHostWakeReasonStats* hidl_stats) {
-    if (!hidl_stats) {
-        return false;
-    }
-    *hidl_stats = {};
-    hidl_stats->totalCmdEventWakeCnt = legacy_stats.wake_reason_cnt.total_cmd_event_wake;
-    hidl_stats->cmdEventWakeCntPerType = legacy_stats.cmd_event_wake_cnt;
-    hidl_stats->totalDriverFwLocalWakeCnt = legacy_stats.wake_reason_cnt.total_driver_fw_local_wake;
-    hidl_stats->driverFwLocalWakeCntPerType = legacy_stats.driver_fw_local_wake_cnt;
-    hidl_stats->totalRxPacketWakeCnt = legacy_stats.wake_reason_cnt.total_rx_data_wake;
-    hidl_stats->rxPktWakeDetails.rxUnicastCnt =
-            legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt;
-    hidl_stats->rxPktWakeDetails.rxMulticastCnt =
-            legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt;
-    hidl_stats->rxPktWakeDetails.rxBroadcastCnt =
-            legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt;
-    hidl_stats->rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt =
-            legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt;
-    hidl_stats->rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt =
-            legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt;
-    hidl_stats->rxMulticastPkWakeDetails.otherRxMulticastAddrCnt =
-            legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt;
-    hidl_stats->rxIcmpPkWakeDetails.icmpPkt =
-            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt;
-    hidl_stats->rxIcmpPkWakeDetails.icmp6Pkt =
-            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt;
-    hidl_stats->rxIcmpPkWakeDetails.icmp6Ra =
-            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra;
-    hidl_stats->rxIcmpPkWakeDetails.icmp6Na =
-            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na;
-    hidl_stats->rxIcmpPkWakeDetails.icmp6Ns =
-            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns;
-    return true;
-}
-
-legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
-        V1_1::IWifiChip::TxPowerScenario hidl_scenario) {
-    switch (hidl_scenario) {
-        // This is the only supported scenario for V1_1
-        case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL:
-            return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL;
-    };
-    CHECK(false);
-}
-
-legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2(
-        V1_2::IWifiChip::TxPowerScenario hidl_scenario) {
-    switch (hidl_scenario) {
-        // This is the only supported scenario for V1_1
-        case V1_2::IWifiChip::TxPowerScenario::VOICE_CALL:
-            return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL;
-        // Those are the supported scenarios for V1_2
-        case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF:
-            return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
-        case V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_ON:
-            return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
-        case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF:
-            return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
-        case V1_2::IWifiChip::TxPowerScenario::ON_BODY_CELL_ON:
-            return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
-    };
-    CHECK(false);
-}
-
-legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy(
-        V1_3::IWifiChip::LatencyMode hidl_latency_mode) {
-    switch (hidl_latency_mode) {
-        case V1_3::IWifiChip::LatencyMode::NORMAL:
-            return legacy_hal::WIFI_LATENCY_MODE_NORMAL;
-        case V1_3::IWifiChip::LatencyMode::LOW:
-            return legacy_hal::WIFI_LATENCY_MODE_LOW;
-    }
-    CHECK(false);
-}
-
-bool convertLegacyWifiMacInfoToHidl(
-        const legacy_hal::WifiMacInfo& legacy_mac_info,
-        V1_4::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) {
-    if (!hidl_radio_mode_info) {
-        return false;
-    }
-    *hidl_radio_mode_info = {};
-
-    hidl_radio_mode_info->radioId = legacy_mac_info.wlan_mac_id;
-    // Convert from bitmask of bands in the legacy HAL to enum value in
-    // the HIDL interface.
-    if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
-        legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND &&
-        legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
-        hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ_6GHZ;
-    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
-               legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
-        hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ_6GHZ;
-    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND) {
-        hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_6GHZ;
-    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND &&
-               legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
-        hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ;
-    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
-        hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ;
-    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
-        hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ;
-    } else {
-        hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_UNSPECIFIED;
-    }
-    std::vector<V1_2::IWifiChipEventCallback::IfaceInfo> iface_info_vec;
-    for (const auto& legacy_iface_info : legacy_mac_info.iface_infos) {
-        V1_2::IWifiChipEventCallback::IfaceInfo iface_info;
-        iface_info.name = legacy_iface_info.name;
-        iface_info.channel = legacy_iface_info.channel;
-        iface_info_vec.push_back(iface_info);
-    }
-    hidl_radio_mode_info->ifaceInfos = iface_info_vec;
-    return true;
-}
-
-uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) {
-    switch (hidl_band) {
-        case V1_5::WifiBand::BAND_24GHZ:
-            return legacy_hal::WLAN_MAC_2_4_BAND;
-        case V1_5::WifiBand::BAND_5GHZ:
-        case V1_5::WifiBand::BAND_5GHZ_DFS:
-        case V1_5::WifiBand::BAND_5GHZ_WITH_DFS:
-            return legacy_hal::WLAN_MAC_5_0_BAND;
-        case V1_5::WifiBand::BAND_24GHZ_5GHZ:
-        case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
-            return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND);
-        case V1_5::WifiBand::BAND_6GHZ:
-            return legacy_hal::WLAN_MAC_6_0_BAND;
-        case V1_5::WifiBand::BAND_5GHZ_6GHZ:
-            return (legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_6_0_BAND);
-        case V1_5::WifiBand::BAND_24GHZ_5GHZ_6GHZ:
-        case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ:
-            return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
-                    legacy_hal::WLAN_MAC_6_0_BAND);
-        case V1_5::WifiBand::BAND_60GHZ:
-            return legacy_hal::WLAN_MAC_60_0_BAND;
-        default:
-            return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
-                    legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND);
-    }
-}
-
-V1_5::WifiBand convertLegacyMacBandToHidlWifiBand(uint32_t band) {
-    switch (band) {
-        case legacy_hal::WLAN_MAC_2_4_BAND:
-            return V1_5::WifiBand::BAND_24GHZ;
-        case legacy_hal::WLAN_MAC_5_0_BAND:
-            return V1_5::WifiBand::BAND_5GHZ;
-        case legacy_hal::WLAN_MAC_6_0_BAND:
-            return V1_5::WifiBand::BAND_6GHZ;
-        case legacy_hal::WLAN_MAC_60_0_BAND:
-            return V1_5::WifiBand::BAND_60GHZ;
-        default:
-            return V1_5::WifiBand::BAND_UNSPECIFIED;
-    }
-}
-
-uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask) {
-    uint32_t legacy_iface_mask = 0;
-    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_STA) {
-        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA);
-    }
-    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP) {
-        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP);
-    }
-    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT) {
-        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT);
-    }
-    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO) {
-        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO);
-    }
-    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_NAN) {
-        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN);
-    }
-    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_TDLS) {
-        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS);
-    }
-    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_MESH) {
-        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH);
-    }
-    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_IBSS) {
-        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS);
-    }
-    return legacy_iface_mask;
-}
-
-uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) {
-    uint32_t hidl_iface_mask = 0;
-    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) {
-        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_STA;
-    }
-    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) {
-        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP;
-    }
-    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) {
-        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT;
-    }
-    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) {
-        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO;
-    }
-    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) {
-        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_NAN;
-    }
-    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) {
-        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_TDLS;
-    }
-    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) {
-        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_MESH;
-    }
-    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) {
-        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_IBSS;
-    }
-    return hidl_iface_mask;
-}
-
-uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask) {
-    uint32_t legacy_filter_mask = 0;
-    if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) {
-        legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
-    }
-    if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CONCURRENCY) {
-        legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
-    }
-    if (hidl_filter_mask & V1_6::IWifiChip::UsableChannelFilter::NAN_INSTANT_MODE) {
-        legacy_filter_mask |= WIFI_USABLE_CHANNEL_FILTER_NAN_INSTANT_MODE;
-    }
-    return legacy_filter_mask;
-}
-
-bool convertLegacyWifiUsableChannelToHidl(
-        const legacy_hal::wifi_usable_channel& legacy_usable_channel,
-        V1_6::WifiUsableChannel* hidl_usable_channel) {
-    if (!hidl_usable_channel) {
-        return false;
-    }
-    *hidl_usable_channel = {};
-    hidl_usable_channel->channel = legacy_usable_channel.freq;
-    hidl_usable_channel->channelBandwidth =
-            convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width);
-    hidl_usable_channel->ifaceModeMask =
-            convertLegacyWifiInterfaceModeToHidl(legacy_usable_channel.iface_mode_mask);
-
-    return true;
-}
-
-bool convertLegacyWifiUsableChannelsToHidl(
-        const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
-        std::vector<V1_6::WifiUsableChannel>* hidl_usable_channels) {
-    if (!hidl_usable_channels) {
-        return false;
-    }
-    *hidl_usable_channels = {};
-    for (const auto& legacy_usable_channel : legacy_usable_channels) {
-        V1_6::WifiUsableChannel hidl_usable_channel;
-        if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel, &hidl_usable_channel)) {
-            return false;
-        }
-        hidl_usable_channels->push_back(hidl_usable_channel);
-    }
-    return true;
-}
-
-bool convertLegacyWifiMacInfosToHidl(
-        const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
-        std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos) {
-    if (!hidl_radio_mode_infos) {
-        return false;
-    }
-    *hidl_radio_mode_infos = {};
-
-    for (const auto& legacy_mac_info : legacy_mac_infos) {
-        V1_4::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info;
-        if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info, &hidl_radio_mode_info)) {
-            return false;
-        }
-        hidl_radio_mode_infos->push_back(hidl_radio_mode_info);
-    }
-    return true;
-}
-
-bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set,
-                                                uint32_t legacy_logger_feature_set,
-                                                uint32_t* hidl_caps) {
-    if (!hidl_caps) {
-        return false;
-    }
-    *hidl_caps = {};
-    using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
-    for (const auto feature : {legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED}) {
-        if (feature & legacy_logger_feature_set) {
-            *hidl_caps |= convertLegacyLoggerFeatureToHidlStaIfaceCapability(feature);
-        }
-    }
-    for (const auto feature :
-         {WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, WIFI_FEATURE_RSSI_MONITOR,
-          WIFI_FEATURE_CONTROL_ROAMING, WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
-          WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, WIFI_FEATURE_TDLS,
-          WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
-        if (feature & legacy_feature_set) {
-            *hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature);
-        }
-    }
-    // There is no flag for this one in the legacy feature set. Adding it to the
-    // set because all the current devices support it.
-    *hidl_caps |= HidlStaIfaceCaps::APF;
-    return true;
-}
-
-bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
-                                        StaApfPacketFilterCapabilities* hidl_caps) {
-    if (!hidl_caps) {
-        return false;
-    }
-    *hidl_caps = {};
-    hidl_caps->version = legacy_caps.version;
-    hidl_caps->maxLength = legacy_caps.max_len;
-    return true;
-}
-
-uint8_t convertHidlGscanReportEventFlagToLegacy(
-        StaBackgroundScanBucketEventReportSchemeMask hidl_flag) {
-    using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
-    switch (hidl_flag) {
-        case HidlFlag::EACH_SCAN:
-            return REPORT_EVENTS_EACH_SCAN;
-        case HidlFlag::FULL_RESULTS:
-            return REPORT_EVENTS_FULL_RESULTS;
-        case HidlFlag::NO_BATCH:
-            return REPORT_EVENTS_NO_BATCH;
-    };
-    CHECK(false);
-}
-
-StaScanDataFlagMask convertLegacyGscanDataFlagToHidl(uint8_t legacy_flag) {
-    switch (legacy_flag) {
-        case legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED:
-            return StaScanDataFlagMask::INTERRUPTED;
-    };
-    CHECK(false) << "Unknown legacy flag: " << legacy_flag;
-    // To silence the compiler warning about reaching the end of non-void
-    // function.
-    return {};
-}
-
-bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
-                                          StaBackgroundScanCapabilities* hidl_caps) {
-    if (!hidl_caps) {
-        return false;
-    }
-    *hidl_caps = {};
-    hidl_caps->maxCacheSize = legacy_caps.max_scan_cache_size;
-    hidl_caps->maxBuckets = legacy_caps.max_scan_buckets;
-    hidl_caps->maxApCachePerScan = legacy_caps.max_ap_cache_per_scan;
-    hidl_caps->maxReportingThreshold = legacy_caps.max_scan_reporting_threshold;
-    return true;
-}
-
-legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band) {
-    switch (band) {
-        case V1_0::WifiBand::BAND_UNSPECIFIED:
-            return legacy_hal::WIFI_BAND_UNSPECIFIED;
-        case V1_0::WifiBand::BAND_24GHZ:
-            return legacy_hal::WIFI_BAND_BG;
-        case V1_0::WifiBand::BAND_5GHZ:
-            return legacy_hal::WIFI_BAND_A;
-        case V1_0::WifiBand::BAND_5GHZ_DFS:
-            return legacy_hal::WIFI_BAND_A_DFS;
-        case V1_0::WifiBand::BAND_5GHZ_WITH_DFS:
-            return legacy_hal::WIFI_BAND_A_WITH_DFS;
-        case V1_0::WifiBand::BAND_24GHZ_5GHZ:
-            return legacy_hal::WIFI_BAND_ABG;
-        case V1_0::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
-            return legacy_hal::WIFI_BAND_ABG_WITH_DFS;
-    };
-    CHECK(false);
-}
-
-bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params,
-                                    legacy_hal::wifi_scan_cmd_params* legacy_scan_params) {
-    if (!legacy_scan_params) {
-        return false;
-    }
-    *legacy_scan_params = {};
-    legacy_scan_params->base_period = hidl_scan_params.basePeriodInMs;
-    legacy_scan_params->max_ap_per_scan = hidl_scan_params.maxApPerScan;
-    legacy_scan_params->report_threshold_percent = hidl_scan_params.reportThresholdPercent;
-    legacy_scan_params->report_threshold_num_scans = hidl_scan_params.reportThresholdNumScans;
-    if (hidl_scan_params.buckets.size() > MAX_BUCKETS) {
-        return false;
-    }
-    legacy_scan_params->num_buckets = hidl_scan_params.buckets.size();
-    for (uint32_t bucket_idx = 0; bucket_idx < hidl_scan_params.buckets.size(); bucket_idx++) {
-        const StaBackgroundScanBucketParameters& hidl_bucket_spec =
-                hidl_scan_params.buckets[bucket_idx];
-        legacy_hal::wifi_scan_bucket_spec& legacy_bucket_spec =
-                legacy_scan_params->buckets[bucket_idx];
-        if (hidl_bucket_spec.bucketIdx >= MAX_BUCKETS) {
-            return false;
-        }
-        legacy_bucket_spec.bucket = hidl_bucket_spec.bucketIdx;
-        legacy_bucket_spec.band = convertHidlWifiBandToLegacy(hidl_bucket_spec.band);
-        legacy_bucket_spec.period = hidl_bucket_spec.periodInMs;
-        legacy_bucket_spec.max_period = hidl_bucket_spec.exponentialMaxPeriodInMs;
-        legacy_bucket_spec.base = hidl_bucket_spec.exponentialBase;
-        legacy_bucket_spec.step_count = hidl_bucket_spec.exponentialStepCount;
-        legacy_bucket_spec.report_events = 0;
-        using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
-        for (const auto flag : {HidlFlag::EACH_SCAN, HidlFlag::FULL_RESULTS, HidlFlag::NO_BATCH}) {
-            if (hidl_bucket_spec.eventReportScheme &
-                static_cast<std::underlying_type<HidlFlag>::type>(flag)) {
-                legacy_bucket_spec.report_events |= convertHidlGscanReportEventFlagToLegacy(flag);
-            }
-        }
-        if (hidl_bucket_spec.frequencies.size() > MAX_CHANNELS) {
-            return false;
-        }
-        legacy_bucket_spec.num_channels = hidl_bucket_spec.frequencies.size();
-        for (uint32_t freq_idx = 0; freq_idx < hidl_bucket_spec.frequencies.size(); freq_idx++) {
-            legacy_bucket_spec.channels[freq_idx].channel = hidl_bucket_spec.frequencies[freq_idx];
-        }
-    }
-    return true;
-}
-
-bool convertLegacyIeToHidl(const legacy_hal::wifi_information_element& legacy_ie,
-                           WifiInformationElement* hidl_ie) {
-    if (!hidl_ie) {
-        return false;
-    }
-    *hidl_ie = {};
-    hidl_ie->id = legacy_ie.id;
-    hidl_ie->data = std::vector<uint8_t>(legacy_ie.data, legacy_ie.data + legacy_ie.len);
-    return true;
-}
-
-bool convertLegacyIeBlobToHidl(const uint8_t* ie_blob, uint32_t ie_blob_len,
-                               std::vector<WifiInformationElement>* hidl_ies) {
-    if (!ie_blob || !hidl_ies) {
-        return false;
-    }
-    *hidl_ies = {};
-    const uint8_t* ies_begin = ie_blob;
-    const uint8_t* ies_end = ie_blob + ie_blob_len;
-    const uint8_t* next_ie = ies_begin;
-    using wifi_ie = legacy_hal::wifi_information_element;
-    constexpr size_t kIeHeaderLen = sizeof(wifi_ie);
-    // Each IE should atleast have the header (i.e |id| & |len| fields).
-    while (next_ie + kIeHeaderLen <= ies_end) {
-        const wifi_ie& legacy_ie = (*reinterpret_cast<const wifi_ie*>(next_ie));
-        uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len;
-        if (next_ie + curr_ie_len > ies_end) {
-            LOG(ERROR) << "Error parsing IE blob. Next IE: " << (void*)next_ie
-                       << ", Curr IE len: " << curr_ie_len << ", IEs End: " << (void*)ies_end;
-            break;
-        }
-        WifiInformationElement hidl_ie;
-        if (!convertLegacyIeToHidl(legacy_ie, &hidl_ie)) {
-            LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id << ", len: " << legacy_ie.len;
-            break;
-        }
-        hidl_ies->push_back(std::move(hidl_ie));
-        next_ie += curr_ie_len;
-    }
-    // Check if the blob has been fully consumed.
-    if (next_ie != ies_end) {
-        LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " << (void*)next_ie
-                   << ", IEs End: " << (void*)ies_end;
-    }
-    return true;
-}
-
-bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
-                                    bool has_ie_data, StaScanResult* hidl_scan_result) {
-    if (!hidl_scan_result) {
-        return false;
-    }
-    *hidl_scan_result = {};
-    hidl_scan_result->timeStampInUs = legacy_scan_result.ts;
-    hidl_scan_result->ssid = std::vector<uint8_t>(
-            legacy_scan_result.ssid,
-            legacy_scan_result.ssid +
-                    strnlen(legacy_scan_result.ssid, sizeof(legacy_scan_result.ssid) - 1));
-    memcpy(hidl_scan_result->bssid.data(), legacy_scan_result.bssid,
-           hidl_scan_result->bssid.size());
-    hidl_scan_result->frequency = legacy_scan_result.channel;
-    hidl_scan_result->rssi = legacy_scan_result.rssi;
-    hidl_scan_result->beaconPeriodInMs = legacy_scan_result.beacon_period;
-    hidl_scan_result->capability = legacy_scan_result.capability;
-    if (has_ie_data) {
-        std::vector<WifiInformationElement> ies;
-        if (!convertLegacyIeBlobToHidl(reinterpret_cast<const uint8_t*>(legacy_scan_result.ie_data),
-                                       legacy_scan_result.ie_length, &ies)) {
-            return false;
-        }
-        hidl_scan_result->informationElements = std::move(ies);
-    }
-    return true;
-}
-
-bool convertLegacyCachedGscanResultsToHidl(
-        const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result,
-        StaScanData* hidl_scan_data) {
-    if (!hidl_scan_data) {
-        return false;
-    }
-    *hidl_scan_data = {};
-    hidl_scan_data->flags = 0;
-    for (const auto flag : {legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED}) {
-        if (legacy_cached_scan_result.flags & flag) {
-            hidl_scan_data->flags |= static_cast<std::underlying_type<StaScanDataFlagMask>::type>(
-                    convertLegacyGscanDataFlagToHidl(flag));
-        }
-    }
-    hidl_scan_data->bucketsScanned = legacy_cached_scan_result.buckets_scanned;
-
-    CHECK(legacy_cached_scan_result.num_results >= 0 &&
-          legacy_cached_scan_result.num_results <= MAX_AP_CACHE_PER_SCAN);
-    std::vector<StaScanResult> hidl_scan_results;
-    for (int32_t result_idx = 0; result_idx < legacy_cached_scan_result.num_results; result_idx++) {
-        StaScanResult hidl_scan_result;
-        if (!convertLegacyGscanResultToHidl(legacy_cached_scan_result.results[result_idx], false,
-                                            &hidl_scan_result)) {
-            return false;
-        }
-        hidl_scan_results.push_back(hidl_scan_result);
-    }
-    hidl_scan_data->results = std::move(hidl_scan_results);
-    return true;
-}
-
-bool convertLegacyVectorOfCachedGscanResultsToHidl(
-        const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
-        std::vector<StaScanData>* hidl_scan_datas) {
-    if (!hidl_scan_datas) {
-        return false;
-    }
-    *hidl_scan_datas = {};
-    for (const auto& legacy_cached_scan_result : legacy_cached_scan_results) {
-        StaScanData hidl_scan_data;
-        if (!convertLegacyCachedGscanResultsToHidl(legacy_cached_scan_result, &hidl_scan_data)) {
-            return false;
-        }
-        hidl_scan_datas->push_back(hidl_scan_data);
-    }
-    return true;
-}
-
-WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToHidl(legacy_hal::wifi_tx_packet_fate fate) {
-    switch (fate) {
-        case legacy_hal::TX_PKT_FATE_ACKED:
-            return WifiDebugTxPacketFate::ACKED;
-        case legacy_hal::TX_PKT_FATE_SENT:
-            return WifiDebugTxPacketFate::SENT;
-        case legacy_hal::TX_PKT_FATE_FW_QUEUED:
-            return WifiDebugTxPacketFate::FW_QUEUED;
-        case legacy_hal::TX_PKT_FATE_FW_DROP_INVALID:
-            return WifiDebugTxPacketFate::FW_DROP_INVALID;
-        case legacy_hal::TX_PKT_FATE_FW_DROP_NOBUFS:
-            return WifiDebugTxPacketFate::FW_DROP_NOBUFS;
-        case legacy_hal::TX_PKT_FATE_FW_DROP_OTHER:
-            return WifiDebugTxPacketFate::FW_DROP_OTHER;
-        case legacy_hal::TX_PKT_FATE_DRV_QUEUED:
-            return WifiDebugTxPacketFate::DRV_QUEUED;
-        case legacy_hal::TX_PKT_FATE_DRV_DROP_INVALID:
-            return WifiDebugTxPacketFate::DRV_DROP_INVALID;
-        case legacy_hal::TX_PKT_FATE_DRV_DROP_NOBUFS:
-            return WifiDebugTxPacketFate::DRV_DROP_NOBUFS;
-        case legacy_hal::TX_PKT_FATE_DRV_DROP_OTHER:
-            return WifiDebugTxPacketFate::DRV_DROP_OTHER;
-    };
-    CHECK(false) << "Unknown legacy fate type: " << fate;
-}
-
-WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToHidl(legacy_hal::wifi_rx_packet_fate fate) {
-    switch (fate) {
-        case legacy_hal::RX_PKT_FATE_SUCCESS:
-            return WifiDebugRxPacketFate::SUCCESS;
-        case legacy_hal::RX_PKT_FATE_FW_QUEUED:
-            return WifiDebugRxPacketFate::FW_QUEUED;
-        case legacy_hal::RX_PKT_FATE_FW_DROP_FILTER:
-            return WifiDebugRxPacketFate::FW_DROP_FILTER;
-        case legacy_hal::RX_PKT_FATE_FW_DROP_INVALID:
-            return WifiDebugRxPacketFate::FW_DROP_INVALID;
-        case legacy_hal::RX_PKT_FATE_FW_DROP_NOBUFS:
-            return WifiDebugRxPacketFate::FW_DROP_NOBUFS;
-        case legacy_hal::RX_PKT_FATE_FW_DROP_OTHER:
-            return WifiDebugRxPacketFate::FW_DROP_OTHER;
-        case legacy_hal::RX_PKT_FATE_DRV_QUEUED:
-            return WifiDebugRxPacketFate::DRV_QUEUED;
-        case legacy_hal::RX_PKT_FATE_DRV_DROP_FILTER:
-            return WifiDebugRxPacketFate::DRV_DROP_FILTER;
-        case legacy_hal::RX_PKT_FATE_DRV_DROP_INVALID:
-            return WifiDebugRxPacketFate::DRV_DROP_INVALID;
-        case legacy_hal::RX_PKT_FATE_DRV_DROP_NOBUFS:
-            return WifiDebugRxPacketFate::DRV_DROP_NOBUFS;
-        case legacy_hal::RX_PKT_FATE_DRV_DROP_OTHER:
-            return WifiDebugRxPacketFate::DRV_DROP_OTHER;
-    };
-    CHECK(false) << "Unknown legacy fate type: " << fate;
-}
-
-WifiDebugPacketFateFrameType convertLegacyDebugPacketFateFrameTypeToHidl(
-        legacy_hal::frame_type type) {
-    switch (type) {
-        case legacy_hal::FRAME_TYPE_UNKNOWN:
-            return WifiDebugPacketFateFrameType::UNKNOWN;
-        case legacy_hal::FRAME_TYPE_ETHERNET_II:
-            return WifiDebugPacketFateFrameType::ETHERNET_II;
-        case legacy_hal::FRAME_TYPE_80211_MGMT:
-            return WifiDebugPacketFateFrameType::MGMT_80211;
-    };
-    CHECK(false) << "Unknown legacy frame type: " << type;
-}
-
-bool convertLegacyDebugPacketFateFrameToHidl(const legacy_hal::frame_info& legacy_frame,
-                                             WifiDebugPacketFateFrameInfo* hidl_frame) {
-    if (!hidl_frame) {
-        return false;
-    }
-    *hidl_frame = {};
-    hidl_frame->frameType = convertLegacyDebugPacketFateFrameTypeToHidl(legacy_frame.payload_type);
-    hidl_frame->frameLen = legacy_frame.frame_len;
-    hidl_frame->driverTimestampUsec = legacy_frame.driver_timestamp_usec;
-    hidl_frame->firmwareTimestampUsec = legacy_frame.firmware_timestamp_usec;
-    const uint8_t* frame_begin =
-            reinterpret_cast<const uint8_t*>(legacy_frame.frame_content.ethernet_ii_bytes);
-    hidl_frame->frameContent =
-            std::vector<uint8_t>(frame_begin, frame_begin + legacy_frame.frame_len);
-    return true;
-}
-
-bool convertLegacyDebugTxPacketFateToHidl(const legacy_hal::wifi_tx_report& legacy_fate,
-                                          WifiDebugTxPacketFateReport* hidl_fate) {
-    if (!hidl_fate) {
-        return false;
-    }
-    *hidl_fate = {};
-    hidl_fate->fate = convertLegacyDebugTxPacketFateToHidl(legacy_fate.fate);
-    return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo);
-}
-
-bool convertLegacyVectorOfDebugTxPacketFateToHidl(
-        const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
-        std::vector<WifiDebugTxPacketFateReport>* hidl_fates) {
-    if (!hidl_fates) {
-        return false;
-    }
-    *hidl_fates = {};
-    for (const auto& legacy_fate : legacy_fates) {
-        WifiDebugTxPacketFateReport hidl_fate;
-        if (!convertLegacyDebugTxPacketFateToHidl(legacy_fate, &hidl_fate)) {
-            return false;
-        }
-        hidl_fates->push_back(hidl_fate);
-    }
-    return true;
-}
-
-bool convertLegacyDebugRxPacketFateToHidl(const legacy_hal::wifi_rx_report& legacy_fate,
-                                          WifiDebugRxPacketFateReport* hidl_fate) {
-    if (!hidl_fate) {
-        return false;
-    }
-    *hidl_fate = {};
-    hidl_fate->fate = convertLegacyDebugRxPacketFateToHidl(legacy_fate.fate);
-    return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo);
-}
-
-bool convertLegacyVectorOfDebugRxPacketFateToHidl(
-        const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
-        std::vector<WifiDebugRxPacketFateReport>* hidl_fates) {
-    if (!hidl_fates) {
-        return false;
-    }
-    *hidl_fates = {};
-    for (const auto& legacy_fate : legacy_fates) {
-        WifiDebugRxPacketFateReport hidl_fate;
-        if (!convertLegacyDebugRxPacketFateToHidl(legacy_fate, &hidl_fate)) {
-            return false;
-        }
-        hidl_fates->push_back(hidl_fate);
-    }
-    return true;
-}
-
-bool convertLegacyLinkLayerRadioStatsToHidl(
-        const legacy_hal::LinkLayerRadioStats& legacy_radio_stat,
-        V1_6::StaLinkLayerRadioStats* hidl_radio_stat) {
-    if (!hidl_radio_stat) {
-        return false;
-    }
-    *hidl_radio_stat = {};
-
-    hidl_radio_stat->radioId = legacy_radio_stat.stats.radio;
-    hidl_radio_stat->V1_0.onTimeInMs = legacy_radio_stat.stats.on_time;
-    hidl_radio_stat->V1_0.txTimeInMs = legacy_radio_stat.stats.tx_time;
-    hidl_radio_stat->V1_0.rxTimeInMs = legacy_radio_stat.stats.rx_time;
-    hidl_radio_stat->V1_0.onTimeInMsForScan = legacy_radio_stat.stats.on_time_scan;
-    hidl_radio_stat->V1_0.txTimeInMsPerLevel = legacy_radio_stat.tx_time_per_levels;
-    hidl_radio_stat->onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd;
-    hidl_radio_stat->onTimeInMsForBgScan = legacy_radio_stat.stats.on_time_gscan;
-    hidl_radio_stat->onTimeInMsForRoamScan = legacy_radio_stat.stats.on_time_roam_scan;
-    hidl_radio_stat->onTimeInMsForPnoScan = legacy_radio_stat.stats.on_time_pno_scan;
-    hidl_radio_stat->onTimeInMsForHs20Scan = legacy_radio_stat.stats.on_time_hs20;
-
-    std::vector<V1_6::WifiChannelStats> hidl_channel_stats;
-
-    for (const auto& channel_stat : legacy_radio_stat.channel_stats) {
-        V1_6::WifiChannelStats hidl_channel_stat;
-        hidl_channel_stat.onTimeInMs = channel_stat.on_time;
-        hidl_channel_stat.ccaBusyTimeInMs = channel_stat.cca_busy_time;
-        /*
-         * TODO once b/119142899 is fixed,
-         * replace below code with convertLegacyWifiChannelInfoToHidl()
-         */
-        hidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20;
-        hidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq;
-        hidl_channel_stat.channel.centerFreq0 = channel_stat.channel.center_freq0;
-        hidl_channel_stat.channel.centerFreq1 = channel_stat.channel.center_freq1;
-        hidl_channel_stats.push_back(hidl_channel_stat);
-    }
-
-    hidl_radio_stat->channelStats = hidl_channel_stats;
-
-    return true;
-}
-
-bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats,
-                                       V1_6::StaLinkLayerStats* hidl_stats) {
-    if (!hidl_stats) {
-        return false;
-    }
-    *hidl_stats = {};
-    // iface legacy_stats conversion.
-    hidl_stats->iface.V1_0.beaconRx = legacy_stats.iface.beacon_rx;
-    hidl_stats->iface.V1_0.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
-    hidl_stats->iface.V1_0.wmeBePktStats.rxMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
-    hidl_stats->iface.V1_0.wmeBePktStats.txMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
-    hidl_stats->iface.V1_0.wmeBePktStats.lostMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
-    hidl_stats->iface.V1_0.wmeBePktStats.retries =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
-    hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMinInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
-    hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
-    hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
-    hidl_stats->iface.wmeBeContentionTimeStats.contentionNumSamples =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
-    hidl_stats->iface.V1_0.wmeBkPktStats.rxMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
-    hidl_stats->iface.V1_0.wmeBkPktStats.txMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
-    hidl_stats->iface.V1_0.wmeBkPktStats.lostMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
-    hidl_stats->iface.V1_0.wmeBkPktStats.retries =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
-    hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMinInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
-    hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
-    hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
-    hidl_stats->iface.wmeBkContentionTimeStats.contentionNumSamples =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
-    hidl_stats->iface.V1_0.wmeViPktStats.rxMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
-    hidl_stats->iface.V1_0.wmeViPktStats.txMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
-    hidl_stats->iface.V1_0.wmeViPktStats.lostMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
-    hidl_stats->iface.V1_0.wmeViPktStats.retries =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
-    hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMinInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
-    hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMaxInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
-    hidl_stats->iface.wmeViContentionTimeStats.contentionTimeAvgInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
-    hidl_stats->iface.wmeViContentionTimeStats.contentionNumSamples =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
-    hidl_stats->iface.V1_0.wmeVoPktStats.rxMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
-    hidl_stats->iface.V1_0.wmeVoPktStats.txMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
-    hidl_stats->iface.V1_0.wmeVoPktStats.lostMpdu =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
-    hidl_stats->iface.V1_0.wmeVoPktStats.retries =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
-    hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMinInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
-    hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
-    hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
-    hidl_stats->iface.wmeVoContentionTimeStats.contentionNumSamples =
-            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
-    hidl_stats->iface.timeSliceDutyCycleInPercent =
-            legacy_stats.iface.info.time_slicing_duty_cycle_percent;
-    // peer info legacy_stats conversion.
-    std::vector<V1_6::StaPeerInfo> hidl_peers_info_stats;
-    for (const auto& legacy_peer_info_stats : legacy_stats.peers) {
-        V1_6::StaPeerInfo hidl_peer_info_stats;
-        if (!convertLegacyPeerInfoStatsToHidl(legacy_peer_info_stats, &hidl_peer_info_stats)) {
-            return false;
-        }
-        hidl_peers_info_stats.push_back(hidl_peer_info_stats);
-    }
-    hidl_stats->iface.peers = hidl_peers_info_stats;
-    // radio legacy_stats conversion.
-    std::vector<V1_6::StaLinkLayerRadioStats> hidl_radios_stats;
-    for (const auto& legacy_radio_stats : legacy_stats.radios) {
-        V1_6::StaLinkLayerRadioStats hidl_radio_stats;
-        if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats, &hidl_radio_stats)) {
-            return false;
-        }
-        hidl_radios_stats.push_back(hidl_radio_stats);
-    }
-    hidl_stats->radios = hidl_radios_stats;
-    // Timestamp in the HAL wrapper here since it's not provided in the legacy
-    // HAL API.
-    hidl_stats->timeStampInMs = uptimeMillis();
-    return true;
-}
-
-bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
-                                      V1_6::StaPeerInfo* hidl_peer_info_stats) {
-    if (!hidl_peer_info_stats) {
-        return false;
-    }
-    *hidl_peer_info_stats = {};
-    hidl_peer_info_stats->staCount = legacy_peer_info_stats.peer_info.bssload.sta_count;
-    hidl_peer_info_stats->chanUtil = legacy_peer_info_stats.peer_info.bssload.chan_util;
-
-    std::vector<V1_6::StaRateStat> hidlRateStats;
-    for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) {
-        V1_6::StaRateStat rateStat;
-        if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate, &rateStat.rateInfo)) {
-            return false;
-        }
-        rateStat.txMpdu = legacy_rate_stats.tx_mpdu;
-        rateStat.rxMpdu = legacy_rate_stats.rx_mpdu;
-        rateStat.mpduLost = legacy_rate_stats.mpdu_lost;
-        rateStat.retries = legacy_rate_stats.retries;
-        hidlRateStats.push_back(rateStat);
-    }
-    hidl_peer_info_stats->rateStats = hidlRateStats;
-    return true;
-}
-
-bool convertLegacyRoamingCapabilitiesToHidl(
-        const legacy_hal::wifi_roaming_capabilities& legacy_caps,
-        StaRoamingCapabilities* hidl_caps) {
-    if (!hidl_caps) {
-        return false;
-    }
-    *hidl_caps = {};
-    hidl_caps->maxBlacklistSize = legacy_caps.max_blacklist_size;
-    hidl_caps->maxWhitelistSize = legacy_caps.max_whitelist_size;
-    return true;
-}
-
-bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config,
-                                      legacy_hal::wifi_roaming_config* legacy_config) {
-    if (!legacy_config) {
-        return false;
-    }
-    *legacy_config = {};
-    if (hidl_config.bssidBlacklist.size() > MAX_BLACKLIST_BSSID ||
-        hidl_config.ssidWhitelist.size() > MAX_WHITELIST_SSID) {
-        return false;
-    }
-    legacy_config->num_blacklist_bssid = hidl_config.bssidBlacklist.size();
-    uint32_t i = 0;
-    for (const auto& bssid : hidl_config.bssidBlacklist) {
-        CHECK(bssid.size() == sizeof(legacy_hal::mac_addr));
-        memcpy(legacy_config->blacklist_bssid[i++], bssid.data(), bssid.size());
-    }
-    legacy_config->num_whitelist_ssid = hidl_config.ssidWhitelist.size();
-    i = 0;
-    for (const auto& ssid : hidl_config.ssidWhitelist) {
-        CHECK(ssid.size() <= sizeof(legacy_hal::ssid_t::ssid_str));
-        legacy_config->whitelist_ssid[i].length = ssid.size();
-        memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data(), ssid.size());
-        i++;
-    }
-    return true;
-}
-
-legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state) {
-    switch (state) {
-        case StaRoamingState::ENABLED:
-            return legacy_hal::ROAMING_ENABLE;
-        case StaRoamingState::DISABLED:
-            return legacy_hal::ROAMING_DISABLE;
-    };
-    CHECK(false);
-}
-
-legacy_hal::NanMatchAlg convertHidlNanMatchAlgToLegacy(NanMatchAlg type) {
-    switch (type) {
-        case NanMatchAlg::MATCH_ONCE:
-            return legacy_hal::NAN_MATCH_ALG_MATCH_ONCE;
-        case NanMatchAlg::MATCH_CONTINUOUS:
-            return legacy_hal::NAN_MATCH_ALG_MATCH_CONTINUOUS;
-        case NanMatchAlg::MATCH_NEVER:
-            return legacy_hal::NAN_MATCH_ALG_MATCH_NEVER;
-    }
-    CHECK(false);
-}
-
-legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy(NanPublishType type) {
-    switch (type) {
-        case NanPublishType::UNSOLICITED:
-            return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED;
-        case NanPublishType::SOLICITED:
-            return legacy_hal::NAN_PUBLISH_TYPE_SOLICITED;
-        case NanPublishType::UNSOLICITED_SOLICITED:
-            return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
-    }
-    CHECK(false);
-}
-
-legacy_hal::NanTxType convertHidlNanTxTypeToLegacy(NanTxType type) {
-    switch (type) {
-        case NanTxType::BROADCAST:
-            return legacy_hal::NAN_TX_TYPE_BROADCAST;
-        case NanTxType::UNICAST:
-            return legacy_hal::NAN_TX_TYPE_UNICAST;
-    }
-    CHECK(false);
-}
-
-legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy(NanSubscribeType type) {
-    switch (type) {
-        case NanSubscribeType::PASSIVE:
-            return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE;
-        case NanSubscribeType::ACTIVE:
-            return legacy_hal::NAN_SUBSCRIBE_TYPE_ACTIVE;
-    }
-    CHECK(false);
-}
-
-legacy_hal::NanSRFType convertHidlNanSrfTypeToLegacy(NanSrfType type) {
-    switch (type) {
-        case NanSrfType::BLOOM_FILTER:
-            return legacy_hal::NAN_SRF_ATTR_BLOOM_FILTER;
-        case NanSrfType::PARTIAL_MAC_ADDR:
-            return legacy_hal::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
-    }
-    CHECK(false);
-}
-
-legacy_hal::NanDataPathChannelCfg convertHidlNanDataPathChannelCfgToLegacy(
-        NanDataPathChannelCfg type) {
-    switch (type) {
-        case NanDataPathChannelCfg::CHANNEL_NOT_REQUESTED:
-            return legacy_hal::NAN_DP_CHANNEL_NOT_REQUESTED;
-        case NanDataPathChannelCfg::REQUEST_CHANNEL_SETUP:
-            return legacy_hal::NAN_DP_REQUEST_CHANNEL_SETUP;
-        case NanDataPathChannelCfg::FORCE_CHANNEL_SETUP:
-            return legacy_hal::NAN_DP_FORCE_CHANNEL_SETUP;
-    }
-    CHECK(false);
-}
-
-NanStatusType convertLegacyNanStatusTypeToHidl(legacy_hal::NanStatusType type) {
-    switch (type) {
-        case legacy_hal::NAN_STATUS_SUCCESS:
-            return NanStatusType::SUCCESS;
-        case legacy_hal::NAN_STATUS_INTERNAL_FAILURE:
-            return NanStatusType::INTERNAL_FAILURE;
-        case legacy_hal::NAN_STATUS_PROTOCOL_FAILURE:
-            return NanStatusType::PROTOCOL_FAILURE;
-        case legacy_hal::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID:
-            return NanStatusType::INVALID_SESSION_ID;
-        case legacy_hal::NAN_STATUS_NO_RESOURCE_AVAILABLE:
-            return NanStatusType::NO_RESOURCES_AVAILABLE;
-        case legacy_hal::NAN_STATUS_INVALID_PARAM:
-            return NanStatusType::INVALID_ARGS;
-        case legacy_hal::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID:
-            return NanStatusType::INVALID_PEER_ID;
-        case legacy_hal::NAN_STATUS_INVALID_NDP_ID:
-            return NanStatusType::INVALID_NDP_ID;
-        case legacy_hal::NAN_STATUS_NAN_NOT_ALLOWED:
-            return NanStatusType::NAN_NOT_ALLOWED;
-        case legacy_hal::NAN_STATUS_NO_OTA_ACK:
-            return NanStatusType::NO_OTA_ACK;
-        case legacy_hal::NAN_STATUS_ALREADY_ENABLED:
-            return NanStatusType::ALREADY_ENABLED;
-        case legacy_hal::NAN_STATUS_FOLLOWUP_QUEUE_FULL:
-            return NanStatusType::FOLLOWUP_TX_QUEUE_FULL;
-        case legacy_hal::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
-            return NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
-    }
-    CHECK(false);
-}
-
-void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
-                            WifiNanStatus* wifiNanStatus) {
-    wifiNanStatus->status = convertLegacyNanStatusTypeToHidl(type);
-    wifiNanStatus->description = safeConvertChar(str, max_len);
-}
-
-bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request,
-                                         legacy_hal::NanEnableRequest* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: null legacy_request";
-        return false;
-    }
-    *legacy_request = {};
-
-    legacy_request->config_2dot4g_support = 1;
-    legacy_request->support_2dot4g_val =
-            hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ];
-    legacy_request->config_support_5g = 1;
-    legacy_request->support_5g_val =
-            hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ];
-    legacy_request->config_hop_count_limit = 1;
-    legacy_request->hop_count_limit_val = hidl_request.hopCountMax;
-    legacy_request->master_pref = hidl_request.configParams.masterPref;
-    legacy_request->discovery_indication_cfg = 0;
-    legacy_request->discovery_indication_cfg |=
-            hidl_request.configParams.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
-    legacy_request->discovery_indication_cfg |=
-            hidl_request.configParams.disableStartedClusterIndication ? 0x2 : 0x0;
-    legacy_request->discovery_indication_cfg |=
-            hidl_request.configParams.disableJoinedClusterIndication ? 0x4 : 0x0;
-    legacy_request->config_sid_beacon = 1;
-    if (hidl_request.configParams.numberOfPublishServiceIdsInBeacon > 127) {
-        LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
-                      "numberOfPublishServiceIdsInBeacon > 127";
-        return false;
-    }
-    legacy_request->sid_beacon_val =
-            (hidl_request.configParams.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
-            (hidl_request.configParams.numberOfPublishServiceIdsInBeacon << 1);
-    legacy_request->config_subscribe_sid_beacon = 1;
-    if (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon > 127) {
-        LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
-                      "numberOfSubscribeServiceIdsInBeacon > 127";
-        return false;
-    }
-    legacy_request->subscribe_sid_beacon_val =
-            (hidl_request.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
-            (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon << 1);
-    legacy_request->config_rssi_window_size = 1;
-    legacy_request->rssi_window_size_val = hidl_request.configParams.rssiWindowSize;
-    legacy_request->config_disc_mac_addr_randomization = 1;
-    legacy_request->disc_mac_addr_rand_interval_sec =
-            hidl_request.configParams.macAddressRandomizationIntervalSec;
-    legacy_request->config_2dot4g_rssi_close = 1;
-    if (hidl_request.configParams.bandSpecificConfig.size() != 3) {
-        LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
-                      "bandSpecificConfig.size() != 3";
-        return false;
-    }
-    legacy_request->rssi_close_2dot4g_val =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-                    .rssiClose;
-    legacy_request->config_2dot4g_rssi_middle = 1;
-    legacy_request->rssi_middle_2dot4g_val =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-                    .rssiMiddle;
-    legacy_request->config_2dot4g_rssi_proximity = 1;
-    legacy_request->rssi_proximity_2dot4g_val =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-                    .rssiCloseProximity;
-    legacy_request->config_scan_params = 1;
-    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-                    .dwellTimeMs;
-    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-                    .scanPeriodSec;
-    legacy_request->config_dw.config_2dot4g_dw_band =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-                    .validDiscoveryWindowIntervalVal;
-    legacy_request->config_dw.dw_2dot4g_interval_val =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-                    .discoveryWindowIntervalVal;
-    legacy_request->config_5g_rssi_close = 1;
-    legacy_request->rssi_close_5g_val =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .rssiClose;
-    legacy_request->config_5g_rssi_middle = 1;
-    legacy_request->rssi_middle_5g_val =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .rssiMiddle;
-    legacy_request->config_5g_rssi_close_proximity = 1;
-    legacy_request->rssi_close_proximity_5g_val =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .rssiCloseProximity;
-    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .dwellTimeMs;
-    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .scanPeriodSec;
-    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .dwellTimeMs;
-    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .scanPeriodSec;
-    legacy_request->config_dw.config_5g_dw_band =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .validDiscoveryWindowIntervalVal;
-    legacy_request->config_dw.dw_5g_interval_val =
-            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .discoveryWindowIntervalVal;
-    if (hidl_request.debugConfigs.validClusterIdVals) {
-        legacy_request->cluster_low = hidl_request.debugConfigs.clusterIdBottomRangeVal;
-        legacy_request->cluster_high = hidl_request.debugConfigs.clusterIdTopRangeVal;
-    } else {  // need 'else' since not configurable in legacy HAL
-        legacy_request->cluster_low = 0x0000;
-        legacy_request->cluster_high = 0xFFFF;
-    }
-    legacy_request->config_intf_addr = hidl_request.debugConfigs.validIntfAddrVal;
-    memcpy(legacy_request->intf_addr_val, hidl_request.debugConfigs.intfAddrVal.data(), 6);
-    legacy_request->config_oui = hidl_request.debugConfigs.validOuiVal;
-    legacy_request->oui_val = hidl_request.debugConfigs.ouiVal;
-    legacy_request->config_random_factor_force =
-            hidl_request.debugConfigs.validRandomFactorForceVal;
-    legacy_request->random_factor_force_val = hidl_request.debugConfigs.randomFactorForceVal;
-    legacy_request->config_hop_count_force = hidl_request.debugConfigs.validHopCountForceVal;
-    legacy_request->hop_count_force_val = hidl_request.debugConfigs.hopCountForceVal;
-    legacy_request->config_24g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal;
-    legacy_request->channel_24g_val =
-            hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
-    legacy_request->config_5g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal;
-    legacy_request->channel_5g_val =
-            hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
-    legacy_request->config_2dot4g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal;
-    legacy_request->beacon_2dot4g_val =
-            hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
-    legacy_request->config_5g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal;
-    legacy_request->beacon_5g_val =
-            hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
-    legacy_request->config_2dot4g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal;
-    legacy_request->sdf_2dot4g_val =
-            hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
-    legacy_request->config_5g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal;
-    legacy_request->sdf_5g_val =
-            hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
-
-    /* TODO: b/145609058
-     * Missing updates needed to legacy_hal::NanEnableRequest and conversion to
-     * it for 6GHz band */
-
-    return true;
-}
-
-bool convertHidlNanEnableRequest_1_6ToLegacy(const V1_4::NanEnableRequest& hidl_request1,
-                                             const NanConfigRequestSupplemental& hidl_request2,
-                                             legacy_hal::NanEnableRequest* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanEnableRequest_1_6ToLegacy: null legacy_request";
-        return false;
-    }
-
-    *legacy_request = {};
-    if (!convertHidlNanEnableRequestToLegacy(hidl_request1, legacy_request)) {
-        return false;
-    }
-
-    legacy_request->config_discovery_beacon_int = 1;
-    legacy_request->discovery_beacon_interval = hidl_request2.V1_5.V1_2.discoveryBeaconIntervalMs;
-    legacy_request->config_nss = 1;
-    legacy_request->nss = hidl_request2.V1_5.V1_2.numberOfSpatialStreamsInDiscovery;
-    legacy_request->config_dw_early_termination = 1;
-    legacy_request->enable_dw_termination =
-            hidl_request2.V1_5.V1_2.enableDiscoveryWindowEarlyTermination;
-    legacy_request->config_enable_ranging = 1;
-    legacy_request->enable_ranging = hidl_request2.V1_5.V1_2.enableRanging;
-
-    legacy_request->config_enable_instant_mode = 1;
-    legacy_request->enable_instant_mode = hidl_request2.V1_5.enableInstantCommunicationMode;
-    legacy_request->config_instant_mode_channel = 1;
-    legacy_request->instant_mode_channel = hidl_request2.instantModeChannel;
-
-    return true;
-}
-
-bool convertHidlNanConfigRequest_1_6ToLegacy(const V1_4::NanConfigRequest& hidl_request1,
-                                             const NanConfigRequestSupplemental& hidl_request2,
-                                             legacy_hal::NanConfigRequest* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanConfigRequest_1_6ToLegacy: null legacy_request";
-        return false;
-    }
-
-    *legacy_request = {};
-    if (!convertHidlNanConfigRequestToLegacy(hidl_request1, legacy_request)) {
-        return false;
-    }
-
-    legacy_request->config_discovery_beacon_int = 1;
-    legacy_request->discovery_beacon_interval = hidl_request2.V1_5.V1_2.discoveryBeaconIntervalMs;
-    legacy_request->config_nss = 1;
-    legacy_request->nss = hidl_request2.V1_5.V1_2.numberOfSpatialStreamsInDiscovery;
-    legacy_request->config_dw_early_termination = 1;
-    legacy_request->enable_dw_termination =
-            hidl_request2.V1_5.V1_2.enableDiscoveryWindowEarlyTermination;
-    legacy_request->config_enable_ranging = 1;
-    legacy_request->enable_ranging = hidl_request2.V1_5.V1_2.enableRanging;
-
-    legacy_request->config_enable_instant_mode = 1;
-    legacy_request->enable_instant_mode = hidl_request2.V1_5.enableInstantCommunicationMode;
-    legacy_request->config_instant_mode_channel = 1;
-    legacy_request->instant_mode_channel = hidl_request2.instantModeChannel;
-
-    return true;
-}
-
-bool convertHidlNanPublishRequestToLegacy(const V1_6::NanPublishRequest& hidl_request,
-                                          legacy_hal::NanPublishRequest* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: null legacy_request";
-        return false;
-    }
-    *legacy_request = {};
-
-    legacy_request->publish_id = hidl_request.baseConfigs.sessionId;
-    legacy_request->ttl = hidl_request.baseConfigs.ttlSec;
-    legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod;
-    legacy_request->publish_count = hidl_request.baseConfigs.discoveryCount;
-    legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size();
-    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
-        LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: service_name_len "
-                      "too large";
-        return false;
-    }
-    memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
-           legacy_request->service_name_len);
-    legacy_request->publish_match_indicator =
-            convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator);
-    legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
-    if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
-                      "service_specific_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->service_specific_info,
-           hidl_request.baseConfigs.serviceSpecificInfo.data(),
-           legacy_request->service_specific_info_len);
-    legacy_request->sdea_service_specific_info_len =
-            hidl_request.baseConfigs.extendedServiceSpecificInfo.size();
-    if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
-                      "sdea_service_specific_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->sdea_service_specific_info,
-           hidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
-           legacy_request->sdea_service_specific_info_len);
-    legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size();
-    if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
-        LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
-                      "rx_match_filter_len too large";
-        return false;
-    }
-    memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(),
-           legacy_request->rx_match_filter_len);
-    legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size();
-    if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
-        LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
-                      "tx_match_filter_len too large";
-        return false;
-    }
-    memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(),
-           legacy_request->tx_match_filter_len);
-    legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold;
-    legacy_request->recv_indication_cfg = 0;
-    legacy_request->recv_indication_cfg |=
-            hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
-    legacy_request->recv_indication_cfg |=
-            hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
-    legacy_request->recv_indication_cfg |=
-            hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
-    legacy_request->recv_indication_cfg |= 0x8;
-    legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType;
-
-    legacy_request->scid_len = hidl_request.baseConfigs.securityConfig.scid.size();
-    if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
-        LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: scid_len too large";
-        return false;
-    }
-    memcpy(legacy_request->scid, hidl_request.baseConfigs.securityConfig.scid.data(),
-           legacy_request->scid_len);
-
-    if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
-        legacy_request->key_info.body.pmk_info.pmk_len =
-                hidl_request.baseConfigs.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
-            LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: invalid pmk_len";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.pmk_info.pmk,
-               hidl_request.baseConfigs.securityConfig.pmk.data(),
-               legacy_request->key_info.body.pmk_info.pmk_len);
-    }
-    if (hidl_request.baseConfigs.securityConfig.securityType ==
-        NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-        legacy_request->key_info.body.passphrase_info.passphrase_len =
-                hidl_request.baseConfigs.securityConfig.passphrase.size();
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
-            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
-                          "passphrase_len too small";
-            return false;
-        }
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
-            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
-                          "passphrase_len too large";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
-               hidl_request.baseConfigs.securityConfig.passphrase.data(),
-               legacy_request->key_info.body.passphrase_info.passphrase_len);
-    }
-    legacy_request->sdea_params.security_cfg =
-            (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
-                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
-                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
-
-    legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired
-                                                        ? legacy_hal::NAN_RANGING_ENABLE
-                                                        : legacy_hal::NAN_RANGING_DISABLE;
-    legacy_request->ranging_cfg.ranging_interval_msec =
-            hidl_request.baseConfigs.rangingIntervalMsec;
-    legacy_request->ranging_cfg.config_ranging_indications =
-            hidl_request.baseConfigs.configRangingIndications;
-    legacy_request->ranging_cfg.distance_ingress_mm =
-            hidl_request.baseConfigs.distanceIngressCm * 10;
-    legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10;
-    legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired
-                                                    ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
-                                                    : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
-    legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
-    legacy_request->publish_type = convertHidlNanPublishTypeToLegacy(hidl_request.publishType);
-    legacy_request->tx_type = convertHidlNanTxTypeToLegacy(hidl_request.txType);
-    legacy_request->service_responder_policy = hidl_request.autoAcceptDataPathRequests
-                                                       ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL
-                                                       : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE;
-
-    return true;
-}
-
-bool convertHidlNanSubscribeRequestToLegacy(const V1_0::NanSubscribeRequest& hidl_request,
-                                            legacy_hal::NanSubscribeRequest* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: legacy_request is null";
-        return false;
-    }
-    *legacy_request = {};
-
-    legacy_request->subscribe_id = hidl_request.baseConfigs.sessionId;
-    legacy_request->ttl = hidl_request.baseConfigs.ttlSec;
-    legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod;
-    legacy_request->subscribe_count = hidl_request.baseConfigs.discoveryCount;
-    legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size();
-    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
-        LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
-                      "service_name_len too large";
-        return false;
-    }
-    memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
-           legacy_request->service_name_len);
-    legacy_request->subscribe_match_indicator =
-            convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator);
-    legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
-    if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
-                      "service_specific_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->service_specific_info,
-           hidl_request.baseConfigs.serviceSpecificInfo.data(),
-           legacy_request->service_specific_info_len);
-    legacy_request->sdea_service_specific_info_len =
-            hidl_request.baseConfigs.extendedServiceSpecificInfo.size();
-    if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
-                      "sdea_service_specific_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->sdea_service_specific_info,
-           hidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
-           legacy_request->sdea_service_specific_info_len);
-    legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size();
-    if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
-        LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
-                      "rx_match_filter_len too large";
-        return false;
-    }
-    memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(),
-           legacy_request->rx_match_filter_len);
-    legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size();
-    if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
-        LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
-                      "tx_match_filter_len too large";
-        return false;
-    }
-    memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(),
-           legacy_request->tx_match_filter_len);
-    legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold;
-    legacy_request->recv_indication_cfg = 0;
-    legacy_request->recv_indication_cfg |=
-            hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
-    legacy_request->recv_indication_cfg |=
-            hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
-    legacy_request->recv_indication_cfg |=
-            hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
-    legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType;
-    if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
-        legacy_request->key_info.body.pmk_info.pmk_len =
-                hidl_request.baseConfigs.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
-            LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: invalid pmk_len";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.pmk_info.pmk,
-               hidl_request.baseConfigs.securityConfig.pmk.data(),
-               legacy_request->key_info.body.pmk_info.pmk_len);
-    }
-    if (hidl_request.baseConfigs.securityConfig.securityType ==
-        NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-        legacy_request->key_info.body.passphrase_info.passphrase_len =
-                hidl_request.baseConfigs.securityConfig.passphrase.size();
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
-            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
-                          "passphrase_len too small";
-            return false;
-        }
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
-            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
-                          "passphrase_len too large";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
-               hidl_request.baseConfigs.securityConfig.passphrase.data(),
-               legacy_request->key_info.body.passphrase_info.passphrase_len);
-    }
-    legacy_request->sdea_params.security_cfg =
-            (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
-                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
-                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
-    legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired
-                                                        ? legacy_hal::NAN_RANGING_ENABLE
-                                                        : legacy_hal::NAN_RANGING_DISABLE;
-    legacy_request->ranging_cfg.ranging_interval_msec =
-            hidl_request.baseConfigs.rangingIntervalMsec;
-    legacy_request->ranging_cfg.config_ranging_indications =
-            hidl_request.baseConfigs.configRangingIndications;
-    legacy_request->ranging_cfg.distance_ingress_mm =
-            hidl_request.baseConfigs.distanceIngressCm * 10;
-    legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10;
-    legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired
-                                                    ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
-                                                    : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
-    legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
-    legacy_request->subscribe_type =
-            convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType);
-    legacy_request->serviceResponseFilter = convertHidlNanSrfTypeToLegacy(hidl_request.srfType);
-    legacy_request->serviceResponseInclude = hidl_request.srfRespondIfInAddressSet
-                                                     ? legacy_hal::NAN_SRF_INCLUDE_RESPOND
-                                                     : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
-    legacy_request->useServiceResponseFilter =
-            hidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF : legacy_hal::NAN_DO_NOT_USE_SRF;
-    legacy_request->ssiRequiredForMatchIndication =
-            hidl_request.isSsiRequiredForMatch ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND
-                                               : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
-    legacy_request->num_intf_addr_present = hidl_request.intfAddr.size();
-    if (legacy_request->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) {
-        LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
-                      "num_intf_addr_present - too many";
-        return false;
-    }
-    for (int i = 0; i < legacy_request->num_intf_addr_present; i++) {
-        memcpy(legacy_request->intf_addr[i], hidl_request.intfAddr[i].data(), 6);
-    }
-
-    return true;
-}
-
-bool convertHidlNanTransmitFollowupRequestToLegacy(
-        const NanTransmitFollowupRequest& hidl_request,
-        legacy_hal::NanTransmitFollowupRequest* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: "
-                      "legacy_request is null";
-        return false;
-    }
-    *legacy_request = {};
-
-    legacy_request->publish_subscribe_id = hidl_request.discoverySessionId;
-    legacy_request->requestor_instance_id = hidl_request.peerId;
-    memcpy(legacy_request->addr, hidl_request.addr.data(), 6);
-    legacy_request->priority = hidl_request.isHighPriority ? legacy_hal::NAN_TX_PRIORITY_HIGH
-                                                           : legacy_hal::NAN_TX_PRIORITY_NORMAL;
-    legacy_request->dw_or_faw = hidl_request.shouldUseDiscoveryWindow
-                                        ? legacy_hal::NAN_TRANSMIT_IN_DW
-                                        : legacy_hal::NAN_TRANSMIT_IN_FAW;
-    legacy_request->service_specific_info_len = hidl_request.serviceSpecificInfo.size();
-    if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: "
-                      "service_specific_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->service_specific_info, hidl_request.serviceSpecificInfo.data(),
-           legacy_request->service_specific_info_len);
-    legacy_request->sdea_service_specific_info_len =
-            hidl_request.extendedServiceSpecificInfo.size();
-    if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: "
-                      "sdea_service_specific_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->sdea_service_specific_info,
-           hidl_request.extendedServiceSpecificInfo.data(),
-           legacy_request->sdea_service_specific_info_len);
-    legacy_request->recv_indication_cfg = hidl_request.disableFollowupResultIndication ? 0x1 : 0x0;
-
-    return true;
-}
-
-bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request,
-                                         legacy_hal::NanConfigRequest* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: legacy_request is null";
-        return false;
-    }
-    *legacy_request = {};
-
-    // TODO: b/34059183 tracks missing configurations in legacy HAL or uknown
-    // defaults
-    legacy_request->master_pref = hidl_request.masterPref;
-    legacy_request->discovery_indication_cfg = 0;
-    legacy_request->discovery_indication_cfg |=
-            hidl_request.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
-    legacy_request->discovery_indication_cfg |=
-            hidl_request.disableStartedClusterIndication ? 0x2 : 0x0;
-    legacy_request->discovery_indication_cfg |=
-            hidl_request.disableJoinedClusterIndication ? 0x4 : 0x0;
-    legacy_request->config_sid_beacon = 1;
-    if (hidl_request.numberOfPublishServiceIdsInBeacon > 127) {
-        LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: "
-                      "numberOfPublishServiceIdsInBeacon > 127";
-        return false;
-    }
-    legacy_request->sid_beacon = (hidl_request.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
-                                 (hidl_request.numberOfPublishServiceIdsInBeacon << 1);
-    legacy_request->config_subscribe_sid_beacon = 1;
-    if (hidl_request.numberOfSubscribeServiceIdsInBeacon > 127) {
-        LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: "
-                      "numberOfSubscribeServiceIdsInBeacon > 127";
-        return false;
-    }
-    legacy_request->subscribe_sid_beacon_val =
-            (hidl_request.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
-            (hidl_request.numberOfSubscribeServiceIdsInBeacon << 1);
-    legacy_request->config_rssi_window_size = 1;
-    legacy_request->rssi_window_size_val = hidl_request.rssiWindowSize;
-    legacy_request->config_disc_mac_addr_randomization = 1;
-    legacy_request->disc_mac_addr_rand_interval_sec =
-            hidl_request.macAddressRandomizationIntervalSec;
-    /* TODO : missing
-    legacy_request->config_2dot4g_rssi_close = 1;
-    legacy_request->rssi_close_2dot4g_val =
-          hidl_request.bandSpecificConfig[
-              (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiClose;
-    legacy_request->config_2dot4g_rssi_middle = 1;
-    legacy_request->rssi_middle_2dot4g_val =
-          hidl_request.bandSpecificConfig[
-              (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiMiddle;
-    legacy_request->config_2dot4g_rssi_proximity = 1;
-    legacy_request->rssi_proximity_2dot4g_val =
-          hidl_request.bandSpecificConfig[
-              (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiCloseProximity;
-    */
-    legacy_request->config_scan_params = 1;
-    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].dwellTimeMs;
-    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].scanPeriodSec;
-    legacy_request->config_dw.config_2dot4g_dw_band =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-                    .validDiscoveryWindowIntervalVal;
-    legacy_request->config_dw.dw_2dot4g_interval_val =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-                    .discoveryWindowIntervalVal;
-    /* TODO: missing
-    legacy_request->config_5g_rssi_close = 1;
-    legacy_request->rssi_close_5g_val =
-          hidl_request.bandSpecificConfig[
-              (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiClose;
-    legacy_request->config_5g_rssi_middle = 1;
-    legacy_request->rssi_middle_5g_val =
-          hidl_request.bandSpecificConfig[
-              (size_t) NanBandIndex::NAN_BAND_5GHZ].rssiMiddle;
-    */
-    legacy_request->config_5g_rssi_close_proximity = 1;
-    legacy_request->rssi_close_proximity_5g_val =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].rssiCloseProximity;
-    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
-    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
-    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
-    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
-    legacy_request->config_dw.config_5g_dw_band =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .validDiscoveryWindowIntervalVal;
-    legacy_request->config_dw.dw_5g_interval_val =
-            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-                    .discoveryWindowIntervalVal;
-    /* TODO: b/145609058
-     * Missing updates needed to legacy_hal::NanConfigRequest and conversion to
-     * it for 6GHz band */
-
-    return true;
-}
-
-bool convertHidlNanDataPathInitiatorRequestToLegacy(
-        const V1_0::NanInitiateDataPathRequest& hidl_request,
-        legacy_hal::NanDataPathInitiatorRequest* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
-                      "legacy_request is null";
-        return false;
-    }
-    *legacy_request = {};
-
-    legacy_request->requestor_instance_id = hidl_request.peerId;
-    memcpy(legacy_request->peer_disc_mac_addr, hidl_request.peerDiscMacAddr.data(), 6);
-    legacy_request->channel_request_type =
-            convertHidlNanDataPathChannelCfgToLegacy(hidl_request.channelRequestType);
-    legacy_request->channel = hidl_request.channel;
-    if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
-        LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
-                      "ifaceName too long";
-        return false;
-    }
-    strlcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
-    legacy_request->ndp_cfg.security_cfg =
-            (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
-                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
-                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
-    legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
-    if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
-                      "ndp_app_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
-           legacy_request->app_info.ndp_app_info_len);
-    legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
-    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
-        legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
-                          "invalid pmk_len";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
-               legacy_request->key_info.body.pmk_info.pmk_len);
-    }
-    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-        legacy_request->key_info.body.passphrase_info.passphrase_len =
-                hidl_request.securityConfig.passphrase.size();
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
-            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
-                          "passphrase_len too small";
-            return false;
-        }
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
-            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
-                          "passphrase_len too large";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
-               hidl_request.securityConfig.passphrase.data(),
-               legacy_request->key_info.body.passphrase_info.passphrase_len);
-    }
-    legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size();
-    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
-                      "service_name_len too large";
-        return false;
-    }
-    memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
-           legacy_request->service_name_len);
-
-    return true;
-}
-
-bool convertHidlNanDataPathInitiatorRequest_1_6ToLegacy(
-        const V1_6::NanInitiateDataPathRequest& hidl_request,
-        legacy_hal::NanDataPathInitiatorRequest* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
-                      "legacy_request is null";
-        return false;
-    }
-    *legacy_request = {};
-
-    legacy_request->requestor_instance_id = hidl_request.peerId;
-    memcpy(legacy_request->peer_disc_mac_addr, hidl_request.peerDiscMacAddr.data(), 6);
-    legacy_request->channel_request_type =
-            convertHidlNanDataPathChannelCfgToLegacy(hidl_request.channelRequestType);
-    legacy_request->channel = hidl_request.channel;
-    if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
-        LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
-                      "ifaceName too long";
-        return false;
-    }
-    strlcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
-    legacy_request->ndp_cfg.security_cfg =
-            (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
-                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
-                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
-    legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
-    if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
-                      "ndp_app_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
-           legacy_request->app_info.ndp_app_info_len);
-    legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
-    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
-        legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
-                          "invalid pmk_len";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
-               legacy_request->key_info.body.pmk_info.pmk_len);
-    }
-    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-        legacy_request->key_info.body.passphrase_info.passphrase_len =
-                hidl_request.securityConfig.passphrase.size();
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
-            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
-                          "passphrase_len too small";
-            return false;
-        }
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
-            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
-                          "passphrase_len too large";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
-               hidl_request.securityConfig.passphrase.data(),
-               legacy_request->key_info.body.passphrase_info.passphrase_len);
-    }
-    legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size();
-    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: "
-                      "service_name_len too large";
-        return false;
-    }
-    memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
-           legacy_request->service_name_len);
-    legacy_request->scid_len = hidl_request.securityConfig.scid.size();
-    if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathInitiatorRequest_1_6ToLegacy: scid_len too large";
-        return false;
-    }
-    memcpy(legacy_request->scid, hidl_request.securityConfig.scid.data(), legacy_request->scid_len);
-
-    return true;
-}
-
-bool convertHidlNanDataPathIndicationResponseToLegacy(
-        const V1_0::NanRespondToDataPathIndicationRequest& hidl_request,
-        legacy_hal::NanDataPathIndicationResponse* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
-                      "legacy_request is null";
-        return false;
-    }
-    *legacy_request = {};
-
-    legacy_request->rsp_code = hidl_request.acceptRequest ? legacy_hal::NAN_DP_REQUEST_ACCEPT
-                                                          : legacy_hal::NAN_DP_REQUEST_REJECT;
-    legacy_request->ndp_instance_id = hidl_request.ndpInstanceId;
-    if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
-        LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
-                      "ifaceName too long";
-        return false;
-    }
-    strlcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
-    legacy_request->ndp_cfg.security_cfg =
-            (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
-                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
-                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
-    legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
-    if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
-                      "ndp_app_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
-           legacy_request->app_info.ndp_app_info_len);
-    legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
-    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
-        legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
-                          "invalid pmk_len";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
-               legacy_request->key_info.body.pmk_info.pmk_len);
-    }
-    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-        legacy_request->key_info.body.passphrase_info.passphrase_len =
-                hidl_request.securityConfig.passphrase.size();
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
-            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
-                          "passphrase_len too small";
-            return false;
-        }
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
-            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
-                          "passphrase_len too large";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
-               hidl_request.securityConfig.passphrase.data(),
-               legacy_request->key_info.body.passphrase_info.passphrase_len);
-    }
-    legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size();
-    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
-                      "service_name_len too large";
-        return false;
-    }
-    memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
-           legacy_request->service_name_len);
-
-    return true;
-}
-
-bool convertHidlNanDataPathIndicationResponse_1_6ToLegacy(
-        const V1_6::NanRespondToDataPathIndicationRequest& hidl_request,
-        legacy_hal::NanDataPathIndicationResponse* legacy_request) {
-    if (!legacy_request) {
-        LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
-                      "legacy_request is null";
-        return false;
-    }
-    *legacy_request = {};
-
-    legacy_request->rsp_code = hidl_request.acceptRequest ? legacy_hal::NAN_DP_REQUEST_ACCEPT
-                                                          : legacy_hal::NAN_DP_REQUEST_REJECT;
-    legacy_request->ndp_instance_id = hidl_request.ndpInstanceId;
-    if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
-        LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
-                      "ifaceName too long";
-        return false;
-    }
-    strlcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
-    legacy_request->ndp_cfg.security_cfg =
-            (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
-                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
-                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
-    legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
-    if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
-                      "ndp_app_info_len too large";
-        return false;
-    }
-    memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
-           legacy_request->app_info.ndp_app_info_len);
-    legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
-    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
-        legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
-                          "invalid pmk_len";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
-               legacy_request->key_info.body.pmk_info.pmk_len);
-    }
-    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-        legacy_request->key_info.body.passphrase_info.passphrase_len =
-                hidl_request.securityConfig.passphrase.size();
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
-            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
-                          "passphrase_len too small";
-            return false;
-        }
-        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
-            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
-            LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
-                          "passphrase_len too large";
-            return false;
-        }
-        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
-               hidl_request.securityConfig.passphrase.data(),
-               legacy_request->key_info.body.passphrase_info.passphrase_len);
-    }
-    legacy_request->service_name_len = hidl_request.serviceNameOutOfBand.size();
-    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: "
-                      "service_name_len too large";
-        return false;
-    }
-    memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
-           legacy_request->service_name_len);
-    legacy_request->scid_len = hidl_request.securityConfig.scid.size();
-    if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
-        LOG(ERROR) << "convertHidlNanDataPathIndicationResponse_1_6ToLegacy: scid_len too large";
-        return false;
-    }
-    memcpy(legacy_request->scid, hidl_request.securityConfig.scid.data(), legacy_request->scid_len);
-
-    return true;
-}
-
-bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response,
-                                          WifiNanStatus* wifiNanStatus) {
-    if (!wifiNanStatus) {
-        LOG(ERROR) << "convertLegacyNanResponseHeaderToHidl: wifiNanStatus is null";
-        return false;
-    }
-    *wifiNanStatus = {};
-
-    convertToWifiNanStatus(legacy_response.status, legacy_response.nan_error,
-                           sizeof(legacy_response.nan_error), wifiNanStatus);
-    return true;
-}
-
-bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response,
-                                                V1_6::NanCapabilities* hidl_response) {
-    if (!hidl_response) {
-        LOG(ERROR) << "convertLegacyNanCapabilitiesResponseToHidl: "
-                      "hidl_response is null";
-        return false;
-    }
-    *hidl_response = {};
-
-    hidl_response->maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters;
-    hidl_response->maxPublishes = legacy_response.max_publishes;
-    hidl_response->maxSubscribes = legacy_response.max_subscribes;
-    hidl_response->maxServiceNameLen = legacy_response.max_service_name_len;
-    hidl_response->maxMatchFilterLen = legacy_response.max_match_filter_len;
-    hidl_response->maxTotalMatchFilterLen = legacy_response.max_total_match_filter_len;
-    hidl_response->maxServiceSpecificInfoLen = legacy_response.max_service_specific_info_len;
-    hidl_response->maxExtendedServiceSpecificInfoLen =
-            legacy_response.max_sdea_service_specific_info_len;
-    hidl_response->maxNdiInterfaces = legacy_response.max_ndi_interfaces;
-    hidl_response->maxNdpSessions = legacy_response.max_ndp_sessions;
-    hidl_response->maxAppInfoLen = legacy_response.max_app_info_len;
-    hidl_response->maxQueuedTransmitFollowupMsgs =
-            legacy_response.max_queued_transmit_followup_msgs;
-    hidl_response->maxSubscribeInterfaceAddresses = legacy_response.max_subscribe_address;
-    hidl_response->supportedCipherSuites = legacy_response.cipher_suites_supported;
-    hidl_response->instantCommunicationModeSupportFlag = legacy_response.is_instant_mode_supported;
-
-    return true;
-}
-
-bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind,
-                                    V1_6::NanMatchInd* hidl_ind) {
-    if (!hidl_ind) {
-        LOG(ERROR) << "convertLegacyNanMatchIndToHidl: hidl_ind is null";
-        return false;
-    }
-    *hidl_ind = {};
-
-    hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
-    hidl_ind->peerId = legacy_ind.requestor_instance_id;
-    hidl_ind->addr = hidl_array<uint8_t, 6>(legacy_ind.addr);
-    hidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
-            legacy_ind.service_specific_info,
-            legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
-    hidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
-            legacy_ind.sdea_service_specific_info,
-            legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
-    hidl_ind->matchFilter =
-            std::vector<uint8_t>(legacy_ind.sdf_match_filter,
-                                 legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len);
-    hidl_ind->matchOccuredInBeaconFlag = legacy_ind.match_occured_flag == 1;
-    hidl_ind->outOfResourceFlag = legacy_ind.out_of_resource_flag == 1;
-    hidl_ind->rssiValue = legacy_ind.rssi_value;
-    hidl_ind->peerCipherType = (V1_6::NanCipherSuiteType)legacy_ind.peer_cipher_type;
-    hidl_ind->peerRequiresSecurityEnabledInNdp =
-            legacy_ind.peer_sdea_params.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
-    hidl_ind->peerRequiresRanging =
-            legacy_ind.peer_sdea_params.ranging_state == legacy_hal::NAN_RANGING_ENABLE;
-    hidl_ind->rangingMeasurementInMm = legacy_ind.range_info.range_measurement_mm;
-    hidl_ind->rangingIndicationType = legacy_ind.range_info.ranging_event_type;
-    hidl_ind->scid = std::vector<uint8_t>(legacy_ind.scid, legacy_ind.scid + legacy_ind.scid_len);
-    return true;
-}
-
-bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind,
-                                       NanFollowupReceivedInd* hidl_ind) {
-    if (!hidl_ind) {
-        LOG(ERROR) << "convertLegacyNanFollowupIndToHidl: hidl_ind is null";
-        return false;
-    }
-    *hidl_ind = {};
-
-    hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
-    hidl_ind->peerId = legacy_ind.requestor_instance_id;
-    hidl_ind->addr = hidl_array<uint8_t, 6>(legacy_ind.addr);
-    hidl_ind->receivedInFaw = legacy_ind.dw_or_faw == 1;
-    hidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
-            legacy_ind.service_specific_info,
-            legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
-    hidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
-            legacy_ind.sdea_service_specific_info,
-            legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
-
-    return true;
-}
-
-bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
-                                              NanDataPathRequestInd* hidl_ind) {
-    if (!hidl_ind) {
-        LOG(ERROR) << "convertLegacyNanDataPathRequestIndToHidl: hidl_ind is null";
-        return false;
-    }
-    *hidl_ind = {};
-
-    hidl_ind->discoverySessionId = legacy_ind.service_instance_id;
-    hidl_ind->peerDiscMacAddr = hidl_array<uint8_t, 6>(legacy_ind.peer_disc_mac_addr);
-    hidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id;
-    hidl_ind->securityRequired =
-            legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
-    hidl_ind->appInfo = std::vector<uint8_t>(
-            legacy_ind.app_info.ndp_app_info,
-            legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
-
-    return true;
-}
-
-bool convertLegacyNdpChannelInfoToHidl(const legacy_hal::NanChannelInfo& legacy_struct,
-                                       V1_6::NanDataPathChannelInfo* hidl_struct) {
-    if (!hidl_struct) {
-        LOG(ERROR) << "convertLegacyNdpChannelInfoToHidl: hidl_struct is null";
-        return false;
-    }
-    *hidl_struct = {};
-
-    hidl_struct->channelFreq = legacy_struct.channel;
-    hidl_struct->channelBandwidth = convertLegacyWifiChannelWidthToHidl(
-            (legacy_hal::wifi_channel_width)legacy_struct.bandwidth);
-    hidl_struct->numSpatialStreams = legacy_struct.nss;
-
-    return true;
-}
-
-bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
-                                              V1_6::NanDataPathConfirmInd* hidl_ind) {
-    if (!hidl_ind) {
-        LOG(ERROR) << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null";
-        return false;
-    }
-    *hidl_ind = {};
-
-    hidl_ind->V1_0.ndpInstanceId = legacy_ind.ndp_instance_id;
-    hidl_ind->V1_0.dataPathSetupSuccess = legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT;
-    hidl_ind->V1_0.peerNdiMacAddr = hidl_array<uint8_t, 6>(legacy_ind.peer_ndi_mac_addr);
-    hidl_ind->V1_0.appInfo = std::vector<uint8_t>(
-            legacy_ind.app_info.ndp_app_info,
-            legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
-    hidl_ind->V1_0.status.status = convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code);
-    hidl_ind->V1_0.status.description = "";  // TODO: b/34059183
-
-    std::vector<V1_6::NanDataPathChannelInfo> channelInfo;
-    for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
-        V1_6::NanDataPathChannelInfo hidl_struct;
-        if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) {
-            return false;
-        }
-        channelInfo.push_back(hidl_struct);
-    }
-    hidl_ind->channelInfo = channelInfo;
-
-    return true;
-}
-
-bool convertLegacyNanDataPathScheduleUpdateIndToHidl(
-        const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
-        V1_6::NanDataPathScheduleUpdateInd* hidl_ind) {
-    if (!hidl_ind) {
-        LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToHidl: "
-                      "hidl_ind is null";
-        return false;
-    }
-    *hidl_ind = {};
-
-    hidl_ind->peerDiscoveryAddress = hidl_array<uint8_t, 6>(legacy_ind.peer_mac_addr);
-    std::vector<V1_6::NanDataPathChannelInfo> channelInfo;
-    for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
-        V1_6::NanDataPathChannelInfo hidl_struct;
-        if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) {
-            return false;
-        }
-        channelInfo.push_back(hidl_struct);
-    }
-    hidl_ind->channelInfo = channelInfo;
-    std::vector<uint32_t> ndpInstanceIds;
-    for (unsigned int i = 0; i < legacy_ind.num_ndp_instances; ++i) {
-        ndpInstanceIds.push_back(legacy_ind.ndp_instance_id[i]);
-    }
-    hidl_ind->ndpInstanceIds = ndpInstanceIds;
-
-    return true;
-}
-
-legacy_hal::wifi_rtt_type convertHidlRttTypeToLegacy(RttType type) {
-    switch (type) {
-        case RttType::ONE_SIDED:
-            return legacy_hal::RTT_TYPE_1_SIDED;
-        case RttType::TWO_SIDED:
-            return legacy_hal::RTT_TYPE_2_SIDED;
-    };
-    CHECK(false);
-}
-
-RttType convertLegacyRttTypeToHidl(legacy_hal::wifi_rtt_type type) {
-    switch (type) {
-        case legacy_hal::RTT_TYPE_1_SIDED:
-            return RttType::ONE_SIDED;
-        case legacy_hal::RTT_TYPE_2_SIDED:
-            return RttType::TWO_SIDED;
-    };
-    CHECK(false) << "Unknown legacy type: " << type;
-}
-
-legacy_hal::rtt_peer_type convertHidlRttPeerTypeToLegacy(RttPeerType type) {
-    switch (type) {
-        case RttPeerType::AP:
-            return legacy_hal::RTT_PEER_AP;
-        case RttPeerType::STA:
-            return legacy_hal::RTT_PEER_STA;
-        case RttPeerType::P2P_GO:
-            return legacy_hal::RTT_PEER_P2P_GO;
-        case RttPeerType::P2P_CLIENT:
-            return legacy_hal::RTT_PEER_P2P_CLIENT;
-        case RttPeerType::NAN:
-            return legacy_hal::RTT_PEER_NAN;
-    };
-    CHECK(false);
-}
-
-legacy_hal::wifi_channel_width convertHidlWifiChannelWidthToLegacy(WifiChannelWidthInMhz type) {
-    switch (type) {
-        case WifiChannelWidthInMhz::WIDTH_20:
-            return legacy_hal::WIFI_CHAN_WIDTH_20;
-        case WifiChannelWidthInMhz::WIDTH_40:
-            return legacy_hal::WIFI_CHAN_WIDTH_40;
-        case WifiChannelWidthInMhz::WIDTH_80:
-            return legacy_hal::WIFI_CHAN_WIDTH_80;
-        case WifiChannelWidthInMhz::WIDTH_160:
-            return legacy_hal::WIFI_CHAN_WIDTH_160;
-        case WifiChannelWidthInMhz::WIDTH_80P80:
-            return legacy_hal::WIFI_CHAN_WIDTH_80P80;
-        case WifiChannelWidthInMhz::WIDTH_5:
-            return legacy_hal::WIFI_CHAN_WIDTH_5;
-        case WifiChannelWidthInMhz::WIDTH_10:
-            return legacy_hal::WIFI_CHAN_WIDTH_10;
-        case V1_6::WifiChannelWidthInMhz::WIDTH_320:
-            return legacy_hal::WIFI_CHAN_WIDTH_320;
-        case WifiChannelWidthInMhz::WIDTH_INVALID:
-            return legacy_hal::WIFI_CHAN_WIDTH_INVALID;
-    };
-    CHECK(false);
-}
-
-V1_6::WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(
-        legacy_hal::wifi_channel_width type) {
-    switch (type) {
-        case legacy_hal::WIFI_CHAN_WIDTH_20:
-            return WifiChannelWidthInMhz::WIDTH_20;
-        case legacy_hal::WIFI_CHAN_WIDTH_40:
-            return WifiChannelWidthInMhz::WIDTH_40;
-        case legacy_hal::WIFI_CHAN_WIDTH_80:
-            return WifiChannelWidthInMhz::WIDTH_80;
-        case legacy_hal::WIFI_CHAN_WIDTH_160:
-            return WifiChannelWidthInMhz::WIDTH_160;
-        case legacy_hal::WIFI_CHAN_WIDTH_80P80:
-            return WifiChannelWidthInMhz::WIDTH_80P80;
-        case legacy_hal::WIFI_CHAN_WIDTH_5:
-            return WifiChannelWidthInMhz::WIDTH_5;
-        case legacy_hal::WIFI_CHAN_WIDTH_10:
-            return WifiChannelWidthInMhz::WIDTH_10;
-        case legacy_hal::WIFI_CHAN_WIDTH_320:
-            return V1_6::WifiChannelWidthInMhz::WIDTH_320;
-        default:
-            return WifiChannelWidthInMhz::WIDTH_INVALID;
-    };
-}
-
-legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy(V1_6::RttPreamble type) {
-    switch (type) {
-        case V1_6::RttPreamble::LEGACY:
-            return legacy_hal::WIFI_RTT_PREAMBLE_LEGACY;
-        case V1_6::RttPreamble::HT:
-            return legacy_hal::WIFI_RTT_PREAMBLE_HT;
-        case V1_6::RttPreamble::VHT:
-            return legacy_hal::WIFI_RTT_PREAMBLE_VHT;
-        case V1_6::RttPreamble::HE:
-            return legacy_hal::WIFI_RTT_PREAMBLE_HE;
-        case V1_6::RttPreamble::EHT:
-            return legacy_hal::WIFI_RTT_PREAMBLE_EHT;
-    };
-    CHECK(false);
-}
-
-V1_6::RttPreamble convertLegacyRttPreambleToHidl(legacy_hal::wifi_rtt_preamble type) {
-    switch (type) {
-        case legacy_hal::WIFI_RTT_PREAMBLE_LEGACY:
-            return V1_6::RttPreamble::LEGACY;
-        case legacy_hal::WIFI_RTT_PREAMBLE_HT:
-            return V1_6::RttPreamble::HT;
-        case legacy_hal::WIFI_RTT_PREAMBLE_VHT:
-            return V1_6::RttPreamble::VHT;
-        case legacy_hal::WIFI_RTT_PREAMBLE_HE:
-            return V1_6::RttPreamble::HE;
-        case legacy_hal::WIFI_RTT_PREAMBLE_EHT:
-            return V1_6::RttPreamble::EHT;
-    };
-    CHECK(false) << "Unknown legacy type: " << type;
-}
-
-legacy_hal::wifi_rtt_bw convertHidlRttBwToLegacy(RttBw type) {
-    switch (type) {
-        case RttBw::BW_5MHZ:
-            return legacy_hal::WIFI_RTT_BW_5;
-        case RttBw::BW_10MHZ:
-            return legacy_hal::WIFI_RTT_BW_10;
-        case RttBw::BW_20MHZ:
-            return legacy_hal::WIFI_RTT_BW_20;
-        case RttBw::BW_40MHZ:
-            return legacy_hal::WIFI_RTT_BW_40;
-        case RttBw::BW_80MHZ:
-            return legacy_hal::WIFI_RTT_BW_80;
-        case RttBw::BW_160MHZ:
-            return legacy_hal::WIFI_RTT_BW_160;
-        case RttBw::BW_320MHZ:
-            return legacy_hal::WIFI_RTT_BW_320;
-    };
-    CHECK(false);
-}
-
-RttBw convertLegacyRttBwToHidl(legacy_hal::wifi_rtt_bw type) {
-    switch (type) {
-        case legacy_hal::WIFI_RTT_BW_5:
-            return RttBw::BW_5MHZ;
-        case legacy_hal::WIFI_RTT_BW_10:
-            return RttBw::BW_10MHZ;
-        case legacy_hal::WIFI_RTT_BW_20:
-            return RttBw::BW_20MHZ;
-        case legacy_hal::WIFI_RTT_BW_40:
-            return RttBw::BW_40MHZ;
-        case legacy_hal::WIFI_RTT_BW_80:
-            return RttBw::BW_80MHZ;
-        case legacy_hal::WIFI_RTT_BW_160:
-            return RttBw::BW_160MHZ;
-        case legacy_hal::WIFI_RTT_BW_320:
-            return RttBw::BW_320MHZ;
-    };
-    CHECK(false) << "Unknown legacy type: " << type;
-}
-
-legacy_hal::wifi_motion_pattern convertHidlRttMotionPatternToLegacy(RttMotionPattern type) {
-    switch (type) {
-        case RttMotionPattern::NOT_EXPECTED:
-            return legacy_hal::WIFI_MOTION_NOT_EXPECTED;
-        case RttMotionPattern::EXPECTED:
-            return legacy_hal::WIFI_MOTION_EXPECTED;
-        case RttMotionPattern::UNKNOWN:
-            return legacy_hal::WIFI_MOTION_UNKNOWN;
-    };
-    CHECK(false);
-}
-
-V1_6::WifiRatePreamble convertLegacyWifiRatePreambleToHidl(uint8_t preamble) {
-    switch (preamble) {
-        case 0:
-            return V1_6::WifiRatePreamble::OFDM;
-        case 1:
-            return V1_6::WifiRatePreamble::CCK;
-        case 2:
-            return V1_6::WifiRatePreamble::HT;
-        case 3:
-            return V1_6::WifiRatePreamble::VHT;
-        case 4:
-            return V1_6::WifiRatePreamble::HE;
-        case 5:
-            return V1_6::WifiRatePreamble::EHT;
-        default:
-            return V1_6::WifiRatePreamble::RESERVED;
-    };
-    CHECK(false) << "Unknown legacy preamble: " << preamble;
-}
-
-WifiRateNss convertLegacyWifiRateNssToHidl(uint8_t nss) {
-    switch (nss) {
-        case 0:
-            return WifiRateNss::NSS_1x1;
-        case 1:
-            return WifiRateNss::NSS_2x2;
-        case 2:
-            return WifiRateNss::NSS_3x3;
-        case 3:
-            return WifiRateNss::NSS_4x4;
-    };
-    CHECK(false) << "Unknown legacy nss: " << nss;
-    return {};
-}
-
-RttStatus convertLegacyRttStatusToHidl(legacy_hal::wifi_rtt_status status) {
-    switch (status) {
-        case legacy_hal::RTT_STATUS_SUCCESS:
-            return RttStatus::SUCCESS;
-        case legacy_hal::RTT_STATUS_FAILURE:
-            return RttStatus::FAILURE;
-        case legacy_hal::RTT_STATUS_FAIL_NO_RSP:
-            return RttStatus::FAIL_NO_RSP;
-        case legacy_hal::RTT_STATUS_FAIL_REJECTED:
-            return RttStatus::FAIL_REJECTED;
-        case legacy_hal::RTT_STATUS_FAIL_NOT_SCHEDULED_YET:
-            return RttStatus::FAIL_NOT_SCHEDULED_YET;
-        case legacy_hal::RTT_STATUS_FAIL_TM_TIMEOUT:
-            return RttStatus::FAIL_TM_TIMEOUT;
-        case legacy_hal::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL:
-            return RttStatus::FAIL_AP_ON_DIFF_CHANNEL;
-        case legacy_hal::RTT_STATUS_FAIL_NO_CAPABILITY:
-            return RttStatus::FAIL_NO_CAPABILITY;
-        case legacy_hal::RTT_STATUS_ABORTED:
-            return RttStatus::ABORTED;
-        case legacy_hal::RTT_STATUS_FAIL_INVALID_TS:
-            return RttStatus::FAIL_INVALID_TS;
-        case legacy_hal::RTT_STATUS_FAIL_PROTOCOL:
-            return RttStatus::FAIL_PROTOCOL;
-        case legacy_hal::RTT_STATUS_FAIL_SCHEDULE:
-            return RttStatus::FAIL_SCHEDULE;
-        case legacy_hal::RTT_STATUS_FAIL_BUSY_TRY_LATER:
-            return RttStatus::FAIL_BUSY_TRY_LATER;
-        case legacy_hal::RTT_STATUS_INVALID_REQ:
-            return RttStatus::INVALID_REQ;
-        case legacy_hal::RTT_STATUS_NO_WIFI:
-            return RttStatus::NO_WIFI;
-        case legacy_hal::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE:
-            return RttStatus::FAIL_FTM_PARAM_OVERRIDE;
-        case legacy_hal::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE:
-            return RttStatus::FAILURE;  // TODO: add HIDL enumeration
-        case legacy_hal::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED:
-            return RttStatus::FAILURE;  // TODO: add HIDL enumeration
-    };
-    CHECK(false) << "Unknown legacy status: " << status;
-}
-
-bool convertHidlWifiChannelInfoToLegacy(const WifiChannelInfo& hidl_info,
-                                        legacy_hal::wifi_channel_info* legacy_info) {
-    if (!legacy_info) {
-        return false;
-    }
-    *legacy_info = {};
-    legacy_info->width = convertHidlWifiChannelWidthToLegacy(hidl_info.width);
-    legacy_info->center_freq = hidl_info.centerFreq;
-    legacy_info->center_freq0 = hidl_info.centerFreq0;
-    legacy_info->center_freq1 = hidl_info.centerFreq1;
-    return true;
-}
-
-bool convertLegacyWifiChannelInfoToHidl(const legacy_hal::wifi_channel_info& legacy_info,
-                                        WifiChannelInfo* hidl_info) {
-    if (!hidl_info) {
-        return false;
-    }
-    *hidl_info = {};
-    hidl_info->width = convertLegacyWifiChannelWidthToHidl(legacy_info.width);
-    hidl_info->centerFreq = legacy_info.center_freq;
-    hidl_info->centerFreq0 = legacy_info.center_freq0;
-    hidl_info->centerFreq1 = legacy_info.center_freq1;
-    return true;
-}
-
-bool convertHidlRttConfigToLegacy(const V1_6::RttConfig& hidl_config,
-                                  legacy_hal::wifi_rtt_config* legacy_config) {
-    if (!legacy_config) {
-        return false;
-    }
-    *legacy_config = {};
-    CHECK(hidl_config.addr.size() == sizeof(legacy_config->addr));
-    memcpy(legacy_config->addr, hidl_config.addr.data(), hidl_config.addr.size());
-    legacy_config->type = convertHidlRttTypeToLegacy(hidl_config.type);
-    legacy_config->peer = convertHidlRttPeerTypeToLegacy(hidl_config.peer);
-    if (!convertHidlWifiChannelInfoToLegacy(hidl_config.channel, &legacy_config->channel)) {
-        return false;
-    }
-    legacy_config->burst_period = hidl_config.burstPeriod;
-    legacy_config->num_burst = hidl_config.numBurst;
-    legacy_config->num_frames_per_burst = hidl_config.numFramesPerBurst;
-    legacy_config->num_retries_per_rtt_frame = hidl_config.numRetriesPerRttFrame;
-    legacy_config->num_retries_per_ftmr = hidl_config.numRetriesPerFtmr;
-    legacy_config->LCI_request = hidl_config.mustRequestLci;
-    legacy_config->LCR_request = hidl_config.mustRequestLcr;
-    legacy_config->burst_duration = hidl_config.burstDuration;
-    legacy_config->preamble = convertHidlRttPreambleToLegacy(hidl_config.preamble);
-    legacy_config->bw = convertHidlRttBwToLegacy(hidl_config.bw);
-    return true;
-}
-
-bool convertHidlVectorOfRttConfigToLegacy(
-        const std::vector<V1_6::RttConfig>& hidl_configs,
-        std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) {
-    if (!legacy_configs) {
-        return false;
-    }
-    *legacy_configs = {};
-    for (const auto& hidl_config : hidl_configs) {
-        legacy_hal::wifi_rtt_config legacy_config;
-        if (!convertHidlRttConfigToLegacy(hidl_config, &legacy_config)) {
-            return false;
-        }
-        legacy_configs->push_back(legacy_config);
-    }
-    return true;
-}
-
-bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info,
-                                          legacy_hal::wifi_lci_information* legacy_info) {
-    if (!legacy_info) {
-        return false;
-    }
-    *legacy_info = {};
-    legacy_info->latitude = hidl_info.latitude;
-    legacy_info->longitude = hidl_info.longitude;
-    legacy_info->altitude = hidl_info.altitude;
-    legacy_info->latitude_unc = hidl_info.latitudeUnc;
-    legacy_info->longitude_unc = hidl_info.longitudeUnc;
-    legacy_info->altitude_unc = hidl_info.altitudeUnc;
-    legacy_info->motion_pattern = convertHidlRttMotionPatternToLegacy(hidl_info.motionPattern);
-    legacy_info->floor = hidl_info.floor;
-    legacy_info->height_above_floor = hidl_info.heightAboveFloor;
-    legacy_info->height_unc = hidl_info.heightUnc;
-    return true;
-}
-
-bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info,
-                                          legacy_hal::wifi_lcr_information* legacy_info) {
-    if (!legacy_info) {
-        return false;
-    }
-    *legacy_info = {};
-    CHECK(hidl_info.countryCode.size() == sizeof(legacy_info->country_code));
-    memcpy(legacy_info->country_code, hidl_info.countryCode.data(), hidl_info.countryCode.size());
-    if (hidl_info.civicInfo.size() > sizeof(legacy_info->civic_info)) {
-        return false;
-    }
-    legacy_info->length = hidl_info.civicInfo.size();
-    memcpy(legacy_info->civic_info, hidl_info.civicInfo.c_str(), hidl_info.civicInfo.size());
-    return true;
-}
-
-bool convertHidlRttResponderToLegacy(const V1_6::RttResponder& hidl_responder,
-                                     legacy_hal::wifi_rtt_responder* legacy_responder) {
-    if (!legacy_responder) {
-        return false;
-    }
-    *legacy_responder = {};
-    if (!convertHidlWifiChannelInfoToLegacy(hidl_responder.channel, &legacy_responder->channel)) {
-        return false;
-    }
-    legacy_responder->preamble = convertHidlRttPreambleToLegacy(hidl_responder.preamble);
-    return true;
-}
-
-bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
-                                     V1_6::RttResponder* hidl_responder) {
-    if (!hidl_responder) {
-        return false;
-    }
-    *hidl_responder = {};
-    if (!convertLegacyWifiChannelInfoToHidl(legacy_responder.channel, &hidl_responder->channel)) {
-        return false;
-    }
-    hidl_responder->preamble = convertLegacyRttPreambleToHidl(legacy_responder.preamble);
-    return true;
-}
-
-bool convertLegacyRttCapabilitiesToHidl(
-        const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
-        V1_6::RttCapabilities* hidl_capabilities) {
-    if (!hidl_capabilities) {
-        return false;
-    }
-    *hidl_capabilities = {};
-    hidl_capabilities->rttOneSidedSupported = legacy_capabilities.rtt_one_sided_supported;
-    hidl_capabilities->rttFtmSupported = legacy_capabilities.rtt_ftm_supported;
-    hidl_capabilities->lciSupported = legacy_capabilities.lci_support;
-    hidl_capabilities->lcrSupported = legacy_capabilities.lcr_support;
-    hidl_capabilities->responderSupported = legacy_capabilities.responder_supported;
-    hidl_capabilities->preambleSupport = 0;
-    for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT,
-                            legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE,
-                            legacy_hal::WIFI_RTT_PREAMBLE_EHT}) {
-        if (legacy_capabilities.preamble_support & flag) {
-            hidl_capabilities->preambleSupport |=
-                    static_cast<std::underlying_type<V1_6::RttPreamble>::type>(
-                            convertLegacyRttPreambleToHidl(flag));
-        }
-    }
-    hidl_capabilities->bwSupport = 0;
-    for (const auto flag :
-         {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20,
-          legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160,
-          legacy_hal::WIFI_RTT_BW_320}) {
-        if (legacy_capabilities.bw_support & flag) {
-            hidl_capabilities->bwSupport |=
-                    static_cast<std::underlying_type<RttBw>::type>(convertLegacyRttBwToHidl(flag));
-        }
-    }
-    hidl_capabilities->mcVersion = legacy_capabilities.mc_version;
-    return true;
-}
-
-bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate,
-                                     V1_6::WifiRateInfo* hidl_rate) {
-    if (!hidl_rate) {
-        return false;
-    }
-    *hidl_rate = {};
-    hidl_rate->preamble = convertLegacyWifiRatePreambleToHidl(legacy_rate.preamble);
-    hidl_rate->nss = convertLegacyWifiRateNssToHidl(legacy_rate.nss);
-    hidl_rate->bw = convertLegacyWifiChannelWidthToHidl(
-            static_cast<legacy_hal::wifi_channel_width>(legacy_rate.bw));
-    hidl_rate->rateMcsIdx = legacy_rate.rateMcsIdx;
-    hidl_rate->bitRateInKbps = legacy_rate.bitrate;
-    return true;
-}
-
-bool convertLegacyRttResultToHidl(const legacy_hal::wifi_rtt_result& legacy_result,
-                                  V1_6::RttResult* hidl_result) {
-    if (!hidl_result) {
-        return false;
-    }
-    *hidl_result = {};
-    CHECK(sizeof(legacy_result.addr) == hidl_result->addr.size());
-    memcpy(hidl_result->addr.data(), legacy_result.addr, sizeof(legacy_result.addr));
-    hidl_result->burstNum = legacy_result.burst_num;
-    hidl_result->measurementNumber = legacy_result.measurement_number;
-    hidl_result->successNumber = legacy_result.success_number;
-    hidl_result->numberPerBurstPeer = legacy_result.number_per_burst_peer;
-    hidl_result->status = convertLegacyRttStatusToHidl(legacy_result.status);
-    hidl_result->retryAfterDuration = legacy_result.retry_after_duration;
-    hidl_result->type = convertLegacyRttTypeToHidl(legacy_result.type);
-    hidl_result->rssi = legacy_result.rssi;
-    hidl_result->rssiSpread = legacy_result.rssi_spread;
-    if (!convertLegacyWifiRateInfoToHidl(legacy_result.tx_rate, &hidl_result->txRate)) {
-        return false;
-    }
-    if (!convertLegacyWifiRateInfoToHidl(legacy_result.rx_rate, &hidl_result->rxRate)) {
-        return false;
-    }
-    hidl_result->rtt = legacy_result.rtt;
-    hidl_result->rttSd = legacy_result.rtt_sd;
-    hidl_result->rttSpread = legacy_result.rtt_spread;
-    hidl_result->distanceInMm = legacy_result.distance_mm;
-    hidl_result->distanceSdInMm = legacy_result.distance_sd_mm;
-    hidl_result->distanceSpreadInMm = legacy_result.distance_spread_mm;
-    hidl_result->timeStampInUs = legacy_result.ts;
-    hidl_result->burstDurationInMs = legacy_result.burst_duration;
-    hidl_result->negotiatedBurstNum = legacy_result.negotiated_burst_num;
-    if (legacy_result.LCI && !convertLegacyIeToHidl(*legacy_result.LCI, &hidl_result->lci)) {
-        return false;
-    }
-    if (legacy_result.LCR && !convertLegacyIeToHidl(*legacy_result.LCR, &hidl_result->lcr)) {
-        return false;
-    }
-    return true;
-}
-
-bool convertLegacyVectorOfRttResultToHidl(
-        const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
-        std::vector<V1_6::RttResult>* hidl_results) {
-    if (!hidl_results) {
-        return false;
-    }
-    *hidl_results = {};
-    for (const auto legacy_result : legacy_results) {
-        V1_6::RttResult hidl_result;
-        if (!convertLegacyRttResultToHidl(*legacy_result, &hidl_result)) {
-            return false;
-        }
-        hidl_results->push_back(hidl_result);
-    }
-    return true;
-}
-
-legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type) {
-    switch (hidl_interface_type) {
-        case IfaceType::STA:
-            return legacy_hal::WIFI_INTERFACE_TYPE_STA;
-        case IfaceType::AP:
-            return legacy_hal::WIFI_INTERFACE_TYPE_AP;
-        case IfaceType::P2P:
-            return legacy_hal::WIFI_INTERFACE_TYPE_P2P;
-        case IfaceType::NAN:
-            return legacy_hal::WIFI_INTERFACE_TYPE_NAN;
-    }
-    CHECK(false);
-}
-
-legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
-        V1_5::IWifiChip::MultiStaUseCase use_case) {
-    switch (use_case) {
-        case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY:
-            return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
-        case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED:
-            return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
-    }
-    CHECK(false);
-}
-
-bool convertHidlCoexUnsafeChannelToLegacy(
-        const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
-        legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) {
-    if (!legacy_unsafe_channel) {
-        return false;
-    }
-    *legacy_unsafe_channel = {};
-    switch (hidl_unsafe_channel.band) {
-        case V1_5::WifiBand::BAND_24GHZ:
-            legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND;
-            break;
-        case V1_5::WifiBand::BAND_5GHZ:
-            legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND;
-            break;
-        default:
-            return false;
-    };
-    legacy_unsafe_channel->channel = hidl_unsafe_channel.channel;
-    legacy_unsafe_channel->power_cap_dbm = hidl_unsafe_channel.powerCapDbm;
-    return true;
-}
-
-bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
-        const std::vector<V1_5::IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
-        std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) {
-    if (!legacy_unsafe_channels) {
-        return false;
-    }
-    *legacy_unsafe_channels = {};
-    for (const auto& hidl_unsafe_channel : hidl_unsafe_channels) {
-        legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel;
-        if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy(hidl_unsafe_channel,
-                                                                    &legacy_unsafe_channel)) {
-            return false;
-        }
-        legacy_unsafe_channels->push_back(legacy_unsafe_channel);
-    }
-    return true;
-}
-
-V1_6::WifiAntennaMode convertLegacyAntennaConfigurationToHidl(uint32_t antenna_cfg) {
-    switch (antenna_cfg) {
-        case legacy_hal::WIFI_ANTENNA_1X1:
-            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_1X1;
-        case legacy_hal::WIFI_ANTENNA_2X2:
-            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_2X2;
-        case legacy_hal::WIFI_ANTENNA_3X3:
-            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_3X3;
-        case legacy_hal::WIFI_ANTENNA_4X4:
-            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_4X4;
-        default:
-            return V1_6::WifiAntennaMode::WIFI_ANTENNA_MODE_UNSPECIFIED;
-    }
-}
-
-bool convertLegacyWifiRadioConfigurationToHidl(
-        legacy_hal::wifi_radio_configuration* radio_configuration,
-        V1_6::WifiRadioConfiguration* hidl_radio_configuration) {
-    if (!hidl_radio_configuration) {
-        return false;
-    }
-    *hidl_radio_configuration = {};
-    hidl_radio_configuration->bandInfo =
-            hidl_struct_util::convertLegacyMacBandToHidlWifiBand(radio_configuration->band);
-    if (hidl_radio_configuration->bandInfo == V1_5::WifiBand::BAND_UNSPECIFIED) {
-        LOG(ERROR) << "Unspecified band";
-        return false;
-    }
-    hidl_radio_configuration->antennaMode =
-            hidl_struct_util::convertLegacyAntennaConfigurationToHidl(
-                    radio_configuration->antenna_cfg);
-    return true;
-}
-
-bool convertLegacyRadioCombinationsMatrixToHidl(
-        legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
-        WifiRadioCombinationMatrix* hidl_matrix) {
-    if (!hidl_matrix || !legacy_matrix) {
-        return false;
-    }
-    *hidl_matrix = {};
-
-    int num_combinations = legacy_matrix->num_radio_combinations;
-    std::vector<V1_6::WifiRadioCombination> radio_combinations_vec;
-    if (!num_combinations) {
-        LOG(ERROR) << "zero radio combinations";
-        return false;
-    }
-    wifi_radio_combination* l_radio_combinations_ptr = legacy_matrix->radio_combinations;
-    for (int i = 0; i < num_combinations; i++) {
-        int num_configurations = l_radio_combinations_ptr->num_radio_configurations;
-        WifiRadioCombination radioCombination;
-        std::vector<V1_6::WifiRadioConfiguration> radio_configurations_vec;
-        if (!num_configurations) {
-            LOG(ERROR) << "zero radio configurations";
-            return false;
-        }
-        for (int j = 0; j < num_configurations; j++) {
-            WifiRadioConfiguration radioConfiguration;
-            wifi_radio_configuration* l_radio_configurations_ptr =
-                    &l_radio_combinations_ptr->radio_configurations[j];
-            if (!hidl_struct_util::convertLegacyWifiRadioConfigurationToHidl(
-                        l_radio_configurations_ptr, &radioConfiguration)) {
-                LOG(ERROR) << "Error converting wifi radio configuration";
-                return false;
-            }
-            radio_configurations_vec.push_back(radioConfiguration);
-        }
-        radioCombination.radioConfigurations = radio_configurations_vec;
-        radio_combinations_vec.push_back(radioCombination);
-        l_radio_combinations_ptr =
-                (wifi_radio_combination*)((u8*)l_radio_combinations_ptr +
-                                          sizeof(wifi_radio_combination) +
-                                          (sizeof(wifi_radio_configuration) * num_configurations));
-    }
-    hidl_matrix->radioCombinations = radio_combinations_vec;
-    return true;
-}
-
-}  // namespace hidl_struct_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/hidl_struct_util.h b/wifi/1.6/default/hidl_struct_util.h
deleted file mode 100644
index 2d4a5f1..0000000
--- a/wifi/1.6/default/hidl_struct_util.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2016 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 HIDL_STRUCT_UTIL_H_
-#define HIDL_STRUCT_UTIL_H_
-
-#include <vector>
-
-#include <android/hardware/wifi/1.0/IWifiChip.h>
-#include <android/hardware/wifi/1.0/types.h>
-#include <android/hardware/wifi/1.2/types.h>
-#include <android/hardware/wifi/1.3/types.h>
-#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
-#include <android/hardware/wifi/1.4/types.h>
-#include <android/hardware/wifi/1.6/IWifiChip.h>
-#include <android/hardware/wifi/1.6/types.h>
-
-#include "wifi_legacy_hal.h"
-
-/**
- * This file contains a bunch of functions to convert structs from the legacy
- * HAL to HIDL and vice versa.
- * TODO(b/32093047): Add unit tests for these conversion methods in the VTS test
- * suite.
- */
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace hidl_struct_util {
-using namespace android::hardware::wifi::V1_0;
-
-// Chip conversion methods.
-bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set,
-                                                 uint32_t legacy_logger_feature_set,
-                                                 uint32_t* hidl_caps);
-bool convertLegacyDebugRingBufferStatusToHidl(
-        const legacy_hal::wifi_ring_buffer_status& legacy_status,
-        WifiDebugRingBufferStatus* hidl_status);
-bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
-        const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
-        std::vector<WifiDebugRingBufferStatus>* hidl_status_vec);
-bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats,
-                                        WifiDebugHostWakeReasonStats* hidl_stats);
-legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
-        V1_1::IWifiChip::TxPowerScenario hidl_scenario);
-legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy(
-        V1_3::IWifiChip::LatencyMode hidl_latency_mode);
-legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2(
-        V1_2::IWifiChip::TxPowerScenario hidl_scenario);
-bool convertLegacyWifiMacInfosToHidl(
-        const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
-        std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos);
-legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type);
-legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
-        V1_5::IWifiChip::MultiStaUseCase use_case);
-bool convertHidlCoexUnsafeChannelToLegacy(
-        const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
-        legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel);
-bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
-        const std::vector<V1_5::IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
-        std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);
-bool convertLegacyRadioCombinationsMatrixToHidl(
-        legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
-        V1_6::WifiRadioCombinationMatrix* hidl_matrix);
-V1_5::WifiBand convertLegacyMacBandToHidlWifiBand(uint32_t band);
-V1_6::WifiAntennaMode convertLegacyAntennaConfigurationToHidl(uint32_t antenna_cfg);
-
-// STA iface conversion methods.
-bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set,
-                                                uint32_t legacy_logger_feature_set,
-                                                uint32_t* hidl_caps);
-bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
-                                        StaApfPacketFilterCapabilities* hidl_caps);
-bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
-                                          StaBackgroundScanCapabilities* hidl_caps);
-legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band);
-bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params,
-                                    legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
-// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11
-// Information Elements (IEs)
-bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
-                                    bool has_ie_data, StaScanResult* hidl_scan_result);
-// |cached_results| is assumed to not include IEs.
-bool convertLegacyVectorOfCachedGscanResultsToHidl(
-        const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
-        std::vector<StaScanData>* hidl_scan_datas);
-bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats,
-                                       V1_6::StaLinkLayerStats* hidl_stats);
-bool convertLegacyRoamingCapabilitiesToHidl(
-        const legacy_hal::wifi_roaming_capabilities& legacy_caps,
-        StaRoamingCapabilities* hidl_caps);
-bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config,
-                                      legacy_hal::wifi_roaming_config* legacy_config);
-legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state);
-bool convertLegacyVectorOfDebugTxPacketFateToHidl(
-        const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
-        std::vector<WifiDebugTxPacketFateReport>* hidl_fates);
-bool convertLegacyVectorOfDebugRxPacketFateToHidl(
-        const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
-        std::vector<WifiDebugRxPacketFateReport>* hidl_fates);
-
-// NAN iface conversion methods.
-void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
-                            WifiNanStatus* wifiNanStatus);
-bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request,
-                                         legacy_hal::NanEnableRequest* legacy_request);
-bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request,
-                                         legacy_hal::NanConfigRequest* legacy_request);
-bool convertHidlNanEnableRequest_1_6ToLegacy(
-        const V1_4::NanEnableRequest& hidl_request1,
-        const V1_6::NanConfigRequestSupplemental& hidl_request2,
-        legacy_hal::NanEnableRequest* legacy_request);
-bool convertHidlNanConfigRequest_1_6ToLegacy(
-        const V1_4::NanConfigRequest& hidl_request1,
-        const V1_6::NanConfigRequestSupplemental& hidl_request2,
-        legacy_hal::NanConfigRequest* legacy_request);
-bool convertHidlNanPublishRequestToLegacy(const V1_6::NanPublishRequest& hidl_request,
-                                          legacy_hal::NanPublishRequest* legacy_request);
-bool convertHidlNanSubscribeRequestToLegacy(const V1_0::NanSubscribeRequest& hidl_request,
-                                            legacy_hal::NanSubscribeRequest* legacy_request);
-bool convertHidlNanTransmitFollowupRequestToLegacy(
-        const NanTransmitFollowupRequest& hidl_request,
-        legacy_hal::NanTransmitFollowupRequest* legacy_request);
-bool convertHidlNanDataPathInitiatorRequestToLegacy(
-        const V1_0::NanInitiateDataPathRequest& hidl_request,
-        legacy_hal::NanDataPathInitiatorRequest* legacy_request);
-bool convertHidlNanDataPathIndicationResponseToLegacy(
-        const V1_0::NanRespondToDataPathIndicationRequest& hidl_response,
-        legacy_hal::NanDataPathIndicationResponse* legacy_response);
-bool convertHidlNanDataPathInitiatorRequest_1_6ToLegacy(
-        const V1_6::NanInitiateDataPathRequest& hidl_request,
-        legacy_hal::NanDataPathInitiatorRequest* legacy_request);
-bool convertHidlNanDataPathIndicationResponse_1_6ToLegacy(
-        const V1_6::NanRespondToDataPathIndicationRequest& hidl_response,
-        legacy_hal::NanDataPathIndicationResponse* legacy_response);
-
-bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response,
-                                          WifiNanStatus* wifiNanStatus);
-bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response,
-                                                V1_6::NanCapabilities* hidl_response);
-bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind,
-                                    V1_6::NanMatchInd* hidl_ind);
-bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind,
-                                       NanFollowupReceivedInd* hidl_ind);
-bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
-                                              NanDataPathRequestInd* hidl_ind);
-bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
-                                              V1_6::NanDataPathConfirmInd* hidl_ind);
-bool convertLegacyNanDataPathScheduleUpdateIndToHidl(
-        const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
-        V1_6::NanDataPathScheduleUpdateInd* hidl_ind);
-
-// RTT controller conversion methods.
-bool convertHidlVectorOfRttConfigToLegacy(const std::vector<V1_6::RttConfig>& hidl_configs,
-                                          std::vector<legacy_hal::wifi_rtt_config>* legacy_configs);
-bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info,
-                                          legacy_hal::wifi_lci_information* legacy_info);
-bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info,
-                                          legacy_hal::wifi_lcr_information* legacy_info);
-bool convertHidlRttResponderToLegacy(const V1_6::RttResponder& hidl_responder,
-                                     legacy_hal::wifi_rtt_responder* legacy_responder);
-bool convertHidlWifiChannelInfoToLegacy(const V1_6::WifiChannelInfo& hidl_info,
-                                        legacy_hal::wifi_channel_info* legacy_info);
-bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
-                                     V1_6::RttResponder* hidl_responder);
-bool convertLegacyRttCapabilitiesToHidl(
-        const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
-        V1_6::RttCapabilities* hidl_capabilities);
-bool convertLegacyVectorOfRttResultToHidl(
-        const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
-        std::vector<V1_6::RttResult>* hidl_results);
-uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band);
-uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask);
-uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask);
-bool convertLegacyWifiUsableChannelsToHidl(
-        const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
-        std::vector<V1_6::WifiUsableChannel>* hidl_usable_channels);
-bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
-                                      V1_6::StaPeerInfo* hidl_peer_info_stats);
-bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate,
-                                     V1_6::WifiRateInfo* hidl_rate);
-}  // namespace hidl_struct_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HIDL_STRUCT_UTIL_H_
diff --git a/wifi/1.6/default/hidl_sync_util.cpp b/wifi/1.6/default/hidl_sync_util.cpp
deleted file mode 100644
index 358d95e..0000000
--- a/wifi/1.6/default/hidl_sync_util.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 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 "hidl_sync_util.h"
-
-namespace {
-std::recursive_mutex g_mutex;
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace hidl_sync_util {
-
-std::unique_lock<std::recursive_mutex> acquireGlobalLock() {
-    return std::unique_lock<std::recursive_mutex>{g_mutex};
-}
-
-}  // namespace hidl_sync_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/hidl_sync_util.h b/wifi/1.6/default/hidl_sync_util.h
deleted file mode 100644
index 2c1c37b..0000000
--- a/wifi/1.6/default/hidl_sync_util.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 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 HIDL_SYNC_UTIL_H_
-#define HIDL_SYNC_UTIL_H_
-
-#include <mutex>
-
-// Utility that provides a global lock to synchronize access between
-// the HIDL thread and the legacy HAL's event loop.
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace hidl_sync_util {
-std::unique_lock<std::recursive_mutex> acquireGlobalLock();
-}  // namespace hidl_sync_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-#endif  // HIDL_SYNC_UTIL_H_
diff --git a/wifi/1.6/default/ringbuffer.cpp b/wifi/1.6/default/ringbuffer.cpp
deleted file mode 100644
index 981bf7b..0000000
--- a/wifi/1.6/default/ringbuffer.cpp
+++ /dev/null
@@ -1,64 +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.
- */
-
-#include <android-base/logging.h>
-
-#include "ringbuffer.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-
-Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {}
-
-enum Ringbuffer::AppendStatus Ringbuffer::append(const std::vector<uint8_t>& input) {
-    if (input.size() == 0) {
-        return AppendStatus::FAIL_IP_BUFFER_ZERO;
-    }
-    if (input.size() > maxSize_) {
-        LOG(INFO) << "Oversized message of " << input.size() << " bytes is dropped";
-        return AppendStatus::FAIL_IP_BUFFER_EXCEEDED_MAXSIZE;
-    }
-    data_.push_back(input);
-    size_ += input.size() * sizeof(input[0]);
-    while (size_ > maxSize_) {
-        if (data_.front().size() <= 0 || data_.front().size() > maxSize_) {
-            LOG(ERROR) << "First buffer in the ring buffer is Invalid. Size: "
-                       << data_.front().size();
-            return AppendStatus::FAIL_RING_BUFFER_CORRUPTED;
-        }
-        size_ -= data_.front().size() * sizeof(data_.front()[0]);
-        data_.pop_front();
-    }
-    return AppendStatus::SUCCESS;
-}
-
-const std::list<std::vector<uint8_t>>& Ringbuffer::getData() const {
-    return data_;
-}
-
-void Ringbuffer::clear() {
-    data_.clear();
-    size_ = 0;
-}
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/ringbuffer.h b/wifi/1.6/default/ringbuffer.h
deleted file mode 100644
index c6a1e4c..0000000
--- a/wifi/1.6/default/ringbuffer.h
+++ /dev/null
@@ -1,62 +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 RINGBUFFER_H_
-#define RINGBUFFER_H_
-
-#include <list>
-#include <vector>
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-
-/**
- * Ringbuffer object used to store debug data.
- */
-class Ringbuffer {
-  public:
-    // Error codes for the append ring buffer operation
-    enum AppendStatus {
-        SUCCESS,
-        FAIL_GENERIC,
-        FAIL_IP_BUFFER_ZERO,
-        FAIL_IP_BUFFER_EXCEEDED_MAXSIZE,
-        FAIL_RING_BUFFER_CORRUPTED
-    };
-    explicit Ringbuffer(size_t maxSize);
-
-    // Appends the data buffer and deletes from the front until buffer is
-    // within |maxSize_|.
-    enum AppendStatus append(const std::vector<uint8_t>& input);
-    const std::list<std::vector<uint8_t>>& getData() const;
-    void clear();
-
-  private:
-    std::list<std::vector<uint8_t>> data_;
-    size_t size_;
-    size_t maxSize_;
-};
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // RINGBUFFER_H_
diff --git a/wifi/1.6/default/service.cpp b/wifi/1.6/default/service.cpp
deleted file mode 100644
index c874d8b..0000000
--- a/wifi/1.6/default/service.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2016 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 <hidl/HidlLazyUtils.h>
-#include <hidl/HidlTransportSupport.h>
-#include <signal.h>
-#include <utils/Looper.h>
-#include <utils/StrongPointer.h>
-
-#include "wifi.h"
-#include "wifi_feature_flags.h"
-#include "wifi_legacy_hal.h"
-#include "wifi_legacy_hal_factory.h"
-#include "wifi_mode_controller.h"
-
-using android::hardware::configureRpcThreadpool;
-using android::hardware::joinRpcThreadpool;
-using android::hardware::LazyServiceRegistrar;
-using android::hardware::wifi::V1_6::implementation::feature_flags::WifiFeatureFlags;
-using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHal;
-using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHalFactory;
-using android::hardware::wifi::V1_6::implementation::mode_controller::WifiModeController;
-
-#ifdef LAZY_SERVICE
-const bool kLazyService = true;
-#else
-const bool kLazyService = false;
-#endif
-
-int main(int /*argc*/, char** argv) {
-    signal(SIGPIPE, SIG_IGN);
-    android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
-    LOG(INFO) << "Wifi Hal is booting up...";
-
-    configureRpcThreadpool(1, true /* callerWillJoin */);
-
-    const auto iface_tool = std::make_shared<android::wifi_system::InterfaceTool>();
-    const auto legacy_hal_factory = std::make_shared<WifiLegacyHalFactory>(iface_tool);
-
-    // Setup hwbinder service
-    android::sp<android::hardware::wifi::V1_6::IWifi> service =
-            new android::hardware::wifi::V1_6::implementation::Wifi(
-                    iface_tool, legacy_hal_factory, std::make_shared<WifiModeController>(),
-                    std::make_shared<WifiFeatureFlags>());
-    if (kLazyService) {
-        auto registrar = LazyServiceRegistrar::getInstance();
-        CHECK_EQ(registrar.registerService(service), android::NO_ERROR)
-                << "Failed to register wifi HAL";
-    } else {
-        CHECK_EQ(service->registerAsService(), android::NO_ERROR) << "Failed to register wifi HAL";
-    }
-
-    joinRpcThreadpool();
-
-    LOG(INFO) << "Wifi Hal is terminating...";
-    return 0;
-}
diff --git a/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp
deleted file mode 100644
index 0dd0aa1..0000000
--- a/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright (C) 2017, 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 <android-base/macros.h>
-#include <gmock/gmock.h>
-
-#undef NAN
-#include "hidl_struct_util.h"
-
-using testing::Test;
-
-namespace {
-constexpr uint32_t kMacId1 = 1;
-constexpr uint32_t kMacId2 = 2;
-constexpr uint32_t kIfaceChannel1 = 3;
-constexpr uint32_t kIfaceChannel2 = 5;
-constexpr char kIfaceName1[] = "wlan0";
-constexpr char kIfaceName2[] = "wlan1";
-}  // namespace
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-using ::android::hardware::wifi::V1_6::WifiChannelWidthInMhz;
-
-class HidlStructUtilTest : public Test {};
-
-TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) {
-    std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
-    legacy_hal::WifiMacInfo legacy_mac_info1 = {
-            .wlan_mac_id = kMacId1,
-            .mac_band = legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND};
-    legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
-    legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
-    legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
-    legacy_mac_info1.iface_infos.push_back(legacy_iface_info2);
-    legacy_mac_infos.push_back(legacy_mac_info1);
-
-    std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
-    ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(legacy_mac_infos,
-                                                                  &hidl_radio_mode_infos));
-
-    ASSERT_EQ(1u, hidl_radio_mode_infos.size());
-    auto hidl_radio_mode_info1 = hidl_radio_mode_infos[0];
-    EXPECT_EQ(legacy_mac_info1.wlan_mac_id, hidl_radio_mode_info1.radioId);
-    EXPECT_EQ(V1_4::WifiBand::BAND_24GHZ_5GHZ, hidl_radio_mode_info1.bandInfo);
-    ASSERT_EQ(2u, hidl_radio_mode_info1.ifaceInfos.size());
-    auto hidl_iface_info1 = hidl_radio_mode_info1.ifaceInfos[0];
-    EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name);
-    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), hidl_iface_info1.channel);
-    auto hidl_iface_info2 = hidl_radio_mode_info1.ifaceInfos[1];
-    EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name);
-    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), hidl_iface_info2.channel);
-}
-
-TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) {
-    std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
-    legacy_hal::WifiMacInfo legacy_mac_info1 = {.wlan_mac_id = kMacId1,
-                                                .mac_band = legacy_hal::WLAN_MAC_5_0_BAND};
-    legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
-    legacy_hal::WifiMacInfo legacy_mac_info2 = {.wlan_mac_id = kMacId2,
-                                                .mac_band = legacy_hal::WLAN_MAC_2_4_BAND};
-    legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
-    legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
-    legacy_mac_infos.push_back(legacy_mac_info1);
-    legacy_mac_info2.iface_infos.push_back(legacy_iface_info2);
-    legacy_mac_infos.push_back(legacy_mac_info2);
-
-    std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
-    ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(legacy_mac_infos,
-                                                                  &hidl_radio_mode_infos));
-
-    ASSERT_EQ(2u, hidl_radio_mode_infos.size());
-
-    // Find mac info 1.
-    const auto hidl_radio_mode_info1 =
-            std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
-                         [&legacy_mac_info1](const V1_4::IWifiChipEventCallback::RadioModeInfo& x) {
-                             return x.radioId == legacy_mac_info1.wlan_mac_id;
-                         });
-    ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1);
-    EXPECT_EQ(V1_4::WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo);
-    ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size());
-    auto hidl_iface_info1 = hidl_radio_mode_info1->ifaceInfos[0];
-    EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name);
-    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), hidl_iface_info1.channel);
-
-    // Find mac info 2.
-    const auto hidl_radio_mode_info2 =
-            std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
-                         [&legacy_mac_info2](const V1_4::IWifiChipEventCallback::RadioModeInfo& x) {
-                             return x.radioId == legacy_mac_info2.wlan_mac_id;
-                         });
-    ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2);
-    EXPECT_EQ(V1_4::WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo);
-    ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size());
-    auto hidl_iface_info2 = hidl_radio_mode_info2->ifaceInfos[0];
-    EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name);
-    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), hidl_iface_info2.channel);
-}
-
-TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) {
-    legacy_hal::LinkLayerStats legacy_stats{};
-    legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
-    legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
-    legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
-    legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
-    legacy_stats.iface.beacon_rx = rand();
-    legacy_stats.iface.rssi_mgmt = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand();
-
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand();
-
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand();
-
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand();
-
-    legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand();
-    legacy_stats.iface.num_peers = 1;
-
-    for (auto& radio : legacy_stats.radios) {
-        radio.stats.radio = rand();
-        radio.stats.on_time = rand();
-        radio.stats.tx_time = rand();
-        radio.stats.rx_time = rand();
-        radio.stats.on_time_scan = rand();
-        radio.stats.on_time_nbd = rand();
-        radio.stats.on_time_gscan = rand();
-        radio.stats.on_time_roam_scan = rand();
-        radio.stats.on_time_pno_scan = rand();
-        radio.stats.on_time_hs20 = rand();
-        for (int i = 0; i < 4; i++) {
-            radio.tx_time_per_levels.push_back(rand());
-        }
-
-        legacy_hal::wifi_channel_stat channel_stat1 = {
-                .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
-                .on_time = 0x1111,
-                .cca_busy_time = 0x55,
-        };
-        legacy_hal::wifi_channel_stat channel_stat2 = {
-                .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
-                .on_time = 0x2222,
-                .cca_busy_time = 0x66,
-        };
-        radio.channel_stats.push_back(channel_stat1);
-        radio.channel_stats.push_back(channel_stat2);
-    }
-
-    for (auto& peer : legacy_stats.peers) {
-        peer.peer_info.bssload.sta_count = rand();
-        peer.peer_info.bssload.chan_util = rand();
-        wifi_rate_stat rate_stat1 = {
-                .rate = {3, 1, 2, 5, 0, 0},
-                .tx_mpdu = 0,
-                .rx_mpdu = 1,
-                .mpdu_lost = 2,
-                .retries = 3,
-                .retries_short = 4,
-                .retries_long = 5,
-        };
-        wifi_rate_stat rate_stat2 = {
-                .rate = {2, 2, 1, 6, 0, 1},
-                .tx_mpdu = 6,
-                .rx_mpdu = 7,
-                .mpdu_lost = 8,
-                .retries = 9,
-                .retries_short = 10,
-                .retries_long = 11,
-        };
-        peer.rate_stats.push_back(rate_stat1);
-        peer.rate_stats.push_back(rate_stat2);
-    }
-
-    V1_6::StaLinkLayerStats converted{};
-    hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &converted);
-    EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.V1_0.beaconRx);
-    EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.V1_0.avgRssiMgmt);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
-              converted.iface.V1_0.wmeBePktStats.rxMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
-              converted.iface.V1_0.wmeBePktStats.txMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
-              converted.iface.V1_0.wmeBePktStats.lostMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries,
-              converted.iface.V1_0.wmeBePktStats.retries);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min,
-              converted.iface.wmeBeContentionTimeStats.contentionTimeMinInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max,
-              converted.iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg,
-              converted.iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
-              converted.iface.wmeBeContentionTimeStats.contentionNumSamples);
-
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
-              converted.iface.V1_0.wmeBkPktStats.rxMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
-              converted.iface.V1_0.wmeBkPktStats.txMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
-              converted.iface.V1_0.wmeBkPktStats.lostMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries,
-              converted.iface.V1_0.wmeBkPktStats.retries);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min,
-              converted.iface.wmeBkContentionTimeStats.contentionTimeMinInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max,
-              converted.iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg,
-              converted.iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
-              converted.iface.wmeBkContentionTimeStats.contentionNumSamples);
-
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
-              converted.iface.V1_0.wmeViPktStats.rxMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
-              converted.iface.V1_0.wmeViPktStats.txMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
-              converted.iface.V1_0.wmeViPktStats.lostMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries,
-              converted.iface.V1_0.wmeViPktStats.retries);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min,
-              converted.iface.wmeViContentionTimeStats.contentionTimeMinInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max,
-              converted.iface.wmeViContentionTimeStats.contentionTimeMaxInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg,
-              converted.iface.wmeViContentionTimeStats.contentionTimeAvgInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
-              converted.iface.wmeViContentionTimeStats.contentionNumSamples);
-
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
-              converted.iface.V1_0.wmeVoPktStats.rxMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
-              converted.iface.V1_0.wmeVoPktStats.txMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
-              converted.iface.V1_0.wmeVoPktStats.lostMpdu);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries,
-              converted.iface.V1_0.wmeVoPktStats.retries);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min,
-              converted.iface.wmeVoContentionTimeStats.contentionTimeMinInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max,
-              converted.iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg,
-              converted.iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec);
-    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
-              converted.iface.wmeVoContentionTimeStats.contentionNumSamples);
-
-    EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent,
-              converted.iface.timeSliceDutyCycleInPercent);
-
-    EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size());
-    for (size_t i = 0; i < legacy_stats.radios.size(); i++) {
-        EXPECT_EQ(legacy_stats.radios[i].stats.radio, converted.radios[i].radioId);
-        EXPECT_EQ(legacy_stats.radios[i].stats.on_time, converted.radios[i].V1_0.onTimeInMs);
-        EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, converted.radios[i].V1_0.txTimeInMs);
-        EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, converted.radios[i].V1_0.rxTimeInMs);
-        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan,
-                  converted.radios[i].V1_0.onTimeInMsForScan);
-        EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(),
-                  converted.radios[i].V1_0.txTimeInMsPerLevel.size());
-        for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); j++) {
-            EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j],
-                      converted.radios[i].V1_0.txTimeInMsPerLevel[j]);
-        }
-        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd,
-                  converted.radios[i].onTimeInMsForNanScan);
-        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan,
-                  converted.radios[i].onTimeInMsForBgScan);
-        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan,
-                  converted.radios[i].onTimeInMsForRoamScan);
-        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan,
-                  converted.radios[i].onTimeInMsForPnoScan);
-        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20,
-                  converted.radios[i].onTimeInMsForHs20Scan);
-        EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(),
-                  converted.radios[i].channelStats.size());
-        for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); k++) {
-            auto& legacy_channel_st = legacy_stats.radios[i].channel_stats[k];
-            EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20,
-                      converted.radios[i].channelStats[k].channel.width);
-            EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq),
-                      converted.radios[i].channelStats[k].channel.centerFreq);
-            EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq0),
-                      converted.radios[i].channelStats[k].channel.centerFreq0);
-            EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq1),
-                      converted.radios[i].channelStats[k].channel.centerFreq1);
-            EXPECT_EQ(legacy_channel_st.cca_busy_time,
-                      converted.radios[i].channelStats[k].ccaBusyTimeInMs);
-            EXPECT_EQ(legacy_channel_st.on_time, converted.radios[i].channelStats[k].onTimeInMs);
-        }
-    }
-
-    EXPECT_EQ(legacy_stats.peers.size(), converted.iface.peers.size());
-    for (size_t i = 0; i < legacy_stats.peers.size(); i++) {
-        EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.sta_count,
-                  converted.iface.peers[i].staCount);
-        EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.chan_util,
-                  converted.iface.peers[i].chanUtil);
-        for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) {
-            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble,
-                      (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.preamble);
-            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.nss,
-                      (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss);
-            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.bw,
-                      (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw);
-            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx,
-                      converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx);
-            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu,
-                      converted.iface.peers[i].rateStats[j].txMpdu);
-            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu,
-                      converted.iface.peers[i].rateStats[j].rxMpdu);
-            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].mpdu_lost,
-                      converted.iface.peers[i].rateStats[j].mpduLost);
-            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].retries,
-                      converted.iface.peers[i].rateStats[j].retries);
-        }
-    }
-}
-
-TEST_F(HidlStructUtilTest, CanConvertLegacyFeaturesToHidl) {
-    using HidlChipCaps = V1_3::IWifiChip::ChipCapabilityMask;
-
-    uint32_t hidle_caps;
-
-    uint32_t legacy_feature_set = WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE;
-    uint32_t legacy_logger_feature_set = legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
-
-    ASSERT_TRUE(hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
-            legacy_feature_set, legacy_logger_feature_set, &hidle_caps));
-
-    EXPECT_EQ(HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA |
-                      HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS |
-                      HidlChipCaps::DEBUG_ERROR_ALERTS | HidlChipCaps::D2D_RTT |
-                      HidlChipCaps::SET_LATENCY_MODE | HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP,
-              hidle_caps);
-}
-
-void insertRadioCombination(legacy_hal::wifi_radio_combination* dst_radio_combination_ptr,
-                            int num_radio_configurations,
-                            legacy_hal::wifi_radio_configuration* radio_configuration) {
-    dst_radio_combination_ptr->num_radio_configurations = num_radio_configurations;
-    memcpy(dst_radio_combination_ptr->radio_configurations, radio_configuration,
-           num_radio_configurations * sizeof(legacy_hal::wifi_radio_configuration));
-}
-
-void verifyRadioCombination(WifiRadioCombination* radioCombination, size_t num_radio_configurations,
-                            legacy_hal::wifi_radio_configuration* radio_configuration) {
-    EXPECT_EQ(num_radio_configurations, radioCombination->radioConfigurations.size());
-    for (size_t i = 0; i < num_radio_configurations; i++) {
-        EXPECT_EQ(hidl_struct_util::convertLegacyMacBandToHidlWifiBand(radio_configuration->band),
-                  radioCombination->radioConfigurations[i].bandInfo);
-        EXPECT_EQ(hidl_struct_util::convertLegacyAntennaConfigurationToHidl(
-                          radio_configuration->antenna_cfg),
-                  radioCombination->radioConfigurations[i].antennaMode);
-        radio_configuration++;
-    }
-}
-
-TEST_F(HidlStructUtilTest, canConvertLegacyRadioCombinationsMatrixToHidl) {
-    legacy_hal::wifi_radio_configuration radio_configurations_array1[] = {
-            {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
-    };
-    legacy_hal::wifi_radio_configuration radio_configurations_array2[] = {
-            {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
-            {.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_3X3},
-    };
-    legacy_hal::wifi_radio_configuration radio_configurations_array3[] = {
-            {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
-            {.band = legacy_hal::WLAN_MAC_6_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
-            {.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_4X4},
-    };
-
-    int num_radio_configs = 0;
-    int num_combinations = 0;
-    std::array<char, 256> buffer;
-    buffer.fill(0);
-    legacy_hal::wifi_radio_combination_matrix* legacy_matrix =
-            reinterpret_cast<wifi_radio_combination_matrix*>(buffer.data());
-    legacy_hal::wifi_radio_combination* radio_combinations;
-
-    // Prepare a legacy wifi_radio_combination_matrix
-    legacy_matrix->num_radio_combinations = 3;
-    // Insert first combination
-    radio_combinations =
-            (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations);
-    insertRadioCombination(
-            radio_combinations,
-            sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
-            radio_configurations_array1);
-    num_combinations++;
-    num_radio_configs +=
-            sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]);
-
-    // Insert second combination
-    radio_combinations =
-            (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
-                                                  (num_combinations *
-                                                   sizeof(legacy_hal::wifi_radio_combination)) +
-                                                  (num_radio_configs *
-                                                   sizeof(wifi_radio_configuration)));
-    insertRadioCombination(
-            radio_combinations,
-            sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
-            radio_configurations_array2);
-    num_combinations++;
-    num_radio_configs +=
-            sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]);
-
-    // Insert third combination
-    radio_combinations =
-            (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
-                                                  (num_combinations *
-                                                   sizeof(legacy_hal::wifi_radio_combination)) +
-                                                  (num_radio_configs *
-                                                   sizeof(wifi_radio_configuration)));
-    insertRadioCombination(
-            radio_combinations,
-            sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
-            radio_configurations_array3);
-
-    V1_6::WifiRadioCombinationMatrix converted_matrix{};
-    hidl_struct_util::convertLegacyRadioCombinationsMatrixToHidl(legacy_matrix, &converted_matrix);
-
-    // Verify the conversion
-    EXPECT_EQ(legacy_matrix->num_radio_combinations, converted_matrix.radioCombinations.size());
-    verifyRadioCombination(
-            &converted_matrix.radioCombinations[0],
-            sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
-            radio_configurations_array1);
-    verifyRadioCombination(
-            &converted_matrix.radioCombinations[1],
-            sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
-            radio_configurations_array2);
-    verifyRadioCombination(
-            &converted_matrix.radioCombinations[2],
-            sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
-            radio_configurations_array3);
-}
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/tests/main.cpp b/wifi/1.6/default/tests/main.cpp
deleted file mode 100644
index 9aac837..0000000
--- a/wifi/1.6/default/tests/main.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 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 <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <android-base/logging.h>
-
-int main(int argc, char** argv) {
-    ::testing::InitGoogleTest(&argc, argv);
-    ::testing::InitGoogleMock(&argc, argv);
-    // Force ourselves to always log to stderr
-    android::base::InitLogging(argv, android::base::StderrLogger);
-    return RUN_ALL_TESTS();
-}
diff --git a/wifi/1.6/default/tests/mock_interface_tool.cpp b/wifi/1.6/default/tests/mock_interface_tool.cpp
deleted file mode 100644
index b99a164..0000000
--- a/wifi/1.6/default/tests/mock_interface_tool.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <gmock/gmock.h>
-
-#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
-#include "mock_interface_tool.h"
-
-namespace android {
-namespace wifi_system {
-
-MockInterfaceTool::MockInterfaceTool() {}
-
-}  // namespace wifi_system
-}  // namespace android
diff --git a/wifi/1.6/default/tests/mock_interface_tool.h b/wifi/1.6/default/tests/mock_interface_tool.h
deleted file mode 100644
index 7ce3992..0000000
--- a/wifi/1.6/default/tests/mock_interface_tool.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MOCK_INTERFACE_TOOL_H
-#define MOCK_INTERFACE_TOOL_H
-
-#include <gmock/gmock.h>
-#include <wifi_system/interface_tool.h>
-
-namespace android {
-namespace wifi_system {
-
-class MockInterfaceTool : public InterfaceTool {
-  public:
-    MockInterfaceTool();
-
-    MOCK_METHOD1(GetUpState, bool(const char* if_name));
-    MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up));
-    MOCK_METHOD1(SetWifiUpState, bool(bool request_up));
-    MOCK_METHOD2(SetMacAddress,
-                 bool(const char* if_name, const std::array<uint8_t, ETH_ALEN>& address));
-    MOCK_METHOD1(GetFactoryMacAddress, std::array<uint8_t, ETH_ALEN>(const char* if_name));
-
-};  // class MockInterfaceTool
-
-}  // namespace wifi_system
-}  // namespace android
-
-#endif  // MOCK_INTERFACE_TOOL_H
diff --git a/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp b/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp
deleted file mode 100644
index d10b74c..0000000
--- a/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 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 <gmock/gmock.h>
-
-#include "mock_wifi_feature_flags.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace feature_flags {
-
-MockWifiFeatureFlags::MockWifiFeatureFlags() {}
-
-}  // namespace feature_flags
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/tests/mock_wifi_feature_flags.h b/wifi/1.6/default/tests/mock_wifi_feature_flags.h
deleted file mode 100644
index fbe1f7a..0000000
--- a/wifi/1.6/default/tests/mock_wifi_feature_flags.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2017 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 MOCK_WIFI_FEATURE_FLAGS_H_
-#define MOCK_WIFI_FEATURE_FLAGS_H_
-
-#include <gmock/gmock.h>
-#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
-
-#include "wifi_feature_flags.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace feature_flags {
-
-class MockWifiFeatureFlags : public WifiFeatureFlags {
-  public:
-    MockWifiFeatureFlags();
-
-    MOCK_METHOD1(getChipModes, std::vector<V1_6::IWifiChip::ChipMode>(bool is_primary));
-    MOCK_METHOD0(isApMacRandomizationDisabled, bool());
-};
-
-}  // namespace feature_flags
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // MOCK_WIFI_FEATURE_FLAGS_H_
diff --git a/wifi/1.6/default/tests/mock_wifi_iface_util.cpp b/wifi/1.6/default/tests/mock_wifi_iface_util.cpp
deleted file mode 100644
index 24b16cb..0000000
--- a/wifi/1.6/default/tests/mock_wifi_iface_util.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <gmock/gmock.h>
-
-#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
-#include "mock_wifi_iface_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace iface_util {
-
-MockWifiIfaceUtil::MockWifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-                                     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
-    : WifiIfaceUtil(iface_tool, legacy_hal) {}
-}  // namespace iface_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/tests/mock_wifi_iface_util.h b/wifi/1.6/default/tests/mock_wifi_iface_util.h
deleted file mode 100644
index 2701c36..0000000
--- a/wifi/1.6/default/tests/mock_wifi_iface_util.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MOCK_WIFI_IFACE_UTIL_H_
-#define MOCK_WIFI_IFACE_UTIL_H_
-
-#include <gmock/gmock.h>
-
-#include "wifi_iface_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace iface_util {
-
-class MockWifiIfaceUtil : public WifiIfaceUtil {
-  public:
-    MockWifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-                      const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
-    MOCK_METHOD1(getFactoryMacAddress, std::array<uint8_t, 6>(const std::string&));
-    MOCK_METHOD2(setMacAddress, bool(const std::string&, const std::array<uint8_t, 6>&));
-    MOCK_METHOD0(getOrCreateRandomMacAddress, std::array<uint8_t, 6>());
-    MOCK_METHOD2(registerIfaceEventHandlers, void(const std::string&, IfaceEventHandlers));
-    MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&));
-    MOCK_METHOD2(setUpState, bool(const std::string&, bool));
-    MOCK_METHOD1(ifNameToIndex, unsigned(const std::string&));
-};
-}  // namespace iface_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // MOCK_WIFI_IFACE_UTIL_H_
diff --git a/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp
deleted file mode 100644
index 2c55861..0000000
--- a/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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 <android-base/macros.h>
-#include <gmock/gmock.h>
-
-#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
-#include "mock_wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace legacy_hal {
-
-MockWifiLegacyHal::MockWifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-                                     const wifi_hal_fn& fn, bool is_primary)
-    : WifiLegacyHal(iface_tool, fn, is_primary) {}
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/tests/mock_wifi_legacy_hal.h b/wifi/1.6/default/tests/mock_wifi_legacy_hal.h
deleted file mode 100644
index 85dbf0f..0000000
--- a/wifi/1.6/default/tests/mock_wifi_legacy_hal.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2017 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 MOCK_WIFI_LEGACY_HAL_H_
-#define MOCK_WIFI_LEGACY_HAL_H_
-
-#include <gmock/gmock.h>
-
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace legacy_hal {
-
-class MockWifiLegacyHal : public WifiLegacyHal {
-  public:
-    MockWifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-                      const wifi_hal_fn& fn, bool is_primary);
-    MOCK_METHOD0(initialize, wifi_error());
-    MOCK_METHOD0(start, wifi_error());
-    MOCK_METHOD2(stop,
-                 wifi_error(std::unique_lock<std::recursive_mutex>*, const std::function<void()>&));
-    MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool));
-    MOCK_METHOD2(registerRadioModeChangeCallbackHandler,
-                 wifi_error(const std::string&, const on_radio_mode_change_callback&));
-    MOCK_METHOD1(getFirmwareVersion,
-                 std::pair<wifi_error, std::string>(const std::string& iface_name));
-    MOCK_METHOD1(getDriverVersion,
-                 std::pair<wifi_error, std::string>(const std::string& iface_name));
-
-    MOCK_METHOD2(selectTxPowerScenario,
-                 wifi_error(const std::string& iface_name, wifi_power_scenario scenario));
-    MOCK_METHOD1(resetTxPowerScenario, wifi_error(const std::string& iface_name));
-    MOCK_METHOD2(nanRegisterCallbackHandlers,
-                 wifi_error(const std::string&, const NanCallbackHandlers&));
-    MOCK_METHOD2(nanDisableRequest, wifi_error(const std::string&, transaction_id));
-    MOCK_METHOD3(nanDataInterfaceDelete,
-                 wifi_error(const std::string&, transaction_id, const std::string&));
-    MOCK_METHOD2(createVirtualInterface,
-                 wifi_error(const std::string& ifname, wifi_interface_type iftype));
-    MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
-    MOCK_METHOD0(waitForDriverReady, wifi_error());
-    MOCK_METHOD2(getSupportedIfaceName, wifi_error(uint32_t, std::string&));
-    MOCK_METHOD1(registerSubsystemRestartCallbackHandler,
-                 wifi_error(const on_subsystem_restart_callback&));
-    MOCK_METHOD1(getSupportedFeatureSet, std::pair<wifi_error, uint64_t>(const std::string&));
-};
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // MOCK_WIFI_LEGACY_HAL_H_
diff --git a/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp b/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp
deleted file mode 100644
index 446f829..0000000
--- a/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 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 <android-base/macros.h>
-#include <gmock/gmock.h>
-
-#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
-#include "mock_wifi_mode_controller.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace mode_controller {
-
-MockWifiModeController::MockWifiModeController() : WifiModeController() {}
-}  // namespace mode_controller
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/tests/mock_wifi_mode_controller.h b/wifi/1.6/default/tests/mock_wifi_mode_controller.h
deleted file mode 100644
index addcc81..0000000
--- a/wifi/1.6/default/tests/mock_wifi_mode_controller.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 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 MOCK_WIFI_MODE_CONTROLLER_H_
-#define MOCK_WIFI_MODE_CONTROLLER_H_
-
-#include <gmock/gmock.h>
-
-#include "wifi_mode_controller.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace mode_controller {
-
-class MockWifiModeController : public WifiModeController {
-  public:
-    MockWifiModeController();
-    MOCK_METHOD0(initialize, bool());
-    MOCK_METHOD1(changeFirmwareMode, bool(IfaceType));
-    MOCK_METHOD1(isFirmwareModeChangeNeeded, bool(IfaceType));
-    MOCK_METHOD0(deinitialize, bool());
-};
-}  // namespace mode_controller
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // MOCK_WIFI_MODE_CONTROLLER_H_
diff --git a/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp b/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp
deleted file mode 100644
index eb86194..0000000
--- a/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp
+++ /dev/null
@@ -1,97 +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.
- */
-
-#include <gmock/gmock.h>
-
-#include "ringbuffer.h"
-
-using testing::Return;
-using testing::Test;
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-
-class RingbufferTest : public Test {
-  public:
-    const uint32_t maxBufferSize_ = 10;
-    Ringbuffer buffer_{maxBufferSize_};
-};
-
-TEST_F(RingbufferTest, CreateEmptyBuffer) {
-    ASSERT_TRUE(buffer_.getData().empty());
-}
-
-TEST_F(RingbufferTest, CanUseFullBufferCapacity) {
-    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
-    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
-    buffer_.append(input);
-    buffer_.append(input2);
-    ASSERT_EQ(2u, buffer_.getData().size());
-    EXPECT_EQ(input, buffer_.getData().front());
-    EXPECT_EQ(input2, buffer_.getData().back());
-}
-
-TEST_F(RingbufferTest, OldDataIsRemovedOnOverflow) {
-    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
-    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
-    const std::vector<uint8_t> input3 = {'G'};
-    buffer_.append(input);
-    buffer_.append(input2);
-    buffer_.append(input3);
-    ASSERT_EQ(2u, buffer_.getData().size());
-    EXPECT_EQ(input2, buffer_.getData().front());
-    EXPECT_EQ(input3, buffer_.getData().back());
-}
-
-TEST_F(RingbufferTest, MultipleOldDataIsRemovedOnOverflow) {
-    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
-    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
-    const std::vector<uint8_t> input3(maxBufferSize_, '2');
-    buffer_.append(input);
-    buffer_.append(input2);
-    buffer_.append(input3);
-    ASSERT_EQ(1u, buffer_.getData().size());
-    EXPECT_EQ(input3, buffer_.getData().front());
-}
-
-TEST_F(RingbufferTest, AppendingEmptyBufferDoesNotAddGarbage) {
-    const std::vector<uint8_t> input = {};
-    buffer_.append(input);
-    ASSERT_TRUE(buffer_.getData().empty());
-}
-
-TEST_F(RingbufferTest, OversizedAppendIsDropped) {
-    const std::vector<uint8_t> input(maxBufferSize_ + 1, '0');
-    buffer_.append(input);
-    ASSERT_TRUE(buffer_.getData().empty());
-}
-
-TEST_F(RingbufferTest, OversizedAppendDoesNotDropExistingData) {
-    const std::vector<uint8_t> input(maxBufferSize_, '0');
-    const std::vector<uint8_t> input2(maxBufferSize_ + 1, '1');
-    buffer_.append(input);
-    buffer_.append(input2);
-    ASSERT_EQ(1u, buffer_.getData().size());
-    EXPECT_EQ(input, buffer_.getData().front());
-}
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/tests/runtests.sh b/wifi/1.6/default/tests/runtests.sh
deleted file mode 100755
index 6bce3ef..0000000
--- a/wifi/1.6/default/tests/runtests.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright(C) 2017 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.
-
-if [ -z $ANDROID_BUILD_TOP ]; then
-  echo "You need to source and lunch before you can use this script"
-  exit 1
-fi
-set -e
-
-$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode android.hardware.wifi@1.0-service-tests
-adb root
-adb sync data
-adb shell /data/nativetest64/vendor/android.hardware.wifi@1.0-service-tests/android.hardware.wifi@1.0-service-tests
diff --git a/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp
deleted file mode 100644
index 81117c5..0000000
--- a/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * Copyright (C) 2017, 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 <android-base/macros.h>
-#include <cutils/properties.h>
-#include <gmock/gmock.h>
-
-#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
-#include "wifi_chip.h"
-
-#include "mock_interface_tool.h"
-#include "mock_wifi_feature_flags.h"
-#include "mock_wifi_iface_util.h"
-#include "mock_wifi_legacy_hal.h"
-#include "mock_wifi_mode_controller.h"
-
-using testing::NiceMock;
-using testing::Return;
-using testing::Test;
-
-namespace {
-using android::hardware::wifi::V1_0::ChipId;
-
-constexpr ChipId kFakeChipId = 5;
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-
-class WifiChipTest : public Test {
-  protected:
-    void setupV1IfaceCombination() {
-        // clang-format off
-        const hidl_vec<IWifiChip::ChipConcurrencyCombination> combinationsSta = {
-            {{{{IfaceConcurrencyType::STA}, 1}, {{IfaceConcurrencyType::P2P}, 1}}}
-        };
-        const hidl_vec<IWifiChip::ChipConcurrencyCombination> combinationsAp = {
-            {{{{IfaceConcurrencyType::AP}, 1}}}
-        };
-        const std::vector<V1_6::IWifiChip::ChipMode> modes = {
-            {feature_flags::chip_mode_ids::kV1Sta, combinationsSta},
-            {feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
-        };
-        // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
-    }
-
-    void setupV1_AwareIfaceCombination() {
-        // clang-format off
-        const hidl_vec<IWifiChip::ChipConcurrencyCombination> combinationsSta = {
-            {{{{IfaceConcurrencyType::STA}, 1},
-              {{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN}, 1}}}
-        };
-        const hidl_vec<IWifiChip::ChipConcurrencyCombination> combinationsAp = {
-            {{{{IfaceConcurrencyType::AP}, 1}}}
-        };
-        const std::vector<V1_6::IWifiChip::ChipMode> modes = {
-            {feature_flags::chip_mode_ids::kV1Sta, combinationsSta},
-            {feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
-        };
-        // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
-    }
-
-    void setupV1_AwareDisabledApIfaceCombination() {
-        // clang-format off
-        const hidl_vec<IWifiChip::ChipConcurrencyCombination> combinationsSta = {
-            {{{{IfaceConcurrencyType::STA}, 1},
-              {{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN}, 1}}}
-        };
-        const std::vector<V1_6::IWifiChip::ChipMode> modes = {
-            {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}
-        };
-        // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
-    }
-
-    void setupV2_AwareIfaceCombination() {
-        // clang-format off
-        const hidl_vec<IWifiChip::ChipConcurrencyCombination> combinations = {
-            {{{{IfaceConcurrencyType::STA}, 1}, {{IfaceConcurrencyType::AP}, 1}}},
-            {{{{IfaceConcurrencyType::STA}, 1},
-              {{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN}, 1}}}
-        };
-        const std::vector<V1_6::IWifiChip::ChipMode> modes = {
-            {feature_flags::chip_mode_ids::kV3, combinations}
-        };
-        // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
-    }
-
-    void setupV2_AwareDisabledApIfaceCombination() {
-        // clang-format off
-        const hidl_vec<IWifiChip::ChipConcurrencyCombination> combinations = {
-            {{{{IfaceConcurrencyType::STA}, 1},
-              {{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN}, 1}}}
-        };
-        const std::vector<V1_6::IWifiChip::ChipMode> modes = {
-            {feature_flags::chip_mode_ids::kV3, combinations}
-        };
-        // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
-    }
-
-    void setup_MultiIfaceCombination() {
-        // clang-format off
-        const hidl_vec<IWifiChip::ChipConcurrencyCombination> combinations = {
-            {{{{IfaceConcurrencyType::STA}, 3}, {{IfaceConcurrencyType::AP}, 1}}}
-        };
-        const std::vector<V1_6::IWifiChip::ChipMode> modes = {
-            {feature_flags::chip_mode_ids::kV3, combinations}
-        };
-        // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
-    }
-
-    void assertNumberOfModes(uint32_t num_modes) {
-        chip_->getAvailableModes_1_6([num_modes](const WifiStatus& status,
-                                                 const std::vector<WifiChip::ChipMode>& modes) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-            // V2_Aware has 1 mode of operation.
-            ASSERT_EQ(num_modes, modes.size());
-        });
-    }
-
-    void findModeAndConfigureForIfaceType(const IfaceConcurrencyType& type) {
-        // This should be aligned with kInvalidModeId in wifi_chip.cpp.
-        ChipModeId mode_id = UINT32_MAX;
-        chip_->getAvailableModes_1_6([&mode_id, &type](
-                                             const WifiStatus& status,
-                                             const std::vector<WifiChip::ChipMode>& modes) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-            for (const auto& mode : modes) {
-                for (const auto& combination : mode.availableCombinations) {
-                    for (const auto& limit : combination.limits) {
-                        if (limit.types.end() !=
-                            std::find(limit.types.begin(), limit.types.end(), type)) {
-                            mode_id = mode.id;
-                        }
-                    }
-                }
-            }
-        });
-        ASSERT_NE(UINT32_MAX, mode_id);
-
-        chip_->configureChip(mode_id, [](const WifiStatus& status) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-        });
-    }
-
-    // Returns an empty string on error.
-    std::string createIface(const IfaceType& type) {
-        std::string iface_name;
-        if (type == IfaceType::AP) {
-            chip_->createApIface(
-                    [&iface_name](const WifiStatus& status, const sp<V1_0::IWifiApIface>& iface) {
-                        if (WifiStatusCode::SUCCESS == status.code) {
-                            ASSERT_NE(iface.get(), nullptr);
-                            iface->getName([&iface_name](const WifiStatus& status,
-                                                         const hidl_string& name) {
-                                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                                iface_name = name.c_str();
-                            });
-                        }
-                    });
-        } else if (type == IfaceType::NAN) {
-            chip_->createNanIface(
-                    [&iface_name](const WifiStatus& status,
-                                  const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) {
-                        if (WifiStatusCode::SUCCESS == status.code) {
-                            ASSERT_NE(iface.get(), nullptr);
-                            iface->getName([&iface_name](const WifiStatus& status,
-                                                         const hidl_string& name) {
-                                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                                iface_name = name.c_str();
-                            });
-                        }
-                    });
-        } else if (type == IfaceType::P2P) {
-            chip_->createP2pIface(
-                    [&iface_name](const WifiStatus& status, const sp<IWifiP2pIface>& iface) {
-                        if (WifiStatusCode::SUCCESS == status.code) {
-                            ASSERT_NE(iface.get(), nullptr);
-                            iface->getName([&iface_name](const WifiStatus& status,
-                                                         const hidl_string& name) {
-                                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                                iface_name = name.c_str();
-                            });
-                        }
-                    });
-        } else if (type == IfaceType::STA) {
-            chip_->createStaIface(
-                    [&iface_name](const WifiStatus& status, const sp<V1_0::IWifiStaIface>& iface) {
-                        if (WifiStatusCode::SUCCESS == status.code) {
-                            ASSERT_NE(iface.get(), nullptr);
-                            iface->getName([&iface_name](const WifiStatus& status,
-                                                         const hidl_string& name) {
-                                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                                iface_name = name.c_str();
-                            });
-                        }
-                    });
-        }
-        return iface_name;
-    }
-
-    void removeIface(const IfaceType& type, const std::string& iface_name) {
-        if (type == IfaceType::AP) {
-            chip_->removeApIface(iface_name, [](const WifiStatus& status) {
-                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-            });
-        } else if (type == IfaceType::NAN) {
-            chip_->removeNanIface(iface_name, [](const WifiStatus& status) {
-                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-            });
-        } else if (type == IfaceType::P2P) {
-            chip_->removeP2pIface(iface_name, [](const WifiStatus& status) {
-                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-            });
-        } else if (type == IfaceType::STA) {
-            chip_->removeStaIface(iface_name, [](const WifiStatus& status) {
-                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-            });
-        }
-    }
-
-    bool createRttController() {
-        bool success = false;
-        chip_->createRttController_1_6(
-                NULL, [&success](const WifiStatus& status, const sp<IWifiRttController>& rtt) {
-                    if (WifiStatusCode::SUCCESS == status.code) {
-                        ASSERT_NE(rtt.get(), nullptr);
-                        success = true;
-                    }
-                });
-        return success;
-    }
-
-    static void subsystemRestartHandler(const std::string& /*error*/) {}
-
-    sp<WifiChip> chip_;
-    ChipId chip_id_ = kFakeChipId;
-    legacy_hal::wifi_hal_fn fake_func_table_;
-    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
-            new NiceMock<wifi_system::MockInterfaceTool>};
-    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
-            new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
-    std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>> mode_controller_{
-            new NiceMock<mode_controller::MockWifiModeController>};
-    std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
-            new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
-    std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>> feature_flags_{
-            new NiceMock<feature_flags::MockWifiFeatureFlags>};
-
-  public:
-    void SetUp() override {
-        chip_ = new WifiChip(chip_id_, true, legacy_hal_, mode_controller_, iface_util_,
-                             feature_flags_, subsystemRestartHandler);
-
-        EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_))
-                .WillRepeatedly(testing::Return(true));
-        EXPECT_CALL(*legacy_hal_, start())
-                .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS));
-        // Vendor HAL does not override the name by default.
-        EXPECT_CALL(*legacy_hal_, getSupportedIfaceName(testing::_, testing::_))
-                .WillRepeatedly(testing::Return(legacy_hal::WIFI_ERROR_UNKNOWN));
-    }
-
-    void TearDown() override {
-        // Restore default system iface names (This should ideally be using a
-        // mock).
-        property_set("wifi.interface", "wlan0");
-        property_set("wifi.concurrent.interface", "wlan1");
-        property_set("wifi.aware.interface", nullptr);
-    }
-};
-
-////////// V1 Iface Combinations ////////////
-// Mode 1 - STA + P2P
-// Mode 2 - AP
-class WifiChipV1IfaceCombinationTest : public WifiChipTest {
-  public:
-    void SetUp() override {
-        setupV1IfaceCombination();
-        WifiChipTest::SetUp();
-        // V1 has 2 modes of operation.
-        assertNumberOfModes(2u);
-    }
-};
-
-TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-}
-
-TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateNan_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_TRUE(createIface(IfaceType::AP).empty());
-}
-
-TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
-}
-
-TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_TRUE(createIface(IfaceType::STA).empty());
-}
-
-TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_TRUE(createIface(IfaceType::STA).empty());
-}
-
-TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
-}
-
-////////// V1 + Aware Iface Combinations ////////////
-// Mode 1 - STA + P2P/NAN
-// Mode 2 - AP
-class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest {
-  public:
-    void SetUp() override {
-        setupV1_AwareIfaceCombination();
-        WifiChipTest::SetUp();
-        // V1_Aware has 2 modes of operation.
-        assertNumberOfModes(2u);
-    }
-};
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateNan_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_TRUE(createIface(IfaceType::AP).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2PNan_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    const auto p2p_iface_name = createIface(IfaceType::P2P);
-    ASSERT_FALSE(p2p_iface_name.empty());
-    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
-
-    // After removing P2P iface, NAN iface creation should succeed.
-    removeIface(IfaceType::P2P, p2p_iface_name);
-    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    const auto nan_iface_name = createIface(IfaceType::NAN);
-    ASSERT_FALSE(nan_iface_name.empty());
-    ASSERT_TRUE(createIface(IfaceType::P2P).empty());
-
-    // After removing NAN iface, P2P iface creation should succeed.
-    removeIface(IfaceType::NAN, nan_iface_name);
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_TRUE(createIface(IfaceType::STA).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_TRUE(createIface(IfaceType::STA).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_TRUE(createRttController());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_TRUE(createRttController());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowApToSta) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    const auto ap_iface_name = createIface(IfaceType::AP);
-    ASSERT_FALSE(ap_iface_name.empty());
-    ASSERT_FALSE(createRttController());
-
-    removeIface(IfaceType::AP, ap_iface_name);
-
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_TRUE(createRttController());
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-    EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
-            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
-    chip_->selectTxPowerScenario_1_2(
-            V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
-            [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); });
-}
-
-TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
-    EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
-            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
-    chip_->selectTxPowerScenario_1_2(
-            V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
-            [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); });
-}
-
-////////// V2 + Aware Iface Combinations ////////////
-// Mode 1 - STA + STA/AP
-//        - STA + P2P/NAN
-class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest {
-  public:
-    void SetUp() override {
-        setupV2_AwareIfaceCombination();
-        WifiChipTest::SetUp();
-        // V2_Aware has 1 mode of operation.
-        assertNumberOfModes(1u);
-    }
-};
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateP2p_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNan_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateAp_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-    ASSERT_TRUE(createIface(IfaceType::STA).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-    ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApSta_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_AfterStaApRemove_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    const auto sta_iface_name = createIface(IfaceType::STA);
-    ASSERT_FALSE(sta_iface_name.empty());
-    const auto ap_iface_name = createIface(IfaceType::AP);
-    ASSERT_FALSE(ap_iface_name.empty());
-
-    ASSERT_TRUE(createIface(IfaceType::STA).empty());
-
-    // After removing AP & STA iface, STA iface creation should succeed.
-    removeIface(IfaceType::STA, sta_iface_name);
-    removeIface(IfaceType::AP, ap_iface_name);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2PNan_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_AfterP2pRemove_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    const auto p2p_iface_name = createIface(IfaceType::P2P);
-    ASSERT_FALSE(p2p_iface_name.empty());
-    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
-
-    // After removing P2P iface, NAN iface creation should succeed.
-    removeIface(IfaceType::P2P, p2p_iface_name);
-    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_AfterNanRemove_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    const auto nan_iface_name = createIface(IfaceType::NAN);
-    ASSERT_FALSE(nan_iface_name.empty());
-    ASSERT_TRUE(createIface(IfaceType::P2P).empty());
-
-    // After removing NAN iface, P2P iface creation should succeed.
-    removeIface(IfaceType::NAN, nan_iface_name);
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApNan_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_FALSE(createIface(IfaceType::AP).empty());
-    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApP2p_ShouldFail) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_FALSE(createIface(IfaceType::AP).empty());
-    ASSERT_TRUE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    const auto p2p_iface_name = createIface(IfaceType::P2P);
-    ASSERT_FALSE(p2p_iface_name.empty());
-    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
-
-    // After removing P2P iface, NAN iface creation should succeed.
-    removeIface(IfaceType::P2P, p2p_iface_name);
-    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    const auto nan_iface_name = createIface(IfaceType::NAN);
-    ASSERT_FALSE(nan_iface_name.empty());
-    ASSERT_TRUE(createIface(IfaceType::P2P).empty());
-
-    // After removing NAN iface, P2P iface creation should succeed.
-    removeIface(IfaceType::NAN, nan_iface_name);
-    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_EnsureDifferentIfaceNames) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    const auto sta_iface_name = createIface(IfaceType::STA);
-    const auto ap_iface_name = createIface(IfaceType::AP);
-    ASSERT_FALSE(sta_iface_name.empty());
-    ASSERT_FALSE(ap_iface_name.empty());
-    ASSERT_NE(sta_iface_name, ap_iface_name);
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_TRUE(createRttController());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_TRUE(createRttController());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlow) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::AP).empty());
-    ASSERT_TRUE(createRttController());
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-    EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
-            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
-    chip_->selectTxPowerScenario_1_2(
-            V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
-            [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); });
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
-    ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
-    EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_))
-            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
-    chip_->selectTxPowerScenario_1_2(
-            V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
-            [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); });
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveNanOnStaRemove) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-
-    // Create NAN iface
-    ASSERT_EQ(createIface(IfaceType::NAN), "wlan0");
-
-    // We should have 1 nan iface.
-    chip_->getNanIfaceNames([](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
-        ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-        ASSERT_EQ(iface_names.size(), 1u);
-        ASSERT_EQ(iface_names[0], "wlan0");
-    });
-    // Retrieve the exact iface object.
-    sp<android::hardware::wifi::V1_0::IWifiNanIface> nan_iface;
-    chip_->getNanIface("wlan0",
-                       [&nan_iface](const WifiStatus& status,
-                                    const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) {
-                           ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                           ASSERT_NE(iface.get(), nullptr);
-                           nan_iface = iface;
-                       });
-
-    // Remove the STA iface.
-    removeIface(IfaceType::STA, "wlan0");
-    // We should have 0 nan iface now.
-    chip_->getNanIfaceNames([](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
-        ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-        ASSERT_EQ(iface_names.size(), 0u);
-    });
-    // Any operation on the nan iface object should return error now.
-    nan_iface->getName([](const WifiStatus& status, const std::string& /* iface_name */) {
-        ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code);
-    });
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveRttControllerOnStaRemove) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-
-    // Create RTT controller
-    sp<IWifiRttController> rtt_controller;
-    chip_->createRttController_1_6(
-            NULL, [&rtt_controller](const WifiStatus& status, const sp<IWifiRttController>& rtt) {
-                if (WifiStatusCode::SUCCESS == status.code) {
-                    ASSERT_NE(rtt.get(), nullptr);
-                    rtt_controller = rtt;
-                }
-            });
-
-    // Remove the STA iface.
-    removeIface(IfaceType::STA, "wlan0");
-
-    // Any operation on the rtt controller object should return error now.
-    rtt_controller->getBoundIface([](const WifiStatus& status, const sp<IWifiIface>& /* iface */) {
-        ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, status.code);
-    });
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) {
-    property_set("wifi.aware.interface", nullptr);
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-    ASSERT_EQ(createIface(IfaceType::NAN), "wlan0");
-    removeIface(IfaceType::NAN, "wlan0");
-    EXPECT_CALL(*iface_util_, setUpState(testing::_, testing::_)).Times(0);
-}
-
-TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithDedicatedNanIface) {
-    property_set("wifi.aware.interface", "aware0");
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-    EXPECT_CALL(*iface_util_, ifNameToIndex("aware0")).WillOnce(testing::Return(4));
-    EXPECT_CALL(*iface_util_, setUpState("aware0", true)).WillOnce(testing::Return(true));
-    ASSERT_EQ(createIface(IfaceType::NAN), "aware0");
-
-    EXPECT_CALL(*iface_util_, setUpState("aware0", false)).WillOnce(testing::Return(true));
-    removeIface(IfaceType::NAN, "aware0");
-}
-
-////////// V1 Iface Combinations when AP creation is disabled //////////
-class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
-  public:
-    void SetUp() override {
-        setupV1_AwareDisabledApIfaceCombination();
-        WifiChipTest::SetUp();
-    }
-};
-
-TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_TRUE(createIface(IfaceType::AP).empty());
-}
-
-////////// V2 Iface Combinations when AP creation is disabled //////////
-class WifiChipV2_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
-  public:
-    void SetUp() override {
-        setupV2_AwareDisabledApIfaceCombination();
-        WifiChipTest::SetUp();
-    }
-};
-
-TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, CreateSta_ShouldSucceed) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_TRUE(createIface(IfaceType::AP).empty());
-}
-
-////////// Hypothetical Iface Combination with multiple ifaces //////////
-class WifiChip_MultiIfaceTest : public WifiChipTest {
-  public:
-    void SetUp() override {
-        setup_MultiIfaceCombination();
-        WifiChipTest::SetUp();
-    }
-};
-
-TEST_F(WifiChip_MultiIfaceTest, Create3Sta) {
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_FALSE(createIface(IfaceType::STA).empty());
-    ASSERT_TRUE(createIface(IfaceType::STA).empty());
-}
-
-TEST_F(WifiChip_MultiIfaceTest, CreateStaWithDefaultNames) {
-    property_set("wifi.interface.0", "");
-    property_set("wifi.interface.1", "");
-    property_set("wifi.interface.2", "");
-    property_set("wifi.interface", "");
-    property_set("wifi.concurrent.interface", "");
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
-}
-
-TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomNames) {
-    property_set("wifi.interface.0", "test0");
-    property_set("wifi.interface.1", "test1");
-    property_set("wifi.interface.2", "test2");
-    property_set("wifi.interface", "bad0");
-    property_set("wifi.concurrent.interface", "bad1");
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "bad0");
-    ASSERT_EQ(createIface(IfaceType::STA), "bad1");
-    ASSERT_EQ(createIface(IfaceType::STA), "test2");
-}
-
-TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomAltNames) {
-    property_set("wifi.interface.0", "");
-    property_set("wifi.interface.1", "");
-    property_set("wifi.interface.2", "");
-    property_set("wifi.interface", "testA0");
-    property_set("wifi.concurrent.interface", "testA1");
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    ASSERT_EQ(createIface(IfaceType::STA), "testA0");
-    ASSERT_EQ(createIface(IfaceType::STA), "testA1");
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
-}
-
-TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) {
-    // WifiChip_MultiIfaceTest iface combo: STAx3 + APx1
-    // When the HAL support dual STAs, AP should start with idx 2.
-    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
-    // First AP will be slotted to wlan1.
-    ASSERT_EQ(createIface(IfaceType::AP), "wlan2");
-    // First STA will be slotted to wlan0.
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-    // All further STA will be slotted to the remaining free indices.
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
-    ASSERT_EQ(createIface(IfaceType::STA), "wlan3");
-}
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp
deleted file mode 100644
index cc9a334..0000000
--- a/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <gmock/gmock.h>
-
-#undef NAN
-#include "wifi_iface_util.h"
-
-#include "mock_interface_tool.h"
-#include "mock_wifi_legacy_hal.h"
-
-using testing::NiceMock;
-using testing::Test;
-
-namespace {
-constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02;
-constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc};
-constexpr char kIfaceName[] = "test-wlan0";
-
-bool isValidUnicastLocallyAssignedMacAddress(const std::array<uint8_t, 6>& mac_address) {
-    uint8_t first_byte = mac_address[0];
-    return (first_byte & 0x3) == kValidUnicastLocallyAssignedMacAddressMask;
-}
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace iface_util {
-class WifiIfaceUtilTest : public Test {
-  protected:
-    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
-            new NiceMock<wifi_system::MockInterfaceTool>};
-    legacy_hal::wifi_hal_fn fake_func_table_;
-    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
-            new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
-    WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_);
-};
-
-TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) {
-    auto mac_address = iface_util_->getOrCreateRandomMacAddress();
-    ASSERT_TRUE(isValidUnicastLocallyAssignedMacAddress(mac_address));
-
-    // All further calls should return the same MAC address.
-    ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
-    ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
-}
-
-TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) {
-    std::array<uint8_t, 6> mac_address = {};
-    std::copy(std::begin(kMacAddress), std::end(kMacAddress), std::begin(mac_address));
-    EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_))
-            .WillRepeatedly(testing::Return(true));
-    EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_))
-            .WillRepeatedly(testing::Return(true));
-
-    // Register for iface state toggle events.
-    bool callback_invoked = false;
-    iface_util::IfaceEventHandlers event_handlers = {};
-    event_handlers.on_state_toggle_off_on =
-            [&callback_invoked](const std::string& /* iface_name */) { callback_invoked = true; };
-    iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers);
-    // Invoke setMacAddress and ensure that the cb is invoked.
-    ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
-    ASSERT_TRUE(callback_invoked);
-
-    // Unregister for iface state toggle events.
-    callback_invoked = false;
-    iface_util_->unregisterIfaceEventHandlers(kIfaceName);
-    // Invoke setMacAddress and ensure that the cb is not invoked.
-    ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
-    ASSERT_FALSE(callback_invoked);
-}
-}  // namespace iface_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp
deleted file mode 100644
index 8a5ddcd..0000000
--- a/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <cutils/properties.h>
-#include <gmock/gmock.h>
-
-#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
-#include "wifi_nan_iface.h"
-
-#include "mock_interface_tool.h"
-#include "mock_wifi_feature_flags.h"
-#include "mock_wifi_iface_util.h"
-#include "mock_wifi_legacy_hal.h"
-
-using testing::NiceMock;
-using testing::Return;
-using testing::Test;
-
-namespace {
-constexpr char kIfaceName[] = "mockWlan0";
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-
-using android::hardware::wifi::V1_2::NanDataPathConfirmInd;
-
-bool CaptureIfaceEventHandlers(const std::string& /* iface_name*/,
-                               iface_util::IfaceEventHandlers in_iface_event_handlers,
-                               iface_util::IfaceEventHandlers* out_iface_event_handlers) {
-    *out_iface_event_handlers = in_iface_event_handlers;
-    return true;
-}
-
-class MockNanIfaceEventCallback : public V1_5::IWifiNanIfaceEventCallback {
-  public:
-    MockNanIfaceEventCallback() = default;
-
-    MOCK_METHOD3(notifyCapabilitiesResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&,
-                              const android::hardware::wifi::V1_0::NanCapabilities&));
-    MOCK_METHOD2(notifyEnableResponse, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyConfigResponse, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyDisableResponse, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD3(notifyStartPublishResponse, Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
-    MOCK_METHOD2(notifyStopPublishResponse, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD3(notifyStartSubscribeResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
-    MOCK_METHOD2(notifyStopSubscribeResponse, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyTransmitFollowupResponse, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyCreateDataInterfaceResponse, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyDeleteDataInterfaceResponse, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD3(notifyInitiateDataPathResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&, uint32_t));
-    MOCK_METHOD2(notifyRespondToDataPathIndicationResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyTerminateDataPathResponse, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD1(eventClusterEvent, Return<void>(const NanClusterEventInd&));
-    MOCK_METHOD1(eventDisabled, Return<void>(const WifiNanStatus&));
-    MOCK_METHOD2(eventPublishTerminated, Return<void>(uint8_t, const WifiNanStatus&));
-    MOCK_METHOD2(eventSubscribeTerminated, Return<void>(uint8_t, const WifiNanStatus&));
-    MOCK_METHOD1(eventMatch, Return<void>(const V1_0::NanMatchInd&));
-    MOCK_METHOD1(eventMatch_1_6, Return<void>(const NanMatchInd&));
-    MOCK_METHOD2(eventMatchExpired, Return<void>(uint8_t, uint32_t));
-    MOCK_METHOD1(eventFollowupReceived, Return<void>(const NanFollowupReceivedInd&));
-    MOCK_METHOD2(eventTransmitFollowup, Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD1(eventDataPathRequest, Return<void>(const NanDataPathRequestInd&));
-    MOCK_METHOD1(eventDataPathConfirm,
-                 Return<void>(const android::hardware::wifi::V1_0::NanDataPathConfirmInd&));
-    MOCK_METHOD1(eventDataPathTerminated, Return<void>(uint32_t));
-    MOCK_METHOD1(eventDataPathConfirm_1_2,
-                 Return<void>(const android::hardware::wifi::V1_2::NanDataPathConfirmInd&));
-    MOCK_METHOD1(eventDataPathConfirm_1_6, Return<void>(const NanDataPathConfirmInd&));
-    MOCK_METHOD1(eventDataPathScheduleUpdate,
-                 Return<void>(const android::hardware::wifi::V1_2::NanDataPathScheduleUpdateInd&));
-    MOCK_METHOD1(eventDataPathScheduleUpdate_1_6,
-                 Return<void>(const NanDataPathScheduleUpdateInd&));
-    MOCK_METHOD3(notifyCapabilitiesResponse_1_5,
-                 Return<void>(uint16_t, const WifiNanStatus&, const V1_5::NanCapabilities&));
-};
-
-class WifiNanIfaceTest : public Test {
-  protected:
-    legacy_hal::wifi_hal_fn fake_func_table_;
-    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
-            new NiceMock<wifi_system::MockInterfaceTool>};
-    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
-            new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
-    std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
-            new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
-};
-
-TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
-    iface_util::IfaceEventHandlers captured_iface_event_handlers = {};
-    EXPECT_CALL(*legacy_hal_, nanRegisterCallbackHandlers(testing::_, testing::_))
-            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
-    EXPECT_CALL(*iface_util_, registerIfaceEventHandlers(testing::_, testing::_))
-            .WillOnce(testing::Invoke(bind(CaptureIfaceEventHandlers, std::placeholders::_1,
-                                           std::placeholders::_2, &captured_iface_event_handlers)));
-    sp<WifiNanIface> nan_iface = new WifiNanIface(kIfaceName, false, legacy_hal_, iface_util_);
-
-    // Register a mock nan event callback.
-    sp<NiceMock<MockNanIfaceEventCallback>> mock_event_callback{
-            new NiceMock<MockNanIfaceEventCallback>};
-    nan_iface->registerEventCallback(mock_event_callback, [](const WifiStatus& status) {
-        ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-    });
-    // Ensure that the eventDisabled() function in mock callback will be
-    // invoked.
-    WifiNanStatus expected_nan_status = {NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
-    EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status)).Times(1);
-
-    // Trigger the iface state toggle callback.
-    captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName);
-}
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi.cpp b/wifi/1.6/default/wifi.cpp
deleted file mode 100644
index c302ce2..0000000
--- a/wifi/1.6/default/wifi.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2016 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 "hidl_return_util.h"
-#include "wifi.h"
-#include "wifi_status_util.h"
-
-namespace {
-// Starting Chip ID, will be assigned to primary chip
-static constexpr android::hardware::wifi::V1_0::ChipId kPrimaryChipId = 0;
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-using hidl_return_util::validateAndCallWithLock;
-
-Wifi::Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
-           const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
-           const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
-           const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
-    : iface_tool_(iface_tool),
-      legacy_hal_factory_(legacy_hal_factory),
-      mode_controller_(mode_controller),
-      feature_flags_(feature_flags),
-      run_state_(RunState::STOPPED) {}
-
-bool Wifi::isValid() {
-    // This object is always valid.
-    return true;
-}
-
-Return<void> Wifi::registerEventCallback(const sp<V1_0::IWifiEventCallback>& event_callback,
-                                         registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
-                           &Wifi::registerEventCallbackInternal, hidl_status_cb, event_callback);
-}
-
-Return<void> Wifi::registerEventCallback_1_5(const sp<V1_5::IWifiEventCallback>& event_callback,
-                                             registerEventCallback_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
-                           &Wifi::registerEventCallbackInternal_1_5, hidl_status_cb,
-                           event_callback);
-}
-
-Return<bool> Wifi::isStarted() {
-    return run_state_ != RunState::STOPPED;
-}
-
-Return<void> Wifi::start(start_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal,
-                           hidl_status_cb);
-}
-
-Return<void> Wifi::stop(stop_cb hidl_status_cb) {
-    return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal,
-                                   hidl_status_cb);
-}
-
-Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipIdsInternal,
-                           hidl_status_cb);
-}
-
-Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipInternal,
-                           hidl_status_cb, chip_id);
-}
-
-Return<void> Wifi::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
-    LOG(INFO) << "-----------Debug is called----------------";
-    if (chips_.size() == 0) {
-        return Void();
-    }
-
-    for (sp<WifiChip> chip : chips_) {
-        if (!chip.get()) continue;
-
-        chip->debug(handle, {});
-    }
-    return Void();
-}
-
-WifiStatus Wifi::registerEventCallbackInternal(
-        const sp<V1_0::IWifiEventCallback>& event_callback __unused) {
-    // Deprecated support for this callback.
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus Wifi::registerEventCallbackInternal_1_5(
-        const sp<V1_5::IWifiEventCallback>& event_callback) {
-    if (!event_cb_handler_.addCallback(event_callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus Wifi::startInternal() {
-    if (run_state_ == RunState::STARTED) {
-        return createWifiStatus(WifiStatusCode::SUCCESS);
-    } else if (run_state_ == RunState::STOPPING) {
-        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
-    }
-    WifiStatus wifi_status = initializeModeControllerAndLegacyHal();
-    if (wifi_status.code == WifiStatusCode::SUCCESS) {
-        // Register the callback for subsystem restart
-        const auto& on_subsystem_restart_callback = [this](const std::string& error) {
-            WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
-            for (const auto& callback : event_cb_handler_.getCallbacks()) {
-                LOG(INFO) << "Attempting to invoke onSubsystemRestart "
-                             "callback";
-                if (!callback->onSubsystemRestart(wifi_status).isOk()) {
-                    LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
-                } else {
-                    LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
-                                 "callback";
-                }
-            }
-        };
-
-        // Create the chip instance once the HAL is started.
-        android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId;
-        for (auto& hal : legacy_hals_) {
-            chips_.push_back(
-                    new WifiChip(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
-                                 std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
-                                 feature_flags_, on_subsystem_restart_callback));
-            chipId++;
-        }
-        run_state_ = RunState::STARTED;
-        for (const auto& callback : event_cb_handler_.getCallbacks()) {
-            if (!callback->onStart().isOk()) {
-                LOG(ERROR) << "Failed to invoke onStart callback";
-            };
-        }
-        LOG(INFO) << "Wifi HAL started";
-    } else {
-        for (const auto& callback : event_cb_handler_.getCallbacks()) {
-            if (!callback->onFailure(wifi_status).isOk()) {
-                LOG(ERROR) << "Failed to invoke onFailure callback";
-            }
-        }
-        LOG(ERROR) << "Wifi HAL start failed";
-        // Clear the event callback objects since the HAL start failed.
-        event_cb_handler_.invalidate();
-    }
-    return wifi_status;
-}
-
-WifiStatus Wifi::stopInternal(
-        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
-    if (run_state_ == RunState::STOPPED) {
-        return createWifiStatus(WifiStatusCode::SUCCESS);
-    } else if (run_state_ == RunState::STOPPING) {
-        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
-    }
-    // Clear the chip object and its child objects since the HAL is now
-    // stopped.
-    for (auto& chip : chips_) {
-        if (chip.get()) {
-            chip->invalidate();
-            chip.clear();
-        }
-    }
-    chips_.clear();
-    WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock);
-    if (wifi_status.code == WifiStatusCode::SUCCESS) {
-        for (const auto& callback : event_cb_handler_.getCallbacks()) {
-            if (!callback->onStop().isOk()) {
-                LOG(ERROR) << "Failed to invoke onStop callback";
-            };
-        }
-        LOG(INFO) << "Wifi HAL stopped";
-    } else {
-        for (const auto& callback : event_cb_handler_.getCallbacks()) {
-            if (!callback->onFailure(wifi_status).isOk()) {
-                LOG(ERROR) << "Failed to invoke onFailure callback";
-            }
-        }
-        LOG(ERROR) << "Wifi HAL stop failed";
-    }
-    // Clear the event callback objects since the HAL is now stopped.
-    event_cb_handler_.invalidate();
-    return wifi_status;
-}
-
-std::pair<WifiStatus, std::vector<ChipId>> Wifi::getChipIdsInternal() {
-    std::vector<ChipId> chip_ids;
-
-    for (auto& chip : chips_) {
-        ChipId chip_id = getChipIdFromWifiChip(chip);
-        if (chip_id != UINT32_MAX) chip_ids.emplace_back(chip_id);
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)};
-}
-
-std::pair<WifiStatus, sp<V1_4::IWifiChip>> Wifi::getChipInternal(ChipId chip_id) {
-    for (auto& chip : chips_) {
-        ChipId cand_id = getChipIdFromWifiChip(chip);
-        if ((cand_id != UINT32_MAX) && (cand_id == chip_id))
-            return {createWifiStatus(WifiStatusCode::SUCCESS), chip};
-    }
-
-    return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
-}
-
-WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
-    if (!mode_controller_->initialize()) {
-        LOG(ERROR) << "Failed to initialize firmware mode controller";
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-
-    legacy_hals_ = legacy_hal_factory_->getHals();
-    if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    int index = 0;  // for failure log
-    for (auto& hal : legacy_hals_) {
-        legacy_hal::wifi_error legacy_status = hal->initialize();
-        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-            // Currently WifiLegacyHal::initialize does not allocate extra mem,
-            // only initializes the function table. If this changes, need to
-            // implement WifiLegacyHal::deinitialize and deinitalize the
-            // HALs already initialized
-            LOG(ERROR) << "Failed to initialize legacy HAL index: " << index
-                       << " error: " << legacyErrorToString(legacy_status);
-            return createWifiStatusFromLegacyError(legacy_status);
-        }
-        index++;
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController(
-        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
-    legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS;
-    int index = 0;
-
-    run_state_ = RunState::STOPPING;
-    for (auto& hal : legacy_hals_) {
-        legacy_hal::wifi_error tmp = hal->stop(lock, [&]() {});
-        if (tmp != legacy_hal::WIFI_SUCCESS) {
-            LOG(ERROR) << "Failed to stop legacy HAL index: " << index
-                       << " error: " << legacyErrorToString(legacy_status);
-            legacy_status = tmp;
-        }
-        index++;
-    }
-    run_state_ = RunState::STOPPED;
-
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "One or more legacy HALs failed to stop";
-        return createWifiStatusFromLegacyError(legacy_status);
-    }
-    if (!mode_controller_->deinitialize()) {
-        LOG(ERROR) << "Failed to deinitialize firmware mode controller";
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-ChipId Wifi::getChipIdFromWifiChip(sp<WifiChip>& chip) {
-    ChipId chip_id = UINT32_MAX;
-    if (chip.get()) {
-        chip->getId([&](WifiStatus status, uint32_t id) {
-            if (status.code == WifiStatusCode::SUCCESS) {
-                chip_id = id;
-            }
-        });
-    }
-
-    return chip_id;
-}
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi.h b/wifi/1.6/default/wifi.h
deleted file mode 100644
index 435358e..0000000
--- a/wifi/1.6/default/wifi.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_H_
-#define WIFI_H_
-
-// HACK: NAN is a macro defined in math.h, which can be included in various
-// headers. This wifi HAL uses an enum called NAN, which does not compile when
-// the macro is defined. Undefine NAN to work around it.
-#undef NAN
-#include <android/hardware/wifi/1.6/IWifi.h>
-
-#include <android-base/macros.h>
-#include <utils/Looper.h>
-#include <functional>
-
-#include "hidl_callback_util.h"
-#include "wifi_chip.h"
-#include "wifi_feature_flags.h"
-#include "wifi_legacy_hal.h"
-#include "wifi_legacy_hal_factory.h"
-#include "wifi_mode_controller.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-
-/**
- * Root HIDL interface object used to control the Wifi HAL.
- */
-class Wifi : public V1_6::IWifi {
-  public:
-    Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
-         const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
-         const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
-         const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
-
-    bool isValid();
-
-    // HIDL methods exposed.
-    Return<void> registerEventCallback(const sp<V1_0::IWifiEventCallback>& event_callback,
-                                       registerEventCallback_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_5(const sp<V1_5::IWifiEventCallback>& event_callback,
-                                           registerEventCallback_1_5_cb hidl_status_cb) override;
-    Return<bool> isStarted() override;
-    Return<void> start(start_cb hidl_status_cb) override;
-    Return<void> stop(stop_cb hidl_status_cb) override;
-    Return<void> getChipIds(getChipIds_cb hidl_status_cb) override;
-    Return<void> getChip(ChipId chip_id, getChip_cb hidl_status_cb) override;
-    Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override;
-
-  private:
-    enum class RunState { STOPPED, STARTED, STOPPING };
-
-    // Corresponding worker functions for the HIDL methods.
-    WifiStatus registerEventCallbackInternal(
-            const sp<V1_0::IWifiEventCallback>& event_callback __unused);
-    WifiStatus registerEventCallbackInternal_1_5(
-            const sp<V1_5::IWifiEventCallback>& event_callback);
-    WifiStatus startInternal();
-    WifiStatus stopInternal(std::unique_lock<std::recursive_mutex>* lock);
-    std::pair<WifiStatus, std::vector<ChipId>> getChipIdsInternal();
-    std::pair<WifiStatus, sp<V1_4::IWifiChip>> getChipInternal(ChipId chip_id);
-
-    WifiStatus initializeModeControllerAndLegacyHal();
-    WifiStatus stopLegacyHalAndDeinitializeModeController(
-            std::unique_lock<std::recursive_mutex>* lock);
-    ChipId getChipIdFromWifiChip(sp<WifiChip>& chip);
-
-    // Instance is created in this root level |IWifi| HIDL interface object
-    // and shared with all the child HIDL interface objects.
-    std::shared_ptr<wifi_system::InterfaceTool> iface_tool_;
-    std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory_;
-    std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
-    std::vector<std::shared_ptr<legacy_hal::WifiLegacyHal>> legacy_hals_;
-    std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
-    RunState run_state_;
-    std::vector<sp<WifiChip>> chips_;
-    hidl_callback_util::HidlCallbackHandler<V1_5::IWifiEventCallback> event_cb_handler_;
-
-    DISALLOW_COPY_AND_ASSIGN(Wifi);
-};
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_H_
diff --git a/wifi/1.6/default/wifi_ap_iface.cpp b/wifi/1.6/default/wifi_ap_iface.cpp
deleted file mode 100644
index b2957db..0000000
--- a/wifi/1.6/default/wifi_ap_iface.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2016 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 "hidl_return_util.h"
-#include "hidl_struct_util.h"
-#include "wifi_ap_iface.h"
-#include "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-WifiApIface::WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
-                         const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-                         const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
-    : ifname_(ifname),
-      instances_(instances),
-      legacy_hal_(legacy_hal),
-      iface_util_(iface_util),
-      is_valid_(true) {}
-
-void WifiApIface::invalidate() {
-    legacy_hal_.reset();
-    is_valid_ = false;
-}
-
-bool WifiApIface::isValid() {
-    return is_valid_;
-}
-
-std::string WifiApIface::getName() {
-    return ifname_;
-}
-
-void WifiApIface::removeInstance(std::string instance) {
-    instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end());
-}
-
-Return<void> WifiApIface::getName(getName_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::getNameInternal, hidl_status_cb);
-}
-
-Return<void> WifiApIface::getType(getType_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::getTypeInternal, hidl_status_cb);
-}
-
-Return<void> WifiApIface::setCountryCode(const hidl_array<int8_t, 2>& code,
-                                         setCountryCode_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::setCountryCodeInternal, hidl_status_cb, code);
-}
-
-Return<void> WifiApIface::getValidFrequenciesForBand(V1_0::WifiBand band,
-                                                     getValidFrequenciesForBand_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::getValidFrequenciesForBandInternal, hidl_status_cb, band);
-}
-
-Return<void> WifiApIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
-                                        setMacAddress_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::setMacAddressInternal, hidl_status_cb, mac);
-}
-
-Return<void> WifiApIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::getFactoryMacAddressInternal, hidl_status_cb,
-                           instances_.size() > 0 ? instances_[0] : ifname_);
-}
-
-Return<void> WifiApIface::resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::resetToFactoryMacAddressInternal, hidl_status_cb);
-}
-
-Return<void> WifiApIface::getBridgedInstances(getBridgedInstances_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::getBridgedInstancesInternal, hidl_status_cb);
-}
-
-std::pair<WifiStatus, std::string> WifiApIface::getNameInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
-}
-
-std::pair<WifiStatus, IfaceType> WifiApIface::getTypeInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::AP};
-}
-
-WifiStatus WifiApIface::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode(
-            instances_.size() > 0 ? instances_[0] : ifname_, code);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
-WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
-    static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch");
-    legacy_hal::wifi_error legacy_status;
-    std::vector<uint32_t> valid_frequencies;
-    std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand(
-            instances_.size() > 0 ? instances_[0] : ifname_,
-            hidl_struct_util::convertHidlWifiBandToLegacy(band));
-    return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
-}
-
-WifiStatus WifiApIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
-    // Support random MAC up to 2 interfaces
-    if (instances_.size() == 2) {
-        int rbyte = 1;
-        for (auto const& intf : instances_) {
-            std::array<uint8_t, 6> rmac = mac;
-            // reverse the bits to avoid collision
-            rmac[rbyte] = 0xff - rmac[rbyte];
-            if (!iface_util_.lock()->setMacAddress(intf, rmac)) {
-                LOG(INFO) << "Failed to set random mac address on " << intf;
-                return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-            }
-            rbyte++;
-        }
-    }
-    // It also needs to set mac address for bridged interface, otherwise the mac
-    // address of bridged interface will be changed after one of instance
-    // down.
-    if (!iface_util_.lock()->setMacAddress(ifname_, mac)) {
-        LOG(ERROR) << "Fail to config MAC for interface " << ifname_;
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, std::array<uint8_t, 6>> WifiApIface::getFactoryMacAddressInternal(
-        const std::string& ifaceName) {
-    std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifaceName);
-    if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
-}
-
-WifiStatus WifiApIface::resetToFactoryMacAddressInternal() {
-    std::pair<WifiStatus, std::array<uint8_t, 6>> getMacResult;
-    if (instances_.size() == 2) {
-        for (auto const& intf : instances_) {
-            getMacResult = getFactoryMacAddressInternal(intf);
-            LOG(DEBUG) << "Reset MAC to factory MAC on " << intf;
-            if (getMacResult.first.code != WifiStatusCode::SUCCESS ||
-                !iface_util_.lock()->setMacAddress(intf, getMacResult.second)) {
-                return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-            }
-        }
-        // It needs to set mac address for bridged interface, otherwise the mac
-        // address of the bridged interface will be changed after one of the
-        // instance down. Thus we are generating a random MAC address for the
-        // bridged interface even if we got the request to reset the Factory
-        // MAC. Since the bridged interface is an internal interface for the
-        // operation of bpf and others networking operation.
-        if (!iface_util_.lock()->setMacAddress(ifname_,
-                                               iface_util_.lock()->createRandomMacAddress())) {
-            LOG(ERROR) << "Fail to config MAC for bridged interface " << ifname_;
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-        }
-    } else {
-        getMacResult = getFactoryMacAddressInternal(ifname_);
-        LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_;
-        if (getMacResult.first.code != WifiStatusCode::SUCCESS ||
-            !iface_util_.lock()->setMacAddress(ifname_, getMacResult.second)) {
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-        }
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, std::vector<hidl_string>> WifiApIface::getBridgedInstancesInternal() {
-    std::vector<hidl_string> instances;
-    for (const auto& instance_name : instances_) {
-        instances.push_back(instance_name);
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), instances};
-}
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_ap_iface.h b/wifi/1.6/default/wifi_ap_iface.h
deleted file mode 100644
index d1c0642..0000000
--- a/wifi/1.6/default/wifi_ap_iface.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_AP_IFACE_H_
-#define WIFI_AP_IFACE_H_
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.5/IWifiApIface.h>
-
-#include "wifi_iface_util.h"
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-
-/**
- * HIDL interface object used to control a AP Iface instance.
- */
-class WifiApIface : public V1_5::IWifiApIface {
-  public:
-    WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
-                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-                const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
-    // Refer to |WifiChip::invalidate()|.
-    void invalidate();
-    bool isValid();
-    std::string getName();
-    void removeInstance(std::string instance);
-
-    // HIDL methods exposed.
-    Return<void> getName(getName_cb hidl_status_cb) override;
-    Return<void> getType(getType_cb hidl_status_cb) override;
-    Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
-                                setCountryCode_cb hidl_status_cb) override;
-    Return<void> getValidFrequenciesForBand(V1_0::WifiBand band,
-                                            getValidFrequenciesForBand_cb hidl_status_cb) override;
-    Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
-                               setMacAddress_cb hidl_status_cb) override;
-    Return<void> getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override;
-    Return<void> resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) override;
-
-    Return<void> getBridgedInstances(getBridgedInstances_cb hidl_status_cb) override;
-
-  private:
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, std::string> getNameInternal();
-    std::pair<WifiStatus, IfaceType> getTypeInternal();
-    WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
-    std::pair<WifiStatus, std::vector<WifiChannelInMhz>> getValidFrequenciesForBandInternal(
-            V1_0::WifiBand band);
-    WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
-    std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal(
-            const std::string& ifaceName);
-    WifiStatus resetToFactoryMacAddressInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>> getBridgedInstancesInternal();
-
-    std::string ifname_;
-    std::vector<std::string> instances_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
-    bool is_valid_;
-
-    DISALLOW_COPY_AND_ASSIGN(WifiApIface);
-};
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_AP_IFACE_H_
diff --git a/wifi/1.6/default/wifi_chip.cpp b/wifi/1.6/default/wifi_chip.cpp
deleted file mode 100644
index c7c00b1..0000000
--- a/wifi/1.6/default/wifi_chip.cpp
+++ /dev/null
@@ -1,2061 +0,0 @@
-/*
- * Copyright (C) 2016 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 <fcntl.h>
-
-#include <android-base/logging.h>
-#include <android-base/unique_fd.h>
-#include <cutils/properties.h>
-#include <net/if.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-
-#include "hidl_return_util.h"
-#include "hidl_struct_util.h"
-#include "wifi_chip.h"
-#include "wifi_status_util.h"
-
-#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
-
-namespace {
-using android::sp;
-using android::base::unique_fd;
-using android::hardware::hidl_string;
-using android::hardware::hidl_vec;
-using android::hardware::wifi::V1_0::ChipModeId;
-using android::hardware::wifi::V1_0::IfaceType;
-using android::hardware::wifi::V1_0::IWifiChip;
-
-constexpr char kCpioMagic[] = "070701";
-constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
-constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
-constexpr uint32_t kMaxRingBufferFileNum = 20;
-constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
-constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
-constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
-constexpr unsigned kMaxWlanIfaces = 5;
-constexpr char kApBridgeIfacePrefix[] = "ap_br_";
-
-template <typename Iface>
-void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
-    iface->invalidate();
-    ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end());
-}
-
-template <typename Iface>
-void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
-    for (const auto& iface : ifaces) {
-        iface->invalidate();
-    }
-    ifaces.clear();
-}
-
-template <typename Iface>
-std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
-    std::vector<hidl_string> names;
-    for (const auto& iface : ifaces) {
-        names.emplace_back(iface->getName());
-    }
-    return names;
-}
-
-template <typename Iface>
-sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces, const std::string& name) {
-    std::vector<hidl_string> names;
-    for (const auto& iface : ifaces) {
-        if (name == iface->getName()) {
-            return iface;
-        }
-    }
-    return nullptr;
-}
-
-std::string getWlanIfaceName(unsigned idx) {
-    if (idx >= kMaxWlanIfaces) {
-        CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
-        return {};
-    }
-
-    std::array<char, PROPERTY_VALUE_MAX> buffer;
-    if (idx == 0 || idx == 1) {
-        const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
-        auto res = property_get(altPropName, buffer.data(), nullptr);
-        if (res > 0) return buffer.data();
-    }
-    std::string propName = "wifi.interface." + std::to_string(idx);
-    auto res = property_get(propName.c_str(), buffer.data(), nullptr);
-    if (res > 0) return buffer.data();
-
-    return "wlan" + std::to_string(idx);
-}
-
-// Returns the dedicated iface name if defined.
-// Returns two ifaces in bridged mode.
-std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
-    std::vector<std::string> ifnames;
-    std::array<char, PROPERTY_VALUE_MAX> buffer;
-    buffer.fill(0);
-    if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) {
-        return ifnames;
-    }
-    ifnames.push_back(buffer.data());
-    if (is_bridged) {
-        buffer.fill(0);
-        if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) {
-            return ifnames;
-        }
-        ifnames.push_back(buffer.data());
-    }
-    return ifnames;
-}
-
-std::string getPredefinedP2pIfaceName() {
-    std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
-    char p2pParentIfname[100];
-    std::string p2pDevIfName = "";
-    std::array<char, PROPERTY_VALUE_MAX> buffer;
-    property_get("wifi.direct.interface", buffer.data(), "p2p0");
-    if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
-        /* Get the p2p parent interface name from p2p device interface name set
-         * in property */
-        strlcpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
-                strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
-        if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) {
-            return buffer.data();
-        }
-        /* Check if the parent interface derived from p2p device interface name
-         * is active */
-        if (strncmp(p2pParentIfname, primaryIfaceName.data(),
-                    strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) {
-            /*
-             * Update the predefined p2p device interface parent interface name
-             * with current active wlan interface
-             */
-            p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
-            p2pDevIfName += primaryIfaceName.data();
-            LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str();
-            return p2pDevIfName;
-        }
-    }
-    return buffer.data();
-}
-
-// Returns the dedicated iface name if one is defined.
-std::string getPredefinedNanIfaceName() {
-    std::array<char, PROPERTY_VALUE_MAX> buffer;
-    if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
-        return {};
-    }
-    return buffer.data();
-}
-
-void setActiveWlanIfaceNameProperty(const std::string& ifname) {
-    auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
-    if (res != 0) {
-        PLOG(ERROR) << "Failed to set active wlan iface name property";
-    }
-}
-
-// delete files that meet either conditions:
-// 1. older than a predefined time in the wifi tombstone dir.
-// 2. Files in excess to a predefined amount, starting from the oldest ones
-bool removeOldFilesInternal() {
-    time_t now = time(0);
-    const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
-    std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir);
-    if (!dir_dump) {
-        PLOG(ERROR) << "Failed to open directory";
-        return false;
-    }
-    struct dirent* dp;
-    bool success = true;
-    std::list<std::pair<const time_t, std::string>> valid_files;
-    while ((dp = readdir(dir_dump.get()))) {
-        if (dp->d_type != DT_REG) {
-            continue;
-        }
-        std::string cur_file_name(dp->d_name);
-        struct stat cur_file_stat;
-        std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
-        if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
-            PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
-            success = false;
-            continue;
-        }
-        const time_t cur_file_time = cur_file_stat.st_mtime;
-        valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
-    }
-    valid_files.sort();  // sort the list of files by last modified time from
-                         // small to big.
-    uint32_t cur_file_count = valid_files.size();
-    for (auto cur_file : valid_files) {
-        if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) {
-            if (unlink(cur_file.second.c_str()) != 0) {
-                PLOG(ERROR) << "Error deleting file";
-                success = false;
-            }
-            cur_file_count--;
-        } else {
-            break;
-        }
-    }
-    return success;
-}
-
-// Helper function for |cpioArchiveFilesInDir|
-bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) {
-    const int buf_size = 32 * 1024;
-    std::array<char, buf_size> read_buf;
-    ssize_t llen = snprintf(
-            read_buf.data(), buf_size, "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
-            kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, st.st_gid,
-            static_cast<int>(st.st_nlink), static_cast<int>(st.st_mtime),
-            static_cast<int>(st.st_size), major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
-            minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
-    if (write(out_fd, read_buf.data(), llen < buf_size ? llen : buf_size - 1) == -1) {
-        PLOG(ERROR) << "Error writing cpio header to file " << file_name;
-        return false;
-    }
-    if (write(out_fd, file_name, file_name_len) == -1) {
-        PLOG(ERROR) << "Error writing filename to file " << file_name;
-        return false;
-    }
-
-    // NUL Pad header up to 4 multiple bytes.
-    llen = (llen + file_name_len) % 4;
-    if (llen != 0) {
-        const uint32_t zero = 0;
-        if (write(out_fd, &zero, 4 - llen) == -1) {
-            PLOG(ERROR) << "Error padding 0s to file " << file_name;
-            return false;
-        }
-    }
-    return true;
-}
-
-// Helper function for |cpioArchiveFilesInDir|
-size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) {
-    // writing content of file
-    std::array<char, 32 * 1024> read_buf;
-    ssize_t llen = st.st_size;
-    size_t n_error = 0;
-    while (llen > 0) {
-        ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
-        if (bytes_read == -1) {
-            PLOG(ERROR) << "Error reading file";
-            return ++n_error;
-        }
-        llen -= bytes_read;
-        if (write(out_fd, read_buf.data(), bytes_read) == -1) {
-            PLOG(ERROR) << "Error writing data to file";
-            return ++n_error;
-        }
-        if (bytes_read == 0) {  // this should never happen, but just in case
-                                // to unstuck from while loop
-            PLOG(ERROR) << "Unexpected read result";
-            n_error++;
-            break;
-        }
-    }
-    llen = st.st_size % 4;
-    if (llen != 0) {
-        const uint32_t zero = 0;
-        if (write(out_fd, &zero, 4 - llen) == -1) {
-            PLOG(ERROR) << "Error padding 0s to file";
-            return ++n_error;
-        }
-    }
-    return n_error;
-}
-
-// Helper function for |cpioArchiveFilesInDir|
-bool cpioWriteFileTrailer(int out_fd) {
-    const int buf_size = 4096;
-    std::array<char, buf_size> read_buf;
-    read_buf.fill(0);
-    ssize_t llen = snprintf(read_buf.data(), 4096, "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0);
-    if (write(out_fd, read_buf.data(), (llen < buf_size ? llen : buf_size - 1) + 4) == -1) {
-        PLOG(ERROR) << "Error writing trailing bytes";
-        return false;
-    }
-    return true;
-}
-
-// Archives all files in |input_dir| and writes result into |out_fd|
-// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
-// portion
-size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
-    struct dirent* dp;
-    size_t n_error = 0;
-    std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), closedir);
-    if (!dir_dump) {
-        PLOG(ERROR) << "Failed to open directory";
-        return ++n_error;
-    }
-    while ((dp = readdir(dir_dump.get()))) {
-        if (dp->d_type != DT_REG) {
-            continue;
-        }
-        std::string cur_file_name(dp->d_name);
-        struct stat st;
-        const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
-        if (stat(cur_file_path.c_str(), &st) == -1) {
-            PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
-            n_error++;
-            continue;
-        }
-        const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
-        if (fd_read == -1) {
-            PLOG(ERROR) << "Failed to open file " << cur_file_path;
-            n_error++;
-            continue;
-        }
-        std::string file_name_with_last_modified_time =
-                cur_file_name + "-" + std::to_string(st.st_mtime);
-        // string.size() does not include the null terminator. The cpio FreeBSD
-        // file header expects the null character to be included in the length.
-        const size_t file_name_len = file_name_with_last_modified_time.size() + 1;
-        unique_fd file_auto_closer(fd_read);
-        if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(),
-                             file_name_len)) {
-            return ++n_error;
-        }
-        size_t write_error = cpioWriteFileContent(fd_read, out_fd, st);
-        if (write_error) {
-            return n_error + write_error;
-        }
-    }
-    if (!cpioWriteFileTrailer(out_fd)) {
-        return ++n_error;
-    }
-    return n_error;
-}
-
-// Helper function to create a non-const char*.
-std::vector<char> makeCharVec(const std::string& str) {
-    std::vector<char> vec(str.size() + 1);
-    vec.assign(str.begin(), str.end());
-    vec.push_back('\0');
-    return vec;
-}
-
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-using hidl_return_util::validateAndCallWithLock;
-
-WifiChip::WifiChip(ChipId chip_id, bool is_primary,
-                   const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-                   const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
-                   const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
-                   const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
-                   const std::function<void(const std::string&)>& handler)
-    : chip_id_(chip_id),
-      legacy_hal_(legacy_hal),
-      mode_controller_(mode_controller),
-      iface_util_(iface_util),
-      is_valid_(true),
-      current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
-      modes_(feature_flags.lock()->getChipModes(is_primary)),
-      debug_ring_buffer_cb_registered_(false),
-      subsystemCallbackHandler_(handler) {
-    setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
-}
-
-void WifiChip::invalidate() {
-    if (!writeRingbufferFilesInternal()) {
-        LOG(ERROR) << "Error writing files to flash";
-    }
-    invalidateAndRemoveAllIfaces();
-    setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
-    legacy_hal_.reset();
-    event_cb_handler_.invalidate();
-    is_valid_ = false;
-}
-
-bool WifiChip::isValid() {
-    return is_valid_;
-}
-
-std::set<sp<V1_4::IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
-    return event_cb_handler_.getCallbacks();
-}
-
-Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal,
-                           hidl_status_cb);
-}
-
-// Deprecated support for this callback
-Return<void> WifiChip::registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback,
-                                             registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::registerEventCallbackInternal, hidl_status_cb,
-                           event_callback);
-}
-
-Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getCapabilitiesInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getAvailableModesInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) {
-    return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                                   &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
-}
-
-Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getModeInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::requestChipDebugInfoInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::requestDriverDebugDumpInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::requestFirmwareDebugDumpInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createApIfaceInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::createBridgedApIface(createBridgedApIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createBridgedApIfaceInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getApIfaceInternal, hidl_status_cb, ifname);
-}
-
-Return<void> WifiChip::removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::removeApIfaceInternal, hidl_status_cb, ifname);
-}
-
-Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface(
-        const hidl_string& ifname, const hidl_string& ifInstanceName,
-        removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, hidl_status_cb,
-                           ifname, ifInstanceName);
-}
-
-Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createNanIfaceInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getNanIfaceInternal, hidl_status_cb, ifname);
-}
-
-Return<void> WifiChip::removeNanIface(const hidl_string& ifname, removeNanIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::removeNanIfaceInternal, hidl_status_cb, ifname);
-}
-
-Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createP2pIfaceInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getP2pIfaceInternal, hidl_status_cb, ifname);
-}
-
-Return<void> WifiChip::removeP2pIface(const hidl_string& ifname, removeP2pIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::removeP2pIfaceInternal, hidl_status_cb, ifname);
-}
-
-Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createStaIfaceInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getStaIfaceInternal, hidl_status_cb, ifname);
-}
-
-Return<void> WifiChip::removeStaIface(const hidl_string& ifname, removeStaIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::removeStaIfaceInternal, hidl_status_cb, ifname);
-}
-
-Return<void> WifiChip::createRttController(const sp<IWifiIface>& bound_iface,
-                                           createRttController_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createRttControllerInternal, hidl_status_cb, bound_iface);
-}
-
-Return<void> WifiChip::getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getDebugRingBuffersStatusInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::startLoggingToDebugRingBuffer(
-        const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
-        uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
-        startLoggingToDebugRingBuffer_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::startLoggingToDebugRingBufferInternal, hidl_status_cb,
-                           ring_name, verbose_level, max_interval_in_sec, min_data_size_in_bytes);
-}
-
-Return<void> WifiChip::forceDumpToDebugRingBuffer(const hidl_string& ring_name,
-                                                  forceDumpToDebugRingBuffer_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::forceDumpToDebugRingBufferInternal, hidl_status_cb,
-                           ring_name);
-}
-
-Return<void> WifiChip::flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::flushRingBufferToFileInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::stopLoggingToDebugRingBuffer(
-        stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::stopLoggingToDebugRingBufferInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getDebugHostWakeReasonStatsInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::enableDebugErrorAlerts(bool enable,
-                                              enableDebugErrorAlerts_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::enableDebugErrorAlertsInternal, hidl_status_cb, enable);
-}
-
-Return<void> WifiChip::selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,
-                                             selectTxPowerScenario_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::selectTxPowerScenarioInternal, hidl_status_cb, scenario);
-}
-
-Return<void> WifiChip::resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::resetTxPowerScenarioInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::setLatencyModeInternal, hidl_status_cb, mode);
-}
-
-Return<void> WifiChip::registerEventCallback_1_2(
-        const sp<V1_2::IWifiChipEventCallback>& event_callback,
-        registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::registerEventCallbackInternal_1_2, hidl_status_cb,
-                           event_callback);
-}
-
-Return<void> WifiChip::selectTxPowerScenario_1_2(TxPowerScenario scenario,
-                                                 selectTxPowerScenario_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::selectTxPowerScenarioInternal_1_2, hidl_status_cb, scenario);
-}
-
-Return<void> WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getCapabilitiesInternal_1_3, hidl_status_cb);
-}
-
-Return<void> WifiChip::getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getCapabilitiesInternal_1_5, hidl_status_cb);
-}
-
-Return<void> WifiChip::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
-    if (handle != nullptr && handle->numFds >= 1) {
-        {
-            std::unique_lock<std::mutex> lk(lock_t);
-            for (const auto& item : ringbuffer_map_) {
-                forceDumpToDebugRingBufferInternal(item.first);
-            }
-            // unique_lock unlocked here
-        }
-        usleep(100 * 1000);  // sleep for 100 milliseconds to wait for
-                             // ringbuffer updates.
-        int fd = handle->data[0];
-        if (!writeRingbufferFilesInternal()) {
-            LOG(ERROR) << "Error writing files to flash";
-        }
-        uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath);
-        if (n_error != 0) {
-            LOG(ERROR) << n_error << " errors occured in cpio function";
-        }
-        fsync(fd);
-    } else {
-        LOG(ERROR) << "File handle error";
-    }
-    return Void();
-}
-
-Return<void> WifiChip::createRttController_1_4(const sp<IWifiIface>& bound_iface,
-                                               createRttController_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createRttControllerInternal_1_4, hidl_status_cb, bound_iface);
-}
-
-Return<void> WifiChip::registerEventCallback_1_4(
-        const sp<V1_4::IWifiChipEventCallback>& event_callback,
-        registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::registerEventCallbackInternal_1_4, hidl_status_cb,
-                           event_callback);
-}
-
-Return<void> WifiChip::setMultiStaPrimaryConnection(
-        const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::setMultiStaPrimaryConnectionInternal, hidl_status_cb, ifname);
-}
-
-Return<void> WifiChip::setMultiStaUseCase(MultiStaUseCase use_case,
-                                          setMultiStaUseCase_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::setMultiStaUseCaseInternal, hidl_status_cb, use_case);
-}
-
-Return<void> WifiChip::setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel>& unsafeChannels,
-                                             hidl_bitfield<CoexRestriction> restrictions,
-                                             setCoexUnsafeChannels_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::setCoexUnsafeChannelsInternal, hidl_status_cb, unsafeChannels,
-                           restrictions);
-}
-
-Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code,
-                                      setCountryCode_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiChip::setCountryCodeInternal, hidl_status_cb, code);
-}
-
-Return<void> WifiChip::getUsableChannels(
-        WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
-        hidl_bitfield<V1_5::IWifiChip::UsableChannelFilter> filterMask,
-        getUsableChannels_cb _hidl_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getUsableChannelsInternal, _hidl_cb, band, ifaceModeMask,
-                           filterMask);
-}
-
-Return<void> WifiChip::triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::triggerSubsystemRestartInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::createRttController_1_6(const sp<IWifiIface>& bound_iface,
-                                               createRttController_1_6_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createRttControllerInternal_1_6, hidl_status_cb, bound_iface);
-}
-
-Return<void> WifiChip::getUsableChannels_1_6(
-        WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
-        hidl_bitfield<V1_6::IWifiChip::UsableChannelFilter> filterMask,
-        getUsableChannels_1_6_cb _hidl_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getUsableChannelsInternal_1_6, _hidl_cb, band, ifaceModeMask,
-                           filterMask);
-}
-
-Return<void> WifiChip::getSupportedRadioCombinationsMatrix(
-        getSupportedRadioCombinationsMatrix_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getSupportedRadioCombinationsMatrixInternal, hidl_status_cb);
-}
-
-Return<void> WifiChip::getAvailableModes_1_6(getAvailableModes_1_6_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getAvailableModesInternal_1_6, hidl_status_cb);
-}
-
-void WifiChip::invalidateAndRemoveAllIfaces() {
-    invalidateAndClearBridgedApAll();
-    invalidateAndClearAll(ap_ifaces_);
-    invalidateAndClearAll(nan_ifaces_);
-    invalidateAndClearAll(p2p_ifaces_);
-    invalidateAndClearAll(sta_ifaces_);
-    // Since all the ifaces are invalid now, all RTT controller objects
-    // using those ifaces also need to be invalidated.
-    for (const auto& rtt : rtt_controllers_) {
-        rtt->invalidate();
-    }
-    rtt_controllers_.clear();
-}
-
-void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) {
-    for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
-        auto nan_iface = *it;
-        if (nan_iface->getName() == removed_iface_name) {
-            nan_iface->invalidate();
-            for (const auto& callback : event_cb_handler_.getCallbacks()) {
-                if (!callback->onIfaceRemoved(IfaceType::NAN, removed_iface_name).isOk()) {
-                    LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
-                }
-            }
-            it = nan_ifaces_.erase(it);
-        } else {
-            ++it;
-        }
-    }
-
-    for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
-        auto rtt = *it;
-        if (rtt->getIfaceName() == removed_iface_name) {
-            rtt->invalidate();
-            it = rtt_controllers_.erase(it);
-        } else {
-            ++it;
-        }
-    }
-}
-
-std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
-}
-
-WifiStatus WifiChip::registerEventCallbackInternal(
-        const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
-    // Deprecated support for this callback.
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
-    // Deprecated support for this callback.
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
-}
-
-std::pair<WifiStatus, std::vector<V1_0::IWifiChip::ChipMode>>
-WifiChip::getAvailableModesInternal() {
-    // Deprecated support -- use getAvailableModes_1_6 for more granular concurrency combinations.
-    std::vector<V1_0::IWifiChip::ChipMode> modes_1_0 = {};
-    for (const auto& mode_1_6 : modes_) {
-        std::vector<V1_0::IWifiChip::ChipIfaceCombination> combos_1_0;
-        for (const auto& combo_1_6 : mode_1_6.availableCombinations) {
-            std::vector<V1_0::IWifiChip::ChipIfaceCombinationLimit> limits_1_0;
-            for (const auto& limit_1_6 : combo_1_6.limits) {
-                std::vector<IfaceType> types_1_0;
-                for (IfaceConcurrencyType type_1_6 : limit_1_6.types) {
-                    switch (type_1_6) {
-                        case IfaceConcurrencyType::STA:
-                            types_1_0.push_back(IfaceType::STA);
-                            break;
-                        case IfaceConcurrencyType::AP:
-                            types_1_0.push_back(IfaceType::AP);
-                            break;
-                        case IfaceConcurrencyType::AP_BRIDGED:
-                            // Ignore AP_BRIDGED
-                            break;
-                        case IfaceConcurrencyType::P2P:
-                            types_1_0.push_back(IfaceType::P2P);
-                            break;
-                        case IfaceConcurrencyType::NAN:
-                            types_1_0.push_back(IfaceType::NAN);
-                            break;
-                    }
-                }
-                if (types_1_0.empty()) {
-                    continue;
-                }
-                V1_0::IWifiChip::ChipIfaceCombinationLimit limit_1_0;
-                limit_1_0.types = hidl_vec(types_1_0);
-                limit_1_0.maxIfaces = limit_1_6.maxIfaces;
-                limits_1_0.push_back(limit_1_0);
-            }
-            if (limits_1_0.empty()) {
-                continue;
-            }
-            V1_0::IWifiChip::ChipIfaceCombination combo_1_0;
-            combo_1_0.limits = hidl_vec(limits_1_0);
-            combos_1_0.push_back(combo_1_0);
-        }
-        if (combos_1_0.empty()) {
-            continue;
-        }
-        V1_0::IWifiChip::ChipMode mode_1_0;
-        mode_1_0.id = mode_1_6.id;
-        mode_1_0.availableCombinations = hidl_vec(combos_1_0);
-        modes_1_0.push_back(mode_1_0);
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), modes_1_0};
-}
-
-WifiStatus WifiChip::configureChipInternal(
-        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
-    if (!isValidModeId(mode_id)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    if (mode_id == current_mode_id_) {
-        LOG(DEBUG) << "Already in the specified mode " << mode_id;
-        return createWifiStatus(WifiStatusCode::SUCCESS);
-    }
-    WifiStatus status = handleChipConfiguration(lock, mode_id);
-    if (status.code != WifiStatusCode::SUCCESS) {
-        for (const auto& callback : event_cb_handler_.getCallbacks()) {
-            if (!callback->onChipReconfigureFailure(status).isOk()) {
-                LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
-            }
-        }
-        return status;
-    }
-    for (const auto& callback : event_cb_handler_.getCallbacks()) {
-        if (!callback->onChipReconfigured(mode_id).isOk()) {
-            LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
-        }
-    }
-    current_mode_id_ = mode_id;
-    LOG(INFO) << "Configured chip in mode " << mode_id;
-    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
-
-    legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_);
-
-    return status;
-}
-
-std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
-    if (!isValidModeId(current_mode_id_)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), current_mode_id_};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
-}
-
-std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> WifiChip::requestChipDebugInfoInternal() {
-    V1_4::IWifiChip::ChipDebugInfo result;
-    legacy_hal::wifi_error legacy_status;
-    std::string driver_desc;
-    const auto ifname = getFirstActiveWlanIfaceName();
-    std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status);
-        WifiStatus status =
-                createWifiStatusFromLegacyError(legacy_status, "failed to get driver version");
-        return {status, result};
-    }
-    result.driverDescription = driver_desc.c_str();
-
-    std::string firmware_desc;
-    std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status);
-        WifiStatus status =
-                createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version");
-        return {status, result};
-    }
-    result.firmwareDescription = firmware_desc.c_str();
-
-    return {createWifiStatus(WifiStatusCode::SUCCESS), result};
-}
-
-std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestDriverDebugDumpInternal() {
-    legacy_hal::wifi_error legacy_status;
-    std::vector<uint8_t> driver_dump;
-    std::tie(legacy_status, driver_dump) =
-            legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName());
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status);
-        return {createWifiStatusFromLegacyError(legacy_status), std::vector<uint8_t>()};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
-}
-
-std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestFirmwareDebugDumpInternal() {
-    legacy_hal::wifi_error legacy_status;
-    std::vector<uint8_t> firmware_dump;
-    std::tie(legacy_status, firmware_dump) =
-            legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName());
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status);
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
-}
-
-WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
-    legacy_hal::wifi_error legacy_status;
-    legacy_status = legacy_hal_.lock()->createVirtualInterface(
-            apVirtIf, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
-                   << legacyErrorToString(legacy_status);
-        return createWifiStatusFromLegacyError(legacy_status);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
-    std::vector<std::string> ap_instances;
-    for (auto const& it : br_ifaces_ap_instances_) {
-        if (it.first == ifname) {
-            ap_instances = it.second;
-        }
-    }
-    sp<WifiApIface> iface = new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_);
-    ap_ifaces_.push_back(iface);
-    for (const auto& callback : event_cb_handler_.getCallbacks()) {
-        if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
-            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
-        }
-    }
-    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
-    return iface;
-}
-
-std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createApIfaceInternal() {
-    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-    }
-    std::string ifname = allocateApIfaceName();
-    WifiStatus status = createVirtualApInterface(ifname);
-    if (status.code != WifiStatusCode::SUCCESS) {
-        return {status, {}};
-    }
-    sp<WifiApIface> iface = newWifiApIface(ifname);
-    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
-}
-
-std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createBridgedApIfaceInternal() {
-    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-    }
-    std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
-    if (ap_instances.size() < 2) {
-        LOG(ERROR) << "Fail to allocate two instances";
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-    }
-    std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
-    for (int i = 0; i < 2; i++) {
-        WifiStatus status = createVirtualApInterface(ap_instances[i]);
-        if (status.code != WifiStatusCode::SUCCESS) {
-            if (i != 0) {  // The failure happened when creating second virtual
-                           // iface.
-                legacy_hal_.lock()->deleteVirtualInterface(
-                        ap_instances.front());  // Remove the first virtual iface.
-            }
-            return {status, {}};
-        }
-    }
-    br_ifaces_ap_instances_[br_ifname] = ap_instances;
-    if (!iface_util_->createBridge(br_ifname)) {
-        LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
-        deleteApIface(br_ifname);
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-    }
-    for (auto const& instance : ap_instances) {
-        // Bind ap instance interface to AP bridge
-        if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
-            LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
-            deleteApIface(br_ifname);
-            return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-        }
-    }
-    sp<WifiApIface> iface = newWifiApIface(br_ifname);
-    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
-}
-
-std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getApIfaceNamesInternal() {
-    if (ap_ifaces_.empty()) {
-        return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
-}
-
-std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::getApIfaceInternal(
-        const std::string& ifname) {
-    const auto iface = findUsingName(ap_ifaces_, ifname);
-    if (!iface.get()) {
-        return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
-}
-
-WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
-    const auto iface = findUsingName(ap_ifaces_, ifname);
-    if (!iface.get()) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    // Invalidate & remove any dependent objects first.
-    // Note: This is probably not required because we never create
-    // nan/rtt objects over AP iface. But, there is no harm to do it
-    // here and not make that assumption all over the place.
-    invalidateAndRemoveDependencies(ifname);
-    deleteApIface(ifname);
-    invalidateAndClear(ap_ifaces_, iface);
-    for (const auto& callback : event_cb_handler_.getCallbacks()) {
-        if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
-            LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
-        }
-    }
-    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
-        const std::string& ifname, const std::string& ifInstanceName) {
-    const auto iface = findUsingName(ap_ifaces_, ifname);
-    if (!iface.get() || ifInstanceName.empty()) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    // Requires to remove one of the instance in bridge mode
-    for (auto const& it : br_ifaces_ap_instances_) {
-        if (it.first == ifname) {
-            std::vector<std::string> ap_instances = it.second;
-            for (auto const& iface : ap_instances) {
-                if (iface == ifInstanceName) {
-                    if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
-                        LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
-                                   << ifname;
-                        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
-                    }
-                    legacy_hal::wifi_error legacy_status =
-                            legacy_hal_.lock()->deleteVirtualInterface(iface);
-                    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-                        LOG(ERROR) << "Failed to del interface: " << iface << " "
-                                   << legacyErrorToString(legacy_status);
-                        return createWifiStatusFromLegacyError(legacy_status);
-                    }
-                    ap_instances.erase(
-                            std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
-                            ap_instances.end());
-                    br_ifaces_ap_instances_[ifname] = ap_instances;
-                    break;
-                }
-            }
-            break;
-        }
-    }
-    iface->removeInstance(ifInstanceName);
-    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
-
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::createNanIfaceInternal() {
-    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::NAN)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-    }
-    bool is_dedicated_iface = true;
-    std::string ifname = getPredefinedNanIfaceName();
-    if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
-        // Use the first shared STA iface (wlan0) if a dedicated aware iface is
-        // not defined.
-        ifname = getFirstActiveWlanIfaceName();
-        is_dedicated_iface = false;
-    }
-    sp<WifiNanIface> iface = new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
-    nan_ifaces_.push_back(iface);
-    for (const auto& callback : event_cb_handler_.getCallbacks()) {
-        if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
-            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
-        }
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
-}
-
-std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getNanIfaceNamesInternal() {
-    if (nan_ifaces_.empty()) {
-        return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
-}
-
-std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::getNanIfaceInternal(
-        const std::string& ifname) {
-    const auto iface = findUsingName(nan_ifaces_, ifname);
-    if (!iface.get()) {
-        return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
-}
-
-WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
-    const auto iface = findUsingName(nan_ifaces_, ifname);
-    if (!iface.get()) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    invalidateAndClear(nan_ifaces_, iface);
-    for (const auto& callback : event_cb_handler_.getCallbacks()) {
-        if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
-            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
-        }
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
-    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::P2P)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-    }
-    std::string ifname = getPredefinedP2pIfaceName();
-    sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
-    p2p_ifaces_.push_back(iface);
-    for (const auto& callback : event_cb_handler_.getCallbacks()) {
-        if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
-            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
-        }
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
-}
-
-std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getP2pIfaceNamesInternal() {
-    if (p2p_ifaces_.empty()) {
-        return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
-}
-
-std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(const std::string& ifname) {
-    const auto iface = findUsingName(p2p_ifaces_, ifname);
-    if (!iface.get()) {
-        return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
-}
-
-WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
-    const auto iface = findUsingName(p2p_ifaces_, ifname);
-    if (!iface.get()) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    invalidateAndClear(p2p_ifaces_, iface);
-    for (const auto& callback : event_cb_handler_.getCallbacks()) {
-        if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
-            LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
-        }
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> WifiChip::createStaIfaceInternal() {
-    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-    }
-    std::string ifname = allocateStaIfaceName();
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface(
-            ifname, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to add interface: " << ifname << " "
-                   << legacyErrorToString(legacy_status);
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
-    sta_ifaces_.push_back(iface);
-    for (const auto& callback : event_cb_handler_.getCallbacks()) {
-        if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
-            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
-        }
-    }
-    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
-    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
-}
-
-std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getStaIfaceNamesInternal() {
-    if (sta_ifaces_.empty()) {
-        return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
-}
-
-std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> WifiChip::getStaIfaceInternal(
-        const std::string& ifname) {
-    const auto iface = findUsingName(sta_ifaces_, ifname);
-    if (!iface.get()) {
-        return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
-}
-
-WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
-    const auto iface = findUsingName(sta_ifaces_, ifname);
-    if (!iface.get()) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    // Invalidate & remove any dependent objects first.
-    invalidateAndRemoveDependencies(ifname);
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to remove interface: " << ifname << " "
-                   << legacyErrorToString(legacy_status);
-    }
-    invalidateAndClear(sta_ifaces_, iface);
-    for (const auto& callback : event_cb_handler_.getCallbacks()) {
-        if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
-            LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
-        }
-    }
-    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, sp<V1_0::IWifiRttController>> WifiChip::createRttControllerInternal(
-        const sp<IWifiIface>& /*bound_iface*/) {
-    LOG(ERROR) << "createRttController is not supported on this HAL";
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
-WifiChip::getDebugRingBuffersStatusInternal() {
-    legacy_hal::wifi_error legacy_status;
-    std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec;
-    std::tie(legacy_status, legacy_ring_buffer_status_vec) =
-            legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
-    if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
-                legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_ring_buffer_status_vec};
-}
-
-WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
-        const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
-        uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
-    WifiStatus status = registerDebugRingBufferCallback();
-    if (status.code != WifiStatusCode::SUCCESS) {
-        return status;
-    }
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging(
-            getFirstActiveWlanIfaceName(), ring_name,
-            static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level),
-            max_interval_in_sec, min_data_size_in_bytes);
-    ringbuffer_map_.insert(
-            std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes)));
-    // if verbose logging enabled, turn up HAL daemon logging as well.
-    if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
-        android::base::SetMinimumLogSeverity(android::base::DEBUG);
-    } else {
-        android::base::SetMinimumLogSeverity(android::base::VERBOSE);
-    }
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(const hidl_string& ring_name) {
-    WifiStatus status = registerDebugRingBufferCallback();
-    if (status.code != WifiStatusCode::SUCCESS) {
-        return status;
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name);
-
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::flushRingBufferToFileInternal() {
-    if (!writeRingbufferFilesInternal()) {
-        LOG(ERROR) << "Error writing files to flash";
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName());
-    if (legacy_status == legacy_hal::WIFI_SUCCESS) {
-        debug_ring_buffer_cb_registered_ = false;
-    }
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
-WifiChip::getDebugHostWakeReasonStatsInternal() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::WakeReasonStats legacy_stats;
-    std::tie(legacy_status, legacy_stats) =
-            legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    WifiDebugHostWakeReasonStats hidl_stats;
-    if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, &hidl_stats)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
-}
-
-WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
-    legacy_hal::wifi_error legacy_status;
-    if (enable) {
-        android::wp<WifiChip> weak_ptr_this(this);
-        const auto& on_alert_callback = [weak_ptr_this](int32_t error_code,
-                                                        std::vector<uint8_t> debug_data) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
-                    LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
-                }
-            }
-        };
-        legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
-                getFirstActiveWlanIfaceName(), on_alert_callback);
-    } else {
-        legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
-                getFirstActiveWlanIfaceName());
-    }
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario) {
-    auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
-            getFirstActiveWlanIfaceName(),
-            hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::resetTxPowerScenarioInternal() {
-    auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
-    auto legacy_status = legacy_hal_.lock()->setLatencyMode(
-            getFirstActiveWlanIfaceName(), hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::registerEventCallbackInternal_1_2(
-        const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
-    // Deprecated support for this callback.
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario) {
-    auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
-            getFirstActiveWlanIfaceName(),
-            hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
-    // Deprecated support for this callback.
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
-}
-
-std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_5() {
-    legacy_hal::wifi_error legacy_status;
-    uint64_t legacy_feature_set;
-    uint32_t legacy_logger_feature_set;
-    const auto ifname = getFirstActiveWlanIfaceName();
-    std::tie(legacy_status, legacy_feature_set) =
-            legacy_hal_.lock()->getSupportedFeatureSet(ifname);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), 0};
-    }
-    std::tie(legacy_status, legacy_logger_feature_set) =
-            legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        // some devices don't support querying logger feature set
-        legacy_logger_feature_set = 0;
-    }
-    uint32_t hidl_caps;
-    if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
-                legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-std::pair<WifiStatus, sp<V1_4::IWifiRttController>> WifiChip::createRttControllerInternal_1_4(
-        const sp<IWifiIface>& /*bound_iface*/) {
-    LOG(ERROR) << "createRttController_1_4 is not supported on this HAL";
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-WifiStatus WifiChip::registerEventCallbackInternal_1_4(
-        const sp<V1_4::IWifiChipEventCallback>& event_callback) {
-    if (!event_cb_handler_.addCallback(event_callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) {
-    auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) {
-    auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
-            hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case));
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,
-                                                   uint32_t restrictions) {
-    std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
-    if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels,
-                                                                        &legacy_unsafe_channels)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    uint32_t legacy_restrictions = 0;
-    if (restrictions & CoexRestriction::WIFI_DIRECT) {
-        legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
-    }
-    if (restrictions & CoexRestriction::SOFTAP) {
-        legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
-    }
-    if (restrictions & CoexRestriction::WIFI_AWARE) {
-        legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
-    }
-    auto legacy_status =
-            legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
-    auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, std::vector<V1_5::WifiUsableChannel>> WifiChip::getUsableChannelsInternal(
-        WifiBand /*band*/, uint32_t /*ifaceModeMask*/, uint32_t /*filterMask*/) {
-    LOG(ERROR) << "getUsableChannels is not supported on this HAL";
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-WifiStatus WifiChip::triggerSubsystemRestartInternal() {
-    auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, sp<V1_6::IWifiRttController>> WifiChip::createRttControllerInternal_1_6(
-        const sp<IWifiIface>& bound_iface) {
-    if (sta_ifaces_.size() == 0 &&
-        !canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
-        LOG(ERROR) << "createRttControllerInternal_1_6: Chip cannot support STAs "
-                      "(and RTT by extension)";
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-    }
-    sp<WifiRttController> rtt =
-            new WifiRttController(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
-    rtt_controllers_.emplace_back(rtt);
-    return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
-}
-
-std::pair<WifiStatus, std::vector<V1_6::WifiUsableChannel>> WifiChip::getUsableChannelsInternal_1_6(
-        WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask) {
-    legacy_hal::wifi_error legacy_status;
-    std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
-    std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels(
-            hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band),
-            hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask),
-            hidl_struct_util::convertHidlUsableChannelFilterToLegacy(filterMask));
-
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    std::vector<V1_6::WifiUsableChannel> hidl_usable_channels;
-    if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(legacy_usable_channels,
-                                                                 &hidl_usable_channels)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
-}
-
-std::pair<WifiStatus, V1_6::WifiRadioCombinationMatrix>
-WifiChip::getSupportedRadioCombinationsMatrixInternal() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_radio_combination_matrix* legacy_matrix;
-
-    std::tie(legacy_status, legacy_matrix) =
-            legacy_hal_.lock()->getSupportedRadioCombinationsMatrix();
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to get SupportedRadioCombinations matrix from legacy HAL: "
-                   << legacyErrorToString(legacy_status);
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-
-    V1_6::WifiRadioCombinationMatrix hidl_matrix;
-    if (!hidl_struct_util::convertLegacyRadioCombinationsMatrixToHidl(legacy_matrix,
-                                                                      &hidl_matrix)) {
-        LOG(ERROR) << "Failed convertLegacyRadioCombinationsMatrixToHidl() ";
-        return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_matrix};
-}
-
-std::pair<WifiStatus, std::vector<V1_6::IWifiChip::ChipMode>>
-WifiChip::getAvailableModesInternal_1_6() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
-}
-
-WifiStatus WifiChip::handleChipConfiguration(
-        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
-    // If the chip is already configured in a different mode, stop
-    // the legacy HAL and then start it after firmware mode change.
-    if (isValidModeId(current_mode_id_)) {
-        LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id;
-        invalidateAndRemoveAllIfaces();
-        legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {});
-        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-            LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status);
-            return createWifiStatusFromLegacyError(legacy_status);
-        }
-    }
-    // Firmware mode change not needed for V2 devices.
-    bool success = true;
-    if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
-        success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
-    } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
-        success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
-    }
-    if (!success) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status);
-        return createWifiStatusFromLegacyError(legacy_status);
-    }
-    // Every time the HAL is restarted, we need to register the
-    // radio mode change callback.
-    WifiStatus status = registerRadioModeChangeCallback();
-    if (status.code != WifiStatusCode::SUCCESS) {
-        // This probably is not a critical failure?
-        LOG(ERROR) << "Failed to register radio mode change callback";
-    }
-    // Extract and save the version information into property.
-    std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> version_info;
-    version_info = WifiChip::requestChipDebugInfoInternal();
-    if (WifiStatusCode::SUCCESS == version_info.first.code) {
-        property_set("vendor.wlan.firmware.version",
-                     version_info.second.firmwareDescription.c_str());
-        property_set("vendor.wlan.driver.version", version_info.second.driverDescription.c_str());
-    }
-
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiChip::registerDebugRingBufferCallback() {
-    if (debug_ring_buffer_cb_registered_) {
-        return createWifiStatus(WifiStatusCode::SUCCESS);
-    }
-
-    android::wp<WifiChip> weak_ptr_this(this);
-    const auto& on_ring_buffer_data_callback =
-            [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data,
-                            const legacy_hal::wifi_ring_buffer_status& status) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                WifiDebugRingBufferStatus hidl_status;
-                Ringbuffer::AppendStatus appendstatus;
-                if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(status,
-                                                                                &hidl_status)) {
-                    LOG(ERROR) << "Error converting ring buffer status";
-                    return;
-                }
-                {
-                    std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
-                    const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
-                    if (target != shared_ptr_this->ringbuffer_map_.end()) {
-                        Ringbuffer& cur_buffer = target->second;
-                        appendstatus = cur_buffer.append(data);
-                    } else {
-                        LOG(ERROR) << "Ringname " << name << " not found";
-                        return;
-                    }
-                    // unique_lock unlocked here
-                }
-                if (appendstatus == Ringbuffer::AppendStatus::FAIL_RING_BUFFER_CORRUPTED) {
-                    LOG(ERROR) << "Ringname " << name << " is corrupted. Clear the ring buffer";
-                    shared_ptr_this->writeRingbufferFilesInternal();
-                    return;
-                }
-
-            };
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler(
-            getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
-
-    if (legacy_status == legacy_hal::WIFI_SUCCESS) {
-        debug_ring_buffer_cb_registered_ = true;
-    }
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiChip::registerRadioModeChangeCallback() {
-    android::wp<WifiChip> weak_ptr_this(this);
-    const auto& on_radio_mode_change_callback =
-            [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
-                if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(mac_infos,
-                                                                       &hidl_radio_mode_infos)) {
-                    LOG(ERROR) << "Error converting wifi mac info";
-                    return;
-                }
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos).isOk()) {
-                        LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
-                                   << " callback on: " << toString(callback);
-                    }
-                }
-            };
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
-                    getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::vector<V1_6::IWifiChip::ChipConcurrencyCombination>
-WifiChip::getCurrentModeConcurrencyCombinations() {
-    if (!isValidModeId(current_mode_id_)) {
-        LOG(ERROR) << "Chip not configured in a mode yet";
-        return {};
-    }
-    for (const auto& mode : modes_) {
-        if (mode.id == current_mode_id_) {
-            return mode.availableCombinations;
-        }
-    }
-    CHECK(0) << "Expected to find concurrency combinations for current mode!";
-    return {};
-}
-
-// Returns a map indexed by IfaceConcurrencyType with the number of ifaces currently
-// created of the corresponding concurrency type.
-std::map<IfaceConcurrencyType, size_t> WifiChip::getCurrentConcurrencyCombination() {
-    std::map<IfaceConcurrencyType, size_t> iface_counts;
-    uint32_t num_ap = 0;
-    uint32_t num_ap_bridged = 0;
-    for (const auto& ap_iface : ap_ifaces_) {
-        std::string ap_iface_name = ap_iface->getName();
-        if (br_ifaces_ap_instances_.count(ap_iface_name) > 0 &&
-            br_ifaces_ap_instances_[ap_iface_name].size() > 1) {
-            num_ap_bridged++;
-        } else {
-            num_ap++;
-        }
-    }
-    iface_counts[IfaceConcurrencyType::AP] = num_ap;
-    iface_counts[IfaceConcurrencyType::AP_BRIDGED] = num_ap_bridged;
-    iface_counts[IfaceConcurrencyType::NAN] = nan_ifaces_.size();
-    iface_counts[IfaceConcurrencyType::P2P] = p2p_ifaces_.size();
-    iface_counts[IfaceConcurrencyType::STA] = sta_ifaces_.size();
-    return iface_counts;
-}
-
-// This expands the provided concurrency combinations to a more parseable
-// form. Returns a vector of available combinations possible with the number
-// of each concurrency type in the combination.
-// This method is a port of HalDeviceManager.expandConcurrencyCombos() from framework.
-std::vector<std::map<IfaceConcurrencyType, size_t>> WifiChip::expandConcurrencyCombinations(
-        const V1_6::IWifiChip::ChipConcurrencyCombination& combination) {
-    uint32_t num_expanded_combos = 1;
-    for (const auto& limit : combination.limits) {
-        for (uint32_t i = 0; i < limit.maxIfaces; i++) {
-            num_expanded_combos *= limit.types.size();
-        }
-    }
-
-    // Allocate the vector of expanded combos and reset all concurrency type counts to 0
-    // in each combo.
-    std::vector<std::map<IfaceConcurrencyType, size_t>> expanded_combos;
-    expanded_combos.resize(num_expanded_combos);
-    for (auto& expanded_combo : expanded_combos) {
-        for (const auto type :
-             {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
-              IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
-            expanded_combo[type] = 0;
-        }
-    }
-    uint32_t span = num_expanded_combos;
-    for (const auto& limit : combination.limits) {
-        for (uint32_t i = 0; i < limit.maxIfaces; i++) {
-            span /= limit.types.size();
-            for (uint32_t k = 0; k < num_expanded_combos; ++k) {
-                const auto iface_type = limit.types[(k / span) % limit.types.size()];
-                expanded_combos[k][iface_type]++;
-            }
-        }
-    }
-    return expanded_combos;
-}
-
-bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
-        const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
-        IfaceConcurrencyType requested_type) {
-    const auto current_combo = getCurrentConcurrencyCombination();
-
-    // Check if we have space for 1 more iface of |type| in this combo
-    for (const auto type :
-         {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
-          IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
-        size_t num_ifaces_needed = current_combo.at(type);
-        if (type == requested_type) {
-            num_ifaces_needed++;
-        }
-        size_t num_ifaces_allowed = expanded_combo.at(type);
-        if (num_ifaces_needed > num_ifaces_allowed) {
-            return false;
-        }
-    }
-    return true;
-}
-
-// This method does the following:
-// a) Enumerate all possible concurrency combos by expanding the current
-//    ChipConcurrencyCombination.
-// b) Check if the requested concurrency type can be added to the current mode
-//    with the concurrency combination that is already active.
-bool WifiChip::canCurrentModeSupportConcurrencyTypeWithCurrentTypes(
-        IfaceConcurrencyType requested_type) {
-    if (!isValidModeId(current_mode_id_)) {
-        LOG(ERROR) << "Chip not configured in a mode yet";
-        return false;
-    }
-    const auto combinations = getCurrentModeConcurrencyCombinations();
-    for (const auto& combination : combinations) {
-        const auto expanded_combos = expandConcurrencyCombinations(combination);
-        for (const auto& expanded_combo : expanded_combos) {
-            if (canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(expanded_combo,
-                                                                                  requested_type)) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-// Note: This does not consider concurrency types already active. It only checks if the
-// provided expanded concurrency combination can support the requested combo.
-bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyCombo(
-        const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
-        const std::map<IfaceConcurrencyType, size_t>& req_combo) {
-    // Check if we have space for 1 more |type| in this combo
-    for (const auto type :
-         {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
-          IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
-        if (req_combo.count(type) == 0) {
-            // Concurrency type not in the req_combo.
-            continue;
-        }
-        size_t num_ifaces_needed = req_combo.at(type);
-        size_t num_ifaces_allowed = expanded_combo.at(type);
-        if (num_ifaces_needed > num_ifaces_allowed) {
-            return false;
-        }
-    }
-    return true;
-}
-// This method does the following:
-// a) Enumerate all possible concurrency combos by expanding the current
-//    ChipConcurrencyCombination.
-// b) Check if the requested concurrency combo can be added to the current mode.
-// Note: This does not consider concurrency types already active. It only checks if the
-// current mode can support the requested combo.
-bool WifiChip::canCurrentModeSupportConcurrencyCombo(
-        const std::map<IfaceConcurrencyType, size_t>& req_combo) {
-    if (!isValidModeId(current_mode_id_)) {
-        LOG(ERROR) << "Chip not configured in a mode yet";
-        return false;
-    }
-    const auto combinations = getCurrentModeConcurrencyCombinations();
-    for (const auto& combination : combinations) {
-        const auto expanded_combos = expandConcurrencyCombinations(combination);
-        for (const auto& expanded_combo : expanded_combos) {
-            if (canExpandedConcurrencyComboSupportConcurrencyCombo(expanded_combo, req_combo)) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-// This method does the following:
-// a) Enumerate all possible concurrency combos by expanding the current
-//    ChipConcurrencyCombination.
-// b) Check if the requested concurrency type can be added to the current mode.
-bool WifiChip::canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type) {
-    // Check if we can support at least 1 of the requested concurrency type.
-    std::map<IfaceConcurrencyType, size_t> req_iface_combo;
-    req_iface_combo[requested_type] = 1;
-    return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
-}
-
-bool WifiChip::isValidModeId(ChipModeId mode_id) {
-    for (const auto& mode : modes_) {
-        if (mode.id == mode_id) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
-    // Check if we can support at least 1 STA & 1 AP concurrently.
-    std::map<IfaceConcurrencyType, size_t> req_iface_combo;
-    req_iface_combo[IfaceConcurrencyType::STA] = 1;
-    req_iface_combo[IfaceConcurrencyType::AP] = 1;
-    return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
-}
-
-bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
-    // Check if we can support at least 2 STA concurrently.
-    std::map<IfaceConcurrencyType, size_t> req_iface_combo;
-    req_iface_combo[IfaceConcurrencyType::STA] = 2;
-    return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
-}
-
-std::string WifiChip::getFirstActiveWlanIfaceName() {
-    if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
-    if (ap_ifaces_.size() > 0) {
-        // If the first active wlan iface is bridged iface.
-        // Return first instance name.
-        for (auto const& it : br_ifaces_ap_instances_) {
-            if (it.first == ap_ifaces_[0]->getName()) {
-                return it.second[0];
-            }
-        }
-        return ap_ifaces_[0]->getName();
-    }
-    // This could happen if the chip call is made before any STA/AP
-    // iface is created. Default to wlan0 for such cases.
-    LOG(WARNING) << "No active wlan interfaces in use! Using default";
-    return getWlanIfaceNameWithType(IfaceType::STA, 0);
-}
-
-// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
-// not already in use.
-// Note: This doesn't check the actual presence of these interfaces.
-std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) {
-    for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
-        const auto ifname = getWlanIfaceNameWithType(type, idx);
-        if (findUsingNameFromBridgedApInstances(ifname)) continue;
-        if (findUsingName(ap_ifaces_, ifname)) continue;
-        if (findUsingName(sta_ifaces_, ifname)) continue;
-        return ifname;
-    }
-    // This should never happen. We screwed up somewhere if it did.
-    CHECK(false) << "All wlan interfaces in use already!";
-    return {};
-}
-
-uint32_t WifiChip::startIdxOfApIface() {
-    if (isDualStaConcurrencyAllowedInCurrentMode()) {
-        // When the HAL support dual STAs, AP should start with idx 2.
-        return 2;
-    } else if (isStaApConcurrencyAllowedInCurrentMode()) {
-        //  When the HAL support STA + AP but it doesn't support dual STAs.
-        //  AP should start with idx 1.
-        return 1;
-    }
-    // No concurrency support.
-    return 0;
-}
-
-// AP iface names start with idx 1 for modes supporting
-// concurrent STA and not dual AP, else start with idx 0.
-std::string WifiChip::allocateApIfaceName() {
-    // Check if we have a dedicated iface for AP.
-    std::vector<std::string> ifnames = getPredefinedApIfaceNames(false);
-    if (!ifnames.empty()) {
-        return ifnames[0];
-    }
-    return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
-}
-
-std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
-    // Check if we have a dedicated iface for AP.
-    std::vector<std::string> instances = getPredefinedApIfaceNames(true);
-    if (instances.size() == 2) {
-        return instances;
-    } else {
-        int num_ifaces_need_to_allocate = 2 - instances.size();
-        for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
-            std::string instance_name =
-                    allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i);
-            if (!instance_name.empty()) {
-                instances.push_back(instance_name);
-            }
-        }
-    }
-    return instances;
-}
-
-// STA iface names start with idx 0.
-// Primary STA iface will always be 0.
-std::string WifiChip::allocateStaIfaceName() {
-    return allocateApOrStaIfaceName(IfaceType::STA, 0);
-}
-
-bool WifiChip::writeRingbufferFilesInternal() {
-    if (!removeOldFilesInternal()) {
-        LOG(ERROR) << "Error occurred while deleting old tombstone files";
-        return false;
-    }
-    // write ringbuffers to file
-    {
-        std::unique_lock<std::mutex> lk(lock_t);
-        for (auto& item : ringbuffer_map_) {
-            Ringbuffer& cur_buffer = item.second;
-            if (cur_buffer.getData().empty()) {
-                continue;
-            }
-            const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX";
-            const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
-            if (dump_fd == -1) {
-                PLOG(ERROR) << "create file failed";
-                return false;
-            }
-            unique_fd file_auto_closer(dump_fd);
-            for (const auto& cur_block : cur_buffer.getData()) {
-                if (cur_block.size() <= 0 || cur_block.size() > kMaxBufferSizeBytes) {
-                    PLOG(ERROR) << "Ring buffer: " << item.first
-                                << " is corrupted. Invalid block size: " << cur_block.size();
-                    break;
-                }
-                if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) ==
-                    -1) {
-                    PLOG(ERROR) << "Error writing to file";
-                }
-            }
-            cur_buffer.clear();
-        }
-        // unique_lock unlocked here
-    }
-    return true;
-}
-
-std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
-    std::string ifname;
-
-    // let the legacy hal override the interface name
-    legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
-    if (err == legacy_hal::WIFI_SUCCESS) return ifname;
-
-    return getWlanIfaceName(idx);
-}
-
-void WifiChip::invalidateAndClearBridgedApAll() {
-    for (auto const& it : br_ifaces_ap_instances_) {
-        for (auto const& iface : it.second) {
-            iface_util_->removeIfaceFromBridge(it.first, iface);
-            legacy_hal_.lock()->deleteVirtualInterface(iface);
-        }
-        iface_util_->deleteBridge(it.first);
-    }
-    br_ifaces_ap_instances_.clear();
-}
-
-void WifiChip::deleteApIface(const std::string& if_name) {
-    if (if_name.empty()) return;
-    // delete bridged interfaces if have
-    for (auto const& it : br_ifaces_ap_instances_) {
-        if (it.first == if_name) {
-            for (auto const& iface : it.second) {
-                iface_util_->removeIfaceFromBridge(if_name, iface);
-                legacy_hal_.lock()->deleteVirtualInterface(iface);
-            }
-            iface_util_->deleteBridge(if_name);
-            br_ifaces_ap_instances_.erase(if_name);
-            // ifname is bridged AP, return here.
-            return;
-        }
-    }
-
-    // No bridged AP case, delete AP iface
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(if_name);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to remove interface: " << if_name << " "
-                   << legacyErrorToString(legacy_status);
-    }
-}
-
-bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
-    for (auto const& it : br_ifaces_ap_instances_) {
-        if (it.first == name) {
-            return true;
-        }
-        for (auto const& iface : it.second) {
-            if (iface == name) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_chip.h b/wifi/1.6/default/wifi_chip.h
deleted file mode 100644
index e8ddaa6..0000000
--- a/wifi/1.6/default/wifi_chip.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_CHIP_H_
-#define WIFI_CHIP_H_
-
-// HACK: NAN is a macro defined in math.h, which can be included in various
-// headers. This wifi HAL uses an enum called NAN, which does not compile when
-// the macro is defined. Undefine NAN to work around it.
-#undef NAN
-
-#include <list>
-#include <map>
-#include <mutex>
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.6/IWifiChip.h>
-#include <android/hardware/wifi/1.6/IWifiRttController.h>
-#include <android/hardware/wifi/1.6/IWifiStaIface.h>
-
-#include "hidl_callback_util.h"
-#include "ringbuffer.h"
-#include "wifi_ap_iface.h"
-#include "wifi_feature_flags.h"
-#include "wifi_legacy_hal.h"
-#include "wifi_mode_controller.h"
-#include "wifi_nan_iface.h"
-#include "wifi_p2p_iface.h"
-#include "wifi_rtt_controller.h"
-#include "wifi_sta_iface.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-using V1_5::WifiBand;
-
-/**
- * HIDL interface object used to control a Wifi HAL chip instance.
- * Since there is only a single chip instance used today, there is no
- * identifying handle information stored here.
- */
-class WifiChip : public V1_6::IWifiChip {
-  public:
-    WifiChip(ChipId chip_id, bool is_primary,
-             const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-             const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
-             const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
-             const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
-             const std::function<void(const std::string&)>& subsystemCallbackHandler);
-    // HIDL does not provide a built-in mechanism to let the server invalidate
-    // a HIDL interface object after creation. If any client process holds onto
-    // a reference to the object in their context, any method calls on that
-    // reference will continue to be directed to the server.
-    //
-    // However Wifi HAL needs to control the lifetime of these objects. So, add
-    // a public |invalidate| method to |WifiChip| and it's child objects. This
-    // will be used to mark an object invalid when either:
-    // a) Wifi HAL is stopped, or
-    // b) Wifi Chip is reconfigured.
-    //
-    // All HIDL method implementations should check if the object is still
-    // marked valid before processing them.
-    void invalidate();
-    bool isValid();
-    std::set<sp<V1_4::IWifiChipEventCallback>> getEventCallbacks();
-
-    // HIDL methods exposed.
-    Return<void> getId(getId_cb hidl_status_cb) override;
-    // Deprecated support for this callback
-    Return<void> registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback,
-                                       registerEventCallback_cb hidl_status_cb) override;
-    Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
-    Return<void> getAvailableModes(getAvailableModes_cb hidl_status_cb) override;
-    Return<void> configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) override;
-    Return<void> getMode(getMode_cb hidl_status_cb) override;
-    Return<void> requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) override;
-    Return<void> requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) override;
-    Return<void> requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) override;
-    Return<void> createApIface(createApIface_cb hidl_status_cb) override;
-    Return<void> createBridgedApIface(createBridgedApIface_cb hidl_status_cb) override;
-    Return<void> getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override;
-    Return<void> getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) override;
-    Return<void> removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) override;
-    Return<void> removeIfaceInstanceFromBridgedApIface(
-            const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName,
-            removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override;
-    Return<void> createNanIface(createNanIface_cb hidl_status_cb) override;
-    Return<void> getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override;
-    Return<void> getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) override;
-    Return<void> removeNanIface(const hidl_string& ifname,
-                                removeNanIface_cb hidl_status_cb) override;
-    Return<void> createP2pIface(createP2pIface_cb hidl_status_cb) override;
-    Return<void> getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) override;
-    Return<void> getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) override;
-    Return<void> removeP2pIface(const hidl_string& ifname,
-                                removeP2pIface_cb hidl_status_cb) override;
-    Return<void> createStaIface(createStaIface_cb hidl_status_cb) override;
-    Return<void> getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) override;
-    Return<void> getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) override;
-    Return<void> removeStaIface(const hidl_string& ifname,
-                                removeStaIface_cb hidl_status_cb) override;
-    Return<void> createRttController(const sp<IWifiIface>& bound_iface,
-                                     createRttController_cb hidl_status_cb) override;
-    Return<void> getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) override;
-    Return<void> startLoggingToDebugRingBuffer(
-            const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
-            uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
-            startLoggingToDebugRingBuffer_cb hidl_status_cb) override;
-    Return<void> forceDumpToDebugRingBuffer(const hidl_string& ring_name,
-                                            forceDumpToDebugRingBuffer_cb hidl_status_cb) override;
-    Return<void> flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) override;
-    Return<void> stopLoggingToDebugRingBuffer(
-            stopLoggingToDebugRingBuffer_cb hidl_status_cb) override;
-    Return<void> getDebugHostWakeReasonStats(
-            getDebugHostWakeReasonStats_cb hidl_status_cb) override;
-    Return<void> enableDebugErrorAlerts(bool enable,
-                                        enableDebugErrorAlerts_cb hidl_status_cb) override;
-    Return<void> selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,
-                                       selectTxPowerScenario_cb hidl_status_cb) override;
-    Return<void> resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) override;
-    Return<void> setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_2(const sp<V1_2::IWifiChipEventCallback>& event_callback,
-                                           registerEventCallback_1_2_cb hidl_status_cb) override;
-    Return<void> selectTxPowerScenario_1_2(TxPowerScenario scenario,
-                                           selectTxPowerScenario_cb hidl_status_cb) override;
-    Return<void> getCapabilities_1_3(getCapabilities_cb hidl_status_cb) override;
-    Return<void> getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) override;
-    Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override;
-    Return<void> createRttController_1_4(const sp<IWifiIface>& bound_iface,
-                                         createRttController_1_4_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_4(const sp<V1_4::IWifiChipEventCallback>& event_callback,
-                                           registerEventCallback_1_4_cb hidl_status_cb) override;
-    Return<void> setMultiStaPrimaryConnection(
-            const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) override;
-    Return<void> setMultiStaUseCase(MultiStaUseCase use_case,
-                                    setMultiStaUseCase_cb hidl_status_cb) override;
-    Return<void> setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel>& unsafe_channels,
-                                       hidl_bitfield<IfaceType> restrictions,
-                                       setCoexUnsafeChannels_cb hidl_status_cb) override;
-    Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
-                                setCountryCode_cb _hidl_cb) override;
-    Return<void> getUsableChannels(WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
-                                   hidl_bitfield<V1_5::IWifiChip::UsableChannelFilter> filterMask,
-                                   getUsableChannels_cb _hidl_cb) override;
-    Return<void> triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) override;
-    Return<void> createRttController_1_6(const sp<IWifiIface>& bound_iface,
-                                         createRttController_1_6_cb hidl_status_cb) override;
-    Return<void> getUsableChannels_1_6(WifiBand band,
-                                       hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
-                                       hidl_bitfield<UsableChannelFilter> filterMask,
-                                       getUsableChannels_1_6_cb _hidl_cb) override;
-    Return<void> getSupportedRadioCombinationsMatrix(
-            getSupportedRadioCombinationsMatrix_cb hidl_status_cb) override;
-    Return<void> getAvailableModes_1_6(getAvailableModes_1_6_cb hidl_status_cb) override;
-
-  private:
-    void invalidateAndRemoveAllIfaces();
-    // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
-    // invalidated & removed.
-    void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
-
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, ChipId> getIdInternal();
-    // Deprecated support for this callback
-    WifiStatus registerEventCallbackInternal(
-            const sp<V1_0::IWifiChipEventCallback>& event_callback);
-    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
-    std::pair<WifiStatus, std::vector<V1_0::IWifiChip::ChipMode>> getAvailableModesInternal();
-    WifiStatus configureChipInternal(std::unique_lock<std::recursive_mutex>* lock,
-                                     ChipModeId mode_id);
-    std::pair<WifiStatus, uint32_t> getModeInternal();
-    std::pair<WifiStatus, IWifiChip::ChipDebugInfo> requestChipDebugInfoInternal();
-    std::pair<WifiStatus, std::vector<uint8_t>> requestDriverDebugDumpInternal();
-    std::pair<WifiStatus, std::vector<uint8_t>> requestFirmwareDebugDumpInternal();
-    sp<WifiApIface> newWifiApIface(std::string& ifname);
-    WifiStatus createVirtualApInterface(const std::string& apVirtIf);
-    std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createApIfaceInternal();
-    std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createBridgedApIfaceInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>> getApIfaceNamesInternal();
-    std::pair<WifiStatus, sp<V1_5::IWifiApIface>> getApIfaceInternal(const std::string& ifname);
-    WifiStatus removeApIfaceInternal(const std::string& ifname);
-    WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal(const std::string& brIfaceName,
-                                                             const std::string& ifInstanceName);
-    std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> createNanIfaceInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>> getNanIfaceNamesInternal();
-    std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> getNanIfaceInternal(const std::string& ifname);
-    WifiStatus removeNanIfaceInternal(const std::string& ifname);
-    std::pair<WifiStatus, sp<IWifiP2pIface>> createP2pIfaceInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>> getP2pIfaceNamesInternal();
-    std::pair<WifiStatus, sp<IWifiP2pIface>> getP2pIfaceInternal(const std::string& ifname);
-    WifiStatus removeP2pIfaceInternal(const std::string& ifname);
-    std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> createStaIfaceInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>> getStaIfaceNamesInternal();
-    std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> getStaIfaceInternal(const std::string& ifname);
-    WifiStatus removeStaIfaceInternal(const std::string& ifname);
-    std::pair<WifiStatus, sp<V1_0::IWifiRttController>> createRttControllerInternal(
-            const sp<IWifiIface>& bound_iface);
-    std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
-    getDebugRingBuffersStatusInternal();
-    WifiStatus startLoggingToDebugRingBufferInternal(const hidl_string& ring_name,
-                                                     WifiDebugRingBufferVerboseLevel verbose_level,
-                                                     uint32_t max_interval_in_sec,
-                                                     uint32_t min_data_size_in_bytes);
-    WifiStatus forceDumpToDebugRingBufferInternal(const hidl_string& ring_name);
-    WifiStatus flushRingBufferToFileInternal();
-    WifiStatus stopLoggingToDebugRingBufferInternal();
-    std::pair<WifiStatus, WifiDebugHostWakeReasonStats> getDebugHostWakeReasonStatsInternal();
-    WifiStatus enableDebugErrorAlertsInternal(bool enable);
-    WifiStatus selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario);
-    WifiStatus resetTxPowerScenarioInternal();
-    WifiStatus setLatencyModeInternal(LatencyMode mode);
-    WifiStatus registerEventCallbackInternal_1_2(
-            const sp<V1_2::IWifiChipEventCallback>& event_callback);
-    WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario);
-    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_3();
-    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_5();
-    std::pair<WifiStatus, sp<V1_4::IWifiRttController>> createRttControllerInternal_1_4(
-            const sp<IWifiIface>& bound_iface);
-    WifiStatus registerEventCallbackInternal_1_4(
-            const sp<V1_4::IWifiChipEventCallback>& event_callback);
-    WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
-    WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case);
-    WifiStatus setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,
-                                             uint32_t restrictions);
-    WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
-    std::pair<WifiStatus, std::vector<V1_5::WifiUsableChannel>> getUsableChannelsInternal(
-            WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask);
-    WifiStatus handleChipConfiguration(std::unique_lock<std::recursive_mutex>* lock,
-                                       ChipModeId mode_id);
-    WifiStatus registerDebugRingBufferCallback();
-    WifiStatus registerRadioModeChangeCallback();
-    std::vector<V1_6::IWifiChip::ChipConcurrencyCombination>
-    getCurrentModeConcurrencyCombinations();
-    std::map<IfaceConcurrencyType, size_t> getCurrentConcurrencyCombination();
-    std::vector<std::map<IfaceConcurrencyType, size_t>> expandConcurrencyCombinations(
-            const V1_6::IWifiChip::ChipConcurrencyCombination& combination);
-    bool canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
-            const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
-            IfaceConcurrencyType requested_type);
-    bool canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType requested_type);
-    bool canExpandedConcurrencyComboSupportConcurrencyCombo(
-            const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
-            const std::map<IfaceConcurrencyType, size_t>& req_combo);
-    bool canCurrentModeSupportConcurrencyCombo(
-            const std::map<IfaceConcurrencyType, size_t>& req_combo);
-    bool canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type);
-    bool isValidModeId(ChipModeId mode_id);
-    bool isStaApConcurrencyAllowedInCurrentMode();
-    bool isDualStaConcurrencyAllowedInCurrentMode();
-    uint32_t startIdxOfApIface();
-    std::string getFirstActiveWlanIfaceName();
-    std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx);
-    std::string allocateApIfaceName();
-    std::vector<std::string> allocateBridgedApInstanceNames();
-    std::string allocateStaIfaceName();
-    bool writeRingbufferFilesInternal();
-    std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx);
-    void invalidateAndClearBridgedApAll();
-    void deleteApIface(const std::string& if_name);
-    bool findUsingNameFromBridgedApInstances(const std::string& name);
-    WifiStatus triggerSubsystemRestartInternal();
-    std::pair<WifiStatus, sp<V1_6::IWifiRttController>> createRttControllerInternal_1_6(
-            const sp<IWifiIface>& bound_iface);
-    std::pair<WifiStatus, std::vector<V1_6::WifiUsableChannel>> getUsableChannelsInternal_1_6(
-            WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask);
-    std::pair<WifiStatus, WifiRadioCombinationMatrix> getSupportedRadioCombinationsMatrixInternal();
-    std::pair<WifiStatus, std::vector<V1_6::IWifiChip::ChipMode>> getAvailableModesInternal_1_6();
-
-    ChipId chip_id_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
-    std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
-    std::vector<sp<WifiApIface>> ap_ifaces_;
-    std::vector<sp<WifiNanIface>> nan_ifaces_;
-    std::vector<sp<WifiP2pIface>> p2p_ifaces_;
-    std::vector<sp<WifiStaIface>> sta_ifaces_;
-    std::vector<sp<WifiRttController>> rtt_controllers_;
-    std::map<std::string, Ringbuffer> ringbuffer_map_;
-    bool is_valid_;
-    // Members pertaining to chip configuration.
-    uint32_t current_mode_id_;
-    std::mutex lock_t;
-    std::vector<V1_6::IWifiChip::ChipMode> modes_;
-    // The legacy ring buffer callback API has only a global callback
-    // registration mechanism. Use this to check if we have already
-    // registered a callback.
-    bool debug_ring_buffer_cb_registered_;
-    hidl_callback_util::HidlCallbackHandler<V1_4::IWifiChipEventCallback> event_cb_handler_;
-
-    const std::function<void(const std::string&)> subsystemCallbackHandler_;
-    std::map<std::string, std::vector<std::string>> br_ifaces_ap_instances_;
-    DISALLOW_COPY_AND_ASSIGN(WifiChip);
-};
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_CHIP_H_
diff --git a/wifi/1.6/default/wifi_feature_flags.cpp b/wifi/1.6/default/wifi_feature_flags.cpp
deleted file mode 100644
index e80a3cd..0000000
--- a/wifi/1.6/default/wifi_feature_flags.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2016 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 <string>
-
-#include <android-base/logging.h>
-#include <cutils/properties.h>
-
-#include "wifi_feature_flags.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace feature_flags {
-
-using V1_0::ChipModeId;
-using V1_0::IWifiChip;
-using V1_6::IfaceConcurrencyType;
-
-/* The chip may either have a single mode supporting any number of combinations,
- * or a fixed dual-mode (so it involves firmware loading to switch between
- * modes) setting. If there is a need to support more modes, it needs to be
- * implemented manually in WiFi HAL (see changeFirmwareMode in
- * WifiChip::handleChipConfiguration).
- *
- * Supported combinations are defined in device's makefile, for example:
- *    WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}},
- *    WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}}
- * What means:
- *    Interface concurrency combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface
- *                             operations.
- *    Interface concurrency combination 2: 1 STA and 2 AP concurrent iface operations.
- *
- * For backward compatibility, the following makefile flags can be used to
- * generate combinations list:
- *  - WIFI_HIDL_FEATURE_DUAL_INTERFACE
- *  - WIFI_HIDL_FEATURE_DISABLE_AP
- *  - WIFI_HIDL_FEATURE_AWARE
- * However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided.
- * With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with
- * two concurrency combinations:
- *    Interface Concurrency Combination 1: Will support 1 STA and 1 P2P or NAN (optional)
- *                             concurrent iface operations.
- *    Interface Concurrency Combination 2: Will support 1 STA and 1 AP concurrent
- *                             iface operations.
- *
- * The only dual-mode configuration supported is for alternating STA and AP
- * mode, that may involve firmware reloading. In such case, there are 2 separate
- * modes of operation with 1 concurrency combination each:
- *    Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional)
- *                       concurrent iface operations.
- *    Mode 2 (AP mode): Will support 1 AP iface operation.
- *
- * If Aware is enabled, the concurrency combination will be modified to support either
- * P2P or NAN in place of just P2P.
- */
-// clang-format off
-#ifdef WIFI_HAL_INTERFACE_COMBINATIONS
-constexpr ChipModeId kMainModeId = chip_mode_ids::kV3;
-#elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE)
-// former V2 (fixed dual interface) setup expressed as V3
-constexpr ChipModeId kMainModeId = chip_mode_ids::kV3;
-#  ifdef WIFI_HIDL_FEATURE_DISABLE_AP
-#    ifdef WIFI_HIDL_FEATURE_AWARE
-//     1 STA + 1 of (P2P or NAN)
-#      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
-#    else
-//     1 STA + 1 P2P
-#      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
-#    endif
-#  else
-#    ifdef WIFI_HIDL_FEATURE_AWARE
-//     (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
-#      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
-                                              {{{STA}, 1}, {{P2P, NAN}, 1}}
-#    else
-//     (1 STA + 1 AP) or (1 STA + 1 P2P)
-#      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
-                                              {{{STA}, 1}, {{P2P}, 1}}
-#    endif
-#  endif
-#else
-// V1 (fixed single interface, dual-mode chip)
-constexpr ChipModeId kMainModeId = chip_mode_ids::kV1Sta;
-#  ifdef WIFI_HIDL_FEATURE_AWARE
-//   1 STA + 1 of (P2P or NAN)
-#    define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
-#  else
-//   1 STA + 1 P2P
-#    define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
-#  endif
-
-#  ifndef WIFI_HIDL_FEATURE_DISABLE_AP
-#    define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}}
-#  endif
-#endif
-// clang-format on
-
-/**
- * Helper class to convert a collection of combination limits to a combination.
- *
- * The main point here is to simplify the syntax required by
- * WIFI_HAL_INTERFACE_COMBINATIONS.
- */
-struct ChipConcurrencyCombination
-    : public hidl_vec<V1_6::IWifiChip::ChipConcurrencyCombinationLimit> {
-    ChipConcurrencyCombination(
-            const std::initializer_list<V1_6::IWifiChip::ChipConcurrencyCombinationLimit> list)
-        : hidl_vec(list) {}
-
-    operator V1_6::IWifiChip::ChipConcurrencyCombination() const { return {*this}; }
-
-    static hidl_vec<V1_6::IWifiChip::ChipConcurrencyCombination> make_vec(
-            const std::initializer_list<ChipConcurrencyCombination> list) {
-        return hidl_vec<V1_6::IWifiChip::ChipConcurrencyCombination>(  //
-                std::begin(list), std::end(list));
-    }
-};
-
-#define STA IfaceConcurrencyType::STA
-#define AP IfaceConcurrencyType::AP
-#define AP_BRIDGED IfaceConcurrencyType::AP_BRIDGED
-#define P2P IfaceConcurrencyType::P2P
-#define NAN IfaceConcurrencyType::NAN
-static const std::vector<V1_6::IWifiChip::ChipMode> kChipModesPrimary{
-        {kMainModeId, ChipConcurrencyCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})},
-#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
-        {chip_mode_ids::kV1Ap,
-         ChipConcurrencyCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
-#endif
-};
-
-static const std::vector<V1_6::IWifiChip::ChipMode> kChipModesSecondary{
-#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
-        {chip_mode_ids::kV3,
-         ChipConcurrencyCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
-#endif
-};
-
-constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
-        "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
-// List of pre-defined concurrency combinations that can be enabled at runtime via
-// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
-// corresponding index value.
-static const std::vector<std::pair<std::string, std::vector<V1_6::IWifiChip::ChipMode>>>
-        kDebugChipModes{// Legacy combination - No STA/AP concurrencies.
-                        // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
-                        {"No STA/AP Concurrency",
-                         {{kMainModeId, ChipConcurrencyCombination::make_vec(
-                                                {{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
-
-                        // STA + AP concurrency
-                        // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
-                        {"STA + AP Concurrency",
-                         {{kMainModeId,
-                           ChipConcurrencyCombination::make_vec(
-                                   {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
-
-                        // STA + STA concurrency
-                        // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
-                        {"Dual STA Concurrency",
-                         {{kMainModeId,
-                           ChipConcurrencyCombination::make_vec(
-                                   {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
-
-                        // AP + AP + STA concurrency
-                        // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
-                        {"Dual AP Concurrency",
-                         {{kMainModeId,
-                           ChipConcurrencyCombination::make_vec(
-                                   {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
-
-                        // STA + STA concurrency and AP + AP + STA concurrency
-                        // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
-                        {"Dual STA & Dual AP Concurrency",
-                         {{kMainModeId,
-                           ChipConcurrencyCombination::make_vec(
-                                   {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
-
-                        // STA + STA concurrency
-                        // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
-                        {"Dual STA or STA plus single other interface",
-                         {{kMainModeId, ChipConcurrencyCombination::make_vec(
-                                                {{{{STA}, 1}, {{P2P, NAN, AP, AP_BRIDGED}, 1}},
-                                                 {{{STA}, 2}}})}}}};
-
-#undef STA
-#undef AP
-#undef P2P
-#undef NAN
-
-#ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
-#pragma message                                                                   \
-        "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
-        "'config_wifi_ap_randomization_supported' in "                            \
-        "frameworks/base/core/res/res/values/config.xml in the device overlay "   \
-        "instead"
-#endif  // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
-
-WifiFeatureFlags::WifiFeatureFlags() {}
-
-std::vector<V1_6::IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
-    std::array<char, PROPERTY_VALUE_MAX> buffer;
-    auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
-    // Debug property not set, use the device preset concurrency combination.
-    if (res <= 0) return kChipModesPrimary;
-
-    // Debug property set, use one of the debug preset concurrency combination.
-    unsigned long idx = std::stoul(buffer.data());
-    if (idx >= kDebugChipModes.size()) {
-        LOG(ERROR) << "Invalid index set in property: "
-                   << kDebugPresetInterfaceCombinationIdxProperty;
-        return kChipModesPrimary;
-    }
-    std::string name;
-    std::vector<V1_6::IWifiChip::ChipMode> chip_modes;
-    std::tie(name, chip_modes) = kDebugChipModes[idx];
-    LOG(INFO) << "Using debug chip mode: <" << name
-              << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
-    return chip_modes;
-}
-
-std::vector<V1_6::IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
-    return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
-}
-
-}  // namespace feature_flags
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_feature_flags.h b/wifi/1.6/default/wifi_feature_flags.h
deleted file mode 100644
index 1635341..0000000
--- a/wifi/1.6/default/wifi_feature_flags.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_FEATURE_FLAGS_H_
-#define WIFI_FEATURE_FLAGS_H_
-
-#include <android/hardware/wifi/1.6/IWifiChip.h>
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace feature_flags {
-
-namespace chip_mode_ids {
-// These mode ID's should be unique (even across combo versions). Refer to
-// handleChipConfiguration() for it's usage.
-constexpr V1_0::ChipModeId kInvalid = UINT32_MAX;
-// Mode ID's for V1
-constexpr V1_0::ChipModeId kV1Sta = 0;
-constexpr V1_0::ChipModeId kV1Ap = 1;
-// Mode ID for V3
-constexpr V1_0::ChipModeId kV3 = 3;
-}  // namespace chip_mode_ids
-
-class WifiFeatureFlags {
-  public:
-    WifiFeatureFlags();
-    virtual ~WifiFeatureFlags() = default;
-
-    virtual std::vector<V1_6::IWifiChip::ChipMode> getChipModes(bool is_primary);
-
-  private:
-    std::vector<V1_6::IWifiChip::ChipMode> getChipModesForPrimary();
-};
-
-}  // namespace feature_flags
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_FEATURE_FLAGS_H_
diff --git a/wifi/1.6/default/wifi_iface_util.cpp b/wifi/1.6/default/wifi_iface_util.cpp
deleted file mode 100644
index d55e4f8..0000000
--- a/wifi/1.6/default/wifi_iface_util.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <net/if.h>
-#include <cstddef>
-#include <iostream>
-#include <limits>
-#include <random>
-
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <private/android_filesystem_config.h>
-
-#undef NAN
-#include "wifi_iface_util.h"
-
-namespace {
-// Constants to set the local bit & clear the multicast bit.
-constexpr uint8_t kMacAddressMulticastMask = 0x01;
-constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02;
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace iface_util {
-
-WifiIfaceUtil::WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-                             const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
-    : iface_tool_(iface_tool),
-      legacy_hal_(legacy_hal),
-      random_mac_address_(nullptr),
-      event_handlers_map_() {}
-
-std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(const std::string& iface_name) {
-    return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str());
-}
-
-bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
-                                  const std::array<uint8_t, 6>& mac) {
-#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
-    legacy_hal::wifi_error legacy_status;
-    uint64_t legacy_feature_set;
-    std::tie(legacy_status, legacy_feature_set) =
-            legacy_hal_.lock()->getSupportedFeatureSet(iface_name);
-
-    if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
-        !iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) {
-        LOG(ERROR) << "SetUpState(false) failed.";
-        return false;
-    }
-#endif
-    bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac);
-#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
-    if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
-        !iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
-        LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready.";
-        // Wait for driver ready and try to set iface UP again
-        if (legacy_hal_.lock()->waitForDriverReady() != legacy_hal::WIFI_SUCCESS) {
-            LOG(ERROR) << "SetUpState(true) wait for driver ready failed.";
-            return false;
-        }
-        if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
-            LOG(ERROR) << "SetUpState(true) failed after retry.";
-            return false;
-        }
-    }
-#endif
-    IfaceEventHandlers event_handlers = {};
-    const auto it = event_handlers_map_.find(iface_name);
-    if (it != event_handlers_map_.end()) {
-        event_handlers = it->second;
-    }
-    if (event_handlers.on_state_toggle_off_on != nullptr) {
-        event_handlers.on_state_toggle_off_on(iface_name);
-    }
-    if (!success) {
-        LOG(ERROR) << "SetMacAddress failed on " << iface_name;
-    } else {
-        LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name;
-    }
-    return success;
-}
-
-std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
-    if (random_mac_address_) {
-        return *random_mac_address_.get();
-    }
-    random_mac_address_ = std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress());
-    return *random_mac_address_.get();
-}
-
-void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
-                                               IfaceEventHandlers handlers) {
-    event_handlers_map_[iface_name] = handlers;
-}
-
-void WifiIfaceUtil::unregisterIfaceEventHandlers(const std::string& iface_name) {
-    event_handlers_map_.erase(iface_name);
-}
-
-std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
-    std::array<uint8_t, 6> address = {};
-    std::random_device rd;
-    std::default_random_engine engine(rd());
-    std::uniform_int_distribution<uint8_t> dist(std::numeric_limits<uint8_t>::min(),
-                                                std::numeric_limits<uint8_t>::max());
-    for (size_t i = 0; i < address.size(); i++) {
-        address[i] = dist(engine);
-    }
-    // Set the local bit and clear the multicast bit.
-    address[0] |= kMacAddressLocallyAssignedMask;
-    address[0] &= ~kMacAddressMulticastMask;
-    return address;
-}
-
-bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) {
-    if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) {
-        LOG(ERROR) << "SetUpState to " << request_up << " failed";
-        return false;
-    }
-    return true;
-}
-
-unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) {
-    return if_nametoindex(iface_name.c_str());
-}
-
-bool WifiIfaceUtil::createBridge(const std::string& br_name) {
-    if (!iface_tool_.lock()->createBridge(br_name)) {
-        return false;
-    }
-
-    if (!iface_tool_.lock()->SetUpState(br_name.c_str(), true)) {
-        LOG(ERROR) << "bridge SetUpState(true) failed.";
-    }
-    return true;
-}
-
-bool WifiIfaceUtil::deleteBridge(const std::string& br_name) {
-    if (!iface_tool_.lock()->SetUpState(br_name.c_str(), false)) {
-        LOG(INFO) << "SetUpState(false) failed for bridge=" << br_name.c_str();
-    }
-
-    return iface_tool_.lock()->deleteBridge(br_name);
-}
-
-bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, const std::string& if_name) {
-    return iface_tool_.lock()->addIfaceToBridge(br_name, if_name);
-}
-
-bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, const std::string& if_name) {
-    return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name);
-}
-
-}  // namespace iface_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_iface_util.h b/wifi/1.6/default/wifi_iface_util.h
deleted file mode 100644
index c5db5de..0000000
--- a/wifi/1.6/default/wifi_iface_util.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef WIFI_IFACE_UTIL_H_
-#define WIFI_IFACE_UTIL_H_
-
-#include <wifi_system/interface_tool.h>
-
-#include <android/hardware/wifi/1.0/IWifi.h>
-
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace iface_util {
-
-// Iface event handlers.
-struct IfaceEventHandlers {
-    // Callback to be invoked when the iface is set down & up for MAC address
-    // change.
-    std::function<void(const std::string& iface_name)> on_state_toggle_off_on;
-};
-
-/**
- * Util class for common iface operations.
- */
-class WifiIfaceUtil {
-  public:
-    WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-                  const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
-    virtual ~WifiIfaceUtil() = default;
-
-    virtual std::array<uint8_t, 6> getFactoryMacAddress(const std::string& iface_name);
-    virtual bool setMacAddress(const std::string& iface_name, const std::array<uint8_t, 6>& mac);
-    // Get or create a random MAC address. The MAC address returned from
-    // this method will remain the same throughout the lifetime of the HAL
-    // daemon. (So, changes on every reboot)
-    virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress();
-
-    // Register for any iface event callbacks for the provided interface.
-    virtual void registerIfaceEventHandlers(const std::string& iface_name,
-                                            IfaceEventHandlers handlers);
-    virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
-    virtual bool setUpState(const std::string& iface_name, bool request_up);
-    virtual unsigned ifNameToIndex(const std::string& iface_name);
-
-    virtual bool createBridge(const std::string& br_name);
-
-    virtual bool deleteBridge(const std::string& br_name);
-
-    virtual bool addIfaceToBridge(const std::string& br_name, const std::string& if_name);
-
-    virtual bool removeIfaceFromBridge(const std::string& br_name, const std::string& if_name);
-    // Get a random MAC address.
-    virtual std::array<uint8_t, 6> createRandomMacAddress();
-
-  private:
-    std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
-    std::map<std::string, IfaceEventHandlers> event_handlers_map_;
-};
-
-}  // namespace iface_util
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_IFACE_UTIL_H_
diff --git a/wifi/1.6/default/wifi_legacy_hal.cpp b/wifi/1.6/default/wifi_legacy_hal.cpp
deleted file mode 100644
index 2211897..0000000
--- a/wifi/1.6/default/wifi_legacy_hal.cpp
+++ /dev/null
@@ -1,1635 +0,0 @@
-/*
- * Copyright (C) 2016 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 <array>
-#include <chrono>
-
-#include <android-base/logging.h>
-#include <cutils/properties.h>
-#include <net/if.h>
-
-#include "hidl_sync_util.h"
-#include "wifi_legacy_hal.h"
-#include "wifi_legacy_hal_stubs.h"
-
-namespace {
-// Constants ported over from the legacy HAL calling code
-// (com_android_server_wifi_WifiNative.cpp). This will all be thrown
-// away when this shim layer is replaced by the real vendor
-// implementation.
-static constexpr uint32_t kMaxVersionStringLength = 256;
-static constexpr uint32_t kMaxCachedGscanResults = 64;
-static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
-static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
-static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
-static constexpr uint32_t kMaxRingBuffers = 10;
-static constexpr uint32_t kMaxWifiUsableChannels = 256;
-static constexpr uint32_t kMaxSupportedRadioCombinationsMatrixLength = 256;
-// need a long timeout (1000ms) for chips that unload their driver.
-static constexpr uint32_t kMaxStopCompleteWaitMs = 1000;
-static constexpr char kDriverPropName[] = "wlan.driver.status";
-
-// Helper function to create a non-const char* for legacy Hal API's.
-std::vector<char> makeCharVec(const std::string& str) {
-    std::vector<char> vec(str.size() + 1);
-    vec.assign(str.begin(), str.end());
-    vec.push_back('\0');
-    return vec;
-}
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace legacy_hal {
-
-// Legacy HAL functions accept "C" style function pointers, so use global
-// functions to pass to the legacy HAL function and store the corresponding
-// std::function methods to be invoked.
-//
-// Callback to be invoked once |stop| is complete
-std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
-void onAsyncStopComplete(wifi_handle handle) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_stop_complete_internal_callback) {
-        on_stop_complete_internal_callback(handle);
-        // Invalidate this callback since we don't want this firing again.
-        on_stop_complete_internal_callback = nullptr;
-    }
-}
-
-// Callback to be invoked for driver dump.
-std::function<void(char*, int)> on_driver_memory_dump_internal_callback;
-void onSyncDriverMemoryDump(char* buffer, int buffer_size) {
-    if (on_driver_memory_dump_internal_callback) {
-        on_driver_memory_dump_internal_callback(buffer, buffer_size);
-    }
-}
-
-// Callback to be invoked for firmware dump.
-std::function<void(char*, int)> on_firmware_memory_dump_internal_callback;
-void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) {
-    if (on_firmware_memory_dump_internal_callback) {
-        on_firmware_memory_dump_internal_callback(buffer, buffer_size);
-    }
-}
-
-// Callback to be invoked for Gscan events.
-std::function<void(wifi_request_id, wifi_scan_event)> on_gscan_event_internal_callback;
-void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_gscan_event_internal_callback) {
-        on_gscan_event_internal_callback(id, event);
-    }
-}
-
-// Callback to be invoked for Gscan full results.
-std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
-        on_gscan_full_result_internal_callback;
-void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result,
-                            uint32_t buckets_scanned) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_gscan_full_result_internal_callback) {
-        on_gscan_full_result_internal_callback(id, result, buckets_scanned);
-    }
-}
-
-// Callback to be invoked for link layer stats results.
-std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
-        on_link_layer_stats_result_internal_callback;
-void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios,
-                                wifi_radio_stat* radio_stat) {
-    if (on_link_layer_stats_result_internal_callback) {
-        on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, radio_stat);
-    }
-}
-
-// Callback to be invoked for rssi threshold breach.
-std::function<void((wifi_request_id, uint8_t*, int8_t))>
-        on_rssi_threshold_breached_internal_callback;
-void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, int8_t rssi) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_rssi_threshold_breached_internal_callback) {
-        on_rssi_threshold_breached_internal_callback(id, bssid, rssi);
-    }
-}
-
-// Callback to be invoked for ring buffer data indication.
-std::function<void(char*, char*, int, wifi_ring_buffer_status*)>
-        on_ring_buffer_data_internal_callback;
-void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size,
-                           wifi_ring_buffer_status* status) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_ring_buffer_data_internal_callback) {
-        on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, status);
-    }
-}
-
-// Callback to be invoked for error alert indication.
-std::function<void(wifi_request_id, char*, int, int)> on_error_alert_internal_callback;
-void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, int err_code) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_error_alert_internal_callback) {
-        on_error_alert_internal_callback(id, buffer, buffer_size, err_code);
-    }
-}
-
-// Callback to be invoked for radio mode change indication.
-std::function<void(wifi_request_id, uint32_t, wifi_mac_info*)>
-        on_radio_mode_change_internal_callback;
-void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, wifi_mac_info* mac_infos) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_radio_mode_change_internal_callback) {
-        on_radio_mode_change_internal_callback(id, num_macs, mac_infos);
-    }
-}
-
-// Callback to be invoked to report subsystem restart
-std::function<void(const char*)> on_subsystem_restart_internal_callback;
-void onAsyncSubsystemRestart(const char* error) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_subsystem_restart_internal_callback) {
-        on_subsystem_restart_internal_callback(error);
-    }
-}
-
-// Callback to be invoked for rtt results results.
-std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result* rtt_results[])>
-        on_rtt_results_internal_callback;
-void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_rtt_results_internal_callback) {
-        on_rtt_results_internal_callback(id, num_results, rtt_results);
-        on_rtt_results_internal_callback = nullptr;
-    }
-}
-
-// Callbacks for the various NAN operations.
-// NOTE: These have very little conversions to perform before invoking the user
-// callbacks.
-// So, handle all of them here directly to avoid adding an unnecessary layer.
-std::function<void(transaction_id, const NanResponseMsg&)> on_nan_notify_response_user_callback;
-void onAysncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_notify_response_user_callback && msg) {
-        on_nan_notify_response_user_callback(id, *msg);
-    }
-}
-
-std::function<void(const NanPublishRepliedInd&)> on_nan_event_publish_replied_user_callback;
-void onAysncNanEventPublishReplied(NanPublishRepliedInd* /* event */) {
-    LOG(ERROR) << "onAysncNanEventPublishReplied triggered";
-}
-
-std::function<void(const NanPublishTerminatedInd&)> on_nan_event_publish_terminated_user_callback;
-void onAysncNanEventPublishTerminated(NanPublishTerminatedInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_publish_terminated_user_callback && event) {
-        on_nan_event_publish_terminated_user_callback(*event);
-    }
-}
-
-std::function<void(const NanMatchInd&)> on_nan_event_match_user_callback;
-void onAysncNanEventMatch(NanMatchInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_match_user_callback && event) {
-        on_nan_event_match_user_callback(*event);
-    }
-}
-
-std::function<void(const NanMatchExpiredInd&)> on_nan_event_match_expired_user_callback;
-void onAysncNanEventMatchExpired(NanMatchExpiredInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_match_expired_user_callback && event) {
-        on_nan_event_match_expired_user_callback(*event);
-    }
-}
-
-std::function<void(const NanSubscribeTerminatedInd&)>
-        on_nan_event_subscribe_terminated_user_callback;
-void onAysncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_subscribe_terminated_user_callback && event) {
-        on_nan_event_subscribe_terminated_user_callback(*event);
-    }
-}
-
-std::function<void(const NanFollowupInd&)> on_nan_event_followup_user_callback;
-void onAysncNanEventFollowup(NanFollowupInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_followup_user_callback && event) {
-        on_nan_event_followup_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDiscEngEventInd&)> on_nan_event_disc_eng_event_user_callback;
-void onAysncNanEventDiscEngEvent(NanDiscEngEventInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_disc_eng_event_user_callback && event) {
-        on_nan_event_disc_eng_event_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDisabledInd&)> on_nan_event_disabled_user_callback;
-void onAysncNanEventDisabled(NanDisabledInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_disabled_user_callback && event) {
-        on_nan_event_disabled_user_callback(*event);
-    }
-}
-
-std::function<void(const NanTCAInd&)> on_nan_event_tca_user_callback;
-void onAysncNanEventTca(NanTCAInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_tca_user_callback && event) {
-        on_nan_event_tca_user_callback(*event);
-    }
-}
-
-std::function<void(const NanBeaconSdfPayloadInd&)> on_nan_event_beacon_sdf_payload_user_callback;
-void onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_beacon_sdf_payload_user_callback && event) {
-        on_nan_event_beacon_sdf_payload_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDataPathRequestInd&)> on_nan_event_data_path_request_user_callback;
-void onAysncNanEventDataPathRequest(NanDataPathRequestInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_data_path_request_user_callback && event) {
-        on_nan_event_data_path_request_user_callback(*event);
-    }
-}
-std::function<void(const NanDataPathConfirmInd&)> on_nan_event_data_path_confirm_user_callback;
-void onAysncNanEventDataPathConfirm(NanDataPathConfirmInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_data_path_confirm_user_callback && event) {
-        on_nan_event_data_path_confirm_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDataPathEndInd&)> on_nan_event_data_path_end_user_callback;
-void onAysncNanEventDataPathEnd(NanDataPathEndInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_data_path_end_user_callback && event) {
-        on_nan_event_data_path_end_user_callback(*event);
-    }
-}
-
-std::function<void(const NanTransmitFollowupInd&)> on_nan_event_transmit_follow_up_user_callback;
-void onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_transmit_follow_up_user_callback && event) {
-        on_nan_event_transmit_follow_up_user_callback(*event);
-    }
-}
-
-std::function<void(const NanRangeRequestInd&)> on_nan_event_range_request_user_callback;
-void onAysncNanEventRangeRequest(NanRangeRequestInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_range_request_user_callback && event) {
-        on_nan_event_range_request_user_callback(*event);
-    }
-}
-
-std::function<void(const NanRangeReportInd&)> on_nan_event_range_report_user_callback;
-void onAysncNanEventRangeReport(NanRangeReportInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_range_report_user_callback && event) {
-        on_nan_event_range_report_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDataPathScheduleUpdateInd&)> on_nan_event_schedule_update_user_callback;
-void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_schedule_update_user_callback && event) {
-        on_nan_event_schedule_update_user_callback(*event);
-    }
-}
-
-// Callbacks for the various TWT operations.
-std::function<void(const TwtSetupResponse&)> on_twt_event_setup_response_callback;
-void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_twt_event_setup_response_callback && event) {
-        on_twt_event_setup_response_callback(*event);
-    }
-}
-
-std::function<void(const TwtTeardownCompletion&)> on_twt_event_teardown_completion_callback;
-void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_twt_event_teardown_completion_callback && event) {
-        on_twt_event_teardown_completion_callback(*event);
-    }
-}
-
-std::function<void(const TwtInfoFrameReceived&)> on_twt_event_info_frame_received_callback;
-void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_twt_event_info_frame_received_callback && event) {
-        on_twt_event_info_frame_received_callback(*event);
-    }
-}
-
-std::function<void(const TwtDeviceNotify&)> on_twt_event_device_notify_callback;
-void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_twt_event_device_notify_callback && event) {
-        on_twt_event_device_notify_callback(*event);
-    }
-}
-
-// Callback to report current CHRE NAN state
-std::function<void(chre_nan_rtt_state)> on_chre_nan_rtt_internal_callback;
-void onAsyncChreNanRttState(chre_nan_rtt_state state) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_chre_nan_rtt_internal_callback) {
-        on_chre_nan_rtt_internal_callback(state);
-    }
-}
-
-// End of the free-standing "C" style callbacks.
-
-WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-                             const wifi_hal_fn& fn, bool is_primary)
-    : global_func_table_(fn),
-      global_handle_(nullptr),
-      awaiting_event_loop_termination_(false),
-      is_started_(false),
-      iface_tool_(iface_tool),
-      is_primary_(is_primary) {}
-
-wifi_error WifiLegacyHal::initialize() {
-    LOG(DEBUG) << "Initialize legacy HAL";
-    // this now does nothing, since HAL function table is provided
-    // to the constructor
-    return WIFI_SUCCESS;
-}
-
-wifi_error WifiLegacyHal::start() {
-    // Ensure that we're starting in a good state.
-    CHECK(global_func_table_.wifi_initialize && !global_handle_ && iface_name_to_handle_.empty() &&
-          !awaiting_event_loop_termination_);
-    if (is_started_) {
-        LOG(DEBUG) << "Legacy HAL already started";
-        return WIFI_SUCCESS;
-    }
-    LOG(DEBUG) << "Waiting for the driver ready";
-    wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
-    if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) {
-        LOG(ERROR) << "Failed or timed out awaiting driver ready";
-        return status;
-    }
-
-    if (is_primary_) {
-        property_set(kDriverPropName, "ok");
-
-        if (!iface_tool_.lock()->SetWifiUpState(true)) {
-            LOG(ERROR) << "Failed to set WiFi interface up";
-            return WIFI_ERROR_UNKNOWN;
-        }
-    }
-
-    LOG(DEBUG) << "Starting legacy HAL";
-    status = global_func_table_.wifi_initialize(&global_handle_);
-    if (status != WIFI_SUCCESS || !global_handle_) {
-        LOG(ERROR) << "Failed to retrieve global handle";
-        return status;
-    }
-    std::thread(&WifiLegacyHal::runEventLoop, this).detach();
-    status = retrieveIfaceHandles();
-    if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) {
-        LOG(ERROR) << "Failed to retrieve wlan interface handle";
-        return status;
-    }
-    LOG(DEBUG) << "Legacy HAL start complete";
-    is_started_ = true;
-    return WIFI_SUCCESS;
-}
-
-wifi_error WifiLegacyHal::stop(
-        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
-        const std::function<void()>& on_stop_complete_user_callback) {
-    if (!is_started_) {
-        LOG(DEBUG) << "Legacy HAL already stopped";
-        on_stop_complete_user_callback();
-        return WIFI_SUCCESS;
-    }
-    LOG(DEBUG) << "Stopping legacy HAL";
-    on_stop_complete_internal_callback = [on_stop_complete_user_callback,
-                                          this](wifi_handle handle) {
-        CHECK_EQ(global_handle_, handle) << "Handle mismatch";
-        LOG(INFO) << "Legacy HAL stop complete callback received";
-        // Invalidate all the internal pointers now that the HAL is
-        // stopped.
-        invalidate();
-        if (is_primary_) iface_tool_.lock()->SetWifiUpState(false);
-        on_stop_complete_user_callback();
-        is_started_ = false;
-    };
-    awaiting_event_loop_termination_ = true;
-    global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
-    const auto status =
-            stop_wait_cv_.wait_for(*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
-                                   [this] { return !awaiting_event_loop_termination_; });
-    if (!status) {
-        LOG(ERROR) << "Legacy HAL stop failed or timed out";
-        return WIFI_ERROR_UNKNOWN;
-    }
-    LOG(DEBUG) << "Legacy HAL stop complete";
-    return WIFI_SUCCESS;
-}
-
-bool WifiLegacyHal::isStarted() {
-    return is_started_;
-}
-
-wifi_error WifiLegacyHal::waitForDriverReady() {
-    return global_func_table_.wifi_wait_for_driver_ready();
-}
-
-std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(const std::string& iface_name) {
-    std::array<char, kMaxVersionStringLength> buffer;
-    buffer.fill(0);
-    wifi_error status = global_func_table_.wifi_get_driver_version(getIfaceHandle(iface_name),
-                                                                   buffer.data(), buffer.size());
-    return {status, buffer.data()};
-}
-
-std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion(
-        const std::string& iface_name) {
-    std::array<char, kMaxVersionStringLength> buffer;
-    buffer.fill(0);
-    wifi_error status = global_func_table_.wifi_get_firmware_version(getIfaceHandle(iface_name),
-                                                                     buffer.data(), buffer.size());
-    return {status, buffer.data()};
-}
-
-std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestDriverMemoryDump(
-        const std::string& iface_name) {
-    std::vector<uint8_t> driver_dump;
-    on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, int buffer_size) {
-        driver_dump.insert(driver_dump.end(), reinterpret_cast<uint8_t*>(buffer),
-                           reinterpret_cast<uint8_t*>(buffer) + buffer_size);
-    };
-    wifi_error status = global_func_table_.wifi_get_driver_memory_dump(getIfaceHandle(iface_name),
-                                                                       {onSyncDriverMemoryDump});
-    on_driver_memory_dump_internal_callback = nullptr;
-    return {status, std::move(driver_dump)};
-}
-
-std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestFirmwareMemoryDump(
-        const std::string& iface_name) {
-    std::vector<uint8_t> firmware_dump;
-    on_firmware_memory_dump_internal_callback = [&firmware_dump](char* buffer, int buffer_size) {
-        firmware_dump.insert(firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer),
-                             reinterpret_cast<uint8_t*>(buffer) + buffer_size);
-    };
-    wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
-            getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump});
-    on_firmware_memory_dump_internal_callback = nullptr;
-    return {status, std::move(firmware_dump)};
-}
-
-std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet(
-        const std::string& iface_name) {
-    feature_set set = 0, chip_set = 0;
-    wifi_error status = WIFI_SUCCESS;
-
-    static_assert(sizeof(set) == sizeof(uint64_t),
-                  "Some feature_flags can not be represented in output");
-    wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
-
-    global_func_table_.wifi_get_chip_feature_set(
-            global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */
-
-    if (iface_handle) {
-        status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set);
-    }
-    return {status, static_cast<uint64_t>(set | chip_set)};
-}
-
-std::pair<wifi_error, PacketFilterCapabilities> WifiLegacyHal::getPacketFilterCapabilities(
-        const std::string& iface_name) {
-    PacketFilterCapabilities caps;
-    wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
-            getIfaceHandle(iface_name), &caps.version, &caps.max_len);
-    return {status, caps};
-}
-
-wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name,
-                                          const std::vector<uint8_t>& program) {
-    return global_func_table_.wifi_set_packet_filter(getIfaceHandle(iface_name), program.data(),
-                                                     program.size());
-}
-
-std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::readApfPacketFilterData(
-        const std::string& iface_name) {
-    PacketFilterCapabilities caps;
-    wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
-            getIfaceHandle(iface_name), &caps.version, &caps.max_len);
-    if (status != WIFI_SUCCESS) {
-        return {status, {}};
-    }
-
-    // Size the buffer to read the entire program & work memory.
-    std::vector<uint8_t> buffer(caps.max_len);
-
-    status = global_func_table_.wifi_read_packet_filter(
-            getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), buffer.size());
-    return {status, move(buffer)};
-}
-
-std::pair<wifi_error, wifi_gscan_capabilities> WifiLegacyHal::getGscanCapabilities(
-        const std::string& iface_name) {
-    wifi_gscan_capabilities caps;
-    wifi_error status =
-            global_func_table_.wifi_get_gscan_capabilities(getIfaceHandle(iface_name), &caps);
-    return {status, caps};
-}
-
-wifi_error WifiLegacyHal::startGscan(
-        const std::string& iface_name, wifi_request_id id, const wifi_scan_cmd_params& params,
-        const std::function<void(wifi_request_id)>& on_failure_user_callback,
-        const on_gscan_results_callback& on_results_user_callback,
-        const on_gscan_full_result_callback& on_full_result_user_callback) {
-    // If there is already an ongoing background scan, reject new scan requests.
-    if (on_gscan_event_internal_callback || on_gscan_full_result_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-
-    // This callback will be used to either trigger |on_results_user_callback|
-    // or |on_failure_user_callback|.
-    on_gscan_event_internal_callback = [iface_name, on_failure_user_callback,
-                                        on_results_user_callback,
-                                        this](wifi_request_id id, wifi_scan_event event) {
-        switch (event) {
-            case WIFI_SCAN_RESULTS_AVAILABLE:
-            case WIFI_SCAN_THRESHOLD_NUM_SCANS:
-            case WIFI_SCAN_THRESHOLD_PERCENT: {
-                wifi_error status;
-                std::vector<wifi_cached_scan_results> cached_scan_results;
-                std::tie(status, cached_scan_results) = getGscanCachedResults(iface_name);
-                if (status == WIFI_SUCCESS) {
-                    on_results_user_callback(id, cached_scan_results);
-                    return;
-                }
-                FALLTHROUGH_INTENDED;
-            }
-            // Fall through if failed. Failure to retrieve cached scan
-            // results should trigger a background scan failure.
-            case WIFI_SCAN_FAILED:
-                on_failure_user_callback(id);
-                on_gscan_event_internal_callback = nullptr;
-                on_gscan_full_result_internal_callback = nullptr;
-                return;
-        }
-        LOG(FATAL) << "Unexpected gscan event received: " << event;
-    };
-
-    on_gscan_full_result_internal_callback = [on_full_result_user_callback](
-                                                     wifi_request_id id, wifi_scan_result* result,
-                                                     uint32_t buckets_scanned) {
-        if (result) {
-            on_full_result_user_callback(id, result, buckets_scanned);
-        }
-    };
-
-    wifi_scan_result_handler handler = {onAsyncGscanFullResult, onAsyncGscanEvent};
-    wifi_error status =
-            global_func_table_.wifi_start_gscan(id, getIfaceHandle(iface_name), params, handler);
-    if (status != WIFI_SUCCESS) {
-        on_gscan_event_internal_callback = nullptr;
-        on_gscan_full_result_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, wifi_request_id id) {
-    // If there is no an ongoing background scan, reject stop requests.
-    // TODO(b/32337212): This needs to be handled by the HIDL object because we
-    // need to return the NOT_STARTED error code.
-    if (!on_gscan_event_internal_callback && !on_gscan_full_result_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    wifi_error status = global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name));
-    // If the request Id is wrong, don't stop the ongoing background scan. Any
-    // other error should be treated as the end of background scan.
-    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
-        on_gscan_event_internal_callback = nullptr;
-        on_gscan_full_result_internal_callback = nullptr;
-    }
-    return status;
-}
-
-std::pair<wifi_error, std::vector<uint32_t>> WifiLegacyHal::getValidFrequenciesForBand(
-        const std::string& iface_name, wifi_band band) {
-    static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
-                  "Wifi Channel cannot be represented in output");
-    std::vector<uint32_t> freqs;
-    freqs.resize(kMaxGscanFrequenciesForBand);
-    int32_t num_freqs = 0;
-    wifi_error status = global_func_table_.wifi_get_valid_channels(
-            getIfaceHandle(iface_name), band, freqs.size(),
-            reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs);
-    CHECK(num_freqs >= 0 && static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
-    freqs.resize(num_freqs);
-    return {status, std::move(freqs)};
-}
-
-wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, bool dfs_on) {
-    return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), dfs_on ? 0 : 1);
-}
-
-wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, bool debug) {
-    wifi_link_layer_params params;
-    params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
-    params.aggressive_statistics_gathering = debug;
-    return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), params);
-}
-
-wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) {
-    // TODO: Do we care about these responses?
-    uint32_t clear_mask_rsp;
-    uint8_t stop_rsp;
-    return global_func_table_.wifi_clear_link_stats(getIfaceHandle(iface_name), 0xFFFFFFFF,
-                                                    &clear_mask_rsp, 1, &stop_rsp);
-}
-
-std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats(
-        const std::string& iface_name) {
-    LinkLayerStats link_stats{};
-    LinkLayerStats* link_stats_ptr = &link_stats;
-
-    on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
-                                                           wifi_request_id /* id */,
-                                                           wifi_iface_stat* iface_stats_ptr,
-                                                           int num_radios,
-                                                           wifi_radio_stat* radio_stats_ptr) {
-        wifi_radio_stat* l_radio_stats_ptr;
-        wifi_peer_info* l_peer_info_stats_ptr;
-
-        if (iface_stats_ptr != nullptr) {
-            link_stats_ptr->iface = *iface_stats_ptr;
-            l_peer_info_stats_ptr = iface_stats_ptr->peer_info;
-            for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) {
-                WifiPeerInfo peer;
-                peer.peer_info = *l_peer_info_stats_ptr;
-                if (l_peer_info_stats_ptr->num_rate > 0) {
-                    /* Copy the rate stats */
-                    peer.rate_stats.assign(
-                            l_peer_info_stats_ptr->rate_stats,
-                            l_peer_info_stats_ptr->rate_stats + l_peer_info_stats_ptr->num_rate);
-                }
-                peer.peer_info.num_rate = 0;
-                link_stats_ptr->peers.push_back(peer);
-                l_peer_info_stats_ptr =
-                        (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + sizeof(wifi_peer_info) +
-                                          (sizeof(wifi_rate_stat) *
-                                           l_peer_info_stats_ptr->num_rate));
-            }
-            link_stats_ptr->iface.num_peers = 0;
-        } else {
-            LOG(ERROR) << "Invalid iface stats in link layer stats";
-        }
-        if (num_radios <= 0 || radio_stats_ptr == nullptr) {
-            LOG(ERROR) << "Invalid radio stats in link layer stats";
-            return;
-        }
-        l_radio_stats_ptr = radio_stats_ptr;
-        for (int i = 0; i < num_radios; i++) {
-            LinkLayerRadioStats radio;
-
-            radio.stats = *l_radio_stats_ptr;
-            // Copy over the tx level array to the separate vector.
-            if (l_radio_stats_ptr->num_tx_levels > 0 &&
-                l_radio_stats_ptr->tx_time_per_levels != nullptr) {
-                radio.tx_time_per_levels.assign(
-                        l_radio_stats_ptr->tx_time_per_levels,
-                        l_radio_stats_ptr->tx_time_per_levels + l_radio_stats_ptr->num_tx_levels);
-            }
-            radio.stats.num_tx_levels = 0;
-            radio.stats.tx_time_per_levels = nullptr;
-            /* Copy over the channel stat to separate vector */
-            if (l_radio_stats_ptr->num_channels > 0) {
-                /* Copy the channel stats */
-                radio.channel_stats.assign(
-                        l_radio_stats_ptr->channels,
-                        l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
-            }
-            link_stats_ptr->radios.push_back(radio);
-            l_radio_stats_ptr =
-                    (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
-                                       (sizeof(wifi_channel_stat) *
-                                        l_radio_stats_ptr->num_channels));
-        }
-    };
-
-    wifi_error status = global_func_table_.wifi_get_link_stats(0, getIfaceHandle(iface_name),
-                                                               {onSyncLinkLayerStatsResult});
-    on_link_layer_stats_result_internal_callback = nullptr;
-    return {status, link_stats};
-}
-
-wifi_error WifiLegacyHal::startRssiMonitoring(
-        const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
-        const on_rssi_threshold_breached_callback& on_threshold_breached_user_callback) {
-    if (on_rssi_threshold_breached_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_rssi_threshold_breached_internal_callback = [on_threshold_breached_user_callback](
-                                                           wifi_request_id id, uint8_t* bssid_ptr,
-                                                           int8_t rssi) {
-        if (!bssid_ptr) {
-            return;
-        }
-        std::array<uint8_t, 6> bssid_arr;
-        // |bssid_ptr| pointer is assumed to have 6 bytes for the mac
-        // address.
-        std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
-        on_threshold_breached_user_callback(id, bssid_arr, rssi);
-    };
-    wifi_error status = global_func_table_.wifi_start_rssi_monitoring(
-            id, getIfaceHandle(iface_name), max_rssi, min_rssi, {onAsyncRssiThresholdBreached});
-    if (status != WIFI_SUCCESS) {
-        on_rssi_threshold_breached_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, wifi_request_id id) {
-    if (!on_rssi_threshold_breached_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    wifi_error status =
-            global_func_table_.wifi_stop_rssi_monitoring(id, getIfaceHandle(iface_name));
-    // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
-    // other error should be treated as the end of background scan.
-    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
-        on_rssi_threshold_breached_internal_callback = nullptr;
-    }
-    return status;
-}
-
-std::pair<wifi_error, wifi_roaming_capabilities> WifiLegacyHal::getRoamingCapabilities(
-        const std::string& iface_name) {
-    wifi_roaming_capabilities caps;
-    wifi_error status =
-            global_func_table_.wifi_get_roaming_capabilities(getIfaceHandle(iface_name), &caps);
-    return {status, caps};
-}
-
-wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name,
-                                           const wifi_roaming_config& config) {
-    wifi_roaming_config config_internal = config;
-    return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), &config_internal);
-}
-
-wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name,
-                                                fw_roaming_state_t state) {
-    return global_func_table_.wifi_enable_firmware_roaming(getIfaceHandle(iface_name), state);
-}
-
-wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, bool enable) {
-    return global_func_table_.wifi_configure_nd_offload(getIfaceHandle(iface_name), enable);
-}
-
-wifi_error WifiLegacyHal::startSendingOffloadedPacket(const std::string& iface_name,
-                                                      uint32_t cmd_id, uint16_t ether_type,
-                                                      const std::vector<uint8_t>& ip_packet_data,
-                                                      const std::array<uint8_t, 6>& src_address,
-                                                      const std::array<uint8_t, 6>& dst_address,
-                                                      uint32_t period_in_ms) {
-    std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
-    std::vector<uint8_t> src_address_internal(src_address.data(),
-                                              src_address.data() + src_address.size());
-    std::vector<uint8_t> dst_address_internal(dst_address.data(),
-                                              dst_address.data() + dst_address.size());
-    return global_func_table_.wifi_start_sending_offloaded_packet(
-            cmd_id, getIfaceHandle(iface_name), ether_type, ip_packet_data_internal.data(),
-            ip_packet_data_internal.size(), src_address_internal.data(),
-            dst_address_internal.data(), period_in_ms);
-}
-
-wifi_error WifiLegacyHal::stopSendingOffloadedPacket(const std::string& iface_name,
-                                                     uint32_t cmd_id) {
-    return global_func_table_.wifi_stop_sending_offloaded_packet(cmd_id,
-                                                                 getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
-                                                wifi_power_scenario scenario) {
-    return global_func_table_.wifi_select_tx_power_scenario(getIfaceHandle(iface_name), scenario);
-}
-
-wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) {
-    return global_func_table_.wifi_reset_tx_power_scenario(getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, wifi_latency_mode mode) {
-    return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), mode);
-}
-
-wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode,
-                                                   uint32_t completion_window) {
-    return global_func_table_.wifi_set_thermal_mitigation_mode(global_handle_, mode,
-                                                               completion_window);
-}
-
-wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
-                                                         uint32_t access_category) {
-    return global_func_table_.wifi_map_dscp_access_category(global_handle_, start, end,
-                                                            access_category);
-}
-
-wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() {
-    return global_func_table_.wifi_reset_dscp_mapping(global_handle_);
-}
-
-std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet(
-        const std::string& iface_name) {
-    uint32_t supported_feature_flags = 0;
-    wifi_error status = WIFI_SUCCESS;
-
-    wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
-
-    if (iface_handle) {
-        status = global_func_table_.wifi_get_logger_supported_feature_set(iface_handle,
-                                                                          &supported_feature_flags);
-    }
-    return {status, supported_feature_flags};
-}
-
-wifi_error WifiLegacyHal::startPktFateMonitoring(const std::string& iface_name) {
-    return global_func_table_.wifi_start_pkt_fate_monitoring(getIfaceHandle(iface_name));
-}
-
-std::pair<wifi_error, std::vector<wifi_tx_report>> WifiLegacyHal::getTxPktFates(
-        const std::string& iface_name) {
-    std::vector<wifi_tx_report> tx_pkt_fates;
-    tx_pkt_fates.resize(MAX_FATE_LOG_LEN);
-    size_t num_fates = 0;
-    wifi_error status = global_func_table_.wifi_get_tx_pkt_fates(
-            getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), &num_fates);
-    CHECK(num_fates <= MAX_FATE_LOG_LEN);
-    tx_pkt_fates.resize(num_fates);
-    return {status, std::move(tx_pkt_fates)};
-}
-
-std::pair<wifi_error, std::vector<wifi_rx_report>> WifiLegacyHal::getRxPktFates(
-        const std::string& iface_name) {
-    std::vector<wifi_rx_report> rx_pkt_fates;
-    rx_pkt_fates.resize(MAX_FATE_LOG_LEN);
-    size_t num_fates = 0;
-    wifi_error status = global_func_table_.wifi_get_rx_pkt_fates(
-            getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), &num_fates);
-    CHECK(num_fates <= MAX_FATE_LOG_LEN);
-    rx_pkt_fates.resize(num_fates);
-    return {status, std::move(rx_pkt_fates)};
-}
-
-std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats(
-        const std::string& iface_name) {
-    WakeReasonStats stats;
-    stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
-    stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
-
-    // This legacy struct needs separate memory to store the variable sized wake
-    // reason types.
-    stats.wake_reason_cnt.cmd_event_wake_cnt =
-            reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data());
-    stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size();
-    stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0;
-    stats.wake_reason_cnt.driver_fw_local_wake_cnt =
-            reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data());
-    stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = stats.driver_fw_local_wake_cnt.size();
-    stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0;
-
-    wifi_error status = global_func_table_.wifi_get_wake_reason_stats(getIfaceHandle(iface_name),
-                                                                      &stats.wake_reason_cnt);
-
-    CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 &&
-          static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <=
-                  kMaxWakeReasonStatsArraySize);
-    stats.cmd_event_wake_cnt.resize(stats.wake_reason_cnt.cmd_event_wake_cnt_used);
-    stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr;
-
-    CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 &&
-          static_cast<uint32_t>(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <=
-                  kMaxWakeReasonStatsArraySize);
-    stats.driver_fw_local_wake_cnt.resize(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used);
-    stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr;
-
-    return {status, stats};
-}
-
-wifi_error WifiLegacyHal::registerRingBufferCallbackHandler(
-        const std::string& iface_name, const on_ring_buffer_data_callback& on_user_data_callback) {
-    if (on_ring_buffer_data_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_ring_buffer_data_internal_callback = [on_user_data_callback](
-                                                    char* ring_name, char* buffer, int buffer_size,
-                                                    wifi_ring_buffer_status* status) {
-        if (status && buffer) {
-            std::vector<uint8_t> buffer_vector(reinterpret_cast<uint8_t*>(buffer),
-                                               reinterpret_cast<uint8_t*>(buffer) + buffer_size);
-            on_user_data_callback(ring_name, buffer_vector, *status);
-        }
-    };
-    wifi_error status = global_func_table_.wifi_set_log_handler(0, getIfaceHandle(iface_name),
-                                                                {onAsyncRingBufferData});
-    if (status != WIFI_SUCCESS) {
-        on_ring_buffer_data_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(const std::string& iface_name) {
-    if (!on_ring_buffer_data_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_ring_buffer_data_internal_callback = nullptr;
-    return global_func_table_.wifi_reset_log_handler(0, getIfaceHandle(iface_name));
-}
-
-std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> WifiLegacyHal::getRingBuffersStatus(
-        const std::string& iface_name) {
-    std::vector<wifi_ring_buffer_status> ring_buffers_status;
-    ring_buffers_status.resize(kMaxRingBuffers);
-    uint32_t num_rings = kMaxRingBuffers;
-    wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
-            getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data());
-    CHECK(num_rings <= kMaxRingBuffers);
-    ring_buffers_status.resize(num_rings);
-    return {status, std::move(ring_buffers_status)};
-}
-
-wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name,
-                                                 const std::string& ring_name,
-                                                 uint32_t verbose_level, uint32_t max_interval_sec,
-                                                 uint32_t min_data_size) {
-    return global_func_table_.wifi_start_logging(getIfaceHandle(iface_name), verbose_level, 0,
-                                                 max_interval_sec, min_data_size,
-                                                 makeCharVec(ring_name).data());
-}
-
-wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name,
-                                            const std::string& ring_name) {
-    return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name),
-                                                 makeCharVec(ring_name).data());
-}
-
-wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
-        const std::string& iface_name, const on_error_alert_callback& on_user_alert_callback) {
-    if (on_error_alert_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_error_alert_internal_callback = [on_user_alert_callback](wifi_request_id id, char* buffer,
-                                                                int buffer_size, int err_code) {
-        if (buffer) {
-            CHECK(id == 0);
-            on_user_alert_callback(
-                    err_code,
-                    std::vector<uint8_t>(reinterpret_cast<uint8_t*>(buffer),
-                                         reinterpret_cast<uint8_t*>(buffer) + buffer_size));
-        }
-    };
-    wifi_error status = global_func_table_.wifi_set_alert_handler(0, getIfaceHandle(iface_name),
-                                                                  {onAsyncErrorAlert});
-    if (status != WIFI_SUCCESS) {
-        on_error_alert_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(const std::string& iface_name) {
-    if (!on_error_alert_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_error_alert_internal_callback = nullptr;
-    return global_func_table_.wifi_reset_alert_handler(0, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
-        const std::string& iface_name,
-        const on_radio_mode_change_callback& on_user_change_callback) {
-    if (on_radio_mode_change_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_radio_mode_change_internal_callback = [on_user_change_callback](
-                                                     wifi_request_id /* id */, uint32_t num_macs,
-                                                     wifi_mac_info* mac_infos_arr) {
-        if (num_macs > 0 && mac_infos_arr) {
-            std::vector<WifiMacInfo> mac_infos_vec;
-            for (uint32_t i = 0; i < num_macs; i++) {
-                WifiMacInfo mac_info;
-                mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id;
-                mac_info.mac_band = mac_infos_arr[i].mac_band;
-                for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) {
-                    WifiIfaceInfo iface_info;
-                    iface_info.name = mac_infos_arr[i].iface_info[j].iface_name;
-                    iface_info.channel = mac_infos_arr[i].iface_info[j].channel;
-                    mac_info.iface_infos.push_back(iface_info);
-                }
-                mac_infos_vec.push_back(mac_info);
-            }
-            on_user_change_callback(mac_infos_vec);
-        }
-    };
-    wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler(
-            0, getIfaceHandle(iface_name), {onAsyncRadioModeChange});
-    if (status != WIFI_SUCCESS) {
-        on_radio_mode_change_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler(
-        const on_subsystem_restart_callback& on_restart_callback) {
-    if (on_subsystem_restart_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_subsystem_restart_internal_callback = [on_restart_callback](const char* error) {
-        on_restart_callback(error);
-    };
-    wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler(
-            global_handle_, {onAsyncSubsystemRestart});
-    if (status != WIFI_SUCCESS) {
-        on_subsystem_restart_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::startRttRangeRequest(
-        const std::string& iface_name, wifi_request_id id,
-        const std::vector<wifi_rtt_config>& rtt_configs,
-        const on_rtt_results_callback& on_results_user_callback) {
-    if (on_rtt_results_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-
-    on_rtt_results_internal_callback = [on_results_user_callback](wifi_request_id id,
-                                                                  unsigned num_results,
-                                                                  wifi_rtt_result* rtt_results[]) {
-        if (num_results > 0 && !rtt_results) {
-            LOG(ERROR) << "Unexpected nullptr in RTT results";
-            return;
-        }
-        std::vector<const wifi_rtt_result*> rtt_results_vec;
-        std::copy_if(rtt_results, rtt_results + num_results, back_inserter(rtt_results_vec),
-                     [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; });
-        on_results_user_callback(id, rtt_results_vec);
-    };
-
-    std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs);
-    wifi_error status = global_func_table_.wifi_rtt_range_request(
-            id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
-            {onAsyncRttResults});
-    if (status != WIFI_SUCCESS) {
-        on_rtt_results_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::cancelRttRangeRequest(
-        const std::string& iface_name, wifi_request_id id,
-        const std::vector<std::array<uint8_t, 6>>& mac_addrs) {
-    if (!on_rtt_results_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, 6>), "MAC address size mismatch");
-    // TODO: How do we handle partial cancels (i.e only a subset of enabled mac
-    // addressed are cancelled).
-    std::vector<std::array<uint8_t, 6>> mac_addrs_internal(mac_addrs);
-    wifi_error status = global_func_table_.wifi_rtt_range_cancel(
-            id, getIfaceHandle(iface_name), mac_addrs.size(),
-            reinterpret_cast<mac_addr*>(mac_addrs_internal.data()));
-    // If the request Id is wrong, don't stop the ongoing range request. Any
-    // other error should be treated as the end of rtt ranging.
-    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
-        on_rtt_results_internal_callback = nullptr;
-    }
-    return status;
-}
-
-std::pair<wifi_error, wifi_rtt_capabilities> WifiLegacyHal::getRttCapabilities(
-        const std::string& iface_name) {
-    wifi_rtt_capabilities rtt_caps;
-    wifi_error status =
-            global_func_table_.wifi_get_rtt_capabilities(getIfaceHandle(iface_name), &rtt_caps);
-    return {status, rtt_caps};
-}
-
-std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
-        const std::string& iface_name) {
-    wifi_rtt_responder rtt_responder;
-    wifi_error status = global_func_table_.wifi_rtt_get_responder_info(getIfaceHandle(iface_name),
-                                                                       &rtt_responder);
-    return {status, rtt_responder};
-}
-
-wifi_error WifiLegacyHal::enableRttResponder(const std::string& iface_name, wifi_request_id id,
-                                             const wifi_channel_info& channel_hint,
-                                             uint32_t max_duration_secs,
-                                             const wifi_rtt_responder& info) {
-    wifi_rtt_responder info_internal(info);
-    return global_func_table_.wifi_enable_responder(id, getIfaceHandle(iface_name), channel_hint,
-                                                    max_duration_secs, &info_internal);
-}
-
-wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, wifi_request_id id) {
-    return global_func_table_.wifi_disable_responder(id, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, wifi_request_id id,
-                                    const wifi_lci_information& info) {
-    wifi_lci_information info_internal(info);
-    return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), &info_internal);
-}
-
-wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, wifi_request_id id,
-                                    const wifi_lcr_information& info) {
-    wifi_lcr_information info_internal(info);
-    return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), &info_internal);
-}
-
-wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(const std::string& iface_name,
-                                                      const NanCallbackHandlers& user_callbacks) {
-    on_nan_notify_response_user_callback = user_callbacks.on_notify_response;
-    on_nan_event_publish_terminated_user_callback = user_callbacks.on_event_publish_terminated;
-    on_nan_event_match_user_callback = user_callbacks.on_event_match;
-    on_nan_event_match_expired_user_callback = user_callbacks.on_event_match_expired;
-    on_nan_event_subscribe_terminated_user_callback = user_callbacks.on_event_subscribe_terminated;
-    on_nan_event_followup_user_callback = user_callbacks.on_event_followup;
-    on_nan_event_disc_eng_event_user_callback = user_callbacks.on_event_disc_eng_event;
-    on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled;
-    on_nan_event_tca_user_callback = user_callbacks.on_event_tca;
-    on_nan_event_beacon_sdf_payload_user_callback = user_callbacks.on_event_beacon_sdf_payload;
-    on_nan_event_data_path_request_user_callback = user_callbacks.on_event_data_path_request;
-    on_nan_event_data_path_confirm_user_callback = user_callbacks.on_event_data_path_confirm;
-    on_nan_event_data_path_end_user_callback = user_callbacks.on_event_data_path_end;
-    on_nan_event_transmit_follow_up_user_callback = user_callbacks.on_event_transmit_follow_up;
-    on_nan_event_range_request_user_callback = user_callbacks.on_event_range_request;
-    on_nan_event_range_report_user_callback = user_callbacks.on_event_range_report;
-    on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update;
-
-    return global_func_table_.wifi_nan_register_handler(
-            getIfaceHandle(iface_name),
-            {onAysncNanNotifyResponse, onAysncNanEventPublishReplied,
-             onAysncNanEventPublishTerminated, onAysncNanEventMatch, onAysncNanEventMatchExpired,
-             onAysncNanEventSubscribeTerminated, onAysncNanEventFollowup,
-             onAysncNanEventDiscEngEvent, onAysncNanEventDisabled, onAysncNanEventTca,
-             onAysncNanEventBeaconSdfPayload, onAysncNanEventDataPathRequest,
-             onAysncNanEventDataPathConfirm, onAysncNanEventDataPathEnd,
-             onAysncNanEventTransmitFollowUp, onAysncNanEventRangeRequest,
-             onAysncNanEventRangeReport, onAsyncNanEventScheduleUpdate});
-}
-
-wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id,
-                                           const NanEnableRequest& msg) {
-    NanEnableRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_enable_request(id, getIfaceHandle(iface_name),
-                                                      &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, transaction_id id) {
-    return global_func_table_.wifi_nan_disable_request(id, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, transaction_id id,
-                                            const NanPublishRequest& msg) {
-    NanPublishRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_publish_request(id, getIfaceHandle(iface_name),
-                                                       &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
-                                                  const NanPublishCancelRequest& msg) {
-    NanPublishCancelRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_publish_cancel_request(id, getIfaceHandle(iface_name),
-                                                              &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, transaction_id id,
-                                              const NanSubscribeRequest& msg) {
-    NanSubscribeRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_subscribe_request(id, getIfaceHandle(iface_name),
-                                                         &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanSubscribeCancelRequest(const std::string& iface_name,
-                                                    transaction_id id,
-                                                    const NanSubscribeCancelRequest& msg) {
-    NanSubscribeCancelRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_subscribe_cancel_request(id, getIfaceHandle(iface_name),
-                                                                &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanTransmitFollowupRequest(const std::string& iface_name,
-                                                     transaction_id id,
-                                                     const NanTransmitFollowupRequest& msg) {
-    NanTransmitFollowupRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_transmit_followup_request(id, getIfaceHandle(iface_name),
-                                                                 &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, transaction_id id,
-                                          const NanStatsRequest& msg) {
-    NanStatsRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_stats_request(id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, transaction_id id,
-                                           const NanConfigRequest& msg) {
-    NanConfigRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_config_request(id, getIfaceHandle(iface_name),
-                                                      &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, transaction_id id,
-                                        const NanTCARequest& msg) {
-    NanTCARequest msg_internal(msg);
-    return global_func_table_.wifi_nan_tca_request(id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(const std::string& iface_name,
-                                                     transaction_id id,
-                                                     const NanBeaconSdfPayloadRequest& msg) {
-    NanBeaconSdfPayloadRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_beacon_sdf_payload_request(id, getIfaceHandle(iface_name),
-                                                                  &msg_internal);
-}
-
-std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() {
-    NanVersion version;
-    wifi_error status = global_func_table_.wifi_nan_get_version(global_handle_, &version);
-    return {status, version};
-}
-
-wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, transaction_id id) {
-    return global_func_table_.wifi_nan_get_capabilities(id, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
-                                                 const std::string& data_iface_name) {
-    return global_func_table_.wifi_nan_data_interface_create(id, getIfaceHandle(iface_name),
-                                                             makeCharVec(data_iface_name).data());
-}
-
-wifi_error WifiLegacyHal::nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
-                                                 const std::string& data_iface_name) {
-    return global_func_table_.wifi_nan_data_interface_delete(id, getIfaceHandle(iface_name),
-                                                             makeCharVec(data_iface_name).data());
-}
-
-wifi_error WifiLegacyHal::nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
-                                                  const NanDataPathInitiatorRequest& msg) {
-    NanDataPathInitiatorRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_data_request_initiator(id, getIfaceHandle(iface_name),
-                                                              &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanDataIndicationResponse(const std::string& iface_name,
-                                                    transaction_id id,
-                                                    const NanDataPathIndicationResponse& msg) {
-    NanDataPathIndicationResponse msg_internal(msg);
-    return global_func_table_.wifi_nan_data_indication_response(id, getIfaceHandle(iface_name),
-                                                                &msg_internal);
-}
-
-typedef struct {
-    u8 num_ndp_instances;
-    NanDataPathId ndp_instance_id;
-} NanDataPathEndSingleNdpIdRequest;
-
-wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, transaction_id id,
-                                     uint32_t ndpInstanceId) {
-    NanDataPathEndSingleNdpIdRequest msg;
-    msg.num_ndp_instances = 1;
-    msg.ndp_instance_id = ndpInstanceId;
-    wifi_error status = global_func_table_.wifi_nan_data_end(id, getIfaceHandle(iface_name),
-                                                             (NanDataPathEndRequest*)&msg);
-    return status;
-}
-
-wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name,
-                                         std::array<int8_t, 2> code) {
-    std::string code_str(code.data(), code.data() + code.size());
-    return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), code_str.c_str());
-}
-
-wifi_error WifiLegacyHal::retrieveIfaceHandles() {
-    wifi_interface_handle* iface_handles = nullptr;
-    int num_iface_handles = 0;
-    wifi_error status =
-            global_func_table_.wifi_get_ifaces(global_handle_, &num_iface_handles, &iface_handles);
-    if (status != WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to enumerate interface handles";
-        return status;
-    }
-    iface_name_to_handle_.clear();
-    for (int i = 0; i < num_iface_handles; ++i) {
-        std::array<char, IFNAMSIZ> iface_name_arr = {};
-        status = global_func_table_.wifi_get_iface_name(iface_handles[i], iface_name_arr.data(),
-                                                        iface_name_arr.size());
-        if (status != WIFI_SUCCESS) {
-            LOG(WARNING) << "Failed to get interface handle name";
-            continue;
-        }
-        // Assuming the interface name is null terminated since the legacy HAL
-        // API does not return a size.
-        std::string iface_name(iface_name_arr.data());
-        LOG(INFO) << "Adding interface handle for " << iface_name;
-        iface_name_to_handle_[iface_name] = iface_handles[i];
-    }
-    return WIFI_SUCCESS;
-}
-
-wifi_interface_handle WifiLegacyHal::getIfaceHandle(const std::string& iface_name) {
-    const auto iface_handle_iter = iface_name_to_handle_.find(iface_name);
-    if (iface_handle_iter == iface_name_to_handle_.end()) {
-        LOG(ERROR) << "Unknown iface name: " << iface_name;
-        return nullptr;
-    }
-    return iface_handle_iter->second;
-}
-
-void WifiLegacyHal::runEventLoop() {
-    LOG(DEBUG) << "Starting legacy HAL event loop";
-    global_func_table_.wifi_event_loop(global_handle_);
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (!awaiting_event_loop_termination_) {
-        LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
-    }
-    LOG(DEBUG) << "Legacy HAL event loop terminated";
-    awaiting_event_loop_termination_ = false;
-    stop_wait_cv_.notify_one();
-}
-
-std::pair<wifi_error, std::vector<wifi_cached_scan_results>> WifiLegacyHal::getGscanCachedResults(
-        const std::string& iface_name) {
-    std::vector<wifi_cached_scan_results> cached_scan_results;
-    cached_scan_results.resize(kMaxCachedGscanResults);
-    int32_t num_results = 0;
-    wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
-            getIfaceHandle(iface_name), true /* always flush */, cached_scan_results.size(),
-            cached_scan_results.data(), &num_results);
-    CHECK(num_results >= 0 && static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
-    cached_scan_results.resize(num_results);
-    // Check for invalid IE lengths in these cached scan results and correct it.
-    for (auto& cached_scan_result : cached_scan_results) {
-        int num_scan_results = cached_scan_result.num_results;
-        for (int i = 0; i < num_scan_results; i++) {
-            auto& scan_result = cached_scan_result.results[i];
-            if (scan_result.ie_length > 0) {
-                LOG(DEBUG) << "Cached scan result has non-zero IE length " << scan_result.ie_length;
-                scan_result.ie_length = 0;
-            }
-        }
-    }
-    return {status, std::move(cached_scan_results)};
-}
-
-wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname,
-                                                 wifi_interface_type iftype) {
-    // Create the interface if it doesn't exist. If interface already exist,
-    // Vendor Hal should return WIFI_SUCCESS.
-    wifi_error status = global_func_table_.wifi_virtual_interface_create(global_handle_,
-                                                                         ifname.c_str(), iftype);
-    return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
-}
-
-wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) {
-    // Delete the interface if it was created dynamically.
-    wifi_error status =
-            global_func_table_.wifi_virtual_interface_delete(global_handle_, ifname.c_str());
-    return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
-}
-
-wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
-                                                                     wifi_error status) {
-    if (status == WIFI_SUCCESS) {
-        // refresh list of handlers now.
-        status = retrieveIfaceHandles();
-    } else if (status == WIFI_ERROR_NOT_SUPPORTED) {
-        // Vendor hal does not implement this API. Such vendor implementations
-        // are expected to create / delete interface by other means.
-
-        // check if interface exists.
-        if (if_nametoindex(ifname.c_str())) {
-            status = retrieveIfaceHandles();
-        }
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, std::string& ifname) {
-    std::array<char, IFNAMSIZ> buffer;
-
-    wifi_error res = global_func_table_.wifi_get_supported_iface_name(
-            global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size());
-    if (res == WIFI_SUCCESS) ifname = buffer.data();
-
-    return res;
-}
-
-wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(const std::string& ifname) {
-    return global_func_table_.wifi_multi_sta_set_primary_connection(global_handle_,
-                                                                    getIfaceHandle(ifname));
-}
-
-wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) {
-    return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, use_case);
-}
-
-wifi_error WifiLegacyHal::setCoexUnsafeChannels(
-        std::vector<wifi_coex_unsafe_channel> unsafe_channels, uint32_t restrictions) {
-    return global_func_table_.wifi_set_coex_unsafe_channels(global_handle_, unsafe_channels.size(),
-                                                            unsafe_channels.data(), restrictions);
-}
-
-wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, wifi_voip_mode mode) {
-    return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode);
-}
-
-wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name,
-                                             const TwtCallbackHandlers& user_callbacks) {
-    on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
-    on_twt_event_teardown_completion_callback = user_callbacks.on_teardown_completion;
-    on_twt_event_info_frame_received_callback = user_callbacks.on_info_frame_received;
-    on_twt_event_device_notify_callback = user_callbacks.on_device_notify;
-
-    return global_func_table_.wifi_twt_register_handler(
-            getIfaceHandle(iface_name),
-            {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion,
-             onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify});
-}
-
-std::pair<wifi_error, TwtCapabilitySet> WifiLegacyHal::twtGetCapability(
-        const std::string& iface_name) {
-    TwtCapabilitySet capSet;
-    wifi_error status =
-            global_func_table_.wifi_twt_get_capability(getIfaceHandle(iface_name), &capSet);
-    return {status, capSet};
-}
-
-wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name,
-                                          const TwtSetupRequest& msg) {
-    TwtSetupRequest msgInternal(msg);
-    return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), &msgInternal);
-}
-
-wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name,
-                                             const TwtTeardownRequest& msg) {
-    TwtTeardownRequest msgInternal(msg);
-    return global_func_table_.wifi_twt_teardown_request(getIfaceHandle(iface_name), &msgInternal);
-}
-
-wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name,
-                                              const TwtInfoFrameRequest& msg) {
-    TwtInfoFrameRequest msgInternal(msg);
-    return global_func_table_.wifi_twt_info_frame_request(getIfaceHandle(iface_name), &msgInternal);
-}
-
-std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats(const std::string& iface_name,
-                                                           uint8_t configId) {
-    TwtStats stats;
-    wifi_error status =
-            global_func_table_.wifi_twt_get_stats(getIfaceHandle(iface_name), configId, &stats);
-    return {status, stats};
-}
-
-wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, uint8_t configId) {
-    return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), configId);
-}
-
-wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) {
-    return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), multiplier);
-}
-
-std::pair<wifi_error, std::vector<wifi_usable_channel>> WifiLegacyHal::getUsableChannels(
-        uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask) {
-    std::vector<wifi_usable_channel> channels;
-    channels.resize(kMaxWifiUsableChannels);
-    uint32_t size = 0;
-    wifi_error status = global_func_table_.wifi_get_usable_channels(
-            global_handle_, band_mask, iface_mode_mask, filter_mask, channels.size(), &size,
-            reinterpret_cast<wifi_usable_channel*>(channels.data()));
-    CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
-    channels.resize(size);
-    return {status, std::move(channels)};
-}
-
-wifi_error WifiLegacyHal::triggerSubsystemRestart() {
-    return global_func_table_.wifi_trigger_subsystem_restart(global_handle_);
-}
-
-wifi_error WifiLegacyHal::setIndoorState(bool isIndoor) {
-    return global_func_table_.wifi_set_indoor_state(global_handle_, isIndoor);
-}
-
-std::pair<wifi_error, wifi_radio_combination_matrix*>
-WifiLegacyHal::getSupportedRadioCombinationsMatrix() {
-    char* buffer = new char[kMaxSupportedRadioCombinationsMatrixLength];
-    std::fill(buffer, buffer + kMaxSupportedRadioCombinationsMatrixLength, 0);
-    uint32_t size = 0;
-    wifi_radio_combination_matrix* radio_combination_matrix_ptr =
-            reinterpret_cast<wifi_radio_combination_matrix*>(buffer);
-    wifi_error status = global_func_table_.wifi_get_supported_radio_combinations_matrix(
-            global_handle_, kMaxSupportedRadioCombinationsMatrixLength, &size,
-            radio_combination_matrix_ptr);
-    CHECK(size >= 0 && size <= kMaxSupportedRadioCombinationsMatrixLength);
-    return {status, radio_combination_matrix_ptr};
-}
-
-wifi_error WifiLegacyHal::chreNanRttRequest(const std::string& iface_name, bool enable) {
-    if (enable)
-        return global_func_table_.wifi_nan_rtt_chre_enable_request(0, getIfaceHandle(iface_name),
-                                                                   NULL);
-    else
-        return global_func_table_.wifi_nan_rtt_chre_disable_request(0, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::chreRegisterHandler(const std::string& iface_name,
-                                              const ChreCallbackHandlers& handler) {
-    if (on_chre_nan_rtt_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-
-    on_chre_nan_rtt_internal_callback = handler.on_wifi_chre_nan_rtt_state;
-
-    wifi_error status = global_func_table_.wifi_chre_register_handler(getIfaceHandle(iface_name),
-                                                                      {onAsyncChreNanRttState});
-    if (status != WIFI_SUCCESS) {
-        on_chre_nan_rtt_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::enableWifiTxPowerLimits(const std::string& iface_name, bool enable) {
-    return global_func_table_.wifi_enable_tx_power_limits(getIfaceHandle(iface_name), enable);
-}
-
-void WifiLegacyHal::invalidate() {
-    global_handle_ = nullptr;
-    iface_name_to_handle_.clear();
-    on_driver_memory_dump_internal_callback = nullptr;
-    on_firmware_memory_dump_internal_callback = nullptr;
-    on_gscan_event_internal_callback = nullptr;
-    on_gscan_full_result_internal_callback = nullptr;
-    on_link_layer_stats_result_internal_callback = nullptr;
-    on_rssi_threshold_breached_internal_callback = nullptr;
-    on_ring_buffer_data_internal_callback = nullptr;
-    on_error_alert_internal_callback = nullptr;
-    on_radio_mode_change_internal_callback = nullptr;
-    on_subsystem_restart_internal_callback = nullptr;
-    on_rtt_results_internal_callback = nullptr;
-    on_nan_notify_response_user_callback = nullptr;
-    on_nan_event_publish_terminated_user_callback = nullptr;
-    on_nan_event_match_user_callback = nullptr;
-    on_nan_event_match_expired_user_callback = nullptr;
-    on_nan_event_subscribe_terminated_user_callback = nullptr;
-    on_nan_event_followup_user_callback = nullptr;
-    on_nan_event_disc_eng_event_user_callback = nullptr;
-    on_nan_event_disabled_user_callback = nullptr;
-    on_nan_event_tca_user_callback = nullptr;
-    on_nan_event_beacon_sdf_payload_user_callback = nullptr;
-    on_nan_event_data_path_request_user_callback = nullptr;
-    on_nan_event_data_path_confirm_user_callback = nullptr;
-    on_nan_event_data_path_end_user_callback = nullptr;
-    on_nan_event_transmit_follow_up_user_callback = nullptr;
-    on_nan_event_range_request_user_callback = nullptr;
-    on_nan_event_range_report_user_callback = nullptr;
-    on_nan_event_schedule_update_user_callback = nullptr;
-    on_twt_event_setup_response_callback = nullptr;
-    on_twt_event_teardown_completion_callback = nullptr;
-    on_twt_event_info_frame_received_callback = nullptr;
-    on_twt_event_device_notify_callback = nullptr;
-    on_chre_nan_rtt_internal_callback = nullptr;
-}
-
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_legacy_hal.h b/wifi/1.6/default/wifi_legacy_hal.h
deleted file mode 100644
index 2b923b4..0000000
--- a/wifi/1.6/default/wifi_legacy_hal.h
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_LEGACY_HAL_H_
-#define WIFI_LEGACY_HAL_H_
-
-#include <condition_variable>
-#include <functional>
-#include <map>
-#include <thread>
-#include <vector>
-
-#include <hardware_legacy/wifi_hal.h>
-#include <wifi_system/interface_tool.h>
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-// This is in a separate namespace to prevent typename conflicts between
-// the legacy HAL types and the HIDL interface types.
-namespace legacy_hal {
-// Import all the types defined inside the legacy HAL header files into this
-// namespace.
-using ::chre_nan_rtt_state;
-using ::frame_info;
-using ::frame_type;
-using ::FRAME_TYPE_80211_MGMT;
-using ::FRAME_TYPE_ETHERNET_II;
-using ::FRAME_TYPE_UNKNOWN;
-using ::fw_roaming_state_t;
-using ::mac_addr;
-using ::NAN_CHANNEL_24G_BAND;
-using ::NAN_CHANNEL_5G_BAND_HIGH;
-using ::NAN_CHANNEL_5G_BAND_LOW;
-using ::NAN_DISABLE_RANGE_REPORT;
-using ::NAN_DO_NOT_USE_SRF;
-using ::NAN_DP_CHANNEL_NOT_REQUESTED;
-using ::NAN_DP_CONFIG_NO_SECURITY;
-using ::NAN_DP_CONFIG_SECURITY;
-using ::NAN_DP_END;
-using ::NAN_DP_FORCE_CHANNEL_SETUP;
-using ::NAN_DP_INITIATOR_RESPONSE;
-using ::NAN_DP_INTERFACE_CREATE;
-using ::NAN_DP_INTERFACE_DELETE;
-using ::NAN_DP_REQUEST_ACCEPT;
-using ::NAN_DP_REQUEST_CHANNEL_SETUP;
-using ::NAN_DP_REQUEST_REJECT;
-using ::NAN_DP_RESPONDER_RESPONSE;
-using ::NAN_GET_CAPABILITIES;
-using ::NAN_MATCH_ALG_MATCH_CONTINUOUS;
-using ::NAN_MATCH_ALG_MATCH_NEVER;
-using ::NAN_MATCH_ALG_MATCH_ONCE;
-using ::NAN_PUBLISH_TYPE_SOLICITED;
-using ::NAN_PUBLISH_TYPE_UNSOLICITED;
-using ::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
-using ::NAN_RANGING_AUTO_RESPONSE_DISABLE;
-using ::NAN_RANGING_AUTO_RESPONSE_ENABLE;
-using ::NAN_RANGING_DISABLE;
-using ::NAN_RANGING_ENABLE;
-using ::NAN_RESPONSE_BEACON_SDF_PAYLOAD;
-using ::NAN_RESPONSE_CONFIG;
-using ::NAN_RESPONSE_DISABLED;
-using ::NAN_RESPONSE_ENABLED;
-using ::NAN_RESPONSE_ERROR;
-using ::NAN_RESPONSE_PUBLISH;
-using ::NAN_RESPONSE_PUBLISH_CANCEL;
-using ::NAN_RESPONSE_STATS;
-using ::NAN_RESPONSE_SUBSCRIBE;
-using ::NAN_RESPONSE_SUBSCRIBE_CANCEL;
-using ::NAN_RESPONSE_TCA;
-using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP;
-using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-using ::NAN_SECURITY_KEY_INPUT_PMK;
-using ::NAN_SERVICE_ACCEPT_POLICY_ALL;
-using ::NAN_SERVICE_ACCEPT_POLICY_NONE;
-using ::NAN_SRF_ATTR_BLOOM_FILTER;
-using ::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
-using ::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
-using ::NAN_SRF_INCLUDE_RESPOND;
-using ::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
-using ::NAN_SSI_REQUIRED_IN_MATCH_IND;
-using ::NAN_STATUS_ALREADY_ENABLED;
-using ::NAN_STATUS_FOLLOWUP_QUEUE_FULL;
-using ::NAN_STATUS_INTERNAL_FAILURE;
-using ::NAN_STATUS_INVALID_NDP_ID;
-using ::NAN_STATUS_INVALID_PARAM;
-using ::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
-using ::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID;
-using ::NAN_STATUS_NAN_NOT_ALLOWED;
-using ::NAN_STATUS_NO_OTA_ACK;
-using ::NAN_STATUS_NO_RESOURCE_AVAILABLE;
-using ::NAN_STATUS_PROTOCOL_FAILURE;
-using ::NAN_STATUS_SUCCESS;
-using ::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
-using ::NAN_SUBSCRIBE_TYPE_ACTIVE;
-using ::NAN_SUBSCRIBE_TYPE_PASSIVE;
-using ::NAN_TRANSMIT_IN_DW;
-using ::NAN_TRANSMIT_IN_FAW;
-using ::NAN_TX_PRIORITY_HIGH;
-using ::NAN_TX_PRIORITY_NORMAL;
-using ::NAN_TX_TYPE_BROADCAST;
-using ::NAN_TX_TYPE_UNICAST;
-using ::NAN_USE_SRF;
-using ::NanBeaconSdfPayloadInd;
-using ::NanCapabilities;
-using ::NanChannelInfo;
-using ::NanConfigRequest;
-using ::NanDataPathChannelCfg;
-using ::NanDataPathConfirmInd;
-using ::NanDataPathEndInd;
-using ::NanDataPathIndicationResponse;
-using ::NanDataPathInitiatorRequest;
-using ::NanDataPathRequestInd;
-using ::NanDataPathScheduleUpdateInd;
-using ::NanDisabledInd;
-using ::NanDiscEngEventInd;
-using ::NanEnableRequest;
-using ::NanFollowupInd;
-using ::NanMatchAlg;
-using ::NanMatchExpiredInd;
-using ::NanMatchInd;
-using ::NanPublishCancelRequest;
-using ::NanPublishRequest;
-using ::NanPublishTerminatedInd;
-using ::NanPublishType;
-using ::NanRangeReportInd;
-using ::NanRangeRequestInd;
-using ::NanResponseMsg;
-using ::NanSRFType;
-using ::NanStatusType;
-using ::NanSubscribeCancelRequest;
-using ::NanSubscribeRequest;
-using ::NanSubscribeTerminatedInd;
-using ::NanSubscribeType;
-using ::NanTransmitFollowupInd;
-using ::NanTransmitFollowupRequest;
-using ::NanTxType;
-using ::ROAMING_DISABLE;
-using ::ROAMING_ENABLE;
-using ::RTT_PEER_AP;
-using ::RTT_PEER_NAN;
-using ::RTT_PEER_P2P_CLIENT;
-using ::RTT_PEER_P2P_GO;
-using ::RTT_PEER_STA;
-using ::rtt_peer_type;
-using ::RTT_STATUS_ABORTED;
-using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
-using ::RTT_STATUS_FAIL_BUSY_TRY_LATER;
-using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
-using ::RTT_STATUS_FAIL_INVALID_TS;
-using ::RTT_STATUS_FAIL_NO_CAPABILITY;
-using ::RTT_STATUS_FAIL_NO_RSP;
-using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
-using ::RTT_STATUS_FAIL_PROTOCOL;
-using ::RTT_STATUS_FAIL_REJECTED;
-using ::RTT_STATUS_FAIL_SCHEDULE;
-using ::RTT_STATUS_FAIL_TM_TIMEOUT;
-using ::RTT_STATUS_FAILURE;
-using ::RTT_STATUS_INVALID_REQ;
-using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
-using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE;
-using ::RTT_STATUS_NO_WIFI;
-using ::RTT_STATUS_SUCCESS;
-using ::RTT_TYPE_1_SIDED;
-using ::RTT_TYPE_2_SIDED;
-using ::RX_PKT_FATE_DRV_DROP_FILTER;
-using ::RX_PKT_FATE_DRV_DROP_INVALID;
-using ::RX_PKT_FATE_DRV_DROP_NOBUFS;
-using ::RX_PKT_FATE_DRV_DROP_OTHER;
-using ::RX_PKT_FATE_DRV_QUEUED;
-using ::RX_PKT_FATE_FW_DROP_FILTER;
-using ::RX_PKT_FATE_FW_DROP_INVALID;
-using ::RX_PKT_FATE_FW_DROP_NOBUFS;
-using ::RX_PKT_FATE_FW_DROP_OTHER;
-using ::RX_PKT_FATE_FW_QUEUED;
-using ::RX_PKT_FATE_SUCCESS;
-using ::ssid_t;
-using ::transaction_id;
-using ::TX_PKT_FATE_ACKED;
-using ::TX_PKT_FATE_DRV_DROP_INVALID;
-using ::TX_PKT_FATE_DRV_DROP_NOBUFS;
-using ::TX_PKT_FATE_DRV_DROP_OTHER;
-using ::TX_PKT_FATE_DRV_QUEUED;
-using ::TX_PKT_FATE_FW_DROP_INVALID;
-using ::TX_PKT_FATE_FW_DROP_NOBUFS;
-using ::TX_PKT_FATE_FW_DROP_OTHER;
-using ::TX_PKT_FATE_FW_QUEUED;
-using ::TX_PKT_FATE_SENT;
-using ::WIFI_AC_BE;
-using ::WIFI_AC_BK;
-using ::WIFI_AC_VI;
-using ::WIFI_AC_VO;
-using ::WIFI_ANTENNA_1X1;
-using ::WIFI_ANTENNA_2X2;
-using ::WIFI_ANTENNA_3X3;
-using ::WIFI_ANTENNA_4X4;
-using ::WIFI_ANTENNA_UNSPECIFIED;
-using ::wifi_band;
-using ::WIFI_BAND_A;
-using ::WIFI_BAND_A_DFS;
-using ::WIFI_BAND_A_WITH_DFS;
-using ::WIFI_BAND_ABG;
-using ::WIFI_BAND_ABG_WITH_DFS;
-using ::WIFI_BAND_BG;
-using ::WIFI_BAND_UNSPECIFIED;
-using ::wifi_cached_scan_results;
-using ::WIFI_CHAN_WIDTH_10;
-using ::WIFI_CHAN_WIDTH_160;
-using ::WIFI_CHAN_WIDTH_20;
-using ::WIFI_CHAN_WIDTH_320;
-using ::WIFI_CHAN_WIDTH_40;
-using ::WIFI_CHAN_WIDTH_5;
-using ::WIFI_CHAN_WIDTH_80;
-using ::WIFI_CHAN_WIDTH_80P80;
-using ::WIFI_CHAN_WIDTH_INVALID;
-using ::wifi_channel_info;
-using ::wifi_channel_stat;
-using ::wifi_channel_width;
-using ::wifi_coex_restriction;
-using ::wifi_coex_unsafe_channel;
-using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
-using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
-using ::wifi_error;
-using ::WIFI_ERROR_BUSY;
-using ::WIFI_ERROR_INVALID_ARGS;
-using ::WIFI_ERROR_INVALID_REQUEST_ID;
-using ::WIFI_ERROR_NONE;
-using ::WIFI_ERROR_NOT_AVAILABLE;
-using ::WIFI_ERROR_NOT_SUPPORTED;
-using ::WIFI_ERROR_OUT_OF_MEMORY;
-using ::WIFI_ERROR_TIMED_OUT;
-using ::WIFI_ERROR_TOO_MANY_REQUESTS;
-using ::WIFI_ERROR_UNINITIALIZED;
-using ::WIFI_ERROR_UNKNOWN;
-using ::wifi_gscan_capabilities;
-using ::wifi_hal_fn;
-using ::wifi_information_element;
-using ::WIFI_INTERFACE_IBSS;
-using ::WIFI_INTERFACE_MESH;
-using ::wifi_interface_mode;
-using ::WIFI_INTERFACE_NAN;
-using ::WIFI_INTERFACE_P2P_CLIENT;
-using ::WIFI_INTERFACE_P2P_GO;
-using ::WIFI_INTERFACE_SOFTAP;
-using ::WIFI_INTERFACE_STA;
-using ::WIFI_INTERFACE_TDLS;
-using ::wifi_interface_type;
-using ::WIFI_INTERFACE_TYPE_AP;
-using ::WIFI_INTERFACE_TYPE_NAN;
-using ::WIFI_INTERFACE_TYPE_P2P;
-using ::WIFI_INTERFACE_TYPE_STA;
-using ::WIFI_INTERFACE_UNKNOWN;
-using ::wifi_latency_mode;
-using ::WIFI_LATENCY_MODE_LOW;
-using ::WIFI_LATENCY_MODE_NORMAL;
-using ::wifi_lci_information;
-using ::wifi_lcr_information;
-using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
-using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
-using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
-using ::WIFI_LOGGER_PACKET_FATE_SUPPORTED;
-using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED;
-using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
-using ::WIFI_MOTION_EXPECTED;
-using ::WIFI_MOTION_NOT_EXPECTED;
-using ::wifi_motion_pattern;
-using ::WIFI_MOTION_UNKNOWN;
-using ::wifi_multi_sta_use_case;
-using ::wifi_power_scenario;
-using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
-using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
-using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
-using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
-using ::WIFI_POWER_SCENARIO_VOICE_CALL;
-using ::wifi_radio_combination;
-using ::wifi_radio_combination_matrix;
-using ::wifi_radio_configuration;
-using ::wifi_rate;
-using ::wifi_request_id;
-using ::wifi_ring_buffer_status;
-using ::wifi_roaming_capabilities;
-using ::wifi_roaming_config;
-using ::wifi_rtt_bw;
-using ::WIFI_RTT_BW_10;
-using ::WIFI_RTT_BW_160;
-using ::WIFI_RTT_BW_20;
-using ::WIFI_RTT_BW_320;
-using ::WIFI_RTT_BW_40;
-using ::WIFI_RTT_BW_5;
-using ::WIFI_RTT_BW_80;
-using ::wifi_rtt_capabilities;
-using ::wifi_rtt_config;
-using ::wifi_rtt_preamble;
-using ::WIFI_RTT_PREAMBLE_EHT;
-using ::WIFI_RTT_PREAMBLE_HE;
-using ::WIFI_RTT_PREAMBLE_HT;
-using ::WIFI_RTT_PREAMBLE_LEGACY;
-using ::WIFI_RTT_PREAMBLE_VHT;
-using ::wifi_rtt_responder;
-using ::wifi_rtt_result;
-using ::wifi_rtt_status;
-using ::wifi_rtt_type;
-using ::wifi_rx_packet_fate;
-using ::wifi_rx_report;
-using ::wifi_scan_bucket_spec;
-using ::wifi_scan_cmd_params;
-using ::WIFI_SCAN_FLAG_INTERRUPTED;
-using ::wifi_scan_result;
-using ::WIFI_SUCCESS;
-using ::wifi_tx_packet_fate;
-using ::wifi_tx_report;
-using ::wifi_usable_channel;
-using ::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
-using ::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
-using ::WLAN_MAC_2_4_BAND;
-using ::WLAN_MAC_5_0_BAND;
-using ::WLAN_MAC_60_0_BAND;
-using ::WLAN_MAC_6_0_BAND;
-
-// APF capabilities supported by the iface.
-struct PacketFilterCapabilities {
-    uint32_t version;
-    uint32_t max_len;
-};
-
-// WARNING: We don't care about the variable sized members of either
-// |wifi_iface_stat|, |wifi_radio_stat| structures. So, using the pragma
-// to escape the compiler warnings regarding this.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
-// The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in
-// |wifi_radio_stat| structure in the legacy HAL API. Separate that out
-// into a separate return element to avoid passing pointers around.
-struct LinkLayerRadioStats {
-    wifi_radio_stat stats;
-    std::vector<uint32_t> tx_time_per_levels;
-    std::vector<wifi_channel_stat> channel_stats;
-};
-
-struct WifiPeerInfo {
-    wifi_peer_info peer_info;
-    std::vector<wifi_rate_stat> rate_stats;
-};
-
-struct LinkLayerStats {
-    wifi_iface_stat iface;
-    std::vector<LinkLayerRadioStats> radios;
-    std::vector<WifiPeerInfo> peers;
-};
-#pragma GCC diagnostic pop
-
-// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
-// |WLAN_DRIVER_WAKE_REASON_CNT.driver_fw_local_wake_cnt| stats is provided
-// as a pointer in |WLAN_DRIVER_WAKE_REASON_CNT| structure in the legacy HAL
-// API. Separate that out into a separate return elements to avoid passing
-// pointers around.
-struct WakeReasonStats {
-    WLAN_DRIVER_WAKE_REASON_CNT wake_reason_cnt;
-    std::vector<uint32_t> cmd_event_wake_cnt;
-    std::vector<uint32_t> driver_fw_local_wake_cnt;
-};
-
-// NAN response and event callbacks struct.
-struct NanCallbackHandlers {
-    // NotifyResponse invoked to notify the status of the Request.
-    std::function<void(transaction_id, const NanResponseMsg&)> on_notify_response;
-    // Various event callbacks.
-    std::function<void(const NanPublishTerminatedInd&)> on_event_publish_terminated;
-    std::function<void(const NanMatchInd&)> on_event_match;
-    std::function<void(const NanMatchExpiredInd&)> on_event_match_expired;
-    std::function<void(const NanSubscribeTerminatedInd&)> on_event_subscribe_terminated;
-    std::function<void(const NanFollowupInd&)> on_event_followup;
-    std::function<void(const NanDiscEngEventInd&)> on_event_disc_eng_event;
-    std::function<void(const NanDisabledInd&)> on_event_disabled;
-    std::function<void(const NanTCAInd&)> on_event_tca;
-    std::function<void(const NanBeaconSdfPayloadInd&)> on_event_beacon_sdf_payload;
-    std::function<void(const NanDataPathRequestInd&)> on_event_data_path_request;
-    std::function<void(const NanDataPathConfirmInd&)> on_event_data_path_confirm;
-    std::function<void(const NanDataPathEndInd&)> on_event_data_path_end;
-    std::function<void(const NanTransmitFollowupInd&)> on_event_transmit_follow_up;
-    std::function<void(const NanRangeRequestInd&)> on_event_range_request;
-    std::function<void(const NanRangeReportInd&)> on_event_range_report;
-    std::function<void(const NanDataPathScheduleUpdateInd&)> on_event_schedule_update;
-};
-
-// Full scan results contain IE info and are hence passed by reference, to
-// preserve the variable length array member |ie_data|. Callee must not retain
-// the pointer.
-using on_gscan_full_result_callback =
-        std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>;
-// These scan results don't contain any IE info, so no need to pass by
-// reference.
-using on_gscan_results_callback =
-        std::function<void(wifi_request_id, const std::vector<wifi_cached_scan_results>&)>;
-
-// Invoked when the rssi value breaches the thresholds set.
-using on_rssi_threshold_breached_callback =
-        std::function<void(wifi_request_id, std::array<uint8_t, 6>, int8_t)>;
-
-// Callback for RTT range request results.
-// Rtt results contain IE info and are hence passed by reference, to
-// preserve the |LCI| and |LCR| pointers. Callee must not retain
-// the pointer.
-using on_rtt_results_callback =
-        std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result*>&)>;
-
-// Callback for ring buffer data.
-using on_ring_buffer_data_callback = std::function<void(
-        const std::string&, const std::vector<uint8_t>&, const wifi_ring_buffer_status&)>;
-
-// Callback for alerts.
-using on_error_alert_callback = std::function<void(int32_t, const std::vector<uint8_t>&)>;
-
-// Callback for subsystem restart
-using on_subsystem_restart_callback = std::function<void(const std::string&)>;
-
-// Struct for the mac info from the legacy HAL. This is a cleaner version
-// of the |wifi_mac_info| & |wifi_iface_info|.
-typedef struct {
-    std::string name;
-    wifi_channel channel;
-} WifiIfaceInfo;
-
-typedef struct {
-    uint32_t wlan_mac_id;
-    /* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */
-    uint32_t mac_band;
-    /* Represents the connected Wi-Fi interfaces associated with each MAC */
-    std::vector<WifiIfaceInfo> iface_infos;
-} WifiMacInfo;
-
-// Callback for radio mode change
-using on_radio_mode_change_callback = std::function<void(const std::vector<WifiMacInfo>&)>;
-
-// TWT response and event callbacks struct.
-struct TwtCallbackHandlers {
-    // Callback for TWT setup response
-    std::function<void(const TwtSetupResponse&)> on_setup_response;
-    // Callback for TWT teardown completion
-    std::function<void(const TwtTeardownCompletion&)> on_teardown_completion;
-    // Callback for TWT info frame received event
-    std::function<void(const TwtInfoFrameReceived&)> on_info_frame_received;
-    // Callback for TWT notification from the device
-    std::function<void(const TwtDeviceNotify&)> on_device_notify;
-};
-
-// CHRE response and event callbacks struct.
-struct ChreCallbackHandlers {
-    // Callback for CHRE NAN RTT
-    std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
-};
-
-/**
- * Class that encapsulates all legacy HAL interactions.
- * This class manages the lifetime of the event loop thread used by legacy HAL.
- *
- * Note: There will only be a single instance of this class created in the Wifi
- * object and will be valid for the lifetime of the process.
- */
-class WifiLegacyHal {
-  public:
-    WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, const wifi_hal_fn& fn,
-                  bool is_primary);
-    virtual ~WifiLegacyHal() = default;
-
-    // Initialize the legacy HAL function table.
-    virtual wifi_error initialize();
-    // Start the legacy HAL and the event looper thread.
-    virtual wifi_error start();
-    // Deinitialize the legacy HAL and wait for the event loop thread to exit
-    // using a predefined timeout.
-    virtual wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
-                            const std::function<void()>& on_complete_callback);
-    virtual wifi_error waitForDriverReady();
-    // Checks if legacy HAL has successfully started
-    bool isStarted();
-    // Wrappers for all the functions in the legacy HAL function table.
-    virtual std::pair<wifi_error, std::string> getDriverVersion(const std::string& iface_name);
-    virtual std::pair<wifi_error, std::string> getFirmwareVersion(const std::string& iface_name);
-    std::pair<wifi_error, std::vector<uint8_t>> requestDriverMemoryDump(
-            const std::string& iface_name);
-    std::pair<wifi_error, std::vector<uint8_t>> requestFirmwareMemoryDump(
-            const std::string& iface_name);
-    virtual std::pair<wifi_error, uint64_t> getSupportedFeatureSet(const std::string& iface_name);
-    // APF functions.
-    std::pair<wifi_error, PacketFilterCapabilities> getPacketFilterCapabilities(
-            const std::string& iface_name);
-    wifi_error setPacketFilter(const std::string& iface_name, const std::vector<uint8_t>& program);
-    std::pair<wifi_error, std::vector<uint8_t>> readApfPacketFilterData(
-            const std::string& iface_name);
-    // Gscan functions.
-    std::pair<wifi_error, wifi_gscan_capabilities> getGscanCapabilities(
-            const std::string& iface_name);
-    // These API's provides a simplified interface over the legacy Gscan API's:
-    // a) All scan events from the legacy HAL API other than the
-    //    |WIFI_SCAN_FAILED| are treated as notification of results.
-    //    This method then retrieves the cached scan results from the legacy
-    //    HAL API and triggers the externally provided
-    //    |on_results_user_callback| on success.
-    // b) |WIFI_SCAN_FAILED| scan event or failure to retrieve cached scan
-    // results
-    //    triggers the externally provided |on_failure_user_callback|.
-    // c) Full scan result event triggers the externally provided
-    //    |on_full_result_user_callback|.
-    wifi_error startGscan(const std::string& iface_name, wifi_request_id id,
-                          const wifi_scan_cmd_params& params,
-                          const std::function<void(wifi_request_id)>& on_failure_callback,
-                          const on_gscan_results_callback& on_results_callback,
-                          const on_gscan_full_result_callback& on_full_result_callback);
-    wifi_error stopGscan(const std::string& iface_name, wifi_request_id id);
-    std::pair<wifi_error, std::vector<uint32_t>> getValidFrequenciesForBand(
-            const std::string& iface_name, wifi_band band);
-    virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on);
-    // Link layer stats functions.
-    wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug);
-    wifi_error disableLinkLayerStats(const std::string& iface_name);
-    std::pair<wifi_error, LinkLayerStats> getLinkLayerStats(const std::string& iface_name);
-    // RSSI monitor functions.
-    wifi_error startRssiMonitoring(
-            const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
-            const on_rssi_threshold_breached_callback& on_threshold_breached_callback);
-    wifi_error stopRssiMonitoring(const std::string& iface_name, wifi_request_id id);
-    std::pair<wifi_error, wifi_roaming_capabilities> getRoamingCapabilities(
-            const std::string& iface_name);
-    wifi_error configureRoaming(const std::string& iface_name, const wifi_roaming_config& config);
-    wifi_error enableFirmwareRoaming(const std::string& iface_name, fw_roaming_state_t state);
-    wifi_error configureNdOffload(const std::string& iface_name, bool enable);
-    wifi_error startSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id,
-                                           uint16_t ether_type,
-                                           const std::vector<uint8_t>& ip_packet_data,
-                                           const std::array<uint8_t, 6>& src_address,
-                                           const std::array<uint8_t, 6>& dst_address,
-                                           uint32_t period_in_ms);
-    wifi_error stopSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id);
-    virtual wifi_error selectTxPowerScenario(const std::string& iface_name,
-                                             wifi_power_scenario scenario);
-    virtual wifi_error resetTxPowerScenario(const std::string& iface_name);
-    wifi_error setLatencyMode(const std::string& iface_name, wifi_latency_mode mode);
-    wifi_error setThermalMitigationMode(wifi_thermal_mode mode, uint32_t completion_window);
-    wifi_error setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
-                                              uint32_t access_category);
-    wifi_error resetDscpToAccessCategoryMapping();
-    // Logger/debug functions.
-    std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet(const std::string& iface_name);
-    wifi_error startPktFateMonitoring(const std::string& iface_name);
-    std::pair<wifi_error, std::vector<wifi_tx_report>> getTxPktFates(const std::string& iface_name);
-    std::pair<wifi_error, std::vector<wifi_rx_report>> getRxPktFates(const std::string& iface_name);
-    std::pair<wifi_error, WakeReasonStats> getWakeReasonStats(const std::string& iface_name);
-    wifi_error registerRingBufferCallbackHandler(
-            const std::string& iface_name, const on_ring_buffer_data_callback& on_data_callback);
-    wifi_error deregisterRingBufferCallbackHandler(const std::string& iface_name);
-    virtual wifi_error registerSubsystemRestartCallbackHandler(
-            const on_subsystem_restart_callback& on_restart_callback);
-    std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> getRingBuffersStatus(
-            const std::string& iface_name);
-    wifi_error startRingBufferLogging(const std::string& iface_name, const std::string& ring_name,
-                                      uint32_t verbose_level, uint32_t max_interval_sec,
-                                      uint32_t min_data_size);
-    wifi_error getRingBufferData(const std::string& iface_name, const std::string& ring_name);
-    wifi_error registerErrorAlertCallbackHandler(const std::string& iface_name,
-                                                 const on_error_alert_callback& on_alert_callback);
-    wifi_error deregisterErrorAlertCallbackHandler(const std::string& iface_name);
-    // Radio mode functions.
-    virtual wifi_error registerRadioModeChangeCallbackHandler(
-            const std::string& iface_name,
-            const on_radio_mode_change_callback& on_user_change_callback);
-    // RTT functions.
-    wifi_error startRttRangeRequest(const std::string& iface_name, wifi_request_id id,
-                                    const std::vector<wifi_rtt_config>& rtt_configs,
-                                    const on_rtt_results_callback& on_results_callback);
-    wifi_error cancelRttRangeRequest(const std::string& iface_name, wifi_request_id id,
-                                     const std::vector<std::array<uint8_t, 6>>& mac_addrs);
-    std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities(const std::string& iface_name);
-    std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo(const std::string& iface_name);
-    wifi_error enableRttResponder(const std::string& iface_name, wifi_request_id id,
-                                  const wifi_channel_info& channel_hint, uint32_t max_duration_secs,
-                                  const wifi_rtt_responder& info);
-    wifi_error disableRttResponder(const std::string& iface_name, wifi_request_id id);
-    wifi_error setRttLci(const std::string& iface_name, wifi_request_id id,
-                         const wifi_lci_information& info);
-    wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id,
-                         const wifi_lcr_information& info);
-    // NAN functions.
-    virtual wifi_error nanRegisterCallbackHandlers(const std::string& iface_name,
-                                                   const NanCallbackHandlers& callbacks);
-    wifi_error nanEnableRequest(const std::string& iface_name, transaction_id id,
-                                const NanEnableRequest& msg);
-    virtual wifi_error nanDisableRequest(const std::string& iface_name, transaction_id id);
-    wifi_error nanPublishRequest(const std::string& iface_name, transaction_id id,
-                                 const NanPublishRequest& msg);
-    wifi_error nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
-                                       const NanPublishCancelRequest& msg);
-    wifi_error nanSubscribeRequest(const std::string& iface_name, transaction_id id,
-                                   const NanSubscribeRequest& msg);
-    wifi_error nanSubscribeCancelRequest(const std::string& iface_name, transaction_id id,
-                                         const NanSubscribeCancelRequest& msg);
-    wifi_error nanTransmitFollowupRequest(const std::string& iface_name, transaction_id id,
-                                          const NanTransmitFollowupRequest& msg);
-    wifi_error nanStatsRequest(const std::string& iface_name, transaction_id id,
-                               const NanStatsRequest& msg);
-    wifi_error nanConfigRequest(const std::string& iface_name, transaction_id id,
-                                const NanConfigRequest& msg);
-    wifi_error nanTcaRequest(const std::string& iface_name, transaction_id id,
-                             const NanTCARequest& msg);
-    wifi_error nanBeaconSdfPayloadRequest(const std::string& iface_name, transaction_id id,
-                                          const NanBeaconSdfPayloadRequest& msg);
-    std::pair<wifi_error, NanVersion> nanGetVersion();
-    wifi_error nanGetCapabilities(const std::string& iface_name, transaction_id id);
-    wifi_error nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
-                                      const std::string& data_iface_name);
-    virtual wifi_error nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
-                                              const std::string& data_iface_name);
-    wifi_error nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
-                                       const NanDataPathInitiatorRequest& msg);
-    wifi_error nanDataIndicationResponse(const std::string& iface_name, transaction_id id,
-                                         const NanDataPathIndicationResponse& msg);
-    wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, uint32_t ndpInstanceId);
-    // AP functions.
-    wifi_error setCountryCode(const std::string& iface_name, std::array<int8_t, 2> code);
-
-    // interface functions.
-    virtual wifi_error createVirtualInterface(const std::string& ifname,
-                                              wifi_interface_type iftype);
-    virtual wifi_error deleteVirtualInterface(const std::string& ifname);
-    virtual wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname);
-
-    // STA + STA functions
-    virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname);
-    virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case);
-
-    // Coex functions.
-    virtual wifi_error setCoexUnsafeChannels(std::vector<wifi_coex_unsafe_channel> unsafe_channels,
-                                             uint32_t restrictions);
-
-    wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode);
-
-    wifi_error twtRegisterHandler(const std::string& iface_name,
-                                  const TwtCallbackHandlers& handler);
-
-    std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(const std::string& iface_name);
-
-    wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg);
-
-    wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg);
-
-    wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg);
-
-    std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, uint8_t configId);
-
-    wifi_error twtClearStats(const std::string& iface_name, uint8_t configId);
-
-    wifi_error setDtimConfig(const std::string& iface_name, uint32_t multiplier);
-
-    // Retrieve the list of usable channels in the requested bands
-    // for the requested modes
-    std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels(
-            uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask);
-
-    wifi_error triggerSubsystemRestart();
-
-    wifi_error setIndoorState(bool isIndoor);
-
-    std::pair<wifi_error, wifi_radio_combination_matrix*> getSupportedRadioCombinationsMatrix();
-
-    // CHRE NAN RTT function
-    wifi_error chreNanRttRequest(const std::string& iface_name, bool enable);
-
-    wifi_error chreRegisterHandler(const std::string& iface_name,
-                                   const ChreCallbackHandlers& handler);
-
-    wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
-
-  private:
-    // Retrieve interface handles for all the available interfaces.
-    wifi_error retrieveIfaceHandles();
-    wifi_interface_handle getIfaceHandle(const std::string& iface_name);
-    // Run the legacy HAL event loop thread.
-    void runEventLoop();
-    // Retrieve the cached gscan results to pass the results back to the
-    // external callbacks.
-    std::pair<wifi_error, std::vector<wifi_cached_scan_results>> getGscanCachedResults(
-            const std::string& iface_name);
-    void invalidate();
-    // Handles wifi (error) status of Virtual interface create/delete
-    wifi_error handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
-                                                          wifi_error status);
-
-    // Global function table of legacy HAL.
-    wifi_hal_fn global_func_table_;
-    // Opaque handle to be used for all global operations.
-    wifi_handle global_handle_;
-    // Map of interface name to handle that is to be used for all interface
-    // specific operations.
-    std::map<std::string, wifi_interface_handle> iface_name_to_handle_;
-    // Flag to indicate if we have initiated the cleanup of legacy HAL.
-    std::atomic<bool> awaiting_event_loop_termination_;
-    std::condition_variable_any stop_wait_cv_;
-    // Flag to indicate if the legacy HAL has been started.
-    bool is_started_;
-    std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
-    // flag to indicate if this HAL is for the primary chip. This is used
-    // in order to avoid some hard-coded behavior used with older HALs,
-    // such as bring wlan0 interface up/down on start/stop HAL.
-    // it may be removed once vendor HALs are updated.
-    bool is_primary_;
-};
-
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_LEGACY_HAL_H_
diff --git a/wifi/1.6/default/wifi_legacy_hal_factory.cpp b/wifi/1.6/default/wifi_legacy_hal_factory.cpp
deleted file mode 100644
index 147bf4d..0000000
--- a/wifi/1.6/default/wifi_legacy_hal_factory.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 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.
- */
-
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <android-base/logging.h>
-#include <dlfcn.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xmlmemory.h>
-
-#include "wifi_legacy_hal_factory.h"
-#include "wifi_legacy_hal_stubs.h"
-
-namespace {
-static constexpr char kVendorHalsDescPath[] = "/vendor/etc/wifi/vendor_hals";
-static constexpr char kVendorHalsDescExt[] = ".xml";
-static constexpr uint32_t kVendorHalsDescVersion = 1;
-
-bool isDirectory(struct dirent* entryPtr) {
-    bool isDir = false;
-    if (entryPtr->d_type != DT_UNKNOWN && entryPtr->d_type != DT_LNK) {
-        isDir = (entryPtr->d_type == DT_DIR);
-    } else {
-        struct stat entryStat;
-        stat(entryPtr->d_name, &entryStat);
-        isDir = S_ISDIR(entryStat.st_mode);
-    }
-    return isDir;
-}
-
-bool isFileExtension(const char* name, const char* ext) {
-    if (name == NULL) return false;
-    if (ext == NULL) return false;
-
-    size_t extLen = strlen(ext);
-    size_t nameLen = strlen(name);
-
-    if (extLen > nameLen) return false;
-
-    if (strncmp(name + nameLen - extLen, ext, extLen) != 0) return false;
-
-    return true;
-}
-};  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace legacy_hal {
-
-WifiLegacyHalFactory::WifiLegacyHalFactory(
-        const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
-    : iface_tool_(iface_tool) {}
-
-std::vector<std::shared_ptr<WifiLegacyHal>> WifiLegacyHalFactory::getHals() {
-    if (legacy_hals_.empty()) {
-        if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList();
-        for (auto& desc : descs_) {
-            std::shared_ptr<WifiLegacyHal> hal =
-                    std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn, desc.primary);
-            legacy_hals_.push_back(hal);
-        }
-    }
-
-    return legacy_hals_;
-}
-
-bool WifiLegacyHalFactory::initVendorHalDescriptorFromLinked() {
-    wifi_hal_lib_desc desc;
-
-    if (!initLinkedHalFunctionTable(&desc.fn)) return false;
-
-    desc.primary = true;
-    desc.handle = NULL;
-    descs_.push_back(desc);
-    return true;
-}
-
-bool WifiLegacyHalFactory::initLinkedHalFunctionTable(wifi_hal_fn* hal_fn) {
-    init_wifi_vendor_hal_func_table_t initfn;
-
-    initfn = (init_wifi_vendor_hal_func_table_t)dlsym(RTLD_DEFAULT,
-                                                      "init_wifi_vendor_hal_func_table");
-    if (!initfn) {
-        LOG(INFO) << "no vendor HAL library linked, will try dynamic load";
-        return false;
-    }
-
-    if (!initHalFuncTableWithStubs(hal_fn)) {
-        LOG(ERROR) << "Can not initialize the basic function pointer table";
-        return false;
-    }
-
-    if (initfn(hal_fn) != WIFI_SUCCESS) {
-        LOG(ERROR) << "Can not initialize the vendor function pointer table";
-        return false;
-    }
-
-    return true;
-}
-
-/*
- * Overall structure of the HAL descriptor XML schema
- *
- * <?xml version="1.0" encoding="UTF-8"?>
- * <WifiVendorHal version="1">
- * <path>/vendor/lib64/libwifi-hal-qcom.so</path>
- * <primary>1</primary>
- * </WifiVendorHal>
- */
-void WifiLegacyHalFactory::initVendorHalsDescriptorList() {
-    xmlDocPtr xml;
-    xmlNodePtr node, cnode;
-    char* version;
-    std::string path;
-    xmlChar* value;
-    wifi_hal_lib_desc desc;
-
-    LOG(INFO) << "processing vendor HALs descriptions in " << kVendorHalsDescPath;
-    DIR* dirPtr = ::opendir(kVendorHalsDescPath);
-    if (dirPtr == NULL) {
-        LOG(ERROR) << "failed to open " << kVendorHalsDescPath;
-        return;
-    }
-    for (struct dirent* entryPtr = ::readdir(dirPtr); entryPtr != NULL;
-         entryPtr = ::readdir(dirPtr)) {
-        if (isDirectory(entryPtr)) continue;
-
-        if (!isFileExtension(entryPtr->d_name, kVendorHalsDescExt))
-            continue;  // only process .xml files
-
-        LOG(INFO) << "processing config file: " << entryPtr->d_name;
-
-        std::string fullPath(kVendorHalsDescPath);
-        fullPath.append("/");
-        fullPath.append(entryPtr->d_name);
-        xml = xmlReadFile(fullPath.c_str(), "UTF-8", XML_PARSE_RECOVER);
-        if (!xml) {
-            LOG(ERROR) << "failed to parse: " << entryPtr->d_name << " skipping...";
-            continue;
-        }
-        node = xmlDocGetRootElement(xml);
-        if (!node) {
-            LOG(ERROR) << "empty config file: " << entryPtr->d_name << " skipping...";
-            goto skip;
-        }
-        if (xmlStrcmp(node->name, BAD_CAST "WifiVendorHal")) {
-            LOG(ERROR) << "bad config, root element not WifiVendorHal: " << entryPtr->d_name
-                       << " skipping...";
-            goto skip;
-        }
-        version = (char*)xmlGetProp(node, BAD_CAST "version");
-        if (!version || strtoul(version, NULL, 0) != kVendorHalsDescVersion) {
-            LOG(ERROR) << "conf file: " << entryPtr->d_name
-                       << "must have version: " << kVendorHalsDescVersion << ", skipping...";
-            goto skip;
-        }
-        cnode = node->children;
-        path.clear();
-        desc.primary = false;
-        while (cnode) {
-            if (!xmlStrcmp(cnode->name, BAD_CAST "path")) {
-                value = xmlNodeListGetString(xml, cnode->children, 1);
-                if (value) path = (char*)value;
-                xmlFree(value);
-            } else if (!xmlStrcmp(cnode->name, BAD_CAST "primary")) {
-                value = xmlNodeListGetString(xml, cnode->children, 1);
-                desc.primary = !xmlStrcmp(value, BAD_CAST "1");
-                xmlFree(value);
-            }
-            cnode = cnode->next;
-        }
-        if (path.empty()) {
-            LOG(ERROR) << "hal library path not provided in: " << entryPtr->d_name
-                       << ", skipping...";
-            goto skip;
-        }
-        if (loadVendorHalLib(path, desc)) {
-            if (desc.primary)
-                descs_.insert(descs_.begin(), desc);
-            else
-                descs_.push_back(desc);
-        }
-    skip:
-        xmlFreeDoc(xml);
-    }
-    ::closedir(dirPtr);
-}
-
-bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc) {
-    void* h = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
-    init_wifi_vendor_hal_func_table_t initfn;
-    wifi_error res;
-
-    if (!h) {
-        LOG(ERROR) << "failed to open vendor hal library: " << path;
-        return false;
-    }
-    initfn = (init_wifi_vendor_hal_func_table_t)dlsym(h, "init_wifi_vendor_hal_func_table");
-    if (!initfn) {
-        LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path;
-        goto out_err;
-    }
-
-    if (!initHalFuncTableWithStubs(&desc.fn)) {
-        LOG(ERROR) << "Can not initialize the basic function pointer table";
-        goto out_err;
-    }
-    res = initfn(&desc.fn);
-    if (res != WIFI_SUCCESS) {
-        LOG(ERROR) << "failed to initialize the vendor func table in: " << path
-                   << " error: " << res;
-        goto out_err;
-    }
-
-    res = desc.fn.wifi_early_initialize();
-    // vendor HALs which do not implement early_initialize will return
-    // WIFI_ERROR_NOT_SUPPORTED, treat this as success.
-    if (res != WIFI_SUCCESS && res != WIFI_ERROR_NOT_SUPPORTED) {
-        LOG(ERROR) << "early initialization failed in: " << path << " error: " << res;
-        goto out_err;
-    }
-
-    desc.handle = h;
-    return true;
-out_err:
-    dlclose(h);
-    return false;
-}
-
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_legacy_hal_factory.h b/wifi/1.6/default/wifi_legacy_hal_factory.h
deleted file mode 100644
index 9f4423e..0000000
--- a/wifi/1.6/default/wifi_legacy_hal_factory.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef WIFI_LEGACY_HAL_FACTORY_H_
-#define WIFI_LEGACY_HAL_FACTORY_H_
-
-#include <wifi_system/interface_tool.h>
-
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-// This is in a separate namespace to prevent typename conflicts between
-// the legacy HAL types and the HIDL interface types.
-namespace legacy_hal {
-/**
- * Class that creates WifiLegacyHal objects for vendor HALs in the system.
- */
-class WifiLegacyHalFactory {
-  public:
-    WifiLegacyHalFactory(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
-    virtual ~WifiLegacyHalFactory() = default;
-
-    std::vector<std::shared_ptr<WifiLegacyHal>> getHals();
-
-  private:
-    typedef struct {
-        wifi_hal_fn fn;
-        bool primary;
-        void* handle;
-    } wifi_hal_lib_desc;
-
-    bool initVendorHalDescriptorFromLinked();
-    void initVendorHalsDescriptorList();
-    bool initLinkedHalFunctionTable(wifi_hal_fn* hal_fn);
-    bool loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc);
-
-    std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
-    std::vector<wifi_hal_lib_desc> descs_;
-    std::vector<std::shared_ptr<WifiLegacyHal>> legacy_hals_;
-};
-
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_LEGACY_HAL_FACTORY_H_
diff --git a/wifi/1.6/default/wifi_legacy_hal_stubs.cpp b/wifi/1.6/default/wifi_legacy_hal_stubs.cpp
deleted file mode 100644
index b3bd373..0000000
--- a/wifi/1.6/default/wifi_legacy_hal_stubs.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2016 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 "wifi_legacy_hal_stubs.h"
-
-// TODO: Remove these stubs from HalTool in libwifi-system.
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace legacy_hal {
-template <typename>
-struct stubFunction;
-
-template <typename R, typename... Args>
-struct stubFunction<R (*)(Args...)> {
-    static constexpr R invoke(Args...) { return WIFI_ERROR_NOT_SUPPORTED; }
-};
-template <typename... Args>
-struct stubFunction<void (*)(Args...)> {
-    static constexpr void invoke(Args...) {}
-};
-
-template <typename T>
-void populateStubFor(T* val) {
-    *val = &stubFunction<T>::invoke;
-}
-
-bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) {
-    if (hal_fn == nullptr) {
-        return false;
-    }
-    populateStubFor(&hal_fn->wifi_initialize);
-    populateStubFor(&hal_fn->wifi_wait_for_driver_ready);
-    populateStubFor(&hal_fn->wifi_cleanup);
-    populateStubFor(&hal_fn->wifi_event_loop);
-    populateStubFor(&hal_fn->wifi_get_error_info);
-    populateStubFor(&hal_fn->wifi_get_supported_feature_set);
-    populateStubFor(&hal_fn->wifi_get_concurrency_matrix);
-    populateStubFor(&hal_fn->wifi_set_scanning_mac_oui);
-    populateStubFor(&hal_fn->wifi_get_supported_channels);
-    populateStubFor(&hal_fn->wifi_is_epr_supported);
-    populateStubFor(&hal_fn->wifi_get_ifaces);
-    populateStubFor(&hal_fn->wifi_get_iface_name);
-    populateStubFor(&hal_fn->wifi_set_iface_event_handler);
-    populateStubFor(&hal_fn->wifi_reset_iface_event_handler);
-    populateStubFor(&hal_fn->wifi_start_gscan);
-    populateStubFor(&hal_fn->wifi_stop_gscan);
-    populateStubFor(&hal_fn->wifi_get_cached_gscan_results);
-    populateStubFor(&hal_fn->wifi_set_bssid_hotlist);
-    populateStubFor(&hal_fn->wifi_reset_bssid_hotlist);
-    populateStubFor(&hal_fn->wifi_set_significant_change_handler);
-    populateStubFor(&hal_fn->wifi_reset_significant_change_handler);
-    populateStubFor(&hal_fn->wifi_get_gscan_capabilities);
-    populateStubFor(&hal_fn->wifi_set_link_stats);
-    populateStubFor(&hal_fn->wifi_get_link_stats);
-    populateStubFor(&hal_fn->wifi_clear_link_stats);
-    populateStubFor(&hal_fn->wifi_get_valid_channels);
-    populateStubFor(&hal_fn->wifi_rtt_range_request);
-    populateStubFor(&hal_fn->wifi_rtt_range_cancel);
-    populateStubFor(&hal_fn->wifi_get_rtt_capabilities);
-    populateStubFor(&hal_fn->wifi_rtt_get_responder_info);
-    populateStubFor(&hal_fn->wifi_enable_responder);
-    populateStubFor(&hal_fn->wifi_disable_responder);
-    populateStubFor(&hal_fn->wifi_set_nodfs_flag);
-    populateStubFor(&hal_fn->wifi_start_logging);
-    populateStubFor(&hal_fn->wifi_set_epno_list);
-    populateStubFor(&hal_fn->wifi_reset_epno_list);
-    populateStubFor(&hal_fn->wifi_set_country_code);
-    populateStubFor(&hal_fn->wifi_get_firmware_memory_dump);
-    populateStubFor(&hal_fn->wifi_set_log_handler);
-    populateStubFor(&hal_fn->wifi_reset_log_handler);
-    populateStubFor(&hal_fn->wifi_set_alert_handler);
-    populateStubFor(&hal_fn->wifi_reset_alert_handler);
-    populateStubFor(&hal_fn->wifi_get_firmware_version);
-    populateStubFor(&hal_fn->wifi_get_ring_buffers_status);
-    populateStubFor(&hal_fn->wifi_get_logger_supported_feature_set);
-    populateStubFor(&hal_fn->wifi_get_ring_data);
-    populateStubFor(&hal_fn->wifi_enable_tdls);
-    populateStubFor(&hal_fn->wifi_disable_tdls);
-    populateStubFor(&hal_fn->wifi_get_tdls_status);
-    populateStubFor(&hal_fn->wifi_get_tdls_capabilities);
-    populateStubFor(&hal_fn->wifi_get_driver_version);
-    populateStubFor(&hal_fn->wifi_set_passpoint_list);
-    populateStubFor(&hal_fn->wifi_reset_passpoint_list);
-    populateStubFor(&hal_fn->wifi_set_lci);
-    populateStubFor(&hal_fn->wifi_set_lcr);
-    populateStubFor(&hal_fn->wifi_start_sending_offloaded_packet);
-    populateStubFor(&hal_fn->wifi_stop_sending_offloaded_packet);
-    populateStubFor(&hal_fn->wifi_start_rssi_monitoring);
-    populateStubFor(&hal_fn->wifi_stop_rssi_monitoring);
-    populateStubFor(&hal_fn->wifi_get_wake_reason_stats);
-    populateStubFor(&hal_fn->wifi_configure_nd_offload);
-    populateStubFor(&hal_fn->wifi_get_driver_memory_dump);
-    populateStubFor(&hal_fn->wifi_start_pkt_fate_monitoring);
-    populateStubFor(&hal_fn->wifi_get_tx_pkt_fates);
-    populateStubFor(&hal_fn->wifi_get_rx_pkt_fates);
-    populateStubFor(&hal_fn->wifi_nan_enable_request);
-    populateStubFor(&hal_fn->wifi_nan_disable_request);
-    populateStubFor(&hal_fn->wifi_nan_publish_request);
-    populateStubFor(&hal_fn->wifi_nan_publish_cancel_request);
-    populateStubFor(&hal_fn->wifi_nan_subscribe_request);
-    populateStubFor(&hal_fn->wifi_nan_subscribe_cancel_request);
-    populateStubFor(&hal_fn->wifi_nan_transmit_followup_request);
-    populateStubFor(&hal_fn->wifi_nan_stats_request);
-    populateStubFor(&hal_fn->wifi_nan_config_request);
-    populateStubFor(&hal_fn->wifi_nan_tca_request);
-    populateStubFor(&hal_fn->wifi_nan_beacon_sdf_payload_request);
-    populateStubFor(&hal_fn->wifi_nan_register_handler);
-    populateStubFor(&hal_fn->wifi_nan_get_version);
-    populateStubFor(&hal_fn->wifi_nan_get_capabilities);
-    populateStubFor(&hal_fn->wifi_nan_data_interface_create);
-    populateStubFor(&hal_fn->wifi_nan_data_interface_delete);
-    populateStubFor(&hal_fn->wifi_nan_data_request_initiator);
-    populateStubFor(&hal_fn->wifi_nan_data_indication_response);
-    populateStubFor(&hal_fn->wifi_nan_data_end);
-    populateStubFor(&hal_fn->wifi_get_packet_filter_capabilities);
-    populateStubFor(&hal_fn->wifi_set_packet_filter);
-    populateStubFor(&hal_fn->wifi_read_packet_filter);
-    populateStubFor(&hal_fn->wifi_get_roaming_capabilities);
-    populateStubFor(&hal_fn->wifi_enable_firmware_roaming);
-    populateStubFor(&hal_fn->wifi_configure_roaming);
-    populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
-    populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
-    populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler);
-    populateStubFor(&hal_fn->wifi_set_latency_mode);
-    populateStubFor(&hal_fn->wifi_set_thermal_mitigation_mode);
-    populateStubFor(&hal_fn->wifi_virtual_interface_create);
-    populateStubFor(&hal_fn->wifi_virtual_interface_delete);
-    populateStubFor(&hal_fn->wifi_map_dscp_access_category);
-    populateStubFor(&hal_fn->wifi_reset_dscp_mapping);
-    populateStubFor(&hal_fn->wifi_set_subsystem_restart_handler);
-    populateStubFor(&hal_fn->wifi_get_supported_iface_name);
-    populateStubFor(&hal_fn->wifi_early_initialize);
-    populateStubFor(&hal_fn->wifi_get_chip_feature_set);
-    populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection);
-    populateStubFor(&hal_fn->wifi_multi_sta_set_use_case);
-    populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels);
-    populateStubFor(&hal_fn->wifi_set_voip_mode);
-    populateStubFor(&hal_fn->wifi_twt_register_handler);
-    populateStubFor(&hal_fn->wifi_twt_get_capability);
-    populateStubFor(&hal_fn->wifi_twt_setup_request);
-    populateStubFor(&hal_fn->wifi_twt_teardown_request);
-    populateStubFor(&hal_fn->wifi_twt_info_frame_request);
-    populateStubFor(&hal_fn->wifi_twt_get_stats);
-    populateStubFor(&hal_fn->wifi_twt_clear_stats);
-    populateStubFor(&hal_fn->wifi_set_dtim_config);
-    populateStubFor(&hal_fn->wifi_get_usable_channels);
-    populateStubFor(&hal_fn->wifi_trigger_subsystem_restart);
-    populateStubFor(&hal_fn->wifi_set_indoor_state);
-    populateStubFor(&hal_fn->wifi_get_supported_radio_combinations_matrix);
-    populateStubFor(&hal_fn->wifi_nan_rtt_chre_enable_request);
-    populateStubFor(&hal_fn->wifi_nan_rtt_chre_disable_request);
-    populateStubFor(&hal_fn->wifi_chre_register_handler);
-    populateStubFor(&hal_fn->wifi_enable_tx_power_limits);
-    return true;
-}
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_legacy_hal_stubs.h b/wifi/1.6/default/wifi_legacy_hal_stubs.h
deleted file mode 100644
index c9a03bf..0000000
--- a/wifi/1.6/default/wifi_legacy_hal_stubs.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_LEGACY_HAL_STUBS_H_
-#define WIFI_LEGACY_HAL_STUBS_H_
-
-#include <hardware_legacy/wifi_hal.h>
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace legacy_hal {
-
-bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn);
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_LEGACY_HAL_STUBS_H_
diff --git a/wifi/1.6/default/wifi_mode_controller.cpp b/wifi/1.6/default/wifi_mode_controller.cpp
deleted file mode 100644
index 4b8ac7d..0000000
--- a/wifi/1.6/default/wifi_mode_controller.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2016 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 <android-base/macros.h>
-#include <private/android_filesystem_config.h>
-
-#include "wifi_mode_controller.h"
-
-using android::hardware::wifi::V1_0::IfaceType;
-using android::wifi_hal::DriverTool;
-
-namespace {
-int convertIfaceTypeToFirmwareMode(IfaceType type) {
-    int mode;
-    switch (type) {
-        case IfaceType::AP:
-            mode = DriverTool::kFirmwareModeAp;
-            break;
-        case IfaceType::P2P:
-            mode = DriverTool::kFirmwareModeP2p;
-            break;
-        case IfaceType::NAN:
-            // NAN is exposed in STA mode currently.
-            mode = DriverTool::kFirmwareModeSta;
-            break;
-        case IfaceType::STA:
-            mode = DriverTool::kFirmwareModeSta;
-            break;
-    }
-    return mode;
-}
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace mode_controller {
-
-WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {}
-
-bool WifiModeController::isFirmwareModeChangeNeeded(IfaceType type) {
-    return driver_tool_->IsFirmwareModeChangeNeeded(convertIfaceTypeToFirmwareMode(type));
-}
-
-bool WifiModeController::initialize() {
-    if (!driver_tool_->LoadDriver()) {
-        LOG(ERROR) << "Failed to load WiFi driver";
-        return false;
-    }
-    return true;
-}
-
-bool WifiModeController::changeFirmwareMode(IfaceType type) {
-    if (!driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))) {
-        LOG(ERROR) << "Failed to change firmware mode";
-        return false;
-    }
-    return true;
-}
-
-bool WifiModeController::deinitialize() {
-    if (!driver_tool_->UnloadDriver()) {
-        LOG(ERROR) << "Failed to unload WiFi driver";
-        return false;
-    }
-    return true;
-}
-}  // namespace mode_controller
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_mode_controller.h b/wifi/1.6/default/wifi_mode_controller.h
deleted file mode 100644
index fee2b66..0000000
--- a/wifi/1.6/default/wifi_mode_controller.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_MODE_CONTROLLER_H_
-#define WIFI_MODE_CONTROLLER_H_
-
-#include <wifi_hal/driver_tool.h>
-
-#include <android/hardware/wifi/1.0/IWifi.h>
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-namespace mode_controller {
-using namespace android::hardware::wifi::V1_0;
-
-/**
- * Class that encapsulates all firmware mode configuration.
- * This class will perform the necessary firmware reloads to put the chip in the
- * required state (essentially a wrapper over DriverTool).
- */
-class WifiModeController {
-  public:
-    WifiModeController();
-    virtual ~WifiModeController() = default;
-
-    // Checks if a firmware mode change is necessary to support the specified
-    // iface type operations.
-    virtual bool isFirmwareModeChangeNeeded(IfaceType type);
-    virtual bool initialize();
-    // Change the firmware mode to support the specified iface type operations.
-    virtual bool changeFirmwareMode(IfaceType type);
-    // Unload the driver. This should be invoked whenever |IWifi.stop()| is
-    // invoked.
-    virtual bool deinitialize();
-
-  private:
-    std::unique_ptr<wifi_hal::DriverTool> driver_tool_;
-};
-
-}  // namespace mode_controller
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_MODE_CONTROLLER_H_
diff --git a/wifi/1.6/default/wifi_nan_iface.cpp b/wifi/1.6/default/wifi_nan_iface.cpp
deleted file mode 100644
index ac2ebc9..0000000
--- a/wifi/1.6/default/wifi_nan_iface.cpp
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * Copyright (C) 2016 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 "hidl_return_util.h"
-#include "hidl_struct_util.h"
-#include "wifi_nan_iface.h"
-#include "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-WifiNanIface::WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
-                           const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-                           const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
-    : ifname_(ifname),
-      is_dedicated_iface_(is_dedicated_iface),
-      legacy_hal_(legacy_hal),
-      iface_util_(iface_util),
-      is_valid_(true) {
-    if (is_dedicated_iface_) {
-        // If using a dedicated iface, set the iface up first.
-        if (!iface_util_.lock()->setUpState(ifname_, true)) {
-            // Fatal failure, invalidate the iface object.
-            invalidate();
-            return;
-        }
-    }
-    // Register all the callbacks here. these should be valid for the lifetime
-    // of the object. Whenever the mode changes legacy HAL will remove
-    // all of these callbacks.
-    legacy_hal::NanCallbackHandlers callback_handlers;
-    android::wp<WifiNanIface> weak_ptr_this(this);
-
-    // Callback for response.
-    callback_handlers.on_notify_response = [weak_ptr_this](legacy_hal::transaction_id id,
-                                                           const legacy_hal::NanResponseMsg& msg) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        WifiNanStatus wifiNanStatus;
-        if (!hidl_struct_util::convertLegacyNanResponseHeaderToHidl(msg, &wifiNanStatus)) {
-            LOG(ERROR) << "Failed to convert nan response header";
-            return;
-        }
-
-        switch (msg.response_type) {
-            case legacy_hal::NAN_RESPONSE_ENABLED: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyEnableResponse(id, wifiNanStatus).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_DISABLED: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyDisableResponse(id, wifiNanStatus).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_PUBLISH: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyStartPublishResponse(id, wifiNanStatus,
-                                                              msg.body.publish_response.publish_id)
-                                 .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyStopPublishResponse(id, wifiNanStatus).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyTransmitFollowupResponse(id, wifiNanStatus).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_SUBSCRIBE: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyStartSubscribeResponse(
-                                         id, wifiNanStatus,
-                                         msg.body.subscribe_response.subscribe_id)
-                                 .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyStopSubscribeResponse(id, wifiNanStatus).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_CONFIG: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyConfigResponse(id, wifiNanStatus).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_GET_CAPABILITIES: {
-                V1_6::NanCapabilities hidl_struct;
-                if (!hidl_struct_util::convertLegacyNanCapabilitiesResponseToHidl(
-                            msg.body.nan_capabilities, &hidl_struct)) {
-                    LOG(ERROR) << "Failed to convert nan capabilities response";
-                    return;
-                }
-                for (const auto& callback : shared_ptr_this->getEventCallbacks_1_6()) {
-                    if (!callback->notifyCapabilitiesResponse_1_6(id, wifiNanStatus, hidl_struct)
-                                 .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_INTERFACE_CREATE: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyCreateDataInterfaceResponse(id, wifiNanStatus).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_INTERFACE_DELETE: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyDeleteDataInterfaceResponse(id, wifiNanStatus).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_INITIATOR_RESPONSE: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyInitiateDataPathResponse(
-                                         id, wifiNanStatus,
-                                         msg.body.data_request_response.ndp_instance_id)
-                                 .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_RESPONDER_RESPONSE: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyRespondToDataPathIndicationResponse(id, wifiNanStatus)
-                                 .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_END: {
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyTerminateDataPathResponse(id, wifiNanStatus).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD:
-            /* fall through */
-            case legacy_hal::NAN_RESPONSE_TCA:
-            /* fall through */
-            case legacy_hal::NAN_RESPONSE_STATS:
-            /* fall through */
-            case legacy_hal::NAN_RESPONSE_ERROR:
-            /* fall through */
-            default:
-                LOG(ERROR) << "Unknown or unhandled response type: " << msg.response_type;
-                return;
-        }
-    };
-
-    callback_handlers.on_event_disc_eng_event =
-            [weak_ptr_this](const legacy_hal::NanDiscEngEventInd& msg) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                NanClusterEventInd hidl_struct;
-                // event types defined identically - hence can be cast
-                hidl_struct.eventType = (NanClusterEventType)msg.event_type;
-                hidl_struct.addr = msg.data.mac_addr.addr;
-
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->eventClusterEvent(hidl_struct).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-            };
-
-    callback_handlers.on_event_disabled = [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        WifiNanStatus status;
-        hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
-                                                 &status);
-
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->eventDisabled(status).isOk()) {
-                LOG(ERROR) << "Failed to invoke the callback";
-            }
-        }
-    };
-
-    callback_handlers.on_event_publish_terminated =
-            [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                WifiNanStatus status;
-                hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason,
-                                                         sizeof(msg.nan_reason), &status);
-
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->eventPublishTerminated(msg.publish_id, status).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-            };
-
-    callback_handlers.on_event_subscribe_terminated =
-            [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                WifiNanStatus status;
-                hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason,
-                                                         sizeof(msg.nan_reason), &status);
-
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->eventSubscribeTerminated(msg.subscribe_id, status).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-            };
-
-    callback_handlers.on_event_match = [weak_ptr_this](const legacy_hal::NanMatchInd& msg) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        V1_6::NanMatchInd hidl_struct;
-        if (!hidl_struct_util::convertLegacyNanMatchIndToHidl(msg, &hidl_struct)) {
-            LOG(ERROR) << "Failed to convert nan capabilities response";
-            return;
-        }
-
-        for (const auto& callback : shared_ptr_this->getEventCallbacks_1_6()) {
-            if (!callback->eventMatch_1_6(hidl_struct).isOk()) {
-                LOG(ERROR) << "Failed to invoke the callback";
-            }
-        }
-    };
-
-    callback_handlers.on_event_match_expired = [weak_ptr_this](
-                                                       const legacy_hal::NanMatchExpiredInd& msg) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->eventMatchExpired(msg.publish_subscribe_id, msg.requestor_instance_id)
-                         .isOk()) {
-                LOG(ERROR) << "Failed to invoke the callback";
-            }
-        }
-    };
-
-    callback_handlers.on_event_followup = [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        NanFollowupReceivedInd hidl_struct;
-        if (!hidl_struct_util::convertLegacyNanFollowupIndToHidl(msg, &hidl_struct)) {
-            LOG(ERROR) << "Failed to convert nan capabilities response";
-            return;
-        }
-
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->eventFollowupReceived(hidl_struct).isOk()) {
-                LOG(ERROR) << "Failed to invoke the callback";
-            }
-        }
-    };
-
-    callback_handlers.on_event_transmit_follow_up =
-            [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                WifiNanStatus status;
-                hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason,
-                                                         sizeof(msg.nan_reason), &status);
-
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->eventTransmitFollowup(msg.id, status).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-            };
-
-    callback_handlers.on_event_data_path_request =
-            [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                NanDataPathRequestInd hidl_struct;
-                if (!hidl_struct_util::convertLegacyNanDataPathRequestIndToHidl(msg,
-                                                                                &hidl_struct)) {
-                    LOG(ERROR) << "Failed to convert nan capabilities response";
-                    return;
-                }
-
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->eventDataPathRequest(hidl_struct).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-            };
-
-    callback_handlers.on_event_data_path_confirm =
-            [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                V1_6::NanDataPathConfirmInd hidl_struct;
-                if (!hidl_struct_util::convertLegacyNanDataPathConfirmIndToHidl(msg,
-                                                                                &hidl_struct)) {
-                    LOG(ERROR) << "Failed to convert nan capabilities response";
-                    return;
-                }
-
-                for (const auto& callback : shared_ptr_this->getEventCallbacks_1_6()) {
-                    if (!callback->eventDataPathConfirm_1_6(hidl_struct).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-            };
-
-    callback_handlers.on_event_data_path_end =
-            [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    for (int i = 0; i < msg.num_ndp_instances; ++i) {
-                        if (!callback->eventDataPathTerminated(msg.ndp_instance_id[i]).isOk()) {
-                            LOG(ERROR) << "Failed to invoke the callback";
-                        }
-                    }
-                }
-            };
-
-    callback_handlers.on_event_beacon_sdf_payload =
-            [weak_ptr_this](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) {
-                LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called";
-            };
-
-    callback_handlers.on_event_range_request =
-            [weak_ptr_this](const legacy_hal::NanRangeRequestInd& /* msg */) {
-                LOG(ERROR) << "on_event_range_request - should not be called";
-            };
-
-    callback_handlers.on_event_range_report =
-            [weak_ptr_this](const legacy_hal::NanRangeReportInd& /* msg */) {
-                LOG(ERROR) << "on_event_range_report - should not be called";
-            };
-
-    callback_handlers.on_event_schedule_update =
-            [weak_ptr_this](const legacy_hal::NanDataPathScheduleUpdateInd& msg) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                V1_6::NanDataPathScheduleUpdateInd hidl_struct;
-                if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl(
-                            msg, &hidl_struct)) {
-                    LOG(ERROR) << "Failed to convert nan capabilities response";
-                    return;
-                }
-
-                for (const auto& callback : shared_ptr_this->getEventCallbacks_1_6()) {
-                    if (!callback->eventDataPathScheduleUpdate_1_6(hidl_struct).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-            };
-
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, callback_handlers);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
-        invalidate();
-    }
-
-    // Register for iface state toggle events.
-    iface_util::IfaceEventHandlers event_handlers = {};
-    event_handlers.on_state_toggle_off_on = [weak_ptr_this](const std::string& /* iface_name */) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        // Tell framework that NAN has been disabled.
-        WifiNanStatus status = {NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->eventDisabled(status).isOk()) {
-                LOG(ERROR) << "Failed to invoke the callback";
-            }
-        }
-    };
-    iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
-}
-
-void WifiNanIface::invalidate() {
-    if (!isValid()) {
-        return;
-    }
-    // send commands to HAL to actually disable and destroy interfaces
-    legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
-    legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
-    legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
-    iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
-    legacy_hal_.reset();
-    event_cb_handler_.invalidate();
-    event_cb_handler_1_2_.invalidate();
-    event_cb_handler_1_5_.invalidate();
-    is_valid_ = false;
-    if (is_dedicated_iface_) {
-        // If using a dedicated iface, set the iface down.
-        iface_util_.lock()->setUpState(ifname_, false);
-    }
-}
-
-bool WifiNanIface::isValid() {
-    return is_valid_;
-}
-
-std::string WifiNanIface::getName() {
-    return ifname_;
-}
-
-std::set<sp<V1_0::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks() {
-    return event_cb_handler_.getCallbacks();
-}
-
-std::set<sp<V1_2::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_2() {
-    return event_cb_handler_1_2_.getCallbacks();
-}
-
-std::set<sp<V1_5::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_5() {
-    return event_cb_handler_1_5_.getCallbacks();
-}
-
-std::set<sp<V1_6::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_6() {
-    return event_cb_handler_1_6_.getCallbacks();
-}
-
-Return<void> WifiNanIface::getName(getName_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::getNameInternal, hidl_status_cb);
-}
-
-Return<void> WifiNanIface::getType(getType_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::getTypeInternal, hidl_status_cb);
-}
-
-Return<void> WifiNanIface::registerEventCallback(
-        const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
-        registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::registerEventCallbackInternal, hidl_status_cb, callback);
-}
-
-Return<void> WifiNanIface::getCapabilitiesRequest(uint16_t cmd_id,
-                                                  getCapabilitiesRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::getCapabilitiesRequestInternal, hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiNanIface::enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg,
-                                         enableRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::enableRequestInternal, hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
-                                         configRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::configRequestInternal, hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::disableRequestInternal, hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiNanIface::startPublishRequest(uint16_t cmd_id, const V1_0::NanPublishRequest& msg,
-                                               startPublishRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::startPublishRequestInternal, hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::stopPublishRequest(uint16_t cmd_id, uint8_t sessionId,
-                                              stopPublishRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::stopPublishRequestInternal, hidl_status_cb, cmd_id,
-                           sessionId);
-}
-
-Return<void> WifiNanIface::startSubscribeRequest(uint16_t cmd_id,
-                                                 const V1_0::NanSubscribeRequest& msg,
-                                                 startSubscribeRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::startSubscribeRequestInternal, hidl_status_cb, cmd_id,
-                           msg);
-}
-
-Return<void> WifiNanIface::stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId,
-                                                stopSubscribeRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::stopSubscribeRequestInternal, hidl_status_cb, cmd_id,
-                           sessionId);
-}
-
-Return<void> WifiNanIface::transmitFollowupRequest(uint16_t cmd_id,
-                                                   const NanTransmitFollowupRequest& msg,
-                                                   transmitFollowupRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::transmitFollowupRequestInternal, hidl_status_cb, cmd_id,
-                           msg);
-}
-
-Return<void> WifiNanIface::createDataInterfaceRequest(
-        uint16_t cmd_id, const hidl_string& iface_name,
-        createDataInterfaceRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::createDataInterfaceRequestInternal, hidl_status_cb,
-                           cmd_id, iface_name);
-}
-
-Return<void> WifiNanIface::deleteDataInterfaceRequest(
-        uint16_t cmd_id, const hidl_string& iface_name,
-        deleteDataInterfaceRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::deleteDataInterfaceRequestInternal, hidl_status_cb,
-                           cmd_id, iface_name);
-}
-
-Return<void> WifiNanIface::initiateDataPathRequest(uint16_t cmd_id,
-                                                   const V1_0::NanInitiateDataPathRequest& msg,
-                                                   initiateDataPathRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::initiateDataPathRequestInternal, hidl_status_cb, cmd_id,
-                           msg);
-}
-
-Return<void> WifiNanIface::respondToDataPathIndicationRequest(
-        uint16_t cmd_id, const V1_0::NanRespondToDataPathIndicationRequest& msg,
-        respondToDataPathIndicationRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::respondToDataPathIndicationRequestInternal,
-                           hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId,
-                                                    terminateDataPathRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::terminateDataPathRequestInternal, hidl_status_cb, cmd_id,
-                           ndpInstanceId);
-}
-
-Return<void> WifiNanIface::registerEventCallback_1_2(
-        const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
-        registerEventCallback_1_2_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::registerEventCallback_1_2Internal, hidl_status_cb,
-                           callback);
-}
-
-Return<void> WifiNanIface::enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
-                                             const V1_2::NanConfigRequestSupplemental& msg2,
-                                             enableRequest_1_2_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::enableRequest_1_2Internal, hidl_status_cb, cmd_id, msg1,
-                           msg2);
-}
-
-Return<void> WifiNanIface::configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
-                                             const V1_2::NanConfigRequestSupplemental& msg2,
-                                             configRequest_1_2_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::configRequest_1_2Internal, hidl_status_cb, cmd_id, msg1,
-                           msg2);
-}
-
-Return<void> WifiNanIface::enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-                                             const V1_2::NanConfigRequestSupplemental& msg2,
-                                             enableRequest_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::enableRequest_1_4Internal, hidl_status_cb, cmd_id, msg1,
-                           msg2);
-}
-
-Return<void> WifiNanIface::configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-                                             const V1_2::NanConfigRequestSupplemental& msg2,
-                                             configRequest_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::configRequest_1_4Internal, hidl_status_cb, cmd_id, msg1,
-                           msg2);
-}
-
-Return<void> WifiNanIface::registerEventCallback_1_5(
-        const sp<V1_5::IWifiNanIfaceEventCallback>& callback,
-        registerEventCallback_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::registerEventCallback_1_5Internal, hidl_status_cb,
-                           callback);
-}
-
-Return<void> WifiNanIface::enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-                                             const V1_5::NanConfigRequestSupplemental& msg2,
-                                             enableRequest_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::enableRequest_1_5Internal, hidl_status_cb, cmd_id, msg1,
-                           msg2);
-}
-
-Return<void> WifiNanIface::configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-                                             const V1_5::NanConfigRequestSupplemental& msg2,
-                                             configRequest_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::configRequest_1_5Internal, hidl_status_cb, cmd_id, msg1,
-                           msg2);
-}
-
-Return<void> WifiNanIface::getCapabilitiesRequest_1_5(
-        uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::getCapabilitiesRequest_1_5Internal, hidl_status_cb,
-                           cmd_id);
-}
-
-Return<void> WifiNanIface::enableRequest_1_6(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-                                             const V1_6::NanConfigRequestSupplemental& msg2,
-                                             enableRequest_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::enableRequest_1_6Internal, hidl_status_cb, cmd_id, msg1,
-                           msg2);
-}
-
-Return<void> WifiNanIface::configRequest_1_6(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-                                             const V1_6::NanConfigRequestSupplemental& msg2,
-                                             configRequest_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::configRequest_1_6Internal, hidl_status_cb, cmd_id, msg1,
-                           msg2);
-}
-
-Return<void> WifiNanIface::initiateDataPathRequest_1_6(uint16_t cmd_id,
-                                                       const V1_6::NanInitiateDataPathRequest& msg,
-                                                       initiateDataPathRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::initiateDataPathRequest_1_6Internal, hidl_status_cb,
-                           cmd_id, msg);
-}
-
-Return<void> WifiNanIface::respondToDataPathIndicationRequest_1_6(
-        uint16_t cmd_id, const V1_6::NanRespondToDataPathIndicationRequest& msg,
-        respondToDataPathIndicationRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::respondToDataPathIndicationRequest_1_6Internal,
-                           hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::startPublishRequest_1_6(uint16_t cmd_id,
-                                                   const V1_6::NanPublishRequest& msg,
-                                                   startPublishRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::startPublishRequest_1_6Internal, hidl_status_cb, cmd_id,
-                           msg);
-}
-
-std::pair<WifiStatus, std::string> WifiNanIface::getNameInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
-}
-
-std::pair<WifiStatus, IfaceType> WifiNanIface::getTypeInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::NAN};
-}
-
-Return<void> WifiNanIface::registerEventCallback_1_6(
-        const sp<V1_6::IWifiNanIfaceEventCallback>& callback,
-        registerEventCallback_1_6_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::registerEventCallback_1_6Internal, hidl_status_cb,
-                           callback);
-}
-
-WifiStatus WifiNanIface::registerEventCallbackInternal(
-        const sp<V1_0::IWifiNanIfaceEventCallback>& callback) {
-    if (!event_cb_handler_.addCallback(callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::enableRequestInternal(uint16_t /* cmd_id */,
-                                               const V1_0::NanEnableRequest& /* msg */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::configRequestInternal(uint16_t /* cmd_id */,
-                                               const V1_0::NanConfigRequest& /* msg */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::disableRequestInternal(uint16_t cmd_id) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::startPublishRequestInternal(uint16_t /* cmd_id */,
-                                                     const V1_0::NanPublishRequest& /* msg */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId) {
-    legacy_hal::NanPublishCancelRequest legacy_msg;
-    legacy_msg.publish_id = sessionId;
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::startSubscribeRequestInternal(uint16_t cmd_id,
-                                                       const V1_0::NanSubscribeRequest& msg) {
-    legacy_hal::NanSubscribeRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanSubscribeRequestToLegacy(msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId) {
-    legacy_hal::NanSubscribeCancelRequest legacy_msg;
-    legacy_msg.subscribe_id = sessionId;
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::transmitFollowupRequestInternal(uint16_t cmd_id,
-                                                         const NanTransmitFollowupRequest& msg) {
-    legacy_hal::NanTransmitFollowupRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanTransmitFollowupRequestToLegacy(msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::createDataInterfaceRequestInternal(uint16_t cmd_id,
-                                                            const std::string& iface_name) {
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-WifiStatus WifiNanIface::deleteDataInterfaceRequestInternal(uint16_t cmd_id,
-                                                            const std::string& iface_name) {
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-WifiStatus WifiNanIface::initiateDataPathRequestInternal(
-        uint16_t cmd_id, const V1_0::NanInitiateDataPathRequest& msg) {
-    legacy_hal::NanDataPathInitiatorRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequestToLegacy(msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-WifiStatus WifiNanIface::respondToDataPathIndicationRequestInternal(
-        uint16_t cmd_id, const V1_0::NanRespondToDataPathIndicationRequest& msg) {
-    legacy_hal::NanDataPathIndicationResponse legacy_msg;
-    if (!hidl_struct_util::convertHidlNanDataPathIndicationResponseToLegacy(msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-WifiStatus WifiNanIface::terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId) {
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::registerEventCallback_1_2Internal(
-        const sp<V1_2::IWifiNanIfaceEventCallback>& callback) {
-    sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
-    if (!event_cb_handler_.addCallback(callback_1_0)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    if (!event_cb_handler_1_2_.addCallback(callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiNanIface::enableRequest_1_2Internal(
-        uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */,
-        const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::configRequest_1_2Internal(
-        uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */,
-        const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::enableRequest_1_4Internal(
-        uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */,
-        const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::configRequest_1_4Internal(
-        uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */,
-        const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::registerEventCallback_1_5Internal(
-        const sp<V1_5::IWifiNanIfaceEventCallback>& callback) {
-    sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
-    if (!event_cb_handler_.addCallback(callback_1_0)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    sp<V1_2::IWifiNanIfaceEventCallback> callback_1_2 = callback;
-    if (!event_cb_handler_1_2_.addCallback(callback_1_2)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    if (!event_cb_handler_1_5_.addCallback(callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::enableRequest_1_5Internal(
-        uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */,
-        const V1_5::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::configRequest_1_5Internal(
-        uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */,
-        const V1_5::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::enableRequest_1_6Internal(uint16_t cmd_id,
-                                                   const V1_4::NanEnableRequest& msg1,
-                                                   const V1_6::NanConfigRequestSupplemental& msg2) {
-    legacy_hal::NanEnableRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanEnableRequest_1_6ToLegacy(msg1, msg2, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::configRequest_1_6Internal(uint16_t cmd_id,
-                                                   const V1_4::NanConfigRequest& msg1,
-                                                   const V1_6::NanConfigRequestSupplemental& msg2) {
-    legacy_hal::NanConfigRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanConfigRequest_1_6ToLegacy(msg1, msg2, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::initiateDataPathRequest_1_6Internal(
-        uint16_t cmd_id, const V1_6::NanInitiateDataPathRequest& msg) {
-    legacy_hal::NanDataPathInitiatorRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequest_1_6ToLegacy(msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::respondToDataPathIndicationRequest_1_6Internal(
-        uint16_t cmd_id, const V1_6::NanRespondToDataPathIndicationRequest& msg) {
-    legacy_hal::NanDataPathIndicationResponse legacy_msg;
-    if (!hidl_struct_util::convertHidlNanDataPathIndicationResponse_1_6ToLegacy(msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::startPublishRequest_1_6Internal(uint16_t cmd_id,
-                                                         const V1_6::NanPublishRequest& msg) {
-    legacy_hal::NanPublishRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanPublishRequestToLegacy(msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::registerEventCallback_1_6Internal(
-        const sp<V1_6::IWifiNanIfaceEventCallback>& callback) {
-    sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
-    if (!event_cb_handler_.addCallback(callback_1_0)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    sp<V1_2::IWifiNanIfaceEventCallback> callback_1_2 = callback;
-    if (!event_cb_handler_1_2_.addCallback(callback_1_2)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    sp<V1_5::IWifiNanIfaceEventCallback> callback_1_5 = callback;
-    if (!event_cb_handler_1_5_.addCallback(callback_1_5)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    if (!event_cb_handler_1_6_.addCallback(callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_nan_iface.h b/wifi/1.6/default/wifi_nan_iface.h
deleted file mode 100644
index 15bf572..0000000
--- a/wifi/1.6/default/wifi_nan_iface.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_NAN_IFACE_H_
-#define WIFI_NAN_IFACE_H_
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.6/IWifiNanIface.h>
-#include <android/hardware/wifi/1.6/IWifiNanIfaceEventCallback.h>
-
-#include "hidl_callback_util.h"
-#include "wifi_iface_util.h"
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-using namespace android::hardware::wifi::V1_2;
-using namespace android::hardware::wifi::V1_4;
-using namespace android::hardware::wifi::V1_6;
-
-/**
- * HIDL interface object used to control a NAN Iface instance.
- */
-class WifiNanIface : public V1_6::IWifiNanIface {
-  public:
-    WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
-                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
-    // Refer to |WifiChip::invalidate()|.
-    void invalidate();
-    bool isValid();
-    std::string getName();
-
-    // HIDL methods exposed.
-    Return<void> getName(getName_cb hidl_status_cb) override;
-    Return<void> getType(getType_cb hidl_status_cb) override;
-    Return<void> registerEventCallback(const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
-                                       registerEventCallback_cb hidl_status_cb) override;
-    Return<void> getCapabilitiesRequest(uint16_t cmd_id,
-                                        getCapabilitiesRequest_cb hidl_status_cb) override;
-    Return<void> enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg,
-                               enableRequest_cb hidl_status_cb) override;
-    Return<void> configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
-                               configRequest_cb hidl_status_cb) override;
-    Return<void> disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) override;
-    Return<void> startPublishRequest(uint16_t cmd_id, const V1_0::NanPublishRequest& msg,
-                                     startPublishRequest_cb hidl_status_cb) override;
-    Return<void> stopPublishRequest(uint16_t cmd_id, uint8_t sessionId,
-                                    stopPublishRequest_cb hidl_status_cb) override;
-    Return<void> startSubscribeRequest(uint16_t cmd_id, const V1_0::NanSubscribeRequest& msg,
-                                       startSubscribeRequest_cb hidl_status_cb) override;
-    Return<void> stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId,
-                                      stopSubscribeRequest_cb hidl_status_cb) override;
-    Return<void> transmitFollowupRequest(uint16_t cmd_id, const NanTransmitFollowupRequest& msg,
-                                         transmitFollowupRequest_cb hidl_status_cb) override;
-    Return<void> createDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name,
-                                            createDataInterfaceRequest_cb hidl_status_cb) override;
-    Return<void> deleteDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name,
-                                            deleteDataInterfaceRequest_cb hidl_status_cb) override;
-    Return<void> initiateDataPathRequest(uint16_t cmd_id,
-                                         const V1_0::NanInitiateDataPathRequest& msg,
-                                         initiateDataPathRequest_cb hidl_status_cb) override;
-    Return<void> respondToDataPathIndicationRequest(
-            uint16_t cmd_id, const V1_0::NanRespondToDataPathIndicationRequest& msg,
-            respondToDataPathIndicationRequest_cb hidl_status_cb) override;
-    Return<void> terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId,
-                                          terminateDataPathRequest_cb hidl_status_cb) override;
-
-    Return<void> registerEventCallback_1_2(const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
-                                           registerEventCallback_1_2_cb hidl_status_cb) override;
-    Return<void> enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
-                                   const V1_2::NanConfigRequestSupplemental& msg2,
-                                   enableRequest_1_2_cb hidl_status_cb) override;
-    Return<void> configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
-                                   const V1_2::NanConfigRequestSupplemental& msg2,
-                                   configRequest_1_2_cb hidl_status_cb) override;
-    Return<void> enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-                                   const V1_2::NanConfigRequestSupplemental& msg2,
-                                   enableRequest_1_4_cb hidl_status_cb) override;
-    Return<void> configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-                                   const V1_2::NanConfigRequestSupplemental& msg2,
-                                   configRequest_1_4_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_5(const sp<V1_5::IWifiNanIfaceEventCallback>& callback,
-                                           registerEventCallback_1_5_cb hidl_status_cb) override;
-    Return<void> enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-                                   const V1_5::NanConfigRequestSupplemental& msg2,
-                                   enableRequest_1_5_cb hidl_status_cb) override;
-    Return<void> configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-                                   const V1_5::NanConfigRequestSupplemental& msg2,
-                                   configRequest_1_5_cb hidl_status_cb) override;
-    Return<void> getCapabilitiesRequest_1_5(uint16_t cmd_id,
-                                            getCapabilitiesRequest_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_6(const sp<V1_6::IWifiNanIfaceEventCallback>& callback,
-                                           registerEventCallback_1_6_cb hidl_status_cb) override;
-    Return<void> initiateDataPathRequest_1_6(
-            uint16_t cmd_id, const V1_6::NanInitiateDataPathRequest& msg,
-            initiateDataPathRequest_1_6_cb hidl_status_cb) override;
-    Return<void> respondToDataPathIndicationRequest_1_6(
-            uint16_t cmd_id, const V1_6::NanRespondToDataPathIndicationRequest& msg,
-            respondToDataPathIndicationRequest_1_6_cb hidl_status_cb) override;
-    Return<void> enableRequest_1_6(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-                                   const V1_6::NanConfigRequestSupplemental& msg2,
-                                   enableRequest_1_6_cb hidl_status_cb) override;
-    Return<void> configRequest_1_6(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-                                   const V1_6::NanConfigRequestSupplemental& msg2,
-                                   configRequest_1_6_cb hidl_status_cb) override;
-    Return<void> startPublishRequest_1_6(uint16_t cmd_id, const V1_6::NanPublishRequest& msg,
-                                         startPublishRequest_cb hidl_status_cb) override;
-
-  private:
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, std::string> getNameInternal();
-    std::pair<WifiStatus, IfaceType> getTypeInternal();
-    WifiStatus registerEventCallbackInternal(const sp<V1_0::IWifiNanIfaceEventCallback>& callback);
-    WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id);
-    WifiStatus enableRequestInternal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg);
-    WifiStatus configRequestInternal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg);
-    WifiStatus disableRequestInternal(uint16_t cmd_id);
-    WifiStatus startPublishRequestInternal(uint16_t cmd_id, const V1_0::NanPublishRequest& msg);
-    WifiStatus stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId);
-    WifiStatus startSubscribeRequestInternal(uint16_t cmd_id, const V1_0::NanSubscribeRequest& msg);
-    WifiStatus stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId);
-    WifiStatus transmitFollowupRequestInternal(uint16_t cmd_id,
-                                               const NanTransmitFollowupRequest& msg);
-    WifiStatus createDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name);
-    WifiStatus deleteDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name);
-    WifiStatus initiateDataPathRequestInternal(uint16_t cmd_id,
-                                               const V1_0::NanInitiateDataPathRequest& msg);
-    WifiStatus respondToDataPathIndicationRequestInternal(
-            uint16_t cmd_id, const V1_0::NanRespondToDataPathIndicationRequest& msg);
-    WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId);
-
-    WifiStatus registerEventCallback_1_2Internal(
-            const sp<V1_2::IWifiNanIfaceEventCallback>& callback);
-    WifiStatus enableRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
-                                         const V1_2::NanConfigRequestSupplemental& msg2);
-    WifiStatus configRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
-                                         const V1_2::NanConfigRequestSupplemental& msg2);
-    WifiStatus enableRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-                                         const V1_2::NanConfigRequestSupplemental& msg2);
-    WifiStatus configRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
-                                         const V1_2::NanConfigRequestSupplemental& msg2);
-    WifiStatus registerEventCallback_1_5Internal(
-            const sp<V1_5::IWifiNanIfaceEventCallback>& callback);
-    WifiStatus enableRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-                                         const V1_5::NanConfigRequestSupplemental& msg2);
-    WifiStatus configRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
-                                         const V1_5::NanConfigRequestSupplemental& msg2);
-    WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id);
-    WifiStatus registerEventCallback_1_6Internal(
-            const sp<V1_6::IWifiNanIfaceEventCallback>& callback);
-
-    WifiStatus enableRequest_1_6Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-                                         const V1_6::NanConfigRequestSupplemental& msg2);
-    WifiStatus configRequest_1_6Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
-                                         const V1_6::NanConfigRequestSupplemental& msg2);
-    WifiStatus startPublishRequest_1_6Internal(uint16_t cmd_id, const V1_6::NanPublishRequest& msg);
-    WifiStatus initiateDataPathRequest_1_6Internal(uint16_t cmd_id,
-                                                   const V1_6::NanInitiateDataPathRequest& msg);
-    WifiStatus respondToDataPathIndicationRequest_1_6Internal(
-            uint16_t cmd_id, const V1_6::NanRespondToDataPathIndicationRequest& msg);
-
-    // all 1_0 and descendant callbacks
-    std::set<sp<V1_0::IWifiNanIfaceEventCallback>> getEventCallbacks();
-    // all 1_2 and descendant callbacks
-    std::set<sp<V1_2::IWifiNanIfaceEventCallback>> getEventCallbacks_1_2();
-    // all 1_5 and descendant callbacks
-    std::set<sp<V1_5::IWifiNanIfaceEventCallback>> getEventCallbacks_1_5();
-    // all 1_6 and descendant callbacks
-    std::set<sp<V1_6::IWifiNanIfaceEventCallback>> getEventCallbacks_1_6();
-
-    std::string ifname_;
-    bool is_dedicated_iface_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
-    bool is_valid_;
-    hidl_callback_util::HidlCallbackHandler<V1_0::IWifiNanIfaceEventCallback> event_cb_handler_;
-    hidl_callback_util::HidlCallbackHandler<V1_2::IWifiNanIfaceEventCallback> event_cb_handler_1_2_;
-    hidl_callback_util::HidlCallbackHandler<V1_5::IWifiNanIfaceEventCallback> event_cb_handler_1_5_;
-    hidl_callback_util::HidlCallbackHandler<V1_6::IWifiNanIfaceEventCallback> event_cb_handler_1_6_;
-
-    DISALLOW_COPY_AND_ASSIGN(WifiNanIface);
-};
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_NAN_IFACE_H_
diff --git a/wifi/1.6/default/wifi_p2p_iface.cpp b/wifi/1.6/default/wifi_p2p_iface.cpp
deleted file mode 100644
index d4b1fca..0000000
--- a/wifi/1.6/default/wifi_p2p_iface.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2016 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 "hidl_return_util.h"
-#include "wifi_p2p_iface.h"
-#include "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-WifiP2pIface::WifiP2pIface(const std::string& ifname,
-                           const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
-    : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}
-
-void WifiP2pIface::invalidate() {
-    legacy_hal_.reset();
-    is_valid_ = false;
-}
-
-bool WifiP2pIface::isValid() {
-    return is_valid_;
-}
-
-std::string WifiP2pIface::getName() {
-    return ifname_;
-}
-
-Return<void> WifiP2pIface::getName(getName_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiP2pIface::getNameInternal, hidl_status_cb);
-}
-
-Return<void> WifiP2pIface::getType(getType_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiP2pIface::getTypeInternal, hidl_status_cb);
-}
-
-std::pair<WifiStatus, std::string> WifiP2pIface::getNameInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
-}
-
-std::pair<WifiStatus, IfaceType> WifiP2pIface::getTypeInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::P2P};
-}
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_p2p_iface.h b/wifi/1.6/default/wifi_p2p_iface.h
deleted file mode 100644
index 0089443..0000000
--- a/wifi/1.6/default/wifi_p2p_iface.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_P2P_IFACE_H_
-#define WIFI_P2P_IFACE_H_
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifiP2pIface.h>
-
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-
-/**
- * HIDL interface object used to control a P2P Iface instance.
- */
-class WifiP2pIface : public V1_0::IWifiP2pIface {
-  public:
-    WifiP2pIface(const std::string& ifname,
-                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
-    // Refer to |WifiChip::invalidate()|.
-    void invalidate();
-    bool isValid();
-    std::string getName();
-
-    // HIDL methods exposed.
-    Return<void> getName(getName_cb hidl_status_cb) override;
-    Return<void> getType(getType_cb hidl_status_cb) override;
-
-  private:
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, std::string> getNameInternal();
-    std::pair<WifiStatus, IfaceType> getTypeInternal();
-
-    std::string ifname_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    bool is_valid_;
-
-    DISALLOW_COPY_AND_ASSIGN(WifiP2pIface);
-};
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_P2P_IFACE_H_
diff --git a/wifi/1.6/default/wifi_rtt_controller.cpp b/wifi/1.6/default/wifi_rtt_controller.cpp
deleted file mode 100644
index aa9ee2f..0000000
--- a/wifi/1.6/default/wifi_rtt_controller.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2016 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 "hidl_return_util.h"
-#include "hidl_struct_util.h"
-#include "wifi_rtt_controller.h"
-#include "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-WifiRttController::WifiRttController(const std::string& iface_name,
-                                     const sp<IWifiIface>& bound_iface,
-                                     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
-    : ifname_(iface_name), bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {}
-
-void WifiRttController::invalidate() {
-    legacy_hal_.reset();
-    event_callbacks_.clear();
-    is_valid_ = false;
-}
-
-bool WifiRttController::isValid() {
-    return is_valid_;
-}
-
-std::vector<sp<V1_6::IWifiRttControllerEventCallback>> WifiRttController::getEventCallbacks() {
-    return event_callbacks_;
-}
-
-std::string WifiRttController::getIfaceName() {
-    return ifname_;
-}
-
-Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::getBoundIfaceInternal, hidl_status_cb);
-}
-
-Return<void> WifiRttController::registerEventCallback(
-        const sp<V1_0::IWifiRttControllerEventCallback>& callback,
-        registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::registerEventCallbackInternal, hidl_status_cb,
-                           callback);
-}
-
-Return<void> WifiRttController::rangeRequest(uint32_t cmd_id,
-                                             const hidl_vec<V1_0::RttConfig>& rtt_configs,
-                                             rangeRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::rangeRequestInternal, hidl_status_cb, cmd_id,
-                           rtt_configs);
-}
-
-Return<void> WifiRttController::rangeCancel(uint32_t cmd_id,
-                                            const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
-                                            rangeCancel_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::rangeCancelInternal, hidl_status_cb, cmd_id, addrs);
-}
-
-Return<void> WifiRttController::getCapabilities(getCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::getCapabilitiesInternal, hidl_status_cb);
-}
-
-Return<void> WifiRttController::setLci(uint32_t cmd_id, const RttLciInformation& lci,
-                                       setLci_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::setLciInternal, hidl_status_cb, cmd_id, lci);
-}
-
-Return<void> WifiRttController::setLcr(uint32_t cmd_id, const RttLcrInformation& lcr,
-                                       setLcr_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::setLcrInternal, hidl_status_cb, cmd_id, lcr);
-}
-
-Return<void> WifiRttController::getResponderInfo(getResponderInfo_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::getResponderInfoInternal, hidl_status_cb);
-}
-
-Return<void> WifiRttController::enableResponder(uint32_t cmd_id,
-                                                const V1_0::WifiChannelInfo& channel_hint,
-                                                uint32_t max_duration_seconds,
-                                                const V1_0::RttResponder& info,
-                                                enableResponder_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::enableResponderInternal, hidl_status_cb, cmd_id,
-                           channel_hint, max_duration_seconds, info);
-}
-
-Return<void> WifiRttController::disableResponder(uint32_t cmd_id,
-                                                 disableResponder_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::disableResponderInternal, hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiRttController::registerEventCallback_1_4(
-        const sp<V1_4::IWifiRttControllerEventCallback>& callback,
-        registerEventCallback_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::registerEventCallbackInternal_1_4, hidl_status_cb,
-                           callback);
-}
-
-Return<void> WifiRttController::rangeRequest_1_4(uint32_t cmd_id,
-                                                 const hidl_vec<V1_4::RttConfig>& rtt_configs,
-                                                 rangeRequest_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::rangeRequestInternal_1_4, hidl_status_cb, cmd_id,
-                           rtt_configs);
-}
-
-Return<void> WifiRttController::getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::getCapabilitiesInternal_1_4, hidl_status_cb);
-}
-
-Return<void> WifiRttController::getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::getResponderInfoInternal_1_4, hidl_status_cb);
-}
-
-Return<void> WifiRttController::enableResponder_1_4(uint32_t cmd_id,
-                                                    const V1_0::WifiChannelInfo& channel_hint,
-                                                    uint32_t max_duration_seconds,
-                                                    const V1_4::RttResponder& info,
-                                                    enableResponder_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::enableResponderInternal_1_4, hidl_status_cb, cmd_id,
-                           channel_hint, max_duration_seconds, info);
-}
-
-Return<void> WifiRttController::registerEventCallback_1_6(
-        const sp<V1_6::IWifiRttControllerEventCallback>& callback,
-        registerEventCallback_1_6_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::registerEventCallbackInternal_1_6, hidl_status_cb,
-                           callback);
-}
-
-Return<void> WifiRttController::rangeRequest_1_6(uint32_t cmd_id,
-                                                 const hidl_vec<V1_6::RttConfig>& rtt_configs,
-                                                 rangeRequest_1_6_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::rangeRequestInternal_1_6, hidl_status_cb, cmd_id,
-                           rtt_configs);
-}
-
-Return<void> WifiRttController::getCapabilities_1_6(getCapabilities_1_6_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::getCapabilitiesInternal_1_6, hidl_status_cb);
-}
-
-Return<void> WifiRttController::getResponderInfo_1_6(getResponderInfo_1_6_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::getResponderInfoInternal_1_6, hidl_status_cb);
-}
-
-Return<void> WifiRttController::enableResponder_1_6(uint32_t cmd_id,
-                                                    const V1_6::WifiChannelInfo& channel_hint,
-                                                    uint32_t max_duration_seconds,
-                                                    const V1_6::RttResponder& info,
-                                                    enableResponder_1_6_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::enableResponderInternal_1_6, hidl_status_cb, cmd_id,
-                           channel_hint, max_duration_seconds, info);
-}
-
-std::pair<WifiStatus, sp<IWifiIface>> WifiRttController::getBoundIfaceInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_};
-}
-
-WifiStatus WifiRttController::registerEventCallbackInternal(
-        const sp<V1_0::IWifiRttControllerEventCallback>& /* callback */) {
-    // Deprecated support for this api
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiRttController::rangeRequestInternal(
-        uint32_t /* cmd_id */, const std::vector<V1_0::RttConfig>& /* rtt_configs */) {
-    // Deprecated support for this api
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiRttController::rangeCancelInternal(
-        uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs) {
-    std::vector<std::array<uint8_t, 6>> legacy_addrs;
-    for (const auto& addr : addrs) {
-        legacy_addrs.push_back(addr);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, legacy_addrs);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, V1_0::RttCapabilities> WifiRttController::getCapabilitiesInternal() {
-    // Deprecated support for this api
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id, const RttLciInformation& lci) {
-    legacy_hal::wifi_lci_information legacy_lci;
-    if (!hidl_struct_util::convertHidlRttLciInformationToLegacy(lci, &legacy_lci)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiRttController::setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr) {
-    legacy_hal::wifi_lcr_information legacy_lcr;
-    if (!hidl_struct_util::convertHidlRttLcrInformationToLegacy(lcr, &legacy_lcr)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, V1_0::RttResponder> WifiRttController::getResponderInfoInternal() {
-    // Deprecated support for this api
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-WifiStatus WifiRttController::enableResponderInternal(
-        uint32_t /* cmd_id */, const V1_0::WifiChannelInfo& /* channel_hint */,
-        uint32_t /* max_duration_seconds */, const V1_0::RttResponder& /* info */) {
-    // Deprecated support for this api
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)};
-}
-
-WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiRttController::registerEventCallbackInternal_1_4(
-        const sp<V1_4::IWifiRttControllerEventCallback>& /* callback */) {
-    // Deprecated support for this api
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiRttController::rangeRequestInternal_1_4(
-        uint32_t /* cmd_id */, const std::vector<V1_4::RttConfig>& /* rtt_configs */) {
-    // Deprecated support for this api
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-std::pair<WifiStatus, V1_4::RttCapabilities> WifiRttController::getCapabilitiesInternal_1_4() {
-    // Deprecated support for this api
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-std::pair<WifiStatus, V1_4::RttResponder> WifiRttController::getResponderInfoInternal_1_4() {
-    // Deprecated support for this api
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-WifiStatus WifiRttController::enableResponderInternal_1_4(
-        uint32_t /* cmd_id */, const V1_0::WifiChannelInfo& /* channel_hint */,
-        uint32_t /* max_duration_seconds */, const V1_4::RttResponder& /* info */) {
-    // Deprecated support for this api
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)};
-}
-
-WifiStatus WifiRttController::registerEventCallbackInternal_1_6(
-        const sp<V1_6::IWifiRttControllerEventCallback>& callback) {
-    // TODO(b/31632518): remove the callback when the client is destroyed
-    event_callbacks_.emplace_back(callback);
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiRttController::rangeRequestInternal_1_6(
-        uint32_t cmd_id, const std::vector<V1_6::RttConfig>& rtt_configs) {
-    std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
-    if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    android::wp<WifiRttController> weak_ptr_this(this);
-    const auto& on_results_callback =
-            [weak_ptr_this](legacy_hal::wifi_request_id id,
-                            const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                std::vector<V1_6::RttResult> hidl_results;
-                if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl(results,
-                                                                            &hidl_results)) {
-                    LOG(ERROR) << "Failed to convert rtt results to HIDL structs";
-                    return;
-                }
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->onResults_1_6(id, hidl_results).isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-            };
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest(
-            ifname_, cmd_id, legacy_configs, on_results_callback);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, V1_6::RttCapabilities> WifiRttController::getCapabilitiesInternal_1_6() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_rtt_capabilities legacy_caps;
-    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    V1_6::RttCapabilities hidl_caps;
-    if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-std::pair<WifiStatus, V1_6::RttResponder> WifiRttController::getResponderInfoInternal_1_6() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_rtt_responder legacy_responder;
-    std::tie(legacy_status, legacy_responder) = legacy_hal_.lock()->getRttResponderInfo(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    V1_6::RttResponder hidl_responder;
-    if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder, &hidl_responder)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder};
-}
-
-WifiStatus WifiRttController::enableResponderInternal_1_6(uint32_t cmd_id,
-                                                          const V1_6::WifiChannelInfo& channel_hint,
-                                                          uint32_t max_duration_seconds,
-                                                          const V1_6::RttResponder& info) {
-    legacy_hal::wifi_channel_info legacy_channel_info;
-    if (!hidl_struct_util::convertHidlWifiChannelInfoToLegacy(channel_hint, &legacy_channel_info)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_rtt_responder legacy_responder;
-    if (!hidl_struct_util::convertHidlRttResponderToLegacy(info, &legacy_responder)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder(
-            ifname_, cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_rtt_controller.h b/wifi/1.6/default/wifi_rtt_controller.h
deleted file mode 100644
index fd5f68b..0000000
--- a/wifi/1.6/default/wifi_rtt_controller.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_RTT_CONTROLLER_H_
-#define WIFI_RTT_CONTROLLER_H_
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifiIface.h>
-#include <android/hardware/wifi/1.6/IWifiRttController.h>
-#include <android/hardware/wifi/1.6/IWifiRttControllerEventCallback.h>
-
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-
-/**
- * HIDL interface object used to control all RTT operations.
- */
-class WifiRttController : public V1_6::IWifiRttController {
-  public:
-    WifiRttController(const std::string& iface_name, const sp<IWifiIface>& bound_iface,
-                      const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
-    // Refer to |WifiChip::invalidate()|.
-    void invalidate();
-    bool isValid();
-    std::vector<sp<V1_6::IWifiRttControllerEventCallback>> getEventCallbacks();
-    std::string getIfaceName();
-
-    // HIDL methods exposed.
-    Return<void> getBoundIface(getBoundIface_cb hidl_status_cb) override;
-    Return<void> registerEventCallback(const sp<V1_0::IWifiRttControllerEventCallback>& callback,
-                                       registerEventCallback_cb hidl_status_cb) override;
-    Return<void> rangeRequest(uint32_t cmd_id, const hidl_vec<V1_0::RttConfig>& rtt_configs,
-                              rangeRequest_cb hidl_status_cb) override;
-    Return<void> rangeCancel(uint32_t cmd_id, const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
-                             rangeCancel_cb hidl_status_cb) override;
-    Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
-    Return<void> setLci(uint32_t cmd_id, const RttLciInformation& lci,
-                        setLci_cb hidl_status_cb) override;
-    Return<void> setLcr(uint32_t cmd_id, const RttLcrInformation& lcr,
-                        setLcr_cb hidl_status_cb) override;
-    Return<void> getResponderInfo(getResponderInfo_cb hidl_status_cb) override;
-    Return<void> enableResponder(uint32_t cmd_id, const V1_0::WifiChannelInfo& channel_hint,
-                                 uint32_t max_duration_seconds, const V1_0::RttResponder& info,
-                                 enableResponder_cb hidl_status_cb) override;
-    Return<void> disableResponder(uint32_t cmd_id, disableResponder_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_4(
-            const sp<V1_4::IWifiRttControllerEventCallback>& callback,
-            registerEventCallback_1_4_cb hidl_status_cb) override;
-    Return<void> rangeRequest_1_4(uint32_t cmd_id, const hidl_vec<V1_4::RttConfig>& rtt_configs,
-                                  rangeRequest_1_4_cb hidl_status_cb) override;
-    Return<void> getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) override;
-    Return<void> getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) override;
-    Return<void> enableResponder_1_4(uint32_t cmd_id, const V1_0::WifiChannelInfo& channel_hint,
-                                     uint32_t max_duration_seconds, const V1_4::RttResponder& info,
-                                     enableResponder_1_4_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_6(
-            const sp<V1_6::IWifiRttControllerEventCallback>& callback,
-            registerEventCallback_1_6_cb hidl_status_cb) override;
-    Return<void> rangeRequest_1_6(uint32_t cmd_id, const hidl_vec<V1_6::RttConfig>& rtt_configs,
-                                  rangeRequest_1_6_cb hidl_status_cb) override;
-    Return<void> getCapabilities_1_6(getCapabilities_1_6_cb hidl_status_cb) override;
-    Return<void> getResponderInfo_1_6(getResponderInfo_1_6_cb hidl_status_cb) override;
-    Return<void> enableResponder_1_6(uint32_t cmd_id, const V1_6::WifiChannelInfo& channel_hint,
-                                     uint32_t max_duration_seconds, const V1_6::RttResponder& info,
-                                     enableResponder_1_6_cb hidl_status_cb) override;
-
-  private:
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, sp<IWifiIface>> getBoundIfaceInternal();
-    WifiStatus registerEventCallbackInternal(
-            const sp<V1_0::IWifiRttControllerEventCallback>& callback);
-    WifiStatus rangeRequestInternal(uint32_t cmd_id,
-                                    const std::vector<V1_0::RttConfig>& rtt_configs);
-    WifiStatus rangeCancelInternal(uint32_t cmd_id,
-                                   const std::vector<hidl_array<uint8_t, 6>>& addrs);
-    std::pair<WifiStatus, V1_0::RttCapabilities> getCapabilitiesInternal();
-    WifiStatus setLciInternal(uint32_t cmd_id, const RttLciInformation& lci);
-    WifiStatus setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr);
-    std::pair<WifiStatus, V1_0::RttResponder> getResponderInfoInternal();
-    WifiStatus enableResponderInternal(uint32_t cmd_id, const V1_0::WifiChannelInfo& channel_hint,
-                                       uint32_t max_duration_seconds,
-                                       const V1_0::RttResponder& info);
-    WifiStatus disableResponderInternal(uint32_t cmd_id);
-    WifiStatus registerEventCallbackInternal_1_4(
-            const sp<V1_4::IWifiRttControllerEventCallback>& callback);
-    WifiStatus rangeRequestInternal_1_4(uint32_t cmd_id,
-                                        const std::vector<V1_4::RttConfig>& rtt_configs);
-    std::pair<WifiStatus, V1_4::RttCapabilities> getCapabilitiesInternal_1_4();
-    std::pair<WifiStatus, V1_4::RttResponder> getResponderInfoInternal_1_4();
-    WifiStatus enableResponderInternal_1_4(uint32_t cmd_id,
-                                           const V1_0::WifiChannelInfo& channel_hint,
-                                           uint32_t max_duration_seconds,
-                                           const V1_4::RttResponder& info);
-    WifiStatus registerEventCallbackInternal_1_6(
-            const sp<V1_6::IWifiRttControllerEventCallback>& callback);
-    WifiStatus rangeRequestInternal_1_6(uint32_t cmd_id,
-                                        const std::vector<V1_6::RttConfig>& rtt_configs);
-    std::pair<WifiStatus, V1_6::RttCapabilities> getCapabilitiesInternal_1_6();
-    std::pair<WifiStatus, V1_6::RttResponder> getResponderInfoInternal_1_6();
-    WifiStatus enableResponderInternal_1_6(uint32_t cmd_id,
-                                           const V1_6::WifiChannelInfo& channel_hint,
-                                           uint32_t max_duration_seconds,
-                                           const V1_6::RttResponder& info);
-
-    std::string ifname_;
-    sp<IWifiIface> bound_iface_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::vector<sp<V1_6::IWifiRttControllerEventCallback>> event_callbacks_;
-    bool is_valid_;
-
-    DISALLOW_COPY_AND_ASSIGN(WifiRttController);
-};
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_RTT_CONTROLLER_H_
diff --git a/wifi/1.6/default/wifi_sta_iface.cpp b/wifi/1.6/default/wifi_sta_iface.cpp
deleted file mode 100644
index dd11839..0000000
--- a/wifi/1.6/default/wifi_sta_iface.cpp
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (C) 2016 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 "hidl_return_util.h"
-#include "hidl_struct_util.h"
-#include "wifi_sta_iface.h"
-#include "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-WifiStaIface::WifiStaIface(const std::string& ifname,
-                           const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-                           const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
-    : ifname_(ifname), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) {
-    // Turn on DFS channel usage for STA iface.
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to set DFS flag; DFS channels may be unavailable.";
-    }
-}
-
-void WifiStaIface::invalidate() {
-    legacy_hal_.reset();
-    event_cb_handler_.invalidate();
-    is_valid_ = false;
-}
-
-bool WifiStaIface::isValid() {
-    return is_valid_;
-}
-
-std::string WifiStaIface::getName() {
-    return ifname_;
-}
-
-std::set<sp<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() {
-    return event_cb_handler_.getCallbacks();
-}
-
-Return<void> WifiStaIface::getName(getName_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getNameInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getType(getType_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getTypeInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::registerEventCallback(const sp<IWifiStaIfaceEventCallback>& callback,
-                                                 registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::registerEventCallbackInternal, hidl_status_cb, callback);
-}
-
-Return<void> WifiStaIface::getCapabilities(getCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getCapabilitiesInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getApfPacketFilterCapabilities(
-        getApfPacketFilterCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getApfPacketFilterCapabilitiesInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::installApfPacketFilter(uint32_t cmd_id, const hidl_vec<uint8_t>& program,
-                                                  installApfPacketFilter_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::installApfPacketFilterInternal, hidl_status_cb, cmd_id,
-                           program);
-}
-
-Return<void> WifiStaIface::readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::readApfPacketFilterDataInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getBackgroundScanCapabilities(
-        getBackgroundScanCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getBackgroundScanCapabilitiesInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getValidFrequenciesForBand(
-        V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getValidFrequenciesForBandInternal, hidl_status_cb, band);
-}
-
-Return<void> WifiStaIface::startBackgroundScan(uint32_t cmd_id,
-                                               const StaBackgroundScanParameters& params,
-                                               startBackgroundScan_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::startBackgroundScanInternal, hidl_status_cb, cmd_id,
-                           params);
-}
-
-Return<void> WifiStaIface::stopBackgroundScan(uint32_t cmd_id,
-                                              stopBackgroundScan_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::stopBackgroundScanInternal, hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiStaIface::enableLinkLayerStatsCollection(
-        bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::enableLinkLayerStatsCollectionInternal, hidl_status_cb,
-                           debug);
-}
-
-Return<void> WifiStaIface::disableLinkLayerStatsCollection(
-        disableLinkLayerStatsCollection_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::disableLinkLayerStatsCollectionInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getLinkLayerStatsInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getLinkLayerStatsInternal_1_3, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getLinkLayerStatsInternal_1_5, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getLinkLayerStats_1_6(getLinkLayerStats_1_6_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getLinkLayerStatsInternal_1_6, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
-                                               startRssiMonitoring_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::startRssiMonitoringInternal, hidl_status_cb, cmd_id,
-                           max_rssi, min_rssi);
-}
-
-Return<void> WifiStaIface::stopRssiMonitoring(uint32_t cmd_id,
-                                              stopRssiMonitoring_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::stopRssiMonitoringInternal, hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiStaIface::getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getRoamingCapabilitiesInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::configureRoaming(const StaRoamingConfig& config,
-                                            configureRoaming_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::configureRoamingInternal, hidl_status_cb, config);
-}
-
-Return<void> WifiStaIface::setRoamingState(StaRoamingState state,
-                                           setRoamingState_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::setRoamingStateInternal, hidl_status_cb, state);
-}
-
-Return<void> WifiStaIface::enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::enableNdOffloadInternal, hidl_status_cb, enable);
-}
-
-Return<void> WifiStaIface::startSendingKeepAlivePackets(
-        uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, uint16_t ether_type,
-        const hidl_array<uint8_t, 6>& src_address, const hidl_array<uint8_t, 6>& dst_address,
-        uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::startSendingKeepAlivePacketsInternal, hidl_status_cb,
-                           cmd_id, ip_packet_data, ether_type, src_address, dst_address,
-                           period_in_ms);
-}
-
-Return<void> WifiStaIface::stopSendingKeepAlivePackets(
-        uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::stopSendingKeepAlivePacketsInternal, hidl_status_cb,
-                           cmd_id);
-}
-
-Return<void> WifiStaIface::setScanningMacOui(const hidl_array<uint8_t, 3>& oui,
-                                             setScanningMacOui_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::setScanningMacOuiInternal, hidl_status_cb, oui);
-}
-
-Return<void> WifiStaIface::startDebugPacketFateMonitoring(
-        startDebugPacketFateMonitoring_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::startDebugPacketFateMonitoringInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getDebugTxPacketFatesInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getDebugRxPacketFatesInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
-                                         setMacAddress_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::setMacAddressInternal, hidl_status_cb, mac);
-}
-
-Return<void> WifiStaIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getFactoryMacAddressInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::setScanMode(bool enable, setScanMode_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::setScanModeInternal, hidl_status_cb, enable);
-}
-
-std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
-}
-
-std::pair<WifiStatus, IfaceType> WifiStaIface::getTypeInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::STA};
-}
-
-WifiStatus WifiStaIface::registerEventCallbackInternal(
-        const sp<IWifiStaIfaceEventCallback>& callback) {
-    if (!event_cb_handler_.addCallback(callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    uint64_t legacy_feature_set;
-    std::tie(legacy_status, legacy_feature_set) =
-            legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), 0};
-    }
-    uint32_t legacy_logger_feature_set;
-    std::tie(legacy_status, legacy_logger_feature_set) =
-            legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        // some devices don't support querying logger feature set
-        legacy_logger_feature_set = 0;
-    }
-    uint32_t hidl_caps;
-    if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
-                legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-std::pair<WifiStatus, StaApfPacketFilterCapabilities>
-WifiStaIface::getApfPacketFilterCapabilitiesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::PacketFilterCapabilities legacy_caps;
-    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getPacketFilterCapabilities(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    StaApfPacketFilterCapabilities hidl_caps;
-    if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-WifiStatus WifiStaIface::installApfPacketFilterInternal(uint32_t /* cmd_id */,
-                                                        const std::vector<uint8_t>& program) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setPacketFilter(ifname_, program);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, std::vector<uint8_t>> WifiStaIface::readApfPacketFilterDataInternal() {
-    const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>> legacy_status_and_data =
-            legacy_hal_.lock()->readApfPacketFilterData(ifname_);
-    return {createWifiStatusFromLegacyError(legacy_status_and_data.first),
-            std::move(legacy_status_and_data.second)};
-}
-
-std::pair<WifiStatus, StaBackgroundScanCapabilities>
-WifiStaIface::getBackgroundScanCapabilitiesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_gscan_capabilities legacy_caps;
-    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getGscanCapabilities(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    StaBackgroundScanCapabilities hidl_caps;
-    if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
-WifiStaIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
-    static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch");
-    legacy_hal::wifi_error legacy_status;
-    std::vector<uint32_t> valid_frequencies;
-    std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand(
-            ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band));
-    return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
-}
-
-WifiStatus WifiStaIface::startBackgroundScanInternal(uint32_t cmd_id,
-                                                     const StaBackgroundScanParameters& params) {
-    legacy_hal::wifi_scan_cmd_params legacy_params;
-    if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params, &legacy_params)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    android::wp<WifiStaIface> weak_ptr_this(this);
-    const auto& on_failure_callback = [weak_ptr_this](legacy_hal::wifi_request_id id) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->onBackgroundScanFailure(id).isOk()) {
-                LOG(ERROR) << "Failed to invoke onBackgroundScanFailure callback";
-            }
-        }
-    };
-    const auto& on_results_callback =
-            [weak_ptr_this](legacy_hal::wifi_request_id id,
-                            const std::vector<legacy_hal::wifi_cached_scan_results>& results) {
-                const auto shared_ptr_this = weak_ptr_this.promote();
-                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                    LOG(ERROR) << "Callback invoked on an invalid object";
-                    return;
-                }
-                std::vector<StaScanData> hidl_scan_datas;
-                if (!hidl_struct_util::convertLegacyVectorOfCachedGscanResultsToHidl(
-                            results, &hidl_scan_datas)) {
-                    LOG(ERROR) << "Failed to convert scan results to HIDL structs";
-                    return;
-                }
-                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->onBackgroundScanResults(id, hidl_scan_datas).isOk()) {
-                        LOG(ERROR) << "Failed to invoke onBackgroundScanResults callback";
-                    }
-                }
-            };
-    const auto& on_full_result_callback = [weak_ptr_this](
-                                                  legacy_hal::wifi_request_id id,
-                                                  const legacy_hal::wifi_scan_result* result,
-                                                  uint32_t buckets_scanned) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        StaScanResult hidl_scan_result;
-        if (!hidl_struct_util::convertLegacyGscanResultToHidl(*result, true, &hidl_scan_result)) {
-            LOG(ERROR) << "Failed to convert full scan results to HIDL structs";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->onBackgroundFullScanResult(id, buckets_scanned, hidl_scan_result)
-                         .isOk()) {
-                LOG(ERROR) << "Failed to invoke onBackgroundFullScanResult callback";
-            }
-        }
-    };
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->startGscan(ifname_, cmd_id, legacy_params, on_failure_callback,
-                                           on_results_callback, on_full_result_callback);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::stopBackgroundScanInternal(uint32_t cmd_id) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopGscan(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableLinkLayerStats(ifname_);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, V1_0::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal() {
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-std::pair<WifiStatus, V1_3::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_3() {
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-std::pair<WifiStatus, V1_5::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_5() {
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-std::pair<WifiStatus, V1_6::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_6() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::LinkLayerStats legacy_stats;
-    std::tie(legacy_status, legacy_stats) = legacy_hal_.lock()->getLinkLayerStats(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    V1_6::StaLinkLayerStats hidl_stats;
-    if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &hidl_stats)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
-}
-
-WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi,
-                                                     int32_t min_rssi) {
-    android::wp<WifiStaIface> weak_ptr_this(this);
-    const auto& on_threshold_breached_callback = [weak_ptr_this](legacy_hal::wifi_request_id id,
-                                                                 std::array<uint8_t, 6> bssid,
-                                                                 int8_t rssi) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback->onRssiThresholdBreached(id, bssid, rssi).isOk()) {
-                LOG(ERROR) << "Failed to invoke onRssiThresholdBreached callback";
-            }
-        }
-    };
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRssiMonitoring(
-            ifname_, cmd_id, max_rssi, min_rssi, on_threshold_breached_callback);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::stopRssiMonitoringInternal(uint32_t cmd_id) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, StaRoamingCapabilities> WifiStaIface::getRoamingCapabilitiesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_roaming_capabilities legacy_caps;
-    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRoamingCapabilities(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    StaRoamingCapabilities hidl_caps;
-    if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-WifiStatus WifiStaIface::configureRoamingInternal(const StaRoamingConfig& config) {
-    legacy_hal::wifi_roaming_config legacy_config;
-    if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config, &legacy_config)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->configureRoaming(ifname_, legacy_config);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableFirmwareRoaming(
-            ifname_, hidl_struct_util::convertHidlRoamingStateToLegacy(state));
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->configureNdOffload(ifname_, enable);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
-        uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, uint16_t ether_type,
-        const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address,
-        uint32_t period_in_ms) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startSendingOffloadedPacket(
-            ifname_, cmd_id, ether_type, ip_packet_data, src_address, dst_address, period_in_ms);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(uint32_t cmd_id) {
-    legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::setScanningMacOuiInternal(const std::array<uint8_t, 3>& /* oui */) {
-    // deprecated.
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startPktFateMonitoring(ifname_);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>
-WifiStaIface::getDebugTxPacketFatesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    std::vector<legacy_hal::wifi_tx_report> legacy_fates;
-    std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getTxPktFates(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    std::vector<WifiDebugTxPacketFateReport> hidl_fates;
-    if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl(legacy_fates,
-                                                                        &hidl_fates)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
-}
-
-std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>>
-WifiStaIface::getDebugRxPacketFatesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    std::vector<legacy_hal::wifi_rx_report> legacy_fates;
-    std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getRxPktFates(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    std::vector<WifiDebugRxPacketFateReport> hidl_fates;
-    if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl(legacy_fates,
-                                                                        &hidl_fates)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
-}
-
-WifiStatus WifiStaIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
-    bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
-    if (!status) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, std::array<uint8_t, 6>> WifiStaIface::getFactoryMacAddressInternal() {
-    std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifname_);
-    if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
-}
-
-WifiStatus WifiStaIface::setScanModeInternal(bool enable) {
-    // OEM's need to implement this on their devices if needed.
-    LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported";
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_sta_iface.h b/wifi/1.6/default/wifi_sta_iface.h
deleted file mode 100644
index c01c50b..0000000
--- a/wifi/1.6/default/wifi_sta_iface.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_STA_IFACE_H_
-#define WIFI_STA_IFACE_H_
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
-#include <android/hardware/wifi/1.6/IWifiStaIface.h>
-
-#include "hidl_callback_util.h"
-#include "wifi_iface_util.h"
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-
-/**
- * HIDL interface object used to control a STA Iface instance.
- */
-class WifiStaIface : public V1_6::IWifiStaIface {
-  public:
-    WifiStaIface(const std::string& ifname,
-                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
-    // Refer to |WifiChip::invalidate()|.
-    void invalidate();
-    bool isValid();
-    std::set<sp<IWifiStaIfaceEventCallback>> getEventCallbacks();
-    std::string getName();
-
-    // HIDL methods exposed.
-    Return<void> getName(getName_cb hidl_status_cb) override;
-    Return<void> getType(getType_cb hidl_status_cb) override;
-    Return<void> registerEventCallback(const sp<IWifiStaIfaceEventCallback>& callback,
-                                       registerEventCallback_cb hidl_status_cb) override;
-    Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
-    Return<void> getApfPacketFilterCapabilities(
-            getApfPacketFilterCapabilities_cb hidl_status_cb) override;
-    Return<void> installApfPacketFilter(uint32_t cmd_id, const hidl_vec<uint8_t>& program,
-                                        installApfPacketFilter_cb hidl_status_cb) override;
-    Return<void> readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) override;
-    Return<void> getBackgroundScanCapabilities(
-            getBackgroundScanCapabilities_cb hidl_status_cb) override;
-    Return<void> getValidFrequenciesForBand(V1_0::WifiBand band,
-                                            getValidFrequenciesForBand_cb hidl_status_cb) override;
-    Return<void> startBackgroundScan(uint32_t cmd_id, const StaBackgroundScanParameters& params,
-                                     startBackgroundScan_cb hidl_status_cb) override;
-    Return<void> stopBackgroundScan(uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) override;
-    Return<void> enableLinkLayerStatsCollection(
-            bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) override;
-    Return<void> disableLinkLayerStatsCollection(
-            disableLinkLayerStatsCollection_cb hidl_status_cb) override;
-    Return<void> getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) override;
-    Return<void> getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) override;
-    Return<void> getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) override;
-    Return<void> getLinkLayerStats_1_6(getLinkLayerStats_1_6_cb hidl_status_cb) override;
-    Return<void> startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
-                                     startRssiMonitoring_cb hidl_status_cb) override;
-    Return<void> stopRssiMonitoring(uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override;
-    Return<void> getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) override;
-    Return<void> configureRoaming(const StaRoamingConfig& config,
-                                  configureRoaming_cb hidl_status_cb) override;
-    Return<void> setRoamingState(StaRoamingState state, setRoamingState_cb hidl_status_cb) override;
-    Return<void> enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) override;
-    Return<void> startSendingKeepAlivePackets(
-            uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, uint16_t ether_type,
-            const hidl_array<uint8_t, 6>& src_address, const hidl_array<uint8_t, 6>& dst_address,
-            uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) override;
-    Return<void> stopSendingKeepAlivePackets(
-            uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) override;
-    Return<void> setScanningMacOui(const hidl_array<uint8_t, 3>& oui,
-                                   setScanningMacOui_cb hidl_status_cb) override;
-    Return<void> startDebugPacketFateMonitoring(
-            startDebugPacketFateMonitoring_cb hidl_status_cb) override;
-    Return<void> getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) override;
-    Return<void> getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) override;
-    Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
-                               setMacAddress_cb hidl_status_cb) override;
-    Return<void> getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override;
-    Return<void> setScanMode(bool enable, setScanMode_cb hidl_status_cb) override;
-
-  private:
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, std::string> getNameInternal();
-    std::pair<WifiStatus, IfaceType> getTypeInternal();
-    WifiStatus registerEventCallbackInternal(const sp<IWifiStaIfaceEventCallback>& callback);
-    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
-    std::pair<WifiStatus, StaApfPacketFilterCapabilities> getApfPacketFilterCapabilitiesInternal();
-    WifiStatus installApfPacketFilterInternal(uint32_t cmd_id, const std::vector<uint8_t>& program);
-    std::pair<WifiStatus, std::vector<uint8_t>> readApfPacketFilterDataInternal();
-    std::pair<WifiStatus, StaBackgroundScanCapabilities> getBackgroundScanCapabilitiesInternal();
-    std::pair<WifiStatus, std::vector<WifiChannelInMhz>> getValidFrequenciesForBandInternal(
-            V1_0::WifiBand band);
-    WifiStatus startBackgroundScanInternal(uint32_t cmd_id,
-                                           const StaBackgroundScanParameters& params);
-    WifiStatus stopBackgroundScanInternal(uint32_t cmd_id);
-    WifiStatus enableLinkLayerStatsCollectionInternal(bool debug);
-    WifiStatus disableLinkLayerStatsCollectionInternal();
-    std::pair<WifiStatus, V1_0::StaLinkLayerStats> getLinkLayerStatsInternal();
-    std::pair<WifiStatus, V1_3::StaLinkLayerStats> getLinkLayerStatsInternal_1_3();
-    std::pair<WifiStatus, V1_5::StaLinkLayerStats> getLinkLayerStatsInternal_1_5();
-    std::pair<WifiStatus, V1_6::StaLinkLayerStats> getLinkLayerStatsInternal_1_6();
-    WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi);
-    WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id);
-    std::pair<WifiStatus, StaRoamingCapabilities> getRoamingCapabilitiesInternal();
-    WifiStatus configureRoamingInternal(const StaRoamingConfig& config);
-    WifiStatus setRoamingStateInternal(StaRoamingState state);
-    WifiStatus enableNdOffloadInternal(bool enable);
-    WifiStatus startSendingKeepAlivePacketsInternal(uint32_t cmd_id,
-                                                    const std::vector<uint8_t>& ip_packet_data,
-                                                    uint16_t ether_type,
-                                                    const std::array<uint8_t, 6>& src_address,
-                                                    const std::array<uint8_t, 6>& dst_address,
-                                                    uint32_t period_in_ms);
-    WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id);
-    WifiStatus setScanningMacOuiInternal(const std::array<uint8_t, 3>& oui);
-    WifiStatus startDebugPacketFateMonitoringInternal();
-    std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>> getDebugTxPacketFatesInternal();
-    std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>> getDebugRxPacketFatesInternal();
-    WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
-    std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal();
-    WifiStatus setScanModeInternal(bool enable);
-
-    std::string ifname_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
-    bool is_valid_;
-    hidl_callback_util::HidlCallbackHandler<IWifiStaIfaceEventCallback> event_cb_handler_;
-
-    DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
-};
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_STA_IFACE_H_
diff --git a/wifi/1.6/default/wifi_status_util.cpp b/wifi/1.6/default/wifi_status_util.cpp
deleted file mode 100644
index 3b18e53..0000000
--- a/wifi/1.6/default/wifi_status_util.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2016 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 "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-
-std::string legacyErrorToString(legacy_hal::wifi_error error) {
-    switch (error) {
-        case legacy_hal::WIFI_SUCCESS:
-            return "SUCCESS";
-        case legacy_hal::WIFI_ERROR_UNINITIALIZED:
-            return "UNINITIALIZED";
-        case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
-            return "NOT_AVAILABLE";
-        case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
-            return "NOT_SUPPORTED";
-        case legacy_hal::WIFI_ERROR_INVALID_ARGS:
-            return "INVALID_ARGS";
-        case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
-            return "INVALID_REQUEST_ID";
-        case legacy_hal::WIFI_ERROR_TIMED_OUT:
-            return "TIMED_OUT";
-        case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
-            return "TOO_MANY_REQUESTS";
-        case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
-            return "OUT_OF_MEMORY";
-        case legacy_hal::WIFI_ERROR_BUSY:
-            return "BUSY";
-        case legacy_hal::WIFI_ERROR_UNKNOWN:
-            return "UNKNOWN";
-        default:
-            return "UNKNOWN ERROR";
-    }
-}
-
-WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description) {
-    return {code, description};
-}
-
-WifiStatus createWifiStatus(WifiStatusCode code) {
-    return createWifiStatus(code, "");
-}
-
-WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, const std::string& desc) {
-    switch (error) {
-        case legacy_hal::WIFI_ERROR_UNINITIALIZED:
-        case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
-            return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, desc);
-
-        case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
-            return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED, desc);
-
-        case legacy_hal::WIFI_ERROR_INVALID_ARGS:
-        case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
-            return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS, desc);
-
-        case legacy_hal::WIFI_ERROR_TIMED_OUT:
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", timed out");
-
-        case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", too many requests");
-
-        case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", out of memory");
-
-        case legacy_hal::WIFI_ERROR_BUSY:
-            return createWifiStatus(WifiStatusCode::ERROR_BUSY);
-
-        case legacy_hal::WIFI_ERROR_NONE:
-            return createWifiStatus(WifiStatusCode::SUCCESS, desc);
-
-        case legacy_hal::WIFI_ERROR_UNKNOWN:
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown");
-
-        default:
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown error");
-    }
-}
-
-WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) {
-    return createWifiStatusFromLegacyError(error, "");
-}
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.6/default/wifi_status_util.h b/wifi/1.6/default/wifi_status_util.h
deleted file mode 100644
index ea1c294..0000000
--- a/wifi/1.6/default/wifi_status_util.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2016 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 WIFI_STATUS_UTIL_H_
-#define WIFI_STATUS_UTIL_H_
-
-#include <android/hardware/wifi/1.4/IWifi.h>
-
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_6 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-
-std::string legacyErrorToString(legacy_hal::wifi_error error);
-WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description);
-WifiStatus createWifiStatus(WifiStatusCode code);
-WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
-                                           const std::string& description);
-WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error);
-
-}  // namespace implementation
-}  // namespace V1_6
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_STATUS_UTIL_H_
diff --git a/wifi/1.6/vts/OWNERS b/wifi/1.6/vts/OWNERS
deleted file mode 100644
index 294fc82..0000000
--- a/wifi/1.6/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.0/vts/OWNERS
diff --git a/wifi/OWNERS b/wifi/OWNERS
new file mode 100644
index 0000000..c10bbab
--- /dev/null
+++ b/wifi/OWNERS
@@ -0,0 +1,10 @@
+# Bug component: 33618
+
+# Please assign all bugs related to /hardware/interfaces/wifi to the team alias:
+#
+#    android-wifi-team@google.com
+#
+# This will get them auto-assigned to the on-call triage engineer, ensuring quickest response.
+#
+arabawy@google.com
+etancohen@google.com
diff --git a/wifi/aidl/Android.bp b/wifi/aidl/Android.bp
new file mode 100644
index 0000000..7bc8ae7
--- /dev/null
+++ b/wifi/aidl/Android.bp
@@ -0,0 +1,54 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.wifi",
+    vendor_available: true,
+    srcs: [
+        "android/hardware/wifi/*.aidl",
+    ],
+    stability: "vintf",
+    backend: {
+        java: {
+            sdk_version: "module_current",
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.wifi",
+            ],
+            min_sdk_version: "30",
+            lint: {
+                // Disable linter to avoid error about fixed size arrays.
+                // Interface will only be accessed on devices >= U.
+                enabled: false,
+            },
+        },
+    },
+    versions_with_info: [
+        {
+            version: "1",
+            imports: [],
+        },
+    ],
+    frozen: true,
+
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/.hash b/wifi/aidl/aidl_api/android.hardware.wifi/1/.hash
new file mode 100644
index 0000000..be9627a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/.hash
@@ -0,0 +1 @@
+aa2d34a8d196759e8f89109768ebe16039e47518
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/AfcChannelAllowance.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/AfcChannelAllowance.aidl
new file mode 100644
index 0000000..4d3cd6e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/AfcChannelAllowance.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable AfcChannelAllowance {
+  android.hardware.wifi.AvailableAfcFrequencyInfo[] availableAfcFrequencyInfos;
+  android.hardware.wifi.AvailableAfcChannelInfo[] availableAfcChannelInfos;
+  long availabilityExpireTimeMs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/AvailableAfcChannelInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/AvailableAfcChannelInfo.aidl
new file mode 100644
index 0000000..d238640
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/AvailableAfcChannelInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable AvailableAfcChannelInfo {
+  int globalOperatingClass;
+  int channelCfi;
+  int maxEirpDbm;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
new file mode 100644
index 0000000..cbea5af
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable AvailableAfcFrequencyInfo {
+  int startFrequencyMhz;
+  int endFrequencyMhz;
+  int maxPsd;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifi.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifi.aidl
new file mode 100644
index 0000000..cc995fc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifi.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifi {
+  @PropagateAllowBlocking android.hardware.wifi.IWifiChip getChip(int chipId);
+  int[] getChipIds();
+  boolean isStarted();
+  void registerEventCallback(in android.hardware.wifi.IWifiEventCallback callback);
+  void start();
+  void stop();
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiApIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiApIface.aidl
new file mode 100644
index 0000000..e71dde4
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiApIface.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiApIface {
+  String getName();
+  String[] getBridgedInstances();
+  byte[6] getFactoryMacAddress();
+  void setCountryCode(in byte[2] code);
+  void resetToFactoryMacAddress();
+  void setMacAddress(in byte[6] mac);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiChip.aidl
new file mode 100644
index 0000000..4ea2081
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiChip.aidl
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiChip {
+  void configureChip(in int modeId);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createApIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createBridgedApIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiNanIface createNanIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiP2pIface createP2pIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiRttController createRttController(in android.hardware.wifi.IWifiStaIface boundIface);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiStaIface createStaIface();
+  void enableDebugErrorAlerts(in boolean enable);
+  void flushRingBufferToFile();
+  void forceDumpToDebugRingBuffer(in String ringName);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface getApIface(in String ifname);
+  String[] getApIfaceNames();
+  android.hardware.wifi.IWifiChip.ChipMode[] getAvailableModes();
+  int getFeatureSet();
+  android.hardware.wifi.WifiDebugHostWakeReasonStats getDebugHostWakeReasonStats();
+  android.hardware.wifi.WifiDebugRingBufferStatus[] getDebugRingBuffersStatus();
+  int getId();
+  int getMode();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiNanIface getNanIface(in String ifname);
+  String[] getNanIfaceNames();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiP2pIface getP2pIface(in String ifname);
+  String[] getP2pIfaceNames();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiStaIface getStaIface(in String ifname);
+  String[] getStaIfaceNames();
+  android.hardware.wifi.WifiRadioCombination[] getSupportedRadioCombinations();
+  android.hardware.wifi.WifiChipCapabilities getWifiChipCapabilities();
+  android.hardware.wifi.WifiUsableChannel[] getUsableChannels(in android.hardware.wifi.WifiBand band, in int ifaceModeMask, in int filterMask);
+  void setAfcChannelAllowance(in android.hardware.wifi.AfcChannelAllowance afcChannelAllowance);
+  void registerEventCallback(in android.hardware.wifi.IWifiChipEventCallback callback);
+  void removeApIface(in String ifname);
+  void removeIfaceInstanceFromBridgedApIface(in String brIfaceName, in String ifaceInstanceName);
+  void removeNanIface(in String ifname);
+  void removeP2pIface(in String ifname);
+  void removeStaIface(in String ifname);
+  android.hardware.wifi.IWifiChip.ChipDebugInfo requestChipDebugInfo();
+  byte[] requestDriverDebugDump();
+  byte[] requestFirmwareDebugDump();
+  void resetTxPowerScenario();
+  void selectTxPowerScenario(in android.hardware.wifi.IWifiChip.TxPowerScenario scenario);
+  void setCoexUnsafeChannels(in android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] unsafeChannels, in int restrictions);
+  void setCountryCode(in byte[2] code);
+  void setLatencyMode(in android.hardware.wifi.IWifiChip.LatencyMode mode);
+  void setMultiStaPrimaryConnection(in String ifName);
+  void setMultiStaUseCase(in android.hardware.wifi.IWifiChip.MultiStaUseCase useCase);
+  void startLoggingToDebugRingBuffer(in String ringName, in android.hardware.wifi.WifiDebugRingBufferVerboseLevel verboseLevel, in int maxIntervalInSec, in int minDataSizeInBytes);
+  void stopLoggingToDebugRingBuffer();
+  void triggerSubsystemRestart();
+  void enableStaChannelForPeerNetwork(in int channelCategoryEnableFlag);
+  void setMloMode(in android.hardware.wifi.IWifiChip.ChipMloMode mode);
+  const int NO_POWER_CAP_CONSTANT = 0x7FFFFFFF;
+  @Backing(type="int") @VintfStability
+  enum FeatureSetMask {
+    SET_TX_POWER_LIMIT = (1 << 0) /* 1 */,
+    D2D_RTT = (1 << 1) /* 2 */,
+    D2AP_RTT = (1 << 2) /* 4 */,
+    USE_BODY_HEAD_SAR = (1 << 3) /* 8 */,
+    SET_LATENCY_MODE = (1 << 4) /* 16 */,
+    P2P_RAND_MAC = (1 << 5) /* 32 */,
+    WIGIG = (1 << 6) /* 64 */,
+    SET_AFC_CHANNEL_ALLOWANCE = (1 << 7) /* 128 */,
+    T2LM_NEGOTIATION = (1 << 8) /* 256 */,
+  }
+  @VintfStability
+  parcelable ChipConcurrencyCombinationLimit {
+    android.hardware.wifi.IfaceConcurrencyType[] types;
+    int maxIfaces;
+  }
+  @VintfStability
+  parcelable ChipConcurrencyCombination {
+    android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit[] limits;
+  }
+  @VintfStability
+  parcelable ChipDebugInfo {
+    String driverDescription;
+    String firmwareDescription;
+  }
+  @VintfStability
+  parcelable ChipIfaceCombinationLimit {
+    android.hardware.wifi.IfaceType[] types;
+    int maxIfaces;
+  }
+  @VintfStability
+  parcelable ChipIfaceCombination {
+    android.hardware.wifi.IWifiChip.ChipIfaceCombinationLimit[] limits;
+  }
+  @VintfStability
+  parcelable ChipMode {
+    int id;
+    android.hardware.wifi.IWifiChip.ChipConcurrencyCombination[] availableCombinations;
+  }
+  @Backing(type="int") @VintfStability
+  enum CoexRestriction {
+    WIFI_DIRECT = (1 << 0) /* 1 */,
+    SOFTAP = (1 << 1) /* 2 */,
+    WIFI_AWARE = (1 << 2) /* 4 */,
+  }
+  @VintfStability
+  parcelable CoexUnsafeChannel {
+    android.hardware.wifi.WifiBand band;
+    int channel;
+    int powerCapDbm;
+  }
+  @Backing(type="int") @VintfStability
+  enum LatencyMode {
+    NORMAL = 0,
+    LOW = 1,
+  }
+  @Backing(type="byte") @VintfStability
+  enum MultiStaUseCase {
+    DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
+    DUAL_STA_NON_TRANSIENT_UNBIASED = 1,
+  }
+  @Backing(type="int") @VintfStability
+  enum TxPowerScenario {
+    VOICE_CALL = 0,
+    ON_HEAD_CELL_OFF = 1,
+    ON_HEAD_CELL_ON = 2,
+    ON_BODY_CELL_OFF = 3,
+    ON_BODY_CELL_ON = 4,
+  }
+  @Backing(type="int") @VintfStability
+  enum UsableChannelFilter {
+    CELLULAR_COEXISTENCE = (1 << 0) /* 1 */,
+    CONCURRENCY = (1 << 1) /* 2 */,
+    NAN_INSTANT_MODE = (1 << 2) /* 4 */,
+  }
+  @Backing(type="int") @VintfStability
+  enum ChannelCategoryMask {
+    INDOOR_CHANNEL = (1 << 0) /* 1 */,
+    DFS_CHANNEL = (1 << 1) /* 2 */,
+  }
+  @Backing(type="int") @VintfStability
+  enum ChipMloMode {
+    DEFAULT = 0,
+    LOW_LATENCY = 1,
+    HIGH_THROUGHPUT = 2,
+    LOW_POWER = 3,
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiChipEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiChipEventCallback.aidl
new file mode 100644
index 0000000..3fd8533
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiChipEventCallback.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiChipEventCallback {
+  oneway void onChipReconfigureFailure(in android.hardware.wifi.WifiStatusCode status);
+  oneway void onChipReconfigured(in int modeId);
+  oneway void onDebugErrorAlert(in int errorCode, in byte[] debugData);
+  oneway void onDebugRingBufferDataAvailable(in android.hardware.wifi.WifiDebugRingBufferStatus status, in byte[] data);
+  oneway void onIfaceAdded(in android.hardware.wifi.IfaceType type, in String name);
+  oneway void onIfaceRemoved(in android.hardware.wifi.IfaceType type, in String name);
+  oneway void onRadioModeChange(in android.hardware.wifi.IWifiChipEventCallback.RadioModeInfo[] radioModeInfos);
+  @VintfStability
+  parcelable IfaceInfo {
+    String name;
+    int channel;
+  }
+  @VintfStability
+  parcelable RadioModeInfo {
+    int radioId;
+    android.hardware.wifi.WifiBand bandInfo;
+    android.hardware.wifi.IWifiChipEventCallback.IfaceInfo[] ifaceInfos;
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiEventCallback.aidl
new file mode 100644
index 0000000..00e5cb6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiEventCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiEventCallback {
+  oneway void onFailure(in android.hardware.wifi.WifiStatusCode status);
+  oneway void onStart();
+  oneway void onStop();
+  oneway void onSubsystemRestart(in android.hardware.wifi.WifiStatusCode status);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiNanIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiNanIface.aidl
new file mode 100644
index 0000000..0e2f90f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiNanIface.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiNanIface {
+  String getName();
+  void configRequest(in char cmdId, in android.hardware.wifi.NanConfigRequest msg1, in android.hardware.wifi.NanConfigRequestSupplemental msg2);
+  void createDataInterfaceRequest(in char cmdId, in String ifaceName);
+  void deleteDataInterfaceRequest(in char cmdId, in String ifaceName);
+  void disableRequest(in char cmdId);
+  void enableRequest(in char cmdId, in android.hardware.wifi.NanEnableRequest msg1, in android.hardware.wifi.NanConfigRequestSupplemental msg2);
+  void getCapabilitiesRequest(in char cmdId);
+  void initiateDataPathRequest(in char cmdId, in android.hardware.wifi.NanInitiateDataPathRequest msg);
+  void registerEventCallback(in android.hardware.wifi.IWifiNanIfaceEventCallback callback);
+  void respondToDataPathIndicationRequest(in char cmdId, in android.hardware.wifi.NanRespondToDataPathIndicationRequest msg);
+  void startPublishRequest(in char cmdId, in android.hardware.wifi.NanPublishRequest msg);
+  void startSubscribeRequest(in char cmdId, in android.hardware.wifi.NanSubscribeRequest msg);
+  void stopPublishRequest(in char cmdId, in byte sessionId);
+  void stopSubscribeRequest(in char cmdId, in byte sessionId);
+  void terminateDataPathRequest(in char cmdId, in int ndpInstanceId);
+  void suspendRequest(in char cmdId, in byte sessionId);
+  void resumeRequest(in char cmdId, in byte sessionId);
+  void transmitFollowupRequest(in char cmdId, in android.hardware.wifi.NanTransmitFollowupRequest msg);
+  void initiatePairingRequest(in char cmdId, in android.hardware.wifi.NanPairingRequest msg);
+  void respondToPairingIndicationRequest(in char cmdId, in android.hardware.wifi.NanRespondToPairingIndicationRequest msg);
+  void initiateBootstrappingRequest(in char cmdId, in android.hardware.wifi.NanBootstrappingRequest msg);
+  void respondToBootstrappingIndicationRequest(in char cmdId, in android.hardware.wifi.NanBootstrappingResponse msg);
+  void terminatePairingRequest(in char cmdId, in int pairingInstanceId);
+  const int MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 8;
+  const int MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 63;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
new file mode 100644
index 0000000..8c44330
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiNanIfaceEventCallback {
+  oneway void eventClusterEvent(in android.hardware.wifi.NanClusterEventInd event);
+  oneway void eventDataPathConfirm(in android.hardware.wifi.NanDataPathConfirmInd event);
+  oneway void eventDataPathRequest(in android.hardware.wifi.NanDataPathRequestInd event);
+  oneway void eventDataPathScheduleUpdate(in android.hardware.wifi.NanDataPathScheduleUpdateInd event);
+  oneway void eventDataPathTerminated(in int ndpInstanceId);
+  oneway void eventDisabled(in android.hardware.wifi.NanStatus status);
+  oneway void eventFollowupReceived(in android.hardware.wifi.NanFollowupReceivedInd event);
+  oneway void eventMatch(in android.hardware.wifi.NanMatchInd event);
+  oneway void eventMatchExpired(in byte discoverySessionId, in int peerId);
+  oneway void eventPublishTerminated(in byte sessionId, in android.hardware.wifi.NanStatus status);
+  oneway void eventSubscribeTerminated(in byte sessionId, in android.hardware.wifi.NanStatus status);
+  oneway void eventTransmitFollowup(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void eventSuspensionModeChanged(in android.hardware.wifi.NanSuspensionModeChangeInd event);
+  oneway void notifyCapabilitiesResponse(in char id, in android.hardware.wifi.NanStatus status, in android.hardware.wifi.NanCapabilities capabilities);
+  oneway void notifyConfigResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyCreateDataInterfaceResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyDeleteDataInterfaceResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyDisableResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyEnableResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyInitiateDataPathResponse(in char id, in android.hardware.wifi.NanStatus status, in int ndpInstanceId);
+  oneway void notifyRespondToDataPathIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyStartPublishResponse(in char id, in android.hardware.wifi.NanStatus status, in byte sessionId);
+  oneway void notifyStartSubscribeResponse(in char id, in android.hardware.wifi.NanStatus status, in byte sessionId);
+  oneway void notifyStopPublishResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyStopSubscribeResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyTerminateDataPathResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifySuspendResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyResumeResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyTransmitFollowupResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void eventPairingRequest(in android.hardware.wifi.NanPairingRequestInd event);
+  oneway void eventPairingConfirm(in android.hardware.wifi.NanPairingConfirmInd event);
+  oneway void notifyInitiatePairingResponse(in char id, in android.hardware.wifi.NanStatus status, in int pairingInstanceId);
+  oneway void notifyRespondToPairingIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void eventBootstrappingRequest(in android.hardware.wifi.NanBootstrappingRequestInd event);
+  oneway void eventBootstrappingConfirm(in android.hardware.wifi.NanBootstrappingConfirmInd event);
+  oneway void notifyInitiateBootstrappingResponse(in char id, in android.hardware.wifi.NanStatus status, in int bootstrappingInstanceId);
+  oneway void notifyRespondToBootstrappingIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyTerminatePairingResponse(in char id, in android.hardware.wifi.NanStatus status);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiP2pIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiP2pIface.aidl
new file mode 100644
index 0000000..5e9948e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiP2pIface.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiP2pIface {
+  String getName();
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiRttController.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiRttController.aidl
new file mode 100644
index 0000000..730a055
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiRttController.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiRttController {
+  void disableResponder(in int cmdId);
+  void enableResponder(in int cmdId, in android.hardware.wifi.WifiChannelInfo channelHint, in int maxDurationInSeconds, in android.hardware.wifi.RttResponder info);
+  android.hardware.wifi.IWifiStaIface getBoundIface();
+  android.hardware.wifi.RttCapabilities getCapabilities();
+  android.hardware.wifi.RttResponder getResponderInfo();
+  void rangeCancel(in int cmdId, in android.hardware.wifi.MacAddress[] addrs);
+  void rangeRequest(in int cmdId, in android.hardware.wifi.RttConfig[] rttConfigs);
+  void registerEventCallback(in android.hardware.wifi.IWifiRttControllerEventCallback callback);
+  void setLci(in int cmdId, in android.hardware.wifi.RttLciInformation lci);
+  void setLcr(in int cmdId, in android.hardware.wifi.RttLcrInformation lcr);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiRttControllerEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
new file mode 100644
index 0000000..a6a33fc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiRttControllerEventCallback {
+  oneway void onResults(in int cmdId, in android.hardware.wifi.RttResult[] results);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiStaIface.aidl
new file mode 100644
index 0000000..923deff
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiStaIface.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiStaIface {
+  String getName();
+  void configureRoaming(in android.hardware.wifi.StaRoamingConfig config);
+  void disableLinkLayerStatsCollection();
+  void enableLinkLayerStatsCollection(in boolean debug);
+  void enableNdOffload(in boolean enable);
+  android.hardware.wifi.StaApfPacketFilterCapabilities getApfPacketFilterCapabilities();
+  android.hardware.wifi.StaBackgroundScanCapabilities getBackgroundScanCapabilities();
+  int getFeatureSet();
+  android.hardware.wifi.WifiDebugRxPacketFateReport[] getDebugRxPacketFates();
+  android.hardware.wifi.WifiDebugTxPacketFateReport[] getDebugTxPacketFates();
+  byte[6] getFactoryMacAddress();
+  android.hardware.wifi.StaLinkLayerStats getLinkLayerStats();
+  android.hardware.wifi.StaRoamingCapabilities getRoamingCapabilities();
+  void installApfPacketFilter(in byte[] program);
+  byte[] readApfPacketFilterData();
+  void registerEventCallback(in android.hardware.wifi.IWifiStaIfaceEventCallback callback);
+  void setMacAddress(in byte[6] mac);
+  void setRoamingState(in android.hardware.wifi.StaRoamingState state);
+  void setScanMode(in boolean enable);
+  void startBackgroundScan(in int cmdId, in android.hardware.wifi.StaBackgroundScanParameters params);
+  void startDebugPacketFateMonitoring();
+  void startRssiMonitoring(in int cmdId, in int maxRssi, in int minRssi);
+  void startSendingKeepAlivePackets(in int cmdId, in byte[] ipPacketData, in char etherType, in byte[6] srcAddress, in byte[6] dstAddress, in int periodInMs);
+  void stopBackgroundScan(in int cmdId);
+  void stopRssiMonitoring(in int cmdId);
+  void stopSendingKeepAlivePackets(in int cmdId);
+  void setDtimMultiplier(in int multiplier);
+  @Backing(type="int") @VintfStability
+  enum FeatureSetMask {
+    APF = (1 << 0) /* 1 */,
+    BACKGROUND_SCAN = (1 << 1) /* 2 */,
+    LINK_LAYER_STATS = (1 << 2) /* 4 */,
+    RSSI_MONITOR = (1 << 3) /* 8 */,
+    CONTROL_ROAMING = (1 << 4) /* 16 */,
+    PROBE_IE_ALLOWLIST = (1 << 5) /* 32 */,
+    SCAN_RAND = (1 << 6) /* 64 */,
+    STA_5G = (1 << 7) /* 128 */,
+    HOTSPOT = (1 << 8) /* 256 */,
+    PNO = (1 << 9) /* 512 */,
+    TDLS = (1 << 10) /* 1024 */,
+    TDLS_OFFCHANNEL = (1 << 11) /* 2048 */,
+    ND_OFFLOAD = (1 << 12) /* 4096 */,
+    KEEP_ALIVE = (1 << 13) /* 8192 */,
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
new file mode 100644
index 0000000..48b85b0
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiStaIfaceEventCallback {
+  oneway void onBackgroundFullScanResult(in int cmdId, in int bucketsScanned, in android.hardware.wifi.StaScanResult result);
+  oneway void onBackgroundScanFailure(in int cmdId);
+  oneway void onBackgroundScanResults(in int cmdId, in android.hardware.wifi.StaScanData[] scanDatas);
+  oneway void onRssiThresholdBreached(in int cmdId, in byte[6] currBssid, in int currRssi);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IfaceConcurrencyType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IfaceConcurrencyType.aidl
new file mode 100644
index 0000000..d584423
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IfaceConcurrencyType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum IfaceConcurrencyType {
+  STA,
+  AP,
+  AP_BRIDGED,
+  P2P,
+  NAN_IFACE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IfaceType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IfaceType.aidl
new file mode 100644
index 0000000..67022df
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/IfaceType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum IfaceType {
+  STA,
+  AP,
+  P2P,
+  NAN_IFACE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/MacAddress.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/MacAddress.aidl
new file mode 100644
index 0000000..c4a0613
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/MacAddress.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable MacAddress {
+  byte[6] data;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBandIndex.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBandIndex.aidl
new file mode 100644
index 0000000..3f1ea5e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBandIndex.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanBandIndex {
+  NAN_BAND_24GHZ = 0,
+  NAN_BAND_5GHZ,
+  NAN_BAND_6GHZ = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBandSpecificConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBandSpecificConfig.aidl
new file mode 100644
index 0000000..57540b3
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBandSpecificConfig.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBandSpecificConfig {
+  byte rssiClose;
+  byte rssiMiddle;
+  byte rssiCloseProximity;
+  char dwellTimeMs;
+  char scanPeriodSec;
+  boolean validDiscoveryWindowIntervalVal;
+  byte discoveryWindowIntervalVal;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
new file mode 100644
index 0000000..5ab8dcd
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingConfirmInd {
+  int bootstrappingInstanceId;
+  android.hardware.wifi.NanBootstrappingResponseCode responseCode;
+  android.hardware.wifi.NanStatus reasonCode;
+  int comeBackDelay;
+  byte[] cookie;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingMethod.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingMethod.aidl
new file mode 100644
index 0000000..6ff62b2
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingMethod.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanBootstrappingMethod {
+  BOOTSTRAPPING_OPPORTUNISTIC_MASK = (1 << 0) /* 1 */,
+  BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK = (1 << 1) /* 2 */,
+  BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK = (1 << 2) /* 4 */,
+  BOOTSTRAPPING_QR_DISPLAY_MASK = (1 << 3) /* 8 */,
+  BOOTSTRAPPING_NFC_TAG_MASK = (1 << 4) /* 16 */,
+  BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK = (1 << 5) /* 32 */,
+  BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK = (1 << 6) /* 64 */,
+  BOOTSTRAPPING_QR_SCAN_MASK = (1 << 7) /* 128 */,
+  BOOTSTRAPPING_NFC_READER_MASK = (1 << 8) /* 256 */,
+  BOOTSTRAPPING_SERVICE_MANAGED_MASK = (1 << 14) /* 16384 */,
+  BOOTSTRAPPING_HANDSHAKE_SHIP_MASK = (1 << 15) /* 32768 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingRequest.aidl
new file mode 100644
index 0000000..dd0a5ed
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingRequest {
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  android.hardware.wifi.NanBootstrappingMethod requestBootstrappingMethod;
+  byte[] cookie;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingRequestInd.aidl
new file mode 100644
index 0000000..a4398e9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingRequestInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingRequestInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  int bootstrappingInstanceId;
+  android.hardware.wifi.NanBootstrappingMethod requestBootstrappingMethod;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingResponse.aidl
new file mode 100644
index 0000000..6dd9b26
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingResponse {
+  int bootstrappingInstanceId;
+  boolean acceptRequest;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingResponseCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingResponseCode.aidl
new file mode 100644
index 0000000..a3e9e4d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanBootstrappingResponseCode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanBootstrappingResponseCode {
+  NAN_BOOTSTRAPPING_REQUEST_ACCEPT = 0,
+  NAN_BOOTSTRAPPING_REQUEST_REJECT,
+  NAN_BOOTSTRAPPING_REQUEST_COMEBACK,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanCapabilities.aidl
new file mode 100644
index 0000000..a30893a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanCapabilities.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanCapabilities {
+  int maxConcurrentClusters;
+  int maxPublishes;
+  int maxSubscribes;
+  int maxServiceNameLen;
+  int maxMatchFilterLen;
+  int maxTotalMatchFilterLen;
+  int maxServiceSpecificInfoLen;
+  int maxExtendedServiceSpecificInfoLen;
+  int maxNdiInterfaces;
+  int maxNdpSessions;
+  int maxAppInfoLen;
+  int maxQueuedTransmitFollowupMsgs;
+  int maxSubscribeInterfaceAddresses;
+  int supportedCipherSuites;
+  boolean instantCommunicationModeSupportFlag;
+  boolean supports6g;
+  boolean supportsHe;
+  boolean supportsPairing;
+  boolean supportsSetClusterId;
+  boolean supportsSuspension;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanCipherSuiteType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanCipherSuiteType.aidl
new file mode 100644
index 0000000..6f3158e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanCipherSuiteType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanCipherSuiteType {
+  NONE = 0,
+  SHARED_KEY_128_MASK = (1 << 0) /* 1 */,
+  SHARED_KEY_256_MASK = (1 << 1) /* 2 */,
+  PUBLIC_KEY_2WDH_128_MASK = (1 << 2) /* 4 */,
+  PUBLIC_KEY_2WDH_256_MASK = (1 << 3) /* 8 */,
+  PUBLIC_KEY_PASN_128_MASK = (1 << 6) /* 64 */,
+  PUBLIC_KEY_PASN_256_MASK = (1 << 7) /* 128 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanClusterEventInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanClusterEventInd.aidl
new file mode 100644
index 0000000..7a3ff81
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanClusterEventInd.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanClusterEventInd {
+  android.hardware.wifi.NanClusterEventType eventType;
+  byte[6] addr;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanClusterEventType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanClusterEventType.aidl
new file mode 100644
index 0000000..6c20543
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanClusterEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanClusterEventType {
+  DISCOVERY_MAC_ADDRESS_CHANGED = 0,
+  STARTED_CLUSTER,
+  JOINED_CLUSTER,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanConfigRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanConfigRequest.aidl
new file mode 100644
index 0000000..5ead651
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanConfigRequest.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanConfigRequest {
+  byte masterPref;
+  boolean disableDiscoveryAddressChangeIndication;
+  boolean disableStartedClusterIndication;
+  boolean disableJoinedClusterIndication;
+  boolean includePublishServiceIdsInBeacon;
+  byte numberOfPublishServiceIdsInBeacon;
+  boolean includeSubscribeServiceIdsInBeacon;
+  byte numberOfSubscribeServiceIdsInBeacon;
+  char rssiWindowSize;
+  int macAddressRandomizationIntervalSec;
+  android.hardware.wifi.NanBandSpecificConfig[3] bandSpecificConfig;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanConfigRequestSupplemental.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanConfigRequestSupplemental.aidl
new file mode 100644
index 0000000..99f2af7
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanConfigRequestSupplemental.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanConfigRequestSupplemental {
+  int discoveryBeaconIntervalMs;
+  int numberOfSpatialStreamsInDiscovery;
+  boolean enableDiscoveryWindowEarlyTermination;
+  boolean enableRanging;
+  boolean enableInstantCommunicationMode;
+  int instantModeChannel;
+  int clusterId;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathChannelCfg.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathChannelCfg.aidl
new file mode 100644
index 0000000..4233c32
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathChannelCfg.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanDataPathChannelCfg {
+  CHANNEL_NOT_REQUESTED = 0,
+  REQUEST_CHANNEL_SETUP,
+  FORCE_CHANNEL_SETUP,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathChannelInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathChannelInfo.aidl
new file mode 100644
index 0000000..d111db7
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathChannelInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathChannelInfo {
+  int channelFreq;
+  android.hardware.wifi.WifiChannelWidthInMhz channelBandwidth;
+  int numSpatialStreams;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathConfirmInd.aidl
new file mode 100644
index 0000000..2e1e2ca
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathConfirmInd.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathConfirmInd {
+  int ndpInstanceId;
+  boolean dataPathSetupSuccess;
+  byte[6] peerNdiMacAddr;
+  byte[] appInfo;
+  android.hardware.wifi.NanStatus status;
+  android.hardware.wifi.NanDataPathChannelInfo[] channelInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathRequestInd.aidl
new file mode 100644
index 0000000..74d5b73
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathRequestInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathRequestInd {
+  byte discoverySessionId;
+  byte[6] peerDiscMacAddr;
+  int ndpInstanceId;
+  boolean securityRequired;
+  byte[] appInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
new file mode 100644
index 0000000..5fabf55
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathScheduleUpdateInd {
+  byte[6] peerDiscoveryAddress;
+  android.hardware.wifi.NanDataPathChannelInfo[] channelInfo;
+  int[] ndpInstanceIds;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathSecurityConfig.aidl
new file mode 100644
index 0000000..635dbce
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathSecurityConfig {
+  android.hardware.wifi.NanDataPathSecurityType securityType;
+  android.hardware.wifi.NanCipherSuiteType cipherType;
+  byte[32] pmk;
+  byte[] passphrase;
+  byte[16] scid;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathSecurityType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathSecurityType.aidl
new file mode 100644
index 0000000..cb7904d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDataPathSecurityType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanDataPathSecurityType {
+  OPEN,
+  PMK,
+  PASSPHRASE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDebugConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDebugConfig.aidl
new file mode 100644
index 0000000..b84d891
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDebugConfig.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDebugConfig {
+  boolean validClusterIdVals;
+  char clusterIdBottomRangeVal;
+  char clusterIdTopRangeVal;
+  boolean validIntfAddrVal;
+  byte[6] intfAddrVal;
+  boolean validOuiVal;
+  int ouiVal;
+  boolean validRandomFactorForceVal;
+  byte randomFactorForceVal;
+  boolean validHopCountForceVal;
+  byte hopCountForceVal;
+  boolean validDiscoveryChannelVal;
+  int[3] discoveryChannelMhzVal;
+  boolean validUseBeaconsInBandVal;
+  boolean[3] useBeaconsInBandVal;
+  boolean validUseSdfInBandVal;
+  boolean[3] useSdfInBandVal;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDiscoveryCommonConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
new file mode 100644
index 0000000..96d940a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDiscoveryCommonConfig {
+  byte sessionId;
+  char ttlSec;
+  char discoveryWindowPeriod;
+  byte discoveryCount;
+  byte[] serviceName;
+  android.hardware.wifi.NanMatchAlg discoveryMatchIndicator;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+  byte[] rxMatchFilter;
+  byte[] txMatchFilter;
+  boolean useRssiThreshold;
+  boolean disableDiscoveryTerminationIndication;
+  boolean disableMatchExpirationIndication;
+  boolean disableFollowupReceivedIndication;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  boolean rangingRequired;
+  int rangingIntervalMs;
+  int configRangingIndications;
+  char distanceIngressCm;
+  char distanceEgressCm;
+  boolean enableSessionSuspendability;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanEnableRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanEnableRequest.aidl
new file mode 100644
index 0000000..eaa009c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanEnableRequest.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanEnableRequest {
+  boolean[3] operateInBand;
+  byte hopCountMax;
+  android.hardware.wifi.NanConfigRequest configParams;
+  android.hardware.wifi.NanDebugConfig debugConfigs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanFollowupReceivedInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanFollowupReceivedInd.aidl
new file mode 100644
index 0000000..743ad9d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanFollowupReceivedInd.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanFollowupReceivedInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] addr;
+  boolean receivedInFaw;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanIdentityResolutionAttribute.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
new file mode 100644
index 0000000..843107e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanIdentityResolutionAttribute {
+  byte[8] nonce;
+  byte[8] tag;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanInitiateDataPathRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanInitiateDataPathRequest.aidl
new file mode 100644
index 0000000..740a140
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanInitiateDataPathRequest.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanInitiateDataPathRequest {
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  android.hardware.wifi.NanDataPathChannelCfg channelRequestType;
+  int channel;
+  String ifaceName;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  byte[] appInfo;
+  byte[] serviceNameOutOfBand;
+  byte discoverySessionId;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanMatchAlg.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanMatchAlg.aidl
new file mode 100644
index 0000000..93ac26b
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanMatchAlg.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanMatchAlg {
+  MATCH_ONCE = 0,
+  MATCH_CONTINUOUS,
+  MATCH_NEVER,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanMatchInd.aidl
new file mode 100644
index 0000000..317489f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanMatchInd.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanMatchInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] addr;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+  byte[] matchFilter;
+  boolean matchOccurredInBeaconFlag;
+  boolean outOfResourceFlag;
+  byte rssiValue;
+  android.hardware.wifi.NanCipherSuiteType peerCipherType;
+  boolean peerRequiresSecurityEnabledInNdp;
+  boolean peerRequiresRanging;
+  int rangingMeasurementInMm;
+  int rangingIndicationType;
+  byte[] scid;
+  android.hardware.wifi.NanPairingConfig peerPairingConfig;
+  android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingAkm.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingAkm.aidl
new file mode 100644
index 0000000..05bbaee
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingAkm.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPairingAkm {
+  SAE = 0,
+  PASN = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingConfig.aidl
new file mode 100644
index 0000000..1c04a96
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingConfig {
+  boolean enablePairingSetup;
+  boolean enablePairingCache;
+  boolean enablePairingVerification;
+  int supportedBootstrappingMethods;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingConfirmInd.aidl
new file mode 100644
index 0000000..8ecf22a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingConfirmInd.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingConfirmInd {
+  int pairingInstanceId;
+  boolean pairingSuccess;
+  android.hardware.wifi.NanStatus status;
+  android.hardware.wifi.NanPairingRequestType requestType;
+  boolean enablePairingCache;
+  android.hardware.wifi.NpkSecurityAssociation npksa;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingRequest.aidl
new file mode 100644
index 0000000..2a644ae
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingRequest.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingRequest {
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  android.hardware.wifi.NanPairingRequestType requestType;
+  boolean enablePairingCache;
+  byte[16] pairingIdentityKey;
+  android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingRequestInd.aidl
new file mode 100644
index 0000000..66762b9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingRequestInd.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingRequestInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  int pairingInstanceId;
+  android.hardware.wifi.NanPairingRequestType requestType;
+  boolean enablePairingCache;
+  android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingRequestType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingRequestType.aidl
new file mode 100644
index 0000000..3488340
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingRequestType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPairingRequestType {
+  NAN_PAIRING_SETUP = 0,
+  NAN_PAIRING_VERIFICATION,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingSecurityConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingSecurityConfig.aidl
new file mode 100644
index 0000000..1a6a13c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingSecurityConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingSecurityConfig {
+  android.hardware.wifi.NanPairingSecurityType securityType;
+  byte[32] pmk;
+  byte[] passphrase;
+  android.hardware.wifi.NanPairingAkm akm;
+  android.hardware.wifi.NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingSecurityType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingSecurityType.aidl
new file mode 100644
index 0000000..9f6c774
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPairingSecurityType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPairingSecurityType {
+  OPPORTUNISTIC,
+  PMK,
+  PASSPHRASE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPublishRequest.aidl
new file mode 100644
index 0000000..c49f5f9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPublishRequest.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPublishRequest {
+  android.hardware.wifi.NanDiscoveryCommonConfig baseConfigs;
+  android.hardware.wifi.NanPublishType publishType;
+  android.hardware.wifi.NanTxType txType;
+  boolean autoAcceptDataPathRequests;
+  android.hardware.wifi.NanPairingConfig pairingConfig;
+  byte[16] identityKey;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPublishType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPublishType.aidl
new file mode 100644
index 0000000..30dffb2
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanPublishType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPublishType {
+  UNSOLICITED = 0,
+  SOLICITED,
+  UNSOLICITED_SOLICITED,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanRangingIndication.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanRangingIndication.aidl
new file mode 100644
index 0000000..cf72dce
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanRangingIndication.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanRangingIndication {
+  CONTINUOUS_INDICATION_MASK = (1 << 0) /* 1 */,
+  INGRESS_MET_MASK = (1 << 1) /* 2 */,
+  EGRESS_MET_MASK = (1 << 2) /* 4 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
new file mode 100644
index 0000000..0f873b5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanRespondToDataPathIndicationRequest {
+  boolean acceptRequest;
+  int ndpInstanceId;
+  String ifaceName;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  byte[] appInfo;
+  byte[] serviceNameOutOfBand;
+  byte discoverySessionId;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
new file mode 100644
index 0000000..a58890c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanRespondToPairingIndicationRequest {
+  boolean acceptRequest;
+  int pairingInstanceId;
+  android.hardware.wifi.NanPairingRequestType requestType;
+  boolean enablePairingCache;
+  byte[16] pairingIdentityKey;
+  android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSrfType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSrfType.aidl
new file mode 100644
index 0000000..82409fd
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSrfType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanSrfType {
+  BLOOM_FILTER = 0,
+  PARTIAL_MAC_ADDR,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanStatus.aidl
new file mode 100644
index 0000000..834558a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanStatus {
+  android.hardware.wifi.NanStatusCode status;
+  String description;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanStatusCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanStatusCode.aidl
new file mode 100644
index 0000000..ec12eb0
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanStatusCode.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanStatusCode {
+  SUCCESS = 0,
+  INTERNAL_FAILURE = 1,
+  PROTOCOL_FAILURE = 2,
+  INVALID_SESSION_ID = 3,
+  NO_RESOURCES_AVAILABLE = 4,
+  INVALID_ARGS = 5,
+  INVALID_PEER_ID = 6,
+  INVALID_NDP_ID = 7,
+  NAN_NOT_ALLOWED = 8,
+  NO_OTA_ACK = 9,
+  ALREADY_ENABLED = 10,
+  FOLLOWUP_TX_QUEUE_FULL = 11,
+  UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12,
+  INVALID_PAIRING_ID = 13,
+  INVALID_BOOTSTRAPPING_ID = 14,
+  REDUNDANT_REQUEST = 15,
+  NOT_SUPPORTED = 16,
+  NO_CONNECTION = 17,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSubscribeRequest.aidl
new file mode 100644
index 0000000..96be096
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanSubscribeRequest {
+  android.hardware.wifi.NanDiscoveryCommonConfig baseConfigs;
+  android.hardware.wifi.NanSubscribeType subscribeType;
+  android.hardware.wifi.NanSrfType srfType;
+  boolean srfRespondIfInAddressSet;
+  boolean shouldUseSrf;
+  boolean isSsiRequiredForMatch;
+  android.hardware.wifi.MacAddress[] intfAddr;
+  android.hardware.wifi.NanPairingConfig pairingConfig;
+  byte[16] identityKey;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSubscribeType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSubscribeType.aidl
new file mode 100644
index 0000000..4f06df9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSubscribeType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanSubscribeType {
+  PASSIVE = 0,
+  ACTIVE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSuspensionModeChangeInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSuspensionModeChangeInd.aidl
new file mode 100644
index 0000000..557fc79
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanSuspensionModeChangeInd.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanSuspensionModeChangeInd {
+  boolean isSuspended;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanTransmitFollowupRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanTransmitFollowupRequest.aidl
new file mode 100644
index 0000000..20c94d9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanTransmitFollowupRequest.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanTransmitFollowupRequest {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] addr;
+  boolean isHighPriority;
+  boolean shouldUseDiscoveryWindow;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+  boolean disableFollowupResultIndication;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanTxType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanTxType.aidl
new file mode 100644
index 0000000..798d3a2
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NanTxType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanTxType {
+  BROADCAST = 0,
+  UNICAST,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NpkSecurityAssociation.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NpkSecurityAssociation.aidl
new file mode 100644
index 0000000..508e920
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/NpkSecurityAssociation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NpkSecurityAssociation {
+  byte[16] peerNanIdentityKey;
+  byte[16] localNanIdentityKey;
+  byte[32] npk;
+  android.hardware.wifi.NanPairingAkm akm;
+  android.hardware.wifi.NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttBw.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttBw.aidl
new file mode 100644
index 0000000..7cc7002
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttBw.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttBw {
+  BW_UNSPECIFIED = 0x0,
+  BW_5MHZ = 0x01,
+  BW_10MHZ = 0x02,
+  BW_20MHZ = 0x04,
+  BW_40MHZ = 0x08,
+  BW_80MHZ = 0x10,
+  BW_160MHZ = 0x20,
+  BW_320MHZ = 0x40,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttCapabilities.aidl
new file mode 100644
index 0000000..cf64687
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttCapabilities.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttCapabilities {
+  boolean rttOneSidedSupported;
+  boolean rttFtmSupported;
+  boolean lciSupported;
+  boolean lcrSupported;
+  boolean responderSupported;
+  android.hardware.wifi.RttPreamble preambleSupport;
+  android.hardware.wifi.RttBw bwSupport;
+  byte mcVersion;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttConfig.aidl
new file mode 100644
index 0000000..ccdf2ce
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttConfig.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttConfig {
+  byte[6] addr;
+  android.hardware.wifi.RttType type;
+  android.hardware.wifi.RttPeerType peer;
+  android.hardware.wifi.WifiChannelInfo channel;
+  int burstPeriod;
+  int numBurst;
+  int numFramesPerBurst;
+  int numRetriesPerRttFrame;
+  int numRetriesPerFtmr;
+  boolean mustRequestLci;
+  boolean mustRequestLcr;
+  int burstDuration;
+  android.hardware.wifi.RttPreamble preamble;
+  android.hardware.wifi.RttBw bw;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttLciInformation.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttLciInformation.aidl
new file mode 100644
index 0000000..0fcf151
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttLciInformation.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttLciInformation {
+  long latitude;
+  long longitude;
+  int altitude;
+  byte latitudeUnc;
+  byte longitudeUnc;
+  byte altitudeUnc;
+  android.hardware.wifi.RttMotionPattern motionPattern;
+  int floor;
+  int heightAboveFloor;
+  int heightUnc;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttLcrInformation.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttLcrInformation.aidl
new file mode 100644
index 0000000..c756dda
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttLcrInformation.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttLcrInformation {
+  byte[2] countryCode;
+  String civicInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttMotionPattern.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttMotionPattern.aidl
new file mode 100644
index 0000000..7c8e369
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttMotionPattern.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttMotionPattern {
+  NOT_EXPECTED = 0,
+  EXPECTED = 1,
+  UNKNOWN = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttPeerType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttPeerType.aidl
new file mode 100644
index 0000000..23fa7f6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttPeerType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttPeerType {
+  AP = 1,
+  STA = 2,
+  P2P_GO = 3,
+  P2P_CLIENT = 4,
+  NAN_TYPE = 5,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttPreamble.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttPreamble.aidl
new file mode 100644
index 0000000..de26f28
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttPreamble.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttPreamble {
+  LEGACY = 0x1,
+  HT = 0x2,
+  VHT = 0x4,
+  HE = 0x8,
+  EHT = 0x10,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttResponder.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttResponder.aidl
new file mode 100644
index 0000000..41463b5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttResponder.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttResponder {
+  android.hardware.wifi.WifiChannelInfo channel;
+  android.hardware.wifi.RttPreamble preamble;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttResult.aidl
new file mode 100644
index 0000000..8375dcb
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttResult.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttResult {
+  byte[6] addr;
+  int burstNum;
+  int measurementNumber;
+  int successNumber;
+  byte numberPerBurstPeer;
+  android.hardware.wifi.RttStatus status;
+  byte retryAfterDuration;
+  android.hardware.wifi.RttType type;
+  int rssi;
+  int rssiSpread;
+  android.hardware.wifi.WifiRateInfo txRate;
+  android.hardware.wifi.WifiRateInfo rxRate;
+  long rtt;
+  long rttSd;
+  long rttSpread;
+  int distanceInMm;
+  int distanceSdInMm;
+  int distanceSpreadInMm;
+  long timeStampInUs;
+  int burstDurationInMs;
+  int negotiatedBurstNum;
+  android.hardware.wifi.WifiInformationElement lci;
+  android.hardware.wifi.WifiInformationElement lcr;
+  int channelFreqMHz;
+  android.hardware.wifi.RttBw packetBw;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttStatus.aidl
new file mode 100644
index 0000000..2817497
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttStatus.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttStatus {
+  SUCCESS = 0,
+  FAILURE = 1,
+  FAIL_NO_RSP = 2,
+  FAIL_REJECTED = 3,
+  FAIL_NOT_SCHEDULED_YET = 4,
+  FAIL_TM_TIMEOUT = 5,
+  FAIL_AP_ON_DIFF_CHANNEL = 6,
+  FAIL_NO_CAPABILITY = 7,
+  ABORTED = 8,
+  FAIL_INVALID_TS = 9,
+  FAIL_PROTOCOL = 10,
+  FAIL_SCHEDULE = 11,
+  FAIL_BUSY_TRY_LATER = 12,
+  INVALID_REQ = 13,
+  NO_WIFI = 14,
+  FAIL_FTM_PARAM_OVERRIDE = 15,
+  NAN_RANGING_PROTOCOL_FAILURE = 16,
+  NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttType.aidl
new file mode 100644
index 0000000..2b6087a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/RttType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttType {
+  ONE_SIDED = 1,
+  TWO_SIDED = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/Ssid.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/Ssid.aidl
new file mode 100644
index 0000000..98b523f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/Ssid.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable Ssid {
+  byte[32] data;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
new file mode 100644
index 0000000..3b4d785
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaApfPacketFilterCapabilities {
+  int version;
+  int maxLength;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
new file mode 100644
index 0000000..249d876
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum StaBackgroundScanBucketEventReportSchemeMask {
+  EACH_SCAN = (1 << 0) /* 1 */,
+  FULL_RESULTS = (1 << 1) /* 2 */,
+  NO_BATCH = (1 << 2) /* 4 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
new file mode 100644
index 0000000..4e9671a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaBackgroundScanBucketParameters {
+  int bucketIdx;
+  android.hardware.wifi.WifiBand band;
+  int[] frequencies;
+  int periodInMs;
+  int eventReportScheme;
+  int exponentialMaxPeriodInMs;
+  int exponentialBase;
+  int exponentialStepCount;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
new file mode 100644
index 0000000..758dd97
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaBackgroundScanCapabilities {
+  int maxCacheSize;
+  int maxBuckets;
+  int maxApCachePerScan;
+  int maxReportingThreshold;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanLimits.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanLimits.aidl
new file mode 100644
index 0000000..05d0277
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanLimits.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum StaBackgroundScanLimits {
+  MAX_CHANNELS = 16,
+  MAX_BUCKETS = 16,
+  MAX_AP_CACHE_PER_SCAN = 32,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanParameters.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanParameters.aidl
new file mode 100644
index 0000000..0773566
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaBackgroundScanParameters.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaBackgroundScanParameters {
+  int basePeriodInMs;
+  int maxApPerScan;
+  int reportThresholdPercent;
+  int reportThresholdNumScans;
+  android.hardware.wifi.StaBackgroundScanBucketParameters[] buckets;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
new file mode 100644
index 0000000..4dee6de
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerIfaceContentionTimeStats {
+  int contentionTimeMinInUsec;
+  int contentionTimeMaxInUsec;
+  int contentionTimeAvgInUsec;
+  int contentionNumSamples;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
new file mode 100644
index 0000000..eddf52e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerIfacePacketStats {
+  long rxMpdu;
+  long txMpdu;
+  long lostMpdu;
+  long retries;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerIfaceStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
new file mode 100644
index 0000000..a419207
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerIfaceStats {
+  android.hardware.wifi.StaLinkLayerLinkStats[] links;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerLinkStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerLinkStats.aidl
new file mode 100644
index 0000000..cd21c25
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerLinkStats.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerLinkStats {
+  int linkId;
+  int radioId;
+  int frequencyMhz;
+  int beaconRx;
+  int avgRssiMgmt;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBePktStats;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBkPktStats;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeViPktStats;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeVoPktStats;
+  byte timeSliceDutyCycleInPercent;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+  android.hardware.wifi.StaPeerInfo[] peers;
+  android.hardware.wifi.StaLinkLayerLinkStats.StaLinkState state;
+  @Backing(type="int") @VintfStability
+  enum StaLinkState {
+    UNKNOWN = 0,
+    NOT_IN_USE = (1 << 0) /* 1 */,
+    IN_USE = (1 << 1) /* 2 */,
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerRadioStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerRadioStats.aidl
new file mode 100644
index 0000000..84d24c9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerRadioStats.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerRadioStats {
+  int onTimeInMs;
+  int txTimeInMs;
+  int[] txTimeInMsPerLevel;
+  int rxTimeInMs;
+  int onTimeInMsForScan;
+  int onTimeInMsForNanScan;
+  int onTimeInMsForBgScan;
+  int onTimeInMsForRoamScan;
+  int onTimeInMsForPnoScan;
+  int onTimeInMsForHs20Scan;
+  android.hardware.wifi.WifiChannelStats[] channelStats;
+  int radioId;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerStats.aidl
new file mode 100644
index 0000000..9c05346
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaLinkLayerStats.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerStats {
+  android.hardware.wifi.StaLinkLayerIfaceStats iface;
+  android.hardware.wifi.StaLinkLayerRadioStats[] radios;
+  long timeStampInMs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaPeerInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaPeerInfo.aidl
new file mode 100644
index 0000000..93a901f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaPeerInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaPeerInfo {
+  char staCount;
+  char chanUtil;
+  android.hardware.wifi.StaRateStat[] rateStats;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRateStat.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRateStat.aidl
new file mode 100644
index 0000000..43b69fc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRateStat.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaRateStat {
+  android.hardware.wifi.WifiRateInfo rateInfo;
+  int txMpdu;
+  int rxMpdu;
+  int mpduLost;
+  int retries;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRoamingCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRoamingCapabilities.aidl
new file mode 100644
index 0000000..9eed877
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRoamingCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaRoamingCapabilities {
+  int maxBlocklistSize;
+  int maxAllowlistSize;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRoamingConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRoamingConfig.aidl
new file mode 100644
index 0000000..2b37cee
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRoamingConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaRoamingConfig {
+  android.hardware.wifi.MacAddress[] bssidBlocklist;
+  android.hardware.wifi.Ssid[] ssidAllowlist;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRoamingState.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRoamingState.aidl
new file mode 100644
index 0000000..1f3d91f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaRoamingState.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="byte") @VintfStability
+enum StaRoamingState {
+  DISABLED = 0,
+  ENABLED = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaScanData.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaScanData.aidl
new file mode 100644
index 0000000..7c75232
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaScanData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaScanData {
+  int flags;
+  int bucketsScanned;
+  android.hardware.wifi.StaScanResult[] results;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaScanDataFlagMask.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaScanDataFlagMask.aidl
new file mode 100644
index 0000000..0ca4b4b
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaScanDataFlagMask.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum StaScanDataFlagMask {
+  INTERRUPTED = (1 << 0) /* 1 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaScanResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaScanResult.aidl
new file mode 100644
index 0000000..9a8d297
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/StaScanResult.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaScanResult {
+  long timeStampInUs;
+  byte[] ssid;
+  byte[6] bssid;
+  int rssi;
+  int frequency;
+  char beaconPeriodInMs;
+  char capability;
+  android.hardware.wifi.WifiInformationElement[] informationElements;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiAntennaMode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiAntennaMode.aidl
new file mode 100644
index 0000000..b47b7f5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiAntennaMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiAntennaMode {
+  WIFI_ANTENNA_MODE_UNSPECIFIED = 0,
+  WIFI_ANTENNA_MODE_1X1 = 1,
+  WIFI_ANTENNA_MODE_2X2 = 2,
+  WIFI_ANTENNA_MODE_3X3 = 3,
+  WIFI_ANTENNA_MODE_4X4 = 4,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiBand.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiBand.aidl
new file mode 100644
index 0000000..e9a87ee
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiBand.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiBand {
+  BAND_UNSPECIFIED = 0,
+  BAND_24GHZ = 1,
+  BAND_5GHZ = 2,
+  BAND_5GHZ_DFS = 4,
+  BAND_5GHZ_WITH_DFS = 6,
+  BAND_24GHZ_5GHZ = 3,
+  BAND_24GHZ_5GHZ_WITH_DFS = 7,
+  BAND_6GHZ = 8,
+  BAND_5GHZ_6GHZ = 10,
+  BAND_24GHZ_5GHZ_6GHZ = 11,
+  BAND_24GHZ_5GHZ_WITH_DFS_6GHZ = 15,
+  BAND_60GHZ = 16,
+  BAND_24GHZ_5GHZ_6GHZ_60GHZ = 27,
+  BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChannelInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChannelInfo.aidl
new file mode 100644
index 0000000..297c923
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChannelInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiChannelInfo {
+  android.hardware.wifi.WifiChannelWidthInMhz width;
+  int centerFreq;
+  int centerFreq0;
+  int centerFreq1;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChannelStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChannelStats.aidl
new file mode 100644
index 0000000..c6e7acc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChannelStats.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiChannelStats {
+  android.hardware.wifi.WifiChannelInfo channel;
+  int onTimeInMs;
+  int ccaBusyTimeInMs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChannelWidthInMhz.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChannelWidthInMhz.aidl
new file mode 100644
index 0000000..e6ea642
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChannelWidthInMhz.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiChannelWidthInMhz {
+  WIDTH_INVALID = (-1) /* -1 */,
+  WIDTH_20 = 0,
+  WIDTH_40 = 1,
+  WIDTH_80 = 2,
+  WIDTH_160 = 3,
+  WIDTH_80P80 = 4,
+  WIDTH_5 = 5,
+  WIDTH_10 = 6,
+  WIDTH_320 = 7,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChipCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChipCapabilities.aidl
new file mode 100644
index 0000000..b5034ea
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiChipCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiChipCapabilities {
+  int maxMloAssociationLinkCount;
+  int maxMloStrLinkCount;
+  int maxConcurrentTdlsSessionCount;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
new file mode 100644
index 0000000..8415e09
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxIcmpPacketDetails {
+  int icmpPkt;
+  int icmp6Pkt;
+  int icmp6Ra;
+  int icmp6Na;
+  int icmp6Ns;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
new file mode 100644
index 0000000..30301d3
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxMulticastPacketDetails {
+  int ipv4RxMulticastAddrCnt;
+  int ipv6RxMulticastAddrCnt;
+  int otherRxMulticastAddrCnt;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
new file mode 100644
index 0000000..8118322
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxPacketDetails {
+  int rxUnicastCnt;
+  int rxMulticastCnt;
+  int rxBroadcastCnt;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
new file mode 100644
index 0000000..1766476
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonStats {
+  int totalCmdEventWakeCnt;
+  int[] cmdEventWakeCntPerType;
+  int totalDriverFwLocalWakeCnt;
+  int[] driverFwLocalWakeCntPerType;
+  int totalRxPacketWakeCnt;
+  android.hardware.wifi.WifiDebugHostWakeReasonRxPacketDetails rxPktWakeDetails;
+  android.hardware.wifi.WifiDebugHostWakeReasonRxMulticastPacketDetails rxMulticastPkWakeDetails;
+  android.hardware.wifi.WifiDebugHostWakeReasonRxIcmpPacketDetails rxIcmpPkWakeDetails;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
new file mode 100644
index 0000000..2ff6cfc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugPacketFateFrameInfo {
+  android.hardware.wifi.WifiDebugPacketFateFrameType frameType;
+  long frameLen;
+  long driverTimestampUsec;
+  long firmwareTimestampUsec;
+  byte[] frameContent;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
new file mode 100644
index 0000000..6db96ef
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugPacketFateFrameType {
+  UNKNOWN,
+  ETHERNET_II,
+  MGMT_80211,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRingBufferFlags.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
new file mode 100644
index 0000000..9ababc3
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugRingBufferFlags {
+  HAS_BINARY_ENTRIES = (1 << 0) /* 1 */,
+  HAS_ASCII_ENTRIES = (1 << 1) /* 2 */,
+  HAS_PER_PACKET_ENTRIES = (1 << 2) /* 4 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRingBufferStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
new file mode 100644
index 0000000..e4249d9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugRingBufferStatus {
+  String ringName;
+  int flags;
+  int ringId;
+  int sizeInBytes;
+  int freeSizeInBytes;
+  int verboseLevel;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
new file mode 100644
index 0000000..e614f3f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugRingBufferVerboseLevel {
+  NONE = 0,
+  DEFAULT = 1,
+  VERBOSE = 2,
+  EXCESSIVE = 3,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRxPacketFate.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRxPacketFate.aidl
new file mode 100644
index 0000000..f638c4f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRxPacketFate.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugRxPacketFate {
+  SUCCESS,
+  FW_QUEUED,
+  FW_DROP_FILTER,
+  FW_DROP_INVALID,
+  FW_DROP_NOBUFS,
+  FW_DROP_OTHER,
+  DRV_QUEUED,
+  DRV_DROP_FILTER,
+  DRV_DROP_INVALID,
+  DRV_DROP_NOBUFS,
+  DRV_DROP_OTHER,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
new file mode 100644
index 0000000..bfe0c0a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugRxPacketFateReport {
+  android.hardware.wifi.WifiDebugRxPacketFate fate;
+  android.hardware.wifi.WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugTxPacketFate.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugTxPacketFate.aidl
new file mode 100644
index 0000000..778ca5d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugTxPacketFate.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugTxPacketFate {
+  ACKED,
+  SENT,
+  FW_QUEUED,
+  FW_DROP_INVALID,
+  FW_DROP_NOBUFS,
+  FW_DROP_OTHER,
+  DRV_QUEUED,
+  DRV_DROP_INVALID,
+  DRV_DROP_NOBUFS,
+  DRV_DROP_OTHER,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
new file mode 100644
index 0000000..aee5c31
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugTxPacketFateReport {
+  android.hardware.wifi.WifiDebugTxPacketFate fate;
+  android.hardware.wifi.WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiIfaceMode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiIfaceMode.aidl
new file mode 100644
index 0000000..557cef4
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiIfaceMode.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiIfaceMode {
+  IFACE_MODE_STA = (1 << 0) /* 1 */,
+  IFACE_MODE_SOFTAP = (1 << 1) /* 2 */,
+  IFACE_MODE_IBSS = (1 << 2) /* 4 */,
+  IFACE_MODE_P2P_CLIENT = (1 << 3) /* 8 */,
+  IFACE_MODE_P2P_GO = (1 << 4) /* 16 */,
+  IFACE_MODE_NAN = (1 << 5) /* 32 */,
+  IFACE_MODE_MESH = (1 << 6) /* 64 */,
+  IFACE_MODE_TDLS = (1 << 7) /* 128 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiInformationElement.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiInformationElement.aidl
new file mode 100644
index 0000000..27ba0db
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiInformationElement.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiInformationElement {
+  byte id;
+  byte[] data;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRadioCombination.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRadioCombination.aidl
new file mode 100644
index 0000000..f060db8
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRadioCombination.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRadioCombination {
+  android.hardware.wifi.WifiRadioConfiguration[] radioConfigurations;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRadioConfiguration.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRadioConfiguration.aidl
new file mode 100644
index 0000000..5169351
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRadioConfiguration.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRadioConfiguration {
+  android.hardware.wifi.WifiBand bandInfo;
+  android.hardware.wifi.WifiAntennaMode antennaMode;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRateInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRateInfo.aidl
new file mode 100644
index 0000000..c4aca63
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRateInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRateInfo {
+  android.hardware.wifi.WifiRatePreamble preamble;
+  android.hardware.wifi.WifiRateNss nss;
+  android.hardware.wifi.WifiChannelWidthInMhz bw;
+  byte rateMcsIdx;
+  int bitRateInKbps;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRateNss.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRateNss.aidl
new file mode 100644
index 0000000..0ad6f04
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRateNss.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiRateNss {
+  NSS_1x1 = 0,
+  NSS_2x2 = 1,
+  NSS_3x3 = 2,
+  NSS_4x4 = 3,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRatePreamble.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRatePreamble.aidl
new file mode 100644
index 0000000..04b6358
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiRatePreamble.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiRatePreamble {
+  OFDM = 0,
+  CCK = 1,
+  HT = 2,
+  VHT = 3,
+  RESERVED = 4,
+  HE = 5,
+  EHT = 6,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiStatusCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiStatusCode.aidl
new file mode 100644
index 0000000..9a15fa1
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiStatusCode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiStatusCode {
+  SUCCESS,
+  ERROR_WIFI_CHIP_INVALID,
+  ERROR_WIFI_IFACE_INVALID,
+  ERROR_WIFI_RTT_CONTROLLER_INVALID,
+  ERROR_NOT_SUPPORTED,
+  ERROR_NOT_AVAILABLE,
+  ERROR_NOT_STARTED,
+  ERROR_INVALID_ARGS,
+  ERROR_BUSY,
+  ERROR_UNKNOWN,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiUsableChannel.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiUsableChannel.aidl
new file mode 100644
index 0000000..774b242
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/1/android/hardware/wifi/WifiUsableChannel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiUsableChannel {
+  int channel;
+  android.hardware.wifi.WifiChannelWidthInMhz channelBandwidth;
+  int ifaceModeMask;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AfcChannelAllowance.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AfcChannelAllowance.aidl
new file mode 100644
index 0000000..4d3cd6e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AfcChannelAllowance.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable AfcChannelAllowance {
+  android.hardware.wifi.AvailableAfcFrequencyInfo[] availableAfcFrequencyInfos;
+  android.hardware.wifi.AvailableAfcChannelInfo[] availableAfcChannelInfos;
+  long availabilityExpireTimeMs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcChannelInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcChannelInfo.aidl
new file mode 100644
index 0000000..d238640
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcChannelInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable AvailableAfcChannelInfo {
+  int globalOperatingClass;
+  int channelCfi;
+  int maxEirpDbm;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
new file mode 100644
index 0000000..cbea5af
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable AvailableAfcFrequencyInfo {
+  int startFrequencyMhz;
+  int endFrequencyMhz;
+  int maxPsd;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifi.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifi.aidl
new file mode 100644
index 0000000..cc995fc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifi.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifi {
+  @PropagateAllowBlocking android.hardware.wifi.IWifiChip getChip(int chipId);
+  int[] getChipIds();
+  boolean isStarted();
+  void registerEventCallback(in android.hardware.wifi.IWifiEventCallback callback);
+  void start();
+  void stop();
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
new file mode 100644
index 0000000..e71dde4
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiApIface {
+  String getName();
+  String[] getBridgedInstances();
+  byte[6] getFactoryMacAddress();
+  void setCountryCode(in byte[2] code);
+  void resetToFactoryMacAddress();
+  void setMacAddress(in byte[6] mac);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
new file mode 100644
index 0000000..4ea2081
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiChip {
+  void configureChip(in int modeId);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createApIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createBridgedApIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiNanIface createNanIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiP2pIface createP2pIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiRttController createRttController(in android.hardware.wifi.IWifiStaIface boundIface);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiStaIface createStaIface();
+  void enableDebugErrorAlerts(in boolean enable);
+  void flushRingBufferToFile();
+  void forceDumpToDebugRingBuffer(in String ringName);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface getApIface(in String ifname);
+  String[] getApIfaceNames();
+  android.hardware.wifi.IWifiChip.ChipMode[] getAvailableModes();
+  int getFeatureSet();
+  android.hardware.wifi.WifiDebugHostWakeReasonStats getDebugHostWakeReasonStats();
+  android.hardware.wifi.WifiDebugRingBufferStatus[] getDebugRingBuffersStatus();
+  int getId();
+  int getMode();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiNanIface getNanIface(in String ifname);
+  String[] getNanIfaceNames();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiP2pIface getP2pIface(in String ifname);
+  String[] getP2pIfaceNames();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiStaIface getStaIface(in String ifname);
+  String[] getStaIfaceNames();
+  android.hardware.wifi.WifiRadioCombination[] getSupportedRadioCombinations();
+  android.hardware.wifi.WifiChipCapabilities getWifiChipCapabilities();
+  android.hardware.wifi.WifiUsableChannel[] getUsableChannels(in android.hardware.wifi.WifiBand band, in int ifaceModeMask, in int filterMask);
+  void setAfcChannelAllowance(in android.hardware.wifi.AfcChannelAllowance afcChannelAllowance);
+  void registerEventCallback(in android.hardware.wifi.IWifiChipEventCallback callback);
+  void removeApIface(in String ifname);
+  void removeIfaceInstanceFromBridgedApIface(in String brIfaceName, in String ifaceInstanceName);
+  void removeNanIface(in String ifname);
+  void removeP2pIface(in String ifname);
+  void removeStaIface(in String ifname);
+  android.hardware.wifi.IWifiChip.ChipDebugInfo requestChipDebugInfo();
+  byte[] requestDriverDebugDump();
+  byte[] requestFirmwareDebugDump();
+  void resetTxPowerScenario();
+  void selectTxPowerScenario(in android.hardware.wifi.IWifiChip.TxPowerScenario scenario);
+  void setCoexUnsafeChannels(in android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] unsafeChannels, in int restrictions);
+  void setCountryCode(in byte[2] code);
+  void setLatencyMode(in android.hardware.wifi.IWifiChip.LatencyMode mode);
+  void setMultiStaPrimaryConnection(in String ifName);
+  void setMultiStaUseCase(in android.hardware.wifi.IWifiChip.MultiStaUseCase useCase);
+  void startLoggingToDebugRingBuffer(in String ringName, in android.hardware.wifi.WifiDebugRingBufferVerboseLevel verboseLevel, in int maxIntervalInSec, in int minDataSizeInBytes);
+  void stopLoggingToDebugRingBuffer();
+  void triggerSubsystemRestart();
+  void enableStaChannelForPeerNetwork(in int channelCategoryEnableFlag);
+  void setMloMode(in android.hardware.wifi.IWifiChip.ChipMloMode mode);
+  const int NO_POWER_CAP_CONSTANT = 0x7FFFFFFF;
+  @Backing(type="int") @VintfStability
+  enum FeatureSetMask {
+    SET_TX_POWER_LIMIT = (1 << 0) /* 1 */,
+    D2D_RTT = (1 << 1) /* 2 */,
+    D2AP_RTT = (1 << 2) /* 4 */,
+    USE_BODY_HEAD_SAR = (1 << 3) /* 8 */,
+    SET_LATENCY_MODE = (1 << 4) /* 16 */,
+    P2P_RAND_MAC = (1 << 5) /* 32 */,
+    WIGIG = (1 << 6) /* 64 */,
+    SET_AFC_CHANNEL_ALLOWANCE = (1 << 7) /* 128 */,
+    T2LM_NEGOTIATION = (1 << 8) /* 256 */,
+  }
+  @VintfStability
+  parcelable ChipConcurrencyCombinationLimit {
+    android.hardware.wifi.IfaceConcurrencyType[] types;
+    int maxIfaces;
+  }
+  @VintfStability
+  parcelable ChipConcurrencyCombination {
+    android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit[] limits;
+  }
+  @VintfStability
+  parcelable ChipDebugInfo {
+    String driverDescription;
+    String firmwareDescription;
+  }
+  @VintfStability
+  parcelable ChipIfaceCombinationLimit {
+    android.hardware.wifi.IfaceType[] types;
+    int maxIfaces;
+  }
+  @VintfStability
+  parcelable ChipIfaceCombination {
+    android.hardware.wifi.IWifiChip.ChipIfaceCombinationLimit[] limits;
+  }
+  @VintfStability
+  parcelable ChipMode {
+    int id;
+    android.hardware.wifi.IWifiChip.ChipConcurrencyCombination[] availableCombinations;
+  }
+  @Backing(type="int") @VintfStability
+  enum CoexRestriction {
+    WIFI_DIRECT = (1 << 0) /* 1 */,
+    SOFTAP = (1 << 1) /* 2 */,
+    WIFI_AWARE = (1 << 2) /* 4 */,
+  }
+  @VintfStability
+  parcelable CoexUnsafeChannel {
+    android.hardware.wifi.WifiBand band;
+    int channel;
+    int powerCapDbm;
+  }
+  @Backing(type="int") @VintfStability
+  enum LatencyMode {
+    NORMAL = 0,
+    LOW = 1,
+  }
+  @Backing(type="byte") @VintfStability
+  enum MultiStaUseCase {
+    DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
+    DUAL_STA_NON_TRANSIENT_UNBIASED = 1,
+  }
+  @Backing(type="int") @VintfStability
+  enum TxPowerScenario {
+    VOICE_CALL = 0,
+    ON_HEAD_CELL_OFF = 1,
+    ON_HEAD_CELL_ON = 2,
+    ON_BODY_CELL_OFF = 3,
+    ON_BODY_CELL_ON = 4,
+  }
+  @Backing(type="int") @VintfStability
+  enum UsableChannelFilter {
+    CELLULAR_COEXISTENCE = (1 << 0) /* 1 */,
+    CONCURRENCY = (1 << 1) /* 2 */,
+    NAN_INSTANT_MODE = (1 << 2) /* 4 */,
+  }
+  @Backing(type="int") @VintfStability
+  enum ChannelCategoryMask {
+    INDOOR_CHANNEL = (1 << 0) /* 1 */,
+    DFS_CHANNEL = (1 << 1) /* 2 */,
+  }
+  @Backing(type="int") @VintfStability
+  enum ChipMloMode {
+    DEFAULT = 0,
+    LOW_LATENCY = 1,
+    HIGH_THROUGHPUT = 2,
+    LOW_POWER = 3,
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChipEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChipEventCallback.aidl
new file mode 100644
index 0000000..3fd8533
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChipEventCallback.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiChipEventCallback {
+  oneway void onChipReconfigureFailure(in android.hardware.wifi.WifiStatusCode status);
+  oneway void onChipReconfigured(in int modeId);
+  oneway void onDebugErrorAlert(in int errorCode, in byte[] debugData);
+  oneway void onDebugRingBufferDataAvailable(in android.hardware.wifi.WifiDebugRingBufferStatus status, in byte[] data);
+  oneway void onIfaceAdded(in android.hardware.wifi.IfaceType type, in String name);
+  oneway void onIfaceRemoved(in android.hardware.wifi.IfaceType type, in String name);
+  oneway void onRadioModeChange(in android.hardware.wifi.IWifiChipEventCallback.RadioModeInfo[] radioModeInfos);
+  @VintfStability
+  parcelable IfaceInfo {
+    String name;
+    int channel;
+  }
+  @VintfStability
+  parcelable RadioModeInfo {
+    int radioId;
+    android.hardware.wifi.WifiBand bandInfo;
+    android.hardware.wifi.IWifiChipEventCallback.IfaceInfo[] ifaceInfos;
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiEventCallback.aidl
new file mode 100644
index 0000000..00e5cb6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiEventCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiEventCallback {
+  oneway void onFailure(in android.hardware.wifi.WifiStatusCode status);
+  oneway void onStart();
+  oneway void onStop();
+  oneway void onSubsystemRestart(in android.hardware.wifi.WifiStatusCode status);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl
new file mode 100644
index 0000000..0e2f90f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiNanIface {
+  String getName();
+  void configRequest(in char cmdId, in android.hardware.wifi.NanConfigRequest msg1, in android.hardware.wifi.NanConfigRequestSupplemental msg2);
+  void createDataInterfaceRequest(in char cmdId, in String ifaceName);
+  void deleteDataInterfaceRequest(in char cmdId, in String ifaceName);
+  void disableRequest(in char cmdId);
+  void enableRequest(in char cmdId, in android.hardware.wifi.NanEnableRequest msg1, in android.hardware.wifi.NanConfigRequestSupplemental msg2);
+  void getCapabilitiesRequest(in char cmdId);
+  void initiateDataPathRequest(in char cmdId, in android.hardware.wifi.NanInitiateDataPathRequest msg);
+  void registerEventCallback(in android.hardware.wifi.IWifiNanIfaceEventCallback callback);
+  void respondToDataPathIndicationRequest(in char cmdId, in android.hardware.wifi.NanRespondToDataPathIndicationRequest msg);
+  void startPublishRequest(in char cmdId, in android.hardware.wifi.NanPublishRequest msg);
+  void startSubscribeRequest(in char cmdId, in android.hardware.wifi.NanSubscribeRequest msg);
+  void stopPublishRequest(in char cmdId, in byte sessionId);
+  void stopSubscribeRequest(in char cmdId, in byte sessionId);
+  void terminateDataPathRequest(in char cmdId, in int ndpInstanceId);
+  void suspendRequest(in char cmdId, in byte sessionId);
+  void resumeRequest(in char cmdId, in byte sessionId);
+  void transmitFollowupRequest(in char cmdId, in android.hardware.wifi.NanTransmitFollowupRequest msg);
+  void initiatePairingRequest(in char cmdId, in android.hardware.wifi.NanPairingRequest msg);
+  void respondToPairingIndicationRequest(in char cmdId, in android.hardware.wifi.NanRespondToPairingIndicationRequest msg);
+  void initiateBootstrappingRequest(in char cmdId, in android.hardware.wifi.NanBootstrappingRequest msg);
+  void respondToBootstrappingIndicationRequest(in char cmdId, in android.hardware.wifi.NanBootstrappingResponse msg);
+  void terminatePairingRequest(in char cmdId, in int pairingInstanceId);
+  const int MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 8;
+  const int MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 63;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
new file mode 100644
index 0000000..8c44330
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiNanIfaceEventCallback {
+  oneway void eventClusterEvent(in android.hardware.wifi.NanClusterEventInd event);
+  oneway void eventDataPathConfirm(in android.hardware.wifi.NanDataPathConfirmInd event);
+  oneway void eventDataPathRequest(in android.hardware.wifi.NanDataPathRequestInd event);
+  oneway void eventDataPathScheduleUpdate(in android.hardware.wifi.NanDataPathScheduleUpdateInd event);
+  oneway void eventDataPathTerminated(in int ndpInstanceId);
+  oneway void eventDisabled(in android.hardware.wifi.NanStatus status);
+  oneway void eventFollowupReceived(in android.hardware.wifi.NanFollowupReceivedInd event);
+  oneway void eventMatch(in android.hardware.wifi.NanMatchInd event);
+  oneway void eventMatchExpired(in byte discoverySessionId, in int peerId);
+  oneway void eventPublishTerminated(in byte sessionId, in android.hardware.wifi.NanStatus status);
+  oneway void eventSubscribeTerminated(in byte sessionId, in android.hardware.wifi.NanStatus status);
+  oneway void eventTransmitFollowup(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void eventSuspensionModeChanged(in android.hardware.wifi.NanSuspensionModeChangeInd event);
+  oneway void notifyCapabilitiesResponse(in char id, in android.hardware.wifi.NanStatus status, in android.hardware.wifi.NanCapabilities capabilities);
+  oneway void notifyConfigResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyCreateDataInterfaceResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyDeleteDataInterfaceResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyDisableResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyEnableResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyInitiateDataPathResponse(in char id, in android.hardware.wifi.NanStatus status, in int ndpInstanceId);
+  oneway void notifyRespondToDataPathIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyStartPublishResponse(in char id, in android.hardware.wifi.NanStatus status, in byte sessionId);
+  oneway void notifyStartSubscribeResponse(in char id, in android.hardware.wifi.NanStatus status, in byte sessionId);
+  oneway void notifyStopPublishResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyStopSubscribeResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyTerminateDataPathResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifySuspendResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyResumeResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyTransmitFollowupResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void eventPairingRequest(in android.hardware.wifi.NanPairingRequestInd event);
+  oneway void eventPairingConfirm(in android.hardware.wifi.NanPairingConfirmInd event);
+  oneway void notifyInitiatePairingResponse(in char id, in android.hardware.wifi.NanStatus status, in int pairingInstanceId);
+  oneway void notifyRespondToPairingIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void eventBootstrappingRequest(in android.hardware.wifi.NanBootstrappingRequestInd event);
+  oneway void eventBootstrappingConfirm(in android.hardware.wifi.NanBootstrappingConfirmInd event);
+  oneway void notifyInitiateBootstrappingResponse(in char id, in android.hardware.wifi.NanStatus status, in int bootstrappingInstanceId);
+  oneway void notifyRespondToBootstrappingIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyTerminatePairingResponse(in char id, in android.hardware.wifi.NanStatus status);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiP2pIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiP2pIface.aidl
new file mode 100644
index 0000000..5e9948e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiP2pIface.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiP2pIface {
+  String getName();
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttController.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttController.aidl
new file mode 100644
index 0000000..730a055
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttController.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiRttController {
+  void disableResponder(in int cmdId);
+  void enableResponder(in int cmdId, in android.hardware.wifi.WifiChannelInfo channelHint, in int maxDurationInSeconds, in android.hardware.wifi.RttResponder info);
+  android.hardware.wifi.IWifiStaIface getBoundIface();
+  android.hardware.wifi.RttCapabilities getCapabilities();
+  android.hardware.wifi.RttResponder getResponderInfo();
+  void rangeCancel(in int cmdId, in android.hardware.wifi.MacAddress[] addrs);
+  void rangeRequest(in int cmdId, in android.hardware.wifi.RttConfig[] rttConfigs);
+  void registerEventCallback(in android.hardware.wifi.IWifiRttControllerEventCallback callback);
+  void setLci(in int cmdId, in android.hardware.wifi.RttLciInformation lci);
+  void setLcr(in int cmdId, in android.hardware.wifi.RttLcrInformation lcr);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttControllerEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
new file mode 100644
index 0000000..a6a33fc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiRttControllerEventCallback {
+  oneway void onResults(in int cmdId, in android.hardware.wifi.RttResult[] results);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
new file mode 100644
index 0000000..923deff
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiStaIface {
+  String getName();
+  void configureRoaming(in android.hardware.wifi.StaRoamingConfig config);
+  void disableLinkLayerStatsCollection();
+  void enableLinkLayerStatsCollection(in boolean debug);
+  void enableNdOffload(in boolean enable);
+  android.hardware.wifi.StaApfPacketFilterCapabilities getApfPacketFilterCapabilities();
+  android.hardware.wifi.StaBackgroundScanCapabilities getBackgroundScanCapabilities();
+  int getFeatureSet();
+  android.hardware.wifi.WifiDebugRxPacketFateReport[] getDebugRxPacketFates();
+  android.hardware.wifi.WifiDebugTxPacketFateReport[] getDebugTxPacketFates();
+  byte[6] getFactoryMacAddress();
+  android.hardware.wifi.StaLinkLayerStats getLinkLayerStats();
+  android.hardware.wifi.StaRoamingCapabilities getRoamingCapabilities();
+  void installApfPacketFilter(in byte[] program);
+  byte[] readApfPacketFilterData();
+  void registerEventCallback(in android.hardware.wifi.IWifiStaIfaceEventCallback callback);
+  void setMacAddress(in byte[6] mac);
+  void setRoamingState(in android.hardware.wifi.StaRoamingState state);
+  void setScanMode(in boolean enable);
+  void startBackgroundScan(in int cmdId, in android.hardware.wifi.StaBackgroundScanParameters params);
+  void startDebugPacketFateMonitoring();
+  void startRssiMonitoring(in int cmdId, in int maxRssi, in int minRssi);
+  void startSendingKeepAlivePackets(in int cmdId, in byte[] ipPacketData, in char etherType, in byte[6] srcAddress, in byte[6] dstAddress, in int periodInMs);
+  void stopBackgroundScan(in int cmdId);
+  void stopRssiMonitoring(in int cmdId);
+  void stopSendingKeepAlivePackets(in int cmdId);
+  void setDtimMultiplier(in int multiplier);
+  @Backing(type="int") @VintfStability
+  enum FeatureSetMask {
+    APF = (1 << 0) /* 1 */,
+    BACKGROUND_SCAN = (1 << 1) /* 2 */,
+    LINK_LAYER_STATS = (1 << 2) /* 4 */,
+    RSSI_MONITOR = (1 << 3) /* 8 */,
+    CONTROL_ROAMING = (1 << 4) /* 16 */,
+    PROBE_IE_ALLOWLIST = (1 << 5) /* 32 */,
+    SCAN_RAND = (1 << 6) /* 64 */,
+    STA_5G = (1 << 7) /* 128 */,
+    HOTSPOT = (1 << 8) /* 256 */,
+    PNO = (1 << 9) /* 512 */,
+    TDLS = (1 << 10) /* 1024 */,
+    TDLS_OFFCHANNEL = (1 << 11) /* 2048 */,
+    ND_OFFLOAD = (1 << 12) /* 4096 */,
+    KEEP_ALIVE = (1 << 13) /* 8192 */,
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
new file mode 100644
index 0000000..48b85b0
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiStaIfaceEventCallback {
+  oneway void onBackgroundFullScanResult(in int cmdId, in int bucketsScanned, in android.hardware.wifi.StaScanResult result);
+  oneway void onBackgroundScanFailure(in int cmdId);
+  oneway void onBackgroundScanResults(in int cmdId, in android.hardware.wifi.StaScanData[] scanDatas);
+  oneway void onRssiThresholdBreached(in int cmdId, in byte[6] currBssid, in int currRssi);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl
new file mode 100644
index 0000000..d584423
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum IfaceConcurrencyType {
+  STA,
+  AP,
+  AP_BRIDGED,
+  P2P,
+  NAN_IFACE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl
new file mode 100644
index 0000000..67022df
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum IfaceType {
+  STA,
+  AP,
+  P2P,
+  NAN_IFACE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/MacAddress.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/MacAddress.aidl
new file mode 100644
index 0000000..c4a0613
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/MacAddress.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable MacAddress {
+  byte[6] data;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl
new file mode 100644
index 0000000..3f1ea5e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanBandIndex {
+  NAN_BAND_24GHZ = 0,
+  NAN_BAND_5GHZ,
+  NAN_BAND_6GHZ = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandSpecificConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandSpecificConfig.aidl
new file mode 100644
index 0000000..57540b3
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandSpecificConfig.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBandSpecificConfig {
+  byte rssiClose;
+  byte rssiMiddle;
+  byte rssiCloseProximity;
+  char dwellTimeMs;
+  char scanPeriodSec;
+  boolean validDiscoveryWindowIntervalVal;
+  byte discoveryWindowIntervalVal;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
new file mode 100644
index 0000000..5ab8dcd
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingConfirmInd {
+  int bootstrappingInstanceId;
+  android.hardware.wifi.NanBootstrappingResponseCode responseCode;
+  android.hardware.wifi.NanStatus reasonCode;
+  int comeBackDelay;
+  byte[] cookie;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingMethod.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingMethod.aidl
new file mode 100644
index 0000000..6ff62b2
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingMethod.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanBootstrappingMethod {
+  BOOTSTRAPPING_OPPORTUNISTIC_MASK = (1 << 0) /* 1 */,
+  BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK = (1 << 1) /* 2 */,
+  BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK = (1 << 2) /* 4 */,
+  BOOTSTRAPPING_QR_DISPLAY_MASK = (1 << 3) /* 8 */,
+  BOOTSTRAPPING_NFC_TAG_MASK = (1 << 4) /* 16 */,
+  BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK = (1 << 5) /* 32 */,
+  BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK = (1 << 6) /* 64 */,
+  BOOTSTRAPPING_QR_SCAN_MASK = (1 << 7) /* 128 */,
+  BOOTSTRAPPING_NFC_READER_MASK = (1 << 8) /* 256 */,
+  BOOTSTRAPPING_SERVICE_MANAGED_MASK = (1 << 14) /* 16384 */,
+  BOOTSTRAPPING_HANDSHAKE_SHIP_MASK = (1 << 15) /* 32768 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
new file mode 100644
index 0000000..dd0a5ed
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingRequest {
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  android.hardware.wifi.NanBootstrappingMethod requestBootstrappingMethod;
+  byte[] cookie;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequestInd.aidl
new file mode 100644
index 0000000..a4398e9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequestInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingRequestInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  int bootstrappingInstanceId;
+  android.hardware.wifi.NanBootstrappingMethod requestBootstrappingMethod;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
new file mode 100644
index 0000000..6dd9b26
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingResponse {
+  int bootstrappingInstanceId;
+  boolean acceptRequest;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponseCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponseCode.aidl
new file mode 100644
index 0000000..a3e9e4d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponseCode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanBootstrappingResponseCode {
+  NAN_BOOTSTRAPPING_REQUEST_ACCEPT = 0,
+  NAN_BOOTSTRAPPING_REQUEST_REJECT,
+  NAN_BOOTSTRAPPING_REQUEST_COMEBACK,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
new file mode 100644
index 0000000..a30893a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanCapabilities {
+  int maxConcurrentClusters;
+  int maxPublishes;
+  int maxSubscribes;
+  int maxServiceNameLen;
+  int maxMatchFilterLen;
+  int maxTotalMatchFilterLen;
+  int maxServiceSpecificInfoLen;
+  int maxExtendedServiceSpecificInfoLen;
+  int maxNdiInterfaces;
+  int maxNdpSessions;
+  int maxAppInfoLen;
+  int maxQueuedTransmitFollowupMsgs;
+  int maxSubscribeInterfaceAddresses;
+  int supportedCipherSuites;
+  boolean instantCommunicationModeSupportFlag;
+  boolean supports6g;
+  boolean supportsHe;
+  boolean supportsPairing;
+  boolean supportsSetClusterId;
+  boolean supportsSuspension;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl
new file mode 100644
index 0000000..6f3158e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanCipherSuiteType {
+  NONE = 0,
+  SHARED_KEY_128_MASK = (1 << 0) /* 1 */,
+  SHARED_KEY_256_MASK = (1 << 1) /* 2 */,
+  PUBLIC_KEY_2WDH_128_MASK = (1 << 2) /* 4 */,
+  PUBLIC_KEY_2WDH_256_MASK = (1 << 3) /* 8 */,
+  PUBLIC_KEY_PASN_128_MASK = (1 << 6) /* 64 */,
+  PUBLIC_KEY_PASN_256_MASK = (1 << 7) /* 128 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventInd.aidl
new file mode 100644
index 0000000..7a3ff81
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventInd.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanClusterEventInd {
+  android.hardware.wifi.NanClusterEventType eventType;
+  byte[6] addr;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl
new file mode 100644
index 0000000..6c20543
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanClusterEventType {
+  DISCOVERY_MAC_ADDRESS_CHANGED = 0,
+  STARTED_CLUSTER,
+  JOINED_CLUSTER,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
new file mode 100644
index 0000000..5ead651
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanConfigRequest {
+  byte masterPref;
+  boolean disableDiscoveryAddressChangeIndication;
+  boolean disableStartedClusterIndication;
+  boolean disableJoinedClusterIndication;
+  boolean includePublishServiceIdsInBeacon;
+  byte numberOfPublishServiceIdsInBeacon;
+  boolean includeSubscribeServiceIdsInBeacon;
+  byte numberOfSubscribeServiceIdsInBeacon;
+  char rssiWindowSize;
+  int macAddressRandomizationIntervalSec;
+  android.hardware.wifi.NanBandSpecificConfig[3] bandSpecificConfig;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl
new file mode 100644
index 0000000..99f2af7
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanConfigRequestSupplemental {
+  int discoveryBeaconIntervalMs;
+  int numberOfSpatialStreamsInDiscovery;
+  boolean enableDiscoveryWindowEarlyTermination;
+  boolean enableRanging;
+  boolean enableInstantCommunicationMode;
+  int instantModeChannel;
+  int clusterId;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl
new file mode 100644
index 0000000..4233c32
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanDataPathChannelCfg {
+  CHANNEL_NOT_REQUESTED = 0,
+  REQUEST_CHANNEL_SETUP,
+  FORCE_CHANNEL_SETUP,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelInfo.aidl
new file mode 100644
index 0000000..d111db7
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathChannelInfo {
+  int channelFreq;
+  android.hardware.wifi.WifiChannelWidthInMhz channelBandwidth;
+  int numSpatialStreams;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathConfirmInd.aidl
new file mode 100644
index 0000000..2e1e2ca
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathConfirmInd.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathConfirmInd {
+  int ndpInstanceId;
+  boolean dataPathSetupSuccess;
+  byte[6] peerNdiMacAddr;
+  byte[] appInfo;
+  android.hardware.wifi.NanStatus status;
+  android.hardware.wifi.NanDataPathChannelInfo[] channelInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathRequestInd.aidl
new file mode 100644
index 0000000..74d5b73
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathRequestInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathRequestInd {
+  byte discoverySessionId;
+  byte[6] peerDiscMacAddr;
+  int ndpInstanceId;
+  boolean securityRequired;
+  byte[] appInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
new file mode 100644
index 0000000..5fabf55
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathScheduleUpdateInd {
+  byte[6] peerDiscoveryAddress;
+  android.hardware.wifi.NanDataPathChannelInfo[] channelInfo;
+  int[] ndpInstanceIds;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
new file mode 100644
index 0000000..635dbce
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathSecurityConfig {
+  android.hardware.wifi.NanDataPathSecurityType securityType;
+  android.hardware.wifi.NanCipherSuiteType cipherType;
+  byte[32] pmk;
+  byte[] passphrase;
+  byte[16] scid;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl
new file mode 100644
index 0000000..cb7904d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanDataPathSecurityType {
+  OPEN,
+  PMK,
+  PASSPHRASE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDebugConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDebugConfig.aidl
new file mode 100644
index 0000000..b84d891
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDebugConfig.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDebugConfig {
+  boolean validClusterIdVals;
+  char clusterIdBottomRangeVal;
+  char clusterIdTopRangeVal;
+  boolean validIntfAddrVal;
+  byte[6] intfAddrVal;
+  boolean validOuiVal;
+  int ouiVal;
+  boolean validRandomFactorForceVal;
+  byte randomFactorForceVal;
+  boolean validHopCountForceVal;
+  byte hopCountForceVal;
+  boolean validDiscoveryChannelVal;
+  int[3] discoveryChannelMhzVal;
+  boolean validUseBeaconsInBandVal;
+  boolean[3] useBeaconsInBandVal;
+  boolean validUseSdfInBandVal;
+  boolean[3] useSdfInBandVal;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
new file mode 100644
index 0000000..96d940a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDiscoveryCommonConfig {
+  byte sessionId;
+  char ttlSec;
+  char discoveryWindowPeriod;
+  byte discoveryCount;
+  byte[] serviceName;
+  android.hardware.wifi.NanMatchAlg discoveryMatchIndicator;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+  byte[] rxMatchFilter;
+  byte[] txMatchFilter;
+  boolean useRssiThreshold;
+  boolean disableDiscoveryTerminationIndication;
+  boolean disableMatchExpirationIndication;
+  boolean disableFollowupReceivedIndication;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  boolean rangingRequired;
+  int rangingIntervalMs;
+  int configRangingIndications;
+  char distanceIngressCm;
+  char distanceEgressCm;
+  boolean enableSessionSuspendability;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanEnableRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanEnableRequest.aidl
new file mode 100644
index 0000000..eaa009c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanEnableRequest.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanEnableRequest {
+  boolean[3] operateInBand;
+  byte hopCountMax;
+  android.hardware.wifi.NanConfigRequest configParams;
+  android.hardware.wifi.NanDebugConfig debugConfigs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanFollowupReceivedInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanFollowupReceivedInd.aidl
new file mode 100644
index 0000000..743ad9d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanFollowupReceivedInd.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanFollowupReceivedInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] addr;
+  boolean receivedInFaw;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanIdentityResolutionAttribute.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
new file mode 100644
index 0000000..843107e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanIdentityResolutionAttribute {
+  byte[8] nonce;
+  byte[8] tag;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl
new file mode 100644
index 0000000..740a140
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanInitiateDataPathRequest {
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  android.hardware.wifi.NanDataPathChannelCfg channelRequestType;
+  int channel;
+  String ifaceName;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  byte[] appInfo;
+  byte[] serviceNameOutOfBand;
+  byte discoverySessionId;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl
new file mode 100644
index 0000000..93ac26b
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanMatchAlg {
+  MATCH_ONCE = 0,
+  MATCH_CONTINUOUS,
+  MATCH_NEVER,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
new file mode 100644
index 0000000..317489f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanMatchInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] addr;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+  byte[] matchFilter;
+  boolean matchOccurredInBeaconFlag;
+  boolean outOfResourceFlag;
+  byte rssiValue;
+  android.hardware.wifi.NanCipherSuiteType peerCipherType;
+  boolean peerRequiresSecurityEnabledInNdp;
+  boolean peerRequiresRanging;
+  int rangingMeasurementInMm;
+  int rangingIndicationType;
+  byte[] scid;
+  android.hardware.wifi.NanPairingConfig peerPairingConfig;
+  android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingAkm.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingAkm.aidl
new file mode 100644
index 0000000..05bbaee
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingAkm.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPairingAkm {
+  SAE = 0,
+  PASN = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfig.aidl
new file mode 100644
index 0000000..1c04a96
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingConfig {
+  boolean enablePairingSetup;
+  boolean enablePairingCache;
+  boolean enablePairingVerification;
+  int supportedBootstrappingMethods;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl
new file mode 100644
index 0000000..8ecf22a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingConfirmInd {
+  int pairingInstanceId;
+  boolean pairingSuccess;
+  android.hardware.wifi.NanStatus status;
+  android.hardware.wifi.NanPairingRequestType requestType;
+  boolean enablePairingCache;
+  android.hardware.wifi.NpkSecurityAssociation npksa;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl
new file mode 100644
index 0000000..2a644ae
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingRequest {
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  android.hardware.wifi.NanPairingRequestType requestType;
+  boolean enablePairingCache;
+  byte[16] pairingIdentityKey;
+  android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl
new file mode 100644
index 0000000..66762b9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingRequestInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  int pairingInstanceId;
+  android.hardware.wifi.NanPairingRequestType requestType;
+  boolean enablePairingCache;
+  android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestType.aidl
new file mode 100644
index 0000000..3488340
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPairingRequestType {
+  NAN_PAIRING_SETUP = 0,
+  NAN_PAIRING_VERIFICATION,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityConfig.aidl
new file mode 100644
index 0000000..1a6a13c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingSecurityConfig {
+  android.hardware.wifi.NanPairingSecurityType securityType;
+  byte[32] pmk;
+  byte[] passphrase;
+  android.hardware.wifi.NanPairingAkm akm;
+  android.hardware.wifi.NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityType.aidl
new file mode 100644
index 0000000..9f6c774
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPairingSecurityType {
+  OPPORTUNISTIC,
+  PMK,
+  PASSPHRASE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
new file mode 100644
index 0000000..c49f5f9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPublishRequest {
+  android.hardware.wifi.NanDiscoveryCommonConfig baseConfigs;
+  android.hardware.wifi.NanPublishType publishType;
+  android.hardware.wifi.NanTxType txType;
+  boolean autoAcceptDataPathRequests;
+  android.hardware.wifi.NanPairingConfig pairingConfig;
+  byte[16] identityKey;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl
new file mode 100644
index 0000000..30dffb2
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPublishType {
+  UNSOLICITED = 0,
+  SOLICITED,
+  UNSOLICITED_SOLICITED,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl
new file mode 100644
index 0000000..cf72dce
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanRangingIndication {
+  CONTINUOUS_INDICATION_MASK = (1 << 0) /* 1 */,
+  INGRESS_MET_MASK = (1 << 1) /* 2 */,
+  EGRESS_MET_MASK = (1 << 2) /* 4 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
new file mode 100644
index 0000000..0f873b5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanRespondToDataPathIndicationRequest {
+  boolean acceptRequest;
+  int ndpInstanceId;
+  String ifaceName;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  byte[] appInfo;
+  byte[] serviceNameOutOfBand;
+  byte discoverySessionId;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
new file mode 100644
index 0000000..a58890c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanRespondToPairingIndicationRequest {
+  boolean acceptRequest;
+  int pairingInstanceId;
+  android.hardware.wifi.NanPairingRequestType requestType;
+  boolean enablePairingCache;
+  byte[16] pairingIdentityKey;
+  android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl
new file mode 100644
index 0000000..82409fd
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanSrfType {
+  BLOOM_FILTER = 0,
+  PARTIAL_MAC_ADDR,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatus.aidl
new file mode 100644
index 0000000..834558a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanStatus {
+  android.hardware.wifi.NanStatusCode status;
+  String description;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl
new file mode 100644
index 0000000..ec12eb0
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanStatusCode {
+  SUCCESS = 0,
+  INTERNAL_FAILURE = 1,
+  PROTOCOL_FAILURE = 2,
+  INVALID_SESSION_ID = 3,
+  NO_RESOURCES_AVAILABLE = 4,
+  INVALID_ARGS = 5,
+  INVALID_PEER_ID = 6,
+  INVALID_NDP_ID = 7,
+  NAN_NOT_ALLOWED = 8,
+  NO_OTA_ACK = 9,
+  ALREADY_ENABLED = 10,
+  FOLLOWUP_TX_QUEUE_FULL = 11,
+  UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12,
+  INVALID_PAIRING_ID = 13,
+  INVALID_BOOTSTRAPPING_ID = 14,
+  REDUNDANT_REQUEST = 15,
+  NOT_SUPPORTED = 16,
+  NO_CONNECTION = 17,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
new file mode 100644
index 0000000..96be096
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanSubscribeRequest {
+  android.hardware.wifi.NanDiscoveryCommonConfig baseConfigs;
+  android.hardware.wifi.NanSubscribeType subscribeType;
+  android.hardware.wifi.NanSrfType srfType;
+  boolean srfRespondIfInAddressSet;
+  boolean shouldUseSrf;
+  boolean isSsiRequiredForMatch;
+  android.hardware.wifi.MacAddress[] intfAddr;
+  android.hardware.wifi.NanPairingConfig pairingConfig;
+  byte[16] identityKey;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl
new file mode 100644
index 0000000..4f06df9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanSubscribeType {
+  PASSIVE = 0,
+  ACTIVE,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSuspensionModeChangeInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSuspensionModeChangeInd.aidl
new file mode 100644
index 0000000..557fc79
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSuspensionModeChangeInd.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanSuspensionModeChangeInd {
+  boolean isSuspended;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTransmitFollowupRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTransmitFollowupRequest.aidl
new file mode 100644
index 0000000..20c94d9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTransmitFollowupRequest.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanTransmitFollowupRequest {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] addr;
+  boolean isHighPriority;
+  boolean shouldUseDiscoveryWindow;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+  boolean disableFollowupResultIndication;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl
new file mode 100644
index 0000000..798d3a2
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanTxType {
+  BROADCAST = 0,
+  UNICAST,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NpkSecurityAssociation.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NpkSecurityAssociation.aidl
new file mode 100644
index 0000000..508e920
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NpkSecurityAssociation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NpkSecurityAssociation {
+  byte[16] peerNanIdentityKey;
+  byte[16] localNanIdentityKey;
+  byte[32] npk;
+  android.hardware.wifi.NanPairingAkm akm;
+  android.hardware.wifi.NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl
new file mode 100644
index 0000000..7cc7002
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttBw {
+  BW_UNSPECIFIED = 0x0,
+  BW_5MHZ = 0x01,
+  BW_10MHZ = 0x02,
+  BW_20MHZ = 0x04,
+  BW_40MHZ = 0x08,
+  BW_80MHZ = 0x10,
+  BW_160MHZ = 0x20,
+  BW_320MHZ = 0x40,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
new file mode 100644
index 0000000..cf64687
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttCapabilities {
+  boolean rttOneSidedSupported;
+  boolean rttFtmSupported;
+  boolean lciSupported;
+  boolean lcrSupported;
+  boolean responderSupported;
+  android.hardware.wifi.RttPreamble preambleSupport;
+  android.hardware.wifi.RttBw bwSupport;
+  byte mcVersion;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
new file mode 100644
index 0000000..ccdf2ce
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttConfig {
+  byte[6] addr;
+  android.hardware.wifi.RttType type;
+  android.hardware.wifi.RttPeerType peer;
+  android.hardware.wifi.WifiChannelInfo channel;
+  int burstPeriod;
+  int numBurst;
+  int numFramesPerBurst;
+  int numRetriesPerRttFrame;
+  int numRetriesPerFtmr;
+  boolean mustRequestLci;
+  boolean mustRequestLcr;
+  int burstDuration;
+  android.hardware.wifi.RttPreamble preamble;
+  android.hardware.wifi.RttBw bw;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLciInformation.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLciInformation.aidl
new file mode 100644
index 0000000..0fcf151
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLciInformation.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttLciInformation {
+  long latitude;
+  long longitude;
+  int altitude;
+  byte latitudeUnc;
+  byte longitudeUnc;
+  byte altitudeUnc;
+  android.hardware.wifi.RttMotionPattern motionPattern;
+  int floor;
+  int heightAboveFloor;
+  int heightUnc;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLcrInformation.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLcrInformation.aidl
new file mode 100644
index 0000000..c756dda
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLcrInformation.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttLcrInformation {
+  byte[2] countryCode;
+  String civicInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttMotionPattern.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttMotionPattern.aidl
new file mode 100644
index 0000000..7c8e369
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttMotionPattern.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttMotionPattern {
+  NOT_EXPECTED = 0,
+  EXPECTED = 1,
+  UNKNOWN = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPeerType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPeerType.aidl
new file mode 100644
index 0000000..23fa7f6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPeerType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttPeerType {
+  AP = 1,
+  STA = 2,
+  P2P_GO = 3,
+  P2P_CLIENT = 4,
+  NAN_TYPE = 5,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
new file mode 100644
index 0000000..de26f28
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttPreamble {
+  LEGACY = 0x1,
+  HT = 0x2,
+  VHT = 0x4,
+  HE = 0x8,
+  EHT = 0x10,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResponder.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResponder.aidl
new file mode 100644
index 0000000..41463b5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResponder.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttResponder {
+  android.hardware.wifi.WifiChannelInfo channel;
+  android.hardware.wifi.RttPreamble preamble;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
new file mode 100644
index 0000000..8375dcb
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttResult {
+  byte[6] addr;
+  int burstNum;
+  int measurementNumber;
+  int successNumber;
+  byte numberPerBurstPeer;
+  android.hardware.wifi.RttStatus status;
+  byte retryAfterDuration;
+  android.hardware.wifi.RttType type;
+  int rssi;
+  int rssiSpread;
+  android.hardware.wifi.WifiRateInfo txRate;
+  android.hardware.wifi.WifiRateInfo rxRate;
+  long rtt;
+  long rttSd;
+  long rttSpread;
+  int distanceInMm;
+  int distanceSdInMm;
+  int distanceSpreadInMm;
+  long timeStampInUs;
+  int burstDurationInMs;
+  int negotiatedBurstNum;
+  android.hardware.wifi.WifiInformationElement lci;
+  android.hardware.wifi.WifiInformationElement lcr;
+  int channelFreqMHz;
+  android.hardware.wifi.RttBw packetBw;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl
new file mode 100644
index 0000000..2817497
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttStatus {
+  SUCCESS = 0,
+  FAILURE = 1,
+  FAIL_NO_RSP = 2,
+  FAIL_REJECTED = 3,
+  FAIL_NOT_SCHEDULED_YET = 4,
+  FAIL_TM_TIMEOUT = 5,
+  FAIL_AP_ON_DIFF_CHANNEL = 6,
+  FAIL_NO_CAPABILITY = 7,
+  ABORTED = 8,
+  FAIL_INVALID_TS = 9,
+  FAIL_PROTOCOL = 10,
+  FAIL_SCHEDULE = 11,
+  FAIL_BUSY_TRY_LATER = 12,
+  INVALID_REQ = 13,
+  NO_WIFI = 14,
+  FAIL_FTM_PARAM_OVERRIDE = 15,
+  NAN_RANGING_PROTOCOL_FAILURE = 16,
+  NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
new file mode 100644
index 0000000..2b6087a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttType {
+  ONE_SIDED = 1,
+  TWO_SIDED = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/Ssid.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/Ssid.aidl
new file mode 100644
index 0000000..98b523f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/Ssid.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable Ssid {
+  byte[32] data;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
new file mode 100644
index 0000000..3b4d785
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaApfPacketFilterCapabilities {
+  int version;
+  int maxLength;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
new file mode 100644
index 0000000..249d876
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum StaBackgroundScanBucketEventReportSchemeMask {
+  EACH_SCAN = (1 << 0) /* 1 */,
+  FULL_RESULTS = (1 << 1) /* 2 */,
+  NO_BATCH = (1 << 2) /* 4 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
new file mode 100644
index 0000000..4e9671a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaBackgroundScanBucketParameters {
+  int bucketIdx;
+  android.hardware.wifi.WifiBand band;
+  int[] frequencies;
+  int periodInMs;
+  int eventReportScheme;
+  int exponentialMaxPeriodInMs;
+  int exponentialBase;
+  int exponentialStepCount;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
new file mode 100644
index 0000000..758dd97
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaBackgroundScanCapabilities {
+  int maxCacheSize;
+  int maxBuckets;
+  int maxApCachePerScan;
+  int maxReportingThreshold;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanLimits.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanLimits.aidl
new file mode 100644
index 0000000..05d0277
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanLimits.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum StaBackgroundScanLimits {
+  MAX_CHANNELS = 16,
+  MAX_BUCKETS = 16,
+  MAX_AP_CACHE_PER_SCAN = 32,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanParameters.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanParameters.aidl
new file mode 100644
index 0000000..0773566
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanParameters.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaBackgroundScanParameters {
+  int basePeriodInMs;
+  int maxApPerScan;
+  int reportThresholdPercent;
+  int reportThresholdNumScans;
+  android.hardware.wifi.StaBackgroundScanBucketParameters[] buckets;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
new file mode 100644
index 0000000..4dee6de
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerIfaceContentionTimeStats {
+  int contentionTimeMinInUsec;
+  int contentionTimeMaxInUsec;
+  int contentionTimeAvgInUsec;
+  int contentionNumSamples;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
new file mode 100644
index 0000000..eddf52e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerIfacePacketStats {
+  long rxMpdu;
+  long txMpdu;
+  long lostMpdu;
+  long retries;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
new file mode 100644
index 0000000..a419207
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerIfaceStats {
+  android.hardware.wifi.StaLinkLayerLinkStats[] links;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl
new file mode 100644
index 0000000..cd21c25
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerLinkStats {
+  int linkId;
+  int radioId;
+  int frequencyMhz;
+  int beaconRx;
+  int avgRssiMgmt;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBePktStats;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBkPktStats;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeViPktStats;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeVoPktStats;
+  byte timeSliceDutyCycleInPercent;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+  android.hardware.wifi.StaPeerInfo[] peers;
+  android.hardware.wifi.StaLinkLayerLinkStats.StaLinkState state;
+  @Backing(type="int") @VintfStability
+  enum StaLinkState {
+    UNKNOWN = 0,
+    NOT_IN_USE = (1 << 0) /* 1 */,
+    IN_USE = (1 << 1) /* 2 */,
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerRadioStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerRadioStats.aidl
new file mode 100644
index 0000000..84d24c9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerRadioStats.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerRadioStats {
+  int onTimeInMs;
+  int txTimeInMs;
+  int[] txTimeInMsPerLevel;
+  int rxTimeInMs;
+  int onTimeInMsForScan;
+  int onTimeInMsForNanScan;
+  int onTimeInMsForBgScan;
+  int onTimeInMsForRoamScan;
+  int onTimeInMsForPnoScan;
+  int onTimeInMsForHs20Scan;
+  android.hardware.wifi.WifiChannelStats[] channelStats;
+  int radioId;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerStats.aidl
new file mode 100644
index 0000000..9c05346
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerStats.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerStats {
+  android.hardware.wifi.StaLinkLayerIfaceStats iface;
+  android.hardware.wifi.StaLinkLayerRadioStats[] radios;
+  long timeStampInMs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaPeerInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaPeerInfo.aidl
new file mode 100644
index 0000000..93a901f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaPeerInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaPeerInfo {
+  char staCount;
+  char chanUtil;
+  android.hardware.wifi.StaRateStat[] rateStats;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRateStat.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRateStat.aidl
new file mode 100644
index 0000000..43b69fc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRateStat.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaRateStat {
+  android.hardware.wifi.WifiRateInfo rateInfo;
+  int txMpdu;
+  int rxMpdu;
+  int mpduLost;
+  int retries;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingCapabilities.aidl
new file mode 100644
index 0000000..9eed877
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaRoamingCapabilities {
+  int maxBlocklistSize;
+  int maxAllowlistSize;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingConfig.aidl
new file mode 100644
index 0000000..2b37cee
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaRoamingConfig {
+  android.hardware.wifi.MacAddress[] bssidBlocklist;
+  android.hardware.wifi.Ssid[] ssidAllowlist;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
new file mode 100644
index 0000000..1f3d91f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="byte") @VintfStability
+enum StaRoamingState {
+  DISABLED = 0,
+  ENABLED = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl
new file mode 100644
index 0000000..7c75232
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaScanData {
+  int flags;
+  int bucketsScanned;
+  android.hardware.wifi.StaScanResult[] results;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl
new file mode 100644
index 0000000..0ca4b4b
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum StaScanDataFlagMask {
+  INTERRUPTED = (1 << 0) /* 1 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanResult.aidl
new file mode 100644
index 0000000..9a8d297
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanResult.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaScanResult {
+  long timeStampInUs;
+  byte[] ssid;
+  byte[6] bssid;
+  int rssi;
+  int frequency;
+  char beaconPeriodInMs;
+  char capability;
+  android.hardware.wifi.WifiInformationElement[] informationElements;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiAntennaMode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiAntennaMode.aidl
new file mode 100644
index 0000000..b47b7f5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiAntennaMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiAntennaMode {
+  WIFI_ANTENNA_MODE_UNSPECIFIED = 0,
+  WIFI_ANTENNA_MODE_1X1 = 1,
+  WIFI_ANTENNA_MODE_2X2 = 2,
+  WIFI_ANTENNA_MODE_3X3 = 3,
+  WIFI_ANTENNA_MODE_4X4 = 4,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiBand.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiBand.aidl
new file mode 100644
index 0000000..e9a87ee
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiBand.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiBand {
+  BAND_UNSPECIFIED = 0,
+  BAND_24GHZ = 1,
+  BAND_5GHZ = 2,
+  BAND_5GHZ_DFS = 4,
+  BAND_5GHZ_WITH_DFS = 6,
+  BAND_24GHZ_5GHZ = 3,
+  BAND_24GHZ_5GHZ_WITH_DFS = 7,
+  BAND_6GHZ = 8,
+  BAND_5GHZ_6GHZ = 10,
+  BAND_24GHZ_5GHZ_6GHZ = 11,
+  BAND_24GHZ_5GHZ_WITH_DFS_6GHZ = 15,
+  BAND_60GHZ = 16,
+  BAND_24GHZ_5GHZ_6GHZ_60GHZ = 27,
+  BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelInfo.aidl
new file mode 100644
index 0000000..297c923
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiChannelInfo {
+  android.hardware.wifi.WifiChannelWidthInMhz width;
+  int centerFreq;
+  int centerFreq0;
+  int centerFreq1;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelStats.aidl
new file mode 100644
index 0000000..c6e7acc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelStats.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiChannelStats {
+  android.hardware.wifi.WifiChannelInfo channel;
+  int onTimeInMs;
+  int ccaBusyTimeInMs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl
new file mode 100644
index 0000000..e6ea642
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiChannelWidthInMhz {
+  WIDTH_INVALID = (-1) /* -1 */,
+  WIDTH_20 = 0,
+  WIDTH_40 = 1,
+  WIDTH_80 = 2,
+  WIDTH_160 = 3,
+  WIDTH_80P80 = 4,
+  WIDTH_5 = 5,
+  WIDTH_10 = 6,
+  WIDTH_320 = 7,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChipCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChipCapabilities.aidl
new file mode 100644
index 0000000..b5034ea
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChipCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiChipCapabilities {
+  int maxMloAssociationLinkCount;
+  int maxMloStrLinkCount;
+  int maxConcurrentTdlsSessionCount;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
new file mode 100644
index 0000000..8415e09
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxIcmpPacketDetails {
+  int icmpPkt;
+  int icmp6Pkt;
+  int icmp6Ra;
+  int icmp6Na;
+  int icmp6Ns;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
new file mode 100644
index 0000000..30301d3
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxMulticastPacketDetails {
+  int ipv4RxMulticastAddrCnt;
+  int ipv6RxMulticastAddrCnt;
+  int otherRxMulticastAddrCnt;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
new file mode 100644
index 0000000..8118322
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxPacketDetails {
+  int rxUnicastCnt;
+  int rxMulticastCnt;
+  int rxBroadcastCnt;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
new file mode 100644
index 0000000..1766476
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonStats {
+  int totalCmdEventWakeCnt;
+  int[] cmdEventWakeCntPerType;
+  int totalDriverFwLocalWakeCnt;
+  int[] driverFwLocalWakeCntPerType;
+  int totalRxPacketWakeCnt;
+  android.hardware.wifi.WifiDebugHostWakeReasonRxPacketDetails rxPktWakeDetails;
+  android.hardware.wifi.WifiDebugHostWakeReasonRxMulticastPacketDetails rxMulticastPkWakeDetails;
+  android.hardware.wifi.WifiDebugHostWakeReasonRxIcmpPacketDetails rxIcmpPkWakeDetails;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
new file mode 100644
index 0000000..2ff6cfc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugPacketFateFrameInfo {
+  android.hardware.wifi.WifiDebugPacketFateFrameType frameType;
+  long frameLen;
+  long driverTimestampUsec;
+  long firmwareTimestampUsec;
+  byte[] frameContent;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
new file mode 100644
index 0000000..6db96ef
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugPacketFateFrameType {
+  UNKNOWN,
+  ETHERNET_II,
+  MGMT_80211,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
new file mode 100644
index 0000000..9ababc3
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugRingBufferFlags {
+  HAS_BINARY_ENTRIES = (1 << 0) /* 1 */,
+  HAS_ASCII_ENTRIES = (1 << 1) /* 2 */,
+  HAS_PER_PACKET_ENTRIES = (1 << 2) /* 4 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
new file mode 100644
index 0000000..e4249d9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugRingBufferStatus {
+  String ringName;
+  int flags;
+  int ringId;
+  int sizeInBytes;
+  int freeSizeInBytes;
+  int verboseLevel;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
new file mode 100644
index 0000000..e614f3f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugRingBufferVerboseLevel {
+  NONE = 0,
+  DEFAULT = 1,
+  VERBOSE = 2,
+  EXCESSIVE = 3,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl
new file mode 100644
index 0000000..f638c4f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugRxPacketFate {
+  SUCCESS,
+  FW_QUEUED,
+  FW_DROP_FILTER,
+  FW_DROP_INVALID,
+  FW_DROP_NOBUFS,
+  FW_DROP_OTHER,
+  DRV_QUEUED,
+  DRV_DROP_FILTER,
+  DRV_DROP_INVALID,
+  DRV_DROP_NOBUFS,
+  DRV_DROP_OTHER,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
new file mode 100644
index 0000000..bfe0c0a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugRxPacketFateReport {
+  android.hardware.wifi.WifiDebugRxPacketFate fate;
+  android.hardware.wifi.WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl
new file mode 100644
index 0000000..778ca5d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugTxPacketFate {
+  ACKED,
+  SENT,
+  FW_QUEUED,
+  FW_DROP_INVALID,
+  FW_DROP_NOBUFS,
+  FW_DROP_OTHER,
+  DRV_QUEUED,
+  DRV_DROP_INVALID,
+  DRV_DROP_NOBUFS,
+  DRV_DROP_OTHER,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
new file mode 100644
index 0000000..aee5c31
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugTxPacketFateReport {
+  android.hardware.wifi.WifiDebugTxPacketFate fate;
+  android.hardware.wifi.WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl
new file mode 100644
index 0000000..557cef4
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiIfaceMode {
+  IFACE_MODE_STA = (1 << 0) /* 1 */,
+  IFACE_MODE_SOFTAP = (1 << 1) /* 2 */,
+  IFACE_MODE_IBSS = (1 << 2) /* 4 */,
+  IFACE_MODE_P2P_CLIENT = (1 << 3) /* 8 */,
+  IFACE_MODE_P2P_GO = (1 << 4) /* 16 */,
+  IFACE_MODE_NAN = (1 << 5) /* 32 */,
+  IFACE_MODE_MESH = (1 << 6) /* 64 */,
+  IFACE_MODE_TDLS = (1 << 7) /* 128 */,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiInformationElement.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiInformationElement.aidl
new file mode 100644
index 0000000..27ba0db
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiInformationElement.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiInformationElement {
+  byte id;
+  byte[] data;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombination.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombination.aidl
new file mode 100644
index 0000000..f060db8
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombination.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRadioCombination {
+  android.hardware.wifi.WifiRadioConfiguration[] radioConfigurations;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioConfiguration.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioConfiguration.aidl
new file mode 100644
index 0000000..5169351
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioConfiguration.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRadioConfiguration {
+  android.hardware.wifi.WifiBand bandInfo;
+  android.hardware.wifi.WifiAntennaMode antennaMode;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateInfo.aidl
new file mode 100644
index 0000000..c4aca63
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRateInfo {
+  android.hardware.wifi.WifiRatePreamble preamble;
+  android.hardware.wifi.WifiRateNss nss;
+  android.hardware.wifi.WifiChannelWidthInMhz bw;
+  byte rateMcsIdx;
+  int bitRateInKbps;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateNss.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateNss.aidl
new file mode 100644
index 0000000..0ad6f04
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateNss.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiRateNss {
+  NSS_1x1 = 0,
+  NSS_2x2 = 1,
+  NSS_3x3 = 2,
+  NSS_4x4 = 3,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRatePreamble.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRatePreamble.aidl
new file mode 100644
index 0000000..04b6358
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRatePreamble.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiRatePreamble {
+  OFDM = 0,
+  CCK = 1,
+  HT = 2,
+  VHT = 3,
+  RESERVED = 4,
+  HE = 5,
+  EHT = 6,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl
new file mode 100644
index 0000000..9a15fa1
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiStatusCode {
+  SUCCESS,
+  ERROR_WIFI_CHIP_INVALID,
+  ERROR_WIFI_IFACE_INVALID,
+  ERROR_WIFI_RTT_CONTROLLER_INVALID,
+  ERROR_NOT_SUPPORTED,
+  ERROR_NOT_AVAILABLE,
+  ERROR_NOT_STARTED,
+  ERROR_INVALID_ARGS,
+  ERROR_BUSY,
+  ERROR_UNKNOWN,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl
new file mode 100644
index 0000000..774b242
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiUsableChannel {
+  int channel;
+  android.hardware.wifi.WifiChannelWidthInMhz channelBandwidth;
+  int ifaceModeMask;
+}
diff --git a/wifi/aidl/android/hardware/wifi/AfcChannelAllowance.aidl b/wifi/aidl/android/hardware/wifi/AfcChannelAllowance.aidl
new file mode 100644
index 0000000..289383c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/AfcChannelAllowance.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.AvailableAfcChannelInfo;
+import android.hardware.wifi.AvailableAfcFrequencyInfo;
+
+/**
+ * Defines the maximum permissible power spectral density to support 6Ghz with standard power for
+ * AFC. The maximum power can be either defined based on frequencies or channel number.
+ *
+ * Note, based on AFC server support, either availableAfcFrequencyInfos or availableAfcChannelInfos
+ * may be empty. If one of them is empty while the other is not, use the non-empty one and ignore
+ * the empty one. If both are empty then it means 6Ghz standard power should not be supported at
+ * all.
+ *
+ * If availableAfcFrequencyInfos is non-empty, set the max permissible power according to the maxPsd
+ * per frequency range, and disallow emmision on 6Ghz frequencies not included in the structure.
+ *
+ * If availableAfcChannelInfos is non-empty, set the max permissible power according to the
+ * maxEirpDbm per channel, and disallow emmision on 6Ghz channels not included in the structure.
+ */
+@VintfStability
+parcelable AfcChannelAllowance {
+    /**
+     * AFC max permissible information queried from AFC server based on frequency.
+     */
+    AvailableAfcFrequencyInfo[] availableAfcFrequencyInfos;
+    /**
+     * AFC max permissible information queried from AFC server on channel number.
+     */
+    AvailableAfcChannelInfo[] availableAfcChannelInfos;
+    /**
+     * The time in UTC at which this information expires, as the difference, measured in
+     * milliseconds between the expiration time and midnight, January 1, 1970 UTC.
+     */
+    long availabilityExpireTimeMs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/AvailableAfcChannelInfo.aidl b/wifi/aidl/android/hardware/wifi/AvailableAfcChannelInfo.aidl
new file mode 100644
index 0000000..398cd12
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/AvailableAfcChannelInfo.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Defines the maximum EIRP per channel for supporting 6Ghz standard power for AFC. The format of
+ * the data structure is derived from the Wi-Fi Alliance AFC System to AFC Device Interface
+ * Specification: AvailableChannelInfo object.
+ */
+@VintfStability
+parcelable AvailableAfcChannelInfo {
+    /**
+     * The global operating class used to define the channel center frequency indices
+     * and operating bandwidth.
+     */
+    int globalOperatingClass;
+
+    /**
+     * The channel center frequency index.
+     */
+    int channelCfi;
+
+    /**
+     * The maximum permissible EIRP in units of dBm available for the channel
+     * specified by channelCfi. In addition, in any portion of the channel, the conducted PSD plus
+     * the maximum antenna gain cannot exceed the maxEirp divided by the channel width defined by
+     * the globalOperatingClass.
+     */
+    int maxEirpDbm;
+}
diff --git a/wifi/aidl/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl b/wifi/aidl/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
new file mode 100644
index 0000000..5de360c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Defines the maximum permissible power spectral density on a range of
+ * frequencies to support 6Ghz with standard power for AFC.
+ * The format of the data follows spec from the Wi-Fi Alliance AFC System to
+ * AFC Device Interface Specification: AvailableFrequencyInfo object.
+ */
+@VintfStability
+parcelable AvailableAfcFrequencyInfo {
+    /**
+     * Defines the lowest frequency included in this 6Ghz frequency range.
+     */
+    int startFrequencyMhz;
+    /**
+     * Defines the highest frequency included in this 6Ghz frequency range.
+     */
+    int endFrequencyMhz;
+    /**
+     * The maximum permissible EIRP available in any one MHz bin within the
+     * frequency range specified. The limit is expressed as a power spectral
+     * density with units of dBm per MHz.
+     */
+    int maxPsd;
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifi.aidl b/wifi/aidl/android/hardware/wifi/IWifi.aidl
new file mode 100644
index 0000000..1d86421
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifi.aidl
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.IWifiChip;
+import android.hardware.wifi.IWifiEventCallback;
+
+/**
+ * This is the root of the HAL module and is the interface returned when
+ * loading an implementation of the Wi-Fi HAL. There must be at most one
+ * module loaded in the system.
+ */
+@VintfStability
+interface IWifi {
+    /**
+     * Gets an AIDL interface object for the chip corresponding to the
+     * provided chipId.
+     *
+     * @param chipId ID of the chip.
+     * @return AIDL interface object representing the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.NOT_STARTED|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    @PropagateAllowBlocking IWifiChip getChip(int chipId);
+
+    /**
+     * Retrieves the list of all chip id's on the device.
+     * The corresponding |IWifiChip| object for any chip can be
+     * retrieved using the |getChip| method.
+     *
+     * @return List of all chip id's on the device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.NOT_STARTED|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    int[] getChipIds();
+
+    /**
+     * Get the current state of the HAL.
+     *
+     * @return true if started, false otherwise.
+     */
+    boolean isStarted();
+
+    /**
+     * Requests notifications of significant HAL events. Multiple calls to
+     * this must register multiple callbacks, each of which must receive all
+     * events. |IWifiEventCallback| object registration must be independent of the
+     * state of the rest of the HAL and must persist though stops/starts. These
+     * objects must be deleted when the corresponding client process is dead.
+     *
+     * @param callback An instance of the |IWifiEventCallback| AIDL interface
+     *        object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void registerEventCallback(in IWifiEventCallback callback);
+
+    /**
+     * Perform any setup that is required to make use of the module.
+     * If the module is already started then this must be a noop.
+     * Must trigger |IWifiEventCallback.onStart| on success.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void start();
+
+    /**
+     * Tear down any state, ongoing commands, etc. If the module is already
+     * stopped then this must be a noop. After calling this, all |IWifiChip|
+     * objects will be considered invalid.
+     * Must trigger |IWifiEventCallback.onStop| on success.
+     * Must trigger |IWifiEventCallback.onFailure| on failure.
+     *
+     * Calling stop() and then start() is a valid way of resetting state in
+     * the HAL, driver, and firmware.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.NOT_STARTED|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void stop();
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
new file mode 100644
index 0000000..b14a800
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiBand;
+
+/**
+ * Represents a network interface in AP mode.
+ *
+ * This can be obtained through |IWifiChip.getApIface|.
+ */
+@VintfStability
+interface IWifiApIface {
+    /**
+     * Get the name of this interface.
+     *
+     * @return Name of this interface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    String getName();
+
+    /**
+     * Get the names of the bridged AP instances.
+     *
+     * @return Vector containing the names of the bridged AP
+     *         instances. Note: Returns an empty vector for a non-bridged AP.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    String[] getBridgedInstances();
+
+    /**
+     * Gets the factory MAC address of the interface.
+     *
+     * @return Factory MAC address of the interface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    byte[6] getFactoryMacAddress();
+
+    /**
+     * Set country code for this iface.
+     *
+     * @param code 2 byte country code (as defined in ISO 3166) to set.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|,
+     *         |WifiStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setCountryCode(in byte[2] code);
+
+    /**
+     * Reset all of the AP interfaces' MAC address to the factory MAC address.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void resetToFactoryMacAddress();
+
+    /**
+     * Changes the MAC address of the interface to the given MAC address.
+     *
+     * @param mac MAC address to change to.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setMacAddress(in byte[6] mac);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
new file mode 100644
index 0000000..c1caa7e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -0,0 +1,1152 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.AfcChannelAllowance;
+import android.hardware.wifi.IWifiApIface;
+import android.hardware.wifi.IWifiChipEventCallback;
+import android.hardware.wifi.IWifiNanIface;
+import android.hardware.wifi.IWifiP2pIface;
+import android.hardware.wifi.IWifiRttController;
+import android.hardware.wifi.IWifiStaIface;
+import android.hardware.wifi.IfaceConcurrencyType;
+import android.hardware.wifi.IfaceType;
+import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiChipCapabilities;
+import android.hardware.wifi.WifiDebugHostWakeReasonStats;
+import android.hardware.wifi.WifiDebugRingBufferStatus;
+import android.hardware.wifi.WifiDebugRingBufferVerboseLevel;
+import android.hardware.wifi.WifiIfaceMode;
+import android.hardware.wifi.WifiRadioCombination;
+import android.hardware.wifi.WifiUsableChannel;
+
+/**
+ * Interface that represents a chip that must be configured as a single unit.
+ */
+@VintfStability
+interface IWifiChip {
+    /**
+     * Capabilities exposed by this chip.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum FeatureSetMask {
+        /**
+         * Set/Reset Tx Power limits.
+         */
+        SET_TX_POWER_LIMIT = 1 << 0,
+        /**
+         * Device to Device RTT.
+         */
+        D2D_RTT = 1 << 1,
+        /**
+         * Device to AP RTT.
+         */
+        D2AP_RTT = 1 << 2,
+        /**
+         * Set/Reset Tx Power limits.
+         */
+        USE_BODY_HEAD_SAR = 1 << 3,
+        /**
+         * Set Latency Mode.
+         */
+        SET_LATENCY_MODE = 1 << 4,
+        /**
+         * Support P2P MAC randomization.
+         */
+        P2P_RAND_MAC = 1 << 5,
+        /**
+         * Chip can operate in the 60GHz band (WiGig chip).
+         */
+        WIGIG = 1 << 6,
+        /**
+         * Chip supports setting allowed channels along with PSD in 6GHz band
+         * for AFC purposes.
+         */
+        SET_AFC_CHANNEL_ALLOWANCE = 1 << 7,
+        /**
+         * Chip supports Tid-To-Link mapping negotiation.
+         */
+        T2LM_NEGOTIATION = 1 << 8,
+    }
+
+    /**
+     * Set of interface concurrency types, along with the maximum number of interfaces that can have
+     * one of the specified concurrency types for a given ChipConcurrencyCombination. See
+     * ChipConcurrencyCombination below for examples.
+     */
+    @VintfStability
+    parcelable ChipConcurrencyCombinationLimit {
+        IfaceConcurrencyType[] types;
+        int maxIfaces;
+    }
+
+    /**
+     * Set of interfaces that can operate concurrently when in a given mode. See
+     * ChipMode below.
+     *
+     * For example:
+     *   [{STA} <= 2]
+     *       At most two STA interfaces are supported
+     *       [], [STA], [STA+STA]
+     *
+     *   [{STA} <= 1, {NAN} <= 1, {AP_BRIDGED} <= 1]
+     *       Any combination of STA, NAN, AP_BRIDGED
+     *       [], [STA], [NAN], [AP_BRIDGED], [STA+NAN], [STA+AP_BRIDGED], [NAN+AP_BRIDGED],
+     *       [STA+NAN+AP_BRIDGED]
+     *
+     *   [{STA} <= 1, {NAN,P2P} <= 1]
+     *       Optionally a STA and either NAN or P2P
+     *       [], [STA], [STA+NAN], [STA+P2P], [NAN], [P2P]
+     *       Not included [NAN+P2P], [STA+NAN+P2P]
+     *
+     *   [{STA} <= 1, {STA,NAN} <= 1]
+     *       Optionally a STA and either a second STA or a NAN
+     *       [], [STA], [STA+NAN], [STA+STA], [NAN]
+     *       Not included [STA+STA+NAN]
+     */
+    @VintfStability
+    parcelable ChipConcurrencyCombination {
+        ChipConcurrencyCombinationLimit[] limits;
+    }
+
+    /**
+     * Information about the version of the driver and firmware running this chip.
+     *
+     * The information in these ASCII strings are vendor specific and does not
+     * need to follow any particular format. It may be dumped as part of the bug
+     * report.
+     */
+    @VintfStability
+    parcelable ChipDebugInfo {
+        String driverDescription;
+        String firmwareDescription;
+    }
+
+    /**
+     * Set of interface types, along with the maximum number of interfaces that can have
+     * one of the specified types for a given ChipIfaceCombination. See
+     * ChipIfaceCombination for examples.
+     */
+    @VintfStability
+    parcelable ChipIfaceCombinationLimit {
+        IfaceType[] types;
+        int maxIfaces;
+    }
+
+    /**
+     * Set of interfaces that can operate concurrently when in a given mode. See
+     * ChipMode below.
+     *
+     * For example:
+     *   [{STA} <= 2]
+     *       At most two STA interfaces are supported
+     *       [], [STA], [STA+STA]
+     *
+     *   [{STA} <= 1, {NAN} <= 1, {AP} <= 1]
+     *       Any combination of STA, NAN, AP
+     *       [], [STA], [NAN], [AP], [STA+NAN], [STA+AP], [NAN+AP], [STA+NAN+AP]
+     *
+     *   [{STA} <= 1, {NAN,P2P} <= 1]
+     *       Optionally a STA and either NAN or P2P
+     *       [], [STA], [STA+NAN], [STA+P2P], [NAN], [P2P]
+     *       Not included [NAN+P2P], [STA+NAN+P2P]
+     *
+     *   [{STA} <= 1, {STA,NAN} <= 1]
+     *       Optionally a STA and either a second STA or a NAN
+     *       [], [STA], [STA+NAN], [STA+STA], [NAN]
+     *       Not included [STA+STA+NAN]
+     */
+    @VintfStability
+    parcelable ChipIfaceCombination {
+        ChipIfaceCombinationLimit[] limits;
+    }
+
+    /**
+     * A mode that the chip can be put in. A mode defines a set of constraints on
+     * the interfaces that can exist while in that mode. Modes define a unit of
+     * configuration where all interfaces must be torn down to switch to a
+     * different mode. Some HALs may only have a single mode, but an example where
+     * multiple modes would be required is if a chip has different firmwares with
+     * different capabilities.
+     *
+     * When in a mode, it must be possible to perform any combination of creating
+     * and removing interfaces as long as at least one of the
+     * ChipConcurrencyCombinations is satisfied. This means that if a chip has two
+     * available combinations, [{STA} <= 1] and [{AP_BRIDGED} <= 1] then it is expected
+     * that exactly one STA type or one AP_BRIDGED type can be created, but it
+     * is not expected that both a STA and AP_BRIDGED type  could be created. If it
+     * was then there would be a single available combination
+     * [{STA} <=1, {AP_BRIDGED} <= 1].
+     *
+     * When switching between two available combinations it is expected that
+     * interfaces only supported by the initial combination must be removed until
+     * the target combination is also satisfied. At that point new interfaces
+     * satisfying only the target combination can be added (meaning the initial
+     * combination limits will no longer satisfied). The addition of these new
+     * interfaces must not impact the existence of interfaces that satisfy both
+     * combinations.
+     *
+     * For example, a chip with available combinations:
+     *     [{STA} <= 2, {NAN} <=1] and [{STA} <=1, {NAN} <= 1, {AP_BRIDGED} <= 1}]
+     * If the chip currently has 3 interfaces STA, STA and NAN and wants to add an
+     * AP_BRIDGED interface in place of one of the STAs, then one of the STA interfaces
+     * must be removed first, and then the AP interface can be created after
+     * the STA has been torn down. During this process the remaining STA and NAN
+     * interfaces must not be removed/recreated.
+     *
+     * If a chip does not support this kind of reconfiguration in this mode then
+     * the combinations must be separated into two separate modes. Before
+     * switching modes, all interfaces must be torn down, the mode switch must be
+     * enacted, and when it completes the new interfaces must be brought up.
+     */
+    @VintfStability
+    parcelable ChipMode {
+        /**
+         * Id that can be used to put the chip in this mode.
+         */
+        int id;
+        /**
+         * A list of the possible interface concurrency type combinations that the
+         * chip can have while in this mode.
+         */
+        ChipConcurrencyCombination[] availableCombinations;
+    }
+
+    /**
+     * Wi-Fi coex channel avoidance support.
+     */
+    const int NO_POWER_CAP_CONSTANT = 0x7FFFFFFF;
+
+    @VintfStability
+    @Backing(type="int")
+    enum CoexRestriction {
+        WIFI_DIRECT = 1 << 0,
+        SOFTAP = 1 << 1,
+        WIFI_AWARE = 1 << 2,
+    }
+
+    /**
+     * Representation of a Wi-Fi channel for Wi-Fi coex channel avoidance.
+     */
+    @VintfStability
+    parcelable CoexUnsafeChannel {
+        /*
+         * Band of the channel.
+         */
+        WifiBand band;
+        /*
+         * Channel number.
+         */
+        int channel;
+        /**
+         * The power cap will be a maximum power value in dbm that is allowed to be transmitted by
+         * the chip on this channel. A value of PowerCapConstant.NO_POWER_CAP means no limitation
+         * on transmitted power is needed by the chip for this channel.
+         */
+        int powerCapDbm;
+    }
+
+    /**
+     * This enum represents the different latency modes that can be set through |setLatencyMode|.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum LatencyMode {
+        NORMAL = 0,
+        LOW = 1,
+    }
+
+    /**
+     * When there are 2 or more simultaneous STA connections, this use case hint indicates what
+     * use-case is being enabled by the framework. This use case hint can be used by the firmware
+     * to modify various firmware configurations like:
+     *   - Allowed BSSIDs the firmware can choose for the initial connection/roaming attempts.
+     *   - Duty cycle to choose for the 2 STA connections if the radio is in MCC mode.
+     *   - Whether roaming, APF and other offloads need to be enabled or not.
+     * Note:
+     *   - This will be invoked before an active wifi connection is established on the second
+     *     interface.
+     *   - This use-case hint is implicitly void when the second STA interface is brought down.
+     *   - When there is only 1 STA interface, we should still retain the last use case
+     *     set, which must become active the next time multi STA is enabled.
+     *     1. Initialize with single STA.
+     *     2. Framework creates second STA.
+     *     3. Framework sets use case to DUAL_STA_NON_TRANSIENT_UNBIASED.
+     *     4. Framework destroys second STA. Only 1 STA remains.
+     *     5. Framework recreates second STA.
+     *     6. The active use case remains DUAL_STA_NON_TRANSIENT_UNBIASED (i.e. firmware should not
+     *        automatically change it during period of single STA unless requested by framework).
+     */
+    @VintfStability
+    @Backing(type="byte")
+    enum MultiStaUseCase {
+        /**
+         * Usage:
+         * - This will be sent down for make before break use-case.
+         * - Platform is trying to speculatively connect to a second network and evaluate it without
+         *  disrupting the primary connection.
+         * Requirements for Firmware:
+         * - Do not reduce the number of tx/rx chains of primary connection.
+         * - If using MCC, should set the MCC duty cycle of the primary connection to be higher than
+         *  the secondary connection (maybe 70/30 split).
+         * - Should pick the best BSSID for the secondary STA (disregard the chip mode) independent
+         *   of the primary STA:
+         *    - Don’t optimize for DBS vs MCC/SCC
+         * - Should not impact the primary connection’s bssid selection:
+         *    - Don’t downgrade chains of the existing primary connection.
+         *    - Don’t optimize for DBS vs MCC/SCC.
+         */
+        DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
+        /**
+         * Usage:
+         * - This will be sent down for any app requested peer to peer connections.
+         * - In this case, both the connections need to be allocated equal resources.
+         * - For the peer to peer use case, BSSID for the secondary connection will be chosen by the
+         *   framework.
+         *
+         * Requirements for Firmware:
+         * - Can choose MCC or DBS mode depending on the MCC efficiency and HW capability.
+         * - If using MCC, set the MCC duty cycle of the primary connection to be equal to the
+         *   secondary connection.
+         * - Prefer BSSID candidates which will help provide the best "overall" performance for both
+         *   the connections.
+         */
+        DUAL_STA_NON_TRANSIENT_UNBIASED = 1,
+    }
+
+    /**
+     * List of preset wifi radio TX power levels for different scenarios.
+     * The actual power values (typically varies based on the channel,
+     * 802.11 connection type, number of MIMO streams, etc) for each scenario
+     * is defined by the OEM as a BDF file since it varies for each wifi chip
+     * vendor and device.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum TxPowerScenario {
+        VOICE_CALL = 0,
+        ON_HEAD_CELL_OFF = 1,
+        ON_HEAD_CELL_ON = 2,
+        ON_BODY_CELL_OFF = 3,
+        ON_BODY_CELL_ON = 4,
+    }
+
+    /**
+     * Usable Wifi channels filter masks.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum UsableChannelFilter {
+        /**
+         * Filter Wifi channels that should be avoided due to extreme
+         * cellular coexistence restrictions. Some Wifi channels can have
+         * extreme interference from/to cellular due to short frequency
+         * seperation with neighboring cellular channels, or when there
+         * is harmonic and intermodulation interference. Channels which
+         * only have some performance degradation (e.g. power back off is
+         * sufficient to deal with coexistence issue) can be included and
+         * should not be filtered out.
+         */
+        CELLULAR_COEXISTENCE = 1 << 0,
+        /**
+         * Filter based on concurrency state.
+         * Examples:
+         * - 5GHz SAP operation may be supported in standalone mode, but if
+         *  there is a STA connection on a 5GHz DFS channel, none of the 5GHz
+         *  channels are usable for SAP if device does not support DFS SAP mode.
+         * - P2P GO may not be supported on indoor channels in the EU during
+         *  standalone mode but if there is a STA connection on indoor channel.
+         *  P2P GO may be supported by some vendors on the same STA channel.
+         */
+        CONCURRENCY = 1 << 1,
+        /**
+         * Filter Wifi channels that are supported for NAN 3.1 Instant communication mode.
+         * This filter should only be applied to a NAN interface.
+         * - If 5G is supported, then default discovery channel 149/44 is considered.
+         * - If 5G is not supported, then channel 6 has to be considered.
+         */
+        NAN_INSTANT_MODE = 1 << 2,
+    }
+
+    /**
+     * Configure the Chip.
+     * This may NOT be called to reconfigure a chip due to an internal
+     * limitation. Calling this when chip is already configured in a different
+     * mode must trigger an ERROR_NOT_SUPPORTED failure.
+     * If you want to do reconfiguration, please call |IWifi.stop| and |IWifi.start|
+     * to restart Wifi HAL before calling this.
+     * Any existing |IWifiIface| objects must be marked invalid after this call.
+     * If this fails then the chip is now in an undefined state and
+     * configureChip must be called again.
+     * Must trigger |IWifiChipEventCallback.onChipReconfigured| on success.
+     * Must trigger |IWifiEventCallback.onFailure| on failure.
+     *
+     * @param modeId Mode that the chip must switch to, corresponding to the
+     *        id property of the target ChipMode.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void configureChip(in int modeId);
+
+    /**
+     * Create an AP iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the AP type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiApIface createApIface();
+
+    /**
+     * Create a bridged AP iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the AP type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiApIface createBridgedApIface();
+
+    /**
+     * Create a NAN iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the NAN type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiNanIface createNanIface();
+
+    /**
+     * Create a P2P iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the P2P type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiP2pIface createP2pIface();
+
+    /**
+     * Create an RTTController instance.
+     *
+     * RTT controller can be either:
+     * a) Bound to a specific STA iface by passing in the corresponding
+     * |IWifiStaIface| object in the |boundIface| param, OR
+     * b) Let the implementation decide the iface to use for RTT operations
+     * by passing null in the |boundIface| param.
+     *
+     * @param boundIface AIDL interface object representing the STA iface if
+     *        the responder must be bound to a specific iface, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    @PropagateAllowBlocking IWifiRttController createRttController(in IWifiStaIface boundIface);
+
+    /**
+     * Create a STA iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the STA type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiStaIface createStaIface();
+
+    /**
+     * API to enable/disable alert notifications from the chip.
+     * These alerts must be used to notify the framework of any fatal error events
+     * that the chip encounters via |IWifiChipEventCallback.onDebugErrorAlert| method.
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void enableDebugErrorAlerts(in boolean enable);
+
+    /**
+     * API to flush debug ring buffer data to files.
+     *
+     * Force flush debug ring buffer using IBase::debug.
+     * This API helps to collect firmware/driver/pkt logs.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void flushRingBufferToFile();
+
+    /**
+     * API to force dump data into the corresponding ring buffer.
+     * This is to be invoked during bugreport collection.
+     *
+     * @param ringName Name of the ring for which data collection should
+     *        be forced. This can be retrieved via the corresponding
+     *        |WifiDebugRingBufferStatus|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void forceDumpToDebugRingBuffer(in String ringName);
+
+    /**
+     * Gets an AIDL interface object for the AP Iface corresponding
+     * to the provided ifname.
+     *
+     * @param ifname Name of the iface.
+     * @return AIDL interface object representing the iface if
+     *         it exists, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    @PropagateAllowBlocking IWifiApIface getApIface(in String ifname);
+
+    /**
+     * List all the AP iface names configured on the chip.
+     * The corresponding |IWifiApIface| object for any iface
+     * can be retrieved using the |getApIface| method.
+     *
+     * @return List of all AP iface names on the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    String[] getApIfaceNames();
+
+    /**
+     * Get the set of operation modes that the chip supports.
+     *
+     * @return List of modes supported by the device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    ChipMode[] getAvailableModes();
+
+    /**
+     * Get the features supported by this chip.
+     *
+     * @return Bitset of |FeatureSetMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    int getFeatureSet();
+
+    /**
+     * API to retrieve the wifi wake up reason stats for debugging.
+     * The driver is expected to start maintaining these stats once the chip
+     * is configured using |configureChip|. These stats must be reset whenever
+     * the chip is reconfigured or the HAL is stopped.
+     *
+     * @return Instance of |WifiDebugHostWakeReasonStats|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    WifiDebugHostWakeReasonStats getDebugHostWakeReasonStats();
+
+    /**
+     * The WiFi debug ring buffer life cycle is as follows:
+     * - At initialization, the framework must call |getDebugRingBuffersStatus|.
+     *   to obtain the names and list of supported ring buffers.
+     *   The driver may expose several different rings, each holding a different
+     *   type of data (connection events, power events, etc).
+     * - When WiFi operations start, the framework must call
+     *   |startLoggingToDebugRingBuffer| to trigger log collection for a specific
+     *   ring. The vebose level for each ring buffer can be specified in this API.
+     * - During wifi operations, the driver must periodically report per ring data
+     *   to framework by invoking the
+     *   |IWifiChipEventCallback.onDebugRingBufferDataAvailable| callback.
+     * - When capturing a bug report, the framework must indicate to driver that
+     *   all the data has to be uploaded urgently by calling |forceDumpToDebugRingBuffer|.
+     *
+     * The data uploaded by driver must be stored by the framework in separate files,
+     * with one stream of file per ring. The framework must store the files in pcapng
+     * format, allowing for easy merging and parsing with network analyzer tools.
+     * TODO: Since we're no longer dumping the raw data, storing in separate
+     * pcapng files for parsing later must not work anymore.
+     */
+
+    /*
+     * API to get the status of all ring buffers supported by driver.
+     *
+     * @return Vector of |WifiDebugRingBufferStatus| corresponding to the
+     *         status of each ring buffer on the device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    WifiDebugRingBufferStatus[] getDebugRingBuffersStatus();
+
+    /**
+     * Get the Id assigned to this chip.
+     *
+     * @return Assigned chip Id.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    int getId();
+
+    /**
+     * Get the current mode that the chip is in.
+     *
+     * @return Mode that the chip is currently configured to,
+     *         corresponding to the Id property of the target ChipMode.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    int getMode();
+
+    /**
+     * Gets an AIDL interface object for the NAN Iface corresponding
+     * to the provided ifname.
+     *
+     * @param ifname Name of the iface.
+     * @return AIDL interface object representing the iface if
+     *         it exists, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    @PropagateAllowBlocking IWifiNanIface getNanIface(in String ifname);
+
+    /**
+     * List all the NAN iface names configured on the chip.
+     * The corresponding |IWifiNanIface| object for any iface can
+     * be retrieved using the |getNanIface| method.
+     *
+     * @return List of all NAN iface names on the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    String[] getNanIfaceNames();
+
+    /**
+     * Gets an AIDL interface object for the P2P Iface corresponding
+     * to the provided ifname.
+     *
+     * @param ifname Name of the iface.
+     * @return AIDL interface object representing the iface if
+     *         it exists, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    @PropagateAllowBlocking IWifiP2pIface getP2pIface(in String ifname);
+
+    /**
+     * List all the P2P iface names configured on the chip.
+     * The corresponding |IWifiP2pIface| object for any iface can
+     * be retrieved using the |getP2pIface| method.
+     *
+     * @return List of all P2P iface names on the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    String[] getP2pIfaceNames();
+
+    /**
+     * Gets an AIDL interface object for the STA Iface corresponding
+     * to the provided ifname.
+     *
+     * @param ifname Name of the iface.
+     * @return AIDL interface object representing the iface if
+     *         it exists, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    @PropagateAllowBlocking IWifiStaIface getStaIface(in String ifname);
+
+    /**
+     * List all the STA iface names configured on the chip.
+     * The corresponding |IWifiStaIface| object for any iface can
+     * be retrieved using the |getStaIface| method.
+     *
+     * @param List of all STA iface names on the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    String[] getStaIfaceNames();
+
+    /**
+     * Retrieve the list of all the possible radio combinations supported by this
+     * chip.
+     *
+     * @return A list of all the possible radio combinations.
+     *         For example, in case of a chip which has two radios, where one radio is
+     *         capable of 2.4GHz 2X2 only and another radio which is capable of either
+     *         5GHz or 6GHz 2X2, the number of possible radio combinations in this case
+     *         is 5 and the possible combinations are:
+     *         {{{2G 2X2}}, //Standalone 2G
+     *         {{5G 2X2}}, //Standalone 5G
+     *         {{6G 2X2}}, //Standalone 6G
+     *         {{2G 2X2}, {5G 2X2}}, //2G+5G DBS
+     *         {{2G 2X2}, {6G 2X2}}} //2G+6G DBS
+     *         Note: Since this chip doesn’t support 5G+6G simultaneous operation,
+     *         as there is only one radio which can support both bands, it can only
+     *         do MCC 5G+6G. This table should not get populated with possible MCC
+     *         configurations. This is only for simultaneous radio configurations
+     *         (such as standalone, multi band simultaneous or single band simultaneous).
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     *
+     */
+    WifiRadioCombination[] getSupportedRadioCombinations();
+
+    /**
+     * Get capabilities supported by this chip.
+     *
+     * @return Chip capabilities represented by |WifiChipCapabilities|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     *
+     */
+    WifiChipCapabilities getWifiChipCapabilities();
+
+    /**
+     * Retrieve a list of usable Wifi channels for the specified band &
+     * operational modes.
+     *
+     * The list of usable Wifi channels in a given band depends on factors
+     * like current country code, operational mode (e.g. STA, SAP, WFD-CLI,
+     * WFD-GO, TDLS, NAN) and other restrictons due to DFS, cellular coexistence
+     * and concurrency state of the device.
+     *
+     * @param band |WifiBand| for which list of usable channels is requested.
+     * @param ifaceModeMask Bitmask of the modes represented by |WifiIfaceMode|.
+     *        Bitmask respresents all the modes that the caller is interested
+     *        in (e.g. STA, SAP, CLI, GO, TDLS, NAN). E.g. If the caller is
+     *        interested in knowing usable channels for P2P CLI, P2P GO & NAN,
+     *        ifaceModeMask would be set to
+     *        IFACE_MODE_P2P_CLIENT|IFACE_MODE_P2P_GO|IFACE_MODE_NAN.
+     * @param filterMask Bitmask of filters represented by
+     *        |UsableChannelFilter|. Specifies whether driver should filter
+     *        channels based on additional criteria. If no filter is specified,
+     *        then the driver should return usable channels purely based on
+     *        regulatory constraints.
+     * @return List of channels represented by |WifiUsableChannel|.
+     *         Each entry represents a channel frequency, bandwidth and
+     *         bitmask of modes (e.g. STA, SAP, CLI, GO, TDLS, NAN) that are
+     *         allowed on that channel. E.g. If only STA mode can be supported
+     *         on an indoor channel, only the IFACE_MODE_STA bit would be set
+     *         for that channel. If 5GHz SAP cannot be supported, then none of
+     *         the 5GHz channels will have IFACE_MODE_SOFTAP bit set.
+     *         Note: Bits do not represent concurrency state. Each bit only
+     *         represents whether a particular mode is allowed on that channel.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     */
+    WifiUsableChannel[] getUsableChannels(
+            in WifiBand band, in int ifaceModeMask, in int filterMask);
+
+    /*
+     * Set the max power level the chip is allowed to transmit on for 6Ghz AFC.
+     * @param afcChannelAllowance Specifies the power limitations for 6Ghz AFC.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|
+     */
+    void setAfcChannelAllowance(in AfcChannelAllowance afcChannelAllowance);
+
+    /**
+     * Requests notifications of significant events on this chip. Multiple calls
+     * to this must register multiple callbacks, each of which must receive all
+     * events.
+     *
+     * @param callback An instance of the |IWifiChipEventCallback| AIDL interface
+     *        object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    void registerEventCallback(in IWifiChipEventCallback callback);
+
+    /**
+     * Removes the AP Iface with the provided ifname.
+     * Any further calls on the corresponding |IWifiApIface| AIDL interface
+     * object must fail.
+     *
+     * @param ifname Name of the iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void removeApIface(in String ifname);
+
+    /**
+     * Removes an instance of AP iface with name |ifaceInstanceName| from the
+     * bridge AP with name |brIfaceName|.
+     *
+     * Use the API |removeApIface| with the brIfaceName to remove the bridge iface.
+     *
+     * @param brIfaceName Name of the bridged AP iface.
+     * @param ifaceInstanceName Name of the AP instance. The empty instance is
+     *        invalid.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    void removeIfaceInstanceFromBridgedApIface(in String brIfaceName, in String ifaceInstanceName);
+
+    /**
+     * Removes the NAN Iface with the provided ifname.
+     * Any further calls on the corresponding |IWifiNanIface| AIDL interface
+     * object must fail.
+     *
+     * @param ifname Name of the iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void removeNanIface(in String ifname);
+
+    /**
+     * Removes the P2P Iface with the provided ifname.
+     * Any further calls on the corresponding |IWifiP2pIface| AIDL interface
+     * object must fail.
+     *
+     * @param ifname Name of the iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void removeP2pIface(in String ifname);
+
+    /**
+     * Removes the STA Iface with the provided ifname.
+     * Any further calls on the corresponding |IWifiStaIface| AIDL interface
+     * object must fail.
+     *
+     * @param ifname Name of the iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void removeStaIface(in String ifname);
+
+    /**
+     * Request information about the chip.
+     *
+     * @return Instance of |ChipDebugInfo|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    ChipDebugInfo requestChipDebugInfo();
+
+    /**
+     * Request vendor debug info from the driver.
+     *
+     * @return Vector of bytes retrieved from the driver.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    byte[] requestDriverDebugDump();
+
+    /**
+     * Request vendor debug info from the firmware.
+     *
+     * @return Vector of bytes retrieved from the firmware.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    byte[] requestFirmwareDebugDump();
+
+    /**
+     * API to reset TX power levels.
+     * This is used to indicate the end of the previously selected TX power
+     * scenario and let the wifi chip fall back to the default power values.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void resetTxPowerScenario();
+
+    /**
+     * API to select one of the preset TX power scenarios.
+     *
+     * The framework must invoke this method with the appropriate scenario to let
+     * the wifi chip change its transmitting power levels.
+     * OEM's should define various power profiles for each of the scenarios
+     * above (defined in |TxPowerScenario|) in a vendor extension.
+     *
+     * @param scenario One of the preselected scenarios defined in
+     *        |TxPowerScenario|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void selectTxPowerScenario(in TxPowerScenario scenario);
+
+    /**
+     * Invoked to indicate that the provided |CoexUnsafeChannels| should be avoided with the
+     * specified restrictions.
+     *
+     * Channel avoidance is a suggestion and should be done on a best-effort approach. If a provided
+     * channel is used, then the specified power cap should be applied.
+     *
+     * In addition, hard restrictions on the Wifi modes may be indicated by |CoexRestriction| bits
+     * (WIFI_DIRECT, SOFTAP, WIFI_AWARE) in the |restrictions| bitfield. If a hard restriction is
+     * provided, then the channels should be completely avoided for the provided Wifi modes instead
+     * of by best-effort.
+     *
+     * @param unsafeChannels List of |CoexUnsafeChannels| to avoid.
+     * @param restrictions Bitset of |CoexRestriction| values indicating Wifi interfaces to
+     *         completely avoid.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     */
+    void setCoexUnsafeChannels(in CoexUnsafeChannel[] unsafeChannels, in int restrictions);
+
+    /**
+     * Set country code for this Wifi chip.
+     *
+     * Country code is global setting across the Wifi chip and not Wifi
+     * interface (STA or AP) specific.
+     *
+     * @param code 2 byte country code (as defined in ISO 3166) to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.FAILURE_UNKNOWN|,
+     *         |WifiStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setCountryCode(in byte[2] code);
+
+    /**
+     * API to set the wifi latency mode
+     *
+     * The latency mode is a hint to the HAL to enable or disable Wi-Fi latency
+     * optimization. The optimization should be enabled if the mode is set to |LOW|
+     * and should be disabled if the mode is set to |NORMAL|.
+     * Wi-Fi latency optimization may trade-off latency against other Wi-Fi
+     * functionality such as scanning, roaming, etc. but it should not result in
+     * completely halting this functionality.
+     *
+     * The low latency mode targets applications such as gaming and virtual reality.
+     */
+    void setLatencyMode(in LatencyMode mode);
+
+    /**
+     * Invoked to indicate that the provided iface is the primary STA iface when more
+     * than 1 STA ifaces are concurrently active.
+     * Notes:
+     * - If the wifi firmware/chip cannot support multiple instances of any offload
+     *   (like roaming, APF, rssi threshold, etc), the firmware should ensure that these
+     *   offloads are at least enabled for the primary interface. If the new primary interface is
+     *   already connected to a network, the firmware must switch all the offloads on
+     *   this new interface without disconnecting.
+     * - When there is only 1 STA interface, the firmware must still retain the last primary
+     *   connection, which must become active the next time multi STA is enabled.
+     *
+     * @param ifname Name of the STA iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void setMultiStaPrimaryConnection(in String ifName);
+
+    /**
+     * Invoked to indicate the STA + STA use-case that is active.
+     *
+     * Refer to documentation of |MultiStaUseCase| for details.
+     *
+     * @param useCase Use case that is active.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void setMultiStaUseCase(in MultiStaUseCase useCase);
+
+    /**
+     * API to trigger the debug data collection.
+     *
+     * @param ringName Name of the ring for which data collection
+     *        shall start. This can be retrieved via the corresponding
+     *        |WifiDebugRingBufferStatus|.
+     * @param verboseLevel Verbose level for logging.
+     * @parm maxIntervalInSec Maximum interval in seconds for driver to invoke
+     *       |onDebugRingBufferData|, ignore if zero.
+     * @parm minDataSizeInBytes: Minimum data size in buffer for driver to invoke
+     *       |onDebugRingBufferData|, ignore if zero.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void startLoggingToDebugRingBuffer(in String ringName,
+            in WifiDebugRingBufferVerboseLevel verboseLevel, in int maxIntervalInSec,
+            in int minDataSizeInBytes);
+
+    /**
+     * API to stop the debug data collection for all ring buffers.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void stopLoggingToDebugRingBuffer();
+
+    /**
+     * Trigger subsystem restart.
+     *
+     * If the framework detects a problem (e.g. connection failure),
+     * it must call this function to attempt recovery.
+     *
+     * When the wifi HAL receives |triggerSubsystemRestart|, it must restart
+     * the wlan subsystem, especially the wlan firmware.
+     *
+     * Regarding the callback function for subsystem restart, refer to documentation of
+     * |IWifiEventCallback.onSubsystemRestart| for details.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void triggerSubsystemRestart();
+
+    /**
+     * Channel category mask.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum ChannelCategoryMask {
+        INDOOR_CHANNEL = 1 << 0,
+        DFS_CHANNEL = 1 << 1,
+    }
+
+    /**
+     * API to enable or disable the feature of allowing current STA-connected channel for WFA GO,
+     * SAP and Aware when the regulatory allows.
+     * If the channel category is enabled and allowed by the regulatory, the HAL method
+     * getUsableChannels() will contain the current STA-connected channel if that channel belongs
+     * to that category.
+     * @param channelCategoryEnableFlag Bitmask of |ChannelCategoryMask| values.
+     *        For each bit, 1 enables the channel category and 0 disables that channel category.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     */
+    void enableStaChannelForPeerNetwork(in int channelCategoryEnableFlag);
+
+    /**
+     * Multi-Link Operation modes.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum ChipMloMode {
+        /**
+         * Default mode for Multi-Link Operation.
+         */
+        DEFAULT = 0,
+        /**
+         * Low latency mode for Multi-link operation.
+         */
+        LOW_LATENCY = 1,
+        /**
+         * High throughput mode for Multi-link operation.
+         */
+        HIGH_THROUGHPUT = 2,
+        /**
+         * Low power mode for Multi-link operation.
+         */
+        LOW_POWER = 3,
+    }
+
+    /**
+     * Set mode for Multi-Link Operation. Various modes are defined by the enum |ChipMloMode|.
+     *
+     * @param mode MLO mode as defined by the enum |ChipMloMode|
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     *
+     */
+    void setMloMode(in ChipMloMode mode);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChipEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiChipEventCallback.aidl
new file mode 100644
index 0000000..2bc4c0e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiChipEventCallback.aidl
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.IfaceType;
+import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiDebugRingBufferStatus;
+import android.hardware.wifi.WifiStatusCode;
+
+/**
+ * Wifi chip event callbacks.
+ */
+@VintfStability
+oneway interface IWifiChipEventCallback {
+    /**
+     * Struct describing the state of each iface operating on the radio chain
+     * (hardware MAC) on the device.
+     */
+    @VintfStability
+    parcelable IfaceInfo {
+        /**
+         * Name of the interface (ex. wlan0).
+         */
+        String name;
+        /**
+         * Wifi channel on which this interface is operating.
+         */
+        int channel;
+    }
+
+    /**
+     * Struct describing the state of each hardware radio chain (hardware MAC)
+     * on the device.
+     */
+    @VintfStability
+    parcelable RadioModeInfo {
+        /**
+         * Identifier for this radio chain. This is vendor dependent and used
+         * only for debugging purposes.
+         */
+        int radioId;
+        /**
+         * List of bands on which this radio chain is operating.
+         * Can be one of:
+         * a) |WifiBand.BAND_24GHZ| => 2.4Ghz.
+         * b) |WifiBand.BAND_5GHZ| => 5Ghz.
+         * c) |WifiBand.BAND_24GHZ_5GHZ| => 2.4Ghz + 5Ghz (Radio is time sharing
+         * across the 2 bands).
+         * d) |WifiBand.BAND_6GHZ| => 6Ghz.
+         * e) |WifiBand.BAND_5GHZ_6GHZ| => 5Ghz + 6Ghz (Radio is time sharing
+         * across the 2 bands).
+         * f) |WifiBand.BAND_24GHZ_5GHZ_6GHZ| => 2.4Ghz + 5Ghz + 6Ghz (Radio is
+         * time sharing across the 3 bands).
+         */
+        WifiBand bandInfo;
+        /**
+         * List of interfaces on this radio chain (hardware MAC).
+         */
+        IfaceInfo[] ifaceInfos;
+    }
+
+    /**
+     * Callback indicating that a chip reconfiguration failed. This is a fatal
+     * error and any iface objects available previously must be considered
+     * invalid. The client can attempt to recover by trying to reconfigure the
+     * chip again using |IWifiChip.configureChip|.
+     *
+     * @param status Failure reason code.
+     */
+    void onChipReconfigureFailure(in WifiStatusCode status);
+
+    /**
+     * Callback indicating that the chip has been reconfigured successfully. At
+     * this point the interfaces available in the mode must be able to be
+     * configured. When this is called, any previous iface objects must be
+     * considered invalid.
+     *
+     * @param modeId The mode that the chip switched to, corresponding to the id
+     *        property of the target ChipMode.
+     */
+    void onChipReconfigured(in int modeId);
+
+    /**
+     * Callback indicating that the chip has encountered a fatal error.
+     * Client must not attempt to parse either the errorCode or debugData.
+     * Must only be captured in a bugreport.
+     *
+     * @param errorCode Vendor defined error code.
+     * @param debugData Vendor defined data used for debugging.
+     */
+    void onDebugErrorAlert(in int errorCode, in byte[] debugData);
+
+    /**
+     * Callbacks for reporting debug ring buffer data.
+     *
+     * The ring buffer data collection is event based:
+     * - Driver calls this callback when new records are available, the
+     *   |WifiDebugRingBufferStatus| passed up to framework in the callback
+     *   indicates to framework if more data is available in the ring buffer.
+     *   It is not expected that driver will necessarily always empty the ring
+     *   immediately as data is available. Instead the driver will report data
+     *   every X seconds, or if N bytes are available, based on the parameters
+     *   set via |startLoggingToDebugRingBuffer|.
+     * - In the case where a bug report has to be captured, the framework will
+     *   require driver to upload all data immediately. This is indicated to
+     *   driver when framework calls |forceDumpToDebugRingBuffer|. The driver
+     *   will start sending all available data in the indicated ring by repeatedly
+     *   invoking this callback.
+     *
+     * @param status Status of the corresponding ring buffer. This should
+     *         contain the name of the ring buffer on which the data is
+     *         available.
+     * @param data Raw bytes of data sent by the driver. Must be dumped
+     *         out to a bugreport and post processed.
+     */
+    void onDebugRingBufferDataAvailable(in WifiDebugRingBufferStatus status, in byte[] data);
+
+    /**
+     * Callback indicating that a new iface has been added to the chip.
+     *
+     * @param type Type of iface added.
+     * @param name Name of iface added.
+     */
+    void onIfaceAdded(in IfaceType type, in String name);
+
+    /**
+     * Callback indicating that an existing iface has been removed from the chip.
+     *
+     * @param type Type of iface removed.
+     * @param name Name of iface removed.
+     */
+    void onIfaceRemoved(in IfaceType type, in String name);
+
+    /**
+     * Indicates a radio mode change.
+     * Radio mode change could be a result of:
+     * a) Bringing up concurrent interfaces (ex. STA + AP).
+     * b) Change in operating band of one of the concurrent interfaces
+     * ( ex. STA connection moved from 2.4G to 5G)
+     *
+     * @param radioModeInfos List of RadioModeInfo structures for each
+     *        radio chain (hardware MAC) on the device.
+     */
+    void onRadioModeChange(in RadioModeInfo[] radioModeInfos);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiEventCallback.aidl
new file mode 100644
index 0000000..761bbf5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiEventCallback.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiStatusCode;
+
+@VintfStability
+oneway interface IWifiEventCallback {
+    /**
+     * Called when the Wi-Fi system failed in a way that caused it be disabled.
+     * Calling start again must restart Wi-Fi as if stop then start was called
+     * (full state reset). When this event is received all IWifiChip & IWifiIface
+     * objects retrieved after the last call to start will be considered invalid.
+     *
+     * @param status Failure reason code.
+     */
+    void onFailure(in WifiStatusCode status);
+
+    /**
+     * Called in response to a call to start indicating that the operation
+     * completed. After this callback the HAL must be fully operational.
+     */
+    void onStart();
+
+    /**
+     * Called in response to a call to stop indicating that the operation
+     * completed. When this event is received all IWifiChip objects retrieved
+     * after the last call to start will be considered invalid.
+     */
+    void onStop();
+
+    /**
+     * Must be called when the Wi-Fi subsystem restart completes.
+     * Once this event is received, framework must fully reset the Wi-Fi stack state.
+     *
+     * @param status Status code.
+     */
+    void onSubsystemRestart(in WifiStatusCode status);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl
new file mode 100644
index 0000000..e5bb34e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.IWifiNanIfaceEventCallback;
+import android.hardware.wifi.NanBootstrappingRequest;
+import android.hardware.wifi.NanBootstrappingResponse;
+import android.hardware.wifi.NanConfigRequest;
+import android.hardware.wifi.NanConfigRequestSupplemental;
+import android.hardware.wifi.NanEnableRequest;
+import android.hardware.wifi.NanInitiateDataPathRequest;
+import android.hardware.wifi.NanPairingRequest;
+import android.hardware.wifi.NanPublishRequest;
+import android.hardware.wifi.NanRespondToDataPathIndicationRequest;
+import android.hardware.wifi.NanRespondToPairingIndicationRequest;
+import android.hardware.wifi.NanSubscribeRequest;
+import android.hardware.wifi.NanTransmitFollowupRequest;
+
+/**
+ * Interface used to represent a single NAN (Neighbour Aware Network) iface.
+ *
+ * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness
+ * Networking (NAN) Technical Specification".
+ */
+@VintfStability
+interface IWifiNanIface {
+    /**
+     * Minimum length of Passphrase argument for a data-path configuration.
+     */
+    const int MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 8;
+
+    /**
+     * Maximum length of Passphrase argument for a data-path configuration.
+     */
+    const int MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 63;
+
+    /**
+     * Get the name of this iface.
+     *
+     * @return Name of this iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    String getName();
+
+    /**
+     * Configures an existing NAN functionality (i.e. assumes
+     * |IWifiNanIface.enableRequest| already submitted and succeeded).
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyConfigResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg1 Instance of |NanConfigRequest|.
+     * @param msg2 Instance of |NanConfigRequestSupplemental|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void configRequest(
+            in char cmdId, in NanConfigRequest msg1, in NanConfigRequestSupplemental msg2);
+
+    /**
+     * Create a NAN Data Interface.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyCreateDataInterfaceResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param ifaceName The name of the interface, e.g. "aware0".
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void createDataInterfaceRequest(in char cmdId, in String ifaceName);
+
+    /**
+     * Delete a NAN Data Interface.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyDeleteDataInterfaceResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param ifaceName The name of the interface, e.g. "aware0".
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void deleteDataInterfaceRequest(in char cmdId, in String ifaceName);
+
+    /**
+     * Disable NAN functionality.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyDisableResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void disableRequest(in char cmdId);
+
+    /**
+     * Configures and activates NAN clustering (does not start
+     * a discovery session or set up data-interfaces or data-paths). Use the
+     * |IWifiNanIface.configureRequest| method to change the configuration of an already enabled
+     * NAN interface.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyEnableResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg1 Instance of |NanEnableRequest|.
+     * @param msg2 Instance of |NanConfigRequestSupplemental|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void enableRequest(
+            in char cmdId, in NanEnableRequest msg1, in NanConfigRequestSupplemental msg2);
+
+    /**
+     * Get NAN capabilities. Asynchronous response is with
+     * |IWifiNanIfaceEventCallback.notifyCapabilitiesResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void getCapabilitiesRequest(in char cmdId);
+
+    /**
+     * Initiate a data-path (NDP) setup operation: Initiator.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyInitiateDataPathResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanInitiateDataPathRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void initiateDataPathRequest(in char cmdId, in NanInitiateDataPathRequest msg);
+
+    /**
+     * Requests notifications of significant events on this iface. Multiple calls
+     * to this must register multiple callbacks, each of which must receive all
+     * events.
+     *
+     * @param callback An instance of the |IWifiNanIfaceEventCallback| AIDL interface
+     *        object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    void registerEventCallback(in IWifiNanIfaceEventCallback callback);
+
+    /**
+     * Respond to a received data indication as part of a data-path (NDP) setup operation.
+     * An indication is received by the Responder from the Initiator.
+     * Asynchronous response is with
+     * |IWifiNanIfaceEventCallback.notifyRespondToDataPathIndicationResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanRespondToDataPathIndicationRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void respondToDataPathIndicationRequest(
+            in char cmdId, in NanRespondToDataPathIndicationRequest msg);
+
+    /**
+     * Publish request to start advertising a discovery service.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyStartPublishResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanPublishRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startPublishRequest(in char cmdId, in NanPublishRequest msg);
+
+    /**
+     * Subscribe request to start searching for a discovery service.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyStartSubscribeResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanSubscribeRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startSubscribeRequest(in char cmdId, in NanSubscribeRequest msg);
+
+    /**
+     * Stop publishing a discovery service.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyStopPublishResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param sessionId ID of the publish discovery session to be stopped.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopPublishRequest(in char cmdId, in byte sessionId);
+
+    /**
+     * Stop subscribing to a discovery service.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyStopSubscribeResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param sessionId ID of the subscribe discovery session to be stopped.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopSubscribeRequest(in char cmdId, in byte sessionId);
+
+    /**
+     * Data-path (NDP) termination request. Executed by either Initiator or Responder.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyTerminateDataPathResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param ndpInstanceId Data-path instance ID to be terminated.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void terminateDataPathRequest(in char cmdId, in int ndpInstanceId);
+
+    /**
+     * Start the suspension of a discovery service. During the suspend state, the Wi-Fi Aware
+     * device must not transmit or receive frames for this session including any active NDPs. If
+     * all discovery sessions are suspended then the Wi-Fi Aware device must not transmit or
+     * receive any Wi-Fi Aware frames.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifySuspendResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param sessionId ID of the publish/subscribe discovery session to be suspended.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void suspendRequest(in char cmdId, in byte sessionId);
+
+    /**
+     * Stop the suspension of a discovery service. Resume cancels an ongoing suspend for this Wi-Fi
+     * Aware discovery session and automatically resumes the session and any associated NDPs to the
+     * state before they were suspended. The Wi-Fi Aware resume operation should be faster than
+     * recreating the corresponding discovery session and NDPs with the same benefit of power.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyResumeResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param sessionId ID of the publish/subscribe discovery session to be resumed.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void resumeRequest(in char cmdId, in byte sessionId);
+
+    /**
+     * NAN transmit follow up message request.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyTransmitFollowupResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanTransmitFollowupRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void transmitFollowupRequest(in char cmdId, in NanTransmitFollowupRequest msg);
+
+    /**
+     * Initiate a NAN pairing operation: Initiator.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyInitiatePairingResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanPairingRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void initiatePairingRequest(in char cmdId, in NanPairingRequest msg);
+
+    /**
+     * Respond to a received request indication of NAN pairing setup operation.
+     * An indication is received by the Responder from the Initiator.
+     * Asynchronous response is with
+     * |IWifiNanIfaceEventCallback.notifyRespondToPairingIndicationResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanRespondToPairingIndicationRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void respondToPairingIndicationRequest(
+            in char cmdId, in NanRespondToPairingIndicationRequest msg);
+
+    /**
+     * Initiate a NAN pairing bootstrapping operation: Initiator.
+     * Asynchronous response is with
+     * |IWifiNanIfaceEventCallback.notifyInitiateBootstrappingResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanBootstrappingRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void initiateBootstrappingRequest(in char cmdId, in NanBootstrappingRequest msg);
+
+    /**
+     * Respond to a received request indication of NAN pairing bootstrapping operation.
+     * An indication is received by the Responder from the Initiator.
+     * Asynchronous response is with
+     * |IWifiNanIfaceEventCallback.notifyRespondToPairingIndicationResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |notifyRespondToBootstrappingIndicationResponse|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void respondToBootstrappingIndicationRequest(in char cmdId, in NanBootstrappingResponse msg);
+
+    /**
+     * Aware pairing termination request. Executed by either the Initiator or Responder.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyTerminatePairingResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param pairingInstanceId Pairing instance ID to be terminated.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void terminatePairingRequest(in char cmdId, in int pairingInstanceId);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
new file mode 100644
index 0000000..3649b7b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanBootstrappingConfirmInd;
+import android.hardware.wifi.NanBootstrappingRequestInd;
+import android.hardware.wifi.NanCapabilities;
+import android.hardware.wifi.NanClusterEventInd;
+import android.hardware.wifi.NanDataPathConfirmInd;
+import android.hardware.wifi.NanDataPathRequestInd;
+import android.hardware.wifi.NanDataPathScheduleUpdateInd;
+import android.hardware.wifi.NanFollowupReceivedInd;
+import android.hardware.wifi.NanMatchInd;
+import android.hardware.wifi.NanPairingConfirmInd;
+import android.hardware.wifi.NanPairingRequestInd;
+import android.hardware.wifi.NanStatus;
+import android.hardware.wifi.NanSuspensionModeChangeInd;
+/**
+ * NAN Response and Asynchronous Event Callbacks.
+ *
+ * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness
+ * Networking (NAN) Technical Specification".
+ */
+@VintfStability
+oneway interface IWifiNanIfaceEventCallback {
+    /**
+     * Callback indicating that a cluster event has been received.
+     *
+     * @param event NanClusterEventInd containing event details.
+     */
+    void eventClusterEvent(in NanClusterEventInd event);
+
+    /**
+     * Callback indicating that a data-path (NDP) setup has been completed.
+     * Received by both Initiator and Responder.
+     *
+     * @param event NanDataPathConfirmInd containing event details.
+     */
+    void eventDataPathConfirm(in NanDataPathConfirmInd event);
+
+    /**
+     * Callback indicating that a data-path (NDP) setup has been requested by
+     * an Initiator peer (received by the intended Responder).
+     *
+     * @param event NanDataPathRequestInd containing event details.
+     */
+    void eventDataPathRequest(in NanDataPathRequestInd event);
+
+    /**
+     * Callback indicating that a data-path (NDP) schedule has been updated
+     * (e.g. channels have been changed).
+     *
+     * @param event NanDataPathScheduleUpdateInd containing event details.
+     */
+    void eventDataPathScheduleUpdate(in NanDataPathScheduleUpdateInd event);
+
+    /**
+     * Callback indicating that a list of data-paths (NDP) have been terminated.
+     * Received by both Initiator and Responder.
+     *
+     * @param ndpInstanceId Data-path ID of the terminated data-path.
+     */
+    void eventDataPathTerminated(in int ndpInstanceId);
+
+    /**
+     * Callback indicating that a NAN has been disabled.
+     *
+     * @param status NanStatus describing the reason for the disable event.
+     *               Possible status codes are:
+     *               |NanStatusCode.SUCCESS|
+     *               |NanStatusCode.UNSUPPORTED_CONCURRENCY_NAN_DISABLED|
+     */
+    void eventDisabled(in NanStatus status);
+
+    /**
+     * Callback indicating that a followup message has been received from a peer.
+     *
+     * @param event NanFollowupReceivedInd containing event details.
+     */
+    void eventFollowupReceived(in NanFollowupReceivedInd event);
+
+    /**
+     * Callback indicating that a match has occurred: i.e. a service has been
+     * discovered.
+     *
+     * @param event NanMatchInd containing event details.
+     */
+    void eventMatch(in NanMatchInd event);
+
+    /**
+     * Callback indicating that a previously discovered match (service) has expired.
+     *
+     * @param discoverySessionId Discovery session ID of the expired match.
+     * @param peerId Peer ID of the expired match.
+     */
+    void eventMatchExpired(in byte discoverySessionId, in int peerId);
+
+    /**
+     * Callback indicating that an active publish session has terminated.
+     *
+     * @param sessionId Discovery session ID of the terminated session.
+     * @param status NanStatus describing the reason for the session termination.
+     *               Possible status codes are:
+     *               |NanStatusCode.SUCCESS|
+     */
+    void eventPublishTerminated(in byte sessionId, in NanStatus status);
+
+    /**
+     * Callback indicating that an active subscribe session has terminated.
+     *
+     * @param sessionId Discovery session ID of the terminated session.
+     * @param status NanStatus describing the reason for the session termination.
+     *               Possible status codes are:
+     *               |NanStatusCode.SUCCESS|
+     */
+    void eventSubscribeTerminated(in byte sessionId, in NanStatus status);
+
+    /**
+     * Callback providing status on a completed followup message transmit operation.
+     *
+     * @param id Command ID corresponding to the original |transmitFollowupRequest| request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *               |NanStatusCode.SUCCESS|
+     *               |NanStatusCode.NO_OTA_ACK|
+     *               |NanStatusCode.PROTOCOL_FAILURE|
+     */
+    void eventTransmitFollowup(in char id, in NanStatus status);
+
+    /**
+     * Callback indicating that device suspension mode status change
+     *
+     * @param event NanSuspensionModeChangeInd containing event details.
+     */
+    void eventSuspensionModeChanged(in NanSuspensionModeChangeInd event);
+
+    /**
+     * Callback invoked in response to a capability request
+     * |IWifiNanIface.getCapabilitiesRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     * @param capabilities Capability data.
+     */
+    void notifyCapabilitiesResponse(
+            in char id, in NanStatus status, in NanCapabilities capabilities);
+
+    /**
+     * Callback invoked in response to a config request |IWifiNanIface.configRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     */
+    void notifyConfigResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a create data interface request
+     * |IWifiNanIface.createDataInterfaceRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifyCreateDataInterfaceResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a delete data interface request
+     * |IWifiNanIface.deleteDataInterfaceRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifyDeleteDataInterfaceResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a disable request |IWifiNanIface.disableRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     */
+    void notifyDisableResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to an enable request |IWifiNanIface.enableRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.ALREADY_ENABLED|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.NAN_NOT_ALLOWED|
+     */
+    void notifyEnableResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to an initiate data path request
+     * |IWifiNanIface.initiateDataPathRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_PEER_ID|
+     * @param ndpInstanceId ID of the new data path being negotiated (on successful status).
+     */
+    void notifyInitiateDataPathResponse(in char id, in NanStatus status, in int ndpInstanceId);
+
+    /**
+     * Callback invoked in response to a respond to data path indication request
+     * |IWifiNanIface.respondToDataPathIndicationRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_NDP_ID|
+     */
+    void notifyRespondToDataPathIndicationResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked to notify the status of the start publish request
+     * |IWifiNanIface.startPublishRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.NO_RESOURCES_AVAILABLE|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     * @param sessionId ID of the new publish session (if successfully created).
+     */
+    void notifyStartPublishResponse(in char id, in NanStatus status, in byte sessionId);
+
+    /**
+     * Callback invoked to notify the status of the start subscribe request
+     * |IWifiNanIface.startSubscribeRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.NO_RESOURCES_AVAILABLE|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     * @param sessionId ID of the new subscribe session (if successfully created).
+     */
+    void notifyStartSubscribeResponse(in char id, in NanStatus status, in byte sessionId);
+
+    /**
+     * Callback invoked in response to a stop publish request
+     * |IWifiNanIface.stopPublishRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifyStopPublishResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a stop subscribe request
+     * |IWifiNanIface.stopSubscribeRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifyStopSubscribeResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a terminate data path request
+     * |IWifiNanIface.terminateDataPathRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_NDP_ID|
+     */
+    void notifyTerminateDataPathResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a suspension request
+     * |IWifiNanIface.suspendRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     *        |NanStatusCode.INVALID_STATE|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifySuspendResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a resume request
+     * |IWifiNanIface.resumeRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     *        |NanStatusCode.INVALID_STATE|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifyResumeResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a transmit followup request
+     * |IWifiNanIface.transmitFollowupRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     *        |NanStatusCode.INVALID_PEER_ID|
+     *        |NanStatusCode.FOLLOWUP_TX_QUEUE_FULL|
+     */
+    void notifyTransmitFollowupResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback indicating that a NAN pairing setup/verification has been requested by
+     * an Initiator peer (received by the intended Responder).
+     *
+     * @param event NanPairingRequestInd containing event details.
+     */
+    void eventPairingRequest(in NanPairingRequestInd event);
+
+    /**
+     * Callback indicating that a NAN pairing setup/verification has been completed.
+     * Received by both Initiator and Responder.
+     *
+     * @param event NanPairingConfirmInd containing event details.
+     */
+    void eventPairingConfirm(in NanPairingConfirmInd event);
+
+    /**
+     * Callback invoked in response to an initiate NAN pairing request
+     * |IWifiNanIface.initiatePairingRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_PEER_ID|
+     * @param pairingInstanceId ID of the new pairing being negotiated (on successful status).
+     */
+    void notifyInitiatePairingResponse(in char id, in NanStatus status, in int pairingInstanceId);
+
+    /**
+     * Callback invoked in response to a respond to NAN pairing indication request
+     * |IWifiNanIface.respondToPairingIndicationRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_NDP_ID|
+     */
+    void notifyRespondToPairingIndicationResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback indicating that a NAN bootstrapping setup has been requested by
+     * an Initiator peer (received by the intended Responder).
+     *
+     * @param event NanBootstrappingRequestInd containing event details.
+     */
+    void eventBootstrappingRequest(in NanBootstrappingRequestInd event);
+
+    /**
+     * Callback indicating that a NAN bootstrapping setuphas been completed.
+     * Received by Initiator.
+     *
+     * @param event NanBootstrappingConfirmInd containing event details.
+     */
+    void eventBootstrappingConfirm(in NanBootstrappingConfirmInd event);
+
+    /**
+     * Callback invoked in response to an initiate NAN pairing bootstrapping request
+     * |IWifiNanIface.initiateBootstrappingRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_PEER_ID|
+     * @param bootstrappingInstanceId ID of the new pairing being negotiated (on successful status).
+     */
+    void notifyInitiateBootstrappingResponse(
+            in char id, in NanStatus status, in int bootstrappingInstanceId);
+
+    /**
+     * Callback invoked in response to a respond to pairing bootstrapping indication request
+     * |IWifiNanIface.respondToBootstrappingIndicationRequest|.
+     *
+     * @param id Command ID corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_NDP_ID|
+     */
+    void notifyRespondToBootstrappingIndicationResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a terminate pairing request
+     * |IWifiNanIface.terminatePairingRequest|.
+     *
+     * @param id Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_PAIRING_ID|
+     */
+    void notifyTerminatePairingResponse(in char id, in NanStatus status);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiP2pIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiP2pIface.aidl
new file mode 100644
index 0000000..287f41d
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiP2pIface.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Interface used to represent a single P2P iface.
+ */
+@VintfStability
+interface IWifiP2pIface {
+    /**
+     * Get the name of this iface.
+     *
+     * @return Name of this iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    String getName();
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiRttController.aidl b/wifi/aidl/android/hardware/wifi/IWifiRttController.aidl
new file mode 100644
index 0000000..99e1a81
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiRttController.aidl
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.IWifiRttControllerEventCallback;
+import android.hardware.wifi.IWifiStaIface;
+import android.hardware.wifi.MacAddress;
+import android.hardware.wifi.RttCapabilities;
+import android.hardware.wifi.RttConfig;
+import android.hardware.wifi.RttLciInformation;
+import android.hardware.wifi.RttLcrInformation;
+import android.hardware.wifi.RttResponder;
+import android.hardware.wifi.WifiChannelInfo;
+
+/**
+ * Interface used to perform RTT (Round trip time) operations.
+ */
+@VintfStability
+interface IWifiRttController {
+    /**
+     * Disable RTT responder mode.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void disableResponder(in int cmdId);
+
+    /**
+     * Enable RTT responder mode.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @parm channelHint Hint for the channel information where RTT responder
+     *       must be enabled on.
+     * @param maxDurationInSeconds Timeout of responder mode.
+     * @param info Instance of |RttResponderInfo|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void enableResponder(in int cmdId, in WifiChannelInfo channelHint, in int maxDurationInSeconds,
+            in RttResponder info);
+
+    /**
+     * Get the iface on which the RTT operations must be performed.
+     *
+     * @return AIDL interface object representing the iface if bound
+     *         to a specific iface, null otherwise
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|
+     */
+    IWifiStaIface getBoundIface();
+
+    /**
+     * RTT capabilities of the device.
+     *
+     * @return Instance of |RttCapabilities|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    RttCapabilities getCapabilities();
+
+    /**
+     * Get RTT responder information (e.g. WiFi channel) to enable responder on.
+     *
+     * @return Instance of |RttResponderInfo|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    RttResponder getResponderInfo();
+
+    /**
+     * API to cancel RTT measurements.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param addrs Vector of addresses for which to cancel.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void rangeCancel(in int cmdId, in MacAddress[] addrs);
+
+    /**
+     * API to request RTT measurement.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param rttConfigs Vector of |RttConfig| parameters.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void rangeRequest(in int cmdId, in RttConfig[] rttConfigs);
+
+    /**
+     * Requests notifications of significant events on this RTT controller.
+     * Multiple calls to this must register multiple callbacks, each of which
+     * must receive all events.
+     *
+     * @param callback An instance of the |IWifiRttControllerEventCallback| AIDL
+     *        interface object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    void registerEventCallback(in IWifiRttControllerEventCallback callback);
+
+    /**
+     * API to configure the LCI (Location civic information).
+     * Used in RTT Responder mode only.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param lci Instance of |RttLciInformation|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setLci(in int cmdId, in RttLciInformation lci);
+
+    /**
+     * API to configure the LCR (Location civic records).
+     * Used in RTT Responder mode only.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param lcr Instance of |RttLcrInformation|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setLcr(in int cmdId, in RttLcrInformation lcr);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiRttControllerEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
new file mode 100644
index 0000000..89f0ed8
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.RttResult;
+
+/**
+ * RTT Response and Event Callbacks.
+ */
+@VintfStability
+oneway interface IWifiRttControllerEventCallback {
+    /**
+     * Invoked when an RTT result is available.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param results Vector of |RttResult| instances.
+     */
+    void onResults(in int cmdId, in RttResult[] results);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
new file mode 100644
index 0000000..6d6afaf
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
@@ -0,0 +1,555 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.IWifiStaIfaceEventCallback;
+import android.hardware.wifi.StaApfPacketFilterCapabilities;
+import android.hardware.wifi.StaBackgroundScanCapabilities;
+import android.hardware.wifi.StaBackgroundScanParameters;
+import android.hardware.wifi.StaLinkLayerStats;
+import android.hardware.wifi.StaRoamingCapabilities;
+import android.hardware.wifi.StaRoamingConfig;
+import android.hardware.wifi.StaRoamingState;
+import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiDebugRxPacketFateReport;
+import android.hardware.wifi.WifiDebugTxPacketFateReport;
+
+/**
+ * Interface used to represent a single STA iface.
+ */
+@VintfStability
+interface IWifiStaIface {
+    /**
+     * Mask of capabilities supported by this iface.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum FeatureSetMask {
+        /**
+         * Support for APF APIs. APF (Android Packet Filter) is a
+         * BPF-like packet filtering bytecode executed by the firmware.
+         */
+        APF = 1 << 0,
+        /**
+         * Support for Background Scan APIs. Background scan allows the host
+         * to send a number of buckets down to the firmware. Each bucket
+         * contains a set of channels, a period, and some parameters about
+         * how and when to report results.
+         */
+        BACKGROUND_SCAN = 1 << 1,
+        /**
+         * Support for link layer stats APIs.
+         */
+        LINK_LAYER_STATS = 1 << 2,
+        /**
+         * Support for RSSI monitor APIs.
+         */
+        RSSI_MONITOR = 1 << 3,
+        /**
+         * Support for roaming APIs.
+         */
+        CONTROL_ROAMING = 1 << 4,
+        /**
+         * Support for Probe IE allow-listing.
+         */
+        PROBE_IE_ALLOWLIST = 1 << 5,
+        /**
+         * Support for MAC & Probe Sequence Number randomization.
+         */
+        SCAN_RAND = 1 << 6,
+        /**
+         * Support for 5 GHz Band.
+         */
+        STA_5G = 1 << 7,
+        /**
+         * Support for GAS/ANQP queries.
+         */
+        HOTSPOT = 1 << 8,
+        /**
+         * Support for Preferred Network Offload.
+         */
+        PNO = 1 << 9,
+        /**
+         * Support for Tunneled Direct Link Setup.
+         */
+        TDLS = 1 << 10,
+        /**
+         * Support for Tunneled Direct Link Setup off channel.
+         */
+        TDLS_OFFCHANNEL = 1 << 11,
+        /**
+         * Support for neighbour discovery offload.
+         */
+        ND_OFFLOAD = 1 << 12,
+        /**
+         * Support for keep alive packet offload.
+         */
+        KEEP_ALIVE = 1 << 13,
+    }
+
+    /**
+     * Get the name of this iface.
+     *
+     * @return Name of this iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    String getName();
+
+    /**
+     * Configure roaming control parameters.
+     * Must fail if |StaIfaceCapabilityMask.CONTROL_ROAMING| is not set.
+     *
+     * @param config Instance of |StaRoamingConfig|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void configureRoaming(in StaRoamingConfig config);
+
+    /**
+     * Disable link layer stats collection.
+     * Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void disableLinkLayerStatsCollection();
+
+    /**
+     * Enable link layer stats collection.
+     * Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set.
+     *
+     * Radio statistics (once started) must not stop until disabled.
+     * Iface statistics (once started) reset and start afresh after each
+     * connection until disabled.
+     *
+     * @param debug true to enable field debug mode, false to disable. Driver
+     *        must collect all statistics regardless of performance impact.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void enableLinkLayerStatsCollection(in boolean debug);
+
+    /**
+     * Enable/Disable neighbour discovery offload functionality in the firmware.
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void enableNdOffload(in boolean enable);
+
+    /**
+     * Used to query additional information about the chip's APF capabilities.
+     * Must fail if |StaIfaceCapabilityMask.APF| is not set.
+     *
+     * @return Instance of |StaApfPacketFilterCapabilities|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaApfPacketFilterCapabilities getApfPacketFilterCapabilities();
+
+    /**
+     * Used to query additional information about the chip's Background Scan capabilities.
+     * Must fail if |StaIfaceCapabilityMask.BACKGROUND_SCAN| is not set.
+     *
+     * @return Instance of |StaBackgroundScanCapabilities|
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaBackgroundScanCapabilities getBackgroundScanCapabilities();
+
+    /**
+     * Get the features supported by this STA iface.
+     *
+     * @return Bitset of |FeatureSetMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    int getFeatureSet();
+
+    /**
+     * API to retrieve the fates of inbound packets.
+     * - HAL implementation must return the fates of
+     *   all the frames received for the most recent association.
+     *   The fate reports must follow the same order as their respective
+     *   packets.
+     * - HAL implementation may choose (but is not required) to include
+     *   reports for management frames.
+     * - Packets reported by firmware, but not recognized by driver,
+     *   must be included. However, the ordering of the corresponding
+     *   reports is at the discretion of HAL implementation.
+     * - Framework must be able to call this API multiple times for the same
+     *   association.
+     *
+     * @return Vector of |WifiDebugRxPacketFateReport| instances corresponding
+     *         to the packet fates.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    WifiDebugRxPacketFateReport[] getDebugRxPacketFates();
+
+    /**
+     * API to retrieve fates of outbound packets.
+     * - HAL implementation must return the fates of
+     *   all the frames transmitted for the most recent association.
+     *   The fate reports must follow the same order as their respective
+     *   packets.
+     * - HAL implementation may choose (but is not required) to include
+     *   reports for management frames.
+     * - Packets reported by firmware, but not recognized by driver,
+     *   must be included. However, the ordering of the corresponding
+     *   reports is at the discretion of HAL implementation.
+     * - Framework must be able to call this API multiple times for the same
+     *   association.
+     *
+     * @return Vector of |WifiDebugTxPacketFateReport| instances corresponding
+     *         to the packet fates.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    WifiDebugTxPacketFateReport[] getDebugTxPacketFates();
+
+    /**
+     * Gets the factory MAC address of the STA interface.
+     *
+     * @return Factory MAC address of the STA interface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    byte[6] getFactoryMacAddress();
+
+    /**
+     * Retrieve the latest link layer stats.
+     * Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set or if
+     * link layer stats collection hasn't been explicitly enabled.
+     *
+     * @return Instance of |LinkLayerStats|.
+     * @throws ServiceSpecificException with one of the following values:
+     *     |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *     |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *     |WifiStatusCode.ERROR_NOT_STARTED|,
+     *     |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *     |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaLinkLayerStats getLinkLayerStats();
+
+    /**
+     * Get roaming control capabilities.
+     * Must fail if |StaIfaceCapabilityMask.CONTROL_ROAMING| is not set.
+     *
+     * @return Instance of |StaRoamingCapabilities|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaRoamingCapabilities getRoamingCapabilities();
+
+    /**
+     * Installs an APF program on this iface, replacing an existing
+     * program if present.
+     * Must fail if |StaIfaceCapabilityMask.APF| is not set.
+     *
+     * APF docs
+     * ==========================================================================
+     * APF functionality, instructions and bytecode/binary format is described in:
+     * http://android.googlesource.com/platform/hardware/google/apf/
+     * +/b75c9f3714cfae3dad3d976958e063150781437e/apf.h
+     *
+     * The interpreter API is described here:
+     * http://android.googlesource.com/platform/hardware/google/apf/+/
+     * b75c9f3714cfae3dad3d976958e063150781437e/apf_interpreter.h#32
+     *
+     * The assembler/generator API is described in javadocs here:
+     * http://android.googlesource.com/platform/frameworks/base/+/
+     * 4456f33a958a7f09e608399da83c4d12b2e7d191/services/net/java/android/net/
+     * apf/ApfGenerator.java
+     *
+     * Disassembler usage is described here:
+     * http://android.googlesource.com/platform/hardware/google/apf/+/
+     * b75c9f3714cfae3dad3d976958e063150781437e/apf_disassembler.c#65
+     *
+     * The BPF to APF translator usage is described here:
+     * http://android.googlesource.com/platform/frameworks/base/+/
+     * 4456f33a958a7f09e608399da83c4d12b2e7d191/tests/net/java/android/net/
+     * apf/Bpf2Apf.java
+     * ==========================================================================
+     *
+     * @param program APF Program to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void installApfPacketFilter(in byte[] program);
+
+    /**
+     * Fetches a consistent snapshot of the entire APF program and working
+     * memory buffer and returns it to the host. The returned buffer contains
+     * both code and data. Its length must match the most recently returned
+     * |StaApfPacketFilterCapabilities.maxLength|.
+     *
+     * While the snapshot is being fetched, the APF interpreter must not execute
+     * and all incoming packets must be passed to the host as if there was no
+     * APF program installed.
+     *
+     * Must fail with |WifiStatusCode.ERROR_NOT_SUPPORTED| if
+     * |StaIfaceCapabilityMask.APF| is not set.
+     *
+     * @return The entire APF working memory buffer when status is
+     *         |WifiStatusCode.SUCCESS|, empty otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     * @see getApfPacketFilterCapabilities()
+     * @see installApfPacketFilter()
+     */
+    byte[] readApfPacketFilterData();
+
+    /**
+     * Requests notifications of significant events on this iface. Multiple calls
+     * to this must register multiple callbacks, each of which must receive all
+     * events.
+     *
+     * @param callback An instance of the |IWifiStaIfaceEventCallback| AIDL
+     *        interface object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    void registerEventCallback(in IWifiStaIfaceEventCallback callback);
+
+    /**
+     * Changes the MAC address of the STA Interface to the given
+     * MAC address.
+     *
+     * @param mac MAC address to change to.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setMacAddress(in byte[6] mac);
+
+    /**
+     * Set the roaming control state with the parameters configured
+     * using |configureRoaming|. Depending on the roaming state set, the
+     * driver/firmware would enable/disable control over roaming decisions.
+     * Must fail if |StaIfaceCapabilityMask.CONTROL_ROAMING| is not set.
+     *
+     * @param state State of the roaming control.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_BUSY|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setRoamingState(in StaRoamingState state);
+
+    /**
+     * Turn on/off scan only mode for the interface.
+     *
+     * @param enable True to enable scan only mode, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     */
+    void setScanMode(in boolean enable);
+
+    /**
+     * Start a background scan using the given cmdId as an identifier. Only one
+     * active background scan need be supported.
+     * Must fail if |StaIfaceCapabilityMask.BACKGROUND_SCAN| is not set.
+     *
+     * When this is called all requested buckets must be scanned, starting the
+     * beginning of the cycle.
+     *
+     * For example:
+     * If there are two buckets specified
+     *  - Bucket 1: period=10s
+     *  - Bucket 2: period=20s
+     *  - Bucket 3: period=30s
+     * Then the following scans must occur
+     *  - t=0  buckets 1, 2, and 3 are scanned
+     *  - t=10 bucket 1 is scanned
+     *  - t=20 bucket 1 and 2 are scanned
+     *  - t=30 bucket 1 and 3 are scanned
+     *  - t=40 bucket 1 and 2 are scanned
+     *  - t=50 bucket 1 is scanned
+     *  - t=60 buckets 1, 2, and 3 are scanned
+     *  - and the pattern repeats
+     *
+     * If any scan does not occur or is incomplete (error, interrupted, etc),
+     * then a cached scan result must still be recorded with the
+     * WIFI_SCAN_FLAG_INTERRUPTED flag set.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param params Background scan parameters.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startBackgroundScan(in int cmdId, in StaBackgroundScanParameters params);
+
+    /**
+     * API to start packet fate monitoring.
+     * - Once started, monitoring must remain active until HAL is stopped or the
+     *   chip is reconfigured.
+     * - When HAL is unloaded, all packet fate buffers must be cleared.
+     * - The packet fates are used to monitor the state of packets transmitted/
+     *   received during association.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startDebugPacketFateMonitoring();
+
+    /**
+     * Start RSSI monitoring on the currently connected access point.
+     * Once the monitoring is enabled, the
+     * |IWifiStaIfaceEventCallback.onRssiThresholdBreached| callback must be
+     * invoked to indicate if the RSSI goes above |maxRssi| or below |minRssi|.
+     * Must fail if |StaIfaceCapabilityMask.RSSI_MONITOR| is not set.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param maxRssi Maximum RSSI threshold.
+     * @param minRssi Minimum RSSI threshold.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_ARGS_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startRssiMonitoring(in int cmdId, in int maxRssi, in int minRssi);
+
+    /**
+     * Start sending the specified keep alive packets periodically.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param ipPacketData IP packet contents to be transmitted.
+     * @param etherType 16 bit ether type to be set in the ethernet frame
+     *        transmitted.
+     * @param srcAddress Source MAC address of the packet.
+     * @param dstAddress Destination MAC address of the packet.
+     * @param periodInMs Interval at which this packet must be transmitted.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startSendingKeepAlivePackets(in int cmdId, in byte[] ipPacketData, in char etherType,
+            in byte[6] srcAddress, in byte[6] dstAddress, in int periodInMs);
+
+    /**
+     * Stop the current background scan.
+     * Must fail if |StaIfaceCapabilityMask.BACKGROUND_SCAN| is not set.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopBackgroundScan(in int cmdId);
+
+    /**
+     * Stop RSSI monitoring.
+     * Must fail if |StaIfaceCapabilityMask.RSSI_MONITOR| is not set.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopRssiMonitoring(in int cmdId);
+
+    /**
+     * Stop sending the specified keep alive packets.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopSendingKeepAlivePackets(in int cmdId);
+
+    /**
+     * Set maximum acceptable DTIM multiplier to hardware driver.
+     * Any multiplier larger than this maximum value must not be accepted since it will cause
+     * packet loss higher than what the system can accept, which will cause unexpected behavior
+     * for apps, and may interrupt the network connection.
+     *
+     * When STA is in the power saving mode and system is suspended,
+     * the wake up interval will be set to:
+     *              1) multiplier * DTIM period if multiplier > 0.
+     *              2) the driver default value if multiplier <= 0.
+     * Some implementations may apply an additional cap to wake up interval in the case of 1).
+     *
+     * @param multiplier integer maximum DTIM multiplier value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setDtimMultiplier(in int multiplier);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
new file mode 100644
index 0000000..93a255f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.StaScanData;
+import android.hardware.wifi.StaScanResult;
+
+@VintfStability
+oneway interface IWifiStaIfaceEventCallback {
+    /**
+     * Called for each received beacon/probe response for a scan with the
+     * |REPORT_EVENTS_FULL_RESULTS| flag set in
+     * |StaBackgroundScanBucketParameters.eventReportScheme|.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @param bucketsScanned Bitset where each bit indicates if the bucket with
+     *        that index (starting at 0) was scanned.
+     * @param result Full scan result for an AP.
+     */
+    void onBackgroundFullScanResult(in int cmdId, in int bucketsScanned, in StaScanResult result);
+
+    /**
+     * Callback indicating that an ongoing background scan request has failed.
+     * The background scan needs to be restarted to continue scanning.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     */
+    void onBackgroundScanFailure(in int cmdId);
+
+    /**
+     * Called when the |StaBackgroundScanBucketParameters.eventReportScheme| flags
+     * for at least one bucket that was just scanned was
+     * |REPORT_EVENTS_EACH_SCAN|, or one of the configured thresholds was
+     * breached.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @param scanDatas List of scan result for all AP's seen since last callback.
+     */
+    void onBackgroundScanResults(in int cmdId, in StaScanData[] scanDatas);
+
+    /**
+     * Called when the RSSI of the currently connected access point goes beyond the
+     * thresholds set via |IWifiStaIface.startRssiMonitoring|.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @param currBssid BSSID of the currently connected access point.
+     * @param currRssi RSSI of the currently connected access point.
+     */
+    void onRssiThresholdBreached(in int cmdId, in byte[6] currBssid, in int currRssi);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IfaceConcurrencyType.aidl b/wifi/aidl/android/hardware/wifi/IfaceConcurrencyType.aidl
new file mode 100644
index 0000000..26c183c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IfaceConcurrencyType.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * List of interface concurrency types, used in reporting device concurrency capabilities.
+ */
+@VintfStability
+@Backing(type="int")
+enum IfaceConcurrencyType {
+    /**
+     * Concurrency type for station mode.
+     */
+    STA,
+    /**
+     * Concurrency type of single-port AP mode.
+     */
+    AP,
+    /**
+     * Concurrency type of two-port bridged AP mode.
+     */
+    AP_BRIDGED,
+    /**
+     * Concurrency type of peer-to-peer mode.
+     */
+    P2P,
+    /**
+     * Concurrency type of neighborhood area network mode.
+     */
+    NAN_IFACE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/IfaceType.aidl b/wifi/aidl/android/hardware/wifi/IfaceType.aidl
new file mode 100644
index 0000000..c89d94b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IfaceType.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * List of supported interface types.
+ */
+@VintfStability
+@Backing(type="int")
+enum IfaceType {
+    STA,
+    AP,
+    P2P,
+    /**
+     * NAN control interface. Datapath support must be queried and created
+     * through this interface. Declared as 'NAN_IFACE' instead of 'NAN'
+     * because the compiler complains that NAN is already defined by math.h
+     */
+    NAN_IFACE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/MacAddress.aidl b/wifi/aidl/android/hardware/wifi/MacAddress.aidl
new file mode 100644
index 0000000..d238565
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/MacAddress.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Byte array representing a Mac Address. Use when we need to
+ * pass an array of Mac Addresses to a method, as variable-sized
+ * 2D arrays are not supported in AIDL.
+ */
+@VintfStability
+parcelable MacAddress {
+    byte[6] data;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBandIndex.aidl b/wifi/aidl/android/hardware/wifi/NanBandIndex.aidl
new file mode 100644
index 0000000..5da5869
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBandIndex.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * The discovery bands supported by NAN.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanBandIndex {
+    NAN_BAND_24GHZ = 0,
+    NAN_BAND_5GHZ,
+    /**
+     * Index for 6 GHz band.
+     */
+    NAN_BAND_6GHZ = 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBandSpecificConfig.aidl b/wifi/aidl/android/hardware/wifi/NanBandSpecificConfig.aidl
new file mode 100644
index 0000000..2e13486
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBandSpecificConfig.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN band-specific configuration.
+ */
+@VintfStability
+parcelable NanBandSpecificConfig {
+    /**
+     * RSSI values controlling clustering behavior per spec. RSSI values are specified without a
+     * sign, e.g. a value of -65dBm would be specified as 65.
+     */
+    byte rssiClose;
+    byte rssiMiddle;
+    /**
+     * RSSI value determining whether discovery is near (used if enabled in discovery by
+     * |NanDiscoveryCommonConfig.useRssiThreshold|).
+     * RSSI values are specified without a sign, e.g. a value of -65dBm would be specified as 65.
+     * NAN Spec: RSSI_close_proximity
+     */
+    byte rssiCloseProximity;
+    /**
+     * Dwell time of each discovery channel in milliseconds. If set to 0, then the firmware
+     * determines the dwell time to use.
+     */
+    char dwellTimeMs;
+    /**
+     * Scan period of each discovery channel in seconds. If set to 0, then the firmware determines
+     * the scan period to use.
+     */
+    char scanPeriodSec;
+    /**
+     * Specifies the discovery window interval for Sync beacons and SDF's.
+     * Valid values of DW Interval are: 1, 2, 3, 4 and 5 corresponding to 1, 2, 4, 8, and 16 DWs.
+     * Value of 0:
+     *  - reserved in 2.4GHz band
+     *  - no wakeup at all in 5GHz band
+     * The publish/subscribe period values don't override the device level configurations if
+     * they are specified.
+     * Configuration is only used only if |validDiscoveryWindowIntervalVal| is set to true.
+     * NAN Spec: Device Capability Attribute / 2.4 GHz DW, Device Capability Attribute / 5 GHz DW
+     */
+    boolean validDiscoveryWindowIntervalVal;
+    byte discoveryWindowIntervalVal;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingConfirmInd.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
new file mode 100644
index 0000000..e72c940
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanBootstrappingResponseCode;
+import android.hardware.wifi.NanStatus;
+
+/**
+ * See Wi-Fi Aware R4.0 section 9.5.21.7
+ */
+@VintfStability
+parcelable NanBootstrappingConfirmInd {
+    /**
+     * Id of the bootstrapping session. Obtained as part of earlier
+     |IWifiNanIface.initiateBootstrappingRequest| success notification.
+     */
+    int bootstrappingInstanceId;
+
+    /**
+     * Indicate whether the bootstrapping method negotiation accept or not
+     */
+    NanBootstrappingResponseCode responseCode;
+
+    /**
+     * Failure reason if |acceptRequest| is false.
+     */
+    NanStatus reasonCode;
+
+    /**
+     * The delay of bootstrapping in seconds for the follow up request.
+     */
+    int comeBackDelay;
+
+    /**
+     * Cookie received from peer with |comeBackDelay| for follow up |NanBootstrappingRequest|
+     */
+    byte[] cookie;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingMethod.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingMethod.aidl
new file mode 100644
index 0000000..da2ff25
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingMethod.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Pairing bootstrapping method flag.
+ * See Wi-Fi Aware R4.0 section 9.5.21.7 table 128
+ */
+@VintfStability
+@Backing(type="int")
+enum NanBootstrappingMethod {
+    BOOTSTRAPPING_OPPORTUNISTIC_MASK = 1 << 0,
+    BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK = 1 << 1,
+    BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK = 1 << 2,
+    BOOTSTRAPPING_QR_DISPLAY_MASK = 1 << 3,
+    BOOTSTRAPPING_NFC_TAG_MASK = 1 << 4,
+    BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK = 1 << 5,
+    BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK = 1 << 6,
+    BOOTSTRAPPING_QR_SCAN_MASK = 1 << 7,
+    BOOTSTRAPPING_NFC_READER_MASK = 1 << 8,
+    BOOTSTRAPPING_SERVICE_MANAGED_MASK = 1 << 14,
+    BOOTSTRAPPING_HANDSHAKE_SHIP_MASK = 1 << 15
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
new file mode 100644
index 0000000..4b74cd9
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanBootstrappingMethod;
+
+/**
+ * See Wi-Fi Aware R4.0 section 9.5.21.7
+ */
+@VintfStability
+parcelable NanBootstrappingRequest {
+    /**
+     * ID of the peer. Obtained as part of an earlier |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    int peerId;
+
+    /**
+     * NAN management interface MAC address of the peer. Obtained as part of an earlier
+     * |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    byte[6] peerDiscMacAddr;
+
+    /**
+     * One of |NanBootstrappingMethod| indicating the bootstrapping method in the request.
+     */
+    NanBootstrappingMethod requestBootstrappingMethod;
+
+    /**
+     * Cookie received from previous |NanBootstrappingConfirmInd| for comeback request.
+     */
+    byte[] cookie;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequestInd.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequestInd.aidl
new file mode 100644
index 0000000..6f43892
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequestInd.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanBootstrappingMethod;
+
+/**
+ * NAN Data path request indication message structure.
+ * Event indication received by an intended Responder when a NAN
+ * data request is initiated by an Initiator. See Wi-Fi Aware R4.0 section 9.5.21.7
+ */
+@VintfStability
+parcelable NanBootstrappingRequestInd {
+    /**
+     * Discovery session (publish or subscribe) ID of a previously created discovery session. The
+     * bootstrapping request is received in the context of this discovery session.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte discoverySessionId;
+    /**
+     * A unique ID of the peer. Can be subsequently used in |IWifiNanIface.transmitFollowupRequest|
+     * or to set up a data-path.
+     */
+    int peerId;
+    /**
+     * MAC address of the Initiator peer. This is the MAC address of the peer's
+     * management/discovery NAN interface.
+     */
+    byte[6] peerDiscMacAddr;
+
+    /**
+     * ID of bootstrapping session. Used to identify the bootstrapping further negotiation/APIs.
+     */
+    int bootstrappingInstanceId;
+
+    /**
+     * One of |NanBootstrappingMethod| indicating the bootstrapping method in the incoming request.
+     */
+    NanBootstrappingMethod requestBootstrappingMethod;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
new file mode 100644
index 0000000..dbe8923
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * See Wi-Fi Aware R4.0 section 9.5.21.7
+ */
+@VintfStability
+parcelable NanBootstrappingResponse {
+    /**
+     * ID of bootstrapping session. Used to identify the bootstrapping further negotiation/APIs.
+     */
+    int bootstrappingInstanceId;
+    /**
+     * True if accept the request, false otherwise.
+     */
+    boolean acceptRequest;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponseCode.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponseCode.aidl
new file mode 100644
index 0000000..17076bf
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponseCode.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Response code from peer NAN Bootstrapping request
+ */
+@VintfStability
+@Backing(type="int")
+enum NanBootstrappingResponseCode {
+    NAN_BOOTSTRAPPING_REQUEST_ACCEPT = 0,
+    NAN_BOOTSTRAPPING_REQUEST_REJECT,
+    NAN_BOOTSTRAPPING_REQUEST_COMEBACK,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl b/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
new file mode 100644
index 0000000..f581c5e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NDP Capabilities response.
+ */
+@VintfStability
+parcelable NanCapabilities {
+    /**
+     * Maximum number of clusters which the device can join concurrently.
+     */
+    int maxConcurrentClusters;
+    /**
+     * Maximum number of concurrent publish discovery sessions.
+     */
+    int maxPublishes;
+    /**
+     * Maximum number of concurrent subscribe discovery sessions.
+     */
+    int maxSubscribes;
+    /**
+     * Maximum length (in bytes) of service name.
+     */
+    int maxServiceNameLen;
+    /**
+     * Maximum length (in bytes) of individual match filters.
+     */
+    int maxMatchFilterLen;
+    /**
+     * Maximum length (in bytes) of aggregate match filters across all active sessions.
+     */
+    int maxTotalMatchFilterLen;
+    /**
+     * Maximum length (in bytes) of the service specific info field.
+     */
+    int maxServiceSpecificInfoLen;
+    /**
+     * Maximum length (in bytes) of the extended service specific info field.
+     */
+    int maxExtendedServiceSpecificInfoLen;
+    /**
+     * Maximum number of data interfaces (NDI) which can be created concurrently on the device.
+     */
+    int maxNdiInterfaces;
+    /**
+     * Maximum number of data paths (NDP) which can be created concurrently on the device, across
+     * all data interfaces (NDI).
+     */
+    int maxNdpSessions;
+    /**
+     * Maximum length (in bytes) of application info field (used in data-path negotiations).
+     */
+    int maxAppInfoLen;
+    /**
+     * Maximum number of transmitted followup messages which can be queued by the firmware.
+     */
+    int maxQueuedTransmitFollowupMsgs;
+    /**
+     * Maximum number MAC interface addresses which can be specified to a subscribe discovery
+     * session.
+     */
+    int maxSubscribeInterfaceAddresses;
+    /**
+     * Bitmap of |NanCipherSuiteType| values indicating the set of supported cipher suites.
+     */
+    int supportedCipherSuites;
+    /**
+     * Flag to indicate if instant communication mode is supported.
+     */
+    boolean instantCommunicationModeSupportFlag;
+    /**
+     * Flag to indicate if 6 GHz is supported.
+     */
+    boolean supports6g;
+    /**
+     * Flag to indicate if High Efficiency is supported.
+     */
+    boolean supportsHe;
+    /**
+     * Flag to indicate if NAN pairing is supported.
+     */
+    boolean supportsPairing;
+    /**
+     * Flag to indicate if setting NAN cluster ID is supported.
+     */
+    boolean supportsSetClusterId;
+    /**
+     * Flag to indicate if NAN suspension is supported.
+     */
+    boolean supportsSuspension;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl b/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl
new file mode 100644
index 0000000..91b5caf
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Cipher suite flags. Wi-Fi Aware Specification 4.0 section 9.5.21.1.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanCipherSuiteType {
+    NONE = 0,
+    /**
+     *  NCS-SK-128
+     */
+    SHARED_KEY_128_MASK = 1 << 0,
+    /**
+     *  NCS-SK-256
+     */
+    SHARED_KEY_256_MASK = 1 << 1,
+    /**
+     *  NCS-PK-2WDH-128
+     */
+    PUBLIC_KEY_2WDH_128_MASK = 1 << 2,
+    /**
+     *  NCS-PK-2WDH-256
+     */
+    PUBLIC_KEY_2WDH_256_MASK = 1 << 3,
+    /**
+     * bit 4 and bit 5 are reserved for NCS-GTK-CCMP-128 and NCS-GTK-CCMP-256. Which are not used
+     * from framework
+     */
+    /**
+     *  NCS-PK-PASN-128
+     */
+    PUBLIC_KEY_PASN_128_MASK = 1 << 6,
+    /**
+     *  NCS-PK-PASN-256
+     */
+    PUBLIC_KEY_PASN_256_MASK = 1 << 7,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanClusterEventInd.aidl b/wifi/aidl/android/hardware/wifi/NanClusterEventInd.aidl
new file mode 100644
index 0000000..76a3034
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanClusterEventInd.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanClusterEventType;
+
+/**
+ * Cluster event indication structure. Triggered on events impacting how this device is
+ * visible to peers - cluster forming, joining a new cluster, or changing of the MAC address.
+ */
+@VintfStability
+parcelable NanClusterEventInd {
+    /**
+     * Event type causing the cluster event indication to be triggered.
+     */
+    NanClusterEventType eventType;
+    /**
+     * MAC Address associated with the corresponding event.
+     */
+    byte[6] addr;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanClusterEventType.aidl b/wifi/aidl/android/hardware/wifi/NanClusterEventType.aidl
new file mode 100644
index 0000000..c07bf17
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanClusterEventType.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Event types for a cluster event indication.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanClusterEventType {
+    /**
+     * Management/discovery interface MAC address has changed
+     * (e.g. due to randomization or at startup).
+     */
+    DISCOVERY_MAC_ADDRESS_CHANGED = 0,
+    /**
+     * A new cluster has been formed by this device.
+     */
+    STARTED_CLUSTER,
+    /**
+     * This device has joined an existing cluster.
+     */
+    JOINED_CLUSTER,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl b/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
new file mode 100644
index 0000000..82a7b6e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanBandSpecificConfig;
+
+/**
+ * Configuration parameters of NAN. Used when enabling and re-configuring a NAN cluster.
+ */
+@VintfStability
+parcelable NanConfigRequest {
+    /**
+     * Master preference of this device.
+     * NAN Spec: Master Indication Attribute / Master Preference
+     */
+    byte masterPref;
+    /**
+     * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+     * for |NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED|.
+     */
+    boolean disableDiscoveryAddressChangeIndication;
+    /**
+     * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+     * for |NanClusterEventType.STARTED_CLUSTER|.
+     */
+    boolean disableStartedClusterIndication;
+    /**
+     * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+     * for |NanClusterEventType.JOINED_CLUSTER|.
+     */
+    boolean disableJoinedClusterIndication;
+    /**
+     * Control whether publish service IDs are included in Sync/Discovery beacons.
+     * NAN Spec: Service ID List Attribute
+     */
+    boolean includePublishServiceIdsInBeacon;
+    /**
+     * If |includePublishServiceIdsInBeacon| is true, then specifies the number of publish service
+     * IDs to include in the Sync/Discovery beacons. Value = 0: include as many service IDs as will
+     * fit into the maximum allowed beacon frame size. Value must fit within 7 bits - i.e. <= 127.
+     */
+    byte numberOfPublishServiceIdsInBeacon;
+    /**
+     * Control whether subscribe service IDs are included in Sync/Discovery beacons.
+     * Spec: Subscribe Service ID List Attribute
+     */
+    boolean includeSubscribeServiceIdsInBeacon;
+    /**
+     * If |includeSubscribeServiceIdsInBeacon| is true, then specifies the number of subscribe
+     * service IDs to include in the Sync/Discovery beacons. Value = 0: include as many service IDs
+     * as will fit into the maximum allowed beacon frame size. Value must fit within 7 bits - i.e.
+     * <= 127.
+     */
+    byte numberOfSubscribeServiceIdsInBeacon;
+    /**
+     * Number of samples used to calculate RSSI.
+     */
+    char rssiWindowSize;
+    /**
+     * Specifies the interval in seconds that the NAN management interface MAC address is
+     * randomized. A value of 0 is used to disable the MAC address randomization.
+     */
+    int macAddressRandomizationIntervalSec;
+    /**
+     * Additional configuration provided per band. Indexed by |NanBandIndex|.
+     */
+    NanBandSpecificConfig[3] bandSpecificConfig;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl b/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl
new file mode 100644
index 0000000..338a549
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Additional NAN configuration request parameters.
+ */
+@VintfStability
+parcelable NanConfigRequestSupplemental {
+    /**
+     * Specify the Discovery Beacon interval in ms. Specification only applicable if the device
+     * transmits Discovery Beacons (based on the Wi-Fi Aware protocol selection criteria). The value
+     * can be increased to reduce power consumption (on devices which would transmit Discovery
+     * Beacons). However, cluster synchronization time will likely increase.
+     * Values are:
+     *  - A value of 0 indicates that the HAL sets the interval to a default (implementation
+     * specific).
+     *  - A positive value.
+     */
+    int discoveryBeaconIntervalMs;
+    /**
+     * The number of spatial streams to be used for transmitting NAN management frames (does NOT
+     * apply to data-path packets). A small value may reduce power consumption for small discovery
+     * packets. Values are:
+     *  - A value of 0 indicates that the HAL sets the number to a default (implementation
+     * specific).
+     *  - A positive value.
+     */
+    int numberOfSpatialStreamsInDiscovery;
+    /**
+     * Controls whether the device may terminate listening on a Discovery Window (DW) earlier than
+     * the DW termination (16ms) if no information is received. Enabling the feature will result in
+     * lower power consumption, but may result in some missed messages and hence increased latency.
+     */
+    boolean enableDiscoveryWindowEarlyTermination;
+    /**
+     * Controls whether NAN RTT (ranging) is permitted. Global flag on any NAN RTT operations are
+     * allowed. Controls ranging in the context of discovery as well as direct RTT.
+     */
+    boolean enableRanging;
+    /**
+     * Controls whether NAN instant communication mode is enabled.
+     */
+    boolean enableInstantCommunicationMode;
+    /**
+     * Controls which channel NAN instant communication mode operates on.
+     */
+    int instantModeChannel;
+    /**
+     * Controls which cluster to join.
+     */
+    int clusterId;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathChannelCfg.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathChannelCfg.aidl
new file mode 100644
index 0000000..3aaea40
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathChannelCfg.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN DP (data-path) channel config options.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanDataPathChannelCfg {
+    CHANNEL_NOT_REQUESTED = 0,
+    REQUEST_CHANNEL_SETUP,
+    FORCE_CHANNEL_SETUP,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathChannelInfo.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathChannelInfo.aidl
new file mode 100644
index 0000000..e5c3538
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathChannelInfo.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+
+/**
+ * NAN data path channel information provided to the framework.
+ */
+@VintfStability
+parcelable NanDataPathChannelInfo {
+    /**
+     * Channel frequency in MHz.
+     */
+    int channelFreq;
+    /**
+     * Channel bandwidth in MHz.
+     */
+    WifiChannelWidthInMhz channelBandwidth;
+    /**
+     * Number of spatial streams used in the channel.
+     */
+    int numSpatialStreams;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathConfirmInd.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathConfirmInd.aidl
new file mode 100644
index 0000000..621f036
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathConfirmInd.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanDataPathChannelInfo;
+import android.hardware.wifi.NanStatus;
+
+/**
+ * NAN Data path confirmation indication structure. Event indication is
+ * received on both initiator and responder side when negotiation for a
+ * data-path finishes on success or failure.
+ */
+@VintfStability
+parcelable NanDataPathConfirmInd {
+    /**
+     * ID of the data-path.
+     */
+    int ndpInstanceId;
+    /**
+     * Indicates whether the data-path setup succeeded (true) or failed (false).
+     */
+    boolean dataPathSetupSuccess;
+    /**
+     * MAC address of the peer's data-interface (not its management/discovery interface).
+     */
+    byte[6] peerNdiMacAddr;
+    /**
+     * Arbitrary information communicated from the peer as part of the data-path setup process -
+     * there is no semantic meaning to these bytes. They are passed-through from sender to receiver
+     * as-is with no parsing. Max length: |NanCapabilities.maxAppInfoLen|. NAN Spec: Data Path
+     * Attributes / NDP Attribute / NDP Specific Info
+     */
+    byte[] appInfo;
+    /**
+     * Failure reason if |dataPathSetupSuccess| is false.
+     */
+    NanStatus status;
+    /**
+     * The channel(s) on which the NDP is scheduled to operate.
+     * Updates to the operational channels are provided using the |eventDataPathScheduleUpdate|
+     * event.
+     */
+    NanDataPathChannelInfo[] channelInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathRequestInd.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathRequestInd.aidl
new file mode 100644
index 0000000..de9ee32
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathRequestInd.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN Data path request indication message structure.
+ * Event indication received by an intended Responder when a NAN
+ * data request initiated by an Initiator.
+ */
+@VintfStability
+parcelable NanDataPathRequestInd {
+    /**
+     * ID of an active publish or subscribe discovery session. The data-path
+     * request is in the context of this discovery session.
+     * NAN Spec: Data Path Attributes / NDP Attribute / Publish ID
+     */
+    byte discoverySessionId;
+    /**
+     * MAC address of the Initiator peer. This is the MAC address of the peer's
+     * management/discovery NAN interface.
+     */
+    byte[6] peerDiscMacAddr;
+    /**
+     * ID of the data-path. Used to identify the data-path in further negotiation/APIs.
+     */
+    int ndpInstanceId;
+    /**
+     * Specifies whether or not security is required by the peer for the data-path being created.
+     * NAN Spec: Data Path Attributes / NDP Attribute / NDP Control / Security Present
+     */
+    boolean securityRequired;
+    /**
+     * Arbitrary information communicated from the peer as part of the data-path setup process.
+     * Therer is no semantic meaning to these bytes. They are passed-through from sender to
+     * receiver as-is with no parsing.
+     * Max length: |NanCapabilities.maxAppInfoLen|.
+     * NAN Spec: Data Path Attributes / NDP Attribute / NDP Specific Info
+     */
+    byte[] appInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
new file mode 100644
index 0000000..0f41d8f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanDataPathChannelInfo;
+
+/**
+ * NAN data path channel information update indication structure.
+ * Event indication is received by all NDP owners whenever the channels on
+ * which the NDP operates are updated.
+ * Note: Multiple NDPs may share the same schedule. The indication specifies
+ * all NDPs to which it applies.
+ */
+@VintfStability
+parcelable NanDataPathScheduleUpdateInd {
+    /**
+     * The discovery address (NMI) of the peer to which the NDP is connected.
+     */
+    byte[6] peerDiscoveryAddress;
+    /**
+     * The updated channel(s) information.
+     */
+    NanDataPathChannelInfo[] channelInfo;
+    /**
+     * The list of NDPs to which this update applies.
+     */
+    int[] ndpInstanceIds;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
new file mode 100644
index 0000000..9a2013b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanDataPathSecurityType;
+
+/**
+ * Configuration of NAN data-path security.
+ */
+@VintfStability
+parcelable NanDataPathSecurityConfig {
+    /**
+     * Security configuration of the data-path (NDP). Security is enabled if not equal to
+     * |NanDataPathSecurityType.OPEN|.
+     * NAN Spec: Service Discovery Extension Attribute (SDEA) / Control / Security Required
+     */
+    NanDataPathSecurityType securityType;
+    /**
+     * One of |NanCipherSuiteType| indicating the cipher type for data-paths.
+     * If |securityType| is |NanDataPathSecurityType.OPEN|, then this must
+     * be set to |NanCipherSuiteType.NONE|. Otherwise a non-|NanCipherSuiteType.NONE| cipher suite
+     * must be specified.
+     */
+    NanCipherSuiteType cipherType;
+    /**
+     * Optional Pairwise Master Key (PMK). Must be specified (and is only used) if |securityType| is
+     * set to |NanDataPathSecurityType.PMK|.
+     * Ref: IEEE 802.11i
+     */
+    byte[32] pmk;
+    /**
+     * Optional Passphrase. Must be specified (and is only used) if |securityType| is set to
+     * |NanDataPathSecurityType.PASSPHRASE|.
+     * Min length: |IWifiNanIface.MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH|
+     * Max length: |IWifiNanIface.MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH|
+     * NAN Spec: Appendix: Mapping passphrase to PMK for NCS-SK Cipher Suites
+     */
+    byte[] passphrase;
+    /**
+     * Security Context Identifier attribute contains PMKID. Shall be included in NDP setup and
+     * response messages. Security Context Identifier identifies the Security Context. When
+     * security is enabled this field contains the 16 octet PMKID identifying the PMK used for
+     * setting up the Secure Data Path.
+     */
+    byte[16] scid;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityType.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityType.aidl
new file mode 100644
index 0000000..da23ffa
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN DP (data-path) security configuration options.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanDataPathSecurityType {
+    OPEN,
+    PMK,
+    PASSPHRASE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDebugConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDebugConfig.aidl
new file mode 100644
index 0000000..d8fab0d
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDebugConfig.aidl
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Debug configuration parameters. Many of these allow non-standard-compliant operation and are
+ * not intended for normal operational mode.
+ */
+@VintfStability
+parcelable NanDebugConfig {
+    /**
+     * Specification of the lower 2 bytes of the cluster ID. The cluster ID is 50-60-9a-01-00-00 to
+     * 50-60-9a-01-FF-FF. Configuration is of the bottom and top values of the range (which default
+     * to 0x0000 and 0xFFFF respectively).
+     * Configuration is only used if |validClusterIdVals| is set to true.
+     */
+    boolean validClusterIdVals;
+    char clusterIdBottomRangeVal;
+    char clusterIdTopRangeVal;
+    /**
+     * NAN management interface address. If specified (|validIntfAddrVal| is true), then overrides
+     * any other configuration (specifically the default randomization configured by
+     * |NanConfigRequest.macAddressRandomizationIntervalSec|).
+     */
+    boolean validIntfAddrVal;
+    byte[6] intfAddrVal;
+    /**
+     * Combination of the 24 bit Organizationally Unique ID (OUI) and the 8 bit OUI type.
+     * Used if |validOuiVal| is set to true.
+     */
+    boolean validOuiVal;
+    int ouiVal;
+    /**
+     * Force the Random Factor to the specified value for all transmitted Sync/Discovery beacons.
+     * Used if |validRandomFactorForceVal| is set to true.
+     * NAN Spec: Master Indication Attribute / Random Factor
+     */
+    boolean validRandomFactorForceVal;
+    byte randomFactorForceVal;
+    /**
+     * Forces the hop-count for all transmitted Sync and Discovery Beacons NO matter the real
+     * hop-count being received over the air. Used if the |validHopCountForceVal| flag is set to
+     * true.
+     * NAN Spec: Cluster Attribute / Anchor Master Information / Hop Count to Anchor Master
+     */
+    boolean validHopCountForceVal;
+    byte hopCountForceVal;
+    /**
+     * Frequency in MHz to of the discovery channel in the specified band. Indexed by
+     * |NanBandIndex|. Used if the |validDiscoveryChannelVal| is set to true.
+     */
+    boolean validDiscoveryChannelVal;
+    int[3] discoveryChannelMhzVal;
+    /**
+     * Specifies whether sync/discovery beacons are transmitted in the specified band. Indexed by
+     * |NanBandIndex|. Used if the |validUseBeaconsInBandVal| is set to true.
+     */
+    boolean validUseBeaconsInBandVal;
+    boolean[3] useBeaconsInBandVal;
+    /**
+     * Specifies whether SDF (service discovery frames) are transmitted in the specified band.
+     * Indexed by |NanBandIndex|. Used if the |validUseSdfInBandVal| is set to true.
+     */
+    boolean validUseSdfInBandVal;
+    boolean[3] useSdfInBandVal;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
new file mode 100644
index 0000000..58777c5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanDataPathSecurityConfig;
+import android.hardware.wifi.NanMatchAlg;
+
+/**
+ * Configurations of NAN discovery sessions. Common to publish and subscribe discovery.
+ */
+@VintfStability
+parcelable NanDiscoveryCommonConfig {
+    /**
+     * The ID of the discovery session being configured. A value of 0 specifies a request to create
+     * a new discovery session. The new discovery session ID is returned with
+     * |IWifiNanIfaceEventCallback.notifyStartPublishResponse| or
+     * |IWifiNanIfaceEventCallback.notifyStartSubscribeResponse|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte sessionId;
+    /**
+     * The lifetime of the discovery session in seconds. A value of 0 means run forever or until
+     * canceled using |IWifiIface.stopPublishRequest| or |IWifiIface.stopSubscribeRequest|.
+     */
+    char ttlSec;
+    /**
+     * Indicates the interval between two Discovery Windows in which the device supporting the
+     * service is awake to transmit or receive the Service Discovery frames. Valid values of Awake
+     * DW Interval are: 1, 2, 4, 8 and 16. A value of 0 will default to 1. Does not override
+     * |NanBandSpecificConfig.discoveryWindowIntervalVal| configurations if those are specified.
+     */
+    char discoveryWindowPeriod;
+    /**
+     * The lifetime of the discovery session in number of transmitted SDF discovery packets. A value
+     * of 0 means forever or until canceled using |IWifiIface.stopPublishRequest| or
+     * |IWifiIface.stopSubscribeRequest|.
+     */
+    byte discoveryCount;
+    /**
+     * UTF-8 encoded string identifying the service.
+     * Max length: |NanCapabilities.maxServiceNameLen|.
+     * NAN Spec: The only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric
+     * values (A-Z, a-z, 0-9), the hyphen ('-'), and the period ('.'). All valid multi-byte UTF-8
+     * characters are acceptable in a Service Name.
+     */
+    byte[] serviceName;
+    /**
+     * Specifies how often to trigger |IWifiNanIfaceEventCallback.eventMatch| when continuously
+     * discovering the same discovery session (with no changes).
+     */
+    NanMatchAlg discoveryMatchIndicator;
+    /**
+     * Arbitrary information communicated in discovery packets - there is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxServiceSpecificInfoLen|. NAN Spec: Service Descriptor Attribute
+     * (SDA) / Service Info
+     */
+    byte[] serviceSpecificInfo;
+    /**
+     * Arbitrary information communicated in discovery packets - there is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxExtendedServiceSpecificInfoLen|. Spec: Service Descriptor
+     * Extension Attribute (SDEA) / Service Info
+     */
+    byte[] extendedServiceSpecificInfo;
+    /**
+     * Ordered sequence of <length, value> pairs (|length| uses 1 byte and contains the number of
+     * bytes in the |value| field) which specify further match criteria (beyond the service name).
+     * The match behavior is specified in details in the NAN spec.
+     * Publisher: used in SOLICITED or SOLICITED_UNSOLICITED sessions.
+     * Subscriber: used in ACTIVE or PASSIVE sessions.
+     * Max length: |NanCapabilities.maxMatchFilterLen|.
+     * NAN Spec: matching_filter_rx
+     */
+    byte[] rxMatchFilter;
+    /**
+     * Ordered sequence of <length, value> pairs (|length| uses 1 byte and contains the number of
+     * bytes in the |value| field) which specify further match criteria (beyond the service name).
+     * The match behavior is specified in details in the NAN spec.
+     * Publisher: used if provided.
+     * Subscriber: used (if provided) only in ACTIVE sessions.
+     * Max length: |NanCapabilities.maxMatchFilterLen|.
+     * NAN Spec: matching_filter_tx and Service Descriptor Attribute (SDA) / Matching Filter
+     */
+    byte[] txMatchFilter;
+    /**
+     * Specifies whether or not the discovery session uses the
+     * |NanBandSpecificConfig.rssiCloseProximity| value (configured in enable/configure requests) to
+     * filter out matched discovered peers.
+     * NAN Spec: Service Descriptor Attribute / Service Control / Discovery Range Limited.
+     */
+    boolean useRssiThreshold;
+    /**
+     * Controls whether or not the |IWifiNanIfaceEventCallback.eventPublishTerminated| (for publish
+     * discovery sessions) or |IWifiNanIfaceEventCallback.eventSubscribeTerminated| (for subscribe
+     * discovery sessions) will be delivered.
+     */
+    boolean disableDiscoveryTerminationIndication;
+    /**
+     * Controls whether or not |IWifiNanIfaceEventCallback.eventMatchExpired| will be delivered.
+     */
+    boolean disableMatchExpirationIndication;
+    /**
+     * Controls whether or not |IWifiNanIfaceEventCallback.eventFollowupReceived| will be delivered.
+     */
+    boolean disableFollowupReceivedIndication;
+    /**
+     * Security configuration of data-paths created in the context of this discovery session.
+     * Security parameters can be overridden during the actual construction of the data-path -
+     * allowing individual data-paths to have unique PMKs or passphrases.
+     */
+    NanDataPathSecurityConfig securityConfig;
+    /**
+     * Specifies whether or not there is a ranging requirement in this discovery session.
+     * Ranging is only performed if all other match criteria with the peer are met. Ranging must
+     * be performed if both peers in the discovery session (publisher and subscriber) set this
+     * flag to true. Otherwise, if either peer sets this flag to false, ranging must not be
+     * performed and must not impact discovery decisions. Note: Specifying that ranging is required
+     * also implies that this device must automatically accept ranging requests from peers. NAN
+     * Spec: Service Discovery Extension Attribute (SDEA) / Control / Ranging Require.
+     */
+    boolean rangingRequired;
+    /**
+     * Interval in ms between two ranging measurements. Only relevant if |rangingRequired| is true.
+     * If the Awake DW interval specified either in |discoveryWindowPeriod| or in
+     * |NanBandSpecificConfig.discoveryWindowIntervalVal| is larger than the ranging interval then
+     * priority is given to Awake DW interval.
+     */
+    int rangingIntervalMs;
+    /**
+     * Bitmap of |NanRangingIndication| values indicating the type of ranging feedback
+     * to be provided by discovery session matches in |IWifiNanIfaceEventCallback.eventMatch|.
+     * Only relevant if |rangingRequired| is true.
+     */
+    int configRangingIndications;
+    /**
+     * The ingress and egress distance in cm. If ranging is enabled (|rangingEnabled| is true) then
+     * |configRangingIndications| is used to determine whether ingress and/or egress (or neither)
+     * are used to determine whether a match has occurred.
+     * NAN Spec: Service Discovery Extension Attribute (SDEA) / Ingress & Egress Range Limit
+     */
+    char distanceIngressCm;
+    char distanceEgressCm;
+    /**
+     * Specifies whether suspension can be possible in this discovery session.
+     * The request would fail if |enableSessionSuspendability| is true but
+     * |NanCapabilities.supportsSuspension| is false.
+     */
+    boolean enableSessionSuspendability;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanEnableRequest.aidl b/wifi/aidl/android/hardware/wifi/NanEnableRequest.aidl
new file mode 100644
index 0000000..8c28fe1
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanEnableRequest.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanConfigRequest;
+import android.hardware.wifi.NanDebugConfig;
+
+/**
+ * Enable requests for NAN. Start-up configuration for |IWifiNanIface.enableRequest|.
+ */
+@VintfStability
+parcelable NanEnableRequest {
+    /**
+     * Enable operation in a specific band. Indexed by |NanBandIndex|.
+     */
+    boolean[3] operateInBand;
+    /**
+     * Specify extent of cluster by specifying the max hop count.
+     */
+    byte hopCountMax;
+    /**
+     * Configurations of NAN cluster operation. Can also be modified at run-time using
+     * |IWifiNanIface.configRequest|.
+     */
+    NanConfigRequest configParams;
+    /**
+     * Non-standard configurations of NAN cluster operation. Useful for debugging operations.
+     */
+    NanDebugConfig debugConfigs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanFollowupReceivedInd.aidl b/wifi/aidl/android/hardware/wifi/NanFollowupReceivedInd.aidl
new file mode 100644
index 0000000..20bc9b1
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanFollowupReceivedInd.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Follow up message received from peer indication structure.
+ */
+@VintfStability
+parcelable NanFollowupReceivedInd {
+    /**
+     * Discovery session (publish or subscribe) ID of a previously created discovery session. The
+     * message is received in the context of this discovery session.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte discoverySessionId;
+    /**
+     * A unique ID of the peer. Can be subsequently used in |IWifiNanIface.transmitFollowupRequest|
+     * or to set up a data-path.
+     */
+    int peerId;
+    /**
+     * The NAN Discovery (management) MAC address of the peer.
+     */
+    byte[6] addr;
+    /**
+     * Indicates whether received in a further availability window (FAW) if true, or in a discovery
+     * window (DW) if false.
+     */
+    boolean receivedInFaw;
+    /**
+     * Received message from the peer. There is no semantic meaning to these bytes. They are
+     * passed-through from sender to receiver as-is with no parsing.
+     * Max length: |NanCapabilities.maxServiceSpecificInfoLen|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Info
+     */
+    byte[] serviceSpecificInfo;
+    /**
+     * Arbitrary information communicated in discovery packets. There is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxExtendedServiceSpecificInfoLen|. Spec: Service Descriptor
+     * Extension Attribute (SDEA) / Service Info
+     */
+    byte[] extendedServiceSpecificInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanIdentityResolutionAttribute.aidl b/wifi/aidl/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
new file mode 100644
index 0000000..807081b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NIRA for pairing identity resolution.
+ * See Wi-Fi Aware R4.0 section 9.5.21.6
+ */
+@VintfStability
+parcelable NanIdentityResolutionAttribute {
+    /**
+     * A random byte string to generate tag
+     */
+    byte[8] nonce;
+
+    /**
+     * A resolvable identity to identify Nan identity key
+     */
+    byte[8] tag;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl b/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl
new file mode 100644
index 0000000..2f25329
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanDataPathChannelCfg;
+import android.hardware.wifi.NanDataPathSecurityConfig;
+
+/**
+ *  Data Path Initiator requesting a data-path.
+ */
+@VintfStability
+parcelable NanInitiateDataPathRequest {
+    /**
+     * ID of the peer. Obtained as part of an earlier |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    int peerId;
+    /**
+     * NAN management interface MAC address of the peer. Obtained as part of an earlier
+     * |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    byte[6] peerDiscMacAddr;
+    /**
+     * Config flag for channel request.
+     */
+    NanDataPathChannelCfg channelRequestType;
+    /**
+     * Channel frequency in MHz to start data-path. Not relevant if |channelRequestType| is
+     * |NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED|.
+     */
+    int channel;
+    /**
+     * NAN data interface name on which this data-path session is to be initiated.
+     * This must be an interface created using |IWifiNanIface.createDataInterfaceRequest|.
+     */
+    String ifaceName;
+    /**
+     * Security configuration of the requested data-path.
+     */
+    NanDataPathSecurityConfig securityConfig;
+    /**
+     * Arbitrary information communicated to the peer as part of the data-path setup process. There
+     * is no semantic meaning to these bytes. They are passed-through from sender to receiver as-is
+     * with no parsing.
+     * Max length: |NanCapabilities.maxAppInfoLen|.
+     * NAN Spec: Data Path Attributes / NDP Attribute / NDP Specific Info
+     */
+    byte[] appInfo;
+    /**
+     * A service name to be used with |passphrase| to construct a Pairwise Master Key (PMK) for the
+     * data-path. Only relevant when a data-path is requested which is not associated with a NAN
+     * discovery session - e.g. using out-of-band discovery.
+     * Constraints: same as |NanDiscoveryCommonConfig.serviceName|
+     * NAN Spec: Appendix: Mapping pass-phrase to PMK for NCS-SK Cipher Suites
+     */
+    byte[] serviceNameOutOfBand;
+    /**
+     * ID of an active publish or subscribe discovery session.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte discoverySessionId;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanMatchAlg.aidl b/wifi/aidl/android/hardware/wifi/NanMatchAlg.aidl
new file mode 100644
index 0000000..dc96a47
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanMatchAlg.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN Match indication type. Controls how often to trigger |IWifiNanIfaceEventCallback.eventMatch|
+ * for a single discovery session - i.e. continuously discovering the same publisher with no new
+ * data.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanMatchAlg {
+    MATCH_ONCE = 0,
+    MATCH_CONTINUOUS,
+    MATCH_NEVER,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
new file mode 100644
index 0000000..5a04376
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanIdentityResolutionAttribute;
+import android.hardware.wifi.NanPairingConfig;
+
+/**
+ * Match indication structure.
+ */
+@VintfStability
+parcelable NanMatchInd {
+    /**
+     * Publish or subscribe discovery session ID of an existing discovery session.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte discoverySessionId;
+    /**
+     * A unique ID of the peer. Can be subsequently used in |IWifiNanIface.transmitFollowupRequest|
+     * or to set up a data-path.
+     */
+    int peerId;
+    /**
+     * The NAN Discovery (management) MAC address of the peer.
+     */
+    byte[6] addr;
+    /**
+     * The arbitrary information contained in the |NanDiscoveryCommonConfig.serviceSpecificInfo| of
+     * the peer's discovery session configuration.
+     * Max length: |NanCapabilities.maxServiceSpecificInfoLen|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Info
+     */
+    byte[] serviceSpecificInfo;
+    /**
+     * Arbitrary information communicated in discovery packets. There is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxExtendedServiceSpecificInfoLen|. Spec: Service Descriptor
+     * Extension Attribute (SDEA) / Service Info
+     */
+    byte[] extendedServiceSpecificInfo;
+    /**
+     * The match filter from the discovery packet (publish or subscribe) which caused service
+     * discovery. Matches the |NanDiscoveryCommonConfig.txMatchFilter| of the peer's Unsolicited
+     * publish message or of the local device's Active subscribe message.
+     * Max length: |NanCapabilities.maxMatchFilterLen|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Matching Filter
+     */
+    byte[] matchFilter;
+    /**
+     * Indicates the type of discovery: true if match occurred on a Beacon frame, false if the match
+     * occurred on a Service Discovery Frame (SDF).
+     */
+    boolean matchOccurredInBeaconFlag;
+    /**
+     * Flag to indicate firmware is out of resources and that it can no longer track this Service
+     * Name. Indicates that while |IWifiNanIfaceEventCallback.eventMatch| will be received, the
+     * |NanDiscoveryCommonConfig.discoveryMatchIndicator| configuration will not be honored.
+     */
+    boolean outOfResourceFlag;
+    /**
+     * If RSSI filtering was enabled using |NanDiscoveryCommonConfig.useRssiThreshold| in discovery
+     * session setup, then this field contains the received RSSI value. It will contain 0 if RSSI
+     * filtering was not enabled.
+     * RSSI values are returned without sign, e.g. -70dBm will be returned as 70.
+     */
+    byte rssiValue;
+    /**
+     * One of |NanCipherSuiteType| indicating the cipher type for data-paths constructed
+     * in the context of this discovery session.
+     * Valid if |peerRequiresSecurityEnabledInNdp| is true.
+     */
+    NanCipherSuiteType peerCipherType;
+    /**
+     * Indicates whether or not the peer requires security enabled in any data-path (NDP)
+     * constructed in the context of this discovery session. The |cipherType| specifies the cipher
+     * type for such data-paths. NAN Spec: Service Discovery Extension Attribute (SDEA) / Control /
+     * Security Required
+     */
+    boolean peerRequiresSecurityEnabledInNdp;
+    /**
+     * Indicates whether or not the peer requires (and hence allows) ranging in the context of this
+     * discovery session.
+     * Note that ranging is only performed if all other match criteria with the peer are met.
+     * NAN Spec: Service Discovery Extension Attribute (SDEA) / Control / Ranging Require.
+     */
+    boolean peerRequiresRanging;
+    /**
+     * Ranging indication supersedes the NanMatchAlg specification.
+     * Ex: If NanMatchAlg is MATCH_ONCE, but ranging indication is continuous, then continuous
+     * match notifications will be received (with ranging information).
+     * Ranging indication data is provided if Ranging required is enabled in the discovery
+     * specification and:
+     *   1) continuous ranging is specified.
+     *   2) ingress/egress is specified and:
+     *       - notify once for ingress >= ingress_distance and egress <= egress_distance,
+     *       - same for ingress_egress_both
+     * If the Awake DW intervals are larger than the ranging intervals, then priority is given
+     * to the device DW intervals.
+     *
+     * If ranging was required and executed, this contains the distance to the peer in mm. The
+     * |rangingIndicationType| field specifies the event which triggered ranging.
+     */
+    int rangingMeasurementInMm;
+    /**
+     * Bitmap of |NanRangingIndication| values indicating the ranging event(s) which triggered the
+     * ranging. e.g. can indicate that continuous ranging was requested, or else that an ingress
+     * event occurred.
+     */
+    int rangingIndicationType;
+    /**
+     * Security Context Identifier attribute contains PMKID. Shall be included in NDP setup and
+     * response messages. Security Context Identifier identifies the Security Context. For NAN
+     * Shared Key Cipher Suite, this field contains the 16 octet PMKID identifying the PMK used for
+     * setting up the Secure Data Path.
+     */
+    byte[] scid;
+    /**
+     * The config for NAN pairing set by the peer
+     */
+    NanPairingConfig peerPairingConfig;
+    /**
+     * The NIRA from peer for NAN pairing verification
+     */
+    NanIdentityResolutionAttribute peerNira;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingAkm.aidl b/wifi/aidl/android/hardware/wifi/NanPairingAkm.aidl
new file mode 100644
index 0000000..a823a3f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingAkm.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * The AKM used in the NAN pairing.
+ */
+@VintfStability @Backing(type="int") enum NanPairingAkm { SAE = 0, PASN=1 }
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingConfig.aidl b/wifi/aidl/android/hardware/wifi/NanPairingConfig.aidl
new file mode 100644
index 0000000..609dac2
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * The NAN pairing config
+ */
+@VintfStability
+parcelable NanPairingConfig {
+    /**
+     * Enable NAN pairing setup
+     */
+    boolean enablePairingSetup;
+    /**
+     * Enable cache NIK/NPK after NAN pairing setup
+     */
+    boolean enablePairingCache;
+    /**
+     * Enable NAN pairing verification with cached NIK/NPK
+     */
+    boolean enablePairingVerification;
+    /**
+     * Bitmap of |NanBootstrappingMethod| values indicating the set of
+     * supported bootstrapping methods.
+     */
+    int supportedBootstrappingMethods;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl b/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
new file mode 100644
index 0000000..a5670ec
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanPairingRequestType;
+import android.hardware.wifi.NanStatus;
+import android.hardware.wifi.NpkSecurityAssociation;
+
+/**
+ * NAN pairing confirmation indication structure. Event indication is
+ * received on both initiator and responder side when negotiation for a
+ * pairing finishes on success or failure. See Wi-Fi Aware R4.0 section 7.6.1.4
+ */
+@VintfStability
+parcelable NanPairingConfirmInd {
+    /**
+     * ID of the pairing session.
+     */
+    int pairingInstanceId;
+    /**
+     * Indicates whether the pairing setup succeeded (true) or failed (false).
+     */
+    boolean pairingSuccess;
+    /**
+     * Failure reason if |pairingSuccess| is false.
+     */
+    NanStatus status;
+    /**
+     * Indicate the pairing session is of setup or verification
+     */
+    NanPairingRequestType requestType;
+    /**
+     * Whether should cache the negotiated NIK/NPK for future verification
+     */
+    boolean enablePairingCache;
+    /**
+     * The security association negotiated for the pairing, can be cached for future verification
+     */
+    NpkSecurityAssociation npksa;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
new file mode 100644
index 0000000..0c2080b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanPairingRequestType;
+import android.hardware.wifi.NanPairingSecurityConfig;
+
+/**
+ * NAN pairing initiate request.
+ * Can be used for setup (the initial pairing request) or
+ * verification (re-pairing for paired devices).
+ * See Wi-Fi Aware R4.0 section 7.6.1.1
+ */
+@VintfStability
+parcelable NanPairingRequest {
+    /**
+     * ID of the peer. Obtained as part of an earlier |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    int peerId;
+    /**
+     * NAN management interface MAC address of the peer. Obtained as part of an earlier
+     * |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    byte[6] peerDiscMacAddr;
+    /**
+     * Indicate the pairing session is for setup or verification
+     */
+    NanPairingRequestType requestType;
+    /**
+     * Whether to cache the negotiated NIK/NPK for future verification
+     */
+    boolean enablePairingCache;
+    /**
+     * The Identity key for pairing, can be used for pairing verification
+     */
+    byte[16] pairingIdentityKey;
+    /**
+     * Security config used for the pairing
+     */
+    NanPairingSecurityConfig securityConfig;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
new file mode 100644
index 0000000..ec8548f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanIdentityResolutionAttribute;
+import android.hardware.wifi.NanPairingRequestType;
+
+/**
+ * NAN pairing request indication message structure.
+ * Event indication received by an intended Responder when a
+ * pairing request is initiated by an Initiator. See Wi-Fi Aware R4.0 section 7.6.1.3
+ */
+@VintfStability
+parcelable NanPairingRequestInd {
+    /**
+     * Discovery session (publish or subscribe) ID of a previously created discovery session. The
+     * pairing request is received in the context of this discovery session.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte discoverySessionId;
+    /**
+     * A unique ID of the peer. Can be subsequently used in |IWifiNanIface.transmitFollowupRequest|
+     * or to set up a data-path.
+     */
+    int peerId;
+    /**
+     * MAC address of the Initiator peer. This is the MAC address of the peer's
+     * management/discovery NAN interface.
+     */
+    byte[6] peerDiscMacAddr;
+    /**
+     * ID of the NAN pairing Used to identify the pairing in further negotiation/APIs.
+     */
+    int pairingInstanceId;
+    /**
+     * Indicate the pairing session is of setup or verification
+     */
+    NanPairingRequestType requestType;
+    /**
+     * Whether should cache the negotiated NIK/NPK for future verification
+     */
+    boolean enablePairingCache;
+    /**
+     * The NIRA from peer for NAN pairing verification
+     */
+    NanIdentityResolutionAttribute peerNira;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequestType.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequestType.aidl
new file mode 100644
index 0000000..a69d04e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequestType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Type of the request of pairing
+ */
+@VintfStability
+@Backing(type="int")
+enum NanPairingRequestType {
+    NAN_PAIRING_SETUP = 0,
+    NAN_PAIRING_VERIFICATION
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingSecurityConfig.aidl b/wifi/aidl/android/hardware/wifi/NanPairingSecurityConfig.aidl
new file mode 100644
index 0000000..a601751
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingSecurityConfig.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanPairingAkm;
+import android.hardware.wifi.NanPairingSecurityType;
+
+/**
+ * Configuration of NAN data-path security.
+ */
+@VintfStability
+parcelable NanPairingSecurityConfig {
+    /**
+     * Security configuration of the NAN pairing. |NanPairingSecurityType.PMK| for verification.
+     * |NanPairingSecurityType.PASSPHRASE| and |NanPairingSecurityType.OPPORTUNISTIC| for setup
+     */
+    NanPairingSecurityType securityType;
+    /**
+     * Optional Pairwise Master Key (PMK). Must be specified (and is only used) if |securityType| is
+     * set to |NanDataPathSecurityType.PMK|.
+     * Ref: IEEE 802.11i
+     */
+    byte[32] pmk;
+    /**
+     * Optional Passphrase. Must be specified (and is only used) if |securityType| is set to
+     * |NanDataPathSecurityType.PASSPHRASE|.
+     * Min length: |IWifiNanIface.MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH|
+     * Max length: |IWifiNanIface.MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH|
+     * NAN Spec: Appendix: Mapping passphrase to PMK for NCS-SK Cipher Suites
+     */
+    byte[] passphrase;
+    /**
+     * The AKM for key exchange
+     */
+    NanPairingAkm akm;
+    /**
+     * Cipher type for pairing. Must be one of |NanCipherSuiteType.PUBLIC_KEY_PASN_128_MASK|
+     * or |NanCipherSuiteType.PUBLIC_KEY_PASN_256_MASK|.
+     */
+    NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingSecurityType.aidl b/wifi/aidl/android/hardware/wifi/NanPairingSecurityType.aidl
new file mode 100644
index 0000000..0f97d51
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingSecurityType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN pairing security configuration options.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanPairingSecurityType {
+    OPPORTUNISTIC,
+    PMK,
+    PASSPHRASE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
new file mode 100644
index 0000000..956a7df
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanDiscoveryCommonConfig;
+import android.hardware.wifi.NanPairingConfig;
+import android.hardware.wifi.NanPublishType;
+import android.hardware.wifi.NanTxType;
+
+/**
+ * Publish request. Specifies a publish discovery operation.
+ */
+@VintfStability
+parcelable NanPublishRequest {
+    /**
+     * Common configuration of discovery sessions.
+     */
+    NanDiscoveryCommonConfig baseConfigs;
+    /**
+     * Type of the publish discovery session.
+     */
+    NanPublishType publishType;
+    /**
+     * For publishType of |NanPublishType.SOLICITED| or |NanPublishType.UNSOLICITED_SOLICITED|,
+     * this specifies the type of transmission used for responding to the probing subscribe
+     * discovery peer.
+     */
+    NanTxType txType;
+    /**
+     * Specifies whether data-path requests |IWifiNanIfaceEventCallback.eventDataPathRequest| (in
+     * the context of this discovery session) are automatically accepted (if true) - in which case
+     * the Responder must not call the |IWifiNanIface.respondToDataPathIndicationRequest| method and
+     * the device must automatically accept the data-path request and complete the negotiation.
+     */
+    boolean autoAcceptDataPathRequests;
+    /**
+     * The config for NAN pairing
+     */
+    NanPairingConfig pairingConfig;
+    /**
+     * The Identity key for pairing, will generate NIRA for verification by the peer
+     */
+    byte[16] identityKey;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPublishType.aidl b/wifi/aidl/android/hardware/wifi/NanPublishType.aidl
new file mode 100644
index 0000000..a7a1c48
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPublishType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN publish discovery session types.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanPublishType {
+    UNSOLICITED = 0,
+    SOLICITED,
+    UNSOLICITED_SOLICITED,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanRangingIndication.aidl b/wifi/aidl/android/hardware/wifi/NanRangingIndication.aidl
new file mode 100644
index 0000000..731cbfc
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanRangingIndication.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Ranging in the context of discovery session indication controls. Controls
+ * the frequency of ranging-driven |IWifiNanIfaceEventCallback.eventMatch|.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanRangingIndication {
+    CONTINUOUS_INDICATION_MASK = 1 << 0,
+    INGRESS_MET_MASK = 1 << 1,
+    EGRESS_MET_MASK = 1 << 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl b/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
new file mode 100644
index 0000000..e543b7b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanDataPathSecurityConfig;
+
+/**
+ * Response to a data-path request from a peer.
+ */
+@VintfStability
+parcelable NanRespondToDataPathIndicationRequest {
+    /**
+     * Accept (true) or reject (false) the request.
+     * NAN Spec: Data Path Attributes / NDP Attribute / Type and Status
+     */
+    boolean acceptRequest;
+    /**
+     * ID of the data-path (NDP) for which we're responding. Obtained as part of the request in
+     * |IWifiNanIfaceEventCallback.eventDataPathRequest|.
+     */
+    int ndpInstanceId;
+    /**
+     * NAN data interface name on which this data-path session is to be started.
+     * This must be an interface created using |IWifiNanIface.createDataInterfaceRequest|.
+     */
+    String ifaceName;
+    /**
+     * Security configuration of the requested data-path.
+     */
+    NanDataPathSecurityConfig securityConfig;
+    /**
+     * Arbitrary information communicated to the peer as part of the data-path setup process. There
+     * is no semantic meaning to these bytes. They are passed-through from sender to receiver as-is
+     * with no parsing.
+     * Max length: |NanCapabilities.maxAppInfoLen|.
+     * NAN Spec: Data Path Attributes / NDP Attribute / NDP Specific Info
+     */
+    byte[] appInfo;
+    /**
+     * A service name to be used with |passphrase| to construct a Pairwise Master Key (PMK) for the
+     * data-path. Only relevant when a data-path is requested which is not associated with a NAN
+     * discovery session - e.g. using out-of-band discovery.
+     * Constraints: same as |NanDiscoveryCommonConfig.serviceName|
+     * NAN Spec: Appendix: Mapping pass-phrase to PMK for NCS-SK Cipher Suites
+     */
+    byte[] serviceNameOutOfBand;
+    /**
+     * ID of an active publish or subscribe discovery session.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte discoverySessionId;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl b/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
new file mode 100644
index 0000000..fab2a40
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanPairingRequestType;
+import android.hardware.wifi.NanPairingSecurityConfig;
+
+/**
+ * Response to a pairing request from a peer.
+ * See Wi-Fi Aware R4.0 section 7.6.1.2
+ */
+@VintfStability
+parcelable NanRespondToPairingIndicationRequest {
+    /**
+     * Accept (true) or reject (false) the request.
+     * NAN Spec: Data Path Attributes / NDP Attribute / Type and Status
+     */
+    boolean acceptRequest;
+    /**
+     * ID of the NAN pairing for which we're responding. Obtained as part of the request in
+     * |IWifiNanIfaceEventCallback.eventPairingRequest|.
+     */
+    int pairingInstanceId;
+    /**
+     * Indicate the pairing session is of setup or verification
+     */
+    NanPairingRequestType requestType;
+    /**
+     * Whether should cache the negotiated NIK/NPK for future verification
+     */
+    boolean enablePairingCache;
+    /**
+     * The Identity key for pairing, can be used for pairing verification
+     */
+    byte[16] pairingIdentityKey;
+    /**
+     * Security config used for the pairing
+     */
+    NanPairingSecurityConfig securityConfig;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanSrfType.aidl b/wifi/aidl/android/hardware/wifi/NanSrfType.aidl
new file mode 100644
index 0000000..4063b17
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanSrfType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN Service Response Filter Attribute Bit.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanSrfType {
+    BLOOM_FILTER = 0,
+    PARTIAL_MAC_ADDR,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanStatus.aidl b/wifi/aidl/android/hardware/wifi/NanStatus.aidl
new file mode 100644
index 0000000..ad29e5b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanStatus.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanStatusCode;
+
+/**
+ * Status information returned in NAN notifications.
+ */
+@VintfStability
+parcelable NanStatus {
+    /**
+     * Status of the command request.
+     */
+    NanStatusCode status;
+    /**
+     * Further description of the issue causing a failure.
+     */
+    String description;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl b/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl
new file mode 100644
index 0000000..6706839
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN API response codes used in request notifications and events.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanStatusCode {
+    SUCCESS = 0,
+    /**
+     * NAN Discovery Engine/Host driver failures.
+     */
+    INTERNAL_FAILURE = 1,
+    /**
+     * NAN OTA failures.
+     */
+    PROTOCOL_FAILURE = 2,
+    /**
+     * The publish/subscribe discovery session id is invalid.
+     */
+    INVALID_SESSION_ID = 3,
+    /**
+     * Out of resources to fufill request.
+     */
+    NO_RESOURCES_AVAILABLE = 4,
+    /**
+     * Invalid arguments passed.
+     */
+    INVALID_ARGS = 5,
+    /**
+     * Invalid peer id.
+     */
+    INVALID_PEER_ID = 6,
+    /**
+     * Invalid NAN data-path (ndp) id.
+     */
+    INVALID_NDP_ID = 7,
+    /**
+     * Attempting to enable NAN when not available, e.g. wifi is disabled.
+     */
+    NAN_NOT_ALLOWED = 8,
+    /**
+     * Over the air ACK not received.
+     */
+    NO_OTA_ACK = 9,
+    /**
+     * Attempting to enable NAN when already enabled.
+     */
+    ALREADY_ENABLED = 10,
+    /**
+     * Can't queue tx followup message for transmission.
+     */
+    FOLLOWUP_TX_QUEUE_FULL = 11,
+    /**
+     * Unsupported concurrency of NAN and another feature - NAN disabled.
+     */
+    UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12,
+    /**
+     * If the pairing id is invalid
+     */
+    INVALID_PAIRING_ID = 13,
+    /**
+     * If the bootstrapping id is invalid
+     */
+    INVALID_BOOTSTRAPPING_ID = 14,
+    /*
+     * If same request is received again
+     */
+    REDUNDANT_REQUEST = 15,
+    /*
+     * If current request is not supported
+     */
+    NOT_SUPPORTED = 16,
+    /*
+     * If no Wifi Aware connection is active
+     */
+    NO_CONNECTION = 17
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
new file mode 100644
index 0000000..0b246ed
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.MacAddress;
+import android.hardware.wifi.NanDiscoveryCommonConfig;
+import android.hardware.wifi.NanPairingConfig;
+import android.hardware.wifi.NanSrfType;
+import android.hardware.wifi.NanSubscribeType;
+
+/**
+ * Subscribe request. Specifies a subscribe discovery operation.
+ */
+@VintfStability
+parcelable NanSubscribeRequest {
+    /**
+     * Common configuration of discovery sessions.
+     */
+    NanDiscoveryCommonConfig baseConfigs;
+    /**
+     * The type of the subscribe discovery session.
+     */
+    NanSubscribeType subscribeType;
+    /**
+     * For |NanSubscribeType.ACTIVE| subscribe discovery sessions, specifies how the Service
+     * Response Filter (SRF) attribute is populated. Relevant only if |shouldUseSrf| is set to true.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Response Filter / SRF Control / SRF
+     * Type
+     */
+    NanSrfType srfType;
+    /**
+     * Configure whether inclusion of an address in |intfAddr| indicates that those devices should
+     * respond or the reverse. Relevant only if |shouldUseSrf| is set to true and |srfType| is set
+     * to |NanSrfType.PARTIAL_MAC_ADDR|. NAN Spec: Service Descriptor Attribute (SDA) / Service
+     * Response Filter / SRF Control / Include
+     */
+    boolean srfRespondIfInAddressSet;
+    /**
+     * Control whether the Service Response Filter (SRF) is used.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Control /
+     *           Service Response Filter Present
+     */
+    boolean shouldUseSrf;
+    /**
+     * Control whether the presence of |NanDiscoveryCommonConfig.serviceSpecificInfo| data is needed
+     * in the publisher in order to trigger service discovery, i.e. a
+     * |IWifiNanIfaceEventCallback.eventMatch|. The test is for presence of data - not for the
+     * specific contents of the data.
+     */
+    boolean isSsiRequiredForMatch;
+    /**
+     * NAN Interface Addresses constituting the Service Response Filter (SRF).
+     * Max length (number of addresses): |NanCapabilities.maxSubscribeInterfaceAddresses|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Response Filter / Address Set
+     */
+    MacAddress[] intfAddr;
+    /**
+     * Security config used for the pairing
+     */
+    NanPairingConfig pairingConfig;
+    /**
+     * The Identity key for pairing, will generate NIRA for verification by the peer
+     */
+    byte[16] identityKey;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanSubscribeType.aidl b/wifi/aidl/android/hardware/wifi/NanSubscribeType.aidl
new file mode 100644
index 0000000..a5e8182
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanSubscribeType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN subscribe discovery session types.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanSubscribeType {
+    PASSIVE = 0,
+    ACTIVE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanSuspensionModeChangeInd.aidl b/wifi/aidl/android/hardware/wifi/NanSuspensionModeChangeInd.aidl
new file mode 100644
index 0000000..057e63b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanSuspensionModeChangeInd.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Event indication that the device entered or exited the suspension mode
+ */
+@VintfStability
+parcelable NanSuspensionModeChangeInd {
+    /**
+     * Indication whether the device has entered or exited the NAN suspension mode(deep sleep)
+     */
+    boolean isSuspended;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanTransmitFollowupRequest.aidl b/wifi/aidl/android/hardware/wifi/NanTransmitFollowupRequest.aidl
new file mode 100644
index 0000000..c88b4ff
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanTransmitFollowupRequest.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Transmit follow up message request.
+ */
+@VintfStability
+parcelable NanTransmitFollowupRequest {
+    /**
+     * ID of an active publish or subscribe discovery session. Follow-up message is transmitted in
+     * the context of the discovery session. NAN Spec: Service Descriptor Attribute (SDA) / Instance
+     * ID
+     */
+    byte discoverySessionId;
+    /**
+     * ID of the peer. Obtained as part of an earlier |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    int peerId;
+    /**
+     * MAC address of the peer. Obtained as part of an earlier
+     * |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    byte[6] addr;
+    /**
+     * Whether the follow-up message should be transmitted with a high priority.
+     */
+    boolean isHighPriority;
+    /**
+     * Whether the follow-up message should be transmitted in a discovery window (true) or a further
+     * availability window (false).
+     */
+    boolean shouldUseDiscoveryWindow;
+    /**
+     * Arbitrary information communicated to the peer. There is no semantic meaning to these
+     * bytes. They are passed-through from sender to receiver as-is with no parsing.
+     * Max length: |NanCapabilities.maxServiceSpecificInfoLen|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Info
+     */
+    byte[] serviceSpecificInfo;
+    /**
+     * Arbitrary information communicated in discovery packets. There is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxExtendedServiceSpecificInfoLen|. Spec: Service Descriptor
+     * Extension Attribute (SDEA) / Service Info
+     */
+    byte[] extendedServiceSpecificInfo;
+    /**
+     * Disable |IWifiNanIfaceEventCallback.eventTransmitFollowup| - i.e. do not get indication on
+     * whether the follow-up was transmitted and received successfully.
+     */
+    boolean disableFollowupResultIndication;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanTxType.aidl b/wifi/aidl/android/hardware/wifi/NanTxType.aidl
new file mode 100644
index 0000000..904a7f4
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanTxType.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN transmit type used in |NanPublishType.SOLICITED| or |NanPublishType.UNSOLICITED_SOLICITED|
+ * publish discovery sessions. Describes the addressing of the packet responding to an ACTIVE
+ * subscribe query.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanTxType {
+    BROADCAST = 0,
+    UNICAST,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NpkSecurityAssociation.aidl b/wifi/aidl/android/hardware/wifi/NpkSecurityAssociation.aidl
new file mode 100644
index 0000000..4d65a41
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NpkSecurityAssociation.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanPairingAkm;
+
+/**
+ * The security association info after Aware Pairing setup.
+ */
+@VintfStability
+parcelable NpkSecurityAssociation {
+    /**
+     * The Aware pairing identity from the peer
+     */
+    byte[16] peerNanIdentityKey;
+    /**
+     * The Aware pairing identity for local device
+     */
+    byte[16] localNanIdentityKey;
+    /**
+     * The PMK is used in this security association
+     */
+    byte[32] npk;
+    /**
+     * The AKM is used for key exchange in this security association
+     */
+    NanPairingAkm akm;
+    /**
+     * Cipher type for pairing. Must be one of |NanCipherSuiteType.PUBLIC_KEY_PASN_128_MASK| or
+     * |NanCipherSuiteType.PUBLIC_KEY_PASN_256_MASK|.
+     */
+    NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttBw.aidl b/wifi/aidl/android/hardware/wifi/RttBw.aidl
new file mode 100644
index 0000000..be9ecbd
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttBw.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * RTT Measurement Bandwidth.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttBw {
+    BW_UNSPECIFIED = 0x0,
+    BW_5MHZ = 0x01,
+    BW_10MHZ = 0x02,
+    BW_20MHZ = 0x04,
+    BW_40MHZ = 0x08,
+    BW_80MHZ = 0x10,
+    BW_160MHZ = 0x20,
+    BW_320MHZ = 0x40,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
new file mode 100644
index 0000000..7c47ed5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.RttBw;
+import android.hardware.wifi.RttPreamble;
+
+/**
+ * RTT Capabilities.
+ */
+@VintfStability
+parcelable RttCapabilities {
+    /**
+     * Whether 1-sided rtt data collection is supported.
+     */
+    boolean rttOneSidedSupported;
+    /**
+     * Whether ftm rtt data collection is supported.
+     */
+    boolean rttFtmSupported;
+    /**
+     * Whether initiator supports LCI request. Applies to 2-sided RTT.
+     */
+    boolean lciSupported;
+    /**
+     * Whether initiator supports LCR request. Applies to 2-sided RTT.
+     */
+    boolean lcrSupported;
+    /**
+     * Whether 11mc responder mode is supported.
+     */
+    boolean responderSupported;
+    /**
+     * Bit mask indicating what preamble is supported by initiator.
+     * Combination of |RttPreamble| values.
+     */
+    RttPreamble preambleSupport;
+    /**
+     * Bit mask indicating what BW is supported by initiator.
+     * Combination of |RttBw| values.
+     */
+    RttBw bwSupport;
+    /**
+     * Draft 11mc spec version supported by chip.
+     * For instance, version 4.0 must be 40 and version 4.3 must be 43 etc.
+     */
+    byte mcVersion;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
new file mode 100644
index 0000000..fc2c2e0
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.RttBw;
+import android.hardware.wifi.RttPeerType;
+import android.hardware.wifi.RttPreamble;
+import android.hardware.wifi.RttType;
+import android.hardware.wifi.WifiChannelInfo;
+
+/**
+ * RTT configuration.
+ */
+@VintfStability
+parcelable RttConfig {
+    /**
+     * Peer device mac address.
+     */
+    byte[6] addr;
+    /**
+     * 1-sided or 2-sided RTT.
+     */
+    RttType type;
+    /**
+     * Optional peer device hint (STA, P2P, AP).
+     */
+    RttPeerType peer;
+    /**
+     * Required for STA-AP mode, optional for P2P, NBD etc.
+     */
+    WifiChannelInfo channel;
+    /**
+     * Time interval between bursts (units: 100 ms).
+     * Applies to 1-sided and 2-sided RTT multi-burst requests.
+     * Range: 0-31, 0: no preference by initiator (2-sided RTT).
+     */
+    int burstPeriod;
+    /**
+     * Total number of RTT bursts to be executed. Will be
+     * specified in the same way as the parameter "Number of
+     * Burst Exponent" found in the FTM frame format. This
+     * applies to both 1-sided RTT and 2-sided RTT. Valid
+     * values are 0 to 15 as defined in 802.11mc std.
+     * 0 means single shot.
+     * The implication of this parameter on the maximum
+     * number of RTT results is the following:
+     * for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst)
+     * for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1)
+     */
+    int numBurst;
+    /**
+     * Number of frames per burst.
+     * Minimum value = 1, Maximum value = 31
+     * For 2-sided, this equals the number of FTM frames
+     * to be attempted in a single burst. This also
+     * equals the number of FTM frames that the
+     * initiator will request that the responder sends
+     * in a single frame.
+     */
+    int numFramesPerBurst;
+    /**
+     * Number of retries for a failed RTT frame.
+     * Applies to 1-sided RTT only. Minimum value = 0, Maximum value = 3
+     */
+    int numRetriesPerRttFrame;
+    /**
+     * The following fields are only valid for 2-side RTT.
+     *
+     *
+     * Maximum number of retries that the initiator can
+     * retry an FTMR frame.
+     * Minimum value = 0, Maximum value = 3
+     */
+    int numRetriesPerFtmr;
+    /**
+     * Whether to request location civic info or not.
+     */
+    boolean mustRequestLci;
+    /**
+     * Whether to request location civic records or not.
+     */
+    boolean mustRequestLcr;
+    /**
+     * Applies to 1-sided and 2-sided RTT. Valid values will
+     * be 2-11 and 15 as specified by the 802.11mc std for
+     * the FTM parameter burst duration. In a multi-burst
+     * request, if responder overrides with larger value,
+     * the initiator will return failure. In a single-burst
+     * request, if responder overrides with larger value,
+     * the initiator will send TMR_STOP to terminate RTT
+     * at the end of the burst_duration it requested.
+     */
+    int burstDuration;
+    /**
+     * RTT preamble to be used in the RTT frames.
+     */
+    RttPreamble preamble;
+    /**
+     * RTT BW to be used in the RTT frames.
+     */
+    RttBw bw;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttLciInformation.aidl b/wifi/aidl/android/hardware/wifi/RttLciInformation.aidl
new file mode 100644
index 0000000..5a49de5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttLciInformation.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.RttMotionPattern;
+
+/**
+ * Movement pattern unknown.
+ */
+@VintfStability
+parcelable RttLciInformation {
+    /**
+     * Latitude in degrees * 2^25 , 2's complement.
+     */
+    long latitude;
+    /**
+     * Longitude in degrees * 2^25 , 2's complement.
+     */
+    long longitude;
+    /**
+     * Altitude in units of 1/256 m.
+     */
+    int altitude;
+    /**
+     * As defined in Section 2.3.2 of IETF RFC 6225.
+     */
+    byte latitudeUnc;
+    /**
+     * As defined in Section 2.3.2 of IETF RFC 6225.
+     */
+    byte longitudeUnc;
+    /**
+     * As defined in Section 2.4.5 from IETF RFC 6225.
+     */
+    byte altitudeUnc;
+    /**
+     * The following elements are for configuring the Z subelement.
+     *
+     *
+     * Motion pattern type.
+     */
+    RttMotionPattern motionPattern;
+    /**
+     * Floor in units of 1/16th of floor. 0x80000000 if unknown.
+     */
+    int floor;
+    /**
+     * In units of 1/64 m.
+     */
+    int heightAboveFloor;
+    /**
+     * In units of 1/64 m. 0 if unknown.
+     */
+    int heightUnc;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttLcrInformation.aidl b/wifi/aidl/android/hardware/wifi/RttLcrInformation.aidl
new file mode 100644
index 0000000..b3bb13a
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttLcrInformation.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+@VintfStability
+parcelable RttLcrInformation {
+    /**
+     * Country code symbol.
+     */
+    byte[2] countryCode;
+    /**
+     * Civic info to be copied in FTM frame.
+     */
+    String civicInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttMotionPattern.aidl b/wifi/aidl/android/hardware/wifi/RttMotionPattern.aidl
new file mode 100644
index 0000000..00517ac
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttMotionPattern.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+@VintfStability
+@Backing(type="int")
+enum RttMotionPattern {
+    /**
+     * Not expected to change location.
+     */
+    NOT_EXPECTED = 0,
+    /**
+     * Expected to change location.
+     */
+    EXPECTED = 1,
+    /**
+     * Movement pattern unknown.
+     */
+    UNKNOWN = 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttPeerType.aidl b/wifi/aidl/android/hardware/wifi/RttPeerType.aidl
new file mode 100644
index 0000000..148a8cc
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttPeerType.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * RTT peer types.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttPeerType {
+    AP = 1,
+    STA = 2,
+    P2P_GO = 3,
+    P2P_CLIENT = 4,
+    NAN_TYPE = 5,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttPreamble.aidl b/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
new file mode 100644
index 0000000..e460a94
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * RTT Measurement Preamble.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttPreamble {
+    LEGACY = 0x1,
+    HT = 0x2,
+    VHT = 0x4,
+    /**
+     * Preamble type for 11ax
+     */
+    HE = 0x8,
+    /**
+     * Preamble type for 11be
+     */
+    EHT = 0x10,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttResponder.aidl b/wifi/aidl/android/hardware/wifi/RttResponder.aidl
new file mode 100644
index 0000000..a16f274
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttResponder.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.RttPreamble;
+import android.hardware.wifi.WifiChannelInfo;
+
+/**
+ * RTT Responder information.
+ */
+@VintfStability
+parcelable RttResponder {
+    WifiChannelInfo channel;
+    RttPreamble preamble;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttResult.aidl b/wifi/aidl/android/hardware/wifi/RttResult.aidl
new file mode 100644
index 0000000..6c45e2c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.RttBw;
+import android.hardware.wifi.RttStatus;
+import android.hardware.wifi.RttType;
+import android.hardware.wifi.WifiInformationElement;
+import android.hardware.wifi.WifiRateInfo;
+
+/**
+ * RTT results.
+ */
+@VintfStability
+parcelable RttResult {
+    /**
+     * Peer device mac address.
+     */
+    byte[6] addr;
+    /**
+     * Burst number in a multi-burst request.
+     */
+    int burstNum;
+    /**
+     * Total RTT measurement frames attempted.
+     */
+    int measurementNumber;
+    /**
+     * Total successful RTT measurement frames.
+     */
+    int successNumber;
+    /**
+     * Maximum number of "FTM frames per burst" supported by
+     * the responder STA. Applies to 2-sided RTT only.
+     * If reponder overrides with larger value:
+     * - for single-burst request, initiator will truncate the
+     * larger value and send a TMR_STOP after receiving as
+     * many frames as originally requested.
+     * - for multi-burst request, initiator will return
+     * failure right away.
+     */
+    byte numberPerBurstPeer;
+    /**
+     * Ranging status.
+     */
+    RttStatus status;
+    /**
+     * If status is RTT_STATUS_FAIL_BUSY_TRY_LATER,
+     * this will be the time provided by the responder as to
+     * when the request can be tried again. Applies to 2-sided
+     * RTT only. In sec, 1-31 sec.
+     */
+    byte retryAfterDuration;
+    /**
+     * RTT type.
+     */
+    RttType type;
+    /**
+     * Average rssi in 0.5 dB steps (e.g. 143 implies -71.5 dB).
+     */
+    int rssi;
+    /**
+     * Rssi spread in 0.5 dB steps (e.g. 5 implies 2.5 dB spread) - optional.
+     */
+    int rssiSpread;
+    /**
+     * 1-sided RTT: TX rate of RTT frame.
+     * 2-sided RTT: TX rate of initiator's Ack in response to FTM frame.
+     */
+    WifiRateInfo txRate;
+    /**
+     * 1-sided RTT: TX rate of Ack from other side.
+     * 2-sided RTT: TX rate of FTM frame coming from responder.
+     */
+    WifiRateInfo rxRate;
+    /**
+     * Round trip time in picoseconds.
+     */
+    long rtt;
+    /**
+     * Rtt standard deviation in picoseconds.
+     */
+    long rttSd;
+    /**
+     * Difference between max and min rtt times recorded in picoseconds.
+     */
+    long rttSpread;
+    /**
+     * Distance in mm (optional).
+     */
+    int distanceInMm;
+    /**
+     * Standard deviation in mm (optional).
+     */
+    int distanceSdInMm;
+    /**
+     * Difference between max and min distance recorded in mm (optional).
+     */
+    int distanceSpreadInMm;
+    /**
+     * Time of the measurement (in microseconds since boot).
+     */
+    long timeStampInUs;
+    /**
+     * Actual time taken by the FW to finish one burst
+     * measurement (in ms). Applies to 1-sided and 2-sided RTT.
+     */
+    int burstDurationInMs;
+    /**
+     * Number of bursts allowed by the responder. Applies
+     * to 2-sided RTT only.
+     */
+    int negotiatedBurstNum;
+    /**
+     * For 11mc only.
+     */
+    WifiInformationElement lci;
+    /**
+     * For 11mc only.
+     */
+    WifiInformationElement lcr;
+    /**
+     * RTT channel frequency in MHz
+     * If frequency is unknown, this will be set to 0.
+     */
+    int channelFreqMHz;
+    /**
+     * RTT packet bandwidth.
+     * This value is an average bandwidth of the bandwidths of measurement
+     * frames. Cap the average close to a specific valid RttBw.
+     */
+    RttBw packetBw;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttStatus.aidl b/wifi/aidl/android/hardware/wifi/RttStatus.aidl
new file mode 100644
index 0000000..600165c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttStatus.aidl
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Ranging status.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttStatus {
+    SUCCESS = 0,
+    /**
+     * General failure status.
+     */
+    FAILURE = 1,
+    /**
+     * Target STA does not respond to request.
+     */
+    FAIL_NO_RSP = 2,
+    /**
+     * Request rejected. Applies to 2-sided RTT only.
+     */
+    FAIL_REJECTED = 3,
+    FAIL_NOT_SCHEDULED_YET = 4,
+    /**
+     * Timing measurement times out.
+     */
+    FAIL_TM_TIMEOUT = 5,
+    /**
+     * Target on different channel, cannot range.
+     */
+    FAIL_AP_ON_DIFF_CHANNEL = 6,
+    /**
+     * Ranging not supported.
+     */
+    FAIL_NO_CAPABILITY = 7,
+    /**
+     * Request aborted for an unknown reason.
+     */
+    ABORTED = 8,
+    /**
+     * Invalid T1-T4 timestamp.
+     */
+    FAIL_INVALID_TS = 9,
+    /**
+     * 11mc protocol failed.
+     */
+    FAIL_PROTOCOL = 10,
+    /**
+     * Request could not be scheduled.
+     */
+    FAIL_SCHEDULE = 11,
+    /**
+     * Responder cannot collaborate at time of request.
+     */
+    FAIL_BUSY_TRY_LATER = 12,
+    /**
+     * Bad request args.
+     */
+    INVALID_REQ = 13,
+    /**
+     * WiFi not enabled.
+     */
+    NO_WIFI = 14,
+    /**
+     * Responder overrides param info, cannot range with new params.
+     */
+    FAIL_FTM_PARAM_OVERRIDE = 15,
+    /**
+     * NAN ranging negotiation failure.
+     */
+    NAN_RANGING_PROTOCOL_FAILURE = 16,
+    /**
+     * NAN concurrency not supported (NDP + RTT).
+     */
+    NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttType.aidl b/wifi/aidl/android/hardware/wifi/RttType.aidl
new file mode 100644
index 0000000..e95a928
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * RTT Types.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttType {
+    ONE_SIDED = 1,
+    TWO_SIDED = 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/Ssid.aidl b/wifi/aidl/android/hardware/wifi/Ssid.aidl
new file mode 100644
index 0000000..230cef6
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/Ssid.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Byte array representing an Ssid. Use when we need to
+ * pass an array of Ssid's to a method, as variable-sized
+ * 2D arrays are not supported in AIDL.
+ */
+@VintfStability
+parcelable Ssid {
+    byte[32] data;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl b/wifi/aidl/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
new file mode 100644
index 0000000..5063b49
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Parameters to specify the APF capabilities of this iface.
+ */
+@VintfStability
+parcelable StaApfPacketFilterCapabilities {
+    /**
+     * Version of the packet filter interpreter supported.
+     */
+    int version;
+    /**
+     * Maximum size of the filter bytecode in bytes for an iface.
+     */
+    int maxLength;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
new file mode 100644
index 0000000..92e2928
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Mask of event reporting schemes that can be specified in background scan
+ * requests.
+ */
+@VintfStability
+@Backing(type="int")
+enum StaBackgroundScanBucketEventReportSchemeMask {
+    /**
+     * Report a scan completion event after scan. If this is not set, then scan
+     * completion events must be reported if report_threshold_percent or
+     * report_threshold_num_scans is reached.
+     */
+    EACH_SCAN = 1 << 0,
+    /**
+     * Forward scan results (beacons/probe responses + IEs) in real time to HAL,
+     * in addition to completion events.
+     * Note: To keep backward compatibility, fire completion events regardless
+     * of REPORT_EVENTS_EACH_SCAN.
+     */
+    FULL_RESULTS = 1 << 1,
+    /**
+     * Controls if scans for this bucket must be placed in the results buffer.
+     */
+    NO_BATCH = 1 << 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
new file mode 100644
index 0000000..76b510d
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiBand;
+
+/**
+ * Background Scan parameters per bucket that can be specified in background
+ * scan requests.
+ */
+@VintfStability
+parcelable StaBackgroundScanBucketParameters {
+    /**
+     * Bucket index. This index is used to report results in
+     * |StaScanData.bucketsScanned|.
+     */
+    int bucketIdx;
+    /**
+     * Bands to scan or |BAND_UNSPECIFIED| if frequencies list must be used
+     * instead.
+     */
+    WifiBand band;
+    /**
+     * Channel frequencies (in Mhz) to scan if |band| is set to
+     * |BAND_UNSPECIFIED|.
+     * Max length: |StaBackgroundScanLimits.MAX_CHANNELS|.
+     */
+    int[] frequencies;
+    /**
+     * Period at which this bucket must be scanned (in milliseconds). Must be an integer
+     * multiple of the |basePeriodInMs| specified in the BackgroundScanParameters.
+     */
+    int periodInMs;
+    /**
+     * Bitset of |StaBackgroundScanBucketEventReportSchemeMask| values controlling
+     * when events for this bucket must be reported.
+     */
+    int eventReportScheme;
+    /**
+     * For exponential back off. If |exponentialMaxPeriodInMs| is non-zero or
+     * different than period, then this bucket is an exponential backoff bucket
+     * and the scan period must grow exponentially as per formula:
+     *   actual_period(N) = period * (base ^ (N/step_count))
+     * to this maximum period (in milliseconds).
+     */
+    int exponentialMaxPeriodInMs;
+    /**
+     * For exponential back off. Multiplier: new_period=old_period * base
+     */
+    int exponentialBase;
+    /**
+     * For exponential back off. Number of scans to perform for a given
+     * period.
+     */
+    int exponentialStepCount;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanCapabilities.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
new file mode 100644
index 0000000..8dd9141
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Parameters to specify the Background Scan capabilities of this iface.
+ */
+@VintfStability
+parcelable StaBackgroundScanCapabilities {
+    /**
+     * Maximum number of bytes available for cached scan results.
+     */
+    int maxCacheSize;
+    /**
+     * Maximum number of buckets that can be supplied for a scan.
+     */
+    int maxBuckets;
+    /**
+     * Maximum number of APs that must be stored for each scan.
+     */
+    int maxApCachePerScan;
+    /**
+     * Max reporting number of scans threshold that can be specified in the scan
+     * parameters.
+     */
+    int maxReportingThreshold;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanLimits.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanLimits.aidl
new file mode 100644
index 0000000..b6fc44c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanLimits.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Max limits for background scan.
+ */
+@VintfStability
+@Backing(type="int")
+enum StaBackgroundScanLimits {
+    MAX_CHANNELS = 16,
+    MAX_BUCKETS = 16,
+    MAX_AP_CACHE_PER_SCAN = 32,
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanParameters.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanParameters.aidl
new file mode 100644
index 0000000..0b56069
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanParameters.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.StaBackgroundScanBucketParameters;
+
+/**
+ * Background Scan parameters that can be specified in background scan
+ * requests.
+ */
+@VintfStability
+parcelable StaBackgroundScanParameters {
+    /**
+     * GCD of all bucket periods (in milliseconds).
+     */
+    int basePeriodInMs;
+    /**
+     * Maximum number of APs that must be stored for each scan. If the maximum
+     * is reached, then the highest RSSI results must be returned.
+     * Max length: |StaBackgroundScanLimits.MAX_AP_CACHE_PER_SCAN|.
+     */
+    int maxApPerScan;
+    /**
+     * % cache buffer filled threshold at which the host must be notified of
+     * batched scan results.
+     */
+    int reportThresholdPercent;
+    /**
+     * Threshold at which the AP must be woken up, in number of scans.
+     */
+    int reportThresholdNumScans;
+    /**
+     * List of buckets to be scheduled.
+     * Max length: |StaBackgroundScanLimits.MAX_BUCKETS|.
+     */
+    StaBackgroundScanBucketParameters[] buckets;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
new file mode 100644
index 0000000..51f6916
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Contention time statistics for different traffic categories.
+ */
+@VintfStability
+parcelable StaLinkLayerIfaceContentionTimeStats {
+    /**
+     * Data packet min contention time (usec). This includes both the internal contention time
+     * among different access categories within the chipset and the contention time for the medium.
+     */
+    int contentionTimeMinInUsec;
+    /**
+     * Data packet max contention time (usec). This includes both the internal contention time
+     * among different access categories within the chipset and the contention time for the medium.
+     */
+    int contentionTimeMaxInUsec;
+    /**
+     * Data packet average contention time (usec). This includes both the internal contention time
+     * among different access categories within the chipset and the contention time for the medium.
+     */
+    int contentionTimeAvgInUsec;
+    /**
+     * Number of data packets used for contention statistics.
+     */
+    int contentionNumSamples;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
new file mode 100644
index 0000000..c0e2c7b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Packet stats for different traffic categories.
+ */
+@VintfStability
+parcelable StaLinkLayerIfacePacketStats {
+    /**
+     * Number of received unicast data packets.
+     */
+    long rxMpdu;
+    /**
+     * Number of successfully transmitted unicast data pkts (ACK rcvd).
+     */
+    long txMpdu;
+    /**
+     * Number of transmitted unicast data pkt losses (no ACK).
+     */
+    long lostMpdu;
+    /**
+     * Number of transmitted unicast data retry pkts.
+     */
+    long retries;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
new file mode 100644
index 0000000..3f8718f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.StaLinkLayerLinkStats;
+
+/**
+ * Iface statistics for the current connection. Current connection may have
+ * single or multiple links.
+ */
+@VintfStability
+parcelable StaLinkLayerIfaceStats {
+    StaLinkLayerLinkStats[] links;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl
new file mode 100644
index 0000000..2519543
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats;
+import android.hardware.wifi.StaLinkLayerIfacePacketStats;
+import android.hardware.wifi.StaPeerInfo;
+
+/**
+ * Per Link statistics for the current connection. For MLO, this is
+ * the statistics for one link in the connection.
+ */
+@VintfStability
+parcelable StaLinkLayerLinkStats {
+    /**
+     * Identifier for the link within MLO. For single link operation this field
+     * is not relevant and can be set to 0.
+     */
+    int linkId;
+    /**
+     * Radio identifier on which the link is currently operating. Refer
+     * |StaLinkLayerRadioStats.radioId|.
+     */
+    int radioId;
+    /**
+     * Frequency of the link in Mhz.
+     */
+    int frequencyMhz;
+    /**
+     * Number of beacons received from the connected AP on the link.
+     */
+    int beaconRx;
+    /**
+     * Access Point Beacon and Management frames RSSI (averaged) on the link.
+     */
+    int avgRssiMgmt;
+    /**
+     * WME Best Effort Access Category packet counters on the link.
+     */
+    StaLinkLayerIfacePacketStats wmeBePktStats;
+    /**
+     * WME Background Access Category packet counters on the link.
+     */
+    StaLinkLayerIfacePacketStats wmeBkPktStats;
+    /**
+     * WME Video Access Category packet counters on the link.
+     */
+    StaLinkLayerIfacePacketStats wmeViPktStats;
+    /**
+     * WME Voice Access Category packet counters on the link.
+     */
+    StaLinkLayerIfacePacketStats wmeVoPktStats;
+    /**
+     * Duty cycle for the link.
+     * If this link is being served using time slicing on a radio with one or
+     * more links then the duty cycle assigned to this link in %. If not using
+     * time slicing, set to 100.
+     */
+    byte timeSliceDutyCycleInPercent;
+    /**
+     * WME Best Effort (BE) Access Category (AC) contention time statistics on
+     * the link.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+    /**
+     * WME Background (BK) Access Category (AC) contention time statistics on
+     * the link.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+    /**
+     * WME Video (VI) Access Category (AC) contention time statistics on the
+     * link.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+    /**
+     * WME Voice (VO) Access Category (AC) contention time statistics on the
+     * link.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+    /**
+     * Per peer statistics for the link.
+     */
+    StaPeerInfo[] peers;
+    /**
+     * Various states of the link.
+     */
+    @Backing(type="int")
+    @VintfStability
+    enum StaLinkState {
+        /**
+         * Chip does not support reporting the state of the link.
+         */
+        UNKNOWN = 0,
+        /**
+         * Link has not been in use since last report. It is placed in power save. All management,
+         * control and data frames for the MLO connection are carried over other links. In this
+         * state the link will not listen to beacons even in DTIM period and does not perform any
+         * GTK/IGTK/BIGTK updates but remains associated.
+         */
+        NOT_IN_USE = 1 << 0,
+        /**
+         * Link is in use. In presence of traffic, it is set to be power active. When the traffic
+         * stops, the link will go into power save mode and will listen for beacons every DTIM
+         * period.
+         *
+         */
+        IN_USE = 1 << 1,
+    }
+    /**
+     * State of the link. Refer |StaLinkState|.
+     */
+    StaLinkState state;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerRadioStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerRadioStats.aidl
new file mode 100644
index 0000000..6105172
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerRadioStats.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiChannelStats;
+
+@VintfStability
+parcelable StaLinkLayerRadioStats {
+    /**
+     * Time for which the radio is awake.
+     */
+    int onTimeInMs;
+    /**
+     * Total time for which the radio is in active transmission.
+     */
+    int txTimeInMs;
+    /**
+     * Time for which the radio is in active tranmission per tx level.
+     */
+    int[] txTimeInMsPerLevel;
+    /**
+     * Time for which the radio is in active receive.
+     */
+    int rxTimeInMs;
+    /**
+     *  Total time for which the radio is awake due to scan.
+     */
+    int onTimeInMsForScan;
+    /**
+     * Total time for which the radio is awake due to NAN scan since boot or crash.
+     */
+    int onTimeInMsForNanScan;
+    /**
+     * Total time for which the radio is awake due to background scan since boot or crash.
+     */
+    int onTimeInMsForBgScan;
+    /**
+     * Total time for which the radio is awake due to roam scan since boot or crash.
+     */
+    int onTimeInMsForRoamScan;
+    /**
+     * Total time for which the radio is awake due to PNO scan since boot or crash.
+     */
+    int onTimeInMsForPnoScan;
+    /**
+     * Total time for which the radio is awake due to Hotspot 2.0 scans and GAS exchange since boot
+     * or crash.
+     */
+    int onTimeInMsForHs20Scan;
+    /**
+     * List of channel stats associated with this radio.
+     */
+    WifiChannelStats[] channelStats;
+    /**
+     * Radio ID: An implementation specific value identifying the radio interface for which the
+     * stats are produced. Framework must not interpret this value. It must use this value for
+     * persistently identifying the statistics between calls,
+     * e.g. if the HAL provides them in different order.
+     */
+    int radioId;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerStats.aidl
new file mode 100644
index 0000000..32be121
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerStats.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.StaLinkLayerIfaceStats;
+import android.hardware.wifi.StaLinkLayerRadioStats;
+
+/**
+ * Link layer stats retrieved via |IWifiStaIface.getLinkLayerStats|.
+ */
+@VintfStability
+parcelable StaLinkLayerStats {
+    StaLinkLayerIfaceStats iface;
+    StaLinkLayerRadioStats[] radios;
+    /**
+     * Timestamp for each stats sample. This is the absolute milliseconds
+     * from boot when these stats were sampled.
+     */
+    long timeStampInMs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaPeerInfo.aidl b/wifi/aidl/android/hardware/wifi/StaPeerInfo.aidl
new file mode 100644
index 0000000..2032802
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaPeerInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.StaRateStat;
+
+/**
+ * Per peer statistics. Types of peers include the Access Point (AP), Tunneled Direct Link
+ * Setup (TDLS), Group Owner (GO), Neighbor Awareness Networking (NAN), etc.
+ */
+@VintfStability
+parcelable StaPeerInfo {
+    /**
+     * Station count: The total number of stations currently associated with the peer.
+     */
+    char staCount;
+    /**
+     * Channel utilization: The percentage of time (normalized to 255, i.e., x% corresponds to
+     * (int) x * 255 / 100) that the medium is sensed as busy measured by either physical or
+     * virtual carrier sense (CS) mechanism.
+     */
+    char chanUtil;
+    /**
+     * Per rate statistics.
+     */
+    StaRateStat[] rateStats;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaRateStat.aidl b/wifi/aidl/android/hardware/wifi/StaRateStat.aidl
new file mode 100644
index 0000000..8326884
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaRateStat.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiRateInfo;
+
+/**
+ * Per rate statistics. The rate is characterized by the combination of preamble, number
+ * of spatial streams, transmission bandwidth, and modulation and coding scheme (MCS).
+ */
+@VintfStability
+parcelable StaRateStat {
+    /**
+     * Wifi rate information: preamble, number of spatial streams, bandwidth, MCS, etc.
+     */
+    WifiRateInfo rateInfo;
+    /**
+     * Number of successfully transmitted data packets (ACK received).
+     */
+    int txMpdu;
+    /**
+     * Number of received data packets.
+     */
+    int rxMpdu;
+    /**
+     * Number of data packet losses (no ACK).
+     */
+    int mpduLost;
+    /**
+     * Number of data packet retries.
+     */
+    int retries;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaRoamingCapabilities.aidl b/wifi/aidl/android/hardware/wifi/StaRoamingCapabilities.aidl
new file mode 100644
index 0000000..7642612
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaRoamingCapabilities.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Structure describing the roaming control capabilities supported.
+ */
+@VintfStability
+parcelable StaRoamingCapabilities {
+    /**
+     * Maximum number of BSSIDs that may be blocklisted.
+     */
+    int maxBlocklistSize;
+    /**
+     * Maximum number of SSIDs that may be allowlisted.
+     */
+    int maxAllowlistSize;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaRoamingConfig.aidl b/wifi/aidl/android/hardware/wifi/StaRoamingConfig.aidl
new file mode 100644
index 0000000..c59c531
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaRoamingConfig.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.MacAddress;
+import android.hardware.wifi.Ssid;
+
+/**
+ * Structure describing the roaming control configuration.
+ */
+@VintfStability
+parcelable StaRoamingConfig {
+    /**
+     * List of BSSIDs that are blocklisted for roaming.
+     */
+    MacAddress[] bssidBlocklist;
+    /**
+     * List of SSIDs that are allowlisted for roaming.
+     */
+    Ssid[] ssidAllowlist;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl b/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
new file mode 100644
index 0000000..d75d323
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Enum describing the various states to set the roaming
+ * control to.
+ */
+@VintfStability
+@Backing(type="byte")
+enum StaRoamingState {
+    /**
+     * Driver/Firmware must not perform any roaming.
+     */
+    DISABLED = 0,
+    /**
+     * Driver/Firmware is allowed to perform roaming while respecting
+     * the |StaRoamingConfig| parameters set using |configureRoaming|.
+     */
+    ENABLED = 1,
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaScanData.aidl b/wifi/aidl/android/hardware/wifi/StaScanData.aidl
new file mode 100644
index 0000000..abc5638
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaScanData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.StaScanResult;
+
+/**
+ * Structure describing all of the access points seen during
+ * the scan.
+ */
+@VintfStability
+parcelable StaScanData {
+    /**
+     * Bitset of |ScanDataFlagMask| values.
+     */
+    int flags;
+    /**
+     * Bitset where each bit indicates if the bucket with that index (starting at
+     * 0) was scanned.
+     */
+    int bucketsScanned;
+    /**
+     * List of scan results.
+     */
+    StaScanResult[] results;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaScanDataFlagMask.aidl b/wifi/aidl/android/hardware/wifi/StaScanDataFlagMask.aidl
new file mode 100644
index 0000000..ea87df5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaScanDataFlagMask.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Mask of flags set in the |ScanData| instance.
+ */
+@VintfStability
+@Backing(type="int")
+enum StaScanDataFlagMask {
+    /**
+     * Indicates that a scan was interrupted/did not occur, so results may be
+     * incomplete.
+     */
+    INTERRUPTED = 1 << 0,
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaScanResult.aidl b/wifi/aidl/android/hardware/wifi/StaScanResult.aidl
new file mode 100644
index 0000000..9f6f415
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaScanResult.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiInformationElement;
+
+/**
+ * Structure describing all the information about a single access point seen
+ * during the scan.
+ */
+@VintfStability
+parcelable StaScanResult {
+    long timeStampInUs;
+    byte[] ssid;
+    byte[6] bssid;
+    int rssi;
+    int frequency;
+    char beaconPeriodInMs;
+    char capability;
+    WifiInformationElement[] informationElements;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiAntennaMode.aidl b/wifi/aidl/android/hardware/wifi/WifiAntennaMode.aidl
new file mode 100644
index 0000000..e21dd87
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiAntennaMode.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Antenna configuration.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiAntennaMode {
+    WIFI_ANTENNA_MODE_UNSPECIFIED = 0,
+    WIFI_ANTENNA_MODE_1X1 = 1,
+    WIFI_ANTENNA_MODE_2X2 = 2,
+    WIFI_ANTENNA_MODE_3X3 = 3,
+    WIFI_ANTENNA_MODE_4X4 = 4,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiBand.aidl b/wifi/aidl/android/hardware/wifi/WifiBand.aidl
new file mode 100644
index 0000000..cfdf944
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiBand.aidl
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Wifi bands defined in the 80211 spec.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiBand {
+    BAND_UNSPECIFIED = 0,
+    /**
+     * 2.4 GHz.
+     */
+    BAND_24GHZ = 1,
+    /**
+     * 5 GHz without DFS.
+     */
+    BAND_5GHZ = 2,
+    /**
+     * 5 GHz DFS only.
+     */
+    BAND_5GHZ_DFS = 4,
+    /**
+     * 5 GHz with DFS.
+     */
+    BAND_5GHZ_WITH_DFS = 6,
+    /**
+     * 2.4 GHz + 5 GHz; no DFS.
+     */
+    BAND_24GHZ_5GHZ = 3,
+    /**
+     * 2.4 GHz + 5 GHz with DFS.
+     */
+    BAND_24GHZ_5GHZ_WITH_DFS = 7,
+    /**
+     * 6 GHz.
+     */
+    BAND_6GHZ = 8,
+    /**
+     * 5 GHz no DFS + 6 GHz.
+     */
+    BAND_5GHZ_6GHZ = 10,
+    /**
+     * 2.4 GHz + 5 GHz no DFS + 6 GHz.
+     */
+    BAND_24GHZ_5GHZ_6GHZ = 11,
+    /**
+     * 2.4 GHz + 5 GHz with DFS + 6 GHz.
+     */
+    BAND_24GHZ_5GHZ_WITH_DFS_6GHZ = 15,
+    /**
+     * 60 GHz.
+     */
+    BAND_60GHZ = 16,
+    /**
+     * 2.4 GHz + 5 GHz no DFS + 6 GHz + 60 GHz.
+     */
+    BAND_24GHZ_5GHZ_6GHZ_60GHZ = 27,
+    /**
+     * 2.4 GHz + 5 GHz with DFS + 6 GHz + 60 GHz.
+     */
+    BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiChannelInfo.aidl b/wifi/aidl/android/hardware/wifi/WifiChannelInfo.aidl
new file mode 100644
index 0000000..8fee7eb
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiChannelInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+
+/**
+ * Channel information.
+ */
+@VintfStability
+parcelable WifiChannelInfo {
+    /**
+     * Channel width (20, 40, 80, 80+80, 160, 320).
+     */
+    WifiChannelWidthInMhz width;
+    /**
+     * Primary 20 MHz channel.
+     */
+    int centerFreq;
+    /**
+     * Center frequency (MHz) first segment.
+     */
+    int centerFreq0;
+    /**
+     * Center frequency (MHz) second segment.
+     */
+    int centerFreq1;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiChannelStats.aidl b/wifi/aidl/android/hardware/wifi/WifiChannelStats.aidl
new file mode 100644
index 0000000..f77821b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiChannelStats.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiChannelInfo;
+
+@VintfStability
+parcelable WifiChannelStats {
+    /**
+     * Channel information.
+     */
+    WifiChannelInfo channel;
+    /**
+     * Total time for which the radio is awake on this channel.
+     */
+    int onTimeInMs;
+    /**
+     * Total time for which CCA is held busy on this channel.
+     */
+    int ccaBusyTimeInMs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiChannelWidthInMhz.aidl b/wifi/aidl/android/hardware/wifi/WifiChannelWidthInMhz.aidl
new file mode 100644
index 0000000..e456530
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiChannelWidthInMhz.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Channel operating width in Mhz.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiChannelWidthInMhz {
+    WIDTH_INVALID = -1,
+    WIDTH_20 = 0,
+    WIDTH_40 = 1,
+    WIDTH_80 = 2,
+    WIDTH_160 = 3,
+    WIDTH_80P80 = 4,
+    WIDTH_5 = 5,
+    WIDTH_10 = 6,
+    /**
+     * 320 MHz
+     */
+    WIDTH_320 = 7,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiChipCapabilities.aidl b/wifi/aidl/android/hardware/wifi/WifiChipCapabilities.aidl
new file mode 100644
index 0000000..77b9049
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiChipCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * WifiChipCapabilities captures various Wifi chip capability params.
+ */
+@VintfStability
+parcelable WifiChipCapabilities {
+    /**
+     * Maximum number of links supported by the chip for MLO association.
+     */
+    int maxMloAssociationLinkCount;
+    /**
+     * Maximum number of Simultaneous Transmit and Receive (STR) links used
+     * in Multi-Link Operation. The maximum number of STR links used can be
+     * different from the maximum number of radios supported by the chip.
+     *
+     * This is a static configuration of the chip.
+     */
+    int maxMloStrLinkCount;
+    /**
+     * Maximum number of concurrent TDLS sessions that can be enabled
+     * by framework via ISupplicantStaIface#initiateTdlsSetup().
+     */
+    int maxConcurrentTdlsSessionCount;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
new file mode 100644
index 0000000..8cf4819
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Struct capturing the count of all rx ICMP packets that caused
+ * host wakeup.
+ */
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxIcmpPacketDetails {
+    /**
+     * Wake icmp packet count.
+     */
+    int icmpPkt;
+    /**
+     * Wake icmp6 packet count.
+     */
+    int icmp6Pkt;
+    /**
+     * Wake icmp6 RA packet count.
+     */
+    int icmp6Ra;
+    /**
+     * Wake icmp6 NA packet count.
+     */
+    int icmp6Na;
+    /**
+     * Wake icmp6 NS packet count.
+     */
+    int icmp6Ns;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
new file mode 100644
index 0000000..51faf66
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Struct capturing the count of all rx multicast packets that caused
+ * host wakeup.
+ */
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxMulticastPacketDetails {
+    /**
+     * Rx wake packet was ipv4 multicast.
+     */
+    int ipv4RxMulticastAddrCnt;
+    /**
+     * Rx wake packet was ipv6 multicast.
+     */
+    int ipv6RxMulticastAddrCnt;
+    /**
+     * Rx wake packet was non-ipv4 and non-ipv6.
+     */
+    int otherRxMulticastAddrCnt;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
new file mode 100644
index 0000000..b5c6a5e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Struct capturing the count of all rx packets that caused
+ * host wakeup.
+ */
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxPacketDetails {
+    /**
+     * Total rx unicast packet which woke up host.
+     */
+    int rxUnicastCnt;
+    /**
+     * Total rx multicast packet which woke up host.
+     */
+    int rxMulticastCnt;
+    /**
+     * Total rx broadcast packet which woke up host.
+     */
+    int rxBroadcastCnt;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
new file mode 100644
index 0000000..82d5d3e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiDebugHostWakeReasonRxIcmpPacketDetails;
+import android.hardware.wifi.WifiDebugHostWakeReasonRxMulticastPacketDetails;
+import android.hardware.wifi.WifiDebugHostWakeReasonRxPacketDetails;
+
+/**
+ * Structure capturing the count of all the wireless related host wakeup.
+ * This is used to capture all the reasons why the host processor
+ * (WLAN driver) was woken up by the WLAN firmware.
+ * These stats may be used to debug any power issues caused due to frequent
+ * wakeup of the host processor by the WLAN firmware.
+ */
+@VintfStability
+parcelable WifiDebugHostWakeReasonStats {
+    /**
+     * Total count of cmd/event wakes.
+     * These must account for all wakeups due to WLAN management
+     * commands/events received over the air.
+     */
+    int totalCmdEventWakeCnt;
+    /**
+     * Vector of wake counts per cmd/event type.
+     * The number of command types and their meaning is only understood by the
+     * vendor.
+     */
+    int[] cmdEventWakeCntPerType;
+    /**
+     * Total count of driver/firmware wakes.
+     * These must account for all wakeups due to local driver/firmware
+     * interactions. These include all vendor implementation specific
+     * interactions like any heart-beat monitoring, bus management, etc.
+     */
+    int totalDriverFwLocalWakeCnt;
+    /**
+     * Vector of wake counts per driver/firmware interaction type.
+     * The number of command types and their meaning is only understood by the
+     * vendor.
+     */
+    int[] driverFwLocalWakeCntPerType;
+    /**
+     * Total data rx packets that woke up host.
+     */
+    int totalRxPacketWakeCnt;
+    WifiDebugHostWakeReasonRxPacketDetails rxPktWakeDetails;
+    WifiDebugHostWakeReasonRxMulticastPacketDetails rxMulticastPkWakeDetails;
+    WifiDebugHostWakeReasonRxIcmpPacketDetails rxIcmpPkWakeDetails;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
new file mode 100644
index 0000000..7601bf2
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiDebugPacketFateFrameType;
+
+/**
+ * Information regarding the frame transmitted/received.
+ */
+@VintfStability
+parcelable WifiDebugPacketFateFrameInfo {
+    /**
+     * The type of MAC-layer frame that this frame_info holds.
+     * - For data frames, use FRAME_TYPE_ETHERNET_II.
+     * - For management frames, use FRAME_TYPE_80211_MGMT.
+     * - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN.
+     */
+    WifiDebugPacketFateFrameType frameType;
+    /**
+     * The number of bytes included in |frameContent|.
+     * If the frame contents are missing (e.g. RX frame dropped in firmware),
+     * |frameLen| must be set to 0.
+     */
+    long frameLen;
+    /**
+     * Host clock when this frame was received by the driver (either outbound
+     * from the host network stack, or inbound from the firmware).
+     * - The timestamp must be taken from a clock which includes time the host
+     *   spent suspended (e.g. ktime_get_boottime()).
+     * - If no host timestamp is available (e.g. RX frame was dropped in firmware),
+     *   this field must be set to 0.
+     */
+    long driverTimestampUsec;
+    /**
+     * Firmware clock when this frame was received by the firmware
+     * (either outbound from the host, or inbound from a remote  station).
+     * - The timestamp must be taken from a clock which includes time firmware
+     *   spent suspended (if applicable).
+     * - If no firmware timestamp is available (e.g. TX frame was dropped by the
+     *   driver), then this field must be set to 0.
+     * - Consumers of |frameInfo| must not assume any synchronization between
+     *   the driver and firmware clocks.
+     */
+    long firmwareTimestampUsec;
+    /**
+     * Actual frame content. This is the raw bytes of the corresponding packet.
+     * - Should be provided for TX frames originated by the host.
+     * - Should be provided for RX frames received by the driver.
+     * - Optionally provided for TX frames originated by firmware.
+     *   (At discretion of HAL implementation.)
+     * - Optionally provided for RX frames dropped in firmware.
+     *   (At discretion of HAL implementation.)
+     * - If frame content is not provided, |frameLen| must be set to 0.
+     */
+    byte[] frameContent;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
new file mode 100644
index 0000000..5c0d171
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Type of frame transmitted/received.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugPacketFateFrameType {
+    UNKNOWN,
+    ETHERNET_II,
+    MGMT_80211,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferFlags.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
new file mode 100644
index 0000000..0d1806e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Flags describing each debug ring buffer.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugRingBufferFlags {
+    HAS_BINARY_ENTRIES = 1 << 0,
+    HAS_ASCII_ENTRIES = 1 << 1,
+    HAS_PER_PACKET_ENTRIES = 1 << 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferStatus.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
new file mode 100644
index 0000000..2b0faa2
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Struct describing each debug ring buffer supported by
+ * the device.
+ */
+@VintfStability
+parcelable WifiDebugRingBufferStatus {
+    /**
+     * Name of this debug ring buffer.
+     */
+    String ringName;
+    /**
+     * Combination of |WifiDebugRingBufferFlags| values.
+     */
+    int flags;
+    /**
+     * Unique integer representing the ring.
+     */
+    int ringId;
+    /**
+     * Total memory size allocated for the buffer.
+     */
+    int sizeInBytes;
+    /**
+     * Amount of free space in the buffer.
+     */
+    int freeSizeInBytes;
+    /**
+     * Verbose level for ring buffer.
+     */
+    int verboseLevel;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
new file mode 100644
index 0000000..30778eb
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Verbose logging level to set for each debug ring buffer supported
+ * by the device.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugRingBufferVerboseLevel {
+    /**
+     * Level 0 corresponds to no collection, and it makes log handler
+     * stop by no more events from driver.
+     */
+    NONE = 0,
+    /**
+     * Level 1 corresponds to normal log level, with minimal user impact.
+     * This is the default value.
+     */
+    DEFAULT = 1,
+    /**
+     * Level 2 is enabled when user is lazily trying to reproduce a problem.
+     * Wifi performance and power can be impacted, but device should not
+     * otherwise be significantly impacted.
+     */
+    VERBOSE = 2,
+    /**
+     * Level 3 is used when trying to actively debug a problem.
+     * This will cause severe performance degradation.
+     */
+    EXCESSIVE = 3,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFate.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFate.aidl
new file mode 100644
index 0000000..2983f81
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFate.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Enum describing the fate of the RX packets.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugRxPacketFate {
+    /**
+     * Valid and delivered to network stack (e.g., netif_rx()).
+     */
+    SUCCESS,
+    /**
+     * Queued within firmware, but not yet sent to driver.
+     */
+    FW_QUEUED,
+    /**
+     * Dropped by firmware due to host-programmable filters.
+     */
+    FW_DROP_FILTER,
+    /**
+     * Dropped by firmware as invalid (e.g. bad checksum, decrypt failed,
+     * or invalid for current state).
+     */
+    FW_DROP_INVALID,
+    /**
+     * Dropped by firmware due to lack of buffer space.
+     */
+    FW_DROP_NOBUFS,
+    /**
+     * Dropped by firmware for any other reason.
+     */
+    FW_DROP_OTHER,
+    /**
+     * Queued within driver, not yet delivered to network stack.
+     */
+    DRV_QUEUED,
+    /**
+     * Dropped by driver due to filter rules.
+     */
+    DRV_DROP_FILTER,
+    /**
+     * Dropped by driver as invalid (e.g. not permitted in current state).
+     */
+    DRV_DROP_INVALID,
+    /**
+     * Dropped by driver due to lack of buffer space.
+     */
+    DRV_DROP_NOBUFS,
+    /**
+     * Dropped by driver for any other reason.
+     */
+    DRV_DROP_OTHER,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
new file mode 100644
index 0000000..f4d709c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiDebugPacketFateFrameInfo;
+import android.hardware.wifi.WifiDebugRxPacketFate;
+
+/**
+ * Struct describing packet fate report for each Rx frame.
+ */
+@VintfStability
+parcelable WifiDebugRxPacketFateReport {
+    WifiDebugRxPacketFate fate;
+    WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFate.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFate.aidl
new file mode 100644
index 0000000..717d62a
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFate.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Enum describing the fate of the TX packets.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugTxPacketFate {
+    /**
+     * Sent over air and ACKed.
+     */
+    ACKED,
+    /**
+     * Sent over air but not ACKed (normal for broadcast/multicast).
+     */
+    SENT,
+    /**
+     * Queued within firmware, but not yet sent over air.
+     */
+    FW_QUEUED,
+    /**
+     * Dropped by firmware as invalid (e.g. bad source address, bad checksum,
+     * or invalid for current state).
+     */
+    FW_DROP_INVALID,
+    /**
+     * Dropped by firmware due to lack of buffer space.
+     */
+    FW_DROP_NOBUFS,
+    /**
+     * Dropped by firmware for any other reason. Includes frames that were sent
+     * by driver to the firmware, but unaccounted for by firmware.
+     */
+    FW_DROP_OTHER,
+    /**
+     * Queued within driver, not yet sent to firmware.
+     */
+    DRV_QUEUED,
+    /**
+     * Dropped by driver as invalid (e.g. bad source address, or invalid for
+     * current state).
+     */
+    DRV_DROP_INVALID,
+    /**
+     * Dropped by driver due to lack of buffer space.
+     */
+    DRV_DROP_NOBUFS,
+    /**
+     * Dropped by driver for any other reason.
+     */
+    DRV_DROP_OTHER,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
new file mode 100644
index 0000000..b59b0a5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiDebugPacketFateFrameInfo;
+import android.hardware.wifi.WifiDebugTxPacketFate;
+
+/**
+ * Struct describing packet fate report for each Tx frame.
+ */
+@VintfStability
+parcelable WifiDebugTxPacketFateReport {
+    WifiDebugTxPacketFate fate;
+    WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiIfaceMode.aidl b/wifi/aidl/android/hardware/wifi/WifiIfaceMode.aidl
new file mode 100644
index 0000000..f70c744
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiIfaceMode.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Interface operating modes.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiIfaceMode {
+    /**
+     * Interface operation mode is client.
+     */
+    IFACE_MODE_STA = 1 << 0,
+    /**
+     * Interface operation mode is Hotspot.
+     */
+    IFACE_MODE_SOFTAP = 1 << 1,
+    /**
+     * Interface operation mode is Ad-Hoc network.
+     */
+    IFACE_MODE_IBSS = 1 << 2,
+    /**
+     * Interface operation mode is Wifi Direct Client.
+     */
+    IFACE_MODE_P2P_CLIENT = 1 << 3,
+    /**
+     * Interface operation mode is Wifi Direct Group Owner.
+     */
+    IFACE_MODE_P2P_GO = 1 << 4,
+    /**
+     * Interface operation mode is Aware.
+     */
+    IFACE_MODE_NAN = 1 << 5,
+    /**
+     * Interface operation mode is Mesh network.
+     */
+    IFACE_MODE_MESH = 1 << 6,
+    /**
+     * Interface operation mode is Tunneled Direct Link Setup.
+     */
+    IFACE_MODE_TDLS = 1 << 7,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiInformationElement.aidl b/wifi/aidl/android/hardware/wifi/WifiInformationElement.aidl
new file mode 100644
index 0000000..f5f6de9
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiInformationElement.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Information elements contained within the |ScanResult| structure.
+ * These elements correspond to the IEEE_802.11 standard.
+ */
+@VintfStability
+parcelable WifiInformationElement {
+    byte id;
+    byte[] data;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRadioCombination.aidl b/wifi/aidl/android/hardware/wifi/WifiRadioCombination.aidl
new file mode 100644
index 0000000..28b15ed
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRadioCombination.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiRadioConfiguration;
+
+/**
+ * Wifi radio combination.
+ */
+@VintfStability
+parcelable WifiRadioCombination {
+    /**
+     * List of radio configurations in this combination.
+     */
+    WifiRadioConfiguration[] radioConfigurations;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRadioConfiguration.aidl b/wifi/aidl/android/hardware/wifi/WifiRadioConfiguration.aidl
new file mode 100644
index 0000000..ae8eff3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRadioConfiguration.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiAntennaMode;
+import android.hardware.wifi.WifiBand;
+
+/**
+ * Wifi radio configuration.
+ */
+@VintfStability
+parcelable WifiRadioConfiguration {
+    /**
+     * Band on which this radio chain is operating.
+     * Valid values of bandInfo are: BAND_24GHZ, BAND_5GHZ, BAND_6GHZ and
+     * BAND_60GHZ.
+     *
+     */
+    WifiBand bandInfo;
+    /**
+     * Wifi Antenna configuration.
+     */
+    WifiAntennaMode antennaMode;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRateInfo.aidl b/wifi/aidl/android/hardware/wifi/WifiRateInfo.aidl
new file mode 100644
index 0000000..c4e285e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRateInfo.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+import android.hardware.wifi.WifiRateNss;
+import android.hardware.wifi.WifiRatePreamble;
+
+/**
+ * Wifi rate info.
+ */
+@VintfStability
+parcelable WifiRateInfo {
+    /**
+     * Preamble used for RTT measurements.
+     */
+    WifiRatePreamble preamble;
+    /**
+     * Number of spatial streams.
+     */
+    WifiRateNss nss;
+    /**
+     * Bandwidth of channel.
+     */
+    WifiChannelWidthInMhz bw;
+    /**
+     * OFDM/CCK rate code as per IEEE std in units of 0.5mbps.
+     * HT/VHT/HE/EHT would be mcs index.
+     */
+    byte rateMcsIdx;
+    /**
+     * Bitrate in units of 100 Kbps.
+     */
+    int bitRateInKbps;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRateNss.aidl b/wifi/aidl/android/hardware/wifi/WifiRateNss.aidl
new file mode 100644
index 0000000..0c263a5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRateNss.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Number of spatial streams in VHT/HT.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiRateNss {
+    NSS_1x1 = 0,
+    NSS_2x2 = 1,
+    NSS_3x3 = 2,
+    NSS_4x4 = 3,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRatePreamble.aidl b/wifi/aidl/android/hardware/wifi/WifiRatePreamble.aidl
new file mode 100644
index 0000000..116e46a
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRatePreamble.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Wifi Rate Preamble.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiRatePreamble {
+    OFDM = 0,
+    CCK = 1,
+    HT = 2,
+    VHT = 3,
+    RESERVED = 4,
+    /**
+     * Preamble type for 11ax.
+     */
+    HE = 5,
+    /**
+     * Preamble type for 11be.
+     */
+    EHT = 6,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiStatusCode.aidl b/wifi/aidl/android/hardware/wifi/WifiStatusCode.aidl
new file mode 100644
index 0000000..30817f3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiStatusCode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Enum values indicating the status of the WiFi operation.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiStatusCode {
+    /**
+     * No errors.
+     */
+    SUCCESS,
+    /**
+     * Method invoked on an invalid |IWifiChip| object.
+     */
+    ERROR_WIFI_CHIP_INVALID,
+    /**
+     * Method invoked on an invalid |IWifiIface| object.
+     */
+    ERROR_WIFI_IFACE_INVALID,
+    /**
+     * Method invoked on an invalid |IWifiRttController| object.
+     */
+    ERROR_WIFI_RTT_CONTROLLER_INVALID,
+    ERROR_NOT_SUPPORTED,
+    ERROR_NOT_AVAILABLE,
+    ERROR_NOT_STARTED,
+    ERROR_INVALID_ARGS,
+    ERROR_BUSY,
+    ERROR_UNKNOWN,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl b/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl
new file mode 100644
index 0000000..077c17e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+
+/**
+ * Wifi usable channel information.
+ */
+@VintfStability
+parcelable WifiUsableChannel {
+    /**
+     * Wifi channel freqeuncy in MHz.
+     */
+    int channel;
+    /**
+     * Wifi channel bandwidth in MHz.
+     */
+    WifiChannelWidthInMhz channelBandwidth;
+    /**
+     * Iface modes feasible on this channel, represented as a bitmask
+     * of |WifiIfaceMode| values.
+     */
+    int ifaceModeMask;
+}
diff --git a/wifi/aidl/default/Android.bp b/wifi/aidl/default/Android.bp
new file mode 100644
index 0000000..91d609d
--- /dev/null
+++ b/wifi/aidl/default/Android.bp
@@ -0,0 +1,218 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+soong_config_module_type {
+    name: "wifi_hal_cc_defaults",
+    module_type: "cc_defaults",
+    config_namespace: "wifi",
+    bool_variables: [
+        "hidl_feature_aware", // WIFI_HIDL_FEATURE_AWARE
+        "hidl_feature_dual_interface", // WIFI_HIDL_FEATURE_DUAL_INTERFACE
+        "hidl_feature_disable_ap", // WIFI_HIDL_FEATURE_DISABLE_AP
+        "hidl_feature_disable_ap_mac_randomization", // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
+        "avoid_iface_reset_mac_change", // WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+        "wifi_skip_state_toggle_off_on_for_nan", // WIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN
+    ],
+    value_variables: [
+        "hal_interface_combinations", // WIFI_HAL_INTERFACE_COMBINATIONS
+    ],
+    properties: [
+        "cppflags",
+    ],
+}
+
+wifi_hal_cc_defaults {
+    name: "android.hardware.wifi-service-cppflags-defaults",
+    soong_config_variables: {
+        hidl_feature_aware: {
+            cppflags: ["-DWIFI_HIDL_FEATURE_AWARE"],
+        },
+        hidl_feature_dual_interface: {
+            cppflags: ["-DWIFI_HIDL_FEATURE_DUAL_INTERFACE"],
+        },
+        hidl_feature_disable_ap: {
+            cppflags: ["-DWIFI_HIDL_FEATURE_DISABLE_AP"],
+        },
+        hidl_feature_disable_ap_mac_randomization: {
+            cppflags: ["-DWIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION"],
+        },
+        avoid_iface_reset_mac_change: {
+            cppflags: ["-DWIFI_AVOID_IFACE_RESET_MAC_CHANGE"],
+        },
+        wifi_skip_state_toggle_off_on_for_nan: {
+            cppflags: ["-DWIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN"],
+        },
+        hal_interface_combinations: {
+            cppflags: ["-DWIFI_HAL_INTERFACE_COMBINATIONS=%s"],
+        },
+    },
+}
+
+cc_library_static {
+    name: "android.hardware.wifi-service-lib",
+    defaults: ["android.hardware.wifi-service-cppflags-defaults"],
+    proprietary: true,
+    compile_multilib: "first",
+    cppflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    // Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed.
+    cflags: ["-Wno-error=implicit-fallthrough"],
+    srcs: [
+        "aidl_struct_util.cpp",
+        "aidl_sync_util.cpp",
+        "ringbuffer.cpp",
+        "wifi.cpp",
+        "wifi_ap_iface.cpp",
+        "wifi_chip.cpp",
+        "wifi_feature_flags.cpp",
+        "wifi_iface_util.cpp",
+        "wifi_legacy_hal.cpp",
+        "wifi_legacy_hal_factory.cpp",
+        "wifi_legacy_hal_stubs.cpp",
+        "wifi_mode_controller.cpp",
+        "wifi_nan_iface.cpp",
+        "wifi_p2p_iface.cpp",
+        "wifi_rtt_controller.cpp",
+        "wifi_sta_iface.cpp",
+        "wifi_status_util.cpp",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "liblog",
+        "libnl",
+        "libutils",
+        "libwifi-hal",
+        "libwifi-system-iface",
+        "libxml2",
+        "android.hardware.wifi-V1-ndk",
+    ],
+
+    export_include_dirs: ["."],
+}
+
+cc_binary {
+    name: "android.hardware.wifi-service",
+    vintf_fragments: ["android.hardware.wifi-service.xml"],
+    relative_install_path: "hw",
+    proprietary: true,
+    cppflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    srcs: ["service.cpp"],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "liblog",
+        "libnl",
+        "libutils",
+        "libwifi-hal",
+        "libwifi-system-iface",
+        "libxml2",
+        "android.hardware.wifi-V1-ndk",
+    ],
+    static_libs: ["android.hardware.wifi-service-lib"],
+    init_rc: ["android.hardware.wifi-service.rc"],
+}
+
+cc_binary {
+    name: "android.hardware.wifi-service-lazy",
+    vintf_fragments: ["android.hardware.wifi-service.xml"],
+    overrides: ["android.hardware.wifi-service"],
+    cflags: ["-DLAZY_SERVICE"],
+    relative_install_path: "hw",
+    proprietary: true,
+    cppflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    srcs: ["service.cpp"],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "liblog",
+        "libnl",
+        "libutils",
+        "libwifi-hal",
+        "libwifi-system-iface",
+        "libxml2",
+        "android.hardware.wifi-V1-ndk",
+    ],
+    static_libs: ["android.hardware.wifi-service-lib"],
+    init_rc: ["android.hardware.wifi-service-lazy.rc"],
+}
+
+cc_test {
+    name: "android.hardware.wifi-service-tests",
+    proprietary: true,
+    compile_multilib: "first",
+    cppflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    srcs: [
+        "tests/aidl_struct_util_unit_tests.cpp",
+        "tests/main.cpp",
+        "tests/mock_interface_tool.cpp",
+        "tests/mock_wifi_feature_flags.cpp",
+        "tests/mock_wifi_iface_util.cpp",
+        "tests/mock_wifi_legacy_hal.cpp",
+        "tests/mock_wifi_mode_controller.cpp",
+        "tests/ringbuffer_unit_tests.cpp",
+        "tests/wifi_nan_iface_unit_tests.cpp",
+        "tests/wifi_chip_unit_tests.cpp",
+        "tests/wifi_iface_util_unit_tests.cpp",
+    ],
+    static_libs: [
+        "libgmock",
+        "libgtest",
+        "android.hardware.wifi-V1-ndk",
+        "android.hardware.wifi-service-lib",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "liblog",
+        "libnl",
+        "libutils",
+        "libwifi-hal",
+        "libwifi-system-iface",
+    ],
+}
+
+filegroup {
+    name: "default-android.hardware.wifi-service.rc",
+    srcs: ["android.hardware.wifi-service.rc"],
+}
+
+filegroup {
+    name: "default-android.hardware.wifi-service.xml",
+    srcs: ["android.hardware.wifi-service.xml"],
+}
diff --git a/wifi/aidl/default/THREADING.README b/wifi/aidl/default/THREADING.README
new file mode 100644
index 0000000..45679da
--- /dev/null
+++ b/wifi/aidl/default/THREADING.README
@@ -0,0 +1,35 @@
+Vendor HAL Threading Model
+==========================
+The vendor HAL service has two threads:
+1. AIDL thread: This is the main thread which processes all the incoming AIDL
+RPC's.
+2. Legacy HAL event loop thread: This is the thread forked off for processing
+the legacy HAL event loop (wifi_event_loop()). This thread is used to process
+any asynchronous netlink events posted by the driver. Any asynchronous
+callbacks passed to the legacy HAL API's are invoked on this thread.
+
+Synchronization Concerns
+========================
+wifi_legacy_hal.cpp has a bunch of global "C" style functions to handle the
+legacy callbacks. Each of these "C" style functions invokes a corresponding
+"std::function" version of the callback which does the actual processing.
+The variables holding these "std::function" callbacks are reset from the AIDL
+thread when they are no longer used. For example: stopGscan() will reset the
+corresponding "on_gscan_*" callback variables which were set when startGscan()
+was invoked. This is not thread safe since these callback variables are
+accesed from the legacy hal event loop thread as well.
+
+Synchronization Solution
+========================
+Adding a global lock seems to be the most trivial solution to the problem.
+a) All of the asynchronous "C" style callbacks will acquire the global lock
+before invoking the corresponding "std::function" callback variables.
+b) All of the AIDL methods will also acquire the global lock before processing
+(in aidl_return_util::validateAndCall()).
+
+Note: It's important that we only acquire the global lock for asynchronous
+callbacks, because there is no guarantee (or documentation to clarify) that the
+synchronous callbacks are invoked on the same invocation thread. If that is not
+the case in some implementation, we will end up deadlocking the system since the
+AIDL thread would have acquired the global lock which is needed by the
+synchronous callback executed on the legacy hal event loop thread.
diff --git a/wifi/aidl/default/aidl_callback_util.h b/wifi/aidl/default/aidl_callback_util.h
new file mode 100644
index 0000000..f8ba53b
--- /dev/null
+++ b/wifi/aidl/default/aidl_callback_util.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AIDL_CALLBACK_UTIL_H_
+#define AIDL_CALLBACK_UTIL_H_
+
+#include <android-base/logging.h>
+
+#include <mutex>
+#include <set>
+#include <unordered_map>
+
+namespace {
+std::unordered_map<void* /* callback */, void* /* handler */> callback_handler_map_;
+std::mutex callback_handler_lock_;
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_callback_util {
+
+// Provides a class to manage callbacks for the various AIDL interfaces and
+// handle the death of the process hosting each callback.
+template <typename CallbackType>
+class AidlCallbackHandler {
+  public:
+    AidlCallbackHandler() {
+        death_handler_ = AIBinder_DeathRecipient_new(AidlCallbackHandler::onCallbackDeath);
+    }
+    ~AidlCallbackHandler() { invalidate(); }
+
+    bool addCallback(const std::shared_ptr<CallbackType>& cb) {
+        std::unique_lock<std::mutex> lk(callback_handler_lock_);
+        void* cbPtr = reinterpret_cast<void*>(cb->asBinder().get());
+        const auto& cbPosition = findCbInSet(cbPtr);
+        if (cbPosition != cb_set_.end()) {
+            LOG(WARNING) << "Duplicate death notification registration";
+            return true;
+        }
+
+        if (AIBinder_linkToDeath(cb->asBinder().get(), death_handler_, cbPtr /* cookie */) !=
+            STATUS_OK) {
+            LOG(ERROR) << "Failed to register death notification";
+            return false;
+        }
+
+        callback_handler_map_[cbPtr] = reinterpret_cast<void*>(this);
+        cb_set_.insert(cb);
+        // unique_lock unlocked here
+        return true;
+    }
+
+    const std::set<std::shared_ptr<CallbackType>>& getCallbacks() {
+        std::unique_lock<std::mutex> lk(callback_handler_lock_);
+        // unique_lock unlocked here
+        return cb_set_;
+    }
+
+    void invalidate() {
+        std::unique_lock<std::mutex> lk(callback_handler_lock_);
+        for (auto cb : cb_set_) {
+            void* cookie = reinterpret_cast<void*>(cb->asBinder().get());
+            if (AIBinder_unlinkToDeath(cb->asBinder().get(), death_handler_, cookie) != STATUS_OK) {
+                LOG(ERROR) << "Failed to deregister death notification";
+            }
+            if (!removeCbFromHandlerMap(cookie)) {
+                LOG(ERROR) << "Failed to remove callback from handler map";
+            }
+        }
+        cb_set_.clear();
+        // unique_lock unlocked here
+    }
+
+    // Entry point for the death handling logic. AIBinder_DeathRecipient
+    // can only call a static function, so use the cookie to find the
+    // proper handler and route the request there.
+    static void onCallbackDeath(void* cookie) {
+        std::unique_lock<std::mutex> lk(callback_handler_lock_);
+        auto cbQuery = callback_handler_map_.find(cookie);
+        if (cbQuery == callback_handler_map_.end()) {
+            LOG(ERROR) << "Invalid death cookie received";
+            return;
+        }
+
+        AidlCallbackHandler* cbHandler = reinterpret_cast<AidlCallbackHandler*>(cbQuery->second);
+        if (cbHandler == nullptr) {
+            LOG(ERROR) << "Handler mapping contained an invalid handler";
+            return;
+        }
+        cbHandler->handleCallbackDeath(cbQuery->first);
+        // unique_lock unlocked here
+    }
+
+  private:
+    std::set<std::shared_ptr<CallbackType>> cb_set_;
+    AIBinder_DeathRecipient* death_handler_;
+
+    typename std::set<std::shared_ptr<CallbackType>>::iterator findCbInSet(void* cbPtr) {
+        const auto& cbPosition = std::find_if(
+                cb_set_.begin(), cb_set_.end(), [cbPtr](const std::shared_ptr<CallbackType>& p) {
+                    return cbPtr == reinterpret_cast<void*>(p->asBinder().get());
+                });
+        return cbPosition;
+    }
+
+    bool removeCbFromHandlerMap(void* cbPtr) {
+        auto cbQuery = callback_handler_map_.find(cbPtr);
+        if (cbQuery != callback_handler_map_.end()) {
+            callback_handler_map_.erase(cbQuery);
+            return true;
+        }
+        return false;
+    }
+
+    void handleCallbackDeath(void* cbPtr) {
+        const auto& cbPosition = findCbInSet(cbPtr);
+        if (cbPosition == cb_set_.end()) {
+            LOG(ERROR) << "Unknown callback death notification received";
+            return;
+        }
+        cb_set_.erase(cbPosition);
+
+        if (!removeCbFromHandlerMap(cbPtr)) {
+            LOG(ERROR) << "Callback was not in callback handler map";
+        }
+    }
+
+    DISALLOW_COPY_AND_ASSIGN(AidlCallbackHandler);
+};
+
+}  // namespace aidl_callback_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // AIDL_CALLBACK_UTIL_H_
diff --git a/wifi/aidl/default/aidl_return_util.h b/wifi/aidl/default/aidl_return_util.h
new file mode 100644
index 0000000..9a49a22
--- /dev/null
+++ b/wifi/aidl/default/aidl_return_util.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AIDL_RETURN_UTIL_H_
+#define AIDL_RETURN_UTIL_H_
+
+#include "aidl_sync_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_return_util {
+using aidl::android::hardware::wifi::WifiStatusCode;
+using aidl::android::hardware::wifi::aidl_sync_util::acquireGlobalLock;
+
+/**
+ * These utility functions are used to invoke a method on the provided
+ * AIDL interface object.
+ * These functions checks if the provided AIDL interface object is valid.
+ * a) If valid, Invokes the corresponding internal implementation function of
+ * the AIDL method.
+ * b) If invalid, return without calling the internal implementation function.
+ */
+
+// Use for AIDL methods which return only an AIDL status.
+template <typename ObjT, typename WorkFuncT, typename... Args>
+::ndk::ScopedAStatus validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid,
+                                     WorkFuncT&& work, Args&&... args) {
+    const auto lock = acquireGlobalLock();
+    if (obj->isValid()) {
+        return (obj->*work)(std::forward<Args>(args)...);
+    } else {
+        return createWifiStatus(status_code_if_invalid);
+    }
+}
+
+// Use for AIDL methods which return only an AIDL status.
+// This version passes the global lock acquired to the body of the method.
+template <typename ObjT, typename WorkFuncT, typename... Args>
+::ndk::ScopedAStatus validateAndCallWithLock(ObjT* obj, WifiStatusCode status_code_if_invalid,
+                                             WorkFuncT&& work, Args&&... args) {
+    auto lock = acquireGlobalLock();
+    if (obj->isValid()) {
+        return (obj->*work)(&lock, std::forward<Args>(args)...);
+    } else {
+        return createWifiStatus(status_code_if_invalid);
+    }
+}
+
+// Use for AIDL methods which have a return value along with the AIDL status
+template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
+::ndk::ScopedAStatus validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid,
+                                     WorkFuncT&& work, ReturnT* ret_val, Args&&... args) {
+    const auto lock = acquireGlobalLock();
+    if (obj->isValid()) {
+        auto call_pair = (obj->*work)(std::forward<Args>(args)...);
+        *ret_val = call_pair.first;
+        return std::forward<::ndk::ScopedAStatus>(call_pair.second);
+    } else {
+        return ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(status_code_if_invalid));
+    }
+}
+
+}  // namespace aidl_return_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+#endif  // AIDL_RETURN_UTIL_H_
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
new file mode 100644
index 0000000..7bc2eeb
--- /dev/null
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -0,0 +1,3359 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <utils/SystemClock.h>
+
+#include "aidl_struct_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_struct_util {
+
+WifiChannelWidthInMhz convertLegacyWifiChannelWidthToAidl(legacy_hal::wifi_channel_width type);
+
+std::string safeConvertChar(const char* str, size_t max_len) {
+    const char* c = str;
+    size_t size = 0;
+    while (*c && (unsigned char)*c < 128 && size < max_len) {
+        ++size;
+        ++c;
+    }
+    return std::string(str, size);
+}
+
+inline std::vector<int32_t> uintToIntVec(const std::vector<uint32_t>& in) {
+    return std::vector<int32_t>(in.begin(), in.end());
+}
+
+IWifiChip::FeatureSetMask convertLegacyChipFeatureToAidl(uint64_t feature) {
+    switch (feature) {
+        case WIFI_FEATURE_SET_TX_POWER_LIMIT:
+            return IWifiChip::FeatureSetMask::SET_TX_POWER_LIMIT;
+        case WIFI_FEATURE_USE_BODY_HEAD_SAR:
+            return IWifiChip::FeatureSetMask::USE_BODY_HEAD_SAR;
+        case WIFI_FEATURE_D2D_RTT:
+            return IWifiChip::FeatureSetMask::D2D_RTT;
+        case WIFI_FEATURE_D2AP_RTT:
+            return IWifiChip::FeatureSetMask::D2AP_RTT;
+        case WIFI_FEATURE_INFRA_60G:
+            return IWifiChip::FeatureSetMask::WIGIG;
+        case WIFI_FEATURE_SET_LATENCY_MODE:
+            return IWifiChip::FeatureSetMask::SET_LATENCY_MODE;
+        case WIFI_FEATURE_P2P_RAND_MAC:
+            return IWifiChip::FeatureSetMask::P2P_RAND_MAC;
+        case WIFI_FEATURE_AFC_CHANNEL:
+            return IWifiChip::FeatureSetMask::SET_AFC_CHANNEL_ALLOWANCE;
+    };
+    CHECK(false) << "Unknown legacy feature: " << feature;
+    return {};
+}
+
+IWifiStaIface::FeatureSetMask convertLegacyStaIfaceFeatureToAidl(uint64_t feature) {
+    switch (feature) {
+        case WIFI_FEATURE_GSCAN:
+            return IWifiStaIface::FeatureSetMask::BACKGROUND_SCAN;
+        case WIFI_FEATURE_LINK_LAYER_STATS:
+            return IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS;
+        case WIFI_FEATURE_RSSI_MONITOR:
+            return IWifiStaIface::FeatureSetMask::RSSI_MONITOR;
+        case WIFI_FEATURE_CONTROL_ROAMING:
+            return IWifiStaIface::FeatureSetMask::CONTROL_ROAMING;
+        case WIFI_FEATURE_IE_WHITELIST:
+            return IWifiStaIface::FeatureSetMask::PROBE_IE_ALLOWLIST;
+        case WIFI_FEATURE_SCAN_RAND:
+            return IWifiStaIface::FeatureSetMask::SCAN_RAND;
+        case WIFI_FEATURE_INFRA_5G:
+            return IWifiStaIface::FeatureSetMask::STA_5G;
+        case WIFI_FEATURE_HOTSPOT:
+            return IWifiStaIface::FeatureSetMask::HOTSPOT;
+        case WIFI_FEATURE_PNO:
+            return IWifiStaIface::FeatureSetMask::PNO;
+        case WIFI_FEATURE_TDLS:
+            return IWifiStaIface::FeatureSetMask::TDLS;
+        case WIFI_FEATURE_TDLS_OFFCHANNEL:
+            return IWifiStaIface::FeatureSetMask::TDLS_OFFCHANNEL;
+        case WIFI_FEATURE_CONFIG_NDO:
+            return IWifiStaIface::FeatureSetMask::ND_OFFLOAD;
+        case WIFI_FEATURE_MKEEP_ALIVE:
+            return IWifiStaIface::FeatureSetMask::KEEP_ALIVE;
+    };
+    CHECK(false) << "Unknown legacy feature: " << feature;
+    return {};
+}
+
+bool convertLegacyChipFeaturesToAidl(uint64_t legacy_feature_set, uint32_t* aidl_feature_set) {
+    if (!aidl_feature_set) {
+        return false;
+    }
+    *aidl_feature_set = 0;
+    std::vector<uint64_t> features = {WIFI_FEATURE_SET_TX_POWER_LIMIT,
+                                      WIFI_FEATURE_USE_BODY_HEAD_SAR,
+                                      WIFI_FEATURE_D2D_RTT,
+                                      WIFI_FEATURE_D2AP_RTT,
+                                      WIFI_FEATURE_INFRA_60G,
+                                      WIFI_FEATURE_SET_LATENCY_MODE,
+                                      WIFI_FEATURE_P2P_RAND_MAC,
+                                      WIFI_FEATURE_AFC_CHANNEL};
+    for (const auto feature : features) {
+        if (feature & legacy_feature_set) {
+            *aidl_feature_set |= static_cast<uint32_t>(convertLegacyChipFeatureToAidl(feature));
+        }
+    }
+
+    return true;
+}
+
+WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToAidl(uint32_t flag) {
+    switch (flag) {
+        case WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES:
+            return WifiDebugRingBufferFlags::HAS_BINARY_ENTRIES;
+        case WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES:
+            return WifiDebugRingBufferFlags::HAS_ASCII_ENTRIES;
+    };
+    CHECK(false) << "Unknown legacy flag: " << flag;
+    return {};
+}
+
+bool convertLegacyDebugRingBufferStatusToAidl(
+        const legacy_hal::wifi_ring_buffer_status& legacy_status,
+        WifiDebugRingBufferStatus* aidl_status) {
+    if (!aidl_status) {
+        return false;
+    }
+    *aidl_status = {};
+    aidl_status->ringName = safeConvertChar(reinterpret_cast<const char*>(legacy_status.name),
+                                            sizeof(legacy_status.name));
+    aidl_status->flags = 0;
+    for (const auto flag :
+         {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES, WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) {
+        if (flag & legacy_status.flags) {
+            aidl_status->flags |= static_cast<std::underlying_type<WifiDebugRingBufferFlags>::type>(
+                    convertLegacyDebugRingBufferFlagsToAidl(flag));
+        }
+    }
+    aidl_status->ringId = legacy_status.ring_id;
+    aidl_status->sizeInBytes = legacy_status.ring_buffer_byte_size;
+    // Calculate free size of the ring the buffer. We don't need to send the
+    // exact read/write pointers that were there in the legacy HAL interface.
+    if (legacy_status.written_bytes >= legacy_status.read_bytes) {
+        aidl_status->freeSizeInBytes = legacy_status.ring_buffer_byte_size -
+                                       (legacy_status.written_bytes - legacy_status.read_bytes);
+    } else {
+        aidl_status->freeSizeInBytes = legacy_status.read_bytes - legacy_status.written_bytes;
+    }
+    aidl_status->verboseLevel = legacy_status.verbose_level;
+    return true;
+}
+
+bool convertLegacyVectorOfDebugRingBufferStatusToAidl(
+        const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
+        std::vector<WifiDebugRingBufferStatus>* aidl_status_vec) {
+    if (!aidl_status_vec) {
+        return false;
+    }
+    *aidl_status_vec = {};
+    for (const auto& legacy_status : legacy_status_vec) {
+        WifiDebugRingBufferStatus aidl_status;
+        if (!convertLegacyDebugRingBufferStatusToAidl(legacy_status, &aidl_status)) {
+            return false;
+        }
+        aidl_status_vec->push_back(aidl_status);
+    }
+    return true;
+}
+
+bool convertLegacyWakeReasonStatsToAidl(const legacy_hal::WakeReasonStats& legacy_stats,
+                                        WifiDebugHostWakeReasonStats* aidl_stats) {
+    if (!aidl_stats) {
+        return false;
+    }
+    *aidl_stats = {};
+    aidl_stats->totalCmdEventWakeCnt = legacy_stats.wake_reason_cnt.total_cmd_event_wake;
+    aidl_stats->cmdEventWakeCntPerType = uintToIntVec(legacy_stats.cmd_event_wake_cnt);
+    aidl_stats->totalDriverFwLocalWakeCnt = legacy_stats.wake_reason_cnt.total_driver_fw_local_wake;
+    aidl_stats->driverFwLocalWakeCntPerType = uintToIntVec(legacy_stats.driver_fw_local_wake_cnt);
+    aidl_stats->totalRxPacketWakeCnt = legacy_stats.wake_reason_cnt.total_rx_data_wake;
+    aidl_stats->rxPktWakeDetails.rxUnicastCnt =
+            legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt;
+    aidl_stats->rxPktWakeDetails.rxMulticastCnt =
+            legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt;
+    aidl_stats->rxPktWakeDetails.rxBroadcastCnt =
+            legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt;
+    aidl_stats->rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt =
+            legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt;
+    aidl_stats->rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt =
+            legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt;
+    aidl_stats->rxMulticastPkWakeDetails.otherRxMulticastAddrCnt =
+            legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt;
+    aidl_stats->rxIcmpPkWakeDetails.icmpPkt =
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt;
+    aidl_stats->rxIcmpPkWakeDetails.icmp6Pkt =
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt;
+    aidl_stats->rxIcmpPkWakeDetails.icmp6Ra =
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra;
+    aidl_stats->rxIcmpPkWakeDetails.icmp6Na =
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na;
+    aidl_stats->rxIcmpPkWakeDetails.icmp6Ns =
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns;
+    return true;
+}
+
+legacy_hal::wifi_power_scenario convertAidlTxPowerScenarioToLegacy(
+        IWifiChip::TxPowerScenario aidl_scenario) {
+    switch (aidl_scenario) {
+        case IWifiChip::TxPowerScenario::VOICE_CALL:
+            return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL;
+        case IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF:
+            return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
+        case IWifiChip::TxPowerScenario::ON_HEAD_CELL_ON:
+            return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
+        case IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF:
+            return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
+        case IWifiChip::TxPowerScenario::ON_BODY_CELL_ON:
+            return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
+    };
+    CHECK(false);
+}
+
+legacy_hal::wifi_latency_mode convertAidlLatencyModeToLegacy(
+        IWifiChip::LatencyMode aidl_latency_mode) {
+    switch (aidl_latency_mode) {
+        case IWifiChip::LatencyMode::NORMAL:
+            return legacy_hal::WIFI_LATENCY_MODE_NORMAL;
+        case IWifiChip::LatencyMode::LOW:
+            return legacy_hal::WIFI_LATENCY_MODE_LOW;
+    }
+    CHECK(false);
+}
+
+bool convertLegacyWifiMacInfoToAidl(const legacy_hal::WifiMacInfo& legacy_mac_info,
+                                    IWifiChipEventCallback::RadioModeInfo* aidl_radio_mode_info) {
+    if (!aidl_radio_mode_info) {
+        return false;
+    }
+    *aidl_radio_mode_info = {};
+
+    aidl_radio_mode_info->radioId = legacy_mac_info.wlan_mac_id;
+    // Convert from bitmask of bands in the legacy HAL to enum value in
+    // the AIDL interface.
+    if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+        legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND &&
+        legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
+        aidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ_6GHZ;
+    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+               legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+        aidl_radio_mode_info->bandInfo = WifiBand::BAND_5GHZ_6GHZ;
+    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND) {
+        aidl_radio_mode_info->bandInfo = WifiBand::BAND_6GHZ;
+    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND &&
+               legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+        aidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ;
+    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
+        aidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ;
+    } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+        aidl_radio_mode_info->bandInfo = WifiBand::BAND_5GHZ;
+    } else {
+        aidl_radio_mode_info->bandInfo = WifiBand::BAND_UNSPECIFIED;
+    }
+    std::vector<IWifiChipEventCallback::IfaceInfo> iface_info_vec;
+    for (const auto& legacy_iface_info : legacy_mac_info.iface_infos) {
+        IWifiChipEventCallback::IfaceInfo iface_info;
+        iface_info.name = legacy_iface_info.name;
+        iface_info.channel = legacy_iface_info.channel;
+        iface_info_vec.push_back(iface_info);
+    }
+    aidl_radio_mode_info->ifaceInfos = iface_info_vec;
+    return true;
+}
+
+uint32_t convertAidlWifiBandToLegacyMacBand(WifiBand aidl_band) {
+    switch (aidl_band) {
+        case WifiBand::BAND_24GHZ:
+            return legacy_hal::WLAN_MAC_2_4_BAND;
+        case WifiBand::BAND_5GHZ:
+        case WifiBand::BAND_5GHZ_DFS:
+        case WifiBand::BAND_5GHZ_WITH_DFS:
+            return legacy_hal::WLAN_MAC_5_0_BAND;
+        case WifiBand::BAND_24GHZ_5GHZ:
+        case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+            return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND);
+        case WifiBand::BAND_6GHZ:
+            return legacy_hal::WLAN_MAC_6_0_BAND;
+        case WifiBand::BAND_5GHZ_6GHZ:
+            return (legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_6_0_BAND);
+        case WifiBand::BAND_24GHZ_5GHZ_6GHZ:
+        case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ:
+            return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
+                    legacy_hal::WLAN_MAC_6_0_BAND);
+        case WifiBand::BAND_60GHZ:
+            return legacy_hal::WLAN_MAC_60_0_BAND;
+        default:
+            return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
+                    legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND);
+    }
+}
+
+WifiBand convertLegacyMacBandToAidlWifiBand(uint32_t band) {
+    switch (band) {
+        case legacy_hal::WLAN_MAC_2_4_BAND:
+            return WifiBand::BAND_24GHZ;
+        case legacy_hal::WLAN_MAC_5_0_BAND:
+            return WifiBand::BAND_5GHZ;
+        case legacy_hal::WLAN_MAC_6_0_BAND:
+            return WifiBand::BAND_6GHZ;
+        case legacy_hal::WLAN_MAC_60_0_BAND:
+            return WifiBand::BAND_60GHZ;
+        default:
+            return WifiBand::BAND_UNSPECIFIED;
+    }
+}
+
+uint32_t convertAidlWifiIfaceModeToLegacy(uint32_t aidl_iface_mask) {
+    uint32_t legacy_iface_mask = 0;
+    if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_STA)) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA);
+    }
+    if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_SOFTAP)) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP);
+    }
+    if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_P2P_CLIENT)) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT);
+    }
+    if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_P2P_GO)) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO);
+    }
+    if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_NAN)) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN);
+    }
+    if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_TDLS)) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS);
+    }
+    if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_MESH)) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH);
+    }
+    if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_IBSS)) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS);
+    }
+    return legacy_iface_mask;
+}
+
+uint32_t convertLegacyWifiInterfaceModeToAidl(uint32_t legacy_iface_mask) {
+    uint32_t aidl_iface_mask = 0;
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) {
+        aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_STA);
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) {
+        aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_SOFTAP);
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) {
+        aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_P2P_CLIENT);
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) {
+        aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_P2P_GO);
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) {
+        aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_NAN);
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) {
+        aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_TDLS);
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) {
+        aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_MESH);
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) {
+        aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_IBSS);
+    }
+    return aidl_iface_mask;
+}
+
+uint32_t convertAidlUsableChannelFilterToLegacy(uint32_t aidl_filter_mask) {
+    uint32_t legacy_filter_mask = 0;
+    if (aidl_filter_mask &
+        static_cast<int32_t>(IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE)) {
+        legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
+    }
+    if (aidl_filter_mask & static_cast<int32_t>(IWifiChip::UsableChannelFilter::CONCURRENCY)) {
+        legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
+    }
+    if (aidl_filter_mask & static_cast<int32_t>(IWifiChip::UsableChannelFilter::NAN_INSTANT_MODE)) {
+        legacy_filter_mask |= WIFI_USABLE_CHANNEL_FILTER_NAN_INSTANT_MODE;
+    }
+    return legacy_filter_mask;
+}
+
+bool convertLegacyWifiUsableChannelToAidl(
+        const legacy_hal::wifi_usable_channel& legacy_usable_channel,
+        WifiUsableChannel* aidl_usable_channel) {
+    if (!aidl_usable_channel) {
+        return false;
+    }
+    *aidl_usable_channel = {};
+    aidl_usable_channel->channel = legacy_usable_channel.freq;
+    aidl_usable_channel->channelBandwidth =
+            convertLegacyWifiChannelWidthToAidl(legacy_usable_channel.width);
+    aidl_usable_channel->ifaceModeMask =
+            convertLegacyWifiInterfaceModeToAidl(legacy_usable_channel.iface_mode_mask);
+
+    return true;
+}
+
+bool convertLegacyWifiUsableChannelsToAidl(
+        const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+        std::vector<WifiUsableChannel>* aidl_usable_channels) {
+    if (!aidl_usable_channels) {
+        return false;
+    }
+    *aidl_usable_channels = {};
+    for (const auto& legacy_usable_channel : legacy_usable_channels) {
+        WifiUsableChannel aidl_usable_channel;
+        if (!convertLegacyWifiUsableChannelToAidl(legacy_usable_channel, &aidl_usable_channel)) {
+            return false;
+        }
+        aidl_usable_channels->push_back(aidl_usable_channel);
+    }
+    return true;
+}
+
+bool convertLegacyWifiMacInfosToAidl(
+        const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+        std::vector<IWifiChipEventCallback::RadioModeInfo>* aidl_radio_mode_infos) {
+    if (!aidl_radio_mode_infos) {
+        return false;
+    }
+    *aidl_radio_mode_infos = {};
+
+    for (const auto& legacy_mac_info : legacy_mac_infos) {
+        IWifiChipEventCallback::RadioModeInfo aidl_radio_mode_info;
+        if (!convertLegacyWifiMacInfoToAidl(legacy_mac_info, &aidl_radio_mode_info)) {
+            return false;
+        }
+        aidl_radio_mode_infos->push_back(aidl_radio_mode_info);
+    }
+    return true;
+}
+
+bool convertLegacyStaIfaceFeaturesToAidl(uint64_t legacy_feature_set, uint32_t* aidl_feature_set) {
+    if (!aidl_feature_set) {
+        return false;
+    }
+    *aidl_feature_set = 0;
+    for (const auto feature :
+         {WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, WIFI_FEATURE_RSSI_MONITOR,
+          WIFI_FEATURE_CONTROL_ROAMING, WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
+          WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, WIFI_FEATURE_TDLS,
+          WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
+        if (feature & legacy_feature_set) {
+            *aidl_feature_set |= static_cast<uint32_t>(convertLegacyStaIfaceFeatureToAidl(feature));
+        }
+    }
+    // There is no flag for this one in the legacy feature set. Adding it to the
+    // set because all the current devices support it.
+    *aidl_feature_set |= static_cast<uint32_t>(IWifiStaIface::FeatureSetMask::APF);
+    return true;
+}
+
+bool convertLegacyApfCapabilitiesToAidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
+                                        StaApfPacketFilterCapabilities* aidl_caps) {
+    if (!aidl_caps) {
+        return false;
+    }
+    *aidl_caps = {};
+    aidl_caps->version = legacy_caps.version;
+    aidl_caps->maxLength = legacy_caps.max_len;
+    return true;
+}
+
+uint8_t convertAidlGscanReportEventFlagToLegacy(
+        StaBackgroundScanBucketEventReportSchemeMask aidl_flag) {
+    using AidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
+    switch (aidl_flag) {
+        case AidlFlag::EACH_SCAN:
+            return REPORT_EVENTS_EACH_SCAN;
+        case AidlFlag::FULL_RESULTS:
+            return REPORT_EVENTS_FULL_RESULTS;
+        case AidlFlag::NO_BATCH:
+            return REPORT_EVENTS_NO_BATCH;
+    };
+    CHECK(false);
+}
+
+StaScanDataFlagMask convertLegacyGscanDataFlagToAidl(uint8_t legacy_flag) {
+    switch (legacy_flag) {
+        case legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED:
+            return StaScanDataFlagMask::INTERRUPTED;
+    };
+    CHECK(false) << "Unknown legacy flag: " << legacy_flag;
+    // To silence the compiler warning about reaching the end of non-void
+    // function.
+    return {};
+}
+
+bool convertLegacyGscanCapabilitiesToAidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
+                                          StaBackgroundScanCapabilities* aidl_caps) {
+    if (!aidl_caps) {
+        return false;
+    }
+    *aidl_caps = {};
+    aidl_caps->maxCacheSize = legacy_caps.max_scan_cache_size;
+    aidl_caps->maxBuckets = legacy_caps.max_scan_buckets;
+    aidl_caps->maxApCachePerScan = legacy_caps.max_ap_cache_per_scan;
+    aidl_caps->maxReportingThreshold = legacy_caps.max_scan_reporting_threshold;
+    return true;
+}
+
+legacy_hal::wifi_band convertAidlWifiBandToLegacy(WifiBand band) {
+    switch (band) {
+        case WifiBand::BAND_UNSPECIFIED:
+            return legacy_hal::WIFI_BAND_UNSPECIFIED;
+        case WifiBand::BAND_24GHZ:
+            return legacy_hal::WIFI_BAND_BG;
+        case WifiBand::BAND_5GHZ:
+            return legacy_hal::WIFI_BAND_A;
+        case WifiBand::BAND_5GHZ_DFS:
+            return legacy_hal::WIFI_BAND_A_DFS;
+        case WifiBand::BAND_5GHZ_WITH_DFS:
+            return legacy_hal::WIFI_BAND_A_WITH_DFS;
+        case WifiBand::BAND_24GHZ_5GHZ:
+            return legacy_hal::WIFI_BAND_ABG;
+        case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+            return legacy_hal::WIFI_BAND_ABG_WITH_DFS;
+        default:
+            CHECK(false);
+            return {};
+    };
+}
+
+bool convertAidlGscanParamsToLegacy(const StaBackgroundScanParameters& aidl_scan_params,
+                                    legacy_hal::wifi_scan_cmd_params* legacy_scan_params) {
+    if (!legacy_scan_params) {
+        return false;
+    }
+    *legacy_scan_params = {};
+    legacy_scan_params->base_period = aidl_scan_params.basePeriodInMs;
+    legacy_scan_params->max_ap_per_scan = aidl_scan_params.maxApPerScan;
+    legacy_scan_params->report_threshold_percent = aidl_scan_params.reportThresholdPercent;
+    legacy_scan_params->report_threshold_num_scans = aidl_scan_params.reportThresholdNumScans;
+    if (aidl_scan_params.buckets.size() > MAX_BUCKETS) {
+        return false;
+    }
+    legacy_scan_params->num_buckets = aidl_scan_params.buckets.size();
+    for (uint32_t bucket_idx = 0; bucket_idx < aidl_scan_params.buckets.size(); bucket_idx++) {
+        const StaBackgroundScanBucketParameters& aidl_bucket_spec =
+                aidl_scan_params.buckets[bucket_idx];
+        legacy_hal::wifi_scan_bucket_spec& legacy_bucket_spec =
+                legacy_scan_params->buckets[bucket_idx];
+        if (aidl_bucket_spec.bucketIdx >= MAX_BUCKETS) {
+            return false;
+        }
+        legacy_bucket_spec.bucket = aidl_bucket_spec.bucketIdx;
+        legacy_bucket_spec.band = convertAidlWifiBandToLegacy(aidl_bucket_spec.band);
+        legacy_bucket_spec.period = aidl_bucket_spec.periodInMs;
+        legacy_bucket_spec.max_period = aidl_bucket_spec.exponentialMaxPeriodInMs;
+        legacy_bucket_spec.base = aidl_bucket_spec.exponentialBase;
+        legacy_bucket_spec.step_count = aidl_bucket_spec.exponentialStepCount;
+        legacy_bucket_spec.report_events = 0;
+        using AidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
+        for (const auto flag : {AidlFlag::EACH_SCAN, AidlFlag::FULL_RESULTS, AidlFlag::NO_BATCH}) {
+            if (aidl_bucket_spec.eventReportScheme &
+                static_cast<std::underlying_type<AidlFlag>::type>(flag)) {
+                legacy_bucket_spec.report_events |= convertAidlGscanReportEventFlagToLegacy(flag);
+            }
+        }
+        if (aidl_bucket_spec.frequencies.size() > MAX_CHANNELS) {
+            return false;
+        }
+        legacy_bucket_spec.num_channels = aidl_bucket_spec.frequencies.size();
+        for (uint32_t freq_idx = 0; freq_idx < aidl_bucket_spec.frequencies.size(); freq_idx++) {
+            legacy_bucket_spec.channels[freq_idx].channel = aidl_bucket_spec.frequencies[freq_idx];
+        }
+    }
+    return true;
+}
+
+bool convertLegacyIeToAidl(const legacy_hal::wifi_information_element& legacy_ie,
+                           WifiInformationElement* aidl_ie) {
+    if (!aidl_ie) {
+        return false;
+    }
+    *aidl_ie = {};
+    aidl_ie->id = legacy_ie.id;
+    aidl_ie->data = std::vector<uint8_t>(legacy_ie.data, legacy_ie.data + legacy_ie.len);
+    return true;
+}
+
+bool convertLegacyIeBlobToAidl(const uint8_t* ie_blob, uint32_t ie_blob_len,
+                               std::vector<WifiInformationElement>* aidl_ies) {
+    if (!ie_blob || !aidl_ies) {
+        return false;
+    }
+    *aidl_ies = {};
+    const uint8_t* ies_begin = ie_blob;
+    const uint8_t* ies_end = ie_blob + ie_blob_len;
+    const uint8_t* next_ie = ies_begin;
+    using wifi_ie = legacy_hal::wifi_information_element;
+    constexpr size_t kIeHeaderLen = sizeof(wifi_ie);
+    // Each IE should at least have the header (i.e |id| & |len| fields).
+    while (next_ie + kIeHeaderLen <= ies_end) {
+        const wifi_ie& legacy_ie = (*reinterpret_cast<const wifi_ie*>(next_ie));
+        uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len;
+        if (next_ie + curr_ie_len > ies_end) {
+            LOG(ERROR) << "Error parsing IE blob. Next IE: " << (void*)next_ie
+                       << ", Curr IE len: " << curr_ie_len << ", IEs End: " << (void*)ies_end;
+            break;
+        }
+        WifiInformationElement aidl_ie;
+        if (!convertLegacyIeToAidl(legacy_ie, &aidl_ie)) {
+            LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id << ", len: " << legacy_ie.len;
+            break;
+        }
+        aidl_ies->push_back(std::move(aidl_ie));
+        next_ie += curr_ie_len;
+    }
+    // Check if the blob has been fully consumed.
+    if (next_ie != ies_end) {
+        LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " << (void*)next_ie
+                   << ", IEs End: " << (void*)ies_end;
+    }
+    return true;
+}
+
+bool convertLegacyGscanResultToAidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
+                                    bool has_ie_data, StaScanResult* aidl_scan_result) {
+    if (!aidl_scan_result) {
+        return false;
+    }
+    *aidl_scan_result = {};
+    aidl_scan_result->timeStampInUs = legacy_scan_result.ts;
+    aidl_scan_result->ssid = std::vector<uint8_t>(
+            legacy_scan_result.ssid,
+            legacy_scan_result.ssid +
+                    strnlen(legacy_scan_result.ssid, sizeof(legacy_scan_result.ssid) - 1));
+    aidl_scan_result->bssid = std::array<uint8_t, 6>();
+    std::copy(legacy_scan_result.bssid, legacy_scan_result.bssid + 6,
+              std::begin(aidl_scan_result->bssid));
+    aidl_scan_result->frequency = legacy_scan_result.channel;
+    aidl_scan_result->rssi = legacy_scan_result.rssi;
+    aidl_scan_result->beaconPeriodInMs = legacy_scan_result.beacon_period;
+    aidl_scan_result->capability = legacy_scan_result.capability;
+    if (has_ie_data) {
+        std::vector<WifiInformationElement> ies;
+        if (!convertLegacyIeBlobToAidl(reinterpret_cast<const uint8_t*>(legacy_scan_result.ie_data),
+                                       legacy_scan_result.ie_length, &ies)) {
+            return false;
+        }
+        aidl_scan_result->informationElements = std::move(ies);
+    }
+    return true;
+}
+
+bool convertLegacyCachedGscanResultsToAidl(
+        const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result,
+        StaScanData* aidl_scan_data) {
+    if (!aidl_scan_data) {
+        return false;
+    }
+    *aidl_scan_data = {};
+    int32_t flags = 0;
+    for (const auto flag : {legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED}) {
+        if (legacy_cached_scan_result.flags & flag) {
+            flags |= static_cast<std::underlying_type<StaScanDataFlagMask>::type>(
+                    convertLegacyGscanDataFlagToAidl(flag));
+        }
+    }
+    aidl_scan_data->flags = flags;
+    aidl_scan_data->bucketsScanned = legacy_cached_scan_result.buckets_scanned;
+
+    CHECK(legacy_cached_scan_result.num_results >= 0 &&
+          legacy_cached_scan_result.num_results <= MAX_AP_CACHE_PER_SCAN);
+    std::vector<StaScanResult> aidl_scan_results;
+    for (int32_t result_idx = 0; result_idx < legacy_cached_scan_result.num_results; result_idx++) {
+        StaScanResult aidl_scan_result;
+        if (!convertLegacyGscanResultToAidl(legacy_cached_scan_result.results[result_idx], false,
+                                            &aidl_scan_result)) {
+            return false;
+        }
+        aidl_scan_results.push_back(aidl_scan_result);
+    }
+    aidl_scan_data->results = std::move(aidl_scan_results);
+    return true;
+}
+
+bool convertLegacyVectorOfCachedGscanResultsToAidl(
+        const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
+        std::vector<StaScanData>* aidl_scan_datas) {
+    if (!aidl_scan_datas) {
+        return false;
+    }
+    *aidl_scan_datas = {};
+    for (const auto& legacy_cached_scan_result : legacy_cached_scan_results) {
+        StaScanData aidl_scan_data;
+        if (!convertLegacyCachedGscanResultsToAidl(legacy_cached_scan_result, &aidl_scan_data)) {
+            return false;
+        }
+        aidl_scan_datas->push_back(aidl_scan_data);
+    }
+    return true;
+}
+
+WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToAidl(legacy_hal::wifi_tx_packet_fate fate) {
+    switch (fate) {
+        case legacy_hal::TX_PKT_FATE_ACKED:
+            return WifiDebugTxPacketFate::ACKED;
+        case legacy_hal::TX_PKT_FATE_SENT:
+            return WifiDebugTxPacketFate::SENT;
+        case legacy_hal::TX_PKT_FATE_FW_QUEUED:
+            return WifiDebugTxPacketFate::FW_QUEUED;
+        case legacy_hal::TX_PKT_FATE_FW_DROP_INVALID:
+            return WifiDebugTxPacketFate::FW_DROP_INVALID;
+        case legacy_hal::TX_PKT_FATE_FW_DROP_NOBUFS:
+            return WifiDebugTxPacketFate::FW_DROP_NOBUFS;
+        case legacy_hal::TX_PKT_FATE_FW_DROP_OTHER:
+            return WifiDebugTxPacketFate::FW_DROP_OTHER;
+        case legacy_hal::TX_PKT_FATE_DRV_QUEUED:
+            return WifiDebugTxPacketFate::DRV_QUEUED;
+        case legacy_hal::TX_PKT_FATE_DRV_DROP_INVALID:
+            return WifiDebugTxPacketFate::DRV_DROP_INVALID;
+        case legacy_hal::TX_PKT_FATE_DRV_DROP_NOBUFS:
+            return WifiDebugTxPacketFate::DRV_DROP_NOBUFS;
+        case legacy_hal::TX_PKT_FATE_DRV_DROP_OTHER:
+            return WifiDebugTxPacketFate::DRV_DROP_OTHER;
+    };
+    CHECK(false) << "Unknown legacy fate type: " << fate;
+}
+
+WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToAidl(legacy_hal::wifi_rx_packet_fate fate) {
+    switch (fate) {
+        case legacy_hal::RX_PKT_FATE_SUCCESS:
+            return WifiDebugRxPacketFate::SUCCESS;
+        case legacy_hal::RX_PKT_FATE_FW_QUEUED:
+            return WifiDebugRxPacketFate::FW_QUEUED;
+        case legacy_hal::RX_PKT_FATE_FW_DROP_FILTER:
+            return WifiDebugRxPacketFate::FW_DROP_FILTER;
+        case legacy_hal::RX_PKT_FATE_FW_DROP_INVALID:
+            return WifiDebugRxPacketFate::FW_DROP_INVALID;
+        case legacy_hal::RX_PKT_FATE_FW_DROP_NOBUFS:
+            return WifiDebugRxPacketFate::FW_DROP_NOBUFS;
+        case legacy_hal::RX_PKT_FATE_FW_DROP_OTHER:
+            return WifiDebugRxPacketFate::FW_DROP_OTHER;
+        case legacy_hal::RX_PKT_FATE_DRV_QUEUED:
+            return WifiDebugRxPacketFate::DRV_QUEUED;
+        case legacy_hal::RX_PKT_FATE_DRV_DROP_FILTER:
+            return WifiDebugRxPacketFate::DRV_DROP_FILTER;
+        case legacy_hal::RX_PKT_FATE_DRV_DROP_INVALID:
+            return WifiDebugRxPacketFate::DRV_DROP_INVALID;
+        case legacy_hal::RX_PKT_FATE_DRV_DROP_NOBUFS:
+            return WifiDebugRxPacketFate::DRV_DROP_NOBUFS;
+        case legacy_hal::RX_PKT_FATE_DRV_DROP_OTHER:
+            return WifiDebugRxPacketFate::DRV_DROP_OTHER;
+    };
+    CHECK(false) << "Unknown legacy fate type: " << fate;
+}
+
+WifiDebugPacketFateFrameType convertLegacyDebugPacketFateFrameTypeToAidl(
+        legacy_hal::frame_type type) {
+    switch (type) {
+        case legacy_hal::FRAME_TYPE_UNKNOWN:
+            return WifiDebugPacketFateFrameType::UNKNOWN;
+        case legacy_hal::FRAME_TYPE_ETHERNET_II:
+            return WifiDebugPacketFateFrameType::ETHERNET_II;
+        case legacy_hal::FRAME_TYPE_80211_MGMT:
+            return WifiDebugPacketFateFrameType::MGMT_80211;
+    };
+    CHECK(false) << "Unknown legacy frame type: " << type;
+}
+
+bool convertLegacyDebugPacketFateFrameToAidl(const legacy_hal::frame_info& legacy_frame,
+                                             WifiDebugPacketFateFrameInfo* aidl_frame) {
+    if (!aidl_frame) {
+        return false;
+    }
+    *aidl_frame = {};
+    aidl_frame->frameType = convertLegacyDebugPacketFateFrameTypeToAidl(legacy_frame.payload_type);
+    aidl_frame->frameLen = legacy_frame.frame_len;
+    aidl_frame->driverTimestampUsec = legacy_frame.driver_timestamp_usec;
+    aidl_frame->firmwareTimestampUsec = legacy_frame.firmware_timestamp_usec;
+    const uint8_t* frame_begin =
+            reinterpret_cast<const uint8_t*>(legacy_frame.frame_content.ethernet_ii_bytes);
+    aidl_frame->frameContent =
+            std::vector<uint8_t>(frame_begin, frame_begin + legacy_frame.frame_len);
+    return true;
+}
+
+bool convertLegacyDebugTxPacketFateToAidl(const legacy_hal::wifi_tx_report& legacy_fate,
+                                          WifiDebugTxPacketFateReport* aidl_fate) {
+    if (!aidl_fate) {
+        return false;
+    }
+    *aidl_fate = {};
+    aidl_fate->fate = convertLegacyDebugTxPacketFateToAidl(legacy_fate.fate);
+    return convertLegacyDebugPacketFateFrameToAidl(legacy_fate.frame_inf, &aidl_fate->frameInfo);
+}
+
+bool convertLegacyVectorOfDebugTxPacketFateToAidl(
+        const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
+        std::vector<WifiDebugTxPacketFateReport>* aidl_fates) {
+    if (!aidl_fates) {
+        return false;
+    }
+    *aidl_fates = {};
+    for (const auto& legacy_fate : legacy_fates) {
+        WifiDebugTxPacketFateReport aidl_fate;
+        if (!convertLegacyDebugTxPacketFateToAidl(legacy_fate, &aidl_fate)) {
+            return false;
+        }
+        aidl_fates->push_back(aidl_fate);
+    }
+    return true;
+}
+
+bool convertLegacyDebugRxPacketFateToAidl(const legacy_hal::wifi_rx_report& legacy_fate,
+                                          WifiDebugRxPacketFateReport* aidl_fate) {
+    if (!aidl_fate) {
+        return false;
+    }
+    *aidl_fate = {};
+    aidl_fate->fate = convertLegacyDebugRxPacketFateToAidl(legacy_fate.fate);
+    return convertLegacyDebugPacketFateFrameToAidl(legacy_fate.frame_inf, &aidl_fate->frameInfo);
+}
+
+bool convertLegacyVectorOfDebugRxPacketFateToAidl(
+        const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
+        std::vector<WifiDebugRxPacketFateReport>* aidl_fates) {
+    if (!aidl_fates) {
+        return false;
+    }
+    *aidl_fates = {};
+    for (const auto& legacy_fate : legacy_fates) {
+        WifiDebugRxPacketFateReport aidl_fate;
+        if (!convertLegacyDebugRxPacketFateToAidl(legacy_fate, &aidl_fate)) {
+            return false;
+        }
+        aidl_fates->push_back(aidl_fate);
+    }
+    return true;
+}
+
+bool convertLegacyLinkLayerRadioStatsToAidl(
+        const legacy_hal::LinkLayerRadioStats& legacy_radio_stat,
+        StaLinkLayerRadioStats* aidl_radio_stat) {
+    if (!aidl_radio_stat) {
+        return false;
+    }
+    *aidl_radio_stat = {};
+
+    aidl_radio_stat->radioId = legacy_radio_stat.stats.radio;
+    aidl_radio_stat->onTimeInMs = legacy_radio_stat.stats.on_time;
+    aidl_radio_stat->txTimeInMs = legacy_radio_stat.stats.tx_time;
+    aidl_radio_stat->rxTimeInMs = legacy_radio_stat.stats.rx_time;
+    aidl_radio_stat->onTimeInMsForScan = legacy_radio_stat.stats.on_time_scan;
+    aidl_radio_stat->txTimeInMsPerLevel = uintToIntVec(legacy_radio_stat.tx_time_per_levels);
+    aidl_radio_stat->onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd;
+    aidl_radio_stat->onTimeInMsForBgScan = legacy_radio_stat.stats.on_time_gscan;
+    aidl_radio_stat->onTimeInMsForRoamScan = legacy_radio_stat.stats.on_time_roam_scan;
+    aidl_radio_stat->onTimeInMsForPnoScan = legacy_radio_stat.stats.on_time_pno_scan;
+    aidl_radio_stat->onTimeInMsForHs20Scan = legacy_radio_stat.stats.on_time_hs20;
+
+    std::vector<WifiChannelStats> aidl_channel_stats;
+
+    for (const auto& channel_stat : legacy_radio_stat.channel_stats) {
+        WifiChannelStats aidl_channel_stat;
+        aidl_channel_stat.onTimeInMs = channel_stat.on_time;
+        aidl_channel_stat.ccaBusyTimeInMs = channel_stat.cca_busy_time;
+        aidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20;
+        aidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq;
+        aidl_channel_stat.channel.centerFreq0 = channel_stat.channel.center_freq0;
+        aidl_channel_stat.channel.centerFreq1 = channel_stat.channel.center_freq1;
+        aidl_channel_stats.push_back(aidl_channel_stat);
+    }
+
+    aidl_radio_stat->channelStats = aidl_channel_stats;
+
+    return true;
+}
+
+bool convertLegacyLinkLayerMlStatsToAidl(const legacy_hal::LinkLayerMlStats& legacy_ml_stats,
+                                         StaLinkLayerStats* aidl_stats) {
+    if (!aidl_stats) {
+        return false;
+    }
+    *aidl_stats = {};
+    std::vector<StaLinkLayerLinkStats> links;
+    // Iterate over each links
+    for (const auto& link : legacy_ml_stats.links) {
+        StaLinkLayerLinkStats linkStats = {};
+        linkStats.linkId = link.stat.link_id;
+        linkStats.radioId = link.stat.radio;
+        linkStats.frequencyMhz = link.stat.frequency;
+        linkStats.beaconRx = link.stat.beacon_rx;
+        linkStats.avgRssiMgmt = link.stat.rssi_mgmt;
+        linkStats.wmeBePktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
+        linkStats.wmeBePktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
+        linkStats.wmeBePktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
+        linkStats.wmeBePktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_BE].retries;
+        linkStats.wmeBeContentionTimeStats.contentionTimeMinInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
+        linkStats.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
+        linkStats.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
+        linkStats.wmeBeContentionTimeStats.contentionNumSamples =
+                link.stat.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
+        linkStats.wmeBkPktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
+        linkStats.wmeBkPktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
+        linkStats.wmeBkPktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
+        linkStats.wmeBkPktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_BK].retries;
+        linkStats.wmeBkContentionTimeStats.contentionTimeMinInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
+        linkStats.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
+        linkStats.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
+        linkStats.wmeBkContentionTimeStats.contentionNumSamples =
+                link.stat.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
+        linkStats.wmeViPktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
+        linkStats.wmeViPktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
+        linkStats.wmeViPktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
+        linkStats.wmeViPktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_VI].retries;
+        linkStats.wmeViContentionTimeStats.contentionTimeMinInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
+        linkStats.wmeViContentionTimeStats.contentionTimeMaxInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
+        linkStats.wmeViContentionTimeStats.contentionTimeAvgInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
+        linkStats.wmeViContentionTimeStats.contentionNumSamples =
+                link.stat.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
+        linkStats.wmeVoPktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
+        linkStats.wmeVoPktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
+        linkStats.wmeVoPktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
+        linkStats.wmeVoPktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_VO].retries;
+        linkStats.wmeVoContentionTimeStats.contentionTimeMinInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
+        linkStats.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
+        linkStats.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
+                link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
+        linkStats.wmeVoContentionTimeStats.contentionNumSamples =
+                link.stat.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
+        linkStats.timeSliceDutyCycleInPercent = link.stat.time_slicing_duty_cycle_percent;
+        // peer info legacy_stats conversion.
+        std::vector<StaPeerInfo> aidl_peers_info_stats;
+        for (const auto& legacy_peer_info_stats : link.peers) {
+            StaPeerInfo aidl_peer_info_stats;
+            if (!convertLegacyPeerInfoStatsToAidl(legacy_peer_info_stats, &aidl_peer_info_stats)) {
+                return false;
+            }
+            aidl_peers_info_stats.push_back(aidl_peer_info_stats);
+        }
+        linkStats.peers = aidl_peers_info_stats;
+        // Push link stats to aidl stats.
+        links.push_back(linkStats);
+    }
+    aidl_stats->iface.links = links;
+    // radio legacy_stats conversion.
+    std::vector<StaLinkLayerRadioStats> aidl_radios_stats;
+    for (const auto& legacy_radio_stats : legacy_ml_stats.radios) {
+        StaLinkLayerRadioStats aidl_radio_stats;
+        if (!convertLegacyLinkLayerRadioStatsToAidl(legacy_radio_stats, &aidl_radio_stats)) {
+            return false;
+        }
+        aidl_radios_stats.push_back(aidl_radio_stats);
+    }
+    aidl_stats->radios = aidl_radios_stats;
+    aidl_stats->timeStampInMs = ::android::uptimeMillis();
+
+    return true;
+}
+
+bool convertLegacyLinkLayerStatsToAidl(const legacy_hal::LinkLayerStats& legacy_stats,
+                                       StaLinkLayerStats* aidl_stats) {
+    if (!aidl_stats) {
+        return false;
+    }
+    *aidl_stats = {};
+    std::vector<StaLinkLayerLinkStats> links;
+    StaLinkLayerLinkStats linkStats = {};
+    // iface legacy_stats conversion.
+    linkStats.linkId = 0;
+    linkStats.beaconRx = legacy_stats.iface.beacon_rx;
+    linkStats.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
+    linkStats.wmeBePktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
+    linkStats.wmeBePktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
+    linkStats.wmeBePktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
+    linkStats.wmeBePktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
+    linkStats.wmeBeContentionTimeStats.contentionTimeMinInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
+    linkStats.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
+    linkStats.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
+    linkStats.wmeBeContentionTimeStats.contentionNumSamples =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
+    linkStats.wmeBkPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
+    linkStats.wmeBkPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
+    linkStats.wmeBkPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
+    linkStats.wmeBkPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
+    linkStats.wmeBkContentionTimeStats.contentionTimeMinInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
+    linkStats.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
+    linkStats.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
+    linkStats.wmeBkContentionTimeStats.contentionNumSamples =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
+    linkStats.wmeViPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
+    linkStats.wmeViPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
+    linkStats.wmeViPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
+    linkStats.wmeViPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
+    linkStats.wmeViContentionTimeStats.contentionTimeMinInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
+    linkStats.wmeViContentionTimeStats.contentionTimeMaxInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
+    linkStats.wmeViContentionTimeStats.contentionTimeAvgInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
+    linkStats.wmeViContentionTimeStats.contentionNumSamples =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
+    linkStats.wmeVoPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
+    linkStats.wmeVoPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
+    linkStats.wmeVoPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
+    linkStats.wmeVoPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
+    linkStats.wmeVoContentionTimeStats.contentionTimeMinInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
+    linkStats.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
+    linkStats.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
+    linkStats.wmeVoContentionTimeStats.contentionNumSamples =
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
+    linkStats.timeSliceDutyCycleInPercent = legacy_stats.iface.info.time_slicing_duty_cycle_percent;
+    // peer info legacy_stats conversion.
+    std::vector<StaPeerInfo> aidl_peers_info_stats;
+    for (const auto& legacy_peer_info_stats : legacy_stats.peers) {
+        StaPeerInfo aidl_peer_info_stats;
+        if (!convertLegacyPeerInfoStatsToAidl(legacy_peer_info_stats, &aidl_peer_info_stats)) {
+            return false;
+        }
+        aidl_peers_info_stats.push_back(aidl_peer_info_stats);
+    }
+    linkStats.peers = aidl_peers_info_stats;
+    links.push_back(linkStats);
+    aidl_stats->iface.links = links;
+    // radio legacy_stats conversion.
+    std::vector<StaLinkLayerRadioStats> aidl_radios_stats;
+    for (const auto& legacy_radio_stats : legacy_stats.radios) {
+        StaLinkLayerRadioStats aidl_radio_stats;
+        if (!convertLegacyLinkLayerRadioStatsToAidl(legacy_radio_stats, &aidl_radio_stats)) {
+            return false;
+        }
+        aidl_radios_stats.push_back(aidl_radio_stats);
+    }
+    aidl_stats->radios = aidl_radios_stats;
+    aidl_stats->timeStampInMs = ::android::uptimeMillis();
+    return true;
+}
+
+bool convertLegacyPeerInfoStatsToAidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+                                      StaPeerInfo* aidl_peer_info_stats) {
+    if (!aidl_peer_info_stats) {
+        return false;
+    }
+    *aidl_peer_info_stats = {};
+    aidl_peer_info_stats->staCount = legacy_peer_info_stats.peer_info.bssload.sta_count;
+    aidl_peer_info_stats->chanUtil = legacy_peer_info_stats.peer_info.bssload.chan_util;
+
+    std::vector<StaRateStat> aidlRateStats;
+    for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) {
+        StaRateStat rateStat;
+        if (!convertLegacyWifiRateInfoToAidl(legacy_rate_stats.rate, &rateStat.rateInfo)) {
+            return false;
+        }
+        rateStat.txMpdu = legacy_rate_stats.tx_mpdu;
+        rateStat.rxMpdu = legacy_rate_stats.rx_mpdu;
+        rateStat.mpduLost = legacy_rate_stats.mpdu_lost;
+        rateStat.retries = legacy_rate_stats.retries;
+        aidlRateStats.push_back(rateStat);
+    }
+    aidl_peer_info_stats->rateStats = aidlRateStats;
+    return true;
+}
+
+bool convertLegacyRoamingCapabilitiesToAidl(
+        const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+        StaRoamingCapabilities* aidl_caps) {
+    if (!aidl_caps) {
+        return false;
+    }
+    *aidl_caps = {};
+    aidl_caps->maxBlocklistSize = legacy_caps.max_blacklist_size;
+    aidl_caps->maxAllowlistSize = legacy_caps.max_whitelist_size;
+    return true;
+}
+
+bool convertAidlRoamingConfigToLegacy(const StaRoamingConfig& aidl_config,
+                                      legacy_hal::wifi_roaming_config* legacy_config) {
+    if (!legacy_config) {
+        return false;
+    }
+    *legacy_config = {};
+    if (aidl_config.bssidBlocklist.size() > MAX_BLACKLIST_BSSID ||
+        aidl_config.ssidAllowlist.size() > MAX_WHITELIST_SSID) {
+        return false;
+    }
+    legacy_config->num_blacklist_bssid = aidl_config.bssidBlocklist.size();
+    uint32_t i = 0;
+    for (const auto& bssid : aidl_config.bssidBlocklist) {
+        CHECK(bssid.data.size() == sizeof(legacy_hal::mac_addr));
+        memcpy(legacy_config->blacklist_bssid[i++], bssid.data.data(), bssid.data.size());
+    }
+    legacy_config->num_whitelist_ssid = aidl_config.ssidAllowlist.size();
+    i = 0;
+    for (const auto& ssid : aidl_config.ssidAllowlist) {
+        CHECK(ssid.data.size() <= sizeof(legacy_hal::ssid_t::ssid_str));
+        legacy_config->whitelist_ssid[i].length = ssid.data.size();
+        memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data.data(), ssid.data.size());
+        i++;
+    }
+    return true;
+}
+
+legacy_hal::fw_roaming_state_t convertAidlRoamingStateToLegacy(StaRoamingState state) {
+    switch (state) {
+        case StaRoamingState::ENABLED:
+            return legacy_hal::ROAMING_ENABLE;
+        case StaRoamingState::DISABLED:
+            return legacy_hal::ROAMING_DISABLE;
+    };
+    CHECK(false);
+}
+
+legacy_hal::NanMatchAlg convertAidlNanMatchAlgToLegacy(NanMatchAlg type) {
+    switch (type) {
+        case NanMatchAlg::MATCH_ONCE:
+            return legacy_hal::NAN_MATCH_ALG_MATCH_ONCE;
+        case NanMatchAlg::MATCH_CONTINUOUS:
+            return legacy_hal::NAN_MATCH_ALG_MATCH_CONTINUOUS;
+        case NanMatchAlg::MATCH_NEVER:
+            return legacy_hal::NAN_MATCH_ALG_MATCH_NEVER;
+    }
+    CHECK(false);
+}
+
+legacy_hal::NanPublishType convertAidlNanPublishTypeToLegacy(NanPublishType type) {
+    switch (type) {
+        case NanPublishType::UNSOLICITED:
+            return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED;
+        case NanPublishType::SOLICITED:
+            return legacy_hal::NAN_PUBLISH_TYPE_SOLICITED;
+        case NanPublishType::UNSOLICITED_SOLICITED:
+            return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
+    }
+    CHECK(false);
+}
+
+legacy_hal::NanTxType convertAidlNanTxTypeToLegacy(NanTxType type) {
+    switch (type) {
+        case NanTxType::BROADCAST:
+            return legacy_hal::NAN_TX_TYPE_BROADCAST;
+        case NanTxType::UNICAST:
+            return legacy_hal::NAN_TX_TYPE_UNICAST;
+    }
+    CHECK(false);
+}
+
+legacy_hal::NanSubscribeType convertAidlNanSubscribeTypeToLegacy(NanSubscribeType type) {
+    switch (type) {
+        case NanSubscribeType::PASSIVE:
+            return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE;
+        case NanSubscribeType::ACTIVE:
+            return legacy_hal::NAN_SUBSCRIBE_TYPE_ACTIVE;
+    }
+    CHECK(false);
+}
+
+legacy_hal::NanSRFType convertAidlNanSrfTypeToLegacy(NanSrfType type) {
+    switch (type) {
+        case NanSrfType::BLOOM_FILTER:
+            return legacy_hal::NAN_SRF_ATTR_BLOOM_FILTER;
+        case NanSrfType::PARTIAL_MAC_ADDR:
+            return legacy_hal::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
+    }
+    CHECK(false);
+}
+
+legacy_hal::NanDataPathChannelCfg convertAidlNanDataPathChannelCfgToLegacy(
+        NanDataPathChannelCfg type) {
+    switch (type) {
+        case NanDataPathChannelCfg::CHANNEL_NOT_REQUESTED:
+            return legacy_hal::NAN_DP_CHANNEL_NOT_REQUESTED;
+        case NanDataPathChannelCfg::REQUEST_CHANNEL_SETUP:
+            return legacy_hal::NAN_DP_REQUEST_CHANNEL_SETUP;
+        case NanDataPathChannelCfg::FORCE_CHANNEL_SETUP:
+            return legacy_hal::NAN_DP_FORCE_CHANNEL_SETUP;
+    }
+    CHECK(false);
+}
+
+legacy_hal::NanPairingRequestType convertAidlNanPairingRequestTypeToLegacy(
+        NanPairingRequestType type) {
+    switch (type) {
+        case NanPairingRequestType::NAN_PAIRING_SETUP:
+            return legacy_hal::NAN_PAIRING_SETUP;
+        case NanPairingRequestType::NAN_PAIRING_VERIFICATION:
+            return legacy_hal::NAN_PAIRING_VERIFICATION;
+    }
+    LOG(FATAL);
+}
+
+NanPairingRequestType convertLegacyNanPairingRequestTypeToAidl(
+        legacy_hal::NanPairingRequestType type) {
+    switch (type) {
+        case legacy_hal::NAN_PAIRING_SETUP:
+            return NanPairingRequestType::NAN_PAIRING_SETUP;
+        case legacy_hal::NAN_PAIRING_VERIFICATION:
+            return NanPairingRequestType::NAN_PAIRING_VERIFICATION;
+    }
+    LOG(FATAL);
+}
+
+legacy_hal::NanAkm convertAidlAkmTypeToLegacy(NanPairingAkm type) {
+    switch (type) {
+        case NanPairingAkm::SAE:
+            return legacy_hal::SAE;
+        case NanPairingAkm::PASN:
+            return legacy_hal::PASN;
+    }
+    LOG(FATAL);
+}
+
+NanPairingAkm convertLegacyAkmTypeToAidl(legacy_hal::NanAkm type) {
+    switch (type) {
+        case legacy_hal::SAE:
+            return NanPairingAkm::SAE;
+        case legacy_hal::PASN:
+            return NanPairingAkm::PASN;
+    }
+    LOG(FATAL);
+}
+
+uint16_t convertAidlBootstrappingMethodToLegacy(NanBootstrappingMethod type) {
+    switch (type) {
+        case NanBootstrappingMethod::BOOTSTRAPPING_OPPORTUNISTIC_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_OPPORTUNISTIC_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_QR_DISPLAY_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_QR_DISPLAY_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_NFC_TAG_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_NFC_TAG_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_QR_SCAN_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_QR_SCAN_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_NFC_READER_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_NFC_READER_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_SERVICE_MANAGED_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_SERVICE_MANAGED_MASK;
+        case NanBootstrappingMethod::BOOTSTRAPPING_HANDSHAKE_SHIP_MASK:
+            return NAN_PAIRING_BOOTSTRAPPING_HANDSHAKE_SHIP_MASK;
+    }
+    LOG(FATAL);
+}
+
+NanBootstrappingMethod convertLegacyBootstrappingMethodToAidl(uint16_t type) {
+    switch (type) {
+        case NAN_PAIRING_BOOTSTRAPPING_OPPORTUNISTIC_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_OPPORTUNISTIC_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_QR_DISPLAY_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_QR_DISPLAY_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_NFC_TAG_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_NFC_TAG_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_QR_SCAN_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_QR_SCAN_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_NFC_READER_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_NFC_READER_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_SERVICE_MANAGED_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_SERVICE_MANAGED_MASK;
+        case NAN_PAIRING_BOOTSTRAPPING_HANDSHAKE_SHIP_MASK:
+            return NanBootstrappingMethod::BOOTSTRAPPING_HANDSHAKE_SHIP_MASK;
+    }
+    LOG(FATAL);
+    return {};
+}
+
+bool covertAidlPairingConfigToLegacy(const NanPairingConfig& aidl_config,
+                                     legacy_hal::NanPairingConfig* legacy_config) {
+    if (!legacy_config) {
+        LOG(ERROR) << "covertAidlPairingConfigToLegacy: legacy_config is null";
+        return false;
+    }
+    legacy_config->enable_pairing_setup = aidl_config.enablePairingSetup ? 0x1 : 0x0;
+    legacy_config->enable_pairing_cache = aidl_config.enablePairingCache ? 0x1 : 0x0;
+    legacy_config->enable_pairing_verification = aidl_config.enablePairingVerification ? 0x1 : 0x0;
+    legacy_config->supported_bootstrapping_methods = aidl_config.supportedBootstrappingMethods;
+    return true;
+}
+
+bool convertLegacyPairingConfigToAidl(const legacy_hal::NanPairingConfig& legacy_config,
+                                      NanPairingConfig* aidl_config) {
+    if (!aidl_config) {
+        LOG(ERROR) << "convertLegacyPairingConfigToAidl: aidl_nira is null";
+        return false;
+    }
+    *aidl_config = {};
+    aidl_config->enablePairingSetup = legacy_config.enable_pairing_setup == 0x1;
+    aidl_config->enablePairingCache = legacy_config.enable_pairing_cache == 0x1;
+    aidl_config->enablePairingVerification = legacy_config.enable_pairing_verification == 0x1;
+    aidl_config->supportedBootstrappingMethods = legacy_config.supported_bootstrapping_methods;
+    return true;
+}
+
+bool convertLegacyNiraToAidl(const legacy_hal::NanIdentityResolutionAttribute& legacy_nira,
+                             NanIdentityResolutionAttribute* aidl_nira) {
+    if (!aidl_nira) {
+        LOG(ERROR) << "convertLegacyNiraToAidl: aidl_nira is null";
+        return false;
+    }
+    *aidl_nira = {};
+    aidl_nira->nonce = std::array<uint8_t, 8>();
+    std::copy(legacy_nira.nonce, legacy_nira.nonce + 8, std::begin(aidl_nira->nonce));
+    aidl_nira->tag = std::array<uint8_t, 8>();
+    std::copy(legacy_nira.tag, legacy_nira.tag + 8, std::begin(aidl_nira->tag));
+    return true;
+}
+
+bool convertLegacyNpsaToAidl(const legacy_hal::NpkSecurityAssociation& legacy_npsa,
+                             NpkSecurityAssociation* aidl_npsa) {
+    if (!aidl_npsa) {
+        LOG(ERROR) << "convertLegacyNiraToAidl: aidl_nira is null";
+        return false;
+    }
+    *aidl_npsa = {};
+    aidl_npsa->peerNanIdentityKey = std::array<uint8_t, 16>();
+    std::copy(legacy_npsa.peer_nan_identity_key, legacy_npsa.peer_nan_identity_key + 16,
+              std::begin(aidl_npsa->peerNanIdentityKey));
+    aidl_npsa->localNanIdentityKey = std::array<uint8_t, 16>();
+    std::copy(legacy_npsa.local_nan_identity_key, legacy_npsa.local_nan_identity_key + 16,
+              std::begin(aidl_npsa->localNanIdentityKey));
+    aidl_npsa->npk = std::array<uint8_t, 32>();
+    std::copy(legacy_npsa.npk.pmk, legacy_npsa.npk.pmk + 32, std::begin(aidl_npsa->npk));
+    aidl_npsa->akm = convertLegacyAkmTypeToAidl(legacy_npsa.akm);
+    aidl_npsa->cipherType = (NanCipherSuiteType)legacy_npsa.cipher_type;
+    return true;
+}
+
+NanStatusCode convertLegacyNanStatusTypeToAidl(legacy_hal::NanStatusType type) {
+    switch (type) {
+        case legacy_hal::NAN_STATUS_SUCCESS:
+            return NanStatusCode::SUCCESS;
+        case legacy_hal::NAN_STATUS_INTERNAL_FAILURE:
+            return NanStatusCode::INTERNAL_FAILURE;
+        case legacy_hal::NAN_STATUS_PROTOCOL_FAILURE:
+            return NanStatusCode::PROTOCOL_FAILURE;
+        case legacy_hal::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID:
+            return NanStatusCode::INVALID_SESSION_ID;
+        case legacy_hal::NAN_STATUS_NO_RESOURCE_AVAILABLE:
+            return NanStatusCode::NO_RESOURCES_AVAILABLE;
+        case legacy_hal::NAN_STATUS_INVALID_PARAM:
+            return NanStatusCode::INVALID_ARGS;
+        case legacy_hal::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID:
+            return NanStatusCode::INVALID_PEER_ID;
+        case legacy_hal::NAN_STATUS_INVALID_NDP_ID:
+            return NanStatusCode::INVALID_NDP_ID;
+        case legacy_hal::NAN_STATUS_NAN_NOT_ALLOWED:
+            return NanStatusCode::NAN_NOT_ALLOWED;
+        case legacy_hal::NAN_STATUS_NO_OTA_ACK:
+            return NanStatusCode::NO_OTA_ACK;
+        case legacy_hal::NAN_STATUS_ALREADY_ENABLED:
+            return NanStatusCode::ALREADY_ENABLED;
+        case legacy_hal::NAN_STATUS_FOLLOWUP_QUEUE_FULL:
+            return NanStatusCode::FOLLOWUP_TX_QUEUE_FULL;
+        case legacy_hal::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
+            return NanStatusCode::UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
+        case legacy_hal::NAN_STATUS_INVALID_PAIRING_ID:
+            return NanStatusCode::INVALID_PAIRING_ID;
+        case legacy_hal::NAN_STATUS_INVALID_BOOTSTRAPPING_ID:
+            return NanStatusCode::INVALID_BOOTSTRAPPING_ID;
+        case legacy_hal::NAN_STATUS_REDUNDANT_REQUEST:
+            return NanStatusCode::REDUNDANT_REQUEST;
+        case legacy_hal::NAN_STATUS_NOT_SUPPORTED:
+            return NanStatusCode::NOT_SUPPORTED;
+        case legacy_hal::NAN_STATUS_NO_CONNECTION:
+            return NanStatusCode::NO_CONNECTION;
+    }
+    CHECK(false);
+}
+
+void convertToNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+                        NanStatus* nanStatus) {
+    nanStatus->status = convertLegacyNanStatusTypeToAidl(type);
+    nanStatus->description = safeConvertChar(str, max_len);
+}
+
+bool convertAidlNanEnableRequestToLegacy(const NanEnableRequest& aidl_request1,
+                                         const NanConfigRequestSupplemental& aidl_request2,
+                                         legacy_hal::NanEnableRequest* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanEnableRequestToLegacy: null legacy_request";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->config_2dot4g_support = 1;
+    legacy_request->support_2dot4g_val =
+            aidl_request1.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+    legacy_request->config_support_5g = 1;
+    legacy_request->support_5g_val =
+            aidl_request1.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+    legacy_request->config_hop_count_limit = 1;
+    legacy_request->hop_count_limit_val = aidl_request1.hopCountMax;
+    legacy_request->master_pref = aidl_request1.configParams.masterPref;
+    legacy_request->discovery_indication_cfg = 0;
+    legacy_request->discovery_indication_cfg |=
+            aidl_request1.configParams.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
+    legacy_request->discovery_indication_cfg |=
+            aidl_request1.configParams.disableStartedClusterIndication ? 0x2 : 0x0;
+    legacy_request->discovery_indication_cfg |=
+            aidl_request1.configParams.disableJoinedClusterIndication ? 0x4 : 0x0;
+    legacy_request->config_sid_beacon = 1;
+    if (aidl_request1.configParams.numberOfPublishServiceIdsInBeacon < 0) {
+        LOG(ERROR) << "convertAidlNanEnableRequestToLegacy: "
+                      "numberOfPublishServiceIdsInBeacon < 0";
+        return false;
+    }
+    legacy_request->sid_beacon_val =
+            (aidl_request1.configParams.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
+            (aidl_request1.configParams.numberOfPublishServiceIdsInBeacon << 1);
+    legacy_request->config_subscribe_sid_beacon = 1;
+    if (aidl_request1.configParams.numberOfSubscribeServiceIdsInBeacon < 0) {
+        LOG(ERROR) << "convertAidlNanEnableRequestToLegacy: "
+                      "numberOfSubscribeServiceIdsInBeacon < 0";
+        return false;
+    }
+    legacy_request->subscribe_sid_beacon_val =
+            (aidl_request1.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
+            (aidl_request1.configParams.numberOfSubscribeServiceIdsInBeacon << 1);
+    legacy_request->config_rssi_window_size = 1;
+    legacy_request->rssi_window_size_val = aidl_request1.configParams.rssiWindowSize;
+    legacy_request->config_disc_mac_addr_randomization = 1;
+    legacy_request->disc_mac_addr_rand_interval_sec =
+            aidl_request1.configParams.macAddressRandomizationIntervalSec;
+    legacy_request->config_2dot4g_rssi_close = 1;
+    if (aidl_request1.configParams.bandSpecificConfig.size() != 3) {
+        LOG(ERROR) << "convertAidlNanEnableRequestToLegacy: "
+                      "bandSpecificConfig.size() != 3";
+        return false;
+    }
+    legacy_request->rssi_close_2dot4g_val =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .rssiClose;
+    legacy_request->config_2dot4g_rssi_middle = 1;
+    legacy_request->rssi_middle_2dot4g_val =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .rssiMiddle;
+    legacy_request->config_2dot4g_rssi_proximity = 1;
+    legacy_request->rssi_proximity_2dot4g_val =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .rssiCloseProximity;
+    legacy_request->config_scan_params = 1;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .scanPeriodSec;
+    legacy_request->config_dw.config_2dot4g_dw_band =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .validDiscoveryWindowIntervalVal;
+    legacy_request->config_dw.dw_2dot4g_interval_val =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .discoveryWindowIntervalVal;
+    legacy_request->config_5g_rssi_close = 1;
+    legacy_request->rssi_close_5g_val =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .rssiClose;
+    legacy_request->config_5g_rssi_middle = 1;
+    legacy_request->rssi_middle_5g_val =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .rssiMiddle;
+    legacy_request->config_5g_rssi_close_proximity = 1;
+    legacy_request->rssi_close_proximity_5g_val =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .rssiCloseProximity;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .scanPeriodSec;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .scanPeriodSec;
+    legacy_request->config_dw.config_5g_dw_band =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .validDiscoveryWindowIntervalVal;
+    legacy_request->config_dw.dw_5g_interval_val =
+            aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .discoveryWindowIntervalVal;
+    if (aidl_request1.debugConfigs.validClusterIdVals) {
+        legacy_request->cluster_low = aidl_request1.debugConfigs.clusterIdBottomRangeVal;
+        legacy_request->cluster_high = aidl_request1.debugConfigs.clusterIdTopRangeVal;
+    } else {  // need 'else' since not configurable in legacy HAL
+        legacy_request->cluster_low = 0x0000;
+        legacy_request->cluster_high = 0xFFFF;
+    }
+    legacy_request->config_intf_addr = aidl_request1.debugConfigs.validIntfAddrVal;
+    memcpy(legacy_request->intf_addr_val, aidl_request1.debugConfigs.intfAddrVal.data(), 6);
+    legacy_request->config_oui = aidl_request1.debugConfigs.validOuiVal;
+    legacy_request->oui_val = aidl_request1.debugConfigs.ouiVal;
+    legacy_request->config_random_factor_force =
+            aidl_request1.debugConfigs.validRandomFactorForceVal;
+    legacy_request->random_factor_force_val = aidl_request1.debugConfigs.randomFactorForceVal;
+    legacy_request->config_hop_count_force = aidl_request1.debugConfigs.validHopCountForceVal;
+    legacy_request->hop_count_force_val = aidl_request1.debugConfigs.hopCountForceVal;
+    legacy_request->config_24g_channel = aidl_request1.debugConfigs.validDiscoveryChannelVal;
+    legacy_request->channel_24g_val =
+            aidl_request1.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+    legacy_request->config_5g_channel = aidl_request1.debugConfigs.validDiscoveryChannelVal;
+    legacy_request->channel_5g_val =
+            aidl_request1.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+    legacy_request->config_2dot4g_beacons = aidl_request1.debugConfigs.validUseBeaconsInBandVal;
+    legacy_request->beacon_2dot4g_val =
+            aidl_request1.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+    legacy_request->config_5g_beacons = aidl_request1.debugConfigs.validUseBeaconsInBandVal;
+    legacy_request->beacon_5g_val =
+            aidl_request1.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+    legacy_request->config_2dot4g_sdf = aidl_request1.debugConfigs.validUseSdfInBandVal;
+    legacy_request->sdf_2dot4g_val =
+            aidl_request1.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+    legacy_request->config_5g_sdf = aidl_request1.debugConfigs.validUseSdfInBandVal;
+    legacy_request->sdf_5g_val =
+            aidl_request1.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+
+    legacy_request->config_discovery_beacon_int = 1;
+    legacy_request->discovery_beacon_interval = aidl_request2.discoveryBeaconIntervalMs;
+    legacy_request->config_nss = 1;
+    legacy_request->nss = aidl_request2.numberOfSpatialStreamsInDiscovery;
+    legacy_request->config_dw_early_termination = 1;
+    legacy_request->enable_dw_termination = aidl_request2.enableDiscoveryWindowEarlyTermination;
+    legacy_request->config_enable_ranging = 1;
+    legacy_request->enable_ranging = aidl_request2.enableRanging;
+
+    legacy_request->config_enable_instant_mode = 1;
+    legacy_request->enable_instant_mode = aidl_request2.enableInstantCommunicationMode;
+    legacy_request->config_instant_mode_channel = 1;
+    legacy_request->instant_mode_channel = aidl_request2.instantModeChannel;
+
+    return true;
+}
+
+bool convertAidlNanConfigRequestToLegacy(const NanConfigRequest& aidl_request1,
+                                         const NanConfigRequestSupplemental& aidl_request2,
+                                         legacy_hal::NanConfigRequest* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanConfigRequestToLegacy: null legacy_request";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->master_pref = aidl_request1.masterPref;
+    legacy_request->discovery_indication_cfg = 0;
+    legacy_request->discovery_indication_cfg |=
+            aidl_request1.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
+    legacy_request->discovery_indication_cfg |=
+            aidl_request1.disableStartedClusterIndication ? 0x2 : 0x0;
+    legacy_request->discovery_indication_cfg |=
+            aidl_request1.disableJoinedClusterIndication ? 0x4 : 0x0;
+    legacy_request->config_sid_beacon = 1;
+    if (aidl_request1.numberOfPublishServiceIdsInBeacon < 0) {
+        LOG(ERROR) << "convertAidlNanConfigRequestToLegacy: "
+                      "numberOfPublishServiceIdsInBeacon < 0";
+        return false;
+    }
+    legacy_request->sid_beacon = (aidl_request1.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
+                                 (aidl_request1.numberOfPublishServiceIdsInBeacon << 1);
+    legacy_request->config_subscribe_sid_beacon = 1;
+    if (aidl_request1.numberOfSubscribeServiceIdsInBeacon < 0) {
+        LOG(ERROR) << "convertAidlNanConfigRequestToLegacy: "
+                      "numberOfSubscribeServiceIdsInBeacon < 0";
+        return false;
+    }
+    legacy_request->subscribe_sid_beacon_val =
+            (aidl_request1.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
+            (aidl_request1.numberOfSubscribeServiceIdsInBeacon << 1);
+    legacy_request->config_rssi_window_size = 1;
+    legacy_request->rssi_window_size_val = aidl_request1.rssiWindowSize;
+    legacy_request->config_disc_mac_addr_randomization = 1;
+    legacy_request->disc_mac_addr_rand_interval_sec =
+            aidl_request1.macAddressRandomizationIntervalSec;
+
+    legacy_request->config_scan_params = 1;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].scanPeriodSec;
+    legacy_request->config_dw.config_2dot4g_dw_band =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .validDiscoveryWindowIntervalVal;
+    legacy_request->config_dw.dw_2dot4g_interval_val =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .discoveryWindowIntervalVal;
+
+    legacy_request->config_5g_rssi_close_proximity = 1;
+    legacy_request->rssi_close_proximity_5g_val =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .rssiCloseProximity;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
+    legacy_request->config_dw.config_5g_dw_band =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .validDiscoveryWindowIntervalVal;
+    legacy_request->config_dw.dw_5g_interval_val =
+            aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .discoveryWindowIntervalVal;
+
+    legacy_request->config_discovery_beacon_int = 1;
+    legacy_request->discovery_beacon_interval = aidl_request2.discoveryBeaconIntervalMs;
+    legacy_request->config_nss = 1;
+    legacy_request->nss = aidl_request2.numberOfSpatialStreamsInDiscovery;
+    legacy_request->config_dw_early_termination = 1;
+    legacy_request->enable_dw_termination = aidl_request2.enableDiscoveryWindowEarlyTermination;
+    legacy_request->config_enable_ranging = 1;
+    legacy_request->enable_ranging = aidl_request2.enableRanging;
+
+    legacy_request->config_enable_instant_mode = 1;
+    legacy_request->enable_instant_mode = aidl_request2.enableInstantCommunicationMode;
+    legacy_request->config_instant_mode_channel = 1;
+    legacy_request->instant_mode_channel = aidl_request2.instantModeChannel;
+    legacy_request->config_cluster_id = 1;
+    legacy_request->cluster_id_val = aidl_request2.clusterId;
+
+    return true;
+}
+
+bool convertAidlNanPublishRequestToLegacy(const NanPublishRequest& aidl_request,
+                                          legacy_hal::NanPublishRequest* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: null legacy_request";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->publish_id = static_cast<uint8_t>(aidl_request.baseConfigs.sessionId);
+    legacy_request->ttl = aidl_request.baseConfigs.ttlSec;
+    legacy_request->period = aidl_request.baseConfigs.discoveryWindowPeriod;
+    legacy_request->publish_count = aidl_request.baseConfigs.discoveryCount;
+    legacy_request->service_name_len = aidl_request.baseConfigs.serviceName.size();
+    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+        LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: service_name_len "
+                      "too large";
+        return false;
+    }
+    memcpy(legacy_request->service_name, aidl_request.baseConfigs.serviceName.data(),
+           legacy_request->service_name_len);
+    legacy_request->publish_match_indicator =
+            convertAidlNanMatchAlgToLegacy(aidl_request.baseConfigs.discoveryMatchIndicator);
+    legacy_request->service_specific_info_len = aidl_request.baseConfigs.serviceSpecificInfo.size();
+    if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+        LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+                      "service_specific_info_len too large";
+        return false;
+    }
+    memcpy(legacy_request->service_specific_info,
+           aidl_request.baseConfigs.serviceSpecificInfo.data(),
+           legacy_request->service_specific_info_len);
+    legacy_request->sdea_service_specific_info_len =
+            aidl_request.baseConfigs.extendedServiceSpecificInfo.size();
+    if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+        LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+                      "sdea_service_specific_info_len too large";
+        return false;
+    }
+    memcpy(legacy_request->sdea_service_specific_info,
+           aidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
+           legacy_request->sdea_service_specific_info_len);
+    legacy_request->rx_match_filter_len = aidl_request.baseConfigs.rxMatchFilter.size();
+    if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+        LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+                      "rx_match_filter_len too large";
+        return false;
+    }
+    memcpy(legacy_request->rx_match_filter, aidl_request.baseConfigs.rxMatchFilter.data(),
+           legacy_request->rx_match_filter_len);
+    legacy_request->tx_match_filter_len = aidl_request.baseConfigs.txMatchFilter.size();
+    if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+        LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+                      "tx_match_filter_len too large";
+        return false;
+    }
+    memcpy(legacy_request->tx_match_filter, aidl_request.baseConfigs.txMatchFilter.data(),
+           legacy_request->tx_match_filter_len);
+    legacy_request->rssi_threshold_flag = aidl_request.baseConfigs.useRssiThreshold;
+    legacy_request->recv_indication_cfg = 0;
+    legacy_request->recv_indication_cfg |=
+            aidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
+    legacy_request->recv_indication_cfg |=
+            aidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
+    legacy_request->recv_indication_cfg |=
+            aidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
+    legacy_request->recv_indication_cfg |= 0x8;
+    legacy_request->cipher_type = (unsigned int)aidl_request.baseConfigs.securityConfig.cipherType;
+
+    legacy_request->scid_len = aidl_request.baseConfigs.securityConfig.scid.size();
+    if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
+        LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: scid_len too large";
+        return false;
+    }
+    memcpy(legacy_request->scid, aidl_request.baseConfigs.securityConfig.scid.data(),
+           legacy_request->scid_len);
+
+    if (aidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+        legacy_request->key_info.body.pmk_info.pmk_len =
+                aidl_request.baseConfigs.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: invalid pmk_len";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.pmk_info.pmk,
+               aidl_request.baseConfigs.securityConfig.pmk.data(),
+               legacy_request->key_info.body.pmk_info.pmk_len);
+    }
+    if (aidl_request.baseConfigs.securityConfig.securityType ==
+        NanDataPathSecurityType::PASSPHRASE) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+        legacy_request->key_info.body.passphrase_info.passphrase_len =
+                aidl_request.baseConfigs.securityConfig.passphrase.size();
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+                          "passphrase_len too small";
+            return false;
+        }
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+                          "passphrase_len too large";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+               aidl_request.baseConfigs.securityConfig.passphrase.data(),
+               legacy_request->key_info.body.passphrase_info.passphrase_len);
+    }
+    legacy_request->sdea_params.security_cfg =
+            (aidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
+                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+
+    legacy_request->sdea_params.ranging_state = aidl_request.baseConfigs.rangingRequired
+                                                        ? legacy_hal::NAN_RANGING_ENABLE
+                                                        : legacy_hal::NAN_RANGING_DISABLE;
+    legacy_request->ranging_cfg.ranging_interval_msec = aidl_request.baseConfigs.rangingIntervalMs;
+    legacy_request->ranging_cfg.config_ranging_indications =
+            aidl_request.baseConfigs.configRangingIndications;
+    legacy_request->ranging_cfg.distance_ingress_mm =
+            aidl_request.baseConfigs.distanceIngressCm * 10;
+    legacy_request->ranging_cfg.distance_egress_mm = aidl_request.baseConfigs.distanceEgressCm * 10;
+    legacy_request->ranging_auto_response = aidl_request.baseConfigs.rangingRequired
+                                                    ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
+                                                    : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+    legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
+    legacy_request->publish_type = convertAidlNanPublishTypeToLegacy(aidl_request.publishType);
+    legacy_request->tx_type = convertAidlNanTxTypeToLegacy(aidl_request.txType);
+    legacy_request->service_responder_policy = aidl_request.autoAcceptDataPathRequests
+                                                       ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL
+                                                       : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE;
+    memcpy(legacy_request->nan_identity_key, aidl_request.identityKey.data(), NAN_IDENTITY_KEY_LEN);
+    if (!covertAidlPairingConfigToLegacy(aidl_request.pairingConfig,
+                                         &legacy_request->nan_pairing_config)) {
+        LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: invalid pairing config";
+        return false;
+    }
+    legacy_request->enable_suspendability = aidl_request.baseConfigs.enableSessionSuspendability;
+
+    return true;
+}
+
+bool convertAidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& aidl_request,
+                                            legacy_hal::NanSubscribeRequest* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: legacy_request is null";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->subscribe_id = static_cast<uint8_t>(aidl_request.baseConfigs.sessionId);
+    legacy_request->ttl = aidl_request.baseConfigs.ttlSec;
+    legacy_request->period = aidl_request.baseConfigs.discoveryWindowPeriod;
+    legacy_request->subscribe_count = aidl_request.baseConfigs.discoveryCount;
+    legacy_request->service_name_len = aidl_request.baseConfigs.serviceName.size();
+    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+        LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+                      "service_name_len too large";
+        return false;
+    }
+    memcpy(legacy_request->service_name, aidl_request.baseConfigs.serviceName.data(),
+           legacy_request->service_name_len);
+    legacy_request->subscribe_match_indicator =
+            convertAidlNanMatchAlgToLegacy(aidl_request.baseConfigs.discoveryMatchIndicator);
+    legacy_request->service_specific_info_len = aidl_request.baseConfigs.serviceSpecificInfo.size();
+    if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+        LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+                      "service_specific_info_len too large";
+        return false;
+    }
+    memcpy(legacy_request->service_specific_info,
+           aidl_request.baseConfigs.serviceSpecificInfo.data(),
+           legacy_request->service_specific_info_len);
+    legacy_request->sdea_service_specific_info_len =
+            aidl_request.baseConfigs.extendedServiceSpecificInfo.size();
+    if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+        LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+                      "sdea_service_specific_info_len too large";
+        return false;
+    }
+    memcpy(legacy_request->sdea_service_specific_info,
+           aidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
+           legacy_request->sdea_service_specific_info_len);
+    legacy_request->rx_match_filter_len = aidl_request.baseConfigs.rxMatchFilter.size();
+    if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+        LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+                      "rx_match_filter_len too large";
+        return false;
+    }
+    memcpy(legacy_request->rx_match_filter, aidl_request.baseConfigs.rxMatchFilter.data(),
+           legacy_request->rx_match_filter_len);
+    legacy_request->tx_match_filter_len = aidl_request.baseConfigs.txMatchFilter.size();
+    if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+        LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+                      "tx_match_filter_len too large";
+        return false;
+    }
+    memcpy(legacy_request->tx_match_filter, aidl_request.baseConfigs.txMatchFilter.data(),
+           legacy_request->tx_match_filter_len);
+    legacy_request->rssi_threshold_flag = aidl_request.baseConfigs.useRssiThreshold;
+    legacy_request->recv_indication_cfg = 0;
+    legacy_request->recv_indication_cfg |=
+            aidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
+    legacy_request->recv_indication_cfg |=
+            aidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
+    legacy_request->recv_indication_cfg |=
+            aidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
+    legacy_request->cipher_type = (unsigned int)aidl_request.baseConfigs.securityConfig.cipherType;
+    if (aidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+        legacy_request->key_info.body.pmk_info.pmk_len =
+                aidl_request.baseConfigs.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: invalid pmk_len";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.pmk_info.pmk,
+               aidl_request.baseConfigs.securityConfig.pmk.data(),
+               legacy_request->key_info.body.pmk_info.pmk_len);
+    }
+    if (aidl_request.baseConfigs.securityConfig.securityType ==
+        NanDataPathSecurityType::PASSPHRASE) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+        legacy_request->key_info.body.passphrase_info.passphrase_len =
+                aidl_request.baseConfigs.securityConfig.passphrase.size();
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+                          "passphrase_len too small";
+            return false;
+        }
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+                          "passphrase_len too large";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+               aidl_request.baseConfigs.securityConfig.passphrase.data(),
+               legacy_request->key_info.body.passphrase_info.passphrase_len);
+    }
+    legacy_request->sdea_params.security_cfg =
+            (aidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
+                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+    legacy_request->sdea_params.ranging_state = aidl_request.baseConfigs.rangingRequired
+                                                        ? legacy_hal::NAN_RANGING_ENABLE
+                                                        : legacy_hal::NAN_RANGING_DISABLE;
+    legacy_request->ranging_cfg.ranging_interval_msec = aidl_request.baseConfigs.rangingIntervalMs;
+    legacy_request->ranging_cfg.config_ranging_indications =
+            aidl_request.baseConfigs.configRangingIndications;
+    legacy_request->ranging_cfg.distance_ingress_mm =
+            aidl_request.baseConfigs.distanceIngressCm * 10;
+    legacy_request->ranging_cfg.distance_egress_mm = aidl_request.baseConfigs.distanceEgressCm * 10;
+    legacy_request->ranging_auto_response = aidl_request.baseConfigs.rangingRequired
+                                                    ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
+                                                    : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+    legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
+    legacy_request->subscribe_type =
+            convertAidlNanSubscribeTypeToLegacy(aidl_request.subscribeType);
+    legacy_request->serviceResponseFilter = convertAidlNanSrfTypeToLegacy(aidl_request.srfType);
+    legacy_request->serviceResponseInclude = aidl_request.srfRespondIfInAddressSet
+                                                     ? legacy_hal::NAN_SRF_INCLUDE_RESPOND
+                                                     : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
+    legacy_request->useServiceResponseFilter =
+            aidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF : legacy_hal::NAN_DO_NOT_USE_SRF;
+    legacy_request->ssiRequiredForMatchIndication =
+            aidl_request.isSsiRequiredForMatch ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND
+                                               : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
+    legacy_request->num_intf_addr_present = aidl_request.intfAddr.size();
+    if (legacy_request->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) {
+        LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+                      "num_intf_addr_present - too many";
+        return false;
+    }
+    for (int i = 0; i < legacy_request->num_intf_addr_present; i++) {
+        memcpy(legacy_request->intf_addr[i], aidl_request.intfAddr[i].data.data(), 6);
+    }
+    memcpy(legacy_request->nan_identity_key, aidl_request.identityKey.data(), NAN_IDENTITY_KEY_LEN);
+    if (!covertAidlPairingConfigToLegacy(aidl_request.pairingConfig,
+                                         &legacy_request->nan_pairing_config)) {
+        LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: invalid pairing config";
+        return false;
+    }
+    legacy_request->enable_suspendability = aidl_request.baseConfigs.enableSessionSuspendability;
+
+    return true;
+}
+
+bool convertAidlNanTransmitFollowupRequestToLegacy(
+        const NanTransmitFollowupRequest& aidl_request,
+        legacy_hal::NanTransmitFollowupRequest* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanTransmitFollowupRequestToLegacy: "
+                      "legacy_request is null";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+    legacy_request->requestor_instance_id = aidl_request.peerId;
+    memcpy(legacy_request->addr, aidl_request.addr.data(), 6);
+    legacy_request->priority = aidl_request.isHighPriority ? legacy_hal::NAN_TX_PRIORITY_HIGH
+                                                           : legacy_hal::NAN_TX_PRIORITY_NORMAL;
+    legacy_request->dw_or_faw = aidl_request.shouldUseDiscoveryWindow
+                                        ? legacy_hal::NAN_TRANSMIT_IN_DW
+                                        : legacy_hal::NAN_TRANSMIT_IN_FAW;
+    legacy_request->service_specific_info_len = aidl_request.serviceSpecificInfo.size();
+    if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+        LOG(ERROR) << "convertAidlNanTransmitFollowupRequestToLegacy: "
+                      "service_specific_info_len too large";
+        return false;
+    }
+    memcpy(legacy_request->service_specific_info, aidl_request.serviceSpecificInfo.data(),
+           legacy_request->service_specific_info_len);
+    legacy_request->sdea_service_specific_info_len =
+            aidl_request.extendedServiceSpecificInfo.size();
+    if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+        LOG(ERROR) << "convertAidlNanTransmitFollowupRequestToLegacy: "
+                      "sdea_service_specific_info_len too large";
+        return false;
+    }
+    memcpy(legacy_request->sdea_service_specific_info,
+           aidl_request.extendedServiceSpecificInfo.data(),
+           legacy_request->sdea_service_specific_info_len);
+    legacy_request->recv_indication_cfg = aidl_request.disableFollowupResultIndication ? 0x1 : 0x0;
+
+    return true;
+}
+
+bool convertAidlNanDataPathInitiatorRequestToLegacy(
+        const NanInitiateDataPathRequest& aidl_request,
+        legacy_hal::NanDataPathInitiatorRequest* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+                      "legacy_request is null";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->requestor_instance_id = aidl_request.peerId;
+    memcpy(legacy_request->peer_disc_mac_addr, aidl_request.peerDiscMacAddr.data(), 6);
+    legacy_request->channel_request_type =
+            convertAidlNanDataPathChannelCfgToLegacy(aidl_request.channelRequestType);
+    legacy_request->channel = aidl_request.channel;
+    if (strnlen(aidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+        LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+                      "ifaceName too long";
+        return false;
+    }
+    strlcpy(legacy_request->ndp_iface, aidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
+    legacy_request->ndp_cfg.security_cfg =
+            (aidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
+                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+    legacy_request->app_info.ndp_app_info_len = aidl_request.appInfo.size();
+    if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+        LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+                      "ndp_app_info_len too large";
+        return false;
+    }
+    memcpy(legacy_request->app_info.ndp_app_info, aidl_request.appInfo.data(),
+           legacy_request->app_info.ndp_app_info_len);
+    legacy_request->cipher_type = (unsigned int)aidl_request.securityConfig.cipherType;
+    if (aidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+        legacy_request->key_info.body.pmk_info.pmk_len = aidl_request.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+                          "invalid pmk_len";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.pmk_info.pmk, aidl_request.securityConfig.pmk.data(),
+               legacy_request->key_info.body.pmk_info.pmk_len);
+    }
+    if (aidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+        legacy_request->key_info.body.passphrase_info.passphrase_len =
+                aidl_request.securityConfig.passphrase.size();
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+                          "passphrase_len too small";
+            return false;
+        }
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+                          "passphrase_len too large";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+               aidl_request.securityConfig.passphrase.data(),
+               legacy_request->key_info.body.passphrase_info.passphrase_len);
+    }
+    legacy_request->service_name_len = aidl_request.serviceNameOutOfBand.size();
+    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+        LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+                      "service_name_len too large";
+        return false;
+    }
+    memcpy(legacy_request->service_name, aidl_request.serviceNameOutOfBand.data(),
+           legacy_request->service_name_len);
+    legacy_request->scid_len = aidl_request.securityConfig.scid.size();
+    if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
+        LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: scid_len too large";
+        return false;
+    }
+    memcpy(legacy_request->scid, aidl_request.securityConfig.scid.data(), legacy_request->scid_len);
+    legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+
+    return true;
+}
+
+bool convertAidlNanDataPathIndicationResponseToLegacy(
+        const NanRespondToDataPathIndicationRequest& aidl_request,
+        legacy_hal::NanDataPathIndicationResponse* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+                      "legacy_request is null";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->rsp_code = aidl_request.acceptRequest ? legacy_hal::NAN_DP_REQUEST_ACCEPT
+                                                          : legacy_hal::NAN_DP_REQUEST_REJECT;
+    legacy_request->ndp_instance_id = aidl_request.ndpInstanceId;
+    if (strnlen(aidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+        LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+                      "ifaceName too long";
+        return false;
+    }
+    strlcpy(legacy_request->ndp_iface, aidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
+    legacy_request->ndp_cfg.security_cfg =
+            (aidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
+                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+    legacy_request->app_info.ndp_app_info_len = aidl_request.appInfo.size();
+    if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+        LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+                      "ndp_app_info_len too large";
+        return false;
+    }
+    memcpy(legacy_request->app_info.ndp_app_info, aidl_request.appInfo.data(),
+           legacy_request->app_info.ndp_app_info_len);
+    legacy_request->cipher_type = (unsigned int)aidl_request.securityConfig.cipherType;
+    if (aidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+        legacy_request->key_info.body.pmk_info.pmk_len = aidl_request.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+                          "invalid pmk_len";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.pmk_info.pmk, aidl_request.securityConfig.pmk.data(),
+               legacy_request->key_info.body.pmk_info.pmk_len);
+    }
+    if (aidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+        legacy_request->key_info.body.passphrase_info.passphrase_len =
+                aidl_request.securityConfig.passphrase.size();
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+                          "passphrase_len too small";
+            return false;
+        }
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+                          "passphrase_len too large";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+               aidl_request.securityConfig.passphrase.data(),
+               legacy_request->key_info.body.passphrase_info.passphrase_len);
+    }
+    legacy_request->service_name_len = aidl_request.serviceNameOutOfBand.size();
+    if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+        LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+                      "service_name_len too large";
+        return false;
+    }
+    memcpy(legacy_request->service_name, aidl_request.serviceNameOutOfBand.data(),
+           legacy_request->service_name_len);
+    legacy_request->scid_len = aidl_request.securityConfig.scid.size();
+    if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
+        LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: scid_len too large";
+        return false;
+    }
+    memcpy(legacy_request->scid, aidl_request.securityConfig.scid.data(), legacy_request->scid_len);
+    legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+
+    return true;
+}
+
+bool convertLegacyNanResponseHeaderToAidl(const legacy_hal::NanResponseMsg& legacy_response,
+                                          NanStatus* nanStatus) {
+    if (!nanStatus) {
+        LOG(ERROR) << "convertLegacyNanResponseHeaderToAidl: nanStatus is null";
+        return false;
+    }
+    *nanStatus = {};
+
+    convertToNanStatus(legacy_response.status, legacy_response.nan_error,
+                       sizeof(legacy_response.nan_error), nanStatus);
+    return true;
+}
+
+bool convertLegacyNanCapabilitiesResponseToAidl(const legacy_hal::NanCapabilities& legacy_response,
+                                                NanCapabilities* aidl_response) {
+    if (!aidl_response) {
+        LOG(ERROR) << "convertLegacyNanCapabilitiesResponseToAidl: "
+                      "aidl_response is null";
+        return false;
+    }
+    *aidl_response = {};
+
+    aidl_response->maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters;
+    aidl_response->maxPublishes = legacy_response.max_publishes;
+    aidl_response->maxSubscribes = legacy_response.max_subscribes;
+    aidl_response->maxServiceNameLen = legacy_response.max_service_name_len;
+    aidl_response->maxMatchFilterLen = legacy_response.max_match_filter_len;
+    aidl_response->maxTotalMatchFilterLen = legacy_response.max_total_match_filter_len;
+    aidl_response->maxServiceSpecificInfoLen = legacy_response.max_service_specific_info_len;
+    aidl_response->maxExtendedServiceSpecificInfoLen =
+            legacy_response.max_sdea_service_specific_info_len;
+    aidl_response->maxNdiInterfaces = legacy_response.max_ndi_interfaces;
+    aidl_response->maxNdpSessions = legacy_response.max_ndp_sessions;
+    aidl_response->maxAppInfoLen = legacy_response.max_app_info_len;
+    aidl_response->maxQueuedTransmitFollowupMsgs =
+            legacy_response.max_queued_transmit_followup_msgs;
+    aidl_response->maxSubscribeInterfaceAddresses = legacy_response.max_subscribe_address;
+    aidl_response->supportedCipherSuites = legacy_response.cipher_suites_supported;
+    aidl_response->instantCommunicationModeSupportFlag = legacy_response.is_instant_mode_supported;
+    aidl_response->supports6g = legacy_response.is_6g_supported;
+    aidl_response->supportsHe = legacy_response.is_he_supported;
+    aidl_response->supportsPairing = legacy_response.is_pairing_supported;
+    aidl_response->supportsSetClusterId = legacy_response.is_set_cluster_id_supported;
+    aidl_response->supportsSuspension = legacy_response.is_suspension_supported;
+
+    return true;
+}
+
+bool convertLegacyNanMatchIndToAidl(const legacy_hal::NanMatchInd& legacy_ind,
+                                    NanMatchInd* aidl_ind) {
+    if (!aidl_ind) {
+        LOG(ERROR) << "convertLegacyNanMatchIndToAidl: aidl_ind is null";
+        return false;
+    }
+    *aidl_ind = {};
+
+    aidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+    aidl_ind->peerId = legacy_ind.requestor_instance_id;
+    aidl_ind->addr = std::array<uint8_t, 6>();
+    std::copy(legacy_ind.addr, legacy_ind.addr + 6, std::begin(aidl_ind->addr));
+    aidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
+            legacy_ind.service_specific_info,
+            legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
+    aidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
+            legacy_ind.sdea_service_specific_info,
+            legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
+    aidl_ind->matchFilter =
+            std::vector<uint8_t>(legacy_ind.sdf_match_filter,
+                                 legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len);
+    aidl_ind->matchOccurredInBeaconFlag = legacy_ind.match_occured_flag == 1;  // NOTYPO
+    aidl_ind->outOfResourceFlag = legacy_ind.out_of_resource_flag == 1;
+    aidl_ind->rssiValue = legacy_ind.rssi_value;
+    aidl_ind->peerCipherType = (NanCipherSuiteType)legacy_ind.peer_cipher_type;
+    aidl_ind->peerRequiresSecurityEnabledInNdp =
+            legacy_ind.peer_sdea_params.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
+    aidl_ind->peerRequiresRanging =
+            legacy_ind.peer_sdea_params.ranging_state == legacy_hal::NAN_RANGING_ENABLE;
+    aidl_ind->rangingMeasurementInMm = legacy_ind.range_info.range_measurement_mm;
+    aidl_ind->rangingIndicationType = legacy_ind.range_info.ranging_event_type;
+    aidl_ind->scid = std::vector<uint8_t>(legacy_ind.scid, legacy_ind.scid + legacy_ind.scid_len);
+
+    if (!convertLegacyNiraToAidl(legacy_ind.nira, &aidl_ind->peerNira)) {
+        LOG(ERROR) << "convertLegacyNanMatchIndToAidl: invalid NIRA";
+        return false;
+    }
+    if (!convertLegacyPairingConfigToAidl(legacy_ind.peer_pairing_config,
+                                          &aidl_ind->peerPairingConfig)) {
+        LOG(ERROR) << "convertLegacyNanMatchIndToAidl: invalid pairing config";
+        return false;
+    }
+    return true;
+}
+
+bool convertLegacyNanFollowupIndToAidl(const legacy_hal::NanFollowupInd& legacy_ind,
+                                       NanFollowupReceivedInd* aidl_ind) {
+    if (!aidl_ind) {
+        LOG(ERROR) << "convertLegacyNanFollowupIndToAidl: aidl_ind is null";
+        return false;
+    }
+    *aidl_ind = {};
+
+    aidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+    aidl_ind->peerId = legacy_ind.requestor_instance_id;
+    aidl_ind->addr = std::array<uint8_t, 6>();
+    std::copy(legacy_ind.addr, legacy_ind.addr + 6, std::begin(aidl_ind->addr));
+    aidl_ind->receivedInFaw = legacy_ind.dw_or_faw == 1;
+    aidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
+            legacy_ind.service_specific_info,
+            legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
+    aidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
+            legacy_ind.sdea_service_specific_info,
+            legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
+
+    return true;
+}
+
+bool convertLegacyNanDataPathRequestIndToAidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
+                                              NanDataPathRequestInd* aidl_ind) {
+    if (!aidl_ind) {
+        LOG(ERROR) << "convertLegacyNanDataPathRequestIndToAidl: aidl_ind is null";
+        return false;
+    }
+    *aidl_ind = {};
+
+    aidl_ind->discoverySessionId = legacy_ind.service_instance_id;
+    aidl_ind->peerDiscMacAddr = std::array<uint8_t, 6>();
+    std::copy(legacy_ind.peer_disc_mac_addr, legacy_ind.peer_disc_mac_addr + 6,
+              std::begin(aidl_ind->peerDiscMacAddr));
+    aidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id;
+    aidl_ind->securityRequired =
+            legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
+    aidl_ind->appInfo = std::vector<uint8_t>(
+            legacy_ind.app_info.ndp_app_info,
+            legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
+
+    return true;
+}
+
+bool convertLegacyNdpChannelInfoToAidl(const legacy_hal::NanChannelInfo& legacy_struct,
+                                       NanDataPathChannelInfo* aidl_struct) {
+    if (!aidl_struct) {
+        LOG(ERROR) << "convertLegacyNdpChannelInfoToAidl: aidl_struct is null";
+        return false;
+    }
+    *aidl_struct = {};
+
+    aidl_struct->channelFreq = legacy_struct.channel;
+    aidl_struct->channelBandwidth = convertLegacyWifiChannelWidthToAidl(
+            (legacy_hal::wifi_channel_width)legacy_struct.bandwidth);
+    aidl_struct->numSpatialStreams = legacy_struct.nss;
+
+    return true;
+}
+
+bool convertLegacyNanDataPathConfirmIndToAidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
+                                              NanDataPathConfirmInd* aidl_ind) {
+    if (!aidl_ind) {
+        LOG(ERROR) << "convertLegacyNanDataPathConfirmIndToAidl: aidl_ind is null";
+        return false;
+    }
+    *aidl_ind = {};
+
+    aidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id;
+    aidl_ind->dataPathSetupSuccess = legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT;
+    aidl_ind->peerNdiMacAddr = std::array<uint8_t, 6>();
+    std::copy(legacy_ind.peer_ndi_mac_addr, legacy_ind.peer_ndi_mac_addr + 6,
+              std::begin(aidl_ind->peerNdiMacAddr));
+    aidl_ind->appInfo = std::vector<uint8_t>(
+            legacy_ind.app_info.ndp_app_info,
+            legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
+    aidl_ind->status.status = convertLegacyNanStatusTypeToAidl(legacy_ind.reason_code);
+    aidl_ind->status.description = "";
+
+    std::vector<NanDataPathChannelInfo> channelInfo;
+    for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
+        NanDataPathChannelInfo aidl_struct;
+        if (!convertLegacyNdpChannelInfoToAidl(legacy_ind.channel_info[i], &aidl_struct)) {
+            return false;
+        }
+        channelInfo.push_back(aidl_struct);
+    }
+    aidl_ind->channelInfo = channelInfo;
+
+    return true;
+}
+
+bool convertLegacyNanDataPathScheduleUpdateIndToAidl(
+        const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
+        NanDataPathScheduleUpdateInd* aidl_ind) {
+    if (!aidl_ind) {
+        LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToAidl: "
+                      "aidl_ind is null";
+        return false;
+    }
+    *aidl_ind = {};
+
+    aidl_ind->peerDiscoveryAddress = std::array<uint8_t, 6>();
+    std::copy(legacy_ind.peer_mac_addr, legacy_ind.peer_mac_addr + 6,
+              std::begin(aidl_ind->peerDiscoveryAddress));
+    std::vector<NanDataPathChannelInfo> channelInfo;
+    for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
+        NanDataPathChannelInfo aidl_struct;
+        if (!convertLegacyNdpChannelInfoToAidl(legacy_ind.channel_info[i], &aidl_struct)) {
+            return false;
+        }
+        channelInfo.push_back(aidl_struct);
+    }
+    aidl_ind->channelInfo = channelInfo;
+    std::vector<uint32_t> ndpInstanceIds;
+    for (unsigned int i = 0; i < legacy_ind.num_ndp_instances; ++i) {
+        ndpInstanceIds.push_back(legacy_ind.ndp_instance_id[i]);
+    }
+    aidl_ind->ndpInstanceIds = uintToIntVec(ndpInstanceIds);
+
+    return true;
+}
+
+legacy_hal::wifi_rtt_type convertAidlRttTypeToLegacy(RttType type) {
+    switch (type) {
+        case RttType::ONE_SIDED:
+            return legacy_hal::RTT_TYPE_1_SIDED;
+        case RttType::TWO_SIDED:
+            return legacy_hal::RTT_TYPE_2_SIDED;
+    };
+    CHECK(false);
+}
+
+RttType convertLegacyRttTypeToAidl(legacy_hal::wifi_rtt_type type) {
+    switch (type) {
+        case legacy_hal::RTT_TYPE_1_SIDED:
+            return RttType::ONE_SIDED;
+        case legacy_hal::RTT_TYPE_2_SIDED:
+            return RttType::TWO_SIDED;
+    };
+    CHECK(false) << "Unknown legacy type: " << type;
+}
+
+legacy_hal::rtt_peer_type convertAidlRttPeerTypeToLegacy(RttPeerType type) {
+    switch (type) {
+        case RttPeerType::AP:
+            return legacy_hal::RTT_PEER_AP;
+        case RttPeerType::STA:
+            return legacy_hal::RTT_PEER_STA;
+        case RttPeerType::P2P_GO:
+            return legacy_hal::RTT_PEER_P2P_GO;
+        case RttPeerType::P2P_CLIENT:
+            return legacy_hal::RTT_PEER_P2P_CLIENT;
+        case RttPeerType::NAN_TYPE:
+            return legacy_hal::RTT_PEER_NAN;
+    };
+    CHECK(false);
+}
+
+legacy_hal::wifi_channel_width convertAidlWifiChannelWidthToLegacy(WifiChannelWidthInMhz type) {
+    switch (type) {
+        case WifiChannelWidthInMhz::WIDTH_20:
+            return legacy_hal::WIFI_CHAN_WIDTH_20;
+        case WifiChannelWidthInMhz::WIDTH_40:
+            return legacy_hal::WIFI_CHAN_WIDTH_40;
+        case WifiChannelWidthInMhz::WIDTH_80:
+            return legacy_hal::WIFI_CHAN_WIDTH_80;
+        case WifiChannelWidthInMhz::WIDTH_160:
+            return legacy_hal::WIFI_CHAN_WIDTH_160;
+        case WifiChannelWidthInMhz::WIDTH_80P80:
+            return legacy_hal::WIFI_CHAN_WIDTH_80P80;
+        case WifiChannelWidthInMhz::WIDTH_5:
+            return legacy_hal::WIFI_CHAN_WIDTH_5;
+        case WifiChannelWidthInMhz::WIDTH_10:
+            return legacy_hal::WIFI_CHAN_WIDTH_10;
+        case WifiChannelWidthInMhz::WIDTH_320:
+            return legacy_hal::WIFI_CHAN_WIDTH_320;
+        case WifiChannelWidthInMhz::WIDTH_INVALID:
+            return legacy_hal::WIFI_CHAN_WIDTH_INVALID;
+    };
+    CHECK(false);
+}
+
+WifiChannelWidthInMhz convertLegacyWifiChannelWidthToAidl(legacy_hal::wifi_channel_width type) {
+    switch (type) {
+        case legacy_hal::WIFI_CHAN_WIDTH_20:
+            return WifiChannelWidthInMhz::WIDTH_20;
+        case legacy_hal::WIFI_CHAN_WIDTH_40:
+            return WifiChannelWidthInMhz::WIDTH_40;
+        case legacy_hal::WIFI_CHAN_WIDTH_80:
+            return WifiChannelWidthInMhz::WIDTH_80;
+        case legacy_hal::WIFI_CHAN_WIDTH_160:
+            return WifiChannelWidthInMhz::WIDTH_160;
+        case legacy_hal::WIFI_CHAN_WIDTH_80P80:
+            return WifiChannelWidthInMhz::WIDTH_80P80;
+        case legacy_hal::WIFI_CHAN_WIDTH_5:
+            return WifiChannelWidthInMhz::WIDTH_5;
+        case legacy_hal::WIFI_CHAN_WIDTH_10:
+            return WifiChannelWidthInMhz::WIDTH_10;
+        case legacy_hal::WIFI_CHAN_WIDTH_320:
+            return WifiChannelWidthInMhz::WIDTH_320;
+        default:
+            return WifiChannelWidthInMhz::WIDTH_INVALID;
+    };
+}
+
+legacy_hal::wifi_rtt_preamble convertAidlRttPreambleToLegacy(RttPreamble type) {
+    switch (type) {
+        case RttPreamble::LEGACY:
+            return legacy_hal::WIFI_RTT_PREAMBLE_LEGACY;
+        case RttPreamble::HT:
+            return legacy_hal::WIFI_RTT_PREAMBLE_HT;
+        case RttPreamble::VHT:
+            return legacy_hal::WIFI_RTT_PREAMBLE_VHT;
+        case RttPreamble::HE:
+            return legacy_hal::WIFI_RTT_PREAMBLE_HE;
+        case RttPreamble::EHT:
+            return legacy_hal::WIFI_RTT_PREAMBLE_EHT;
+    };
+    CHECK(false);
+}
+
+RttPreamble convertLegacyRttPreambleToAidl(legacy_hal::wifi_rtt_preamble type) {
+    switch (type) {
+        case legacy_hal::WIFI_RTT_PREAMBLE_LEGACY:
+            return RttPreamble::LEGACY;
+        case legacy_hal::WIFI_RTT_PREAMBLE_HT:
+            return RttPreamble::HT;
+        case legacy_hal::WIFI_RTT_PREAMBLE_VHT:
+            return RttPreamble::VHT;
+        case legacy_hal::WIFI_RTT_PREAMBLE_HE:
+            return RttPreamble::HE;
+        case legacy_hal::WIFI_RTT_PREAMBLE_EHT:
+            return RttPreamble::EHT;
+    };
+    CHECK(false) << "Unknown legacy type: " << type;
+}
+
+legacy_hal::wifi_rtt_bw convertAidlRttBwToLegacy(RttBw type) {
+    switch (type) {
+        case RttBw::BW_5MHZ:
+            return legacy_hal::WIFI_RTT_BW_5;
+        case RttBw::BW_10MHZ:
+            return legacy_hal::WIFI_RTT_BW_10;
+        case RttBw::BW_20MHZ:
+            return legacy_hal::WIFI_RTT_BW_20;
+        case RttBw::BW_40MHZ:
+            return legacy_hal::WIFI_RTT_BW_40;
+        case RttBw::BW_80MHZ:
+            return legacy_hal::WIFI_RTT_BW_80;
+        case RttBw::BW_160MHZ:
+            return legacy_hal::WIFI_RTT_BW_160;
+        case RttBw::BW_320MHZ:
+            return legacy_hal::WIFI_RTT_BW_320;
+        case RttBw::BW_UNSPECIFIED:
+            return legacy_hal::WIFI_RTT_BW_UNSPECIFIED;
+    };
+    CHECK(false);
+}
+
+RttBw convertLegacyRttBwToAidl(legacy_hal::wifi_rtt_bw type) {
+    switch (type) {
+        case legacy_hal::WIFI_RTT_BW_5:
+            return RttBw::BW_5MHZ;
+        case legacy_hal::WIFI_RTT_BW_10:
+            return RttBw::BW_10MHZ;
+        case legacy_hal::WIFI_RTT_BW_20:
+            return RttBw::BW_20MHZ;
+        case legacy_hal::WIFI_RTT_BW_40:
+            return RttBw::BW_40MHZ;
+        case legacy_hal::WIFI_RTT_BW_80:
+            return RttBw::BW_80MHZ;
+        case legacy_hal::WIFI_RTT_BW_160:
+            return RttBw::BW_160MHZ;
+        case legacy_hal::WIFI_RTT_BW_320:
+            return RttBw::BW_320MHZ;
+        case legacy_hal::WIFI_RTT_BW_UNSPECIFIED:
+            return RttBw::BW_UNSPECIFIED;
+    };
+    CHECK(false) << "Unknown legacy type: " << type;
+}
+
+legacy_hal::wifi_motion_pattern convertAidlRttMotionPatternToLegacy(RttMotionPattern type) {
+    switch (type) {
+        case RttMotionPattern::NOT_EXPECTED:
+            return legacy_hal::WIFI_MOTION_NOT_EXPECTED;
+        case RttMotionPattern::EXPECTED:
+            return legacy_hal::WIFI_MOTION_EXPECTED;
+        case RttMotionPattern::UNKNOWN:
+            return legacy_hal::WIFI_MOTION_UNKNOWN;
+    };
+    CHECK(false);
+}
+
+WifiRatePreamble convertLegacyWifiRatePreambleToAidl(uint8_t preamble) {
+    switch (preamble) {
+        case 0:
+            return WifiRatePreamble::OFDM;
+        case 1:
+            return WifiRatePreamble::CCK;
+        case 2:
+            return WifiRatePreamble::HT;
+        case 3:
+            return WifiRatePreamble::VHT;
+        case 4:
+            return WifiRatePreamble::HE;
+        case 5:
+            return WifiRatePreamble::EHT;
+        default:
+            return WifiRatePreamble::RESERVED;
+    };
+    CHECK(false) << "Unknown legacy preamble: " << preamble;
+}
+
+WifiRateNss convertLegacyWifiRateNssToAidl(uint8_t nss) {
+    switch (nss) {
+        case 0:
+            return WifiRateNss::NSS_1x1;
+        case 1:
+            return WifiRateNss::NSS_2x2;
+        case 2:
+            return WifiRateNss::NSS_3x3;
+        case 3:
+            return WifiRateNss::NSS_4x4;
+    };
+    CHECK(false) << "Unknown legacy nss: " << nss;
+    return {};
+}
+
+RttStatus convertLegacyRttStatusToAidl(legacy_hal::wifi_rtt_status status) {
+    switch (status) {
+        case legacy_hal::RTT_STATUS_SUCCESS:
+            return RttStatus::SUCCESS;
+        case legacy_hal::RTT_STATUS_FAILURE:
+            return RttStatus::FAILURE;
+        case legacy_hal::RTT_STATUS_FAIL_NO_RSP:
+            return RttStatus::FAIL_NO_RSP;
+        case legacy_hal::RTT_STATUS_FAIL_REJECTED:
+            return RttStatus::FAIL_REJECTED;
+        case legacy_hal::RTT_STATUS_FAIL_NOT_SCHEDULED_YET:
+            return RttStatus::FAIL_NOT_SCHEDULED_YET;
+        case legacy_hal::RTT_STATUS_FAIL_TM_TIMEOUT:
+            return RttStatus::FAIL_TM_TIMEOUT;
+        case legacy_hal::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL:
+            return RttStatus::FAIL_AP_ON_DIFF_CHANNEL;
+        case legacy_hal::RTT_STATUS_FAIL_NO_CAPABILITY:
+            return RttStatus::FAIL_NO_CAPABILITY;
+        case legacy_hal::RTT_STATUS_ABORTED:
+            return RttStatus::ABORTED;
+        case legacy_hal::RTT_STATUS_FAIL_INVALID_TS:
+            return RttStatus::FAIL_INVALID_TS;
+        case legacy_hal::RTT_STATUS_FAIL_PROTOCOL:
+            return RttStatus::FAIL_PROTOCOL;
+        case legacy_hal::RTT_STATUS_FAIL_SCHEDULE:
+            return RttStatus::FAIL_SCHEDULE;
+        case legacy_hal::RTT_STATUS_FAIL_BUSY_TRY_LATER:
+            return RttStatus::FAIL_BUSY_TRY_LATER;
+        case legacy_hal::RTT_STATUS_INVALID_REQ:
+            return RttStatus::INVALID_REQ;
+        case legacy_hal::RTT_STATUS_NO_WIFI:
+            return RttStatus::NO_WIFI;
+        case legacy_hal::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE:
+            return RttStatus::FAIL_FTM_PARAM_OVERRIDE;
+        case legacy_hal::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE:
+            return RttStatus::NAN_RANGING_PROTOCOL_FAILURE;
+        case legacy_hal::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED:
+            return RttStatus::NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
+    };
+    CHECK(false) << "Unknown legacy status: " << status;
+}
+
+bool convertAidlWifiChannelInfoToLegacy(const WifiChannelInfo& aidl_info,
+                                        legacy_hal::wifi_channel_info* legacy_info) {
+    if (!legacy_info) {
+        return false;
+    }
+    *legacy_info = {};
+    legacy_info->width = convertAidlWifiChannelWidthToLegacy(aidl_info.width);
+    legacy_info->center_freq = aidl_info.centerFreq;
+    legacy_info->center_freq0 = aidl_info.centerFreq0;
+    legacy_info->center_freq1 = aidl_info.centerFreq1;
+    return true;
+}
+
+bool convertLegacyWifiChannelInfoToAidl(const legacy_hal::wifi_channel_info& legacy_info,
+                                        WifiChannelInfo* aidl_info) {
+    if (!aidl_info) {
+        return false;
+    }
+    *aidl_info = {};
+    aidl_info->width = convertLegacyWifiChannelWidthToAidl(legacy_info.width);
+    aidl_info->centerFreq = legacy_info.center_freq;
+    aidl_info->centerFreq0 = legacy_info.center_freq0;
+    aidl_info->centerFreq1 = legacy_info.center_freq1;
+    return true;
+}
+
+bool convertAidlRttConfigToLegacy(const RttConfig& aidl_config,
+                                  legacy_hal::wifi_rtt_config* legacy_config) {
+    if (!legacy_config) {
+        return false;
+    }
+    *legacy_config = {};
+    CHECK(aidl_config.addr.size() == sizeof(legacy_config->addr));
+    memcpy(legacy_config->addr, aidl_config.addr.data(), aidl_config.addr.size());
+    legacy_config->type = convertAidlRttTypeToLegacy(aidl_config.type);
+    legacy_config->peer = convertAidlRttPeerTypeToLegacy(aidl_config.peer);
+    if (!convertAidlWifiChannelInfoToLegacy(aidl_config.channel, &legacy_config->channel)) {
+        return false;
+    }
+    legacy_config->burst_period = aidl_config.burstPeriod;
+    legacy_config->num_burst = aidl_config.numBurst;
+    legacy_config->num_frames_per_burst = aidl_config.numFramesPerBurst;
+    legacy_config->num_retries_per_rtt_frame = aidl_config.numRetriesPerRttFrame;
+    legacy_config->num_retries_per_ftmr = aidl_config.numRetriesPerFtmr;
+    legacy_config->LCI_request = aidl_config.mustRequestLci;
+    legacy_config->LCR_request = aidl_config.mustRequestLcr;
+    legacy_config->burst_duration = aidl_config.burstDuration;
+    legacy_config->preamble = convertAidlRttPreambleToLegacy(aidl_config.preamble);
+    legacy_config->bw = convertAidlRttBwToLegacy(aidl_config.bw);
+    return true;
+}
+
+bool convertAidlVectorOfRttConfigToLegacy(
+        const std::vector<RttConfig>& aidl_configs,
+        std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) {
+    if (!legacy_configs) {
+        return false;
+    }
+    *legacy_configs = {};
+    for (const auto& aidl_config : aidl_configs) {
+        legacy_hal::wifi_rtt_config legacy_config;
+        if (!convertAidlRttConfigToLegacy(aidl_config, &legacy_config)) {
+            return false;
+        }
+        legacy_configs->push_back(legacy_config);
+    }
+    return true;
+}
+
+bool convertAidlRttLciInformationToLegacy(const RttLciInformation& aidl_info,
+                                          legacy_hal::wifi_lci_information* legacy_info) {
+    if (!legacy_info) {
+        return false;
+    }
+    *legacy_info = {};
+    legacy_info->latitude = aidl_info.latitude;
+    legacy_info->longitude = aidl_info.longitude;
+    legacy_info->altitude = aidl_info.altitude;
+    legacy_info->latitude_unc = aidl_info.latitudeUnc;
+    legacy_info->longitude_unc = aidl_info.longitudeUnc;
+    legacy_info->altitude_unc = aidl_info.altitudeUnc;
+    legacy_info->motion_pattern = convertAidlRttMotionPatternToLegacy(aidl_info.motionPattern);
+    legacy_info->floor = aidl_info.floor;
+    legacy_info->height_above_floor = aidl_info.heightAboveFloor;
+    legacy_info->height_unc = aidl_info.heightUnc;
+    return true;
+}
+
+bool convertAidlRttLcrInformationToLegacy(const RttLcrInformation& aidl_info,
+                                          legacy_hal::wifi_lcr_information* legacy_info) {
+    if (!legacy_info) {
+        return false;
+    }
+    *legacy_info = {};
+    CHECK(aidl_info.countryCode.size() == sizeof(legacy_info->country_code));
+    memcpy(legacy_info->country_code, aidl_info.countryCode.data(), aidl_info.countryCode.size());
+    if (aidl_info.civicInfo.size() > sizeof(legacy_info->civic_info)) {
+        return false;
+    }
+    legacy_info->length = aidl_info.civicInfo.size();
+    memcpy(legacy_info->civic_info, aidl_info.civicInfo.c_str(), aidl_info.civicInfo.size());
+    return true;
+}
+
+bool convertAidlRttResponderToLegacy(const RttResponder& aidl_responder,
+                                     legacy_hal::wifi_rtt_responder* legacy_responder) {
+    if (!legacy_responder) {
+        return false;
+    }
+    *legacy_responder = {};
+    if (!convertAidlWifiChannelInfoToLegacy(aidl_responder.channel, &legacy_responder->channel)) {
+        return false;
+    }
+    legacy_responder->preamble = convertAidlRttPreambleToLegacy(aidl_responder.preamble);
+    return true;
+}
+
+bool convertLegacyRttResponderToAidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
+                                     RttResponder* aidl_responder) {
+    if (!aidl_responder) {
+        return false;
+    }
+    *aidl_responder = {};
+    if (!convertLegacyWifiChannelInfoToAidl(legacy_responder.channel, &aidl_responder->channel)) {
+        return false;
+    }
+    aidl_responder->preamble = convertLegacyRttPreambleToAidl(legacy_responder.preamble);
+    return true;
+}
+
+bool convertLegacyRttCapabilitiesToAidl(
+        const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
+        RttCapabilities* aidl_capabilities) {
+    if (!aidl_capabilities) {
+        return false;
+    }
+    *aidl_capabilities = {};
+    aidl_capabilities->rttOneSidedSupported = legacy_capabilities.rtt_one_sided_supported;
+    aidl_capabilities->rttFtmSupported = legacy_capabilities.rtt_ftm_supported;
+    aidl_capabilities->lciSupported = legacy_capabilities.lci_support;
+    aidl_capabilities->lcrSupported = legacy_capabilities.lcr_support;
+    aidl_capabilities->responderSupported = legacy_capabilities.responder_supported;
+    int32_t preambleSupport = 0;
+    for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT,
+                            legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE,
+                            legacy_hal::WIFI_RTT_PREAMBLE_EHT}) {
+        if (legacy_capabilities.preamble_support & flag) {
+            preambleSupport |= static_cast<std::underlying_type<RttPreamble>::type>(
+                    convertLegacyRttPreambleToAidl(flag));
+        }
+    }
+    aidl_capabilities->preambleSupport = static_cast<RttPreamble>(preambleSupport);
+    int32_t bwSupport = 0;
+    for (const auto flag :
+         {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20,
+          legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160,
+          legacy_hal::WIFI_RTT_BW_320}) {
+        if (legacy_capabilities.bw_support & flag) {
+            bwSupport |=
+                    static_cast<std::underlying_type<RttBw>::type>(convertLegacyRttBwToAidl(flag));
+        }
+    }
+    aidl_capabilities->bwSupport = static_cast<RttBw>(bwSupport);
+    aidl_capabilities->mcVersion = legacy_capabilities.mc_version;
+    return true;
+}
+
+bool convertLegacyWifiRateInfoToAidl(const legacy_hal::wifi_rate& legacy_rate,
+                                     WifiRateInfo* aidl_rate) {
+    if (!aidl_rate) {
+        return false;
+    }
+    *aidl_rate = {};
+    aidl_rate->preamble = convertLegacyWifiRatePreambleToAidl(legacy_rate.preamble);
+    aidl_rate->nss = convertLegacyWifiRateNssToAidl(legacy_rate.nss);
+    aidl_rate->bw = convertLegacyWifiChannelWidthToAidl(
+            static_cast<legacy_hal::wifi_channel_width>(legacy_rate.bw));
+    aidl_rate->rateMcsIdx = legacy_rate.rateMcsIdx;
+    aidl_rate->bitRateInKbps = legacy_rate.bitrate;
+    return true;
+}
+
+bool convertLegacyRttResultToAidl(const legacy_hal::wifi_rtt_result& legacy_result,
+                                  RttResult* aidl_result) {
+    if (!aidl_result) {
+        return false;
+    }
+    *aidl_result = {};
+    aidl_result->addr = std::array<uint8_t, 6>();
+    CHECK(sizeof(legacy_result.addr) == aidl_result->addr.size());
+    std::copy(legacy_result.addr, legacy_result.addr + 6, std::begin(aidl_result->addr));
+    aidl_result->burstNum = legacy_result.burst_num;
+    aidl_result->measurementNumber = legacy_result.measurement_number;
+    aidl_result->successNumber = legacy_result.success_number;
+    aidl_result->numberPerBurstPeer = legacy_result.number_per_burst_peer;
+    aidl_result->status = convertLegacyRttStatusToAidl(legacy_result.status);
+    aidl_result->retryAfterDuration = legacy_result.retry_after_duration;
+    aidl_result->type = convertLegacyRttTypeToAidl(legacy_result.type);
+    aidl_result->rssi = legacy_result.rssi;
+    aidl_result->rssiSpread = legacy_result.rssi_spread;
+    if (!convertLegacyWifiRateInfoToAidl(legacy_result.tx_rate, &aidl_result->txRate)) {
+        return false;
+    }
+    if (!convertLegacyWifiRateInfoToAidl(legacy_result.rx_rate, &aidl_result->rxRate)) {
+        return false;
+    }
+    aidl_result->rtt = legacy_result.rtt;
+    aidl_result->rttSd = legacy_result.rtt_sd;
+    aidl_result->rttSpread = legacy_result.rtt_spread;
+    aidl_result->distanceInMm = legacy_result.distance_mm;
+    aidl_result->distanceSdInMm = legacy_result.distance_sd_mm;
+    aidl_result->distanceSpreadInMm = legacy_result.distance_spread_mm;
+    aidl_result->timeStampInUs = legacy_result.ts;
+    aidl_result->burstDurationInMs = legacy_result.burst_duration;
+    aidl_result->negotiatedBurstNum = legacy_result.negotiated_burst_num;
+    if (legacy_result.LCI && !convertLegacyIeToAidl(*legacy_result.LCI, &aidl_result->lci)) {
+        return false;
+    }
+    if (legacy_result.LCR && !convertLegacyIeToAidl(*legacy_result.LCR, &aidl_result->lcr)) {
+        return false;
+    }
+    return true;
+}
+
+bool convertLegacyVectorOfRttResultToAidl(
+        const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
+        std::vector<RttResult>* aidl_results) {
+    if (!aidl_results) {
+        return false;
+    }
+    *aidl_results = {};
+    for (const auto legacy_result : legacy_results) {
+        RttResult aidl_result;
+        if (!convertLegacyRttResultToAidl(*legacy_result, &aidl_result)) {
+            return false;
+        }
+        aidl_result.channelFreqMHz = 0;
+        aidl_result.packetBw = RttBw::BW_UNSPECIFIED;
+        aidl_results->push_back(aidl_result);
+    }
+    return true;
+}
+
+bool convertLegacyVectorOfRttResultV2ToAidl(
+        const std::vector<const legacy_hal::wifi_rtt_result_v2*>& legacy_results,
+        std::vector<RttResult>* aidl_results) {
+    if (!aidl_results) {
+        return false;
+    }
+    *aidl_results = {};
+    for (const auto legacy_result : legacy_results) {
+        RttResult aidl_result;
+        if (!convertLegacyRttResultToAidl(legacy_result->rtt_result, &aidl_result)) {
+            return false;
+        }
+        aidl_result.channelFreqMHz =
+                legacy_result->frequency != UNSPECIFIED ? legacy_result->frequency : 0;
+        aidl_result.packetBw = convertLegacyRttBwToAidl(legacy_result->packet_bw);
+        aidl_results->push_back(aidl_result);
+    }
+    return true;
+}
+
+legacy_hal::wifi_interface_type convertAidlIfaceTypeToLegacy(IfaceType aidl_interface_type) {
+    switch (aidl_interface_type) {
+        case IfaceType::STA:
+            return legacy_hal::WIFI_INTERFACE_TYPE_STA;
+        case IfaceType::AP:
+            return legacy_hal::WIFI_INTERFACE_TYPE_AP;
+        case IfaceType::P2P:
+            return legacy_hal::WIFI_INTERFACE_TYPE_P2P;
+        case IfaceType::NAN_IFACE:
+            return legacy_hal::WIFI_INTERFACE_TYPE_NAN;
+    }
+    CHECK(false);
+}
+
+legacy_hal::wifi_multi_sta_use_case convertAidlMultiStaUseCaseToLegacy(
+        IWifiChip::MultiStaUseCase use_case) {
+    switch (use_case) {
+        case IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY:
+            return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+        case IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED:
+            return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
+    }
+    CHECK(false);
+}
+
+bool convertAidlCoexUnsafeChannelToLegacy(
+        const IWifiChip::CoexUnsafeChannel& aidl_unsafe_channel,
+        legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) {
+    if (!legacy_unsafe_channel) {
+        return false;
+    }
+    *legacy_unsafe_channel = {};
+    switch (aidl_unsafe_channel.band) {
+        case WifiBand::BAND_24GHZ:
+            legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND;
+            break;
+        case WifiBand::BAND_5GHZ:
+            legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND;
+            break;
+        default:
+            return false;
+    };
+    legacy_unsafe_channel->channel = aidl_unsafe_channel.channel;
+    legacy_unsafe_channel->power_cap_dbm = aidl_unsafe_channel.powerCapDbm;
+    return true;
+}
+
+bool convertAidlVectorOfCoexUnsafeChannelToLegacy(
+        const std::vector<IWifiChip::CoexUnsafeChannel>& aidl_unsafe_channels,
+        std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) {
+    if (!legacy_unsafe_channels) {
+        return false;
+    }
+    *legacy_unsafe_channels = {};
+    for (const auto& aidl_unsafe_channel : aidl_unsafe_channels) {
+        legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel;
+        if (!aidl_struct_util::convertAidlCoexUnsafeChannelToLegacy(aidl_unsafe_channel,
+                                                                    &legacy_unsafe_channel)) {
+            return false;
+        }
+        legacy_unsafe_channels->push_back(legacy_unsafe_channel);
+    }
+    return true;
+}
+
+WifiAntennaMode convertLegacyAntennaConfigurationToAidl(uint32_t antenna_cfg) {
+    switch (antenna_cfg) {
+        case legacy_hal::WIFI_ANTENNA_1X1:
+            return WifiAntennaMode::WIFI_ANTENNA_MODE_1X1;
+        case legacy_hal::WIFI_ANTENNA_2X2:
+            return WifiAntennaMode::WIFI_ANTENNA_MODE_2X2;
+        case legacy_hal::WIFI_ANTENNA_3X3:
+            return WifiAntennaMode::WIFI_ANTENNA_MODE_3X3;
+        case legacy_hal::WIFI_ANTENNA_4X4:
+            return WifiAntennaMode::WIFI_ANTENNA_MODE_4X4;
+        default:
+            return WifiAntennaMode::WIFI_ANTENNA_MODE_UNSPECIFIED;
+    }
+}
+
+bool convertLegacyWifiRadioConfigurationToAidl(
+        legacy_hal::wifi_radio_configuration* radio_configuration,
+        WifiRadioConfiguration* aidl_radio_configuration) {
+    if (!aidl_radio_configuration) {
+        return false;
+    }
+    *aidl_radio_configuration = {};
+    aidl_radio_configuration->bandInfo =
+            aidl_struct_util::convertLegacyMacBandToAidlWifiBand(radio_configuration->band);
+    if (aidl_radio_configuration->bandInfo == WifiBand::BAND_UNSPECIFIED) {
+        LOG(ERROR) << "Unspecified band";
+        return false;
+    }
+    aidl_radio_configuration->antennaMode =
+            aidl_struct_util::convertLegacyAntennaConfigurationToAidl(
+                    radio_configuration->antenna_cfg);
+    return true;
+}
+
+bool convertLegacyRadioCombinationsMatrixToAidl(
+        legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
+        std::vector<WifiRadioCombination>* aidl_combinations) {
+    if (!aidl_combinations || !legacy_matrix) {
+        return false;
+    }
+    *aidl_combinations = {};
+
+    int num_combinations = legacy_matrix->num_radio_combinations;
+    if (!num_combinations) {
+        LOG(ERROR) << "zero radio combinations";
+        return false;
+    }
+    wifi_radio_combination* l_radio_combinations_ptr = legacy_matrix->radio_combinations;
+    for (int i = 0; i < num_combinations; i++) {
+        int num_configurations = l_radio_combinations_ptr->num_radio_configurations;
+        WifiRadioCombination radioCombination;
+        std::vector<WifiRadioConfiguration> radio_configurations_vec;
+        if (!num_configurations) {
+            LOG(ERROR) << "zero radio configurations";
+            return false;
+        }
+        for (int j = 0; j < num_configurations; j++) {
+            WifiRadioConfiguration radioConfiguration;
+            wifi_radio_configuration* l_radio_configurations_ptr =
+                    &l_radio_combinations_ptr->radio_configurations[j];
+            if (!aidl_struct_util::convertLegacyWifiRadioConfigurationToAidl(
+                        l_radio_configurations_ptr, &radioConfiguration)) {
+                LOG(ERROR) << "Error converting wifi radio configuration";
+                return false;
+            }
+            radio_configurations_vec.push_back(radioConfiguration);
+        }
+        radioCombination.radioConfigurations = radio_configurations_vec;
+        aidl_combinations->push_back(radioCombination);
+        l_radio_combinations_ptr =
+                (wifi_radio_combination*)((u8*)l_radio_combinations_ptr +
+                                          sizeof(wifi_radio_combination) +
+                                          (sizeof(wifi_radio_configuration) * num_configurations));
+    }
+    return true;
+}
+
+bool convertAidlNanPairingInitiatorRequestToLegacy(const NanPairingRequest& aidl_request,
+                                                   legacy_hal::NanPairingRequest* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanPairingInitiatorRequestToLegacy: "
+                      "legacy_request is null";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->requestor_instance_id = aidl_request.peerId;
+    memcpy(legacy_request->peer_disc_mac_addr, aidl_request.peerDiscMacAddr.data(), 6);
+    legacy_request->nan_pairing_request_type =
+            convertAidlNanPairingRequestTypeToLegacy(aidl_request.requestType);
+    legacy_request->enable_pairing_cache = aidl_request.enablePairingCache;
+
+    memcpy(legacy_request->nan_identity_key, aidl_request.pairingIdentityKey.data(),
+           NAN_IDENTITY_KEY_LEN);
+
+    legacy_request->is_opportunistic =
+            aidl_request.securityConfig.securityType == NanPairingSecurityType::OPPORTUNISTIC ? 1
+                                                                                              : 0;
+    legacy_request->akm = convertAidlAkmTypeToLegacy(aidl_request.securityConfig.akm);
+    legacy_request->cipher_type = (unsigned int)aidl_request.securityConfig.cipherType;
+    if (aidl_request.securityConfig.securityType == NanPairingSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+        legacy_request->key_info.body.pmk_info.pmk_len = aidl_request.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            LOG(ERROR) << "convertAidlNanPairingInitiatorRequestToLegacy: "
+                          "invalid pmk_len";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.pmk_info.pmk, aidl_request.securityConfig.pmk.data(),
+               legacy_request->key_info.body.pmk_info.pmk_len);
+    }
+    if (aidl_request.securityConfig.securityType == NanPairingSecurityType::PASSPHRASE) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+        legacy_request->key_info.body.passphrase_info.passphrase_len =
+                aidl_request.securityConfig.passphrase.size();
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanPairingInitiatorRequestToLegacy: "
+                          "passphrase_len too small";
+            return false;
+        }
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanPairingInitiatorRequestToLegacy: "
+                          "passphrase_len too large";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+               aidl_request.securityConfig.passphrase.data(),
+               legacy_request->key_info.body.passphrase_info.passphrase_len);
+    }
+
+    return true;
+}
+
+bool convertAidlNanPairingIndicationResponseToLegacy(
+        const NanRespondToPairingIndicationRequest& aidl_request,
+        legacy_hal::NanPairingIndicationResponse* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanPairingIndicationResponseToLegacy: "
+                      "legacy_request is null";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->pairing_instance_id = aidl_request.pairingInstanceId;
+    legacy_request->nan_pairing_request_type =
+            convertAidlNanPairingRequestTypeToLegacy(aidl_request.requestType);
+    legacy_request->enable_pairing_cache = aidl_request.enablePairingCache;
+
+    memcpy(legacy_request->nan_identity_key, aidl_request.pairingIdentityKey.data(),
+           NAN_IDENTITY_KEY_LEN);
+
+    legacy_request->is_opportunistic =
+            aidl_request.securityConfig.securityType == NanPairingSecurityType::OPPORTUNISTIC ? 1
+                                                                                              : 0;
+    legacy_request->akm = convertAidlAkmTypeToLegacy(aidl_request.securityConfig.akm);
+    legacy_request->cipher_type = (unsigned int)aidl_request.securityConfig.cipherType;
+    legacy_request->rsp_code =
+            aidl_request.acceptRequest ? NAN_PAIRING_REQUEST_ACCEPT : NAN_PAIRING_REQUEST_REJECT;
+    if (aidl_request.securityConfig.securityType == NanPairingSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+        legacy_request->key_info.body.pmk_info.pmk_len = aidl_request.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            LOG(ERROR) << "convertAidlNanPairingIndicationResponseToLegacy: "
+                          "invalid pmk_len";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.pmk_info.pmk, aidl_request.securityConfig.pmk.data(),
+               legacy_request->key_info.body.pmk_info.pmk_len);
+    }
+    if (aidl_request.securityConfig.securityType == NanPairingSecurityType::PASSPHRASE) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+        legacy_request->key_info.body.passphrase_info.passphrase_len =
+                aidl_request.securityConfig.passphrase.size();
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+            NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanPairingIndicationResponseToLegacy: "
+                          "passphrase_len too small";
+            return false;
+        }
+        if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+            NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+            LOG(ERROR) << "convertAidlNanPairingIndicationResponseToLegacy: "
+                          "passphrase_len too large";
+            return false;
+        }
+        memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+               aidl_request.securityConfig.passphrase.data(),
+               legacy_request->key_info.body.passphrase_info.passphrase_len);
+    }
+
+    return true;
+}
+
+bool convertAidlNanBootstrappingInitiatorRequestToLegacy(
+        const NanBootstrappingRequest& aidl_request,
+        legacy_hal::NanBootstrappingRequest* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanBootstrappingInitiatorRequestToLegacy: "
+                      "legacy_request is null";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->requestor_instance_id = aidl_request.peerId;
+    memcpy(legacy_request->peer_disc_mac_addr, aidl_request.peerDiscMacAddr.data(), 6);
+    legacy_request->request_bootstrapping_method =
+            convertAidlBootstrappingMethodToLegacy(aidl_request.requestBootstrappingMethod);
+    legacy_request->cookie_length = aidl_request.cookie.size();
+
+    memcpy(legacy_request->cookie, aidl_request.cookie.data(), legacy_request->cookie_length);
+
+    return true;
+}
+
+bool convertAidlNanBootstrappingIndicationResponseToLegacy(
+        const NanBootstrappingResponse& aidl_request,
+        legacy_hal::NanBootstrappingIndicationResponse* legacy_request) {
+    if (!legacy_request) {
+        LOG(ERROR) << "convertAidlNanBootstrappingIndicationResponseToLegacy: "
+                      "legacy_request is null";
+        return false;
+    }
+    *legacy_request = {};
+
+    legacy_request->service_instance_id = aidl_request.bootstrappingInstanceId;
+    legacy_request->rsp_code = aidl_request.acceptRequest ? NAN_BOOTSTRAPPING_REQUEST_ACCEPT
+                                                          : NAN_BOOTSTRAPPING_REQUEST_REJECT;
+
+    return true;
+}
+
+bool convertLegacyNanPairingRequestIndToAidl(const legacy_hal::NanPairingRequestInd& legacy_ind,
+                                             NanPairingRequestInd* aidl_ind) {
+    if (!aidl_ind) {
+        LOG(ERROR) << "convertLegacyNanPairingRequestIndToAidl: aidl_ind is null";
+        return false;
+    }
+    *aidl_ind = {};
+
+    aidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+    aidl_ind->peerId = legacy_ind.requestor_instance_id;
+    aidl_ind->peerDiscMacAddr = std::array<uint8_t, 6>();
+    std::copy(legacy_ind.peer_disc_mac_addr, legacy_ind.peer_disc_mac_addr + 6,
+              std::begin(aidl_ind->peerDiscMacAddr));
+    aidl_ind->pairingInstanceId = legacy_ind.pairing_instance_id;
+    aidl_ind->enablePairingCache = legacy_ind.enable_pairing_cache == 1;
+    aidl_ind->requestType =
+            convertLegacyNanPairingRequestTypeToAidl(legacy_ind.nan_pairing_request_type);
+    if (!convertLegacyNiraToAidl(legacy_ind.nira, &aidl_ind->peerNira)) {
+        return false;
+    }
+    return true;
+}
+
+bool convertLegacyNanPairingConfirmIndToAidl(const legacy_hal::NanPairingConfirmInd& legacy_ind,
+                                             NanPairingConfirmInd* aidl_ind) {
+    if (!aidl_ind) {
+        LOG(ERROR) << "convertLegacyNanPairingRequestIndToAidl: aidl_ind is null";
+        return false;
+    }
+    *aidl_ind = {};
+
+    aidl_ind->pairingInstanceId = legacy_ind.pairing_instance_id;
+    aidl_ind->enablePairingCache = legacy_ind.enable_pairing_cache == 1;
+    aidl_ind->requestType =
+            convertLegacyNanPairingRequestTypeToAidl(legacy_ind.nan_pairing_request_type);
+    aidl_ind->pairingSuccess = legacy_ind.rsp_code == NAN_PAIRING_REQUEST_ACCEPT;
+    aidl_ind->status.status = convertLegacyNanStatusTypeToAidl(legacy_ind.reason_code);
+    if (!convertLegacyNpsaToAidl(legacy_ind.npk_security_association, &aidl_ind->npksa)) {
+        return false;
+    }
+    return true;
+}
+
+bool convertLegacyNanBootstrappingRequestIndToAidl(
+        const legacy_hal::NanBootstrappingRequestInd& legacy_ind,
+        NanBootstrappingRequestInd* aidl_ind) {
+    if (!aidl_ind) {
+        LOG(ERROR) << "convertLegacyNanBootstrappingRequestIndToAidl: aidl_ind is null";
+        return false;
+    }
+    *aidl_ind = {};
+
+    aidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+    aidl_ind->peerId = legacy_ind.requestor_instance_id;
+    aidl_ind->peerDiscMacAddr = std::array<uint8_t, 6>();
+    std::copy(legacy_ind.peer_disc_mac_addr, legacy_ind.peer_disc_mac_addr + 6,
+              std::begin(aidl_ind->peerDiscMacAddr));
+    aidl_ind->bootstrappingInstanceId = legacy_ind.bootstrapping_instance_id;
+    aidl_ind->requestBootstrappingMethod =
+            convertLegacyBootstrappingMethodToAidl(legacy_ind.request_bootstrapping_method);
+    return true;
+}
+
+bool convertLegacyNanBootstrappingConfirmIndToAidl(
+        const legacy_hal::NanBootstrappingConfirmInd& legacy_ind,
+        NanBootstrappingConfirmInd* aidl_ind) {
+    if (!aidl_ind) {
+        LOG(ERROR) << "convertLegacyNanBootstrappingConfirmIndToAidl: aidl_ind is null";
+        return false;
+    }
+    *aidl_ind = {};
+
+    aidl_ind->bootstrappingInstanceId = legacy_ind.bootstrapping_instance_id;
+    aidl_ind->responseCode = static_cast<NanBootstrappingResponseCode>(legacy_ind.rsp_code);
+    aidl_ind->reasonCode.status = convertLegacyNanStatusTypeToAidl(legacy_ind.reason_code);
+    aidl_ind->comeBackDelay = legacy_ind.come_back_delay;
+    aidl_ind->cookie =
+            std::vector<uint8_t>(legacy_ind.cookie, legacy_ind.cookie + legacy_ind.cookie_length);
+    return true;
+}
+
+bool convertLegacyWifiChipCapabilitiesToAidl(
+        const legacy_hal::wifi_chip_capabilities& legacy_chip_capabilities,
+        WifiChipCapabilities& aidl_chip_capabilities) {
+    aidl_chip_capabilities.maxMloStrLinkCount = legacy_chip_capabilities.max_mlo_str_link_count;
+    aidl_chip_capabilities.maxMloAssociationLinkCount =
+            legacy_chip_capabilities.max_mlo_association_link_count;
+    aidl_chip_capabilities.maxConcurrentTdlsSessionCount =
+            legacy_chip_capabilities.max_concurrent_tdls_session_count;
+    return true;
+}
+
+uint32_t convertAidlChannelCategoryToLegacy(uint32_t aidl_channel_category_mask) {
+    uint32_t channel_category_mask = 0;
+    if (aidl_channel_category_mask &
+        static_cast<int32_t>(IWifiChip::ChannelCategoryMask::INDOOR_CHANNEL)) {
+        channel_category_mask |= legacy_hal::WIFI_INDOOR_CHANNEL;
+    }
+    if (aidl_channel_category_mask &
+        static_cast<int32_t>(IWifiChip::ChannelCategoryMask::DFS_CHANNEL)) {
+        channel_category_mask |= legacy_hal::WIFI_DFS_CHANNEL;
+    }
+    return channel_category_mask;
+}
+
+bool convertLegacyIfaceMaskToIfaceConcurrencyType(u32 mask,
+                                                  std::vector<IfaceConcurrencyType>* types) {
+    if (!mask) return false;
+
+#ifndef BIT
+#define BIT(x) (1 << (x))
+#endif
+    if (mask & BIT(WIFI_INTERFACE_TYPE_STA)) types->push_back(IfaceConcurrencyType::STA);
+    if (mask & BIT(WIFI_INTERFACE_TYPE_AP)) types->push_back(IfaceConcurrencyType::AP);
+    if (mask & BIT(WIFI_INTERFACE_TYPE_AP_BRIDGED))
+        types->push_back(IfaceConcurrencyType::AP_BRIDGED);
+    if (mask & BIT(WIFI_INTERFACE_TYPE_P2P)) types->push_back(IfaceConcurrencyType::P2P);
+    if (mask & BIT(WIFI_INTERFACE_TYPE_NAN)) types->push_back(IfaceConcurrencyType::NAN_IFACE);
+
+    return true;
+}
+
+bool convertLegacyIfaceCombinationsMatrixToChipMode(
+        legacy_hal::wifi_iface_concurrency_matrix& legacy_matrix, IWifiChip::ChipMode* chip_mode) {
+    if (!chip_mode) {
+        LOG(ERROR) << "chip_mode is null";
+        return false;
+    }
+    *chip_mode = {};
+
+    int num_combinations = legacy_matrix.num_iface_combinations;
+    std::vector<IWifiChip::ChipConcurrencyCombination> driver_Combinations_vec;
+    if (!num_combinations) {
+        LOG(ERROR) << "zero iface combinations";
+        return false;
+    }
+
+    for (int i = 0; i < num_combinations; i++) {
+        IWifiChip::ChipConcurrencyCombination chipComb;
+        std::vector<IWifiChip::ChipConcurrencyCombinationLimit> limits;
+        wifi_iface_combination* comb = &legacy_matrix.iface_combinations[i];
+        if (!comb->num_iface_limits) continue;
+        for (u32 j = 0; j < comb->num_iface_limits; j++) {
+            IWifiChip::ChipConcurrencyCombinationLimit chipLimit;
+            chipLimit.maxIfaces = comb->iface_limits[j].max_limit;
+            std::vector<IfaceConcurrencyType> types;
+            if (!convertLegacyIfaceMaskToIfaceConcurrencyType(comb->iface_limits[j].iface_mask,
+                                                              &types)) {
+                LOG(ERROR) << "Failed to convert from iface_mask:"
+                           << comb->iface_limits[j].iface_mask;
+                return false;
+            }
+            chipLimit.types = types;
+            limits.push_back(chipLimit);
+        }
+        chipComb.limits = limits;
+        driver_Combinations_vec.push_back(chipComb);
+    }
+
+    chip_mode->availableCombinations = driver_Combinations_vec;
+    return true;
+}
+
+}  // namespace aidl_struct_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
new file mode 100644
index 0000000..e4ff963
--- /dev/null
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AIDL_STRUCT_UTIL_H_
+#define AIDL_STRUCT_UTIL_H_
+
+#include <aidl/android/hardware/wifi/IWifiChip.h>
+#include <aidl/android/hardware/wifi/IWifiChipEventCallback.h>
+#include <aidl/android/hardware/wifi/NanBandIndex.h>
+#include <aidl/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.h>
+#include <aidl/android/hardware/wifi/StaScanDataFlagMask.h>
+#include <aidl/android/hardware/wifi/WifiDebugRingBufferFlags.h>
+#include <aidl/android/hardware/wifi/WifiIfaceMode.h>
+
+#include <vector>
+
+#include "wifi_legacy_hal.h"
+
+/**
+ * This file contains a bunch of functions to convert structs from the legacy
+ * HAL to AIDL and vice versa.
+ */
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_struct_util {
+
+// Chip conversion methods.
+bool convertLegacyChipFeaturesToAidl(uint64_t legacy_feature_set, uint32_t* aidl_feature_set);
+bool convertLegacyDebugRingBufferStatusToAidl(
+        const legacy_hal::wifi_ring_buffer_status& legacy_status,
+        WifiDebugRingBufferStatus* aidl_status);
+bool convertLegacyVectorOfDebugRingBufferStatusToAidl(
+        const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
+        std::vector<WifiDebugRingBufferStatus>* aidl_status_vec);
+bool convertLegacyWakeReasonStatsToAidl(const legacy_hal::WakeReasonStats& legacy_stats,
+                                        WifiDebugHostWakeReasonStats* aidl_stats);
+legacy_hal::wifi_power_scenario convertAidlTxPowerScenarioToLegacy(
+        IWifiChip::TxPowerScenario aidl_scenario);
+legacy_hal::wifi_latency_mode convertAidlLatencyModeToLegacy(
+        IWifiChip::LatencyMode aidl_latency_mode);
+bool convertLegacyWifiMacInfosToAidl(
+        const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+        std::vector<IWifiChipEventCallback::RadioModeInfo>* aidl_radio_mode_infos);
+legacy_hal::wifi_interface_type convertAidlIfaceTypeToLegacy(IfaceType aidl_interface_type);
+legacy_hal::wifi_multi_sta_use_case convertAidlMultiStaUseCaseToLegacy(
+        IWifiChip::MultiStaUseCase use_case);
+bool convertAidlCoexUnsafeChannelToLegacy(
+        const IWifiChip::CoexUnsafeChannel& aidl_unsafe_channel,
+        legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel);
+bool convertAidlVectorOfCoexUnsafeChannelToLegacy(
+        const std::vector<IWifiChip::CoexUnsafeChannel>& aidl_unsafe_channels,
+        std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);
+bool convertLegacyRadioCombinationsMatrixToAidl(
+        legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
+        std::vector<WifiRadioCombination>* aidl_combinations);
+WifiBand convertLegacyMacBandToAidlWifiBand(uint32_t band);
+WifiAntennaMode convertLegacyAntennaConfigurationToAidl(uint32_t antenna_cfg);
+bool convertLegacyIfaceCombinationsMatrixToChipMode(
+        legacy_hal::wifi_iface_concurrency_matrix& legacy_matrix, IWifiChip::ChipMode* chip_mode);
+
+// STA iface conversion methods.
+bool convertLegacyStaIfaceFeaturesToAidl(uint64_t legacy_feature_set, uint32_t* aidl_feature_set);
+bool convertLegacyApfCapabilitiesToAidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
+                                        StaApfPacketFilterCapabilities* aidl_caps);
+bool convertLegacyGscanCapabilitiesToAidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
+                                          StaBackgroundScanCapabilities* aidl_caps);
+legacy_hal::wifi_band convertAidlWifiBandToLegacy(WifiBand band);
+bool convertAidlGscanParamsToLegacy(const StaBackgroundScanParameters& aidl_scan_params,
+                                    legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
+// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11
+// Information Elements (IEs)
+bool convertLegacyGscanResultToAidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
+                                    bool has_ie_data, StaScanResult* aidl_scan_result);
+// |cached_results| is assumed to not include IEs.
+bool convertLegacyVectorOfCachedGscanResultsToAidl(
+        const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
+        std::vector<StaScanData>* aidl_scan_datas);
+bool convertLegacyLinkLayerMlStatsToAidl(const legacy_hal::LinkLayerMlStats& legacy_ml_stats,
+                                         StaLinkLayerStats* aidl_stats);
+bool convertLegacyLinkLayerStatsToAidl(const legacy_hal::LinkLayerStats& legacy_stats,
+                                       StaLinkLayerStats* aidl_stats);
+bool convertLegacyRoamingCapabilitiesToAidl(
+        const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+        StaRoamingCapabilities* aidl_caps);
+bool convertAidlRoamingConfigToLegacy(const StaRoamingConfig& aidl_config,
+                                      legacy_hal::wifi_roaming_config* legacy_config);
+legacy_hal::fw_roaming_state_t convertAidlRoamingStateToLegacy(StaRoamingState state);
+bool convertLegacyVectorOfDebugTxPacketFateToAidl(
+        const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
+        std::vector<WifiDebugTxPacketFateReport>* aidl_fates);
+bool convertLegacyVectorOfDebugRxPacketFateToAidl(
+        const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
+        std::vector<WifiDebugRxPacketFateReport>* aidl_fates);
+
+// NAN iface conversion methods.
+void convertToNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+                        NanStatus* nanStatus);
+bool convertAidlNanEnableRequestToLegacy(const NanEnableRequest& aidl_request1,
+                                         const NanConfigRequestSupplemental& aidl_request2,
+                                         legacy_hal::NanEnableRequest* legacy_request);
+bool convertAidlNanConfigRequestToLegacy(const NanConfigRequest& aidl_request1,
+                                         const NanConfigRequestSupplemental& aidl_request2,
+                                         legacy_hal::NanConfigRequest* legacy_request);
+bool convertAidlNanPublishRequestToLegacy(const NanPublishRequest& aidl_request,
+                                          legacy_hal::NanPublishRequest* legacy_request);
+bool convertAidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& aidl_request,
+                                            legacy_hal::NanSubscribeRequest* legacy_request);
+bool convertAidlNanTransmitFollowupRequestToLegacy(
+        const NanTransmitFollowupRequest& aidl_request,
+        legacy_hal::NanTransmitFollowupRequest* legacy_request);
+bool convertAidlNanDataPathInitiatorRequestToLegacy(
+        const NanInitiateDataPathRequest& aidl_request,
+        legacy_hal::NanDataPathInitiatorRequest* legacy_request);
+bool convertAidlNanDataPathIndicationResponseToLegacy(
+        const NanRespondToDataPathIndicationRequest& aidl_response,
+        legacy_hal::NanDataPathIndicationResponse* legacy_response);
+bool convertLegacyNanResponseHeaderToAidl(const legacy_hal::NanResponseMsg& legacy_response,
+                                          NanStatus* nanStatus);
+bool convertLegacyNanCapabilitiesResponseToAidl(const legacy_hal::NanCapabilities& legacy_response,
+                                                NanCapabilities* aidl_response);
+bool convertLegacyNanMatchIndToAidl(const legacy_hal::NanMatchInd& legacy_ind,
+                                    NanMatchInd* aidl_ind);
+bool convertLegacyNanFollowupIndToAidl(const legacy_hal::NanFollowupInd& legacy_ind,
+                                       NanFollowupReceivedInd* aidl_ind);
+bool convertLegacyNanDataPathRequestIndToAidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
+                                              NanDataPathRequestInd* aidl_ind);
+bool convertLegacyNanDataPathConfirmIndToAidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
+                                              NanDataPathConfirmInd* aidl_ind);
+bool convertLegacyNanDataPathScheduleUpdateIndToAidl(
+        const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
+        NanDataPathScheduleUpdateInd* aidl_ind);
+
+// RTT controller conversion methods.
+bool convertAidlVectorOfRttConfigToLegacy(const std::vector<RttConfig>& aidl_configs,
+                                          std::vector<legacy_hal::wifi_rtt_config>* legacy_configs);
+bool convertAidlRttLciInformationToLegacy(const RttLciInformation& aidl_info,
+                                          legacy_hal::wifi_lci_information* legacy_info);
+bool convertAidlRttLcrInformationToLegacy(const RttLcrInformation& aidl_info,
+                                          legacy_hal::wifi_lcr_information* legacy_info);
+bool convertAidlRttResponderToLegacy(const RttResponder& aidl_responder,
+                                     legacy_hal::wifi_rtt_responder* legacy_responder);
+bool convertAidlWifiChannelInfoToLegacy(const WifiChannelInfo& aidl_info,
+                                        legacy_hal::wifi_channel_info* legacy_info);
+bool convertLegacyRttResponderToAidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
+                                     RttResponder* aidl_responder);
+bool convertLegacyRttCapabilitiesToAidl(
+        const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
+        RttCapabilities* aidl_capabilities);
+bool convertLegacyVectorOfRttResultToAidl(
+        const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
+        std::vector<RttResult>* aidl_results);
+bool convertLegacyVectorOfRttResultV2ToAidl(
+        const std::vector<const legacy_hal::wifi_rtt_result_v2*>& legacy_results,
+        std::vector<RttResult>* aidl_results);
+uint32_t convertAidlWifiBandToLegacyMacBand(WifiBand band);
+uint32_t convertAidlWifiIfaceModeToLegacy(uint32_t aidl_iface_mask);
+uint32_t convertAidlUsableChannelFilterToLegacy(uint32_t aidl_filter_mask);
+bool convertLegacyWifiUsableChannelsToAidl(
+        const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+        std::vector<WifiUsableChannel>* aidl_usable_channels);
+bool convertLegacyPeerInfoStatsToAidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+                                      StaPeerInfo* aidl_peer_info_stats);
+bool convertLegacyWifiRateInfoToAidl(const legacy_hal::wifi_rate& legacy_rate,
+                                     WifiRateInfo* aidl_rate);
+bool convertLegacyWifiChipCapabilitiesToAidl(
+        const legacy_hal::wifi_chip_capabilities& legacy_chip_capabilities,
+        WifiChipCapabilities& aidl_chip_capabilities);
+bool convertAidlNanPairingInitiatorRequestToLegacy(const NanPairingRequest& aidl_request,
+                                                   legacy_hal::NanPairingRequest* legacy_request);
+bool convertAidlNanPairingIndicationResponseToLegacy(
+        const NanRespondToPairingIndicationRequest& aidl_response,
+        legacy_hal::NanPairingIndicationResponse* legacy_response);
+bool convertAidlNanBootstrappingInitiatorRequestToLegacy(
+        const NanBootstrappingRequest& aidl_request,
+        legacy_hal::NanBootstrappingRequest* legacy_request);
+bool convertAidlNanBootstrappingIndicationResponseToLegacy(
+        const NanBootstrappingResponse& aidl_response,
+        legacy_hal::NanBootstrappingIndicationResponse* legacy_response);
+bool convertLegacyNanPairingRequestIndToAidl(const legacy_hal::NanPairingRequestInd& legacy_ind,
+                                             NanPairingRequestInd* aidl_ind);
+bool convertLegacyNanPairingConfirmIndToAidl(const legacy_hal::NanPairingConfirmInd& legacy_ind,
+                                             NanPairingConfirmInd* aidl_ind);
+bool convertLegacyNanBootstrappingRequestIndToAidl(
+        const legacy_hal::NanBootstrappingRequestInd& legacy_ind,
+        NanBootstrappingRequestInd* aidl_ind);
+bool convertLegacyNanBootstrappingConfirmIndToAidl(
+        const legacy_hal::NanBootstrappingConfirmInd& legacy_ind,
+        NanBootstrappingConfirmInd* aidl_ind);
+uint32_t convertAidlChannelCategoryToLegacy(uint32_t aidl_channel_category_mask);
+}  // namespace aidl_struct_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // AIDL_STRUCT_UTIL_H_
diff --git a/wifi/aidl/default/aidl_sync_util.cpp b/wifi/aidl/default/aidl_sync_util.cpp
new file mode 100644
index 0000000..d81eb81
--- /dev/null
+++ b/wifi/aidl/default/aidl_sync_util.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "aidl_sync_util.h"
+
+namespace {
+std::recursive_mutex g_mutex;
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_sync_util {
+
+std::unique_lock<std::recursive_mutex> acquireGlobalLock() {
+    return std::unique_lock<std::recursive_mutex>{g_mutex};
+}
+
+}  // namespace aidl_sync_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/aidl_sync_util.h b/wifi/aidl/default/aidl_sync_util.h
new file mode 100644
index 0000000..a61cd3f
--- /dev/null
+++ b/wifi/aidl/default/aidl_sync_util.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AIDL_SYNC_UTIL_H_
+#define AIDL_SYNC_UTIL_H_
+
+#include <mutex>
+
+// Utility that provides a global lock to synchronize access between
+// the AIDL thread and the legacy HAL's event loop.
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_sync_util {
+std::unique_lock<std::recursive_mutex> acquireGlobalLock();
+}  // namespace aidl_sync_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+#endif  // AIDL_SYNC_UTIL_H_
diff --git a/wifi/aidl/default/android.hardware.wifi-service-lazy.rc b/wifi/aidl/default/android.hardware.wifi-service-lazy.rc
new file mode 100644
index 0000000..12d3ff7
--- /dev/null
+++ b/wifi/aidl/default/android.hardware.wifi-service-lazy.rc
@@ -0,0 +1,8 @@
+service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi-service-lazy
+    interface aidl android.hardware.wifi.IWifi/default
+    oneshot
+    disabled
+    class hal
+    capabilities NET_ADMIN NET_RAW SYS_MODULE
+    user wifi
+    group wifi gps
diff --git a/wifi/aidl/default/android.hardware.wifi-service.rc b/wifi/aidl/default/android.hardware.wifi-service.rc
new file mode 100644
index 0000000..ec8acf5
--- /dev/null
+++ b/wifi/aidl/default/android.hardware.wifi-service.rc
@@ -0,0 +1,6 @@
+service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi-service
+    interface aidl android.hardware.wifi.IWifi/default
+    class hal
+    capabilities NET_ADMIN NET_RAW SYS_MODULE
+    user wifi
+    group wifi gps
diff --git a/wifi/aidl/default/android.hardware.wifi-service.xml b/wifi/aidl/default/android.hardware.wifi-service.xml
new file mode 100644
index 0000000..5398ee7
--- /dev/null
+++ b/wifi/aidl/default/android.hardware.wifi-service.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+	<hal format="aidl">
+		<name>android.hardware.wifi</name>
+		<fqname>IWifi/default</fqname>
+	</hal>
+</manifest>
diff --git a/wifi/aidl/default/ringbuffer.cpp b/wifi/aidl/default/ringbuffer.cpp
new file mode 100644
index 0000000..9d08a73
--- /dev/null
+++ b/wifi/aidl/default/ringbuffer.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ringbuffer.h"
+
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {}
+
+enum Ringbuffer::AppendStatus Ringbuffer::append(const std::vector<uint8_t>& input) {
+    if (input.size() == 0) {
+        return AppendStatus::FAIL_IP_BUFFER_ZERO;
+    }
+    if (input.size() > maxSize_) {
+        LOG(INFO) << "Oversized message of " << input.size() << " bytes is dropped";
+        return AppendStatus::FAIL_IP_BUFFER_EXCEEDED_MAXSIZE;
+    }
+    data_.push_back(input);
+    size_ += input.size() * sizeof(input[0]);
+    while (size_ > maxSize_) {
+        if (data_.front().size() <= 0 || data_.front().size() > maxSize_) {
+            LOG(ERROR) << "First buffer in the ring buffer is Invalid. Size: "
+                       << data_.front().size();
+            return AppendStatus::FAIL_RING_BUFFER_CORRUPTED;
+        }
+        size_ -= data_.front().size() * sizeof(data_.front()[0]);
+        data_.pop_front();
+    }
+    return AppendStatus::SUCCESS;
+}
+
+const std::list<std::vector<uint8_t>>& Ringbuffer::getData() const {
+    return data_;
+}
+
+void Ringbuffer::clear() {
+    data_.clear();
+    size_ = 0;
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/ringbuffer.h b/wifi/aidl/default/ringbuffer.h
new file mode 100644
index 0000000..80c0c11
--- /dev/null
+++ b/wifi/aidl/default/ringbuffer.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RINGBUFFER_H_
+#define RINGBUFFER_H_
+
+#include <list>
+#include <vector>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * Ringbuffer object used to store debug data.
+ */
+class Ringbuffer {
+  public:
+    // Error codes for the append ring buffer operation
+    enum AppendStatus {
+        SUCCESS,
+        FAIL_GENERIC,
+        FAIL_IP_BUFFER_ZERO,
+        FAIL_IP_BUFFER_EXCEEDED_MAXSIZE,
+        FAIL_RING_BUFFER_CORRUPTED
+    };
+    explicit Ringbuffer(size_t maxSize);
+
+    // Appends the data buffer and deletes from the front until buffer is
+    // within |maxSize_|.
+    enum AppendStatus append(const std::vector<uint8_t>& input);
+    const std::list<std::vector<uint8_t>>& getData() const;
+    void clear();
+
+  private:
+    std::list<std::vector<uint8_t>> data_;
+    size_t size_;
+    size_t maxSize_;
+};
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // RINGBUFFER_H_
diff --git a/wifi/aidl/default/service.cpp b/wifi/aidl/default/service.cpp
new file mode 100644
index 0000000..789a7a5
--- /dev/null
+++ b/wifi/aidl/default/service.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <signal.h>
+
+#include "wifi.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_legacy_hal_factory.h"
+#include "wifi_mode_controller.h"
+
+using aidl::android::hardware::wifi::feature_flags::WifiFeatureFlags;
+using aidl::android::hardware::wifi::legacy_hal::WifiLegacyHal;
+using aidl::android::hardware::wifi::legacy_hal::WifiLegacyHalFactory;
+using aidl::android::hardware::wifi::mode_controller::WifiModeController;
+
+#ifdef LAZY_SERVICE
+const bool kLazyService = true;
+#else
+const bool kLazyService = false;
+#endif
+
+int main(int /*argc*/, char** argv) {
+    signal(SIGPIPE, SIG_IGN);
+    android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
+    LOG(INFO) << "Wifi Hal is booting up...";
+
+    // Prepare the RPC-serving thread pool. Allocate 1 thread in the pool,
+    // which our main thread will join below.
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+
+    const auto iface_tool = std::make_shared<::android::wifi_system::InterfaceTool>();
+    const auto legacy_hal_factory = std::make_shared<WifiLegacyHalFactory>(iface_tool);
+
+    // Setup binder service
+    std::shared_ptr<aidl::android::hardware::wifi::Wifi> service =
+            ndk::SharedRefBase::make<aidl::android::hardware::wifi::Wifi>(
+                    iface_tool, legacy_hal_factory, std::make_shared<WifiModeController>(),
+                    std::make_shared<WifiFeatureFlags>());
+    std::string instance =
+            std::string() + aidl::android::hardware::wifi::Wifi::descriptor + "/default";
+    if (kLazyService) {
+        auto result =
+                AServiceManager_registerLazyService(service->asBinder().get(), instance.c_str());
+        CHECK_EQ(result, STATUS_OK) << "Failed to register lazy wifi HAL";
+    } else {
+        auto result = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+        CHECK_EQ(result, STATUS_OK) << "Failed to register wifi HAL";
+    }
+
+    ABinderProcess_startThreadPool();
+    LOG(INFO) << "Joining RPC thread pool";
+    ABinderProcess_joinThreadPool();
+
+    LOG(INFO) << "Wifi Hal is terminating...";
+    return 0;
+}
diff --git a/wifi/aidl/default/tests/README.md b/wifi/aidl/default/tests/README.md
new file mode 100644
index 0000000..fc0a98a
--- /dev/null
+++ b/wifi/aidl/default/tests/README.md
@@ -0,0 +1,14 @@
+# Vendor HAL gTest Suite
+
+## Overview
+Rather than testing an active instance of the service like the VTS tests,
+this test suite will test individual files from the Vendor HAL.
+This is especially useful for testing conversion methods (see `aidl_struct_util_unit_tests.cpp`),
+but can also be used to test things like `wifi_chip`.
+
+## Usage
+Run the test script with a device connected:
+
+```
+./runtests.sh
+```
diff --git a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
new file mode 100644
index 0000000..5c334f8
--- /dev/null
+++ b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
@@ -0,0 +1,873 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "aidl_struct_util.h"
+
+using testing::Test;
+
+namespace {
+constexpr uint32_t kMacId1 = 1;
+constexpr uint32_t kMacId2 = 2;
+constexpr uint32_t kIfaceChannel1 = 3;
+constexpr uint32_t kIfaceChannel2 = 5;
+constexpr char kIfaceName1[] = "wlan0";
+constexpr char kIfaceName2[] = "wlan1";
+constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc};
+byte LCI[] = {0x27, 0x1A, 0x1,  0x00, 0x8,  0x01, 0x00, 0x08, 0x00, 0x10, 0x52,
+              0x83, 0x4d, 0x12, 0xef, 0xd2, 0xb0, 0x8b, 0x9b, 0x4b, 0xf1, 0xcc,
+              0x2c, 0x00, 0x00, 0x41, 0x06, 0x03, 0x06, 0x00, 0x80};
+byte LCR[] = {0x27, 0xE,  0x1,  0x00, 0xB,  0x01, 0x00, 0x0b, 0x00, 0x09,
+              0x55, 0x53, 0x18, 0x05, 0x39, 0x34, 0x30, 0x34, 0x33};
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+class AidlStructUtilTest : public Test {};
+
+TEST_F(AidlStructUtilTest, CanConvertLegacyWifiMacInfosToAidlWithOneMac) {
+    std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
+    legacy_hal::WifiMacInfo legacy_mac_info1 = {
+            .wlan_mac_id = kMacId1,
+            .mac_band = legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND};
+    legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
+    legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
+    legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
+    legacy_mac_info1.iface_infos.push_back(legacy_iface_info2);
+    legacy_mac_infos.push_back(legacy_mac_info1);
+
+    std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
+    ASSERT_TRUE(aidl_struct_util::convertLegacyWifiMacInfosToAidl(legacy_mac_infos,
+                                                                  &aidl_radio_mode_infos));
+
+    ASSERT_EQ(1u, aidl_radio_mode_infos.size());
+    auto aidl_radio_mode_info1 = aidl_radio_mode_infos[0];
+    EXPECT_EQ(legacy_mac_info1.wlan_mac_id, (uint32_t)aidl_radio_mode_info1.radioId);
+    EXPECT_EQ(WifiBand::BAND_24GHZ_5GHZ, aidl_radio_mode_info1.bandInfo);
+    ASSERT_EQ(2u, aidl_radio_mode_info1.ifaceInfos.size());
+    auto aidl_iface_info1 = aidl_radio_mode_info1.ifaceInfos[0];
+    EXPECT_EQ(legacy_iface_info1.name, aidl_iface_info1.name);
+    EXPECT_EQ(static_cast<int32_t>(legacy_iface_info1.channel), aidl_iface_info1.channel);
+    auto aidl_iface_info2 = aidl_radio_mode_info1.ifaceInfos[1];
+    EXPECT_EQ(legacy_iface_info2.name, aidl_iface_info2.name);
+    EXPECT_EQ(static_cast<int32_t>(legacy_iface_info2.channel), aidl_iface_info2.channel);
+}
+
+TEST_F(AidlStructUtilTest, CanConvertLegacyWifiMacInfosToAidlWithTwoMac) {
+    std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
+    legacy_hal::WifiMacInfo legacy_mac_info1 = {.wlan_mac_id = kMacId1,
+                                                .mac_band = legacy_hal::WLAN_MAC_5_0_BAND};
+    legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
+    legacy_hal::WifiMacInfo legacy_mac_info2 = {.wlan_mac_id = kMacId2,
+                                                .mac_band = legacy_hal::WLAN_MAC_2_4_BAND};
+    legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
+    legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
+    legacy_mac_infos.push_back(legacy_mac_info1);
+    legacy_mac_info2.iface_infos.push_back(legacy_iface_info2);
+    legacy_mac_infos.push_back(legacy_mac_info2);
+
+    std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
+    ASSERT_TRUE(aidl_struct_util::convertLegacyWifiMacInfosToAidl(legacy_mac_infos,
+                                                                  &aidl_radio_mode_infos));
+
+    ASSERT_EQ(2u, aidl_radio_mode_infos.size());
+
+    // Find mac info 1.
+    const auto aidl_radio_mode_info1 =
+            std::find_if(aidl_radio_mode_infos.begin(), aidl_radio_mode_infos.end(),
+                         [&legacy_mac_info1](const IWifiChipEventCallback::RadioModeInfo& x) {
+                             return (uint32_t)x.radioId == legacy_mac_info1.wlan_mac_id;
+                         });
+    ASSERT_NE(aidl_radio_mode_infos.end(), aidl_radio_mode_info1);
+    EXPECT_EQ(WifiBand::BAND_5GHZ, aidl_radio_mode_info1->bandInfo);
+    ASSERT_EQ(1u, aidl_radio_mode_info1->ifaceInfos.size());
+    auto aidl_iface_info1 = aidl_radio_mode_info1->ifaceInfos[0];
+    EXPECT_EQ(legacy_iface_info1.name, aidl_iface_info1.name);
+    EXPECT_EQ(static_cast<int32_t>(legacy_iface_info1.channel), aidl_iface_info1.channel);
+
+    // Find mac info 2.
+    const auto aidl_radio_mode_info2 =
+            std::find_if(aidl_radio_mode_infos.begin(), aidl_radio_mode_infos.end(),
+                         [&legacy_mac_info2](const IWifiChipEventCallback::RadioModeInfo& x) {
+                             return (uint32_t)x.radioId == legacy_mac_info2.wlan_mac_id;
+                         });
+    ASSERT_NE(aidl_radio_mode_infos.end(), aidl_radio_mode_info2);
+    EXPECT_EQ(WifiBand::BAND_24GHZ, aidl_radio_mode_info2->bandInfo);
+    ASSERT_EQ(1u, aidl_radio_mode_info2->ifaceInfos.size());
+    auto aidl_iface_info2 = aidl_radio_mode_info2->ifaceInfos[0];
+    EXPECT_EQ(legacy_iface_info2.name, aidl_iface_info2.name);
+    EXPECT_EQ(static_cast<int32_t>(legacy_iface_info2.channel), aidl_iface_info2.channel);
+}
+
+TEST_F(AidlStructUtilTest, canConvertLegacyLinkLayerMlStatsToAidl) {
+    legacy_hal::LinkLayerMlStats legacy_ml_stats{};
+    // Add two radio stats
+    legacy_ml_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+    legacy_ml_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+    // Add two links.
+    legacy_ml_stats.links.push_back(legacy_hal::LinkStats{});
+    legacy_ml_stats.links.push_back(legacy_hal::LinkStats{});
+    // Set stats for each link.
+    for (legacy_hal::LinkStats& link : legacy_ml_stats.links) {
+        link.peers.push_back(legacy_hal::WifiPeerInfo{});
+        link.peers.push_back(legacy_hal::WifiPeerInfo{});
+        link.stat.beacon_rx = rand();
+        // MLO link id: 0 - 15
+        link.stat.link_id = rand() % 16;
+        // Maximum number of radios is limited to 3 for testing.
+        link.stat.radio = rand() % 4;
+        link.stat.frequency = rand();
+        // RSSI: 0 to -127
+        link.stat.rssi_mgmt = (rand() % 128) * -1;
+        link.stat.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BE].retries = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand();
+
+        link.stat.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BK].retries = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand();
+
+        link.stat.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VI].retries = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand();
+
+        link.stat.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VO].retries = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand();
+        link.stat.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand();
+
+        link.stat.time_slicing_duty_cycle_percent = rand() % 101;
+        link.stat.num_peers = 2;
+
+        // Set peer stats for each of the peers.
+        for (auto& peer : link.peers) {
+            // Max station count is limited to 32 for testing.
+            peer.peer_info.bssload.sta_count = rand() % 33;
+            peer.peer_info.bssload.chan_util = rand() % 101;
+            wifi_rate_stat rate_stat1 = {
+                    .rate = {3, 1, 2, 5, 0, 0},
+                    .tx_mpdu = 0,
+                    .rx_mpdu = 1,
+                    .mpdu_lost = 2,
+                    .retries = 3,
+                    .retries_short = 4,
+                    .retries_long = 5,
+            };
+            wifi_rate_stat rate_stat2 = {
+                    .rate = {2, 2, 1, 6, 0, 1},
+                    .tx_mpdu = 6,
+                    .rx_mpdu = 7,
+                    .mpdu_lost = 8,
+                    .retries = 9,
+                    .retries_short = 10,
+                    .retries_long = 11,
+            };
+            peer.rate_stats.push_back(rate_stat1);
+            peer.rate_stats.push_back(rate_stat2);
+        }
+    }
+    // Set radio stats
+    for (auto& radio : legacy_ml_stats.radios) {
+        // Maximum number of radios is limited to 3 for testing.
+        radio.stats.radio = rand() % 4;
+        radio.stats.on_time = rand();
+        radio.stats.tx_time = rand();
+        radio.stats.rx_time = rand();
+        radio.stats.on_time_scan = rand();
+        radio.stats.on_time_nbd = rand();
+        radio.stats.on_time_gscan = rand();
+        radio.stats.on_time_roam_scan = rand();
+        radio.stats.on_time_pno_scan = rand();
+        radio.stats.on_time_hs20 = rand();
+        for (int i = 0; i < 4; i++) {
+            radio.tx_time_per_levels.push_back(rand());
+        }
+
+        legacy_hal::wifi_channel_stat channel_stat1 = {
+                .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
+                .on_time = 0x1111,
+                .cca_busy_time = 0x55,
+        };
+        legacy_hal::wifi_channel_stat channel_stat2 = {
+                .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
+                .on_time = 0x2222,
+                .cca_busy_time = 0x66,
+        };
+        radio.channel_stats.push_back(channel_stat1);
+        radio.channel_stats.push_back(channel_stat2);
+    }
+    // Convert to AIDL
+    StaLinkLayerStats converted{};
+    aidl_struct_util::convertLegacyLinkLayerMlStatsToAidl(legacy_ml_stats, &converted);
+    // Validate
+    int l = 0;
+    for (legacy_hal::LinkStats& link : legacy_ml_stats.links) {
+        EXPECT_EQ(link.stat.link_id, (uint8_t)converted.iface.links[l].linkId);
+        EXPECT_EQ(link.stat.radio, converted.iface.links[l].radioId);
+        EXPECT_EQ(link.stat.frequency, (uint32_t)converted.iface.links[l].frequencyMhz);
+        EXPECT_EQ(link.stat.beacon_rx, (uint32_t)converted.iface.links[l].beaconRx);
+        EXPECT_EQ(link.stat.rssi_mgmt, converted.iface.links[l].avgRssiMgmt);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
+                  converted.iface.links[l].wmeBePktStats.rxMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
+                  converted.iface.links[l].wmeBePktStats.txMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
+                  converted.iface.links[l].wmeBePktStats.lostMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].retries,
+                  converted.iface.links[l].wmeBePktStats.retries);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_min,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeBeContentionTimeStats.contentionTimeMinInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_max,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeBeContentionTimeStats.contentionTimeMaxInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_avg,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeBeContentionTimeStats.contentionTimeAvgInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
+                  (uint32_t)converted.iface.links[l].wmeBeContentionTimeStats.contentionNumSamples);
+
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
+                  converted.iface.links[l].wmeBkPktStats.rxMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
+                  converted.iface.links[l].wmeBkPktStats.txMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
+                  converted.iface.links[l].wmeBkPktStats.lostMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].retries,
+                  converted.iface.links[l].wmeBkPktStats.retries);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_min,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeBkContentionTimeStats.contentionTimeMinInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_max,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeBkContentionTimeStats.contentionTimeMaxInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_avg,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeBkContentionTimeStats.contentionTimeAvgInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
+                  (uint32_t)converted.iface.links[l].wmeBkContentionTimeStats.contentionNumSamples);
+
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
+                  converted.iface.links[l].wmeViPktStats.rxMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
+                  converted.iface.links[l].wmeViPktStats.txMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
+                  converted.iface.links[l].wmeViPktStats.lostMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].retries,
+                  converted.iface.links[l].wmeViPktStats.retries);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_min,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeViContentionTimeStats.contentionTimeMinInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_max,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeViContentionTimeStats.contentionTimeMaxInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_avg,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeViContentionTimeStats.contentionTimeAvgInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
+                  (uint32_t)converted.iface.links[l].wmeViContentionTimeStats.contentionNumSamples);
+
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
+                  converted.iface.links[l].wmeVoPktStats.rxMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
+                  converted.iface.links[l].wmeVoPktStats.txMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
+                  converted.iface.links[l].wmeVoPktStats.lostMpdu);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].retries,
+                  converted.iface.links[l].wmeVoPktStats.retries);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_min,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeVoContentionTimeStats.contentionTimeMinInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_max,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeVoContentionTimeStats.contentionTimeMaxInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_avg,
+                  (uint32_t)converted.iface.links[l]
+                          .wmeVoContentionTimeStats.contentionTimeAvgInUsec);
+        EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
+                  (uint32_t)converted.iface.links[l].wmeVoContentionTimeStats.contentionNumSamples);
+
+        EXPECT_EQ(link.stat.time_slicing_duty_cycle_percent,
+                  converted.iface.links[l].timeSliceDutyCycleInPercent);
+
+        EXPECT_EQ(link.peers.size(), converted.iface.links[l].peers.size());
+        for (size_t i = 0; i < link.peers.size(); i++) {
+            EXPECT_EQ(link.peers[i].peer_info.bssload.sta_count,
+                      converted.iface.links[l].peers[i].staCount);
+            EXPECT_EQ(link.peers[i].peer_info.bssload.chan_util,
+                      converted.iface.links[l].peers[i].chanUtil);
+            for (size_t j = 0; j < link.peers[i].rate_stats.size(); j++) {
+                EXPECT_EQ(
+                        link.peers[i].rate_stats[j].rate.preamble,
+                        (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rateInfo.preamble);
+                EXPECT_EQ(link.peers[i].rate_stats[j].rate.nss,
+                          (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rateInfo.nss);
+                EXPECT_EQ(link.peers[i].rate_stats[j].rate.bw,
+                          (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rateInfo.bw);
+                EXPECT_EQ(link.peers[i].rate_stats[j].rate.rateMcsIdx,
+                          (uint32_t)converted.iface.links[l]
+                                  .peers[i]
+                                  .rateStats[j]
+                                  .rateInfo.rateMcsIdx);
+                EXPECT_EQ(link.peers[i].rate_stats[j].tx_mpdu,
+                          (uint32_t)converted.iface.links[l].peers[i].rateStats[j].txMpdu);
+                EXPECT_EQ(link.peers[i].rate_stats[j].rx_mpdu,
+                          (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rxMpdu);
+                EXPECT_EQ(link.peers[i].rate_stats[j].mpdu_lost,
+                          (uint32_t)converted.iface.links[l].peers[i].rateStats[j].mpduLost);
+                EXPECT_EQ(link.peers[i].rate_stats[j].retries,
+                          (uint32_t)converted.iface.links[l].peers[i].rateStats[j].retries);
+            }
+        }
+        ++l;
+    }  // loop over links
+
+    EXPECT_EQ(legacy_ml_stats.radios.size(), converted.radios.size());
+    for (size_t i = 0; i < legacy_ml_stats.radios.size(); i++) {
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.radio, converted.radios[i].radioId);
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time,
+                  (uint32_t)converted.radios[i].onTimeInMs);
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.tx_time,
+                  (uint32_t)converted.radios[i].txTimeInMs);
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.rx_time,
+                  (uint32_t)converted.radios[i].rxTimeInMs);
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_scan,
+                  (uint32_t)converted.radios[i].onTimeInMsForScan);
+        EXPECT_EQ(legacy_ml_stats.radios[i].tx_time_per_levels.size(),
+                  converted.radios[i].txTimeInMsPerLevel.size());
+        for (size_t j = 0; j < legacy_ml_stats.radios[i].tx_time_per_levels.size(); j++) {
+            EXPECT_EQ(legacy_ml_stats.radios[i].tx_time_per_levels[j],
+                      (uint32_t)converted.radios[i].txTimeInMsPerLevel[j]);
+        }
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_nbd,
+                  (uint32_t)converted.radios[i].onTimeInMsForNanScan);
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_gscan,
+                  (uint32_t)converted.radios[i].onTimeInMsForBgScan);
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_roam_scan,
+                  (uint32_t)converted.radios[i].onTimeInMsForRoamScan);
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_pno_scan,
+                  (uint32_t)converted.radios[i].onTimeInMsForPnoScan);
+        EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_hs20,
+                  (uint32_t)converted.radios[i].onTimeInMsForHs20Scan);
+        EXPECT_EQ(legacy_ml_stats.radios[i].channel_stats.size(),
+                  converted.radios[i].channelStats.size());
+        for (size_t k = 0; k < legacy_ml_stats.radios[i].channel_stats.size(); k++) {
+            auto& legacy_channel_st = legacy_ml_stats.radios[i].channel_stats[k];
+            EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20,
+                      converted.radios[i].channelStats[k].channel.width);
+            EXPECT_EQ(legacy_channel_st.channel.center_freq,
+                      converted.radios[i].channelStats[k].channel.centerFreq);
+            EXPECT_EQ(legacy_channel_st.channel.center_freq0,
+                      converted.radios[i].channelStats[k].channel.centerFreq0);
+            EXPECT_EQ(legacy_channel_st.channel.center_freq1,
+                      converted.radios[i].channelStats[k].channel.centerFreq1);
+            EXPECT_EQ(legacy_channel_st.cca_busy_time,
+                      (uint32_t)converted.radios[i].channelStats[k].ccaBusyTimeInMs);
+            EXPECT_EQ(legacy_channel_st.on_time,
+                      (uint32_t)converted.radios[i].channelStats[k].onTimeInMs);
+        }
+    }
+}
+
+TEST_F(AidlStructUtilTest, canConvertLegacyLinkLayerStatsToAidl) {
+    legacy_hal::LinkLayerStats legacy_stats{};
+    legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+    legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+    legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
+    legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
+    legacy_stats.iface.beacon_rx = rand();
+    // RSSI: 0 to -127
+    legacy_stats.iface.rssi_mgmt = rand() % 128;
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand();
+
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand();
+
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand();
+
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand();
+
+    legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand() % 101;
+    legacy_stats.iface.num_peers = 1;
+
+    for (auto& radio : legacy_stats.radios) {
+        // Max number of radios limit to 3.
+        radio.stats.radio = rand() % 4;
+        radio.stats.on_time = rand();
+        radio.stats.tx_time = rand();
+        radio.stats.rx_time = rand();
+        radio.stats.on_time_scan = rand();
+        radio.stats.on_time_nbd = rand();
+        radio.stats.on_time_gscan = rand();
+        radio.stats.on_time_roam_scan = rand();
+        radio.stats.on_time_pno_scan = rand();
+        radio.stats.on_time_hs20 = rand();
+        for (int i = 0; i < 4; i++) {
+            radio.tx_time_per_levels.push_back(rand());
+        }
+
+        legacy_hal::wifi_channel_stat channel_stat1 = {
+                .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
+                .on_time = 0x1111,
+                .cca_busy_time = 0x55,
+        };
+        legacy_hal::wifi_channel_stat channel_stat2 = {
+                .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
+                .on_time = 0x2222,
+                .cca_busy_time = 0x66,
+        };
+        radio.channel_stats.push_back(channel_stat1);
+        radio.channel_stats.push_back(channel_stat2);
+    }
+
+    for (auto& peer : legacy_stats.peers) {
+        // Max number of stations is limited to 32 for testing.
+        peer.peer_info.bssload.sta_count = rand() % 33;
+        peer.peer_info.bssload.chan_util = rand() % 101;
+        wifi_rate_stat rate_stat1 = {
+                .rate = {3, 1, 2, 5, 0, 0},
+                .tx_mpdu = 0,
+                .rx_mpdu = 1,
+                .mpdu_lost = 2,
+                .retries = 3,
+                .retries_short = 4,
+                .retries_long = 5,
+        };
+        wifi_rate_stat rate_stat2 = {
+                .rate = {2, 2, 1, 6, 0, 1},
+                .tx_mpdu = 6,
+                .rx_mpdu = 7,
+                .mpdu_lost = 8,
+                .retries = 9,
+                .retries_short = 10,
+                .retries_long = 11,
+        };
+        peer.rate_stats.push_back(rate_stat1);
+        peer.rate_stats.push_back(rate_stat2);
+    }
+
+    StaLinkLayerStats converted{};
+    aidl_struct_util::convertLegacyLinkLayerStatsToAidl(legacy_stats, &converted);
+    EXPECT_EQ(0, converted.iface.links[0].linkId);
+    EXPECT_EQ(legacy_stats.iface.beacon_rx, (uint32_t)converted.iface.links[0].beaconRx);
+    EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.links[0].avgRssiMgmt);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
+              converted.iface.links[0].wmeBePktStats.rxMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
+              converted.iface.links[0].wmeBePktStats.txMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
+              converted.iface.links[0].wmeBePktStats.lostMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries,
+              converted.iface.links[0].wmeBePktStats.retries);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min,
+              (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionTimeMinInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max,
+              (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionTimeMaxInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg,
+              (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionTimeAvgInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
+              (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionNumSamples);
+
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
+              converted.iface.links[0].wmeBkPktStats.rxMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
+              converted.iface.links[0].wmeBkPktStats.txMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
+              converted.iface.links[0].wmeBkPktStats.lostMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries,
+              converted.iface.links[0].wmeBkPktStats.retries);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min,
+              (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionTimeMinInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max,
+              (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionTimeMaxInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg,
+              (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionTimeAvgInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
+              (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionNumSamples);
+
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
+              converted.iface.links[0].wmeViPktStats.rxMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
+              converted.iface.links[0].wmeViPktStats.txMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
+              converted.iface.links[0].wmeViPktStats.lostMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries,
+              converted.iface.links[0].wmeViPktStats.retries);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min,
+              (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionTimeMinInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max,
+              (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionTimeMaxInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg,
+              (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionTimeAvgInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
+              (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionNumSamples);
+
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
+              converted.iface.links[0].wmeVoPktStats.rxMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
+              converted.iface.links[0].wmeVoPktStats.txMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
+              converted.iface.links[0].wmeVoPktStats.lostMpdu);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries,
+              converted.iface.links[0].wmeVoPktStats.retries);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min,
+              (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionTimeMinInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max,
+              (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionTimeMaxInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg,
+              (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionTimeAvgInUsec);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
+              (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionNumSamples);
+
+    EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent,
+              converted.iface.links[0].timeSliceDutyCycleInPercent);
+
+    EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size());
+    for (size_t i = 0; i < legacy_stats.radios.size(); i++) {
+        EXPECT_EQ(legacy_stats.radios[i].stats.radio, converted.radios[i].radioId);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time, (uint32_t)converted.radios[i].onTimeInMs);
+        EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, (uint32_t)converted.radios[i].txTimeInMs);
+        EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, (uint32_t)converted.radios[i].rxTimeInMs);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan,
+                  (uint32_t)converted.radios[i].onTimeInMsForScan);
+        EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(),
+                  converted.radios[i].txTimeInMsPerLevel.size());
+        for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); j++) {
+            EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j],
+                      (uint32_t)converted.radios[i].txTimeInMsPerLevel[j]);
+        }
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd,
+                  (uint32_t)converted.radios[i].onTimeInMsForNanScan);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan,
+                  (uint32_t)converted.radios[i].onTimeInMsForBgScan);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan,
+                  (uint32_t)converted.radios[i].onTimeInMsForRoamScan);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan,
+                  (uint32_t)converted.radios[i].onTimeInMsForPnoScan);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20,
+                  (uint32_t)converted.radios[i].onTimeInMsForHs20Scan);
+        EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(),
+                  converted.radios[i].channelStats.size());
+        for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); k++) {
+            auto& legacy_channel_st = legacy_stats.radios[i].channel_stats[k];
+            EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20,
+                      converted.radios[i].channelStats[k].channel.width);
+            EXPECT_EQ(legacy_channel_st.channel.center_freq,
+                      converted.radios[i].channelStats[k].channel.centerFreq);
+            EXPECT_EQ(legacy_channel_st.channel.center_freq0,
+                      converted.radios[i].channelStats[k].channel.centerFreq0);
+            EXPECT_EQ(legacy_channel_st.channel.center_freq1,
+                      converted.radios[i].channelStats[k].channel.centerFreq1);
+            EXPECT_EQ(legacy_channel_st.cca_busy_time,
+                      (uint32_t)converted.radios[i].channelStats[k].ccaBusyTimeInMs);
+            EXPECT_EQ(legacy_channel_st.on_time,
+                      (uint32_t)converted.radios[i].channelStats[k].onTimeInMs);
+        }
+    }
+
+    EXPECT_EQ(legacy_stats.peers.size(), converted.iface.links[0].peers.size());
+    for (size_t i = 0; i < legacy_stats.peers.size(); i++) {
+        EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.sta_count,
+                  converted.iface.links[0].peers[i].staCount);
+        EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.chan_util,
+                  converted.iface.links[0].peers[i].chanUtil);
+        for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) {
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble,
+                      (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.preamble);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.nss,
+                      (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.nss);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.bw,
+                      (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.bw);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx,
+                      (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.rateMcsIdx);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu,
+                      (uint32_t)converted.iface.links[0].peers[i].rateStats[j].txMpdu);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu,
+                      (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rxMpdu);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].mpdu_lost,
+                      (uint32_t)converted.iface.links[0].peers[i].rateStats[j].mpduLost);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].retries,
+                      (uint32_t)converted.iface.links[0].peers[i].rateStats[j].retries);
+        }
+    }
+}
+
+TEST_F(AidlStructUtilTest, CanConvertLegacyFeaturesToAidl) {
+    using AidlChipCaps = IWifiChip::FeatureSetMask;
+
+    uint32_t aidl_features;
+    uint32_t legacy_feature_set = WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE;
+
+    ASSERT_TRUE(
+            aidl_struct_util::convertLegacyChipFeaturesToAidl(legacy_feature_set, &aidl_features));
+
+    EXPECT_EQ((uint32_t)AidlChipCaps::D2D_RTT | (uint32_t)AidlChipCaps::SET_LATENCY_MODE,
+              aidl_features);
+}
+
+void insertRadioCombination(legacy_hal::wifi_radio_combination* dst_radio_combination_ptr,
+                            int num_radio_configurations,
+                            legacy_hal::wifi_radio_configuration* radio_configuration) {
+    dst_radio_combination_ptr->num_radio_configurations = num_radio_configurations;
+    memcpy(dst_radio_combination_ptr->radio_configurations, radio_configuration,
+           num_radio_configurations * sizeof(legacy_hal::wifi_radio_configuration));
+}
+
+void verifyRadioCombination(WifiRadioCombination* radioCombination, size_t num_radio_configurations,
+                            legacy_hal::wifi_radio_configuration* radio_configuration) {
+    EXPECT_EQ(num_radio_configurations, radioCombination->radioConfigurations.size());
+    for (size_t i = 0; i < num_radio_configurations; i++) {
+        EXPECT_EQ(aidl_struct_util::convertLegacyMacBandToAidlWifiBand(radio_configuration->band),
+                  radioCombination->radioConfigurations[i].bandInfo);
+        EXPECT_EQ(aidl_struct_util::convertLegacyAntennaConfigurationToAidl(
+                          radio_configuration->antenna_cfg),
+                  radioCombination->radioConfigurations[i].antennaMode);
+        radio_configuration++;
+    }
+}
+
+TEST_F(AidlStructUtilTest, canConvertLegacyRadioCombinationsMatrixToAidl) {
+    legacy_hal::wifi_radio_configuration radio_configurations_array1[] = {
+            {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
+    };
+    legacy_hal::wifi_radio_configuration radio_configurations_array2[] = {
+            {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
+            {.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_3X3},
+    };
+    legacy_hal::wifi_radio_configuration radio_configurations_array3[] = {
+            {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
+            {.band = legacy_hal::WLAN_MAC_6_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
+            {.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_4X4},
+    };
+
+    int num_radio_configs = 0;
+    int num_combinations = 0;
+    std::array<char, 256> buffer;
+    buffer.fill(0);
+    legacy_hal::wifi_radio_combination_matrix* legacy_matrix =
+            reinterpret_cast<wifi_radio_combination_matrix*>(buffer.data());
+    legacy_hal::wifi_radio_combination* radio_combinations;
+
+    // Prepare a legacy wifi_radio_combination_matrix
+    legacy_matrix->num_radio_combinations = 3;
+    // Insert first combination
+    radio_combinations =
+            (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations);
+    insertRadioCombination(
+            radio_combinations,
+            sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
+            radio_configurations_array1);
+    num_combinations++;
+    num_radio_configs +=
+            sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]);
+
+    // Insert second combination
+    radio_combinations =
+            (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
+                                                  (num_combinations *
+                                                   sizeof(legacy_hal::wifi_radio_combination)) +
+                                                  (num_radio_configs *
+                                                   sizeof(wifi_radio_configuration)));
+    insertRadioCombination(
+            radio_combinations,
+            sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
+            radio_configurations_array2);
+    num_combinations++;
+    num_radio_configs +=
+            sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]);
+
+    // Insert third combination
+    radio_combinations =
+            (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
+                                                  (num_combinations *
+                                                   sizeof(legacy_hal::wifi_radio_combination)) +
+                                                  (num_radio_configs *
+                                                   sizeof(wifi_radio_configuration)));
+    insertRadioCombination(
+            radio_combinations,
+            sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
+            radio_configurations_array3);
+
+    std::vector<WifiRadioCombination> converted_combinations;
+    aidl_struct_util::convertLegacyRadioCombinationsMatrixToAidl(legacy_matrix,
+                                                                 &converted_combinations);
+
+    // Verify the conversion
+    EXPECT_EQ(legacy_matrix->num_radio_combinations, converted_combinations.size());
+    verifyRadioCombination(
+            &converted_combinations[0],
+            sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
+            radio_configurations_array1);
+    verifyRadioCombination(
+            &converted_combinations[1],
+            sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
+            radio_configurations_array2);
+    verifyRadioCombination(
+            &converted_combinations[2],
+            sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
+            radio_configurations_array3);
+}
+
+void verifyRttResult(wifi_rtt_result* legacy_rtt_result_ptr, RttResult* aidl_results_ptr) {
+    EXPECT_EQ((int)legacy_rtt_result_ptr->burst_num, aidl_results_ptr->burstNum);
+    EXPECT_EQ((int)legacy_rtt_result_ptr->measurement_number, aidl_results_ptr->measurementNumber);
+    EXPECT_EQ((int)legacy_rtt_result_ptr->success_number, aidl_results_ptr->successNumber);
+    EXPECT_EQ(legacy_rtt_result_ptr->number_per_burst_peer, aidl_results_ptr->numberPerBurstPeer);
+    EXPECT_EQ(legacy_rtt_result_ptr->retry_after_duration, aidl_results_ptr->retryAfterDuration);
+    EXPECT_EQ(legacy_rtt_result_ptr->rssi, aidl_results_ptr->rssi);
+    EXPECT_EQ(legacy_rtt_result_ptr->rssi_spread, aidl_results_ptr->rssiSpread);
+    EXPECT_EQ(legacy_rtt_result_ptr->rtt, aidl_results_ptr->rtt);
+    EXPECT_EQ(legacy_rtt_result_ptr->rtt_sd, aidl_results_ptr->rttSd);
+    EXPECT_EQ(legacy_rtt_result_ptr->rtt_spread, aidl_results_ptr->rttSpread);
+    EXPECT_EQ(legacy_rtt_result_ptr->distance_mm, aidl_results_ptr->distanceInMm);
+    EXPECT_EQ(legacy_rtt_result_ptr->distance_sd_mm, aidl_results_ptr->distanceSdInMm);
+    EXPECT_EQ(legacy_rtt_result_ptr->distance_spread_mm, aidl_results_ptr->distanceSpreadInMm);
+    EXPECT_EQ(legacy_rtt_result_ptr->ts, aidl_results_ptr->timeStampInUs);
+    EXPECT_EQ(legacy_rtt_result_ptr->burst_duration, aidl_results_ptr->burstDurationInMs);
+    EXPECT_EQ(legacy_rtt_result_ptr->negotiated_burst_num, aidl_results_ptr->negotiatedBurstNum);
+    EXPECT_EQ(legacy_rtt_result_ptr->LCI->id, aidl_results_ptr->lci.id);
+    for (int i = 0; i < legacy_rtt_result_ptr->LCI->len; i++) {
+        EXPECT_EQ(legacy_rtt_result_ptr->LCI->data[i], aidl_results_ptr->lci.data[i]);
+    }
+    EXPECT_EQ(legacy_rtt_result_ptr->LCR->id, aidl_results_ptr->lcr.id);
+    for (int i = 0; i < legacy_rtt_result_ptr->LCR->len; i++) {
+        EXPECT_EQ(legacy_rtt_result_ptr->LCR->data[i], aidl_results_ptr->lcr.data[i]);
+    }
+}
+
+void fillLegacyRttResult(wifi_rtt_result* rtt_result_ptr) {
+    std::copy(std::begin(kMacAddress), std::end(kMacAddress), std::begin(rtt_result_ptr->addr));
+    rtt_result_ptr->burst_num = rand();
+    rtt_result_ptr->measurement_number = rand();
+    rtt_result_ptr->success_number = rand();
+    rtt_result_ptr->number_per_burst_peer = 0xF & rand();
+    rtt_result_ptr->status = RTT_STATUS_SUCCESS;
+    rtt_result_ptr->retry_after_duration = 0xF & rand();
+    rtt_result_ptr->type = RTT_TYPE_2_SIDED;
+    rtt_result_ptr->rssi = rand();
+    rtt_result_ptr->rssi_spread = rand();
+    rtt_result_ptr->rtt = rand();
+    rtt_result_ptr->rtt_sd = rand();
+    rtt_result_ptr->rtt_spread = rand();
+    rtt_result_ptr->distance_mm = rand();
+    rtt_result_ptr->distance_sd_mm = rand();
+    rtt_result_ptr->distance_spread_mm = rand();
+    rtt_result_ptr->burst_duration = rand();
+    rtt_result_ptr->negotiated_burst_num = rand();
+    rtt_result_ptr->LCI = (wifi_information_element*)LCI;
+    rtt_result_ptr->LCR = (wifi_information_element*)LCR;
+}
+
+TEST_F(AidlStructUtilTest, convertLegacyVectorOfRttResultToAidl) {
+    std::vector<const wifi_rtt_result*> rtt_results_vec;
+    wifi_rtt_result rttResults[2];
+
+    // fill legacy rtt results
+    for (int i = 0; i < 2; i++) {
+        fillLegacyRttResult(&rttResults[i]);
+        rtt_results_vec.push_back(&rttResults[i]);
+    }
+
+    std::vector<RttResult> aidl_results;
+    aidl_struct_util::convertLegacyVectorOfRttResultToAidl(rtt_results_vec, &aidl_results);
+
+    EXPECT_EQ(rtt_results_vec.size(), aidl_results.size());
+    for (size_t i = 0; i < rtt_results_vec.size(); i++) {
+        verifyRttResult(&rttResults[i], &aidl_results[i]);
+        EXPECT_EQ(aidl_results[i].channelFreqMHz, 0);
+        EXPECT_EQ(aidl_results[i].packetBw, RttBw::BW_UNSPECIFIED);
+    }
+}
+
+TEST_F(AidlStructUtilTest, convertLegacyVectorOfRttResultV2ToAidl) {
+    std::vector<const wifi_rtt_result_v2*> rtt_results_vec_v2;
+    wifi_rtt_result_v2 rttResults_v2[2];
+
+    // fill legacy rtt results v2
+    for (int i = 0; i < 2; i++) {
+        fillLegacyRttResult(&rttResults_v2[i].rtt_result);
+        rttResults_v2[i].frequency = 2412 + i * 5;
+        rttResults_v2[i].packet_bw = WIFI_RTT_BW_80;
+        rtt_results_vec_v2.push_back(&rttResults_v2[i]);
+    }
+
+    std::vector<RttResult> aidl_results;
+    aidl_struct_util::convertLegacyVectorOfRttResultV2ToAidl(rtt_results_vec_v2, &aidl_results);
+
+    EXPECT_EQ(rtt_results_vec_v2.size(), aidl_results.size());
+    for (size_t i = 0; i < rtt_results_vec_v2.size(); i++) {
+        verifyRttResult(&rttResults_v2[i].rtt_result, &aidl_results[i]);
+        EXPECT_EQ(aidl_results[i].channelFreqMHz, rttResults_v2[i].frequency);
+        EXPECT_EQ(aidl_results[i].packetBw, RttBw::BW_80MHZ);
+    }
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/tests/main.cpp b/wifi/aidl/default/tests/main.cpp
new file mode 100644
index 0000000..767422c
--- /dev/null
+++ b/wifi/aidl/default/tests/main.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ::testing::InitGoogleMock(&argc, argv);
+    // Force ourselves to always log to stderr
+    android::base::InitLogging(argv, android::base::StderrLogger);
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/default/tests/mock_interface_tool.cpp b/wifi/aidl/default/tests/mock_interface_tool.cpp
new file mode 100644
index 0000000..79f3d1e
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_interface_tool.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "mock_interface_tool.h"
+
+namespace android {
+namespace wifi_system {
+
+MockInterfaceTool::MockInterfaceTool() {}
+
+}  // namespace wifi_system
+}  // namespace android
diff --git a/wifi/aidl/default/tests/mock_interface_tool.h b/wifi/aidl/default/tests/mock_interface_tool.h
new file mode 100644
index 0000000..9795de8
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_interface_tool.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_INTERFACE_TOOL_H
+#define MOCK_INTERFACE_TOOL_H
+
+#include <gmock/gmock.h>
+#include <wifi_system/interface_tool.h>
+
+namespace android {
+namespace wifi_system {
+
+class MockInterfaceTool : public InterfaceTool {
+  public:
+    MockInterfaceTool();
+
+    MOCK_METHOD1(GetUpState, bool(const char* if_name));
+    MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up));
+    MOCK_METHOD1(SetWifiUpState, bool(bool request_up));
+    MOCK_METHOD2(SetMacAddress,
+                 bool(const char* if_name, const std::array<uint8_t, ETH_ALEN>& address));
+    MOCK_METHOD1(GetFactoryMacAddress, std::array<uint8_t, ETH_ALEN>(const char* if_name));
+
+};  // class MockInterfaceTool
+
+}  // namespace wifi_system
+}  // namespace android
+
+#endif  // MOCK_INTERFACE_TOOL_H
diff --git a/wifi/aidl/default/tests/mock_wifi_feature_flags.cpp b/wifi/aidl/default/tests/mock_wifi_feature_flags.cpp
new file mode 100644
index 0000000..0c4e59d
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_feature_flags.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+
+#include "mock_wifi_feature_flags.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace feature_flags {
+
+MockWifiFeatureFlags::MockWifiFeatureFlags() {}
+
+}  // namespace feature_flags
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/tests/mock_wifi_feature_flags.h b/wifi/aidl/default/tests/mock_wifi_feature_flags.h
new file mode 100644
index 0000000..9143d15
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_feature_flags.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_WIFI_FEATURE_FLAGS_H_
+#define MOCK_WIFI_FEATURE_FLAGS_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_feature_flags.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace feature_flags {
+
+class MockWifiFeatureFlags : public WifiFeatureFlags {
+  public:
+    MockWifiFeatureFlags();
+
+    MOCK_METHOD1(getChipModes, std::vector<IWifiChip::ChipMode>(bool is_primary));
+    MOCK_METHOD0(isApMacRandomizationDisabled, bool());
+};
+
+}  // namespace feature_flags
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // MOCK_WIFI_FEATURE_FLAGS_H_
diff --git a/wifi/aidl/default/tests/mock_wifi_iface_util.cpp b/wifi/aidl/default/tests/mock_wifi_iface_util.cpp
new file mode 100644
index 0000000..0f787f2
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_iface_util.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "mock_wifi_iface_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+MockWifiIfaceUtil::MockWifiIfaceUtil(
+        const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+        const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+    : WifiIfaceUtil(iface_tool, legacy_hal) {}
+
+}  // namespace iface_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/tests/mock_wifi_iface_util.h b/wifi/aidl/default/tests/mock_wifi_iface_util.h
new file mode 100644
index 0000000..49a8636
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_iface_util.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_WIFI_IFACE_UTIL_H_
+#define MOCK_WIFI_IFACE_UTIL_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_iface_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+class MockWifiIfaceUtil : public iface_util::WifiIfaceUtil {
+  public:
+    MockWifiIfaceUtil(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+                      const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+    MOCK_METHOD1(getFactoryMacAddress, std::array<uint8_t, 6>(const std::string&));
+    MOCK_METHOD2(setMacAddress, bool(const std::string&, const std::array<uint8_t, 6>&));
+    MOCK_METHOD0(getOrCreateRandomMacAddress, std::array<uint8_t, 6>());
+    MOCK_METHOD2(registerIfaceEventHandlers,
+                 void(const std::string&, iface_util::IfaceEventHandlers));
+    MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&));
+    MOCK_METHOD2(setUpState, bool(const std::string&, bool));
+    MOCK_METHOD1(ifNameToIndex, unsigned(const std::string&));
+};
+
+}  // namespace iface_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // MOCK_WIFI_IFACE_UTIL_H_
diff --git a/wifi/aidl/default/tests/mock_wifi_legacy_hal.cpp b/wifi/aidl/default/tests/mock_wifi_legacy_hal.cpp
new file mode 100644
index 0000000..33b2b1c
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_legacy_hal.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "mock_wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+MockWifiLegacyHal::MockWifiLegacyHal(
+        const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+        const wifi_hal_fn& fn, bool is_primary)
+    : WifiLegacyHal(iface_tool, fn, is_primary) {}
+}  // namespace legacy_hal
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/tests/mock_wifi_legacy_hal.h b/wifi/aidl/default/tests/mock_wifi_legacy_hal.h
new file mode 100644
index 0000000..28129a9
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_legacy_hal.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_WIFI_LEGACY_HAL_H_
+#define MOCK_WIFI_LEGACY_HAL_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+class MockWifiLegacyHal : public WifiLegacyHal {
+  public:
+    MockWifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+                      const wifi_hal_fn& fn, bool is_primary);
+    MOCK_METHOD0(initialize, wifi_error());
+    MOCK_METHOD0(start, wifi_error());
+    MOCK_METHOD2(stop,
+                 wifi_error(std::unique_lock<std::recursive_mutex>*, const std::function<void()>&));
+    MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool));
+    MOCK_METHOD2(registerRadioModeChangeCallbackHandler,
+                 wifi_error(const std::string&, const on_radio_mode_change_callback&));
+    MOCK_METHOD1(getFirmwareVersion,
+                 std::pair<wifi_error, std::string>(const std::string& iface_name));
+    MOCK_METHOD1(getDriverVersion,
+                 std::pair<wifi_error, std::string>(const std::string& iface_name));
+
+    MOCK_METHOD2(selectTxPowerScenario,
+                 wifi_error(const std::string& iface_name, wifi_power_scenario scenario));
+    MOCK_METHOD1(resetTxPowerScenario, wifi_error(const std::string& iface_name));
+    MOCK_METHOD2(nanRegisterCallbackHandlers,
+                 wifi_error(const std::string&, const NanCallbackHandlers&));
+    MOCK_METHOD2(nanDisableRequest, wifi_error(const std::string&, transaction_id));
+    MOCK_METHOD3(nanDataInterfaceDelete,
+                 wifi_error(const std::string&, transaction_id, const std::string&));
+    MOCK_METHOD2(createVirtualInterface,
+                 wifi_error(const std::string& ifname, wifi_interface_type iftype));
+    MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
+    MOCK_METHOD0(waitForDriverReady, wifi_error());
+    MOCK_METHOD2(getSupportedIfaceName, wifi_error(uint32_t, std::string&));
+    MOCK_METHOD1(registerSubsystemRestartCallbackHandler,
+                 wifi_error(const on_subsystem_restart_callback&));
+    MOCK_METHOD1(getSupportedFeatureSet, std::pair<wifi_error, uint64_t>(const std::string&));
+};
+}  // namespace legacy_hal
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // MOCK_WIFI_LEGACY_HAL_H_
diff --git a/wifi/aidl/default/tests/mock_wifi_mode_controller.cpp b/wifi/aidl/default/tests/mock_wifi_mode_controller.cpp
new file mode 100644
index 0000000..f4cc4c4
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_mode_controller.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "mock_wifi_mode_controller.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace mode_controller {
+
+MockWifiModeController::MockWifiModeController() : WifiModeController() {}
+
+}  // namespace mode_controller
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/tests/mock_wifi_mode_controller.h b/wifi/aidl/default/tests/mock_wifi_mode_controller.h
new file mode 100644
index 0000000..f77f7d0
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_mode_controller.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_WIFI_MODE_CONTROLLER_H_
+#define MOCK_WIFI_MODE_CONTROLLER_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_mode_controller.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace mode_controller {
+
+class MockWifiModeController : public WifiModeController {
+  public:
+    MockWifiModeController();
+    MOCK_METHOD0(initialize, bool());
+    MOCK_METHOD1(changeFirmwareMode, bool(IfaceType));
+    MOCK_METHOD1(isFirmwareModeChangeNeeded, bool(IfaceType));
+    MOCK_METHOD0(deinitialize, bool());
+};
+}  // namespace mode_controller
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // MOCK_WIFI_MODE_CONTROLLER_H_
diff --git a/wifi/aidl/default/tests/ringbuffer_unit_tests.cpp b/wifi/aidl/default/tests/ringbuffer_unit_tests.cpp
new file mode 100644
index 0000000..c257100
--- /dev/null
+++ b/wifi/aidl/default/tests/ringbuffer_unit_tests.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+
+#include "ringbuffer.h"
+
+using testing::Return;
+using testing::Test;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+class RingbufferTest : public Test {
+  public:
+    const uint32_t maxBufferSize_ = 10;
+    Ringbuffer buffer_{maxBufferSize_};
+};
+
+TEST_F(RingbufferTest, CreateEmptyBuffer) {
+    ASSERT_TRUE(buffer_.getData().empty());
+}
+
+TEST_F(RingbufferTest, CanUseFullBufferCapacity) {
+    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
+    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
+    buffer_.append(input);
+    buffer_.append(input2);
+    ASSERT_EQ(2u, buffer_.getData().size());
+    EXPECT_EQ(input, buffer_.getData().front());
+    EXPECT_EQ(input2, buffer_.getData().back());
+}
+
+TEST_F(RingbufferTest, OldDataIsRemovedOnOverflow) {
+    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
+    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
+    const std::vector<uint8_t> input3 = {'G'};
+    buffer_.append(input);
+    buffer_.append(input2);
+    buffer_.append(input3);
+    ASSERT_EQ(2u, buffer_.getData().size());
+    EXPECT_EQ(input2, buffer_.getData().front());
+    EXPECT_EQ(input3, buffer_.getData().back());
+}
+
+TEST_F(RingbufferTest, MultipleOldDataIsRemovedOnOverflow) {
+    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
+    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
+    const std::vector<uint8_t> input3(maxBufferSize_, '2');
+    buffer_.append(input);
+    buffer_.append(input2);
+    buffer_.append(input3);
+    ASSERT_EQ(1u, buffer_.getData().size());
+    EXPECT_EQ(input3, buffer_.getData().front());
+}
+
+TEST_F(RingbufferTest, AppendingEmptyBufferDoesNotAddGarbage) {
+    const std::vector<uint8_t> input = {};
+    buffer_.append(input);
+    ASSERT_TRUE(buffer_.getData().empty());
+}
+
+TEST_F(RingbufferTest, OversizedAppendIsDropped) {
+    const std::vector<uint8_t> input(maxBufferSize_ + 1, '0');
+    buffer_.append(input);
+    ASSERT_TRUE(buffer_.getData().empty());
+}
+
+TEST_F(RingbufferTest, OversizedAppendDoesNotDropExistingData) {
+    const std::vector<uint8_t> input(maxBufferSize_, '0');
+    const std::vector<uint8_t> input2(maxBufferSize_ + 1, '1');
+    buffer_.append(input);
+    buffer_.append(input2);
+    ASSERT_EQ(1u, buffer_.getData().size());
+    EXPECT_EQ(input, buffer_.getData().front());
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/tests/runtests.sh b/wifi/aidl/default/tests/runtests.sh
new file mode 100755
index 0000000..228c82b
--- /dev/null
+++ b/wifi/aidl/default/tests/runtests.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+# Copyright(C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0(the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http:// www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [ -z $ANDROID_BUILD_TOP ]; then
+  echo "You need to source and lunch before you can use this script"
+  exit 1
+fi
+set -e
+
+adb root
+adb wait-for-device
+$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode android.hardware.wifi-service-tests
+adb sync data
+adb shell /data/nativetest64/vendor/android.hardware.wifi-service-tests/android.hardware.wifi-service-tests
diff --git a/wifi/aidl/default/tests/wifi_chip_unit_tests.cpp b/wifi/aidl/default/tests/wifi_chip_unit_tests.cpp
new file mode 100644
index 0000000..f9afb4b
--- /dev/null
+++ b/wifi/aidl/default/tests/wifi_chip_unit_tests.cpp
@@ -0,0 +1,855 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <cutils/properties.h>
+#include <gmock/gmock.h>
+
+#include "wifi_chip.h"
+
+#include "mock_interface_tool.h"
+#include "mock_wifi_feature_flags.h"
+#include "mock_wifi_iface_util.h"
+#include "mock_wifi_legacy_hal.h"
+#include "mock_wifi_mode_controller.h"
+
+using testing::NiceMock;
+using testing::Return;
+using testing::Test;
+
+namespace {
+constexpr int kFakeChipId = 5;
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+class WifiChipTest : public Test {
+  protected:
+    void setupV1IfaceCombination() {
+        // clang-format off
+		// 1 STA + 1 P2P
+        const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsSta =
+		{
+        	{
+				{
+					{{IfaceConcurrencyType::STA}, 1},
+					{{IfaceConcurrencyType::P2P}, 1}
+				}
+			}
+		};
+		// 1 AP
+        const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsAp =
+		{
+            {
+				{
+					{{IfaceConcurrencyType::AP}, 1}
+				}
+			}
+        };
+        const std::vector<IWifiChip::ChipMode> modes = {
+            {feature_flags::chip_mode_ids::kV1Sta, combinationsSta},
+            {feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
+        };
+        // clang-format on
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+    }
+
+    void setupV1_AwareIfaceCombination() {
+        // clang-format off
+		// 1 STA + 1 of (P2P or NAN)
+        const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsSta =
+		{
+            {
+				{
+					{{IfaceConcurrencyType::STA}, 1},
+              		{{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
+				}
+			}
+        };
+		// 1 AP
+        const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsAp =
+		{
+            {
+				{
+					{{IfaceConcurrencyType::AP}, 1}
+				}
+			}
+        };
+        const std::vector<IWifiChip::ChipMode> modes = {
+            {feature_flags::chip_mode_ids::kV1Sta, combinationsSta},
+            {feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
+        };
+        // clang-format on
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+    }
+
+    void setupV1_AwareDisabledApIfaceCombination() {
+        // clang-format off
+		// 1 STA + 1 of (P2P or NAN)
+        const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsSta =
+		{
+            {
+				{
+					{{IfaceConcurrencyType::STA}, 1},
+              		{{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
+				}
+			}
+        };
+        const std::vector<IWifiChip::ChipMode> modes = {
+            {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}
+        };
+        // clang-format on
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+    }
+
+    void setupV2_AwareIfaceCombination() {
+        // clang-format off
+		// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+        const std::vector<IWifiChip::ChipConcurrencyCombination> combinations =
+		{
+            {
+				{
+					{{IfaceConcurrencyType::STA}, 1},
+					{{IfaceConcurrencyType::AP}, 1}
+				}
+			},
+            {
+				{
+					{{IfaceConcurrencyType::STA}, 1},
+              		{{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
+				}
+			}
+        };
+        const std::vector<IWifiChip::ChipMode> modes = {
+            {feature_flags::chip_mode_ids::kV3, combinations}
+        };
+        // clang-format on
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+    }
+
+    void setupV2_AwareDisabledApIfaceCombination() {
+        // clang-format off
+		// 1 STA + 1 of (P2P or NAN)
+        const std::vector<IWifiChip::ChipConcurrencyCombination> combinations =
+		{
+            {
+				{
+					{{IfaceConcurrencyType::STA}, 1},
+              		{{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
+				}
+			}
+        };
+        const std::vector<IWifiChip::ChipMode> modes = {
+            {feature_flags::chip_mode_ids::kV3, combinations}
+        };
+        // clang-format on
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+    }
+
+    void setup_MultiIfaceCombination() {
+        // clang-format off
+		// 3 STA + 1 AP
+        const std::vector<IWifiChip::ChipConcurrencyCombination> combinations =
+		{
+            {
+				{
+					{{IfaceConcurrencyType::STA}, 3},
+					{{IfaceConcurrencyType::AP}, 1}
+				}
+			}
+        };
+        const std::vector<IWifiChip::ChipMode> modes = {
+            {feature_flags::chip_mode_ids::kV3, combinations}
+        };
+        // clang-format on
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+    }
+
+    void assertNumberOfModes(uint32_t num_modes) {
+        std::vector<IWifiChip::ChipMode> modes;
+        ASSERT_TRUE(chip_->getAvailableModes(&modes).isOk());
+        // V2_Aware has 1 mode of operation.
+        ASSERT_EQ(num_modes, modes.size());
+    }
+
+    void findModeAndConfigureForIfaceType(const IfaceConcurrencyType& type) {
+        // This should be aligned with kInvalidModeId in wifi_chip.cpp
+        int32_t mode_id = INT32_MAX;
+        std::vector<IWifiChip::ChipMode> modes;
+        ASSERT_TRUE(chip_->getAvailableModes(&modes).isOk());
+
+        for (const auto& mode : modes) {
+            for (const auto& combination : mode.availableCombinations) {
+                for (const auto& limit : combination.limits) {
+                    if (limit.types.end() !=
+                        std::find(limit.types.begin(), limit.types.end(), type)) {
+                        mode_id = mode.id;
+                    }
+                }
+            }
+        }
+
+        ASSERT_NE(INT32_MAX, mode_id);
+        ASSERT_TRUE(chip_->configureChip(mode_id).isOk());
+    }
+
+    // Returns an empty string on error.
+    std::string createIface(const IfaceType& type) {
+        std::string iface_name;
+        if (type == IfaceType::AP) {
+            std::shared_ptr<IWifiApIface> iface;
+            if (!chip_->createApIface(&iface).isOk()) {
+                return "";
+            }
+            EXPECT_NE(iface.get(), nullptr);
+            EXPECT_TRUE(iface->getName(&iface_name).isOk());
+        } else if (type == IfaceType::NAN_IFACE) {
+            std::shared_ptr<IWifiNanIface> iface;
+            if (!chip_->createNanIface(&iface).isOk()) {
+                return "";
+            }
+            EXPECT_NE(iface.get(), nullptr);
+            EXPECT_TRUE(iface->getName(&iface_name).isOk());
+        } else if (type == IfaceType::P2P) {
+            std::shared_ptr<IWifiP2pIface> iface;
+            if (!chip_->createP2pIface(&iface).isOk()) {
+                return "";
+            }
+            EXPECT_NE(iface.get(), nullptr);
+            EXPECT_TRUE(iface->getName(&iface_name).isOk());
+        } else if (type == IfaceType::STA) {
+            std::shared_ptr<IWifiStaIface> iface;
+            if (!chip_->createStaIface(&iface).isOk()) {
+                return "";
+            }
+            EXPECT_NE(iface.get(), nullptr);
+            EXPECT_TRUE(iface->getName(&iface_name).isOk());
+        }
+        return iface_name;
+    }
+
+    void removeIface(const IfaceType& type, const std::string& iface_name) {
+        if (type == IfaceType::AP) {
+            ASSERT_TRUE(chip_->removeApIface(iface_name).isOk());
+        } else if (type == IfaceType::NAN_IFACE) {
+            ASSERT_TRUE(chip_->removeNanIface(iface_name).isOk());
+        } else if (type == IfaceType::P2P) {
+            ASSERT_TRUE(chip_->removeP2pIface(iface_name).isOk());
+        } else if (type == IfaceType::STA) {
+            ASSERT_TRUE(chip_->removeStaIface(iface_name).isOk());
+        }
+    }
+
+    bool createRttController() {
+        std::shared_ptr<IWifiRttController> rtt_controller;
+        auto status = chip_->createRttController(nullptr, &rtt_controller);
+        return status.isOk();
+    }
+
+    static void subsystemRestartHandler(const std::string& /*error*/) {}
+
+    std::shared_ptr<WifiChip> chip_;
+    int chip_id_ = kFakeChipId;
+    legacy_hal::wifi_hal_fn fake_func_table_;
+    std::shared_ptr<NiceMock<::android::wifi_system::MockInterfaceTool>> iface_tool_{
+            new NiceMock<::android::wifi_system::MockInterfaceTool>};
+    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+            new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
+    std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>> mode_controller_{
+            new NiceMock<mode_controller::MockWifiModeController>};
+    std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
+            new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
+    std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>> feature_flags_{
+            new NiceMock<feature_flags::MockWifiFeatureFlags>};
+
+  public:
+    void SetUp() override {
+        chip_ = WifiChip::create(chip_id_, true, legacy_hal_, mode_controller_, iface_util_,
+                                 feature_flags_, subsystemRestartHandler, true);
+
+        EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_))
+                .WillRepeatedly(testing::Return(true));
+        EXPECT_CALL(*legacy_hal_, start())
+                .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS));
+        // Vendor HAL does not override the name by default.
+        EXPECT_CALL(*legacy_hal_, getSupportedIfaceName(testing::_, testing::_))
+                .WillRepeatedly(testing::Return(legacy_hal::WIFI_ERROR_UNKNOWN));
+    }
+
+    void TearDown() override {
+        // Restore default system iface names (This should ideally be using a
+        // mock).
+        property_set("wifi.interface", "wlan0");
+        property_set("wifi.concurrent.interface", "wlan1");
+        property_set("wifi.aware.interface", nullptr);
+    }
+};
+
+////////// V1 Iface Combinations ////////////
+// Mode 1 - STA + P2P
+// Mode 2 - AP
+class WifiChipV1IfaceCombinationTest : public WifiChipTest {
+  public:
+    void SetUp() override {
+        setupV1IfaceCombination();
+        WifiChipTest::SetUp();
+        // V1 has 2 modes of operation.
+        assertNumberOfModes(2);
+    }
+};
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateNan_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+////////// V1 + Aware Iface Combinations ////////////
+// Mode 1 - STA + P2P/NAN
+// Mode 2 - AP
+class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest {
+  public:
+    void SetUp() override {
+        setupV1_AwareIfaceCombination();
+        WifiChipTest::SetUp();
+        // V1_Aware has 2 modes of operation.
+        assertNumberOfModes(2u);
+    }
+};
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateNan_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2PNan_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+    ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    std::string p2p_iface_name = createIface(IfaceType::P2P);
+    ASSERT_FALSE(p2p_iface_name.empty());
+    ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+
+    // After removing P2P iface, NAN iface creation should succeed.
+    removeIface(IfaceType::P2P, p2p_iface_name);
+    ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    std::string nan_iface_name = createIface(IfaceType::NAN_IFACE);
+    ASSERT_FALSE(nan_iface_name.empty());
+    ASSERT_TRUE(createIface(IfaceType::P2P).empty());
+
+    // After removing NAN iface, P2P iface creation should succeed.
+    removeIface(IfaceType::NAN_IFACE, nan_iface_name);
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowApToSta) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    std::string ap_iface_name = createIface(IfaceType::AP);
+    ASSERT_FALSE(ap_iface_name.empty());
+    ASSERT_FALSE(createRttController());
+
+    removeIface(IfaceType::AP, ap_iface_name);
+
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+    ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
+    EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+    ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
+}
+
+////////// V2 + Aware Iface Combinations ////////////
+// Mode 1 - STA + STA/AP
+//        - STA + P2P/NAN
+class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest {
+  public:
+    void SetUp() override {
+        setupV2_AwareIfaceCombination();
+        WifiChipTest::SetUp();
+        // V2_Aware has 1 mode of operation.
+        assertNumberOfModes(1u);
+    }
+};
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateP2p_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNan_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateAp_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApSta_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_AfterStaApRemove_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    std::string sta_iface_name = createIface(IfaceType::STA);
+    ASSERT_FALSE(sta_iface_name.empty());
+    std::string ap_iface_name = createIface(IfaceType::AP);
+    ASSERT_FALSE(ap_iface_name.empty());
+
+    ASSERT_TRUE(createIface(IfaceType::STA).empty());
+
+    // After removing AP & STA iface, STA iface creation should succeed.
+    removeIface(IfaceType::STA, sta_iface_name);
+    removeIface(IfaceType::AP, ap_iface_name);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2PNan_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+    ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_AfterP2pRemove_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    std::string p2p_iface_name = createIface(IfaceType::P2P);
+    ASSERT_FALSE(p2p_iface_name.empty());
+    ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+
+    // After removing P2P iface, NAN iface creation should succeed.
+    removeIface(IfaceType::P2P, p2p_iface_name);
+    ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_AfterNanRemove_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    std::string nan_iface_name = createIface(IfaceType::NAN_IFACE);
+    ASSERT_FALSE(nan_iface_name.empty());
+    ASSERT_TRUE(createIface(IfaceType::P2P).empty());
+
+    // After removing NAN iface, P2P iface creation should succeed.
+    removeIface(IfaceType::NAN_IFACE, nan_iface_name);
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApNan_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_FALSE(createIface(IfaceType::AP).empty());
+    ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApP2p_ShouldFail) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_FALSE(createIface(IfaceType::AP).empty());
+    ASSERT_TRUE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    std::string p2p_iface_name = createIface(IfaceType::P2P);
+    ASSERT_FALSE(p2p_iface_name.empty());
+    ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+
+    // After removing P2P iface, NAN iface creation should succeed.
+    removeIface(IfaceType::P2P, p2p_iface_name);
+    ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    std::string nan_iface_name = createIface(IfaceType::NAN_IFACE);
+    ASSERT_FALSE(nan_iface_name.empty());
+    ASSERT_TRUE(createIface(IfaceType::P2P).empty());
+
+    // After removing NAN iface, P2P iface creation should succeed.
+    removeIface(IfaceType::NAN_IFACE, nan_iface_name);
+    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_EnsureDifferentIfaceNames) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    std::string sta_iface_name = createIface(IfaceType::STA);
+    std::string ap_iface_name = createIface(IfaceType::AP);
+    ASSERT_FALSE(sta_iface_name.empty());
+    ASSERT_FALSE(ap_iface_name.empty());
+    ASSERT_NE(sta_iface_name, ap_iface_name);
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlow) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::AP).empty());
+    ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+    ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+    ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+    EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_))
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+    ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveNanOnStaRemove) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+
+    // Create NAN iface
+    ASSERT_EQ(createIface(IfaceType::NAN_IFACE), "wlan0");
+
+    // We should have 1 nan iface.
+    std::vector<std::string> iface_names;
+    ASSERT_TRUE(chip_->getNanIfaceNames(&iface_names).isOk());
+    ASSERT_EQ(iface_names.size(), 1u);
+    ASSERT_EQ(iface_names[0], "wlan0");
+
+    // Retrieve the nan iface object.
+    std::shared_ptr<IWifiNanIface> nan_iface;
+    ASSERT_TRUE(chip_->getNanIface("wlan0", &nan_iface).isOk());
+    ASSERT_NE(nan_iface.get(), nullptr);
+
+    // Remove the STA iface. We should have 0 nan ifaces now.
+    removeIface(IfaceType::STA, "wlan0");
+    ASSERT_TRUE(chip_->getNanIfaceNames(&iface_names).isOk());
+    ASSERT_EQ(iface_names.size(), 0u);
+
+    // Any operation on the nan iface object should now return an error.
+    std::string name;
+    auto status = nan_iface->getName(&name);
+    ASSERT_EQ(status.getServiceSpecificError(),
+              static_cast<int32_t>(WifiStatusCode::ERROR_WIFI_IFACE_INVALID));
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveRttControllerOnStaRemove) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+
+    // Create RTT controller
+    std::shared_ptr<IWifiRttController> rtt_controller;
+    ASSERT_TRUE(chip_->createRttController(nullptr, &rtt_controller).isOk());
+
+    // Remove the STA iface.
+    removeIface(IfaceType::STA, "wlan0");
+
+    // Any operation on the rtt controller object should now return an error.
+    std::shared_ptr<IWifiStaIface> bound_iface;
+    auto status = rtt_controller->getBoundIface(&bound_iface);
+    ASSERT_EQ(status.getServiceSpecificError(),
+              static_cast<int32_t>(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID));
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) {
+    property_set("wifi.aware.interface", nullptr);
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    ASSERT_EQ(createIface(IfaceType::NAN_IFACE), "wlan0");
+    removeIface(IfaceType::NAN_IFACE, "wlan0");
+    EXPECT_CALL(*iface_util_, setUpState(testing::_, testing::_)).Times(0);
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithDedicatedNanIface) {
+    property_set("wifi.aware.interface", "aware0");
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    EXPECT_CALL(*iface_util_, ifNameToIndex("aware0")).WillOnce(testing::Return(4));
+    EXPECT_CALL(*iface_util_, setUpState("aware0", true)).WillOnce(testing::Return(true));
+    ASSERT_EQ(createIface(IfaceType::NAN_IFACE), "aware0");
+
+    EXPECT_CALL(*iface_util_, setUpState("aware0", false)).WillOnce(testing::Return(true));
+    removeIface(IfaceType::NAN_IFACE, "aware0");
+}
+
+////////// V1 Iface Combinations when AP creation is disabled //////////
+class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
+  public:
+    void SetUp() override {
+        setupV1_AwareDisabledApIfaceCombination();
+        WifiChipTest::SetUp();
+    }
+};
+
+TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
+////////// V2 Iface Combinations when AP creation is disabled //////////
+class WifiChipV2_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
+  public:
+    void SetUp() override {
+        setupV2_AwareDisabledApIfaceCombination();
+        WifiChipTest::SetUp();
+    }
+};
+
+TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, CreateSta_ShouldSucceed) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
+////////// Hypothetical Iface Combination with multiple ifaces //////////
+class WifiChip_MultiIfaceTest : public WifiChipTest {
+  public:
+    void SetUp() override {
+        setup_MultiIfaceCombination();
+        WifiChipTest::SetUp();
+    }
+};
+
+TEST_F(WifiChip_MultiIfaceTest, Create3Sta) {
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_FALSE(createIface(IfaceType::STA).empty());
+    ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateStaWithDefaultNames) {
+    property_set("wifi.interface.0", "");
+    property_set("wifi.interface.1", "");
+    property_set("wifi.interface.2", "");
+    property_set("wifi.interface", "");
+    property_set("wifi.concurrent.interface", "");
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomNames) {
+    property_set("wifi.interface.0", "test0");
+    property_set("wifi.interface.1", "test1");
+    property_set("wifi.interface.2", "test2");
+    property_set("wifi.interface", "bad0");
+    property_set("wifi.concurrent.interface", "bad1");
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "bad0");
+    ASSERT_EQ(createIface(IfaceType::STA), "bad1");
+    ASSERT_EQ(createIface(IfaceType::STA), "test2");
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomAltNames) {
+    property_set("wifi.interface.0", "");
+    property_set("wifi.interface.1", "");
+    property_set("wifi.interface.2", "");
+    property_set("wifi.interface", "testA0");
+    property_set("wifi.concurrent.interface", "testA1");
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    ASSERT_EQ(createIface(IfaceType::STA), "testA0");
+    ASSERT_EQ(createIface(IfaceType::STA), "testA1");
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) {
+    // WifiChip_MultiIfaceTest iface combo: STAx3 + APx1
+    // When the HAL support dual STAs, AP should start with idx 2.
+    findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+    // First AP will be slotted to wlan1.
+    ASSERT_EQ(createIface(IfaceType::AP), "wlan2");
+    // First STA will be slotted to wlan0.
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+    // All further STA will be slotted to the remaining free indices.
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
+    ASSERT_EQ(createIface(IfaceType::STA), "wlan3");
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/aidl/default/tests/wifi_iface_util_unit_tests.cpp
new file mode 100644
index 0000000..e0db6fd
--- /dev/null
+++ b/wifi/aidl/default/tests/wifi_iface_util_unit_tests.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "wifi_iface_util.h"
+
+#include "mock_interface_tool.h"
+#include "mock_wifi_legacy_hal.h"
+
+using testing::NiceMock;
+using testing::Test;
+
+namespace {
+constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02;
+constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc};
+constexpr char kIfaceName[] = "test-wlan0";
+
+bool isValidUnicastLocallyAssignedMacAddress(const std::array<uint8_t, 6>& mac_address) {
+    uint8_t first_byte = mac_address[0];
+    return (first_byte & 0x3) == kValidUnicastLocallyAssignedMacAddressMask;
+}
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+class WifiIfaceUtilTest : public Test {
+  protected:
+    std::shared_ptr<NiceMock<::android::wifi_system::MockInterfaceTool>> iface_tool_{
+            new NiceMock<::android::wifi_system::MockInterfaceTool>};
+    legacy_hal::wifi_hal_fn fake_func_table_;
+    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+            new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
+    WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_);
+};
+
+TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) {
+    auto mac_address = iface_util_->getOrCreateRandomMacAddress();
+    ASSERT_TRUE(isValidUnicastLocallyAssignedMacAddress(mac_address));
+
+    // All further calls should return the same MAC address.
+    ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
+    ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
+}
+
+TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) {
+    std::array<uint8_t, 6> mac_address = {};
+    std::copy(std::begin(kMacAddress), std::end(kMacAddress), std::begin(mac_address));
+    EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_))
+            .WillRepeatedly(testing::Return(true));
+    EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_))
+            .WillRepeatedly(testing::Return(true));
+
+    // Register for iface state toggle events.
+    bool callback_invoked = false;
+    iface_util::IfaceEventHandlers event_handlers = {};
+    event_handlers.on_state_toggle_off_on =
+            [&callback_invoked](const std::string& /* iface_name */) { callback_invoked = true; };
+    iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers);
+    // Invoke setMacAddress and ensure that the cb is invoked.
+    ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
+    ASSERT_TRUE(callback_invoked);
+
+    // Unregister for iface state toggle events.
+    callback_invoked = false;
+    iface_util_->unregisterIfaceEventHandlers(kIfaceName);
+    // Invoke setMacAddress and ensure that the cb is not invoked.
+    ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
+    ASSERT_FALSE(callback_invoked);
+}
+}  // namespace iface_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp
new file mode 100644
index 0000000..d58a9b0
--- /dev/null
+++ b/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <cutils/properties.h>
+#include <gmock/gmock.h>
+
+#include "wifi_nan_iface.h"
+
+#include "mock_interface_tool.h"
+#include "mock_wifi_feature_flags.h"
+#include "mock_wifi_iface_util.h"
+#include "mock_wifi_legacy_hal.h"
+
+using testing::NiceMock;
+using testing::Return;
+using testing::Test;
+
+namespace {
+constexpr char kIfaceName[] = "mockWlan0";
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+bool CaptureIfaceEventHandlers(const std::string& /* iface_name*/,
+                               iface_util::IfaceEventHandlers in_iface_event_handlers,
+                               iface_util::IfaceEventHandlers* out_iface_event_handlers) {
+    *out_iface_event_handlers = in_iface_event_handlers;
+    return true;
+}
+
+class MockNanIface : public WifiNanIface {
+  public:
+    MockNanIface(const std::string& ifname, bool is_dedicated_iface,
+                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+        : WifiNanIface(ifname, is_dedicated_iface, legacy_hal, iface_util) {}
+
+    static std::shared_ptr<MockNanIface> createMock(
+            const std::string& ifname, bool is_dedicated_iface,
+            const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+            const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) {
+        std::shared_ptr<MockNanIface> ptr = ndk::SharedRefBase::make<MockNanIface>(
+                ifname, is_dedicated_iface, legacy_hal, iface_util);
+        std::weak_ptr<MockNanIface> weak_ptr_this(ptr);
+        ptr->setWeakPtr(weak_ptr_this);
+        ptr->registerCallbackHandlers();
+        return ptr;
+    }
+
+    // Override getEventCallbacks() so that we can return a mocked callback object.
+    std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> getEventCallbacks() override {
+        return {callback_};
+    }
+
+    void setMockCallback(std::shared_ptr<IWifiNanIfaceEventCallback> cb) { callback_ = cb; }
+
+  private:
+    std::shared_ptr<IWifiNanIfaceEventCallback> callback_;
+};
+
+class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback {
+  public:
+    ndk::SpAIBinder asBinder() override { return ::ndk::SpAIBinder{}; }
+    bool isRemote() override { return false; }
+
+    ::ndk::ScopedAStatus getInterfaceVersion(int32_t* _aidl_return) override {
+        *_aidl_return = 1;
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus getInterfaceHash(std::string* _aidl_return) override {
+        *_aidl_return = "some_hash";
+        return ndk::ScopedAStatus::ok();
+    }
+
+    MOCK_METHOD3(notifyCapabilitiesResponse,
+                 ndk::ScopedAStatus(char16_t, const NanStatus&, const NanCapabilities&));
+    MOCK_METHOD2(notifyEnableResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD2(notifyConfigResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD2(notifyDisableResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD3(notifyStartPublishResponse,
+                 ndk::ScopedAStatus(char16_t, const NanStatus&, int8_t));
+    MOCK_METHOD2(notifyStopPublishResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD3(notifyStartSubscribeResponse,
+                 ndk::ScopedAStatus(char16_t, const NanStatus&, int8_t));
+    MOCK_METHOD2(notifyStopSubscribeResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD2(notifyTransmitFollowupResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD2(notifyCreateDataInterfaceResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD2(notifyDeleteDataInterfaceResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD3(notifyInitiateDataPathResponse,
+                 ndk::ScopedAStatus(char16_t, const NanStatus&, int32_t));
+    MOCK_METHOD2(notifyRespondToDataPathIndicationResponse,
+                 ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD2(notifyTerminateDataPathResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD1(eventClusterEvent, ndk::ScopedAStatus(const NanClusterEventInd&));
+    MOCK_METHOD1(eventDisabled, ndk::ScopedAStatus(const NanStatus&));
+    MOCK_METHOD2(eventPublishTerminated, ndk::ScopedAStatus(int8_t, const NanStatus&));
+    MOCK_METHOD2(eventSubscribeTerminated, ndk::ScopedAStatus(int8_t, const NanStatus&));
+    MOCK_METHOD1(eventMatch, ndk::ScopedAStatus(const NanMatchInd&));
+    MOCK_METHOD2(eventMatchExpired, ndk::ScopedAStatus(int8_t, int32_t));
+    MOCK_METHOD1(eventFollowupReceived, ndk::ScopedAStatus(const NanFollowupReceivedInd&));
+    MOCK_METHOD2(eventTransmitFollowup, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD1(eventDataPathRequest, ndk::ScopedAStatus(const NanDataPathRequestInd&));
+    MOCK_METHOD1(eventDataPathConfirm, ndk::ScopedAStatus(const NanDataPathConfirmInd&));
+    MOCK_METHOD1(eventDataPathTerminated, ndk::ScopedAStatus(int32_t));
+    MOCK_METHOD1(eventDataPathScheduleUpdate,
+                 ndk::ScopedAStatus(const NanDataPathScheduleUpdateInd&));
+    MOCK_METHOD1(eventPairingConfirm, ndk::ScopedAStatus(const NanPairingConfirmInd&));
+    MOCK_METHOD1(eventPairingRequest, ndk::ScopedAStatus(const NanPairingRequestInd&));
+    MOCK_METHOD1(eventBootstrappingConfirm, ndk::ScopedAStatus(const NanBootstrappingConfirmInd&));
+    MOCK_METHOD1(eventBootstrappingRequest, ndk::ScopedAStatus(const NanBootstrappingRequestInd&));
+    MOCK_METHOD3(notifyInitiatePairingResponse,
+                 ndk::ScopedAStatus(char16_t, const NanStatus&, int32_t));
+    MOCK_METHOD2(notifyRespondToPairingIndicationResponse,
+                 ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD3(notifyInitiateBootstrappingResponse,
+                 ndk::ScopedAStatus(char16_t, const NanStatus&, int32_t));
+    MOCK_METHOD2(notifyRespondToBootstrappingIndicationResponse,
+                 ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD2(notifySuspendResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD2(notifyResumeResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD2(notifyTerminatePairingResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+    MOCK_METHOD1(eventSuspensionModeChanged, ndk::ScopedAStatus(const NanSuspensionModeChangeInd&));
+};
+
+class WifiNanIfaceTest : public Test {
+  protected:
+    legacy_hal::wifi_hal_fn fake_func_table_;
+    std::shared_ptr<NiceMock<::android::wifi_system::MockInterfaceTool>> iface_tool_{
+            new NiceMock<::android::wifi_system::MockInterfaceTool>};
+    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+            new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
+    std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
+            new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
+};
+
+TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
+    // Ensure that event handlers are registered during nan iface creation.
+    iface_util::IfaceEventHandlers captured_iface_event_handlers = {};
+    EXPECT_CALL(*legacy_hal_, nanRegisterCallbackHandlers(testing::_, testing::_))
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+    EXPECT_CALL(*iface_util_, registerIfaceEventHandlers(testing::_, testing::_))
+            .WillOnce(testing::Invoke(bind(CaptureIfaceEventHandlers, std::placeholders::_1,
+                                           std::placeholders::_2, &captured_iface_event_handlers)));
+
+    // Create nan iface and register a callback.
+    // Note: Since we can't register a callback directly (gTest fails on
+    //       AIBinder_linkToDeath), simulate the registration by overriding
+    //       getEventCallbacks() to return our mock callback object.
+    std::shared_ptr<MockNanIface> mock_nan_iface =
+            MockNanIface::createMock(kIfaceName, false, legacy_hal_, iface_util_);
+    std::shared_ptr<MockNanIfaceEventCallback> mock_event_callback =
+            ndk::SharedRefBase::make<MockNanIfaceEventCallback>();
+    mock_nan_iface->setMockCallback(mock_event_callback);
+
+    // Ensure that the eventDisabled() function in the mock callback will be invoked.
+    NanStatus expected_nan_status = {NanStatusCode::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+    EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status)).Times(1);
+
+    // Trigger the iface state toggle callback.
+    captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName);
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi.cpp b/wifi/aidl/default/wifi.cpp
new file mode 100644
index 0000000..34a7f35
--- /dev/null
+++ b/wifi/aidl/default/wifi.cpp
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "aidl_sync_util.h"
+#include "wifi_status_util.h"
+
+namespace {
+// Starting Chip ID, will be assigned to primary chip
+static constexpr int32_t kPrimaryChipId = 0;
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+using aidl_return_util::validateAndCallWithLock;
+using aidl_sync_util::acquireGlobalLock;
+
+Wifi::Wifi(const std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+           const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
+           const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
+           const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
+    : iface_tool_(iface_tool),
+      legacy_hal_factory_(legacy_hal_factory),
+      mode_controller_(mode_controller),
+      feature_flags_(feature_flags),
+      run_state_(RunState::STOPPED) {}
+
+bool Wifi::isValid() {
+    // This object is always valid.
+    return true;
+}
+
+ndk::ScopedAStatus Wifi::registerEventCallback(
+        const std::shared_ptr<IWifiEventCallback>& in_callback) {
+    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
+                           &Wifi::registerEventCallbackInternal, in_callback);
+}
+
+ndk::ScopedAStatus Wifi::isStarted(bool* _aidl_return) {
+    *_aidl_return = (run_state_ != RunState::STOPPED);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Wifi::start() {
+    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal);
+}
+
+ndk::ScopedAStatus Wifi::stop() {
+    return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal);
+}
+
+ndk::ScopedAStatus Wifi::getChipIds(std::vector<int32_t>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipIdsInternal,
+                           _aidl_return);
+}
+
+ndk::ScopedAStatus Wifi::getChip(int32_t in_chipId, std::shared_ptr<IWifiChip>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipInternal,
+                           _aidl_return, in_chipId);
+}
+
+binder_status_t Wifi::dump(int fd, const char** args, uint32_t numArgs) {
+    const auto lock = acquireGlobalLock();
+    LOG(INFO) << "-----------Debug was called----------------";
+    if (chips_.size() == 0) {
+        LOG(INFO) << "No chips to display.";
+        return STATUS_OK;
+    }
+
+    for (std::shared_ptr<WifiChip> chip : chips_) {
+        if (!chip.get()) continue;
+        chip->dump(fd, args, numArgs);
+    }
+    return STATUS_OK;
+}
+
+ndk::ScopedAStatus Wifi::registerEventCallbackInternal(
+        const std::shared_ptr<IWifiEventCallback>& event_callback) {
+    if (!event_cb_handler_.addCallback(event_callback)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Wifi::startInternal() {
+    if (run_state_ == RunState::STARTED) {
+        return ndk::ScopedAStatus::ok();
+    } else if (run_state_ == RunState::STOPPING) {
+        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
+    }
+    ndk::ScopedAStatus wifi_status = initializeModeControllerAndLegacyHal();
+    if (wifi_status.isOk()) {
+        // Register the callback for subsystem restart
+        const auto& on_subsystem_restart_callback = [this](const std::string& error) {
+            ndk::ScopedAStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
+            for (const auto& callback : event_cb_handler_.getCallbacks()) {
+                LOG(INFO) << "Attempting to invoke onSubsystemRestart "
+                             "callback";
+                WifiStatusCode errorCode =
+                        static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
+                if (!callback->onSubsystemRestart(errorCode).isOk()) {
+                    LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
+                } else {
+                    LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
+                                 "callback";
+                }
+            }
+        };
+
+        // Create the chip instance once the HAL is started.
+        int32_t chipId = kPrimaryChipId;
+        for (auto& hal : legacy_hals_) {
+            chips_.push_back(
+                    WifiChip::create(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
+                                     std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
+                                     feature_flags_, on_subsystem_restart_callback, false));
+            chipId++;
+        }
+        run_state_ = RunState::STARTED;
+        for (const auto& callback : event_cb_handler_.getCallbacks()) {
+            if (!callback->onStart().isOk()) {
+                LOG(ERROR) << "Failed to invoke onStart callback";
+            };
+        }
+        LOG(INFO) << "Wifi HAL started";
+    } else {
+        for (const auto& callback : event_cb_handler_.getCallbacks()) {
+            WifiStatusCode errorCode =
+                    static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
+            if (!callback->onFailure(errorCode).isOk()) {
+                LOG(ERROR) << "Failed to invoke onFailure callback";
+            }
+        }
+        LOG(ERROR) << "Wifi HAL start failed";
+        // Clear the event callback objects since the HAL start failed.
+        event_cb_handler_.invalidate();
+    }
+    return wifi_status;
+}
+
+ndk::ScopedAStatus Wifi::stopInternal(
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
+    if (run_state_ == RunState::STOPPED) {
+        return ndk::ScopedAStatus::ok();
+    } else if (run_state_ == RunState::STOPPING) {
+        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
+    }
+    // Clear the chip object and its child objects since the HAL is now
+    // stopped.
+    for (auto& chip : chips_) {
+        if (chip.get()) {
+            chip->invalidate();
+            chip.reset();
+        }
+    }
+    chips_.clear();
+    ndk::ScopedAStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock);
+    if (wifi_status.isOk()) {
+        for (const auto& callback : event_cb_handler_.getCallbacks()) {
+            if (!callback->onStop().isOk()) {
+                LOG(ERROR) << "Failed to invoke onStop callback";
+            };
+        }
+        LOG(INFO) << "Wifi HAL stopped";
+    } else {
+        for (const auto& callback : event_cb_handler_.getCallbacks()) {
+            WifiStatusCode errorCode =
+                    static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
+            if (!callback->onFailure(errorCode).isOk()) {
+                LOG(ERROR) << "Failed to invoke onFailure callback";
+            }
+        }
+        LOG(ERROR) << "Wifi HAL stop failed";
+    }
+    // Clear the event callback objects since the HAL is now stopped.
+    event_cb_handler_.invalidate();
+    return wifi_status;
+}
+
+std::pair<std::vector<int32_t>, ndk::ScopedAStatus> Wifi::getChipIdsInternal() {
+    std::vector<int32_t> chip_ids;
+
+    for (auto& chip : chips_) {
+        int32_t chip_id = getChipIdFromWifiChip(chip);
+        if (chip_id != INT32_MAX) chip_ids.emplace_back(chip_id);
+    }
+    return {std::move(chip_ids), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiChip>, ndk::ScopedAStatus> Wifi::getChipInternal(int32_t chip_id) {
+    for (auto& chip : chips_) {
+        int32_t cand_id = getChipIdFromWifiChip(chip);
+        if ((cand_id != INT32_MAX) && (cand_id == chip_id)) return {chip, ndk::ScopedAStatus::ok()};
+    }
+
+    return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+}
+
+ndk::ScopedAStatus Wifi::initializeModeControllerAndLegacyHal() {
+    if (!mode_controller_->initialize()) {
+        LOG(ERROR) << "Failed to initialize firmware mode controller";
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+
+    legacy_hals_ = legacy_hal_factory_->getHals();
+    if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    int index = 0;  // for failure log
+    for (auto& hal : legacy_hals_) {
+        legacy_hal::wifi_error legacy_status = hal->initialize();
+        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+            // Currently WifiLegacyHal::initialize does not allocate extra mem,
+            // only initializes the function table. If this changes, need to
+            // implement WifiLegacyHal::deinitialize and deinitalize the
+            // HALs already initialized
+            LOG(ERROR) << "Failed to initialize legacy HAL index: " << index
+                       << " error: " << legacyErrorToString(legacy_status);
+            return createWifiStatusFromLegacyError(legacy_status);
+        }
+        index++;
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Wifi::stopLegacyHalAndDeinitializeModeController(
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
+    legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS;
+    int index = 0;
+
+    run_state_ = RunState::STOPPING;
+    for (auto& hal : legacy_hals_) {
+        legacy_hal::wifi_error tmp = hal->stop(lock, [&]() {});
+        if (tmp != legacy_hal::WIFI_SUCCESS) {
+            LOG(ERROR) << "Failed to stop legacy HAL index: " << index
+                       << " error: " << legacyErrorToString(legacy_status);
+            legacy_status = tmp;
+        }
+        index++;
+    }
+    run_state_ = RunState::STOPPED;
+
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "One or more legacy HALs failed to stop";
+        return createWifiStatusFromLegacyError(legacy_status);
+    }
+    if (!mode_controller_->deinitialize()) {
+        LOG(ERROR) << "Failed to deinitialize firmware mode controller";
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+int32_t Wifi::getChipIdFromWifiChip(std::shared_ptr<WifiChip>& chip) {
+    int32_t chip_id = INT32_MAX;
+    if (chip.get()) {
+        ndk::ScopedAStatus status = chip->getId(&chip_id);
+        if (!status.isOk()) {
+            // Reset value if operation failed.
+            chip_id = INT32_MAX;
+        }
+    }
+    return chip_id;
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi.h b/wifi/aidl/default/wifi.h
new file mode 100644
index 0000000..9334524
--- /dev/null
+++ b/wifi/aidl/default/wifi.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_H_
+#define WIFI_H_
+
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <android-base/macros.h>
+#include <utils/Looper.h>
+
+#include <functional>
+
+#include "aidl_callback_util.h"
+#include "wifi_chip.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_legacy_hal_factory.h"
+#include "wifi_mode_controller.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * Root AIDL interface object used to control the Wifi HAL.
+ */
+class Wifi : public BnWifi {
+  public:
+    Wifi(const std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+         const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
+         const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
+         const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
+
+    bool isValid();
+
+    // AIDL methods exposed.
+    ndk::ScopedAStatus registerEventCallback(
+            const std::shared_ptr<IWifiEventCallback>& in_callback) override;
+    ndk::ScopedAStatus isStarted(bool* _aidl_return) override;
+    ndk::ScopedAStatus start() override;
+    ndk::ScopedAStatus stop() override;
+    ndk::ScopedAStatus getChipIds(std::vector<int32_t>* _aidl_return) override;
+    ndk::ScopedAStatus getChip(int32_t in_chipId,
+                               std::shared_ptr<IWifiChip>* _aidl_return) override;
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+  private:
+    enum class RunState { STOPPED, STARTED, STOPPING };
+
+    // Corresponding worker functions for the AIDL methods.
+    ndk::ScopedAStatus registerEventCallbackInternal(
+            const std::shared_ptr<IWifiEventCallback>& event_callback __unused);
+    ndk::ScopedAStatus startInternal();
+    ndk::ScopedAStatus stopInternal(std::unique_lock<std::recursive_mutex>* lock);
+    std::pair<std::vector<int32_t>, ndk::ScopedAStatus> getChipIdsInternal();
+    std::pair<std::shared_ptr<IWifiChip>, ndk::ScopedAStatus> getChipInternal(int32_t chip_id);
+
+    ndk::ScopedAStatus initializeModeControllerAndLegacyHal();
+    ndk::ScopedAStatus stopLegacyHalAndDeinitializeModeController(
+            std::unique_lock<std::recursive_mutex>* lock);
+    int32_t getChipIdFromWifiChip(std::shared_ptr<WifiChip>& chip);
+
+    // Instance is created in this root level |IWifi| AIDL interface object
+    // and shared with all the child AIDL interface objects.
+    std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
+    std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory_;
+    std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
+    std::vector<std::shared_ptr<legacy_hal::WifiLegacyHal>> legacy_hals_;
+    std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
+    RunState run_state_;
+    std::vector<std::shared_ptr<WifiChip>> chips_;
+    aidl_callback_util::AidlCallbackHandler<IWifiEventCallback> event_cb_handler_;
+
+    DISALLOW_COPY_AND_ASSIGN(Wifi);
+};
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_H_
diff --git a/wifi/aidl/default/wifi_ap_iface.cpp b/wifi/aidl/default/wifi_ap_iface.cpp
new file mode 100644
index 0000000..7779750
--- /dev/null
+++ b/wifi/aidl/default/wifi_ap_iface.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_ap_iface.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiApIface::WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
+                         const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                         const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+    : ifname_(ifname),
+      instances_(instances),
+      legacy_hal_(legacy_hal),
+      iface_util_(iface_util),
+      is_valid_(true) {}
+
+void WifiApIface::invalidate() {
+    legacy_hal_.reset();
+    is_valid_ = false;
+}
+
+bool WifiApIface::isValid() {
+    return is_valid_;
+}
+
+std::string WifiApIface::getName() {
+    return ifname_;
+}
+
+void WifiApIface::removeInstance(std::string instance) {
+    instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end());
+}
+
+ndk::ScopedAStatus WifiApIface::getName(std::string* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiApIface::getNameInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiApIface::setCountryCode(const std::array<uint8_t, 2>& in_code) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiApIface::setCountryCodeInternal, in_code);
+}
+
+ndk::ScopedAStatus WifiApIface::setMacAddress(const std::array<uint8_t, 6>& in_mac) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiApIface::setMacAddressInternal, in_mac);
+}
+
+ndk::ScopedAStatus WifiApIface::getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiApIface::getFactoryMacAddressInternal, _aidl_return,
+                           instances_.size() > 0 ? instances_[0] : ifname_);
+}
+
+ndk::ScopedAStatus WifiApIface::resetToFactoryMacAddress() {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiApIface::resetToFactoryMacAddressInternal);
+}
+
+ndk::ScopedAStatus WifiApIface::getBridgedInstances(std::vector<std::string>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiApIface::getBridgedInstancesInternal, _aidl_return);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> WifiApIface::getNameInternal() {
+    return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiApIface::setCountryCodeInternal(const std::array<uint8_t, 2>& code) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode(
+            instances_.size() > 0 ? instances_[0] : ifname_, code);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiApIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
+    // Support random MAC up to 2 interfaces
+    if (instances_.size() == 2) {
+        int rbyte = 1;
+        for (auto const& intf : instances_) {
+            std::array<uint8_t, 6> rmac = mac;
+            // reverse the bits to avoid collision
+            rmac[rbyte] = 0xff - rmac[rbyte];
+            if (!iface_util_.lock()->setMacAddress(intf, rmac)) {
+                LOG(INFO) << "Failed to set random mac address on " << intf;
+                return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+            }
+            rbyte++;
+        }
+    }
+    // It also needs to set mac address for bridged interface, otherwise the mac
+    // address of bridged interface will be changed after one of instance
+    // down.
+    if (!iface_util_.lock()->setMacAddress(ifname_, mac)) {
+        LOG(ERROR) << "Fail to config MAC for interface " << ifname_;
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> WifiApIface::getFactoryMacAddressInternal(
+        const std::string& ifaceName) {
+    std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifaceName);
+    if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
+        return {mac, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {mac, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiApIface::resetToFactoryMacAddressInternal() {
+    std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getMacResult;
+    if (instances_.size() == 2) {
+        for (auto const& intf : instances_) {
+            getMacResult = getFactoryMacAddressInternal(intf);
+            LOG(DEBUG) << "Reset MAC to factory MAC on " << intf;
+            if (!getMacResult.second.isOk() ||
+                !iface_util_.lock()->setMacAddress(intf, getMacResult.first)) {
+                return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+            }
+        }
+        // We need to set mac address for bridged interface, otherwise the mac
+        // address of the bridged interface will be changed after one of the
+        // instances goes down. Thus we are generating a random MAC address for
+        // the bridged interface even if we got the request to reset the Factory
+        // MAC. This is because the bridged interface is an internal interface
+        // for the operation of bpf and other networking operations.
+        if (!iface_util_.lock()->setMacAddress(ifname_,
+                                               iface_util_.lock()->createRandomMacAddress())) {
+            LOG(ERROR) << "Fail to config MAC for bridged interface " << ifname_;
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+        }
+    } else {
+        getMacResult = getFactoryMacAddressInternal(ifname_);
+        LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_;
+        if (!getMacResult.second.isOk() ||
+            !iface_util_.lock()->setMacAddress(ifname_, getMacResult.first)) {
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiApIface::getBridgedInstancesInternal() {
+    return {instances_, ndk::ScopedAStatus::ok()};
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_ap_iface.h b/wifi/aidl/default/wifi_ap_iface.h
new file mode 100644
index 0000000..7378f98
--- /dev/null
+++ b/wifi/aidl/default/wifi_ap_iface.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_AP_IFACE_H_
+#define WIFI_AP_IFACE_H_
+
+#include <aidl/android/hardware/wifi/BnWifiApIface.h>
+#include <android-base/macros.h>
+
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control an AP Iface instance.
+ */
+class WifiApIface : public BnWifiApIface {
+  public:
+    WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
+                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+    // Refer to |WifiChip::invalidate()|.
+    void invalidate();
+    bool isValid();
+    std::string getName();
+    void removeInstance(std::string instance);
+
+    // AIDL methods exposed.
+    ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+    ndk::ScopedAStatus setCountryCode(const std::array<uint8_t, 2>& in_code) override;
+    ndk::ScopedAStatus setMacAddress(const std::array<uint8_t, 6>& in_mac) override;
+    ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
+    ndk::ScopedAStatus resetToFactoryMacAddress() override;
+    ndk::ScopedAStatus getBridgedInstances(std::vector<std::string>* _aidl_return) override;
+
+  private:
+    // Corresponding worker functions for the AIDL methods.
+    std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+    ndk::ScopedAStatus setCountryCodeInternal(const std::array<uint8_t, 2>& code);
+    ndk::ScopedAStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
+    std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal(
+            const std::string& ifaceName);
+    ndk::ScopedAStatus resetToFactoryMacAddressInternal();
+    std::pair<std::vector<std::string>, ndk::ScopedAStatus> getBridgedInstancesInternal();
+
+    std::string ifname_;
+    std::vector<std::string> instances_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+    bool is_valid_;
+
+    DISALLOW_COPY_AND_ASSIGN(WifiApIface);
+};
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_AP_IFACE_H_
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
new file mode 100644
index 0000000..6dd9156
--- /dev/null
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -0,0 +1,2028 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_chip.h"
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <cutils/properties.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_status_util.h"
+
+#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
+
+namespace {
+using aidl::android::hardware::wifi::IfaceType;
+using aidl::android::hardware::wifi::IWifiChip;
+using CoexRestriction = aidl::android::hardware::wifi::IWifiChip::CoexRestriction;
+using ChannelCategoryMask = aidl::android::hardware::wifi::IWifiChip::ChannelCategoryMask;
+using android::base::unique_fd;
+
+constexpr char kCpioMagic[] = "070701";
+constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
+constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
+constexpr uint32_t kMaxRingBufferFileNum = 20;
+constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
+constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
+constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
+constexpr unsigned kMaxWlanIfaces = 5;
+constexpr char kApBridgeIfacePrefix[] = "ap_br_";
+
+template <typename Iface>
+void invalidateAndClear(std::vector<std::shared_ptr<Iface>>& ifaces, std::shared_ptr<Iface> iface) {
+    iface->invalidate();
+    ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end());
+}
+
+template <typename Iface>
+void invalidateAndClearAll(std::vector<std::shared_ptr<Iface>>& ifaces) {
+    for (const auto& iface : ifaces) {
+        iface->invalidate();
+    }
+    ifaces.clear();
+}
+
+template <typename Iface>
+std::vector<std::string> getNames(std::vector<std::shared_ptr<Iface>>& ifaces) {
+    std::vector<std::string> names;
+    for (const auto& iface : ifaces) {
+        names.emplace_back(iface->getName());
+    }
+    return names;
+}
+
+template <typename Iface>
+std::shared_ptr<Iface> findUsingName(std::vector<std::shared_ptr<Iface>>& ifaces,
+                                     const std::string& name) {
+    std::vector<std::string> names;
+    for (const auto& iface : ifaces) {
+        if (name == iface->getName()) {
+            return iface;
+        }
+    }
+    return nullptr;
+}
+
+std::string getWlanIfaceName(unsigned idx) {
+    if (idx >= kMaxWlanIfaces) {
+        CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
+        return {};
+    }
+
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    if (idx == 0 || idx == 1) {
+        const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
+        auto res = property_get(altPropName, buffer.data(), nullptr);
+        if (res > 0) return buffer.data();
+    }
+    std::string propName = "wifi.interface." + std::to_string(idx);
+    auto res = property_get(propName.c_str(), buffer.data(), nullptr);
+    if (res > 0) return buffer.data();
+
+    return "wlan" + std::to_string(idx);
+}
+
+// Returns the dedicated iface name if defined.
+// Returns two ifaces in bridged mode.
+std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
+    std::vector<std::string> ifnames;
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    buffer.fill(0);
+    if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) {
+        return ifnames;
+    }
+    ifnames.push_back(buffer.data());
+    if (is_bridged) {
+        buffer.fill(0);
+        if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) {
+            return ifnames;
+        }
+        ifnames.push_back(buffer.data());
+    }
+    return ifnames;
+}
+
+std::string getPredefinedP2pIfaceName() {
+    std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
+    char p2pParentIfname[100];
+    std::string p2pDevIfName = "";
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    property_get("wifi.direct.interface", buffer.data(), "p2p0");
+    if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+        /* Get the p2p parent interface name from p2p device interface name set
+         * in property */
+        strlcpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
+                strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
+        if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) {
+            return buffer.data();
+        }
+        /* Check if the parent interface derived from p2p device interface name
+         * is active */
+        if (strncmp(p2pParentIfname, primaryIfaceName.data(),
+                    strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) {
+            /*
+             * Update the predefined p2p device interface parent interface name
+             * with current active wlan interface
+             */
+            p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
+            p2pDevIfName += primaryIfaceName.data();
+            LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str();
+            return p2pDevIfName;
+        }
+    }
+    return buffer.data();
+}
+
+// Returns the dedicated iface name if one is defined.
+std::string getPredefinedNanIfaceName() {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
+        return {};
+    }
+    return buffer.data();
+}
+
+void setActiveWlanIfaceNameProperty(const std::string& ifname) {
+    auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
+    if (res != 0) {
+        PLOG(ERROR) << "Failed to set active wlan iface name property";
+    }
+}
+
+// Delete files that meet either condition:
+// 1. Older than a predefined time in the wifi tombstone dir.
+// 2. Files in excess to a predefined amount, starting from the oldest ones
+bool removeOldFilesInternal() {
+    time_t now = time(0);
+    const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
+    std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir);
+    if (!dir_dump) {
+        PLOG(ERROR) << "Failed to open directory";
+        return false;
+    }
+    struct dirent* dp;
+    bool success = true;
+    std::list<std::pair<const time_t, std::string>> valid_files;
+    while ((dp = readdir(dir_dump.get()))) {
+        if (dp->d_type != DT_REG) {
+            continue;
+        }
+        std::string cur_file_name(dp->d_name);
+        struct stat cur_file_stat;
+        std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
+        if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
+            PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
+            success = false;
+            continue;
+        }
+        const time_t cur_file_time = cur_file_stat.st_mtime;
+        valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
+    }
+    valid_files.sort();  // sort the list of files by last modified time from
+                         // small to big.
+    uint32_t cur_file_count = valid_files.size();
+    for (auto cur_file : valid_files) {
+        if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) {
+            if (unlink(cur_file.second.c_str()) != 0) {
+                PLOG(ERROR) << "Error deleting file";
+                success = false;
+            }
+            cur_file_count--;
+        } else {
+            break;
+        }
+    }
+    return success;
+}
+
+// Helper function for |cpioArchiveFilesInDir|
+bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) {
+    const int buf_size = 32 * 1024;
+    std::array<char, buf_size> read_buf;
+    ssize_t llen = snprintf(
+            read_buf.data(), buf_size, "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
+            kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, st.st_gid,
+            static_cast<int>(st.st_nlink), static_cast<int>(st.st_mtime),
+            static_cast<int>(st.st_size), major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
+            minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
+    if (write(out_fd, read_buf.data(), llen < buf_size ? llen : buf_size - 1) == -1) {
+        PLOG(ERROR) << "Error writing cpio header to file " << file_name;
+        return false;
+    }
+    if (write(out_fd, file_name, file_name_len) == -1) {
+        PLOG(ERROR) << "Error writing filename to file " << file_name;
+        return false;
+    }
+
+    // NUL Pad header up to 4 multiple bytes.
+    llen = (llen + file_name_len) % 4;
+    if (llen != 0) {
+        const uint32_t zero = 0;
+        if (write(out_fd, &zero, 4 - llen) == -1) {
+            PLOG(ERROR) << "Error padding 0s to file " << file_name;
+            return false;
+        }
+    }
+    return true;
+}
+
+// Helper function for |cpioArchiveFilesInDir|
+size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) {
+    // writing content of file
+    std::array<char, 32 * 1024> read_buf;
+    ssize_t llen = st.st_size;
+    size_t n_error = 0;
+    while (llen > 0) {
+        ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
+        if (bytes_read == -1) {
+            PLOG(ERROR) << "Error reading file";
+            return ++n_error;
+        }
+        llen -= bytes_read;
+        if (write(out_fd, read_buf.data(), bytes_read) == -1) {
+            PLOG(ERROR) << "Error writing data to file";
+            return ++n_error;
+        }
+        if (bytes_read == 0) {  // this should never happen, but just in case
+                                // to unstuck from while loop
+            PLOG(ERROR) << "Unexpected read result";
+            n_error++;
+            break;
+        }
+    }
+    llen = st.st_size % 4;
+    if (llen != 0) {
+        const uint32_t zero = 0;
+        if (write(out_fd, &zero, 4 - llen) == -1) {
+            PLOG(ERROR) << "Error padding 0s to file";
+            return ++n_error;
+        }
+    }
+    return n_error;
+}
+
+// Helper function for |cpioArchiveFilesInDir|
+bool cpioWriteFileTrailer(int out_fd) {
+    const int buf_size = 4096;
+    std::array<char, buf_size> read_buf;
+    read_buf.fill(0);
+    ssize_t llen = snprintf(read_buf.data(), 4096, "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0);
+    if (write(out_fd, read_buf.data(), (llen < buf_size ? llen : buf_size - 1) + 4) == -1) {
+        PLOG(ERROR) << "Error writing trailing bytes";
+        return false;
+    }
+    return true;
+}
+
+// Archives all files in |input_dir| and writes result into |out_fd|
+// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
+// portion
+size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
+    struct dirent* dp;
+    size_t n_error = 0;
+    std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), closedir);
+    if (!dir_dump) {
+        PLOG(ERROR) << "Failed to open directory";
+        return ++n_error;
+    }
+    while ((dp = readdir(dir_dump.get()))) {
+        if (dp->d_type != DT_REG) {
+            continue;
+        }
+        std::string cur_file_name(dp->d_name);
+        struct stat st;
+        const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
+        if (stat(cur_file_path.c_str(), &st) == -1) {
+            PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
+            n_error++;
+            continue;
+        }
+        const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
+        if (fd_read == -1) {
+            PLOG(ERROR) << "Failed to open file " << cur_file_path;
+            n_error++;
+            continue;
+        }
+        std::string file_name_with_last_modified_time =
+                cur_file_name + "-" + std::to_string(st.st_mtime);
+        // string.size() does not include the null terminator. The cpio FreeBSD
+        // file header expects the null character to be included in the length.
+        const size_t file_name_len = file_name_with_last_modified_time.size() + 1;
+        unique_fd file_auto_closer(fd_read);
+        if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(),
+                             file_name_len)) {
+            return ++n_error;
+        }
+        size_t write_error = cpioWriteFileContent(fd_read, out_fd, st);
+        if (write_error) {
+            return n_error + write_error;
+        }
+    }
+    if (!cpioWriteFileTrailer(out_fd)) {
+        return ++n_error;
+    }
+    return n_error;
+}
+
+// Helper function to create a non-const char*.
+std::vector<char> makeCharVec(const std::string& str) {
+    std::vector<char> vec(str.size() + 1);
+    vec.assign(str.begin(), str.end());
+    vec.push_back('\0');
+    return vec;
+}
+
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+using aidl_return_util::validateAndCallWithLock;
+
+WifiChip::WifiChip(int32_t chip_id, bool is_primary,
+                   const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                   const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+                   const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+                   const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+                   const std::function<void(const std::string&)>& handler,
+                   bool using_dynamic_iface_combination)
+    : chip_id_(chip_id),
+      legacy_hal_(legacy_hal),
+      mode_controller_(mode_controller),
+      iface_util_(iface_util),
+      is_valid_(true),
+      current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
+      modes_(feature_flags.lock()->getChipModes(is_primary)),
+      debug_ring_buffer_cb_registered_(false),
+      using_dynamic_iface_combination_(using_dynamic_iface_combination),
+      subsystemCallbackHandler_(handler) {
+    setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
+}
+
+void WifiChip::retrieveDynamicIfaceCombination() {
+    if (using_dynamic_iface_combination_) return;
+
+    legacy_hal::wifi_iface_concurrency_matrix legacy_matrix;
+    legacy_hal::wifi_error legacy_status;
+
+    std::tie(legacy_status, legacy_matrix) =
+            legacy_hal_.lock()->getSupportedIfaceConcurrencyMatrix();
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to get SupportedIfaceCombinations matrix from legacy HAL: "
+                   << legacyErrorToString(legacy_status);
+        return;
+    }
+
+    IWifiChip::ChipMode aidl_chip_mode;
+    if (!aidl_struct_util::convertLegacyIfaceCombinationsMatrixToChipMode(legacy_matrix,
+                                                                          &aidl_chip_mode)) {
+        LOG(ERROR) << "Failed convertLegacyIfaceCombinationsMatrixToChipMode() ";
+        return;
+    }
+
+    LOG(INFO) << "Reloading iface concurrency combination from driver";
+    aidl_chip_mode.id = feature_flags::chip_mode_ids::kV3;
+    modes_.clear();
+    modes_.push_back(aidl_chip_mode);
+    using_dynamic_iface_combination_ = true;
+}
+
+std::shared_ptr<WifiChip> WifiChip::create(
+        int32_t chip_id, bool is_primary, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+        const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+        const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+        const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+        const std::function<void(const std::string&)>& handler,
+        bool using_dynamic_iface_combination) {
+    std::shared_ptr<WifiChip> ptr = ndk::SharedRefBase::make<WifiChip>(
+            chip_id, is_primary, legacy_hal, mode_controller, iface_util, feature_flags, handler,
+            using_dynamic_iface_combination);
+    std::weak_ptr<WifiChip> weak_ptr_this(ptr);
+    ptr->setWeakPtr(weak_ptr_this);
+    return ptr;
+}
+
+void WifiChip::invalidate() {
+    if (!writeRingbufferFilesInternal()) {
+        LOG(ERROR) << "Error writing files to flash";
+    }
+    invalidateAndRemoveAllIfaces();
+    setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
+    legacy_hal_.reset();
+    event_cb_handler_.invalidate();
+    is_valid_ = false;
+}
+
+void WifiChip::setWeakPtr(std::weak_ptr<WifiChip> ptr) {
+    weak_ptr_this_ = ptr;
+}
+
+bool WifiChip::isValid() {
+    return is_valid_;
+}
+
+std::set<std::shared_ptr<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
+    return event_cb_handler_.getCallbacks();
+}
+
+ndk::ScopedAStatus WifiChip::getId(int32_t* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal,
+                           _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::registerEventCallback(
+        const std::shared_ptr<IWifiChipEventCallback>& event_callback) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::registerEventCallbackInternal, event_callback);
+}
+
+ndk::ScopedAStatus WifiChip::getFeatureSet(int32_t* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getFeatureSetInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getAvailableModes(std::vector<IWifiChip::ChipMode>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getAvailableModesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::configureChip(int32_t in_modeId) {
+    return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                                   &WifiChip::configureChipInternal, in_modeId);
+}
+
+ndk::ScopedAStatus WifiChip::getMode(int32_t* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getModeInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::requestChipDebugInfo(IWifiChip::ChipDebugInfo* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::requestChipDebugInfoInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::requestDriverDebugDump(std::vector<uint8_t>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::requestDriverDebugDumpInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::requestFirmwareDebugDump(std::vector<uint8_t>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::requestFirmwareDebugDumpInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::createApIface(std::shared_ptr<IWifiApIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::createApIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::createBridgedApIface(std::shared_ptr<IWifiApIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::createBridgedApIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getApIfaceNames(std::vector<std::string>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getApIfaceNamesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getApIface(const std::string& in_ifname,
+                                        std::shared_ptr<IWifiApIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getApIfaceInternal, _aidl_return, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeApIface(const std::string& in_ifname) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::removeApIfaceInternal, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeIfaceInstanceFromBridgedApIface(
+        const std::string& in_brIfaceName, const std::string& in_ifaceInstanceName) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, in_brIfaceName,
+                           in_ifaceInstanceName);
+}
+
+ndk::ScopedAStatus WifiChip::createNanIface(std::shared_ptr<IWifiNanIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::createNanIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getNanIfaceNames(std::vector<std::string>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getNanIfaceNamesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getNanIface(const std::string& in_ifname,
+                                         std::shared_ptr<IWifiNanIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getNanIfaceInternal, _aidl_return, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeNanIface(const std::string& in_ifname) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::removeNanIfaceInternal, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::createP2pIface(std::shared_ptr<IWifiP2pIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::createP2pIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getP2pIfaceNames(std::vector<std::string>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getP2pIfaceNamesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getP2pIface(const std::string& in_ifname,
+                                         std::shared_ptr<IWifiP2pIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getP2pIfaceInternal, _aidl_return, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeP2pIface(const std::string& in_ifname) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::removeP2pIfaceInternal, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::createStaIface(std::shared_ptr<IWifiStaIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::createStaIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getStaIfaceNames(std::vector<std::string>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getStaIfaceNamesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getStaIface(const std::string& in_ifname,
+                                         std::shared_ptr<IWifiStaIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getStaIfaceInternal, _aidl_return, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeStaIface(const std::string& in_ifname) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::removeStaIfaceInternal, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::createRttController(
+        const std::shared_ptr<IWifiStaIface>& in_boundIface,
+        std::shared_ptr<IWifiRttController>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::createRttControllerInternal, _aidl_return, in_boundIface);
+}
+
+ndk::ScopedAStatus WifiChip::getDebugRingBuffersStatus(
+        std::vector<WifiDebugRingBufferStatus>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getDebugRingBuffersStatusInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::startLoggingToDebugRingBuffer(
+        const std::string& in_ringName, WifiDebugRingBufferVerboseLevel in_verboseLevel,
+        int32_t in_maxIntervalInSec, int32_t in_minDataSizeInBytes) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::startLoggingToDebugRingBufferInternal, in_ringName,
+                           in_verboseLevel, in_maxIntervalInSec, in_minDataSizeInBytes);
+}
+
+ndk::ScopedAStatus WifiChip::forceDumpToDebugRingBuffer(const std::string& in_ringName) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::forceDumpToDebugRingBufferInternal, in_ringName);
+}
+
+ndk::ScopedAStatus WifiChip::flushRingBufferToFile() {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::flushRingBufferToFileInternal);
+}
+
+ndk::ScopedAStatus WifiChip::stopLoggingToDebugRingBuffer() {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::stopLoggingToDebugRingBufferInternal);
+}
+
+ndk::ScopedAStatus WifiChip::getDebugHostWakeReasonStats(
+        WifiDebugHostWakeReasonStats* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getDebugHostWakeReasonStatsInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::enableDebugErrorAlerts(bool in_enable) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::enableDebugErrorAlertsInternal, in_enable);
+}
+
+ndk::ScopedAStatus WifiChip::selectTxPowerScenario(IWifiChip::TxPowerScenario in_scenario) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::selectTxPowerScenarioInternal, in_scenario);
+}
+
+ndk::ScopedAStatus WifiChip::resetTxPowerScenario() {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::resetTxPowerScenarioInternal);
+}
+
+ndk::ScopedAStatus WifiChip::setLatencyMode(IWifiChip::LatencyMode in_mode) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::setLatencyModeInternal, in_mode);
+}
+
+binder_status_t WifiChip::dump(int fd, const char**, uint32_t) {
+    {
+        std::unique_lock<std::mutex> lk(lock_t);
+        for (const auto& item : ringbuffer_map_) {
+            forceDumpToDebugRingBufferInternal(item.first);
+        }
+        // unique_lock unlocked here
+    }
+    usleep(100 * 1000);  // sleep for 100 milliseconds to wait for
+                         // ringbuffer updates.
+    if (!writeRingbufferFilesInternal()) {
+        LOG(ERROR) << "Error writing files to flash";
+    }
+    uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath);
+    if (n_error != 0) {
+        LOG(ERROR) << n_error << " errors occurred in cpio function";
+    }
+    fsync(fd);
+    return STATUS_OK;
+}
+
+ndk::ScopedAStatus WifiChip::setMultiStaPrimaryConnection(const std::string& in_ifName) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::setMultiStaPrimaryConnectionInternal, in_ifName);
+}
+
+ndk::ScopedAStatus WifiChip::setMultiStaUseCase(IWifiChip::MultiStaUseCase in_useCase) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::setMultiStaUseCaseInternal, in_useCase);
+}
+
+ndk::ScopedAStatus WifiChip::setCoexUnsafeChannels(
+        const std::vector<IWifiChip::CoexUnsafeChannel>& in_unsafeChannels,
+        int32_t in_restrictions) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::setCoexUnsafeChannelsInternal, in_unsafeChannels,
+                           in_restrictions);
+}
+
+ndk::ScopedAStatus WifiChip::setCountryCode(const std::array<uint8_t, 2>& in_code) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiChip::setCountryCodeInternal, in_code);
+}
+
+ndk::ScopedAStatus WifiChip::getUsableChannels(WifiBand in_band, int32_t in_ifaceModeMask,
+                                               int32_t in_filterMask,
+                                               std::vector<WifiUsableChannel>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getUsableChannelsInternal, _aidl_return, in_band,
+                           in_ifaceModeMask, in_filterMask);
+}
+
+ndk::ScopedAStatus WifiChip::setAfcChannelAllowance(
+        const AfcChannelAllowance& afcChannelAllowance) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::setAfcChannelAllowanceInternal, afcChannelAllowance);
+}
+
+ndk::ScopedAStatus WifiChip::triggerSubsystemRestart() {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::triggerSubsystemRestartInternal);
+}
+
+ndk::ScopedAStatus WifiChip::getSupportedRadioCombinations(
+        std::vector<WifiRadioCombination>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getSupportedRadioCombinationsInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getWifiChipCapabilities(WifiChipCapabilities* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getWifiChipCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::enableStaChannelForPeerNetwork(int32_t in_channelCategoryEnableFlag) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::enableStaChannelForPeerNetworkInternal,
+                           in_channelCategoryEnableFlag);
+}
+
+ndk::ScopedAStatus WifiChip::setMloMode(const ChipMloMode in_mode) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::setMloModeInternal, in_mode);
+}
+
+void WifiChip::invalidateAndRemoveAllIfaces() {
+    invalidateAndClearBridgedApAll();
+    invalidateAndClearAll(ap_ifaces_);
+    invalidateAndClearAll(nan_ifaces_);
+    invalidateAndClearAll(p2p_ifaces_);
+    invalidateAndClearAll(sta_ifaces_);
+    // Since all the ifaces are invalid now, all RTT controller objects
+    // using those ifaces also need to be invalidated.
+    for (const auto& rtt : rtt_controllers_) {
+        rtt->invalidate();
+    }
+    rtt_controllers_.clear();
+}
+
+void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) {
+    for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
+        auto nan_iface = *it;
+        if (nan_iface->getName() == removed_iface_name) {
+            nan_iface->invalidate();
+            for (const auto& callback : event_cb_handler_.getCallbacks()) {
+                if (!callback->onIfaceRemoved(IfaceType::NAN_IFACE, removed_iface_name).isOk()) {
+                    LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+                }
+            }
+            it = nan_ifaces_.erase(it);
+        } else {
+            ++it;
+        }
+    }
+
+    for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
+        auto rtt = *it;
+        if (rtt->getIfaceName() == removed_iface_name) {
+            rtt->invalidate();
+            it = rtt_controllers_.erase(it);
+        } else {
+            ++it;
+        }
+    }
+}
+
+std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getIdInternal() {
+    return {chip_id_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::registerEventCallbackInternal(
+        const std::shared_ptr<IWifiChipEventCallback>& event_callback) {
+    if (!event_cb_handler_.addCallback(event_callback)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getFeatureSetInternal() {
+    legacy_hal::wifi_error legacy_status;
+    uint64_t legacy_feature_set;
+    uint32_t legacy_logger_feature_set;
+    const auto ifname = getFirstActiveWlanIfaceName();
+    std::tie(legacy_status, legacy_feature_set) =
+            legacy_hal_.lock()->getSupportedFeatureSet(ifname);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {0, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    std::tie(legacy_status, legacy_logger_feature_set) =
+            legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        // some devices don't support querying logger feature set
+        legacy_logger_feature_set = 0;
+    }
+    uint32_t aidl_feature_set;
+    if (!aidl_struct_util::convertLegacyChipFeaturesToAidl(legacy_feature_set, &aidl_feature_set)) {
+        return {0, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_feature_set, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<IWifiChip::ChipMode>, ndk::ScopedAStatus>
+WifiChip::getAvailableModesInternal() {
+    return {modes_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::configureChipInternal(
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, int32_t mode_id) {
+    if (!isValidModeId(mode_id)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    if (mode_id == current_mode_id_) {
+        LOG(DEBUG) << "Already in the specified mode " << mode_id;
+        return ndk::ScopedAStatus::ok();
+    }
+    ndk::ScopedAStatus status = handleChipConfiguration(lock, mode_id);
+    if (!status.isOk()) {
+        WifiStatusCode errorCode = static_cast<WifiStatusCode>(status.getServiceSpecificError());
+        for (const auto& callback : event_cb_handler_.getCallbacks()) {
+            if (!callback->onChipReconfigureFailure(errorCode).isOk()) {
+                LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
+            }
+        }
+        return status;
+    }
+    for (const auto& callback : event_cb_handler_.getCallbacks()) {
+        if (!callback->onChipReconfigured(mode_id).isOk()) {
+            LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
+        }
+    }
+    current_mode_id_ = mode_id;
+    LOG(INFO) << "Configured chip in mode " << mode_id;
+    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+
+    legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_);
+
+    return status;
+}
+
+std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getModeInternal() {
+    if (!isValidModeId(current_mode_id_)) {
+        return {current_mode_id_, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+    }
+    return {current_mode_id_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> WifiChip::requestChipDebugInfoInternal() {
+    IWifiChip::ChipDebugInfo result;
+    legacy_hal::wifi_error legacy_status;
+    std::string driver_desc;
+    const auto ifname = getFirstActiveWlanIfaceName();
+    std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status);
+        ndk::ScopedAStatus status =
+                createWifiStatusFromLegacyError(legacy_status, "failed to get driver version");
+        return {std::move(result), std::move(status)};
+    }
+    result.driverDescription = driver_desc.c_str();
+
+    std::string firmware_desc;
+    std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status);
+        ndk::ScopedAStatus status =
+                createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version");
+        return {std::move(result), std::move(status)};
+    }
+    result.firmwareDescription = firmware_desc.c_str();
+
+    return {std::move(result), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> WifiChip::requestDriverDebugDumpInternal() {
+    legacy_hal::wifi_error legacy_status;
+    std::vector<uint8_t> driver_dump;
+    std::tie(legacy_status, driver_dump) =
+            legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName());
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status);
+        return {std::vector<uint8_t>(), createWifiStatusFromLegacyError(legacy_status)};
+    }
+    return {driver_dump, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> WifiChip::requestFirmwareDebugDumpInternal() {
+    legacy_hal::wifi_error legacy_status;
+    std::vector<uint8_t> firmware_dump;
+    std::tie(legacy_status, firmware_dump) =
+            legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName());
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status);
+        return {std::vector<uint8_t>(), createWifiStatusFromLegacyError(legacy_status)};
+    }
+    return {firmware_dump, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
+    legacy_hal::wifi_error legacy_status;
+    legacy_status = legacy_hal_.lock()->createVirtualInterface(
+            apVirtIf, aidl_struct_util::convertAidlIfaceTypeToLegacy(IfaceType::AP));
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
+                   << legacyErrorToString(legacy_status);
+        return createWifiStatusFromLegacyError(legacy_status);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
+    std::vector<std::string> ap_instances;
+    for (auto const& it : br_ifaces_ap_instances_) {
+        if (it.first == ifname) {
+            ap_instances = it.second;
+        }
+    }
+    std::shared_ptr<WifiApIface> iface =
+            ndk::SharedRefBase::make<WifiApIface>(ifname, ap_instances, legacy_hal_, iface_util_);
+    ap_ifaces_.push_back(iface);
+    for (const auto& callback : event_cb_handler_.getCallbacks()) {
+        if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
+            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+        }
+    }
+    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+    return iface;
+}
+
+std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> WifiChip::createApIfaceInternal() {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP)) {
+        return {std::shared_ptr<WifiApIface>(),
+                createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+    }
+    std::string ifname = allocateApIfaceName();
+    ndk::ScopedAStatus status = createVirtualApInterface(ifname);
+    if (!status.isOk()) {
+        return {std::shared_ptr<WifiApIface>(), std::move(status)};
+    }
+    std::shared_ptr<WifiApIface> iface = newWifiApIface(ifname);
+    return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus>
+WifiChip::createBridgedApIfaceInternal() {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+    }
+    std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
+    if (ap_instances.size() < 2) {
+        LOG(ERROR) << "Fail to allocate two instances";
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+    }
+    std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
+    for (int i = 0; i < 2; i++) {
+        ndk::ScopedAStatus status = createVirtualApInterface(ap_instances[i]);
+        if (!status.isOk()) {
+            if (i != 0) {  // The failure happened when creating second virtual
+                           // iface.
+                legacy_hal_.lock()->deleteVirtualInterface(
+                        ap_instances.front());  // Remove the first virtual iface.
+            }
+            return {nullptr, std::move(status)};
+        }
+    }
+    br_ifaces_ap_instances_[br_ifname] = ap_instances;
+    if (!iface_util_->createBridge(br_ifname)) {
+        LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
+        deleteApIface(br_ifname);
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+    }
+    for (auto const& instance : ap_instances) {
+        // Bind ap instance interface to AP bridge
+        if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
+            LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
+            deleteApIface(br_ifname);
+            return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+        }
+    }
+    std::shared_ptr<WifiApIface> iface = newWifiApIface(br_ifname);
+    return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getApIfaceNamesInternal() {
+    if (ap_ifaces_.empty()) {
+        return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
+    }
+    return {getNames(ap_ifaces_), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> WifiChip::getApIfaceInternal(
+        const std::string& ifname) {
+    const auto iface = findUsingName(ap_ifaces_, ifname);
+    if (!iface.get()) {
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+    }
+    return {iface, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
+    const auto iface = findUsingName(ap_ifaces_, ifname);
+    if (!iface.get()) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    // Invalidate & remove any dependent objects first.
+    // Note: This is probably not required because we never create
+    // nan/rtt objects over AP iface. But, there is no harm to do it
+    // here and not make that assumption all over the place.
+    invalidateAndRemoveDependencies(ifname);
+    deleteApIface(ifname);
+    invalidateAndClear(ap_ifaces_, iface);
+    for (const auto& callback : event_cb_handler_.getCallbacks()) {
+        if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
+            LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+        }
+    }
+    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
+        const std::string& ifname, const std::string& ifInstanceName) {
+    const auto iface = findUsingName(ap_ifaces_, ifname);
+    if (!iface.get() || ifInstanceName.empty()) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    // Requires to remove one of the instance in bridge mode
+    for (auto const& it : br_ifaces_ap_instances_) {
+        if (it.first == ifname) {
+            std::vector<std::string> ap_instances = it.second;
+            for (auto const& iface : ap_instances) {
+                if (iface == ifInstanceName) {
+                    if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
+                        LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
+                                   << ifname;
+                        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
+                    }
+                    legacy_hal::wifi_error legacy_status =
+                            legacy_hal_.lock()->deleteVirtualInterface(iface);
+                    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+                        LOG(ERROR) << "Failed to del interface: " << iface << " "
+                                   << legacyErrorToString(legacy_status);
+                        return createWifiStatusFromLegacyError(legacy_status);
+                    }
+                    ap_instances.erase(
+                            std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
+                            ap_instances.end());
+                    br_ifaces_ap_instances_[ifname] = ap_instances;
+                    break;
+                }
+            }
+            break;
+        }
+    }
+    iface->removeInstance(ifInstanceName);
+    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+
+    return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> WifiChip::createNanIfaceInternal() {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::NAN_IFACE)) {
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+    }
+    bool is_dedicated_iface = true;
+    std::string ifname = getPredefinedNanIfaceName();
+    if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
+        // Use the first shared STA iface (wlan0) if a dedicated aware iface is
+        // not defined.
+        ifname = getFirstActiveWlanIfaceName();
+        is_dedicated_iface = false;
+    }
+    std::shared_ptr<WifiNanIface> iface =
+            WifiNanIface::create(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
+    nan_ifaces_.push_back(iface);
+    for (const auto& callback : event_cb_handler_.getCallbacks()) {
+        if (!callback->onIfaceAdded(IfaceType::NAN_IFACE, ifname).isOk()) {
+            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+        }
+    }
+    return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getNanIfaceNamesInternal() {
+    if (nan_ifaces_.empty()) {
+        return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
+    }
+    return {getNames(nan_ifaces_), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> WifiChip::getNanIfaceInternal(
+        const std::string& ifname) {
+    const auto iface = findUsingName(nan_ifaces_, ifname);
+    if (!iface.get()) {
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+    }
+    return {iface, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
+    const auto iface = findUsingName(nan_ifaces_, ifname);
+    if (!iface.get()) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    invalidateAndClear(nan_ifaces_, iface);
+    for (const auto& callback : event_cb_handler_.getCallbacks()) {
+        if (!callback->onIfaceRemoved(IfaceType::NAN_IFACE, ifname).isOk()) {
+            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> WifiChip::createP2pIfaceInternal() {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::P2P)) {
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+    }
+    std::string ifname = getPredefinedP2pIfaceName();
+    std::shared_ptr<WifiP2pIface> iface =
+            ndk::SharedRefBase::make<WifiP2pIface>(ifname, legacy_hal_);
+    p2p_ifaces_.push_back(iface);
+    for (const auto& callback : event_cb_handler_.getCallbacks()) {
+        if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
+            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+        }
+    }
+    return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getP2pIfaceNamesInternal() {
+    if (p2p_ifaces_.empty()) {
+        return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
+    }
+    return {getNames(p2p_ifaces_), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> WifiChip::getP2pIfaceInternal(
+        const std::string& ifname) {
+    const auto iface = findUsingName(p2p_ifaces_, ifname);
+    if (!iface.get()) {
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+    }
+    return {iface, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
+    const auto iface = findUsingName(p2p_ifaces_, ifname);
+    if (!iface.get()) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    invalidateAndClear(p2p_ifaces_, iface);
+    for (const auto& callback : event_cb_handler_.getCallbacks()) {
+        if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
+            LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> WifiChip::createStaIfaceInternal() {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+    }
+    std::string ifname = allocateStaIfaceName();
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface(
+            ifname, aidl_struct_util::convertAidlIfaceTypeToLegacy(IfaceType::STA));
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to add interface: " << ifname << " "
+                   << legacyErrorToString(legacy_status);
+        return {nullptr, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    std::shared_ptr<WifiStaIface> iface = WifiStaIface::create(ifname, legacy_hal_, iface_util_);
+    sta_ifaces_.push_back(iface);
+    for (const auto& callback : event_cb_handler_.getCallbacks()) {
+        if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
+            LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+        }
+    }
+    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+    return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getStaIfaceNamesInternal() {
+    if (sta_ifaces_.empty()) {
+        return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
+    }
+    return {getNames(sta_ifaces_), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> WifiChip::getStaIfaceInternal(
+        const std::string& ifname) {
+    const auto iface = findUsingName(sta_ifaces_, ifname);
+    if (!iface.get()) {
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+    }
+    return {iface, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
+    const auto iface = findUsingName(sta_ifaces_, ifname);
+    if (!iface.get()) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    // Invalidate & remove any dependent objects first.
+    invalidateAndRemoveDependencies(ifname);
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to remove interface: " << ifname << " "
+                   << legacyErrorToString(legacy_status);
+    }
+    invalidateAndClear(sta_ifaces_, iface);
+    for (const auto& callback : event_cb_handler_.getCallbacks()) {
+        if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
+            LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+        }
+    }
+    setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+    return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<IWifiRttController>, ndk::ScopedAStatus>
+WifiChip::createRttControllerInternal(const std::shared_ptr<IWifiStaIface>& bound_iface) {
+    if (sta_ifaces_.size() == 0 &&
+        !canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
+        LOG(ERROR) << "createRttControllerInternal: Chip cannot support STAs "
+                      "(and RTT by extension)";
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+    }
+    std::shared_ptr<WifiRttController> rtt =
+            WifiRttController::create(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
+    rtt_controllers_.emplace_back(rtt);
+    return {rtt, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<WifiDebugRingBufferStatus>, ndk::ScopedAStatus>
+WifiChip::getDebugRingBuffersStatusInternal() {
+    legacy_hal::wifi_error legacy_status;
+    std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec;
+    std::tie(legacy_status, legacy_ring_buffer_status_vec) =
+            legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {std::vector<WifiDebugRingBufferStatus>(),
+                createWifiStatusFromLegacyError(legacy_status)};
+    }
+    std::vector<WifiDebugRingBufferStatus> aidl_ring_buffer_status_vec;
+    if (!aidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToAidl(
+                legacy_ring_buffer_status_vec, &aidl_ring_buffer_status_vec)) {
+        return {std::vector<WifiDebugRingBufferStatus>(),
+                createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_ring_buffer_status_vec, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::startLoggingToDebugRingBufferInternal(
+        const std::string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+        uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
+    ndk::ScopedAStatus status = registerDebugRingBufferCallback();
+    if (!status.isOk()) {
+        return status;
+    }
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging(
+            getFirstActiveWlanIfaceName(), ring_name,
+            static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level),
+            max_interval_in_sec, min_data_size_in_bytes);
+    ringbuffer_map_.insert(
+            std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes)));
+    // if verbose logging enabled, turn up HAL daemon logging as well.
+    if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
+        ::android::base::SetMinimumLogSeverity(::android::base::DEBUG);
+    } else {
+        ::android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
+    }
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::forceDumpToDebugRingBufferInternal(const std::string& ring_name) {
+    ndk::ScopedAStatus status = registerDebugRingBufferCallback();
+    if (!status.isOk()) {
+        return status;
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name);
+
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::flushRingBufferToFileInternal() {
+    if (!writeRingbufferFilesInternal()) {
+        LOG(ERROR) << "Error writing files to flash";
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName());
+    if (legacy_status == legacy_hal::WIFI_SUCCESS) {
+        debug_ring_buffer_cb_registered_ = false;
+    }
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiDebugHostWakeReasonStats, ndk::ScopedAStatus>
+WifiChip::getDebugHostWakeReasonStatsInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::WakeReasonStats legacy_stats;
+    std::tie(legacy_status, legacy_stats) =
+            legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {WifiDebugHostWakeReasonStats{}, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    WifiDebugHostWakeReasonStats aidl_stats;
+    if (!aidl_struct_util::convertLegacyWakeReasonStatsToAidl(legacy_stats, &aidl_stats)) {
+        return {WifiDebugHostWakeReasonStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_stats, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
+    legacy_hal::wifi_error legacy_status;
+    if (enable) {
+        std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
+        const auto& on_alert_callback = [weak_ptr_this](int32_t error_code,
+                                                        std::vector<uint8_t> debug_data) {
+            const auto shared_ptr_this = weak_ptr_this.lock();
+            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                LOG(ERROR) << "Callback invoked on an invalid object";
+                return;
+            }
+            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
+                    LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
+                }
+            }
+        };
+        legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
+                getFirstActiveWlanIfaceName(), on_alert_callback);
+    } else {
+        legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
+                getFirstActiveWlanIfaceName());
+    }
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::selectTxPowerScenarioInternal(IWifiChip::TxPowerScenario scenario) {
+    auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
+            getFirstActiveWlanIfaceName(),
+            aidl_struct_util::convertAidlTxPowerScenarioToLegacy(scenario));
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::resetTxPowerScenarioInternal() {
+    auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setLatencyModeInternal(IWifiChip::LatencyMode mode) {
+    auto legacy_status = legacy_hal_.lock()->setLatencyMode(
+            getFirstActiveWlanIfaceName(), aidl_struct_util::convertAidlLatencyModeToLegacy(mode));
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) {
+    auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setMultiStaUseCaseInternal(IWifiChip::MultiStaUseCase use_case) {
+    auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
+            aidl_struct_util::convertAidlMultiStaUseCaseToLegacy(use_case));
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setCoexUnsafeChannelsInternal(
+        std::vector<IWifiChip::CoexUnsafeChannel> unsafe_channels, int32_t aidl_restrictions) {
+    std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
+    if (!aidl_struct_util::convertAidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels,
+                                                                        &legacy_unsafe_channels)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    uint32_t legacy_restrictions = 0;
+    if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::WIFI_DIRECT)) {
+        legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
+    }
+    if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::SOFTAP)) {
+        legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
+    }
+    if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::WIFI_AWARE)) {
+        legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
+    }
+    auto legacy_status =
+            legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setCountryCodeInternal(const std::array<uint8_t, 2>& code) {
+    auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<std::vector<WifiUsableChannel>, ndk::ScopedAStatus> WifiChip::getUsableChannelsInternal(
+        WifiBand band, int32_t ifaceModeMask, int32_t filterMask) {
+    legacy_hal::wifi_error legacy_status;
+    std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
+    std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels(
+            aidl_struct_util::convertAidlWifiBandToLegacyMacBand(band),
+            aidl_struct_util::convertAidlWifiIfaceModeToLegacy(ifaceModeMask),
+            aidl_struct_util::convertAidlUsableChannelFilterToLegacy(filterMask));
+
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {std::vector<WifiUsableChannel>(), createWifiStatusFromLegacyError(legacy_status)};
+    }
+    std::vector<WifiUsableChannel> aidl_usable_channels;
+    if (!aidl_struct_util::convertLegacyWifiUsableChannelsToAidl(legacy_usable_channels,
+                                                                 &aidl_usable_channels)) {
+        return {std::vector<WifiUsableChannel>(), createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_usable_channels, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::setAfcChannelAllowanceInternal(
+        const AfcChannelAllowance& afcChannelAllowance) {
+    LOG(INFO) << "setAfcChannelAllowance is not yet supported. availableAfcFrequencyInfos size="
+              << afcChannelAllowance.availableAfcFrequencyInfos.size()
+              << " availableAfcChannelInfos size="
+              << afcChannelAllowance.availableAfcChannelInfos.size()
+              << " availabilityExpireTimeMs=" << afcChannelAllowance.availabilityExpireTimeMs;
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+std::pair<std::vector<WifiRadioCombination>, ndk::ScopedAStatus>
+WifiChip::getSupportedRadioCombinationsInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_radio_combination_matrix* legacy_matrix;
+    std::vector<WifiRadioCombination> aidl_combinations;
+
+    std::tie(legacy_status, legacy_matrix) =
+            legacy_hal_.lock()->getSupportedRadioCombinationsMatrix();
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to get SupportedRadioCombinations matrix from legacy HAL: "
+                   << legacyErrorToString(legacy_status);
+        return {aidl_combinations, createWifiStatusFromLegacyError(legacy_status)};
+    }
+
+    if (!aidl_struct_util::convertLegacyRadioCombinationsMatrixToAidl(legacy_matrix,
+                                                                      &aidl_combinations)) {
+        LOG(ERROR) << "Failed convertLegacyRadioCombinationsMatrixToAidl() ";
+        return {aidl_combinations, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+    }
+    return {aidl_combinations, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<WifiChipCapabilities, ndk::ScopedAStatus> WifiChip::getWifiChipCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_chip_capabilities legacy_chip_capabilities;
+    std::tie(legacy_status, legacy_chip_capabilities) =
+            legacy_hal_.lock()->getWifiChipCapabilities();
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to get chip capabilities from legacy HAL: "
+                   << legacyErrorToString(legacy_status);
+        return {WifiChipCapabilities(), createWifiStatusFromLegacyError(legacy_status)};
+    }
+    WifiChipCapabilities aidl_chip_capabilities;
+    if (!aidl_struct_util::convertLegacyWifiChipCapabilitiesToAidl(legacy_chip_capabilities,
+                                                                   aidl_chip_capabilities)) {
+        LOG(ERROR) << "Failed convertLegacyWifiChipCapabilitiesToAidl() ";
+        return {WifiChipCapabilities(), createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+    }
+
+    return {aidl_chip_capabilities, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::enableStaChannelForPeerNetworkInternal(
+        int32_t channelCategoryEnableFlag) {
+    auto legacy_status = legacy_hal_.lock()->enableStaChannelForPeerNetwork(
+            aidl_struct_util::convertAidlChannelCategoryToLegacy(channelCategoryEnableFlag));
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::triggerSubsystemRestartInternal() {
+    auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::handleChipConfiguration(
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, int32_t mode_id) {
+    // If the chip is already configured in a different mode, stop
+    // the legacy HAL and then start it after firmware mode change.
+    if (isValidModeId(current_mode_id_)) {
+        LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id;
+        invalidateAndRemoveAllIfaces();
+        legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {});
+        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+            LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status);
+            return createWifiStatusFromLegacyError(legacy_status);
+        }
+    }
+    // Firmware mode change not needed for V2 devices.
+    bool success = true;
+    if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
+        success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
+    } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
+        success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
+    }
+    if (!success) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status);
+        return createWifiStatusFromLegacyError(legacy_status);
+    }
+    // Every time the HAL is restarted, we need to register the
+    // radio mode change callback.
+    ndk::ScopedAStatus status = registerRadioModeChangeCallback();
+    if (!status.isOk()) {
+        // This is probably not a critical failure?
+        LOG(ERROR) << "Failed to register radio mode change callback";
+    }
+    // Extract and save the version information into property.
+    std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> version_info;
+    version_info = WifiChip::requestChipDebugInfoInternal();
+    if (version_info.second.isOk()) {
+        property_set("vendor.wlan.firmware.version",
+                     version_info.first.firmwareDescription.c_str());
+        property_set("vendor.wlan.driver.version", version_info.first.driverDescription.c_str());
+    }
+    // Get the driver supported interface combination.
+    retrieveDynamicIfaceCombination();
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiChip::registerDebugRingBufferCallback() {
+    if (debug_ring_buffer_cb_registered_) {
+        return ndk::ScopedAStatus::ok();
+    }
+
+    std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
+    const auto& on_ring_buffer_data_callback =
+            [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data,
+                            const legacy_hal::wifi_ring_buffer_status& status) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                WifiDebugRingBufferStatus aidl_status;
+                Ringbuffer::AppendStatus appendstatus;
+                if (!aidl_struct_util::convertLegacyDebugRingBufferStatusToAidl(status,
+                                                                                &aidl_status)) {
+                    LOG(ERROR) << "Error converting ring buffer status";
+                    return;
+                }
+                {
+                    std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
+                    const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
+                    if (target != shared_ptr_this->ringbuffer_map_.end()) {
+                        Ringbuffer& cur_buffer = target->second;
+                        appendstatus = cur_buffer.append(data);
+                    } else {
+                        LOG(ERROR) << "Ringname " << name << " not found";
+                        return;
+                    }
+                    // unique_lock unlocked here
+                }
+                if (appendstatus == Ringbuffer::AppendStatus::FAIL_RING_BUFFER_CORRUPTED) {
+                    LOG(ERROR) << "Ringname " << name << " is corrupted. Clear the ring buffer";
+                    shared_ptr_this->writeRingbufferFilesInternal();
+                    return;
+                }
+            };
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler(
+            getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
+
+    if (legacy_status == legacy_hal::WIFI_SUCCESS) {
+        debug_ring_buffer_cb_registered_ = true;
+    }
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::registerRadioModeChangeCallback() {
+    std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
+    const auto& on_radio_mode_change_callback =
+            [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
+                if (!aidl_struct_util::convertLegacyWifiMacInfosToAidl(mac_infos,
+                                                                       &aidl_radio_mode_infos)) {
+                    LOG(ERROR) << "Error converting wifi mac info";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->onRadioModeChange(aidl_radio_mode_infos).isOk()) {
+                        LOG(ERROR) << "Failed to invoke onRadioModeChange callback";
+                    }
+                }
+            };
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
+                    getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::vector<IWifiChip::ChipConcurrencyCombination>
+WifiChip::getCurrentModeConcurrencyCombinations() {
+    if (!isValidModeId(current_mode_id_)) {
+        LOG(ERROR) << "Chip not configured in a mode yet";
+        return std::vector<IWifiChip::ChipConcurrencyCombination>();
+    }
+    for (const auto& mode : modes_) {
+        if (mode.id == current_mode_id_) {
+            return mode.availableCombinations;
+        }
+    }
+    CHECK(0) << "Expected to find concurrency combinations for current mode!";
+    return std::vector<IWifiChip::ChipConcurrencyCombination>();
+}
+
+// Returns a map indexed by IfaceConcurrencyType with the number of ifaces currently
+// created of the corresponding concurrency type.
+std::map<IfaceConcurrencyType, size_t> WifiChip::getCurrentConcurrencyCombination() {
+    std::map<IfaceConcurrencyType, size_t> iface_counts;
+    uint32_t num_ap = 0;
+    uint32_t num_ap_bridged = 0;
+    for (const auto& ap_iface : ap_ifaces_) {
+        std::string ap_iface_name = ap_iface->getName();
+        if (br_ifaces_ap_instances_.count(ap_iface_name) > 0 &&
+            br_ifaces_ap_instances_[ap_iface_name].size() > 1) {
+            num_ap_bridged++;
+        } else {
+            num_ap++;
+        }
+    }
+    iface_counts[IfaceConcurrencyType::AP] = num_ap;
+    iface_counts[IfaceConcurrencyType::AP_BRIDGED] = num_ap_bridged;
+    iface_counts[IfaceConcurrencyType::NAN_IFACE] = nan_ifaces_.size();
+    iface_counts[IfaceConcurrencyType::P2P] = p2p_ifaces_.size();
+    iface_counts[IfaceConcurrencyType::STA] = sta_ifaces_.size();
+    return iface_counts;
+}
+
+// This expands the provided concurrency combinations to a more parseable
+// form. Returns a vector of available combinations possible with the number
+// of each concurrency type in the combination.
+// This method is a port of HalDeviceManager.expandConcurrencyCombos() from framework.
+std::vector<std::map<IfaceConcurrencyType, size_t>> WifiChip::expandConcurrencyCombinations(
+        const IWifiChip::ChipConcurrencyCombination& combination) {
+    int32_t num_expanded_combos = 1;
+    for (const auto& limit : combination.limits) {
+        for (int32_t i = 0; i < limit.maxIfaces; i++) {
+            num_expanded_combos *= limit.types.size();
+        }
+    }
+
+    // Allocate the vector of expanded combos and reset all concurrency type counts to 0
+    // in each combo.
+    std::vector<std::map<IfaceConcurrencyType, size_t>> expanded_combos;
+    expanded_combos.resize(num_expanded_combos);
+    for (auto& expanded_combo : expanded_combos) {
+        for (const auto type : {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
+                                IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P,
+                                IfaceConcurrencyType::STA}) {
+            expanded_combo[type] = 0;
+        }
+    }
+    int32_t span = num_expanded_combos;
+    for (const auto& limit : combination.limits) {
+        for (int32_t i = 0; i < limit.maxIfaces; i++) {
+            span /= limit.types.size();
+            for (int32_t k = 0; k < num_expanded_combos; ++k) {
+                const auto iface_type = limit.types[(k / span) % limit.types.size()];
+                expanded_combos[k][iface_type]++;
+            }
+        }
+    }
+    return expanded_combos;
+}
+
+bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
+        const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+        IfaceConcurrencyType requested_type) {
+    const auto current_combo = getCurrentConcurrencyCombination();
+
+    // Check if we have space for 1 more iface of |type| in this combo
+    for (const auto type :
+         {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
+          IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
+        size_t num_ifaces_needed = current_combo.at(type);
+        if (type == requested_type) {
+            num_ifaces_needed++;
+        }
+        size_t num_ifaces_allowed = expanded_combo.at(type);
+        if (num_ifaces_needed > num_ifaces_allowed) {
+            return false;
+        }
+    }
+    return true;
+}
+
+// This method does the following:
+// a) Enumerate all possible concurrency combos by expanding the current
+//    ChipConcurrencyCombination.
+// b) Check if the requested concurrency type can be added to the current mode
+//    with the concurrency combination that is already active.
+bool WifiChip::canCurrentModeSupportConcurrencyTypeWithCurrentTypes(
+        IfaceConcurrencyType requested_type) {
+    if (!isValidModeId(current_mode_id_)) {
+        LOG(ERROR) << "Chip not configured in a mode yet";
+        return false;
+    }
+    const auto combinations = getCurrentModeConcurrencyCombinations();
+    for (const auto& combination : combinations) {
+        const auto expanded_combos = expandConcurrencyCombinations(combination);
+        for (const auto& expanded_combo : expanded_combos) {
+            if (canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(expanded_combo,
+                                                                                  requested_type)) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+// Note: This does not consider concurrency types already active. It only checks if the
+// provided expanded concurrency combination can support the requested combo.
+bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyCombo(
+        const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+        const std::map<IfaceConcurrencyType, size_t>& req_combo) {
+    // Check if we have space for 1 more |type| in this combo
+    for (const auto type :
+         {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
+          IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
+        if (req_combo.count(type) == 0) {
+            // Concurrency type not in the req_combo.
+            continue;
+        }
+        size_t num_ifaces_needed = req_combo.at(type);
+        size_t num_ifaces_allowed = expanded_combo.at(type);
+        if (num_ifaces_needed > num_ifaces_allowed) {
+            return false;
+        }
+    }
+    return true;
+}
+
+// This method does the following:
+// a) Enumerate all possible concurrency combos by expanding the current
+//    ChipConcurrencyCombination.
+// b) Check if the requested concurrency combo can be added to the current mode.
+// Note: This does not consider concurrency types already active. It only checks if the
+// current mode can support the requested combo.
+bool WifiChip::canCurrentModeSupportConcurrencyCombo(
+        const std::map<IfaceConcurrencyType, size_t>& req_combo) {
+    if (!isValidModeId(current_mode_id_)) {
+        LOG(ERROR) << "Chip not configured in a mode yet";
+        return false;
+    }
+    const auto combinations = getCurrentModeConcurrencyCombinations();
+    for (const auto& combination : combinations) {
+        const auto expanded_combos = expandConcurrencyCombinations(combination);
+        for (const auto& expanded_combo : expanded_combos) {
+            if (canExpandedConcurrencyComboSupportConcurrencyCombo(expanded_combo, req_combo)) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+// This method does the following:
+// a) Enumerate all possible concurrency combos by expanding the current
+//    ChipConcurrencyCombination.
+// b) Check if the requested concurrency type can be added to the current mode.
+bool WifiChip::canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type) {
+    // Check if we can support at least 1 of the requested concurrency type.
+    std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+    req_iface_combo[requested_type] = 1;
+    return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
+}
+
+bool WifiChip::isValidModeId(int32_t mode_id) {
+    for (const auto& mode : modes_) {
+        if (mode.id == mode_id) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
+    // Check if we can support at least 1 STA & 1 AP concurrently.
+    std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+    req_iface_combo[IfaceConcurrencyType::STA] = 1;
+    req_iface_combo[IfaceConcurrencyType::AP] = 1;
+    return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
+}
+
+bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
+    // Check if we can support at least 2 STA concurrently.
+    std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+    req_iface_combo[IfaceConcurrencyType::STA] = 2;
+    return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
+}
+
+std::string WifiChip::getFirstActiveWlanIfaceName() {
+    if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
+    if (ap_ifaces_.size() > 0) {
+        // If the first active wlan iface is bridged iface.
+        // Return first instance name.
+        for (auto const& it : br_ifaces_ap_instances_) {
+            if (it.first == ap_ifaces_[0]->getName()) {
+                return it.second[0];
+            }
+        }
+        return ap_ifaces_[0]->getName();
+    }
+    // This could happen if the chip call is made before any STA/AP
+    // iface is created. Default to wlan0 for such cases.
+    LOG(WARNING) << "No active wlan interfaces in use! Using default";
+    return getWlanIfaceNameWithType(IfaceType::STA, 0);
+}
+
+// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
+// not already in use.
+// Note: This doesn't check the actual presence of these interfaces.
+std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) {
+    for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
+        const auto ifname = getWlanIfaceNameWithType(type, idx);
+        if (findUsingNameFromBridgedApInstances(ifname)) continue;
+        if (findUsingName(ap_ifaces_, ifname)) continue;
+        if (findUsingName(sta_ifaces_, ifname)) continue;
+        return ifname;
+    }
+    // This should never happen. We screwed up somewhere if it did.
+    CHECK(false) << "All wlan interfaces in use already!";
+    return {};
+}
+
+uint32_t WifiChip::startIdxOfApIface() {
+    if (isDualStaConcurrencyAllowedInCurrentMode()) {
+        // When the HAL support dual STAs, AP should start with idx 2.
+        return 2;
+    } else if (isStaApConcurrencyAllowedInCurrentMode()) {
+        //  When the HAL support STA + AP but it doesn't support dual STAs.
+        //  AP should start with idx 1.
+        return 1;
+    }
+    // No concurrency support.
+    return 0;
+}
+
+// AP iface names start with idx 1 for modes supporting
+// concurrent STA and not dual AP, else start with idx 0.
+std::string WifiChip::allocateApIfaceName() {
+    // Check if we have a dedicated iface for AP.
+    std::vector<std::string> ifnames = getPredefinedApIfaceNames(true);
+    for (auto const& ifname : ifnames) {
+        if (findUsingName(ap_ifaces_, ifname)) continue;
+        return ifname;
+    }
+    return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
+}
+
+std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
+    // Check if we have a dedicated iface for AP.
+    std::vector<std::string> instances = getPredefinedApIfaceNames(true);
+    if (instances.size() == 2) {
+        return instances;
+    } else {
+        int num_ifaces_need_to_allocate = 2 - instances.size();
+        for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
+            std::string instance_name =
+                    allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i);
+            if (!instance_name.empty()) {
+                instances.push_back(instance_name);
+            }
+        }
+    }
+    return instances;
+}
+
+// STA iface names start with idx 0.
+// Primary STA iface will always be 0.
+std::string WifiChip::allocateStaIfaceName() {
+    return allocateApOrStaIfaceName(IfaceType::STA, 0);
+}
+
+bool WifiChip::writeRingbufferFilesInternal() {
+    if (!removeOldFilesInternal()) {
+        LOG(ERROR) << "Error occurred while deleting old tombstone files";
+        return false;
+    }
+    // write ringbuffers to file
+    {
+        std::unique_lock<std::mutex> lk(lock_t);
+        for (auto& item : ringbuffer_map_) {
+            Ringbuffer& cur_buffer = item.second;
+            if (cur_buffer.getData().empty()) {
+                continue;
+            }
+            const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX";
+            const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
+            if (dump_fd == -1) {
+                PLOG(ERROR) << "create file failed";
+                return false;
+            }
+            unique_fd file_auto_closer(dump_fd);
+            for (const auto& cur_block : cur_buffer.getData()) {
+                if (cur_block.size() <= 0 || cur_block.size() > kMaxBufferSizeBytes) {
+                    PLOG(ERROR) << "Ring buffer: " << item.first
+                                << " is corrupted. Invalid block size: " << cur_block.size();
+                    break;
+                }
+                if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) ==
+                    -1) {
+                    PLOG(ERROR) << "Error writing to file";
+                }
+            }
+            cur_buffer.clear();
+        }
+        // unique_lock unlocked here
+    }
+    return true;
+}
+
+std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
+    std::string ifname;
+
+    // let the legacy hal override the interface name
+    legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
+    if (err == legacy_hal::WIFI_SUCCESS) return ifname;
+
+    return getWlanIfaceName(idx);
+}
+
+void WifiChip::invalidateAndClearBridgedApAll() {
+    for (auto const& it : br_ifaces_ap_instances_) {
+        for (auto const& iface : it.second) {
+            iface_util_->removeIfaceFromBridge(it.first, iface);
+            legacy_hal_.lock()->deleteVirtualInterface(iface);
+        }
+        iface_util_->deleteBridge(it.first);
+    }
+    br_ifaces_ap_instances_.clear();
+}
+
+void WifiChip::deleteApIface(const std::string& if_name) {
+    if (if_name.empty()) return;
+    // delete bridged interfaces if any
+    for (auto const& it : br_ifaces_ap_instances_) {
+        if (it.first == if_name) {
+            for (auto const& iface : it.second) {
+                iface_util_->removeIfaceFromBridge(if_name, iface);
+                legacy_hal_.lock()->deleteVirtualInterface(iface);
+            }
+            iface_util_->deleteBridge(if_name);
+            br_ifaces_ap_instances_.erase(if_name);
+            // ifname is bridged AP, return here.
+            return;
+        }
+    }
+
+    // No bridged AP case, delete AP iface
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(if_name);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to remove interface: " << if_name << " "
+                   << legacyErrorToString(legacy_status);
+    }
+}
+
+bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
+    for (auto const& it : br_ifaces_ap_instances_) {
+        if (it.first == name) {
+            return true;
+        }
+        for (auto const& iface : it.second) {
+            if (iface == name) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+ndk::ScopedAStatus WifiChip::setMloModeInternal(const WifiChip::ChipMloMode in_mode) {
+    legacy_hal::wifi_mlo_mode mode;
+    switch (in_mode) {
+        case WifiChip::ChipMloMode::DEFAULT:
+            mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_DEFAULT;
+            break;
+        case WifiChip::ChipMloMode::LOW_LATENCY:
+            mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_LOW_LATENCY;
+            break;
+        case WifiChip::ChipMloMode::HIGH_THROUGHPUT:
+            mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_HIGH_THROUGHPUT;
+            break;
+        case WifiChip::ChipMloMode::LOW_POWER:
+            mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_LOW_POWER;
+            break;
+        default:
+            PLOG(ERROR) << "Error: invalid mode: " << toString(in_mode);
+            return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    return createWifiStatusFromLegacyError(legacy_hal_.lock()->setMloMode(mode));
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
new file mode 100644
index 0000000..1a36032
--- /dev/null
+++ b/wifi/aidl/default/wifi_chip.h
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_CHIP_H_
+#define WIFI_CHIP_H_
+
+#include <aidl/android/hardware/wifi/BnWifiChip.h>
+#include <aidl/android/hardware/wifi/IWifiRttController.h>
+#include <android-base/macros.h>
+
+#include <list>
+#include <map>
+#include <mutex>
+
+#include "aidl_callback_util.h"
+#include "ringbuffer.h"
+#include "wifi_ap_iface.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_mode_controller.h"
+#include "wifi_nan_iface.h"
+#include "wifi_p2p_iface.h"
+#include "wifi_rtt_controller.h"
+#include "wifi_sta_iface.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control a Wifi HAL chip instance.
+ * Since there is only a single chip instance used today, there is no
+ * identifying handle information stored here.
+ */
+class WifiChip : public BnWifiChip {
+  public:
+    WifiChip(int32_t chip_id, bool is_primary,
+             const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+             const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+             const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+             const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+             const std::function<void(const std::string&)>& subsystemCallbackHandler,
+             bool using_dynamic_iface_combination);
+
+    // Factory method - use instead of default constructor.
+    static std::shared_ptr<WifiChip> create(
+            int32_t chip_id, bool is_primary,
+            const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+            const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+            const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+            const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+            const std::function<void(const std::string&)>& subsystemCallbackHandler,
+            bool using_dynamic_iface_combination);
+
+    // AIDL does not provide a built-in mechanism to let the server invalidate
+    // an AIDL interface object after creation. If any client process holds onto
+    // a reference to the object in their context, any method calls on that
+    // reference will continue to be directed to the server.
+    //
+    // However Wifi HAL needs to control the lifetime of these objects. So, add
+    // a public |invalidate| method to |WifiChip| and its child objects. This
+    // will be used to mark an object invalid when either:
+    // a) Wifi HAL is stopped, or
+    // b) Wifi Chip is reconfigured.
+    //
+    // All AIDL method implementations should check if the object is still
+    // marked valid before processing them.
+    void invalidate();
+    bool isValid();
+    std::set<std::shared_ptr<IWifiChipEventCallback>> getEventCallbacks();
+
+    // AIDL methods exposed.
+    ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus registerEventCallback(
+            const std::shared_ptr<IWifiChipEventCallback>& in_callback) override;
+    ndk::ScopedAStatus getFeatureSet(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getAvailableModes(std::vector<IWifiChip::ChipMode>* _aidl_return) override;
+    ndk::ScopedAStatus configureChip(int32_t in_modeId) override;
+    ndk::ScopedAStatus getMode(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus requestChipDebugInfo(IWifiChip::ChipDebugInfo* _aidl_return) override;
+    ndk::ScopedAStatus requestDriverDebugDump(std::vector<uint8_t>* _aidl_return) override;
+    ndk::ScopedAStatus requestFirmwareDebugDump(std::vector<uint8_t>* _aidl_return) override;
+    ndk::ScopedAStatus createApIface(std::shared_ptr<IWifiApIface>* _aidl_return) override;
+    ndk::ScopedAStatus createBridgedApIface(std::shared_ptr<IWifiApIface>* _aidl_return) override;
+    ndk::ScopedAStatus getApIfaceNames(std::vector<std::string>* _aidl_return) override;
+    ndk::ScopedAStatus getApIface(const std::string& in_ifname,
+                                  std::shared_ptr<IWifiApIface>* _aidl_return) override;
+    ndk::ScopedAStatus removeApIface(const std::string& in_ifname) override;
+    ndk::ScopedAStatus removeIfaceInstanceFromBridgedApIface(
+            const std::string& in_brIfaceName, const std::string& in_ifaceInstanceName) override;
+    ndk::ScopedAStatus createNanIface(std::shared_ptr<IWifiNanIface>* _aidl_return) override;
+    ndk::ScopedAStatus getNanIfaceNames(std::vector<std::string>* _aidl_return) override;
+    ndk::ScopedAStatus getNanIface(const std::string& in_ifname,
+                                   std::shared_ptr<IWifiNanIface>* _aidl_return) override;
+    ndk::ScopedAStatus removeNanIface(const std::string& in_ifname) override;
+    ndk::ScopedAStatus createP2pIface(std::shared_ptr<IWifiP2pIface>* _aidl_return) override;
+    ndk::ScopedAStatus getP2pIfaceNames(std::vector<std::string>* _aidl_return) override;
+    ndk::ScopedAStatus getP2pIface(const std::string& in_ifname,
+                                   std::shared_ptr<IWifiP2pIface>* _aidl_return) override;
+    ndk::ScopedAStatus removeP2pIface(const std::string& in_ifname) override;
+    ndk::ScopedAStatus createStaIface(std::shared_ptr<IWifiStaIface>* _aidl_return) override;
+    ndk::ScopedAStatus getStaIfaceNames(std::vector<std::string>* _aidl_return) override;
+    ndk::ScopedAStatus getStaIface(const std::string& in_ifname,
+                                   std::shared_ptr<IWifiStaIface>* _aidl_return) override;
+    ndk::ScopedAStatus removeStaIface(const std::string& in_ifname) override;
+    ndk::ScopedAStatus createRttController(
+            const std::shared_ptr<IWifiStaIface>& in_boundIface,
+            std::shared_ptr<IWifiRttController>* _aidl_return) override;
+    ndk::ScopedAStatus getDebugRingBuffersStatus(
+            std::vector<WifiDebugRingBufferStatus>* _aidl_return) override;
+    ndk::ScopedAStatus startLoggingToDebugRingBuffer(
+            const std::string& in_ringName, WifiDebugRingBufferVerboseLevel in_verboseLevel,
+            int32_t in_maxIntervalInSec, int32_t in_minDataSizeInBytes) override;
+    ndk::ScopedAStatus forceDumpToDebugRingBuffer(const std::string& in_ringName) override;
+    ndk::ScopedAStatus flushRingBufferToFile() override;
+    ndk::ScopedAStatus stopLoggingToDebugRingBuffer() override;
+    ndk::ScopedAStatus getDebugHostWakeReasonStats(
+            WifiDebugHostWakeReasonStats* _aidl_return) override;
+    ndk::ScopedAStatus enableDebugErrorAlerts(bool in_enable) override;
+    ndk::ScopedAStatus selectTxPowerScenario(IWifiChip::TxPowerScenario in_scenario) override;
+    ndk::ScopedAStatus resetTxPowerScenario() override;
+    ndk::ScopedAStatus setLatencyMode(IWifiChip::LatencyMode in_mode) override;
+    ndk::ScopedAStatus setMultiStaPrimaryConnection(const std::string& in_ifName) override;
+    ndk::ScopedAStatus setMultiStaUseCase(IWifiChip::MultiStaUseCase in_useCase) override;
+    ndk::ScopedAStatus setCoexUnsafeChannels(
+            const std::vector<IWifiChip::CoexUnsafeChannel>& in_unsafeChannels,
+            int32_t in_restrictions) override;
+    ndk::ScopedAStatus setCountryCode(const std::array<uint8_t, 2>& in_code) override;
+    ndk::ScopedAStatus getUsableChannels(WifiBand in_band, int32_t in_ifaceModeMask,
+                                         int32_t in_filterMask,
+                                         std::vector<WifiUsableChannel>* _aidl_return) override;
+    ndk::ScopedAStatus setAfcChannelAllowance(
+            const AfcChannelAllowance& afcChannelAllowance) override;
+    ndk::ScopedAStatus triggerSubsystemRestart() override;
+    ndk::ScopedAStatus getSupportedRadioCombinations(
+            std::vector<WifiRadioCombination>* _aidl_return) override;
+    ndk::ScopedAStatus getWifiChipCapabilities(WifiChipCapabilities* _aidl_return) override;
+    ndk::ScopedAStatus enableStaChannelForPeerNetwork(
+            int32_t in_channelCategoryEnableFlag) override;
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+    ndk::ScopedAStatus setMloMode(const ChipMloMode in_mode) override;
+
+  private:
+    void invalidateAndRemoveAllIfaces();
+    // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
+    // invalidated & removed.
+    void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
+
+    // Corresponding worker functions for the AIDL methods.
+    std::pair<int32_t, ndk::ScopedAStatus> getIdInternal();
+    ndk::ScopedAStatus registerEventCallbackInternal(
+            const std::shared_ptr<IWifiChipEventCallback>& event_callback);
+    std::pair<int32_t, ndk::ScopedAStatus> getFeatureSetInternal();
+    std::pair<std::vector<IWifiChip::ChipMode>, ndk::ScopedAStatus> getAvailableModesInternal();
+    ndk::ScopedAStatus configureChipInternal(std::unique_lock<std::recursive_mutex>* lock,
+                                             int32_t mode_id);
+    std::pair<int32_t, ndk::ScopedAStatus> getModeInternal();
+    std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> requestChipDebugInfoInternal();
+    std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> requestDriverDebugDumpInternal();
+    std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> requestFirmwareDebugDumpInternal();
+    std::shared_ptr<WifiApIface> newWifiApIface(std::string& ifname);
+    ndk::ScopedAStatus createVirtualApInterface(const std::string& apVirtIf);
+    std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createApIfaceInternal();
+    std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createBridgedApIfaceInternal();
+    std::pair<std::vector<std::string>, ndk::ScopedAStatus> getApIfaceNamesInternal();
+    std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> getApIfaceInternal(
+            const std::string& ifname);
+    ndk::ScopedAStatus removeApIfaceInternal(const std::string& ifname);
+    ndk::ScopedAStatus removeIfaceInstanceFromBridgedApIfaceInternal(
+            const std::string& brIfaceName, const std::string& ifInstanceName);
+    std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> createNanIfaceInternal();
+    std::pair<std::vector<std::string>, ndk::ScopedAStatus> getNanIfaceNamesInternal();
+    std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> getNanIfaceInternal(
+            const std::string& ifname);
+    ndk::ScopedAStatus removeNanIfaceInternal(const std::string& ifname);
+    std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> createP2pIfaceInternal();
+    std::pair<std::vector<std::string>, ndk::ScopedAStatus> getP2pIfaceNamesInternal();
+    std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> getP2pIfaceInternal(
+            const std::string& ifname);
+    ndk::ScopedAStatus removeP2pIfaceInternal(const std::string& ifname);
+    std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> createStaIfaceInternal();
+    std::pair<std::vector<std::string>, ndk::ScopedAStatus> getStaIfaceNamesInternal();
+    std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> getStaIfaceInternal(
+            const std::string& ifname);
+    ndk::ScopedAStatus removeStaIfaceInternal(const std::string& ifname);
+    std::pair<std::shared_ptr<IWifiRttController>, ndk::ScopedAStatus> createRttControllerInternal(
+            const std::shared_ptr<IWifiStaIface>& bound_iface);
+    std::pair<std::vector<WifiDebugRingBufferStatus>, ndk::ScopedAStatus>
+    getDebugRingBuffersStatusInternal();
+    ndk::ScopedAStatus startLoggingToDebugRingBufferInternal(
+            const std::string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+            uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes);
+    ndk::ScopedAStatus forceDumpToDebugRingBufferInternal(const std::string& ring_name);
+    ndk::ScopedAStatus flushRingBufferToFileInternal();
+    ndk::ScopedAStatus stopLoggingToDebugRingBufferInternal();
+    std::pair<WifiDebugHostWakeReasonStats, ndk::ScopedAStatus>
+    getDebugHostWakeReasonStatsInternal();
+    ndk::ScopedAStatus enableDebugErrorAlertsInternal(bool enable);
+    ndk::ScopedAStatus selectTxPowerScenarioInternal(IWifiChip::TxPowerScenario scenario);
+    ndk::ScopedAStatus resetTxPowerScenarioInternal();
+    ndk::ScopedAStatus setLatencyModeInternal(IWifiChip::LatencyMode mode);
+    ndk::ScopedAStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
+    ndk::ScopedAStatus setMultiStaUseCaseInternal(IWifiChip::MultiStaUseCase use_case);
+    ndk::ScopedAStatus setCoexUnsafeChannelsInternal(
+            std::vector<IWifiChip::CoexUnsafeChannel> unsafe_channels, int32_t restrictions);
+    ndk::ScopedAStatus setCountryCodeInternal(const std::array<uint8_t, 2>& in_code);
+    std::pair<std::vector<WifiUsableChannel>, ndk::ScopedAStatus> getUsableChannelsInternal(
+            WifiBand band, int32_t ifaceModeMask, int32_t filterMask);
+    ndk::ScopedAStatus enableStaChannelForPeerNetworkInternal(int32_t channelCategoryEnableFlag);
+    ndk::ScopedAStatus setAfcChannelAllowanceInternal(
+            const AfcChannelAllowance& afcChannelAllowance);
+    ndk::ScopedAStatus handleChipConfiguration(std::unique_lock<std::recursive_mutex>* lock,
+                                               int32_t mode_id);
+    ndk::ScopedAStatus registerDebugRingBufferCallback();
+    ndk::ScopedAStatus registerRadioModeChangeCallback();
+
+    std::vector<ChipConcurrencyCombination> getCurrentModeConcurrencyCombinations();
+    std::map<IfaceConcurrencyType, size_t> getCurrentConcurrencyCombination();
+    std::vector<std::map<IfaceConcurrencyType, size_t>> expandConcurrencyCombinations(
+            const ChipConcurrencyCombination& combination);
+    bool canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
+            const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+            IfaceConcurrencyType requested_type);
+    bool canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType requested_type);
+    bool canExpandedConcurrencyComboSupportConcurrencyCombo(
+            const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+            const std::map<IfaceConcurrencyType, size_t>& req_combo);
+    bool canCurrentModeSupportConcurrencyCombo(
+            const std::map<IfaceConcurrencyType, size_t>& req_combo);
+    bool canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type);
+
+    bool isValidModeId(int32_t mode_id);
+    bool isStaApConcurrencyAllowedInCurrentMode();
+    bool isDualStaConcurrencyAllowedInCurrentMode();
+    uint32_t startIdxOfApIface();
+    std::string getFirstActiveWlanIfaceName();
+    std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx);
+    std::string allocateApIfaceName();
+    std::vector<std::string> allocateBridgedApInstanceNames();
+    std::string allocateStaIfaceName();
+    bool writeRingbufferFilesInternal();
+    std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx);
+    void invalidateAndClearBridgedApAll();
+    void deleteApIface(const std::string& if_name);
+    bool findUsingNameFromBridgedApInstances(const std::string& name);
+    ndk::ScopedAStatus triggerSubsystemRestartInternal();
+    std::pair<std::vector<WifiRadioCombination>, ndk::ScopedAStatus>
+    getSupportedRadioCombinationsInternal();
+    std::pair<WifiChipCapabilities, ndk::ScopedAStatus> getWifiChipCapabilitiesInternal();
+    ndk::ScopedAStatus setMloModeInternal(const ChipMloMode in_mode);
+    void retrieveDynamicIfaceCombination();
+    void setWeakPtr(std::weak_ptr<WifiChip> ptr);
+
+    int32_t chip_id_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
+    std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
+    std::vector<std::shared_ptr<WifiApIface>> ap_ifaces_;
+    std::vector<std::shared_ptr<WifiNanIface>> nan_ifaces_;
+    std::vector<std::shared_ptr<WifiP2pIface>> p2p_ifaces_;
+    std::vector<std::shared_ptr<WifiStaIface>> sta_ifaces_;
+    std::vector<std::shared_ptr<WifiRttController>> rtt_controllers_;
+    std::map<std::string, Ringbuffer> ringbuffer_map_;
+    bool is_valid_;
+    // Members pertaining to chip configuration.
+    int32_t current_mode_id_;
+    std::mutex lock_t;
+    std::vector<IWifiChip::ChipMode> modes_;
+    // The legacy ring buffer callback API has only a global callback
+    // registration mechanism. Use this to check if we have already
+    // registered a callback.
+    bool debug_ring_buffer_cb_registered_;
+    bool using_dynamic_iface_combination_;
+    aidl_callback_util::AidlCallbackHandler<IWifiChipEventCallback> event_cb_handler_;
+    std::weak_ptr<WifiChip> weak_ptr_this_;
+
+    const std::function<void(const std::string&)> subsystemCallbackHandler_;
+    std::map<std::string, std::vector<std::string>> br_ifaces_ap_instances_;
+    DISALLOW_COPY_AND_ASSIGN(WifiChip);
+};
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_CHIP_H_
diff --git a/wifi/aidl/default/wifi_feature_flags.cpp b/wifi/aidl/default/wifi_feature_flags.cpp
new file mode 100644
index 0000000..3c9f042
--- /dev/null
+++ b/wifi/aidl/default/wifi_feature_flags.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include "wifi_feature_flags.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace feature_flags {
+
+/* The chip may either have a single mode supporting any number of combinations,
+ * or a fixed dual-mode (so it involves firmware loading to switch between
+ * modes) setting. If there is a need to support more modes, it needs to be
+ * implemented manually in WiFi HAL (see changeFirmwareMode in
+ * WifiChip::handleChipConfiguration).
+ *
+ * Supported combinations are defined in device's makefile, for example:
+ *    WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}},
+ *    WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}}
+ * What this means:
+ *    Interface concurrency combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface
+ *                             operations.
+ *    Interface concurrency combination 2: 1 STA and 2 AP concurrent iface operations.
+ *
+ * For backward compatibility, the following makefile flags can be used to
+ * generate combinations list:
+ *  - WIFI_HIDL_FEATURE_DUAL_INTERFACE
+ *  - WIFI_HIDL_FEATURE_DISABLE_AP
+ *  - WIFI_HIDL_FEATURE_AWARE
+ * However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided.
+ * With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with
+ * two concurrency combinations:
+ *    Interface Concurrency Combination 1: Will support 1 STA and 1 P2P or NAN (optional)
+ *                             concurrent iface operations.
+ *    Interface Concurrency Combination 2: Will support 1 STA and 1 AP concurrent
+ *                             iface operations.
+ *
+ * The only dual-mode configuration supported is for alternating STA and AP
+ * mode, that may involve firmware reloading. In such case, there are 2 separate
+ * modes of operation with 1 concurrency combination each:
+ *    Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional)
+ *                       concurrent iface operations.
+ *    Mode 2 (AP mode): Will support 1 AP iface operation.
+ *
+ * If Aware is enabled, the concurrency combination will be modified to support either
+ * P2P or NAN in place of just P2P.
+ */
+// clang-format off
+#ifdef WIFI_HAL_INTERFACE_COMBINATIONS
+constexpr int kMainModeId = chip_mode_ids::kV3;
+#elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE)
+// former V2 (fixed dual interface) setup expressed as V3
+constexpr int kMainModeId = chip_mode_ids::kV3;
+#  ifdef WIFI_HIDL_FEATURE_DISABLE_AP
+#    ifdef WIFI_HIDL_FEATURE_AWARE
+//     1 STA + 1 of (P2P or NAN)
+#      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
+#    else
+//     1 STA + 1 P2P
+#      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
+#    endif
+#  else
+#    ifdef WIFI_HIDL_FEATURE_AWARE
+//     (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+#      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
+                                              {{{STA}, 1}, {{P2P, NAN}, 1}}
+#    else
+//     (1 STA + 1 AP) or (1 STA + 1 P2P)
+#      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
+                                              {{{STA}, 1}, {{P2P}, 1}}
+#    endif
+#  endif
+#else
+// V1 (fixed single interface, dual-mode chip)
+constexpr int kMainModeId = chip_mode_ids::kV1Sta;
+#  ifdef WIFI_HIDL_FEATURE_AWARE
+//   1 STA + 1 of (P2P or NAN)
+#    define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
+#  else
+//   1 STA + 1 P2P
+#    define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
+#  endif
+
+#  ifndef WIFI_HIDL_FEATURE_DISABLE_AP
+#    define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}}
+#  endif
+#endif
+// clang-format on
+
+// Convert from the legacy format (used by the WIFI_HAL_INTERFACE_COMBINATIONS
+// config variable) to a list of ChipConcurrencyCombination objects.
+std::vector<IWifiChip::ChipConcurrencyCombination> legacyToChipConcurrencyComboList(
+        std::vector<std::vector<IWifiChip::ChipConcurrencyCombinationLimit>> legacyLimits) {
+    std::vector<IWifiChip::ChipConcurrencyCombination> combos;
+    for (auto& legacyLimit : legacyLimits) {
+        IWifiChip::ChipConcurrencyCombination combo = {legacyLimit};
+        combos.push_back(combo);
+    }
+    return combos;
+}
+
+#define STA IfaceConcurrencyType::STA
+#define AP IfaceConcurrencyType::AP
+#define AP_BRIDGED IfaceConcurrencyType::AP_BRIDGED
+#define P2P IfaceConcurrencyType::P2P
+#define NAN IfaceConcurrencyType::NAN_IFACE
+static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
+        {kMainModeId, legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS})},
+#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
+        {chip_mode_ids::kV1Ap,
+         legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
+#endif
+};
+
+static const std::vector<IWifiChip::ChipMode> kChipModesSecondary{
+#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
+        {chip_mode_ids::kV3,
+         legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
+#endif
+};
+
+constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
+        "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
+// List of pre-defined concurrency combinations that can be enabled at runtime via
+// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
+// corresponding index value.
+static const std::vector<std::pair<std::string, std::vector<IWifiChip::ChipMode>>> kDebugChipModes{
+        // Legacy combination - No STA/AP concurrencies.
+        // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
+        {"No STA/AP Concurrency",
+         {{kMainModeId,
+           legacyToChipConcurrencyComboList({{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + AP concurrency
+        // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+        {"STA + AP Concurrency",
+         {{kMainModeId, legacyToChipConcurrencyComboList(
+                                {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + STA concurrency
+        // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
+        {"Dual STA Concurrency",
+         {{kMainModeId, legacyToChipConcurrencyComboList(
+                                {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+        // AP + AP + STA concurrency
+        // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
+        {"Dual AP Concurrency",
+         {{kMainModeId, legacyToChipConcurrencyComboList(
+                                {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + STA concurrency and AP + AP + STA concurrency
+        // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
+        {"Dual STA & Dual AP Concurrency",
+         {{kMainModeId, legacyToChipConcurrencyComboList(
+                                {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + STA concurrency
+        // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
+        {"Dual STA or STA plus single other interface",
+         {{kMainModeId, legacyToChipConcurrencyComboList(
+                                {{{{STA}, 1}, {{P2P, NAN, AP, AP_BRIDGED}, 1}}, {{{STA}, 2}}})}}}};
+
+#undef STA
+#undef AP
+#undef AP_BRIDGED
+#undef P2P
+#undef NAN
+
+#ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
+#pragma message                                                                   \
+        "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
+        "'config_wifi_ap_randomization_supported' in "                            \
+        "frameworks/base/core/res/res/values/config.xml in the device overlay "   \
+        "instead"
+#endif  // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
+
+WifiFeatureFlags::WifiFeatureFlags() {}
+
+std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
+    // Debug property not set, use the device preset concurrency combination.
+    if (res <= 0) return kChipModesPrimary;
+
+    // Debug property set, use one of the debug preset concurrency combination.
+    unsigned long idx = std::stoul(buffer.data());
+    if (idx >= kDebugChipModes.size()) {
+        LOG(ERROR) << "Invalid index set in property: "
+                   << kDebugPresetInterfaceCombinationIdxProperty;
+        return kChipModesPrimary;
+    }
+    std::string name;
+    std::vector<IWifiChip::ChipMode> chip_modes;
+    std::tie(name, chip_modes) = kDebugChipModes[idx];
+    LOG(INFO) << "Using debug chip mode: <" << name
+              << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
+    return chip_modes;
+}
+
+std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
+    return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
+}
+
+}  // namespace feature_flags
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_feature_flags.h b/wifi/aidl/default/wifi_feature_flags.h
new file mode 100644
index 0000000..af1b6a6
--- /dev/null
+++ b/wifi/aidl/default/wifi_feature_flags.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_FEATURE_FLAGS_H_
+#define WIFI_FEATURE_FLAGS_H_
+
+#include <aidl/android/hardware/wifi/IWifiChip.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace feature_flags {
+
+namespace chip_mode_ids {
+// These mode ID's should be unique (even across combo versions). Refer to
+// handleChipConfiguration() for its usage.
+constexpr uint32_t kInvalid = UINT32_MAX;
+// Mode ID's for V1
+constexpr uint32_t kV1Sta = 0;
+constexpr uint32_t kV1Ap = 1;
+// Mode ID for V3
+constexpr uint32_t kV3 = 3;
+}  // namespace chip_mode_ids
+
+class WifiFeatureFlags {
+  public:
+    WifiFeatureFlags();
+    virtual ~WifiFeatureFlags() = default;
+
+    virtual std::vector<IWifiChip::ChipMode> getChipModes(bool is_primary);
+
+  private:
+    std::vector<IWifiChip::ChipMode> getChipModesForPrimary();
+};
+
+}  // namespace feature_flags
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_FEATURE_FLAGS_H_
diff --git a/wifi/aidl/default/wifi_iface_util.cpp b/wifi/aidl/default/wifi_iface_util.cpp
new file mode 100644
index 0000000..f788217
--- /dev/null
+++ b/wifi/aidl/default/wifi_iface_util.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <net/if.h>
+#include <private/android_filesystem_config.h>
+
+#include <cstddef>
+#include <iostream>
+#include <limits>
+#include <random>
+
+#include "wifi_iface_util.h"
+
+namespace {
+// Constants to set the local bit & clear the multicast bit.
+constexpr uint8_t kMacAddressMulticastMask = 0x01;
+constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02;
+
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+WifiIfaceUtil::WifiIfaceUtil(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+                             const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+    : iface_tool_(iface_tool),
+      legacy_hal_(legacy_hal),
+      random_mac_address_(nullptr),
+      event_handlers_map_() {}
+
+std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(const std::string& iface_name) {
+    return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str());
+}
+
+bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
+                                  const std::array<uint8_t, 6>& mac) {
+#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+    legacy_hal::wifi_error legacy_status;
+    uint64_t legacy_feature_set;
+    std::tie(legacy_status, legacy_feature_set) =
+            legacy_hal_.lock()->getSupportedFeatureSet(iface_name);
+
+    if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
+        !iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) {
+        LOG(ERROR) << "SetUpState(false) failed.";
+        return false;
+    }
+#endif
+    bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac);
+#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+    if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
+        !iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
+        LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready.";
+        // Wait for driver ready and try to set iface UP again
+        if (legacy_hal_.lock()->waitForDriverReady() != legacy_hal::WIFI_SUCCESS) {
+            LOG(ERROR) << "SetUpState(true) wait for driver ready failed.";
+            return false;
+        }
+        if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
+            LOG(ERROR) << "SetUpState(true) failed after retry.";
+            return false;
+        }
+    }
+#endif
+    IfaceEventHandlers event_handlers = {};
+    const auto it = event_handlers_map_.find(iface_name);
+    if (it != event_handlers_map_.end()) {
+        event_handlers = it->second;
+    }
+    if (event_handlers.on_state_toggle_off_on != nullptr) {
+        event_handlers.on_state_toggle_off_on(iface_name);
+    }
+    if (!success) {
+        LOG(ERROR) << "SetMacAddress failed on " << iface_name;
+    } else {
+        LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name;
+    }
+    return success;
+}
+
+std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
+    if (random_mac_address_) {
+        return *random_mac_address_.get();
+    }
+    random_mac_address_ = std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress());
+    return *random_mac_address_.get();
+}
+
+void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
+                                               IfaceEventHandlers handlers) {
+    event_handlers_map_[iface_name] = handlers;
+}
+
+void WifiIfaceUtil::unregisterIfaceEventHandlers(const std::string& iface_name) {
+    event_handlers_map_.erase(iface_name);
+}
+
+std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
+    std::array<uint8_t, 6> address = {};
+    std::random_device rd;
+    std::default_random_engine engine(rd());
+    std::uniform_int_distribution<uint8_t> dist(std::numeric_limits<uint8_t>::min(),
+                                                std::numeric_limits<uint8_t>::max());
+    for (size_t i = 0; i < address.size(); i++) {
+        address[i] = dist(engine);
+    }
+    // Set the local bit and clear the multicast bit.
+    address[0] |= kMacAddressLocallyAssignedMask;
+    address[0] &= ~kMacAddressMulticastMask;
+    return address;
+}
+
+bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) {
+    if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) {
+        LOG(ERROR) << "SetUpState to " << request_up << " failed";
+        return false;
+    }
+    return true;
+}
+
+unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) {
+    return if_nametoindex(iface_name.c_str());
+}
+
+bool WifiIfaceUtil::createBridge(const std::string& br_name) {
+    if (!iface_tool_.lock()->createBridge(br_name)) {
+        return false;
+    }
+
+    if (!iface_tool_.lock()->SetUpState(br_name.c_str(), true)) {
+        LOG(ERROR) << "bridge SetUpState(true) failed.";
+    }
+    return true;
+}
+
+bool WifiIfaceUtil::deleteBridge(const std::string& br_name) {
+    if (!iface_tool_.lock()->SetUpState(br_name.c_str(), false)) {
+        LOG(INFO) << "SetUpState(false) failed for bridge=" << br_name.c_str();
+    }
+
+    return iface_tool_.lock()->deleteBridge(br_name);
+}
+
+bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, const std::string& if_name) {
+    return iface_tool_.lock()->addIfaceToBridge(br_name, if_name);
+}
+
+bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, const std::string& if_name) {
+    return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name);
+}
+
+}  // namespace iface_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_iface_util.h b/wifi/aidl/default/wifi_iface_util.h
new file mode 100644
index 0000000..a3236a5
--- /dev/null
+++ b/wifi/aidl/default/wifi_iface_util.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_IFACE_UTIL_H_
+#define WIFI_IFACE_UTIL_H_
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <wifi_system/interface_tool.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+// Iface event handlers.
+struct IfaceEventHandlers {
+    // Callback to be invoked when the iface is set down & up for MAC address
+    // change.
+    std::function<void(const std::string& iface_name)> on_state_toggle_off_on;
+};
+
+/**
+ * Util class for common iface operations.
+ */
+class WifiIfaceUtil {
+  public:
+    WifiIfaceUtil(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+                  const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+    virtual ~WifiIfaceUtil() = default;
+
+    virtual std::array<uint8_t, 6> getFactoryMacAddress(const std::string& iface_name);
+    virtual bool setMacAddress(const std::string& iface_name, const std::array<uint8_t, 6>& mac);
+    // Get or create a random MAC address. The MAC address returned from
+    // this method will remain the same throughout the lifetime of the HAL
+    // daemon. (So, changes on every reboot)
+    virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress();
+
+    // Register for any iface event callbacks for the provided interface.
+    virtual void registerIfaceEventHandlers(const std::string& iface_name,
+                                            IfaceEventHandlers handlers);
+    virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
+    virtual bool setUpState(const std::string& iface_name, bool request_up);
+    virtual unsigned ifNameToIndex(const std::string& iface_name);
+
+    virtual bool createBridge(const std::string& br_name);
+
+    virtual bool deleteBridge(const std::string& br_name);
+
+    virtual bool addIfaceToBridge(const std::string& br_name, const std::string& if_name);
+
+    virtual bool removeIfaceFromBridge(const std::string& br_name, const std::string& if_name);
+    // Get a random MAC address.
+    virtual std::array<uint8_t, 6> createRandomMacAddress();
+
+  private:
+    std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
+    std::map<std::string, IfaceEventHandlers> event_handlers_map_;
+};
+
+}  // namespace iface_util
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_IFACE_UTIL_H_
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
new file mode 100644
index 0000000..209670b
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -0,0 +1,1943 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_legacy_hal.h"
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+#include <net/if.h>
+
+#include <array>
+#include <chrono>
+
+#include "aidl_sync_util.h"
+#include "wifi_legacy_hal_stubs.h"
+
+namespace {
+// Constants ported over from the legacy HAL calling code
+// (com_android_server_wifi_WifiNative.cpp). This will all be thrown
+// away when this shim layer is replaced by the real vendor
+// implementation.
+static constexpr uint32_t kMaxVersionStringLength = 256;
+static constexpr uint32_t kMaxCachedGscanResults = 64;
+static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
+static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
+static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
+static constexpr uint32_t kMaxRingBuffers = 10;
+static constexpr uint32_t kMaxWifiUsableChannels = 256;
+static constexpr uint32_t kMaxSupportedRadioCombinationsMatrixLength = 256;
+// Need a long timeout (1000ms) for chips that unload their driver.
+static constexpr uint32_t kMaxStopCompleteWaitMs = 1000;
+static constexpr char kDriverPropName[] = "wlan.driver.status";
+
+// Helper function to create a non-const char* for legacy Hal API's.
+std::vector<char> makeCharVec(const std::string& str) {
+    std::vector<char> vec(str.size() + 1);
+    vec.assign(str.begin(), str.end());
+    vec.push_back('\0');
+    return vec;
+}
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+// Legacy HAL functions accept "C" style function pointers, so use global
+// functions to pass to the legacy HAL function and store the corresponding
+// std::function methods to be invoked.
+//
+// Callback to be invoked once |stop| is complete
+std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
+void onAsyncStopComplete(wifi_handle handle) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_stop_complete_internal_callback) {
+        on_stop_complete_internal_callback(handle);
+        // Invalidate this callback since we don't want this firing again.
+        on_stop_complete_internal_callback = nullptr;
+    }
+}
+
+// Callback to be invoked for driver dump.
+std::function<void(char*, int)> on_driver_memory_dump_internal_callback;
+void onSyncDriverMemoryDump(char* buffer, int buffer_size) {
+    if (on_driver_memory_dump_internal_callback) {
+        on_driver_memory_dump_internal_callback(buffer, buffer_size);
+    }
+}
+
+// Callback to be invoked for firmware dump.
+std::function<void(char*, int)> on_firmware_memory_dump_internal_callback;
+void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) {
+    if (on_firmware_memory_dump_internal_callback) {
+        on_firmware_memory_dump_internal_callback(buffer, buffer_size);
+    }
+}
+
+// Callback to be invoked for Gscan events.
+std::function<void(wifi_request_id, wifi_scan_event)> on_gscan_event_internal_callback;
+void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_gscan_event_internal_callback) {
+        on_gscan_event_internal_callback(id, event);
+    }
+}
+
+// Callback to be invoked for Gscan full results.
+std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
+        on_gscan_full_result_internal_callback;
+void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result,
+                            uint32_t buckets_scanned) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_gscan_full_result_internal_callback) {
+        on_gscan_full_result_internal_callback(id, result, buckets_scanned);
+    }
+}
+
+// Callback to be invoked for link layer stats results.
+std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
+        on_link_layer_stats_result_internal_callback;
+void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios,
+                                wifi_radio_stat* radio_stat) {
+    if (on_link_layer_stats_result_internal_callback) {
+        on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, radio_stat);
+    }
+}
+
+// Callback to be invoked for Multi link layer stats results.
+std::function<void((wifi_request_id, wifi_iface_ml_stat*, int, wifi_radio_stat*))>
+        on_link_layer_ml_stats_result_internal_callback;
+void onSyncLinkLayerMlStatsResult(wifi_request_id id, wifi_iface_ml_stat* iface_ml_stat,
+                                  int num_radios, wifi_radio_stat* radio_stat) {
+    if (on_link_layer_ml_stats_result_internal_callback) {
+        on_link_layer_ml_stats_result_internal_callback(id, iface_ml_stat, num_radios, radio_stat);
+    }
+}
+
+// Callback to be invoked for rssi threshold breach.
+std::function<void((wifi_request_id, uint8_t*, int8_t))>
+        on_rssi_threshold_breached_internal_callback;
+void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, int8_t rssi) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_rssi_threshold_breached_internal_callback) {
+        on_rssi_threshold_breached_internal_callback(id, bssid, rssi);
+    }
+}
+
+// Callback to be invoked for ring buffer data indication.
+std::function<void(char*, char*, int, wifi_ring_buffer_status*)>
+        on_ring_buffer_data_internal_callback;
+void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size,
+                           wifi_ring_buffer_status* status) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_ring_buffer_data_internal_callback) {
+        on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, status);
+    }
+}
+
+// Callback to be invoked for error alert indication.
+std::function<void(wifi_request_id, char*, int, int)> on_error_alert_internal_callback;
+void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, int err_code) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_error_alert_internal_callback) {
+        on_error_alert_internal_callback(id, buffer, buffer_size, err_code);
+    }
+}
+
+// Callback to be invoked for radio mode change indication.
+std::function<void(wifi_request_id, uint32_t, wifi_mac_info*)>
+        on_radio_mode_change_internal_callback;
+void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, wifi_mac_info* mac_infos) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_radio_mode_change_internal_callback) {
+        on_radio_mode_change_internal_callback(id, num_macs, mac_infos);
+    }
+}
+
+// Callback to be invoked to report subsystem restart
+std::function<void(const char*)> on_subsystem_restart_internal_callback;
+void onAsyncSubsystemRestart(const char* error) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_subsystem_restart_internal_callback) {
+        on_subsystem_restart_internal_callback(error);
+    }
+}
+
+// Callback to be invoked for rtt results results.
+std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result* rtt_results[])>
+        on_rtt_results_internal_callback;
+std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result_v2* rtt_results_v2[])>
+        on_rtt_results_internal_callback_v2;
+
+void invalidateRttResultsCallbacks() {
+    on_rtt_results_internal_callback = nullptr;
+    on_rtt_results_internal_callback_v2 = nullptr;
+};
+
+void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_rtt_results_internal_callback) {
+        on_rtt_results_internal_callback(id, num_results, rtt_results);
+        invalidateRttResultsCallbacks();
+    }
+}
+
+void onAsyncRttResultsV2(wifi_request_id id, unsigned num_results,
+                         wifi_rtt_result_v2* rtt_results_v2[]) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_rtt_results_internal_callback_v2) {
+        on_rtt_results_internal_callback_v2(id, num_results, rtt_results_v2);
+        invalidateRttResultsCallbacks();
+    }
+}
+
+// Callbacks for the various NAN operations.
+// NOTE: These have very little conversions to perform before invoking the user
+// callbacks.
+// So, handle all of them here directly to avoid adding an unnecessary layer.
+std::function<void(transaction_id, const NanResponseMsg&)> on_nan_notify_response_user_callback;
+void onAsyncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_notify_response_user_callback && msg) {
+        on_nan_notify_response_user_callback(id, *msg);
+    }
+}
+
+std::function<void(const NanPublishRepliedInd&)> on_nan_event_publish_replied_user_callback;
+void onAsyncNanEventPublishReplied(NanPublishRepliedInd* /* event */) {
+    LOG(ERROR) << "onAsyncNanEventPublishReplied triggered";
+}
+
+std::function<void(const NanPublishTerminatedInd&)> on_nan_event_publish_terminated_user_callback;
+void onAsyncNanEventPublishTerminated(NanPublishTerminatedInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_publish_terminated_user_callback && event) {
+        on_nan_event_publish_terminated_user_callback(*event);
+    }
+}
+
+std::function<void(const NanMatchInd&)> on_nan_event_match_user_callback;
+void onAsyncNanEventMatch(NanMatchInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_match_user_callback && event) {
+        on_nan_event_match_user_callback(*event);
+    }
+}
+
+std::function<void(const NanMatchExpiredInd&)> on_nan_event_match_expired_user_callback;
+void onAsyncNanEventMatchExpired(NanMatchExpiredInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_match_expired_user_callback && event) {
+        on_nan_event_match_expired_user_callback(*event);
+    }
+}
+
+std::function<void(const NanSubscribeTerminatedInd&)>
+        on_nan_event_subscribe_terminated_user_callback;
+void onAsyncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_subscribe_terminated_user_callback && event) {
+        on_nan_event_subscribe_terminated_user_callback(*event);
+    }
+}
+
+std::function<void(const NanFollowupInd&)> on_nan_event_followup_user_callback;
+void onAsyncNanEventFollowup(NanFollowupInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_followup_user_callback && event) {
+        on_nan_event_followup_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDiscEngEventInd&)> on_nan_event_disc_eng_event_user_callback;
+void onAsyncNanEventDiscEngEvent(NanDiscEngEventInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_disc_eng_event_user_callback && event) {
+        on_nan_event_disc_eng_event_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDisabledInd&)> on_nan_event_disabled_user_callback;
+void onAsyncNanEventDisabled(NanDisabledInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_disabled_user_callback && event) {
+        on_nan_event_disabled_user_callback(*event);
+    }
+}
+
+std::function<void(const NanTCAInd&)> on_nan_event_tca_user_callback;
+void onAsyncNanEventTca(NanTCAInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_tca_user_callback && event) {
+        on_nan_event_tca_user_callback(*event);
+    }
+}
+
+std::function<void(const NanBeaconSdfPayloadInd&)> on_nan_event_beacon_sdf_payload_user_callback;
+void onAsyncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_beacon_sdf_payload_user_callback && event) {
+        on_nan_event_beacon_sdf_payload_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDataPathRequestInd&)> on_nan_event_data_path_request_user_callback;
+void onAsyncNanEventDataPathRequest(NanDataPathRequestInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_data_path_request_user_callback && event) {
+        on_nan_event_data_path_request_user_callback(*event);
+    }
+}
+std::function<void(const NanDataPathConfirmInd&)> on_nan_event_data_path_confirm_user_callback;
+void onAsyncNanEventDataPathConfirm(NanDataPathConfirmInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_data_path_confirm_user_callback && event) {
+        on_nan_event_data_path_confirm_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDataPathEndInd&)> on_nan_event_data_path_end_user_callback;
+void onAsyncNanEventDataPathEnd(NanDataPathEndInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_data_path_end_user_callback && event) {
+        on_nan_event_data_path_end_user_callback(*event);
+    }
+}
+
+std::function<void(const NanTransmitFollowupInd&)> on_nan_event_transmit_follow_up_user_callback;
+void onAsyncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_transmit_follow_up_user_callback && event) {
+        on_nan_event_transmit_follow_up_user_callback(*event);
+    }
+}
+
+std::function<void(const NanRangeRequestInd&)> on_nan_event_range_request_user_callback;
+void onAsyncNanEventRangeRequest(NanRangeRequestInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_range_request_user_callback && event) {
+        on_nan_event_range_request_user_callback(*event);
+    }
+}
+
+std::function<void(const NanRangeReportInd&)> on_nan_event_range_report_user_callback;
+void onAsyncNanEventRangeReport(NanRangeReportInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_range_report_user_callback && event) {
+        on_nan_event_range_report_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDataPathScheduleUpdateInd&)> on_nan_event_schedule_update_user_callback;
+void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_schedule_update_user_callback && event) {
+        on_nan_event_schedule_update_user_callback(*event);
+    }
+}
+
+std::function<void(const NanSuspensionModeChangeInd&)>
+        on_nan_event_suspension_mode_change_user_callback;
+void onAsyncNanEventSuspensionModeChange(NanSuspensionModeChangeInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_suspension_mode_change_user_callback && event) {
+        on_nan_event_suspension_mode_change_user_callback(*event);
+    }
+}
+
+std::function<void(const NanPairingRequestInd&)> on_nan_event_pairing_request_user_callback;
+void onAsyncNanEventPairingRequest(NanPairingRequestInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_pairing_request_user_callback && event) {
+        on_nan_event_pairing_request_user_callback(*event);
+    }
+}
+
+std::function<void(const NanPairingConfirmInd&)> on_nan_event_pairing_confirm_user_callback;
+void onAsyncNanEventPairingConfirm(NanPairingConfirmInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_pairing_confirm_user_callback && event) {
+        on_nan_event_pairing_confirm_user_callback(*event);
+    }
+}
+
+std::function<void(const NanBootstrappingRequestInd&)>
+        on_nan_event_bootstrapping_request_user_callback;
+void onAsyncNanEventBootstrappingRequest(NanBootstrappingRequestInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_bootstrapping_request_user_callback && event) {
+        on_nan_event_bootstrapping_request_user_callback(*event);
+    }
+}
+
+std::function<void(const NanBootstrappingConfirmInd&)>
+        on_nan_event_bootstrapping_confirm_user_callback;
+void onAsyncNanEventBootstrappingConfirm(NanBootstrappingConfirmInd* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_bootstrapping_confirm_user_callback && event) {
+        on_nan_event_bootstrapping_confirm_user_callback(*event);
+    }
+}
+
+// Callbacks for the various TWT operations.
+std::function<void(const TwtSetupResponse&)> on_twt_event_setup_response_callback;
+void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_twt_event_setup_response_callback && event) {
+        on_twt_event_setup_response_callback(*event);
+    }
+}
+
+std::function<void(const TwtTeardownCompletion&)> on_twt_event_teardown_completion_callback;
+void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_twt_event_teardown_completion_callback && event) {
+        on_twt_event_teardown_completion_callback(*event);
+    }
+}
+
+std::function<void(const TwtInfoFrameReceived&)> on_twt_event_info_frame_received_callback;
+void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_twt_event_info_frame_received_callback && event) {
+        on_twt_event_info_frame_received_callback(*event);
+    }
+}
+
+std::function<void(const TwtDeviceNotify&)> on_twt_event_device_notify_callback;
+void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_twt_event_device_notify_callback && event) {
+        on_twt_event_device_notify_callback(*event);
+    }
+}
+
+// Callback to report current CHRE NAN state
+std::function<void(chre_nan_rtt_state)> on_chre_nan_rtt_internal_callback;
+void onAsyncChreNanRttState(chre_nan_rtt_state state) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_chre_nan_rtt_internal_callback) {
+        on_chre_nan_rtt_internal_callback(state);
+    }
+}
+
+// Callback to report cached scan results
+std::function<void(wifi_cached_scan_report*)> on_cached_scan_results_internal_callback;
+void onSyncCachedScanResults(wifi_cached_scan_report* cache_report) {
+    if (on_cached_scan_results_internal_callback) {
+        on_cached_scan_results_internal_callback(cache_report);
+    }
+}
+
+// End of the free-standing "C" style callbacks.
+
+WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+                             const wifi_hal_fn& fn, bool is_primary)
+    : global_func_table_(fn),
+      global_handle_(nullptr),
+      awaiting_event_loop_termination_(false),
+      is_started_(false),
+      iface_tool_(iface_tool),
+      is_primary_(is_primary) {}
+
+wifi_error WifiLegacyHal::initialize() {
+    LOG(DEBUG) << "Initialize legacy HAL";
+    // this now does nothing, since HAL function table is provided
+    // to the constructor
+    return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::start() {
+    // Ensure that we're starting in a good state.
+    CHECK(global_func_table_.wifi_initialize && !global_handle_ && iface_name_to_handle_.empty() &&
+          !awaiting_event_loop_termination_);
+    if (is_started_) {
+        LOG(DEBUG) << "Legacy HAL already started";
+        return WIFI_SUCCESS;
+    }
+    LOG(DEBUG) << "Waiting for the driver ready";
+    wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
+    if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) {
+        LOG(ERROR) << "Failed or timed out awaiting driver ready";
+        return status;
+    }
+
+    if (is_primary_) {
+        property_set(kDriverPropName, "ok");
+
+        if (!iface_tool_.lock()->SetWifiUpState(true)) {
+            LOG(ERROR) << "Failed to set WiFi interface up";
+            return WIFI_ERROR_UNKNOWN;
+        }
+    }
+
+    LOG(DEBUG) << "Starting legacy HAL";
+    status = global_func_table_.wifi_initialize(&global_handle_);
+    if (status != WIFI_SUCCESS || !global_handle_) {
+        LOG(ERROR) << "Failed to retrieve global handle";
+        return status;
+    }
+    std::thread(&WifiLegacyHal::runEventLoop, this).detach();
+    status = retrieveIfaceHandles();
+    if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) {
+        LOG(ERROR) << "Failed to retrieve wlan interface handle";
+        return status;
+    }
+    LOG(DEBUG) << "Legacy HAL start complete";
+    is_started_ = true;
+    return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::stop(
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
+        const std::function<void()>& on_stop_complete_user_callback) {
+    if (!is_started_) {
+        LOG(DEBUG) << "Legacy HAL already stopped";
+        on_stop_complete_user_callback();
+        return WIFI_SUCCESS;
+    }
+    LOG(DEBUG) << "Stopping legacy HAL";
+    on_stop_complete_internal_callback = [on_stop_complete_user_callback,
+                                          this](wifi_handle handle) {
+        CHECK_EQ(global_handle_, handle) << "Handle mismatch";
+        LOG(INFO) << "Legacy HAL stop complete callback received";
+        // Invalidate all the internal pointers now that the HAL is
+        // stopped.
+        invalidate();
+        if (is_primary_) iface_tool_.lock()->SetWifiUpState(false);
+        on_stop_complete_user_callback();
+        is_started_ = false;
+    };
+    awaiting_event_loop_termination_ = true;
+    global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
+    const auto status =
+            stop_wait_cv_.wait_for(*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
+                                   [this] { return !awaiting_event_loop_termination_; });
+    if (!status) {
+        LOG(ERROR) << "Legacy HAL stop failed or timed out";
+        return WIFI_ERROR_UNKNOWN;
+    }
+    LOG(DEBUG) << "Legacy HAL stop complete";
+    return WIFI_SUCCESS;
+}
+
+bool WifiLegacyHal::isStarted() {
+    return is_started_;
+}
+
+wifi_error WifiLegacyHal::waitForDriverReady() {
+    return global_func_table_.wifi_wait_for_driver_ready();
+}
+
+std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(const std::string& iface_name) {
+    std::array<char, kMaxVersionStringLength> buffer;
+    buffer.fill(0);
+    wifi_error status = global_func_table_.wifi_get_driver_version(getIfaceHandle(iface_name),
+                                                                   buffer.data(), buffer.size());
+    return {status, buffer.data()};
+}
+
+std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion(
+        const std::string& iface_name) {
+    std::array<char, kMaxVersionStringLength> buffer;
+    buffer.fill(0);
+    wifi_error status = global_func_table_.wifi_get_firmware_version(getIfaceHandle(iface_name),
+                                                                     buffer.data(), buffer.size());
+    return {status, buffer.data()};
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestDriverMemoryDump(
+        const std::string& iface_name) {
+    std::vector<uint8_t> driver_dump;
+    on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, int buffer_size) {
+        driver_dump.insert(driver_dump.end(), reinterpret_cast<uint8_t*>(buffer),
+                           reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+    };
+    wifi_error status = global_func_table_.wifi_get_driver_memory_dump(getIfaceHandle(iface_name),
+                                                                       {onSyncDriverMemoryDump});
+    on_driver_memory_dump_internal_callback = nullptr;
+    return {status, std::move(driver_dump)};
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestFirmwareMemoryDump(
+        const std::string& iface_name) {
+    std::vector<uint8_t> firmware_dump;
+    on_firmware_memory_dump_internal_callback = [&firmware_dump](char* buffer, int buffer_size) {
+        firmware_dump.insert(firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer),
+                             reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+    };
+    wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
+            getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump});
+    on_firmware_memory_dump_internal_callback = nullptr;
+    return {status, std::move(firmware_dump)};
+}
+
+std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet(
+        const std::string& iface_name) {
+    feature_set set = 0, chip_set = 0;
+    wifi_error status = WIFI_SUCCESS;
+
+    static_assert(sizeof(set) == sizeof(uint64_t),
+                  "Some feature_flags can not be represented in output");
+    wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
+
+    global_func_table_.wifi_get_chip_feature_set(
+            global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */
+
+    if (iface_handle) {
+        status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set);
+    }
+    return {status, static_cast<uint64_t>(set | chip_set)};
+}
+
+std::pair<wifi_error, PacketFilterCapabilities> WifiLegacyHal::getPacketFilterCapabilities(
+        const std::string& iface_name) {
+    PacketFilterCapabilities caps;
+    wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
+            getIfaceHandle(iface_name), &caps.version, &caps.max_len);
+    return {status, caps};
+}
+
+wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name,
+                                          const std::vector<uint8_t>& program) {
+    return global_func_table_.wifi_set_packet_filter(getIfaceHandle(iface_name), program.data(),
+                                                     program.size());
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::readApfPacketFilterData(
+        const std::string& iface_name) {
+    PacketFilterCapabilities caps;
+    wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
+            getIfaceHandle(iface_name), &caps.version, &caps.max_len);
+    if (status != WIFI_SUCCESS) {
+        return {status, {}};
+    }
+
+    // Size the buffer to read the entire program & work memory.
+    std::vector<uint8_t> buffer(caps.max_len);
+
+    status = global_func_table_.wifi_read_packet_filter(
+            getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), buffer.size());
+    return {status, std::move(buffer)};
+}
+
+std::pair<wifi_error, wifi_gscan_capabilities> WifiLegacyHal::getGscanCapabilities(
+        const std::string& iface_name) {
+    wifi_gscan_capabilities caps;
+    wifi_error status =
+            global_func_table_.wifi_get_gscan_capabilities(getIfaceHandle(iface_name), &caps);
+    return {status, caps};
+}
+
+wifi_error WifiLegacyHal::startGscan(
+        const std::string& iface_name, wifi_request_id id, const wifi_scan_cmd_params& params,
+        const std::function<void(wifi_request_id)>& on_failure_user_callback,
+        const on_gscan_results_callback& on_results_user_callback,
+        const on_gscan_full_result_callback& on_full_result_user_callback) {
+    // If there is already an ongoing background scan, reject new scan requests.
+    if (on_gscan_event_internal_callback || on_gscan_full_result_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    // This callback will be used to either trigger |on_results_user_callback|
+    // or |on_failure_user_callback|.
+    on_gscan_event_internal_callback = [iface_name, on_failure_user_callback,
+                                        on_results_user_callback,
+                                        this](wifi_request_id id, wifi_scan_event event) {
+        switch (event) {
+            case WIFI_SCAN_RESULTS_AVAILABLE:
+            case WIFI_SCAN_THRESHOLD_NUM_SCANS:
+            case WIFI_SCAN_THRESHOLD_PERCENT: {
+                wifi_error status;
+                std::vector<wifi_cached_scan_results> cached_scan_results;
+                std::tie(status, cached_scan_results) = getGscanCachedResults(iface_name);
+                if (status == WIFI_SUCCESS) {
+                    on_results_user_callback(id, cached_scan_results);
+                    return;
+                }
+                FALLTHROUGH_INTENDED;
+            }
+            // Fall through if failed. Failure to retrieve cached scan
+            // results should trigger a background scan failure.
+            case WIFI_SCAN_FAILED:
+                on_failure_user_callback(id);
+                on_gscan_event_internal_callback = nullptr;
+                on_gscan_full_result_internal_callback = nullptr;
+                return;
+        }
+        LOG(FATAL) << "Unexpected gscan event received: " << event;
+    };
+
+    on_gscan_full_result_internal_callback = [on_full_result_user_callback](
+                                                     wifi_request_id id, wifi_scan_result* result,
+                                                     uint32_t buckets_scanned) {
+        if (result) {
+            on_full_result_user_callback(id, result, buckets_scanned);
+        }
+    };
+
+    wifi_scan_result_handler handler = {onAsyncGscanFullResult, onAsyncGscanEvent};
+    wifi_error status =
+            global_func_table_.wifi_start_gscan(id, getIfaceHandle(iface_name), params, handler);
+    if (status != WIFI_SUCCESS) {
+        on_gscan_event_internal_callback = nullptr;
+        on_gscan_full_result_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, wifi_request_id id) {
+    // If there is no an ongoing background scan, reject stop requests.
+    // TODO(b/32337212): This needs to be handled by the HIDL object because we
+    // need to return the NOT_STARTED error code.
+    if (!on_gscan_event_internal_callback && !on_gscan_full_result_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    wifi_error status = global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name));
+    // If the request Id is wrong, don't stop the ongoing background scan. Any
+    // other error should be treated as the end of background scan.
+    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+        on_gscan_event_internal_callback = nullptr;
+        on_gscan_full_result_internal_callback = nullptr;
+    }
+    return status;
+}
+
+std::pair<wifi_error, std::vector<uint32_t>> WifiLegacyHal::getValidFrequenciesForBand(
+        const std::string& iface_name, wifi_band band) {
+    static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
+                  "Wifi Channel cannot be represented in output");
+    std::vector<uint32_t> freqs;
+    freqs.resize(kMaxGscanFrequenciesForBand);
+    int32_t num_freqs = 0;
+    wifi_error status = global_func_table_.wifi_get_valid_channels(
+            getIfaceHandle(iface_name), band, freqs.size(),
+            reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs);
+    CHECK(num_freqs >= 0 && static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
+    freqs.resize(num_freqs);
+    return {status, std::move(freqs)};
+}
+
+wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, bool dfs_on) {
+    return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), dfs_on ? 0 : 1);
+}
+
+wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, bool debug) {
+    wifi_link_layer_params params;
+    params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
+    params.aggressive_statistics_gathering = debug;
+    return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), params);
+}
+
+wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) {
+    // TODO: Do we care about these responses?
+    uint32_t clear_mask_rsp;
+    uint8_t stop_rsp;
+    return global_func_table_.wifi_clear_link_stats(getIfaceHandle(iface_name), 0xFFFFFFFF,
+                                                    &clear_mask_rsp, 1, &stop_rsp);
+}
+
+// Copies wifi_peer_info* to vector<WifiPeerInfo> and returns poiner to next element.
+wifi_peer_info* WifiLegacyHal::copyPeerInfo(wifi_peer_info* peer_ptr,
+                                            std::vector<WifiPeerInfo>& peers) {
+    WifiPeerInfo peer;
+    peer.peer_info = *peer_ptr;
+    if (peer_ptr->num_rate > 0) {
+        // Copy the rate stats.
+        peer.rate_stats.assign(peer_ptr->rate_stats, peer_ptr->rate_stats + peer_ptr->num_rate);
+    }
+    peer.peer_info.num_rate = 0;
+    // Push peer info.
+    peers.push_back(peer);
+    // Return the address of next peer info.
+    return (wifi_peer_info*)((u8*)peer_ptr + sizeof(wifi_peer_info) +
+                             (sizeof(wifi_rate_stat) * peer_ptr->num_rate));
+}
+// Copies wifi_link_stat* to vector<LinkStats> and returns poiner to next element.
+wifi_link_stat* WifiLegacyHal::copyLinkStat(wifi_link_stat* stat_ptr,
+                                            std::vector<LinkStats>& stats) {
+    LinkStats linkStat;
+    linkStat.stat = *stat_ptr;
+    wifi_peer_info* l_peer_info_stats_ptr = stat_ptr->peer_info;
+    for (uint32_t i = 0; i < linkStat.stat.num_peers; i++) {
+        l_peer_info_stats_ptr = copyPeerInfo(l_peer_info_stats_ptr, linkStat.peers);
+    }
+    // Copied all peers to linkStat.peers.
+    linkStat.stat.num_peers = 0;
+    // Push link stat.
+    stats.push_back(linkStat);
+    // Read all peers, return the address of next wifi_link_stat.
+    return (wifi_link_stat*)l_peer_info_stats_ptr;
+}
+
+wifi_error WifiLegacyHal::getLinkLayerStats(const std::string& iface_name,
+                                            LinkLayerStats& link_stats,
+                                            LinkLayerMlStats& link_ml_stats) {
+    LinkLayerStats* link_stats_ptr = &link_stats;
+    link_stats_ptr->valid = false;
+
+    on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
+                                                           wifi_request_id /* id */,
+                                                           wifi_iface_stat* iface_stats_ptr,
+                                                           int num_radios,
+                                                           wifi_radio_stat* radio_stats_ptr) {
+        wifi_radio_stat* l_radio_stats_ptr;
+        wifi_peer_info* l_peer_info_stats_ptr;
+        link_stats_ptr->valid = true;
+
+        if (iface_stats_ptr != nullptr) {
+            link_stats_ptr->iface = *iface_stats_ptr;
+            l_peer_info_stats_ptr = iface_stats_ptr->peer_info;
+            for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) {
+                WifiPeerInfo peer;
+                peer.peer_info = *l_peer_info_stats_ptr;
+                if (l_peer_info_stats_ptr->num_rate > 0) {
+                    /* Copy the rate stats */
+                    peer.rate_stats.assign(
+                            l_peer_info_stats_ptr->rate_stats,
+                            l_peer_info_stats_ptr->rate_stats + l_peer_info_stats_ptr->num_rate);
+                }
+                peer.peer_info.num_rate = 0;
+                link_stats_ptr->peers.push_back(peer);
+                l_peer_info_stats_ptr =
+                        (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + sizeof(wifi_peer_info) +
+                                          (sizeof(wifi_rate_stat) *
+                                           l_peer_info_stats_ptr->num_rate));
+            }
+            link_stats_ptr->iface.num_peers = 0;
+        } else {
+            LOG(ERROR) << "Invalid iface stats in link layer stats";
+        }
+        if (num_radios <= 0 || radio_stats_ptr == nullptr) {
+            LOG(ERROR) << "Invalid radio stats in link layer stats";
+            return;
+        }
+        l_radio_stats_ptr = radio_stats_ptr;
+        for (int i = 0; i < num_radios; i++) {
+            LinkLayerRadioStats radio;
+
+            radio.stats = *l_radio_stats_ptr;
+            // Copy over the tx level array to the separate vector.
+            if (l_radio_stats_ptr->num_tx_levels > 0 &&
+                l_radio_stats_ptr->tx_time_per_levels != nullptr) {
+                radio.tx_time_per_levels.assign(
+                        l_radio_stats_ptr->tx_time_per_levels,
+                        l_radio_stats_ptr->tx_time_per_levels + l_radio_stats_ptr->num_tx_levels);
+            }
+            radio.stats.num_tx_levels = 0;
+            radio.stats.tx_time_per_levels = nullptr;
+            /* Copy over the channel stat to separate vector */
+            if (l_radio_stats_ptr->num_channels > 0) {
+                /* Copy the channel stats */
+                radio.channel_stats.assign(
+                        l_radio_stats_ptr->channels,
+                        l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
+            }
+            link_stats_ptr->radios.push_back(radio);
+            l_radio_stats_ptr =
+                    (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
+                                       (sizeof(wifi_channel_stat) *
+                                        l_radio_stats_ptr->num_channels));
+        }
+    };
+
+    LinkLayerMlStats* link_ml_stats_ptr = &link_ml_stats;
+    link_ml_stats_ptr->valid = false;
+
+    on_link_layer_ml_stats_result_internal_callback =
+            [this, &link_ml_stats_ptr](wifi_request_id /* id */,
+                                       wifi_iface_ml_stat* iface_ml_stats_ptr, int num_radios,
+                                       wifi_radio_stat* radio_stats_ptr) {
+                wifi_radio_stat* l_radio_stats_ptr;
+                wifi_link_stat* l_link_stat_ptr;
+                link_ml_stats_ptr->valid = true;
+
+                if (iface_ml_stats_ptr != nullptr && iface_ml_stats_ptr->num_links > 0) {
+                    // Copy stats from wifi_iface_ml_stat to LinkLayerMlStats,
+                    //  - num_links * links[] to vector of links.
+                    //  - num_peers * peer_info[] to vector of links[i].peers.
+                    link_ml_stats_ptr->iface = *iface_ml_stats_ptr;
+                    l_link_stat_ptr = iface_ml_stats_ptr->links;
+                    for (int l = 0; l < iface_ml_stats_ptr->num_links; ++l) {
+                        l_link_stat_ptr = copyLinkStat(l_link_stat_ptr, link_ml_stats_ptr->links);
+                    }
+                } else {
+                    LOG(ERROR) << "Invalid iface stats in link layer stats";
+                }
+                if (num_radios <= 0 || radio_stats_ptr == nullptr) {
+                    LOG(ERROR) << "Invalid radio stats in link layer stats";
+                    return;
+                }
+                l_radio_stats_ptr = radio_stats_ptr;
+                for (int i = 0; i < num_radios; i++) {
+                    LinkLayerRadioStats radio;
+
+                    radio.stats = *l_radio_stats_ptr;
+                    // Copy over the tx level array to the separate vector.
+                    if (l_radio_stats_ptr->num_tx_levels > 0 &&
+                        l_radio_stats_ptr->tx_time_per_levels != nullptr) {
+                        radio.tx_time_per_levels.assign(l_radio_stats_ptr->tx_time_per_levels,
+                                                        l_radio_stats_ptr->tx_time_per_levels +
+                                                                l_radio_stats_ptr->num_tx_levels);
+                    }
+                    radio.stats.num_tx_levels = 0;
+                    radio.stats.tx_time_per_levels = nullptr;
+                    /* Copy over the channel stat to separate vector */
+                    if (l_radio_stats_ptr->num_channels > 0) {
+                        /* Copy the channel stats */
+                        radio.channel_stats.assign(
+                                l_radio_stats_ptr->channels,
+                                l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
+                    }
+                    link_ml_stats_ptr->radios.push_back(radio);
+                    l_radio_stats_ptr =
+                            (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
+                                               (sizeof(wifi_channel_stat) *
+                                                l_radio_stats_ptr->num_channels));
+                }
+            };
+
+    wifi_error status = global_func_table_.wifi_get_link_stats(
+            0, getIfaceHandle(iface_name),
+            {onSyncLinkLayerStatsResult, onSyncLinkLayerMlStatsResult});
+    on_link_layer_stats_result_internal_callback = nullptr;
+    on_link_layer_ml_stats_result_internal_callback = nullptr;
+
+    return status;
+}
+
+wifi_error WifiLegacyHal::startRssiMonitoring(
+        const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
+        const on_rssi_threshold_breached_callback& on_threshold_breached_user_callback) {
+    if (on_rssi_threshold_breached_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_rssi_threshold_breached_internal_callback = [on_threshold_breached_user_callback](
+                                                           wifi_request_id id, uint8_t* bssid_ptr,
+                                                           int8_t rssi) {
+        if (!bssid_ptr) {
+            return;
+        }
+        std::array<uint8_t, ETH_ALEN> bssid_arr;
+        // |bssid_ptr| pointer is assumed to have 6 bytes for the mac
+        // address.
+        std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
+        on_threshold_breached_user_callback(id, bssid_arr, rssi);
+    };
+    wifi_error status = global_func_table_.wifi_start_rssi_monitoring(
+            id, getIfaceHandle(iface_name), max_rssi, min_rssi, {onAsyncRssiThresholdBreached});
+    if (status != WIFI_SUCCESS) {
+        on_rssi_threshold_breached_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, wifi_request_id id) {
+    if (!on_rssi_threshold_breached_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    wifi_error status =
+            global_func_table_.wifi_stop_rssi_monitoring(id, getIfaceHandle(iface_name));
+    // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
+    // other error should be treated as the end of background scan.
+    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+        on_rssi_threshold_breached_internal_callback = nullptr;
+    }
+    return status;
+}
+
+std::pair<wifi_error, wifi_roaming_capabilities> WifiLegacyHal::getRoamingCapabilities(
+        const std::string& iface_name) {
+    wifi_roaming_capabilities caps;
+    wifi_error status =
+            global_func_table_.wifi_get_roaming_capabilities(getIfaceHandle(iface_name), &caps);
+    return {status, caps};
+}
+
+wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name,
+                                           const wifi_roaming_config& config) {
+    wifi_roaming_config config_internal = config;
+    return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), &config_internal);
+}
+
+wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name,
+                                                fw_roaming_state_t state) {
+    return global_func_table_.wifi_enable_firmware_roaming(getIfaceHandle(iface_name), state);
+}
+
+wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, bool enable) {
+    return global_func_table_.wifi_configure_nd_offload(getIfaceHandle(iface_name), enable);
+}
+
+wifi_error WifiLegacyHal::startSendingOffloadedPacket(const std::string& iface_name, int32_t cmd_id,
+                                                      uint16_t ether_type,
+                                                      const std::vector<uint8_t>& ip_packet_data,
+                                                      const std::array<uint8_t, 6>& src_address,
+                                                      const std::array<uint8_t, 6>& dst_address,
+                                                      int32_t period_in_ms) {
+    std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
+    std::vector<uint8_t> src_address_internal(src_address.data(),
+                                              src_address.data() + src_address.size());
+    std::vector<uint8_t> dst_address_internal(dst_address.data(),
+                                              dst_address.data() + dst_address.size());
+    return global_func_table_.wifi_start_sending_offloaded_packet(
+            cmd_id, getIfaceHandle(iface_name), ether_type, ip_packet_data_internal.data(),
+            ip_packet_data_internal.size(), src_address_internal.data(),
+            dst_address_internal.data(), period_in_ms);
+}
+
+wifi_error WifiLegacyHal::stopSendingOffloadedPacket(const std::string& iface_name,
+                                                     uint32_t cmd_id) {
+    return global_func_table_.wifi_stop_sending_offloaded_packet(cmd_id,
+                                                                 getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
+                                                wifi_power_scenario scenario) {
+    return global_func_table_.wifi_select_tx_power_scenario(getIfaceHandle(iface_name), scenario);
+}
+
+wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) {
+    return global_func_table_.wifi_reset_tx_power_scenario(getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, wifi_latency_mode mode) {
+    return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), mode);
+}
+
+wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode,
+                                                   uint32_t completion_window) {
+    return global_func_table_.wifi_set_thermal_mitigation_mode(global_handle_, mode,
+                                                               completion_window);
+}
+
+wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
+                                                         uint32_t access_category) {
+    return global_func_table_.wifi_map_dscp_access_category(global_handle_, start, end,
+                                                            access_category);
+}
+
+wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() {
+    return global_func_table_.wifi_reset_dscp_mapping(global_handle_);
+}
+
+std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet(
+        const std::string& iface_name) {
+    uint32_t supported_feature_flags = 0;
+    wifi_error status = WIFI_SUCCESS;
+
+    wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
+
+    if (iface_handle) {
+        status = global_func_table_.wifi_get_logger_supported_feature_set(iface_handle,
+                                                                          &supported_feature_flags);
+    }
+    return {status, supported_feature_flags};
+}
+
+wifi_error WifiLegacyHal::startPktFateMonitoring(const std::string& iface_name) {
+    return global_func_table_.wifi_start_pkt_fate_monitoring(getIfaceHandle(iface_name));
+}
+
+std::pair<wifi_error, std::vector<wifi_tx_report>> WifiLegacyHal::getTxPktFates(
+        const std::string& iface_name) {
+    std::vector<wifi_tx_report> tx_pkt_fates;
+    tx_pkt_fates.resize(MAX_FATE_LOG_LEN);
+    size_t num_fates = 0;
+    wifi_error status = global_func_table_.wifi_get_tx_pkt_fates(
+            getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), &num_fates);
+    CHECK(num_fates <= MAX_FATE_LOG_LEN);
+    tx_pkt_fates.resize(num_fates);
+    return {status, std::move(tx_pkt_fates)};
+}
+
+std::pair<wifi_error, std::vector<wifi_rx_report>> WifiLegacyHal::getRxPktFates(
+        const std::string& iface_name) {
+    std::vector<wifi_rx_report> rx_pkt_fates;
+    rx_pkt_fates.resize(MAX_FATE_LOG_LEN);
+    size_t num_fates = 0;
+    wifi_error status = global_func_table_.wifi_get_rx_pkt_fates(
+            getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), &num_fates);
+    CHECK(num_fates <= MAX_FATE_LOG_LEN);
+    rx_pkt_fates.resize(num_fates);
+    return {status, std::move(rx_pkt_fates)};
+}
+
+std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats(
+        const std::string& iface_name) {
+    WakeReasonStats stats;
+    stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
+    stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
+
+    // This legacy struct needs separate memory to store the variable sized wake
+    // reason types.
+    stats.wake_reason_cnt.cmd_event_wake_cnt =
+            reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data());
+    stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size();
+    stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0;
+    stats.wake_reason_cnt.driver_fw_local_wake_cnt =
+            reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data());
+    stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = stats.driver_fw_local_wake_cnt.size();
+    stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0;
+
+    wifi_error status = global_func_table_.wifi_get_wake_reason_stats(getIfaceHandle(iface_name),
+                                                                      &stats.wake_reason_cnt);
+
+    CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 &&
+          static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <=
+                  kMaxWakeReasonStatsArraySize);
+    stats.cmd_event_wake_cnt.resize(stats.wake_reason_cnt.cmd_event_wake_cnt_used);
+    stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr;
+
+    CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 &&
+          static_cast<uint32_t>(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <=
+                  kMaxWakeReasonStatsArraySize);
+    stats.driver_fw_local_wake_cnt.resize(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used);
+    stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr;
+
+    return {status, stats};
+}
+
+wifi_error WifiLegacyHal::registerRingBufferCallbackHandler(
+        const std::string& iface_name, const on_ring_buffer_data_callback& on_user_data_callback) {
+    if (on_ring_buffer_data_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_ring_buffer_data_internal_callback = [on_user_data_callback](
+                                                    char* ring_name, char* buffer, int buffer_size,
+                                                    wifi_ring_buffer_status* status) {
+        if (status && buffer) {
+            std::vector<uint8_t> buffer_vector(reinterpret_cast<uint8_t*>(buffer),
+                                               reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+            on_user_data_callback(ring_name, buffer_vector, *status);
+        }
+    };
+    wifi_error status = global_func_table_.wifi_set_log_handler(0, getIfaceHandle(iface_name),
+                                                                {onAsyncRingBufferData});
+    if (status != WIFI_SUCCESS) {
+        on_ring_buffer_data_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(const std::string& iface_name) {
+    if (!on_ring_buffer_data_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_ring_buffer_data_internal_callback = nullptr;
+    return global_func_table_.wifi_reset_log_handler(0, getIfaceHandle(iface_name));
+}
+
+std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> WifiLegacyHal::getRingBuffersStatus(
+        const std::string& iface_name) {
+    std::vector<wifi_ring_buffer_status> ring_buffers_status;
+    ring_buffers_status.resize(kMaxRingBuffers);
+    uint32_t num_rings = kMaxRingBuffers;
+    wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
+            getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data());
+    CHECK(num_rings <= kMaxRingBuffers);
+    ring_buffers_status.resize(num_rings);
+    return {status, std::move(ring_buffers_status)};
+}
+
+wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name,
+                                                 const std::string& ring_name,
+                                                 uint32_t verbose_level, uint32_t max_interval_sec,
+                                                 uint32_t min_data_size) {
+    return global_func_table_.wifi_start_logging(getIfaceHandle(iface_name), verbose_level, 0,
+                                                 max_interval_sec, min_data_size,
+                                                 makeCharVec(ring_name).data());
+}
+
+wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name,
+                                            const std::string& ring_name) {
+    return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name),
+                                                 makeCharVec(ring_name).data());
+}
+
+wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
+        const std::string& iface_name, const on_error_alert_callback& on_user_alert_callback) {
+    if (on_error_alert_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_error_alert_internal_callback = [on_user_alert_callback](wifi_request_id id, char* buffer,
+                                                                int buffer_size, int err_code) {
+        if (buffer) {
+            CHECK(id == 0);
+            on_user_alert_callback(
+                    err_code,
+                    std::vector<uint8_t>(reinterpret_cast<uint8_t*>(buffer),
+                                         reinterpret_cast<uint8_t*>(buffer) + buffer_size));
+        }
+    };
+    wifi_error status = global_func_table_.wifi_set_alert_handler(0, getIfaceHandle(iface_name),
+                                                                  {onAsyncErrorAlert});
+    if (status != WIFI_SUCCESS) {
+        on_error_alert_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(const std::string& iface_name) {
+    if (!on_error_alert_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_error_alert_internal_callback = nullptr;
+    return global_func_table_.wifi_reset_alert_handler(0, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
+        const std::string& iface_name,
+        const on_radio_mode_change_callback& on_user_change_callback) {
+    if (on_radio_mode_change_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_radio_mode_change_internal_callback = [on_user_change_callback](
+                                                     wifi_request_id /* id */, uint32_t num_macs,
+                                                     wifi_mac_info* mac_infos_arr) {
+        if (num_macs > 0 && mac_infos_arr) {
+            std::vector<WifiMacInfo> mac_infos_vec;
+            for (uint32_t i = 0; i < num_macs; i++) {
+                WifiMacInfo mac_info;
+                mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id;
+                mac_info.mac_band = mac_infos_arr[i].mac_band;
+                for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) {
+                    WifiIfaceInfo iface_info;
+                    iface_info.name = mac_infos_arr[i].iface_info[j].iface_name;
+                    iface_info.channel = mac_infos_arr[i].iface_info[j].channel;
+                    mac_info.iface_infos.push_back(iface_info);
+                }
+                mac_infos_vec.push_back(mac_info);
+            }
+            on_user_change_callback(mac_infos_vec);
+        }
+    };
+    wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler(
+            0, getIfaceHandle(iface_name), {onAsyncRadioModeChange});
+    if (status != WIFI_SUCCESS) {
+        on_radio_mode_change_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler(
+        const on_subsystem_restart_callback& on_restart_callback) {
+    if (on_subsystem_restart_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_subsystem_restart_internal_callback = [on_restart_callback](const char* error) {
+        on_restart_callback(error);
+    };
+    wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler(
+            global_handle_, {onAsyncSubsystemRestart});
+    if (status != WIFI_SUCCESS) {
+        on_subsystem_restart_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::startRttRangeRequest(
+        const std::string& iface_name, wifi_request_id id,
+        const std::vector<wifi_rtt_config>& rtt_configs,
+        const on_rtt_results_callback& on_results_user_callback,
+        const on_rtt_results_callback_v2& on_results_user_callback_v2) {
+    if (on_rtt_results_internal_callback || on_rtt_results_internal_callback_v2) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    on_rtt_results_internal_callback = [on_results_user_callback](wifi_request_id id,
+                                                                  unsigned num_results,
+                                                                  wifi_rtt_result* rtt_results[]) {
+        if (num_results > 0 && !rtt_results) {
+            LOG(ERROR) << "Unexpected nullptr in RTT results";
+            return;
+        }
+        std::vector<const wifi_rtt_result*> rtt_results_vec;
+        std::copy_if(rtt_results, rtt_results + num_results, back_inserter(rtt_results_vec),
+                     [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; });
+        on_results_user_callback(id, rtt_results_vec);
+    };
+
+    on_rtt_results_internal_callback_v2 = [on_results_user_callback_v2](
+                                                  wifi_request_id id, unsigned num_results,
+                                                  wifi_rtt_result_v2* rtt_results_v2[]) {
+        if (num_results > 0 && !rtt_results_v2) {
+            LOG(ERROR) << "Unexpected nullptr in RTT results";
+            return;
+        }
+        std::vector<const wifi_rtt_result_v2*> rtt_results_vec_v2;
+        std::copy_if(rtt_results_v2, rtt_results_v2 + num_results,
+                     back_inserter(rtt_results_vec_v2),
+                     [](wifi_rtt_result_v2* rtt_result_v2) { return rtt_result_v2 != nullptr; });
+        on_results_user_callback_v2(id, rtt_results_vec_v2);
+    };
+
+    std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs);
+    wifi_error status = global_func_table_.wifi_rtt_range_request(
+            id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
+            {onAsyncRttResults, onAsyncRttResultsV2});
+    if (status != WIFI_SUCCESS) {
+        invalidateRttResultsCallbacks();
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::cancelRttRangeRequest(
+        const std::string& iface_name, wifi_request_id id,
+        const std::vector<std::array<uint8_t, ETH_ALEN>>& mac_addrs) {
+    if (!on_rtt_results_internal_callback && !on_rtt_results_internal_callback_v2) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, ETH_ALEN>),
+                  "MAC address size mismatch");
+    // TODO: How do we handle partial cancels (i.e only a subset of enabled mac
+    // addressed are cancelled).
+    std::vector<std::array<uint8_t, ETH_ALEN>> mac_addrs_internal(mac_addrs);
+    wifi_error status = global_func_table_.wifi_rtt_range_cancel(
+            id, getIfaceHandle(iface_name), mac_addrs.size(),
+            reinterpret_cast<mac_addr*>(mac_addrs_internal.data()));
+    // If the request Id is wrong, don't stop the ongoing range request. Any
+    // other error should be treated as the end of rtt ranging.
+    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+        invalidateRttResultsCallbacks();
+    }
+    return status;
+}
+
+std::pair<wifi_error, wifi_rtt_capabilities> WifiLegacyHal::getRttCapabilities(
+        const std::string& iface_name) {
+    wifi_rtt_capabilities rtt_caps;
+    wifi_error status =
+            global_func_table_.wifi_get_rtt_capabilities(getIfaceHandle(iface_name), &rtt_caps);
+    return {status, rtt_caps};
+}
+
+std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
+        const std::string& iface_name) {
+    wifi_rtt_responder rtt_responder;
+    wifi_error status = global_func_table_.wifi_rtt_get_responder_info(getIfaceHandle(iface_name),
+                                                                       &rtt_responder);
+    return {status, rtt_responder};
+}
+
+wifi_error WifiLegacyHal::enableRttResponder(const std::string& iface_name, wifi_request_id id,
+                                             const wifi_channel_info& channel_hint,
+                                             uint32_t max_duration_secs,
+                                             const wifi_rtt_responder& info) {
+    wifi_rtt_responder info_internal(info);
+    return global_func_table_.wifi_enable_responder(id, getIfaceHandle(iface_name), channel_hint,
+                                                    max_duration_secs, &info_internal);
+}
+
+wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, wifi_request_id id) {
+    return global_func_table_.wifi_disable_responder(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, wifi_request_id id,
+                                    const wifi_lci_information& info) {
+    wifi_lci_information info_internal(info);
+    return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), &info_internal);
+}
+
+wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, wifi_request_id id,
+                                    const wifi_lcr_information& info) {
+    wifi_lcr_information info_internal(info);
+    return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), &info_internal);
+}
+
+wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(const std::string& iface_name,
+                                                      const NanCallbackHandlers& user_callbacks) {
+    on_nan_notify_response_user_callback = user_callbacks.on_notify_response;
+    on_nan_event_publish_terminated_user_callback = user_callbacks.on_event_publish_terminated;
+    on_nan_event_match_user_callback = user_callbacks.on_event_match;
+    on_nan_event_match_expired_user_callback = user_callbacks.on_event_match_expired;
+    on_nan_event_subscribe_terminated_user_callback = user_callbacks.on_event_subscribe_terminated;
+    on_nan_event_followup_user_callback = user_callbacks.on_event_followup;
+    on_nan_event_disc_eng_event_user_callback = user_callbacks.on_event_disc_eng_event;
+    on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled;
+    on_nan_event_tca_user_callback = user_callbacks.on_event_tca;
+    on_nan_event_beacon_sdf_payload_user_callback = user_callbacks.on_event_beacon_sdf_payload;
+    on_nan_event_data_path_request_user_callback = user_callbacks.on_event_data_path_request;
+    on_nan_event_pairing_request_user_callback = user_callbacks.on_event_pairing_request;
+    on_nan_event_pairing_confirm_user_callback = user_callbacks.on_event_pairing_confirm;
+    on_nan_event_bootstrapping_request_user_callback =
+            user_callbacks.on_event_bootstrapping_request;
+    on_nan_event_bootstrapping_confirm_user_callback =
+            user_callbacks.on_event_bootstrapping_confirm;
+    on_nan_event_data_path_confirm_user_callback = user_callbacks.on_event_data_path_confirm;
+    on_nan_event_data_path_end_user_callback = user_callbacks.on_event_data_path_end;
+    on_nan_event_transmit_follow_up_user_callback = user_callbacks.on_event_transmit_follow_up;
+    on_nan_event_range_request_user_callback = user_callbacks.on_event_range_request;
+    on_nan_event_range_report_user_callback = user_callbacks.on_event_range_report;
+    on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update;
+    on_nan_event_suspension_mode_change_user_callback =
+            user_callbacks.on_event_suspension_mode_change;
+
+    return global_func_table_.wifi_nan_register_handler(getIfaceHandle(iface_name),
+                                                        {onAsyncNanNotifyResponse,
+                                                         onAsyncNanEventPublishReplied,
+                                                         onAsyncNanEventPublishTerminated,
+                                                         onAsyncNanEventMatch,
+                                                         onAsyncNanEventMatchExpired,
+                                                         onAsyncNanEventSubscribeTerminated,
+                                                         onAsyncNanEventFollowup,
+                                                         onAsyncNanEventDiscEngEvent,
+                                                         onAsyncNanEventDisabled,
+                                                         onAsyncNanEventTca,
+                                                         onAsyncNanEventBeaconSdfPayload,
+                                                         onAsyncNanEventDataPathRequest,
+                                                         onAsyncNanEventDataPathConfirm,
+                                                         onAsyncNanEventDataPathEnd,
+                                                         onAsyncNanEventTransmitFollowUp,
+                                                         onAsyncNanEventRangeRequest,
+                                                         onAsyncNanEventRangeReport,
+                                                         onAsyncNanEventScheduleUpdate,
+                                                         onAsyncNanEventPairingRequest,
+                                                         onAsyncNanEventPairingConfirm,
+                                                         onAsyncNanEventBootstrappingRequest,
+                                                         onAsyncNanEventBootstrappingConfirm,
+                                                         onAsyncNanEventSuspensionModeChange});
+}
+
+wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id,
+                                           const NanEnableRequest& msg) {
+    NanEnableRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_enable_request(id, getIfaceHandle(iface_name),
+                                                      &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, transaction_id id) {
+    return global_func_table_.wifi_nan_disable_request(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, transaction_id id,
+                                            const NanPublishRequest& msg) {
+    NanPublishRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_publish_request(id, getIfaceHandle(iface_name),
+                                                       &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
+                                                  const NanPublishCancelRequest& msg) {
+    NanPublishCancelRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_publish_cancel_request(id, getIfaceHandle(iface_name),
+                                                              &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, transaction_id id,
+                                              const NanSubscribeRequest& msg) {
+    NanSubscribeRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_subscribe_request(id, getIfaceHandle(iface_name),
+                                                         &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanSubscribeCancelRequest(const std::string& iface_name,
+                                                    transaction_id id,
+                                                    const NanSubscribeCancelRequest& msg) {
+    NanSubscribeCancelRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_subscribe_cancel_request(id, getIfaceHandle(iface_name),
+                                                                &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanTransmitFollowupRequest(const std::string& iface_name,
+                                                     transaction_id id,
+                                                     const NanTransmitFollowupRequest& msg) {
+    NanTransmitFollowupRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_transmit_followup_request(id, getIfaceHandle(iface_name),
+                                                                 &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, transaction_id id,
+                                          const NanStatsRequest& msg) {
+    NanStatsRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_stats_request(id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, transaction_id id,
+                                           const NanConfigRequest& msg) {
+    NanConfigRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_config_request(id, getIfaceHandle(iface_name),
+                                                      &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, transaction_id id,
+                                        const NanTCARequest& msg) {
+    NanTCARequest msg_internal(msg);
+    return global_func_table_.wifi_nan_tca_request(id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(const std::string& iface_name,
+                                                     transaction_id id,
+                                                     const NanBeaconSdfPayloadRequest& msg) {
+    NanBeaconSdfPayloadRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_beacon_sdf_payload_request(id, getIfaceHandle(iface_name),
+                                                                  &msg_internal);
+}
+
+std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() {
+    NanVersion version;
+    wifi_error status = global_func_table_.wifi_nan_get_version(global_handle_, &version);
+    return {status, version};
+}
+
+wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, transaction_id id) {
+    return global_func_table_.wifi_nan_get_capabilities(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
+                                                 const std::string& data_iface_name) {
+    return global_func_table_.wifi_nan_data_interface_create(id, getIfaceHandle(iface_name),
+                                                             makeCharVec(data_iface_name).data());
+}
+
+wifi_error WifiLegacyHal::nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
+                                                 const std::string& data_iface_name) {
+    return global_func_table_.wifi_nan_data_interface_delete(id, getIfaceHandle(iface_name),
+                                                             makeCharVec(data_iface_name).data());
+}
+
+wifi_error WifiLegacyHal::nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
+                                                  const NanDataPathInitiatorRequest& msg) {
+    NanDataPathInitiatorRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_data_request_initiator(id, getIfaceHandle(iface_name),
+                                                              &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanDataIndicationResponse(const std::string& iface_name,
+                                                    transaction_id id,
+                                                    const NanDataPathIndicationResponse& msg) {
+    NanDataPathIndicationResponse msg_internal(msg);
+    return global_func_table_.wifi_nan_data_indication_response(id, getIfaceHandle(iface_name),
+                                                                &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanPairingRequest(const std::string& iface_name, transaction_id id,
+                                            const NanPairingRequest& msg) {
+    NanPairingRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_pairing_request(id, getIfaceHandle(iface_name),
+                                                       &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanPairingIndicationResponse(const std::string& iface_name,
+                                                       transaction_id id,
+                                                       const NanPairingIndicationResponse& msg) {
+    NanPairingIndicationResponse msg_internal(msg);
+    return global_func_table_.wifi_nan_pairing_indication_response(id, getIfaceHandle(iface_name),
+                                                                   &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanBootstrappingRequest(const std::string& iface_name, transaction_id id,
+                                                  const NanBootstrappingRequest& msg) {
+    NanBootstrappingRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_bootstrapping_request(id, getIfaceHandle(iface_name),
+                                                             &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanBootstrappingIndicationResponse(
+        const std::string& iface_name, transaction_id id,
+        const NanBootstrappingIndicationResponse& msg) {
+    NanBootstrappingIndicationResponse msg_internal(msg);
+    return global_func_table_.wifi_nan_bootstrapping_indication_response(
+            id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+typedef struct {
+    u8 num_ndp_instances;
+    NanDataPathId ndp_instance_id;
+} NanDataPathEndSingleNdpIdRequest;
+
+wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, transaction_id id,
+                                     uint32_t ndpInstanceId) {
+    NanDataPathEndSingleNdpIdRequest msg;
+    msg.num_ndp_instances = 1;
+    msg.ndp_instance_id = ndpInstanceId;
+    wifi_error status = global_func_table_.wifi_nan_data_end(id, getIfaceHandle(iface_name),
+                                                             (NanDataPathEndRequest*)&msg);
+    return status;
+}
+
+wifi_error WifiLegacyHal::nanPairingEnd(const std::string& iface_name, transaction_id id,
+                                        uint32_t pairingId) {
+    NanPairingEndRequest msg;
+    msg.pairing_instance_id = pairingId;
+    wifi_error status =
+            global_func_table_.wifi_nan_pairing_end(id, getIfaceHandle(iface_name), &msg);
+    return status;
+}
+
+wifi_error WifiLegacyHal::nanSuspendRequest(const std::string& iface_name, transaction_id id,
+                                            const NanSuspendRequest& msg) {
+    NanSuspendRequest msg_internal(msg);
+    wifi_error status = global_func_table_.wifi_nan_suspend_request(id, getIfaceHandle(iface_name),
+                                                                    &msg_internal);
+    return status;
+}
+
+wifi_error WifiLegacyHal::nanResumeRequest(const std::string& iface_name, transaction_id id,
+                                           const NanResumeRequest& msg) {
+    NanResumeRequest msg_internal(msg);
+    wifi_error status = global_func_table_.wifi_nan_resume_request(id, getIfaceHandle(iface_name),
+                                                                   &msg_internal);
+    return status;
+}
+
+wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name,
+                                         const std::array<uint8_t, 2> code) {
+    std::string code_str(code.data(), code.data() + code.size());
+    return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), code_str.c_str());
+}
+
+wifi_error WifiLegacyHal::retrieveIfaceHandles() {
+    wifi_interface_handle* iface_handles = nullptr;
+    int num_iface_handles = 0;
+    wifi_error status =
+            global_func_table_.wifi_get_ifaces(global_handle_, &num_iface_handles, &iface_handles);
+    if (status != WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to enumerate interface handles";
+        return status;
+    }
+    iface_name_to_handle_.clear();
+    for (int i = 0; i < num_iface_handles; ++i) {
+        std::array<char, IFNAMSIZ> iface_name_arr = {};
+        status = global_func_table_.wifi_get_iface_name(iface_handles[i], iface_name_arr.data(),
+                                                        iface_name_arr.size());
+        if (status != WIFI_SUCCESS) {
+            LOG(WARNING) << "Failed to get interface handle name";
+            continue;
+        }
+        // Assuming the interface name is null terminated since the legacy HAL
+        // API does not return a size.
+        std::string iface_name(iface_name_arr.data());
+        LOG(INFO) << "Adding interface handle for " << iface_name;
+        iface_name_to_handle_[iface_name] = iface_handles[i];
+    }
+    return WIFI_SUCCESS;
+}
+
+wifi_interface_handle WifiLegacyHal::getIfaceHandle(const std::string& iface_name) {
+    const auto iface_handle_iter = iface_name_to_handle_.find(iface_name);
+    if (iface_handle_iter == iface_name_to_handle_.end()) {
+        LOG(ERROR) << "Unknown iface name: " << iface_name;
+        return nullptr;
+    }
+    return iface_handle_iter->second;
+}
+
+void WifiLegacyHal::runEventLoop() {
+    LOG(DEBUG) << "Starting legacy HAL event loop";
+    global_func_table_.wifi_event_loop(global_handle_);
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (!awaiting_event_loop_termination_) {
+        LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
+    }
+    LOG(DEBUG) << "Legacy HAL event loop terminated";
+    awaiting_event_loop_termination_ = false;
+    stop_wait_cv_.notify_one();
+}
+
+std::pair<wifi_error, std::vector<wifi_cached_scan_results>> WifiLegacyHal::getGscanCachedResults(
+        const std::string& iface_name) {
+    std::vector<wifi_cached_scan_results> cached_scan_results;
+    cached_scan_results.resize(kMaxCachedGscanResults);
+    int32_t num_results = 0;
+    wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
+            getIfaceHandle(iface_name), true /* always flush */, cached_scan_results.size(),
+            cached_scan_results.data(), &num_results);
+    CHECK(num_results >= 0 && static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
+    cached_scan_results.resize(num_results);
+    // Check for invalid IE lengths in these cached scan results and correct it.
+    for (auto& cached_scan_result : cached_scan_results) {
+        int num_scan_results = cached_scan_result.num_results;
+        for (int i = 0; i < num_scan_results; i++) {
+            auto& scan_result = cached_scan_result.results[i];
+            if (scan_result.ie_length > 0) {
+                LOG(DEBUG) << "Cached scan result has non-zero IE length " << scan_result.ie_length;
+                scan_result.ie_length = 0;
+            }
+        }
+    }
+    return {status, std::move(cached_scan_results)};
+}
+
+wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname,
+                                                 wifi_interface_type iftype) {
+    // Create the interface if it doesn't exist. If interface already exist,
+    // Vendor Hal should return WIFI_SUCCESS.
+    wifi_error status = global_func_table_.wifi_virtual_interface_create(global_handle_,
+                                                                         ifname.c_str(), iftype);
+    return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
+}
+
+wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) {
+    // Delete the interface if it was created dynamically.
+    wifi_error status =
+            global_func_table_.wifi_virtual_interface_delete(global_handle_, ifname.c_str());
+    return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
+}
+
+wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
+                                                                     wifi_error status) {
+    if (status == WIFI_SUCCESS) {
+        // refresh list of handlers now.
+        status = retrieveIfaceHandles();
+    } else if (status == WIFI_ERROR_NOT_SUPPORTED) {
+        // Vendor hal does not implement this API. Such vendor implementations
+        // are expected to create / delete interface by other means.
+
+        // check if interface exists.
+        if (if_nametoindex(ifname.c_str())) {
+            status = retrieveIfaceHandles();
+        }
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, std::string& ifname) {
+    std::array<char, IFNAMSIZ> buffer;
+
+    wifi_error res = global_func_table_.wifi_get_supported_iface_name(
+            global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size());
+    if (res == WIFI_SUCCESS) ifname = buffer.data();
+
+    return res;
+}
+
+wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(const std::string& ifname) {
+    return global_func_table_.wifi_multi_sta_set_primary_connection(global_handle_,
+                                                                    getIfaceHandle(ifname));
+}
+
+wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) {
+    return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, use_case);
+}
+
+wifi_error WifiLegacyHal::setCoexUnsafeChannels(
+        std::vector<wifi_coex_unsafe_channel> unsafe_channels, uint32_t restrictions) {
+    return global_func_table_.wifi_set_coex_unsafe_channels(global_handle_, unsafe_channels.size(),
+                                                            unsafe_channels.data(), restrictions);
+}
+
+wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, wifi_voip_mode mode) {
+    return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode);
+}
+
+wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name,
+                                             const TwtCallbackHandlers& user_callbacks) {
+    on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
+    on_twt_event_teardown_completion_callback = user_callbacks.on_teardown_completion;
+    on_twt_event_info_frame_received_callback = user_callbacks.on_info_frame_received;
+    on_twt_event_device_notify_callback = user_callbacks.on_device_notify;
+
+    return global_func_table_.wifi_twt_register_handler(
+            getIfaceHandle(iface_name),
+            {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion,
+             onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify});
+}
+
+std::pair<wifi_error, TwtCapabilitySet> WifiLegacyHal::twtGetCapability(
+        const std::string& iface_name) {
+    TwtCapabilitySet capSet;
+    wifi_error status =
+            global_func_table_.wifi_twt_get_capability(getIfaceHandle(iface_name), &capSet);
+    return {status, capSet};
+}
+
+wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name,
+                                          const TwtSetupRequest& msg) {
+    TwtSetupRequest msgInternal(msg);
+    return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name,
+                                             const TwtTeardownRequest& msg) {
+    TwtTeardownRequest msgInternal(msg);
+    return global_func_table_.wifi_twt_teardown_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name,
+                                              const TwtInfoFrameRequest& msg) {
+    TwtInfoFrameRequest msgInternal(msg);
+    return global_func_table_.wifi_twt_info_frame_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats(const std::string& iface_name,
+                                                           uint8_t configId) {
+    TwtStats stats;
+    wifi_error status =
+            global_func_table_.wifi_twt_get_stats(getIfaceHandle(iface_name), configId, &stats);
+    return {status, stats};
+}
+
+wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, uint8_t configId) {
+    return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), configId);
+}
+
+wifi_error WifiLegacyHal::setScanMode(const std::string& iface_name, bool enable) {
+    return global_func_table_.wifi_set_scan_mode(iface_name.c_str(), enable);
+}
+
+wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) {
+    return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), multiplier);
+}
+
+std::pair<wifi_error, std::vector<wifi_usable_channel>> WifiLegacyHal::getUsableChannels(
+        uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask) {
+    std::vector<wifi_usable_channel> channels;
+    channels.resize(kMaxWifiUsableChannels);
+    uint32_t size = 0;
+    wifi_error status = global_func_table_.wifi_get_usable_channels(
+            global_handle_, band_mask, iface_mode_mask, filter_mask, channels.size(), &size,
+            reinterpret_cast<wifi_usable_channel*>(channels.data()));
+    CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
+    channels.resize(size);
+    return {status, std::move(channels)};
+}
+
+wifi_error WifiLegacyHal::triggerSubsystemRestart() {
+    return global_func_table_.wifi_trigger_subsystem_restart(global_handle_);
+}
+
+wifi_error WifiLegacyHal::setIndoorState(bool isIndoor) {
+    return global_func_table_.wifi_set_indoor_state(global_handle_, isIndoor);
+}
+
+std::pair<wifi_error, wifi_radio_combination_matrix*>
+WifiLegacyHal::getSupportedRadioCombinationsMatrix() {
+    char* buffer = new char[kMaxSupportedRadioCombinationsMatrixLength];
+    std::fill(buffer, buffer + kMaxSupportedRadioCombinationsMatrixLength, 0);
+    uint32_t size = 0;
+    wifi_radio_combination_matrix* radio_combination_matrix_ptr =
+            reinterpret_cast<wifi_radio_combination_matrix*>(buffer);
+    wifi_error status = global_func_table_.wifi_get_supported_radio_combinations_matrix(
+            global_handle_, kMaxSupportedRadioCombinationsMatrixLength, &size,
+            radio_combination_matrix_ptr);
+    CHECK(size >= 0 && size <= kMaxSupportedRadioCombinationsMatrixLength);
+    return {status, radio_combination_matrix_ptr};
+}
+
+wifi_error WifiLegacyHal::chreNanRttRequest(const std::string& iface_name, bool enable) {
+    if (enable)
+        return global_func_table_.wifi_nan_rtt_chre_enable_request(0, getIfaceHandle(iface_name),
+                                                                   NULL);
+    else
+        return global_func_table_.wifi_nan_rtt_chre_disable_request(0, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::chreRegisterHandler(const std::string& iface_name,
+                                              const ChreCallbackHandlers& handler) {
+    if (on_chre_nan_rtt_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    on_chre_nan_rtt_internal_callback = handler.on_wifi_chre_nan_rtt_state;
+
+    wifi_error status = global_func_table_.wifi_chre_register_handler(getIfaceHandle(iface_name),
+                                                                      {onAsyncChreNanRttState});
+    if (status != WIFI_SUCCESS) {
+        on_chre_nan_rtt_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::enableWifiTxPowerLimits(const std::string& iface_name, bool enable) {
+    return global_func_table_.wifi_enable_tx_power_limits(getIfaceHandle(iface_name), enable);
+}
+
+wifi_error WifiLegacyHal::getWifiCachedScanResults(
+        const std::string& iface_name, const CachedScanResultsCallbackHandlers& handler) {
+    on_cached_scan_results_internal_callback = handler.on_cached_scan_results;
+
+    wifi_error status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
+                                                                        {onSyncCachedScanResults});
+
+    on_cached_scan_results_internal_callback = nullptr;
+    return status;
+}
+
+std::pair<wifi_error, wifi_chip_capabilities> WifiLegacyHal::getWifiChipCapabilities() {
+    wifi_chip_capabilities chip_capabilities;
+    wifi_error status =
+            global_func_table_.wifi_get_chip_capabilities(global_handle_, &chip_capabilities);
+    return {status, chip_capabilities};
+}
+
+wifi_error WifiLegacyHal::enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag) {
+    return global_func_table_.wifi_enable_sta_channel_for_peer_network(global_handle_,
+                                                                       channelCategoryEnableFlag);
+}
+
+wifi_error WifiLegacyHal::setMloMode(wifi_mlo_mode mode) {
+    return global_func_table_.wifi_set_mlo_mode(global_handle_, mode);
+}
+
+std::pair<wifi_error, wifi_iface_concurrency_matrix>
+WifiLegacyHal::getSupportedIfaceConcurrencyMatrix() {
+    wifi_iface_concurrency_matrix iface_concurrency_matrix;
+    wifi_error status = global_func_table_.wifi_get_supported_iface_concurrency_matrix(
+            global_handle_, &iface_concurrency_matrix);
+    return {status, iface_concurrency_matrix};
+}
+
+void WifiLegacyHal::invalidate() {
+    global_handle_ = nullptr;
+    iface_name_to_handle_.clear();
+    on_driver_memory_dump_internal_callback = nullptr;
+    on_firmware_memory_dump_internal_callback = nullptr;
+    on_gscan_event_internal_callback = nullptr;
+    on_gscan_full_result_internal_callback = nullptr;
+    on_link_layer_stats_result_internal_callback = nullptr;
+    on_link_layer_ml_stats_result_internal_callback = nullptr;
+    on_rssi_threshold_breached_internal_callback = nullptr;
+    on_ring_buffer_data_internal_callback = nullptr;
+    on_error_alert_internal_callback = nullptr;
+    on_radio_mode_change_internal_callback = nullptr;
+    on_subsystem_restart_internal_callback = nullptr;
+    invalidateRttResultsCallbacks();
+    on_nan_notify_response_user_callback = nullptr;
+    on_nan_event_publish_terminated_user_callback = nullptr;
+    on_nan_event_match_user_callback = nullptr;
+    on_nan_event_match_expired_user_callback = nullptr;
+    on_nan_event_subscribe_terminated_user_callback = nullptr;
+    on_nan_event_followup_user_callback = nullptr;
+    on_nan_event_disc_eng_event_user_callback = nullptr;
+    on_nan_event_disabled_user_callback = nullptr;
+    on_nan_event_tca_user_callback = nullptr;
+    on_nan_event_beacon_sdf_payload_user_callback = nullptr;
+    on_nan_event_data_path_request_user_callback = nullptr;
+    on_nan_event_pairing_request_user_callback = nullptr;
+    on_nan_event_pairing_confirm_user_callback = nullptr;
+    on_nan_event_bootstrapping_request_user_callback = nullptr;
+    on_nan_event_bootstrapping_confirm_user_callback = nullptr;
+    on_nan_event_data_path_confirm_user_callback = nullptr;
+    on_nan_event_data_path_end_user_callback = nullptr;
+    on_nan_event_transmit_follow_up_user_callback = nullptr;
+    on_nan_event_range_request_user_callback = nullptr;
+    on_nan_event_range_report_user_callback = nullptr;
+    on_nan_event_schedule_update_user_callback = nullptr;
+    on_twt_event_setup_response_callback = nullptr;
+    on_twt_event_teardown_completion_callback = nullptr;
+    on_twt_event_info_frame_received_callback = nullptr;
+    on_twt_event_device_notify_callback = nullptr;
+    on_chre_nan_rtt_internal_callback = nullptr;
+}
+
+}  // namespace legacy_hal
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
new file mode 100644
index 0000000..5168a8b
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -0,0 +1,828 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_LEGACY_HAL_H_
+#define WIFI_LEGACY_HAL_H_
+
+#include <hardware_legacy/wifi_hal.h>
+#include <wifi_system/interface_tool.h>
+
+#include <condition_variable>
+#include <functional>
+#include <map>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+// This is in a separate namespace to prevent typename conflicts between
+// the legacy HAL types and the AIDL interface types.
+namespace legacy_hal {
+// Import all the types defined inside the legacy HAL header files into this
+// namespace.
+using ::chre_nan_rtt_state;
+using ::frame_info;
+using ::frame_type;
+using ::FRAME_TYPE_80211_MGMT;
+using ::FRAME_TYPE_ETHERNET_II;
+using ::FRAME_TYPE_UNKNOWN;
+using ::fw_roaming_state_t;
+using ::mac_addr;
+using ::NAN_BOOTSTRAPPING_INITIATOR_RESPONSE;
+using ::NAN_BOOTSTRAPPING_RESPONDER_RESPONSE;
+using ::NAN_CHANNEL_24G_BAND;
+using ::NAN_CHANNEL_5G_BAND_HIGH;
+using ::NAN_CHANNEL_5G_BAND_LOW;
+using ::NAN_DISABLE_RANGE_REPORT;
+using ::NAN_DO_NOT_USE_SRF;
+using ::NAN_DP_CHANNEL_NOT_REQUESTED;
+using ::NAN_DP_CONFIG_NO_SECURITY;
+using ::NAN_DP_CONFIG_SECURITY;
+using ::NAN_DP_END;
+using ::NAN_DP_FORCE_CHANNEL_SETUP;
+using ::NAN_DP_INITIATOR_RESPONSE;
+using ::NAN_DP_INTERFACE_CREATE;
+using ::NAN_DP_INTERFACE_DELETE;
+using ::NAN_DP_REQUEST_ACCEPT;
+using ::NAN_DP_REQUEST_CHANNEL_SETUP;
+using ::NAN_DP_REQUEST_REJECT;
+using ::NAN_DP_RESPONDER_RESPONSE;
+using ::NAN_GET_CAPABILITIES;
+using ::NAN_MATCH_ALG_MATCH_CONTINUOUS;
+using ::NAN_MATCH_ALG_MATCH_NEVER;
+using ::NAN_MATCH_ALG_MATCH_ONCE;
+using ::NAN_PAIRING_END;
+using ::NAN_PAIRING_INITIATOR_RESPONSE;
+using ::NAN_PAIRING_RESPONDER_RESPONSE;
+using ::NAN_PAIRING_SETUP;
+using ::NAN_PAIRING_VERIFICATION;
+using ::NAN_PUBLISH_TYPE_SOLICITED;
+using ::NAN_PUBLISH_TYPE_UNSOLICITED;
+using ::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
+using ::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+using ::NAN_RANGING_AUTO_RESPONSE_ENABLE;
+using ::NAN_RANGING_DISABLE;
+using ::NAN_RANGING_ENABLE;
+using ::NAN_RESPONSE_BEACON_SDF_PAYLOAD;
+using ::NAN_RESPONSE_CONFIG;
+using ::NAN_RESPONSE_DISABLED;
+using ::NAN_RESPONSE_ENABLED;
+using ::NAN_RESPONSE_ERROR;
+using ::NAN_RESPONSE_PUBLISH;
+using ::NAN_RESPONSE_PUBLISH_CANCEL;
+using ::NAN_RESPONSE_STATS;
+using ::NAN_RESPONSE_SUBSCRIBE;
+using ::NAN_RESPONSE_SUBSCRIBE_CANCEL;
+using ::NAN_RESPONSE_TCA;
+using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP;
+using ::NAN_RESUME_REQUEST_RESPONSE;
+using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+using ::NAN_SECURITY_KEY_INPUT_PMK;
+using ::NAN_SERVICE_ACCEPT_POLICY_ALL;
+using ::NAN_SERVICE_ACCEPT_POLICY_NONE;
+using ::NAN_SRF_ATTR_BLOOM_FILTER;
+using ::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
+using ::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
+using ::NAN_SRF_INCLUDE_RESPOND;
+using ::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
+using ::NAN_SSI_REQUIRED_IN_MATCH_IND;
+using ::NAN_STATUS_ALREADY_ENABLED;
+using ::NAN_STATUS_FOLLOWUP_QUEUE_FULL;
+using ::NAN_STATUS_INTERNAL_FAILURE;
+using ::NAN_STATUS_INVALID_BOOTSTRAPPING_ID;
+using ::NAN_STATUS_INVALID_NDP_ID;
+using ::NAN_STATUS_INVALID_PAIRING_ID;
+using ::NAN_STATUS_INVALID_PARAM;
+using ::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
+using ::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID;
+using ::NAN_STATUS_NAN_NOT_ALLOWED;
+using ::NAN_STATUS_NO_CONNECTION;
+using ::NAN_STATUS_NO_OTA_ACK;
+using ::NAN_STATUS_NO_RESOURCE_AVAILABLE;
+using ::NAN_STATUS_NOT_SUPPORTED;
+using ::NAN_STATUS_PROTOCOL_FAILURE;
+using ::NAN_STATUS_REDUNDANT_REQUEST;
+using ::NAN_STATUS_SUCCESS;
+using ::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
+using ::NAN_SUBSCRIBE_TYPE_ACTIVE;
+using ::NAN_SUBSCRIBE_TYPE_PASSIVE;
+using ::NAN_SUSPEND_REQUEST_RESPONSE;
+using ::NAN_TRANSMIT_IN_DW;
+using ::NAN_TRANSMIT_IN_FAW;
+using ::NAN_TX_PRIORITY_HIGH;
+using ::NAN_TX_PRIORITY_NORMAL;
+using ::NAN_TX_TYPE_BROADCAST;
+using ::NAN_TX_TYPE_UNICAST;
+using ::NAN_USE_SRF;
+using ::NanAkm;
+using ::NanBeaconSdfPayloadInd;
+using ::NanBootstrappingConfirmInd;
+using ::NanBootstrappingIndicationResponse;
+using ::NanBootstrappingRequest;
+using ::NanBootstrappingRequestInd;
+using ::NanBootstrappingRequestResponse;
+using ::NanBootstrappingResponseCode;
+using ::NanCapabilities;
+using ::NanChannelInfo;
+using ::NanConfigRequest;
+using ::NanDataPathChannelCfg;
+using ::NanDataPathConfirmInd;
+using ::NanDataPathEndInd;
+using ::NanDataPathIndicationResponse;
+using ::NanDataPathInitiatorRequest;
+using ::NanDataPathRequestInd;
+using ::NanDataPathScheduleUpdateInd;
+using ::NanDisabledInd;
+using ::NanDiscEngEventInd;
+using ::NanEnableRequest;
+using ::NanFollowupInd;
+using ::NanIdentityResolutionAttribute;
+using ::NanMatchAlg;
+using ::NanMatchExpiredInd;
+using ::NanMatchInd;
+using ::NanPairingConfig;
+using ::NanPairingConfirmInd;
+using ::NanPairingEndRequest;
+using ::NanPairingIndicationResponse;
+using ::NanPairingRequest;
+using ::NanPairingRequestInd;
+using ::NanPairingRequestResponse;
+using ::NanPairingRequestType;
+using ::NanPairingResponseCode;
+using ::NanPublishCancelRequest;
+using ::NanPublishRequest;
+using ::NanPublishTerminatedInd;
+using ::NanPublishType;
+using ::NanRangeReportInd;
+using ::NanRangeRequestInd;
+using ::NanResponseMsg;
+using ::NanResumeRequest;
+using ::NanSRFType;
+using ::NanStatusType;
+using ::NanSubscribeCancelRequest;
+using ::NanSubscribeRequest;
+using ::NanSubscribeTerminatedInd;
+using ::NanSubscribeType;
+using ::NanSuspendRequest;
+using ::NanSuspensionModeChangeInd;
+using ::NanTransmitFollowupInd;
+using ::NanTransmitFollowupRequest;
+using ::NanTxType;
+using ::NpkSecurityAssociation;
+using ::PASN;
+using ::ROAMING_DISABLE;
+using ::ROAMING_ENABLE;
+using ::RTT_PEER_AP;
+using ::RTT_PEER_NAN;
+using ::RTT_PEER_P2P_CLIENT;
+using ::RTT_PEER_P2P_GO;
+using ::RTT_PEER_STA;
+using ::rtt_peer_type;
+using ::RTT_STATUS_ABORTED;
+using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
+using ::RTT_STATUS_FAIL_BUSY_TRY_LATER;
+using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
+using ::RTT_STATUS_FAIL_INVALID_TS;
+using ::RTT_STATUS_FAIL_NO_CAPABILITY;
+using ::RTT_STATUS_FAIL_NO_RSP;
+using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
+using ::RTT_STATUS_FAIL_PROTOCOL;
+using ::RTT_STATUS_FAIL_REJECTED;
+using ::RTT_STATUS_FAIL_SCHEDULE;
+using ::RTT_STATUS_FAIL_TM_TIMEOUT;
+using ::RTT_STATUS_FAILURE;
+using ::RTT_STATUS_INVALID_REQ;
+using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
+using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE;
+using ::RTT_STATUS_NO_WIFI;
+using ::RTT_STATUS_SUCCESS;
+using ::RTT_TYPE_1_SIDED;
+using ::RTT_TYPE_2_SIDED;
+using ::RX_PKT_FATE_DRV_DROP_FILTER;
+using ::RX_PKT_FATE_DRV_DROP_INVALID;
+using ::RX_PKT_FATE_DRV_DROP_NOBUFS;
+using ::RX_PKT_FATE_DRV_DROP_OTHER;
+using ::RX_PKT_FATE_DRV_QUEUED;
+using ::RX_PKT_FATE_FW_DROP_FILTER;
+using ::RX_PKT_FATE_FW_DROP_INVALID;
+using ::RX_PKT_FATE_FW_DROP_NOBUFS;
+using ::RX_PKT_FATE_FW_DROP_OTHER;
+using ::RX_PKT_FATE_FW_QUEUED;
+using ::RX_PKT_FATE_SUCCESS;
+using ::SAE;
+using ::ssid_t;
+using ::transaction_id;
+using ::TX_PKT_FATE_ACKED;
+using ::TX_PKT_FATE_DRV_DROP_INVALID;
+using ::TX_PKT_FATE_DRV_DROP_NOBUFS;
+using ::TX_PKT_FATE_DRV_DROP_OTHER;
+using ::TX_PKT_FATE_DRV_QUEUED;
+using ::TX_PKT_FATE_FW_DROP_INVALID;
+using ::TX_PKT_FATE_FW_DROP_NOBUFS;
+using ::TX_PKT_FATE_FW_DROP_OTHER;
+using ::TX_PKT_FATE_FW_QUEUED;
+using ::TX_PKT_FATE_SENT;
+using ::WIFI_AC_BE;
+using ::WIFI_AC_BK;
+using ::WIFI_AC_VI;
+using ::WIFI_AC_VO;
+using ::WIFI_ANTENNA_1X1;
+using ::WIFI_ANTENNA_2X2;
+using ::WIFI_ANTENNA_3X3;
+using ::WIFI_ANTENNA_4X4;
+using ::WIFI_ANTENNA_UNSPECIFIED;
+using ::wifi_band;
+using ::WIFI_BAND_A;
+using ::WIFI_BAND_A_DFS;
+using ::WIFI_BAND_A_WITH_DFS;
+using ::WIFI_BAND_ABG;
+using ::WIFI_BAND_ABG_WITH_DFS;
+using ::WIFI_BAND_BG;
+using ::WIFI_BAND_UNSPECIFIED;
+using ::wifi_cached_scan_report;
+using ::wifi_cached_scan_results;
+using ::WIFI_CHAN_WIDTH_10;
+using ::WIFI_CHAN_WIDTH_160;
+using ::WIFI_CHAN_WIDTH_20;
+using ::WIFI_CHAN_WIDTH_320;
+using ::WIFI_CHAN_WIDTH_40;
+using ::WIFI_CHAN_WIDTH_5;
+using ::WIFI_CHAN_WIDTH_80;
+using ::WIFI_CHAN_WIDTH_80P80;
+using ::WIFI_CHAN_WIDTH_INVALID;
+using ::wifi_channel_category;
+using ::wifi_channel_info;
+using ::wifi_channel_stat;
+using ::wifi_channel_width;
+using ::wifi_chip_capabilities;
+using ::wifi_coex_restriction;
+using ::wifi_coex_unsafe_channel;
+using ::WIFI_DFS_CHANNEL;
+using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
+using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+using ::wifi_error;
+using ::WIFI_ERROR_BUSY;
+using ::WIFI_ERROR_INVALID_ARGS;
+using ::WIFI_ERROR_INVALID_REQUEST_ID;
+using ::WIFI_ERROR_NONE;
+using ::WIFI_ERROR_NOT_AVAILABLE;
+using ::WIFI_ERROR_NOT_SUPPORTED;
+using ::WIFI_ERROR_OUT_OF_MEMORY;
+using ::WIFI_ERROR_TIMED_OUT;
+using ::WIFI_ERROR_TOO_MANY_REQUESTS;
+using ::WIFI_ERROR_UNINITIALIZED;
+using ::WIFI_ERROR_UNKNOWN;
+using ::wifi_gscan_capabilities;
+using ::wifi_hal_fn;
+using ::wifi_iface_concurrency_matrix;
+using ::WIFI_INDOOR_CHANNEL;
+using ::wifi_information_element;
+using ::WIFI_INTERFACE_IBSS;
+using ::WIFI_INTERFACE_MESH;
+using ::wifi_interface_mode;
+using ::WIFI_INTERFACE_NAN;
+using ::WIFI_INTERFACE_P2P_CLIENT;
+using ::WIFI_INTERFACE_P2P_GO;
+using ::WIFI_INTERFACE_SOFTAP;
+using ::WIFI_INTERFACE_STA;
+using ::WIFI_INTERFACE_TDLS;
+using ::wifi_interface_type;
+using ::WIFI_INTERFACE_TYPE_AP;
+using ::WIFI_INTERFACE_TYPE_NAN;
+using ::WIFI_INTERFACE_TYPE_P2P;
+using ::WIFI_INTERFACE_TYPE_STA;
+using ::WIFI_INTERFACE_UNKNOWN;
+using ::wifi_latency_mode;
+using ::WIFI_LATENCY_MODE_LOW;
+using ::WIFI_LATENCY_MODE_NORMAL;
+using ::wifi_lci_information;
+using ::wifi_lcr_information;
+using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
+using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
+using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
+using ::WIFI_LOGGER_PACKET_FATE_SUPPORTED;
+using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED;
+using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
+using ::wifi_mlo_mode;
+using ::WIFI_MOTION_EXPECTED;
+using ::WIFI_MOTION_NOT_EXPECTED;
+using ::wifi_motion_pattern;
+using ::WIFI_MOTION_UNKNOWN;
+using ::wifi_multi_sta_use_case;
+using ::wifi_power_scenario;
+using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
+using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
+using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
+using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
+using ::WIFI_POWER_SCENARIO_VOICE_CALL;
+using ::wifi_radio_combination;
+using ::wifi_radio_combination_matrix;
+using ::wifi_radio_configuration;
+using ::wifi_rate;
+using ::wifi_request_id;
+using ::wifi_ring_buffer_status;
+using ::wifi_roaming_capabilities;
+using ::wifi_roaming_config;
+using ::wifi_rtt_bw;
+using ::WIFI_RTT_BW_10;
+using ::WIFI_RTT_BW_160;
+using ::WIFI_RTT_BW_20;
+using ::WIFI_RTT_BW_320;
+using ::WIFI_RTT_BW_40;
+using ::WIFI_RTT_BW_5;
+using ::WIFI_RTT_BW_80;
+using ::WIFI_RTT_BW_UNSPECIFIED;
+using ::wifi_rtt_capabilities;
+using ::wifi_rtt_config;
+using ::wifi_rtt_preamble;
+using ::WIFI_RTT_PREAMBLE_EHT;
+using ::WIFI_RTT_PREAMBLE_HE;
+using ::WIFI_RTT_PREAMBLE_HT;
+using ::WIFI_RTT_PREAMBLE_LEGACY;
+using ::WIFI_RTT_PREAMBLE_VHT;
+using ::wifi_rtt_responder;
+using ::wifi_rtt_result;
+using ::wifi_rtt_result_v2;
+using ::wifi_rtt_status;
+using ::wifi_rtt_type;
+using ::wifi_rx_packet_fate;
+using ::wifi_rx_report;
+using ::wifi_scan_bucket_spec;
+using ::wifi_scan_cmd_params;
+using ::WIFI_SCAN_FLAG_INTERRUPTED;
+using ::wifi_scan_result;
+using ::WIFI_SUCCESS;
+using ::wifi_tx_packet_fate;
+using ::wifi_tx_report;
+using ::wifi_usable_channel;
+using ::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
+using ::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
+using ::WLAN_MAC_2_4_BAND;
+using ::WLAN_MAC_5_0_BAND;
+using ::WLAN_MAC_60_0_BAND;
+using ::WLAN_MAC_6_0_BAND;
+
+// APF capabilities supported by the iface.
+struct PacketFilterCapabilities {
+    uint32_t version;
+    uint32_t max_len;
+};
+
+// WARNING: We don't care about the variable sized members of either
+// |wifi_iface_stat|, |wifi_radio_stat| structures. So, using the pragma
+// to escape the compiler warnings regarding this.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
+// The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in
+// |wifi_radio_stat| structure in the legacy HAL API. Separate that out
+// into a separate return element to avoid passing pointers around.
+struct LinkLayerRadioStats {
+    wifi_radio_stat stats;
+    std::vector<uint32_t> tx_time_per_levels;
+    std::vector<wifi_channel_stat> channel_stats;
+};
+
+struct WifiPeerInfo {
+    wifi_peer_info peer_info;
+    std::vector<wifi_rate_stat> rate_stats;
+};
+
+struct LinkLayerStats {
+    wifi_iface_stat iface;
+    std::vector<LinkLayerRadioStats> radios;
+    std::vector<WifiPeerInfo> peers;
+    bool valid;
+};
+
+struct LinkStats {
+    wifi_link_stat stat;
+    std::vector<WifiPeerInfo> peers;
+};
+
+struct LinkLayerMlStats {
+    wifi_iface_ml_stat iface;
+    std::vector<LinkStats> links;
+    std::vector<LinkLayerRadioStats> radios;
+    bool valid;
+};
+
+#pragma GCC diagnostic pop
+
+// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
+// |WLAN_DRIVER_WAKE_REASON_CNT.driver_fw_local_wake_cnt| stats is provided
+// as a pointer in |WLAN_DRIVER_WAKE_REASON_CNT| structure in the legacy HAL
+// API. Separate that out into a separate return elements to avoid passing
+// pointers around.
+struct WakeReasonStats {
+    WLAN_DRIVER_WAKE_REASON_CNT wake_reason_cnt;
+    std::vector<uint32_t> cmd_event_wake_cnt;
+    std::vector<uint32_t> driver_fw_local_wake_cnt;
+};
+
+// NAN response and event callbacks struct.
+struct NanCallbackHandlers {
+    // NotifyResponse invoked to notify the status of the Request.
+    std::function<void(transaction_id, const NanResponseMsg&)> on_notify_response;
+    // Various event callbacks.
+    std::function<void(const NanPublishTerminatedInd&)> on_event_publish_terminated;
+    std::function<void(const NanMatchInd&)> on_event_match;
+    std::function<void(const NanMatchExpiredInd&)> on_event_match_expired;
+    std::function<void(const NanSubscribeTerminatedInd&)> on_event_subscribe_terminated;
+    std::function<void(const NanFollowupInd&)> on_event_followup;
+    std::function<void(const NanDiscEngEventInd&)> on_event_disc_eng_event;
+    std::function<void(const NanDisabledInd&)> on_event_disabled;
+    std::function<void(const NanTCAInd&)> on_event_tca;
+    std::function<void(const NanBeaconSdfPayloadInd&)> on_event_beacon_sdf_payload;
+    std::function<void(const NanDataPathRequestInd&)> on_event_data_path_request;
+    std::function<void(const NanDataPathConfirmInd&)> on_event_data_path_confirm;
+    std::function<void(const NanDataPathEndInd&)> on_event_data_path_end;
+    std::function<void(const NanTransmitFollowupInd&)> on_event_transmit_follow_up;
+    std::function<void(const NanRangeRequestInd&)> on_event_range_request;
+    std::function<void(const NanRangeReportInd&)> on_event_range_report;
+    std::function<void(const NanDataPathScheduleUpdateInd&)> on_event_schedule_update;
+    std::function<void(const NanPairingRequestInd&)> on_event_pairing_request;
+    std::function<void(const NanPairingConfirmInd&)> on_event_pairing_confirm;
+    std::function<void(const NanBootstrappingRequestInd&)> on_event_bootstrapping_request;
+    std::function<void(const NanBootstrappingConfirmInd&)> on_event_bootstrapping_confirm;
+    std::function<void(const NanSuspensionModeChangeInd&)> on_event_suspension_mode_change;
+};
+
+// Full scan results contain IE info and are hence passed by reference, to
+// preserve the variable length array member |ie_data|. Callee must not retain
+// the pointer.
+using on_gscan_full_result_callback =
+        std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>;
+// These scan results don't contain any IE info, so no need to pass by
+// reference.
+using on_gscan_results_callback =
+        std::function<void(wifi_request_id, const std::vector<wifi_cached_scan_results>&)>;
+
+// Invoked when the rssi value breaches the thresholds set.
+using on_rssi_threshold_breached_callback =
+        std::function<void(wifi_request_id, std::array<uint8_t, ETH_ALEN>, int8_t)>;
+
+// Callback for RTT range request results.
+// Rtt results contain IE info and are hence passed by reference, to
+// preserve the |LCI| and |LCR| pointers. Callee must not retain
+// the pointer.
+using on_rtt_results_callback =
+        std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result*>&)>;
+using on_rtt_results_callback_v2 =
+        std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result_v2*>&)>;
+
+// Callback for ring buffer data.
+using on_ring_buffer_data_callback = std::function<void(
+        const std::string&, const std::vector<uint8_t>&, const wifi_ring_buffer_status&)>;
+
+// Callback for alerts.
+using on_error_alert_callback = std::function<void(int32_t, const std::vector<uint8_t>&)>;
+
+// Callback for subsystem restart
+using on_subsystem_restart_callback = std::function<void(const std::string&)>;
+
+// Struct for the mac info from the legacy HAL. This is a cleaner version
+// of the |wifi_mac_info| & |wifi_iface_info|.
+typedef struct {
+    std::string name;
+    wifi_channel channel;
+} WifiIfaceInfo;
+
+typedef struct {
+    uint32_t wlan_mac_id;
+    /* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */
+    uint32_t mac_band;
+    /* Represents the connected Wi-Fi interfaces associated with each MAC */
+    std::vector<WifiIfaceInfo> iface_infos;
+} WifiMacInfo;
+
+// Callback for radio mode change
+using on_radio_mode_change_callback = std::function<void(const std::vector<WifiMacInfo>&)>;
+
+// TWT response and event callbacks struct.
+struct TwtCallbackHandlers {
+    // Callback for TWT setup response
+    std::function<void(const TwtSetupResponse&)> on_setup_response;
+    // Callback for TWT teardown completion
+    std::function<void(const TwtTeardownCompletion&)> on_teardown_completion;
+    // Callback for TWT info frame received event
+    std::function<void(const TwtInfoFrameReceived&)> on_info_frame_received;
+    // Callback for TWT notification from the device
+    std::function<void(const TwtDeviceNotify&)> on_device_notify;
+};
+
+// CHRE response and event callbacks struct.
+struct ChreCallbackHandlers {
+    // Callback for CHRE NAN RTT
+    std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
+};
+
+// Cached Scan Results response and event callbacks struct.
+struct CachedScanResultsCallbackHandlers {
+    // Callback for Cached Scan Results
+    std::function<void(wifi_cached_scan_report*)> on_cached_scan_results;
+};
+
+/**
+ * Class that encapsulates all legacy HAL interactions.
+ * This class manages the lifetime of the event loop thread used by legacy HAL.
+ *
+ * Note: There will only be a single instance of this class created in the Wifi
+ * object and will be valid for the lifetime of the process.
+ */
+class WifiLegacyHal {
+  public:
+    WifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+                  const wifi_hal_fn& fn, bool is_primary);
+    virtual ~WifiLegacyHal() = default;
+
+    // Initialize the legacy HAL function table.
+    virtual wifi_error initialize();
+    // Start the legacy HAL and the event looper thread.
+    virtual wifi_error start();
+    // Deinitialize the legacy HAL and wait for the event loop thread to exit
+    // using a predefined timeout.
+    virtual wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
+                            const std::function<void()>& on_complete_callback);
+    virtual wifi_error waitForDriverReady();
+    // Checks if legacy HAL has successfully started
+    bool isStarted();
+    // Wrappers for all the functions in the legacy HAL function table.
+    virtual std::pair<wifi_error, std::string> getDriverVersion(const std::string& iface_name);
+    virtual std::pair<wifi_error, std::string> getFirmwareVersion(const std::string& iface_name);
+    std::pair<wifi_error, std::vector<uint8_t>> requestDriverMemoryDump(
+            const std::string& iface_name);
+    std::pair<wifi_error, std::vector<uint8_t>> requestFirmwareMemoryDump(
+            const std::string& iface_name);
+    virtual std::pair<wifi_error, uint64_t> getSupportedFeatureSet(const std::string& iface_name);
+    // APF functions.
+    std::pair<wifi_error, PacketFilterCapabilities> getPacketFilterCapabilities(
+            const std::string& iface_name);
+    wifi_error setPacketFilter(const std::string& iface_name, const std::vector<uint8_t>& program);
+    std::pair<wifi_error, std::vector<uint8_t>> readApfPacketFilterData(
+            const std::string& iface_name);
+    // Gscan functions.
+    std::pair<wifi_error, wifi_gscan_capabilities> getGscanCapabilities(
+            const std::string& iface_name);
+    // These API's provides a simplified interface over the legacy Gscan API's:
+    // a) All scan events from the legacy HAL API other than the
+    //    |WIFI_SCAN_FAILED| are treated as notification of results.
+    //    This method then retrieves the cached scan results from the legacy
+    //    HAL API and triggers the externally provided
+    //    |on_results_user_callback| on success.
+    // b) |WIFI_SCAN_FAILED| scan event or failure to retrieve cached scan
+    // results
+    //    Triggers the externally provided |on_failure_user_callback|.
+    // c) Full scan result event triggers the externally provided
+    //    |on_full_result_user_callback|.
+    wifi_error startGscan(const std::string& iface_name, wifi_request_id id,
+                          const wifi_scan_cmd_params& params,
+                          const std::function<void(wifi_request_id)>& on_failure_callback,
+                          const on_gscan_results_callback& on_results_callback,
+                          const on_gscan_full_result_callback& on_full_result_callback);
+    wifi_error stopGscan(const std::string& iface_name, wifi_request_id id);
+    std::pair<wifi_error, std::vector<uint32_t>> getValidFrequenciesForBand(
+            const std::string& iface_name, wifi_band band);
+    virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on);
+    // Link layer stats functions.
+    wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug);
+    wifi_error disableLinkLayerStats(const std::string& iface_name);
+    wifi_error getLinkLayerStats(const std::string& iface_name,
+                                 legacy_hal::LinkLayerStats& legacy_stats,
+                                 legacy_hal::LinkLayerMlStats& legacy_ml_stats);
+    // RSSI monitor functions.
+    wifi_error startRssiMonitoring(
+            const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
+            const on_rssi_threshold_breached_callback& on_threshold_breached_callback);
+    wifi_error stopRssiMonitoring(const std::string& iface_name, wifi_request_id id);
+    std::pair<wifi_error, wifi_roaming_capabilities> getRoamingCapabilities(
+            const std::string& iface_name);
+    wifi_error configureRoaming(const std::string& iface_name, const wifi_roaming_config& config);
+    wifi_error enableFirmwareRoaming(const std::string& iface_name, fw_roaming_state_t state);
+    wifi_error configureNdOffload(const std::string& iface_name, bool enable);
+    wifi_error startSendingOffloadedPacket(const std::string& iface_name, int32_t cmd_id,
+                                           uint16_t ether_type,
+                                           const std::vector<uint8_t>& ip_packet_data,
+                                           const std::array<uint8_t, 6>& src_address,
+                                           const std::array<uint8_t, 6>& dst_address,
+                                           int32_t period_in_ms);
+    wifi_error stopSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id);
+    virtual wifi_error selectTxPowerScenario(const std::string& iface_name,
+                                             wifi_power_scenario scenario);
+    virtual wifi_error resetTxPowerScenario(const std::string& iface_name);
+    wifi_error setLatencyMode(const std::string& iface_name, wifi_latency_mode mode);
+    wifi_error setThermalMitigationMode(wifi_thermal_mode mode, uint32_t completion_window);
+    wifi_error setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
+                                              uint32_t access_category);
+    wifi_error resetDscpToAccessCategoryMapping();
+    // Logger/debug functions.
+    std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet(const std::string& iface_name);
+    wifi_error startPktFateMonitoring(const std::string& iface_name);
+    std::pair<wifi_error, std::vector<wifi_tx_report>> getTxPktFates(const std::string& iface_name);
+    std::pair<wifi_error, std::vector<wifi_rx_report>> getRxPktFates(const std::string& iface_name);
+    std::pair<wifi_error, WakeReasonStats> getWakeReasonStats(const std::string& iface_name);
+    wifi_error registerRingBufferCallbackHandler(
+            const std::string& iface_name, const on_ring_buffer_data_callback& on_data_callback);
+    wifi_error deregisterRingBufferCallbackHandler(const std::string& iface_name);
+    virtual wifi_error registerSubsystemRestartCallbackHandler(
+            const on_subsystem_restart_callback& on_restart_callback);
+    std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> getRingBuffersStatus(
+            const std::string& iface_name);
+    wifi_error startRingBufferLogging(const std::string& iface_name, const std::string& ring_name,
+                                      uint32_t verbose_level, uint32_t max_interval_sec,
+                                      uint32_t min_data_size);
+    wifi_error getRingBufferData(const std::string& iface_name, const std::string& ring_name);
+    wifi_error registerErrorAlertCallbackHandler(const std::string& iface_name,
+                                                 const on_error_alert_callback& on_alert_callback);
+    wifi_error deregisterErrorAlertCallbackHandler(const std::string& iface_name);
+    // Radio mode functions.
+    virtual wifi_error registerRadioModeChangeCallbackHandler(
+            const std::string& iface_name,
+            const on_radio_mode_change_callback& on_user_change_callback);
+    // RTT functions.
+    wifi_error startRttRangeRequest(const std::string& iface_name, wifi_request_id id,
+                                    const std::vector<wifi_rtt_config>& rtt_configs,
+                                    const on_rtt_results_callback& on_results_callback,
+                                    const on_rtt_results_callback_v2& on_results_callback_v2);
+    wifi_error cancelRttRangeRequest(const std::string& iface_name, wifi_request_id id,
+                                     const std::vector<std::array<uint8_t, ETH_ALEN>>& mac_addrs);
+    std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities(const std::string& iface_name);
+    std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo(const std::string& iface_name);
+    wifi_error enableRttResponder(const std::string& iface_name, wifi_request_id id,
+                                  const wifi_channel_info& channel_hint, uint32_t max_duration_secs,
+                                  const wifi_rtt_responder& info);
+    wifi_error disableRttResponder(const std::string& iface_name, wifi_request_id id);
+    wifi_error setRttLci(const std::string& iface_name, wifi_request_id id,
+                         const wifi_lci_information& info);
+    wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id,
+                         const wifi_lcr_information& info);
+    // NAN functions.
+    virtual wifi_error nanRegisterCallbackHandlers(const std::string& iface_name,
+                                                   const NanCallbackHandlers& callbacks);
+    wifi_error nanEnableRequest(const std::string& iface_name, transaction_id id,
+                                const NanEnableRequest& msg);
+    virtual wifi_error nanDisableRequest(const std::string& iface_name, transaction_id id);
+    wifi_error nanPublishRequest(const std::string& iface_name, transaction_id id,
+                                 const NanPublishRequest& msg);
+    wifi_error nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
+                                       const NanPublishCancelRequest& msg);
+    wifi_error nanSubscribeRequest(const std::string& iface_name, transaction_id id,
+                                   const NanSubscribeRequest& msg);
+    wifi_error nanSubscribeCancelRequest(const std::string& iface_name, transaction_id id,
+                                         const NanSubscribeCancelRequest& msg);
+    wifi_error nanTransmitFollowupRequest(const std::string& iface_name, transaction_id id,
+                                          const NanTransmitFollowupRequest& msg);
+    wifi_error nanStatsRequest(const std::string& iface_name, transaction_id id,
+                               const NanStatsRequest& msg);
+    wifi_error nanConfigRequest(const std::string& iface_name, transaction_id id,
+                                const NanConfigRequest& msg);
+    wifi_error nanTcaRequest(const std::string& iface_name, transaction_id id,
+                             const NanTCARequest& msg);
+    wifi_error nanBeaconSdfPayloadRequest(const std::string& iface_name, transaction_id id,
+                                          const NanBeaconSdfPayloadRequest& msg);
+    std::pair<wifi_error, NanVersion> nanGetVersion();
+    wifi_error nanGetCapabilities(const std::string& iface_name, transaction_id id);
+    wifi_error nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
+                                      const std::string& data_iface_name);
+    virtual wifi_error nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
+                                              const std::string& data_iface_name);
+    wifi_error nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
+                                       const NanDataPathInitiatorRequest& msg);
+    wifi_error nanDataIndicationResponse(const std::string& iface_name, transaction_id id,
+                                         const NanDataPathIndicationResponse& msg);
+    wifi_error nanPairingRequest(const std::string& iface_name, transaction_id id,
+                                 const NanPairingRequest& msg);
+    wifi_error nanPairingIndicationResponse(const std::string& iface_name, transaction_id id,
+                                            const NanPairingIndicationResponse& msg);
+    wifi_error nanBootstrappingRequest(const std::string& iface_name, transaction_id id,
+                                       const NanBootstrappingRequest& msg);
+    wifi_error nanBootstrappingIndicationResponse(const std::string& iface_name, transaction_id id,
+                                                  const NanBootstrappingIndicationResponse& msg);
+    wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, uint32_t ndpInstanceId);
+    wifi_error nanPairingEnd(const std::string& iface_name, transaction_id id, uint32_t pairingId);
+    wifi_error nanSuspendRequest(const std::string& iface_name, transaction_id id,
+                                 const NanSuspendRequest& msg);
+    wifi_error nanResumeRequest(const std::string& iface_name, transaction_id id,
+                                const NanResumeRequest& msg);
+    // AP functions.
+    wifi_error setCountryCode(const std::string& iface_name, const std::array<uint8_t, 2> code);
+
+    // Interface functions.
+    virtual wifi_error createVirtualInterface(const std::string& ifname,
+                                              wifi_interface_type iftype);
+    virtual wifi_error deleteVirtualInterface(const std::string& ifname);
+    virtual wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname);
+
+    // STA + STA functions
+    virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname);
+    virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case);
+
+    // Coex functions.
+    virtual wifi_error setCoexUnsafeChannels(std::vector<wifi_coex_unsafe_channel> unsafe_channels,
+                                             uint32_t restrictions);
+
+    wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode);
+
+    wifi_error twtRegisterHandler(const std::string& iface_name,
+                                  const TwtCallbackHandlers& handler);
+
+    std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(const std::string& iface_name);
+
+    wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg);
+
+    wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg);
+
+    wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg);
+
+    std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, uint8_t configId);
+
+    wifi_error twtClearStats(const std::string& iface_name, uint8_t configId);
+
+    wifi_error setScanMode(const std::string& iface_name, bool enable);
+
+    wifi_error setDtimConfig(const std::string& iface_name, uint32_t multiplier);
+
+    // Retrieve the list of usable channels in the requested bands
+    // for the requested modes
+    std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels(
+            uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask);
+
+    wifi_error triggerSubsystemRestart();
+
+    wifi_error setIndoorState(bool isIndoor);
+
+    std::pair<wifi_error, wifi_radio_combination_matrix*> getSupportedRadioCombinationsMatrix();
+
+    // CHRE NAN RTT function
+    wifi_error chreNanRttRequest(const std::string& iface_name, bool enable);
+
+    wifi_error chreRegisterHandler(const std::string& iface_name,
+                                   const ChreCallbackHandlers& handler);
+
+    wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
+    wifi_error getWifiCachedScanResults(const std::string& iface_name,
+                                        const CachedScanResultsCallbackHandlers& handler);
+    std::pair<wifi_error, wifi_chip_capabilities> getWifiChipCapabilities();
+    wifi_error enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag);
+    wifi_error setMloMode(wifi_mlo_mode mode);
+    std::pair<wifi_error, wifi_iface_concurrency_matrix> getSupportedIfaceConcurrencyMatrix();
+
+  private:
+    // Retrieve interface handles for all the available interfaces.
+    wifi_error retrieveIfaceHandles();
+    wifi_interface_handle getIfaceHandle(const std::string& iface_name);
+    // Run the legacy HAL event loop thread.
+    void runEventLoop();
+    // Retrieve the cached gscan results to pass the results back to the
+    // external callbacks.
+    std::pair<wifi_error, std::vector<wifi_cached_scan_results>> getGscanCachedResults(
+            const std::string& iface_name);
+    void invalidate();
+    // Handles wifi (error) status of Virtual interface create/delete
+    wifi_error handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
+                                                          wifi_error status);
+    wifi_link_stat* copyLinkStat(wifi_link_stat* stat_ptr, std::vector<LinkStats>& stats);
+    wifi_peer_info* copyPeerInfo(wifi_peer_info* peer_ptr, std::vector<WifiPeerInfo>& peers);
+
+    // Global function table of legacy HAL.
+    wifi_hal_fn global_func_table_;
+    // Opaque handle to be used for all global operations.
+    wifi_handle global_handle_;
+    // Map of interface name to handle that is to be used for all interface
+    // specific operations.
+    std::map<std::string, wifi_interface_handle> iface_name_to_handle_;
+    // Flag to indicate if we have initiated the cleanup of legacy HAL.
+    std::atomic<bool> awaiting_event_loop_termination_;
+    std::condition_variable_any stop_wait_cv_;
+    // Flag to indicate if the legacy HAL has been started.
+    bool is_started_;
+    std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
+    // Flag to indicate if this HAL is for the primary chip. This is used
+    // in order to avoid some hard-coded behavior used with older HALs,
+    // such as bring wlan0 interface up/down on start/stop HAL.
+    // it may be removed once vendor HALs are updated.
+    bool is_primary_;
+};
+
+}  // namespace legacy_hal
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_LEGACY_HAL_H_
diff --git a/wifi/aidl/default/wifi_legacy_hal_factory.cpp b/wifi/aidl/default/wifi_legacy_hal_factory.cpp
new file mode 100644
index 0000000..0359d6f
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal_factory.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_legacy_hal_factory.h"
+
+#include <android-base/logging.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "wifi_legacy_hal_stubs.h"
+
+namespace {
+static constexpr char kVendorHalsDescPath[] = "/vendor/etc/wifi/vendor_hals";
+static constexpr char kVendorHalsDescExt[] = ".xml";
+static constexpr uint32_t kVendorHalsDescVersion = 1;
+
+bool isDirectory(struct dirent* entryPtr) {
+    bool isDir = false;
+    if (entryPtr->d_type != DT_UNKNOWN && entryPtr->d_type != DT_LNK) {
+        isDir = (entryPtr->d_type == DT_DIR);
+    } else {
+        struct stat entryStat;
+        stat(entryPtr->d_name, &entryStat);
+        isDir = S_ISDIR(entryStat.st_mode);
+    }
+    return isDir;
+}
+
+bool isFileExtension(const char* name, const char* ext) {
+    if (name == NULL) return false;
+    if (ext == NULL) return false;
+
+    size_t extLen = strlen(ext);
+    size_t nameLen = strlen(name);
+
+    if (extLen > nameLen) return false;
+
+    if (strncmp(name + nameLen - extLen, ext, extLen) != 0) return false;
+
+    return true;
+}
+};  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+WifiLegacyHalFactory::WifiLegacyHalFactory(
+        const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool)
+    : iface_tool_(iface_tool) {}
+
+std::vector<std::shared_ptr<WifiLegacyHal>> WifiLegacyHalFactory::getHals() {
+    if (legacy_hals_.empty()) {
+        if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList();
+        for (auto& desc : descs_) {
+            std::shared_ptr<WifiLegacyHal> hal =
+                    std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn, desc.primary);
+            legacy_hals_.push_back(hal);
+        }
+    }
+
+    return legacy_hals_;
+}
+
+bool WifiLegacyHalFactory::initVendorHalDescriptorFromLinked() {
+    wifi_hal_lib_desc desc;
+
+    if (!initLinkedHalFunctionTable(&desc.fn)) return false;
+
+    desc.primary = true;
+    desc.handle = NULL;
+    descs_.push_back(desc);
+    return true;
+}
+
+bool WifiLegacyHalFactory::initLinkedHalFunctionTable(wifi_hal_fn* hal_fn) {
+    init_wifi_vendor_hal_func_table_t initfn;
+
+    initfn = (init_wifi_vendor_hal_func_table_t)dlsym(RTLD_DEFAULT,
+                                                      "init_wifi_vendor_hal_func_table");
+    if (!initfn) {
+        LOG(INFO) << "no vendor HAL library linked, will try dynamic load";
+        return false;
+    }
+
+    if (!initHalFuncTableWithStubs(hal_fn)) {
+        LOG(ERROR) << "Can not initialize the basic function pointer table";
+        return false;
+    }
+
+    if (initfn(hal_fn) != WIFI_SUCCESS) {
+        LOG(ERROR) << "Can not initialize the vendor function pointer table";
+        return false;
+    }
+
+    return true;
+}
+
+/*
+ * Overall structure of the HAL descriptor XML schema
+ *
+ * <?xml version="1.0" encoding="UTF-8"?>
+ * <WifiVendorHal version="1">
+ * <path>/vendor/lib64/libwifi-hal-qcom.so</path>
+ * <primary>1</primary>
+ * </WifiVendorHal>
+ */
+void WifiLegacyHalFactory::initVendorHalsDescriptorList() {
+    xmlDocPtr xml;
+    xmlNodePtr node, cnode;
+    char* version = NULL;
+    std::string path;
+    xmlChar* value;
+    wifi_hal_lib_desc desc;
+
+    LOG(INFO) << "processing vendor HALs descriptions in " << kVendorHalsDescPath;
+    DIR* dirPtr = ::opendir(kVendorHalsDescPath);
+    if (dirPtr == NULL) {
+        LOG(ERROR) << "failed to open " << kVendorHalsDescPath;
+        return;
+    }
+    for (struct dirent* entryPtr = ::readdir(dirPtr); entryPtr != NULL;
+         entryPtr = ::readdir(dirPtr)) {
+        if (isDirectory(entryPtr)) continue;
+
+        if (!isFileExtension(entryPtr->d_name, kVendorHalsDescExt))
+            continue;  // only process .xml files
+
+        LOG(INFO) << "processing config file: " << entryPtr->d_name;
+
+        std::string fullPath(kVendorHalsDescPath);
+        fullPath.append("/");
+        fullPath.append(entryPtr->d_name);
+        xml = xmlReadFile(fullPath.c_str(), "UTF-8", XML_PARSE_RECOVER);
+        if (!xml) {
+            LOG(ERROR) << "failed to parse: " << entryPtr->d_name << " skipping...";
+            continue;
+        }
+        node = xmlDocGetRootElement(xml);
+        if (!node) {
+            LOG(ERROR) << "empty config file: " << entryPtr->d_name << " skipping...";
+            goto skip;
+        }
+        if (xmlStrcmp(node->name, BAD_CAST "WifiVendorHal")) {
+            LOG(ERROR) << "bad config, root element not WifiVendorHal: " << entryPtr->d_name
+                       << " skipping...";
+            goto skip;
+        }
+        version = (char*)xmlGetProp(node, BAD_CAST "version");
+        if (!version || strtoul(version, NULL, 0) != kVendorHalsDescVersion) {
+            LOG(ERROR) << "conf file: " << entryPtr->d_name
+                       << "must have version: " << kVendorHalsDescVersion << ", skipping...";
+            goto skip;
+        }
+        cnode = node->children;
+        path.clear();
+        desc.primary = false;
+        while (cnode) {
+            if (!xmlStrcmp(cnode->name, BAD_CAST "path")) {
+                value = xmlNodeListGetString(xml, cnode->children, 1);
+                if (value) path = (char*)value;
+                xmlFree(value);
+            } else if (!xmlStrcmp(cnode->name, BAD_CAST "primary")) {
+                value = xmlNodeListGetString(xml, cnode->children, 1);
+                desc.primary = !xmlStrcmp(value, BAD_CAST "1");
+                xmlFree(value);
+            }
+            cnode = cnode->next;
+        }
+        if (path.empty()) {
+            LOG(ERROR) << "hal library path not provided in: " << entryPtr->d_name
+                       << ", skipping...";
+            goto skip;
+        }
+        if (loadVendorHalLib(path, desc)) {
+            if (desc.primary)
+                descs_.insert(descs_.begin(), desc);
+            else
+                descs_.push_back(desc);
+        }
+    skip:
+        xmlFreeDoc(xml);
+        if (version) {
+            xmlFree(version);
+            version = NULL;
+        }
+    }
+    ::closedir(dirPtr);
+}
+
+bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc) {
+    void* h = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
+    init_wifi_vendor_hal_func_table_t initfn;
+    wifi_error res;
+
+    if (!h) {
+        LOG(ERROR) << "failed to open vendor hal library: " << path;
+        return false;
+    }
+    initfn = (init_wifi_vendor_hal_func_table_t)dlsym(h, "init_wifi_vendor_hal_func_table");
+    if (!initfn) {
+        LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path;
+        goto out_err;
+    }
+
+    if (!initHalFuncTableWithStubs(&desc.fn)) {
+        LOG(ERROR) << "Can not initialize the basic function pointer table";
+        goto out_err;
+    }
+    res = initfn(&desc.fn);
+    if (res != WIFI_SUCCESS) {
+        LOG(ERROR) << "failed to initialize the vendor func table in: " << path
+                   << " error: " << res;
+        goto out_err;
+    }
+
+    res = desc.fn.wifi_early_initialize();
+    // vendor HALs which do not implement early_initialize will return
+    // WIFI_ERROR_NOT_SUPPORTED, treat this as success.
+    if (res != WIFI_SUCCESS && res != WIFI_ERROR_NOT_SUPPORTED) {
+        LOG(ERROR) << "early initialization failed in: " << path << " error: " << res;
+        goto out_err;
+    }
+
+    desc.handle = h;
+    return true;
+out_err:
+    dlclose(h);
+    return false;
+}
+
+}  // namespace legacy_hal
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_legacy_hal_factory.h b/wifi/aidl/default/wifi_legacy_hal_factory.h
new file mode 100644
index 0000000..e7b287a
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal_factory.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_LEGACY_HAL_FACTORY_H_
+#define WIFI_LEGACY_HAL_FACTORY_H_
+
+#include <wifi_system/interface_tool.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+// This is in a separate namespace to prevent typename conflicts between
+// the legacy HAL types and the AIDL interface types.
+namespace legacy_hal {
+/**
+ * Class that creates WifiLegacyHal objects for vendor HALs in the system.
+ */
+class WifiLegacyHalFactory {
+  public:
+    WifiLegacyHalFactory(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool);
+    virtual ~WifiLegacyHalFactory() = default;
+
+    std::vector<std::shared_ptr<WifiLegacyHal>> getHals();
+
+  private:
+    typedef struct {
+        wifi_hal_fn fn;
+        bool primary;
+        void* handle;
+    } wifi_hal_lib_desc;
+
+    bool initVendorHalDescriptorFromLinked();
+    void initVendorHalsDescriptorList();
+    bool initLinkedHalFunctionTable(wifi_hal_fn* hal_fn);
+    bool loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc);
+
+    std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
+    std::vector<wifi_hal_lib_desc> descs_;
+    std::vector<std::shared_ptr<WifiLegacyHal>> legacy_hals_;
+};
+
+}  // namespace legacy_hal
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_LEGACY_HAL_FACTORY_H_
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
new file mode 100644
index 0000000..b5196c9
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_legacy_hal_stubs.h"
+
+// TODO: Remove these stubs from HalTool in libwifi-system.
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+template <typename>
+struct stubFunction;
+
+template <typename R, typename... Args>
+struct stubFunction<R (*)(Args...)> {
+    static constexpr R invoke(Args...) { return WIFI_ERROR_NOT_SUPPORTED; }
+};
+template <typename... Args>
+struct stubFunction<void (*)(Args...)> {
+    static constexpr void invoke(Args...) {}
+};
+
+template <typename T>
+void populateStubFor(T* val) {
+    *val = &stubFunction<T>::invoke;
+}
+
+bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) {
+    if (hal_fn == nullptr) {
+        return false;
+    }
+    populateStubFor(&hal_fn->wifi_initialize);
+    populateStubFor(&hal_fn->wifi_wait_for_driver_ready);
+    populateStubFor(&hal_fn->wifi_cleanup);
+    populateStubFor(&hal_fn->wifi_event_loop);
+    populateStubFor(&hal_fn->wifi_get_error_info);
+    populateStubFor(&hal_fn->wifi_get_supported_feature_set);
+    populateStubFor(&hal_fn->wifi_get_concurrency_matrix);
+    populateStubFor(&hal_fn->wifi_set_scanning_mac_oui);
+    populateStubFor(&hal_fn->wifi_get_supported_channels);
+    populateStubFor(&hal_fn->wifi_is_epr_supported);
+    populateStubFor(&hal_fn->wifi_get_ifaces);
+    populateStubFor(&hal_fn->wifi_get_iface_name);
+    populateStubFor(&hal_fn->wifi_set_iface_event_handler);
+    populateStubFor(&hal_fn->wifi_reset_iface_event_handler);
+    populateStubFor(&hal_fn->wifi_start_gscan);
+    populateStubFor(&hal_fn->wifi_stop_gscan);
+    populateStubFor(&hal_fn->wifi_get_cached_gscan_results);
+    populateStubFor(&hal_fn->wifi_set_bssid_hotlist);
+    populateStubFor(&hal_fn->wifi_reset_bssid_hotlist);
+    populateStubFor(&hal_fn->wifi_set_significant_change_handler);
+    populateStubFor(&hal_fn->wifi_reset_significant_change_handler);
+    populateStubFor(&hal_fn->wifi_get_gscan_capabilities);
+    populateStubFor(&hal_fn->wifi_set_link_stats);
+    populateStubFor(&hal_fn->wifi_get_link_stats);
+    populateStubFor(&hal_fn->wifi_clear_link_stats);
+    populateStubFor(&hal_fn->wifi_get_valid_channels);
+    populateStubFor(&hal_fn->wifi_rtt_range_request);
+    populateStubFor(&hal_fn->wifi_rtt_range_cancel);
+    populateStubFor(&hal_fn->wifi_get_rtt_capabilities);
+    populateStubFor(&hal_fn->wifi_rtt_get_responder_info);
+    populateStubFor(&hal_fn->wifi_enable_responder);
+    populateStubFor(&hal_fn->wifi_disable_responder);
+    populateStubFor(&hal_fn->wifi_set_nodfs_flag);
+    populateStubFor(&hal_fn->wifi_start_logging);
+    populateStubFor(&hal_fn->wifi_set_epno_list);
+    populateStubFor(&hal_fn->wifi_reset_epno_list);
+    populateStubFor(&hal_fn->wifi_set_country_code);
+    populateStubFor(&hal_fn->wifi_get_firmware_memory_dump);
+    populateStubFor(&hal_fn->wifi_set_log_handler);
+    populateStubFor(&hal_fn->wifi_reset_log_handler);
+    populateStubFor(&hal_fn->wifi_set_alert_handler);
+    populateStubFor(&hal_fn->wifi_reset_alert_handler);
+    populateStubFor(&hal_fn->wifi_get_firmware_version);
+    populateStubFor(&hal_fn->wifi_get_ring_buffers_status);
+    populateStubFor(&hal_fn->wifi_get_logger_supported_feature_set);
+    populateStubFor(&hal_fn->wifi_get_ring_data);
+    populateStubFor(&hal_fn->wifi_enable_tdls);
+    populateStubFor(&hal_fn->wifi_disable_tdls);
+    populateStubFor(&hal_fn->wifi_get_tdls_status);
+    populateStubFor(&hal_fn->wifi_get_tdls_capabilities);
+    populateStubFor(&hal_fn->wifi_get_driver_version);
+    populateStubFor(&hal_fn->wifi_set_passpoint_list);
+    populateStubFor(&hal_fn->wifi_reset_passpoint_list);
+    populateStubFor(&hal_fn->wifi_set_lci);
+    populateStubFor(&hal_fn->wifi_set_lcr);
+    populateStubFor(&hal_fn->wifi_start_sending_offloaded_packet);
+    populateStubFor(&hal_fn->wifi_stop_sending_offloaded_packet);
+    populateStubFor(&hal_fn->wifi_start_rssi_monitoring);
+    populateStubFor(&hal_fn->wifi_stop_rssi_monitoring);
+    populateStubFor(&hal_fn->wifi_get_wake_reason_stats);
+    populateStubFor(&hal_fn->wifi_configure_nd_offload);
+    populateStubFor(&hal_fn->wifi_get_driver_memory_dump);
+    populateStubFor(&hal_fn->wifi_start_pkt_fate_monitoring);
+    populateStubFor(&hal_fn->wifi_get_tx_pkt_fates);
+    populateStubFor(&hal_fn->wifi_get_rx_pkt_fates);
+    populateStubFor(&hal_fn->wifi_nan_enable_request);
+    populateStubFor(&hal_fn->wifi_nan_disable_request);
+    populateStubFor(&hal_fn->wifi_nan_publish_request);
+    populateStubFor(&hal_fn->wifi_nan_publish_cancel_request);
+    populateStubFor(&hal_fn->wifi_nan_subscribe_request);
+    populateStubFor(&hal_fn->wifi_nan_subscribe_cancel_request);
+    populateStubFor(&hal_fn->wifi_nan_transmit_followup_request);
+    populateStubFor(&hal_fn->wifi_nan_stats_request);
+    populateStubFor(&hal_fn->wifi_nan_config_request);
+    populateStubFor(&hal_fn->wifi_nan_tca_request);
+    populateStubFor(&hal_fn->wifi_nan_beacon_sdf_payload_request);
+    populateStubFor(&hal_fn->wifi_nan_register_handler);
+    populateStubFor(&hal_fn->wifi_nan_get_version);
+    populateStubFor(&hal_fn->wifi_nan_get_capabilities);
+    populateStubFor(&hal_fn->wifi_nan_data_interface_create);
+    populateStubFor(&hal_fn->wifi_nan_data_interface_delete);
+    populateStubFor(&hal_fn->wifi_nan_data_request_initiator);
+    populateStubFor(&hal_fn->wifi_nan_data_indication_response);
+    populateStubFor(&hal_fn->wifi_nan_pairing_request);
+    populateStubFor(&hal_fn->wifi_nan_pairing_indication_response);
+    populateStubFor(&hal_fn->wifi_nan_bootstrapping_request);
+    populateStubFor(&hal_fn->wifi_nan_bootstrapping_indication_response);
+    populateStubFor(&hal_fn->wifi_nan_data_end);
+    populateStubFor(&hal_fn->wifi_nan_pairing_end);
+    populateStubFor(&hal_fn->wifi_get_packet_filter_capabilities);
+    populateStubFor(&hal_fn->wifi_set_packet_filter);
+    populateStubFor(&hal_fn->wifi_read_packet_filter);
+    populateStubFor(&hal_fn->wifi_get_roaming_capabilities);
+    populateStubFor(&hal_fn->wifi_enable_firmware_roaming);
+    populateStubFor(&hal_fn->wifi_configure_roaming);
+    populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
+    populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
+    populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler);
+    populateStubFor(&hal_fn->wifi_set_latency_mode);
+    populateStubFor(&hal_fn->wifi_set_thermal_mitigation_mode);
+    populateStubFor(&hal_fn->wifi_virtual_interface_create);
+    populateStubFor(&hal_fn->wifi_virtual_interface_delete);
+    populateStubFor(&hal_fn->wifi_map_dscp_access_category);
+    populateStubFor(&hal_fn->wifi_reset_dscp_mapping);
+    populateStubFor(&hal_fn->wifi_set_subsystem_restart_handler);
+    populateStubFor(&hal_fn->wifi_get_supported_iface_name);
+    populateStubFor(&hal_fn->wifi_early_initialize);
+    populateStubFor(&hal_fn->wifi_get_chip_feature_set);
+    populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection);
+    populateStubFor(&hal_fn->wifi_multi_sta_set_use_case);
+    populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels);
+    populateStubFor(&hal_fn->wifi_set_voip_mode);
+    populateStubFor(&hal_fn->wifi_twt_register_handler);
+    populateStubFor(&hal_fn->wifi_twt_get_capability);
+    populateStubFor(&hal_fn->wifi_twt_setup_request);
+    populateStubFor(&hal_fn->wifi_twt_teardown_request);
+    populateStubFor(&hal_fn->wifi_twt_info_frame_request);
+    populateStubFor(&hal_fn->wifi_twt_get_stats);
+    populateStubFor(&hal_fn->wifi_twt_clear_stats);
+    populateStubFor(&hal_fn->wifi_set_dtim_config);
+    populateStubFor(&hal_fn->wifi_get_usable_channels);
+    populateStubFor(&hal_fn->wifi_trigger_subsystem_restart);
+    populateStubFor(&hal_fn->wifi_set_indoor_state);
+    populateStubFor(&hal_fn->wifi_get_supported_radio_combinations_matrix);
+    populateStubFor(&hal_fn->wifi_nan_rtt_chre_enable_request);
+    populateStubFor(&hal_fn->wifi_nan_rtt_chre_disable_request);
+    populateStubFor(&hal_fn->wifi_chre_register_handler);
+    populateStubFor(&hal_fn->wifi_enable_tx_power_limits);
+    populateStubFor(&hal_fn->wifi_get_cached_scan_results);
+    populateStubFor(&hal_fn->wifi_get_chip_capabilities);
+    populateStubFor(&hal_fn->wifi_enable_sta_channel_for_peer_network);
+    populateStubFor(&hal_fn->wifi_nan_suspend_request);
+    populateStubFor(&hal_fn->wifi_nan_resume_request);
+    populateStubFor(&hal_fn->wifi_set_scan_mode);
+    populateStubFor(&hal_fn->wifi_set_mlo_mode);
+    populateStubFor(&hal_fn->wifi_get_supported_iface_concurrency_matrix);
+    return true;
+}
+
+}  // namespace legacy_hal
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.h b/wifi/aidl/default/wifi_legacy_hal_stubs.h
new file mode 100644
index 0000000..603ecf2
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_LEGACY_HAL_STUBS_H_
+#define WIFI_LEGACY_HAL_STUBS_H_
+
+#include <hardware_legacy/wifi_hal.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn);
+}  // namespace legacy_hal
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_LEGACY_HAL_STUBS_H_
diff --git a/wifi/aidl/default/wifi_mode_controller.cpp b/wifi/aidl/default/wifi_mode_controller.cpp
new file mode 100644
index 0000000..07cb072
--- /dev/null
+++ b/wifi/aidl/default/wifi_mode_controller.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_mode_controller.h"
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <private/android_filesystem_config.h>
+
+namespace {
+using aidl::android::hardware::wifi::IfaceType;
+using android::wifi_hal::DriverTool;
+
+int convertIfaceTypeToFirmwareMode(IfaceType type) {
+    int mode;
+    switch (type) {
+        case IfaceType::AP:
+            mode = DriverTool::kFirmwareModeAp;
+            break;
+        case IfaceType::P2P:
+            mode = DriverTool::kFirmwareModeP2p;
+            break;
+        case IfaceType::NAN_IFACE:
+            // NAN is exposed in STA mode currently.
+            mode = DriverTool::kFirmwareModeSta;
+            break;
+        case IfaceType::STA:
+            mode = DriverTool::kFirmwareModeSta;
+            break;
+    }
+    return mode;
+}
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace mode_controller {
+
+WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {}
+
+bool WifiModeController::isFirmwareModeChangeNeeded(IfaceType type) {
+    return driver_tool_->IsFirmwareModeChangeNeeded(convertIfaceTypeToFirmwareMode(type));
+}
+
+bool WifiModeController::initialize() {
+    if (!driver_tool_->LoadDriver()) {
+        LOG(ERROR) << "Failed to load WiFi driver";
+        return false;
+    }
+    return true;
+}
+
+bool WifiModeController::changeFirmwareMode(IfaceType type) {
+    if (!driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))) {
+        LOG(ERROR) << "Failed to change firmware mode";
+        return false;
+    }
+    return true;
+}
+
+bool WifiModeController::deinitialize() {
+    if (!driver_tool_->UnloadDriver()) {
+        LOG(ERROR) << "Failed to unload WiFi driver";
+        return false;
+    }
+    return true;
+}
+
+}  // namespace mode_controller
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_mode_controller.h b/wifi/aidl/default/wifi_mode_controller.h
new file mode 100644
index 0000000..1a9fb1a
--- /dev/null
+++ b/wifi/aidl/default/wifi_mode_controller.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_MODE_CONTROLLER_H_
+#define WIFI_MODE_CONTROLLER_H_
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <wifi_hal/driver_tool.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace mode_controller {
+
+/**
+ * Class that encapsulates all firmware mode configuration.
+ * This class will perform the necessary firmware reloads to put the chip in the
+ * required state (essentially a wrapper over DriverTool).
+ */
+class WifiModeController {
+  public:
+    WifiModeController();
+    virtual ~WifiModeController() = default;
+
+    // Checks if a firmware mode change is necessary to support the specified
+    // iface type operations.
+    virtual bool isFirmwareModeChangeNeeded(IfaceType type);
+    virtual bool initialize();
+    // Change the firmware mode to support the specified iface type operations.
+    virtual bool changeFirmwareMode(IfaceType type);
+    // Unload the driver. This should be invoked whenever |IWifi.stop()| is
+    // invoked.
+    virtual bool deinitialize();
+
+  private:
+    std::unique_ptr<::android::wifi_hal::DriverTool> driver_tool_;
+};
+
+}  // namespace mode_controller
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_MODE_CONTROLLER_H_
diff --git a/wifi/aidl/default/wifi_nan_iface.cpp b/wifi/aidl/default/wifi_nan_iface.cpp
new file mode 100644
index 0000000..cefe7f7
--- /dev/null
+++ b/wifi/aidl/default/wifi_nan_iface.cpp
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_nan_iface.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiNanIface::WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
+                           const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                           const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+    : ifname_(ifname),
+      is_dedicated_iface_(is_dedicated_iface),
+      legacy_hal_(legacy_hal),
+      iface_util_(iface_util),
+      is_valid_(true) {}
+
+std::shared_ptr<WifiNanIface> WifiNanIface::create(
+        const std::string& ifname, bool is_dedicated_iface,
+        const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+        const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) {
+    std::shared_ptr<WifiNanIface> ptr = ndk::SharedRefBase::make<WifiNanIface>(
+            ifname, is_dedicated_iface, legacy_hal, iface_util);
+    if (is_dedicated_iface) {
+        // If using a dedicated iface, set the iface up first.
+        if (!iface_util.lock()->setUpState(ifname, true)) {
+            // Fatal failure, invalidate the iface object.
+            ptr->invalidate();
+            return nullptr;
+        }
+    }
+    std::weak_ptr<WifiNanIface> weak_ptr_this(ptr);
+    ptr->setWeakPtr(weak_ptr_this);
+    ptr->registerCallbackHandlers();
+    return ptr;
+}
+
+void WifiNanIface::registerCallbackHandlers() {
+    // Register all the callbacks here. These should be valid for the lifetime
+    // of the object. Whenever the mode changes legacy HAL will remove
+    // all of these callbacks.
+    legacy_hal::NanCallbackHandlers callback_handlers;
+    std::weak_ptr<WifiNanIface> weak_ptr_this = weak_ptr_this_;
+
+    // Callback for response.
+    callback_handlers.on_notify_response = [weak_ptr_this](legacy_hal::transaction_id id,
+                                                           const legacy_hal::NanResponseMsg& msg) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        NanStatus nanStatus;
+        if (!aidl_struct_util::convertLegacyNanResponseHeaderToAidl(msg, &nanStatus)) {
+            LOG(ERROR) << "Failed to convert nan response header";
+            return;
+        }
+
+        switch (msg.response_type) {
+            case legacy_hal::NAN_RESPONSE_ENABLED: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyEnableResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_DISABLED: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyDisableResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_PUBLISH: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyStartPublishResponse(id, nanStatus,
+                                                              msg.body.publish_response.publish_id)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyStopPublishResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyTransmitFollowupResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_SUBSCRIBE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyStartSubscribeResponse(
+                                         id, nanStatus, msg.body.subscribe_response.subscribe_id)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyStopSubscribeResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_CONFIG: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyConfigResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_GET_CAPABILITIES: {
+                NanCapabilities aidl_struct;
+                if (!aidl_struct_util::convertLegacyNanCapabilitiesResponseToAidl(
+                            msg.body.nan_capabilities, &aidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyCapabilitiesResponse(id, nanStatus, aidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_INTERFACE_CREATE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyCreateDataInterfaceResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_INTERFACE_DELETE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyDeleteDataInterfaceResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_INITIATOR_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyInitiateDataPathResponse(
+                                         id, nanStatus,
+                                         msg.body.data_request_response.ndp_instance_id)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_RESPONDER_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyRespondToDataPathIndicationResponse(id, nanStatus)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_END: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyTerminateDataPathResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_PAIRING_INITIATOR_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyInitiatePairingResponse(
+                                         id, nanStatus,
+                                         msg.body.pairing_request_response.paring_instance_id)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_PAIRING_RESPONDER_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyRespondToPairingIndicationResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_PAIRING_END: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyTerminatePairingResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_BOOTSTRAPPING_INITIATOR_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyInitiateBootstrappingResponse(
+                                         id, nanStatus,
+                                         msg.body.bootstrapping_request_response
+                                                 .bootstrapping_instance_id)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_BOOTSTRAPPING_RESPONDER_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyRespondToBootstrappingIndicationResponse(id, nanStatus)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_SUSPEND_REQUEST_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifySuspendResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESUME_REQUEST_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyResumeResponse(id, nanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD:
+            /* fall through */
+            case legacy_hal::NAN_RESPONSE_TCA:
+            /* fall through */
+            case legacy_hal::NAN_RESPONSE_STATS:
+            /* fall through */
+            case legacy_hal::NAN_RESPONSE_ERROR:
+            /* fall through */
+            default:
+                LOG(ERROR) << "Unknown or unhandled response type: " << msg.response_type;
+                return;
+        }
+    };
+
+    callback_handlers.on_event_disc_eng_event = [weak_ptr_this](
+                                                        const legacy_hal::NanDiscEngEventInd& msg) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        NanClusterEventInd aidl_struct;
+        // event types defined identically - hence can be cast
+        aidl_struct.eventType = (NanClusterEventType)msg.event_type;
+        aidl_struct.addr = std::array<uint8_t, 6>();
+        std::copy(msg.data.mac_addr.addr, msg.data.mac_addr.addr + 6, std::begin(aidl_struct.addr));
+
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventClusterEvent(aidl_struct).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+
+    callback_handlers.on_event_disabled = [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        NanStatus status;
+        aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
+                                             &status);
+
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventDisabled(status).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+
+    callback_handlers.on_event_publish_terminated =
+            [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanStatus status;
+                aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason,
+                                                     sizeof(msg.nan_reason), &status);
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventPublishTerminated(msg.publish_id, status).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_subscribe_terminated =
+            [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanStatus status;
+                aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason,
+                                                     sizeof(msg.nan_reason), &status);
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventSubscribeTerminated(msg.subscribe_id, status).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_match = [weak_ptr_this](const legacy_hal::NanMatchInd& msg) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        NanMatchInd aidl_struct;
+        if (!aidl_struct_util::convertLegacyNanMatchIndToAidl(msg, &aidl_struct)) {
+            LOG(ERROR) << "Failed to convert nan capabilities response";
+            return;
+        }
+
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventMatch(aidl_struct).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+
+    callback_handlers.on_event_match_expired = [weak_ptr_this](
+                                                       const legacy_hal::NanMatchExpiredInd& msg) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventMatchExpired(msg.publish_subscribe_id, msg.requestor_instance_id)
+                         .isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+
+    callback_handlers.on_event_followup = [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        NanFollowupReceivedInd aidl_struct;
+        if (!aidl_struct_util::convertLegacyNanFollowupIndToAidl(msg, &aidl_struct)) {
+            LOG(ERROR) << "Failed to convert nan capabilities response";
+            return;
+        }
+
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventFollowupReceived(aidl_struct).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+
+    callback_handlers.on_event_transmit_follow_up =
+            [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanStatus status;
+                aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason,
+                                                     sizeof(msg.nan_reason), &status);
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventTransmitFollowup(msg.id, status).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_data_path_request =
+            [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanDataPathRequestInd aidl_struct;
+                if (!aidl_struct_util::convertLegacyNanDataPathRequestIndToAidl(msg,
+                                                                                &aidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventDataPathRequest(aidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_data_path_confirm =
+            [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanDataPathConfirmInd aidl_struct;
+                if (!aidl_struct_util::convertLegacyNanDataPathConfirmIndToAidl(msg,
+                                                                                &aidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventDataPathConfirm(aidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_data_path_end =
+            [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    for (int i = 0; i < msg.num_ndp_instances; ++i) {
+                        if (!callback->eventDataPathTerminated(msg.ndp_instance_id[i]).isOk()) {
+                            LOG(ERROR) << "Failed to invoke the callback";
+                        }
+                    }
+                }
+            };
+
+    callback_handlers.on_event_pairing_request =
+            [weak_ptr_this](const legacy_hal::NanPairingRequestInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanPairingRequestInd aidl_struct;
+                if (!aidl_struct_util::convertLegacyNanPairingRequestIndToAidl(msg, &aidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventPairingRequest(aidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+    callback_handlers.on_event_pairing_confirm =
+            [weak_ptr_this](const legacy_hal::NanPairingConfirmInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanPairingConfirmInd aidl_struct;
+                if (!aidl_struct_util::convertLegacyNanPairingConfirmIndToAidl(msg, &aidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventPairingConfirm(aidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+    callback_handlers.on_event_bootstrapping_request =
+            [weak_ptr_this](const legacy_hal::NanBootstrappingRequestInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanBootstrappingRequestInd aidl_struct;
+                if (!aidl_struct_util::convertLegacyNanBootstrappingRequestIndToAidl(
+                            msg, &aidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventBootstrappingRequest(aidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+    callback_handlers.on_event_bootstrapping_confirm =
+            [weak_ptr_this](const legacy_hal::NanBootstrappingConfirmInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanBootstrappingConfirmInd aidl_struct;
+                if (!aidl_struct_util::convertLegacyNanBootstrappingConfirmIndToAidl(
+                            msg, &aidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventBootstrappingConfirm(aidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_beacon_sdf_payload =
+            [](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) {
+                LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called";
+            };
+
+    callback_handlers.on_event_range_request = [](const legacy_hal::NanRangeRequestInd& /* msg */) {
+        LOG(ERROR) << "on_event_range_request - should not be called";
+    };
+
+    callback_handlers.on_event_range_report = [](const legacy_hal::NanRangeReportInd& /* msg */) {
+        LOG(ERROR) << "on_event_range_report - should not be called";
+    };
+
+    callback_handlers.on_event_schedule_update =
+            [weak_ptr_this](const legacy_hal::NanDataPathScheduleUpdateInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanDataPathScheduleUpdateInd aidl_struct;
+                if (!aidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToAidl(
+                            msg, &aidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventDataPathScheduleUpdate(aidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+    callback_handlers.on_event_suspension_mode_change =
+            [weak_ptr_this](const legacy_hal::NanSuspensionModeChangeInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanSuspensionModeChangeInd aidl_struct;
+                aidl_struct.isSuspended = msg.is_suspended;
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventSuspensionModeChanged(aidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, callback_handlers);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
+        invalidate();
+    }
+
+    // Register for iface state toggle events.
+    iface_util::IfaceEventHandlers event_handlers = {};
+#ifndef WIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN
+    event_handlers.on_state_toggle_off_on = [weak_ptr_this](const std::string& /* iface_name */) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        // Tell framework that NAN has been disabled.
+        NanStatus status = {NanStatusCode::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventDisabled(status).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+#endif
+    iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
+}
+
+void WifiNanIface::setWeakPtr(std::weak_ptr<WifiNanIface> ptr) {
+    weak_ptr_this_ = ptr;
+}
+
+void WifiNanIface::invalidate() {
+    if (!isValid()) {
+        return;
+    }
+    // send commands to HAL to actually disable and destroy interfaces
+    legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
+    legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
+    legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
+    iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
+    legacy_hal_.reset();
+    event_cb_handler_.invalidate();
+    is_valid_ = false;
+    if (is_dedicated_iface_) {
+        // If using a dedicated iface, set the iface down.
+        iface_util_.lock()->setUpState(ifname_, false);
+    }
+}
+
+bool WifiNanIface::isValid() {
+    return is_valid_;
+}
+
+std::string WifiNanIface::getName() {
+    return ifname_;
+}
+
+std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks() {
+    LOG(ERROR) << "Using original getEventCallbacks";
+    return event_cb_handler_.getCallbacks();
+}
+
+ndk::ScopedAStatus WifiNanIface::getName(std::string* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::getNameInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiNanIface::registerEventCallback(
+        const std::shared_ptr<IWifiNanIfaceEventCallback>& callback) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::registerEventCallbackInternal, callback);
+}
+
+ndk::ScopedAStatus WifiNanIface::getCapabilitiesRequest(char16_t in_cmdId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::getCapabilitiesRequestInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiNanIface::enableRequest(char16_t in_cmdId, const NanEnableRequest& in_msg1,
+                                               const NanConfigRequestSupplemental& in_msg2) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::enableRequestInternal, in_cmdId, in_msg1, in_msg2);
+}
+
+ndk::ScopedAStatus WifiNanIface::configRequest(char16_t in_cmdId, const NanConfigRequest& in_msg1,
+                                               const NanConfigRequestSupplemental& in_msg2) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::configRequestInternal, in_cmdId, in_msg1, in_msg2);
+}
+
+ndk::ScopedAStatus WifiNanIface::disableRequest(char16_t in_cmdId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::disableRequestInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiNanIface::startPublishRequest(char16_t in_cmdId,
+                                                     const NanPublishRequest& in_msg) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::startPublishRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::stopPublishRequest(char16_t in_cmdId, int8_t in_sessionId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::stopPublishRequestInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiNanIface::startSubscribeRequest(char16_t in_cmdId,
+                                                       const NanSubscribeRequest& in_msg) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::startSubscribeRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::stopSubscribeRequest(char16_t in_cmdId, int8_t in_sessionId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::stopSubscribeRequestInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiNanIface::transmitFollowupRequest(char16_t in_cmdId,
+                                                         const NanTransmitFollowupRequest& in_msg) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::transmitFollowupRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::createDataInterfaceRequest(char16_t in_cmdId,
+                                                            const std::string& in_ifaceName) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::createDataInterfaceRequestInternal, in_cmdId,
+                           in_ifaceName);
+}
+
+ndk::ScopedAStatus WifiNanIface::deleteDataInterfaceRequest(char16_t in_cmdId,
+                                                            const std::string& in_ifaceName) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::deleteDataInterfaceRequestInternal, in_cmdId,
+                           in_ifaceName);
+}
+
+ndk::ScopedAStatus WifiNanIface::initiateDataPathRequest(char16_t in_cmdId,
+                                                         const NanInitiateDataPathRequest& in_msg) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::initiateDataPathRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::respondToDataPathIndicationRequest(
+        char16_t in_cmdId, const NanRespondToDataPathIndicationRequest& in_msg) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::respondToDataPathIndicationRequestInternal, in_cmdId,
+                           in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::terminateDataPathRequest(char16_t in_cmdId,
+                                                          int32_t in_ndpInstanceId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::terminateDataPathRequestInternal, in_cmdId,
+                           in_ndpInstanceId);
+}
+
+ndk::ScopedAStatus WifiNanIface::initiatePairingRequest(char16_t in_cmdId,
+                                                        const NanPairingRequest& in_msg) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::initiatePairingRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::respondToPairingIndicationRequest(
+        char16_t in_cmdId, const NanRespondToPairingIndicationRequest& in_msg) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::respondToPairingIndicationRequestInternal, in_cmdId,
+                           in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::terminatePairingRequest(char16_t in_cmdId,
+                                                         int32_t in_ndpInstanceId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::terminatePairingRequestInternal, in_cmdId,
+                           in_ndpInstanceId);
+}
+
+ndk::ScopedAStatus WifiNanIface::initiateBootstrappingRequest(
+        char16_t in_cmdId, const NanBootstrappingRequest& in_msg) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::initiateBootstrappingRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::respondToBootstrappingIndicationRequest(
+        char16_t in_cmdId, const NanBootstrappingResponse& in_msg) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::respondToBootstrappingIndicationRequestInternal, in_cmdId,
+                           in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::suspendRequest(char16_t in_cmdId, int8_t in_sessionId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::suspendRequestInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiNanIface::resumeRequest(char16_t in_cmdId, int8_t in_sessionId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::resumeRequestInternal, in_cmdId, in_sessionId);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> WifiNanIface::getNameInternal() {
+    return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiNanIface::registerEventCallbackInternal(
+        const std::shared_ptr<IWifiNanIfaceEventCallback>& callback) {
+    if (!event_cb_handler_.addCallback(callback)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiNanIface::getCapabilitiesRequestInternal(char16_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::enableRequestInternal(char16_t cmd_id,
+                                                       const NanEnableRequest& msg1,
+                                                       const NanConfigRequestSupplemental& msg2) {
+    legacy_hal::NanEnableRequest legacy_msg;
+    if (!aidl_struct_util::convertAidlNanEnableRequestToLegacy(msg1, msg2, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::configRequestInternal(char16_t cmd_id,
+                                                       const NanConfigRequest& msg1,
+                                                       const NanConfigRequestSupplemental& msg2) {
+    legacy_hal::NanConfigRequest legacy_msg;
+    if (!aidl_struct_util::convertAidlNanConfigRequestToLegacy(msg1, msg2, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::disableRequestInternal(char16_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::startPublishRequestInternal(char16_t cmd_id,
+                                                             const NanPublishRequest& msg) {
+    legacy_hal::NanPublishRequest legacy_msg;
+    if (!aidl_struct_util::convertAidlNanPublishRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::stopPublishRequestInternal(char16_t cmd_id, int8_t sessionId) {
+    legacy_hal::NanPublishCancelRequest legacy_msg;
+    legacy_msg.publish_id = sessionId;
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::startSubscribeRequestInternal(char16_t cmd_id,
+                                                               const NanSubscribeRequest& msg) {
+    legacy_hal::NanSubscribeRequest legacy_msg;
+    if (!aidl_struct_util::convertAidlNanSubscribeRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::stopSubscribeRequestInternal(char16_t cmd_id, int8_t sessionId) {
+    legacy_hal::NanSubscribeCancelRequest legacy_msg;
+    legacy_msg.subscribe_id = sessionId;
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::transmitFollowupRequestInternal(
+        char16_t cmd_id, const NanTransmitFollowupRequest& msg) {
+    legacy_hal::NanTransmitFollowupRequest legacy_msg;
+    if (!aidl_struct_util::convertAidlNanTransmitFollowupRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::createDataInterfaceRequestInternal(char16_t cmd_id,
+                                                                    const std::string& iface_name) {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::deleteDataInterfaceRequestInternal(char16_t cmd_id,
+                                                                    const std::string& iface_name) {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::initiateDataPathRequestInternal(
+        char16_t cmd_id, const NanInitiateDataPathRequest& msg) {
+    legacy_hal::NanDataPathInitiatorRequest legacy_msg;
+    if (!aidl_struct_util::convertAidlNanDataPathInitiatorRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::respondToDataPathIndicationRequestInternal(
+        char16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg) {
+    legacy_hal::NanDataPathIndicationResponse legacy_msg;
+    if (!aidl_struct_util::convertAidlNanDataPathIndicationResponseToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::terminateDataPathRequestInternal(char16_t cmd_id,
+                                                                  int32_t ndpInstanceId) {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::initiatePairingRequestInternal(char16_t cmd_id,
+                                                                const NanPairingRequest& msg) {
+    legacy_hal::NanPairingRequest legacy_msg;
+    if (!aidl_struct_util::convertAidlNanPairingInitiatorRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanPairingRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::respondToPairingIndicationRequestInternal(
+        char16_t cmd_id, const NanRespondToPairingIndicationRequest& msg) {
+    legacy_hal::NanPairingIndicationResponse legacy_msg;
+    if (!aidl_struct_util::convertAidlNanPairingIndicationResponseToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanPairingIndicationResponse(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::terminatePairingRequestInternal(char16_t cmd_id,
+                                                                 int32_t ndpInstanceId) {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanPairingEnd(ifname_, cmd_id, ndpInstanceId);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::initiateBootstrappingRequestInternal(
+        char16_t cmd_id, const NanBootstrappingRequest& msg) {
+    legacy_hal::NanBootstrappingRequest legacy_msg;
+    if (!aidl_struct_util::convertAidlNanBootstrappingInitiatorRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanBootstrappingRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::respondToBootstrappingIndicationRequestInternal(
+        char16_t cmd_id, const NanBootstrappingResponse& msg) {
+    legacy_hal::NanBootstrappingIndicationResponse legacy_msg;
+    if (!aidl_struct_util::convertAidlNanBootstrappingIndicationResponseToLegacy(msg,
+                                                                                 &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanBootstrappingIndicationResponse(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::suspendRequestInternal(char16_t cmd_id, int8_t sessionId) {
+    legacy_hal::NanSuspendRequest legacy_msg;
+    legacy_msg.publish_subscribe_id = sessionId;
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanSuspendRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::resumeRequestInternal(char16_t cmd_id, int8_t sessionId) {
+    legacy_hal::NanResumeRequest legacy_msg;
+    legacy_msg.publish_subscribe_id = sessionId;
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanResumeRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_nan_iface.h b/wifi/aidl/default/wifi_nan_iface.h
new file mode 100644
index 0000000..a49ae8c
--- /dev/null
+++ b/wifi/aidl/default/wifi_nan_iface.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_NAN_IFACE_H_
+#define WIFI_NAN_IFACE_H_
+
+#include <aidl/android/hardware/wifi/BnWifiNanIface.h>
+#include <aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.h>
+#include <android-base/macros.h>
+
+#include "aidl_callback_util.h"
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control a NAN Iface instance.
+ */
+class WifiNanIface : public BnWifiNanIface {
+  public:
+    WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
+                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+
+    // Factory method - use instead of default constructor.
+    static std::shared_ptr<WifiNanIface> create(
+            const std::string& ifname, bool is_dedicated_iface,
+            const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+            const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+
+    // Refer to |WifiChip::invalidate()|.
+    void invalidate();
+    bool isValid();
+    std::string getName();
+
+    // AIDL methods exposed.
+    ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+    ndk::ScopedAStatus registerEventCallback(
+            const std::shared_ptr<IWifiNanIfaceEventCallback>& in_callback) override;
+    ndk::ScopedAStatus getCapabilitiesRequest(char16_t in_cmdId) override;
+    ndk::ScopedAStatus enableRequest(char16_t in_cmdId, const NanEnableRequest& in_msg1,
+                                     const NanConfigRequestSupplemental& in_msg2) override;
+    ndk::ScopedAStatus configRequest(char16_t in_cmdId, const NanConfigRequest& in_msg1,
+                                     const NanConfigRequestSupplemental& in_msg2) override;
+    ndk::ScopedAStatus disableRequest(char16_t in_cmdId) override;
+    ndk::ScopedAStatus startPublishRequest(char16_t in_cmdId,
+                                           const NanPublishRequest& in_msg) override;
+    ndk::ScopedAStatus stopPublishRequest(char16_t in_cmdId, int8_t in_sessionId) override;
+    ndk::ScopedAStatus startSubscribeRequest(char16_t in_cmdId,
+                                             const NanSubscribeRequest& in_msg) override;
+    ndk::ScopedAStatus stopSubscribeRequest(char16_t in_cmdId, int8_t in_sessionId) override;
+    ndk::ScopedAStatus transmitFollowupRequest(char16_t in_cmdId,
+                                               const NanTransmitFollowupRequest& in_msg) override;
+    ndk::ScopedAStatus createDataInterfaceRequest(char16_t in_cmdId,
+                                                  const std::string& in_ifaceName) override;
+    ndk::ScopedAStatus deleteDataInterfaceRequest(char16_t in_cmdId,
+                                                  const std::string& in_ifaceName) override;
+    ndk::ScopedAStatus initiateDataPathRequest(char16_t in_cmdId,
+                                               const NanInitiateDataPathRequest& in_msg) override;
+    ndk::ScopedAStatus respondToDataPathIndicationRequest(
+            char16_t in_cmdId, const NanRespondToDataPathIndicationRequest& in_msg) override;
+    ndk::ScopedAStatus terminateDataPathRequest(char16_t in_cmdId,
+                                                int32_t in_ndpInstanceId) override;
+    ndk::ScopedAStatus initiatePairingRequest(char16_t in_cmdId,
+                                              const NanPairingRequest& in_msg) override;
+    ndk::ScopedAStatus respondToPairingIndicationRequest(
+            char16_t in_cmdId, const NanRespondToPairingIndicationRequest& in_msg) override;
+    ndk::ScopedAStatus terminatePairingRequest(char16_t in_cmdId, int32_t in_pairingId) override;
+    ndk::ScopedAStatus initiateBootstrappingRequest(char16_t in_cmdId,
+                                                    const NanBootstrappingRequest& in_msg) override;
+    ndk::ScopedAStatus respondToBootstrappingIndicationRequest(
+            char16_t in_cmdId, const NanBootstrappingResponse& in_msg) override;
+    ndk::ScopedAStatus suspendRequest(char16_t in_cmdId, int8_t sessionId) override;
+    ndk::ScopedAStatus resumeRequest(char16_t in_cmdId, int8_t sessionId) override;
+
+  protected:
+    // Accessible to child class in the gTest suite.
+    void setWeakPtr(std::weak_ptr<WifiNanIface> ptr);
+    void registerCallbackHandlers();
+
+  private:
+    // Corresponding worker functions for the AIDL methods.
+    std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+    ndk::ScopedAStatus registerEventCallbackInternal(
+            const std::shared_ptr<IWifiNanIfaceEventCallback>& callback);
+    ndk::ScopedAStatus getCapabilitiesRequestInternal(char16_t cmd_id);
+    ndk::ScopedAStatus enableRequestInternal(char16_t cmd_id, const NanEnableRequest& msg1,
+                                             const NanConfigRequestSupplemental& msg2);
+    ndk::ScopedAStatus configRequestInternal(char16_t cmd_id, const NanConfigRequest& msg1,
+                                             const NanConfigRequestSupplemental& msg2);
+    ndk::ScopedAStatus disableRequestInternal(char16_t cmd_id);
+    ndk::ScopedAStatus startPublishRequestInternal(char16_t cmd_id, const NanPublishRequest& msg);
+    ndk::ScopedAStatus stopPublishRequestInternal(char16_t cmd_id, int8_t sessionId);
+    ndk::ScopedAStatus startSubscribeRequestInternal(char16_t cmd_id,
+                                                     const NanSubscribeRequest& msg);
+    ndk::ScopedAStatus stopSubscribeRequestInternal(char16_t cmd_id, int8_t sessionId);
+    ndk::ScopedAStatus transmitFollowupRequestInternal(char16_t cmd_id,
+                                                       const NanTransmitFollowupRequest& msg);
+    ndk::ScopedAStatus createDataInterfaceRequestInternal(char16_t cmd_id,
+                                                          const std::string& iface_name);
+    ndk::ScopedAStatus deleteDataInterfaceRequestInternal(char16_t cmd_id,
+                                                          const std::string& iface_name);
+    ndk::ScopedAStatus initiateDataPathRequestInternal(char16_t cmd_id,
+                                                       const NanInitiateDataPathRequest& msg);
+    ndk::ScopedAStatus respondToDataPathIndicationRequestInternal(
+            char16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg);
+    ndk::ScopedAStatus terminateDataPathRequestInternal(char16_t cmd_id, int32_t ndpInstanceId);
+    ndk::ScopedAStatus initiatePairingRequestInternal(char16_t cmd_id,
+                                                      const NanPairingRequest& msg);
+    ndk::ScopedAStatus respondToPairingIndicationRequestInternal(
+            char16_t cmd_id, const NanRespondToPairingIndicationRequest& msg);
+    ndk::ScopedAStatus terminatePairingRequestInternal(char16_t cmd_id, int32_t pairingId);
+    ndk::ScopedAStatus initiateBootstrappingRequestInternal(char16_t cmd_id,
+                                                            const NanBootstrappingRequest& msg);
+    ndk::ScopedAStatus respondToBootstrappingIndicationRequestInternal(
+            char16_t cmd_id, const NanBootstrappingResponse& msg);
+    ndk::ScopedAStatus suspendRequestInternal(char16_t in_cmdId, int8_t sessionId);
+    ndk::ScopedAStatus resumeRequestInternal(char16_t in_cmdId, int8_t sessionId);
+
+    // Overridden in the gTest suite.
+    virtual std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> getEventCallbacks();
+
+    std::string ifname_;
+    bool is_dedicated_iface_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+    bool is_valid_;
+    std::weak_ptr<WifiNanIface> weak_ptr_this_;
+    aidl_callback_util::AidlCallbackHandler<IWifiNanIfaceEventCallback> event_cb_handler_;
+
+    DISALLOW_COPY_AND_ASSIGN(WifiNanIface);
+};
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_NAN_IFACE_H_
diff --git a/wifi/aidl/default/wifi_p2p_iface.cpp b/wifi/aidl/default/wifi_p2p_iface.cpp
new file mode 100644
index 0000000..48ec6d6
--- /dev/null
+++ b/wifi/aidl/default/wifi_p2p_iface.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_p2p_iface.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiP2pIface::WifiP2pIface(const std::string& ifname,
+                           const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+    : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}
+
+void WifiP2pIface::invalidate() {
+    legacy_hal_.reset();
+    is_valid_ = false;
+}
+
+bool WifiP2pIface::isValid() {
+    return is_valid_;
+}
+
+std::string WifiP2pIface::getName() {
+    return ifname_;
+}
+
+ndk::ScopedAStatus WifiP2pIface::getName(std::string* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiP2pIface::getNameInternal, _aidl_return);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> WifiP2pIface::getNameInternal() {
+    return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_p2p_iface.h b/wifi/aidl/default/wifi_p2p_iface.h
new file mode 100644
index 0000000..d17470e
--- /dev/null
+++ b/wifi/aidl/default/wifi_p2p_iface.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_P2P_IFACE_H_
+#define WIFI_P2P_IFACE_H_
+
+#include <aidl/android/hardware/wifi/BnWifiP2pIface.h>
+#include <android-base/macros.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control a P2P Iface instance.
+ */
+class WifiP2pIface : public BnWifiP2pIface {
+  public:
+    WifiP2pIface(const std::string& ifname,
+                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+    // Refer to |WifiChip::invalidate()|.
+    void invalidate();
+    bool isValid();
+    std::string getName();
+
+    // AIDL methods exposed.
+    ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+
+  private:
+    // Corresponding worker functions for the AIDL methods.
+    std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+
+    std::string ifname_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    bool is_valid_;
+
+    DISALLOW_COPY_AND_ASSIGN(WifiP2pIface);
+};
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_P2P_IFACE_H_
diff --git a/wifi/aidl/default/wifi_rtt_controller.cpp b/wifi/aidl/default/wifi_rtt_controller.cpp
new file mode 100644
index 0000000..a5f6768
--- /dev/null
+++ b/wifi/aidl/default/wifi_rtt_controller.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_rtt_controller.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiRttController::WifiRttController(const std::string& iface_name,
+                                     const std::shared_ptr<IWifiStaIface>& bound_iface,
+                                     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+    : ifname_(iface_name), bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {}
+
+std::shared_ptr<WifiRttController> WifiRttController::create(
+        const std::string& iface_name, const std::shared_ptr<IWifiStaIface>& bound_iface,
+        const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) {
+    std::shared_ptr<WifiRttController> ptr =
+            ndk::SharedRefBase::make<WifiRttController>(iface_name, bound_iface, legacy_hal);
+    std::weak_ptr<WifiRttController> weak_ptr_this(ptr);
+    ptr->setWeakPtr(weak_ptr_this);
+    return ptr;
+}
+
+void WifiRttController::invalidate() {
+    legacy_hal_.reset();
+    event_callbacks_.clear();
+    is_valid_ = false;
+};
+
+bool WifiRttController::isValid() {
+    return is_valid_;
+}
+
+void WifiRttController::setWeakPtr(std::weak_ptr<WifiRttController> ptr) {
+    weak_ptr_this_ = ptr;
+}
+
+std::vector<std::shared_ptr<IWifiRttControllerEventCallback>>
+WifiRttController::getEventCallbacks() {
+    return event_callbacks_;
+}
+
+std::string WifiRttController::getIfaceName() {
+    return ifname_;
+}
+
+ndk::ScopedAStatus WifiRttController::getBoundIface(std::shared_ptr<IWifiStaIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::getBoundIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiRttController::registerEventCallback(
+        const std::shared_ptr<IWifiRttControllerEventCallback>& callback) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::registerEventCallbackInternal, callback);
+}
+
+ndk::ScopedAStatus WifiRttController::rangeRequest(int32_t in_cmdId,
+                                                   const std::vector<RttConfig>& in_rttConfigs) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::rangeRequestInternal, in_cmdId, in_rttConfigs);
+}
+
+ndk::ScopedAStatus WifiRttController::rangeCancel(int32_t in_cmdId,
+                                                  const std::vector<MacAddress>& in_addrs) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::rangeCancelInternal, in_cmdId, in_addrs);
+}
+
+ndk::ScopedAStatus WifiRttController::getCapabilities(RttCapabilities* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::getCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiRttController::setLci(int32_t in_cmdId, const RttLciInformation& in_lci) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::setLciInternal, in_cmdId, in_lci);
+}
+
+ndk::ScopedAStatus WifiRttController::setLcr(int32_t in_cmdId, const RttLcrInformation& in_lcr) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::setLcrInternal, in_cmdId, in_lcr);
+}
+
+ndk::ScopedAStatus WifiRttController::getResponderInfo(RttResponder* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::getResponderInfoInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiRttController::enableResponder(int32_t in_cmdId,
+                                                      const WifiChannelInfo& in_channelHint,
+                                                      int32_t in_maxDurationInSeconds,
+                                                      const RttResponder& in_info) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::enableResponderInternal, in_cmdId, in_channelHint,
+                           in_maxDurationInSeconds, in_info);
+}
+
+ndk::ScopedAStatus WifiRttController::disableResponder(int32_t in_cmdId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::disableResponderInternal, in_cmdId);
+}
+
+std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus>
+WifiRttController::getBoundIfaceInternal() {
+    return {bound_iface_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiRttController::registerEventCallbackInternal(
+        const std::shared_ptr<IWifiRttControllerEventCallback>& callback) {
+    event_callbacks_.emplace_back(callback);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiRttController::rangeRequestInternal(
+        int32_t cmd_id, const std::vector<RttConfig>& rtt_configs) {
+    std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
+    if (!aidl_struct_util::convertAidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    std::weak_ptr<WifiRttController> weak_ptr_this = weak_ptr_this_;
+    const auto& on_results_callback =
+            [weak_ptr_this](legacy_hal::wifi_request_id id,
+                            const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                std::vector<RttResult> aidl_results;
+                if (!aidl_struct_util::convertLegacyVectorOfRttResultToAidl(results,
+                                                                            &aidl_results)) {
+                    LOG(ERROR) << "Failed to convert rtt results to AIDL structs";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->onResults(id, aidl_results).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+    const auto& on_results_callback_v2 =
+            [weak_ptr_this](legacy_hal::wifi_request_id id,
+                            const std::vector<const legacy_hal::wifi_rtt_result_v2*>& results) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "v2 Callback invoked on an invalid object";
+                    return;
+                }
+                std::vector<RttResult> aidl_results;
+                if (!aidl_struct_util::convertLegacyVectorOfRttResultV2ToAidl(results,
+                                                                              &aidl_results)) {
+                    LOG(ERROR) << "Failed to convert rtt results v2 to AIDL structs";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->onResults(id, aidl_results).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the v2 callback";
+                    }
+                }
+            };
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest(
+            ifname_, cmd_id, legacy_configs, on_results_callback, on_results_callback_v2);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiRttController::rangeCancelInternal(int32_t cmd_id,
+                                                          const std::vector<MacAddress>& addrs) {
+    std::vector<std::array<uint8_t, ETH_ALEN>> legacy_addrs;
+    for (const auto& addr : addrs) {
+        std::array<uint8_t, ETH_ALEN> addr_array;
+        std::copy_n(addr.data.begin(), ETH_ALEN, addr_array.begin());
+        legacy_addrs.push_back(addr_array);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, legacy_addrs);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<RttCapabilities, ndk::ScopedAStatus> WifiRttController::getCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_rtt_capabilities legacy_caps;
+    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {RttCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    RttCapabilities aidl_caps;
+    if (!aidl_struct_util::convertLegacyRttCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+        return {RttCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_caps, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiRttController::setLciInternal(int32_t cmd_id, const RttLciInformation& lci) {
+    legacy_hal::wifi_lci_information legacy_lci;
+    if (!aidl_struct_util::convertAidlRttLciInformationToLegacy(lci, &legacy_lci)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiRttController::setLcrInternal(int32_t cmd_id, const RttLcrInformation& lcr) {
+    legacy_hal::wifi_lcr_information legacy_lcr;
+    if (!aidl_struct_util::convertAidlRttLcrInformationToLegacy(lcr, &legacy_lcr)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<RttResponder, ndk::ScopedAStatus> WifiRttController::getResponderInfoInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_rtt_responder legacy_responder;
+    std::tie(legacy_status, legacy_responder) = legacy_hal_.lock()->getRttResponderInfo(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {RttResponder{}, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    RttResponder aidl_responder;
+    if (!aidl_struct_util::convertLegacyRttResponderToAidl(legacy_responder, &aidl_responder)) {
+        return {RttResponder{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_responder, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiRttController::enableResponderInternal(int32_t cmd_id,
+                                                              const WifiChannelInfo& channel_hint,
+                                                              int32_t max_duration_seconds,
+                                                              const RttResponder& info) {
+    legacy_hal::wifi_channel_info legacy_channel_info;
+    if (!aidl_struct_util::convertAidlWifiChannelInfoToLegacy(channel_hint, &legacy_channel_info)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_rtt_responder legacy_responder;
+    if (!aidl_struct_util::convertAidlRttResponderToLegacy(info, &legacy_responder)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder(
+            ifname_, cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiRttController::disableResponderInternal(int32_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_rtt_controller.h b/wifi/aidl/default/wifi_rtt_controller.h
new file mode 100644
index 0000000..db690c3
--- /dev/null
+++ b/wifi/aidl/default/wifi_rtt_controller.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_RTT_CONTROLLER_H_
+#define WIFI_RTT_CONTROLLER_H_
+
+#include <aidl/android/hardware/wifi/BnWifiRttController.h>
+#include <aidl/android/hardware/wifi/IWifiRttControllerEventCallback.h>
+#include <aidl/android/hardware/wifi/IWifiStaIface.h>
+#include <android-base/macros.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control all RTT operations.
+ */
+class WifiRttController : public BnWifiRttController {
+  public:
+    WifiRttController(const std::string& iface_name,
+                      const std::shared_ptr<IWifiStaIface>& bound_iface,
+                      const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+    // Factory method - use instead of default constructor.
+    static std::shared_ptr<WifiRttController> create(
+            const std::string& iface_name, const std::shared_ptr<IWifiStaIface>& bound_iface,
+            const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+
+    // Refer to |WifiChip::invalidate()|.
+    void invalidate();
+    bool isValid();
+    std::vector<std::shared_ptr<IWifiRttControllerEventCallback>> getEventCallbacks();
+    std::string getIfaceName();
+
+    // AIDL methods exposed.
+    ndk::ScopedAStatus getBoundIface(std::shared_ptr<IWifiStaIface>* _aidl_return) override;
+    ndk::ScopedAStatus registerEventCallback(
+            const std::shared_ptr<IWifiRttControllerEventCallback>& callback) override;
+    ndk::ScopedAStatus rangeRequest(int32_t in_cmdId,
+                                    const std::vector<RttConfig>& in_rttConfigs) override;
+    ndk::ScopedAStatus rangeCancel(int32_t in_cmdId,
+                                   const std::vector<MacAddress>& in_addrs) override;
+    ndk::ScopedAStatus getCapabilities(RttCapabilities* _aidl_return) override;
+    ndk::ScopedAStatus setLci(int32_t in_cmdId, const RttLciInformation& in_lci) override;
+    ndk::ScopedAStatus setLcr(int32_t in_cmdId, const RttLcrInformation& in_lcr) override;
+    ndk::ScopedAStatus getResponderInfo(RttResponder* _aidl_return) override;
+    ndk::ScopedAStatus enableResponder(int32_t in_cmdId, const WifiChannelInfo& in_channelHint,
+                                       int32_t in_maxDurationInSeconds,
+                                       const RttResponder& in_info) override;
+    ndk::ScopedAStatus disableResponder(int32_t in_cmdId) override;
+
+  private:
+    // Corresponding worker functions for the AIDL methods.
+    std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> getBoundIfaceInternal();
+    ndk::ScopedAStatus registerEventCallbackInternal(
+            const std::shared_ptr<IWifiRttControllerEventCallback>& callback);
+    ndk::ScopedAStatus rangeRequestInternal(int32_t cmd_id,
+                                            const std::vector<RttConfig>& rtt_configs);
+    ndk::ScopedAStatus rangeCancelInternal(int32_t cmd_id, const std::vector<MacAddress>& addrs);
+    std::pair<RttCapabilities, ndk::ScopedAStatus> getCapabilitiesInternal();
+    ndk::ScopedAStatus setLciInternal(int32_t cmd_id, const RttLciInformation& lci);
+    ndk::ScopedAStatus setLcrInternal(int32_t cmd_id, const RttLcrInformation& lcr);
+    std::pair<RttResponder, ndk::ScopedAStatus> getResponderInfoInternal();
+    ndk::ScopedAStatus enableResponderInternal(int32_t cmd_id, const WifiChannelInfo& channel_hint,
+                                               int32_t max_duration_seconds,
+                                               const RttResponder& info);
+    ndk::ScopedAStatus disableResponderInternal(int32_t cmd_id);
+
+    void setWeakPtr(std::weak_ptr<WifiRttController> ptr);
+
+    std::string ifname_;
+    std::shared_ptr<IWifiStaIface> bound_iface_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::vector<std::shared_ptr<IWifiRttControllerEventCallback>> event_callbacks_;
+    std::weak_ptr<WifiRttController> weak_ptr_this_;
+    bool is_valid_;
+
+    DISALLOW_COPY_AND_ASSIGN(WifiRttController);
+};
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_RTT_CONTROLLER_H_
diff --git a/wifi/aidl/default/wifi_sta_iface.cpp b/wifi/aidl/default/wifi_sta_iface.cpp
new file mode 100644
index 0000000..800813f
--- /dev/null
+++ b/wifi/aidl/default/wifi_sta_iface.cpp
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_sta_iface.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiStaIface::WifiStaIface(const std::string& ifname,
+                           const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                           const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+    : ifname_(ifname), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) {
+    // Turn on DFS channel usage for STA iface.
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to set DFS flag; DFS channels may be unavailable.";
+    }
+}
+
+std::shared_ptr<WifiStaIface> WifiStaIface::create(
+        const std::string& ifname, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+        const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) {
+    std::shared_ptr<WifiStaIface> ptr =
+            ndk::SharedRefBase::make<WifiStaIface>(ifname, legacy_hal, iface_util);
+    std::weak_ptr<WifiStaIface> weak_ptr_this(ptr);
+    ptr->setWeakPtr(weak_ptr_this);
+    return ptr;
+}
+
+void WifiStaIface::invalidate() {
+    legacy_hal_.reset();
+    event_cb_handler_.invalidate();
+    is_valid_ = false;
+}
+
+void WifiStaIface::setWeakPtr(std::weak_ptr<WifiStaIface> ptr) {
+    weak_ptr_this_ = ptr;
+}
+
+bool WifiStaIface::isValid() {
+    return is_valid_;
+}
+
+std::string WifiStaIface::getName() {
+    return ifname_;
+}
+
+std::set<std::shared_ptr<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() {
+    return event_cb_handler_.getCallbacks();
+}
+
+ndk::ScopedAStatus WifiStaIface::getName(std::string* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getNameInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::registerEventCallback(
+        const std::shared_ptr<IWifiStaIfaceEventCallback>& in_callback) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::registerEventCallbackInternal, in_callback);
+}
+
+ndk::ScopedAStatus WifiStaIface::getFeatureSet(int32_t* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getFeatureSetInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::getApfPacketFilterCapabilities(
+        StaApfPacketFilterCapabilities* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getApfPacketFilterCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::installApfPacketFilter(const std::vector<uint8_t>& in_program) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::installApfPacketFilterInternal, in_program);
+}
+
+ndk::ScopedAStatus WifiStaIface::readApfPacketFilterData(std::vector<uint8_t>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::readApfPacketFilterDataInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::getBackgroundScanCapabilities(
+        StaBackgroundScanCapabilities* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getBackgroundScanCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::startBackgroundScan(int32_t in_cmdId,
+                                                     const StaBackgroundScanParameters& in_params) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::startBackgroundScanInternal, in_cmdId, in_params);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopBackgroundScan(int32_t in_cmdId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::stopBackgroundScanInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiStaIface::enableLinkLayerStatsCollection(bool in_debug) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::enableLinkLayerStatsCollectionInternal, in_debug);
+}
+
+ndk::ScopedAStatus WifiStaIface::disableLinkLayerStatsCollection() {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::disableLinkLayerStatsCollectionInternal);
+}
+
+ndk::ScopedAStatus WifiStaIface::getLinkLayerStats(StaLinkLayerStats* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getLinkLayerStatsInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::startRssiMonitoring(int32_t in_cmdId, int32_t in_maxRssi,
+                                                     int32_t in_minRssi) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::startRssiMonitoringInternal, in_cmdId, in_maxRssi,
+                           in_minRssi);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopRssiMonitoring(int32_t in_cmdId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::stopRssiMonitoringInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiStaIface::getRoamingCapabilities(StaRoamingCapabilities* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getRoamingCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::configureRoaming(const StaRoamingConfig& in_config) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::configureRoamingInternal, in_config);
+}
+
+ndk::ScopedAStatus WifiStaIface::setRoamingState(StaRoamingState in_state) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setRoamingStateInternal, in_state);
+}
+
+ndk::ScopedAStatus WifiStaIface::enableNdOffload(bool in_enable) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::enableNdOffloadInternal, in_enable);
+}
+
+ndk::ScopedAStatus WifiStaIface::startSendingKeepAlivePackets(
+        int32_t in_cmdId, const std::vector<uint8_t>& in_ipPacketData, char16_t in_etherType,
+        const std::array<uint8_t, 6>& in_srcAddress, const std::array<uint8_t, 6>& in_dstAddress,
+        int32_t in_periodInMs) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::startSendingKeepAlivePacketsInternal, in_cmdId,
+                           in_ipPacketData, in_etherType, in_srcAddress, in_dstAddress,
+                           in_periodInMs);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopSendingKeepAlivePackets(int32_t in_cmdId) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::stopSendingKeepAlivePacketsInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiStaIface::startDebugPacketFateMonitoring() {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::startDebugPacketFateMonitoringInternal);
+}
+
+ndk::ScopedAStatus WifiStaIface::getDebugTxPacketFates(
+        std::vector<WifiDebugTxPacketFateReport>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getDebugTxPacketFatesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::getDebugRxPacketFates(
+        std::vector<WifiDebugRxPacketFateReport>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getDebugRxPacketFatesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::setMacAddress(const std::array<uint8_t, 6>& in_mac) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setMacAddressInternal, in_mac);
+}
+
+ndk::ScopedAStatus WifiStaIface::getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getFactoryMacAddressInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::setScanMode(bool in_enable) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setScanModeInternal, in_enable);
+}
+
+ndk::ScopedAStatus WifiStaIface::setDtimMultiplier(int32_t in_multiplier) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setDtimMultiplierInternal, in_multiplier);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> WifiStaIface::getNameInternal() {
+    return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::registerEventCallbackInternal(
+        const std::shared_ptr<IWifiStaIfaceEventCallback>& callback) {
+    if (!event_cb_handler_.addCallback(callback)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::pair<int32_t, ndk::ScopedAStatus> WifiStaIface::getFeatureSetInternal() {
+    legacy_hal::wifi_error legacy_status;
+    uint64_t legacy_feature_set;
+    std::tie(legacy_status, legacy_feature_set) =
+            legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {0, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    uint32_t aidl_feature_set;
+    if (!aidl_struct_util::convertLegacyStaIfaceFeaturesToAidl(legacy_feature_set,
+                                                               &aidl_feature_set)) {
+        return {0, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_feature_set, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<StaApfPacketFilterCapabilities, ndk::ScopedAStatus>
+WifiStaIface::getApfPacketFilterCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::PacketFilterCapabilities legacy_caps;
+    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getPacketFilterCapabilities(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {StaApfPacketFilterCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    StaApfPacketFilterCapabilities aidl_caps;
+    if (!aidl_struct_util::convertLegacyApfCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+        return {StaApfPacketFilterCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_caps, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::installApfPacketFilterInternal(
+        const std::vector<uint8_t>& program) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setPacketFilter(ifname_, program);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+WifiStaIface::readApfPacketFilterDataInternal() {
+    const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>> legacy_status_and_data =
+            legacy_hal_.lock()->readApfPacketFilterData(ifname_);
+    return {std::move(legacy_status_and_data.second),
+            createWifiStatusFromLegacyError(legacy_status_and_data.first)};
+}
+
+std::pair<StaBackgroundScanCapabilities, ndk::ScopedAStatus>
+WifiStaIface::getBackgroundScanCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_gscan_capabilities legacy_caps;
+    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getGscanCapabilities(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {StaBackgroundScanCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    StaBackgroundScanCapabilities aidl_caps;
+    if (!aidl_struct_util::convertLegacyGscanCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+        return {StaBackgroundScanCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_caps, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::startBackgroundScanInternal(
+        int32_t cmd_id, const StaBackgroundScanParameters& params) {
+    legacy_hal::wifi_scan_cmd_params legacy_params;
+    if (!aidl_struct_util::convertAidlGscanParamsToLegacy(params, &legacy_params)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
+    const auto& on_failure_callback = [weak_ptr_this](legacy_hal::wifi_request_id id) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onBackgroundScanFailure(id).isOk()) {
+                LOG(ERROR) << "Failed to invoke onBackgroundScanFailure callback";
+            }
+        }
+    };
+    const auto& on_results_callback =
+            [weak_ptr_this](legacy_hal::wifi_request_id id,
+                            const std::vector<legacy_hal::wifi_cached_scan_results>& results) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                std::vector<StaScanData> aidl_scan_datas;
+                if (!aidl_struct_util::convertLegacyVectorOfCachedGscanResultsToAidl(
+                            results, &aidl_scan_datas)) {
+                    LOG(ERROR) << "Failed to convert scan results to AIDL structs";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->onBackgroundScanResults(id, aidl_scan_datas).isOk()) {
+                        LOG(ERROR) << "Failed to invoke onBackgroundScanResults callback";
+                    }
+                }
+            };
+    const auto& on_full_result_callback = [weak_ptr_this](
+                                                  legacy_hal::wifi_request_id id,
+                                                  const legacy_hal::wifi_scan_result* result,
+                                                  uint32_t buckets_scanned) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        StaScanResult aidl_scan_result;
+        if (!aidl_struct_util::convertLegacyGscanResultToAidl(*result, true, &aidl_scan_result)) {
+            LOG(ERROR) << "Failed to convert full scan results to AIDL structs";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onBackgroundFullScanResult(id, buckets_scanned, aidl_scan_result)
+                         .isOk()) {
+                LOG(ERROR) << "Failed to invoke onBackgroundFullScanResult callback";
+            }
+        }
+    };
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->startGscan(ifname_, cmd_id, legacy_params, on_failure_callback,
+                                           on_results_callback, on_full_result_callback);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopBackgroundScanInternal(int32_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopGscan(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableLinkLayerStats(ifname_);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<StaLinkLayerStats, ndk::ScopedAStatus> WifiStaIface::getLinkLayerStatsInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::LinkLayerStats legacy_stats{};
+    legacy_hal::LinkLayerMlStats legacy_ml_stats{};
+    legacy_status = legacy_hal_.lock()->getLinkLayerStats(ifname_, legacy_stats, legacy_ml_stats);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {StaLinkLayerStats{}, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    StaLinkLayerStats aidl_stats;
+    if (legacy_stats.valid) {
+        if (!aidl_struct_util::convertLegacyLinkLayerStatsToAidl(legacy_stats, &aidl_stats)) {
+            return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+        }
+    } else if (legacy_ml_stats.valid) {
+        if (!aidl_struct_util::convertLegacyLinkLayerMlStatsToAidl(legacy_ml_stats, &aidl_stats)) {
+            return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+        }
+    } else {
+        return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_stats, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::startRssiMonitoringInternal(int32_t cmd_id, int32_t max_rssi,
+                                                             int32_t min_rssi) {
+    std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
+    const auto& on_threshold_breached_callback =
+            [weak_ptr_this](legacy_hal::wifi_request_id id, std::array<uint8_t, ETH_ALEN> bssid,
+                            int8_t rssi) {
+                const auto shared_ptr_this = weak_ptr_this.lock();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->onRssiThresholdBreached(id, bssid, rssi).isOk()) {
+                        LOG(ERROR) << "Failed to invoke onRssiThresholdBreached callback";
+                    }
+                }
+            };
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRssiMonitoring(
+            ifname_, cmd_id, max_rssi, min_rssi, on_threshold_breached_callback);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopRssiMonitoringInternal(int32_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<StaRoamingCapabilities, ndk::ScopedAStatus>
+WifiStaIface::getRoamingCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_roaming_capabilities legacy_caps;
+    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRoamingCapabilities(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {StaRoamingCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+    }
+    StaRoamingCapabilities aidl_caps;
+    if (!aidl_struct_util::convertLegacyRoamingCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+        return {StaRoamingCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_caps, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::configureRoamingInternal(const StaRoamingConfig& config) {
+    legacy_hal::wifi_roaming_config legacy_config;
+    if (!aidl_struct_util::convertAidlRoamingConfigToLegacy(config, &legacy_config)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->configureRoaming(ifname_, legacy_config);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableFirmwareRoaming(
+            ifname_, aidl_struct_util::convertAidlRoamingStateToLegacy(state));
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::enableNdOffloadInternal(bool enable) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->configureNdOffload(ifname_, enable);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
+        int32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, char16_t ether_type,
+        const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address,
+        int32_t period_in_ms) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startSendingOffloadedPacket(
+            ifname_, cmd_id, ether_type, ip_packet_data, src_address, dst_address, period_in_ms);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(int32_t cmd_id) {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startPktFateMonitoring(ifname_);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<std::vector<WifiDebugTxPacketFateReport>, ndk::ScopedAStatus>
+WifiStaIface::getDebugTxPacketFatesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    std::vector<legacy_hal::wifi_tx_report> legacy_fates;
+    std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getTxPktFates(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {std::vector<WifiDebugTxPacketFateReport>(),
+                createWifiStatusFromLegacyError(legacy_status)};
+    }
+    std::vector<WifiDebugTxPacketFateReport> aidl_fates;
+    if (!aidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToAidl(legacy_fates,
+                                                                        &aidl_fates)) {
+        return {std::vector<WifiDebugTxPacketFateReport>(),
+                createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_fates, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<WifiDebugRxPacketFateReport>, ndk::ScopedAStatus>
+WifiStaIface::getDebugRxPacketFatesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    std::vector<legacy_hal::wifi_rx_report> legacy_fates;
+    std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getRxPktFates(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {std::vector<WifiDebugRxPacketFateReport>(),
+                createWifiStatusFromLegacyError(legacy_status)};
+    }
+    std::vector<WifiDebugRxPacketFateReport> aidl_fates;
+    if (!aidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToAidl(legacy_fates,
+                                                                        &aidl_fates)) {
+        return {std::vector<WifiDebugRxPacketFateReport>(),
+                createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {aidl_fates, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
+    bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
+    if (!status) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> WifiStaIface::getFactoryMacAddressInternal() {
+    std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifname_);
+    if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
+        return {mac, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+    }
+    return {mac, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::setScanModeInternal(bool enable) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setScanMode(ifname_, enable);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::setDtimMultiplierInternal(const int multiplier) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDtimConfig(ifname_, multiplier);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_sta_iface.h b/wifi/aidl/default/wifi_sta_iface.h
new file mode 100644
index 0000000..3d7ec4d
--- /dev/null
+++ b/wifi/aidl/default/wifi_sta_iface.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_STA_IFACE_H_
+#define WIFI_STA_IFACE_H_
+
+#include <aidl/android/hardware/wifi/BnWifiStaIface.h>
+#include <aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.h>
+#include <android-base/macros.h>
+
+#include "aidl_callback_util.h"
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control a STA Iface instance.
+ */
+class WifiStaIface : public BnWifiStaIface {
+  public:
+    WifiStaIface(const std::string& ifname,
+                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+
+    // Factory method - use instead of default constructor.
+    static std::shared_ptr<WifiStaIface> create(
+            const std::string& ifname, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+            const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+
+    // Refer to |WifiChip::invalidate()|.
+    void invalidate();
+    bool isValid();
+    std::set<std::shared_ptr<IWifiStaIfaceEventCallback>> getEventCallbacks();
+    std::string getName();
+
+    // AIDL methods exposed.
+    ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+    ndk::ScopedAStatus registerEventCallback(
+            const std::shared_ptr<IWifiStaIfaceEventCallback>& in_callback) override;
+    ndk::ScopedAStatus getFeatureSet(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getApfPacketFilterCapabilities(
+            StaApfPacketFilterCapabilities* _aidl_return) override;
+    ndk::ScopedAStatus installApfPacketFilter(const std::vector<uint8_t>& in_program) override;
+    ndk::ScopedAStatus readApfPacketFilterData(std::vector<uint8_t>* _aidl_return) override;
+    ndk::ScopedAStatus getBackgroundScanCapabilities(
+            StaBackgroundScanCapabilities* _aidl_return) override;
+    ndk::ScopedAStatus startBackgroundScan(int32_t in_cmdId,
+                                           const StaBackgroundScanParameters& in_params) override;
+    ndk::ScopedAStatus stopBackgroundScan(int32_t in_cmdId) override;
+    ndk::ScopedAStatus enableLinkLayerStatsCollection(bool in_debug) override;
+    ndk::ScopedAStatus disableLinkLayerStatsCollection() override;
+    ndk::ScopedAStatus getLinkLayerStats(StaLinkLayerStats* _aidl_return) override;
+    ndk::ScopedAStatus startRssiMonitoring(int32_t in_cmdId, int32_t in_maxRssi,
+                                           int32_t in_minRssi) override;
+    ndk::ScopedAStatus stopRssiMonitoring(int32_t in_cmdId) override;
+    ndk::ScopedAStatus getRoamingCapabilities(StaRoamingCapabilities* _aidl_return) override;
+    ndk::ScopedAStatus configureRoaming(const StaRoamingConfig& in_config) override;
+    ndk::ScopedAStatus setRoamingState(StaRoamingState in_state) override;
+    ndk::ScopedAStatus enableNdOffload(bool in_enable) override;
+    ndk::ScopedAStatus startSendingKeepAlivePackets(int32_t in_cmdId,
+                                                    const std::vector<uint8_t>& in_ipPacketData,
+                                                    char16_t in_etherType,
+                                                    const std::array<uint8_t, 6>& in_srcAddress,
+                                                    const std::array<uint8_t, 6>& in_dstAddress,
+                                                    int32_t in_periodInMs) override;
+    ndk::ScopedAStatus stopSendingKeepAlivePackets(int32_t in_cmdId) override;
+    ndk::ScopedAStatus startDebugPacketFateMonitoring() override;
+    ndk::ScopedAStatus getDebugTxPacketFates(
+            std::vector<WifiDebugTxPacketFateReport>* _aidl_return) override;
+    ndk::ScopedAStatus getDebugRxPacketFates(
+            std::vector<WifiDebugRxPacketFateReport>* _aidl_return) override;
+    ndk::ScopedAStatus setMacAddress(const std::array<uint8_t, 6>& in_mac) override;
+    ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
+    ndk::ScopedAStatus setScanMode(bool in_enable) override;
+    ndk::ScopedAStatus setDtimMultiplier(int32_t in_multiplier) override;
+
+  private:
+    // Corresponding worker functions for the AIDL methods.
+    std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+    ndk::ScopedAStatus registerEventCallbackInternal(
+            const std::shared_ptr<IWifiStaIfaceEventCallback>& callback);
+    std::pair<int32_t, ndk::ScopedAStatus> getFeatureSetInternal();
+    std::pair<StaApfPacketFilterCapabilities, ndk::ScopedAStatus>
+    getApfPacketFilterCapabilitiesInternal();
+    ndk::ScopedAStatus installApfPacketFilterInternal(const std::vector<uint8_t>& program);
+    std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> readApfPacketFilterDataInternal();
+    std::pair<StaBackgroundScanCapabilities, ndk::ScopedAStatus>
+    getBackgroundScanCapabilitiesInternal();
+    ndk::ScopedAStatus startBackgroundScanInternal(int32_t cmd_id,
+                                                   const StaBackgroundScanParameters& params);
+    ndk::ScopedAStatus stopBackgroundScanInternal(int32_t cmd_id);
+    ndk::ScopedAStatus enableLinkLayerStatsCollectionInternal(bool debug);
+    ndk::ScopedAStatus disableLinkLayerStatsCollectionInternal();
+    std::pair<StaLinkLayerStats, ndk::ScopedAStatus> getLinkLayerStatsInternal();
+    ndk::ScopedAStatus startRssiMonitoringInternal(int32_t cmd_id, int32_t max_rssi,
+                                                   int32_t min_rssi);
+    ndk::ScopedAStatus stopRssiMonitoringInternal(int32_t cmd_id);
+    std::pair<StaRoamingCapabilities, ndk::ScopedAStatus> getRoamingCapabilitiesInternal();
+    ndk::ScopedAStatus configureRoamingInternal(const StaRoamingConfig& config);
+    ndk::ScopedAStatus setRoamingStateInternal(StaRoamingState state);
+    ndk::ScopedAStatus enableNdOffloadInternal(bool enable);
+    ndk::ScopedAStatus startSendingKeepAlivePacketsInternal(
+            int32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, char16_t ether_type,
+            const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address,
+            int32_t period_in_ms);
+    ndk::ScopedAStatus stopSendingKeepAlivePacketsInternal(int32_t cmd_id);
+    ndk::ScopedAStatus startDebugPacketFateMonitoringInternal();
+    std::pair<std::vector<WifiDebugTxPacketFateReport>, ndk::ScopedAStatus>
+    getDebugTxPacketFatesInternal();
+    std::pair<std::vector<WifiDebugRxPacketFateReport>, ndk::ScopedAStatus>
+    getDebugRxPacketFatesInternal();
+    ndk::ScopedAStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
+    std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal();
+    ndk::ScopedAStatus setScanModeInternal(bool enable);
+    ndk::ScopedAStatus setDtimMultiplierInternal(const int multiplier);
+
+    void setWeakPtr(std::weak_ptr<WifiStaIface> ptr);
+
+    std::string ifname_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+    std::weak_ptr<WifiStaIface> weak_ptr_this_;
+    bool is_valid_;
+    aidl_callback_util::AidlCallbackHandler<IWifiStaIfaceEventCallback> event_cb_handler_;
+
+    DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
+};
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_STA_IFACE_H_
diff --git a/wifi/aidl/default/wifi_status_util.cpp b/wifi/aidl/default/wifi_status_util.cpp
new file mode 100644
index 0000000..25ecd71
--- /dev/null
+++ b/wifi/aidl/default/wifi_status_util.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+std::string legacyErrorToString(legacy_hal::wifi_error error) {
+    switch (error) {
+        case legacy_hal::WIFI_SUCCESS:
+            return "SUCCESS";
+        case legacy_hal::WIFI_ERROR_UNINITIALIZED:
+            return "UNINITIALIZED";
+        case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
+            return "NOT_AVAILABLE";
+        case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
+            return "NOT_SUPPORTED";
+        case legacy_hal::WIFI_ERROR_INVALID_ARGS:
+            return "INVALID_ARGS";
+        case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
+            return "INVALID_REQUEST_ID";
+        case legacy_hal::WIFI_ERROR_TIMED_OUT:
+            return "TIMED_OUT";
+        case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
+            return "TOO_MANY_REQUESTS";
+        case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
+            return "OUT_OF_MEMORY";
+        case legacy_hal::WIFI_ERROR_BUSY:
+            return "BUSY";
+        case legacy_hal::WIFI_ERROR_UNKNOWN:
+            return "UNKNOWN";
+        default:
+            return "UNKNOWN ERROR";
+    }
+}
+
+ndk::ScopedAStatus createWifiStatus(WifiStatusCode code, const std::string& description) {
+    return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(static_cast<int32_t>(code),
+                                                                   description.c_str());
+}
+
+ndk::ScopedAStatus createWifiStatus(WifiStatusCode code) {
+    return ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(code));
+}
+
+ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
+                                                   const std::string& desc) {
+    switch (error) {
+        case legacy_hal::WIFI_ERROR_NONE:
+            return ndk::ScopedAStatus::ok();
+
+        case legacy_hal::WIFI_ERROR_UNINITIALIZED:
+        case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
+            return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, desc);
+
+        case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
+            return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED, desc);
+
+        case legacy_hal::WIFI_ERROR_INVALID_ARGS:
+        case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
+            return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS, desc);
+
+        case legacy_hal::WIFI_ERROR_TIMED_OUT:
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", timed out");
+
+        case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", too many requests");
+
+        case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", out of memory");
+
+        case legacy_hal::WIFI_ERROR_BUSY:
+            return createWifiStatus(WifiStatusCode::ERROR_BUSY);
+
+        case legacy_hal::WIFI_ERROR_UNKNOWN:
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown");
+
+        default:
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown error");
+    }
+}
+
+ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) {
+    return createWifiStatusFromLegacyError(error, "");
+}
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wifi/aidl/default/wifi_status_util.h b/wifi/aidl/default/wifi_status_util.h
new file mode 100644
index 0000000..633811d
--- /dev/null
+++ b/wifi/aidl/default/wifi_status_util.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_STATUS_UTIL_H_
+#define WIFI_STATUS_UTIL_H_
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using ::aidl::android::hardware::wifi::WifiStatusCode;
+
+std::string legacyErrorToString(legacy_hal::wifi_error error);
+ndk::ScopedAStatus createWifiStatus(WifiStatusCode code, const std::string& description);
+ndk::ScopedAStatus createWifiStatus(WifiStatusCode code);
+ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
+                                                   const std::string& description);
+ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error);
+
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WIFI_STATUS_UTIL_H_
diff --git a/wifi/aidl/vts/functional/Android.bp b/wifi/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..1277182
--- /dev/null
+++ b/wifi/aidl/vts/functional/Android.bp
@@ -0,0 +1,169 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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_test {
+    name: "VtsHalWifiChipTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "wifi_chip_aidl_test.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+        "libvndksupport",
+    ],
+    static_libs: [
+        "VtsHalWifiTargetTestUtil",
+        "android.hardware.wifi-V1-ndk",
+        "libwifi-system-iface",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
+
+cc_test {
+    name: "VtsHalWifiStaIfaceTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "wifi_sta_iface_aidl_test.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+        "libvndksupport",
+    ],
+    static_libs: [
+        "VtsHalWifiTargetTestUtil",
+        "android.hardware.wifi-V1-ndk",
+        "libwifi-system-iface",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
+
+cc_test {
+    name: "VtsHalWifiApIfaceTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "wifi_ap_iface_aidl_test.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+        "libvndksupport",
+    ],
+    static_libs: [
+        "VtsHalWifiTargetTestUtil",
+        "android.hardware.wifi-V1-ndk",
+        "libwifi-system-iface",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
+
+cc_test {
+    name: "VtsHalWifiNanIfaceTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "wifi_nan_iface_aidl_test.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+        "libvndksupport",
+    ],
+    static_libs: [
+        "VtsHalWifiTargetTestUtil",
+        "android.hardware.wifi-V1-ndk",
+        "libwifi-system-iface",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
+
+cc_test {
+    name: "VtsHalWifiRttControllerTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "wifi_rtt_controller_aidl_test.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+        "libvndksupport",
+    ],
+    static_libs: [
+        "VtsHalWifiTargetTestUtil",
+        "android.hardware.wifi-V1-ndk",
+        "libwifi-system-iface",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
+
+cc_library_static {
+    name: "VtsHalWifiTargetTestUtil",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "wifi_aidl_test_utils.cpp",
+    ],
+    export_include_dirs: [
+        ".",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+        "libnativehelper",
+    ],
+    static_libs: [
+        "android.hardware.wifi-V1-ndk",
+        "libwifi-system-iface",
+    ],
+}
diff --git a/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp b/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
new file mode 100644
index 0000000..ca3c4b7
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_aidl_test_utils.h"
+
+using ::android::wifi_system::InterfaceTool;
+
+namespace {
+bool findAnyModeSupportingConcurrencyType(IfaceConcurrencyType desired_type,
+                                          const std::vector<IWifiChip::ChipMode>& modes,
+                                          int* mode_id) {
+    for (const auto& mode : modes) {
+        for (const auto& combination : mode.availableCombinations) {
+            for (const auto& iface_limit : combination.limits) {
+                const auto& iface_types = iface_limit.types;
+                if (std::find(iface_types.begin(), iface_types.end(), desired_type) !=
+                    iface_types.end()) {
+                    *mode_id = mode.id;
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+bool configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip>& wifi_chip,
+                                                   IfaceConcurrencyType type,
+                                                   int* configured_mode_id) {
+    if (!configured_mode_id) {
+        return false;
+    }
+    std::vector<IWifiChip::ChipMode> chip_modes;
+    auto status = wifi_chip->getAvailableModes(&chip_modes);
+    if (!status.isOk()) {
+        return false;
+    }
+    if (!findAnyModeSupportingConcurrencyType(type, chip_modes, configured_mode_id)) {
+        return false;
+    }
+    if (!wifi_chip->configureChip(*configured_mode_id).isOk()) {
+        return false;
+    }
+    return true;
+}
+
+bool configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip>& wifi_chip,
+                                                   IfaceConcurrencyType type) {
+    int mode_id;
+    return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, &mode_id);
+}
+}  // namespace
+
+bool checkStatusCode(ndk::ScopedAStatus* status, WifiStatusCode expected_code) {
+    if (status == nullptr) {
+        return false;
+    }
+    return status->getServiceSpecificError() == static_cast<int32_t>(expected_code);
+}
+
+std::shared_ptr<IWifi> getWifi(const char* instance_name) {
+    return IWifi::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(instance_name)));
+}
+
+std::shared_ptr<IWifiChip> getWifiChip(const char* instance_name) {
+    std::shared_ptr<IWifi> wifi = getWifi(instance_name);
+    if (!wifi.get()) {
+        return nullptr;
+    }
+
+    const int retry_interval_ms = 2;
+    const int max_retries = 5;
+    int retry_count = 0;
+    auto status = wifi->start();
+    while (retry_count < max_retries && !status.isOk()) {
+        retry_count++;
+        usleep(retry_interval_ms * 1000);
+        status = wifi->start();
+    }
+    if (!status.isOk()) {
+        return nullptr;
+    }
+
+    std::vector<int> chip_ids = {};
+    status = wifi->getChipIds(&chip_ids);
+    if (!status.isOk() || chip_ids.size() == 0) {
+        return nullptr;
+    }
+    std::shared_ptr<IWifiChip> chip;
+    status = wifi->getChip(chip_ids[0], &chip);
+    if (!status.isOk()) {
+        return nullptr;
+    }
+    return chip;
+}
+
+void setupStaIface(const std::shared_ptr<IWifiStaIface>& iface) {
+    std::string iface_name;
+    auto status = iface->getName(&iface_name);
+    if (status.isOk()) {
+        InterfaceTool iface_tool;
+        iface_tool.SetUpState(iface_name.c_str(), true);
+    }
+}
+
+void setupNanIface(const std::shared_ptr<IWifiNanIface>& iface) {
+    std::string iface_name;
+    auto status = iface->getName(&iface_name);
+    if (status.isOk()) {
+        InterfaceTool iface_tool;
+        iface_tool.SetUpState(iface_name.c_str(), true);
+    }
+}
+
+std::shared_ptr<IWifiStaIface> getWifiStaIface(const char* instance_name) {
+    std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::STA)) {
+        return nullptr;
+    }
+    std::shared_ptr<IWifiStaIface> iface;
+    auto status = wifi_chip->createStaIface(&iface);
+    if (!status.isOk()) {
+        return nullptr;
+    }
+    setupStaIface(iface);
+    return iface;
+}
+
+std::shared_ptr<IWifiNanIface> getWifiNanIface(const char* instance_name) {
+    std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip,
+                                                       IfaceConcurrencyType::NAN_IFACE)) {
+        return nullptr;
+    }
+    std::shared_ptr<IWifiNanIface> iface;
+    auto status = wifi_chip->createNanIface(&iface);
+    if (!status.isOk()) {
+        return nullptr;
+    }
+    setupNanIface(iface);
+    return iface;
+}
+
+std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name) {
+    std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP)) {
+        return nullptr;
+    }
+    std::shared_ptr<IWifiApIface> iface;
+    auto status = wifi_chip->createApIface(&iface);
+    if (!status.isOk()) {
+        return nullptr;
+    }
+    return iface;
+}
+
+std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip) {
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    int mode_id;
+    std::shared_ptr<IWifiApIface> iface;
+    configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP, &mode_id);
+    auto status = wifi_chip->createBridgedApIface(&iface);
+    if (!status.isOk()) {
+        return nullptr;
+    }
+    return iface;
+}
+
+std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name) {
+    std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+    return getBridgedWifiApIface(wifi_chip);
+}
+
+bool configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
+                                           IfaceConcurrencyType type, int* configured_mode_id) {
+    return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, configured_mode_id);
+}
+
+void stopWifiService(const char* instance_name) {
+    std::shared_ptr<IWifi> wifi = getWifi(instance_name);
+    if (wifi != nullptr) {
+        wifi->stop();
+    }
+}
+
+int32_t getChipFeatureSet(const std::shared_ptr<IWifiChip>& wifi_chip) {
+    int32_t features = 0;
+    if (wifi_chip->getFeatureSet(&features).isOk()) {
+        return features;
+    }
+    return 0;
+}
+
+bool isAidlServiceAvailable(const char* instance_name) {
+    return AServiceManager_isDeclared(instance_name);
+}
diff --git a/wifi/aidl/vts/functional/wifi_aidl_test_utils.h b/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
new file mode 100644
index 0000000..0d70c3b
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <VtsCoreUtil.h>
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <aidl/android/hardware/wifi/IWifiChip.h>
+#include <android/binder_manager.h>
+#include <wifi_system/interface_tool.h>
+
+using aidl::android::hardware::wifi::IfaceConcurrencyType;
+using aidl::android::hardware::wifi::IWifi;
+using aidl::android::hardware::wifi::IWifiApIface;
+using aidl::android::hardware::wifi::IWifiChip;
+using aidl::android::hardware::wifi::IWifiNanIface;
+using aidl::android::hardware::wifi::IWifiStaIface;
+using aidl::android::hardware::wifi::WifiStatusCode;
+
+// Helper functions to obtain references to the various AIDL interface objects.
+std::shared_ptr<IWifi> getWifi(const char* instance_name);
+std::shared_ptr<IWifiChip> getWifiChip(const char* instance_name);
+std::shared_ptr<IWifiStaIface> getWifiStaIface(const char* instance_name);
+std::shared_ptr<IWifiNanIface> getWifiNanIface(const char* instance_name);
+std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name);
+std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name);
+std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip);
+// Configure the chip in a mode to support the creation of the provided iface type.
+bool configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
+                                           IfaceConcurrencyType type, int* configured_mode_id);
+// Used to trigger IWifi.stop() at the end of every test.
+void stopWifiService(const char* instance_name);
+int32_t getChipFeatureSet(const std::shared_ptr<IWifiChip>& wifi_chip);
+bool checkStatusCode(ndk::ScopedAStatus* status, WifiStatusCode expected_code);
+bool isAidlServiceAvailable(const char* instance_name);
diff --git a/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp
new file mode 100644
index 0000000..d39cfb4
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::IWifiApIface;
+using aidl::android::hardware::wifi::WifiBand;
+
+class WifiApIfaceAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        isBridgedSupport_ = testing::checkSubstringInCommandOutput(
+                "/system/bin/cmd wifi get-softap-supported-features",
+                "wifi_softap_bridged_ap_supported");
+        stopWifiService(getInstanceName());
+    }
+
+    void TearDown() override { stopWifiService(getInstanceName()); }
+
+  protected:
+    bool isBridgedSupport_ = false;
+    const char* getInstanceName() { return GetParam().c_str(); }
+};
+
+/*
+ * SetMacAddress
+ */
+TEST_P(WifiApIfaceAidlTest, SetMacAddress) {
+    std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+    ASSERT_NE(nullptr, wifi_ap_iface.get());
+    std::array<uint8_t, 6> mac = {0x12, 0x22, 0x33, 0x52, 0x10, 0x44};
+    EXPECT_TRUE(wifi_ap_iface->setMacAddress(mac).isOk());
+}
+
+/*
+ * SetCountryCode
+ */
+TEST_P(WifiApIfaceAidlTest, SetCountryCode) {
+    std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+    ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+    const std::array<uint8_t, 2> country_code = {0x55, 0x53};
+    EXPECT_TRUE(wifi_ap_iface->setCountryCode(country_code).isOk());
+}
+
+/*
+ * GetFactoryMacAddress
+ */
+TEST_P(WifiApIfaceAidlTest, GetFactoryMacAddress) {
+    std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+    ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+    std::array<uint8_t, 6> mac;
+    EXPECT_TRUE(wifi_ap_iface->getFactoryMacAddress(&mac).isOk());
+    std::array<uint8_t, 6> all_zero_mac = {0, 0, 0, 0, 0, 0};
+    EXPECT_NE(mac, all_zero_mac);
+}
+
+/**
+ * GetBridgedInstances - non-bridged mode
+ */
+TEST_P(WifiApIfaceAidlTest, GetBridgedInstances) {
+    std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+    ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+    std::vector<std::string> instances;
+    EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
+    EXPECT_EQ(instances.size(), 0);
+}
+
+/**
+ * GetBridgedInstances - bridged AP mode.
+ */
+TEST_P(WifiApIfaceAidlTest, GetBridgedInstances_Bridged) {
+    if (!isBridgedSupport_) {
+        GTEST_SKIP() << "Missing Bridged AP support";
+    }
+    std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(getInstanceName());
+    ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+    std::vector<std::string> instances;
+    EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
+    EXPECT_EQ(instances.size(), 2);
+}
+
+/**
+ * ResetToFactoryMacAddress - non-bridged mode
+ */
+TEST_P(WifiApIfaceAidlTest, ResetToFactoryMacAddress) {
+    std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+    ASSERT_NE(nullptr, wifi_ap_iface.get());
+    EXPECT_TRUE(wifi_ap_iface->resetToFactoryMacAddress().isOk());
+}
+
+/**
+ * ResetToFactoryMacAddress - bridged AP mode
+ */
+TEST_P(WifiApIfaceAidlTest, ResetToFactoryMacAddress_Bridged) {
+    if (!isBridgedSupport_) {
+        GTEST_SKIP() << "Missing Bridged AP support";
+    }
+    std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(getInstanceName());
+    ASSERT_NE(nullptr, wifi_ap_iface.get());
+    EXPECT_TRUE(wifi_ap_iface->resetToFactoryMacAddress().isOk());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiApIfaceAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiApIfaceAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    android::ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
new file mode 100644
index 0000000..bbd27f9
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
@@ -0,0 +1,857 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <numeric>
+#include <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <aidl/android/hardware/wifi/BnWifiChipEventCallback.h>
+#include <aidl/android/hardware/wifi/WifiIfaceMode.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::BnWifiChipEventCallback;
+using aidl::android::hardware::wifi::IfaceType;
+using aidl::android::hardware::wifi::IWifiApIface;
+using aidl::android::hardware::wifi::IWifiChip;
+using aidl::android::hardware::wifi::IWifiNanIface;
+using aidl::android::hardware::wifi::IWifiP2pIface;
+using aidl::android::hardware::wifi::IWifiRttController;
+using aidl::android::hardware::wifi::WifiBand;
+using aidl::android::hardware::wifi::WifiDebugHostWakeReasonStats;
+using aidl::android::hardware::wifi::WifiDebugRingBufferStatus;
+using aidl::android::hardware::wifi::WifiDebugRingBufferVerboseLevel;
+using aidl::android::hardware::wifi::WifiIfaceMode;
+using aidl::android::hardware::wifi::WifiRadioCombination;
+using aidl::android::hardware::wifi::WifiStatusCode;
+using aidl::android::hardware::wifi::WifiUsableChannel;
+
+class WifiChipAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        stopWifiService(getInstanceName());
+        wifi_chip_ = getWifiChip(getInstanceName());
+        ASSERT_NE(nullptr, wifi_chip_.get());
+    }
+
+    void TearDown() override { stopWifiService(getInstanceName()); }
+
+  protected:
+    int configureChipForConcurrencyType(IfaceConcurrencyType type) {
+        int mode_id;
+        EXPECT_TRUE(configureChipToSupportConcurrencyType(wifi_chip_, type, &mode_id));
+        return mode_id;
+    }
+
+    std::shared_ptr<IWifiStaIface> configureChipForStaAndGetIface() {
+        std::shared_ptr<IWifiStaIface> iface;
+        configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+        EXPECT_TRUE(wifi_chip_->createStaIface(&iface).isOk());
+        EXPECT_NE(nullptr, iface.get());
+        return iface;
+    }
+
+    std::shared_ptr<IWifiP2pIface> configureChipForP2pAndGetIface() {
+        std::shared_ptr<IWifiP2pIface> iface;
+        configureChipForConcurrencyType(IfaceConcurrencyType::P2P);
+        EXPECT_TRUE(wifi_chip_->createP2pIface(&iface).isOk());
+        EXPECT_NE(nullptr, iface.get());
+        return iface;
+    }
+
+    std::shared_ptr<IWifiApIface> configureChipForApAndGetIface() {
+        std::shared_ptr<IWifiApIface> iface;
+        configureChipForConcurrencyType(IfaceConcurrencyType::AP);
+        EXPECT_TRUE(wifi_chip_->createApIface(&iface).isOk());
+        EXPECT_NE(nullptr, iface.get());
+        return iface;
+    }
+
+    std::shared_ptr<IWifiNanIface> configureChipForNanAndGetIface() {
+        std::shared_ptr<IWifiNanIface> iface;
+        configureChipForConcurrencyType(IfaceConcurrencyType::NAN_IFACE);
+        EXPECT_TRUE(wifi_chip_->createNanIface(&iface).isOk());
+        EXPECT_NE(nullptr, iface.get());
+        return iface;
+    }
+
+    std::string getStaIfaceName(const std::shared_ptr<IWifiStaIface>& iface) {
+        std::string iface_name;
+        EXPECT_TRUE(iface->getName(&iface_name).isOk());
+        return iface_name;
+    }
+
+    std::string getP2pIfaceName(const std::shared_ptr<IWifiP2pIface>& iface) {
+        std::string iface_name;
+        EXPECT_TRUE(iface->getName(&iface_name).isOk());
+        return iface_name;
+    }
+
+    std::string getApIfaceName(const std::shared_ptr<IWifiApIface>& iface) {
+        std::string iface_name;
+        EXPECT_TRUE(iface->getName(&iface_name).isOk());
+        return iface_name;
+    }
+
+    std::string getNanIfaceName(const std::shared_ptr<IWifiNanIface>& iface) {
+        std::string iface_name;
+        EXPECT_TRUE(iface->getName(&iface_name).isOk());
+        return iface_name;
+    }
+
+    std::vector<std::shared_ptr<IWifiStaIface>> create2StaIfacesIfPossible() {
+        std::shared_ptr<IWifiStaIface> iface1 = configureChipForStaAndGetIface();
+
+        // Try create a create second iface.
+        std::shared_ptr<IWifiStaIface> iface2;
+        bool add_second_success = wifi_chip_->createStaIface(&iface2).isOk();
+        if (!add_second_success) {
+            return {iface1};
+        }
+        EXPECT_NE(nullptr, iface2.get());
+        return {iface1, iface2};
+    }
+
+    const char* getInstanceName() { return GetParam().c_str(); }
+
+    std::shared_ptr<IWifiChip> wifi_chip_;
+};
+
+class WifiChipEventCallback : public BnWifiChipEventCallback {
+  public:
+    WifiChipEventCallback() = default;
+
+    ::ndk::ScopedAStatus onChipReconfigureFailure(WifiStatusCode /* status */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onChipReconfigured(int /* modeId */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDebugErrorAlert(int /* errorCode */,
+                                           const std::vector<uint8_t>& /* debugData */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDebugRingBufferDataAvailable(
+            const WifiDebugRingBufferStatus& /* status */,
+            const std::vector<uint8_t>& /* data */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onIfaceAdded(IfaceType /* type */,
+                                      const std::string& /* name */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onIfaceRemoved(IfaceType /* type */,
+                                        const std::string& /* name */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onRadioModeChange(
+            const std::vector<RadioModeInfo>& /* radioModeInfos */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
+/*
+ * RegisterEventCallback
+ *
+ * Note: it is not feasible to test the invocation of the callback function,
+ * since events are triggered internally in the HAL implementation and cannot be
+ * triggered from the test case.
+ */
+TEST_P(WifiChipAidlTest, RegisterEventCallback) {
+    std::shared_ptr<WifiChipEventCallback> callback =
+            ndk::SharedRefBase::make<WifiChipEventCallback>();
+    ASSERT_NE(nullptr, callback.get());
+    EXPECT_TRUE(wifi_chip_->registerEventCallback(callback).isOk());
+}
+
+/*
+ * GetFeatureSet
+ */
+TEST_P(WifiChipAidlTest, GetFeatureSet) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    int32_t features;
+    EXPECT_TRUE(wifi_chip_->getFeatureSet(&features).isOk());
+}
+
+/*
+ * GetId
+ */
+TEST_P(WifiChipAidlTest, GetId) {
+    int id;
+    EXPECT_TRUE(wifi_chip_->getId(&id).isOk());
+}
+
+/*
+ * GetAvailableModes
+ */
+TEST_P(WifiChipAidlTest, GetAvailableModes) {
+    std::vector<IWifiChip::ChipMode> modes;
+    EXPECT_TRUE(wifi_chip_->getAvailableModes(&modes).isOk());
+    EXPECT_NE(modes.size(), 0);
+}
+
+/*
+ * GetMode
+ */
+TEST_P(WifiChipAidlTest, GetMode) {
+    int expected_mode = configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    int retrieved_mode;
+    EXPECT_TRUE(wifi_chip_->getMode(&retrieved_mode).isOk());
+    EXPECT_EQ(retrieved_mode, expected_mode);
+}
+
+/*
+ * GetUsableChannels
+ */
+TEST_P(WifiChipAidlTest, GetUsableChannels) {
+    WifiBand band = WifiBand::BAND_24GHZ_5GHZ_6GHZ;
+    uint32_t ifaceModeMask = static_cast<uint32_t>(WifiIfaceMode::IFACE_MODE_P2P_CLIENT) |
+                             static_cast<uint32_t>(WifiIfaceMode::IFACE_MODE_P2P_GO);
+    uint32_t filterMask =
+            static_cast<uint32_t>(IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) |
+            static_cast<uint32_t>(IWifiChip::UsableChannelFilter::CONCURRENCY);
+
+    std::vector<WifiUsableChannel> channels;
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    auto status = wifi_chip_->getUsableChannels(band, ifaceModeMask, filterMask, &channels);
+    if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        GTEST_SKIP() << "getUsableChannels() is not supported by vendor.";
+    }
+    EXPECT_TRUE(status.isOk());
+}
+
+/*
+ * GetSupportedRadioCombinations
+ */
+TEST_P(WifiChipAidlTest, GetSupportedRadioCombinations) {
+    std::vector<WifiRadioCombination> combinations;
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    auto status = wifi_chip_->getSupportedRadioCombinations(&combinations);
+    if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        GTEST_SKIP() << "Skipping this test since getSupportedRadioCombinations() "
+                        "is not supported by vendor.";
+    }
+    EXPECT_TRUE(status.isOk());
+}
+
+/*
+ * SetCountryCode
+ */
+TEST_P(WifiChipAidlTest, SetCountryCode) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    std::array<uint8_t, 2> country_code = {0x55, 0x53};
+    EXPECT_TRUE(wifi_chip_->setCountryCode(country_code).isOk());
+}
+
+/*
+ * SetLatencyMode_normal
+ * Tests the setLatencyMode() API with Latency mode NORMAL.
+ */
+TEST_P(WifiChipAidlTest, SetLatencyMode_normal) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    int32_t features = getChipFeatureSet(wifi_chip_);
+    auto status = wifi_chip_->setLatencyMode(IWifiChip::LatencyMode::NORMAL);
+    if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_LATENCY_MODE)) {
+        EXPECT_TRUE(status.isOk());
+    } else {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+}
+
+/*
+ * SetLatencyMode_low
+ * Tests the setLatencyMode() API with Latency mode LOW.
+ */
+TEST_P(WifiChipAidlTest, SetLatencyMode_low) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    int32_t features = getChipFeatureSet(wifi_chip_);
+    auto status = wifi_chip_->setLatencyMode(IWifiChip::LatencyMode::LOW);
+    if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_LATENCY_MODE)) {
+        EXPECT_TRUE(status.isOk());
+    } else {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+}
+
+/*
+ * SetMultiStaPrimaryConnection
+ *
+ * Only runs if the device supports 2 STA ifaces.
+ */
+TEST_P(WifiChipAidlTest, SetMultiStaPrimaryConnection) {
+    auto ifaces = create2StaIfacesIfPossible();
+    if (ifaces.size() < 2) {
+        GTEST_SKIP() << "Device does not support more than 1 STA concurrently";
+    }
+
+    auto status = wifi_chip_->setMultiStaPrimaryConnection(getStaIfaceName(ifaces[0]));
+    if (!status.isOk()) {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+}
+
+/*
+ * SetMultiStaUseCase
+ *
+ * Only runs if the device supports 2 STA ifaces.
+ */
+TEST_P(WifiChipAidlTest, setMultiStaUseCase) {
+    auto ifaces = create2StaIfacesIfPossible();
+    if (ifaces.size() < 2) {
+        GTEST_SKIP() << "Device does not support more than 1 STA concurrently";
+    }
+
+    auto status = wifi_chip_->setMultiStaUseCase(
+            IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY);
+    if (!status.isOk()) {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+}
+
+/*
+ * SetCoexUnsafeChannels
+ */
+TEST_P(WifiChipAidlTest, SetCoexUnsafeChannels) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+
+    // Test with an empty vector of CoexUnsafeChannels.
+    std::vector<IWifiChip::CoexUnsafeChannel> vec;
+    int restrictions = 0;
+    auto status = wifi_chip_->setCoexUnsafeChannels(vec, restrictions);
+    if (!status.isOk()) {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+
+    // Test with a non-empty vector of CoexUnsafeChannels.
+    IWifiChip::CoexUnsafeChannel unsafeChannel24Ghz;
+    unsafeChannel24Ghz.band = WifiBand::BAND_24GHZ;
+    unsafeChannel24Ghz.channel = 6;
+    vec.push_back(unsafeChannel24Ghz);
+    IWifiChip::CoexUnsafeChannel unsafeChannel5Ghz;
+    unsafeChannel5Ghz.band = WifiBand::BAND_5GHZ;
+    unsafeChannel5Ghz.channel = 36;
+    vec.push_back(unsafeChannel5Ghz);
+    restrictions = static_cast<int32_t>(IWifiChip::CoexRestriction::WIFI_AWARE) |
+                   static_cast<int32_t>(IWifiChip::CoexRestriction::SOFTAP) |
+                   static_cast<int32_t>(IWifiChip::CoexRestriction::WIFI_DIRECT);
+
+    status = wifi_chip_->setCoexUnsafeChannels(vec, restrictions);
+    if (!status.isOk()) {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+}
+
+/*
+ * SelectTxPowerScenario - Body
+ */
+TEST_P(WifiChipAidlTest, SelectTxPowerScenario_body) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    int32_t features = getChipFeatureSet(wifi_chip_);
+    int32_t expected_features =
+            static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_TX_POWER_LIMIT) |
+            static_cast<int32_t>(IWifiChip::FeatureSetMask::USE_BODY_HEAD_SAR);
+    auto status = wifi_chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF);
+    if (features & expected_features) {
+        EXPECT_TRUE(status.isOk());
+    } else {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+}
+
+/*
+ * SelectTxPowerScenario - Voice Call
+ */
+TEST_P(WifiChipAidlTest, SelectTxPowerScenario_voiceCall) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    int32_t features = getChipFeatureSet(wifi_chip_);
+    auto status = wifi_chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::VOICE_CALL);
+    if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_TX_POWER_LIMIT)) {
+        EXPECT_TRUE(status.isOk());
+    } else {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+}
+
+/*
+ * ResetTxPowerScenario
+ */
+TEST_P(WifiChipAidlTest, ResetTxPowerScenario) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    int32_t features = getChipFeatureSet(wifi_chip_);
+    auto status = wifi_chip_->resetTxPowerScenario();
+    if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_TX_POWER_LIMIT)) {
+        EXPECT_TRUE(status.isOk());
+    } else {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+}
+
+/*
+ * ConfigureChip
+ */
+TEST_P(WifiChipAidlTest, ConfigureChip) {
+    std::vector<IWifiChip::ChipMode> modes;
+    EXPECT_TRUE(wifi_chip_->getAvailableModes(&modes).isOk());
+    EXPECT_NE(modes.size(), 0);
+    for (const auto& mode : modes) {
+        // configureChip() requires a fresh IWifiChip object.
+        wifi_chip_ = getWifiChip(getInstanceName());
+        ASSERT_NE(nullptr, wifi_chip_.get());
+        EXPECT_TRUE(wifi_chip_->configureChip(mode.id).isOk());
+        stopWifiService(getInstanceName());
+        // Sleep for 5 milliseconds between each wifi state toggle.
+        usleep(5000);
+    }
+}
+
+/*
+ * RequestChipDebugInfo
+ */
+TEST_P(WifiChipAidlTest, RequestChipDebugInfo) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    IWifiChip::ChipDebugInfo debug_info = {};
+    EXPECT_TRUE(wifi_chip_->requestChipDebugInfo(&debug_info).isOk());
+    EXPECT_NE(debug_info.driverDescription.size(), 0);
+    EXPECT_NE(debug_info.firmwareDescription.size(), 0);
+}
+
+/*
+ * RequestFirmwareDebugDump
+ */
+TEST_P(WifiChipAidlTest, RequestFirmwareDebugDump) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    std::vector<uint8_t> debug_dump;
+    auto status = wifi_chip_->requestFirmwareDebugDump(&debug_dump);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * RequestDriverDebugDump
+ */
+TEST_P(WifiChipAidlTest, RequestDriverDebugDump) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    std::vector<uint8_t> debug_dump;
+    auto status = wifi_chip_->requestDriverDebugDump(&debug_dump);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * GetDebugRingBuffersStatus
+ */
+TEST_P(WifiChipAidlTest, GetDebugRingBuffersStatus) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    std::vector<WifiDebugRingBufferStatus> ring_buffer_status;
+    auto status = wifi_chip_->getDebugRingBuffersStatus(&ring_buffer_status);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    if (status.isOk()) {
+        ASSERT_NE(ring_buffer_status.size(), 0);
+        for (const auto& ring_buffer : ring_buffer_status) {
+            EXPECT_NE(ring_buffer.ringName.size(), 0);
+        }
+    }
+}
+
+/*
+ * GetDebugHostWakeReasonStats
+ */
+TEST_P(WifiChipAidlTest, GetDebugHostWakeReasonStats) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    WifiDebugHostWakeReasonStats wake_reason_stats = {};
+    auto status = wifi_chip_->getDebugHostWakeReasonStats(&wake_reason_stats);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * StartLoggingToDebugRingBuffer
+ */
+TEST_P(WifiChipAidlTest, StartLoggingToDebugRingBuffer) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    std::string ring_name;
+    std::vector<WifiDebugRingBufferStatus> ring_buffer_status;
+
+    auto status = wifi_chip_->getDebugRingBuffersStatus(&ring_buffer_status);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    if (status.isOk()) {
+        ASSERT_NE(ring_buffer_status.size(), 0);
+        ring_name = ring_buffer_status[0].ringName;
+    }
+
+    status = wifi_chip_->startLoggingToDebugRingBuffer(
+            ring_name, WifiDebugRingBufferVerboseLevel::VERBOSE, 5, 1024);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * ForceDumpToDebugRingBuffer
+ */
+TEST_P(WifiChipAidlTest, ForceDumpToDebugRingBuffer) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+    std::string ring_name;
+    std::vector<WifiDebugRingBufferStatus> ring_buffer_status;
+
+    auto status = wifi_chip_->getDebugRingBuffersStatus(&ring_buffer_status);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    if (status.isOk()) {
+        ASSERT_NE(ring_buffer_status.size(), 0);
+        ring_name = ring_buffer_status[0].ringName;
+    }
+
+    status = wifi_chip_->forceDumpToDebugRingBuffer(ring_name);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * CreateStaIface
+ * Configures the chip in STA mode and creates an iface.
+ */
+TEST_P(WifiChipAidlTest, CreateStaIface) {
+    configureChipForStaAndGetIface();
+}
+
+/*
+ * CreateApIface
+ */
+TEST_P(WifiChipAidlTest, CreateApIface) {
+    configureChipForApAndGetIface();
+}
+
+/*
+ * CreateNanIface
+ */
+TEST_P(WifiChipAidlTest, CreateNanIface) {
+    if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) {
+        GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+    }
+    configureChipForNanAndGetIface();
+}
+
+/*
+ * CreateP2pIface
+ */
+TEST_P(WifiChipAidlTest, CreateP2pIface) {
+    configureChipForP2pAndGetIface();
+}
+
+/*
+ * GetStaIfaceNames
+ * Configures the chip in STA mode and ensures that the iface name list is
+ * empty before creating the iface. Then create the iface and ensure that
+ * iface name is returned in the iface name list.
+ */
+TEST_P(WifiChipAidlTest, GetStaIfaceNames) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+
+    std::vector<std::string> iface_names;
+    EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 0);
+
+    std::shared_ptr<IWifiStaIface> iface;
+    EXPECT_TRUE(wifi_chip_->createStaIface(&iface).isOk());
+    ASSERT_NE(nullptr, iface.get());
+
+    std::string iface_name = getStaIfaceName(iface);
+    EXPECT_TRUE(wifi_chip_->getStaIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 1);
+    EXPECT_EQ(iface_name, iface_names[0]);
+
+    EXPECT_TRUE(wifi_chip_->removeStaIface(iface_name).isOk());
+    EXPECT_TRUE(wifi_chip_->getStaIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 0);
+}
+
+/*
+ * GetP2pIfaceNames
+ */
+TEST_P(WifiChipAidlTest, GetP2pIfaceNames) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::P2P);
+
+    std::vector<std::string> iface_names;
+    EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 0);
+
+    std::shared_ptr<IWifiP2pIface> iface;
+    EXPECT_TRUE(wifi_chip_->createP2pIface(&iface).isOk());
+    ASSERT_NE(nullptr, iface.get());
+
+    std::string iface_name = getP2pIfaceName(iface);
+    EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 1);
+    EXPECT_EQ(iface_name, iface_names[0]);
+
+    EXPECT_TRUE(wifi_chip_->removeP2pIface(iface_name).isOk());
+    EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 0);
+}
+
+/*
+ * GetApIfaceNames
+ */
+TEST_P(WifiChipAidlTest, GetApIfaceNames) {
+    configureChipForConcurrencyType(IfaceConcurrencyType::AP);
+
+    std::vector<std::string> iface_names;
+    EXPECT_TRUE(wifi_chip_->getApIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 0);
+
+    std::shared_ptr<IWifiApIface> iface;
+    EXPECT_TRUE(wifi_chip_->createApIface(&iface).isOk());
+    ASSERT_NE(nullptr, iface.get());
+
+    std::string iface_name = getApIfaceName(iface);
+    EXPECT_TRUE(wifi_chip_->getApIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 1);
+    EXPECT_EQ(iface_name, iface_names[0]);
+
+    EXPECT_TRUE(wifi_chip_->removeApIface(iface_name).isOk());
+    EXPECT_TRUE(wifi_chip_->getApIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 0);
+}
+
+/*
+ * GetNanIfaceNames
+ */
+TEST_P(WifiChipAidlTest, GetNanIfaceNames) {
+    if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) {
+        GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+    }
+    configureChipForConcurrencyType(IfaceConcurrencyType::NAN_IFACE);
+
+    std::vector<std::string> iface_names;
+    EXPECT_TRUE(wifi_chip_->getNanIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 0);
+
+    std::shared_ptr<IWifiNanIface> iface;
+    EXPECT_TRUE(wifi_chip_->createNanIface(&iface).isOk());
+    ASSERT_NE(nullptr, iface.get());
+
+    std::string iface_name = getNanIfaceName(iface);
+    EXPECT_TRUE(wifi_chip_->getNanIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 1);
+    EXPECT_EQ(iface_name, iface_names[0]);
+
+    EXPECT_TRUE(wifi_chip_->removeNanIface(iface_name).isOk());
+    EXPECT_TRUE(wifi_chip_->getNanIfaceNames(&iface_names).isOk());
+    EXPECT_EQ(iface_names.size(), 0);
+}
+
+/*
+ * GetStaIface
+ * Configures the chip in STA mode and creates an iface. Then retrieves
+ * the iface object using its name and ensures that any other name
+ * doesn't retrieve a valid iface object.
+ */
+TEST_P(WifiChipAidlTest, GetStaIface) {
+    std::shared_ptr<IWifiStaIface> iface = configureChipForStaAndGetIface();
+    std::string iface_name = getStaIfaceName(iface);
+
+    std::shared_ptr<IWifiStaIface> retrieved_iface;
+    EXPECT_TRUE(wifi_chip_->getStaIface(iface_name, &retrieved_iface).isOk());
+    EXPECT_NE(nullptr, retrieved_iface.get());
+
+    std::string invalid_name = iface_name + "0";
+    std::shared_ptr<IWifiStaIface> invalid_iface;
+    auto status = wifi_chip_->getStaIface(invalid_name, &invalid_iface);
+    EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    EXPECT_EQ(nullptr, invalid_iface.get());
+}
+
+/*
+ * GetP2pIface
+ */
+TEST_P(WifiChipAidlTest, GetP2pIface) {
+    std::shared_ptr<IWifiP2pIface> iface = configureChipForP2pAndGetIface();
+    std::string iface_name = getP2pIfaceName(iface);
+
+    std::shared_ptr<IWifiP2pIface> retrieved_iface;
+    EXPECT_TRUE(wifi_chip_->getP2pIface(iface_name, &retrieved_iface).isOk());
+    EXPECT_NE(nullptr, retrieved_iface.get());
+
+    std::string invalid_name = iface_name + "0";
+    std::shared_ptr<IWifiP2pIface> invalid_iface;
+    auto status = wifi_chip_->getP2pIface(invalid_name, &invalid_iface);
+    EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    EXPECT_EQ(nullptr, invalid_iface.get());
+}
+
+/*
+ * GetApIface
+ */
+TEST_P(WifiChipAidlTest, GetApIface) {
+    std::shared_ptr<IWifiApIface> iface = configureChipForApAndGetIface();
+    std::string iface_name = getApIfaceName(iface);
+
+    std::shared_ptr<IWifiApIface> retrieved_iface;
+    EXPECT_TRUE(wifi_chip_->getApIface(iface_name, &retrieved_iface).isOk());
+    EXPECT_NE(nullptr, retrieved_iface.get());
+
+    std::string invalid_name = iface_name + "0";
+    std::shared_ptr<IWifiApIface> invalid_iface;
+    auto status = wifi_chip_->getApIface(invalid_name, &invalid_iface);
+    EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    EXPECT_EQ(nullptr, invalid_iface.get());
+}
+
+/*
+ * GetNanIface
+ */
+TEST_P(WifiChipAidlTest, GetNanIface) {
+    if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) {
+        GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+    }
+    std::shared_ptr<IWifiNanIface> iface = configureChipForNanAndGetIface();
+    std::string iface_name = getNanIfaceName(iface);
+
+    std::shared_ptr<IWifiNanIface> retrieved_iface;
+    EXPECT_TRUE(wifi_chip_->getNanIface(iface_name, &retrieved_iface).isOk());
+    EXPECT_NE(nullptr, retrieved_iface.get());
+
+    std::string invalid_name = iface_name + "0";
+    std::shared_ptr<IWifiNanIface> invalid_iface;
+    auto status = wifi_chip_->getNanIface(invalid_name, &invalid_iface);
+    EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    EXPECT_EQ(nullptr, invalid_iface.get());
+}
+
+/*
+ * RemoveStaIface
+ * Configures the chip in STA mode and creates an iface. Then removes
+ * the iface object using the correct name and ensures that any other
+ * name doesn't remove the iface.
+ */
+TEST_P(WifiChipAidlTest, RemoveStaIface) {
+    std::shared_ptr<IWifiStaIface> iface = configureChipForStaAndGetIface();
+    std::string iface_name = getStaIfaceName(iface);
+
+    std::string invalid_name = iface_name + "0";
+    auto status = wifi_chip_->removeStaIface(invalid_name);
+    EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    EXPECT_TRUE(wifi_chip_->removeStaIface(iface_name).isOk());
+
+    // No such iface exists now, so this should return failure.
+    EXPECT_FALSE(wifi_chip_->removeStaIface(iface_name).isOk());
+}
+
+/*
+ * RemoveP2pIface
+ */
+TEST_P(WifiChipAidlTest, RemoveP2pIface) {
+    std::shared_ptr<IWifiP2pIface> iface = configureChipForP2pAndGetIface();
+    std::string iface_name = getP2pIfaceName(iface);
+
+    std::string invalid_name = iface_name + "0";
+    auto status = wifi_chip_->removeP2pIface(invalid_name);
+    EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    EXPECT_TRUE(wifi_chip_->removeP2pIface(iface_name).isOk());
+
+    // No such iface exists now, so this should return failure.
+    EXPECT_FALSE(wifi_chip_->removeP2pIface(iface_name).isOk());
+}
+
+/*
+ * RemoveApIface
+ */
+TEST_P(WifiChipAidlTest, RemoveApIface) {
+    std::shared_ptr<IWifiApIface> iface = configureChipForApAndGetIface();
+    std::string iface_name = getApIfaceName(iface);
+
+    std::string invalid_name = iface_name + "0";
+    auto status = wifi_chip_->removeApIface(invalid_name);
+    EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    EXPECT_TRUE(wifi_chip_->removeApIface(iface_name).isOk());
+
+    // No such iface exists now, so this should return failure.
+    EXPECT_FALSE(wifi_chip_->removeApIface(iface_name).isOk());
+}
+
+/*
+ * RemoveNanIface
+ */
+TEST_P(WifiChipAidlTest, RemoveNanIface) {
+    if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) {
+        GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+    }
+    std::shared_ptr<IWifiNanIface> iface = configureChipForNanAndGetIface();
+    std::string iface_name = getNanIfaceName(iface);
+
+    std::string invalid_name = iface_name + "0";
+    auto status = wifi_chip_->removeNanIface(invalid_name);
+    EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    EXPECT_TRUE(wifi_chip_->removeNanIface(iface_name).isOk());
+
+    // No such iface exists now, so this should return failure.
+    EXPECT_FALSE(wifi_chip_->removeNanIface(iface_name).isOk());
+}
+
+/*
+ * CreateRttController
+ */
+TEST_P(WifiChipAidlTest, CreateRttController) {
+    std::shared_ptr<IWifiStaIface> iface = configureChipForStaAndGetIface();
+    std::shared_ptr<IWifiRttController> rtt_controller;
+    auto status = wifi_chip_->createRttController(iface, &rtt_controller);
+    if (status.isOk()) {
+        EXPECT_NE(nullptr, rtt_controller.get());
+    } else {
+        EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+    }
+}
+
+/**
+ * CreateBridgedApIface & RemoveIfaceInstanceFromBridgedApIface
+ */
+TEST_P(WifiChipAidlTest, CreateBridgedApIfaceAndremoveIfaceInstanceFromBridgedApIfaceTest) {
+    bool isBridgedSupport = testing::checkSubstringInCommandOutput(
+            "/system/bin/cmd wifi get-softap-supported-features",
+            "wifi_softap_bridged_ap_supported");
+    if (!isBridgedSupport) {
+        GTEST_SKIP() << "Missing Bridged AP support";
+    }
+
+    std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
+    ASSERT_NE(nullptr, wifi_chip.get());
+    std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(wifi_chip);
+    ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+    std::string br_name;
+    std::vector<std::string> instances;
+    EXPECT_TRUE(wifi_ap_iface->getName(&br_name).isOk());
+    EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
+    EXPECT_EQ(instances.size(), 2);
+
+    std::vector<std::string> instances_after_remove;
+    EXPECT_TRUE(wifi_chip->removeIfaceInstanceFromBridgedApIface(br_name, instances[0]).isOk());
+    EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances_after_remove).isOk());
+    EXPECT_EQ(instances_after_remove.size(), 1);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiChipAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    android::ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
new file mode 100644
index 0000000..738e72c
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <aidl/android/hardware/wifi/BnWifiNanIfaceEventCallback.h>
+#include <aidl/android/hardware/wifi/NanBandIndex.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::BnWifiNanIfaceEventCallback;
+using aidl::android::hardware::wifi::IWifiNanIface;
+using aidl::android::hardware::wifi::NanBandIndex;
+using aidl::android::hardware::wifi::NanBandSpecificConfig;
+using aidl::android::hardware::wifi::NanBootstrappingConfirmInd;
+using aidl::android::hardware::wifi::NanBootstrappingRequestInd;
+using aidl::android::hardware::wifi::NanCapabilities;
+using aidl::android::hardware::wifi::NanClusterEventInd;
+using aidl::android::hardware::wifi::NanConfigRequest;
+using aidl::android::hardware::wifi::NanConfigRequestSupplemental;
+using aidl::android::hardware::wifi::NanDataPathConfirmInd;
+using aidl::android::hardware::wifi::NanDataPathRequestInd;
+using aidl::android::hardware::wifi::NanDataPathScheduleUpdateInd;
+using aidl::android::hardware::wifi::NanDataPathSecurityType;
+using aidl::android::hardware::wifi::NanEnableRequest;
+using aidl::android::hardware::wifi::NanFollowupReceivedInd;
+using aidl::android::hardware::wifi::NanInitiateDataPathRequest;
+using aidl::android::hardware::wifi::NanMatchAlg;
+using aidl::android::hardware::wifi::NanMatchInd;
+using aidl::android::hardware::wifi::NanPairingConfirmInd;
+using aidl::android::hardware::wifi::NanPairingRequestInd;
+using aidl::android::hardware::wifi::NanPublishRequest;
+using aidl::android::hardware::wifi::NanPublishType;
+using aidl::android::hardware::wifi::NanRespondToDataPathIndicationRequest;
+using aidl::android::hardware::wifi::NanStatus;
+using aidl::android::hardware::wifi::NanStatusCode;
+using aidl::android::hardware::wifi::NanSuspensionModeChangeInd;
+using aidl::android::hardware::wifi::NanTxType;
+
+#define TIMEOUT_PERIOD 10
+
+class WifiNanIfaceAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware"))
+            GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+        stopWifiService(getInstanceName());
+
+        wifi_nan_iface_ = getWifiNanIface(getInstanceName());
+        ASSERT_NE(nullptr, wifi_nan_iface_.get());
+        std::shared_ptr<WifiNanIfaceEventCallback> callback =
+                ndk::SharedRefBase::make<WifiNanIfaceEventCallback>(*this);
+        EXPECT_TRUE(wifi_nan_iface_->registerEventCallback(callback).isOk());
+    }
+
+    void TearDown() override { stopWifiService(getInstanceName()); }
+
+    enum CallbackType {
+        INVALID = 0,
+
+        NOTIFY_CAPABILITIES_RESPONSE = 1,
+        NOTIFY_ENABLE_RESPONSE,
+        NOTIFY_CONFIG_RESPONSE,
+        NOTIFY_DISABLE_RESPONSE,
+        NOTIFY_START_PUBLISH_RESPONSE,
+        NOTIFY_STOP_PUBLISH_RESPONSE,
+        NOTIFY_START_SUBSCRIBE_RESPONSE,
+        NOTIFY_STOP_SUBSCRIBE_RESPONSE,
+        NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE,
+        NOTIFY_CREATE_DATA_INTERFACE_RESPONSE,
+        NOTIFY_DELETE_DATA_INTERFACE_RESPONSE,
+        NOTIFY_INITIATE_DATA_PATH_RESPONSE,
+        NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE,
+        NOTIFY_TERMINATE_DATA_PATH_RESPONSE,
+        NOTIFY_INITIATE_PAIRING_RESPONSE,
+        NOTIFY_RESPOND_TO_PAIRING_INDICATION_RESPONSE,
+        NOTIFY_INITIATE_BOOTSTRAPPING_RESPONSE,
+        NOTIFY_RESPOND_TO_BOOTSTRAPPING_INDICATION_RESPONSE,
+        NOTIFY_SUSPEND_RESPONSE,
+        NOTIFY_RESUME_RESPONSE,
+        NOTIFY_TERMINATE_PAIRING_RESPONSE,
+
+        EVENT_CLUSTER_EVENT,
+        EVENT_DISABLED,
+        EVENT_PUBLISH_TERMINATED,
+        EVENT_SUBSCRIBE_TERMINATED,
+        EVENT_MATCH,
+        EVENT_MATCH_EXPIRED,
+        EVENT_FOLLOWUP_RECEIVED,
+        EVENT_TRANSMIT_FOLLOWUP,
+        EVENT_DATA_PATH_REQUEST,
+        EVENT_DATA_PATH_CONFIRM,
+        EVENT_DATA_PATH_TERMINATED,
+        EVENT_DATA_PATH_SCHEDULE_UPDATE,
+        EVENT_PAIRING_REQUEST,
+        EVENT_PAIRING_CONFIRM,
+        EVENT_BOOTSTRAPPING_REQUEST,
+        EVENT_BOOTSTRAPPING_CONFIRM,
+        EVENT_SUSPENSION_MODE_CHANGE,
+    };
+
+    // Used as a mechanism to inform the test about data/event callbacks.
+    inline void notify(CallbackType callbackType) {
+        std::unique_lock<std::mutex> lock(mtx_);
+        callback_event_bitmap_ |= (UINT64_C(0x1) << callbackType);
+        cv_.notify_one();
+    }
+
+    // Test code calls this function to wait for data/event callback.
+    // Must set callback_event_bitmap_ to 0 before calling this function.
+    inline std::cv_status wait(CallbackType waitForCallbackType) {
+        std::unique_lock<std::mutex> lock(mtx_);
+        EXPECT_NE(INVALID, waitForCallbackType);
+
+        std::cv_status status = std::cv_status::no_timeout;
+        auto now = std::chrono::system_clock::now();
+        while (!(receivedCallback(waitForCallbackType))) {
+            status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+            if (status == std::cv_status::timeout) return status;
+        }
+        return status;
+    }
+
+    inline bool receivedCallback(CallbackType waitForCallbackType) {
+        return callback_event_bitmap_ & (UINT64_C(0x1) << waitForCallbackType);
+    }
+
+    class WifiNanIfaceEventCallback : public BnWifiNanIfaceEventCallback {
+      public:
+        WifiNanIfaceEventCallback(WifiNanIfaceAidlTest& parent) : parent_(parent){};
+
+        ::ndk::ScopedAStatus eventClusterEvent(const NanClusterEventInd& event) override {
+            parent_.nan_cluster_event_ind_ = event;
+            parent_.notify(EVENT_CLUSTER_EVENT);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventDataPathConfirm(const NanDataPathConfirmInd& event) override {
+            parent_.nan_data_path_confirm_ind_ = event;
+            parent_.notify(EVENT_DATA_PATH_CONFIRM);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventDataPathRequest(const NanDataPathRequestInd& event) override {
+            parent_.nan_data_path_request_ind_ = event;
+            parent_.notify(EVENT_DATA_PATH_REQUEST);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventDataPathScheduleUpdate(
+                const NanDataPathScheduleUpdateInd& event) override {
+            parent_.nan_data_path_schedule_update_ind_ = event;
+            parent_.notify(EVENT_DATA_PATH_SCHEDULE_UPDATE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventDataPathTerminated(int32_t ndpInstanceId) override {
+            parent_.ndp_instance_id_ = ndpInstanceId;
+            parent_.notify(EVENT_DATA_PATH_TERMINATED);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventDisabled(const NanStatus& status) override {
+            parent_.status_ = status;
+            parent_.notify(EVENT_DISABLED);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventFollowupReceived(const NanFollowupReceivedInd& event) override {
+            parent_.nan_followup_received_ind_ = event;
+            parent_.notify(EVENT_FOLLOWUP_RECEIVED);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventMatch(const NanMatchInd& event) override {
+            parent_.nan_match_ind_ = event;
+            parent_.notify(EVENT_MATCH);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventMatchExpired(int8_t discoverySessionId, int32_t peerId) override {
+            parent_.session_id_ = discoverySessionId;
+            parent_.peer_id_ = peerId;
+            parent_.notify(EVENT_MATCH_EXPIRED);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventPublishTerminated(int8_t sessionId,
+                                                    const NanStatus& status) override {
+            parent_.session_id_ = sessionId;
+            parent_.status_ = status;
+            parent_.notify(EVENT_PUBLISH_TERMINATED);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventSubscribeTerminated(int8_t sessionId,
+                                                      const NanStatus& status) override {
+            parent_.session_id_ = sessionId;
+            parent_.status_ = status;
+            parent_.notify(EVENT_SUBSCRIBE_TERMINATED);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventTransmitFollowup(char16_t id, const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(EVENT_TRANSMIT_FOLLOWUP);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventPairingConfirm(const NanPairingConfirmInd& event) override {
+            parent_.nan_pairing_confirm_ind_ = event;
+            parent_.notify(EVENT_PAIRING_CONFIRM);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventPairingRequest(const NanPairingRequestInd& event) override {
+            parent_.nan_pairing_request_ind_ = event;
+            parent_.notify(EVENT_PAIRING_REQUEST);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventBootstrappingConfirm(
+                const NanBootstrappingConfirmInd& event) override {
+            parent_.nan_bootstrapping_confirm_ind_ = event;
+            parent_.notify(EVENT_BOOTSTRAPPING_CONFIRM);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventBootstrappingRequest(
+                const NanBootstrappingRequestInd& event) override {
+            parent_.nan_bootstrapping_request_ind_ = event;
+            parent_.notify(EVENT_BOOTSTRAPPING_REQUEST);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus eventSuspensionModeChanged(
+                const NanSuspensionModeChangeInd& event) override {
+            parent_.nan_suspension_mode_change_ind_ = event;
+            parent_.notify(EVENT_SUSPENSION_MODE_CHANGE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyCapabilitiesResponse(
+                char16_t id, const NanStatus& status,
+                const NanCapabilities& capabilities) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.capabilities_ = capabilities;
+            parent_.notify(NOTIFY_CAPABILITIES_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyConfigResponse(char16_t id, const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_CONFIG_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyCreateDataInterfaceResponse(char16_t id,
+                                                               const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_CREATE_DATA_INTERFACE_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyDeleteDataInterfaceResponse(char16_t id,
+                                                               const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_DELETE_DATA_INTERFACE_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyDisableResponse(char16_t id, const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_DISABLE_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyEnableResponse(char16_t id, const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_ENABLE_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyInitiateDataPathResponse(char16_t id, const NanStatus& status,
+                                                            int32_t ndpInstanceId) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.ndp_instance_id_ = ndpInstanceId;
+            parent_.notify(NOTIFY_INITIATE_DATA_PATH_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyRespondToDataPathIndicationResponse(
+                char16_t id, const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyStartPublishResponse(char16_t id, const NanStatus& status,
+                                                        int8_t sessionId) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.session_id_ = sessionId;
+            parent_.notify(NOTIFY_START_PUBLISH_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyStartSubscribeResponse(char16_t id, const NanStatus& status,
+                                                          int8_t sessionId) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.session_id_ = sessionId;
+            parent_.notify(NOTIFY_START_SUBSCRIBE_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyStopPublishResponse(char16_t id,
+                                                       const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_STOP_PUBLISH_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyStopSubscribeResponse(char16_t id,
+                                                         const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_STOP_SUBSCRIBE_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyTerminateDataPathResponse(char16_t id,
+                                                             const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_TERMINATE_DATA_PATH_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifySuspendResponse(char16_t id, const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_SUSPEND_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyResumeResponse(char16_t id, const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_RESUME_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyTransmitFollowupResponse(char16_t id,
+                                                            const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyInitiatePairingResponse(char16_t id, const NanStatus& status,
+                                                           int32_t pairingInstanceId) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.pairing_instance_id_ = pairingInstanceId;
+            parent_.notify(NOTIFY_INITIATE_PAIRING_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyRespondToPairingIndicationResponse(
+                char16_t id, const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_RESPOND_TO_PAIRING_INDICATION_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyInitiateBootstrappingResponse(
+                char16_t id, const NanStatus& status, int32_t bootstrapppingInstanceId) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.bootstrappping_instance_id_ = bootstrapppingInstanceId;
+            parent_.notify(NOTIFY_INITIATE_BOOTSTRAPPING_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyRespondToBootstrappingIndicationResponse(
+                char16_t id, const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_RESPOND_TO_BOOTSTRAPPING_INDICATION_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+        ::ndk::ScopedAStatus notifyTerminatePairingResponse(char16_t id,
+                                                            const NanStatus& status) override {
+            parent_.id_ = id;
+            parent_.status_ = status;
+            parent_.notify(NOTIFY_TERMINATE_PAIRING_RESPONSE);
+            return ndk::ScopedAStatus::ok();
+        }
+
+      private:
+        WifiNanIfaceAidlTest& parent_;
+    };
+
+  protected:
+    std::shared_ptr<IWifiNanIface> wifi_nan_iface_;
+    uint64_t callback_event_bitmap_;
+    uint16_t id_;
+    uint8_t session_id_;
+    uint32_t ndp_instance_id_;
+    uint32_t pairing_instance_id_;
+    uint32_t bootstrappping_instance_id_;
+    uint32_t peer_id_;
+    NanCapabilities capabilities_;
+    NanClusterEventInd nan_cluster_event_ind_;
+    NanDataPathConfirmInd nan_data_path_confirm_ind_;
+    NanDataPathRequestInd nan_data_path_request_ind_;
+    NanDataPathScheduleUpdateInd nan_data_path_schedule_update_ind_;
+    NanFollowupReceivedInd nan_followup_received_ind_;
+    NanMatchInd nan_match_ind_;
+    NanStatus status_;
+    NanPairingRequestInd nan_pairing_request_ind_;
+    NanPairingConfirmInd nan_pairing_confirm_ind_;
+    NanBootstrappingRequestInd nan_bootstrapping_request_ind_;
+    NanBootstrappingConfirmInd nan_bootstrapping_confirm_ind_;
+    NanSuspensionModeChangeInd nan_suspension_mode_change_ind_;
+
+    const char* getInstanceName() { return GetParam().c_str(); }
+
+  private:
+    // synchronization objects
+    std::mutex mtx_;
+    std::condition_variable cv_;
+};
+
+/*
+ * FailOnIfaceInvalid
+ * Ensure that API calls to an interface fail with code ERROR_WIFI_IFACE_INVALID
+ * after wifi is disabled.
+ */
+TEST_P(WifiNanIfaceAidlTest, FailOnIfaceInvalid) {
+    stopWifiService(getInstanceName());
+    sleep(5);  // Ensure that all chips/interfaces are invalidated.
+    auto status = wifi_nan_iface_->getCapabilitiesRequest(0);
+    ASSERT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_WIFI_IFACE_INVALID));
+}
+
+/*
+ * EnableRequest - Invalid Args
+ */
+TEST_P(WifiNanIfaceAidlTest, EnableRequest_InvalidArgs) {
+    uint16_t inputCmdId = 10;
+    callback_event_bitmap_ = 0;
+    NanEnableRequest nanEnableRequest = {};
+    NanConfigRequestSupplemental nanConfigRequestSupp = {};
+    auto status =
+            wifi_nan_iface_->enableRequest(inputCmdId, nanEnableRequest, nanConfigRequestSupp);
+    if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        ASSERT_TRUE(status.isOk());
+
+        // Wait for a callback.
+        ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
+        ASSERT_TRUE(receivedCallback(NOTIFY_ENABLE_RESPONSE));
+        ASSERT_EQ(id_, inputCmdId);
+        ASSERT_EQ(status_.status, NanStatusCode::INVALID_ARGS);
+    }
+}
+
+/*
+ * ConfigRequest - Invalid Args
+ */
+TEST_P(WifiNanIfaceAidlTest, ConfigRequest_InvalidArgs) {
+    uint16_t inputCmdId = 10;
+    callback_event_bitmap_ = 0;
+    NanConfigRequest nanConfigRequest = {};
+    NanConfigRequestSupplemental nanConfigRequestSupp = {};
+    auto status =
+            wifi_nan_iface_->configRequest(inputCmdId, nanConfigRequest, nanConfigRequestSupp);
+
+    if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        ASSERT_TRUE(status.isOk());
+
+        // Wait for a callback.
+        ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
+        ASSERT_TRUE(receivedCallback(NOTIFY_CONFIG_RESPONSE));
+        ASSERT_EQ(id_, inputCmdId);
+        ASSERT_EQ(status_.status, NanStatusCode::INVALID_ARGS);
+    }
+}
+
+/*
+ * EnableRequest - Invalid Args in Shim Conversion
+ */
+TEST_P(WifiNanIfaceAidlTest, EnableRequest_InvalidShimArgs) {
+    uint16_t inputCmdId = 10;
+    NanEnableRequest nanEnableRequest = {};
+    nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon = -15;  // must be > 0
+    NanConfigRequestSupplemental nanConfigRequestSupp = {};
+    auto status =
+            wifi_nan_iface_->enableRequest(inputCmdId, nanEnableRequest, nanConfigRequestSupp);
+    if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        ASSERT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    }
+}
+
+/*
+ * ConfigRequest - Invalid Args in Shim Conversion
+ */
+TEST_P(WifiNanIfaceAidlTest, ConfigRequest_InvalidShimArgs) {
+    uint16_t inputCmdId = 10;
+    NanConfigRequest nanConfigRequest = {};
+    nanConfigRequest.numberOfPublishServiceIdsInBeacon = -15;  // must be > 0
+    NanConfigRequestSupplemental nanConfigRequestSupp = {};
+    auto status =
+            wifi_nan_iface_->configRequest(inputCmdId, nanConfigRequest, nanConfigRequestSupp);
+    if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        ASSERT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+    }
+}
+
+/*
+ * NotifyCapabilitiesResponse
+ */
+TEST_P(WifiNanIfaceAidlTest, NotifyCapabilitiesResponse) {
+    uint16_t inputCmdId = 10;
+    callback_event_bitmap_ = 0;
+    EXPECT_TRUE(wifi_nan_iface_->getCapabilitiesRequest(inputCmdId).isOk());
+
+    // Wait for a callback.
+    ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CAPABILITIES_RESPONSE));
+    ASSERT_TRUE(receivedCallback(NOTIFY_CAPABILITIES_RESPONSE));
+    ASSERT_EQ(id_, inputCmdId);
+    ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
+
+    // Check for reasonable capability values.
+    EXPECT_GT(capabilities_.maxConcurrentClusters, 0);
+    EXPECT_GT(capabilities_.maxPublishes, 0);
+    EXPECT_GT(capabilities_.maxSubscribes, 0);
+    EXPECT_EQ(capabilities_.maxServiceNameLen, 255);
+    EXPECT_EQ(capabilities_.maxMatchFilterLen, 255);
+    EXPECT_GT(capabilities_.maxTotalMatchFilterLen, 255);
+    EXPECT_EQ(capabilities_.maxServiceSpecificInfoLen, 255);
+    EXPECT_GE(capabilities_.maxExtendedServiceSpecificInfoLen, 255);
+    EXPECT_GT(capabilities_.maxNdiInterfaces, 0);
+    EXPECT_GT(capabilities_.maxNdpSessions, 0);
+    EXPECT_GT(capabilities_.maxAppInfoLen, 0);
+    EXPECT_GT(capabilities_.maxQueuedTransmitFollowupMsgs, 0);
+    EXPECT_GT(capabilities_.maxSubscribeInterfaceAddresses, 0);
+    EXPECT_NE(static_cast<int32_t>(capabilities_.supportedCipherSuites), 0);
+}
+
+/*
+ * StartPublishRequest
+ */
+TEST_P(WifiNanIfaceAidlTest, StartPublishRequest) {
+    uint16_t inputCmdId = 10;
+    NanBandSpecificConfig config24 = {};
+    config24.rssiClose = 60;
+    config24.rssiMiddle = 70;
+    config24.rssiCloseProximity = 60;
+    config24.dwellTimeMs = 200;
+    config24.scanPeriodSec = 20;
+    config24.validDiscoveryWindowIntervalVal = false;
+    config24.discoveryWindowIntervalVal = 0;
+
+    NanBandSpecificConfig config5 = {};
+    config5.rssiClose = 60;
+    config5.rssiMiddle = 75;
+    config5.rssiCloseProximity = 60;
+    config5.dwellTimeMs = 200;
+    config5.scanPeriodSec = 20;
+    config5.validDiscoveryWindowIntervalVal = false;
+    config5.discoveryWindowIntervalVal = 0;
+
+    NanEnableRequest req = {};
+    req.operateInBand[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = true;
+    req.operateInBand[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = false;
+    req.hopCountMax = 2;
+    req.configParams.masterPref = 0;
+    req.configParams.disableDiscoveryAddressChangeIndication = true;
+    req.configParams.disableStartedClusterIndication = true;
+    req.configParams.disableJoinedClusterIndication = true;
+    req.configParams.includePublishServiceIdsInBeacon = true;
+    req.configParams.numberOfPublishServiceIdsInBeacon = 0;
+    req.configParams.includeSubscribeServiceIdsInBeacon = true;
+    req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
+    req.configParams.rssiWindowSize = 8;
+    req.configParams.macAddressRandomizationIntervalSec = 1800;
+    req.configParams.bandSpecificConfig[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] =
+            config24;
+    req.configParams.bandSpecificConfig[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] =
+            config5;
+
+    req.debugConfigs.validClusterIdVals = true;
+    req.debugConfigs.clusterIdTopRangeVal = 65535;
+    req.debugConfigs.clusterIdBottomRangeVal = 0;
+    req.debugConfigs.validIntfAddrVal = false;
+    req.debugConfigs.validOuiVal = false;
+    req.debugConfigs.ouiVal = 0;
+    req.debugConfigs.validRandomFactorForceVal = false;
+    req.debugConfigs.randomFactorForceVal = 0;
+    req.debugConfigs.validHopCountForceVal = false;
+    req.debugConfigs.hopCountForceVal = 0;
+    req.debugConfigs.validDiscoveryChannelVal = false;
+    req.debugConfigs.discoveryChannelMhzVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = 0;
+    req.debugConfigs.discoveryChannelMhzVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = 0;
+    req.debugConfigs.validUseBeaconsInBandVal = false;
+    req.debugConfigs.useBeaconsInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = true;
+    req.debugConfigs.useBeaconsInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = true;
+    req.debugConfigs.validUseSdfInBandVal = false;
+    req.debugConfigs.useSdfInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = true;
+    req.debugConfigs.useSdfInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = true;
+
+    NanConfigRequestSupplemental nanConfigRequestSupp = {};
+    nanConfigRequestSupp.discoveryBeaconIntervalMs = 20;
+    nanConfigRequestSupp.numberOfSpatialStreamsInDiscovery = 0;
+    nanConfigRequestSupp.enableDiscoveryWindowEarlyTermination = false;
+
+    callback_event_bitmap_ = 0;
+    auto status = wifi_nan_iface_->enableRequest(inputCmdId, req, nanConfigRequestSupp);
+    if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        ASSERT_TRUE(status.isOk());
+
+        // Wait for a callback.
+        ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
+        ASSERT_TRUE(receivedCallback(NOTIFY_ENABLE_RESPONSE));
+        ASSERT_EQ(id_, inputCmdId);
+        ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
+    }
+
+    NanPublishRequest nanPublishRequest = {};
+    nanPublishRequest.baseConfigs.sessionId = 0;
+    nanPublishRequest.baseConfigs.ttlSec = 0;
+    nanPublishRequest.baseConfigs.discoveryWindowPeriod = 1;
+    nanPublishRequest.baseConfigs.discoveryCount = 0;
+    nanPublishRequest.baseConfigs.serviceName = {97};
+    nanPublishRequest.baseConfigs.discoveryMatchIndicator = NanMatchAlg::MATCH_NEVER;
+    nanPublishRequest.baseConfigs.useRssiThreshold = false;
+    nanPublishRequest.baseConfigs.disableDiscoveryTerminationIndication = false;
+    nanPublishRequest.baseConfigs.disableMatchExpirationIndication = true;
+    nanPublishRequest.baseConfigs.disableFollowupReceivedIndication = false;
+    nanPublishRequest.baseConfigs.securityConfig.securityType = NanDataPathSecurityType::OPEN;
+    nanPublishRequest.autoAcceptDataPathRequests = false;
+    nanPublishRequest.publishType = NanPublishType::UNSOLICITED;
+    nanPublishRequest.txType = NanTxType::BROADCAST;
+
+    status = wifi_nan_iface_->startPublishRequest(inputCmdId + 1, nanPublishRequest);
+    if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        ASSERT_TRUE(status.isOk());
+
+        // Wait for a callback.
+        ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_START_PUBLISH_RESPONSE));
+        ASSERT_TRUE(receivedCallback(NOTIFY_START_PUBLISH_RESPONSE));
+        ASSERT_EQ(id_, inputCmdId + 1);
+        ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
+    }
+}
+
+/*
+ * RespondToDataPathIndicationRequest - Invalid Args
+ */
+TEST_P(WifiNanIfaceAidlTest, RespondToDataPathIndicationRequest_InvalidArgs) {
+    uint16_t inputCmdId = 10;
+    callback_event_bitmap_ = 0;
+    NanRespondToDataPathIndicationRequest nanRespondToDataPathIndicationRequest = {};
+    nanRespondToDataPathIndicationRequest.ifaceName = "AwareInterfaceNameTooLong";
+    auto status = wifi_nan_iface_->respondToDataPathIndicationRequest(
+            inputCmdId, nanRespondToDataPathIndicationRequest);
+
+    if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        ASSERT_EQ(status.getServiceSpecificError(),
+                  static_cast<int32_t>(WifiStatusCode::ERROR_INVALID_ARGS));
+    }
+}
+
+/*
+ * InitiateDataPathRequest - Invalid Args
+ */
+TEST_P(WifiNanIfaceAidlTest, InitiateDataPathRequest_InvalidArgs) {
+    uint16_t inputCmdId = 10;
+    callback_event_bitmap_ = 0;
+    NanInitiateDataPathRequest nanInitiateDataPathRequest = {};
+    nanInitiateDataPathRequest.ifaceName = "AwareInterfaceNameTooLong";
+    auto status = wifi_nan_iface_->initiateDataPathRequest(inputCmdId, nanInitiateDataPathRequest);
+
+    if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        ASSERT_EQ(status.getServiceSpecificError(),
+                  static_cast<int32_t>(WifiStatusCode::ERROR_INVALID_ARGS));
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiNanIfaceAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    android::ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp
new file mode 100644
index 0000000..4aedc0e
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <aidl/android/hardware/wifi/BnWifiRttControllerEventCallback.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::BnWifiRttControllerEventCallback;
+using aidl::android::hardware::wifi::IWifiRttController;
+using aidl::android::hardware::wifi::RttBw;
+using aidl::android::hardware::wifi::RttCapabilities;
+using aidl::android::hardware::wifi::RttConfig;
+using aidl::android::hardware::wifi::RttPeerType;
+using aidl::android::hardware::wifi::RttPreamble;
+using aidl::android::hardware::wifi::RttResponder;
+using aidl::android::hardware::wifi::RttResult;
+using aidl::android::hardware::wifi::RttType;
+using aidl::android::hardware::wifi::WifiChannelInfo;
+using aidl::android::hardware::wifi::WifiChannelWidthInMhz;
+using aidl::android::hardware::wifi::WifiStatusCode;
+
+class WifiRttControllerAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        if (!::testing::deviceSupportsFeature("android.hardware.wifi.rtt"))
+            GTEST_SKIP() << "Skipping this test since RTT is not supported.";
+        stopWifiService(getInstanceName());
+        wifi_rtt_controller_ = getWifiRttController();
+        ASSERT_NE(nullptr, wifi_rtt_controller_.get());
+
+        // Check RTT support before we run the test.
+        RttCapabilities caps = {};
+        auto status = wifi_rtt_controller_->getCapabilities(&caps);
+        if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+            GTEST_SKIP() << "Skipping this test since RTT is not supported.";
+        }
+    }
+
+    void TearDown() override { stopWifiService(getInstanceName()); }
+
+  protected:
+    std::shared_ptr<IWifiRttController> getWifiRttController() {
+        std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
+        EXPECT_NE(nullptr, wifi_chip.get());
+
+        std::shared_ptr<IWifiStaIface> wifi_sta_iface = getWifiStaIface(getInstanceName());
+        EXPECT_NE(nullptr, wifi_sta_iface.get());
+
+        std::shared_ptr<IWifiRttController> rtt_controller;
+        EXPECT_TRUE(wifi_chip->createRttController(wifi_sta_iface, &rtt_controller).isOk());
+        EXPECT_NE(nullptr, rtt_controller.get());
+        return rtt_controller;
+    }
+
+    RttCapabilities getCapabilities() {
+        RttCapabilities caps = {};
+        EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk());
+        return caps;
+    }
+
+    std::shared_ptr<IWifiRttController> wifi_rtt_controller_;
+
+  private:
+    const char* getInstanceName() { return GetParam().c_str(); }
+};
+
+class WifiRttControllerEventCallback : public BnWifiRttControllerEventCallback {
+  public:
+    WifiRttControllerEventCallback() = default;
+
+    ::ndk::ScopedAStatus onResults(int /* cmdId */,
+                                   const std::vector<RttResult>& /* results */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
+/*
+ * RegisterEventCallback
+ *
+ * Note: it is not feasible to test the invocation of the callback function,
+ * since events are triggered internally in the HAL implementation and cannot be
+ * triggered from the test case.
+ */
+TEST_P(WifiRttControllerAidlTest, RegisterEventCallback) {
+    std::shared_ptr<WifiRttControllerEventCallback> callback =
+            ndk::SharedRefBase::make<WifiRttControllerEventCallback>();
+    ASSERT_NE(nullptr, callback.get());
+    EXPECT_TRUE(wifi_rtt_controller_->registerEventCallback(callback).isOk());
+}
+
+/*
+ * GetCapabilities
+ */
+TEST_P(WifiRttControllerAidlTest, GetCapabilities) {
+    RttCapabilities caps = {};
+    EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk());
+}
+
+/*
+ * GetResponderInfo
+ */
+TEST_P(WifiRttControllerAidlTest, GetResponderInfo) {
+    RttCapabilities caps = getCapabilities();
+    if (!caps.responderSupported) {
+        GTEST_SKIP() << "Skipping because responder is not supported";
+    }
+
+    RttResponder responder = {};
+    EXPECT_TRUE(wifi_rtt_controller_->getResponderInfo(&responder).isOk());
+}
+
+/*
+ * EnableResponder
+ */
+TEST_P(WifiRttControllerAidlTest, EnableResponder) {
+    RttCapabilities caps = getCapabilities();
+    if (!caps.responderSupported) {
+        GTEST_SKIP() << "Skipping because responder is not supported";
+    }
+
+    int cmdId = 55;
+    WifiChannelInfo channelInfo;
+    channelInfo.width = WifiChannelWidthInMhz::WIDTH_80;
+    channelInfo.centerFreq = 5660;
+    channelInfo.centerFreq0 = 5660;
+    channelInfo.centerFreq1 = 0;
+
+    RttResponder responder = {};
+    EXPECT_TRUE(wifi_rtt_controller_->getResponderInfo(&responder).isOk());
+    EXPECT_TRUE(wifi_rtt_controller_->enableResponder(cmdId, channelInfo, 10, responder).isOk());
+}
+
+/*
+ * Request2SidedRangeMeasurement
+ * Tests the two sided ranging - 802.11mc FTM protocol.
+ */
+TEST_P(WifiRttControllerAidlTest, Request2SidedRangeMeasurement) {
+    RttCapabilities caps = getCapabilities();
+    if (!caps.rttFtmSupported) {
+        GTEST_SKIP() << "Skipping two sided RTT since driver/fw does not support";
+    }
+
+    RttConfig config;
+    config.addr = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}};
+    config.type = RttType::TWO_SIDED;
+    config.peer = RttPeerType::AP;
+    config.channel.width = WifiChannelWidthInMhz::WIDTH_80;
+    config.channel.centerFreq = 5180;
+    config.channel.centerFreq0 = 5210;
+    config.channel.centerFreq1 = 0;
+    config.bw = RttBw::BW_20MHZ;
+    config.preamble = RttPreamble::HT;
+    config.mustRequestLci = false;
+    config.mustRequestLcr = false;
+    config.burstPeriod = 0;
+    config.numBurst = 0;
+    config.numFramesPerBurst = 8;
+    config.numRetriesPerRttFrame = 0;
+    config.numRetriesPerFtmr = 0;
+    config.burstDuration = 9;
+
+    int cmdId = 55;
+    std::vector<RttConfig> configs = {config};
+    EXPECT_TRUE(wifi_rtt_controller_->rangeRequest(cmdId, configs).isOk());
+
+    // Sleep for 2 seconds to wait for driver/firmware to complete RTT.
+    sleep(2);
+}
+
+/*
+ * RangeRequest
+ */
+TEST_P(WifiRttControllerAidlTest, RangeRequest) {
+    RttCapabilities caps = getCapabilities();
+    if (!caps.rttOneSidedSupported) {
+        GTEST_SKIP() << "Skipping one sided RTT since driver/fw does not support";
+    }
+
+    // Get the highest supported preamble.
+    int preamble = 1;
+    int caps_preamble_support = static_cast<int>(caps.preambleSupport);
+    caps_preamble_support >>= 1;
+    while (caps_preamble_support != 0) {
+        caps_preamble_support >>= 1;
+        preamble <<= 1;
+    }
+
+    RttConfig config;
+    config.addr = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}};
+    config.type = RttType::ONE_SIDED;
+    config.peer = RttPeerType::AP;
+    config.channel.width = WifiChannelWidthInMhz::WIDTH_80;
+    config.channel.centerFreq = 5765;
+    config.channel.centerFreq0 = 5775;
+    config.channel.centerFreq1 = 0;
+    config.bw = RttBw::BW_80MHZ;
+    config.preamble = static_cast<RttPreamble>(preamble);
+    config.mustRequestLci = false;
+    config.mustRequestLcr = false;
+    config.burstPeriod = 0;
+    config.numBurst = 0;
+    config.numFramesPerBurst = 8;
+    config.numRetriesPerRttFrame = 3;
+    config.numRetriesPerFtmr = 3;
+    config.burstDuration = 9;
+
+    int cmdId = 55;
+    std::vector<RttConfig> configs = {config};
+    EXPECT_TRUE(wifi_rtt_controller_->rangeRequest(cmdId, configs).isOk());
+
+    // Sleep for 2 seconds to wait for driver/firmware to complete RTT.
+    sleep(2);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiRttControllerAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiRttControllerAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    android::ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
new file mode 100644
index 0000000..fa7149f
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <cctype>
+#include <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cutils/properties.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::IWifi;
+using aidl::android::hardware::wifi::IWifiStaIface;
+using aidl::android::hardware::wifi::MacAddress;
+using aidl::android::hardware::wifi::Ssid;
+using aidl::android::hardware::wifi::StaApfPacketFilterCapabilities;
+using aidl::android::hardware::wifi::StaBackgroundScanCapabilities;
+using aidl::android::hardware::wifi::StaLinkLayerStats;
+using aidl::android::hardware::wifi::StaRoamingCapabilities;
+using aidl::android::hardware::wifi::StaRoamingConfig;
+using aidl::android::hardware::wifi::StaRoamingState;
+using aidl::android::hardware::wifi::WifiBand;
+using aidl::android::hardware::wifi::WifiDebugRxPacketFateReport;
+using aidl::android::hardware::wifi::WifiDebugTxPacketFateReport;
+using aidl::android::hardware::wifi::WifiStatusCode;
+
+class WifiStaIfaceAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    void SetUp() override {
+        stopWifiService(getInstanceName());
+        wifi_sta_iface_ = getWifiStaIface(getInstanceName());
+        ASSERT_NE(nullptr, wifi_sta_iface_.get());
+    }
+
+    void TearDown() override { stopWifiService(getInstanceName()); }
+
+  protected:
+    bool isFeatureSupported(IWifiStaIface::FeatureSetMask expected) {
+        int32_t features = 0;
+        EXPECT_TRUE(wifi_sta_iface_->getFeatureSet(&features).isOk());
+        return features & static_cast<int32_t>(expected);
+    }
+
+    ndk::ScopedAStatus createStaIface(std::shared_ptr<IWifiStaIface>* sta_iface) {
+        std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
+        EXPECT_NE(nullptr, wifi_chip.get());
+        return wifi_chip->createStaIface(sta_iface);
+    }
+
+    std::shared_ptr<IWifiStaIface> wifi_sta_iface_;
+
+    // Checks if the mDNS Offload is supported by any NIC.
+    bool isMdnsOffloadPresentInNIC() {
+        return testing::deviceSupportsFeature("com.google.android.tv.mdns_offload");
+    }
+
+    // Detected panel TV device by using ro.oem.key1 property.
+    // https://docs.partner.android.com/tv/build/platform/props-vars/ro-oem-key1
+    bool isPanelTvDevice() {
+        const std::string oem_key1 = getPropertyString("ro.oem.key1");
+        if (oem_key1.size() < 9) {
+            return false;
+        }
+        if (oem_key1.substr(0, 3) != "ATV") {
+            return false;
+        }
+        const std::string psz_string = oem_key1.substr(6, 3);
+        // If PSZ string contains non digit, then it is not a panel TV device.
+        for (char ch : psz_string) {
+            if (!isdigit(ch)) {
+                return false;
+            }
+        }
+        // If PSZ is "000", then it is not a panel TV device.
+        if (psz_string == "000") {
+            return false;
+        }
+        return true;
+    }
+
+    std::string getPropertyString(const char* property_name) {
+        char property_string_raw_bytes[PROPERTY_VALUE_MAX] = {};
+        int len = property_get(property_name, property_string_raw_bytes, "");
+        return std::string(property_string_raw_bytes, len);
+    }
+
+  private:
+    const char* getInstanceName() { return GetParam().c_str(); }
+};
+
+/*
+ * GetFactoryMacAddress
+ * Ensures that calls to getFactoryMacAddress will retrieve a non-zero MAC.
+ */
+TEST_P(WifiStaIfaceAidlTest, GetFactoryMacAddress) {
+    std::array<uint8_t, 6> mac;
+    EXPECT_TRUE(wifi_sta_iface_->getFactoryMacAddress(&mac).isOk());
+    std::array<uint8_t, 6> all_zero_mac = {0, 0, 0, 0, 0, 0};
+    EXPECT_NE(mac, all_zero_mac);
+}
+
+/*
+ * GetFeatureSet
+ */
+TEST_P(WifiStaIfaceAidlTest, GetFeatureSet) {
+    int32_t features = 0;
+    EXPECT_TRUE(wifi_sta_iface_->getFeatureSet(&features).isOk());
+    EXPECT_NE(features, 0);
+}
+
+/*
+ * CheckApfIsSupported:
+ * Ensures the APF packet filter is fully supported as required in VSR 14:
+ * https://docs.partner.android.com/gms/policies/vsr/vsr-14
+ */
+// @VsrTest = 5.3.12
+TEST_P(WifiStaIfaceAidlTest, CheckApfIsSupported) {
+    // Flat panel TV devices that support MDNS offload do not have to implement APF if the WiFi
+    // chipset does not have sufficient RAM to do so.
+    if (isPanelTvDevice() && isMdnsOffloadPresentInNIC()) {
+        GTEST_SKIP() << "Panel TV supports mDNS offload. It is not required to support APF";
+    }
+    int vendor_api_level = property_get_int32("ro.vendor.api_level", 0);
+    // Before VSR 14, APF support is optional.
+    if (vendor_api_level < __ANDROID_API_U__) {
+        if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::APF)) {
+            GTEST_SKIP() << "APF packet filter capabilities are not supported.";
+        }
+        StaApfPacketFilterCapabilities apf_caps = {};
+        EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
+    } else {
+        EXPECT_TRUE(isFeatureSupported(IWifiStaIface::FeatureSetMask::APF));
+        StaApfPacketFilterCapabilities apf_caps = {};
+        EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
+        // The APF version must be 4 and the usable memory must be at least
+        // 1024 bytes.
+        EXPECT_EQ(apf_caps.version, 4);
+        EXPECT_GE(apf_caps.maxLength, 1024);
+    }
+}
+
+/*
+ * GetBackgroundScanCapabilities
+ */
+TEST_P(WifiStaIfaceAidlTest, GetBackgroundScanCapabilities) {
+    if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::BACKGROUND_SCAN)) {
+        GTEST_SKIP() << "Background scan capabilities are not supported.";
+    }
+    StaBackgroundScanCapabilities caps = {};
+    EXPECT_TRUE(wifi_sta_iface_->getBackgroundScanCapabilities(&caps).isOk());
+}
+
+/*
+ * GetLinkLayerStats
+ * Ensures that calls to getLinkLayerStats will retrieve a non-empty
+ * StaLinkLayerStats after link layer stats collection is enabled.
+ */
+TEST_P(WifiStaIfaceAidlTest, GetLinkLayerStats) {
+    if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS)) {
+        GTEST_SKIP() << "Skipping this test since link layer stats are not supported.";
+    }
+
+    // Enable link layer stats collection.
+    EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
+
+    // Retrieve link layer stats.
+    StaLinkLayerStats link_layer_stats = {};
+    EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
+    EXPECT_GT(link_layer_stats.timeStampInMs, 0);
+
+    // Try to create a 2nd iface. If successful, it should fill the duty cycle field.
+    std::shared_ptr<IWifiStaIface> iface;
+    auto status = createStaIface(&iface);
+    if (status.isOk()) {
+        EXPECT_GT(link_layer_stats.iface.links[0].timeSliceDutyCycleInPercent, 0);
+    }
+
+    // Disable link layer stats collection.
+    EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
+}
+
+/*
+ * SetMacAddress
+ * Ensures that calls to setMacAddress will return successfully.
+ */
+TEST_P(WifiStaIfaceAidlTest, SetMacAddress) {
+    std::array<uint8_t, 6> mac = {0x12, 0x22, 0x33, 0x52, 0x10, 0x41};
+    EXPECT_TRUE(wifi_sta_iface_->setMacAddress(mac).isOk());
+}
+
+/*
+ * SetScanMode
+ */
+TEST_P(WifiStaIfaceAidlTest, SetScanMode) {
+    auto status = wifi_sta_iface_->setScanMode(true);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+
+    status = wifi_sta_iface_->setScanMode(false);
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * LinkLayerStatsCollection
+ */
+TEST_P(WifiStaIfaceAidlTest, LinkLayerStatsCollection) {
+    if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS)) {
+        GTEST_SKIP() << "Link layer stats collection is not supported.";
+    }
+
+    // Enable link layer stats collection.
+    EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
+
+    // Retrieve link layer stats.
+    StaLinkLayerStats link_layer_stats = {};
+    EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
+
+    // Disable link layer stats collection.
+    EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
+}
+
+/*
+ * RSSIMonitoring
+ * Ensures that calls to startRssiMonitoring and stopRssiMonitoring will fail
+ * if the device is not connected to an AP.
+ */
+TEST_P(WifiStaIfaceAidlTest, RSSIMonitoring) {
+    if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::RSSI_MONITOR)) {
+        GTEST_SKIP() << "RSSI monitoring is not supported.";
+    }
+
+    const int cmd = 1;
+    const int maxRssi = -50;
+    const int minRssi = -90;
+    // Expected to fail because device is not connected to an AP.
+    EXPECT_FALSE(wifi_sta_iface_->startRssiMonitoring(cmd, maxRssi, minRssi).isOk());
+    EXPECT_FALSE(wifi_sta_iface_->stopRssiMonitoring(cmd).isOk());
+}
+
+/*
+ * RoamingControl
+ */
+TEST_P(WifiStaIfaceAidlTest, RoamingControl) {
+    if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::CONTROL_ROAMING)) {
+        GTEST_SKIP() << "Roaming control is not supported.";
+    }
+
+    // Retrieve roaming capabilities.
+    StaRoamingCapabilities caps = {};
+    EXPECT_TRUE(wifi_sta_iface_->getRoamingCapabilities(&caps).isOk());
+
+    // Set up roaming configuration based on roaming capabilities.
+    StaRoamingConfig roaming_config = {};
+    if (caps.maxBlocklistSize > 0) {
+        MacAddress block_list_entry;
+        block_list_entry.data = std::array<uint8_t, 6>{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}};
+        roaming_config.bssidBlocklist = {block_list_entry};
+    }
+    if (caps.maxAllowlistSize > 0) {
+        Ssid allow_list_entry = {};
+        allow_list_entry.data = std::array<uint8_t, 32>{{0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}};
+        roaming_config.ssidAllowlist = {allow_list_entry};
+    }
+
+    // Configure roaming.
+    EXPECT_TRUE(wifi_sta_iface_->configureRoaming(roaming_config).isOk());
+
+    // Enable roaming.
+    EXPECT_TRUE(wifi_sta_iface_->setRoamingState(StaRoamingState::ENABLED).isOk());
+}
+
+/*
+ * EnableNDOffload
+ */
+TEST_P(WifiStaIfaceAidlTest, EnableNDOffload) {
+    if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::ND_OFFLOAD)) {
+        GTEST_SKIP() << "ND offload is not supported.";
+    }
+    EXPECT_TRUE(wifi_sta_iface_->enableNdOffload(true).isOk());
+}
+
+/*
+ * PacketFateMonitoring
+ */
+TEST_P(WifiStaIfaceAidlTest, PacketFateMonitoring) {
+    // Start packet fate monitoring.
+    auto status = wifi_sta_iface_->startDebugPacketFateMonitoring();
+    EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+
+    // Retrieve packets.
+    if (status.isOk()) {
+        std::vector<WifiDebugRxPacketFateReport> rx_reports;
+        std::vector<WifiDebugTxPacketFateReport> tx_reports;
+        EXPECT_TRUE(wifi_sta_iface_->getDebugRxPacketFates(&rx_reports).isOk());
+        EXPECT_TRUE(wifi_sta_iface_->getDebugTxPacketFates(&tx_reports).isOk());
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiStaIfaceAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    android::ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/apex/Android.bp b/wifi/apex/Android.bp
new file mode 100644
index 0000000..f8ba5c4
--- /dev/null
+++ b/wifi/apex/Android.bp
@@ -0,0 +1,55 @@
+package {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex_key {
+    name: "com.android.hardware.wifi.key",
+    public_key: "com.android.hardware.wifi.avbpubkey",
+    private_key: "com.android.hardware.wifi.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.wifi.certificate",
+    certificate: "com.android.hardware.wifi",
+}
+
+genrule {
+    name: "gen-android.hardware.wifi.rc",
+    srcs: [":default-android.hardware.wifi-service.rc"],
+    out: ["com.android.hardware.wifi-service.rc"],
+    cmd: "sed -e 's@/vendor/bin/@/apex/com.android.hardware.wifi/bin/@' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "com.android.hardware.wifi.rc",
+    src: ":gen-android.hardware.wifi.rc",
+    installable: false,
+}
+
+prebuilt_etc {
+    name: "com.android.hardware.wifi.xml",
+    src: ":default-android.hardware.wifi-service.xml",
+    installable: false,
+    sub_dir: "vintf",
+}
+
+apex {
+    name: "com.android.hardware.wifi",
+    manifest: "apex_manifest.json",
+    key: "com.android.hardware.wifi.key",
+    certificate: ":com.android.hardware.wifi.certificate",
+    file_contexts: "file_contexts",
+    use_vndk_as_stable: true,
+    updatable: false,
+    soc_specific: true,
+    binaries: [
+        "android.hardware.wifi-service",
+    ],
+    prebuilts: [
+        "com.android.hardware.wifi.rc",
+        "com.android.hardware.wifi.xml",
+    ],
+    overrides: [
+        "android.hardware.wifi-service",
+    ],
+}
diff --git a/wifi/apex/apex_manifest.json b/wifi/apex/apex_manifest.json
new file mode 100644
index 0000000..cab0814
--- /dev/null
+++ b/wifi/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+    "name": "com.android.hardware.wifi",
+    "version": 1
+}
diff --git a/wifi/apex/com.android.hardware.wifi.avbpubkey b/wifi/apex/com.android.hardware.wifi.avbpubkey
new file mode 100644
index 0000000..63fba77
--- /dev/null
+++ b/wifi/apex/com.android.hardware.wifi.avbpubkey
Binary files differ
diff --git a/wifi/apex/com.android.hardware.wifi.pem b/wifi/apex/com.android.hardware.wifi.pem
new file mode 100644
index 0000000..9e589ac
--- /dev/null
+++ b/wifi/apex/com.android.hardware.wifi.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQCtT/vNnVVg2QVD
+eMdG+YZ8qYz/fbAQF9hnH8dE5RWHXzoYItBG7DSOuVT4T6POBVmFaVKlWDd7tDyw
+nFO3MmE2/FzhVSiBPwhMITa7UIERr3od3rWJ5g6oaTCOu4wa98L466Jp60f2fYSZ
+M9lGiKaDpLDSpxTU9hexjp7C4PfinnkYnlHBnrFXTmiO6f8AvOEwFFx73/rUNoe7
+F3TkGvjZDqHvE+pjz/nilkhXYuOl3zgSaeznJ9+TO5C/Z+Xr+zRhaJGI4v5Dkgmc
+jNy74+0hjwobXO3iWE44InQMvMh8zDKBx9l1oSsFoG3waj9ayqSYD7M74RX3PkUL
+QrhgAHZWi5iEnpu50xBzAqZB1ZDVkdZiKiGzweJ8OqltnVpvzlnW3rA3y3HtFyLm
+73C4ll9MdLaw266vBxgZfFOcjpphbbh9J9uGjOCJY1AxUzsqKygFD2CyOdb1jab3
+AC6VvRa+bLtv8fd2etp3atXv+Y9ACUX6zNK6Oa8Zktoo2Z//OLtcrk7xhgKKDkUF
+OPQrIjW9x0fdClDioIS+y7EHNUrfyRL7XPtUqGCszgz5jK2SMVGMpFaEtfbyNP1H
+BTGXdzcDP0RZdOOKTdBFgoRW5+6TH5CU9Nl4uevpxzwsTkXg0a+W1BGP+s9J7ssH
+rNPmHz+pbKZPDs/nxlpsKq+N+K8cCwIDAQABAoICAAJL943Lgnikl53DyXxGzUH0
+q0Itg7pK3prLQIRItubS2727JGB0O+QST650u7p8tql+clJvn1ib1FwQzkk0uTYV
+1RNFYiKIV89Od1+3GubFmQwxSd2Yd2RC9JpHoP0wgFx1HvNhY1RAaJPxLHVzVSWU
+dqVsAmoqErlPJwp1GcPejsNFQdcbh8Uc7GTMdA0p86AD/Q/FMZlDWbwgfPOS6e5S
+c9HrxSTqeijHDhFeZZ7qnN8dmT6c+CkG1o26zkC41QJfdOJIA8+YbVkuQrSYuilC
+MIOZUSu5ONwklL4geFWzDQ5MPDUDXEMYU6ymc817tv+u4ZSvEG/02sxh53iaOPc6
+C6im4nm6ZlRP9HzIvLAiRSbvwEb9cnLKgYpioSGXehDYg3zMPURwoqIxw+7IlIUh
+s+rhmCJV62PK1Z0nmo7m7S8r+z6j4G7aztGcbvdecocOJYOQB1VB8Zh4bNEIWp0a
+GDteG6aWXOCHoYRWAOluppDWa7Z+EgesU3Oj9Prn/ekUzzXx3V30zSTZYxRnQCO0
+vZIZ6hrlsNJcNrDpxmiWBaEOd4k5QI39pu6fDHc+UEEJMN+7eVk8d9QVA/LhrCjc
+JH1EVjtWosMUeMaMTpcmHTQKnEvmT2LO2fxGlF4JvjzDdVMloJrIP2LSQjovo2PX
+x9UXVu8Dt3kQRefZ42XxAoIBAQDkBoSYVajaFlyv9lW8oPmrQyzp93ite+TKVR8z
+PmcFQukjp5Gm8PGlGtGoH8aeE9Ev+R86aNPFy4n4ZJ7fmZYH1hxZ6dSc/56k6lLn
+uVKvTudYqwcRgBKuSZ8IDPFz3sHd+MnOBonDIri28fcBTDNv4LJP/6cAUoIOCCPm
+lQtJBfMNMDOXG4jv1Rv/1P5opGFATerRCubOxmeaFhZIDEjvN5WvLK5jmL7I8lX3
+X+gPiMHFWBQFmVTOHeVYEORDO5xFCOvHqCVB78b2xe1NkkrQ0CexpdflJVLE9IWt
+wWH43nhjxaK+eiBPrj37BliJvNaYfuxqcAj3p8c5KweFEtP7AoIBAQDCkx72K/Ja
+rFrrI0Avfo+3n6yoTMtMkiVhMuIKKPBJ2o4Opc/uixk+uLH5UH0X5GZsE51FAhUD
+L3bWMxV+vzVefWS8Iryo94ucvnfqhsN3KZXHDGoAuYv72jND8qPLKksM0dceMBfl
+aoyXSPAe8zAZeEx4iR2axgtnA0EbiXIaNVE/LF+WYdM74jvk/QtRzJ8IAAkSc5Rr
+GiTHeeP3nRnkjWjkmwKXYSJHcrEl26c/2ckeZORtblqxR9wMU5OgvJvMSzmOIpVH
+Y5lylZUOTuJCkApHFNKdRsawsSNKsy4yfY1byN/WkODb7le6Crt1gcwldMxDZAo9
+iB25FHq4zksxAoIBAQC+SBYkDO9PtnN4PycCto5B9VeokmN42bdthKT5nSxY/qIQ
+p8fquIvdzEiCdKnIxh69WrVNh6aZGyWySz0suDyzo1+bRH6w2LrpQcUXK9YtBroV
+ivrmBqsQF82G6U4f9BZxhifZLimN1g6wU7Bcu9r8lFQYX+1bXn66+N4EkAGP2VAe
+hEe45Dhccsjfrzzx06J4B81YzjEXAgf4VFAZpW7DeO4G9VE9OXyTsW49dSHwvJ1+
+ceabWX2kVtxIpiflVvwru6sNvGoC4PV2fmptXhPitqE5JHzJ8mBkjOx0t7hq9jMe
+hxEsxDrsYynDrWL65cNqFBhzJbTF/ZNJSHgI+1I7AoIBAQC7m0shJOJ61vCbA9Qh
+dzBvZn/9jn3/CHMOMxeLoEl/jEGokevZHzlqJn9D2n2jCdBPqOHc5dMIzT0R7xNs
+sERvJQx58ixh5r0wlt3cva++N9R4pdmXdVApuAvyGgQgIllWtQVr0AdaZs/EFsmf
+re/Uvw9MsThgQVBBNPwT5wSjjIEYHlrUDuKzPMFvWyUM6/Tyq8YTimmykvSfeUF7
+QHj0y/w1X9ixyTBaH5X64L10bTLkIXe2o87CXH0pTXRsaS73XhjSmTnCKaCMwPmF
+YD383BFs1AD3MITnXQSgQ//pIvGnbBmXMv38UOU5NpvlAw+pleJVoCHXjmTKTZq+
+kfohAoIBAQCrEecN8XEPjGdtY71rDYEwHGM6G4czHX0PNhlMjQos3aBVZ/YvVxPG
+pkXbms3GRXv4W92u7b2MwEKBPxcBepEdDZN9wSpe63bDFE6gpkipDhgj97JlLEUd
+s7h6oOoazdxmsRZyFho99SRQWrvyOiiKdLJCRZiqjUB4roOQmy7f9VAz6+OxyGV9
+XZigwW6bfUzMCmhx5Ss6zW8wZI+gINQh+2sDmiBiMQv14Ya5zlNYN+4/257Sk/jS
+o3QUDJITbReq/DNZ6UUzQS+AZ7ztc81rk5kRg0I33FZarRJ7TLAz+XmZZFoIOORz
+etEvMk8bJ4u7X89NWW/i2J+kQiDQg819
+-----END PRIVATE KEY-----
diff --git a/wifi/apex/com.android.hardware.wifi.pk8 b/wifi/apex/com.android.hardware.wifi.pk8
new file mode 100644
index 0000000..f4481bf
--- /dev/null
+++ b/wifi/apex/com.android.hardware.wifi.pk8
Binary files differ
diff --git a/wifi/apex/com.android.hardware.wifi.x509.pem b/wifi/apex/com.android.hardware.wifi.x509.pem
new file mode 100644
index 0000000..c942e71
--- /dev/null
+++ b/wifi/apex/com.android.hardware.wifi.x509.pem
@@ -0,0 +1,36 @@
+-----BEGIN CERTIFICATE-----
+MIIGOzCCBCOgAwIBAgIUIEueuBFEoCFmLyEvXDsKVuZeH0EwDQYJKoZIhvcNAQEL
+BQAwgasxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
+DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
+b2lkMScwJQYDVQQDDB5jb20uYW5kcm9pZC5oYXJkd2FyZS53aWZpLmFwZXgxIjAg
+BgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5kcm9pZC5jb20wIBcNMjIxMDA2MTY1MDQy
+WhgPNDc2MDA5MDExNjUwNDJaMIGrMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs
+aWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9p
+ZDEQMA4GA1UECwwHQW5kcm9pZDEnMCUGA1UEAwweY29tLmFuZHJvaWQuaGFyZHdh
+cmUud2lmaS5hcGV4MSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAo4N23iL0J42qG2lt4ysD
+t6XxAKdi4sTWB6ZjFWerBm11s3yLr1KBZV82z3j2o7+EOaWa/91Mgc+aoiGYUa1f
+IweugKTrnRmrzOvtq/Wp5PGqSxsmLPPvH3wyEB/CMgAn0pqDf0WyCWJ2kAlcCkmy
+qVNFupkGFyIE6gkoc+AmJGbSTquDlL07R/8XYDicqrcgeqy9ZaCJ5FLfmbnnRb2A
+vm4Un7e5dFz5+dPaOJXf4AOMUSPUd7fuBliGYFLzcZnYQbzMktXa4XnPuSlmerwy
+EwY767L2bjRjaSgPb0Js13gZ4S4ZHZe07AV7HPlt/EzbxV/jtMgHl4xn5p0WhVnK
+MPtLsO/e7FkDPAKpT02sgUK6pVKqgBGOWm27tmTB09lscMLQeVFqwpoFq2zMUrDn
+ipDFMWRBeLrEDKx41zF3gqdPmP+SMkQYJu4OATIXOndIeo7AN9iE+N6snHkckNyE
+saCwmnzyhVAbMn/epfIQZz3zcyljA9yfOpv5jctN4es+3i0htDnoNO9ij4M5fxuP
+jtNAP3EA61nKZ5+Js0/MMQKrfwCLogPl/4vCNuuGT2rhCkhq1CLYXmb9ghvVzcPe
+BOGXNDKdB+aUTxrQUOYlHf0cRDHdU6cchrz9+QhR7t9dlibtiyCZE34xgR3klmyz
+XJ3M1r/QRihjARH7exrrwiUCAwEAAaNTMFEwHQYDVR0OBBYEFGN9tMk+4SDk7twk
+MrLjM+nRxGDJMB8GA1UdIwQYMBaAFGN9tMk+4SDk7twkMrLjM+nRxGDJMA8GA1Ud
+EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHoTfVBRG0rVE7gkV526gwR5
+/3mXyYA57lKJhZ21fu2qfTE6WYj4DsOTZKrPIAUFv/SnzZ6Rvv7W81XV5M/1m+5R
+/1wYvWwm3FBOvvt4VDUiel0Zfc9+nwynjz1seYdXU8fNIOzBcr9hutkYdRZDkNpc
+Zcl4NG04TzyedkQ/0SyHnygmq4ZY9OUEvrNaWBFHzw2SQhYvHh8jUrqpPvoJz0Px
+avKI8bOgXTJRJ+Pk7hjXDFQY/fbE0RGivorPMLs+XHaEIb+YPyXsX4OZwowG5KL8
+txyvUsH+qZToytdPk4LCuwYBobBlr+AAg7pxOtbDW1ITDhQ9n05UFK2iUwsJecgg
+VDA0K3GuCjmGVmkw7SFRYfToCyGWah8sQCUMCCcsof7gS+dMxuWeee+sRxRJcJY+
+xR2uySe8g4ohwNjQ0zLQv7PZOKQh91yEWxRXmhPYVpiVAjpSD2zH7Vd6CJ9xji//
+5S1UrxWwQ5igvu8v5veqNAW7uXGXADnxL69HVGTLm0XDIUUOAUIG8waiVkYUo3UU
+AzAFbF7ewYMKdg7ylUYcTaMRIsKYW/3/1t3NJv2z99W4V/p8e1kRCeWMPB5C+/Lo
+b/hSWj1NF9AJ30ukBndMh6bRprq+G5NLV6OaoCLp606CMdXdT8uw9lYCt7DbQHG9
+Hw3iw61svpUwcaWfN1hI
+-----END CERTIFICATE-----
diff --git a/wifi/apex/file_contexts b/wifi/apex/file_contexts
new file mode 100644
index 0000000..d932fac
--- /dev/null
+++ b/wifi/apex/file_contexts
@@ -0,0 +1,3 @@
+(/.*)?                                          u:object_r:vendor_file:s0
+/etc(/.*)?                                      u:object_r:vendor_configs_file:s0
+/bin/hw/android\.hardware\.wifi-service			u:object_r:hal_wifi_default_exec:s0
diff --git a/wifi/hostapd/1.0/vts/OWNERS b/wifi/hostapd/1.0/vts/OWNERS
deleted file mode 100644
index 287152d..0000000
--- a/wifi/hostapd/1.0/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 33618
-arabawy@google.com
-etancohen@google.com
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
index bb99ae4..46cba93 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
@@ -48,6 +48,13 @@
     virtual void SetUp() override {
         wifi_instance_name_ = std::get<0>(GetParam());
         hostapd_instance_name_ = std::get<1>(GetParam());
+
+        // Disable Wi-Fi framework to avoid interference
+        isWifiEnabled_ = isWifiFrameworkEnabled();
+        isScanAlwaysEnabled_ = isWifiScanAlwaysAvailable();
+        toggleWifiFramework(false);
+        toggleWifiScanAlwaysAvailable(false);
+
         stopSupplicantIfNeeded(wifi_instance_name_);
         startHostapdAndWaitForHidlService(wifi_instance_name_,
                                           hostapd_instance_name_);
@@ -58,14 +65,21 @@
     virtual void TearDown() override {
         HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate);
         stopHostapd(wifi_instance_name_);
+
+        // Restore Wi-Fi framework state
+        toggleWifiFramework(isWifiEnabled_);
+        toggleWifiScanAlwaysAvailable(isScanAlwaysEnabled_);
     }
 
    protected:
-    std::string getPrimaryWlanIfaceName() {
+     bool isWifiEnabled_ = false;
+     bool isScanAlwaysEnabled_ = false;
+
+     std::string getPrimaryWlanIfaceName() {
         std::array<char, PROPERTY_VALUE_MAX> buffer;
         property_get("wifi.interface", buffer.data(), "wlan0");
         return buffer.data();
-    }
+     }
 
     IHostapd::IfaceParams getIfaceParamsWithAcs() {
         IHostapd::IfaceParams iface_params;
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
index 75d6252..4c452fb 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
@@ -41,10 +41,9 @@
 using ::android::wifi_system::HostapdManager;
 using ::android::wifi_system::SupplicantManager;
 
-namespace {
 // Helper function to initialize the driver and firmware to AP mode
 // using the vendor HAL HIDL interface.
-void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+void initializeDriverAndFirmware(const std::string& wifi_instance_name) {
     if (getWifi(wifi_instance_name) != nullptr) {
         sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
         ChipModeId mode_id;
@@ -57,21 +56,20 @@
 
 // Helper function to deinitialize the driver and firmware
 // using the vendor HAL HIDL interface.
-void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name) {
     if (getWifi(wifi_instance_name) != nullptr) {
         stopWifi(wifi_instance_name);
     } else {
         LOG(WARNING) << __func__ << ": Vendor HAL not supported";
     }
 }
-}  // namespace
 
 void stopSupplicantIfNeeded(const std::string& instance_name) {
     SupplicantManager supplicant_manager;
     if (supplicant_manager.IsSupplicantRunning()) {
         LOG(INFO) << "Supplicant is running, stop supplicant first.";
         ASSERT_TRUE(supplicant_manager.StopSupplicant());
-        deInitilializeDriverAndFirmware(instance_name);
+        deInitializeDriverAndFirmware(instance_name);
         ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
     }
 }
@@ -80,13 +78,13 @@
     HostapdManager hostapd_manager;
 
     ASSERT_TRUE(hostapd_manager.StopHostapd());
-    deInitilializeDriverAndFirmware(instance_name);
+    deInitializeDriverAndFirmware(instance_name);
 }
 
 void startHostapdAndWaitForHidlService(
     const std::string& wifi_instance_name,
     const std::string& hostapd_instance_name) {
-    initilializeDriverAndFirmware(wifi_instance_name);
+    initializeDriverAndFirmware(wifi_instance_name);
 
     HostapdManager hostapd_manager;
     ASSERT_TRUE(hostapd_manager.StartHostapd());
@@ -100,3 +98,24 @@
         ::android::hardware::wifi::hostapd::V1_1::IHostapd::castFrom(hostapd);
     return hostapd_1_1.get() != nullptr;
 }
+
+void toggleWifiFramework(bool enable) {
+    std::string cmd = "/system/bin/cmd wifi set-wifi-enabled ";
+    cmd += enable ? "enabled" : "disabled";
+    testing::checkSubstringInCommandOutput(cmd.c_str(), "X");
+}
+
+void toggleWifiScanAlwaysAvailable(bool enable) {
+    std::string cmd = "/system/bin/cmd wifi set-scan-always-available ";
+    cmd += enable ? "enabled" : "disabled";
+    testing::checkSubstringInCommandOutput(cmd.c_str(), "X");
+}
+
+bool isWifiFrameworkEnabled() {
+    return testing::checkSubstringInCommandOutput("/system/bin/cmd wifi status", "Wifi is enabled");
+}
+
+bool isWifiScanAlwaysAvailable() {
+    return testing::checkSubstringInCommandOutput("/system/bin/cmd wifi status",
+                                                  "Wifi scanning is always available");
+}
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
index 5cb4f01..aa34c9a 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
@@ -17,14 +17,17 @@
 #ifndef HOSTAPD_HIDL_TEST_UTILS_H
 #define HOSTAPD_HIDL_TEST_UTILS_H
 
+#include <VtsCoreUtil.h>
 #include <android/hardware/wifi/hostapd/1.0/IHostapd.h>
 #include <android/hardware/wifi/hostapd/1.1/IHostapd.h>
 
 // Used to stop the android wifi framework before every test.
-void stopWifiFramework(const std::string& instance_name);
-void startWifiFramework(const std::string& instance_name);
 void stopSupplicantIfNeeded(const std::string& instance_name);
 void stopHostapd(const std::string& instance_name);
+void toggleWifiFramework(bool enable);
+void toggleWifiScanAlwaysAvailable(bool enable);
+bool isWifiFrameworkEnabled();
+bool isWifiScanAlwaysAvailable();
 // Used to configure the chip, driver and start wpa_hostapd before every
 // test.
 void startHostapdAndWaitForHidlService(
@@ -33,5 +36,9 @@
 
 bool is_1_1(const android::sp<android::hardware::wifi::hostapd::V1_0::IHostapd>&
                 hostapd);
+// Used to initialize/deinitialize the driver and firmware at the
+// beginning and end of each test.
+void initializeDriverAndFirmware(const std::string& wifi_instance_name);
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name);
 
 #endif /* HOSTAPD_HIDL_TEST_UTILS_H */
diff --git a/wifi/hostapd/1.1/vts/OWNERS b/wifi/hostapd/1.1/vts/OWNERS
deleted file mode 100644
index 294fc82..0000000
--- a/wifi/hostapd/1.1/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.0/vts/OWNERS
diff --git a/wifi/hostapd/1.2/vts/OWNERS b/wifi/hostapd/1.2/vts/OWNERS
deleted file mode 100644
index 294fc82..0000000
--- a/wifi/hostapd/1.2/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.0/vts/OWNERS
diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
index 5c59819..b4840a6 100644
--- a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
@@ -69,6 +69,7 @@
                                           hostapd_instance_name_);
         hostapd_ = IHostapd::getService(hostapd_instance_name_);
         ASSERT_NE(hostapd_.get(), nullptr);
+        setupApIfaceIfNeeded();
         isAcsSupport_ = testing::checkSubstringInCommandOutput(
             "/system/bin/cmd wifi get-softap-supported-features",
             "wifi_softap_acs_supported");
@@ -86,14 +87,21 @@
     bool isWpa3SaeSupport_ = false;
     bool isAcsSupport_ = false;
 
-    std::string setupApIfaceIfNeededAndGetName() {
+    void setupApIfaceIfNeeded() {
         sp<IWifiApIface> wifi_ap_iface;
         wifi_ap_iface = getWifiApIface_1_4(wifi_instance_name_);
         EXPECT_NE(nullptr, wifi_ap_iface.get());
 
         const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
         EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code);
-        return status_and_name.second;
+    }
+
+    std::string getPrimaryWlanIfaceName() {
+        std::array<char, PROPERTY_VALUE_MAX> buffer;
+        auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr);
+        if (res > 0) return buffer.data();
+        property_get("wifi.interface", buffer.data(), "wlan0");
+        return buffer.data();
     }
 
     IHostapd::IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
@@ -243,7 +251,7 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                               getIfaceParamsWithAcs(ifname), getPskNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -257,7 +265,7 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                               getIfaceParamsWithAcsAndFreqRange(ifname),
                               getPskNwParams());
@@ -272,7 +280,7 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                               getIfaceParamsWithAcsAndInvalidFreqRange(ifname),
                               getPskNwParams());
@@ -287,7 +295,7 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                               getIfaceParamsWithAcs(ifname), getOpenNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -300,7 +308,7 @@
 TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                     getIfaceParamsWithoutAcs(ifname), getPskNwParams());
@@ -314,7 +322,7 @@
 TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                     getIfaceParamsWithoutAcs(ifname), getOpenNwParams());
@@ -329,7 +337,7 @@
     if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                               getIfaceParamsWithoutAcs(ifname),
                               getSaeTransitionNwParams());
@@ -344,7 +352,7 @@
     if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                     getIfaceParamsWithoutAcs(ifname), getSaeNwParams());
@@ -359,7 +367,7 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status_1_2 =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithAcs(ifname),
                     getPskNwParams());
@@ -377,7 +385,7 @@
 TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status_1_2 =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                     getIfaceParamsWithoutAcs(ifname), getPskNwParams());
@@ -395,7 +403,7 @@
 TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                     getIfaceParamsWithInvalidChannel(ifname), getPskNwParams());
@@ -409,7 +417,7 @@
 TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                     getIfaceParamsWithoutAcs(ifname), getInvalidPskNwParams());
@@ -424,7 +432,7 @@
     if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                               getIfaceParamsWithoutAcs(ifname),
                               getInvalidSaeTransitionNwParams());
@@ -439,7 +447,7 @@
     if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                     getIfaceParamsWithoutAcs(ifname), getInvalidSaeNwParams());
@@ -451,7 +459,7 @@
  * when hotspot interface doesn't init..
  */
 TEST_P(HostapdHidlTest, DisconnectClientWhenIfaceNotAvailable) {
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status = HIDL_INVOKE(hostapd_, forceClientDisconnect, ifname,
                               kTestZeroMacAddr, kTestDisconnectReasonCode);
     EXPECT_EQ(HostapdStatusCode::FAILURE_IFACE_UNKNOWN, status.code);
@@ -464,7 +472,7 @@
 TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    std::string ifname = setupApIfaceIfNeededAndGetName();
+    std::string ifname = getPrimaryWlanIfaceName();
     auto status_1_2 =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
                     getIfaceParamsWithoutAcs(ifname), getOpenNwParams());
diff --git a/wifi/hostapd/1.3/vts/OWNERS b/wifi/hostapd/1.3/vts/OWNERS
deleted file mode 100644
index 294fc82..0000000
--- a/wifi/hostapd/1.3/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.0/vts/OWNERS
diff --git a/wifi/hostapd/aidl/Android.bp b/wifi/hostapd/aidl/Android.bp
index c97f8da..54895c1 100644
--- a/wifi/hostapd/aidl/Android.bp
+++ b/wifi/hostapd/aidl/Android.bp
@@ -38,9 +38,7 @@
             min_sdk_version: "30",
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
+            gen_trace: true,
         },
     },
     versions_with_info: [
diff --git a/wifi/hostapd/aidl/lint-baseline.xml b/wifi/hostapd/aidl/lint-baseline.xml
new file mode 100644
index 0000000..657622e
--- /dev/null
+++ b/wifi/hostapd/aidl/lint-baseline.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V1-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"
+            line="55"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V1-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"
+            line="46"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V2-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"
+            line="117"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V2-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"
+            line="62"
+            column="12"/>
+    </issue>
+
+</issues>
\ No newline at end of file
diff --git a/wifi/hostapd/aidl/vts/OWNERS b/wifi/hostapd/aidl/vts/OWNERS
deleted file mode 100644
index 2a7a7b0..0000000
--- a/wifi/hostapd/aidl/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-etancohen@google.com
-lzye@google.com
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index a24bcc0..ff35056 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -36,6 +36,10 @@
         "android.hardware.wifi@1.4",
         "android.hardware.wifi@1.5",
         "android.hardware.wifi@1.6",
+        "android.hardware.wifi-V1-ndk",
+        "libwifi-system",
+        "libwifi-system-iface",
+        "VtsHalWifiTargetTestUtil",
     ],
     test_suites: [
         "general-tests",
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index 1b9c0b0..137537d 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <aidl/android/hardware/wifi/IWifi.h>
 #include <android/hardware/wifi/1.0/IWifi.h>
 #include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
 
@@ -31,6 +32,9 @@
 #include <wifi_hidl_test_utils_1_5.h>
 #include <wifi_hidl_test_utils_1_6.h>
 
+#include "hostapd_test_utils.h"
+#include "wifi_aidl_test_utils.h"
+
 using aidl::android::hardware::wifi::hostapd::BandMask;
 using aidl::android::hardware::wifi::hostapd::BnHostapdCallback;
 using aidl::android::hardware::wifi::hostapd::ChannelBandwidth;
@@ -53,8 +57,7 @@
 const int kIfaceChannel = 6;
 const int kIfaceInvalidChannel = 567;
 const std::vector<uint8_t> kTestZeroMacAddr(6, 0x0);
-const Ieee80211ReasonCode kTestDisconnectReasonCode =
-    Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
+const Ieee80211ReasonCode kTestDisconnectReasonCode = Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
 
 inline BandMask operator|(BandMask a, BandMask b) {
     return static_cast<BandMask>(static_cast<int32_t>(a) |
@@ -65,10 +68,13 @@
 class HostapdAidl : public testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        hostapd = IHostapd::fromBinder(ndk::SpAIBinder(
-            AServiceManager_waitForService(GetParam().c_str())));
+        disableHalsAndFramework();
+        initializeHostapdAndVendorHal(GetParam());
+
+        hostapd = getHostapd(GetParam());
         ASSERT_NE(hostapd, nullptr);
         EXPECT_TRUE(hostapd->setDebugParams(DebugLevel::EXCESSIVE).isOk());
+
         isAcsSupport = testing::checkSubstringInCommandOutput(
             "/system/bin/cmd wifi get-softap-supported-features",
             "wifi_softap_acs_supported");
@@ -76,44 +82,23 @@
             "/system/bin/cmd wifi get-softap-supported-features",
             "wifi_softap_wpa3_sae_supported");
         isBridgedSupport = testing::checkSubstringInCommandOutput(
-            "/system/bin/cmd wifi get-softap-supported-features",
-            "wifi_softap_bridged_ap_supported");
-        const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
-                ::android::hardware::wifi::V1_0::IWifi::descriptor);
-        EXPECT_NE(0, instances.size());
-        wifiInstanceName = instances[0];
+                "/system/bin/cmd wifi get-softap-supported-features",
+                "wifi_softap_bridged_ap_supported");
     }
 
     virtual void TearDown() override {
-        if (getWifi(wifiInstanceName) != nullptr) {
-            stopWifi(wifiInstanceName);
-        }
         hostapd->terminate();
         //  Wait 3 seconds to allow terminate to complete
         sleep(3);
+        stopHostapdAndVendorHal();
+        startWifiFramework();
     }
 
     std::shared_ptr<IHostapd> hostapd;
-    std::string wifiInstanceName;
     bool isAcsSupport;
     bool isWpa3SaeSupport;
     bool isBridgedSupport;
 
-    std::string setupApIfaceAndGetName(bool isBridged) {
-        android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
-        if (isBridged) {
-            wifi_ap_iface = getBridgedWifiApIface_1_6(wifiInstanceName);
-        } else {
-            wifi_ap_iface = getWifiApIface_1_5(wifiInstanceName);
-        }
-        EXPECT_NE(nullptr, wifi_ap_iface.get());
-
-        const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
-        EXPECT_EQ(android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS,
-                  status_and_name.first.code);
-        return status_and_name.second;
-    }
-
     IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
         IfaceParams iface_params;
         ChannelParams channelParams;
diff --git a/wifi/hostapd/aidl/vts/functional/hostapd_aidl_test_utils.h b/wifi/hostapd/aidl/vts/functional/hostapd_aidl_test_utils.h
new file mode 100644
index 0000000..93540b2
--- /dev/null
+++ b/wifi/hostapd/aidl/vts/functional/hostapd_aidl_test_utils.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <android-base/logging.h>
+
+#include "wifi_aidl_test_utils.h"
+
+namespace {
+
+const std::string kWifiInstanceNameStr = std::string() + IWifi::descriptor + "/default";
+const char* kWifiInstanceName = kWifiInstanceNameStr.c_str();
+
+}  // namespace
+
+namespace HostapdAidlTestUtils {
+
+bool useAidlService() {
+    return isAidlServiceAvailable(kWifiInstanceName);
+}
+
+void startAndConfigureVendorHal() {
+    if (getWifi(kWifiInstanceName) != nullptr) {
+        std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(kWifiInstanceName);
+        int mode_id;
+        EXPECT_TRUE(configureChipToSupportConcurrencyType(wifi_chip, IfaceConcurrencyType::AP,
+                                                          &mode_id));
+    } else {
+        LOG(ERROR) << "Unable to initialize Vendor HAL";
+    }
+}
+
+void stopVendorHal() {
+    if (getWifi(kWifiInstanceName) != nullptr) {
+        stopWifiService(kWifiInstanceName);
+    } else {
+        LOG(ERROR) << "Unable to stop Vendor HAL";
+    }
+}
+
+std::string setupApIfaceAndGetName(bool isBridged) {
+    std::shared_ptr<IWifiApIface> wifi_ap_iface;
+    if (isBridged) {
+        wifi_ap_iface = getBridgedWifiApIface(kWifiInstanceName);
+    } else {
+        wifi_ap_iface = getWifiApIface(kWifiInstanceName);
+    }
+
+    EXPECT_TRUE(wifi_ap_iface.get() != nullptr);
+    if (!wifi_ap_iface.get()) {
+        LOG(ERROR) << "Unable to create iface. isBridged=" << isBridged;
+        return "";
+    }
+
+    std::string ap_iface_name;
+    auto status = wifi_ap_iface->getName(&ap_iface_name);
+    EXPECT_TRUE(status.isOk());
+    if (!status.isOk()) {
+        LOG(ERROR) << "Unable to retrieve iface name. isBridged=" << isBridged;
+        return "";
+    }
+    return ap_iface_name;
+}
+
+}  // namespace HostapdAidlTestUtils
diff --git a/wifi/hostapd/aidl/vts/functional/hostapd_legacy_test_utils.h b/wifi/hostapd/aidl/vts/functional/hostapd_legacy_test_utils.h
new file mode 100644
index 0000000..fb59dc2
--- /dev/null
+++ b/wifi/hostapd/aidl/vts/functional/hostapd_legacy_test_utils.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/logging.h>
+
+#include "hostapd_hidl_test_utils.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::WifiStatus;
+
+namespace {
+
+std::string getWifiInstanceName() {
+    const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
+            ::android::hardware::wifi::V1_0::IWifi::descriptor);
+    EXPECT_NE(0, instances.size());
+    return instances.size() != 0 ? instances[0] : "";
+}
+
+}  // namespace
+
+namespace HostapdLegacyTestUtils {
+
+void startAndConfigureVendorHal() {
+    initializeDriverAndFirmware(getWifiInstanceName());
+}
+
+void stopVendorHal() {
+    deInitializeDriverAndFirmware(getWifiInstanceName());
+}
+
+std::string setupApIfaceAndGetName(bool isBridged) {
+    android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
+    if (isBridged) {
+        wifi_ap_iface = getBridgedWifiApIface_1_6(getWifiInstanceName());
+    } else {
+        wifi_ap_iface = getWifiApIface_1_5(getWifiInstanceName());
+    }
+
+    EXPECT_TRUE(wifi_ap_iface.get() != nullptr);
+    if (!wifi_ap_iface.get()) {
+        LOG(ERROR) << "Unable to create iface. isBridged=" << isBridged;
+        return "";
+    }
+
+    const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
+    EXPECT_TRUE(status_and_name.first.code ==
+                android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS);
+    if (status_and_name.first.code != android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS) {
+        LOG(ERROR) << "Unable to retrieve iface name. isBridged=" << isBridged;
+        return "";
+    }
+    return status_and_name.second;
+}
+
+}  // namespace HostapdLegacyTestUtils
diff --git a/wifi/hostapd/aidl/vts/functional/hostapd_test_utils.h b/wifi/hostapd/aidl/vts/functional/hostapd_test_utils.h
new file mode 100644
index 0000000..50a38d3
--- /dev/null
+++ b/wifi/hostapd/aidl/vts/functional/hostapd_test_utils.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
+#include <android-base/logging.h>
+#include <wifi_system/hostapd_manager.h>
+#include <wifi_system/supplicant_manager.h>
+
+#include "hostapd_aidl_test_utils.h"
+#include "hostapd_legacy_test_utils.h"
+
+using aidl::android::hardware::wifi::hostapd::IHostapd;
+using android::wifi_system::HostapdManager;
+using android::wifi_system::SupplicantManager;
+
+namespace {
+
+void startAndConfigureVendorHal() {
+    if (HostapdAidlTestUtils::useAidlService()) {
+        HostapdAidlTestUtils::startAndConfigureVendorHal();
+    } else {
+        HostapdLegacyTestUtils::startAndConfigureVendorHal();
+    }
+}
+
+void stopVendorHal() {
+    if (HostapdAidlTestUtils::useAidlService()) {
+        HostapdAidlTestUtils::stopVendorHal();
+    } else {
+        HostapdLegacyTestUtils::stopVendorHal();
+    }
+}
+
+void stopHostapd() {
+    HostapdManager hostapd_manager;
+    ASSERT_TRUE(hostapd_manager.StopHostapd());
+}
+
+void waitForSupplicantState(bool enable) {
+    SupplicantManager supplicant_manager;
+    int count = 50;  // wait at most 5 seconds
+    while (count-- > 0) {
+        if (supplicant_manager.IsSupplicantRunning() == enable) {
+            return;
+        }
+        usleep(100000);  // 100 ms
+    }
+    LOG(ERROR) << "Unable to " << (enable ? "start" : "stop") << " supplicant";
+}
+
+void toggleWifiFrameworkAndScan(bool enable) {
+    if (enable) {
+        std::system("svc wifi enable");
+        std::system("cmd wifi set-scan-always-available enabled");
+        waitForSupplicantState(true);
+    } else {
+        std::system("svc wifi disable");
+        std::system("cmd wifi set-scan-always-available disabled");
+        waitForSupplicantState(false);
+    }
+}
+
+}  // namespace
+
+std::shared_ptr<IHostapd> getHostapd(const std::string& hostapd_instance_name) {
+    return IHostapd::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(hostapd_instance_name.c_str())));
+}
+
+/**
+ * Disable the Wifi framework, hostapd, and vendor HAL.
+ *
+ * Note: The framework should be disabled to avoid having
+ *       any other clients to the HALs during testing.
+ */
+void disableHalsAndFramework() {
+    toggleWifiFrameworkAndScan(false);
+    stopHostapd();
+    stopVendorHal();
+
+    // Wait for the services to stop.
+    sleep(3);
+}
+
+void initializeHostapdAndVendorHal(const std::string& hostapd_instance_name) {
+    startAndConfigureVendorHal();
+    HostapdManager hostapd_manager;
+    ASSERT_TRUE(hostapd_manager.StartHostapd());
+    getHostapd(hostapd_instance_name);
+}
+
+void stopHostapdAndVendorHal() {
+    stopHostapd();
+    stopVendorHal();
+}
+
+void startWifiFramework() {
+    toggleWifiFrameworkAndScan(true);
+}
+
+std::string setupApIfaceAndGetName(bool isBridged) {
+    if (HostapdAidlTestUtils::useAidlService()) {
+        return HostapdAidlTestUtils::setupApIfaceAndGetName(isBridged);
+    } else {
+        return HostapdLegacyTestUtils::setupApIfaceAndGetName(isBridged);
+    }
+}
diff --git a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
index ded9122..e84a5cf 100644
--- a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
+++ b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
@@ -28,7 +28,7 @@
 using namespace std::chrono_literals;
 
 static constexpr std::chrono::milliseconds kPollTimeout = 300ms;
-static constexpr bool kSuperVerbose = true;
+static constexpr bool kSuperVerbose = false;
 
 InterceptorRelay::InterceptorRelay(uint32_t nlFamily, uint32_t clientNlPid,
                                    const std::string& clientName)
diff --git a/wifi/netlinkinterceptor/aidl/default/OWNERS b/wifi/netlinkinterceptor/aidl/default/OWNERS
deleted file mode 100644
index b738dac..0000000
--- a/wifi/netlinkinterceptor/aidl/default/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-chrisweir@google.com
-twasilczyk@google.com
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/Android.bp b/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
index 00cae32..671cd85 100644
--- a/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
+++ b/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
@@ -37,10 +37,8 @@
         "libutils",
     ],
     sanitize: {
-        address: true,
         undefined: true,
         all_undefined: true,
-        fuzzer: true,
         cfi: true,
         integer_overflow: true,
         scs: true,
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h b/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
index ac8653e..32e5a6e 100644
--- a/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
+++ b/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
@@ -117,14 +117,13 @@
     int clientSocketFd, const char* clientName,
     struct android_nlinterceptor_InterceptedSocket* interceptedSocket);
 
-void android_nlinterceptor_closeSocket(
-    const struct android_nlinterceptor_InterceptedSocket* sock);
+void android_nlinterceptor_closeSocket(struct android_nlinterceptor_InterceptedSocket sock);
 
-bool android_nlinterceptor_subscribe(
-    const struct android_nlinterceptor_InterceptedSocket* sock, uint32_t group);
+bool android_nlinterceptor_subscribe(struct android_nlinterceptor_InterceptedSocket sock,
+                                     uint32_t group);
 
-bool android_nlinterceptor_unsubscribe(
-    const struct android_nlinterceptor_InterceptedSocket* sock, uint32_t group);
+bool android_nlinterceptor_unsubscribe(struct android_nlinterceptor_InterceptedSocket sock,
+                                       uint32_t group);
 
 #ifdef __cplusplus
 }
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp b/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
index 575f900..aae7a3a 100644
--- a/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
+++ b/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
@@ -150,25 +150,18 @@
     return true;
 }
 
-extern "C" void android_nlinterceptor_closeSocket(
-    const android_nlinterceptor_InterceptedSocket* sock) {
-    if (!sock) {
-        LOG(ERROR) << "Can't close socket identified by a null pointer!";
-        return;
-    }
-    closeSocket({sock->nlFamily, sock->portId});
+extern "C" void android_nlinterceptor_closeSocket(android_nlinterceptor_InterceptedSocket sock) {
+    closeSocket({sock.nlFamily, sock.portId});
 }
 
-extern "C" bool android_nlinterceptor_subscribe(
-    const android_nlinterceptor_InterceptedSocket* sock, uint32_t group) {
-    if (!sock) return false;
-    return subscribe({sock->nlFamily, sock->portId}, group);
+extern "C" bool android_nlinterceptor_subscribe(android_nlinterceptor_InterceptedSocket sock,
+                                                uint32_t group) {
+    return subscribe({sock.nlFamily, sock.portId}, group);
 }
 
-extern "C" bool android_nlinterceptor_unsubscribe(
-    const android_nlinterceptor_InterceptedSocket* sock, uint32_t group) {
-    if (!sock) return false;
-    return unsubscribe({sock->nlFamily, sock->portId}, group);
+extern "C" bool android_nlinterceptor_unsubscribe(android_nlinterceptor_InterceptedSocket sock,
+                                                  uint32_t group) {
+    return unsubscribe({sock.nlFamily, sock.portId}, group);
 }
 
 }  // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/vts/OWNERS b/wifi/netlinkinterceptor/vts/OWNERS
deleted file mode 100644
index b738dac..0000000
--- a/wifi/netlinkinterceptor/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-chrisweir@google.com
-twasilczyk@google.com
diff --git a/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp
deleted file mode 100644
index 8fd602d..0000000
--- a/wifi/offload/1.0/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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.wifi.offload@1.0",
-    root: "android.hardware",
-    srcs: [
-        "types.hal",
-        "IOffload.hal",
-        "IOffloadCallback.hal",
-    ],
-    interfaces: [
-        "android.hidl.base@1.0",
-    ],
-    gen_java: false,
-}
diff --git a/wifi/offload/1.0/IOffload.hal b/wifi/offload/1.0/IOffload.hal
deleted file mode 100644
index 4819519..0000000
--- a/wifi/offload/1.0/IOffload.hal
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.wifi.offload@1.0;
-
-import IOffloadCallback;
-
-interface IOffload {
-    /**
-     * Configure the offload module to perform scans and filter results
-     * Scans must not be triggered due to configuration of the module.
-     *
-     * @param ScanParam paramters for scanning
-     * @param ScanFilter settings to filter scan result
-     * @return OffloadStatus indicating status of operation provided by this API
-     * If OffloadStatusCode::OK is returned, the operation was successful
-     * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost
-     * If OffloadStatusCode::ERROR is returned, requested operation could not be completed
-     */
-    @entry
-    @callflow(next={"setEventCallback", "subscribeScanResults"})
-    configureScans(ScanParam param, ScanFilter filter) generates (OffloadStatus status);
-
-    /**
-     * Get scan statistics
-     *
-     * @return OffloadStatus indicating status of operation provided by this API
-     * @return ScanStats statistics of scans performed
-     * If OffloadStatusCode::OK is returned, the operation was successful
-     * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost
-     * If OffloadStatusCode::ERROR is returned, requested operation could not be completed
-     * If OffloadStatusCode::TIMEOUT is returned, time out waiting for the requested data
-     */
-    @exit
-    @callflow(next={"subscribeScanResults", "unsubscribeScanResults", "getScanStats"})
-    getScanStats() generates (OffloadStatus status, ScanStats scanStats);
-
-    /**
-     * Subscribe to asynchronous scan events sent by offload module. This enables
-     * offload scans to be performed as per scan parameters, filtering the scan
-     * results based on configured scan filter and delivering the results after
-     * at least delayMs milliseconds from this call. If the client is already
-     * subscribed to the scan results, a call to this API must be a no-op.
-     *
-     * @param delayMs an integer expressing the minimum delay in mS after
-     *        subscribing when scan results must be delivered to the client
-     * @return OffloadStatus indicating status of operation provided by this API
-     * If OffloadStatusCode::OK is returned, the operation was successful
-     * If OffloadStatusCode::NO_CONNECTION is returned, connection to the hardware is lost
-     * If OffloadStatusCode::ERROR is returned, requested operation could not be completed
-     */
-    @callflow(next={"unsubscribeScanResults", "getScanStats"})
-    subscribeScanResults(uint32_t delayMs) generates (OffloadStatus status);
-
-    /**
-     * Unsubscribe to scan events sent by the offload module, hence disabling scans.
-     * If the client is already unsubscribed, a call to this API will be a no-op.
-     */
-    @exit
-    @callflow(next={"*"})
-    unsubscribeScanResults();
-
-    /**
-     * Setup the HIDL interface for reporting asynchronous scan events. A maximum
-     * of one callback interface is supported. Only one callback must be registered
-     * at any given time. If two consecutive calls are made with different callback
-     * interface objects, the latest one must be used to deliver events to client.
-     *
-     * @param cb An instance of the |IOffloadCallback| HIDL interface object
-     */
-    @entry
-    @callflow(next={"subscribeScanStats", "configureScans"})
-    setEventCallback(IOffloadCallback cb);
-};
diff --git a/wifi/offload/1.0/IOffloadCallback.hal b/wifi/offload/1.0/IOffloadCallback.hal
deleted file mode 100644
index 4888125..0000000
--- a/wifi/offload/1.0/IOffloadCallback.hal
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.hardware.wifi.offload@1.0;
-
-interface IOffloadCallback {
-    /**
-     * Interface for the Offload HAL to return scan events to the client
-     *
-     * @param scanResult a vector of scan result objects
-     */
-    oneway onScanResult(vec<ScanResult> scanResult);
-    /**
-     * Interface for the Offload HAL to inform the client of error conditions
-     * see OffloadStatus for the error conditions to be reported
-     *
-     * @param status OffloadStatus
-     */
-    oneway onError(OffloadStatus status);
-};
diff --git a/wifi/offload/1.0/types.hal b/wifi/offload/1.0/types.hal
deleted file mode 100644
index 234f3fc..0000000
--- a/wifi/offload/1.0/types.hal
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.hardware.wifi.offload@1.0;
-
-/**
- * Defines a bitmap of security modes
- */
-enum SecurityMode : uint8_t {
-    OPEN                    = 0x1 << 1,
-    WEP                     = 0x1 << 2,
-    PSK                     = 0x1 << 3,
-    EAP                     = 0x1 << 4,
-};
-
-/**
- * SSID of the Access Point, maximum 32 characters
- */
-typedef vec<uint8_t> Ssid;
-
-/**
- * Preferred network information
- * SSID and associated security mode(s)
- */
-struct NetworkInfo {
-    Ssid ssid;
-    /* SecurityMode flags that are associated with this SSID
-     * More than one security mode can be supported, see SecurityMode */
-    bitfield<SecurityMode> flags;
-};
-
-/**
- * This is a bit mask describing the capabilities of a BSS.
- * See IEEE Std 802.11: 8.4.1.4
- */
-enum Capability : uint16_t {
-    ESS                     = 1 << 0,
-    IBSS                    = 1 << 1,
-    CF_POLLABLE             = 1 << 2,
-    CF_PLL_REQ              = 1 << 3,
-    PRIVACY                 = 1 << 4,
-    SHORT_PREAMBLE          = 1 << 5,
-    PBCC                    = 1 << 6,
-    CHANNEL_AGILITY         = 1 << 7,
-    SPECTURM_MGMT           = 1 << 8,
-    QOS                     = 1 << 9,
-    SHORT_SLOT_TIME         = 1 << 10,
-    APSD                    = 1 << 11,
-    RADIO_MEASUREMENT       = 1 << 12,
-    DSSS_OFDM               = 1 << 13,
-    DELAYED_BLOCK_ACK       = 1 << 14,
-    IMMEDIATE_BLOCK_ACK     = 1 << 15,
-};
-
-/**
- * Scan Results returned by the offload Hal
- */
-struct ScanResult {
-    /* Information about this BSS
-     * SSID and security modes supported */
-    NetworkInfo networkInfo;
-    /* BSSID of the BSS */
-    uint8_t[6] bssid;
-    /* Can have multiple bits set, see Capability */
-    bitfield<Capability> capability;
-    /* Frequency scanned, in mHz */
-    uint32_t frequency;
-    /* Signal strength in dBm */
-    int8_t rssi;
-    /* TSF found in beacon/probe response */
-    uint64_t tsf;
-};
-
-
-/**
- * Parameters for performing offload scans
- */
-struct ScanParam {
-    /* Specify a list of SSIDs to scan, an empty list implies no preferred
-     * networks to scan */
-    vec<Ssid> ssidList;
-    /* Frequencies to scan, in mHz, an empty frequency list implies a full scan */
-    vec<uint32_t> frequencyList;
-    /* Periodicity of the scans to be performed by the offload module
-     * A value of zero indicates disable periodic scans. For this revision,
-     * where offload module is performing scans in disconnected mode, this value
-     * should not be zero. In future versions, periodic scans can be eliminated */
-    uint32_t disconnectedModeScanIntervalMs;
-};
-
-/**
- * Instruction on how to filter the scan result before performing network
- * selection and waking up the AP to connect
- */
-struct ScanFilter {
-    /* Preferred network List of SSIDs and their security mode of interest
-     * The filter will drop the remaining scan results in the scan event.
-     * An empty list implies no filtering of scan result based on SSID and
-     * security mode. */
-    vec<NetworkInfo> preferredNetworkInfoList;
-    /* Minimum qualifying RSSI to be considered for network selection (dBm) */
-    int8_t rssiThreshold;
-};
-
-struct ScanRecord {
-    /* Amount of time spent scanning */
-    uint64_t durationMs;
-    /* Number of channels scanned */
-    uint32_t numChannelsScanned;
-    /* Number of entries aggregated into this record */
-    uint32_t numEntriesAggregated;
-};
-
-/**
- * Enumerates the type of log that is recorded
- */
-enum RecordName : uint32_t {
-    CMD_BASE                        = 0x00001000,
-    /* Record name corresponding to initialization */
-    CMD_INT                         = CMD_BASE + 0,
-   /* Record name corresponding to configureScans() API */
-    CMD_CONFIG_SCANS                = CMD_BASE + 1,
-    /* Record name corresponding to subscribeScanResults() API */
-    CMD_SUBSCRIBE_SCAN_RESULTS      = CMD_BASE + 2,
-    /* Record name corresponding to unsubscribeScanResults() API */
-    CMD_UNSUBSCRIBE_SCAN_RESULTS    = CMD_BASE + 3,
-    /* Record name corresponding to getScanStats() API */
-    CMD_GET_SCAN_STATS              = CMD_BASE + 4,
-    /* Record name corresponding to a reset*/
-    CMD_RESET                       = CMD_BASE + 5,
-    /* Add new commands here */
-    EVENT_RECVD_BASE                = 0x00002000,
-    /* Record name corresponding to scan monitor event*/
-    EVENT_RECVD_SCAN_RESULT_ASYNC   = EVENT_RECVD_BASE + 0,
-    /* Record name corresponding to scan response event */
-    EVENT_RECVD_SCAN_RESULT         = EVENT_RECVD_BASE + 1,
-    /* Add new events received here */
-    EVENT_SENT_BASE                 = 0x00003000,
-    /* Record name corresponding to scan event sent */
-    EVENT_SENT_SCAN_RESULT          = EVENT_SENT_BASE + 0,
-    /* Record name corresponding to abort event sent */
-    EVENT_SENT_ABORT                = EVENT_SENT_BASE + 1,
-    /* Record name corresponding to error event sent */
-    EVENT_SENT_ERROR                = EVENT_SENT_BASE + 2,
-    /* Add new events sent here */
-    REQ_BASE                        = 0x00004000,
-    /* Record name corresponding to scan request sent*/
-    REQ_SCAN                        = REQ_BASE + 0,
-    /* Add new requests here */
-};
-
-/**
- * Defines the structure of each log record
- */
-struct LogRecord {
-    /* Indicates the log recorded */
-    RecordName recordName;
-    /* Platform reference time in milliseconds when the log is recorded */
-    uint64_t logTimeMs;
-};
-
-/**
- * Defines the scan statistics to be returned to the framework
- */
-struct ScanStats {
-    /* Incremented everytime a new scan is requested */
-    uint32_t numScansRequestedByWifi;
-    /* Incremented everytime the scan is serviced by performing a scan*/
-    uint32_t numScansServicedByWifi;
-    /* Incremented everytime the scan is serviced by the scan cache */
-    uint32_t numScansServicedbyCache;
-    /* The last (CHRE reference) time this data structure is updated */
-    uint64_t lastUpdated;
-    /* The last (CHRE reference) time this data structure is read */
-    uint64_t lastRead;
-    /* The total time when the Offload module could be performing scans (T2 - T1)
-     * T1 - time when the framework subscribes for scan result (includes delayMs)
-     * T2 - min (time when the framework unsubscribes for scan result,
-     * currentTime) */
-    uint64_t subscriptionDurationMs;
-    /* Histograms of the channels scanned, 802.11 and with an 8 bit
-     * representation, only 256 channels are available */
-    uint8_t[256] histogramChannelsScanned;
-    /* Scan Record for this subscribe duration */
-    vec<ScanRecord> scanRecord;
-    /* Vector of the logRecord entries */
-    vec<LogRecord> logRecord;
-};
-
-/**
- * Defines a list of return codes to indicate status of Offload HAL
- */
-enum OffloadStatusCode : uint32_t {
-    /* No error */
-    OK,
-    /* No Connection to underlying implementation */
-    NO_CONNECTION,
-    /* Operation timeout */
-    TIMEOUT,
-    /* Other errors */
-    ERROR
-};
-
-/**
- * Generic structures to return the status of an operation
- */
-struct OffloadStatus {
-  OffloadStatusCode code;
-  /* Error message */
-  string description;
-};
-
-
-
diff --git a/wifi/offload/1.0/vts/OWNERS b/wifi/offload/1.0/vts/OWNERS
deleted file mode 100644
index 287152d..0000000
--- a/wifi/offload/1.0/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 33618
-arabawy@google.com
-etancohen@google.com
diff --git a/wifi/offload/1.0/vts/functional/Android.bp b/wifi/offload/1.0/vts/functional/Android.bp
deleted file mode 100644
index a0eb048..0000000
--- a/wifi/offload/1.0/vts/functional/Android.bp
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
-    // See: http://go/android-license-faq
-    // 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_test {
-    name: "VtsHalWifiOffloadV1_0TargetTest",
-    defaults: ["VtsHalTargetTestDefaults"],
-    srcs: ["VtsHalWifiOffloadV1_0TargetTest.cpp"],
-    static_libs: ["android.hardware.wifi.offload@1.0"],
-    test_suites: ["general-tests", "vts"],
-}
diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
deleted file mode 100644
index ffd5149..0000000
--- a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2016 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 "wifi_offload_hidl_hal_test"
-
-#include <android-base/logging.h>
-#include <android/hardware/wifi/offload/1.0/IOffload.h>
-#include <android/hardware/wifi/offload/1.0/IOffloadCallback.h>
-#include <android/hardware/wifi/offload/1.0/types.h>
-#include <gtest/gtest.h>
-#include <hidl/GtestPrinter.h>
-#include <hidl/ServiceManagement.h>
-
-#include <VtsHalHidlTargetCallbackBase.h>
-
-#include <vector>
-
-#include "hidl_call_util.h"
-
-using ::android::hardware::wifi::offload::V1_0::IOffload;
-using ::android::hardware::wifi::offload::V1_0::IOffloadCallback;
-using ::android::hardware::wifi::offload::V1_0::ScanResult;
-using ::android::hardware::wifi::offload::V1_0::ScanParam;
-using ::android::hardware::wifi::offload::V1_0::Ssid;
-using ::android::hardware::wifi::offload::V1_0::NetworkInfo;
-using ::android::hardware::wifi::offload::V1_0::ScanFilter;
-using ::android::hardware::wifi::offload::V1_0::ScanStats;
-using ::android::hardware::wifi::offload::V1_0::OffloadStatus;
-using ::android::hardware::wifi::offload::V1_0::OffloadStatusCode;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::sp;
-
-constexpr char kOffloadCallbackSendScanResult[] = "onScanResult";
-constexpr char kOffloadCallbackSendError[] = "onError";
-
-namespace {
-const uint8_t kSsid1[] = {'G', 'o', 'o', 'g', 'l', 'e'};
-const uint8_t kSsid2[] = {'X', 'f', 'i', 'n', 'i', 't', 'y'};
-const uint8_t kBssid[6] = {0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b};
-const int16_t kRssi = -60;
-const uint32_t kFrequency = 2412;
-const uint8_t kBssidSize = 6;
-const uint64_t kTsf = 0;
-const uint16_t kCapability = 0;
-const uint8_t kNetworkFlags = 0;
-const uint32_t kFrequency1 = 2412;
-const uint32_t kFrequency2 = 2437;
-const uint32_t kDisconnectedModeScanIntervalMs = 5000;
-const int16_t kRssiThreshold = -76;
-}
-
-class OffloadCallbackArgs {
-   public:
-    hidl_vec<ScanResult> scan_results_;
-    OffloadStatus error_code_;
-};
-
-// The main test class for WifiOffload HIDL HAL.
-class WifiOffloadHidlTest : public ::testing::TestWithParam<std::string> {
-   public:
-    virtual void SetUp() override {
-        wifi_offload_ = IOffload::getService(GetParam());
-        ASSERT_NE(wifi_offload_, nullptr);
-
-        wifi_offload_cb_ = new OffloadCallback();
-        ASSERT_NE(wifi_offload_cb_, nullptr);
-    }
-
-    virtual void TearDown() override {}
-
-    /* Callback class for Offload HAL. */
-    class OffloadCallback
-        : public ::testing::VtsHalHidlTargetCallbackBase<OffloadCallbackArgs>,
-          public IOffloadCallback {
-       public:
-        OffloadCallback(){};
-
-        virtual ~OffloadCallback() = default;
-
-        Return<void> onScanResult(
-            const hidl_vec<ScanResult>& scan_result) override {
-            OffloadCallbackArgs args;
-            args.scan_results_ = scan_result;
-            NotifyFromCallback(kOffloadCallbackSendScanResult, args);
-            return Void();
-        };
-
-        Return<void> onError(const OffloadStatus& status) override {
-            OffloadCallbackArgs args;
-            args.error_code_ = status;
-            NotifyFromCallback(kOffloadCallbackSendError, args);
-            return Void();
-        }
-    };
-
-    sp<IOffload> wifi_offload_;
-    sp<OffloadCallback> wifi_offload_cb_;
-};
-
-/*
- * Verify that setEventCallback method returns without errors
- */
-TEST_P(WifiOffloadHidlTest, setEventCallback) {
-    auto returnObject = wifi_offload_->setEventCallback(wifi_offload_cb_);
-    ASSERT_EQ(true, returnObject.isOk());
-}
-
-/*
- * Verify that subscribeScanResults method returns without errors
- */
-TEST_P(WifiOffloadHidlTest, subscribeScanResults) {
-    const auto& result = HIDL_INVOKE(wifi_offload_, subscribeScanResults, 0);
-    ASSERT_EQ(OffloadStatusCode::OK, result.code);
-}
-
-/*
- * Verify that unsubscribeScanResults method returns without errors
- */
-TEST_P(WifiOffloadHidlTest, unsubscribeScanResults) {
-    auto returnObject = wifi_offload_->unsubscribeScanResults();
-    ASSERT_EQ(true, returnObject.isOk());
-}
-
-/*
- * Verify that configureScans method returns without errors
- */
-TEST_P(WifiOffloadHidlTest, configureScans) {
-    ScanParam* pScanParam = new ScanParam();
-    std::vector<uint32_t> frequencyList = {kFrequency1, kFrequency2};
-    pScanParam->disconnectedModeScanIntervalMs =
-        kDisconnectedModeScanIntervalMs;
-    pScanParam->frequencyList = frequencyList;
-    std::vector<Ssid> ssidList;
-    std::vector<std::vector<uint8_t>> ssids{kSsid1, kSsid2};
-    for (const auto& ssid : ssids) {
-        Ssid tmp = ssid;
-        ssidList.push_back(tmp);
-    }
-    pScanParam->ssidList = ssidList;
-    ScanFilter* pScanFilter = new ScanFilter();
-    pScanFilter->rssiThreshold = kRssiThreshold;
-    std::vector<std::vector<uint8_t>> match_ssids{kSsid1, kSsid2};
-    std::vector<uint8_t> security_flags{kNetworkFlags, kNetworkFlags};
-    std::vector<NetworkInfo> preferredNetworksList;
-    for (size_t i = 0; i < security_flags.size(); i++) {
-        NetworkInfo nwInfo;
-        nwInfo.ssid = match_ssids[i];
-        nwInfo.flags = security_flags[i];
-        preferredNetworksList.push_back(nwInfo);
-    }
-    const auto& result =
-        HIDL_INVOKE(wifi_offload_, configureScans, *pScanParam, *pScanFilter);
-    ASSERT_EQ(OffloadStatusCode::OK, result.code);
-}
-
-/*
- * Verify that getScanStats returns without any errors
- */
-TEST_P(WifiOffloadHidlTest, getScanStats) {
-    const auto& result = HIDL_INVOKE(wifi_offload_, getScanStats);
-    OffloadStatus status = result.first;
-    ASSERT_EQ(OffloadStatusCode::OK, status.code);
-}
-
-/*
- * Verify that onScanResult callback is invoked
- */
-TEST_P(WifiOffloadHidlTest, getScanResults) {
-    wifi_offload_->setEventCallback(wifi_offload_cb_);
-    std::vector<ScanResult> scan_results;
-    std::vector<uint8_t> ssid(kSsid1, kSsid1 + sizeof(kSsid1));
-    ScanResult scan_result;
-    scan_result.tsf = kTsf;
-    scan_result.rssi = kRssi;
-    scan_result.frequency = kFrequency;
-    scan_result.capability = kCapability;
-    memcpy(&scan_result.bssid[0], &kBssid[0], kBssidSize);
-    scan_result.networkInfo.ssid = ssid;
-    scan_result.networkInfo.flags = kNetworkFlags;
-    scan_results.push_back(scan_result);
-    wifi_offload_cb_->onScanResult(scan_results);
-    auto res =
-        wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendScanResult);
-    ASSERT_EQ(true, res.no_timeout);
-}
-
-/*
- * Verify that onError callback is invoked
- */
-TEST_P(WifiOffloadHidlTest, getError) {
-    wifi_offload_->setEventCallback(wifi_offload_cb_);
-    OffloadStatus status = {OffloadStatusCode::ERROR, ""};
-    wifi_offload_cb_->onError(status);
-    auto res = wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendError);
-    ASSERT_EQ(true, res.no_timeout);
-}
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiOffloadHidlTest);
-INSTANTIATE_TEST_SUITE_P(
-    PerInstance, WifiOffloadHidlTest,
-    testing::ValuesIn(
-        android::hardware::getAllHalInstanceNames(IOffload::descriptor)),
-    android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/offload/1.0/vts/functional/hidl_call_util.h b/wifi/offload/1.0/vts/functional/hidl_call_util.h
deleted file mode 100644
index 99868e8..0000000
--- a/wifi/offload/1.0/vts/functional/hidl_call_util.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2017 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 <functional>
-#include <tuple>
-#include <type_traits>
-#include <utility>
-
-namespace {
-namespace detail {
-template <typename>
-struct functionArgSaver;
-
-// Provides a std::function that takes one argument, and a buffer
-// wherein the function will store its argument. The buffer has
-// the same type as the argument, but with const and reference
-// modifiers removed.
-template <typename ArgT>
-struct functionArgSaver<std::function<void(ArgT)>> final {
-    using StorageT = typename std::remove_const<
-        typename std::remove_reference<ArgT>::type>::type;
-
-    std::function<void(ArgT)> saveArgs = [this](ArgT arg) {
-        this->saved_values = arg;
-    };
-
-    StorageT saved_values;
-};
-
-// Provides a std::function that takes two arguments, and a buffer
-// wherein the function will store its arguments. The buffer is a
-// std::pair, whose elements have the same types as the arguments
-// (but with const and reference modifiers removed).
-template <typename Arg1T, typename Arg2T>
-struct functionArgSaver<std::function<void(Arg1T, Arg2T)>> final {
-    using StorageT =
-        std::pair<typename std::remove_const<
-                      typename std::remove_reference<Arg1T>::type>::type,
-                  typename std::remove_const<
-                      typename std::remove_reference<Arg2T>::type>::type>;
-
-    std::function<void(Arg1T, Arg2T)> saveArgs = [this](Arg1T arg1,
-                                                        Arg2T arg2) {
-        this->saved_values = {arg1, arg2};
-    };
-
-    StorageT saved_values;
-};
-
-// Provides a std::function that takes three or more arguments, and a
-// buffer wherein the function will store its arguments. The buffer is a
-// std::tuple whose elements have the same types as the arguments (but
-// with const and reference modifiers removed).
-template <typename... ArgT>
-struct functionArgSaver<std::function<void(ArgT...)>> final {
-    using StorageT = std::tuple<typename std::remove_const<
-        typename std::remove_reference<ArgT>::type>::type...>;
-
-    std::function<void(ArgT...)> saveArgs = [this](ArgT... arg) {
-        this->saved_values = {arg...};
-    };
-
-    StorageT saved_values;
-};
-
-// Invokes |method| on |object|, providing |method| a CallbackT as the
-// final argument. Returns a copy of the parameters that |method| provided
-// to CallbackT. (The parameters are returned by value.)
-template <typename CallbackT, typename MethodT, typename ObjectT,
-          typename... ArgT>
-typename functionArgSaver<CallbackT>::StorageT invokeMethod(
-    MethodT method, ObjectT object, ArgT&&... methodArg) {
-    functionArgSaver<CallbackT> result_buffer;
-    const auto& res = ((*object).*method)(std::forward<ArgT>(methodArg)...,
-                                          result_buffer.saveArgs);
-    EXPECT_TRUE(res.isOk());
-    return result_buffer.saved_values;
-}
-}  // namespace detail
-}  // namespace
-
-// Invokes |method| on |strong_pointer|, passing provided arguments through to
-// |method|.
-//
-// Returns either:
-// - A copy of the result callback parameter (for callbacks with a single
-//   parameter), OR
-// - A pair containing a copy of the result callback parameters (for callbacks
-//   with two parameters), OR
-// - A tuple containing a copy of the result callback paramters (for callbacks
-//   with three or more parameters).
-//
-// Example usage:
-//   EXPECT_EQ(WifiStatusCode::SUCCESS,
-//       HIDL_INVOKE(strong_pointer, methodReturningWifiStatus).code);
-//   EXPECT_EQ(WifiStatusCode::SUCCESS,
-//       HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndOneMore)
-//         .first.code);
-//   EXPECT_EQ(WifiStatusCode::SUCCESS, std::get<0>(
-//       HIDL_INVOKE(strong_pointer, methodReturningWifiStatusAndTwoMore))
-//         .code);
-#define HIDL_INVOKE(strong_pointer, method, ...)                              \
-    (detail::invokeMethod<                                                    \
-        std::remove_reference<decltype(*strong_pointer)>::type::method##_cb>( \
-        &std::remove_reference<decltype(*strong_pointer)>::type::method,      \
-        strong_pointer, ##__VA_ARGS__))
diff --git a/wifi/supplicant/1.0/vts/OWNERS b/wifi/supplicant/1.0/vts/OWNERS
deleted file mode 100644
index b16dc11..0000000
--- a/wifi/supplicant/1.0/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.3/vts/OWNERS
diff --git a/wifi/supplicant/1.1/vts/OWNERS b/wifi/supplicant/1.1/vts/OWNERS
deleted file mode 100644
index b16dc11..0000000
--- a/wifi/supplicant/1.1/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.3/vts/OWNERS
diff --git a/wifi/supplicant/1.2/vts/OWNERS b/wifi/supplicant/1.2/vts/OWNERS
deleted file mode 100644
index b16dc11..0000000
--- a/wifi/supplicant/1.2/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.3/vts/OWNERS
diff --git a/wifi/supplicant/1.4/vts/OWNERS b/wifi/supplicant/1.4/vts/OWNERS
deleted file mode 100644
index b16dc11..0000000
--- a/wifi/supplicant/1.4/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 33618
-include ../../1.3/vts/OWNERS
diff --git a/wifi/supplicant/OWNERS b/wifi/supplicant/OWNERS
deleted file mode 100644
index 7febd60..0000000
--- a/wifi/supplicant/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 33618
-arabawy@google.com
-etancohen@google.com
-gbiren@google.com
-lzye@google.com
diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp
index ca0785b..ac5a952 100644
--- a/wifi/supplicant/aidl/Android.bp
+++ b/wifi/supplicant/aidl/Android.bp
@@ -36,11 +36,14 @@
                 "com.android.wifi",
             ],
             min_sdk_version: "30",
+            lint: {
+                // Disable linter to avoid error about fixed size arrays.
+                // Interface will only be accessed on devices >= T.
+                enabled: false,
+            },
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
+            gen_trace: true,
         },
     },
     versions_with_info: [
@@ -48,6 +51,12 @@
             version: "1",
             imports: [],
         },
+        {
+            version: "2",
+            imports: [],
+        },
+
     ],
+    frozen: true,
 
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/.hash b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/.hash
new file mode 100644
index 0000000..e691512
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/.hash
@@ -0,0 +1 @@
+5e5c6d9e5565999f73fa7f797f5b94616174745b
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AnqpData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AnqpData.aidl
new file mode 100644
index 0000000..d8e49d7
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AnqpData.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable AnqpData {
+  byte[] venueName;
+  byte[] roamingConsortium;
+  byte[] ipAddrTypeAvailability;
+  byte[] naiRealm;
+  byte[] anqp3gppCellularNetwork;
+  byte[] domainName;
+  byte[] venueUrl;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AnqpInfoId.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AnqpInfoId.aidl
new file mode 100644
index 0000000..cc32360
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AnqpInfoId.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum AnqpInfoId {
+  VENUE_NAME = 258,
+  ROAMING_CONSORTIUM = 261,
+  IP_ADDR_TYPE_AVAILABILITY = 262,
+  NAI_REALM = 263,
+  ANQP_3GPP_CELLULAR_NETWORK = 264,
+  DOMAIN_NAME = 268,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AssociationRejectionData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AssociationRejectionData.aidl
new file mode 100644
index 0000000..f6830dc
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AssociationRejectionData.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable AssociationRejectionData {
+  byte[] ssid;
+  byte[] bssid;
+  android.hardware.wifi.supplicant.StaIfaceStatusCode statusCode;
+  boolean timedOut;
+  boolean isMboAssocDisallowedReasonCodePresent;
+  android.hardware.wifi.supplicant.MboAssocDisallowedReasonCode mboAssocDisallowedReason;
+  boolean isOceRssiBasedAssocRejectAttrPresent;
+  android.hardware.wifi.supplicant.OceRssiBasedAssocRejectAttr oceRssiBasedAssocRejectData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AuthAlgMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AuthAlgMask.aidl
new file mode 100644
index 0000000..4421018
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AuthAlgMask.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum AuthAlgMask {
+  OPEN = (1 << 0) /* 1 */,
+  SHARED = (1 << 1) /* 2 */,
+  LEAP = (1 << 2) /* 4 */,
+  SAE = (1 << 4) /* 16 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AuxiliarySupplicantEventCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AuxiliarySupplicantEventCode.aidl
new file mode 100644
index 0000000..a339a92
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/AuxiliarySupplicantEventCode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum AuxiliarySupplicantEventCode {
+  EAP_METHOD_SELECTED,
+  SSID_TEMP_DISABLED,
+  OPEN_SSL_FAILURE,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssTmData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssTmData.aidl
new file mode 100644
index 0000000..34d894d
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssTmData.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable BssTmData {
+  android.hardware.wifi.supplicant.BssTmStatusCode status;
+  android.hardware.wifi.supplicant.BssTmDataFlagsMask flags;
+  int assocRetryDelayMs;
+  android.hardware.wifi.supplicant.MboTransitionReasonCode mboTransitionReason;
+  android.hardware.wifi.supplicant.MboCellularDataConnectionPrefValue mboCellPreference;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl
new file mode 100644
index 0000000..6f0045c
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum BssTmDataFlagsMask {
+  WNM_MODE_PREFERRED_CANDIDATE_LIST_INCLUDED = (1 << 0) /* 1 */,
+  WNM_MODE_ABRIDGED = (1 << 1) /* 2 */,
+  WNM_MODE_DISASSOCIATION_IMMINENT = (1 << 2) /* 4 */,
+  WNM_MODE_BSS_TERMINATION_INCLUDED = (1 << 3) /* 8 */,
+  WNM_MODE_ESS_DISASSOCIATION_IMMINENT = (1 << 4) /* 16 */,
+  MBO_TRANSITION_REASON_CODE_INCLUDED = (1 << 5) /* 32 */,
+  MBO_ASSOC_RETRY_DELAY_INCLUDED = (1 << 6) /* 64 */,
+  MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED = (1 << 7) /* 128 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssTmStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssTmStatusCode.aidl
new file mode 100644
index 0000000..c95825f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssTmStatusCode.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum BssTmStatusCode {
+  ACCEPT = 0,
+  REJECT_UNSPECIFIED = 1,
+  REJECT_INSUFFICIENT_BEACON = 2,
+  REJECT_INSUFFICIENT_CAPABITY = 3,
+  REJECT_BSS_TERMINATION_UNDESIRED = 4,
+  REJECT_BSS_TERMINATION_DELAY_REQUEST = 5,
+  REJECT_STA_CANDIDATE_LIST_PROVIDED = 6,
+  REJECT_NO_SUITABLE_CANDIDATES = 7,
+  REJECT_LEAVING_ESS = 8,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssidChangeReason.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssidChangeReason.aidl
new file mode 100644
index 0000000..1d24579
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BssidChangeReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum BssidChangeReason {
+  ASSOC_START = 0,
+  ASSOC_COMPLETE = 1,
+  DISASSOC = 2,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
new file mode 100644
index 0000000..bdc1b4a
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum BtCoexistenceMode {
+  ENABLED = 0,
+  DISABLED = 1,
+  SENSE = 2,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
new file mode 100644
index 0000000..553cbc8
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable ConnectionCapabilities {
+  android.hardware.wifi.supplicant.WifiTechnology technology;
+  int channelBandwidth;
+  int maxNumberTxSpatialStreams;
+  int maxNumberRxSpatialStreams;
+  android.hardware.wifi.supplicant.LegacyMode legacyMode;
+  boolean apTidToLinkMapNegotiationSupported;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DebugLevel.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DebugLevel.aidl
new file mode 100644
index 0000000..fbfb5b3
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DebugLevel.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DebugLevel {
+  EXCESSIVE = 0,
+  MSGDUMP = 1,
+  DEBUG = 2,
+  INFO = 3,
+  WARNING = 4,
+  ERROR = 5,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppAkm.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppAkm.aidl
new file mode 100644
index 0000000..730843d
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppAkm.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DppAkm {
+  PSK,
+  PSK_SAE,
+  SAE,
+  DPP,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppConfigurationData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppConfigurationData.aidl
new file mode 100644
index 0000000..2225330
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppConfigurationData.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable DppConfigurationData {
+  byte[] ssid;
+  String password;
+  byte[] psk;
+  android.hardware.wifi.supplicant.DppAkm securityAkm;
+  android.hardware.wifi.supplicant.DppConnectionKeys dppConnectionKeys;
+  boolean connStatusRequested;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppConnectionKeys.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppConnectionKeys.aidl
new file mode 100644
index 0000000..559d1c9
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppConnectionKeys.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable DppConnectionKeys {
+  byte[] connector;
+  byte[] cSign;
+  byte[] netAccessKey;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppCurve.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppCurve.aidl
new file mode 100644
index 0000000..14cb49f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppCurve.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DppCurve {
+  PRIME256V1,
+  SECP384R1,
+  SECP521R1,
+  BRAINPOOLP256R1,
+  BRAINPOOLP384R1,
+  BRAINPOOLP512R1,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppEventType.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppEventType.aidl
new file mode 100644
index 0000000..47c8cc0
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppEventType.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DppEventType {
+  CONFIGURATION_SENT,
+  CONFIGURATION_APPLIED,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppFailureCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppFailureCode.aidl
new file mode 100644
index 0000000..89fbc4b
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppFailureCode.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DppFailureCode {
+  INVALID_URI,
+  AUTHENTICATION,
+  NOT_COMPATIBLE,
+  CONFIGURATION,
+  BUSY,
+  TIMEOUT,
+  FAILURE,
+  NOT_SUPPORTED,
+  CONFIGURATION_REJECTED,
+  CANNOT_FIND_NETWORK,
+  ENROLLEE_AUTHENTICATION,
+  URI_GENERATION,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppNetRole.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppNetRole.aidl
new file mode 100644
index 0000000..77a910b
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppNetRole.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DppNetRole {
+  STA,
+  AP,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppProgressCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppProgressCode.aidl
new file mode 100644
index 0000000..ea244de
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppProgressCode.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DppProgressCode {
+  AUTHENTICATION_SUCCESS,
+  RESPONSE_PENDING,
+  CONFIGURATION_SENT_WAITING_RESPONSE,
+  CONFIGURATION_ACCEPTED,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl
new file mode 100644
index 0000000..8b6492b
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable DppResponderBootstrapInfo {
+  int bootstrapId;
+  int listenChannel;
+  String uri;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl
new file mode 100644
index 0000000..21f07dd
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DppStatusErrorCode {
+  UNKNOWN = (-1) /* -1 */,
+  SUCCESS = 0,
+  NOT_COMPATIBLE = 1,
+  AUTH_FAILURE = 2,
+  UNWRAP_FAILURE = 3,
+  BAD_GROUP = 4,
+  CONFIGURE_FAILURE = 5,
+  RESPONSE_PENDING = 6,
+  INVALID_CONNECTOR = 7,
+  NO_MATCH = 8,
+  CONFIG_REJECTED = 9,
+  NO_AP = 10,
+  CONFIGURE_PENDING = 11,
+  CSR_NEEDED = 12,
+  CSR_BAD = 13,
+  NEW_KEY_NEEDED = 14,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/EapErrorCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/EapErrorCode.aidl
new file mode 100644
index 0000000..2cf81d9
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/EapErrorCode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum EapErrorCode {
+  SIM_GENERAL_FAILURE_AFTER_AUTH = 0,
+  SIM_TEMPORARILY_DENIED = 1026,
+  SIM_NOT_SUBSCRIBED = 1031,
+  SIM_GENERAL_FAILURE_BEFORE_AUTH = 16384,
+  SIM_VENDOR_SPECIFIC_EXPIRED_CERT = 16385,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/EapMethod.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/EapMethod.aidl
new file mode 100644
index 0000000..4ab23af
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/EapMethod.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum EapMethod {
+  PEAP = 0,
+  TLS = 1,
+  TTLS = 2,
+  PWD = 3,
+  SIM = 4,
+  AKA = 5,
+  AKA_PRIME = 6,
+  WFA_UNAUTH_TLS = 7,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/EapPhase2Method.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/EapPhase2Method.aidl
new file mode 100644
index 0000000..4bd93a0
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/EapPhase2Method.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum EapPhase2Method {
+  NONE = 0,
+  PAP = 1,
+  MSPAP = 2,
+  MSPAPV2 = 3,
+  GTC = 4,
+  SIM = 5,
+  AKA = 6,
+  AKA_PRIME = 7,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
new file mode 100644
index 0000000..cbf1a3e
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum ExtRadioWorkDefaults {
+  TIMEOUT_IN_SECS = 10,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/FreqRange.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/FreqRange.aidl
new file mode 100644
index 0000000..0971d51
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/FreqRange.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable FreqRange {
+  int min;
+  int max;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/GroupCipherMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/GroupCipherMask.aidl
new file mode 100644
index 0000000..d22d3d0
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/GroupCipherMask.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum GroupCipherMask {
+  WEP40 = (1 << 1) /* 2 */,
+  WEP104 = (1 << 2) /* 4 */,
+  TKIP = (1 << 3) /* 8 */,
+  CCMP = (1 << 4) /* 16 */,
+  GTK_NOT_USED = (1 << 14) /* 16384 */,
+  GCMP_256 = (1 << 8) /* 256 */,
+  SMS4 = (1 << 7) /* 128 */,
+  GCMP_128 = (1 << 6) /* 64 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/GroupMgmtCipherMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/GroupMgmtCipherMask.aidl
new file mode 100644
index 0000000..23bb04f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/GroupMgmtCipherMask.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum GroupMgmtCipherMask {
+  BIP_GMAC_128 = (1 << 11) /* 2048 */,
+  BIP_GMAC_256 = (1 << 12) /* 4096 */,
+  BIP_CMAC_256 = (1 << 13) /* 8192 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/GsmRand.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/GsmRand.aidl
new file mode 100644
index 0000000..599a683
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/GsmRand.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable GsmRand {
+  byte[] data;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/Hs20AnqpData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/Hs20AnqpData.aidl
new file mode 100644
index 0000000..43b182a
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/Hs20AnqpData.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable Hs20AnqpData {
+  byte[] operatorFriendlyName;
+  byte[] wanMetrics;
+  byte[] connectionCapability;
+  byte[] osuProvidersList;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
new file mode 100644
index 0000000..270d43b
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum Hs20AnqpSubtypes {
+  OPERATOR_FRIENDLY_NAME = 3,
+  WAN_METRICS = 4,
+  CONNECTION_CAPABILITY = 5,
+  OSU_PROVIDERS_LIST = 8,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
new file mode 100644
index 0000000..bcf0ea8
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+interface INonStandardCertCallback {
+  byte[] getBlob(in String alias);
+  String[] listAliases(in String prefix);
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicant.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicant.aidl
new file mode 100644
index 0000000..dd62167
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicant.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicant {
+  @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pIface addP2pInterface(in String ifName);
+  @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantStaIface addStaInterface(in String ifName);
+  android.hardware.wifi.supplicant.DebugLevel getDebugLevel();
+  @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pIface getP2pInterface(in String ifName);
+  @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantStaIface getStaInterface(in String ifName);
+  boolean isDebugShowKeysEnabled();
+  boolean isDebugShowTimestampEnabled();
+  android.hardware.wifi.supplicant.IfaceInfo[] listInterfaces();
+  void registerCallback(in android.hardware.wifi.supplicant.ISupplicantCallback callback);
+  void removeInterface(in android.hardware.wifi.supplicant.IfaceInfo ifaceInfo);
+  void setConcurrencyPriority(in android.hardware.wifi.supplicant.IfaceType type);
+  void setDebugParams(in android.hardware.wifi.supplicant.DebugLevel level, in boolean showTimestamp, in boolean showKeys);
+  oneway void terminate();
+  void registerNonStandardCertCallback(in android.hardware.wifi.supplicant.INonStandardCertCallback callback);
+  const int EXT_RADIO_WORK_TIMEOUT_IN_SECS = 10;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantCallback.aidl
new file mode 100644
index 0000000..7281053
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantCallback {
+  oneway void onInterfaceCreated(in String ifaceName);
+  oneway void onInterfaceRemoved(in String ifaceName);
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
new file mode 100644
index 0000000..19e6728
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -0,0 +1,100 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantP2pIface {
+  void addBonjourService(in byte[] query, in byte[] response);
+  void addGroup(in boolean persistent, in int persistentNetworkId);
+  void addGroupWithConfig(in byte[] ssid, in String pskPassphrase, in boolean persistent, in int freq, in byte[] peerAddress, in boolean joinExistingGroup);
+  @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pNetwork addNetwork();
+  void addUpnpService(in int version, in String serviceName);
+  void cancelConnect();
+  void cancelServiceDiscovery(in long identifier);
+  void cancelWps(in String groupIfName);
+  void configureExtListen(in int periodInMillis, in int intervalInMillis);
+  String connect(in byte[] peerAddress, in android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod, in String preSelectedPin, in boolean joinExistingGroup, in boolean persistent, in int goIntent);
+  byte[] createNfcHandoverRequestMessage();
+  byte[] createNfcHandoverSelectMessage();
+  void enableWfd(in boolean enable);
+  void find(in int timeoutInSec);
+  void flush();
+  void flushServices();
+  byte[] getDeviceAddress();
+  boolean getEdmg();
+  android.hardware.wifi.supplicant.P2pGroupCapabilityMask getGroupCapability(in byte[] peerAddress);
+  String getName();
+  @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pNetwork getNetwork(in int id);
+  byte[] getSsid(in byte[] peerAddress);
+  android.hardware.wifi.supplicant.IfaceType getType();
+  void invite(in String groupIfName, in byte[] goDeviceAddress, in byte[] peerAddress);
+  int[] listNetworks();
+  void provisionDiscovery(in byte[] peerAddress, in android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod);
+  void registerCallback(in android.hardware.wifi.supplicant.ISupplicantP2pIfaceCallback callback);
+  void reinvoke(in int persistentNetworkId, in byte[] peerAddress);
+  void reject(in byte[] peerAddress);
+  void removeBonjourService(in byte[] query);
+  void removeGroup(in String groupIfName);
+  void removeNetwork(in int id);
+  void removeUpnpService(in int version, in String serviceName);
+  void reportNfcHandoverInitiation(in byte[] select);
+  void reportNfcHandoverResponse(in byte[] request);
+  long requestServiceDiscovery(in byte[] peerAddress, in byte[] query);
+  void saveConfig();
+  void setDisallowedFrequencies(in android.hardware.wifi.supplicant.FreqRange[] ranges);
+  void setEdmg(in boolean enable);
+  void setGroupIdle(in String groupIfName, in int timeoutInSec);
+  void setListenChannel(in int channel, in int operatingClass);
+  void setMacRandomization(in boolean enable);
+  void setMiracastMode(in android.hardware.wifi.supplicant.MiracastMode mode);
+  void setPowerSave(in String groupIfName, in boolean enable);
+  void setSsidPostfix(in byte[] postfix);
+  void setWfdDeviceInfo(in byte[] info);
+  void setWfdR2DeviceInfo(in byte[] info);
+  void removeClient(in byte[] peerAddress, in boolean isLegacyClient);
+  void setWpsConfigMethods(in android.hardware.wifi.supplicant.WpsConfigMethods configMethods);
+  void setWpsDeviceName(in String name);
+  void setWpsDeviceType(in byte[] type);
+  void setWpsManufacturer(in String manufacturer);
+  void setWpsModelName(in String modelName);
+  void setWpsModelNumber(in String modelNumber);
+  void setWpsSerialNumber(in String serialNumber);
+  void startWpsPbc(in String groupIfName, in byte[] bssid);
+  String startWpsPinDisplay(in String groupIfName, in byte[] bssid);
+  void startWpsPinKeypad(in String groupIfName, in String pin);
+  void stopFind();
+  void findOnSocialChannels(in int timeoutInSec);
+  void findOnSpecificFrequency(in int freqInHz, in int timeoutInSec);
+  void setVendorElements(in android.hardware.wifi.supplicant.P2pFrameTypeMask frameTypeMask, in byte[] vendorElemBytes);
+  void configureEapolIpAddressAllocationParams(in int ipAddressGo, in int ipAddressMask, in int ipAddressStart, in int ipAddressEnd);
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
new file mode 100644
index 0000000..da3ca52
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantP2pIfaceCallback {
+  oneway void onDeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo);
+  oneway void onDeviceLost(in byte[] p2pDeviceAddress);
+  oneway void onFindStopped();
+  oneway void onGoNegotiationCompleted(in android.hardware.wifi.supplicant.P2pStatusCode status);
+  oneway void onGoNegotiationRequest(in byte[] srcAddress, in android.hardware.wifi.supplicant.WpsDevPasswordId passwordId);
+  oneway void onGroupFormationFailure(in String failureReason);
+  oneway void onGroupFormationSuccess();
+  oneway void onGroupRemoved(in String groupIfname, in boolean isGroupOwner);
+  oneway void onGroupStarted(in String groupIfname, in boolean isGroupOwner, in byte[] ssid, in int frequency, in byte[] psk, in String passphrase, in byte[] goDeviceAddress, in boolean isPersistent);
+  oneway void onInvitationReceived(in byte[] srcAddress, in byte[] goDeviceAddress, in byte[] bssid, in int persistentNetworkId, in int operatingFrequency);
+  oneway void onInvitationResult(in byte[] bssid, in android.hardware.wifi.supplicant.P2pStatusCode status);
+  oneway void onProvisionDiscoveryCompleted(in byte[] p2pDeviceAddress, in boolean isRequest, in android.hardware.wifi.supplicant.P2pProvDiscStatusCode status, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in String generatedPin);
+  oneway void onR2DeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo);
+  oneway void onServiceDiscoveryResponse(in byte[] srcAddress, in char updateIndicator, in byte[] tlvs);
+  oneway void onStaAuthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
+  oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
+  oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency);
+  oneway void onDeviceFoundWithVendorElements(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo, in byte[] vendorElemBytes);
+  oneway void onGroupStartedWithParams(in android.hardware.wifi.supplicant.P2pGroupStartedEventParams groupStartedEventParams);
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl
new file mode 100644
index 0000000..ef72724
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantP2pNetwork {
+  byte[] getBssid();
+  android.hardware.wifi.supplicant.MacAddress[] getClientList();
+  int getId();
+  String getInterfaceName();
+  byte[] getSsid();
+  android.hardware.wifi.supplicant.IfaceType getType();
+  boolean isCurrent();
+  boolean isGroupOwner();
+  boolean isPersistent();
+  void setClientList(in android.hardware.wifi.supplicant.MacAddress[] clients);
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
new file mode 100644
index 0000000..1616b26
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -0,0 +1,102 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantStaIface {
+  int addDppPeerUri(in String uri);
+  int addExtRadioWork(in String name, in int freqInMhz, in int timeoutInSec);
+  @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantStaNetwork addNetwork();
+  void addRxFilter(in android.hardware.wifi.supplicant.RxFilterType type);
+  void cancelWps();
+  void disconnect();
+  void enableAutoReconnect(in boolean enable);
+  void filsHlpAddRequest(in byte[] dst_mac, in byte[] pkt);
+  void filsHlpFlushRequest();
+  android.hardware.wifi.supplicant.DppResponderBootstrapInfo generateDppBootstrapInfoForResponder(in byte[] macAddress, in String deviceInfo, in android.hardware.wifi.supplicant.DppCurve curve);
+  void generateSelfDppConfiguration(in String ssid, in byte[] privEcKey);
+  android.hardware.wifi.supplicant.ConnectionCapabilities getConnectionCapabilities();
+  android.hardware.wifi.supplicant.MloLinksInfo getConnectionMloLinksInfo();
+  android.hardware.wifi.supplicant.KeyMgmtMask getKeyMgmtCapabilities();
+  byte[] getMacAddress();
+  String getName();
+  @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantStaNetwork getNetwork(in int id);
+  android.hardware.wifi.supplicant.IfaceType getType();
+  android.hardware.wifi.supplicant.WpaDriverCapabilitiesMask getWpaDriverCapabilities();
+  void initiateAnqpQuery(in byte[] macAddress, in android.hardware.wifi.supplicant.AnqpInfoId[] infoElements, in android.hardware.wifi.supplicant.Hs20AnqpSubtypes[] subTypes);
+  void initiateHs20IconQuery(in byte[] macAddress, in String fileName);
+  void initiateTdlsDiscover(in byte[] macAddress);
+  void initiateTdlsSetup(in byte[] macAddress);
+  void initiateTdlsTeardown(in byte[] macAddress);
+  void initiateVenueUrlAnqpQuery(in byte[] macAddress);
+  int[] listNetworks();
+  void reassociate();
+  void reconnect();
+  void registerCallback(in android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback callback);
+  void setQosPolicyFeatureEnabled(in boolean enable);
+  void sendQosPolicyResponse(in int qosPolicyRequestId, in boolean morePolicies, in android.hardware.wifi.supplicant.QosPolicyStatus[] qosPolicyStatusList);
+  void removeAllQosPolicies();
+  void removeDppUri(in int id);
+  void removeExtRadioWork(in int id);
+  void removeNetwork(in int id);
+  void removeRxFilter(in android.hardware.wifi.supplicant.RxFilterType type);
+  void setBtCoexistenceMode(in android.hardware.wifi.supplicant.BtCoexistenceMode mode);
+  void setBtCoexistenceScanModeEnabled(in boolean enable);
+  void setCountryCode(in byte[] code);
+  void setExternalSim(in boolean useExternalSim);
+  void setMboCellularDataStatus(in boolean available);
+  void setPowerSave(in boolean enable);
+  void setSuspendModeEnabled(in boolean enable);
+  void setWpsConfigMethods(in android.hardware.wifi.supplicant.WpsConfigMethods configMethods);
+  void setWpsDeviceName(in String name);
+  void setWpsDeviceType(in byte[] type);
+  void setWpsManufacturer(in String manufacturer);
+  void setWpsModelName(in String modelName);
+  void setWpsModelNumber(in String modelNumber);
+  void setWpsSerialNumber(in String serialNumber);
+  byte[] startDppConfiguratorInitiator(in int peerBootstrapId, in int ownBootstrapId, in String ssid, in String password, in String psk, in android.hardware.wifi.supplicant.DppNetRole netRole, in android.hardware.wifi.supplicant.DppAkm securityAkm, in byte[] privEcKey);
+  void startDppEnrolleeInitiator(in int peerBootstrapId, in int ownBootstrapId);
+  void startDppEnrolleeResponder(in int listenChannel);
+  void startRxFilter();
+  void startWpsPbc(in byte[] bssid);
+  String startWpsPinDisplay(in byte[] bssid);
+  void startWpsPinKeypad(in String pin);
+  void startWpsRegistrar(in byte[] bssid, in String pin);
+  void stopDppInitiator();
+  void stopDppResponder(in int ownBootstrapId);
+  void stopRxFilter();
+  android.hardware.wifi.supplicant.SignalPollResult[] getSignalPollResults();
+  android.hardware.wifi.supplicant.QosPolicyScsRequestStatus[] addQosPolicyRequestForScs(in android.hardware.wifi.supplicant.QosPolicyScsData[] qosPolicyData);
+  android.hardware.wifi.supplicant.QosPolicyScsRequestStatus[] removeQosPolicyForScs(in byte[] scsPolicyIds);
+  const int MAX_POLICIES_PER_QOS_SCS_REQUEST = 16;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
new file mode 100644
index 0000000..1c23223
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -0,0 +1,87 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantStaIfaceCallback {
+  oneway void onAnqpQueryDone(in byte[] bssid, in android.hardware.wifi.supplicant.AnqpData data, in android.hardware.wifi.supplicant.Hs20AnqpData hs20Data);
+  oneway void onAssociationRejected(in android.hardware.wifi.supplicant.AssociationRejectionData assocRejectData);
+  oneway void onAuthenticationTimeout(in byte[] bssid);
+  oneway void onAuxiliarySupplicantEvent(in android.hardware.wifi.supplicant.AuxiliarySupplicantEventCode eventCode, in byte[] bssid, in String reasonString);
+  oneway void onBssTmHandlingDone(in android.hardware.wifi.supplicant.BssTmData tmData);
+  oneway void onBssidChanged(in android.hardware.wifi.supplicant.BssidChangeReason reason, in byte[] bssid);
+  oneway void onDisconnected(in byte[] bssid, in boolean locallyGenerated, in android.hardware.wifi.supplicant.StaIfaceReasonCode reasonCode);
+  oneway void onDppFailure(in android.hardware.wifi.supplicant.DppFailureCode code, in String ssid, in String channelList, in char[] bandList);
+  oneway void onDppProgress(in android.hardware.wifi.supplicant.DppProgressCode code);
+  oneway void onDppSuccess(in android.hardware.wifi.supplicant.DppEventType event);
+  /**
+   * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onDppConfigReceived.
+   */
+  oneway void onDppSuccessConfigReceived(in byte[] ssid, in String password, in byte[] psk, in android.hardware.wifi.supplicant.DppAkm securityAkm, in android.hardware.wifi.supplicant.DppConnectionKeys dppConnectionKeys);
+  oneway void onDppSuccessConfigSent();
+  oneway void onEapFailure(in byte[] bssid, in int errorCode);
+  oneway void onExtRadioWorkStart(in int id);
+  oneway void onExtRadioWorkTimeout(in int id);
+  oneway void onHs20DeauthImminentNotice(in byte[] bssid, in int reasonCode, in int reAuthDelayInSec, in String url);
+  oneway void onHs20IconQueryDone(in byte[] bssid, in String fileName, in byte[] data);
+  oneway void onHs20SubscriptionRemediation(in byte[] bssid, in android.hardware.wifi.supplicant.OsuMethod osuMethod, in String url);
+  oneway void onHs20TermsAndConditionsAcceptanceRequestedNotification(in byte[] bssid, in String url);
+  oneway void onNetworkAdded(in int id);
+  oneway void onNetworkNotFound(in byte[] ssid);
+  oneway void onNetworkRemoved(in int id);
+  /**
+   * @deprecated use onPmkSaCacheAdded() instead.
+   */
+  oneway void onPmkCacheAdded(in long expirationTimeInSec, in byte[] serializedEntry);
+  /**
+   * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onSupplicantStateChanged()
+   */
+  oneway void onStateChanged(in android.hardware.wifi.supplicant.StaIfaceCallbackState newState, in byte[] bssid, in int id, in byte[] ssid, in boolean filsHlpSent);
+  oneway void onWpsEventFail(in byte[] bssid, in android.hardware.wifi.supplicant.WpsConfigError configError, in android.hardware.wifi.supplicant.WpsErrorIndication errorInd);
+  oneway void onWpsEventPbcOverlap();
+  oneway void onWpsEventSuccess();
+  oneway void onQosPolicyReset();
+  oneway void onQosPolicyRequest(in int qosPolicyRequestId, in android.hardware.wifi.supplicant.QosPolicyData[] qosPolicyData);
+  oneway void onMloLinksInfoChanged(in android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback.MloLinkInfoChangeReason reason);
+  oneway void onDppConfigReceived(in android.hardware.wifi.supplicant.DppConfigurationData configData);
+  oneway void onDppConnectionStatusResultSent(in android.hardware.wifi.supplicant.DppStatusErrorCode code);
+  oneway void onBssFrequencyChanged(in int frequencyMhz);
+  oneway void onSupplicantStateChanged(in android.hardware.wifi.supplicant.SupplicantStateChangeData stateChangeData);
+  oneway void onQosPolicyResponseForScs(in android.hardware.wifi.supplicant.QosPolicyScsResponseStatus[] qosPolicyScsResponseStatus);
+  oneway void onPmkSaCacheAdded(in android.hardware.wifi.supplicant.PmkSaCacheData pmkSaData);
+  @Backing(type="int") @VintfStability
+  enum MloLinkInfoChangeReason {
+    TID_TO_LINK_MAP = 0,
+    MULTI_LINK_RECONFIG_AP_REMOVAL = 1,
+  }
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
new file mode 100644
index 0000000..bfc05a4
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -0,0 +1,138 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantStaNetwork {
+  void disable();
+  void enable(in boolean noConnect);
+  void enableSaePkOnlyMode(in boolean enable);
+  void enableSuiteBEapOpenSslCiphers();
+  void enableTlsSuiteBEapPhase1Param(in boolean enable);
+  android.hardware.wifi.supplicant.AuthAlgMask getAuthAlg();
+  byte[] getBssid();
+  String getEapAltSubjectMatch();
+  byte[] getEapAnonymousIdentity();
+  String getEapCACert();
+  String getEapCAPath();
+  String getEapClientCert();
+  String getEapDomainSuffixMatch();
+  boolean getEapEngine();
+  String getEapEngineId();
+  byte[] getEapIdentity();
+  android.hardware.wifi.supplicant.EapMethod getEapMethod();
+  byte[] getEapPassword();
+  android.hardware.wifi.supplicant.EapPhase2Method getEapPhase2Method();
+  String getEapPrivateKeyId();
+  String getEapSubjectMatch();
+  boolean getEdmg();
+  android.hardware.wifi.supplicant.GroupCipherMask getGroupCipher();
+  android.hardware.wifi.supplicant.GroupMgmtCipherMask getGroupMgmtCipher();
+  int getId();
+  String getIdStr();
+  String getInterfaceName();
+  android.hardware.wifi.supplicant.KeyMgmtMask getKeyMgmt();
+  android.hardware.wifi.supplicant.OcspType getOcsp();
+  android.hardware.wifi.supplicant.PairwiseCipherMask getPairwiseCipher();
+  android.hardware.wifi.supplicant.ProtoMask getProto();
+  byte[] getPsk();
+  String getPskPassphrase();
+  boolean getRequirePmf();
+  String getSaePassword();
+  String getSaePasswordId();
+  boolean getScanSsid();
+  byte[] getSsid();
+  android.hardware.wifi.supplicant.IfaceType getType();
+  String getWapiCertSuite();
+  byte[] getWepKey(in int keyIdx);
+  int getWepTxKeyIdx();
+  byte[] getWpsNfcConfigurationToken();
+  void registerCallback(in android.hardware.wifi.supplicant.ISupplicantStaNetworkCallback callback);
+  void select();
+  void sendNetworkEapIdentityResponse(in byte[] identity, in byte[] encryptedIdentity);
+  void sendNetworkEapSimGsmAuthFailure();
+  void sendNetworkEapSimGsmAuthResponse(in android.hardware.wifi.supplicant.NetworkResponseEapSimGsmAuthParams[] params);
+  void sendNetworkEapSimUmtsAuthFailure();
+  void sendNetworkEapSimUmtsAuthResponse(in android.hardware.wifi.supplicant.NetworkResponseEapSimUmtsAuthParams params);
+  void sendNetworkEapSimUmtsAutsResponse(in byte[] auts);
+  void setAuthAlg(in android.hardware.wifi.supplicant.AuthAlgMask authAlgMask);
+  void setBssid(in byte[] bssid);
+  void setDppKeys(in android.hardware.wifi.supplicant.DppConnectionKeys keys);
+  void setEapAltSubjectMatch(in String match);
+  void setEapAnonymousIdentity(in byte[] identity);
+  void setEapCACert(in String path);
+  void setEapCAPath(in String path);
+  void setEapClientCert(in String path);
+  void setEapDomainSuffixMatch(in String match);
+  void setEapEncryptedImsiIdentity(in byte[] identity);
+  void setEapEngine(in boolean enable);
+  void setEapEngineID(in String id);
+  void setEapErp(in boolean enable);
+  void setEapIdentity(in byte[] identity);
+  void setEapMethod(in android.hardware.wifi.supplicant.EapMethod method);
+  void setEapPassword(in byte[] password);
+  void setEapPhase2Method(in android.hardware.wifi.supplicant.EapPhase2Method method);
+  void setEapPrivateKeyId(in String id);
+  void setEapSubjectMatch(in String match);
+  void setEdmg(in boolean enable);
+  void setGroupCipher(in android.hardware.wifi.supplicant.GroupCipherMask groupCipherMask);
+  void setGroupMgmtCipher(in android.hardware.wifi.supplicant.GroupMgmtCipherMask groupMgmtCipherMask);
+  void setIdStr(in String idStr);
+  void setKeyMgmt(in android.hardware.wifi.supplicant.KeyMgmtMask keyMgmtMask);
+  void setOcsp(in android.hardware.wifi.supplicant.OcspType ocspType);
+  void setPairwiseCipher(in android.hardware.wifi.supplicant.PairwiseCipherMask pairwiseCipherMask);
+  void setPmkCache(in byte[] serializedEntry);
+  void setProactiveKeyCaching(in boolean enable);
+  void setProto(in android.hardware.wifi.supplicant.ProtoMask protoMask);
+  void setPsk(in byte[] psk);
+  void setPskPassphrase(in String psk);
+  void setRequirePmf(in boolean enable);
+  void setSaeH2eMode(in android.hardware.wifi.supplicant.SaeH2eMode mode);
+  void setSaePassword(in String saePassword);
+  void setSaePasswordId(in String saePasswordId);
+  void setScanSsid(in boolean enable);
+  void setSsid(in byte[] ssid);
+  void setUpdateIdentifier(in int id);
+  void setWapiCertSuite(in String suite);
+  void setWepKey(in int keyIdx, in byte[] wepKey);
+  void setWepTxKeyIdx(in int keyIdx);
+  void setRoamingConsortiumSelection(in byte[] selectedRcoi);
+  void setMinimumTlsVersionEapPhase1Param(android.hardware.wifi.supplicant.TlsVersion tlsVersion);
+  void setStrictConservativePeerMode(in boolean enable);
+  const int SSID_MAX_LEN_IN_BYTES = 32;
+  const int PSK_PASSPHRASE_MIN_LEN_IN_BYTES = 8;
+  const int PSK_PASSPHRASE_MAX_LEN_IN_BYTES = 63;
+  const int WEP_KEYS_MAX_NUM = 4;
+  const int WEP40_KEY_LEN_IN_BYTES = 5;
+  const int WEP104_KEY_LEN_IN_BYTES = 13;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
new file mode 100644
index 0000000..f9a078b
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantStaNetworkCallback {
+  oneway void onNetworkEapIdentityRequest();
+  oneway void onNetworkEapSimGsmAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimGsmAuthParams params);
+  oneway void onNetworkEapSimUmtsAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams params);
+  oneway void onTransitionDisable(in android.hardware.wifi.supplicant.TransitionDisableIndication ind);
+  oneway void onServerCertificateAvailable(in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
+  oneway void onPermanentIdReqDenied();
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/IfaceInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/IfaceInfo.aidl
new file mode 100644
index 0000000..6706c8c
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/IfaceInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable IfaceInfo {
+  android.hardware.wifi.supplicant.IfaceType type;
+  String name;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/IfaceType.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/IfaceType.aidl
new file mode 100644
index 0000000..e11c2f7
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/IfaceType.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum IfaceType {
+  STA,
+  P2P,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/IpVersion.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/IpVersion.aidl
new file mode 100644
index 0000000..9580314
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/IpVersion.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum IpVersion {
+  VERSION_4,
+  VERSION_6,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
new file mode 100644
index 0000000..35d51bc
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum KeyMgmtMask {
+  WPA_EAP = (1 << 0) /* 1 */,
+  WPA_PSK = (1 << 1) /* 2 */,
+  NONE = (1 << 2) /* 4 */,
+  IEEE8021X = (1 << 3) /* 8 */,
+  FT_EAP = (1 << 5) /* 32 */,
+  FT_PSK = (1 << 6) /* 64 */,
+  OSEN = (1 << 15) /* 32768 */,
+  WPA_EAP_SHA256 = (1 << 7) /* 128 */,
+  WPA_PSK_SHA256 = (1 << 8) /* 256 */,
+  SAE = (1 << 10) /* 1024 */,
+  SUITE_B_192 = (1 << 17) /* 131072 */,
+  OWE = (1 << 22) /* 4194304 */,
+  DPP = (1 << 23) /* 8388608 */,
+  WAPI_PSK = (1 << 12) /* 4096 */,
+  WAPI_CERT = (1 << 13) /* 8192 */,
+  FILS_SHA256 = (1 << 18) /* 262144 */,
+  FILS_SHA384 = (1 << 19) /* 524288 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/LegacyMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/LegacyMode.aidl
new file mode 100644
index 0000000..6896d75
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/LegacyMode.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum LegacyMode {
+  UNKNOWN = 0,
+  A_MODE = 1,
+  B_MODE = 2,
+  G_MODE = 3,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MacAddress.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MacAddress.aidl
new file mode 100644
index 0000000..d17930a
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MacAddress.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable MacAddress {
+  byte[] data;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl
new file mode 100644
index 0000000..661165d
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum MboAssocDisallowedReasonCode {
+  RESERVED = 0,
+  UNSPECIFIED = 1,
+  MAX_NUM_STA_ASSOCIATED = 2,
+  AIR_INTERFACE_OVERLOADED = 3,
+  AUTH_SERVER_OVERLOADED = 4,
+  INSUFFICIENT_RSSI = 5,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl
new file mode 100644
index 0000000..c4024d0
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum MboCellularDataConnectionPrefValue {
+  EXCLUDED = 0,
+  NOT_PREFERRED = 1,
+  PREFERRED = 255,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl
new file mode 100644
index 0000000..caed095
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum MboTransitionReasonCode {
+  UNSPECIFIED = 0,
+  EXCESSIVE_FRAME_LOSS = 1,
+  EXCESSIVE_TRAFFIC_DELAY = 2,
+  INSUFFICIENT_BANDWIDTH = 3,
+  LOAD_BALANCING = 4,
+  LOW_RSSI = 5,
+  RX_EXCESSIVE_RETRIES = 6,
+  HIGH_INTERFERENCE = 7,
+  GRAY_ZONE = 8,
+  TRANSITION_TO_PREMIUM_AP = 9,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MiracastMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MiracastMode.aidl
new file mode 100644
index 0000000..6bc9e4d
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MiracastMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum MiracastMode {
+  DISABLED = 0,
+  SOURCE = 1,
+  SINK = 2,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MloLink.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MloLink.aidl
new file mode 100644
index 0000000..8bda324
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MloLink.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable MloLink {
+  byte linkId;
+  byte[] staLinkMacAddress;
+  byte tidsUplinkMap;
+  byte tidsDownlinkMap;
+  @nullable byte[6] apLinkMacAddress;
+  int frequencyMHz;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MloLinksInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MloLinksInfo.aidl
new file mode 100644
index 0000000..3dac2d6
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/MloLinksInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable MloLinksInfo {
+  android.hardware.wifi.supplicant.MloLink[] links;
+  int apMloLinkId;
+  @nullable byte[6] apMldMacAddress;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
new file mode 100644
index 0000000..1f03bb8
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable NetworkRequestEapSimGsmAuthParams {
+  android.hardware.wifi.supplicant.GsmRand[] rands;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
new file mode 100644
index 0000000..956a799
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable NetworkRequestEapSimUmtsAuthParams {
+  byte[] rand;
+  byte[] autn;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
new file mode 100644
index 0000000..29415b7
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable NetworkResponseEapSimGsmAuthParams {
+  byte[] kc;
+  byte[] sres;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
new file mode 100644
index 0000000..4e58dd8
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable NetworkResponseEapSimUmtsAuthParams {
+  byte[] res;
+  byte[] ik;
+  byte[] ck;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.aidl
new file mode 100644
index 0000000..95a95bc
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+parcelable OceRssiBasedAssocRejectAttr {
+  int deltaRssi;
+  int retryDelayS;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/OcspType.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/OcspType.aidl
new file mode 100644
index 0000000..d5ed084
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/OcspType.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum OcspType {
+  NONE,
+  REQUEST_CERT_STATUS,
+  REQUIRE_CERT_STATUS,
+  REQUIRE_ALL_CERTS_STATUS,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/OsuMethod.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/OsuMethod.aidl
new file mode 100644
index 0000000..1b99e2f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/OsuMethod.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum OsuMethod {
+  OMA_DM = 0,
+  SOAP_XML_SPP = 1,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl
new file mode 100644
index 0000000..db31ca1
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pClientEapolIpAddressInfo {
+  int ipAddressClient;
+  int ipAddressMask;
+  int ipAddressGo;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pFrameTypeMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pFrameTypeMask.aidl
new file mode 100644
index 0000000..3c6f8ed
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pFrameTypeMask.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum P2pFrameTypeMask {
+  P2P_FRAME_PROBE_REQ_P2P = (1 << 0) /* 1 */,
+  P2P_FRAME_PROBE_RESP_P2P = (1 << 1) /* 2 */,
+  P2P_FRAME_PROBE_RESP_P2P_GO = (1 << 2) /* 4 */,
+  P2P_FRAME_BEACON_P2P_GO = (1 << 3) /* 8 */,
+  P2P_FRAME_P2P_PD_REQ = (1 << 4) /* 16 */,
+  P2P_FRAME_P2P_PD_RESP = (1 << 5) /* 32 */,
+  P2P_FRAME_P2P_GO_NEG_REQ = (1 << 6) /* 64 */,
+  P2P_FRAME_P2P_GO_NEG_RESP = (1 << 7) /* 128 */,
+  P2P_FRAME_P2P_GO_NEG_CONF = (1 << 8) /* 256 */,
+  P2P_FRAME_P2P_INV_REQ = (1 << 9) /* 512 */,
+  P2P_FRAME_P2P_INV_RESP = (1 << 10) /* 1024 */,
+  P2P_FRAME_P2P_ASSOC_REQ = (1 << 11) /* 2048 */,
+  P2P_FRAME_P2P_ASSOC_RESP = (1 << 12) /* 4096 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl
new file mode 100644
index 0000000..e477131
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum P2pGroupCapabilityMask {
+  GROUP_OWNER = (1 << 0) /* 1 */,
+  PERSISTENT_GROUP = (1 << 1) /* 2 */,
+  GROUP_LIMIT = (1 << 2) /* 4 */,
+  INTRA_BSS_DIST = (1 << 3) /* 8 */,
+  CROSS_CONN = (1 << 4) /* 16 */,
+  PERSISTENT_RECONN = (1 << 5) /* 32 */,
+  GROUP_FORMATION = (1 << 6) /* 64 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
new file mode 100644
index 0000000..5465a86
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pGroupStartedEventParams {
+  String groupInterfaceName;
+  boolean isGroupOwner;
+  byte[] ssid;
+  int frequencyMHz;
+  byte[] psk;
+  String passphrase;
+  boolean isPersistent;
+  byte[6] goDeviceAddress;
+  byte[6] goInterfaceAddress;
+  boolean isP2pClientEapolIpAddressInfoPresent;
+  android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo p2pClientIpInfo;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
new file mode 100644
index 0000000..c8e53b9
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum P2pProvDiscStatusCode {
+  SUCCESS = 0,
+  TIMEOUT = 1,
+  REJECTED = 2,
+  TIMEOUT_JOIN = 3,
+  INFO_UNAVAILABLE = 4,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pStatusCode.aidl
new file mode 100644
index 0000000..c7ad383
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/P2pStatusCode.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum P2pStatusCode {
+  SUCCESS = 0,
+  FAIL_INFO_CURRENTLY_UNAVAILABLE = 1,
+  FAIL_INCOMPATIBLE_PARAMS = 2,
+  FAIL_LIMIT_REACHED = 3,
+  FAIL_INVALID_PARAMS = 4,
+  FAIL_UNABLE_TO_ACCOMMODATE = 5,
+  FAIL_PREV_PROTOCOL_ERROR = 6,
+  FAIL_NO_COMMON_CHANNELS = 7,
+  FAIL_UNKNOWN_GROUP = 8,
+  FAIL_BOTH_GO_INTENT_15 = 9,
+  FAIL_INCOMPATIBLE_PROV_METHOD = 10,
+  FAIL_REJECTED_BY_USER = 11,
+  SUCCESS_DEFERRED = 12,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
new file mode 100644
index 0000000..a4c7b60
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum PairwiseCipherMask {
+  NONE = (1 << 0) /* 1 */,
+  TKIP = (1 << 3) /* 8 */,
+  CCMP = (1 << 4) /* 16 */,
+  GCMP_128 = (1 << 6) /* 64 */,
+  SMS4 = (1 << 7) /* 128 */,
+  GCMP_256 = (1 << 8) /* 256 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/PmkSaCacheData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
new file mode 100644
index 0000000..c31b167
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable PmkSaCacheData {
+  byte[6] bssid;
+  long expirationTimeInSec;
+  byte[] serializedEntry;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/PortRange.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/PortRange.aidl
new file mode 100644
index 0000000..b2004f2
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/PortRange.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable PortRange {
+  int startPort;
+  int endPort;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ProtoMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ProtoMask.aidl
new file mode 100644
index 0000000..ba79025
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ProtoMask.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum ProtoMask {
+  WPA = (1 << 0) /* 1 */,
+  RSN = (1 << 1) /* 2 */,
+  WAPI = (1 << 2) /* 4 */,
+  OSEN = (1 << 3) /* 8 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ProtocolNextHeader.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ProtocolNextHeader.aidl
new file mode 100644
index 0000000..8fb91d0
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/ProtocolNextHeader.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum ProtocolNextHeader {
+  TCP = 6,
+  UDP = 17,
+  ESP = 50,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
new file mode 100644
index 0000000..156d57a
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosPolicyClassifierParams {
+  android.hardware.wifi.supplicant.IpVersion ipVersion;
+  android.hardware.wifi.supplicant.QosPolicyClassifierParamsMask classifierParamMask;
+  byte[] srcIp;
+  byte[] dstIp;
+  int srcPort;
+  android.hardware.wifi.supplicant.PortRange dstPortRange;
+  android.hardware.wifi.supplicant.ProtocolNextHeader protocolNextHdr;
+  byte[] flowLabelIpv6;
+  String domainName;
+  byte dscp;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
new file mode 100644
index 0000000..fda5e3e
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum QosPolicyClassifierParamsMask {
+  SRC_IP = (1 << 0) /* 1 */,
+  DST_IP = (1 << 1) /* 2 */,
+  SRC_PORT = (1 << 2) /* 4 */,
+  DST_PORT_RANGE = (1 << 3) /* 8 */,
+  PROTOCOL_NEXT_HEADER = (1 << 4) /* 16 */,
+  FLOW_LABEL = (1 << 5) /* 32 */,
+  DOMAIN_NAME = (1 << 6) /* 64 */,
+  DSCP = (1 << 7) /* 128 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyData.aidl
new file mode 100644
index 0000000..1719565
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyData.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosPolicyData {
+  byte policyId;
+  android.hardware.wifi.supplicant.QosPolicyRequestType requestType;
+  byte dscp;
+  android.hardware.wifi.supplicant.QosPolicyClassifierParams classifierParams;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyRequestType.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyRequestType.aidl
new file mode 100644
index 0000000..fd4e787
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyRequestType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum QosPolicyRequestType {
+  QOS_POLICY_ADD,
+  QOS_POLICY_REMOVE,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
new file mode 100644
index 0000000..4e5e8ae
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosPolicyScsData {
+  byte policyId;
+  byte userPriority;
+  android.hardware.wifi.supplicant.QosPolicyClassifierParams classifierParams;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
new file mode 100644
index 0000000..d5573af
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosPolicyScsRequestStatus {
+  byte policyId;
+  android.hardware.wifi.supplicant.QosPolicyScsRequestStatusCode qosPolicyScsRequestStatusCode;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
new file mode 100644
index 0000000..8e0467f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum QosPolicyScsRequestStatusCode {
+  SENT,
+  ALREADY_ACTIVE,
+  NOT_EXIST,
+  INVALID,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
new file mode 100644
index 0000000..2737f1a
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosPolicyScsResponseStatus {
+  byte policyId;
+  android.hardware.wifi.supplicant.QosPolicyScsResponseStatusCode qosPolicyScsResponseStatusCode;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
new file mode 100644
index 0000000..5d460c6
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum QosPolicyScsResponseStatusCode {
+  SUCCESS,
+  TCLAS_REQUEST_DECLINED,
+  TCLAS_NOT_SUPPORTED_BY_AP,
+  TCLAS_INSUFFICIENT_RESOURCES,
+  TCLAS_RESOURCES_EXHAUSTED,
+  TCLAS_PROCESSING_TERMINATED_INSUFFICIENT_QOS,
+  TCLAS_PROCESSING_TERMINATED_POLICY_CONFLICT,
+  TCLAS_PROCESSING_TERMINATED,
+  TIMEOUT,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyStatus.aidl
new file mode 100644
index 0000000..61278c5
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosPolicyStatus {
+  byte policyId;
+  android.hardware.wifi.supplicant.QosPolicyStatusCode status;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyStatusCode.aidl
new file mode 100644
index 0000000..9228632
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/QosPolicyStatusCode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum QosPolicyStatusCode {
+  QOS_POLICY_SUCCESS,
+  QOS_POLICY_REQUEST_DECLINED,
+  QOS_POLICY_CLASSIFIER_NOT_SUPPORTED,
+  QOS_POLICY_INSUFFICIENT_RESOURCES,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/RxFilterType.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/RxFilterType.aidl
new file mode 100644
index 0000000..63f5bf2
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/RxFilterType.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum RxFilterType {
+  V4_MULTICAST = 0,
+  V6_MULTICAST = 1,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SaeH2eMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SaeH2eMode.aidl
new file mode 100644
index 0000000..4730d72
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SaeH2eMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum SaeH2eMode {
+  DISABLED,
+  H2E_OPTIONAL,
+  H2E_MANDATORY,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SignalPollResult.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SignalPollResult.aidl
new file mode 100644
index 0000000..52d3f24
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SignalPollResult.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable SignalPollResult {
+  int linkId;
+  int currentRssiDbm;
+  int txBitrateMbps;
+  int rxBitrateMbps;
+  int frequencyMhz;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl
new file mode 100644
index 0000000..d78cfa2
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum StaIfaceCallbackState {
+  DISCONNECTED = 0,
+  IFACE_DISABLED = 1,
+  INACTIVE = 2,
+  SCANNING = 3,
+  AUTHENTICATING = 4,
+  ASSOCIATING = 5,
+  ASSOCIATED = 6,
+  FOURWAY_HANDSHAKE = 7,
+  GROUP_HANDSHAKE = 8,
+  COMPLETED = 9,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/StaIfaceReasonCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/StaIfaceReasonCode.aidl
new file mode 100644
index 0000000..f26e7c5
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/StaIfaceReasonCode.aidl
@@ -0,0 +1,98 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum StaIfaceReasonCode {
+  UNSPECIFIED = 1,
+  PREV_AUTH_NOT_VALID = 2,
+  DEAUTH_LEAVING = 3,
+  DISASSOC_DUE_TO_INACTIVITY = 4,
+  DISASSOC_AP_BUSY = 5,
+  CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+  CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+  DISASSOC_STA_HAS_LEFT = 8,
+  STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+  PWR_CAPABILITY_NOT_VALID = 10,
+  SUPPORTED_CHANNEL_NOT_VALID = 11,
+  BSS_TRANSITION_DISASSOC = 12,
+  INVALID_IE = 13,
+  MICHAEL_MIC_FAILURE = 14,
+  FOURWAY_HANDSHAKE_TIMEOUT = 15,
+  GROUP_KEY_UPDATE_TIMEOUT = 16,
+  IE_IN_4WAY_DIFFERS = 17,
+  GROUP_CIPHER_NOT_VALID = 18,
+  PAIRWISE_CIPHER_NOT_VALID = 19,
+  AKMP_NOT_VALID = 20,
+  UNSUPPORTED_RSN_IE_VERSION = 21,
+  INVALID_RSN_IE_CAPAB = 22,
+  IEEE_802_1X_AUTH_FAILED = 23,
+  CIPHER_SUITE_REJECTED = 24,
+  TDLS_TEARDOWN_UNREACHABLE = 25,
+  TDLS_TEARDOWN_UNSPECIFIED = 26,
+  SSP_REQUESTED_DISASSOC = 27,
+  NO_SSP_ROAMING_AGREEMENT = 28,
+  BAD_CIPHER_OR_AKM = 29,
+  NOT_AUTHORIZED_THIS_LOCATION = 30,
+  SERVICE_CHANGE_PRECLUDES_TS = 31,
+  UNSPECIFIED_QOS_REASON = 32,
+  NOT_ENOUGH_BANDWIDTH = 33,
+  DISASSOC_LOW_ACK = 34,
+  EXCEEDED_TXOP = 35,
+  STA_LEAVING = 36,
+  END_TS_BA_DLS = 37,
+  UNKNOWN_TS_BA = 38,
+  TIMEOUT = 39,
+  PEERKEY_MISMATCH = 45,
+  AUTHORIZED_ACCESS_LIMIT_REACHED = 46,
+  EXTERNAL_SERVICE_REQUIREMENTS = 47,
+  INVALID_FT_ACTION_FRAME_COUNT = 48,
+  INVALID_PMKID = 49,
+  INVALID_MDE = 50,
+  INVALID_FTE = 51,
+  MESH_PEERING_CANCELLED = 52,
+  MESH_MAX_PEERS = 53,
+  MESH_CONFIG_POLICY_VIOLATION = 54,
+  MESH_CLOSE_RCVD = 55,
+  MESH_MAX_RETRIES = 56,
+  MESH_CONFIRM_TIMEOUT = 57,
+  MESH_INVALID_GTK = 58,
+  MESH_INCONSISTENT_PARAMS = 59,
+  MESH_INVALID_SECURITY_CAP = 60,
+  MESH_PATH_ERROR_NO_PROXY_INFO = 61,
+  MESH_PATH_ERROR_NO_FORWARDING_INFO = 62,
+  MESH_PATH_ERROR_DEST_UNREACHABLE = 63,
+  MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64,
+  MESH_CHANNEL_SWITCH_REGULATORY_REQ = 65,
+  MESH_CHANNEL_SWITCH_UNSPECIFIED = 66,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/StaIfaceStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/StaIfaceStatusCode.aidl
new file mode 100644
index 0000000..13529a5
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/StaIfaceStatusCode.aidl
@@ -0,0 +1,134 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum StaIfaceStatusCode {
+  SUCCESS = 0,
+  UNSPECIFIED_FAILURE = 1,
+  TDLS_WAKEUP_ALTERNATE = 2,
+  TDLS_WAKEUP_REJECT = 3,
+  SECURITY_DISABLED = 5,
+  UNACCEPTABLE_LIFETIME = 6,
+  NOT_IN_SAME_BSS = 7,
+  CAPS_UNSUPPORTED = 10,
+  REASSOC_NO_ASSOC = 11,
+  ASSOC_DENIED_UNSPEC = 12,
+  NOT_SUPPORTED_AUTH_ALG = 13,
+  UNKNOWN_AUTH_TRANSACTION = 14,
+  CHALLENGE_FAIL = 15,
+  AUTH_TIMEOUT = 16,
+  AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+  ASSOC_DENIED_RATES = 18,
+  ASSOC_DENIED_NOSHORT = 19,
+  SPEC_MGMT_REQUIRED = 22,
+  PWR_CAPABILITY_NOT_VALID = 23,
+  SUPPORTED_CHANNEL_NOT_VALID = 24,
+  ASSOC_DENIED_NO_SHORT_SLOT_TIME = 25,
+  ASSOC_DENIED_NO_HT = 27,
+  R0KH_UNREACHABLE = 28,
+  ASSOC_DENIED_NO_PCO = 29,
+  ASSOC_REJECTED_TEMPORARILY = 30,
+  ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
+  UNSPECIFIED_QOS_FAILURE = 32,
+  DENIED_INSUFFICIENT_BANDWIDTH = 33,
+  DENIED_POOR_CHANNEL_CONDITIONS = 34,
+  DENIED_QOS_NOT_SUPPORTED = 35,
+  REQUEST_DECLINED = 37,
+  INVALID_PARAMETERS = 38,
+  REJECTED_WITH_SUGGESTED_CHANGES = 39,
+  INVALID_IE = 40,
+  GROUP_CIPHER_NOT_VALID = 41,
+  PAIRWISE_CIPHER_NOT_VALID = 42,
+  AKMP_NOT_VALID = 43,
+  UNSUPPORTED_RSN_IE_VERSION = 44,
+  INVALID_RSN_IE_CAPAB = 45,
+  CIPHER_REJECTED_PER_POLICY = 46,
+  TS_NOT_CREATED = 47,
+  DIRECT_LINK_NOT_ALLOWED = 48,
+  DEST_STA_NOT_PRESENT = 49,
+  DEST_STA_NOT_QOS_STA = 50,
+  ASSOC_DENIED_LISTEN_INT_TOO_LARGE = 51,
+  INVALID_FT_ACTION_FRAME_COUNT = 52,
+  INVALID_PMKID = 53,
+  INVALID_MDIE = 54,
+  INVALID_FTIE = 55,
+  REQUESTED_TCLAS_NOT_SUPPORTED = 56,
+  INSUFFICIENT_TCLAS_PROCESSING_RESOURCES = 57,
+  TRY_ANOTHER_BSS = 58,
+  GAS_ADV_PROTO_NOT_SUPPORTED = 59,
+  NO_OUTSTANDING_GAS_REQ = 60,
+  GAS_RESP_NOT_RECEIVED = 61,
+  STA_TIMED_OUT_WAITING_FOR_GAS_RESP = 62,
+  GAS_RESP_LARGER_THAN_LIMIT = 63,
+  REQ_REFUSED_HOME = 64,
+  ADV_SRV_UNREACHABLE = 65,
+  REQ_REFUSED_SSPN = 67,
+  REQ_REFUSED_UNAUTH_ACCESS = 68,
+  INVALID_RSNIE = 72,
+  U_APSD_COEX_NOT_SUPPORTED = 73,
+  U_APSD_COEX_MODE_NOT_SUPPORTED = 74,
+  BAD_INTERVAL_WITH_U_APSD_COEX = 75,
+  ANTI_CLOGGING_TOKEN_REQ = 76,
+  FINITE_CYCLIC_GROUP_NOT_SUPPORTED = 77,
+  CANNOT_FIND_ALT_TBTT = 78,
+  TRANSMISSION_FAILURE = 79,
+  REQ_TCLAS_NOT_SUPPORTED = 80,
+  TCLAS_RESOURCES_EXCHAUSTED = 81,
+  REJECTED_WITH_SUGGESTED_BSS_TRANSITION = 82,
+  REJECT_WITH_SCHEDULE = 83,
+  REJECT_NO_WAKEUP_SPECIFIED = 84,
+  SUCCESS_POWER_SAVE_MODE = 85,
+  PENDING_ADMITTING_FST_SESSION = 86,
+  PERFORMING_FST_NOW = 87,
+  PENDING_GAP_IN_BA_WINDOW = 88,
+  REJECT_U_PID_SETTING = 89,
+  REFUSED_EXTERNAL_REASON = 92,
+  REFUSED_AP_OUT_OF_MEMORY = 93,
+  REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED = 94,
+  QUERY_RESP_OUTSTANDING = 95,
+  REJECT_DSE_BAND = 96,
+  TCLAS_PROCESSING_TERMINATED = 97,
+  TS_SCHEDULE_CONFLICT = 98,
+  DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
+  MCCAOP_RESERVATION_CONFLICT = 100,
+  MAF_LIMIT_EXCEEDED = 101,
+  MCCA_TRACK_LIMIT_EXCEEDED = 102,
+  DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
+  ASSOC_DENIED_NO_VHT = 104,
+  ENABLEMENT_DENIED = 105,
+  RESTRICTION_FROM_AUTHORIZED_GDB = 106,
+  AUTHORIZATION_DEENABLED = 107,
+  FILS_AUTHENTICATION_FAILURE = 112,
+  UNKNOWN_AUTHENTICATION_SERVER = 113,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
new file mode 100644
index 0000000..1d37635
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable SupplicantStateChangeData {
+  android.hardware.wifi.supplicant.StaIfaceCallbackState newState;
+  int id;
+  byte[] ssid;
+  byte[6] bssid;
+  android.hardware.wifi.supplicant.KeyMgmtMask keyMgmtMask;
+  int frequencyMhz;
+  boolean filsHlpSent;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
new file mode 100644
index 0000000..d7ff798
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum SupplicantStatusCode {
+  SUCCESS,
+  FAILURE_UNKNOWN,
+  FAILURE_ARGS_INVALID,
+  FAILURE_IFACE_INVALID,
+  FAILURE_IFACE_UNKNOWN,
+  FAILURE_IFACE_EXISTS,
+  FAILURE_IFACE_DISABLED,
+  FAILURE_IFACE_NOT_DISCONNECTED,
+  FAILURE_NETWORK_INVALID,
+  FAILURE_NETWORK_UNKNOWN,
+  FAILURE_UNSUPPORTED,
+  FAILURE_ONGOING_REQUEST,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/TlsVersion.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/TlsVersion.aidl
new file mode 100644
index 0000000..b31826a
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/TlsVersion.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum TlsVersion {
+  TLS_V1_0,
+  TLS_V1_1,
+  TLS_V1_2,
+  TLS_V1_3,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl
new file mode 100644
index 0000000..f1d7370
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum TransitionDisableIndication {
+  USE_WPA3_PERSONAL = (1 << 0) /* 1 */,
+  USE_SAE_PK = (1 << 1) /* 2 */,
+  USE_WPA3_ENTERPRISE = (1 << 2) /* 4 */,
+  USE_ENHANCED_OPEN = (1 << 3) /* 8 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WifiTechnology.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WifiTechnology.aidl
new file mode 100644
index 0000000..bf5081e
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WifiTechnology.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum WifiTechnology {
+  UNKNOWN = 0,
+  LEGACY = 1,
+  HT = 2,
+  VHT = 3,
+  HE = 4,
+  EHT = 5,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
new file mode 100644
index 0000000..330f2aa
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum WpaDriverCapabilitiesMask {
+  MBO = (1 << 0) /* 1 */,
+  OCE = (1 << 1) /* 2 */,
+  SAE_PK = (1 << 2) /* 4 */,
+  WFD_R2 = (1 << 3) /* 8 */,
+  TRUST_ON_FIRST_USE = (1 << 4) /* 16 */,
+  SET_TLS_MINIMUM_VERSION = (1 << 5) /* 32 */,
+  TLS_V1_3 = (1 << 6) /* 64 */,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsConfigError.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsConfigError.aidl
new file mode 100644
index 0000000..c48b282
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsConfigError.aidl
@@ -0,0 +1,58 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum WpsConfigError {
+  NO_ERROR = 0,
+  OOB_IFACE_READ_ERROR = 1,
+  DECRYPTION_CRC_FAILURE = 2,
+  CHAN_24_NOT_SUPPORTED = 3,
+  CHAN_50_NOT_SUPPORTED = 4,
+  SIGNAL_TOO_WEAK = 5,
+  NETWORK_AUTH_FAILURE = 6,
+  NETWORK_ASSOC_FAILURE = 7,
+  NO_DHCP_RESPONSE = 8,
+  FAILED_DHCP_CONFIG = 9,
+  IP_ADDR_CONFLICT = 10,
+  NO_CONN_TO_REGISTRAR = 11,
+  MULTIPLE_PBC_DETECTED = 12,
+  ROGUE_SUSPECTED = 13,
+  DEVICE_BUSY = 14,
+  SETUP_LOCKED = 15,
+  MSG_TIMEOUT = 16,
+  REG_SESS_TIMEOUT = 17,
+  DEV_PASSWORD_AUTH_FAILURE = 18,
+  CHAN_60G_NOT_SUPPORTED = 19,
+  PUBLIC_KEY_HASH_MISMATCH = 20,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsConfigMethods.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsConfigMethods.aidl
new file mode 100644
index 0000000..b9ea211
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsConfigMethods.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum WpsConfigMethods {
+  USBA = 0x0001,
+  ETHERNET = 0x0002,
+  LABEL = 0x0004,
+  DISPLAY = 0x0008,
+  EXT_NFC_TOKEN = 0x0010,
+  INT_NFC_TOKEN = 0x0020,
+  NFC_INTERFACE = 0x0040,
+  PUSHBUTTON = 0x0080,
+  KEYPAD = 0x0100,
+  VIRT_PUSHBUTTON = 0x0280,
+  PHY_PUSHBUTTON = 0x0480,
+  P2PS = 0x1000,
+  VIRT_DISPLAY = 0x2008,
+  PHY_DISPLAY = 0x4008,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl
new file mode 100644
index 0000000..9a20187
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum WpsDevPasswordId {
+  DEFAULT = 0x0000,
+  USER_SPECIFIED = 0x0001,
+  MACHINE_SPECIFIED = 0x0002,
+  REKEY = 0x0003,
+  PUSHBUTTON = 0x0004,
+  REGISTRAR_SPECIFIED = 0x0005,
+  NFC_CONNECTION_HANDOVER = 0x0007,
+  P2PS_DEFAULT = 0x0008,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsErrorIndication.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
new file mode 100644
index 0000000..50e69ff
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum WpsErrorIndication {
+  NO_ERROR = 0,
+  SECURITY_TKIP_ONLY_PROHIBITED = 1,
+  SECURITY_WEP_PROHIBITED = 2,
+  AUTH_FAILURE = 3,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
new file mode 100644
index 0000000..177d218
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/2/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum WpsProvisionMethod {
+  PBC,
+  DISPLAY,
+  KEYPAD,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
index 433b3d80..553cbc8 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -39,4 +39,5 @@
   int maxNumberTxSpatialStreams;
   int maxNumberRxSpatialStreams;
   android.hardware.wifi.supplicant.LegacyMode legacyMode;
+  boolean apTidToLinkMapNegotiationSupported;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppConfigurationData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppConfigurationData.aidl
new file mode 100644
index 0000000..2225330
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppConfigurationData.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable DppConfigurationData {
+  byte[] ssid;
+  String password;
+  byte[] psk;
+  android.hardware.wifi.supplicant.DppAkm securityAkm;
+  android.hardware.wifi.supplicant.DppConnectionKeys dppConnectionKeys;
+  boolean connStatusRequested;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl
new file mode 100644
index 0000000..d72633b
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DppStatusErrorCode {
+  UNKNOWN = -1,
+  SUCCESS = 0,
+  NOT_COMPATIBLE = 1,
+  AUTH_FAILURE = 2,
+  UNWRAP_FAILURE = 3,
+  BAD_GROUP = 4,
+  CONFIGURE_FAILURE = 5,
+  RESPONSE_PENDING = 6,
+  INVALID_CONNECTOR = 7,
+  NO_MATCH = 8,
+  CONFIG_REJECTED = 9,
+  NO_AP = 10,
+  CONFIGURE_PENDING = 11,
+  CSR_NEEDED = 12,
+  CSR_BAD = 13,
+  NEW_KEY_NEEDED = 14,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
new file mode 100644
index 0000000..bcf0ea8
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+interface INonStandardCertCallback {
+  byte[] getBlob(in String alias);
+  String[] listAliases(in String prefix);
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
index 4b26ac3..dd62167 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
@@ -47,5 +47,6 @@
   void setConcurrencyPriority(in android.hardware.wifi.supplicant.IfaceType type);
   void setDebugParams(in android.hardware.wifi.supplicant.DebugLevel level, in boolean showTimestamp, in boolean showKeys);
   oneway void terminate();
+  void registerNonStandardCertCallback(in android.hardware.wifi.supplicant.INonStandardCertCallback callback);
   const int EXT_RADIO_WORK_TIMEOUT_IN_SECS = 10;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index e204184..19e6728 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -96,4 +96,5 @@
   void findOnSocialChannels(in int timeoutInSec);
   void findOnSpecificFrequency(in int freqInHz, in int timeoutInSec);
   void setVendorElements(in android.hardware.wifi.supplicant.P2pFrameTypeMask frameTypeMask, in byte[] vendorElemBytes);
+  void configureEapolIpAddressAllocationParams(in int ipAddressGo, in int ipAddressMask, in int ipAddressStart, in int ipAddressEnd);
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 8d9f498..da3ca52 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -52,4 +52,5 @@
   oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
   oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency);
   oneway void onDeviceFoundWithVendorElements(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo, in byte[] vendorElemBytes);
+  oneway void onGroupStartedWithParams(in android.hardware.wifi.supplicant.P2pGroupStartedEventParams groupStartedEventParams);
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index 53d5770..1616b26 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -95,4 +95,8 @@
   void stopDppInitiator();
   void stopDppResponder(in int ownBootstrapId);
   void stopRxFilter();
+  android.hardware.wifi.supplicant.SignalPollResult[] getSignalPollResults();
+  android.hardware.wifi.supplicant.QosPolicyScsRequestStatus[] addQosPolicyRequestForScs(in android.hardware.wifi.supplicant.QosPolicyScsData[] qosPolicyData);
+  android.hardware.wifi.supplicant.QosPolicyScsRequestStatus[] removeQosPolicyForScs(in byte[] scsPolicyIds);
+  const int MAX_POLICIES_PER_QOS_SCS_REQUEST = 16;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 25a09b4..1c23223 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -44,6 +44,9 @@
   oneway void onDppFailure(in android.hardware.wifi.supplicant.DppFailureCode code, in String ssid, in String channelList, in char[] bandList);
   oneway void onDppProgress(in android.hardware.wifi.supplicant.DppProgressCode code);
   oneway void onDppSuccess(in android.hardware.wifi.supplicant.DppEventType event);
+  /**
+   * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onDppConfigReceived.
+   */
   oneway void onDppSuccessConfigReceived(in byte[] ssid, in String password, in byte[] psk, in android.hardware.wifi.supplicant.DppAkm securityAkm, in android.hardware.wifi.supplicant.DppConnectionKeys dppConnectionKeys);
   oneway void onDppSuccessConfigSent();
   oneway void onEapFailure(in byte[] bssid, in int errorCode);
@@ -56,11 +59,29 @@
   oneway void onNetworkAdded(in int id);
   oneway void onNetworkNotFound(in byte[] ssid);
   oneway void onNetworkRemoved(in int id);
+  /**
+   * @deprecated use onPmkSaCacheAdded() instead.
+   */
   oneway void onPmkCacheAdded(in long expirationTimeInSec, in byte[] serializedEntry);
+  /**
+   * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onSupplicantStateChanged()
+   */
   oneway void onStateChanged(in android.hardware.wifi.supplicant.StaIfaceCallbackState newState, in byte[] bssid, in int id, in byte[] ssid, in boolean filsHlpSent);
   oneway void onWpsEventFail(in byte[] bssid, in android.hardware.wifi.supplicant.WpsConfigError configError, in android.hardware.wifi.supplicant.WpsErrorIndication errorInd);
   oneway void onWpsEventPbcOverlap();
   oneway void onWpsEventSuccess();
   oneway void onQosPolicyReset();
   oneway void onQosPolicyRequest(in int qosPolicyRequestId, in android.hardware.wifi.supplicant.QosPolicyData[] qosPolicyData);
+  oneway void onMloLinksInfoChanged(in android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback.MloLinkInfoChangeReason reason);
+  oneway void onDppConfigReceived(in android.hardware.wifi.supplicant.DppConfigurationData configData);
+  oneway void onDppConnectionStatusResultSent(in android.hardware.wifi.supplicant.DppStatusErrorCode code);
+  oneway void onBssFrequencyChanged(in int frequencyMhz);
+  oneway void onSupplicantStateChanged(in android.hardware.wifi.supplicant.SupplicantStateChangeData stateChangeData);
+  oneway void onQosPolicyResponseForScs(in android.hardware.wifi.supplicant.QosPolicyScsResponseStatus[] qosPolicyScsResponseStatus);
+  oneway void onPmkSaCacheAdded(in android.hardware.wifi.supplicant.PmkSaCacheData pmkSaData);
+  @Backing(type="int") @VintfStability
+  enum MloLinkInfoChangeReason {
+    TID_TO_LINK_MAP = 0,
+    MULTI_LINK_RECONFIG_AP_REMOVAL = 1,
+  }
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
index 0b3cb81..bfc05a4 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -127,6 +127,8 @@
   void setWepKey(in int keyIdx, in byte[] wepKey);
   void setWepTxKeyIdx(in int keyIdx);
   void setRoamingConsortiumSelection(in byte[] selectedRcoi);
+  void setMinimumTlsVersionEapPhase1Param(android.hardware.wifi.supplicant.TlsVersion tlsVersion);
+  void setStrictConservativePeerMode(in boolean enable);
   const int SSID_MAX_LEN_IN_BYTES = 32;
   const int PSK_PASSPHRASE_MIN_LEN_IN_BYTES = 8;
   const int PSK_PASSPHRASE_MAX_LEN_IN_BYTES = 63;
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index 6276a35..f9a078b 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -39,4 +39,5 @@
   oneway void onNetworkEapSimUmtsAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams params);
   oneway void onTransitionDisable(in android.hardware.wifi.supplicant.TransitionDisableIndication ind);
   oneway void onServerCertificateAvailable(in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
+  oneway void onPermanentIdReqDenied();
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl
index 5e2c47b..8bda324 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl
@@ -36,4 +36,8 @@
 parcelable MloLink {
   byte linkId;
   byte[] staLinkMacAddress;
+  byte tidsUplinkMap;
+  byte tidsDownlinkMap;
+  @nullable byte[6] apLinkMacAddress;
+  int frequencyMHz;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLinksInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLinksInfo.aidl
index 14fcb91..3dac2d6 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLinksInfo.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLinksInfo.aidl
@@ -35,4 +35,6 @@
 @VintfStability
 parcelable MloLinksInfo {
   android.hardware.wifi.supplicant.MloLink[] links;
+  int apMloLinkId;
+  @nullable byte[6] apMldMacAddress;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl
new file mode 100644
index 0000000..db31ca1
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pClientEapolIpAddressInfo {
+  int ipAddressClient;
+  int ipAddressMask;
+  int ipAddressGo;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
new file mode 100644
index 0000000..5465a86
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable P2pGroupStartedEventParams {
+  String groupInterfaceName;
+  boolean isGroupOwner;
+  byte[] ssid;
+  int frequencyMHz;
+  byte[] psk;
+  String passphrase;
+  boolean isPersistent;
+  byte[6] goDeviceAddress;
+  byte[6] goInterfaceAddress;
+  boolean isP2pClientEapolIpAddressInfoPresent;
+  android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo p2pClientIpInfo;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
new file mode 100644
index 0000000..c31b167
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable PmkSaCacheData {
+  byte[6] bssid;
+  long expirationTimeInSec;
+  byte[] serializedEntry;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
index 8bf5fd8..156d57a 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
@@ -43,4 +43,5 @@
   android.hardware.wifi.supplicant.ProtocolNextHeader protocolNextHdr;
   byte[] flowLabelIpv6;
   String domainName;
+  byte dscp;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
index 280ddbe..9c0c0b6 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
@@ -41,4 +41,5 @@
   PROTOCOL_NEXT_HEADER = 16,
   FLOW_LABEL = 32,
   DOMAIN_NAME = 64,
+  DSCP = 128,
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
new file mode 100644
index 0000000..4e5e8ae
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosPolicyScsData {
+  byte policyId;
+  byte userPriority;
+  android.hardware.wifi.supplicant.QosPolicyClassifierParams classifierParams;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
new file mode 100644
index 0000000..d5573af
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosPolicyScsRequestStatus {
+  byte policyId;
+  android.hardware.wifi.supplicant.QosPolicyScsRequestStatusCode qosPolicyScsRequestStatusCode;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
new file mode 100644
index 0000000..4d81566
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum QosPolicyScsRequestStatusCode {
+  SENT = 0,
+  ALREADY_ACTIVE = 1,
+  NOT_EXIST = 2,
+  INVALID = 3,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
new file mode 100644
index 0000000..2737f1a
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable QosPolicyScsResponseStatus {
+  byte policyId;
+  android.hardware.wifi.supplicant.QosPolicyScsResponseStatusCode qosPolicyScsResponseStatusCode;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
new file mode 100644
index 0000000..693d3e0
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum QosPolicyScsResponseStatusCode {
+  SUCCESS = 0,
+  TCLAS_REQUEST_DECLINED = 1,
+  TCLAS_NOT_SUPPORTED_BY_AP = 2,
+  TCLAS_INSUFFICIENT_RESOURCES = 3,
+  TCLAS_RESOURCES_EXHAUSTED = 4,
+  TCLAS_PROCESSING_TERMINATED_INSUFFICIENT_QOS = 5,
+  TCLAS_PROCESSING_TERMINATED_POLICY_CONFLICT = 6,
+  TCLAS_PROCESSING_TERMINATED = 7,
+  TIMEOUT = 8,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SignalPollResult.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SignalPollResult.aidl
new file mode 100644
index 0000000..52d3f24
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SignalPollResult.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable SignalPollResult {
+  int linkId;
+  int currentRssiDbm;
+  int txBitrateMbps;
+  int rxBitrateMbps;
+  int frequencyMhz;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
new file mode 100644
index 0000000..1d37635
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable SupplicantStateChangeData {
+  android.hardware.wifi.supplicant.StaIfaceCallbackState newState;
+  int id;
+  byte[] ssid;
+  byte[6] bssid;
+  android.hardware.wifi.supplicant.KeyMgmtMask keyMgmtMask;
+  int frequencyMhz;
+  boolean filsHlpSent;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
index 32d71a3..d84ff95 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
@@ -45,4 +45,5 @@
   FAILURE_NETWORK_INVALID = 8,
   FAILURE_NETWORK_UNKNOWN = 9,
   FAILURE_UNSUPPORTED = 10,
+  FAILURE_ONGOING_REQUEST = 11,
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TlsVersion.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TlsVersion.aidl
new file mode 100644
index 0000000..22a374f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TlsVersion.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum TlsVersion {
+  TLS_V1_0 = 0,
+  TLS_V1_1 = 1,
+  TLS_V1_2 = 2,
+  TLS_V1_3 = 3,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index 9a0a924..32e1510 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -39,4 +39,6 @@
   SAE_PK = 4,
   WFD_R2 = 8,
   TRUST_ON_FIRST_USE = 16,
+  SET_TLS_MINIMUM_VERSION = 32,
+  TLS_V1_3 = 64,
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
index 1718413..4921a67 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -44,4 +44,8 @@
      * detailed network mode for legacy network
      */
     LegacyMode legacyMode;
+    /**
+     * Indicates the AP support for TID-to-link mapping negotiation.
+     */
+    boolean apTidToLinkMapNegotiationSupported;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppConfigurationData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppConfigurationData.aidl
new file mode 100644
index 0000000..b25bc40
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppConfigurationData.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.DppAkm;
+import android.hardware.wifi.supplicant.DppConnectionKeys;
+
+/**
+ * DPP configuration related information.
+ */
+@VintfStability
+parcelable DppConfigurationData {
+    /*
+     * SSID of the network.
+     */
+    byte[] ssid;
+    /*
+     * WPA2 or SAE passphrase.
+     */
+    String password;
+    /*
+     * Pre-shared key encoded in hex.
+     */
+    byte[] psk;
+    /*
+     * AKM that can be provisioned using DPP.
+     */
+    DppAkm securityAkm;
+    /*
+     * Connection keys that are used for DPP network connection.
+     */
+    DppConnectionKeys dppConnectionKeys;
+    /*
+     * Optional flag to indicate that the configurator requested connection status
+     * result.
+     * This flag is set to true if the enrollee receives the configuration response
+     * frame with sendConnStatus attribute.
+     */
+    boolean connStatusRequested;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl
new file mode 100644
index 0000000..30965d6
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * DppStatusErrorCode: The possible values for the DPP status and error codes
+ * in the DPP protocol.
+ * See Easy Connect specification V2.0 section 8.3.4 for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum DppStatusErrorCode {
+    UNKNOWN = -1,
+    SUCCESS = 0,
+    NOT_COMPATIBLE = 1,
+    AUTH_FAILURE = 2,
+    UNWRAP_FAILURE = 3,
+    BAD_GROUP = 4,
+    CONFIGURE_FAILURE = 5,
+    RESPONSE_PENDING = 6,
+    INVALID_CONNECTOR = 7,
+    NO_MATCH = 8,
+    CONFIG_REJECTED = 9,
+    NO_AP = 10,
+    CONFIGURE_PENDING = 11,
+    CSR_NEEDED = 12,
+    CSR_BAD = 13,
+    NEW_KEY_NEEDED = 14,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
new file mode 100644
index 0000000..2e11c76
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Callback to allow supplicant to retrieve non-standard certificate types
+ * from the framework. Certificates can be stored in the framework using
+ * the WifiKeystore#put system API.
+ *
+ * Must be registered by the client at initialization, so that
+ * supplicant can call into the client to retrieve any values.
+ */
+@VintfStability
+interface INonStandardCertCallback {
+    /**
+     * Requests a binary blob from the certificate key-value store.
+     *
+     * @param alias Key into the key-value mapping.
+     * @return Value associated with |alias| in the certificate store.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    byte[] getBlob(in String alias);
+
+    /**
+     * List the aliases currently stored in the database.
+     *
+     * @param prefix Prefix to filter the aliases by.
+     * @return List of alias strings in the certificate store.
+               The resulting strings will each exclude the prefix.
+     */
+    String[] listAliases(in String prefix);
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
index c17289d..b187c2f 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
@@ -17,6 +17,7 @@
 package android.hardware.wifi.supplicant;
 
 import android.hardware.wifi.supplicant.DebugLevel;
+import android.hardware.wifi.supplicant.INonStandardCertCallback;
 import android.hardware.wifi.supplicant.ISupplicantCallback;
 import android.hardware.wifi.supplicant.ISupplicantP2pIface;
 import android.hardware.wifi.supplicant.ISupplicantStaIface;
@@ -158,4 +159,14 @@
      * wait to be restarted.
      */
     oneway void terminate();
+
+    /**
+     * Register a Non-Standard Certificate callback with supplicant.
+     *
+     * @param callback An instance of the |INonStandardCertCallback| AIDL interface
+     *        object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void registerNonStandardCertCallback(in INonStandardCertCallback callback);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 313ee8b..e58422c 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -827,4 +827,22 @@
      *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
      */
     void setVendorElements(in P2pFrameTypeMask frameTypeMask, in byte[] vendorElemBytes);
+
+    /**
+     * Configure the IP addresses in supplicant for P2P GO to provide the IP address to
+     * client in EAPOL handshake. Refer Wi-Fi P2P Technical Specification v1.7 - Section  4.2.8
+     * "IP Address Allocation in EAPOL-Key Frames (4-Way Handshake)" for more details.
+     * The IP addresses are IPV4 addresses and higher-order address bytes are in the lower-order
+     * int bytes (e.g. 1.2.3.4 is represented as 0x04030201)
+     *
+     * @param ipAddressGo The P2P Group Owner IP address.
+     * @param ipAddressMask The P2P Group owner subnet mask.
+     * @param ipAddressStart The starting address in the IP address pool.
+     * @param ipAddressEnd The ending address in the IP address pool.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void configureEapolIpAddressAllocationParams(
+            in int ipAddressGo, in int ipAddressMask, in int ipAddressStart, in int ipAddressEnd);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 7c8c1f2..9d6fa67 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -17,6 +17,7 @@
 package android.hardware.wifi.supplicant;
 
 import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
+import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
 import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
 import android.hardware.wifi.supplicant.P2pStatusCode;
 import android.hardware.wifi.supplicant.WpsConfigMethods;
@@ -243,4 +244,11 @@
             in byte[] primaryDeviceType, in String deviceName, in WpsConfigMethods configMethods,
             in byte deviceCapabilities, in P2pGroupCapabilityMask groupCapabilities,
             in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo, in byte[] vendorElemBytes);
+
+    /**
+     * Used to indicate the start of a P2P group, with some parameters describing the group.
+     *
+     * @param groupStartedEventParams Parameters describing the P2P group.
+     */
+    void onGroupStartedWithParams(in P2pGroupStartedEventParams groupStartedEventParams);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index 9edf210..06ab8fb 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -29,8 +29,11 @@
 import android.hardware.wifi.supplicant.IfaceType;
 import android.hardware.wifi.supplicant.KeyMgmtMask;
 import android.hardware.wifi.supplicant.MloLinksInfo;
+import android.hardware.wifi.supplicant.QosPolicyScsData;
+import android.hardware.wifi.supplicant.QosPolicyScsRequestStatus;
 import android.hardware.wifi.supplicant.QosPolicyStatus;
 import android.hardware.wifi.supplicant.RxFilterType;
+import android.hardware.wifi.supplicant.SignalPollResult;
 import android.hardware.wifi.supplicant.WpaDriverCapabilitiesMask;
 import android.hardware.wifi.supplicant.WpsConfigMethods;
 
@@ -781,4 +784,70 @@
      *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
      */
     void stopRxFilter();
+
+    /**
+     * This method returns the signal poll results. Results will be for each
+     * link in case of Multiple Link Operation (MLO).
+     *
+     * @return Signal Poll Results per link.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    SignalPollResult[] getSignalPollResults();
+
+    /**
+     * Maximum number of policies that can be included in a QoS SCS add/remove request.
+     */
+    const int MAX_POLICIES_PER_QOS_SCS_REQUEST = 16;
+
+    /**
+     * Send a set of QoS SCS policy add requests to the AP.
+     *
+     * This is a request to the AP (if it supports the feature) to apply the QoS policies
+     * on traffic in the downlink.
+     *
+     * Synchronous response will indicate which policies were sent to the AP, and which
+     * were rejected immediately by supplicant. Caller will also receive an asynchronous
+     * response in |ISupplicantStaIfaceCallback.onQosPolicyResponseForScs| indicating
+     * the response from the AP for each policy that was sent.
+     *
+     * @param  qosPolicyScsData QoS policies info provided by STA.
+     * @return QosPolicyScsRequestStatus[] synchronously corresponding to all
+     *         the scs policies. Size of the result array will be the same as
+     *         the size of the input array.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN| if the number of policies in the
+     *          request is greater than |MAX_POLICIES_PER_QOS_SCS_REQUEST|
+     *
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED| if the AP does not support
+     *          the feature.
+     *
+     *         |SupplicantStatusCode.FAILURE_ONGOING_REQUEST| if a request is currently
+     *          being processed. Supplicant will only handle one request at a time.
+     */
+    QosPolicyScsRequestStatus[] addQosPolicyRequestForScs(in QosPolicyScsData[] qosPolicyData);
+
+    /**
+     * Request the removal of specific QoS policies for SCS configured by the STA.
+     *
+     * Synchronous response will indicate which policies were sent to the AP, and which
+     * were rejected immediately by supplicant. Caller will also receive an asynchronous
+     * response in |ISupplicantStaIfaceCallback.onQosPolicyResponseForScs| indicating
+     * the response from the AP for each policy that was sent.
+     *
+     * @param  scsPolicyIds policy id's to be removed.
+     * @return QosPolicyScsRequestStatus[] synchronously corresponding to all
+     *         the scs policies.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN| if the number of policies in the
+     *          request is greater than |MAX_POLICIES_PER_QOS_SCS_REQUEST|
+     *
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED| if the AP does not support
+     *          the feature.
+     *
+     *         |SupplicantStatusCode.FAILURE_ONGOING_REQUEST| if a request is currently
+     *          being processed. Supplicant will only handle one request at a time.
+     */
+    QosPolicyScsRequestStatus[] removeQosPolicyForScs(in byte[] scsPolicyIds);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 0730a8c..17a220d 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -22,15 +22,20 @@
 import android.hardware.wifi.supplicant.BssTmData;
 import android.hardware.wifi.supplicant.BssidChangeReason;
 import android.hardware.wifi.supplicant.DppAkm;
+import android.hardware.wifi.supplicant.DppConfigurationData;
 import android.hardware.wifi.supplicant.DppConnectionKeys;
 import android.hardware.wifi.supplicant.DppEventType;
 import android.hardware.wifi.supplicant.DppFailureCode;
 import android.hardware.wifi.supplicant.DppProgressCode;
+import android.hardware.wifi.supplicant.DppStatusErrorCode;
 import android.hardware.wifi.supplicant.Hs20AnqpData;
 import android.hardware.wifi.supplicant.OsuMethod;
+import android.hardware.wifi.supplicant.PmkSaCacheData;
 import android.hardware.wifi.supplicant.QosPolicyData;
+import android.hardware.wifi.supplicant.QosPolicyScsResponseStatus;
 import android.hardware.wifi.supplicant.StaIfaceCallbackState;
 import android.hardware.wifi.supplicant.StaIfaceReasonCode;
+import android.hardware.wifi.supplicant.SupplicantStateChangeData;
 import android.hardware.wifi.supplicant.WpsConfigError;
 import android.hardware.wifi.supplicant.WpsErrorIndication;
 
@@ -143,6 +148,9 @@
      * Indicates DPP configuration received success event in Enrolee mode.
      * This is also triggered when Configurator generates credentials for itself
      * using generateSelfDppConfiguration() API
+     * <p>
+     * @deprecated This callback is deprecated from AIDL v2, newer HAL should call
+     * onDppConfigReceived.
      */
     void onDppSuccessConfigReceived(in byte[] ssid, in String password, in byte[] psk,
             in DppAkm securityAkm, in DppConnectionKeys dppConnectionKeys);
@@ -241,6 +249,8 @@
     /**
      * Indicates pairwise master key (PMK) cache added event.
      *
+     * @deprecated use onPmkSaCacheAdded() instead.
+     *
      * @param expirationTimeInSec expiration time in seconds
      * @param serializedEntry is serialized PMK cache entry, the content is
      *              opaque for the framework and depends on the native implementation.
@@ -252,6 +262,9 @@
      * event is triggered by a particular network, the |SupplicantNetworkId|,
      * |ssid|, |bssid| parameters must indicate the parameters of the network/AP
      * which caused this state transition.
+     * <p>
+     * @deprecated This callback is deprecated from AIDL v2, newer HAL should call
+     * onSupplicantStateChanged()
      *
      * @param newState New State of the interface. This must be one of the |State|
      *        values above.
@@ -303,4 +316,91 @@
      * @param qosPolicyData QoS policies info requested by the AP.
      */
     void onQosPolicyRequest(in int qosPolicyRequestId, in QosPolicyData[] qosPolicyData);
+
+    /**
+     * Reason codes to be used with the callback |ISupplicantStaIfaceCallback.onMloLinksInfoChanged|
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum MloLinkInfoChangeReason {
+        /**
+         * TID-to-link mapping has changed. Updated mappings will be set in
+         * |MloLinksInfo.MloLink[].tids_downlink_map| and
+         * |MloLinksInfo.MloLink[].tids_uplink_map| for each of the links.
+         *
+         * STA MLD will operate in default mode if a TID-to-link mapping is not
+         * indicated by the callback. In default mode, all TIDs are mapped to
+         * all setup links in downlink and uplink directions.
+         */
+        TID_TO_LINK_MAP = 0,
+        /**
+         * Multi-link reconfiguration - AP removal as described in
+         * IEEE 802.11be spec, section 35.3.6. This is a mandatory feature for
+         * station.
+         *
+         * Removed link will not be present in |ISupplicantStaIface.getConnectionMloLinksInfo|.
+         */
+        MULTI_LINK_RECONFIG_AP_REMOVAL = 1,
+    }
+
+    /**
+     * Used to indicate that Multi Link status has changed due to the provided
+     * reason. Upadted MLO link status can be fetched using
+     * |ISupplicantStaIface.getConnectionMloLinksInfo|
+     *
+     * |MloLink.linkId| and |MloLink.staLinkMacAddress| are not expected
+     * to change.
+     *
+     * @param reason Reason as given in MloLinkInfoChangeReason.
+     */
+    void onMloLinksInfoChanged(in MloLinkInfoChangeReason reason);
+
+    /**
+     * Indicates DPP configuration received success event in Enrollee mode.
+     * This is also triggered when Configurator generates credentials for itself
+     * using generateSelfDppConfiguration() API
+     */
+    void onDppConfigReceived(in DppConfigurationData configData);
+
+    /**
+     * Indicates that DPP connection status result frame is sent.
+     */
+    void onDppConnectionStatusResultSent(in DppStatusErrorCode code);
+
+    /**
+     * Used to indicate that the operating frequency has changed for this BSS.
+     * This event is triggered when STA switches the channel due to channel
+     * switch announcement from the connected access point.
+     *
+     * @param frequencyMhz New operating frequency in MHz.
+     */
+    void onBssFrequencyChanged(in int frequencyMhz);
+
+    /**
+     * Used to indicate a state change event on this particular iface.
+     *
+     * @param stateChangeData Supplicant state change related information.
+     */
+    void onSupplicantStateChanged(in SupplicantStateChangeData stateChangeData);
+
+    /**
+     * Indicates an SCS response from the AP.
+     *
+     * If the AP does not send a response within the timeout period (1 sec),
+     * supplicant will call this API with the TIMEOUT status for each policy.
+     *
+     * The AP can trigger an unsolicited scs response to indicate the removal of
+     * previously requested policies.
+     *
+     * @param qosPolicyScsResponseStatus[] status for each SCS id.
+     */
+    void onQosPolicyResponseForScs(in QosPolicyScsResponseStatus[] qosPolicyScsResponseStatus);
+
+    /**
+     * Indicates pairwise master key (PMK) cache added event.
+     *
+     * @param pmkSaData PMKSA cache entry added details.
+     *
+     */
+    void onPmkSaCacheAdded(in PmkSaCacheData pmkSaData);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
index 267f1e8..750cf72 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -31,6 +31,7 @@
 import android.hardware.wifi.supplicant.PairwiseCipherMask;
 import android.hardware.wifi.supplicant.ProtoMask;
 import android.hardware.wifi.supplicant.SaeH2eMode;
+import android.hardware.wifi.supplicant.TlsVersion;
 
 /**
  * Interface exposed by the supplicant for each station mode network
@@ -1118,4 +1119,26 @@
      *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
      */
     void setRoamingConsortiumSelection(in byte[] selectedRcoi);
+
+    /**
+     * Set the minimum TLS version for EAP phase1 param.
+     *
+     * @param tlsVersion the TLS version
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setMinimumTlsVersionEapPhase1Param(TlsVersion tlsVersion);
+
+    /**
+     * Enable the strict conservative peer mode for EAP-SIM/AKA/AKA'
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setStrictConservativePeerMode(in boolean enable);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index de7b675..4f892be 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -71,4 +71,11 @@
      */
     void onServerCertificateAvailable(
             in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
+
+    /**
+     * Used to notify the AT_PERMANENT_ID_REQ denied event.
+     *
+     * In strict conservative mode, AT_PERMANENT_ID_REQ is denied from eap_peer side.
+     */
+    void onPermanentIdReqDenied();
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl
index 0e23728..0b4d66e 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl
@@ -30,4 +30,40 @@
      * STA Link MAC Address
      */
     byte[/* 6 */] staLinkMacAddress;
+    /**
+     * Bitset where each bit indicates TID mapped to this link in uplink and
+     * downlink direction.
+     *
+     * Traffic Identifier (TID) is an identifier used to classify a packet. It
+     * is represented as a four bit number identifying the QoS traffic within
+     * MAC data service. There are 16 possible values for TID, out of only 8 are
+     * practically used to identify differentiated services.
+     *
+     * A TID-to-link mapping indicates links on which frames belonging to each
+     * TID can be exchanged. IEEE 802.11be draft 2.0 defines the mapping for TID
+     * values between 0 to 7 only. Once associated, an MLO link state is
+     * considered as active if at least one TID is mapped to the link. Link
+     * state is considered as idle if no TID is mapped to the link.
+     *
+     * TIDs can be mapped to uplink, downlink or both directions.
+     * e.g.
+     *  - TID 4 is mapped to this link in uplink direction, if bit 4 in
+     *    MloLink#tids_uplink_map is set.
+     *  - TID 2 is mapped to both directions for this link, if bit 2 of both
+     *    MloLink#tids_uplink_map and MloLink#tids_downlink_map are set.
+     *
+     * In case of default link mapping, tids_uplink_map and tids_downlink_map
+     * is set to 0xFF for all the links.
+     *
+     */
+    byte tidsUplinkMap;
+    byte tidsDownlinkMap;
+    /**
+     * AP Link MAC Address
+     */
+    @nullable byte[6] apLinkMacAddress;
+    /**
+     * Frequency on which the link operates in MHz.
+     */
+    int frequencyMHz;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLinksInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLinksInfo.aidl
index 2f14717..3b81df8 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLinksInfo.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLinksInfo.aidl
@@ -28,4 +28,12 @@
      * List of MLO links
      */
     MloLink[] links;
+    /**
+     * The MLO link-id for the access point. It is the link-id used for association.
+     */
+    int apMloLinkId;
+    /**
+     * AP MLD MAC address.
+     */
+    @nullable byte[6] apMldMacAddress;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl
new file mode 100644
index 0000000..148e4a4
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * P2P Client IPV4 address allocated via EAPOL exchange.
+ * The IP addresses are IPV4 addresses and higher-order address bytes are in the lower-order
+ * int bytes (e.g. 1.2.3.4 is represented as 0x04030201)
+ */
+@VintfStability
+parcelable P2pClientEapolIpAddressInfo {
+    /**
+     * The P2P Client IP address.
+     */
+    int ipAddressClient;
+    /**
+     * The subnet that the P2P Group Owner is using.
+     */
+    int ipAddressMask;
+    /**
+     * The P2P Group Owner IP address.
+     */
+    int ipAddressGo;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
new file mode 100644
index 0000000..96f1e16
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo;
+
+/**
+ * Parameters passed as part of Wifi P2P group start event.
+ */
+@VintfStability
+parcelable P2pGroupStartedEventParams {
+    /** Interface name of the group (For ex: p2p-p2p0-1). */
+    String groupInterfaceName;
+
+    /** Whether this device is owner of the group. */
+    boolean isGroupOwner;
+
+    /** SSID of the group. */
+    byte[] ssid;
+
+    /** Frequency in MHz on which this group is created. */
+    int frequencyMHz;
+
+    /** PSK used to secure the group. */
+    byte[] psk;
+
+    /** PSK passphrase used to secure the group. */
+    String passphrase;
+
+    /** Whether this group is persisted or not. */
+    boolean isPersistent;
+
+    /** MAC Address of the owner of this group. */
+    byte[6] goDeviceAddress;
+
+    /** MAC Address of the P2P interface of the owner of this group. */
+    byte[6] goInterfaceAddress;
+
+    /**
+     * Flag to indicate that the P2P Client IP address is allocated via EAPOL exchange.
+     */
+    boolean isP2pClientEapolIpAddressInfoPresent;
+
+    /**
+     * The P2P Client IP Address allocated by the P2P Group Owner in EAPOL
+     * key exchange.
+     * Refer Wi-Fi P2P Technical Specification v1.7 - Section  4.2.8
+     * "IP Address Allocation in EAPOL-Key Frames (4-Way Handshake)" for more details.
+     * The value is undefined if isP2pClientEapolIpAddressInfoPresent is false.
+     */
+    P2pClientEapolIpAddressInfo p2pClientIpInfo;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
new file mode 100644
index 0000000..e0f1d31
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Details of the PMKSA cache entry that was added in supplicant.
+ */
+@VintfStability
+parcelable PmkSaCacheData {
+    /**
+     * BSSID of the access point to which the station is associated.
+     */
+    byte[6] bssid;
+    /**
+     * PMK expiration time in seconds.
+     */
+    long expirationTimeInSec;
+    /**
+     * Serialized PMK cache entry.
+     * The content is opaque for the framework and depends on the native implementation.
+     */
+    byte[] serializedEntry;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
index d95d18d..478b09d 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
@@ -62,4 +62,10 @@
      * "reg-name" in RFC 3986.
      */
     String domainName;
+
+    /**
+     * Differentiated Services Code Point (DSCP) value.
+     * Used by AP for mapping the data streams to apply the user priority.
+     */
+    byte dscp;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
index 51bc14c..c15fec0 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
@@ -29,4 +29,5 @@
     PROTOCOL_NEXT_HEADER = 1 << 4,
     FLOW_LABEL = 1 << 5,
     DOMAIN_NAME = 1 << 6,
+    DSCP = 1 << 7,
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
new file mode 100644
index 0000000..86a4dac
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -0,0 +1,24 @@
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.QosPolicyClassifierParams;
+
+/**
+ * QoS policy information in SCS request.
+ * TCLAS Processing element is always set to 0.
+ */
+@VintfStability
+parcelable QosPolicyScsData {
+    /** SCS QoS Policy identifier. */
+    byte policyId;
+
+    /**
+     * User Priority (UP) which the AP should apply to streams that match
+     * the classifier parameters.
+     */
+    byte userPriority;
+
+    /**
+     * QoS policy SCS classifier type information.
+     */
+    QosPolicyClassifierParams classifierParams;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
new file mode 100644
index 0000000..e233f32
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
@@ -0,0 +1,13 @@
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.QosPolicyScsRequestStatusCode;
+
+/**
+ * QoS policy status info per scsId. Returned immediately by supplicant
+ * upon SCS request.
+ */
+@VintfStability
+parcelable QosPolicyScsRequestStatus {
+    byte policyId;
+    QosPolicyScsRequestStatusCode qosPolicyScsRequestStatusCode;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
new file mode 100644
index 0000000..daf1578
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
@@ -0,0 +1,25 @@
+package android.hardware.wifi.supplicant;
+
+/**
+ * Enum values for QoS policy request status.
+ */
+@VintfStability
+@Backing(type="int")
+enum QosPolicyScsRequestStatusCode {
+    /**
+     * SCS request was sent to the AP.
+     */
+    SENT,
+    /**
+     * Add request conflicts with an existing policy ID.
+     */
+    ALREADY_ACTIVE,
+    /**
+     * Remove request is for a policy ID that does not exist.
+     */
+    NOT_EXIST,
+    /**
+     * QoS policy params are invalid.
+     */
+    INVALID,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
new file mode 100644
index 0000000..846a0e2
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
@@ -0,0 +1,13 @@
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.QosPolicyScsResponseStatusCode;
+
+/**
+ * QoS policy status info per scsId. Returned in a callback once replies are
+ * received from the AP.
+ */
+@VintfStability
+parcelable QosPolicyScsResponseStatus {
+    byte policyId;
+    QosPolicyScsResponseStatusCode qosPolicyScsResponseStatusCode;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
new file mode 100644
index 0000000..f4ecd2a
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
@@ -0,0 +1,46 @@
+package android.hardware.wifi.supplicant;
+
+/**
+ * Enum values for QoS policy response status.
+ */
+@VintfStability
+@Backing(type="int")
+enum QosPolicyScsResponseStatusCode {
+    SUCCESS,
+    /**
+     * Network policy does not permit the stream to be assigned the requested
+     * user priority (UP), but the AP might accept another request from the STA
+     * with the same TCLAS classifier(s) but a different user priority (UP).
+     */
+    TCLAS_REQUEST_DECLINED,
+    /**
+     * Requested TCLAS processing is not supported by the AP.
+     */
+    TCLAS_NOT_SUPPORTED_BY_AP,
+    /**
+     * The AP has insufficient TCLAS processing resources to satisfy the request
+     * (i.e. to classify and process the traffic).
+     */
+    TCLAS_INSUFFICIENT_RESOURCES,
+    /**
+     * Sufficient TCLAS processing resources were available when the SCS
+     * stream was created, but are no longer available.
+     */
+    TCLAS_RESOURCES_EXHAUSTED,
+    /**
+     * Insufficient capacity to sustain the current QoS treatment.
+     */
+    TCLAS_PROCESSING_TERMINATED_INSUFFICIENT_QOS,
+    /**
+     * Conflict with a (new or dynamic) network policy.
+     */
+    TCLAS_PROCESSING_TERMINATED_POLICY_CONFLICT,
+    /**
+     * Other reason for decline.
+     */
+    TCLAS_PROCESSING_TERMINATED,
+    /**
+     * AP did not send a response within the timeout period (1 sec).
+     */
+    TIMEOUT,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SignalPollResult.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SignalPollResult.aidl
new file mode 100644
index 0000000..a3b11a0
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SignalPollResult.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Signal polling results.
+ */
+@VintfStability
+parcelable SignalPollResult {
+    /**
+     * Link identifier.
+     */
+    int linkId;
+    /**
+     * RSSI value in dBM.
+     */
+    int currentRssiDbm;
+    /**
+     * Last transmitted packet bit rate in Mbps.
+     */
+    int txBitrateMbps;
+    /**
+     * Last received packet bit rate in Mbps.
+     */
+    int rxBitrateMbps;
+    /**
+     * Frequency in MHz.
+     */
+    int frequencyMhz;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
new file mode 100644
index 0000000..f7c66e0
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.KeyMgmtMask;
+import android.hardware.wifi.supplicant.StaIfaceCallbackState;
+
+/**
+ * Supplicant state change related information.
+ */
+@VintfStability
+parcelable SupplicantStateChangeData {
+    /**
+     * New State of the interface. This must be one of the
+     * |StaIfaceCallbackState| values.
+     */
+    StaIfaceCallbackState newState;
+    /**
+     * ID of the corresponding network which caused this
+     * state change event. This must be invalid (-1) if this
+     * event is not specific to a particular network.
+     */
+    int id;
+    /**
+     * SSID of the corresponding network which caused this state
+     * change event. This must be empty if this event is not specific
+     * to a particular network.
+     */
+    byte[] ssid;
+    /**
+     * BSSID of the corresponding AP which caused this state
+     * change event. This must be zero'ed if this event is not
+     * specific to a particular network.
+     */
+    byte[6] bssid;
+
+    /**
+     * Currently used key mgmt mask.
+     */
+    KeyMgmtMask keyMgmtMask;
+    /*
+     * Frequency of the connected channel in MHz. This must be zero if this
+     * event is not specific to a particular network.
+     */
+    int frequencyMhz;
+    /*
+     * Flag to indicate that FILS HLP IEs were included in this association.
+     * This flag is valid only for WPA_COMPLETED state change.
+     */
+    boolean filsHlpSent;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
index c7b7ffd..e97d6ee 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
@@ -63,4 +63,8 @@
      */
     FAILURE_NETWORK_UNKNOWN,
     FAILURE_UNSUPPORTED,
+    /**
+     * A different request is currently being processed.
+     */
+    FAILURE_ONGOING_REQUEST,
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TlsVersion.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TlsVersion.aidl
new file mode 100644
index 0000000..316e881
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TlsVersion.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * TlsVersion: TLS version.
+ */
+@VintfStability
+@Backing(type="int")
+enum TlsVersion {
+    TLS_V1_0,
+    TLS_V1_1,
+    TLS_V1_2,
+    TLS_V1_3,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index 08006cf..a9434c4 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -42,4 +42,12 @@
      * Trust On First Use
      */
     TRUST_ON_FIRST_USE = 1 << 4,
+    /**
+     * TLS minimum version
+     */
+    SET_TLS_MINIMUM_VERSION = 1 << 5,
+    /**
+     * TLS V1.3
+     */
+    TLS_V1_3 = 1 << 6,
 }
diff --git a/wifi/supplicant/aidl/lint-baseline.xml b/wifi/supplicant/aidl/lint-baseline.xml
new file mode 100644
index 0000000..0631223
--- /dev/null
+++ b/wifi/supplicant/aidl/lint-baseline.xml
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicant.java"
+            line="84"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantCallback.java"
+            line="43"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pIface.java"
+            line="237"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.java"
+            line="91"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.java"
+            line="76"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaIface.java"
+            line="235"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.java"
+            line="124"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaNetwork.java"
+            line="354"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.java"
+            line="52"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/INonStandardCertCallback.java"
+            line="67"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicant.java"
+            line="200"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantCallback.java"
+            line="60"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pIface.java"
+            line="928"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.java"
+            line="265"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.java"
+            line="164"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaIface.java"
+            line="939"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.java"
+            line="390"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaNetwork.java"
+            line="1239"
+            column="12"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.java"
+            line="97"
+            column="12"/>
+    </issue>
+
+</issues>
\ No newline at end of file
diff --git a/wifi/supplicant/aidl/vts/functional/Android.bp b/wifi/supplicant/aidl/vts/functional/Android.bp
index 8e142ec..f7c619a 100644
--- a/wifi/supplicant/aidl/vts/functional/Android.bp
+++ b/wifi/supplicant/aidl/vts/functional/Android.bp
@@ -44,12 +44,14 @@
         "android.hardware.wifi@1.5",
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi.supplicant@1.1",
-        "android.hardware.wifi.supplicant-V1-ndk",
+        "android.hardware.wifi.supplicant-V2-ndk",
         "libwifi-system",
         "libwifi-system-iface",
         "VtsHalWifiV1_0TargetTestUtil",
         "VtsHalWifiV1_5TargetTestUtil",
         "VtsHalWifiSupplicantV1_0TargetTestUtil",
+        "android.hardware.wifi-V1-ndk",
+        "VtsHalWifiTargetTestUtil",
     ],
     test_suites: [
         "general-tests",
@@ -78,12 +80,14 @@
         "android.hardware.wifi@1.5",
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi.supplicant@1.1",
-        "android.hardware.wifi.supplicant-V1-ndk",
+        "android.hardware.wifi.supplicant-V2-ndk",
         "libwifi-system",
         "libwifi-system-iface",
         "VtsHalWifiV1_0TargetTestUtil",
         "VtsHalWifiV1_5TargetTestUtil",
         "VtsHalWifiSupplicantV1_0TargetTestUtil",
+        "android.hardware.wifi-V1-ndk",
+        "VtsHalWifiTargetTestUtil",
     ],
     test_suites: [
         "general-tests",
@@ -112,12 +116,14 @@
         "android.hardware.wifi@1.5",
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi.supplicant@1.1",
-        "android.hardware.wifi.supplicant-V1-ndk",
+        "android.hardware.wifi.supplicant-V2-ndk",
         "libwifi-system",
         "libwifi-system-iface",
         "VtsHalWifiV1_0TargetTestUtil",
         "VtsHalWifiV1_5TargetTestUtil",
         "VtsHalWifiSupplicantV1_0TargetTestUtil",
+        "android.hardware.wifi-V1-ndk",
+        "VtsHalWifiTargetTestUtil",
     ],
     test_suites: [
         "general-tests",
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_aidl_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_aidl_test_utils.h
new file mode 100644
index 0000000..a850e50
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_aidl_test_utils.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <VtsCoreUtil.h>
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <android-base/logging.h>
+#include <wifi_system/supplicant_manager.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using android::wifi_system::SupplicantManager;
+
+// Helper methods to interact with wifi_aidl_test_utils
+namespace SupplicantAidlTestUtils {
+const std::string kWifiInstanceNameStr = std::string() + IWifi::descriptor + "/default";
+const char* kWifiInstanceName = kWifiInstanceNameStr.c_str();
+
+// Initialize the driver and firmware to STA mode using the vendor HAL.
+void initializeDriverAndFirmware(const std::string& wifi_instance_name) {
+    // Skip if wifi instance is not set.
+    if (wifi_instance_name == "") {
+        return;
+    }
+    if (getWifi(wifi_instance_name.c_str()) != nullptr) {
+        std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name.c_str());
+        int mode_id;
+        EXPECT_TRUE(configureChipToSupportConcurrencyType(wifi_chip, IfaceConcurrencyType::STA,
+                                                          &mode_id));
+    } else {
+        LOG(WARNING) << __func__ << ": Vendor HAL not supported";
+    }
+}
+
+// Deinitialize the driver and firmware using the vendor HAL.
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name) {
+    // Skip if wifi instance is not set.
+    if (wifi_instance_name == "") {
+        return;
+    }
+    if (getWifi(wifi_instance_name.c_str()) != nullptr) {
+        stopWifiService(wifi_instance_name.c_str());
+    } else {
+        LOG(WARNING) << __func__ << ": Vendor HAL not supported";
+    }
+}
+
+bool waitForSupplicantState(bool is_running) {
+    SupplicantManager supplicant_manager;
+    int count = 50; /* wait at most 5 seconds for completion */
+    while (count-- > 0) {
+        if (supplicant_manager.IsSupplicantRunning() == is_running) {
+            return true;
+        }
+        usleep(100000);
+    }
+    LOG(ERROR) << "Unable to " << (is_running ? "start" : "stop") << " supplicant";
+    return false;
+}
+
+bool waitForSupplicantStart() {
+    return waitForSupplicantState(true);
+}
+
+bool waitForSupplicantStop() {
+    return waitForSupplicantState(false);
+}
+
+bool waitForWifiHalStop(const std::string& wifi_instance_name) {
+    std::shared_ptr<IWifi> wifi = getWifi(wifi_instance_name.c_str());
+    int count = 50; /* wait at most 5 seconds for completion */
+    while (count-- > 0) {
+        if (wifi != nullptr) {
+            bool started = false;
+            auto status = wifi->isStarted(&started);
+            if (status.isOk() && !started) {
+                return true;
+            }
+        }
+        usleep(100000);
+        wifi = getWifi(wifi_instance_name.c_str());
+    }
+    LOG(ERROR) << "Wifi HAL was not stopped";
+    return false;
+}
+
+bool waitForFrameworkReady() {
+    int waitCount = 15;
+    do {
+        // Check whether package service is ready or not.
+        if (!testing::checkSubstringInCommandOutput("/system/bin/service check package",
+                                                    ": not found")) {
+            return true;
+        }
+        LOG(INFO) << "Framework is not ready";
+        sleep(1);
+    } while (waitCount-- > 0);
+    return false;
+}
+
+bool useAidlService() {
+    return isAidlServiceAvailable(kWifiInstanceName);
+}
+
+void startSupplicant() {
+    initializeDriverAndFirmware(kWifiInstanceName);
+    SupplicantManager supplicant_manager;
+    ASSERT_TRUE(supplicant_manager.StartSupplicant());
+    ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
+}
+
+void stopSupplicantService() {
+    SupplicantManager supplicant_manager;
+    ASSERT_TRUE(supplicant_manager.StopSupplicant());
+    deInitializeDriverAndFirmware(kWifiInstanceName);
+    ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
+}
+
+bool stopWifiFramework(const std::string& wifi_instance_name) {
+    std::system("svc wifi disable");
+    std::system("cmd wifi set-scan-always-available disabled");
+    return waitForSupplicantStop() && waitForWifiHalStop(wifi_instance_name);
+}
+
+void initializeService() {
+    ASSERT_TRUE(stopWifiFramework(kWifiInstanceName));
+    std::system("/system/bin/start");
+    ASSERT_TRUE(waitForFrameworkReady());
+    stopSupplicantService();
+    startSupplicant();
+}
+}  // namespace SupplicantAidlTestUtils
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_legacy_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_legacy_test_utils.h
new file mode 100644
index 0000000..a20a458
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_legacy_test_utils.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <VtsCoreUtil.h>
+#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <hidl/ServiceManagement.h>
+#include <supplicant_hidl_test_utils.h>
+#include <wifi_system/supplicant_manager.h>
+
+using android::wifi_system::SupplicantManager;
+
+// Helper methods to interact with supplicant_hidl_test_utils
+namespace SupplicantLegacyTestUtils {
+std::string getWifiInstanceName() {
+    const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
+            ::android::hardware::wifi::V1_0::IWifi::descriptor);
+    EXPECT_NE(0, instances.size());
+    return instances.size() != 0 ? instances[0] : "";
+}
+
+void stopSupplicantService() {
+    stopSupplicant(getWifiInstanceName());
+}
+
+void startSupplicant() {
+    initializeDriverAndFirmware(getWifiInstanceName());
+    SupplicantManager supplicant_manager;
+    ASSERT_TRUE(supplicant_manager.StartSupplicant());
+    ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
+}
+
+void initializeService() {
+    ASSERT_TRUE(stopWifiFramework(getWifiInstanceName()));
+    std::system("/system/bin/start");
+    ASSERT_TRUE(waitForFrameworkReady());
+    stopSupplicantService();
+    startSupplicant();
+}
+}  // namespace SupplicantLegacyTestUtils
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
index 6f8fde6..a260408 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -19,6 +19,7 @@
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
 #include <aidl/android/hardware/wifi/supplicant/BnSupplicantP2pIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
 #include <android/binder_manager.h>
 #include <android/binder_status.h>
 #include <binder/IServiceManager.h>
@@ -36,8 +37,10 @@
 using aidl::android::hardware::wifi::supplicant::MiracastMode;
 using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
 using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
+using aidl::android::hardware::wifi::supplicant::P2pGroupStartedEventParams;
 using aidl::android::hardware::wifi::supplicant::P2pProvDiscStatusCode;
 using aidl::android::hardware::wifi::supplicant::P2pStatusCode;
+using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
 using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
 using aidl::android::hardware::wifi::supplicant::WpsDevPasswordId;
 using aidl::android::hardware::wifi::supplicant::WpsProvisionMethod;
@@ -175,6 +178,10 @@
             const std::vector<uint8_t>& /* vendorElemBytes */) override {
         return ndk::ScopedAStatus::ok();
     }
+    ::ndk::ScopedAStatus onGroupStartedWithParams(
+            const P2pGroupStartedEventParams& /* groupStartedEventParams */) override {
+        return ndk::ScopedAStatus::ok();
+    }
 };
 
 class SupplicantP2pIfaceAidlTest : public testing::TestWithParam<std::string> {
@@ -413,7 +420,12 @@
  */
 TEST_P(SupplicantP2pIfaceAidlTest, EnableMacRandomization) {
     // Enable twice
-    EXPECT_TRUE(p2p_iface_->setMacRandomization(true).isOk());
+    auto status = p2p_iface_->setMacRandomization(true);
+    if (!status.isOk() && status.getServiceSpecificError() ==
+                                  static_cast<int32_t>(SupplicantStatusCode::FAILURE_UNSUPPORTED)) {
+        GTEST_SKIP() << "Mac randomization is not supported.";
+    }
+    EXPECT_TRUE(status.isOk());
     EXPECT_TRUE(p2p_iface_->setMacRandomization(true).isOk());
 
     // Disable twice
@@ -524,12 +536,11 @@
  * Connect
  */
 TEST_P(SupplicantP2pIfaceAidlTest, Connect) {
-  std::string pin;
-  EXPECT_TRUE(p2p_iface_
-                  ->connect(kTestMacAddr, WpsProvisionMethod::PBC,
-                            kTestConnectPin, true, false, kTestConnectGoIntent,
-                            &pin)
-                  .isOk());
+    std::string pin;
+    EXPECT_TRUE(p2p_iface_
+                        ->connect(kTestMacAddr, WpsProvisionMethod::PBC, kTestConnectPin, true,
+                                  false, kTestConnectGoIntent, &pin)
+                        .isOk());
 }
 
 /*
@@ -538,10 +549,9 @@
 TEST_P(SupplicantP2pIfaceAidlTest, CancelConnect) {
     std::string pin;
     EXPECT_TRUE(p2p_iface_
-                    ->connect(kTestMacAddr, WpsProvisionMethod::PBC,
-                              kTestConnectPin, true, false,
-                              kTestConnectGoIntent, &pin)
-                    .isOk());
+                        ->connect(kTestMacAddr, WpsProvisionMethod::PBC, kTestConnectPin, true,
+                                  false, kTestConnectGoIntent, &pin)
+                        .isOk());
     EXPECT_TRUE(p2p_iface_->cancelConnect().isOk());
 }
 
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
index 272a427..5d00485 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -206,6 +206,39 @@
                                       QosPolicyData /* qosPolicyData */>&) override {
         return ndk::ScopedAStatus::ok();
     }
+    ::ndk::ScopedAStatus onSupplicantStateChanged(
+            const ::aidl::android::hardware::wifi::supplicant::
+                    SupplicantStateChangeData& /* stateChangeData */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onMloLinksInfoChanged(
+            ::aidl::android::hardware::wifi::supplicant::ISupplicantStaIfaceCallback::
+                    MloLinkInfoChangeReason /* reason */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDppConfigReceived(
+            const ::aidl::android::hardware::wifi::supplicant::
+                    DppConfigurationData& /* configData */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDppConnectionStatusResultSent(
+            ::aidl::android::hardware::wifi::supplicant::DppStatusErrorCode /* code */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onBssFrequencyChanged(int32_t /* frequencyMhz */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onQosPolicyResponseForScs(
+            const std::vector<::aidl::android::hardware::wifi::supplicant::
+                                      QosPolicyScsResponseStatus>& /* qosPolicyScsResponseStatus */)
+            override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onPmkSaCacheAdded(
+            const ::aidl::android::hardware::wifi::supplicant::PmkSaCacheData& /* pmkSaData */)
+            override {
+        return ndk::ScopedAStatus::ok();
+    }
 };
 
 class SupplicantStaIfaceAidlTest : public testing::TestWithParam<std::string> {
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
index b3f70da..973b56a 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -19,6 +19,7 @@
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
 #include <aidl/android/hardware/wifi/supplicant/BnSupplicantStaNetworkCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/TlsVersion.h>
 #include <android/binder_manager.h>
 #include <android/binder_status.h>
 #include <binder/IServiceManager.h>
@@ -51,6 +52,7 @@
 using aidl::android::hardware::wifi::supplicant::PairwiseCipherMask;
 using aidl::android::hardware::wifi::supplicant::ProtoMask;
 using aidl::android::hardware::wifi::supplicant::SaeH2eMode;
+using aidl::android::hardware::wifi::supplicant::TlsVersion;
 using aidl::android::hardware::wifi::supplicant::TransitionDisableIndication;
 using aidl::android::hardware::wifi::supplicant::WpaDriverCapabilitiesMask;
 using android::ProcessState;
@@ -98,6 +100,7 @@
             const std::vector<uint8_t>& /* certBlob */) override {
         return ndk::ScopedAStatus::ok();
     }
+    ::ndk::ScopedAStatus onPermanentIdReqDenied() override { return ndk::ScopedAStatus::ok(); }
 };
 
 class SupplicantStaNetworkAidlTest
@@ -648,6 +651,19 @@
 }
 
 /*
+ * SetStrictConservativePeerMode
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetStrictConversativePeerMode) {
+    int32_t version = 0;
+    sta_network_->getInterfaceVersion(&version);
+    if (version < 2) {
+        GTEST_SKIP() << "Skipping test since it is not supported on this interface version";
+    }
+    EXPECT_TRUE(sta_network_->setStrictConservativePeerMode(true).isOk());
+    EXPECT_TRUE(sta_network_->setStrictConservativePeerMode(false).isOk());
+}
+
+/*
  * SendNetworkEapIdentityResponse
  */
 TEST_P(SupplicantStaNetworkAidlTest, SendNetworkEapIdentityResponse) {
@@ -791,6 +807,21 @@
     EXPECT_TRUE(sta_network_->setRoamingConsortiumSelection(testSelection).isOk());
 }
 
+/*
+ * SetMinimumTlsVersionEapPhase1Param
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetMinimumTlsVersionEapPhase1Param) {
+    WpaDriverCapabilitiesMask caps;
+    EXPECT_TRUE(sta_iface_->getWpaDriverCapabilities(&caps).isOk());
+    const bool tlsV13Supported = !!(static_cast<uint32_t>(caps) &
+                                    static_cast<uint32_t>(WpaDriverCapabilitiesMask::TLS_V1_3));
+    LOG(INFO) << "TLS_V1_3 Supported: " << tlsV13Supported;
+
+    // Operation will succeed if TLS_V1_3 is supported, or fail otherwise.
+    EXPECT_EQ(sta_network_->setMinimumTlsVersionEapPhase1Param(TlsVersion::TLS_V1_3).isOk(),
+              tlsV13Supported);
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest);
 INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
index 31042a2..f2cb3f6 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
@@ -14,22 +14,16 @@
  * limitations under the License.
  */
 
-#ifndef SUPPLICANT_TEST_UTILS_H
-#define SUPPLICANT_TEST_UTILS_H
+#pragma once
 
-#include <VtsCoreUtil.h>
-#include <android-base/logging.h>
-#include <android/hardware/wifi/1.0/IWifi.h>
-#include <hidl/ServiceManagement.h>
-#include <supplicant_hidl_test_utils.h>
-#include <wifi_system/supplicant_manager.h>
+#include "supplicant_aidl_test_utils.h"
+#include "supplicant_legacy_test_utils.h"
 
 using aidl::android::hardware::wifi::supplicant::IfaceInfo;
 using aidl::android::hardware::wifi::supplicant::ISupplicant;
 using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
 using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
 using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
-using android::wifi_system::SupplicantManager;
 
 std::string getStaIfaceName() {
     std::array<char, PROPERTY_VALUE_MAX> buffer;
@@ -43,16 +37,7 @@
     return std::string(buffer.data());
 }
 
-std::string getWifiInstanceName() {
-    const std::vector<std::string> instances =
-        android::hardware::getAllHalInstanceNames(
-            ::android::hardware::wifi::V1_0::IWifi::descriptor);
-    EXPECT_NE(0, instances.size());
-    return instances.size() != 0 ? instances[0] : "";
-}
-
-bool keyMgmtSupported(std::shared_ptr<ISupplicantStaIface> iface,
-                      KeyMgmtMask expected) {
+bool keyMgmtSupported(std::shared_ptr<ISupplicantStaIface> iface, KeyMgmtMask expected) {
     KeyMgmtMask caps;
     if (!iface->getKeyMgmtCapabilities(&caps).isOk()) {
         return false;
@@ -67,22 +52,22 @@
     return keyMgmtSupported(iface, filsMask);
 }
 
-void startSupplicant() {
-    initializeDriverAndFirmware(getWifiInstanceName());
-    SupplicantManager supplicant_manager;
-    ASSERT_TRUE(supplicant_manager.StartSupplicant());
-    ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
+void stopSupplicantService() {
+    // Select method based on whether the HIDL or AIDL
+    // Vendor HAL is available.
+    if (SupplicantAidlTestUtils::useAidlService()) {
+        SupplicantAidlTestUtils::stopSupplicantService();
+    } else {
+        SupplicantLegacyTestUtils::stopSupplicantService();
+    }
 }
 
-// Wrapper around the implementation in supplicant_hidl_test_util.
-void stopSupplicantService() { stopSupplicant(getWifiInstanceName()); }
-
 void initializeService() {
-    ASSERT_TRUE(stopWifiFramework(getWifiInstanceName()));
-    std::system("/system/bin/start");
-    ASSERT_TRUE(waitForFrameworkReady());
-    stopSupplicantService();
-    startSupplicant();
+    if (SupplicantAidlTestUtils::useAidlService()) {
+        SupplicantAidlTestUtils::initializeService();
+    } else {
+        SupplicantLegacyTestUtils::initializeService();
+    }
 }
 
 void addStaIface(const std::shared_ptr<ISupplicant> supplicant) {
@@ -106,5 +91,3 @@
     }
     return supplicant;
 }
-
-#endif  // SUPPLICANT_TEST_UTILS_H
\ No newline at end of file